/* =============================================================
   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 es GLOBAL: la usa también el storefront (mega-menú, hovers de
       navegación cliente-final) — es la marca Kosiuko de cara al público, NO tocar. */
    --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 */

    /* Acento del ADMIN (pedido de Walter 2026-08-06): borravino/vino en vez del naranja
       del storefront, SOLO para botones primarios del panel interno. Se aplica vía
       override scopeado a `.rkxt-admin` (ver reglas .rkxt-btn-primary / .rkxt-tree-btn
       más abajo) — nunca reemplaza --rkxt-primary global. */
    --rkxt-admin-primary: #7A1F3D;        /* borravino */
    --rkxt-admin-primary-hover: #611931;  /* borravino más oscuro, hover/active */

    --rkxt-bg: #FFFFFF;
    --rkxt-bg-alt: #FBF8F4;           /* crema sutil */
    --rkxt-surface: #FFFFFF;
    --rkxt-surface-2: #F5F1EB;        /* crema más marcada */
    /* 2026-08-28 (Walter) — fondo del menú lateral del catálogo y de la cabecera de su grilla, "un
       poco más oscuro" que --rkxt-surface-2. Se DERIVA con color-mix en vez de fijar un gris: cada
       mundo de marca trae su propia superficie (Kosiuko crema, Herencia dorado, Label 99 otra) y un
       #EDEDED clavado se vería sucio en todas menos en una. Cambiar el 8% mueve las dos superficies
       a la vez, que es como Walter las pidió: juntas. */
    --rkxt-sf-panel-bg: color-mix(in srgb, var(--rkxt-surface-2) 92%, #000);
    /* Los dos controles que Walter quiere en NEGRO sí o sí (lupa del header y "Agregar al pedido"),
       por encima del acento del tema — en Herencia el acento es dorado y ahí no funcionan. */
    --rkxt-sf-btn-oscuro: #111111;
    /* Bordó para la acción destructiva del carrito (Walter 2026-08-29). Mismo valor que el
       borravino del admin (--rkxt-admin-primary), pero con token propio del storefront: son dos
       decisiones distintas —el acento del panel interno y el color de "descartar" en la tienda— y
       si algún día una cambia, no tiene por qué arrastrar a la otra. */
    --rkxt-sf-btn-bordo: #7A1F3D;
    --rkxt-sf-btn-bordo-hover: #611931;
    --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;

    /* 2026-08-29 (Walter) — la tinta de las tres sombras es NEUTRA. `md` era la excepción: tenía el
       naranja Rakuxt (rgba(235,82,2,.10)) hardcodeado mientras `sm` y `lg` ya usaban gris, así que
       el halo del hover salía naranja en cualquier tienda — en kosiuko-wholesale, que es azul
       corporativo, se veía un resplandor de otra marca. Una sombra es ausencia de luz, no un acento:
       el color de marca va en bordes, textos y fondos, que sí son parametrizables por tema. */
    --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(15, 15, 18, 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; }

/* Botones del asesor de recompra (Analizar / Simular), lado a lado — ficha del cliente y detalle
   del pedido del Colector. */
.rkxt-asesor-botones { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
.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); }
/* Admin-only: el árbol de categorías vive solo en /admin, pero el override queda scopeado
   igual (ver .rkxt-btn-primary más abajo) para que el borravino del admin nunca dependa de
   dónde se reutilice esta clase en el futuro. */
.rkxt-admin .rkxt-tree-btn:hover { border-color: var(--rkxt-admin-primary); color: var(--rkxt-admin-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); }

/* Admin (pedido de Walter 2026-08-06): botones primarios del panel interno en borravino en
   vez del naranja Kosiuko — el storefront (público, .rkxt-shell) sigue usando --rkxt-primary
   sin cambios. Scopeado a `.rkxt-admin` (wrapper de AdminLayout.razor), NO se toca la variable
   global --rkxt-primary. */
.rkxt-admin .rkxt-btn-primary {
    background: var(--rkxt-admin-primary);
    box-shadow: 0 6px 18px rgba(122, 31, 61, 0.22);
}

.rkxt-admin .rkxt-btn-primary:hover {
    background: var(--rkxt-admin-primary-hover);
    box-shadow: 0 8px 24px rgba(122, 31, 61, 0.28);
}

.rkxt-admin .rkxt-btn-primary:active { background: var(--rkxt-admin-primary-hover); }

.rkxt-btn-wine {
    background: var(--rkxt-admin-primary);
    color: #FFFFFF;
    box-shadow: 0 6px 18px rgba(122, 31, 61, 0.22);
}

.rkxt-btn-wine:hover {
    background: var(--rkxt-admin-primary-hover);
    color: #FFFFFF;
    box-shadow: 0 8px 24px rgba(122, 31, 61, 0.28);
}

.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);
}

/* TODAS las cabeceras de grilla del admin en borravino (2026-08-06, mismo acento que los botones
   — ver --rkxt-admin-primary más arriba). Gana por especificidad sobre los overrides puntuales que
   ya tenían algunas pantallas (Clientes, PedidoRecompra, PedidoColectorDetalle — esas reglas
   quedaron redundantes pero no rotas, mismo color). El sort de <ThOrden> (naranja en el resto del
   admin) pasa a blanco acá para no chocar con el fondo. */
.rkxt-admin .rkxt-table thead th {
    background: var(--rkxt-admin-primary);
    color: #fff;
    box-shadow: none;
}
.rkxt-admin .rkxt-th-sort:hover,
.rkxt-admin .rkxt-th-sort-active,
.rkxt-admin .rkxt-th-sort-active:hover,
.rkxt-admin .rkxt-th-sort-arrow {
    color: #fff;
}
.rkxt-admin .rkxt-th-sort:focus-visible { outline-color: #fff; }

.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);
}

/* Admin: mismo criterio que .rkxt-btn-primary — el hover de los botones ghost también
   pasa a borravino, para no mezclar naranja storefront con el acento nuevo del panel. */
.rkxt-admin .rkxt-btn-ghost:hover { border-color: var(--rkxt-admin-primary); }

/* ============ 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); }
}

/* ── Barra de progreso al lado del botón/link busy (rkxt-action-feedback.js) ──
   No hay canal servidor→cliente en los POST SSR clásicos, así que esto NO es
   un % real: es señal de vida para acciones largas (barra indeterminada +
   segundos transcurridos + hint opcional de contexto). Solo aparece si la
   acción tarda más de ~900ms (ver PROGRESS_DELAY_MS en el JS) — en acciones
   de 1s no llega a mostrarse, cero flash.
   `display:inline-flex` a propósito: si el botón vive en un contenedor en fila
   (.rkxt-form-actions, .rkxt-dash-toolbar) la barra queda AL LADO; si el
   contenedor es una columna (.rkxt-ed-aplicar) cae como renglón propio debajo.
   Ambos casos son correctos, se adapta al layout de cada pantalla. */
.rkxt-busy-progress {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: 12px;
    vertical-align: middle;
    max-width: 300px;
    animation: rkxt-busy-progress-in 0.18s ease-out;
}

@keyframes rkxt-busy-progress-in {
    from { opacity: 0; transform: translateX(-4px); }
    to   { opacity: 1; transform: none; }
}

.rkxt-busy-progress-track {
    position: relative;
    display: block;
    width: 110px;
    height: 6px;
    flex: 0 0 auto;
    border-radius: var(--rkxt-radius-pill);
    background: var(--rkxt-surface-2);
    overflow: hidden;
}

.rkxt-busy-progress-fill {
    position: absolute;
    inset: 0;
    display: block;
    width: 40%;
    border-radius: var(--rkxt-radius-pill);
    background: var(--rkxt-grad-primary);
    animation: rkxt-busy-progress-indeterminate 1.1s ease-in-out infinite;
}

@keyframes rkxt-busy-progress-indeterminate {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}

.rkxt-busy-progress-meta {
    display: flex;
    flex-direction: column;
    font-size: 11.5px;
    line-height: 1.3;
    color: var(--rkxt-text-muted);
    white-space: nowrap;
}

.rkxt-busy-progress-line { display: block; }

.rkxt-busy-progress-time {
    font-weight: 700;
    color: var(--rkxt-text);
    font-variant-numeric: tabular-nums;
}

.rkxt-busy-progress-hint {
    font-style: italic;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 220px;
}

.rkxt-busy-progress-patience {
    display: block;
    font-size: 11px;
    color: var(--rkxt-text-dim);
}

.rkxt-busy-progress-patience[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
    .rkxt-busy-progress-fill { animation: none; left: 0; width: 100%; opacity: .55; }
    .rkxt-busy-progress { animation: none; }
}

/* ── Overlay de página completa (OPT-IN, `data-busy-overlay="Título…"`) ──────
   Para la acción sincrónica realmente larga (ej. aplicar curva a todo el
   catálogo). Bloquea el resto de la pantalla mientras dura — evita que el
   usuario dispare otro submit de la misma página mientras espera, y da la
   señal fuerte de "esto sigue, no cierres esto" que pide la regla 4 de Rakuxt
   para procesos largos. No es el comportamiento default de ningún botón. */
.rkxt-busy-overlay {
    position: fixed;
    inset: 0;
    z-index: 9998;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(14, 14, 17, 0.45);
    backdrop-filter: blur(1.5px);
    animation: rkxt-busy-overlay-in 0.15s ease-out;
}

@keyframes rkxt-busy-overlay-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.rkxt-busy-overlay-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    max-width: 380px;
    padding: 28px 32px;
    background: var(--rkxt-surface);
    border-radius: var(--rkxt-radius);
    box-shadow: var(--rkxt-shadow-lg);
    text-align: center;
}

.rkxt-busy-overlay-spinner {
    width: 28px;
    height: 28px;
    border-width: 3px;
    margin-right: 0;
}

.rkxt-busy-overlay-title {
    font-size: 1rem;
    color: var(--rkxt-text);
}

.rkxt-busy-overlay-card .rkxt-busy-progress-track {
    width: 220px;
    height: 8px;
}

.rkxt-busy-overlay-card .rkxt-busy-progress-meta {
    align-items: center;
    text-align: center;
    white-space: normal;
}

.rkxt-busy-overlay-card .rkxt-busy-progress-hint {
    max-width: none;
    white-space: normal;
}

/* ============================================================================
   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);
}

/* Selección sutil: sin recuadro de color de fondo, solo el borde izquierdo acentuado +
   negrita, en blanco — nada de naranja acá (a pedido explícito). */
.rkxt-admin-link.active {
    background: transparent;
    color: #fff;
    border-left-color: #fff;
    font-weight: 700;
}

/* El sidebar admin tiene fondo negro fijo (AdminLayout.razor.css, igual al de la topbar) en
   vez del crema casi blanco de --rkxt-bg-alt del resto del panel. --rkxt-text-dim casi no
   contrasta contra el negro, así que el estado default de los links (no hover, no active) se
   overridea acá a blanco. */
.rkxt-admin-sidebar .rkxt-admin-link,
.rkxt-admin-sidebar .rkxt-admin-group-toggle,
.rkxt-admin-sidebar .rkxt-admin-group-chevron,
.rkxt-admin-sidebar .rkxt-field-label {
    color: rgba(255, 255, 255, 0.85);
}

/* Bug encontrado 2026-08-06 (reporte de Walter: "recuadro blanco que tapa la palabra") — el hover
   genérico de .rkxt-admin-link (más abajo) pone fondo BLANCO sólido + texto oscuro, pero acá arriba
   hay una regla con la MISMA especificidad (2 clases) que fija el texto en casi-blanco; por orden de
   aparición esta gana también en :hover, así que quedaba texto casi blanco sobre fondo blanco — la
   palabra se volvía invisible, no era solo "brusco". Fix: override explícito con más especificidad
   (3 clases) y un tinte translúcido en vez de blanco sólido — mucho más sutil y sin flip de color. */
.rkxt-admin-sidebar .rkxt-admin-link:hover,
.rkxt-admin-sidebar .rkxt-admin-group-toggle:hover {
    background: rgba(255, 255, 255, 0.08);
}

/* Un poco más chico que el default (.rkxt-admin-link 0.92rem / .rkxt-admin-link-sub 0.88rem). */
.rkxt-admin-sidebar .rkxt-admin-link {
    font-size: 0.82rem;
}

.rkxt-admin-sidebar .rkxt-admin-link.active {
    color: #fff;
}

/* El fix de que el footer no invada la columna del sidebar admin vive en MainLayout.razor.css
   (.rkxt-footer-admin) — se decide por ruta en el @code de MainLayout, no acá. El intento
   anterior con :has() cruzando scopes (MainLayout↔AdminLayout) no se aplicaba de forma
   confiable en la práctica y se sacó. */

/* ============================================================================
   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 INCLUYE el ancho de la scrollbar vertical → son más
       anchos que el viewport visible. `clip` recorta el sobrante 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).

       ⚠️ El sobrante NO es "1px" como decía este comentario: es la MITAD de la scrollbar por lado.
       Medido en rakuxt.com/t/kosiuko-wholesale (2026-08-13, Chrome 1920px, scrollbar 15px):
       .rkxt-sf-footer-motor arranca en left = −7,5px y mide 1920. Con padding lateral CERO —que es
       justo lo que trae sAncho='completo'— eso se come la PRIMERA LETRA del texto pegado al borde
       ("OLÍTICAS" en vez de "POLÍTICAS"). Para fotos/fondos es invisible; para texto no.
       ⇒ Regla de producto: sAncho='completo' solo para fondos, fotos y cintillos que entran y salen
       de cuadro. Cualquier sección con TEXTO cerca del borde va sAncho='contenido' (se recentra a
       1200 con padding fluido). Los moldes atómicos de texto ya se auto-acotan por CSS (ver la
       lista de .rkxt-sf-sec-ancho-completo .rkxt-sf-sec-col > …), pero las columnas de links del
       footer (MenuLinks/Redes/AppBadges) NO están en esa lista a propósito: capar cada columna por
       separado les mete padding interno y las descoloca. Arreglarlo de raíz pide compensar el
       ancho de la scrollbar por JS (--sbw) — pendiente, no vale un flash de layout en SSR. */
    overflow-x: clip;
}

/* ── TELÓN al cambiar de mundo de marca (DOC11 F2) ───────────────────────────────────────────
   Reemplazó al "pliegue" (el shell se corría 14% y bajaba a opacity .3, y el mundo nuevo entraba
   desde el otro costado). El dueño lo pidió como telón de teatro: «un barrido perfecto, mientras
   una página se va mostrando la otra se va ocultando».

   CÓMO: un panel del COLOR DE LA MARCA DESTINO barre la pantalla, siempre hacia la izquierda —
   entra desde la derecha (de donde salen las lengüetas) tapando la página actual, y después de la
   navegación sigue viajando hacia la izquierda destapando la nueva. Un solo movimiento continuo de
   200vw partido en dos mitades por el full page reload (regla: el storefront navega con
   data-enhance-nav="false"). Efecto lateral bienvenido: el parpadeo blanco del reload queda
   ESCONDIDO detrás del telón, así que la transición se siente más limpia que antes.

   POR QUÉ UN PSEUDO-ELEMENTO DE <html> Y NO UN <div>:
   la mitad de ENTRADA tiene que estar cubriendo la pantalla ANTES del primer paint — si no, se ve
   un frame de la página nueva y recién después el telón, que es exactamente lo que arruina el
   efecto. Los <script> del sitio van al final del <body>, demasiado tarde. Con un pseudo-elemento
   alcanza con que un script inline del <head> ponga una clase en <html> (no necesita que exista
   el body, no crea DOM y el CSS ya está cargado porque app.css es render-blocking).

   El shell NO se mueve más. Además de simplificar, saca un bug latente: un `transform` en el shell
   lo convierte en containing block y los position:fixed de adentro (header sticky, globo de
   WhatsApp, la propia guía) dejan de anclarse al viewport mientras dura la animación. */

/* Los colores los pone el JS/head en <html> con los valores REALES de la lengüeta clickeada
   (background y color ya resueltos por getComputedStyle) → el telón es del color de la marca a la
   que vas. El fallback solo existe para que nunca haya un telón transparente. */
html.rkxt-telon::before,
html.rkxt-telon::after {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    /* Sobre TODO el chrome del storefront: la guía está en z-index 90 y el globo de WhatsApp en
       100 — el telón tiene que taparlos también, si no "asoman" flotando sobre el barrido. */
    z-index: 9990;
    will-change: transform;
}

html.rkxt-telon::before {
    background: var(--rkxt-telon-color, #111111);
}

/* Nombre de la marca destino, viajando con el telón: dice a dónde vas y le da el aire editorial
   del cartel de teatro. Sale de data-rkxt-telon; sin el atributo, content queda vacío y no se ve. */
html.rkxt-telon::after {
    content: attr(data-rkxt-telon);
    z-index: 9991;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--rkxt-telon-fg, #FFFFFF);
    font-family: var(--rkxt-font-display, var(--rkxt-font-body, inherit));
    font-size: clamp(1.1rem, 3.5vw, 2.4rem);
    font-weight: 600;
    letter-spacing: .34em;
    text-transform: uppercase;
    opacity: .92;
    padding-inline: 1rem;
    text-align: center;
}

/* Mitad 1 — el telón entra desde la derecha y tapa (el JS navega al terminar).
   Mitad 2 — el telón sigue hacia la izquierda y destapa el mundo nuevo, ya renderizado abajo.
   `both` en las dos: la 1 tiene que QUEDAR cubriendo hasta que el browser cambie de página, y la 2
   tiene que quedar fuera de pantalla si algo impide limpiar la clase. */
html.rkxt-telon-entra::before,
html.rkxt-telon-entra::after {
    animation: rkxt-telon-entra 400ms cubic-bezier(.76, 0, .24, 1) both;
}

html.rkxt-telon-sale::before,
html.rkxt-telon-sale::after {
    animation: rkxt-telon-sale 460ms cubic-bezier(.76, 0, .24, 1) both;
}

@keyframes rkxt-telon-entra { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes rkxt-telon-sale  { from { transform: translateX(0);    } to { transform: translateX(-100%); } }

/* Quien pidió menos movimiento navega sin animación (el JS ya ni intercepta el click, así que la
   mitad de entrada tampoco se arma; esto es el cinturón por si la clase quedó de una sesión previa). */
@media (prefers-reduced-motion: reduce) {
    html.rkxt-telon::before,
    html.rkxt-telon::after {
        animation: none;
        display: none;
    }
}

/* 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; }
/* Menú propio de la marca en la fila del header (HeaderProps.Links). `margin-right:auto` es lo que
   arma el layout de header editorial: logo a la izquierda, links a continuación y los iconos
   empujados al extremo derecho — igual que herenciacustomgarage/kosiuko. Sin eso, los links quedan
   pegados a los iconos porque .rkxt-sf-nav alinea todo a la derecha. */
.rkxt-sf-nav-links {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 2.2vw, 2rem);
    margin-right: auto;
    margin-left: clamp(1rem, 3vw, 2.5rem);
    flex-wrap: wrap;
}
/* El selector lleva `.rkxt-sf-nav` adelante a propósito: `.rkxt-sf-nav a` ya fija un gris para los
   links utilitarios del header y, con la misma especificidad, ganaba por orden en el archivo. Estos
   links son el MENÚ de la marca: tienen que tomar el color de texto del header (el que el operador
   eligió en el componente), no el gris de los utilitarios. El color por-link, si está, llega inline
   y pisa igual. */
.rkxt-sf-nav .rkxt-sf-nav-links a {
    text-transform: uppercase;
    letter-spacing: .06em;
    font-size: .82rem;
    font-weight: 500;
    white-space: nowrap;
    text-decoration: none;
    color: inherit;
    transition: opacity .15s ease;
}
.rkxt-sf-nav .rkxt-sf-nav-links a:hover { opacity: .62; text-decoration: none; }

/* En pantallas chicas los links del header se esconden: el menú vive en el drawer (donde también
   se listan estos mismos links). Sin esto, 6 items en una fila rompen el header en mobile. */
@media (max-width: 900px) {
    .rkxt-sf-nav-links { display: none; }
}

/* Hamburguesa del header CLÁSICO: sólo en mobile. En desktop el menú ya está en la fila del header
   (los links de la marca o el trigger del mega-menú), así que mostrarla sería duplicar la puerta;
   en mobile es la ÚNICA, porque la fila de links está oculta por la regla de arriba. El header
   centrado usa .rkxt-sf-hamb a secas y la muestra siempre — ahí es parte del diseño. */
.rkxt-sf-hamb--movil { display: none; }
@media (max-width: 900px) {
    .rkxt-sf-hamb--movil { display: inline-flex; }
}

/* 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; }

/* "Mi cuenta" en el header (Walter 22/08, ajustado 22/08): el nombre del cliente es un LINK
   directo a /cuenta/pedidos (página principal de cuenta, /cuenta quedó oculta). Al lado, una
   flechita aparte con <details> nativo (sin JS propio) que SOLO despliega "Cerrar sesión". */
.rkxt-sf-cuenta-wrap { display: inline-flex; align-items: center; gap: 2px; }
.rkxt-sf-cuenta-dd { position: relative; }
.rkxt-sf-cuenta-dd-caret {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    cursor: pointer;
    list-style: none;
    font-size: .8rem;
    opacity: .7;
    border-radius: var(--rkxt-radius-sm, 6px);
}
.rkxt-sf-cuenta-dd-caret:hover { opacity: 1; background: var(--rkxt-surface-2); }
.rkxt-sf-cuenta-dd-caret::-webkit-details-marker { display: none; }
.rkxt-sf-cuenta-dd-panel {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 6px;
    min-width: 170px;
    background: var(--rkxt-surface, #fff);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm, 8px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .14);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 20;
}
.rkxt-sf-cuenta-dd-panel a,
.rkxt-sf-cuenta-dd-panel button {
    display: block;
    width: 100%;
    padding: 8px 10px;
    border: none;
    background: none;
    text-align: left;
    border-radius: var(--rkxt-radius-sm, 6px);
    color: var(--rkxt-text);
    text-decoration: none;
    font-size: .85rem;
    font-weight: 500;
    cursor: pointer;
}
.rkxt-sf-cuenta-dd-panel a:hover,
.rkxt-sf-cuenta-dd-panel button:hover { background: var(--rkxt-surface-2); }
.rkxt-sf-cuenta-dd-panel form { margin: 0; }

/* Lupa del header CENTRADO: dropdown con el input de búsqueda, mismo patrón <details> que la
   cuenta. La barra "clásica" (header con buscador en la fila) no usa esto. */
.rkxt-sf-search-dd { position: relative; }
.rkxt-sf-search-dd > summary { cursor: pointer; list-style: none; }
.rkxt-sf-search-dd > summary::-webkit-details-marker { display: none; }
.rkxt-sf-search-dd-panel {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 6px;
    width: max(260px, 80vw);
    max-width: 320px;
    background: var(--rkxt-surface, #fff);
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm, 8px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .14);
    padding: 8px;
    display: flex;
    align-items: center;
    gap: 6px;
    z-index: 20;
}
.rkxt-sf-search-dd-panel input {
    flex: 1;
    min-width: 0;
}
.rkxt-sf-search-dd-panel button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex: none;
    border: none;
    background: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary, #fff);
    border-radius: var(--rkxt-radius-sm, 6px);
    cursor: pointer;
}

/* 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.
   El wrapper .rkxt-sf-pagina entra en la lista porque también es full-bleed (width:100vw +
   margin-inline negativo): sin neutralizarlo se lleva las columnas 44px a la izquierda del panel y
   la primera queda CORTADA contra el borde de la ventana, con el resto repartido por todo el
   viewport en vez de por el ancho útil. */
.rkxt-sf-mega-body .rkxt-sf-pagina,
.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; }
}

/* En celular el mega-menú es el menú: la hamburguesa abre este mismo panel y las columnas se apilan
   (5→3→2→1). Apiladas, las de categorías —con sus hijos y su "Ver todo"— empujan la columna de links
   hasta el fondo: para llegar al catálogo hay que pasar tres ramas enteras. En pantalla chica esa
   columna sube al principio. Solo reordena lo apilado; en desktop el orden es el que armó el
   operador (y en los menús de marca, el calcado de la web minorista). */
@media (max-width: 680px) {
    .rkxt-sf-mega-body .rkxt-sf-sec-col:has(> .rkxt-sf-ml) { order: -1; }
}

/* 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; }
    /* Mismo tamaño que el nombre también en mobile: acá el precio quedaba MÁS GRANDE que la prenda. */
    .rkxt-sf-card-precio { font-size: 0.92rem; }
}
@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; }
}

/* ===== FILAS DE BANNERS: en celular NO se apilan, se deslizan (2026-08-20) =====

   El colapso a 1 columna es lo correcto para un footer o una fila de texto, pero para una fila de
   banners de categoría es pésimo: cuatro fotos full-bleed apiladas son cuatro pantallas enteras de
   scroll para mostrar lo que en escritorio se ve de un vistazo. Medido en el mayorista antes de
   esta regla: la home de Kosiuko pasaba de 9.500px en escritorio a 12.500px en un teléfono de
   390px de ancho. Ninguna de las cuatro webs minoristas hace eso — todas publican esa misma fila
   como carrusel horizontal en celular (`row-slider-3` / `banner-section mobile-only` en su tema).

   La regla se acota SOLA al caso correcto con :has() — una sección a todo el ancho cuyas columnas
   contienen UNA imagen full-width y nada más. Eso es exactamente una fila de banners, y nunca un
   footer (sus columnas llevan MenuLinks). NO se pide además que la sección sea "ancho completo":
   una fila de categorías puede ir al ancho del contenido y necesita deslizarse igual (Casa Chic
   publica sus dos filas así). Lo que discrimina es la columna, no el ancho. Sin :has() el navegador
   ignora el bloque y queda el apilado de antes: es mejora progresiva, no un requisito.

   Se deja asomar la tarjeta siguiente (86% de ancho) porque una que ocupa el 100% no da ninguna
   pista de que hay más al costado — el mismo motivo por el que el hero muestra los dots. */
@media (max-width: 680px) {
    .rkxt-sf-sec:is(.rkxt-sf-sec-2col, .rkxt-sf-sec-3col, .rkxt-sf-sec-4col, .rkxt-sf-sec-5col):has(> .rkxt-sf-sec-cols > .rkxt-sf-sec-col > .rkxt-sf-img.is-alto-auto:only-child)
    > .rkxt-sf-sec-cols {
        display: flex;
        grid-template-columns: none;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        scroll-behavior: smooth;
        scrollbar-width: none;
        gap: 8px;
    }
    .rkxt-sf-sec:is(.rkxt-sf-sec-2col, .rkxt-sf-sec-3col, .rkxt-sf-sec-4col, .rkxt-sf-sec-5col):has(> .rkxt-sf-sec-cols > .rkxt-sf-sec-col > .rkxt-sf-img.is-alto-auto:only-child)
    > .rkxt-sf-sec-cols::-webkit-scrollbar { display: none; }
    .rkxt-sf-sec:is(.rkxt-sf-sec-2col, .rkxt-sf-sec-3col, .rkxt-sf-sec-4col, .rkxt-sf-sec-5col):has(> .rkxt-sf-sec-cols > .rkxt-sf-sec-col > .rkxt-sf-img.is-alto-auto:only-child)
    > .rkxt-sf-sec-cols > .rkxt-sf-sec-col {
        flex: 0 0 86%;
        scroll-snap-align: center;
    }
}

/* ===== 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: respira más 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).

       2026-08-29 (Walter) — bajado de 3rem/1.5rem a 1.75rem/1rem. El footer venía sumando aire
       tres veces: este padding, MÁS el padding propio de cada sección con fondo, MÁS el alto del
       bloque de newsletter. Sacado el newsletter (ver footer-sacar-newsletter-2026-08-29.sql), el
       pie quedaba igual de alto porque el aire seguía siendo el de un footer de tres franjas. */
    padding-block: clamp(1.25rem, 2.5vw, 1.75rem) clamp(.75rem, 2vw, 1rem);

    /* 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);
}

/* Las secciones con fondo traen el padding de una franja de PÁGINA (hasta 3rem arriba y abajo),
   que es el aire correcto para un bloque de contenido pero no para una franja de pie: en un
   footer de dos o tres secciones apiladas ese padding se cobra dos veces por cada costura y el
   pie termina midiendo más que muchas pantallas de contenido.
   Sólo el eje VERTICAL: el lateral define el calce del full-bleed (ver el comentario de
   .rkxt-sf-footer-motor) y tocarlo desborda el ancho. (2026-08-29, Walter: "el footer tiene que
   ser más bajo, es muy alto"). */
.rkxt-sf-footer-motor .rkxt-sf-sec-fondo {
    padding-block: clamp(1rem, 2.5vw, 1.75rem);
}

/* 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) con
   --rkxt-card-hover-lift, --rkxt-card-hover-border, --rkxt-card-hover-shadow y --rkxt-card-img-zoom;
   un tema editorial puede apagarlo entero y dejar solo el zoom sutil de la imagen.

   2026-08-29 (Walter) — por default el hover ya NO pinta el borde con el color de acento. Al pasar
   el mouse por una foto del listado la card se enmarcaba en el --rkxt-primary del tema, que en
   kosiuko-wholesale es azul corporativo (#1E40AF): un recuadro azul fuerte alrededor de la prenda.
   Ahora el borde de hover queda en --rkxt-border, el mismo que en reposo, así que la card no se
   enmarca — el hover sigue existiendo por el lift y la sombra.

   Se invirtió el DEFAULT en vez de apagarlo por tema a propósito: apagarlo en el JSON del tema deja
   el recuadro escondido a un cambio de dato (basta asignarle tema propio a un mundo de marca, o que
   el seeder built-in pise las variables, para que reaparezca sin que nadie entienda de dónde salió).
   El tema que lo quiera lo enciende explícito: --rkxt-card-hover-border: var(--rkxt-primary); */
.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-border));
    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);
}

/* 2026-08-28 (Walter) — el precio va del MISMO color que el nombre de la prenda, sin negrita y más
   fino que él. Antes salía en el acento de la marca (--rkxt-primary: dorado en Herencia, naranja en
   Kosiuko) en 700 y un punto MÁS GRANDE que el nombre, así que gritaba más fuerte que el producto.
   Ahora el nombre manda (700) y el precio acompaña (400), los dos en --rkxt-on-surface y al mismo
   tamaño: la jerarquía la da el peso, no el color.
   .rkxt-sf-precio-now hereda color y weight, así que alcanza con tocar acá. La ÚNICA excepción que
   se conserva es el precio de oferta, que sigue en rojo (.has-oferta) — ahí el color no es adorno,
   es la señal de que hay descuento. */
.rkxt-sf-card-precio {
    color: var(--rkxt-on-surface);
    font-weight: 400;
    font-size: 1rem;
    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: block;
    position: relative;
    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;
}

/* Mismo criterio que .rkxt-sf-card (2026-08-29, Walter): la tarjeta de categoría tampoco se enmarca
   en el color de acento al pasar el mouse — es la misma foto con el mismo recuadro azul, sólo que
   en la grilla de categorías en vez de la de productos. Queda el lift + la sombra. */
.rkxt-sf-cat-card:hover {
    transform: translateY(-2px);
    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;
}

/* Nombre de categoría superpuesto sobre la foto (estilo kosiuko.com): serif institucional en
   blanco, centrado, con el subrayado fino característico. `rkxt-sf-cat-card` necesita
   position:relative (arriba) para que este absolute tome la tarjeta entera como referencia. */
.rkxt-sf-cat-card-name {
    position: absolute;
    left: 50%;
    top: 55%;
    transform: translate(-50%, -50%);
    width: max-content;
    max-width: 88%;
    text-align: center;
    font-family: var(--rkxt-font-serif);
    font-weight: 400;
    font-size: clamp(1.05rem, 1.6vw, 1.55rem);
    letter-spacing: 0.01em;
    color: #FFFFFF;
    text-decoration: underline;
    text-underline-offset: 10px;
    text-decoration-thickness: 1px;
    text-shadow: 0 1px 10px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

/* Sin foto (placeholder con iniciales): el nombre vuelve a ser una etiqueta normal debajo,
   blanco sobre fondo claro sería ilegible. */
.rkxt-sf-cat-card-sinfoto {
    display: flex;
    flex-direction: column;
}

.rkxt-sf-cat-card-sinfoto .rkxt-sf-cat-card-name {
    position: static;
    transform: none;
    width: auto;
    max-width: none;
    padding: 14px 18px;
    font-family: inherit;
    font-weight: 600;
    font-size: 1rem;
    letter-spacing: normal;
    color: var(--rkxt-on-surface);
    text-decoration: none;
    text-shadow: none;
    pointer-events: auto;
}

/* ============ 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.3rem;
    font-weight: 400;
    text-transform: uppercase;
    margin-bottom: 4px;
}

.rkxt-sf-pdp-sku {
    color: var(--rkxt-text-muted);
    margin-bottom: 16px;
}

.rkxt-sf-pdp-precio {
    color: var(--rkxt-text);
    font-family: var(--rkxt-font-display);
    font-size: 1.3rem;
    font-weight: 400;
    margin-bottom: 14px;
}

.rkxt-sf-pdp-detalle {
    margin-top: 24px;
}

.rkxt-sf-pdp-detalle h2 {
    font-size: 1rem;
    text-transform: uppercase;
    margin: 0 0 8px 0;
    color: var(--rkxt-text);
}

.rkxt-sf-pdp-desc {
    color: var(--rkxt-text-muted);
    font-size: 0.85rem;
    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);
}

/* Botón "Agregar al carrito" de la ficha — negro sólido / letras blancas, estilo Kosiuko
   (referencia: kosiuko.com #product-addtocart-button), sin tocar --rkxt-primary del resto
   del sitio. Scoped a .rkxt-sf-pdp-cta a propósito: no es el primary institucional. */
.rkxt-sf-pdp-cta button[type="submit"].rkxt-btn-primary {
    background: #000000;
    border-color: #000000;
    color: #ffffff;
    box-shadow: none;
    font-weight: 400;
    width: 100%;
}
.rkxt-sf-pdp-cta button[type="submit"].rkxt-btn-primary:hover {
    background: #1a1a1a;
    border-color: #1a1a1a;
    box-shadow: none;
}

/* 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-precio { 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: 10px;
}

.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 10px;
}

/* Botón "Volver" mínimo (ficha de producto) — chico y casi del color de la
   página: fondo transparente, solo un borde sutil para que se note que es
   clickeable, sin gritar como acción secundaria del CTA principal. */
.rkxt-sf-volver-mini {
    background: transparent;
    color: var(--rkxt-text-muted);
    border: 1px solid var(--rkxt-border);
    padding: 4px 10px;
    font-size: 0.72rem;
    font-weight: 400;
    box-shadow: none;
}
.rkxt-sf-volver-mini:hover {
    background: var(--rkxt-bg-alt);
    color: var(--rkxt-text);
    border-color: var(--rkxt-text-dim);
}

.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;
}

/* Chip informativo en la línea del breadcrumb. Hoy lo usa el mundo de marca (DOC11) para avisar
   que la vista está mostrando todas las marcas porque se está revisando el pedido en curso. */
.rkxt-sf-bc-chip {
    margin-left: 8px;
    padding: 2px 8px;
    border: 1px solid var(--rkxt-border);
    border-radius: 999px;
    font-size: 11px;
    letter-spacing: .02em;
    color: var(--rkxt-text-muted);
    white-space: nowrap;
}

/* 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: 200px 1fr;   /* 2026-08-28: columna mas angosta (Walter) */
    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 */
    }
}

/* 2026-08-28 (Walter) — el panel del catálogo dejó de ser una caja de filtros y pasó a ser un menú
   de navegación despojado, con el mismo look del mega-menú: sin recuadro, sin fondo, sin padding de
   caja y SIN SCROLL PROPIO (tiene que entrar en la pantalla). Se mantiene sticky para que acompañe
   al scroll de la grilla, pero sin max-height ni overflow: si algún día no entrara, se corta el
   árbol —mostrando menos ramas— antes que devolverle la barra de scroll. */
.rkxt-sf-sidebar {
    /* Fondo apenas distinto del papel (Walter, 2026-08-28: "probemos un fondo apenas gris"). Sale del
       token del tema, NO de un gris fijo: cada mundo de marca define el suyo, y un #F5F5F5 hardcodeado
       se vería sucio sobre el fondo de Herencia o de Label 99. Sin borde: el fondo separa la columna
       sin dibujar el recuadro que Walter pidió sacar. */
    background: var(--rkxt-sf-panel-bg);
    border: none;
    border-radius: var(--rkxt-sf-radius);
    padding: 18px 16px;
    /* 2026-08-28 (Walter): "el sombreado tiene que ocupar todo el ancho del sector que tiene destinado
       al costado de la grilla". Antes era height:fit-content, así que el fondo terminaba donde
       terminaba la última categoría y al lado de una grilla larga quedaba una manchita corta. Ahora la
       columna se estira a todo el alto de la fila y el sticky se mueve ADENTRO, al <nav>: el sombreado
       acompaña a la grilla y el menú sigue pegado arriba al scrollear. */
    align-self: stretch;
}
.rkxt-sf-sidebar > nav {
    position: sticky;
    /* Pegado a la altura del PRIMER registro (debajo del header de tienda + encabezado de columnas
       sticky, medido en --rkxt-sf-panel-top) para que no se esconda tras la cabecera al scrollear. */
    top: calc(var(--rkxt-sf-panel-top, 20px) + 4px);
}

/* ===== Menú de categorías del catálogo (2026-08-28) =====
   Una sola columna, sin cajas. La tipografía NO se redefine acá: el título de cada raíz usa
   .rkxt-sf-ml-tit y las hijas .rkxt-sf-ml-list, las mismas del mega-menú, así que las dos vistas
   comparten fuente/tamaño/espaciado por construcción y no por copia. Acá solo se ajusta la métrica
   vertical (el título del menú trae 1rem de margen inferior, demasiado para un panel que tiene que
   entrar en pantalla) y el estado activo. */
/* Tamaño: un punto por debajo del mega-menú (Walter, 2026-08-28). Se baja ACÁ y no en
   .rkxt-sf-ml-tit/.rkxt-sf-ml-list, que son compartidas con el menú de la hamburguesa y con el
   footer — tocarlas ahí encogería las tres. */
.rkxt-sf-catnav { display: flex; flex-direction: column; gap: 1rem; font-size: .85rem; }
.rkxt-sf-catnav .rkxt-sf-ml-tit { font-size: .72rem; }
.rkxt-sf-catnav-todo {
    color: inherit; text-decoration: none; opacity: .82;
    font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
}
.rkxt-sf-catnav-todo:hover { opacity: 1; text-decoration: underline; }
.rkxt-sf-catnav-grupo { display: flex; flex-direction: column; }
/* El título de raíz es un LINK (filtra por esa rama entera), pero se ve como el título del menú. */
.rkxt-sf-catnav-raiz { display: block; margin: 0 0 .5rem; color: inherit; text-decoration: none; }
.rkxt-sf-catnav-raiz:hover { text-decoration: underline; }
.rkxt-sf-catnav-hijas { gap: .4rem; padding-left: .1rem; }
/* Activo = la rama en la que estoy parado. Sin recuadro ni fondo: solo peso y opacidad plena,
   coherente con un menú despojado. */
.rkxt-sf-catnav .is-activa { opacity: 1; font-weight: 700; }

/* ===== 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: 200px 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 > nav { display: none; }   /* 2026-08-28: el panel es <nav>, ya no <form> */
.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 del panel/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-panel {
    position: relative;
    z-index: 2;
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 24px 40px 40px 40px;
}

.rkxt-auth-panel-card {
    width: 100%;
    max-width: 368px;
    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-foot {
        padding: 12px 20px 16px 20px;
        justify-content: center;
        text-align: center;
    }
}

@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 ============ */
/* ── Selector de mundo de marca del editor (DOC11 F3) ────────────────────────────────────────
   Va ARRIBA de las tabs de página y con otro peso visual (pills sobre panel, no subrayado):
   son dos ejes distintos —qué marca y qué página— y confundirlos sería fácil si compartieran
   el mismo tratamiento. Elegir mundo cambia TODO lo de abajo, así que manda jerárquicamente. */
.rkxt-diseno-mundos {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin: 20px 0 -8px;
    padding: 10px 12px;
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: 10px;
}

.rkxt-diseno-mundos-label {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--rkxt-text-muted);
    margin-right: 4px;
}

.rkxt-diseno-mundo {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--rkxt-surface);
    border: 1px solid var(--rkxt-border);
    border-radius: 999px;
    padding: 6px 14px;
    font-size: 13px;
    font-weight: 600;
    color: var(--rkxt-text);
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.rkxt-diseno-mundo:hover {
    border-color: var(--rkxt-primary);
}

.rkxt-diseno-mundo.is-active {
    background: var(--rkxt-primary);
    border-color: var(--rkxt-primary);
    color: var(--rkxt-fg-on-primary);
}

/* El diseño de la tienda es el que heredan los demás: se marca aparte para que no se lea como
   "una marca más" en la fila. */
.rkxt-diseno-mundo-base {
    font-style: italic;
}

.rkxt-diseno-mundo-hereda {
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .04em;
    opacity: .65;
    border: 1px solid currentColor;
    border-radius: 4px;
    padding: 0 4px;
}

/* Aviso de "este mundo todavía hereda": no es un error, es el estado normal de una marca nueva. */
.rkxt-diseno-hereda {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 14px 16px;
    margin-bottom: 16px;
    background: var(--rkxt-bg-alt);
    border: 1px dashed var(--rkxt-border);
    border-radius: 10px;
}

/* Variante de alerta: tocaste un bloque que no es de este mundo. No es un error del sistema, es
   una aclaración de a quién le pertenece lo que estás por editar — de ahí el ámbar y no el rojo. */
.rkxt-diseno-hereda-alerta {
    border-style: solid;
    border-color: #d97706;
    background: #fffbeb;
}

.rkxt-diseno-hereda-acciones {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}

/* Path del preview junto al título: deja ver a qué mundo apunta el iframe. */
.rkxt-diseno-preview-path {
    font-size: 11px;
    font-weight: 400;
    color: var(--rkxt-text-muted);
    background: var(--rkxt-bg-alt);
    border: 1px solid var(--rkxt-border);
    border-radius: 4px;
    padding: 1px 6px;
    margin-left: 6px;
}

.rkxt-diseno-hereda strong {
    display: block;
    margin-bottom: 2px;
}

.rkxt-diseno-hereda span {
    font-size: 13px;
    color: var(--rkxt-text-muted);
}

.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 del color de una MARCA en el listado /admin/config/marcas: muestra el hex sobre su propio
   color, con el texto que va a usar la lengüeta real (calculado por contraste, ColorUtil.TextoSobre).
   Así el listado no "dice" el color: lo muestra tal como se va a ver en el storefront. A diferencia
   de .rkxt-color-demo NO fuerza color ni text-shadow — el contraste ya está resuelto. */
.rkxt-marca-chip {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid rgba(0, 0, 0, .12);
    font: 600 .72rem/1.5 var(--rkxt-font-mono, monospace);
    letter-spacing: .02em;
}

/* 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;
}

/* 2026-08-25 (a pedido de Walter) — el corte estaba en 1100px de ventana, pero el sidebar del admin
   (260px) + el padding del contenido (72px) se comen ~332px reales antes de llegar a esta grilla: en
   una notebook de 1280px (caso reportado: 15", 1280x1024) el contenido disponible son ~948px, muy por
   debajo de los ~1100 que esta regla asumía. Corte movido a 1500px de VENTANA (≈ 1100 + esos ~332px +
   margen) para que las cards de 4 columnas pasen a 2 antes de apretarse ilegibles. */
@media (max-width: 1500px) {
    .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;
}
/* 2026-08-25 (a pedido de Walter) — mismo motivo que .rkxt-dash-grid arriba: el corte real tiene que
   contemplar el sidebar+padding del admin (~332px), no el ancho de ventana pelado. */
@media (max-width: 1500px) { .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;
}
/* 2026-08-25 — mismo ajuste por el sidebar+padding del admin (~332px reales): 900px de ventana
   pelada dejaba ~568px de contenido para 2 gráficos Chart.js, subido a 1100 (≈768px reales). */
@media (max-width: 1100px) { .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;
}

/* ============ 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;
}
/* Admin: el anillo de foco (accesibilidad teclado) de los botones también en borravino.
   `.rkxt-sf-search-btn` es storefront — queda afuera a propósito. */
.rkxt-admin .rkxt-btn:focus-visible { outline-color: var(--rkxt-admin-primary); }
.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; }

/* --- 4. FranjaLogos: fila de logos con enlace (marcas del grupo, medios de pago, sellos) ---
   El alto lo fija cada logo por style inline (se calibra por marca: un SVG con aire en el viewBox
   se ve chico al lado de un PNG ajustado con el mismo height). El gap es fluido para que la fila
   se comprima en mobile antes de apilarse. */
.rkxt-sf-logos {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: clamp(var(--rkxt-logos-gap-min, 20px), 5vw, var(--rkxt-logos-gap-max, 40px));
    padding: 8px 16px;
}
.rkxt-sf-logos.is-izquierda { justify-content: flex-start; }
.rkxt-sf-logos.is-centro    { justify-content: center; }
.rkxt-sf-logos.is-derecha   { justify-content: flex-end; }
.rkxt-sf-logo {
    display: flex; align-items: center; justify-content: center;
    opacity: var(--rkxt-logos-op, 1);
    transition: opacity .2s ease, filter .2s ease;
}
.rkxt-sf-logo img {
    height: 100%; width: auto;
    max-width: var(--rkxt-logos-maxw, none);
    object-fit: contain; display: block;
}
.rkxt-sf-logos.is-grises .rkxt-sf-logo { filter: grayscale(100%); }
a.rkxt-sf-logo:hover { opacity: 1; filter: none; text-decoration: none; }

/* --- 5. TextoRotativo: cintillo de textos en loop continuo (marquee editorial) ---
   El molde emite la lista DUPLICADA ×2 y acá la animación traslada el track -50%: al terminar la
   1ª copia, la 2ª está calzada al pixel y el loop no tiene costura.

   ⚠️ El aire entre textos va como `padding-inline` DEL ÍTEM, no como `gap` del track. Con `gap` el
   ancho total es sum(items) + (2n−1)·gap → el -50% cae medio gap corrido y cada vuelta pega un
   tirón visible. Con padding por ítem, media pista es exactamente una copia. No cambiar a gap. */
.rkxt-sf-txrot {
    overflow: hidden;
    white-space: nowrap;
    padding-block: var(--rkxt-txrot-pad-y, 16px);
    /* Sin color propio: hereda el fondo/texto de la sección salvo que los props los pisen inline
       (regla 25 — nada de colores hardcodeados por tenant). */
    color: inherit;
}
.rkxt-sf-txrot.is-bordes {
    /* Derivado de currentColor → legible en cintillo claro y oscuro, igual que .rkxt-sf-appbadge. */
    border-top: 1px solid color-mix(in srgb, currentColor 12%, transparent);
    border-bottom: 1px solid color-mix(in srgb, currentColor 12%, transparent);
}
.rkxt-sf-txrot.is-mayusculas { text-transform: uppercase; }

.rkxt-sf-txrot-track {
    display: inline-flex;
    align-items: center;
    will-change: transform;
    animation: rkxt-txrot-marquee var(--rkxt-txrot-dur, 26s) linear infinite;
}
.rkxt-sf-txrot.is-derecha .rkxt-sf-txrot-track { animation-name: rkxt-txrot-marquee-inv; }

.rkxt-sf-txrot-item {
    flex: 0 0 auto;
    padding-inline: var(--rkxt-txrot-pad-x, 24px);
    font-size: var(--rkxt-txrot-size, 14px);
    font-weight: var(--rkxt-txrot-peso, 600);
    letter-spacing: var(--rkxt-txrot-tracking, .14em);
    line-height: 1.2;
}
.rkxt-sf-txrot-item a { color: inherit; text-decoration: none; }
.rkxt-sf-txrot-item a:hover { text-decoration: underline; }
/* Glifo separador: acompaña al texto pero un punto más apagado (es puntuación, no contenido). */
.rkxt-sf-txrot-sep { font-style: normal; opacity: .45; margin-left: var(--rkxt-txrot-pad-x, 24px); }

/* Pausa al pasar el cursor (opt-in por props): útil cuando los textos son enlaces y hay que
   clickearlos sin perseguirlos. */
.rkxt-sf-txrot.is-pausable:hover .rkxt-sf-txrot-track { animation-play-state: paused; }

@keyframes rkxt-txrot-marquee     { from { transform: translateX(0);    } to { transform: translateX(-50%); } }
@keyframes rkxt-txrot-marquee-inv { from { transform: translateX(-50%); } to { transform: translateX(0);    } }

/* Accesibilidad: con "reducir movimiento" el cintillo queda quieto (mismo criterio que la
   marquesina del Promobar). Se ve la 1ª copia; la 2ª sigue existiendo pero fuera de cuadro. */
@media (prefers-reduced-motion: reduce) {
    .rkxt-sf-txrot-track { animation: none; }
}

/* --- 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: 1100px;
}
/* Layout de 2 columnas (Walter 21/08, sin título de página — "Mis pedidos" se sacó): el contenido
   (nav + acciones + "Tus compras") a la izquierda + panel de datos del cliente (nombre, vendedor,
   última compra, objetivos por marca) a la derecha.
   ⚠️⚠️⚠️ 21/08 — DOS intentos de romper el cap de 1200px de .rkxt-sf-main (con `:has()` primero,
   con el breakout full-bleed 100vw después) terminaron en el mismo síntoma reproducible en
   navegador real (aunque el HTML/CSS servidos eran 100% correctos — verificado logueado por curl
   contra producción). Se abandona la pelea por el ancho completo: flexbox simple DENTRO del
   .rkxt-sf-main de 1200px de siempre — el mismo contenedor que usa el resto del sitio sin bugs,
   sin :has(), sin breakout, sin grid. El panel no llega al borde físico de la pantalla, pero es
   el tradeoff consciente frente a un layout que se rompía en un navegador real por razones que no
   pudimos aislar con certeza. min-width:0 en ambos hijos es lo que le permite al contenido angostar
   en vez de forzar overflow (mismo patrón que .rkxt-cs-pedidos-col/.rkxt-cs-donut-side, más abajo,
   que nunca tuvieron este problema). */
.rkxt-sf-cuenta-pedidos-layout {
    display: flex;
    gap: 32px;
    align-items: flex-start;
}
/* 2026-08-31 (Walter, tres vueltas) — "Tus compras" tiene que quedar SIEMPRE en su tope real de
   1113px (grilla 590px fija + donuts/tabla, ver .rkxt-sf-cuenta-pedidos-compras), ni un pixel
   menos: con "flex: 0 1 auto" (intento anterior) el navegador NO garantiza que un hijo llegue a
   su max-width, calcula un tamaño de "ajustar al contenido" que en la práctica dio MENOS que
   1113 — los donuts se achicaron de nuevo y el panel, con flex-grow:1, se comió esa diferencia de
   más, corriéndose mucho más de lo debido. Fix: base FIJA de 1113px (grow:0 porque no necesita
   más, shrink:1 para no desbordar en pantallas angostas) — así "Tus compras" llega SIEMPRE a su
   tope exacto y el panel solo recibe lo que sobra de verdad, ni un pixel de más. */
.rkxt-sf-cuenta-pedidos-content {
    flex: 0 1 1113px;
    min-width: 0;
}
/* Bajado de 640px a 400px primero, después a mano 513px, y recién con el content fijo de arriba
   el panel puede tomar lo que sobra de verdad: flex-grow:1 con base 480px y techo 750px (para no
   terminar con botones gigantes en un monitor enorme). */
.rkxt-sf-cuenta-pedidos-panel {
    flex: 1 1 480px;
    max-width: 750px;
    min-width: 0;
}
@media (max-width: 900px) {
    .rkxt-sf-cuenta-pedidos-layout { flex-direction: column; }
    .rkxt-sf-cuenta-pedidos-panel { flex-basis: auto; }
}
/* 2026-08-31 (Walter, captura grilla.JPG: "VARASANA DISTRIBUIDORA S.R.L." partía en 2 líneas) —
   bajado de 2.3rem a 1.5rem para que razones sociales largas entren en una sola línea dentro del
   panel de 400px. No hay garantía absoluta para CUALQUIER nombre (una razón social larguísima
   igual puede partir), pero a este tamaño entran cómodas las que hoy vimos en producción. */
.rkxt-sf-cliente-nombre {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.2;
    margin-bottom: 20px;
}
.rkxt-sf-cliente-datos {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0 0 18px;
}
.rkxt-sf-cliente-datos p {
    margin: 0;
    font-size: .6rem;
    color: var(--rkxt-text-muted);
}
.rkxt-sf-cliente-datos strong { color: var(--rkxt-text); font-weight: 600; }
.rkxt-sf-cliente-objetivos {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.rkxt-sf-cliente-objetivos li {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: baseline;
    gap: 10px;
    font-size: .6rem;
}
.rkxt-sf-cliente-objetivo-cump { color: var(--rkxt-text-muted); white-space: nowrap; }

/* Acciones migradas desde /cuenta (Walter 22/08): "Cambiar contraseña" / "Mis mensajes" / "Mi
   stock" como botones finos, uno al lado del otro, ocupando el ancho del panel — formato propio,
   distinto de las cards grandes de /cuenta. */
.rkxt-sf-cuenta-pedidos-panel-acciones {
    display: flex;
    gap: 8px;
    margin-top: 20px;
}
.rkxt-sf-cuenta-pedidos-panel-acciones form { flex: 1 1 0; margin: 0; }
.rkxt-sf-panel-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    flex: 1 1 0;
    padding: 7px 8px;
    font-size: .68rem;
    font-weight: 600;
    line-height: 1.2;
    border: none;
    border-radius: var(--rkxt-radius-sm, 6px);
    color: #fff;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    gap: 6px;
}
.rkxt-sf-panel-btn--borravino { background: var(--rkxt-admin-primary, #7A1F3D); }
.rkxt-sf-panel-btn--borravino:hover { background: var(--rkxt-admin-primary-hover, #611931); }
.rkxt-sf-panel-btn--negro { background: #111214; }
.rkxt-sf-panel-btn--negro:hover { background: #000; }
.rkxt-sf-panel-btn-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: #fff;
    color: var(--rkxt-admin-primary, #7A1F3D);
    font-size: .62rem;
    font-weight: 700;
}
.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: nowrap;   /* los botones NUNCA bajan de línea en desktop — ver media query abajo */
}
/* El bloque de título+texto es el que tiene que ceder ancho (su párrafo ya hace wrap solo);
   min-width:0 es lo que le permite angostarse en vez de empujar las acciones a la línea de abajo. */
.rkxt-sf-cuenta-pedidos-head > div:first-child { min-width: 0; flex: 1 1 auto; }
.rkxt-sf-cuenta-pedidos-acciones { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; margin-left: auto; }
.rkxt-sf-nuevo-pedido-cta { white-space: nowrap; }
/* "← Volver a mis pedidos" del detalle de pedido (CuentaPedidoDashboard.razor) — debajo del
   renglón de fecha/total, en borravino (mismo acento que el admin). */
/* Fila de acciones del detalle: "Volver a mis pedidos" + "Modificar el pedido" juntos. */
.rkxt-sf-pedido-acciones {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 10px;
}
.rkxt-sf-pedido-volver {
    display: inline-block;
    background: var(--rkxt-admin-primary, #7A1F3D);
    border-color: var(--rkxt-admin-primary, #7A1F3D);
}
.rkxt-sf-pedido-volver:hover,
.rkxt-sf-pedido-volver:active {
    background: var(--rkxt-admin-primary-hover, #611931);
    border-color: var(--rkxt-admin-primary-hover, #611931);
}
@media (max-width: 640px) {
    .rkxt-sf-cuenta-pedidos-head { flex-wrap: wrap; }
    .rkxt-sf-cuenta-pedidos-acciones { flex-wrap: wrap; }
}
/* 2026-08-25 (a pedido de Walter) — "Volver a mis pedidos / Modificar el pedido / Descargar
   proforma / Eliminar pedido" heredaban el tamaño BASE de .rkxt-btn (padding 11px 18px, 0.95rem),
   pensado para un botón suelto, no para 4 en fila en el header del detalle de pedido. Achicados
   SIEMPRE (no solo por debajo de un breakpoint — 1366px de ventana quedaba arriba del corte viejo
   de 1359px y no se aplicaba nada ahí, que es justo la resolución reportada). */
.rkxt-sf-pedido-acciones .rkxt-btn {
    padding: 7px 12px;
    font-size: 0.8rem;
}
/* Pedido de Walter 2026-08-20: este CTA puntual en borravino (--rkxt-admin-primary, la misma
   var que usa el admin) en vez del naranja institucional del storefront — --rkxt-primary global
   no se toca (regla 25/CLAUDE.md), solo este botón puntual. */
.rkxt-sf-nuevo-pedido-cta.rkxt-btn-primary {
    background: var(--rkxt-admin-primary);
    border-color: var(--rkxt-admin-primary);
}
.rkxt-sf-nuevo-pedido-cta.rkxt-btn-primary:hover,
.rkxt-sf-nuevo-pedido-cta.rkxt-btn-primary:active {
    background: var(--rkxt-admin-primary-hover);
    border-color: var(--rkxt-admin-primary-hover);
}
/* 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; }
/* Armado por el operador: la misma barra en azul, no en el ámbar del cliente. El operador está
   dentro de la tienda del cliente y todo se ve igual que para él — el color es lo que le recuerda,
   de un vistazo y en cualquier pantalla, que lo que toca es el pedido de otra persona. */
.rkxt-sf-edicion-banner--op {
    background: var(--rkxt-info-soft, #E0F2FE);
    border-bottom-color: color-mix(in srgb, var(--rkxt-info, #0284C7) 45%, transparent);
}
.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); }

/* Ficha del cliente: grilla de "Últimos pedidos" a la izquierda + donuts de marca a la derecha —
   cada columna ocupa la mitad de la sección. */
.rkxt-cs-marca-layout { display: flex; gap: 32px; align-items: flex-start; }
.rkxt-cs-pedidos-col { flex: 1 1 50%; min-width: 0; }
.rkxt-cs-donut-side { flex: 1 1 50%; min-width: 0; }

/* "Tus compras" del cliente (CuentaPedidos.razor): la tabla tiene 6 columnas contra las 4 de la
   ficha admin, así que necesita más aire que el 50/50 de arriba.
   2026-08-31 (Walter) — dejan de ser porcentuales A PROPÓSITO. Walter quiere agrandar la sección
   completa pero que SOLO lo aproveche el lado de los donuts/tabla, con la grilla de compras
   clavada en su ancho actual (~590px, el que ya tenía con el 61% de antes) — y el resto del
   ancho ganado (ver .rkxt-sf-cuenta-pedidos-compras) libre para agrandar más adelante el panel
   de datos del cliente. Con % ambos lados crecen juntos; con la grilla fija y el donut-side en
   auto+grow:1, TODO lo que se agranda la sección de acá en más cae solo del lado del donut. */
.rkxt-cs-marca-layout--cliente .rkxt-cs-pedidos-col { flex: 0 1 590px; min-width: 0; }
.rkxt-cs-marca-layout--cliente .rkxt-cs-donut-side { flex: 1 1 auto; min-width: 0; }

/* ⚠️⚠️⚠️ 22/08 — ACÁ estaba el bug real de "no veo Fecha/Tipo" que nos tuvo dando vueltas todo el
   21/08 con capturas, zoom, :has(), grid, full-bleed, flexbox... Esta regla (de ANTES de esa
   sesión) tiraba la sección entera 260px hacia la IZQUIERDA con margen negativo para "ganar
   ancho", asumiendo que siempre iba a haber 260px de aire de sobra a la izquierda (cierto con el
   layout viejo, centrado con márgenes generosos). Con el contenido pegado contra el borde de la
   pantalla (layout nuevo de esta página), esos -260px arrastraban Fecha/Tipo/parte de Número
   directo AFUERA del área visible — y el comentario original ya avisaba que el contenedor
   RECORTA lo que se sale (no hace scroll), así que no era invisible, estaba literalmente cortado.
   Por eso el zoom a 140% "arreglaba" todo sin tocar código: a ese zoom el ancho efectivo de
   pantalla baja de 1400px (el breakpoint de esta regla) y el tirón se desactivaba solo.
   Fix: SIN margen negativo. Corrida a la derecha con margin-left:auto (positivo, nunca recorta
   nada, como mucho angosta la sección dentro de su propio contenedor).
   2026-08-31 (Walter, "agrandá 3cm, pero no liberes todo — quiero guardar lugar para agrandar
   el panel del cliente después") — +113px (3cm a 96dpi/2.54, la conversión estándar de CSS) en
   vez de sacar el cap: 1000 → 1113px. Con la grilla ahora fija en 590px (ver
   .rkxt-cs-marca-layout--cliente más abajo), esos 113px de más los absorbe entero el lado de los
   donuts. El resto del ancho que liberó el panel angostado a 400px queda SIN usar acá, a
   propósito, para el próximo ajuste del panel. */
.rkxt-sf-cuenta-pedidos-compras {
    max-width: 1113px;
    margin-left: auto;
}

/* Donuts "Distribución por marca" (Unidades/Importe) — el doble del tamaño anterior (156px/204px
   → 312px/408px). flex-wrap ya estaba puesto: si los dos no entran lado a lado en el ancho
   disponible de .rkxt-cs-donut-side, se apilan solos en vez de desbordar. */
.rkxt-cs-donuts { display: flex; flex-wrap: wrap; gap: 20px; margin: 6px 0 16px; }
.rkxt-cs-donut-col { flex: 1 1 312px; max-width: 408px; }
.rkxt-cs-donut-title { margin: 0 0 6px; font-size: .82rem; color: var(--rkxt-text-muted, #6b6b76); }
.rkxt-cs-donut-wrap { position: relative; height: 312px; }
.rkxt-cs-tabla-chica { width: 100%; max-width: 432px; font-size: .85em; }
.rkxt-cs-tabla-chica-total td { border-top: 1px solid var(--rkxt-border); padding-top: 6px; }

/* "Tus compras" del cliente — 22/08: nacieron chicos (160px) para entrar los dos lado a lado.
   2026-08-31 (Walter, dos vueltas: "agrandalos" y después, viendo que se habían apilado, "tienen
   que estar uno al lado del otro") — de fijar un height en px (que asumía un ancho de contenedor
   que en la práctica varía con la pantalla y terminaba apilando por flex-wrap) se pasa a
   `flex-wrap: nowrap` (NUNCA se apilan) + `aspect-ratio: 1/1` en el wrap: cada donut ocupa la
   mitad real del ancho disponible en .rkxt-cs-donut-side (columnas al 50%, sin max-width fijo) y
   el alto se deriva solo del ancho — se agranda o achica con la pantalla, pero SIEMPRE circular y
   SIEMPRE de a dos. Tope de 260px para que en un monitor enorme no queden gigantes. */
.rkxt-cs-donuts--cliente { gap: 12px; flex-wrap: nowrap; }
/* min-width:0 explícito: sin esto el flex-item usa min-width:auto (tamaño mínimo de contenido),
   y un <canvas> sin CSS propio tiene 300px de ancho intrínseco (default HTML) hasta que Chart.js
   lo redimensiona por JS — ese 300px podía competir con el ancho real antes de que el gráfico
   terminara de montarse. */
.rkxt-cs-donuts--cliente .rkxt-cs-donut-col { flex: 1 1 0; max-width: 260px; min-width: 0; }
.rkxt-cs-donuts--cliente .rkxt-cs-donut-wrap { height: auto; aspect-ratio: 1 / 1; }
.rkxt-cs-donuts--cliente canvas { max-width: 100%; }
/* La tabla chica (MARCA/UNIDADES/IMPORTE) es la misma clase que usa la ficha admin (432px allá,
   con su 50/50) — acá, con más ancho ganado del lado del donut, se le saca el tope para que
   también aproveche el espacio (Walter: "los donuts y la tabla"). Scoped a esta página nomás. */
.rkxt-sf-cuenta-pedidos-compras .rkxt-cs-tabla-chica { max-width: none; }

/* ============ Patrón "pedido de recompra" (donuts x marca + grilla + barras x categoría) ============
   Global (no scoped) a propósito: lo usan PedidoRecompra.razor (editable) y NoComprado.razor
   (solo lectura, Walter 2026-09-01) — movido acá desde PedidoRecompra.razor.css el mismo día para
   que la 2da pantalla pudiera reusarlo (CSS isolation no cruza componentes). */

/* Header: info del pedido · donuts chicos por marca · acciones. */
.rkxt-pr-header {
    display: flex;
    align-items: center;   /* centra verticalmente info + donuts + acciones en la altura del header */
    gap: 28px;
    flex-wrap: wrap;
}
.rkxt-pr-headinfo { flex: 0 1 auto; align-self: center; }
.rkxt-pr-headinfo h1 { margin: 0; }
.rkxt-pr-headinfo p { margin: 4px 0 0; }
.rkxt-pr-headdonuts { display: flex; gap: 24px; margin-left: 6cm; }
.rkxt-pr-hd-col { text-align: center; }
.rkxt-pr-hd-title {
    display: block;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--rkxt-text-muted, #6b6b76);
    margin-bottom: 2px;
}
/* Donuts 20% más grandes; ancho holgado para que la leyenda entre en una sola línea. */
.rkxt-pr-hd-wrap { position: relative; height: 154px; width: 240px; }
.rkxt-pr-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }

/* Cuerpo: grilla (izq, más angosta) + barras por categoría (der, más anchas). */
.rkxt-pr-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 480px;
    gap: 20px;
    align-items: start;
}
.rkxt-pr-main { min-width: 0; }

/* Barra de escaneo/alta rápida por código — pegada al margen izquierdo, justo encima del
   encabezado "Detalle del pedido" de la grilla. */
.rkxt-pr-scanbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.rkxt-pr-scaninput { width: 220px; }
.rkxt-pr-scanmsg { font-size: .78rem; max-width: 260px; }
.rkxt-pr-scanmsg-ok { color: var(--rkxt-success, #2e7d32); }
.rkxt-pr-scanmsg-error { color: var(--rkxt-danger, #c62828); }

/* Grilla del pedido — filas compactas (menos altas, un poco más angostas). */
.rkxt-pr-gridhead { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
/* "Quitar Marca" / "Quitar Categoría" — empujados al borde derecho de la grilla, justo arriba de ella. */
.rkxt-pr-gridhead-actions { margin-left: auto; display: flex; gap: 10px; align-items: center; }
.rkxt-pr-quitar-wrap { position: relative; }
.rkxt-pr-quitar-panel {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--rkxt-bg, #fff);
    border: 1px solid var(--rkxt-border, #e2e0dc);
    border-radius: 8px;
    padding: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
    white-space: nowrap;
    z-index: 6;
}
.rkxt-pr-quitar-panel select.rkxt-input { width: 180px; }

/* Botones "Quitar Marca/Categoría" — mismo color que la cabecera de la grilla (borravino admin),
   pero sutiles (outline, no relleno sólido) y 25% más chicos que .rkxt-btn-inline
   (padding 8px 14px / font .85rem -> 6px 10px / font .64rem). */
.rkxt-pr-btn-quitar {
    width: auto;
    padding: 6px 10px;
    font-size: .64rem;
    background: transparent;
    color: var(--rkxt-admin-primary, #7A1F3D);
    border: 1px solid var(--rkxt-admin-primary, #7A1F3D);
}
.rkxt-pr-btn-quitar:hover:not(:disabled) {
    background: var(--rkxt-admin-primary, #7A1F3D);
    color: #fff;
}
.rkxt-pr-btn-quitar:disabled { opacity: .5; cursor: not-allowed; }
.rkxt-pr-tabla { width: 100%; font-size: .84rem; }
.rkxt-pr-tabla th, .rkxt-pr-tabla td { padding: 3px 8px; }
.rkxt-pr-tabla thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    /* Borravino del admin (2026-08-06, mismo acento que los botones — ver --rkxt-admin-primary
       en app.css), antes crema default. */
    background: var(--rkxt-admin-primary, #7A1F3D);
    color: #fff;
}
.rkxt-pr-cod {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    white-space: nowrap;
}
.rkxt-pr-cant { width: 70px; text-align: right; padding: 2px 6px; }
.rkxt-pr-rowacciones { display: flex; gap: 4px; justify-content: flex-end; white-space: nowrap; }
.rkxt-pr-rowacciones .rkxt-pr-chip-x { font-size: 1rem; }

.rkxt-pr-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .85rem;
    background: var(--rkxt-bg-alt, #f4f3f1);
    border-radius: 999px;
    padding: 2px 10px;
}
.rkxt-pr-chip-x {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--rkxt-text-muted, #6b6b76);
    font-size: .9rem;
    line-height: 1;
    padding: 0 2px;
}

/* Barras por categoría a la derecha (sticky, anchas y altas para que entren todas). */
.rkxt-pr-side {
    position: sticky;
    top: 12px;
    min-width: 0;
}
.rkxt-pr-sidehead { display: flex; align-items: center; gap: 8px; }
.rkxt-pr-hint { margin: 2px 0 8px; font-size: .78rem; }
.rkxt-pr-bars { position: relative; height: 540px; }

@media (max-width: 1100px) {
    .rkxt-pr-layout { grid-template-columns: 1fr; }
    .rkxt-pr-side { position: static; }
}

/* NoComprado.razor (2026-09-01): mismo patrón .rkxt-pr-header, donuts más grandes con clases propias
   (rkxt-nc-*) para no tocar el tamaño de PedidoRecompra.razor, que comparte el resto de .rkxt-pr-*.
   "Volver al cliente" bajó de la esquina superior derecha a debajo del título — ese ancho libre es
   justo lo que necesitan los donuts más grandes para no empujar la fila. */
.rkxt-nc-header { align-items: flex-start; }
.rkxt-nc-volver { margin-top: 10px; }
.rkxt-nc-headdonuts { margin-left: auto; gap: 36px; }
/* Descendiente (2 clases) a propósito, no un ".rkxt-nc-hd-wrap" plano: gana por especificidad a
   ".rkxt-pr-hd-wrap" sin depender del orden de aparición en la hoja de estilos. */
.rkxt-nc-headdonuts .rkxt-pr-hd-wrap { width: 300px; height: 220px; }

@media (max-width: 900px) {
    .rkxt-nc-headdonuts { margin-left: 0; }
    .rkxt-nc-headdonuts .rkxt-pr-hd-wrap { width: 260px; height: 200px; }
}

/* Grilla de últimos pedidos (Colector): desglose por marca dentro de la celda, con el punto de
   color fijo de cada marca (mismo mapeo que los donuts) para identidad visual consistente. */
.rkxt-cs-tabla-pedidos { width: 100%; }

/* "Tus compras" del cliente (CuentaPedidos.razor) — 5 columnas (Fecha/Tipo/Importe total/Importe
   por marca/Unidades por marca). Columna "Número" sacada del todo (Walter 21/08): en este listado
   siempre mostraba "—" (los pedidos Web no traen número propio) y solo restaba ancho.
   ⚠️⚠️⚠️ 21/08 — LA CABECERA es la que dictaba el ancho, no los datos: .rkxt-table th (regla base)
   fija SU PROPIO font-size (0.78rem) + mayúsculas + letter-spacing, y una propiedad puesta directo
   sobre el elemento le gana SIEMPRE a lo heredado desde la tabla, sin importar cuánto achicara el
   font-size de arriba — por eso "IMPORTE TOTAL" en mayúsculas seguía gigante aunque los importes de
   abajo ya fueran chicos. Achicamos el th directo (gana por ser igual especificidad + venir después
   en la hoja) y le sacamos mayúsculas/letter-spacing. Headers largos ("Importe por marca") pueden
   partirse en 2 líneas — el nowrap queda SOLO en los <td> de datos (fecha/tipo/importe no deben
   partirse), nunca en su cabecera. SIN table-layout:fixed — layout automático, que por definición
   nunca puede llevar una columna con contenido a 0 (si no entra, scrollea horizontal dentro de
   .rkxt-table-wrap, que ya tiene overflow-x:auto). */
.rkxt-cs-tabla-pedidos--cliente { font-size: 0.8rem; }
.rkxt-cs-tabla-pedidos--cliente th, .rkxt-cs-tabla-pedidos--cliente td { padding: 7px 9px; }
.rkxt-cs-tabla-pedidos--cliente th {
    font-size: 0.66rem;
    text-transform: none;
    letter-spacing: 0;
    line-height: 1.2;
    white-space: normal;
}
.rkxt-cs-tabla-pedidos--cliente td:nth-child(1),
.rkxt-cs-tabla-pedidos--cliente td:nth-child(2),
.rkxt-cs-tabla-pedidos--cliente td:nth-child(3) {
    white-space: nowrap;
}
/* Sin el recuadro de .rkxt-badge en Tipo (Walter 22/08: "innecesario") — texto plano, mismo
   tratamiento que Fecha/Importe total. */
.rkxt-cs-tabla-pedidos--cliente th:nth-child(4), .rkxt-cs-tabla-pedidos--cliente td:nth-child(4),
.rkxt-cs-tabla-pedidos--cliente th:nth-child(5), .rkxt-cs-tabla-pedidos--cliente td:nth-child(5) {
    max-width: 190px;
}
/* Red de seguridad: si igual algún "Marca: $importe" no entra en su ancho, que haga wrap a una
   segunda línea DENTRO de la celda en vez de desbordar — nunca confiar solo en el cálculo de %. */
.rkxt-cs-tabla-pedidos--cliente .rkxt-cs-marca-linea { white-space: normal; font-size: 0.76rem; }

/* Fila de "Últimos pedidos" clickeable → detalle del pedido. Patrón "stretched link": el <a> real
   (navegación nativa, no @onclick de Blazor) se estira con un ::after absoluto sobre TODA la fila.
   El <tr> es el containing block (position:relative) porque ningún <td> tiene position propio. */
.rkxt-cs-pedido-fila { position: relative; cursor: pointer; }
.rkxt-cs-pedido-fila:hover { background: var(--rkxt-bg-alt, #f4f3f1); }
/* Compras de OTRA temporada (no la vigente) en "Tus compras" del cliente — atenuado suave, sigue
   siendo clickeable, solo baja de jerarquía visual frente a lo de la temporada actual. */
.rkxt-cs-pedido-fila--otra-temporada { background: rgba(0, 0, 0, .088); }
.rkxt-cs-pedido-fila--otra-temporada:hover { background: rgba(0, 0, 0, .112); }
.rkxt-sf-cuenta-pedidos-temporada { margin: 0 0 10px; font-size: .78rem; }
.rkxt-cs-pedido-link { color: var(--rkxt-text); font-weight: 600; }
.rkxt-cs-pedido-link::after { content: ""; position: absolute; inset: 0; }

.rkxt-cs-marca-linea { display: flex; align-items: center; gap: 6px; font-size: .85rem; white-space: nowrap; }
.rkxt-cs-marca-linea + .rkxt-cs-marca-linea { margin-top: 2px; }
.rkxt-cs-marca-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }

@media (max-width: 900px) {
    .rkxt-cs-marca-layout { flex-direction: column; }
}

/* 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; }

/* --- F26: tandas de cambios del vendedor con antes→después + delta (storefront). Identidad propia:
   NO reusa .rkxt-dash-* / .rkxt-cambios-* del admin (ver nota de separación admin/storefront arriba). --- */
.rkxt-sf-dash-modv-tandas { display: flex; flex-direction: column; gap: 14px; margin-top: 10px; }
.rkxt-sf-dash-modv-tanda {
    padding: 10px 0 2px;
    border-top: 1px solid color-mix(in srgb, var(--rkxt-warn) 25%, transparent);
}
.rkxt-sf-dash-modv-tanda:first-child { border-top: none; padding-top: 0; }
.rkxt-sf-dash-modv-tanda-head {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 12px;
    align-items: baseline;
    margin-bottom: 4px;
}
.rkxt-sf-dash-modv-tanda-fecha { font-size: .82rem; color: var(--rkxt-text-muted); }
.rkxt-sf-dash-modv-tanda-resumen { font-size: .86rem; font-weight: 600; color: var(--rkxt-text); }
.rkxt-sf-dash-modv-grupo-title {
    margin: 8px 0 2px;
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--rkxt-text-muted);
}

/* --- 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; } }

/* Detalle de pedido del cliente (PedidoMarcasCategorias.razor, usado por CuentaPedidoDashboard) —
   layout CALCADO del admin (/admin/sales/pedidos/{id}, PedidoColectorDetalle.razor.css): donuts
   chicos arriba + grid detalle(izq) / barras por categoría sticky(der). Clases propias porque las
   .rkxt-pcd-* del admin son CSS isolation de ese componente, no reusables acá. */
/* nowrap + flex:1 en cada mini = los dos donuts COMPARTEN el ancho de su columna y se achican
   juntos. Con wrap, en cuanto la columna no daba para los dos a 374px el segundo caia abajo y el
   bloque pasaba de dos donuts en fila a dos apilados, que no es el diseno. */
.rkxt-sf-pdc-donuts { grid-area: donuts; display: flex; justify-content: flex-end; gap: 20px; flex-wrap: nowrap; }
.rkxt-sf-pdc-donut-mini { text-align: center; min-width: 0; }
/* Donuts +15% (140x200 -> 161x230), +25% (161x230 -> 201x288), +30% (201x288 -> 261x374, 2026-08-24
   a pedido de Walter). El % de cada porción no crece con esto — es font fijo en px, controlado aparte
   por dataFont en RenderDonutsAsync (queda en el default). Las referencias (leyenda) van AL REVÉS,
   20% más chicas — ver legendFont/legendPad/legendBox en RenderDonutsAsync. */
/* 2026-08-24 — el tamano dejo de estar clavado en px y sale de --rkxt-pdc-donut-w/h, que
   escalonan por breakpoint (ver "ESCALERA RESPONSIVE" al final del bloque). Estaba fijo en
   374x261 desde 1101px para arriba: en un monitor de 1366 los dos donuts se comian 768px y a la
   grilla de 9 columnas le quedaban ~540px, con lo cual la CABECERA wrapeaba a 3 renglones y tapaba
   el cuerpo de la tabla. Chart.js redibuja solo al cambiar el contenedor (responsive:true). */
.rkxt-sf-pdc-donut-wrap {
    position: relative;
    /* Ocupa lo que le da su columna y NUNCA pasa de --rkxt-pdc-donut-w (374px = el tamano que se
       fijo el 2026-08-24, ahora un tope y no una medida fija). El alto sale del aspect-ratio, asi
       la proporcion original 374x261 se mantiene sola en cualquier ancho. */
    width: 100%;
    max-width: var(--rkxt-pdc-donut-w, 374px);
    aspect-ratio: 374 / 261;
    height: auto;
}
.rkxt-sf-pdc-donut-mini { flex: 1 1 0; min-width: 0; }

/* Grilla 20% más angosta (380px -> 520px de columna fija para el costado) para darle más lugar
   a los donuts + barras por categoría.
   22/08 — los donuts entraron AL grid (fila 1 de la columna derecha) en vez de ser una fila propia
   a todo el ancho arriba. Antes esa fila reservaba ~240px de alto en TODO el ancho aunque los
   donuts estuvieran pegados a la derecha, y la grilla arrancaba recién debajo: mitad izquierda en
   blanco entre "Volver a mis pedidos" y la tabla. Con `grid-template-areas` la grilla ocupa las dos
   filas de la izquierda y sube sola, sin tocar la posición de los donuts.
   La columna fija pasa de 520px a 596px = 288*2 + 20 de gap (el ancho exacto de los dos donuts), y
   2026-08-24 a 768px = 374*2 + 20, con los donuts +30% de arriba: si quedara más angosta los donuts
   se saldrían del área y pisarían el borde derecho de la tabla. */
.rkxt-sf-pdc-layout {
    display: grid;
    /* ⚠⚠ 2026-08-24 — PORCENTAJE, no px. El ancho de la columna derecha se derivaba del tamano
       de los donuts (768px con los de 374), y eso solo cierra si el contenedor es ancho. Pero
       .rkxt-sf-main capea en 1200px: en CUALQUIER monitor el area util son ~1136px, asi que a la
       grilla de 9 columnas le quedaban ~344 y la tabla se desbordaba de su celda y se montaba
       encima de los donuts. Con un % la grilla siempre se queda con el 62% del ancho REAL, tenga
       el tenant el cap de 1200 o el modo "ancho completo". */
    grid-template-columns: minmax(0, 1fr) minmax(0, 38%);
    grid-template-areas:
        "main donuts"
        "main side";
    /* `auto 1fr`, NO `auto auto`: la grilla (area "main") ocupa las DOS filas y es larguisima, y con
       las dos filas en `auto` el navegador le reparte ese alto entre ambas — la fila de los donuts
       se estiraba cientos de px y las barras por categoria terminaban despegadas, abajo de todo.
       Un item que cruza una fila flexible queda EXCLUIDO del calculo intrinseco de las otras, asi
       que con `1fr` en la fila 2 la fila 1 mide exactamente los donuts y las barras quedan pegadas
       abajo de ellos, como estaban antes. */
    grid-template-rows: auto 1fr;
    column-gap: 24px;
    row-gap: 14px;
    align-items: start;
}
.rkxt-sf-pdc-main { grid-area: main; min-width: 0; }
/* flex-wrap: sin el, el titulo + el chip de filtro + los dos botones "Quitar" se aplastaban unos
   contra otros en cuanto la columna se angostaba. position:relative es el ancla del panel de
   "Quitar" cuando en mobile deja de colgar de su propio boton (ver media query 700px). */
.rkxt-sf-pdc-gridhead {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 8px;
    position: relative;
}

/* Cabecera de la grilla en borravino (mismo acento que el admin, ver .rkxt-pcd-tabla thead th).

   ⚠️⚠️ 2026-08-24 — ESTA REGLA TIENE QUE PISAR `position/top/z-index` DE `.rkxt-table thead th`.
   La regla base (linea ~716) es del ADMIN: `top: var(--rkxt-theadtop)` (variable que calcula
   AdminLayout y que en el storefront NO EXISTE -> caia a 0px) y `z-index: 10`. Heredarla causaba
   los dos sintomas reportados:
     1. el panel de "Quitar marca/categoria" (z-index del popover) quedaba DEBAJO de la cabecera,
        asi que el boton abria un control que no se podia usar;
     2. con top:0 la cabecera se despegaba del header de tienda y flotaba por encima de TODO al
        scrollear — encima de los donuts en pantallas chicas.
   El admin no lo sufre porque ya se pisaba a si mismo con `z-index: 2` (PedidoColectorDetalle.razor.css).
   Aca el offset correcto es --rkxt-sf-theadtop (header de tienda + barra sticky), que mide en
   runtime rkxt-catalogo-agente.js. */
.rkxt-sf-pdc-tabla thead th {
    position: sticky;
    top: var(--rkxt-sf-theadtop, 0px);
    z-index: 2;
    background: var(--rkxt-admin-primary, #7A1F3D);
    color: #fff;
}

/* --- Edición en sitio del pedido (Editable=true en PedidoMarcasCategorias) ---
   Calcado de .rkxt-pr-* del admin (PedidoRecompra.razor.css): las de allá son CSS isolation de ese
   componente, no se pueden reusar desde acá. Mismo look para que la vendedora y el cliente estén
   mirando la misma herramienta. */
.rkxt-sf-pdc-gridhead-actions { margin-left: auto; display: flex; gap: 10px; align-items: center; }
.rkxt-sf-pdc-quitar-wrap { position: relative; }
.rkxt-sf-pdc-quitar-panel {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--rkxt-bg, #fff);
    border: 1px solid var(--rkxt-border, #e2e0dc);
    border-radius: 8px;
    padding: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
    white-space: nowrap;
    /* Por encima de la cabecera sticky (z-index 2) y de la barra de cambios (8). Es un popover:
       siempre gana. Antes valia 6 y perdia contra el thead, que heredaba 10 del admin. */
    z-index: 30;
}
.rkxt-sf-pdc-quitar-panel select.rkxt-input { width: 180px; }
.rkxt-sf-pdc-btn-quitar {
    width: auto;
    padding: 6px 10px;
    font-size: .64rem;
    background: transparent;
    color: var(--rkxt-admin-primary, #7A1F3D);
    border: 1px solid var(--rkxt-admin-primary, #7A1F3D);
}
.rkxt-sf-pdc-btn-quitar:hover:not(:disabled) {
    background: var(--rkxt-admin-primary, #7A1F3D);
    color: #fff;
}
.rkxt-sf-pdc-btn-quitar:disabled { opacity: .5; cursor: not-allowed; }
.rkxt-sf-pdc-cant { width: 70px; text-align: right; padding: 2px 6px; }
.rkxt-sf-pdc-rowacciones { display: flex; gap: 4px; justify-content: flex-end; white-space: nowrap; }
.rkxt-sf-pdc-rowacciones .rkxt-pdc-chip-x { font-size: 1rem; }

/* Barra de cambios sin guardar. Sticky arriba de la grilla: en un pedido de 600 renglones el cliente
   toca una fila del fondo y el botón de guardar tiene que seguir a la vista, si no se va creyendo que
   el cambio ya quedó (que es exactamente el fallo silencioso que arreglamos del lado del servidor). */
.rkxt-sf-pdc-dirtybar {
    position: sticky;
    /* Debajo del header de tienda (si el tenant lo tiene sticky), no pegada al borde del viewport.
       Lleva ademas .rkxt-sf-sticky-filtros en el markup: esa clase no le da estilo (esta regla gana
       por orden), sirve para que rkxt-catalogo-agente.js la MIDA y sume su alto a --rkxt-sf-theadtop,
       asi la cabecera de la grilla se pega JUSTO DEBAJO en vez de encimarse con ella. */
    top: var(--rkxt-sf-sticky-top, 0px);
    z-index: 8;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 8px;
    padding: 8px 12px;
    border: 1px solid var(--rkxt-admin-primary, #7A1F3D);
    border-radius: 8px;
    background: #fdf5f8;
    box-shadow: 0 4px 12px rgba(0, 0, 0, .08);
}
.rkxt-sf-pdc-dirtytxt { font-size: .82rem; color: var(--rkxt-admin-primary, #7A1F3D); margin-right: auto; }

.rkxt-sf-pdc-side { grid-area: side; position: sticky; top: 12px; min-width: 0; }
.rkxt-sf-pdc-sidehead { display: flex; align-items: center; gap: 8px; }
.rkxt-sf-pdc-hint { margin: 2px 0 10px; font-size: .78rem; }
.rkxt-sf-pdc-barblock { margin-bottom: 18px; }
.rkxt-sf-pdc-barblock:last-child { margin-bottom: 0; }
.rkxt-sf-pdc-barwrap { position: relative; }

/* 22/08 — "Modificar el pedido" bajó a la fila de acciones (al lado de "Volver a mis pedidos"), asi
   que el costado derecho del header quedo vacio. Los donuts trepan a ese hueco con un margin-top
   negativo: la fila 1 del grid mide contenido + margen, o sea que achicarla sube los donuts Y las
   barras juntos, sin tocar la grilla (que arranca en el borde de arriba del grid y no se mueve).

   El combinador ADYACENTE `+` no es cosmetico, es el resguardo: entre el header y el grid pueden
   aparecer el aviso de pedido bloqueado (.rkxt-flash) o el bloque "tu vendedor ajusto este pedido"
   (.rkxt-sf-dash-modv), los dos a todo el ancho. Si alguno esta presente el selector NO matchea y
   los donuts se quedan quietos, en vez de subir 104px y taparlo.

   El cap de ancho del bloque de titulo es la otra mitad del resguardo: sin el, un titulo o un
   renglon de fecha/total largo se meteria por debajo de los donuts ya trepados. 792px = los 768 de
   la columna (donuts +30%, 2026-08-24) + el gap. */
@media (min-width: 1101px) {
    /* 2026-08-25 (a pedido de Walter, "los donuts pueden ir más arriba aún") — de -104 a -130px. */
    .rkxt-sf-section-head + .rkxt-sf-pdc-layout .rkxt-sf-pdc-donuts { margin-top: -130px; }
    /* El cap del bloque de titulo sigue al ancho REAL de la columna derecha (los dos donuts + el
       gap), que ahora escalona por breakpoint. Antes era el literal 792px, calculado para los
       donuts de 374: en cuanto se achicaban, el titulo dejaba de usar el ancho que quedaba libre. */
    .rkxt-sf-pedido-dash .rkxt-sf-cuenta-pedidos-head > div:first-child { max-width: 60%; }
}

/* 2026-08-24 (a pedido de Walter) — corre todo el bloque un poco más contra el margen izquierdo:
   negativo acotado a ESTA sección (no toca el padding lateral global de .rkxt-sf-main, que usan
   todas las páginas de la tienda). */
.rkxt-sf-pedido-dash { margin-left: -16px; }

/* ============================================================================
   ESCALERA RESPONSIVE del detalle de pedido (2026-08-24)

   El problema que resuelve: el layout tenia UN SOLO corte (1100px). De 1101 para arriba la columna
   derecha valia 768px FIJOS y la grilla se quedaba con lo que sobrara — en 1366 eran ~540px para 9
   columnas, y ahi se encadenaban los tres sintomas que reporto Walter: los controles del header de
   la grilla encimandose, la cabecera wrapeando a varios renglones y comiendose el cuerpo, y la
   cabecera sticky pisando los graficos.

   El ancho del donut es la unica perilla: la columna derecha (calc w*2 + 20) y el cap del titulo
   salen de el. Alto = ancho * 0,698 (la proporcion original 374x261).
   ============================================================================ */
/* 2026-08-25 (a pedido de Walter, "no es necesario que los donuts sean tan grandes") — bajado de
   374px a 260px y, en la misma sesión, a 190px (seguía pareciendo grande). La leyenda
   (RenderDonutsAsync en PedidoMarcasCategorias.razor) también se agrandó de vuelta porque a 374px +
   legendFont:7 quedaba ilegible; ver ese archivo. */
.rkxt-sf-pedido-dash,
.rkxt-sf-pdc-layout { --rkxt-pdc-donut-w: 190px; }

/* La cabecera NO wrapea: los titulos son cortos ("Precio unit." es el peor) y en cuanto uno se parte
   en dos renglones el thead sticky crece y se come el cuerpo de la tabla, que es el sintoma
   reportado. El que absorbe el ancho sobrante y wrapea es el cuerpo de Descripcion. */
.rkxt-sf-pdc-tabla thead th { white-space: nowrap; letter-spacing: .02em; }
/* overflow-wrap y NO word-break: word-break parte cualquier palabra a la mitad apenas la columna
   se angosta ("Kosiuko" salia como "Kosiuk/o"). overflow-wrap solo corta la palabra que no entra
   entera en su renglon ni sola, que es el caso real (un codigo o una descripcion larguisima). */
.rkxt-sf-pdc-tabla td { overflow-wrap: break-word; }
/* Cantidad / Precio unit. / Subtotal: alineados a la derecha y NUNCA partidos ("$ 49.000,00" se
   cortaba en dos renglones, con el signo arriba y el numero abajo). */
.rkxt-sf-pdc-num { text-align: right; white-space: nowrap; }

/* Densidad: NO depende del monitor. .rkxt-sf-main capea en 1200px, asi que hasta en un 4K esta
   grilla vive en ~700px reales — con la densidad por defecto (.9rem, padding 10/14) no entra. */
.rkxt-sf-pdc-tabla { font-size: .82rem; }
.rkxt-sf-pdc-tabla th, .rkxt-sf-pdc-tabla td { padding: 7px 9px; }
@media (max-width: 1359px) {
    .rkxt-sf-pdc-tabla { font-size: .78rem; }
    .rkxt-sf-pdc-tabla th, .rkxt-sf-pdc-tabla td { padding: 6px 7px; }
    .rkxt-sf-pdc-cant { width: 58px; }
}

/* 2026-08-25 (a pedido de Walter) — el corte estaba en 1100px. .rkxt-sf-main capea en 1200px, así
   que esta grilla fue pensada para hasta ~1200px de contenido real — una ventana de 1280px (caso
   reportado: notebook 15", 1280x1024) recién le da ~1216px, apenas arriba del cap, y a los 38% del
   aside (≈456px) les compite el donut fijo de 374px×2. Corte subido a 1250px para apilar (donuts
   arriba, tabla, barras abajo) en vez de repartir esa columna angosta. */
@media (max-width: 1250px) {
    .rkxt-sf-pdc-layout {
        grid-template-columns: 1fr;
        grid-template-areas: "donuts" "main" "side";
    }
    /* Apilado los donuts vuelven a tener lugar, pero sin comerse la pantalla en celular. */
    .rkxt-sf-pedido-dash,
    .rkxt-sf-pdc-layout { --rkxt-pdc-donut-w: min(190px, 42vw); }
    .rkxt-sf-pdc-donuts { justify-content: center; }
    .rkxt-sf-pdc-side { position: static; }
}

/* Tablet/mobile: la grilla de 9 columnas no entra a lo ancho por mas que se compacte, asi que pasa a
   scroll horizontal propio. El wrapper con overflow-x ANULA el sticky del thead (se ancla al wrapper
   en vez de a la pagina, gotcha ya documentado en .rkxt-sf-qo-scroll), asi que aca el thead vuelve a
   `static` a proposito en vez de quedar flotando mal anclado. */
@media (max-width: 900px) {
    .rkxt-sf-pdc-tablawrap {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .rkxt-sf-pdc-tabla { min-width: 700px; }
    .rkxt-sf-pdc-tabla thead th { position: static; }
    /* El negativo de escritorio le come el padding lateral a la seccion en pantallas chicas. */
    .rkxt-sf-pedido-dash { margin-left: 0; }
    .rkxt-sf-pdc-donuts { gap: 14px; }
}

/* Angosto: el panel de "Quitar" deja de colgar de su boton (se salia de la pantalla por izquierda,
   con dos selects de 180px + boton en una sola linea nowrap) y pasa a ocupar el ancho del header. */
@media (max-width: 700px) {
    .rkxt-sf-pdc-gridhead-actions { margin-left: 0; width: 100%; }
    .rkxt-sf-pdc-btn-quitar { flex: 1 1 auto; }
    .rkxt-sf-pdc-quitar-wrap { position: static; flex: 1 1 auto; }
    .rkxt-sf-pdc-quitar-panel {
        left: 0;
        right: 0;
        white-space: normal;
        flex-wrap: wrap;
    }
    .rkxt-sf-pdc-quitar-panel select.rkxt-input { width: 100%; flex: 1 1 100%; }
}

/* Chip de filtro activo (categoría/marca), mismo look que .rkxt-pcd-chip del admin. */
.rkxt-pdc-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .85rem;
    background: var(--rkxt-bg-alt, #f4f3f1);
    border-radius: 999px;
    padding: 2px 10px;
}
.rkxt-pdc-chip-x {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--rkxt-text-muted, #6b6b76);
    font-size: .9rem;
    line-height: 1;
    padding: 0 2px;
}
.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 (rediseño 2026-07-25 — cabecera comprimida) =====
   Queja de Gustavo: con la cabecera anterior (2 columnas: KPIs + filtros/curva apilados) la
   primera fila de la tabla quedaba fuera del viewport en pantallas normales — para una pantalla
   que existe para cargar cientos de renglones, eso es inaceptable. Ahora la cabecera es UNA sola
   franja compacta apilada verticalmente:
     1. .rkxt-ed-kpibar   — Total / Piezas / Por marca / aviso de fotos, todo en UNA línea horizontal.
     2. .rkxt-ed-filtros  — fila de filtros (modo/buscar/marca/cat/Filtrar) + botón que abre el
                             POPOVER de "Carga por curva" (ver más abajo, fuera de este wrapper) +
                             <details> "Más filtros" SIEMPRE colapsado (antes se auto-abría con
                             filtros activos, sumando alto de más; ahora se ven como chips de
                             resumen al lado del toggle, sección "Más filtros" abajo).
   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. */
.rkxt-ed-cabecera.rkxt-filterbar {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 0 12px;
}

/* --- Barra de KPIs: UNA línea horizontal (antes: columna angosta a la izquierda con el donut
   grande de 92px + leyenda vertical → ese solo bloque medía ~150-160px de alto). Donut bajado a
   26px, leyenda inline (separada por coma visual vía flex-wrap), separadores verticales finos
   entre indicador e indicador. rkxt-kpi-label/val se reusan de Dashboard/Detalle/Analytics — el
   tamaño se pisa scopeado a .rkxt-ed-kpibar, nunca en la regla base. */
.rkxt-ed-kpibar {
    display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
    padding-bottom: 8px; margin-bottom: 2px;
    border-bottom: 1px solid var(--rkxt-border-soft);
    font-size: .85rem;
}
.rkxt-ed-kpibar-sep { width: 1px; height: 20px; background: var(--rkxt-border-soft); flex: 0 0 auto; }
.rkxt-ed-kpi--inline { display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap; }
.rkxt-ed-kpibar .rkxt-kpi-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--rkxt-text-dim); }
.rkxt-ed-kpibar .rkxt-kpi-val { font-size: 1rem; font-weight: 700; }
.rkxt-ed-vs { font-size: .8rem; }
.rkxt-ed-kpi--marca { display: flex; align-items: center; gap: 8px; }
.rkxt-ed-kpibar .rkxt-ed-donut { width: 26px; height: 26px; transform: rotate(-90deg); flex: 0 0 auto; }
.rkxt-ed-pie-leg { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 3px 10px; }
.rkxt-ed-pie-leg--inline li { font-size: .78rem; }
.rkxt-ed-pie-leg li { display: flex; align-items: center; gap: 5px; }
.rkxt-ed-pie-dot { width: 9px; height: 9px; border-radius: 3px; display: inline-block; flex: 0 0 auto; }
/* Aviso "productos sin foto ocultos" — antes un <p> propio que empujaba la tabla ~20-25px hacia
   abajo; ahora un chip discreto en la barra de KPIs con tooltip nativo (title=), sin JS. */
.rkxt-ed-foto-hint {
    font-size: .76rem; color: var(--rkxt-text-dim); cursor: help;
    border-bottom: 1px dashed var(--rkxt-text-dim);
}

/* 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/Filtrar
   + el botón que abre el popover "Carga por curva"), fila 2 = <details> "Más filtros" con
   Talle/Color/Precio/Stock (ver bloque de abajo), SIEMPRE colapsada por defecto (rediseño
   2026-07-25: antes se auto-abría si había algún filtro activo, ahora eso se resuelve con los
   chips de resumen .rkxt-ed-masfiltros-chips). El <form method=get> YA NO carga la clase
   .rkxt-filterbar — el sticky + fondo + borde vive en el wrapper .rkxt-ed-cabecera (ver arriba). */
.rkxt-ed-filtros { display: flex; flex-direction: column; gap: 8px; }
.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; }
/* Botón que abre el popover de carga por curva — visualmente distinto de "Filtrar" (ghost) porque
   es la acción potente de la pantalla, no un filtro más. Ver popover .rkxt-popover más abajo. */
.rkxt-ed-curva-abrir { margin-left: auto; }
@media (max-width: 640px) { .rkxt-ed-curva-abrir { margin-left: 0; } }

/* --- "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);
}

/* Resumen de filtros avanzados activos cuando el <details> está COLAPSADO (default siempre ahora,
   ver comentario arriba) — así el vendedor ve qué hay tildado sin gastar el alto de abrir el
   panel entero. Chips read-only (no checkbox), mismo look que .rkxt-badge pero pill y más chatos. */
.rkxt-ed-masfiltros-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: -2px 0 0; }
.rkxt-ed-filtro-chip {
    display: inline-flex; align-items: center;
    padding: 3px 10px; border-radius: var(--rkxt-radius-pill);
    background: var(--rkxt-primary-soft); border: 1px solid var(--rkxt-border);
    color: var(--rkxt-primary); font-size: .74rem; font-weight: 600; white-space: nowrap;
}

/* 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; }

/* ===== Popover nativo (HTML5 Popover API) — MODAL SIN JS ==========================
   EditarPedido.razor es SSR estática (sin @rendermode InteractiveServer: 677 productos + forms
   GET/POST, convertirla a InteractiveServer sería una reescritura mayor y cae en la regla 26 del
   CLAUDE.md de Rakuxt — Layout+Page con DbContext scoped). Por eso NO se puede usar el patrón
   .rkxt-modal-backdrop + @onclick (requiere un circuit interactivo). El atributo HTML nativo
   `popover` + `popovertarget`/`popovertargetaction` (Chrome/Edge 114+, Firefox 125+, Safari 17+,
   soporte de base sólido en 2026) resuelve abrir/cerrar/Esc/foco/top-layer sin una línea de JS —
   el navegador lo maneja solo. Reusa el look de .rkxt-modal-head/-body/-foot/-close (definidos
   arriba, patrón "Personalizar dashboard") para que se sienta consistente con el resto del admin.
   Reusable para cualquier pantalla que necesite un modal SIN InteractiveServer: dejar el prefijo
   genérico rkxt-popover (no rkxt-ed-*) a propósito. */
[popover].rkxt-popover {
    margin: auto; border: none; padding: 0; color: inherit;
    border-radius: var(--rkxt-radius);
    background: var(--rkxt-surface);
    box-shadow: var(--rkxt-shadow-lg);
    width: 100%; max-width: 640px;
    max-height: calc(100vh - 48px);
}
/* OJO especificidad: la UA stylesheet oculta [popover] con
   "[popover]:not(:popover-open){display:none}" (misma especificidad que un selector de atributo+
   clase). Si acá pisáramos "display" siempre, se vería aunque esté cerrado — por eso el override
   de display SOLO entra atado a :popover-open (mayor especificidad, gana siempre). */
[popover].rkxt-popover:popover-open { display: flex; flex-direction: column; }
[popover].rkxt-popover::backdrop { background: rgba(15, 15, 18, .5); }

/* --- Contenido del popover "Carga por curva": llena de una vez los N productos del filtro
   actual. El submit ya recibe feedback del loader global del admin (rkxt-admin-navloader.js) —
   sumale confirm() porque sobreescribe muchos renglones de una, mismo criterio que "↺ Restaurar
   pedido original" en este mismo archivo. */
.rkxt-ed-curva-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.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: 10px 0 0; font-size: .78rem; color: var(--rkxt-text-muted); }
.rkxt-ed-curva-foot-note { margin-right: auto; font-size: .8rem; }

/* Hint dinámico del select "Método" (curvas / total_ajustado) — mismo texto que en
   Crm/PedidosMasivos/Nuevo.razor, pero ahí es @bind + @if (InteractiveServer) y acá esta pantalla
   es SSR estática: un @if en @code NO se re-renderiza al cambiar el <select> sin postback. Se
   pintan los DOS hints siempre y CSS puro con :has(option:checked) muestra solo el que matchea la
   opción seleccionada — cero JS, funciona en SSR. */
.rkxt-ed-metodo-hint { display: none; flex-basis: 100%; margin: -2px 0 0; font-size: .76rem; color: var(--rkxt-text-muted); }
.rkxt-ed-curva-form:has(select[name=metodoCurva] option[value=curvas]:checked) .rkxt-ed-metodo-hint[data-when=curvas] { display: block; }
.rkxt-ed-curva-form:has(select[name=metodoCurva] option[value=total_ajustado]:checked) .rkxt-ed-metodo-hint[data-when=total_ajustado] { display: block; }

/* ---- 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; }

/* ============================================================================
   F26 — "Cambios del pedido": timeline renglón por renglón (Admin/Sales/Pedidos/Detalle.razor).
   Reusa .rkxt-dash-block (misma familia que "Cómo está armado el pedido"), .rkxt-table para las
   líneas y .rkxt-badge-success/-warning para el chip de autor (cliente=ok/verde, vendedor=warn/ámbar,
   mismo semáforo que .rkxt-sf-dash-modv). El filtro por autor es 100% CSS (radios + :has()): la
   lista ya viene entera en el render, no hay round-trip. Sin soporte de :has() simplemente no filtra.
   ============================================================================ */
.rkxt-cambios-filtro {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    margin: 0 0 14px;
    font-size: .86rem;
}
.rkxt-cambios-filtro-opt {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    color: var(--rkxt-text-muted);
}
.rkxt-cambios-filtro-opt:has(input:checked) { color: var(--rkxt-text); font-weight: 600; }
.rkxt-cambios-filtro-opt input { margin: 0; accent-color: var(--rkxt-primary); }

/* Los radios y la lista comparten .rkxt-cambios-block como ancestro común. */
.rkxt-cambios-block:has(input[name="rkxt-cambios-autor"][value="cliente"]:checked) .rkxt-cambios-tanda[data-cambios-autor="V"] { display: none; }
.rkxt-cambios-block:has(input[name="rkxt-cambios-autor"][value="vendedor"]:checked) .rkxt-cambios-tanda[data-cambios-autor="C"] { display: none; }

/* Alto acotado con scroll propio: puede haber decenas de tandas y cientos de renglones por tanda
   (recortados con Take(CORTE) + fila "…y N más") — no debe reventar el alto de la página. */
.rkxt-cambios-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-height: 560px;
    overflow-y: auto;
    padding-right: 4px;
}

.rkxt-cambios-tanda {
    /* flex:0 0 auto es OBLIGATORIO: .rkxt-cambios-list es flex column con max-height, y un ítem flex
       tiene flex-shrink:1 por defecto. Sin esto, cuando el total de tandas supera los 560px cada
       tanda se ENCOGE y —al tener overflow:hidden por el border-radius— recorta sus últimas filas
       en silencio, en vez de que scrollee la lista. Se veía "AGREGÓ (1)" sin el renglón debajo. */
    flex: 0 0 auto;
    border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm);
    background: var(--rkxt-surface);
    overflow: hidden;
}
.rkxt-cambios-tanda-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 14px;
    background: var(--rkxt-bg-alt);
    border-bottom: 1px solid var(--rkxt-border);
    font-size: .85rem;
}
.rkxt-cambios-tanda-autor { flex: 0 0 auto; }
.rkxt-cambios-tanda-email,
.rkxt-cambios-tanda-fecha { color: var(--rkxt-text-muted); font-size: .82rem; }
.rkxt-cambios-tanda-resumen { margin-left: auto; color: var(--rkxt-text-muted); white-space: nowrap; }
.rkxt-cambios-delta-pos { color: var(--rkxt-ok); }
.rkxt-cambios-delta-neg { color: var(--rkxt-bad); }

/* Tabla anidada: SIN el thead sticky global — el offset --rkxt-theadtop lo calcula el JS de
   AdminLayout para el .rkxt-filterbar de PÁGINA, y esta tabla vive dentro de su propio scroll. */
.rkxt-cambios-table { border: none; border-radius: 0; font-size: .85rem; }
.rkxt-cambios-table thead th { position: static; box-shadow: none; }
.rkxt-cambios-table th, .rkxt-cambios-table td { padding: 7px 14px; }

.rkxt-cambios-grouprow td {
    font-weight: 700;
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--rkxt-text-muted);
    background: var(--rkxt-surface-2);
    padding-top: 6px;
    padding-bottom: 6px;
}
.rkxt-cambios-grouprow--add td { box-shadow: inset 3px 0 0 var(--rkxt-ok); }
.rkxt-cambios-grouprow--del td { box-shadow: inset 3px 0 0 var(--rkxt-bad); }
.rkxt-cambios-grouprow--chg td { box-shadow: inset 3px 0 0 var(--rkxt-warn); }
.rkxt-cambios-linea--add > td:first-child { box-shadow: inset 3px 0 0 var(--rkxt-ok); }
.rkxt-cambios-linea--del > td:first-child { box-shadow: inset 3px 0 0 var(--rkxt-bad); }
.rkxt-cambios-linea--chg > td:first-child { box-shadow: inset 3px 0 0 var(--rkxt-warn); }
.rkxt-cambios-masrow td { color: var(--rkxt-text-dim); font-style: italic; font-size: .82rem; }

@media (max-width: 720px) {
    .rkxt-cambios-tanda-resumen { margin-left: 0; }
}

/* F26 — tag "tu vendedor cambió N renglones" en el listado de pedidos del cliente (storefront).
   Mismo tono ámbar de aviso que .rkxt-sf-dash-modv, en formato chip clickeable. */
.rkxt-sf-pedido-modv-tag {
    display: inline-block;
    margin-top: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: .74rem;
    font-weight: 600;
    text-decoration: none;
    color: var(--rkxt-warn);
    background: color-mix(in srgb, var(--rkxt-warn) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--rkxt-warn) 35%, transparent);
}
.rkxt-sf-pedido-modv-tag:hover { background: color-mix(in srgb, var(--rkxt-warn) 20%, transparent); }

/* Barra de filtros de /admin/sales/pedidos (cliente + ventana de fechas). Las fechas van a la vista
   porque antes la grilla recortaba por la temporada vigente sin decirlo: un pedido fuera de esa
   ventana simplemente "no existía" y no había nada en pantalla que lo explicara. */
.rkxt-pedidos-filtros {
    display: flex;
    align-items: flex-end;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}
.rkxt-pedidos-filtros .rkxt-field { margin: 0; }
.rkxt-pedidos-filtros .rkxt-input { min-width: 190px; }
.rkxt-pedidos-filtros input[type="date"].rkxt-input { min-width: 150px; }
.rkxt-pedidos-filtros-info {
    margin-left: auto;
    font-size: .8rem;
    color: var(--rkxt-text-muted);
    white-space: nowrap;
}

/* ===== 2026-08-28 (Walter) — negro para los dos controles de acción del catálogo =====
   El acento del tema no sirve acá: en Herencia es dorado y el botón se pierde. Van con el token
   --rkxt-sf-btn-oscuro, no con un #111 repetido, para poder moverlos de un solo lugar. */
.rkxt-sf-search-btn { background: var(--rkxt-sf-btn-oscuro); color: #FFFFFF; }
.rkxt-sf-search-btn:hover { background: #000000; }
.rkxt-sf-qo-bar .rkxt-btn-primary {
    background: var(--rkxt-sf-btn-oscuro);
    border-color: var(--rkxt-sf-btn-oscuro);
    color: #FFFFFF;
}
.rkxt-sf-qo-bar .rkxt-btn-primary:hover { background: #000000; border-color: #000000; }

/* ===== 2026-08-29 (Walter) — "Confirmar pedido" del carrito =====
   Estaba al final de la tabla y se llamaba "Continuar pedido". Dos problemas: con un pedido
   mayorista de decenas de renglones había que scrollear hasta el fondo para cerrarlo, y
   "continuar" no dice que ahí se confirma.
   Ahora vive arriba a la derecha del encabezado, a la altura del nombre del usuario del header,
   y va en negro por el mismo motivo que la lupa y "Agregar al pedido": el acento del tema no
   sirve para la acción principal (en Herencia es dorado y se pierde). Mismo token, se mueven
   todos juntos. */
.rkxt-sf-cart-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}
/* El bloque de título cede ancho (su texto ya hace wrap); min-width:0 es lo que evita que
   empuje el botón a la línea de abajo. */
.rkxt-sf-cart-head > div:first-child { min-width: 0; flex: 1 1 auto; }
/* stretch, no center: "Descartar" es un <button> dentro de un <form> y "Confirmar" es un <a>
   suelto. Con align-items:center cada uno queda con el alto de su propia caja y se ven de
   distinto tamaño; con stretch los dos toman el alto del más alto y calzan parejos (el form
   también se estira, por eso es flex — si no, el botón que lleva adentro no lo hereda). */
.rkxt-sf-cart-head-acciones { display: flex; align-items: stretch; gap: 10px; flex: 0 0 auto; margin-left: auto; }
.rkxt-sf-cart-head-acciones > form { display: flex; margin: 0; }

/* Las dos acciones del pedido comparten forma y tamaño; las separa el COLOR (Walter 2026-08-29):
   confirmar en negro, descartar en bordó. Antes eran dos botones negros idénticos pegados y uno
   tira el pedido entero — el color es lo que evita el clic equivocado, no la confirmación.
   display:inline-flex + align-items:center: uno es un <a> y el otro un <button>, y sin esto cada
   uno calcula su alto con su propia caja (ver también el stretch del contenedor). */
.rkxt-sf-cart-confirmar,
.rkxt-sf-cart-descartar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #FFFFFF;
    white-space: nowrap;
}
.rkxt-sf-cart-confirmar {
    background: var(--rkxt-sf-btn-oscuro);
    border-color: var(--rkxt-sf-btn-oscuro);
}
.rkxt-sf-cart-confirmar:hover { background: #000000; border-color: #000000; color: #FFFFFF; }

.rkxt-sf-cart-descartar {
    background: var(--rkxt-sf-btn-bordo);
    border-color: var(--rkxt-sf-btn-bordo);
}

/* Alto de los botones de la barra del pedido, en las DOS vistas (/cart y /cart/estadistica).
   2026-08-29 (Walter): "sobra lugar arriba y abajo del texto". El .rkxt-btn general trae
   padding: 11px 18px; acá el vertical baja a 6px, que sobre un texto de ~18px deja el botón un
   25% más bajo (de ~42px a ~32px). Sólo el eje vertical y sólo en esta barra: el resto de los
   botones del storefront no cambia. */
.rkxt-sf-cart-head-acciones .rkxt-btn { padding-block: 6px; }

/* Posición vertical de la barra en /cart/estadistica: -5 mm (estaba en 5 mm y Walter pidió un
   centímetro más arriba).
   Antes estuvo en -1cm y fue un error: el header del storefront es STICKY, así que subir la barra
   la metía por detrás de él y los botones quedaban tapados.
   En mobile no aplica: los botones se apilan debajo del título y moverlos los encimaría. */
.rkxt-sf-cart-head--estadistica .rkxt-sf-cart-head-acciones { margin-top: -5mm; }
@media (max-width: 640px) {
    .rkxt-sf-cart-head--estadistica .rkxt-sf-cart-head-acciones { margin-top: 0; }
}

/* ===== /cart/estadistica — la grilla se corre al borde izquierdo y los donuts crecen 20% =====
   2026-08-29 (Walter). El bloque arranca 1,5 cm más a la izquierda y se ensancha lo mismo, así el
   borde derecho no se mueve: lo que gana es la COLUMNA DERECHA del layout, que es donde viven los
   donuts. Sin el `width`, correr el bloque movería también su borde derecho y no se liberaría nada.

   Los donuts no tienen un alto fijo: --rkxt-pdc-donut-w es el TOPE de ancho y la altura sale del
   aspect-ratio (alto = ancho × 0,698), así que subir la variable los agranda enteros y en
   proporción, sin tocar el canvas ni el JS que los dibuja. El valor vigente es 190 px —bajado dos
   veces el 2026-08-25 desde 374, "no es necesario que sean tan grandes"—, así que el +20% sale
   190 → 228 px. Ojo con eso: el default que declara .rkxt-sf-pdc-donut-wrap sigue siendo 374 y no
   es el que manda.

   Acotado a esta página con .rkxt-sf-cart-estadistica-vista: el layout .rkxt-sf-pdc-* lo comparte
   con el detalle del pedido enviado (/cuenta/pedidos/{id}), donde no se pidió cambiar nada.
   En mobile no aplica: ahí el layout es de una sola columna y correrlo lo sacaría de pantalla. */
.rkxt-sf-cart-estadistica-vista .rkxt-sf-pdc-layout {
    margin-left: -1.5cm;
    width: calc(100% + 1.5cm);
    --rkxt-pdc-donut-w: 228px;
}
@media (max-width: 900px) {
    .rkxt-sf-cart-estadistica-vista .rkxt-sf-pdc-layout {
        margin-left: 0;
        width: 100%;
    }
}

/* "Estadística del pedido" — la tercera acción del encabezado. Va en ghost (borde, sin relleno) a
   propósito: es una forma de MIRAR el mismo pedido, no una acción sobre él. Los dos rellenos
   sólidos quedan para las que cambian algo — confirmar y descartar. */
.rkxt-sf-cart-estadistica {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    border-color: var(--rkxt-sf-btn-oscuro);
    color: var(--rkxt-sf-btn-oscuro);
    background: transparent;
}
.rkxt-sf-cart-estadistica:hover {
    background: var(--rkxt-sf-btn-oscuro);
    border-color: var(--rkxt-sf-btn-oscuro);
    color: #FFFFFF;
}
.rkxt-sf-cart-descartar:hover {
    background: var(--rkxt-sf-btn-bordo-hover);
    border-color: var(--rkxt-sf-btn-bordo-hover);
    color: #FFFFFF;
}

/* En mobile el botón pasa a ocupar el ancho y se apila debajo del título: al lado no entra sin
   partir el texto en dos líneas. */
@media (max-width: 640px) {
    .rkxt-sf-cart-head { flex-direction: column; align-items: stretch; }
    .rkxt-sf-cart-head-acciones { margin-left: 0; }
    /* Los botones y el form que envuelve a Descartar reparten el ancho en partes iguales. */
    .rkxt-sf-cart-head-acciones > * { flex: 1 1 0; }
    .rkxt-sf-cart-confirmar,
    .rkxt-sf-cart-estadistica,
    .rkxt-sf-cart-descartar { width: 100%; justify-content: center; }
}

/* Cabecera de la grilla del catálogo, al mismo tono que el menú lateral (los dos con el token
   derivado, así se mueven juntos). */
.rkxt-sf-qo-tabla thead th { background: var(--rkxt-sf-panel-bg); }

/* Resto del buscador retirado del catálogo: aviso de "estás viendo resultados de X". */
.rkxt-sf-qo-search-activa {
    margin: 0; display: flex; align-items: baseline; gap: .75rem;
    font-size: .9rem; color: var(--rkxt-text-muted);
}

/* ============================================================================
   Revisión del catálogo (/admin/catalog/revision) — 2026-09-06
   La pantalla de trabajo de lo que trajo el barredor de las webs minoristas.
   Se parece al catálogo del storefront a propósito: quien la usa reconoce el
   producto por la foto antes que por el código.
   Los filtros quedan fijos mientras se scrollea la grilla. El sticky va en la
   COLUMNA, no en el panel de adentro: un sticky sobre un hijo sin altura propia
   no tiene contra qué anclarse (misma lección que el thead de las tablas).
   ============================================================================ */
.rkxt-rev { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 1.25rem; align-items: start; }
.rkxt-rev-side { position: sticky; top: 1rem; align-self: start; max-height: calc(100vh - 2rem); overflow-y: auto; }
.rkxt-rev-side-in { display: flex; flex-direction: column; gap: .9rem; padding-right: .4rem; }
.rkxt-rev-titulo h1 { margin: 0 0 .15rem; font-size: 1.15rem; }
.rkxt-rev-titulo p { margin: 0; font-size: .78rem; line-height: 1.35; }

.rkxt-rev-pendientes {
    display: flex; align-items: baseline; gap: .4rem;
    background: var(--rkxt-surface-2); border: 1px solid var(--rkxt-border);
    border-radius: var(--rkxt-radius-sm, 6px); padding: .5rem .7rem;
}
.rkxt-rev-pend-n { font-size: 1.5rem; font-weight: 700; color: var(--rkxt-primary); line-height: 1; }
.rkxt-rev-pend-t { font-size: .78rem; color: var(--rkxt-text-muted); }

.rkxt-rev-buscar { display: block; }
.rkxt-rev-buscar .rkxt-input { width: 100%; font-size: .85rem; }

.rkxt-rev-grupo { display: flex; flex-wrap: wrap; gap: .3rem; }
.rkxt-rev-grupo-t {
    width: 100%; font-size: .68rem; text-transform: uppercase; letter-spacing: .06em;
    color: var(--rkxt-text-muted); margin-bottom: .1rem;
}
.rkxt-rev-chip {
    display: inline-flex; align-items: center; gap: .3rem;
    border: 1px solid var(--rkxt-border); background: var(--rkxt-surface);
    color: var(--rkxt-text); border-radius: 999px; padding: .22rem .6rem;
    font-size: .76rem; cursor: pointer; line-height: 1.3;
}
.rkxt-rev-chip:hover:not(:disabled) { border-color: var(--rkxt-primary); }
.rkxt-rev-chip.is-on { background: var(--rkxt-primary); border-color: var(--rkxt-primary); color: #fff; }
.rkxt-rev-chip:disabled { opacity: .55; cursor: default; }
.rkxt-rev-chip-n { font-size: .68rem; opacity: .75; font-variant-numeric: tabular-nums; }
.rkxt-rev-check { display: flex; align-items: center; gap: .4rem; font-size: .8rem; cursor: pointer; }
.rkxt-rev-link { font-size: .78rem; color: var(--rkxt-text-muted); text-decoration: none; }
.rkxt-rev-link:hover { color: var(--rkxt-primary); }

.rkxt-rev-main { min-width: 0; }
.rkxt-rev-barra {
    position: sticky; top: 0; z-index: 4;
    display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; justify-content: space-between;
    background: var(--rkxt-surface); border-bottom: 1px solid var(--rkxt-border);
    padding: .55rem 0; margin-bottom: .7rem;
}
.rkxt-rev-barra-info { font-size: .88rem; }
.rkxt-rev-sel { color: var(--rkxt-primary); font-weight: 600; }
/* La selección se arma entre páginas y filtros, así que hay que decir en voz alta cuántos de los
   seleccionados no están a la vista: la acción en bloque también cae sobre ellos. */
.rkxt-rev-fuera {
    margin-left: .45rem; font-size: .72rem; padding: .1rem .4rem; border-radius: 999px;
    background: #FEF3C7; color: #92400E; font-weight: 600;
}
.rkxt-rev-barra-acc { display: flex; flex-wrap: wrap; gap: .35rem; }

.rkxt-rev-vacio { padding: 2.5rem 0; text-align: center; }
.rkxt-rev-limpio { font-size: 1.05rem; font-weight: 600; margin: 0 0 .3rem; }

.rkxt-rev-grid {
    display: grid; gap: .85rem;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.rkxt-rev-card {
    display: flex; flex-direction: column; overflow: hidden;
    border: 1px solid var(--rkxt-border); border-radius: var(--rkxt-radius-sm, 6px);
    background: var(--rkxt-surface);
}
.rkxt-rev-card.is-sel { border-color: var(--rkxt-primary); box-shadow: 0 0 0 1px var(--rkxt-primary); }

/* La foto es el disparador de todo: ocupa el ancho completo y es también la casilla de selección,
   así elegir en bloque es un clic sobre lo mismo que el usuario ya está mirando. */
.rkxt-rev-card-img {
    position: relative; display: block; aspect-ratio: 3 / 4; background: var(--rkxt-surface-2);
    cursor: pointer; overflow: hidden;
}
.rkxt-rev-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rkxt-rev-card-img input[type=checkbox] {
    position: absolute; top: .4rem; left: .4rem; z-index: 2; width: 1.05rem; height: 1.05rem; cursor: pointer;
}
.rkxt-rev-sinfoto {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-size: .75rem; color: var(--rkxt-text-muted);
}
.rkxt-rev-fotoweb {
    position: absolute; right: .35rem; bottom: .35rem; background: rgba(17,17,22,.72); color: #fff;
    font-size: .62rem; padding: .1rem .35rem; border-radius: 3px;
}

.rkxt-rev-card-body { display: flex; flex-direction: column; gap: .28rem; padding: .55rem .6rem .6rem; }
.rkxt-rev-card-top { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.rkxt-rev-marca { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--rkxt-text-muted); }
.rkxt-rev-nombre {
    margin: 0; font-size: .84rem; font-weight: 600; line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.rkxt-rev-cod { font-size: .7rem; color: var(--rkxt-text-muted); font-variant-numeric: tabular-nums; }
.rkxt-rev-cat {
    font-size: .72rem; color: var(--rkxt-text-muted); line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.rkxt-rev-nocat { color: #b45309; font-weight: 600; }
.rkxt-rev-datos { display: flex; flex-wrap: wrap; gap: .5rem; font-size: .72rem; color: var(--rkxt-text-muted); }
.rkxt-rev-asuntos { display: flex; flex-wrap: wrap; gap: .22rem; }
.rkxt-rev-asunto {
    font-size: .64rem; padding: .1rem .35rem; border-radius: 3px;
    background: var(--rkxt-surface-2); color: var(--rkxt-text-muted);
}
.rkxt-rev-asunto.is-fuerte { background: #FEF3C7; color: #92400E; }

.rkxt-rev-acc { display: flex; flex-wrap: wrap; gap: .28rem; align-items: center; margin-top: .2rem; }
.rkxt-rev-decidido { font-size: .72rem; font-weight: 600; color: var(--rkxt-primary); }
.rkxt-rev-ver { font-size: .7rem; color: var(--rkxt-text-muted); text-decoration: underline; margin-left: auto; }

.rkxt-rev-catbox {
    display: flex; flex-direction: column; gap: .3rem; padding: .4rem;
    background: var(--rkxt-surface-2); border-radius: 4px;
}
.rkxt-rev-catlista { display: flex; flex-direction: column; max-height: 190px; overflow-y: auto; gap: .12rem; }
.rkxt-rev-catop {
    text-align: left; font-size: .72rem; padding: .22rem .35rem; border: 0; cursor: pointer;
    background: var(--rkxt-surface); border-radius: 3px; line-height: 1.25;
}
.rkxt-rev-catop:hover:not(:disabled) { background: var(--rkxt-primary); color: #fff; }

.rkxt-rev-pag { display: flex; align-items: center; justify-content: center; gap: .8rem; padding: 1.1rem 0; }

@media (max-width: 900px) {
    .rkxt-rev { grid-template-columns: 1fr; }
    .rkxt-rev-side { position: static; max-height: none; }
}
