/* /Components/Account/Shared/AuthLayout.razor.rz.scp.css */
/* El login es la primera pantalla del día y era la única que no parecía el mismo producto: tenía
   19 colores propios (shell gris, botón casi negro, rojo y verde de Bootstrap) y hasta un focus ring
   AZUL, cuando el global es teal. Ahora va sobre los mismos tokens que el resto del panel, así que
   un cambio de paleta también lo alcanza — y el modo oscuro sale gratis en vez de a parches. */
.auth-shell[b-5evrjo8s2h] {
    min-height: 100vh;
    min-height: 100dvh;   /* la barra de URL móvil se come parte de 100vh */
    display: flex;
    background: var(--paper);
}

.auth-main[b-5evrjo8s2h] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex: 1;
    padding: 48px 24px;
}

.auth-card[b-5evrjo8s2h] {
    width: 100%;
    max-width: 420px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    padding: 40px 36px;
    box-shadow: var(--shadow-md);
}

.auth-brand[b-5evrjo8s2h] {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 24px;
}

.auth-brand-mark[b-5evrjo8s2h] {
    width: 28px;
    height: 28px;
    background: var(--brand);
    color: var(--on-brand);
    border-radius: var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.auth-brand-name[b-5evrjo8s2h] {
    font-size: var(--text-2xl);
    font-weight: 700;
    letter-spacing: -.01em;
}

.auth-foot[b-5evrjo8s2h] {
    margin-top: 20px;
    font-size: var(--text-xs);
    color: var(--ink-muted);
}

[b-5evrjo8s2h] .auth-title {
    font-size: var(--text-3xl);
    font-weight: 600;
    letter-spacing: -.015em;
    margin: 0 0 4px;
}

[b-5evrjo8s2h] .auth-sub {
    font-size: var(--text-lg);
    color: var(--ink-soft);
    margin: 0 0 20px;
}

[b-5evrjo8s2h] .auth-error {
    background: var(--status-red-bg);
    border: 1px solid var(--status-red);
    color: var(--status-red);
    border-radius: var(--radius-lg);
    padding: 10px 12px;
    font-size: var(--text-base);
    margin-bottom: 16px;
}

[b-5evrjo8s2h] .auth-success {
    background: var(--status-green-bg);
    border: 1px solid var(--status-green);
    color: var(--status-green);
    border-radius: var(--radius-lg);
    padding: 10px 12px;
    font-size: var(--text-base);
    margin-bottom: 16px;
}

[b-5evrjo8s2h] .auth-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

[b-5evrjo8s2h] .field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

[b-5evrjo8s2h] .field-label {
    font-size: var(--text-base);
    font-weight: 600;
}

[b-5evrjo8s2h] .field-label .req {
    color: var(--status-red);
}

[b-5evrjo8s2h] .input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    font-size: var(--text-lg);
    background: var(--surface);
    color: var(--ink);
}

/* El mismo anillo de foco que el resto de la app (app.css lo define en --brand-text). El azul de
   Bootstrap que había acá era el único foco distinto de todo el panel. */
[b-5evrjo8s2h] .input:focus-visible {
    outline: 2px solid var(--brand-text);
    outline-offset: 2px;
}

[b-5evrjo8s2h] .field-error {
    color: var(--status-red);
    font-size: var(--text-xs);
}

[b-5evrjo8s2h] .auth-remember {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--text-base);
    user-select: none;
}

[b-5evrjo8s2h] .auth-submit {
    width: 100%;
    padding: 11px 14px;
    border: none;
    border-radius: var(--radius-lg);
    background: var(--brand);
    color: var(--on-brand);
    font-size: var(--text-lg);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--transition-fast);
}

[b-5evrjo8s2h] .auth-submit:hover {
    background: var(--brand-hover);
}

[b-5evrjo8s2h] .auth-links {
    margin-top: 18px;
    font-size: var(--text-base);
    text-align: center;
}

/* ---- Responsive ---------------------------------------------------------
   El login es la primera pantalla que ve alguien, y muchas veces desde el
   teléfono. Con 36px de padding por lado más 24px del contenedor, en 360px
   quedaban 240px reales para el formulario. */
@media (max-width: 600px) {
    .auth-main[b-5evrjo8s2h] { padding: 24px 16px; }

    .auth-card[b-5evrjo8s2h] {
        padding: 28px 20px;
        border-radius: var(--radius-xl);
    }

    /* El botón de entrar ya es ancho completo; solo le falta alto de dedo. */
    [b-5evrjo8s2h] .auth-submit { min-height: 44px; }

    /* El checkbox de "recordarme" es un blanco de ~13px sin esto. */
    [b-5evrjo8s2h] .auth-remember input[type="checkbox"] {
        width: 18px;
        height: 18px;
    }
}

/* Sin parche de dark: los tokens de arriba ya cambian con el tema. Acá había dos reglas con
   :host-context(), que es un selector de Shadow DOM y en un scoped stylesheet de Blazor no matchea
   nunca — o sea, código muerto que aparentaba resolver el modo oscuro. */
/* /Components/Layout/MainLayout.razor.rz.scp.css */
.app-shell[b-d0xna3yqt3] {
    display: flex;
    min-height: 100vh;
    min-height: 100dvh;   /* la barra de URL móvil se come parte de 100vh */
    background: var(--paper);
}

.main-area[b-d0xna3yqt3] {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    margin-left: var(--sidebar-width);
    transition: margin-left var(--transition-slow);
}

/* The rail is position:fixed, so the content area's margin is what actually
   reclaims the space — it has to move in step with the collapse. */
.app-shell--nav-collapsed .main-area[b-d0xna3yqt3] {
    margin-left: var(--sidebar-width-collapsed);
}

/* El padding responde a los tokens de app.css en vez de tener sus propias media
   queries. /conversations tiene que cancelar exactamente este padding con un
   margen negativo, y con números literales acá los tenía que copiar a mano. */
.page-content[b-d0xna3yqt3] {
    flex: 1;
    padding: var(--page-pad-y) var(--page-pad-x);
    overflow-y: auto;
}

/* Oculto por defecto y no solo "sin estilos". El drawer únicamente se abre
   bajo 900px, pero ensanchar la ventana con el drawer abierto deja el scrim
   montado: sin este display:none quedaría un botón vacío sin estilar metido
   entre el riel y el contenido en pleno escritorio. */
.nav-scrim[b-d0xna3yqt3] { display: none; }

/* Laptop: the rail is forced to the icon rail regardless of the user's
   preference — 240px of navigation is not worth it at this width. */
@media (min-width: 901px) and (max-width: 1100px) {
    .main-area[b-d0xna3yqt3] { margin-left: var(--sidebar-width-collapsed); }
}

/* Tablet y teléfono: el riel es un drawer que flota sobre el contenido, así
   que no hay ancho que reservarle. Este margen en 0 es la mitad de lo que
   hace responsive a la app — la otra mitad es el translateX de NavMenu. */
@media (max-width: 900px) {
    .main-area[b-d0xna3yqt3],
    .app-shell--nav-collapsed .main-area[b-d0xna3yqt3] {
        margin-left: 0;
    }

    /* Tocar fuera cierra el drawer, como cualquier panel deslizable. Es un
       <button> y no un <div> para que también responda a Enter/Espacio y
       aparezca en el recorrido del teclado. z-index entre el contenido y el
       drawer (100), nunca por encima de él. */
    .nav-scrim[b-d0xna3yqt3] {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 99;
        border: none;
        padding: 0;
        background: var(--scrim);
        cursor: pointer;
    }
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
.sidebar[b-vp3qh5h25t] {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    width: var(--sidebar-width);
    background: var(--surface);
    border-right: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    z-index: 100;
    transition: width var(--transition-slow);
}

/* ---- Collapsed rail: icons only ----------------------------------------
   Labels are hidden with width:0 + overflow rather than display:none so the
   width transition has something to animate against; going straight to
   display:none makes the rail snap instead of slide. */
.sidebar--collapsed[b-vp3qh5h25t] { width: var(--sidebar-width-collapsed); }

/* .nav-label lives inside the <a> NavLink renders, so it never carries this
   component's scope attribute — it has to be reached through ::deep, unlike
   .brand-name and .nav-cap which are written directly in NavMenu.razor. */
.sidebar--collapsed .brand-name[b-vp3qh5h25t],
.sidebar--collapsed .nav-cap[b-vp3qh5h25t],
.sidebar--collapsed .nav-section[b-vp3qh5h25t]  .nav-label {
    opacity: 0;
    width: 0;
    overflow: hidden;
    white-space: nowrap;
    pointer-events: none;
}

/* Centrar el riel pide dos cosas más que justify-content, porque el label sigue
   siendo un flex item aunque no se vea:
   - flex: 0 0 0 — .nav-label lleva flex:1 en el riel expandido, y el flex-basis
     le gana al width:0 de arriba, así que seguiría creciendo hasta comerse el
     espacio libre y dejar a justify-content sin nada que centrar.
   - gap: 0 — el gap se aplica igual entre el ícono y un item de ancho cero, y
     corría el ícono media luz a la izquierda (mismo caso en .sidebar-brand). */
.sidebar--collapsed .nav-section[b-vp3qh5h25t]  .nav-label { flex: 0 0 0; }

.sidebar--collapsed .sidebar-brand[b-vp3qh5h25t],
.sidebar--collapsed .nav-section[b-vp3qh5h25t]  .nav-item {
    justify-content: center;
    gap: 0;
    padding-left: 0;
    padding-right: 0;
}

/* The takeover badge is the one thing that must survive collapsing — it is the
   signal that someone is waiting. Shrunk to a dot pinned to the icon. */
.sidebar--collapsed .nav-section[b-vp3qh5h25t]  .nav-badge {
    position: absolute;
    top: 6px;
    right: 12px;
    min-width: 8px;
    width: 8px;
    height: 8px;
    padding: 0;
    font-size: 0;
    border-radius: 50%;
}

.sidebar--collapsed .sidebar-collapse svg[b-vp3qh5h25t] { transform: rotate(180deg); }

/* ---- Collapse control --------------------------------------------------- */
.sidebar-collapse[b-vp3qh5h25t] {
    position: absolute;
    top: calc(var(--topbar-height) / 2 - 12px);
    right: -12px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 50%;
    background: var(--surface);
    color: var(--ink-muted);
    cursor: pointer;
    z-index: 101;
    transition: background var(--transition-fast),
                color var(--transition-fast),
                border-color var(--transition-fast);
}

.sidebar-collapse:hover[b-vp3qh5h25t] {
    background: var(--surface-hover);
    color: var(--ink);
    border-color: var(--ink-muted);
}

.sidebar-collapse svg[b-vp3qh5h25t] { transition: transform var(--transition-slow); }

/* Below this width the rail is always the icon rail (901–1100px) or a drawer
   (≤900px), so the manual control has nothing left to do — hiding it beats
   leaving a button that does nothing. */
@media (max-width: 1100px) {
    .sidebar-collapse[b-vp3qh5h25t] { display: none; }
}

/* ---- Laptop: riel de íconos forzado -------------------------------------
   OJO con el límite inferior. Esto se escribió como `max-width: 1100px` a
   secas, cuando por debajo no había nada más. Ahora sí lo hay: bajo 900px el
   riel es un drawer de 240px CON etiquetas, y estas reglas —que existen justo
   para esconder las etiquetas— lo dejarían como una columna de íconos mudos
   deslizándose sobre el contenido. El rango cerrado es lo que las mantiene en
   el ancho para el que se pensaron. */
@media (min-width: 901px) and (max-width: 1100px) {
    .sidebar[b-vp3qh5h25t] { width: var(--sidebar-width-collapsed); }

    .sidebar .brand-name[b-vp3qh5h25t],
    .sidebar .nav-cap[b-vp3qh5h25t],
    .sidebar .nav-section[b-vp3qh5h25t]  .nav-label {
        opacity: 0;
        width: 0;
        overflow: hidden;
        white-space: nowrap;
        pointer-events: none;
    }

    /* Mismo par de reglas que el riel colapsado manual — ver el comentario de arriba. */
    .sidebar .nav-section[b-vp3qh5h25t]  .nav-label { flex: 0 0 0; }

    .sidebar .sidebar-brand[b-vp3qh5h25t],
    .sidebar .nav-section[b-vp3qh5h25t]  .nav-item {
        justify-content: center;
        gap: 0;
        padding-left: 0;
        padding-right: 0;
    }

    .sidebar .nav-section[b-vp3qh5h25t]  .nav-badge {
        position: absolute;
        top: 6px;
        right: 12px;
        min-width: 8px;
        width: 8px;
        height: 8px;
        padding: 0;
        font-size: 0;
        border-radius: 50%;
    }
}

/* ---- Tablet y teléfono: drawer off-canvas -------------------------------
   Acá el riel no se encoge, se va. A 360px los 64px del riel de íconos son
   casi una quinta parte de la pantalla gastada en símbolos sin nombre; sale
   del flujo y vuelve a ancho completo CON etiquetas cuando se lo pide.

   Mismo patrón que el drawer de la lista en Conversations.razor.css, a
   propósito: dos deslizables que se comportan distinto en la misma app son
   dos cosas que aprender. */
@media (max-width: 900px) {
    .sidebar[b-vp3qh5h25t] {
        width: var(--sidebar-width);
        transform: translateX(-101%);      /* 101% se lleva también el borde de 1px */
        /* visibility, y no solo transform, por dos motivos que van juntos:
           un menú corrido fuera de pantalla sigue en el DOM y sus links
           siguen siendo tabulables, así que sin esto tabular desde el topbar
           manda el foco a un link invisible; y visibility:hidden es lo que
           efectivamente los saca del orden de tabulación.

           La primera versión resolvía eso con `.sidebar:focus-within` para
           que tabular hacia adentro lo abriera. Era la herramienta
           equivocada: :focus-within no distingue teclado de dedo, y hacer
           clic en un item deja el foco EN ese link, así que el menú se
           quedaba abierto tapando la página recién elegida — encima
           interceptando los clics, con la hamburguesa debajo sin responder.
           No se veía en todas las rutas: <FocusOnNavigate Selector="h1"> de
           Routes.razor le roba el foco al link, pero solo en las páginas que
           tienen un <h1>. */
        visibility: hidden;
        box-shadow: var(--shadow-lg);
        transition: transform var(--transition-slow), visibility var(--transition-slow);
        overscroll-behavior: contain;      /* scrollear el menú no arrastra la página */
    }

    .app-shell--nav-open .sidebar[b-vp3qh5h25t] {
        transform: translateX(0);
        visibility: visible;
    }

    /* La preferencia de escritorio no manda acá. Si alguien colapsó el riel en
       la notebook y después abre en el teléfono, .sidebar--collapsed sigue
       puesta y su bloque de reglas —que está arriba, sin media query— dejaría
       el drawer en 64px de íconos anónimos. Estas cuatro reglas lo devuelven a
       un menú con nombres, que es lo único que tiene sentido en un panel que
       se desliza sobre el contenido. */
    .sidebar--collapsed .brand-name[b-vp3qh5h25t],
    .sidebar--collapsed .nav-cap[b-vp3qh5h25t],
    .sidebar--collapsed .nav-section[b-vp3qh5h25t]  .nav-label {
        opacity: 1;
        width: auto;
        overflow: visible;
        pointer-events: auto;
    }

    .sidebar--collapsed .nav-section[b-vp3qh5h25t]  .nav-label { flex: 1; }

    .sidebar--collapsed .sidebar-brand[b-vp3qh5h25t] {
        justify-content: flex-start;
        gap: 11px;
        padding: 0 20px;
    }

    .sidebar--collapsed .nav-section[b-vp3qh5h25t]  .nav-item {
        justify-content: flex-start;
        gap: 11px;
        padding: 9px 12px;
    }

    /* El badge de takeover vuelve a ser el número, no el punto del riel. */
    .sidebar--collapsed .nav-section[b-vp3qh5h25t]  .nav-badge {
        position: static;
        min-width: 18px;
        width: auto;
        height: 18px;
        padding: 0 5px;
        font-size: var(--text-2xs);
        border-radius: 999px;
    }
}

.sidebar-brand[b-vp3qh5h25t] {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 0 20px;
    height: var(--topbar-height);
    border-bottom: 1px solid var(--line-soft);
    flex-shrink: 0;
}

.brand-icon[b-vp3qh5h25t] {
    width: 32px;
    height: 32px;
    background: var(--brand);
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--on-brand);
    flex-shrink: 0;
}

.brand-name[b-vp3qh5h25t] {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -0.02em;
}

.nav-section[b-vp3qh5h25t] {
    padding: 14px 12px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
}

.nav-cap[b-vp3qh5h25t] {
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-muted);
    padding: 12px 12px 6px;
}

/* NavLink renders its own <a>, which does NOT inherit this component's
   scoped attribute. Reach it through ::deep from the scoped .nav-section. */
.nav-section[b-vp3qh5h25t]  .nav-item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 12px;
    border-radius: var(--radius-md);
    color: var(--ink-soft);
    font-size: var(--text-md);
    font-weight: 500;
    text-decoration: none;
    position: relative;
    transition: background var(--transition), color var(--transition);
    cursor: pointer;
}

.nav-section[b-vp3qh5h25t]  .nav-item:hover {
    background: var(--surface-hover);
    color: var(--ink);
    text-decoration: none;
}

.nav-section[b-vp3qh5h25t]  .nav-item.active {
    background: var(--brand-soft);
    color: var(--brand-text);
    font-weight: 600;
}

.nav-section[b-vp3qh5h25t]  .nav-item.active .nav-icon { color: var(--brand-text); }

.nav-section[b-vp3qh5h25t]  .nav-icon {
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--ink-muted);
    transition: color var(--transition);
}

.nav-section[b-vp3qh5h25t]  .nav-label { flex: 1; }

.nav-section[b-vp3qh5h25t]  .nav-badge {
    flex-shrink: 0;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--coral);
    color: var(--on-coral);
    font-size: var(--text-2xs);
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-9f073djd9t],
.components-reconnect-repeated-attempt-visible[b-9f073djd9t],
.components-reconnect-failed-visible[b-9f073djd9t],
.components-pause-visible[b-9f073djd9t],
.components-resume-failed-visible[b-9f073djd9t],
.components-rejoining-animation[b-9f073djd9t] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-9f073djd9t],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-9f073djd9t],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-9f073djd9t],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-9f073djd9t],
#components-reconnect-modal.components-reconnect-retrying[b-9f073djd9t],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-9f073djd9t],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-9f073djd9t],
#components-reconnect-modal.components-reconnect-failed[b-9f073djd9t],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-9f073djd9t] {
    display: block;
}


#components-reconnect-modal[b-9f073djd9t] {
    background-color: var(--surface);
    width: 20rem;
    /* 20rem son 280px con la raíz en 14px, así que en 320px el diálogo entra
       justo y sin aire. El tope lo deja siempre con margen a los costados. */
    max-width: calc(100vw - 2rem);
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-9f073djd9t 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-9f073djd9t 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-9f073djd9t 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-9f073djd9t]::backdrop {
    background-color: var(--scrim);
    animation: components-reconnect-modal-fadeInOpacity-b-9f073djd9t 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-9f073djd9t {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-9f073djd9t {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-9f073djd9t {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-9f073djd9t] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-9f073djd9t] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-9f073djd9t] {
    border: 0;
    background-color: var(--brand);
    color: var(--on-brand);
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-9f073djd9t] {
        background-color: var(--brand-hover);
    }

    #components-reconnect-modal button:active[b-9f073djd9t] {
        background-color: var(--brand);
    }

.components-rejoining-animation[b-9f073djd9t] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-9f073djd9t] {
        position: absolute;
        border: 3px solid var(--brand);
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-9f073djd9t 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-9f073djd9t] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-9f073djd9t {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Layout/TopBar.razor.rz.scp.css */
.topbar[b-yhejbtocwc] {
    height: var(--topbar-height);
    /* Was rgba(255,255,255,0.85) — a hardcoded white bar that would have stayed
       white in the dark theme. color-mix keeps the translucency while following
       whatever --surface currently is. */
    background: color-mix(in srgb, var(--surface) 85%, transparent);
    backdrop-filter: saturate(140%) blur(8px);
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 2rem;
    position: sticky;
    top: 0;
    z-index: 50;
    flex-shrink: 0;
}

.topbar-left[b-yhejbtocwc] {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.topbar-brand[b-yhejbtocwc] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink-muted);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* ---- Hamburguesa --------------------------------------------------------
   Oculta arriba de 900px: ahí la navegación está permanentemente a la vista
   y un botón para "abrirla" solo confundiría. */
.nav-toggle[b-yhejbtocwc] {
    display: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin-left: -8px;      /* alinea el ícono con el borde óptico de la barra */
    padding: 0;
    border: none;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--ink-soft);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.nav-toggle:hover[b-yhejbtocwc] {
    background: var(--surface-hover);
    color: var(--ink);
}

.topbar-right[b-yhejbtocwc] {
    display: flex;
    align-items: center;
    gap: 12px;
}

.logout-form[b-yhejbtocwc] {
    display: inline-flex;
}

.logout-btn[b-yhejbtocwc] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: transparent;
    color: var(--ink-muted);
    font-size: 13px;
    cursor: pointer;
}

.logout-btn:hover[b-yhejbtocwc] {
    color: var(--ink, inherit);
    border-color: var(--ink-muted);
}

/* El link a /perfil comparte .logout-btn, que es un <button>: como <a> hereda
   el color de enlace de app.css en vez del gris de la barra. */
a.logout-btn[b-yhejbtocwc] { color: var(--ink-muted); text-decoration: none; }

/* ---- Responsive ---------------------------------------------------------
   La barra tiene que entrar en 360px con cuatro cosas adentro: hamburguesa,
   tema, selector de negocio y salir. El selector es lo único que no puede
   desaparecer —sin él no se sabe qué negocio se está mirando, y cada dato de
   la pantalla depende de eso—, así que lo que se recorta es todo lo demás. */
@media (max-width: 900px) {
    .nav-toggle[b-yhejbtocwc] { display: inline-flex; }
}

@media (max-width: 600px) {
    .topbar[b-yhejbtocwc] { padding: 0 1rem; gap: 8px; }

    /* El nombre de la plataforma ya está arriba de todo en el drawer, y acá
       compite por el ancho con el único control que importa. */
    .topbar-brand[b-yhejbtocwc] { display: none; }

    .topbar-right[b-yhejbtocwc] { gap: 6px; min-width: 0; }

    /* El selector se queda con el espacio que sobra en vez de exigir 200px. */
    .topbar-right[b-yhejbtocwc]  .app-select { min-width: 0; flex: 1 1 auto; }

    .logout-btn[b-yhejbtocwc] { padding: 8px; }

    /* Solo el ícono, pero el nombre sigue existiendo para lectores de
       pantalla — el mismo recorte que .sr-only en app.css. */
    .logout-label[b-yhejbtocwc] {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }
}
/* /Components/Pages/AgentPage.razor.rz.scp.css */
.agent-layout[b-bpeehdipa3] {
    display: flex;
    gap: 1.5rem;
    align-items: flex-start;
}

/* ── Sidebar ── */
.agent-sidebar[b-bpeehdipa3] {
    width: 240px;
    flex-shrink: 0;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.sidebar-header[b-bpeehdipa3] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--line);
}

.sidebar-label[b-bpeehdipa3] {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.agent-list[b-bpeehdipa3] {
    list-style: none;
    margin: 0;
    padding: 0.25rem 0;
}

.agent-item[b-bpeehdipa3] {
    /* Button reset — a <button> styled as a row (see AgentPage.razor). */
    width: 100%;
    font: inherit;
    color: inherit;
    background: none;
    border: none;
    text-align: left;

    display: flex;
    align-items: center;
    justify-content: space-between;
    /* Left padding reserves the accent bar so selecting never shifts the row. */
    padding: 0.6rem 1rem 0.6rem calc(1rem + 4px);
    cursor: pointer;
    gap: 0.5rem;
    position: relative;
    transition: background var(--transition-fast);
}

.agent-item[b-bpeehdipa3]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: transparent;
    transition: background var(--transition-fast);
}

.agent-item:hover[b-bpeehdipa3] {
    background: var(--surface-hover);
}

.agent-item:focus-visible[b-bpeehdipa3] {
    outline: 2px solid var(--brand-text);
    outline-offset: -2px;
}

.agent-item--active[b-bpeehdipa3] {
    background: var(--brand-soft);
}

.agent-item--active[b-bpeehdipa3]::before { background: var(--brand); }

.agent-item-name[b-bpeehdipa3] {
    font-size: var(--text-md);
    font-weight: 500;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar-empty[b-bpeehdipa3] {
    padding: 1.5rem 1rem;
    font-size: var(--text-base);
    color: var(--ink-soft);
}

/* ── Detail panel ── */
/*
   640px dejaba el textarea de instrucciones en ~592px útiles: un párrafo de reglas entraba cortado
   en renglones cortísimos y era imposible releerlo. 780 sigue por debajo del ancho cómodo de
   lectura y no compite con la lista de agentes de la izquierda en los breakpoints existentes.
*/
.agent-detail[b-bpeehdipa3] {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
    max-width: 780px;
}

/* Envuelve el formulario para poder llevar @key. Hereda el espaciado que antes daba .agent-detail
   directamente a sus hijos, así el div extra no cambia nada de cómo se ve. */
.agent-form[b-bpeehdipa3] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.detail-placeholder[b-bpeehdipa3] {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 200px;
    font-size: var(--text-md);
    color: var(--ink-soft);
}

/* ── Shared form helpers ── */
.section-title[b-bpeehdipa3] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 1rem;
}

.form-grid[b-bpeehdipa3] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.form-row[b-bpeehdipa3] {
    display: flex;
    align-items: center;
    gap: 1rem;
}

/* Notas de "esto se mudó", donde antes estaban los textareas de políticas. */
.policy-moved[b-bpeehdipa3] {
    margin: 0;
    font-size: var(--text-md);
    color: var(--ink-soft);
}

.save-row[b-bpeehdipa3] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1rem;
    padding-top: 0.5rem;
}

.save-success[b-bpeehdipa3] {
    font-size: var(--text-base);
    color: var(--status-green);
    font-weight: 500;
}

.loading-state[b-bpeehdipa3] {
    font-size: var(--text-md);
    color: var(--ink-soft);
    padding: 2rem 0;
}

/* ---- Responsive ---------------------------------------------------------
   The 240px agent rail is fine beside a wide form and useless beside a narrow
   one — below the breakpoint it stops being a column and sits above the
   detail panel as a full-width list. */
@media (max-width: 900px) {
    .agent-layout[b-bpeehdipa3] {
        flex-direction: column;
        align-items: stretch;
    }

    .agent-sidebar[b-bpeehdipa3] {
        width: 100%;
    }

    .agent-list[b-bpeehdipa3] {
        display: flex;
        flex-wrap: wrap;
        gap: 4px;
        padding: 8px;
    }

    .agent-list li[b-bpeehdipa3] { flex: 1 1 220px; }

    .agent-item[b-bpeehdipa3] {
        border-radius: var(--radius-md);
    }
}

/* Las reglas (las del negocio y las de escalado) se editan con RuleListEditor, que se trajo su
   propio CSS: el markup dejó de estar acá y las tres listas del panel tienen que verse iguales. */

@media (max-width: 600px) {
    /* .form-row pone label y control lado a lado. Con 328px útiles el control
       queda en una franja donde no entra ni su propio texto. */
    .form-row[b-bpeehdipa3] {
        flex-direction: column;
        align-items: stretch;
        gap: 0.6rem;
    }

    /* Guardar a ancho completo y abajo de todo: es la acción de la pantalla. */
    .save-row[b-bpeehdipa3] {
        flex-direction: column-reverse;
        align-items: stretch;
        gap: 0.75rem;
    }

    .save-row[b-bpeehdipa3]  .app-btn { width: 100%; }

    .save-success[b-bpeehdipa3] { text-align: center; }

    /* Una sola columna: dos ítems de 220px no entran, y `flex: 1 1 220px`
       los dejaría estirados a la mitad del ancho con el nombre cortado. */
    .agent-list li[b-bpeehdipa3] { flex: 1 1 100%; }
}
/* /Components/Pages/AnalyticsPage.razor.rz.scp.css */
/* ---- Sections ---- */
.an-section[b-qnr0t1lrlf] {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--ink);
    margin: 2rem 0 1rem;
}

/* The first section heading sits right under the PageHeader, which already spaces
   itself; the 2rem above is for the gap between sections, not for the top. */
.an-section:first-child[b-qnr0t1lrlf] {
    margin-top: 0;
}

.an-grid[b-qnr0t1lrlf] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: 1rem;
}

/* ::deep + .app-card because <Card> renders its own root div outside this
   page's isolation scope — see the note in CatalogPage.razor.css. */
[b-qnr0t1lrlf] .app-card.an-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 1.1rem 1.25rem;
}

[b-qnr0t1lrlf] .app-card.an-card--accent { border-color: var(--brand-line); }

.an-label[b-qnr0t1lrlf] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

.an-value[b-qnr0t1lrlf] {
    font-size: var(--text-4xl);
    font-weight: 600;
    color: var(--ink);
    line-height: 1.15;
    letter-spacing: -0.01em;
}

.an-sub[b-qnr0t1lrlf] {
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

.an-two[b-qnr0t1lrlf] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: 1rem;
    margin-top: 1rem;
}

[b-qnr0t1lrlf] .app-card.an-panel {
    padding: 1.25rem;
}

/* A panel that follows a grid of stat cards directly. The grids space their own
   children but nothing spaces what comes after them, so the panel would sit
   flush against the row above it. */
[b-qnr0t1lrlf] .an-grid + .app-card.an-panel {
    margin-top: 1rem;
}

.an-panel-title[b-qnr0t1lrlf] {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 600;
    color: var(--ink);
    margin: 0 0 4px;
}

.an-panel-sub[b-qnr0t1lrlf] {
    margin: 0 0 1rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

.an-empty[b-qnr0t1lrlf] {
    margin: 0;
    padding: 1.5rem 0;
    text-align: center;
    font-size: var(--text-base);
    color: var(--ink-muted);
}

.an-note[b-qnr0t1lrlf] {
    margin: 1rem 0 0;
    font-size: var(--text-base);
    color: var(--ink-muted);
    max-width: 60ch;
}

.an-footnote[b-qnr0t1lrlf] {
    margin: 1.5rem 0 0;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

/* ---- Tables -------------------------------------------------------------
   The scroll container is on the wrapper, not the table: at 360px a wide table
   has to scroll inside its card, never take the whole page sideways with it.
   The negative margin lets the scrolled edge reach the card's own padding, so a
   half-visible column doesn't look clipped by an invisible boundary. */
.an-table-scroll[b-qnr0t1lrlf] {
    overflow-x: auto;
    margin: 0 -1.25rem;
    padding: 0 1.25rem;
}

.an-table[b-qnr0t1lrlf] {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-base);
}

.an-table th[b-qnr0t1lrlf] {
    text-align: left;
    font-weight: 500;
    color: var(--ink-muted);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 8px 12px;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}

.an-table td[b-qnr0t1lrlf] {
    padding: 12px;
    border-bottom: 1px solid var(--line);
    color: var(--ink);
}

.an-table tbody tr:last-child td[b-qnr0t1lrlf] {
    border-bottom: none;
}

.an-num[b-qnr0t1lrlf] {
    text-align: right;
    white-space: nowrap;
}

.an-link[b-qnr0t1lrlf] {
    color: inherit;
    text-decoration: none;
}

.an-link:hover[b-qnr0t1lrlf] {
    text-decoration: underline;
}

/* Realineado de 700px al breakpoint estándar de teléfono — ver la tabla de
   breakpoints en app.css. */
@media (max-width: 600px) {
    [b-qnr0t1lrlf] .app-card.an-panel { padding: 1rem; }

    .an-table-scroll[b-qnr0t1lrlf] {
        margin: 0 -1rem;
        padding: 0 1rem;
    }
}
/* /Components/Pages/BusinessesPage.razor.rz.scp.css */
.businesses-grid[b-cz40qkvtyx] {
    display: grid;
    /* min() para que el piso ceda cuando el contenedor es más angosto que él
       — ver la nota en Home.razor.css. */
    grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

/* ::deep + .app-card because <Card> renders its own root div outside this
   page's isolation scope — see the note in CatalogPage.razor.css. */
[b-cz40qkvtyx] .app-card.biz-card {
    padding: 1.25rem;
}

.biz-header[b-cz40qkvtyx] {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
}

.biz-avatar[b-cz40qkvtyx] {
    width: 42px;
    height: 42px;
    border-radius: 12px;
    background: var(--brand);
    color: var(--on-brand);
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.biz-info[b-cz40qkvtyx] {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.biz-name[b-cz40qkvtyx] {
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--ink);
}

.biz-vertical[b-cz40qkvtyx] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

.biz-meta[b-cz40qkvtyx] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.biz-currency[b-cz40qkvtyx] {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
    background: var(--surface-hover);
    padding: 2px 8px;
    border-radius: var(--radius-sm);
}

[b-cz40qkvtyx] .app-card.create-card {
    max-width: 560px;
}

.section-title[b-cz40qkvtyx] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 1rem;
}

.form-grid[b-cz40qkvtyx] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1rem;
}

.form-error[b-cz40qkvtyx] {
    font-size: var(--text-base);
    color: var(--status-red);
    background: var(--status-red-bg);
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
}

/* En el teléfono el botón de guardar ocupa el ancho: alineado a la derecha en
   una columna angosta queda contra el borde y a un dedo de distancia del
   scroll. Misma decisión en AgentPage y UsersPage. */
@media (max-width: 600px) {
    .form-actions[b-cz40qkvtyx]  .app-btn { width: 100%; }

    [b-cz40qkvtyx] .app-card.biz-card { padding: 1rem; }
}

.form-actions[b-cz40qkvtyx] {
    display: flex;
    justify-content: flex-end;
}
/* /Components/Pages/CatalogPage.razor.rz.scp.css */
/* <Card> renders its own <div>, so this page's CSS-isolation scope is never
   stamped on it and a bare `.conn-card {}` matches nothing — every rule aimed
   at a Card root has to reach through with ::deep. The extra `.app-card` is
   what outranks Card.razor.css's own padding, which is bundled after this file
   and would otherwise win on equal specificity. Same shape on every page. */
[b-0cfb8thiny] .app-card.conn-card {
    margin-bottom: 1.75rem;
}

.conn-header[b-0cfb8thiny] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.conn-info[b-0cfb8thiny] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.conn-label[b-0cfb8thiny] {
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--ink);
}

.conn-meta[b-0cfb8thiny] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.conn-sync[b-0cfb8thiny] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

.connect-link[b-0cfb8thiny] {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--brand-text);
    text-decoration: none;
    background: none;
    border: none;
    padding: 0;
    font-family: inherit;
    cursor: pointer;
}

.connect-link:hover[b-0cfb8thiny] { color: var(--brand-hover); }

.sync-notice[b-0cfb8thiny] {
    margin-top: 10px;
    font-size: var(--text-sm);
    color: var(--status-green);
    background: var(--status-green-bg);
    padding: 8px 12px;
    border-radius: var(--radius-sm);
}

/* The table draws its own edge-to-edge rows and the header carries its own
   inset, so the card must not add a second one around them. */
[b-0cfb8thiny] .app-card.products-card {
    padding: 0;
}

.products-header[b-0cfb8thiny] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.5rem;
    border-bottom: 1px solid var(--line);
}

.search-wrap[b-0cfb8thiny] {
    position: relative;
    flex: 0 1 380px;
}

.search-icon[b-0cfb8thiny] {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--ink-muted);
    pointer-events: none;
}

.search-wrap[b-0cfb8thiny]  .search-input {
    padding-left: 34px;
}

.products-count[b-0cfb8thiny] {
    font-size: var(--text-sm);
    color: var(--ink-muted);
    white-space: nowrap;
    flex-shrink: 0;
}

.products-table-wrap[b-0cfb8thiny] {
    overflow-x: auto;
}

.products-table[b-0cfb8thiny] {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-md);
}

.products-table th[b-0cfb8thiny] {
    padding: 10px 16px;
    text-align: left;
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 1px solid var(--line);
    background: var(--paper);
    position: sticky;
    top: 0;
    z-index: 1;
}

.products-table td[b-0cfb8thiny] {
    padding: 10px 16px;
    border-bottom: 1px solid var(--line);
    color: var(--ink);
    vertical-align: middle;
}

.products-table tr:last-child td[b-0cfb8thiny] { border-bottom: none; }
.products-table tr:hover td[b-0cfb8thiny] { background: var(--paper); }

.products-table th.num[b-0cfb8thiny],
.products-table td.num[b-0cfb8thiny] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.col-product[b-0cfb8thiny] {
    min-width: 260px;
}

.product-cell[b-0cfb8thiny] {
    display: flex;
    align-items: center;
    gap: 12px;
}

.product-thumb[b-0cfb8thiny] {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    border: 1px solid var(--line);
    background: var(--surface-hover);
    object-fit: cover;
    flex-shrink: 0;
}

.product-thumb--empty[b-0cfb8thiny] {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-muted);
}

.product-cell-text[b-0cfb8thiny] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.product-name[b-0cfb8thiny] {
    font-weight: 600;
    color: var(--ink);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.product-brand[b-0cfb8thiny] {
    font-size: var(--text-sm);
    color: var(--ink-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.category-chip[b-0cfb8thiny] {
    display: inline-block;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--category);
    background: var(--category-soft);
    border: 1px solid var(--category-line);
    padding: 2px 10px;
    border-radius: 999px;
    white-space: nowrap;
}

.product-price[b-0cfb8thiny] {
    font-weight: 600;
    color: var(--ink);
}

.stock-out[b-0cfb8thiny] {
    color: var(--status-red);
    font-weight: 600;
}

.stock-low[b-0cfb8thiny] {
    color: var(--status-amber);
    font-weight: 600;
}

.dim[b-0cfb8thiny] { color: var(--ink-soft); }

.product-row[b-0cfb8thiny] { cursor: pointer; transition: background var(--transition-fast); }
.product-row:hover[b-0cfb8thiny] { background: var(--surface-hover); }

/* Keeps the row highlighted while the link inside it holds focus, so keyboard
   and mouse land on the same visual state. */
.product-row:focus-within[b-0cfb8thiny] { background: var(--surface-hover); }

/* ---- Responsive ---------------------------------------------------------
   La estructura de tarjetas la pone .table-cards en app.css. Lo que queda acá
   es lo que .table-cards NO puede ganar: Blazor le estampa el atributo de
   scope a estas reglas (`.products-table td` → `.products-table td[b-x1y2]`),
   así que en padding, borde y alineación le ganan por especificidad Y por
   orden de carga a cualquier selector global. Todo lo demás (display, las
   etiquetas ::before, el marco de la tarjeta) lo resuelve la utilidad. */
@media (max-width: 600px) {
    .products-header[b-0cfb8thiny] {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
        padding: 1rem;
    }

    .search-wrap[b-0cfb8thiny] { flex: 1 1 auto; }

    .products-count[b-0cfb8thiny] { align-self: flex-start; }

    /* Ya no hay nada que desplazar de costado. */
    .products-table-wrap[b-0cfb8thiny] { overflow-x: visible; }

    /* El piso de 260px era para que el nombre no se estrangulara entre otras
       cinco columnas; apilada, la celda es la fila entera. */
    .col-product[b-0cfb8thiny] { min-width: 0; }

    .products-table td[b-0cfb8thiny] {
        padding: 4px 0;
        border-bottom: none;
    }

    /* Celda héroe: encabeza la tarjeta y la separa del resto. La línea va acá
       y no en .table-cards porque la regla de arriba ya apagó el borde de
       todos los td con la especificidad del scope. */
    .products-table td.col-product[b-0cfb8thiny] {
        padding: 0 0 8px;
        margin-bottom: 4px;
        border-bottom: 1px solid var(--line-soft);
    }

    .products-table td.num[b-0cfb8thiny] { text-align: left; }

    /* El hover pinta la tarjeta, no cada línea suelta de adentro. */
    .products-table tr:hover td[b-0cfb8thiny] { background: transparent; }
}
/* /Components/Pages/ChannelsPage.razor.rz.scp.css */
.channels-page[b-ofgo56ldoj] {
    display: flex;
    flex-direction: column;
    gap: 1.75rem;
}

.section-eyebrow[b-ofgo56ldoj] {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 1rem;
}

.channels-section .section-eyebrow[b-ofgo56ldoj] {
    margin-bottom: 0.75rem;
}

.channels-list[b-ofgo56ldoj] {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}

/* ::deep + .app-card because <Card> renders its own root div outside this
   page's isolation scope — see the note in CatalogPage.razor.css. */
[b-ofgo56ldoj] .app-card.channel-card {
    padding: 1.1rem 1.35rem;
    transition: border-color var(--transition), box-shadow var(--transition);
}

[b-ofgo56ldoj] .app-card.channel-card:hover {
    border-color: var(--brand-line);
    box-shadow: var(--shadow-md);
}

.channel-row[b-ofgo56ldoj] {
    display: flex;
    align-items: center;
    gap: 16px;
}

.channel-icon[b-ofgo56ldoj] {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.channel-icon--live[b-ofgo56ldoj] {
    background: var(--status-green-bg);
    color: var(--status-green);
}

.channel-icon--test[b-ofgo56ldoj] {
    background: var(--accent2-soft);
    color: var(--accent2-hover);
}

.channel-info[b-ofgo56ldoj] {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.channel-info-top[b-ofgo56ldoj] {
    display: flex;
    align-items: baseline;
    gap: 9px;
    flex-wrap: wrap;
}

.channel-phone[b-ofgo56ldoj] {
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--ink);
}

.channel-type-tag[b-ofgo56ldoj] {
    font-size: var(--text-2xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--status-green);
}

.channel-type-tag--test[b-ofgo56ldoj] {
    color: var(--accent2-hover);
}

.channel-waba[b-ofgo56ldoj] {
    font-size: var(--text-sm);
    color: var(--ink-muted);
    font-family: monospace;
}

.channel-meta[b-ofgo56ldoj] {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-shrink: 0;
    padding-left: 16px;
    border-left: 1px solid var(--line);
}

.channel-agent-field[b-ofgo56ldoj] {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.channel-meta-label[b-ofgo56ldoj] {
    font-size: var(--text-2xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ink-muted);
}

[b-ofgo56ldoj] .app-card.webhook-card {
    background: var(--paper);
}

.webhook-url[b-ofgo56ldoj] {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 10px 14px;
    margin-bottom: 8px;
}

.webhook-code[b-ofgo56ldoj] {
    font-size: var(--text-base);
    color: var(--brand-text);
    font-family: monospace;
}

.webhook-hint[b-ofgo56ldoj] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
    margin: 0;
}

[b-ofgo56ldoj] .app-card.add-card {
    max-width: 560px;
}

.form-grid[b-ofgo56ldoj] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1rem;
}

.form-error[b-ofgo56ldoj] {
    font-size: var(--text-base);
    color: var(--status-red);
    background: var(--status-red-bg);
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
}

.form-success[b-ofgo56ldoj] {
    font-size: var(--text-base);
    color: var(--status-green);
    background: var(--status-green-bg);
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
}

.form-warning[b-ofgo56ldoj] {
    font-size: var(--text-base);
    color: var(--status-amber);
    background: var(--status-amber-bg);
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
}

.form-actions[b-ofgo56ldoj] {
    display: flex;
    justify-content: flex-end;
}

/* Realineado de 720px al breakpoint estándar de teléfono — ver la tabla de
   breakpoints en app.css. El ícono y los datos del canal se quedan en una
   fila; lo que baja es el bloque de la derecha, que es el que no entra. */
@media (max-width: 600px) {
    .channel-row[b-ofgo56ldoj] {
        flex-wrap: wrap;
        gap: 12px;
    }

    .channel-meta[b-ofgo56ldoj] {
        width: 100%;
        border-left: none;
        /* 52px = 40 del ícono + 12 del gap: alinea con el texto del canal en
           vez de volver al margen de la tarjeta. */
        padding-left: 52px;
        padding-top: 4px;
    }

    /* El webhook es una URL sin espacios: sin esto estira la tarjeta entera. */
    .webhook-code[b-ofgo56ldoj] { overflow-wrap: anywhere; }

    .webhook-url[b-ofgo56ldoj] { padding: 10px 12px; }
}
/* /Components/Pages/Conversations.razor.rz.scp.css */
.conv-layout[b-5ma7dah5tt] {
    display: flex;
    height: calc(100vh - var(--topbar-height));
    height: calc(100dvh - var(--topbar-height));
    gap: 0;
    /* Cancela el padding de .page-content para que el hilo llegue de borde a
       borde. Ambos lados leen los mismos tokens, así que ya no hay nada que
       "mantener en sync": cambiar el padding de página lo mueve solo. */
    margin: calc(-1 * var(--page-pad-y)) calc(-1 * var(--page-pad-x));
    overflow: hidden;
}

/* ---- Left panel: conversation list ---- */
.conv-sidebar[b-5ma7dah5tt] {
    width: 360px;
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.conv-sidebar-header[b-5ma7dah5tt] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 67px;
    padding: 0 1.4rem;
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
}

.conv-sidebar-title[b-5ma7dah5tt] {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--ink);
}

.conv-count[b-5ma7dah5tt] {
    background: var(--brand-soft);
    color: var(--brand-text);
    font-size: var(--text-sm);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    padding: 3px 11px;
    border-radius: 999px;
}

.conv-list[b-5ma7dah5tt] {
    flex: 1;
    overflow-y: auto;
    padding-bottom: 8px;
}

/* ---- Right panel: thread ---- */
.conv-main[b-5ma7dah5tt] {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: var(--paper);
    overflow: hidden;
    min-width: 0;
}

.conv-empty[b-5ma7dah5tt] {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Thread header */
.thread-header[b-5ma7dah5tt] {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    height: 67px;
    padding: 0 1.5rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-shrink: 0;
}

.thread-header--human[b-5ma7dah5tt] { box-shadow: inset 4px 0 0 var(--coral); }

/* La IA pidió que alguien mire esta conversación. Franja informativa, no una alerta: el bot
   sigue atendiendo, así que no hay nada roto que arreglar ya mismo. */
.thread-attention[b-5ma7dah5tt] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.625rem 1.5rem;
    background: var(--status-amber-bg);
    border-bottom: 1px solid var(--line);
    font-size: 0.8125rem;
    flex-shrink: 0;
}

.thread-attention-title[b-5ma7dah5tt] {
    font-weight: 650;
    /* Token, no un hex: el literal que estaba acá quedaba ilegible en tema oscuro. */
    color: var(--status-amber);
}

.thread-attention-reason[b-5ma7dah5tt] { color: var(--ink-soft); }

.thread-contact[b-5ma7dah5tt] {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.thread-avatar[b-5ma7dah5tt] {
    width: 40px;
    height: 40px;
    border-radius: 12px;
    background: var(--brand);
    color: var(--on-brand);
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.thread-info[b-5ma7dah5tt] {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.thread-name[b-5ma7dah5tt] {
    font-size: var(--text-xl);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--ink);
}

.thread-phone[b-5ma7dah5tt] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

.thread-location[b-5ma7dah5tt] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
    text-decoration: none;
}

.thread-location:hover[b-5ma7dah5tt] {
    color: var(--ink);
    text-decoration: underline;
}

/* Drive-state indicator — who is holding the conversation */
.drive-state[b-5ma7dah5tt] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    padding: 6px 13px;
    border-radius: 999px;
    font-size: var(--text-sm);
    font-weight: 600;
}

.drive-dot[b-5ma7dah5tt] {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}

.drive-state--ai[b-5ma7dah5tt] {
    background: var(--brand-soft);
    color: var(--brand-text);
}
.drive-state--ai .drive-dot[b-5ma7dah5tt] {
    background: var(--brand);
    animation: pulse-dot-b-5ma7dah5tt 2s infinite;
}

.drive-state--human[b-5ma7dah5tt] {
    background: var(--coral-soft);
    color: var(--coral-deep);
}
.drive-state--human .drive-dot[b-5ma7dah5tt] { background: var(--coral); }

@keyframes pulse-dot-b-5ma7dah5tt {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.4; transform: scale(0.8); }
}

.thread-actions[b-5ma7dah5tt] {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-shrink: 0;
}

/* Messages canvas */
.thread-messages[b-5ma7dah5tt] {
    flex: 1;
    overflow-y: auto;
    padding: 1.75rem 2rem;
    display: flex;
    flex-direction: column;
    scroll-behavior: smooth;
}

/* Composer */
.thread-composer[b-5ma7dah5tt] {
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding: 13px 1.5rem;
    display: flex;
    align-items: flex-end;
    gap: 11px;
    flex-shrink: 0;
    transition: box-shadow var(--transition);
}

.thread-composer--human[b-5ma7dah5tt] { box-shadow: inset 4px 0 0 var(--coral); }

.composer-input[b-5ma7dah5tt] {
    flex: 1;
    padding: 11px 14px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    font-family: var(--font);
    font-size: var(--text-lg);
    color: var(--ink);
    outline: none;
    resize: none;
    transition: border-color var(--transition), box-shadow var(--transition);
    line-height: 1.5;
}

.composer-input:focus[b-5ma7dah5tt] {
    border-color: var(--brand-line);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.thread-composer--human .composer-input:focus[b-5ma7dah5tt] {
    border-color: var(--coral-line);
    box-shadow: 0 0 0 3px var(--coral-soft);
}

.composer-input[b-5ma7dah5tt]::placeholder { color: var(--ink-muted); }

/* Reaction failures surface here rather than in a toast: the cause is usually
   per-message (no wamid yet, Meta rejected it), so it belongs next to the thread. */
.thread-reaction-error[b-5ma7dah5tt] {
    margin: 0 16px 8px;
    padding: 8px 12px;
    font-size: var(--text-base);
    color: var(--status-red);
    background: var(--status-red-bg);
    border-radius: var(--radius-sm);
}

/* ---- Responsive ---------------------------------------------------------
   The composer needs horizontal room more than the list does, so below the
   tablet breakpoint the list stops being a column and becomes a drawer that
   slides over the thread. Los márgenes ya no se repiten acá: .conv-layout
   niega los tokens --page-pad-*, que cambian solos en cada breakpoint. */
@media (max-width: 1100px) {
    .conv-sidebar[b-5ma7dah5tt] { width: 320px; }
}

/* Abajo del breakpoint esto deja de ser dos columnas y pasa a ser maestro y
   detalle: una pantalla a la vez.

   - Sin hilo abierto, la LISTA es la pantalla. Es lo que se espera al entrar a
     "Conversaciones": ver las conversaciones. Antes se entraba a un panel
     vacío que decía "elegí una" con la lista escondida en un cajón cerrado.
   - Con un hilo abierto se invierte: el hilo ocupa todo y la lista vuelve a
     ser el cajón que abre el botón del encabezado.

   .conv-layout--thread-open lo pone Conversations.razor según haya o no una
   conversación seleccionada. */
@media (max-width: 900px) {
    .conv-layout[b-5ma7dah5tt] { position: relative; }

    .conv-sidebar[b-5ma7dah5tt],
    .conv-main[b-5ma7dah5tt] {
        width: 100%;
    }

    .conv-sidebar[b-5ma7dah5tt] { border-right: none; }

    /* El hilo no existe hasta que se elige uno. */
    .conv-layout:not(.conv-layout--thread-open) .conv-main[b-5ma7dah5tt] { display: none; }

    .conv-layout--thread-open .conv-sidebar[b-5ma7dah5tt] {
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        z-index: 20;
        width: min(340px, 86vw);
        border-right: 1px solid var(--line);
        box-shadow: var(--shadow-lg);
        transform: translateX(-101%);      /* 101% clears the 1px border too */
        /* visibility saca los items de la lista del orden de tabulación
           mientras el cajón está cerrado. Acá había un `:focus-within` que
           lo abría, y tenía el mismo defecto que el del menú principal
           (ver NavMenu.razor.css): elegir una conversación deja el foco en
           ella, así que el cajón se quedaba abierto sobre el hilo que
           acababa de abrirse. */
        visibility: hidden;
        transition: transform var(--transition-slow), visibility var(--transition-slow);
    }

    .conv-layout--thread-open.conv-layout--list-open .conv-sidebar[b-5ma7dah5tt] {
        transform: translateX(0);
        visibility: visible;
    }
}

/* ---- Drawer controls ----------------------------------------------------
   Both are desktop-hidden: above the breakpoint the list is a permanent
   column, so an opener and a scrim would be dead weight. */
.thread-list-toggle[b-5ma7dah5tt],
.conv-scrim[b-5ma7dah5tt] { display: none; }

@media (max-width: 900px) {
    .thread-list-toggle[b-5ma7dah5tt] {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        /* 44px es el mínimo táctil de WCAG 2.5.5. Este botón es la única forma
           de volver a la lista en el teléfono, así que es el peor lugar
           posible para dejar un blanco de 34px. */
        width: 44px;
        height: 44px;
        flex-shrink: 0;
        margin-right: 4px;
        padding: 0;
        border: 1px solid var(--line);
        border-radius: var(--radius-md);
        background: var(--surface);
        color: var(--ink-soft);
        cursor: pointer;
        transition: background var(--transition-fast), color var(--transition-fast);
    }

    .thread-list-toggle:hover[b-5ma7dah5tt] {
        background: var(--surface-hover);
        color: var(--ink);
    }

    .conv-scrim[b-5ma7dah5tt] {
        display: block;
        position: absolute;
        inset: 0;
        z-index: 19;              /* under the drawer (20), over the thread */
        border: none;
        padding: 0;
        background: var(--scrim);
        cursor: pointer;
    }
}

/* ---- Teléfono -----------------------------------------------------------
   El encabezado del hilo tiene cinco cosas en una fila (volver, avatar,
   nombre, quién maneja la conversación, acciones) y en 360px no entran ni
   estrujadas: lo que cede es el nombre del contacto, que queda en dos letras
   al lado de un botón cortado. Pasa a dos filas, y se recorta lo que no
   aporta: el avatar es la inicial del nombre que está justo al lado, y el
   texto de "La IA está respondiendo" es lo que el punto de color ya dice.

   Las acciones se van a la fila de abajo enteras: tomar el control y cerrar
   son decisiones, y una decisión no se toma con un botón a medio leer. */
@media (max-width: 600px) {
    /* Solo cuando la lista es cajón. Sin calificar, este ancho le ganaba al
       100% de la vista maestro y la lista entraba a /conversations ocupando
       340px de los 390 de la pantalla, con una franja muerta al costado. */
    .conv-layout--thread-open .conv-sidebar[b-5ma7dah5tt] { width: min(340px, 92vw); }

    .thread-header[b-5ma7dah5tt] {
        height: auto;
        min-height: 60px;
        flex-wrap: wrap;
        gap: 8px;
        padding: 8px 10px;
    }

    .thread-avatar[b-5ma7dah5tt] { display: none; }

    .thread-contact[b-5ma7dah5tt] {
        flex: 1 1 auto;
        min-width: 0;
        gap: 0;
    }

    .thread-name[b-5ma7dah5tt],
    .thread-phone[b-5ma7dah5tt] {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Solo el punto: el color ya distingue IA (teal) de humano (ámbar), y es
       la misma señal que usa la lista de al lado. */
    .drive-state[b-5ma7dah5tt] {
        gap: 0;
        padding: 6px;
    }

    .drive-label[b-5ma7dah5tt] {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    .thread-actions[b-5ma7dah5tt] {
        width: 100%;
        gap: 8px;
    }

    .thread-actions[b-5ma7dah5tt]  .app-btn { flex: 1; }

    .thread-messages[b-5ma7dah5tt] { padding: 1rem 0.75rem; }

    .thread-composer[b-5ma7dah5tt] { padding: 10px 0.75rem; }

    .thread-window-closed[b-5ma7dah5tt] { margin: 10px 0.75rem; }

    .thread-reaction-error[b-5ma7dah5tt] { margin: 0 0.75rem 8px; }
}

/* ============ Ventana de 24hs de WhatsApp (Meta) cerrada ============ */
/* Sobre tokens ámbar y no sobre hexes propios: los literales que había acá quedaban en ~2,5:1 en
   tema oscuro, o sea el aviso que explica por qué no se puede escribir era el que no se leía. */
.thread-window-closed[b-5ma7dah5tt] {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 12px 16px 16px;
    padding: 12px 14px;
    border-radius: var(--radius-xl);
    border: 1px solid var(--coral-line);
    background: var(--status-amber-bg);
    color: var(--ink);
    font-size: var(--text-base);
    line-height: 1.45;
}

.thread-window-closed svg[b-5ma7dah5tt] {
    flex-shrink: 0;
    margin-top: 2px;
    color: var(--status-amber);
}

.thread-window-closed mark[b-5ma7dah5tt] {
    background: none;
    color: var(--status-amber);
    font-weight: 600;
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* El min() no es adorno: `minmax(240px, 1fr)` a secas es un PISO duro, y
   cuando el ancho disponible es menor a 240px la columna igual mide 240 y se
   sale de la pantalla. `min(240px, 100%)` hace que el piso ceda al contenedor
   cuando el contenedor es más chico. Mismo patrón en todas las grillas. */
.stats-grid[b-imqsbdxijc] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
    gap: 1.25rem;
}

.stat-card[b-imqsbdxijc] {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 1.5rem 1.6rem 1.6rem;
    display: flex;
    flex-direction: column;
    gap: 10px;
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--transition), transform var(--transition);
}

.stat-card:hover[b-imqsbdxijc] {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.stat-card--link[b-imqsbdxijc] {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}

.stat-card--link:hover[b-imqsbdxijc] {
    border-color: var(--brand-text);
}

.stat-card--link:focus-visible[b-imqsbdxijc] {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

/* "Needing human" — coral, the moment a person is required */
.stat-card--alert[b-imqsbdxijc] {
    border-color: var(--coral-line);
    background: linear-gradient(160deg, var(--coral-soft) 0%, var(--surface) 60%);
}

.stat-header[b-imqsbdxijc] {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.stat-label[b-imqsbdxijc] {
    font-size: var(--text-xs);
    font-weight: 700;
    color: var(--ink-soft);
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.stat-icon[b-imqsbdxijc] {
    width: 34px;
    height: 34px;
    border-radius: 11px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.stat-icon--blue[b-imqsbdxijc] { background: var(--surface-hover); color: var(--ink-soft); }
.stat-icon--coral[b-imqsbdxijc] { background: var(--coral-soft); color: var(--coral-deep); }
.stat-icon--green[b-imqsbdxijc] { background: var(--brand-soft); color: var(--brand-text); }
.stat-icon--purple[b-imqsbdxijc] { background: var(--brand-soft); color: var(--brand-text); }

.stat-value[b-imqsbdxijc] {
    font-family: var(--font-display);
    font-size: var(--text-5xl);
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -0.03em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.stat-value--coral[b-imqsbdxijc] { color: var(--coral-deep); }
.stat-value--sm[b-imqsbdxijc] { font-size: var(--text-3xl); letter-spacing: -0.015em; }

.stat-sub[b-imqsbdxijc] {
    font-size: var(--text-base);
    color: var(--ink-soft);
}

/* Skeleton — the bars themselves are <SkeletonBlock>, shared with every other
   loading state in the console. Only the card's own layout lives here. */
.stat-card--skeleton[b-imqsbdxijc] {
    pointer-events: none;
    gap: 10px;
}

/* ---- Responsive --------------------------------------------------------- */
@media (max-width: 600px) {
    .stats-grid[b-imqsbdxijc] { gap: 0.85rem; }

    .stat-card[b-imqsbdxijc] { padding: 1.15rem 1.2rem 1.25rem; }

    /* --text-5xl son 38px: en una tarjeta a ancho de teléfono, un número de
       cuatro cifras se parte en dos líneas. */
    .stat-value[b-imqsbdxijc] { font-size: var(--text-4xl); }
    .stat-value--sm[b-imqsbdxijc] { font-size: var(--text-2xl); }

    /* El realce al pasar por encima no existe en táctil, y el translateY deja
       la tarjeta movida después de tocarla. */
    .stat-card:hover[b-imqsbdxijc] { transform: none; }
}

/* /Components/Pages/KnowledgePage.razor.rz.scp.css */
/* <Card> renders its own <div>, so this page's CSS-isolation scope is never
   stamped on it and a bare `.kb-card {}` matches nothing — every rule aimed
   at a Card root has to reach through with ::deep. The extra `.app-card` is
   what outranks Card.razor.css's own padding, which is bundled after this file
   and would otherwise win on equal specificity. Same shape on every page. */
[b-3vq64ulbwa] .app-card.kb-card {
    margin-bottom: 1.75rem;
}

.kb-error[b-3vq64ulbwa] {
    margin-bottom: 1.25rem;
    padding: 0.75rem 1rem;
    border-radius: var(--radius-md);
    background: var(--danger-soft, rgba(220, 38, 38, 0.1));
    color: var(--status-red);
    font-size: var(--text-md);
}

/* Ámbar y no rojo a propósito: el documento SÍ se guardó. Lo único que falta es
   el indexado, que se reintenta solo. */
.kb-warning[b-3vq64ulbwa] {
    margin-bottom: 1.25rem;
    padding: 0.75rem 1rem;
    border-radius: var(--radius-md);
    background: var(--warning-soft, rgba(217, 119, 6, 0.1));
    color: var(--status-amber, #b45309);
    font-size: var(--text-md);
}

.section-title[b-3vq64ulbwa] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.35rem;
}

.form-grid[b-3vq64ulbwa] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* ── Vista previa de fragmentos ── */

.kb-preview[b-3vq64ulbwa] {
    margin-top: 1rem;
    padding: 0.85rem 1rem;
    border: 1px dashed var(--line);
    border-radius: var(--radius-md);
    background: var(--surface-hover);
}

.kb-preview-head[b-3vq64ulbwa] {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
    margin-bottom: 0.5rem;
}

.kb-preview-list[b-3vq64ulbwa] {
    margin: 0;
    padding-left: 1.35rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.kb-preview-list li[b-3vq64ulbwa] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
    line-height: 1.45;
}

/* ── Lista de documentos ── */

.kb-section-head[b-3vq64ulbwa] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.kb-list[b-3vq64ulbwa] {
    display: flex;
    flex-direction: column;
}

.kb-item[b-3vq64ulbwa] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.9rem 0;
    border-top: 1px solid var(--line);
    flex-wrap: wrap;
}

.kb-item:first-child[b-3vq64ulbwa] {
    border-top: none;
}

.kb-item-main[b-3vq64ulbwa] {
    min-width: 0;
    flex: 1 1 20rem;
}

.kb-item-title[b-3vq64ulbwa] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--ink);
    flex-wrap: wrap;
}

.kb-item-excerpt[b-3vq64ulbwa] {
    margin: 0.3rem 0 0;
    font-size: var(--text-sm);
    color: var(--ink-soft);
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.kb-item-meta[b-3vq64ulbwa] {
    margin-top: 0.35rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

.kb-item-warn[b-3vq64ulbwa] {
    color: var(--status-amber, #b45309);
}

.kb-item-actions[b-3vq64ulbwa],
.kb-item-confirm[b-3vq64ulbwa] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}

.kb-item-confirm[b-3vq64ulbwa] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
    flex-wrap: wrap;
}

/* ── Plantillas del estado vacío ── */

.kb-templates[b-3vq64ulbwa] {
    margin-top: 1rem;
    text-align: center;
}

.kb-templates-head[b-3vq64ulbwa] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
    margin-bottom: 0.6rem;
}

.kb-templates-row[b-3vq64ulbwa] {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.kb-actions[b-3vq64ulbwa] {
    display: flex;
    gap: 0.6rem;
    margin-top: 1.15rem;
}

@media (max-width: 600px) {
    .kb-item-actions[b-3vq64ulbwa],
    .kb-item-confirm[b-3vq64ulbwa] {
        width: 100%;
    }
}
/* /Components/Pages/PerfilPage.razor.rz.scp.css */
.perfil-grid[b-bic8wrrqu7] {
    display: grid;
    grid-template-columns: minmax(0, 380px) minmax(0, 420px);
    gap: 16px;
    align-items: start;
}

@media (max-width: 900px) {
    .perfil-grid[b-bic8wrrqu7] {
        grid-template-columns: 1fr;
    }
}

.perfil-data[b-bic8wrrqu7] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 8px 16px;
    margin: 0;
    font-size: 13px;
}

.perfil-data dt[b-bic8wrrqu7] {
    color: var(--ink-muted);
    font-weight: 600;
}

.perfil-data dd[b-bic8wrrqu7] {
    margin: 0;
}

/* Mismo verde de éxito que el resto del panel, no uno propio de esta página. */
.perfil-ok[b-bic8wrrqu7] {
    background: var(--status-green-bg);
    border: 1px solid var(--status-green);
    color: var(--status-green);
    border-radius: var(--radius-lg);
    padding: 10px 12px;
    font-size: var(--text-base);
    margin-bottom: 12px;
}

.field[b-bic8wrrqu7] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field-label[b-bic8wrrqu7] {
    font-size: 13px;
    font-weight: 600;
}

.field-hint[b-bic8wrrqu7] {
    font-size: 11.5px;
    color: var(--ink-muted);
}

.perfil-input[b-bic8wrrqu7] {
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface);
    color: inherit;
    font-size: 13px;
}

/* .section-title / .form-grid / .form-error / .form-actions NO son globales:
   el markup de arriba las usa, pero como cada página las define en su propio
   CSS aislado, acá no existían y los campos quedaban sin separación con el
   botón pegado al último input. Mismo caso —y mismos valores— que
   UsersPage/BusinessesPage/ChannelsPage. */
.section-title[b-bic8wrrqu7] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 1rem;
}

.form-grid[b-bic8wrrqu7] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1rem;
}

.form-error[b-bic8wrrqu7] {
    font-size: var(--text-base);
    color: var(--status-red);
    background: var(--status-red-bg);
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
}

.form-actions[b-bic8wrrqu7] {
    display: flex;
    justify-content: flex-end;
}

/* ---- Responsive ---------------------------------------------------------
   La grilla ya colapsa a una columna en 900px. Falta lo del teléfono: el
   email de la cuenta no tiene espacios donde cortar y estira la tarjeta, y el
   botón de guardar alineado a la derecha en una columna angosta queda contra
   el borde. Los inputs suben a 16px por la regla anti-zoom de app.css. */
@media (max-width: 600px) {
    .perfil-data dd[b-bic8wrrqu7] { overflow-wrap: anywhere; }

    .form-actions[b-bic8wrrqu7]  .app-btn { width: 100%; }
}
/* /Components/Pages/Playground.razor.rz.scp.css */
/* La página ocupa el alto del área de contenido y reparte: encabezado, barra y
   ayuda toman lo que necesitan, el chat se queda con el resto. Todo lo que se
   resta acá es geometría conocida y no una estimación — la altura del topbar y
   el padding vertical de la página son tokens, no números sueltos. */
.pg-page[b-qxehr1sts0] {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--topbar-height) - 2 * var(--page-pad-y));
    height: calc(100dvh - var(--topbar-height) - 2 * var(--page-pad-y));
}

.pg-toolbar[b-qxehr1sts0] {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.85rem;
    flex-shrink: 0;
}

.pg-agent-pick[b-qxehr1sts0] {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.pg-label[b-qxehr1sts0] {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
}

/* Panel de ubicación de prueba: la única forma de ejercitar find_nearest_branch sin un celular. */
.pg-location[b-qxehr1sts0] {
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 0.85rem;
    margin-bottom: 1rem;
    flex-shrink: 0;
}

.pg-location-row[b-qxehr1sts0] {
    display: flex;
    align-items: flex-end;
    gap: 0.75rem;
}

.pg-location-row > :first-child[b-qxehr1sts0],
.pg-location-row > :nth-child(2)[b-qxehr1sts0] {
    flex: 1;
}

.pg-location-presets[b-qxehr1sts0] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.7rem;
}

.pg-preset[b-qxehr1sts0] {
    border: 1px solid var(--line);
    background: transparent;
    color: var(--ink-soft);
    font-size: var(--text-sm);
    padding: 4px 10px;
    border-radius: 999px;
    cursor: pointer;
}

.pg-preset:hover[b-qxehr1sts0] {
    color: var(--ink);
    border-color: var(--ink-soft);
}

.pg-location-error[b-qxehr1sts0] {
    margin-top: 0.6rem;
    font-size: var(--text-sm);
    color: var(--status-red);
}

@media (max-width: 600px) {
    .pg-location-row[b-qxehr1sts0] {
        flex-direction: column;
        align-items: stretch;
    }
}

.pg-hint[b-qxehr1sts0] {
    background: var(--brand-soft);
    color: var(--brand-text);
    font-size: var(--text-sm);
    padding: 9px 14px;
    border-radius: var(--radius-md);
    margin-bottom: 1rem;
    flex-shrink: 0;
}

.pg-hint code[b-qxehr1sts0] {
    font-family: var(--font-mono, monospace);
    background: rgba(0, 0, 0, 0.06);
    padding: 1px 5px;
    border-radius: 4px;
}

/* Se queda con el alto que sobra de .pg-page. min-height:0 es obligatorio: sin
   él un ítem flex no puede achicarse por debajo del alto de su contenido, y el
   chat volvería a empujar el composer fuera de la pantalla. */
.pg-chat[b-qxehr1sts0] {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg, 14px);
    overflow: hidden;
}

.pg-messages[b-qxehr1sts0] {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 1.5rem 1.75rem;
    display: flex;
    flex-direction: column;
    scroll-behavior: smooth;
}

.pg-placeholder[b-qxehr1sts0] {
    margin: auto;
    color: var(--ink-muted);
    font-size: var(--text-lg);
    text-align: center;
}

/* Typing indicator while the agent's reply is in flight */
.pg-typing[b-qxehr1sts0] {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 11px 14px;
    align-self: flex-start;
}

.pg-typing span[b-qxehr1sts0] {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--brand);
    opacity: 0.5;
    animation: pg-bounce-b-qxehr1sts0 1.2s infinite ease-in-out;
}

.pg-typing span:nth-child(2)[b-qxehr1sts0] { animation-delay: 0.15s; }
.pg-typing span:nth-child(3)[b-qxehr1sts0] { animation-delay: 0.3s; }

@keyframes pg-bounce-b-qxehr1sts0 {
    0%, 80%, 100% { transform: translateY(0); opacity: 0.4; }
    40% { transform: translateY(-4px); opacity: 1; }
}

.pg-composer[b-qxehr1sts0] {
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding: 13px 1.5rem;
    display: flex;
    align-items: flex-end;
    gap: 11px;
    flex-shrink: 0;
}

.pg-input[b-qxehr1sts0] {
    flex: 1;
    padding: 11px 14px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    font-family: var(--font);
    font-size: var(--text-lg);
    color: var(--ink);
    outline: none;
    resize: none;
    line-height: 1.5;
    transition: border-color var(--transition), box-shadow var(--transition);
}

.pg-input:focus[b-qxehr1sts0] {
    border-color: var(--brand-line);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

/* ---- Attachment: button, preview strip, dropzone ---- */
.pg-dropzone[b-qxehr1sts0] {
    position: relative;
    transition: background var(--transition);
}

.pg-dropzone--over[b-qxehr1sts0] {
    background: var(--brand-soft);
    outline: 2px dashed var(--brand-line);
    outline-offset: -5px;
    border-radius: var(--radius-md);
}

.pg-attach[b-qxehr1sts0] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--paper);
    color: var(--ink-soft);
    cursor: pointer;
    flex-shrink: 0;
    align-self: flex-end;
    transition: border-color var(--transition), background var(--transition), color var(--transition);
}

.pg-attach:hover[b-qxehr1sts0] {
    border-color: var(--brand-line);
    background: var(--brand-soft);
    color: var(--brand-text);
}

.pg-attach:focus-within[b-qxehr1sts0] {
    border-color: var(--brand-line);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.pg-attach svg[b-qxehr1sts0] {
    width: 18px;
    height: 18px;
}

/* Keep the native input focusable (visually hidden, not display:none) via ::deep —
   CSS isolation does not reach the InputFile child component. */
.pg-attach[b-qxehr1sts0]  input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Preview strip shown above the composer once an image is attached */
.pg-attachment[b-qxehr1sts0] {
    display: flex;
    align-items: center;
    gap: 11px;
    margin: 0 1.5rem 9px;
    padding: 8px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}

.pg-attachment-thumb[b-qxehr1sts0] {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: 8px;
    flex-shrink: 0;
    border: 1px solid var(--line);
}

.pg-attachment-info[b-qxehr1sts0] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.pg-attachment-name[b-qxehr1sts0] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pg-attachment-hint[b-qxehr1sts0] {
    font-size: var(--text-xs);
    color: var(--ink-muted);
}

.pg-attachment-remove[b-qxehr1sts0] {
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--ink-soft);
    font-size: var(--text-lg);
    line-height: 1;
    padding: 5px 7px;
    border-radius: 7px;
    flex-shrink: 0;
    transition: background var(--transition), color var(--transition);
}

.pg-attachment-remove:hover[b-qxehr1sts0] {
    background: var(--line);
    color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
    .pg-dropzone[b-qxehr1sts0], .pg-attach[b-qxehr1sts0], .pg-attachment-remove[b-qxehr1sts0] { transition: none; }
}

.pg-input[b-qxehr1sts0]::placeholder { color: var(--ink-muted); }

.pg-paused[b-qxehr1sts0] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 11px 1.5rem;
    background: var(--coral-soft);
    color: var(--coral-deep);
    border-top: 1px solid var(--line);
    font-size: var(--text-base);
}

/* ---- Responsive --------------------------------------------------------- */
@media (max-width: 600px) {
    /* El selector de agente y lo que va a su derecha no comparten fila. */
    .pg-toolbar[b-qxehr1sts0] {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }

    .pg-messages[b-qxehr1sts0] { padding: 1rem 0.75rem; }

    .pg-paused[b-qxehr1sts0] {
        flex-direction: column;
        align-items: stretch;
        gap: 0.6rem;
        padding: 11px 0.75rem;
    }
}
/* /Components/Pages/ProductDetailPage.razor.rz.scp.css */
.pd-loading[b-hqnmgucpbl] {
    padding: 3rem;
    text-align: center;
    color: var(--ink-muted);
    font-size: var(--text-lg);
}

.pd-top[b-hqnmgucpbl] {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.pd-back[b-hqnmgucpbl] {
    background: none;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 7px 13px;
    font-family: var(--font);
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition);
}

.pd-back:hover[b-hqnmgucpbl] {
    background: var(--surface);
    border-color: var(--brand-line);
}

/* ::deep + .app-card because <Card> renders its own root div outside this
   page's isolation scope — see the note in CatalogPage.razor.css. */
[b-hqnmgucpbl] .app-card.pd-head {
    margin-bottom: 1.25rem;
}

.pd-head-row[b-hqnmgucpbl] {
    display: flex;
    gap: 1.25rem;
    align-items: flex-start;
}

.pd-img[b-hqnmgucpbl] {
    width: 96px;
    height: 96px;
    border-radius: var(--radius-md);
    object-fit: cover;
    border: 1px solid var(--line);
    flex-shrink: 0;
}

.pd-head-info[b-hqnmgucpbl] {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}

.pd-name[b-hqnmgucpbl] {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--ink);
    line-height: 1.2;
}

.pd-meta[b-hqnmgucpbl] {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
}

.pd-chip[b-hqnmgucpbl] {
    background: var(--brand-soft);
    color: var(--brand-text);
    font-size: var(--text-sm);
    font-weight: 600;
    padding: 3px 10px;
    border-radius: 999px;
}

.pd-link[b-hqnmgucpbl] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--brand-text);
    text-decoration: none;
    width: fit-content;
}

.pd-link:hover[b-hqnmgucpbl] { text-decoration: underline; }

[b-hqnmgucpbl] .app-card.pd-section {
    margin-bottom: 1.25rem;
}

[b-hqnmgucpbl] .app-card.pd-section:last-child {
    margin-bottom: 0;
}

.pd-section-title[b-hqnmgucpbl] {
    font-size: var(--text-base);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ink-soft);
    margin-bottom: 0.85rem;
}

.pd-description[b-hqnmgucpbl] {
    font-size: var(--text-lg);
    line-height: 1.6;
    color: var(--ink);
    word-break: break-word;
}

.pd-description :deep(img)[b-hqnmgucpbl] { max-width: 100%; height: auto; border-radius: 8px; }
.pd-description :deep(p)[b-hqnmgucpbl] { margin: 0 0 0.6rem; }
.pd-description :deep(a)[b-hqnmgucpbl] { color: var(--brand-text); }

.pd-attrs[b-hqnmgucpbl] {
    display: grid;
    /* min() para que el piso ceda cuando el contenedor es más angosto que él
       — ver la nota en Home.razor.css. */
    grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
    gap: 10px;
}

.pd-attr[b-hqnmgucpbl] {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 9px 12px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}

.pd-attr-k[b-hqnmgucpbl] {
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--ink-muted);
}

.pd-attr-v[b-hqnmgucpbl] {
    font-size: var(--text-lg);
    color: var(--ink);
}

.pd-empty-variants[b-hqnmgucpbl] {
    color: var(--ink-muted);
    font-size: var(--text-lg);
}

.pd-table-wrap[b-hqnmgucpbl] { overflow-x: auto; }

.pd-table[b-hqnmgucpbl] {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-lg);
}

.pd-table th[b-hqnmgucpbl] {
    text-align: left;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
    padding: 8px 12px;
    border-bottom: 1px solid var(--line);
}

.pd-table td[b-hqnmgucpbl] {
    padding: 11px 12px;
    border-bottom: 1px solid var(--line);
    color: var(--ink);
}

.pd-table tr:last-child td[b-hqnmgucpbl] { border-bottom: none; }

.pd-table .num[b-hqnmgucpbl] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.pd-table .dim[b-hqnmgucpbl] { color: var(--ink-soft); }

.pd-footer[b-hqnmgucpbl] {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    padding: 0.5rem 0.25rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

/* ---- Responsive ---------------------------------------------------------
   Ver la nota de CatalogPage.razor.css: la estructura de tarjetas la pone
   .table-cards en app.css, y acá va solo lo que el scope de Blazor le gana
   por especificidad. */
@media (max-width: 600px) {
    /* La ficha se lee de arriba abajo: foto, después nombre y chips. */
    .pd-head-row[b-hqnmgucpbl] {
        flex-direction: column;
        gap: 1rem;
    }

    .pd-img[b-hqnmgucpbl] {
        width: 72px;
        height: 72px;
    }

    .pd-name[b-hqnmgucpbl] { font-size: var(--text-2xl); }

    .pd-table-wrap[b-hqnmgucpbl] { overflow-x: visible; }

    .pd-table td[b-hqnmgucpbl] {
        padding: 4px 0;
        border-bottom: none;
    }

    /* Celda héroe: la variante encabeza su tarjeta. Es el único td sin
       data-label, que es como .table-cards distingue una de otra. */
    .pd-table td:not([data-label])[b-hqnmgucpbl] {
        padding: 0 0 8px;
        margin-bottom: 4px;
        border-bottom: 1px solid var(--line-soft);
        font-weight: 600;
    }

    .pd-table .num[b-hqnmgucpbl] { text-align: left; }

    .pd-footer[b-hqnmgucpbl] { gap: 0.5rem; flex-direction: column; }
}
/* /Components/Pages/ReturnsPage.razor.rz.scp.css */
/* <Card> renders its own <div>, so this page's CSS-isolation scope is never
   stamped on it and a bare `.ret-card {}` matches nothing — every rule aimed
   at a Card root has to reach through with ::deep. The extra `.app-card` is
   what outranks Card.razor.css's own padding, which is bundled after this file
   and would otherwise win on equal specificity. Same shape on every page. */
[b-lds40neixt] .app-card.ret-card {
    margin-bottom: 1.75rem;
}

.ret-error[b-lds40neixt] {
    margin-bottom: 1.25rem;
    padding: 0.75rem 1rem;
    border-radius: var(--radius-md);
    background: var(--danger-soft, rgba(220, 38, 38, 0.1));
    color: var(--status-red);
    font-size: var(--text-md);
}

.ret-section-head[b-lds40neixt] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.section-title[b-lds40neixt] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.35rem;
}

.ret-hint[b-lds40neixt] {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--ink-soft);
    max-width: 62ch;
    line-height: 1.5;
}

.form-grid[b-lds40neixt] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.ret-field[b-lds40neixt] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.ret-label[b-lds40neixt] {
    font-size: var(--text-md);
    font-weight: 500;
    color: var(--ink-soft);
}

.ret-checks[b-lds40neixt] {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
}

/* Los grupos de campos cortos van en fila y se apilan en pantallas chicas: los
   breakpoints son los mismos 600/900/1100 que usa el resto del panel. */
.ret-row[b-lds40neixt] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    align-items: end;
}

.ret-coords[b-lds40neixt] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.ret-coords > :first-child[b-lds40neixt] {
    flex: 1;
}

.ret-verify[b-lds40neixt] {
    font-size: var(--text-sm);
    color: var(--brand-text);
    text-decoration: none;
    padding-bottom: 0.6rem;
    white-space: nowrap;
}

.ret-verify:hover[b-lds40neixt] {
    text-decoration: underline;
}

.ret-actions[b-lds40neixt] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 1.25rem;
}

.ret-saved[b-lds40neixt] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

.ret-branch-form[b-lds40neixt] {
    padding: 1rem;
    margin-bottom: 1.25rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}

.ret-branches[b-lds40neixt] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.ret-branch[b-lds40neixt] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}

.ret-branch--off[b-lds40neixt] {
    opacity: 0.6;
}

.ret-branch-main[b-lds40neixt] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.ret-branch-name[b-lds40neixt] {
    font-weight: 600;
    color: var(--ink);
}

.ret-branch-address[b-lds40neixt],
.ret-branch-hours[b-lds40neixt] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

.ret-branch-side[b-lds40neixt] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}

@media (max-width: 900px) {
    .ret-row[b-lds40neixt] {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 600px) {
    .ret-row[b-lds40neixt],
    .ret-coords[b-lds40neixt] {
        grid-template-columns: 1fr;
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }

    .ret-section-head[b-lds40neixt] {
        flex-direction: column;
        align-items: stretch;
    }

    .ret-branch[b-lds40neixt] {
        flex-direction: column;
        align-items: flex-start;
    }
}
/* /Components/Pages/UsersPage.razor.rz.scp.css */
.users-grid[b-u04w46f1rq] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 16px;
    align-items: start;
}

@media (max-width: 1100px) {
    .users-grid[b-u04w46f1rq] {
        grid-template-columns: 1fr;
    }
}

.users-tbl[b-u04w46f1rq] {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm, 13px);
}

.users-tbl th[b-u04w46f1rq] {
    text-align: left;
    padding: 8px 12px;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--ink-muted);
    border-bottom: 1px solid var(--line);
}

.users-tbl td[b-u04w46f1rq] {
    padding: 10px 12px;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}

.users-tbl tbody tr:last-child td[b-u04w46f1rq] {
    border-bottom: none;
}

.u-name[b-u04w46f1rq] {
    display: block;
    font-weight: 600;
}

.u-email[b-u04w46f1rq] {
    display: block;
    font-size: 12px;
    color: var(--ink-muted);
}

.u-role[b-u04w46f1rq] {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 12px;
    border: 1px solid var(--line);
    color: var(--ink-muted);
}

/* Los tres colores de esta tabla eran hexes propios (un dorado, un verde y un rojo inventados acá),
   así que no cambiaban con el tema y no coincidían con los mismos estados en el resto del panel. */
.u-role--admin[b-u04w46f1rq] {
    border-color: var(--coral-line);
    color: var(--status-amber);
}

.u-state[b-u04w46f1rq] {
    font-size: var(--text-xs);
    font-weight: 600;
}

.u-state--active[b-u04w46f1rq] {
    color: var(--status-green);
}

.u-state--locked[b-u04w46f1rq] {
    color: var(--status-red);
}

.u-date[b-u04w46f1rq] {
    font-size: 12px;
    color: var(--ink-muted);
    white-space: nowrap;
}

.u-actions[b-u04w46f1rq] {
    white-space: nowrap;
    text-align: right;
}

.u-actions[b-u04w46f1rq]  .app-btn + .app-btn {
    margin-left: 4px;
}

/* .section-title / .form-grid / .form-error / .form-actions no son globales:
   cada página las define en su propio CSS aislado (ver BusinessesPage/ChannelsPage).
   Sin esto el formulario queda sin separación entre campos y el botón pegado al
   último control. */
.section-title[b-u04w46f1rq] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.5rem;
}

.form-grid[b-u04w46f1rq] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1rem;
}

.form-error[b-u04w46f1rq] {
    font-size: var(--text-base);
    color: var(--status-red);
    background: var(--status-red-bg);
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
}

.form-actions[b-u04w46f1rq] {
    display: flex;
    justify-content: flex-end;
}

.users-form-hint[b-u04w46f1rq] {
    font-size: 13px;
    color: var(--ink-muted);
    margin: 0 0 1rem;
    line-height: 1.5;
}

.cred-banner[b-u04w46f1rq] {
    background: #1a9e6c14;
    border: 1px dashed #1a9e6c88;
    border-radius: 8px;
    padding: 10px 12px;
    font-size: 13px;
    margin-bottom: 12px;
}

.cred-email[b-u04w46f1rq] {
    font-family: var(--font-mono, monospace);
    font-size: 12px;
}

.cred-pwd[b-u04w46f1rq] {
    display: block;
    margin-top: 6px;
    padding: 8px 10px;
    border-radius: 6px;
    background: var(--surface);
    border: 1px solid var(--line);
    font-family: var(--font-mono, monospace);
    font-size: 13px;
    letter-spacing: .02em;
    user-select: all;
    word-break: break-all;
}

.field[b-u04w46f1rq] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* Mismos valores que el label de AppTextField, para que "Rol" no desentone
   con "Nombre"/"Email" (los de AppTextField viven en su propio CSS aislado). */
.field-label[b-u04w46f1rq] {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--ink);
}

/* ---- Responsive ---------------------------------------------------------
   Ver la nota de CatalogPage.razor.css: la estructura de tarjetas la pone
   .table-cards en app.css, y acá va solo lo que el scope de Blazor le gana
   por especificidad. */
@media (max-width: 600px) {
    .users-tbl td[b-u04w46f1rq] {
        padding: 4px 0;
        border-bottom: none;
    }

    /* Celda héroe: nombre + email encabezan la tarjeta. */
    .users-tbl td:not([data-label]):first-child[b-u04w46f1rq] {
        padding: 0 0 8px;
        margin-bottom: 4px;
        border-bottom: 1px solid var(--line-soft);
    }

    /* La celda de acciones también viene sin data-label, pero no es un héroe:
       es el pie de la tarjeta. Los dos botones pasan a ocupar el ancho, que en
       táctil es la diferencia entre acertarle y no.

       Va calificada con .users-tbl y no como `.u-actions` a secas porque tiene
       que ganarle a `.table-cards td:not([data-label])` de app.css, que es más
       específica que una clase sola aun con el atributo de scope. */
    .users-tbl td.u-actions[b-u04w46f1rq] {
        display: flex;
        gap: 8px;
        margin: 8px 0 0;
        padding: 8px 0 0;
        border-bottom: none;
        border-top: 1px solid var(--line-soft);
        white-space: normal;
        text-align: left;
    }

    .u-actions[b-u04w46f1rq]  .app-btn {
        flex: 1;
        justify-content: center;
    }

    .u-actions[b-u04w46f1rq]  .app-btn + .app-btn { margin-left: 0; }

    /* La contraseña inicial se copia a mano de acá: tiene que entrar entera. */
    .cred-pwd[b-u04w46f1rq] { font-size: 14px; }

    .form-actions[b-u04w46f1rq]  .app-btn { width: 100%; }
}
/* /Components/Shared/AppButton.razor.rz.scp.css */
.app-btn[b-55wz7ia63z] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-family: var(--font);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--transition), box-shadow var(--transition), transform var(--transition), opacity var(--transition), border-color var(--transition);
    white-space: nowrap;
    line-height: 1;
}

.app-btn:disabled[b-55wz7ia63z] {
    opacity: 0.5;
    cursor: not-allowed;
}

.app-btn:not(:disabled):active[b-55wz7ia63z] {
    transform: translateY(1px);
}

/* Hover shifts the surface, not a coloured glow. The old rules carried
   hardcoded emerald/coral/gold shadows from the previous palette — on a dark
   canvas those read as smudges rather than lift. */
.app-btn--primary[b-55wz7ia63z] { background: var(--brand); color: var(--on-brand); }
.app-btn--primary:not(:disabled):hover[b-55wz7ia63z] { background: var(--brand-hover); }

.app-btn--secondary[b-55wz7ia63z] { background: var(--surface); color: var(--ink); border-color: var(--line); }
.app-btn--secondary:not(:disabled):hover[b-55wz7ia63z] { background: var(--surface-hover); border-color: var(--ink-muted); }

/* Danger hovers within red. It used to hover to --coral-deep, which is now the
   takeover amber — "delete" would have turned into the human-handoff colour. */
.app-btn--danger[b-55wz7ia63z] { background: var(--status-red); color: var(--on-coral); }
.app-btn--danger:not(:disabled):hover[b-55wz7ia63z] { filter: brightness(1.12); }

.app-btn--ghost[b-55wz7ia63z] { background: transparent; color: var(--ink-soft); }
.app-btn--ghost:not(:disabled):hover[b-55wz7ia63z] { background: var(--surface-hover); color: var(--ink); }

.app-btn--accent2[b-55wz7ia63z] { background: var(--accent2-soft); color: var(--accent2-deep); border-color: var(--accent2-line); }
.app-btn--accent2:not(:disabled):hover[b-55wz7ia63z] { background: var(--surface-hover); border-color: var(--accent2); color: var(--ink); }

.app-btn--sm[b-55wz7ia63z] { padding: 7px 13px; font-size: var(--text-sm); border-radius: var(--radius-sm); }
.app-btn--md[b-55wz7ia63z] { padding: 9px 17px; font-size: var(--text-md); }
.app-btn--lg[b-55wz7ia63z] { padding: 12px 24px; font-size: var(--text-xl); border-radius: var(--radius-lg); }

/* Área táctil. Con el padding de escritorio, --sm mide unos 29px de alto y --md
   unos 33: con un mouse se le acierta igual, con la yema del dedo no. 44px es
   el mínimo que recomienda WCAG 2.5.5, y es la medida a la que un botón deja
   de fallarse solo. El padding horizontal no se toca: el alto lo pone
   min-height y el texto queda centrado por el align-items del .app-btn. */
@media (max-width: 900px) {
    .app-btn[b-55wz7ia63z] { min-height: 44px; }
}

.app-btn--loading[b-55wz7ia63z] { pointer-events: none; }

.btn-spinner[b-55wz7ia63z] {
    width: 14px;
    height: 14px;
    /* currentColor at low alpha, so the ring works on a ghost/secondary button
       too — the old hardcoded white was invisible on light surfaces. */
    border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
    border-top-color: currentColor;
    border-radius: 50%;
    animation: spin-b-55wz7ia63z 0.6s linear infinite;
    display: inline-block;
}

@keyframes spin-b-55wz7ia63z { to { transform: rotate(360deg); } }
/* /Components/Shared/AppSelect.razor.rz.scp.css */
.app-select[b-f6cyrdk3kg] {
    position: relative;
    display: inline-block;
    min-width: 190px;
}

.app-select-trigger[b-f6cyrdk3kg] {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 8px 12px;
    font-family: var(--font);
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
    text-align: left;
    transition: border-color var(--transition), box-shadow var(--transition);
}

.app-select-trigger:hover[b-f6cyrdk3kg] { border-color: var(--brand-line); }

.app-select.is-open .app-select-trigger[b-f6cyrdk3kg] {
    border-color: var(--brand-line);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.app-select-trigger:disabled[b-f6cyrdk3kg] {
    background: var(--surface-3);
    color: var(--ink-muted);
    cursor: not-allowed;
}

.app-select-leading[b-f6cyrdk3kg] {
    display: flex;
    align-items: center;
    color: var(--brand-text);
    flex-shrink: 0;
}

.app-select-value[b-f6cyrdk3kg] {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app-select-value.is-placeholder[b-f6cyrdk3kg] {
    color: var(--ink-muted);
    font-weight: 500;
}

.app-select-chevron[b-f6cyrdk3kg] {
    display: flex;
    align-items: center;
    color: var(--ink-muted);
    flex-shrink: 0;
    transition: transform var(--transition);
}

.app-select.is-open .app-select-chevron[b-f6cyrdk3kg] { transform: rotate(180deg); }

/* Backdrop: closes the menu on any outside click, no JS interop needed. */
.app-select-backdrop[b-f6cyrdk3kg] {
    position: fixed;
    inset: 0;
    z-index: 150;
    background: transparent;
}

.app-select-menu[b-f6cyrdk3kg] {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 100%;
    margin: 0;
    padding: 5px;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    z-index: 200;
    max-height: 280px;
    overflow-y: auto;
    animation: app-select-in-b-f6cyrdk3kg 130ms cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes app-select-in-b-f6cyrdk3kg {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

.app-select-option[b-f6cyrdk3kg] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--ink-soft);
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
}

.app-select-option:hover[b-f6cyrdk3kg] {
    background: var(--surface-3);
    color: var(--ink);
}

.app-select-option.is-selected[b-f6cyrdk3kg] {
    background: var(--brand-soft);
    color: var(--brand-text);
    font-weight: 600;
}

.app-select-option-label[b-f6cyrdk3kg] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}

.app-select-option-badge[b-f6cyrdk3kg] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--coral);
    color: var(--on-coral);
    font-size: var(--text-2xs);
    font-weight: 700;
    line-height: 1;
    flex-shrink: 0;
}

.app-select-check[b-f6cyrdk3kg] {
    display: flex;
    align-items: center;
    color: var(--brand-text);
    flex-shrink: 0;
}

/* Pill variant — for the top-bar business switcher. */
.app-select--pill[b-f6cyrdk3kg] { min-width: 200px; }

.app-select--pill .app-select-trigger[b-f6cyrdk3kg] {
    border-radius: 999px;
    padding: 7px 14px;
    box-shadow: var(--shadow-sm);
}

.app-select--pill .app-select-menu[b-f6cyrdk3kg] {
    border-radius: var(--radius-lg);
}

/* ---- Responsive ---------------------------------------------------------
   Los mínimos de 190/200px se pensaron para que el control no quedara
   ridículamente angosto en un formulario amplio. En 360px son lo contrario:
   un piso que el contenedor no puede respetar y que termina empujando la
   fila entera fuera de pantalla. El trigger ya recorta su texto con puntos
   suspensivos, así que achicarlo no pierde nada.

   El menú también necesita techo: es absolute con min-width:100% y sin tope,
   así que un nombre de negocio largo lo estira hacia la derecha hasta salirse
   de la ventana. Las opciones ya recortan con ellipsis. */
@media (max-width: 600px) {
    .app-select[b-f6cyrdk3kg],
    .app-select--pill[b-f6cyrdk3kg] {
        min-width: 0;
    }

    .app-select-menu[b-f6cyrdk3kg] {
        max-width: calc(100vw - 2rem);
    }
}
/* /Components/Shared/AppTextArea.razor.rz.scp.css */
.field[b-b9wupya4u0] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field-label[b-b9wupya4u0] {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--ink);
}

.field-input[b-b9wupya4u0] {
    width: 100%;
    padding: 9px 12px;
    background: var(--surface-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    font-family: var(--font);
    font-size: var(--text-md);
    color: var(--ink);
    outline: none;
    transition: border-color var(--transition), box-shadow var(--transition);
    resize: vertical;
}

.field-input:focus[b-b9wupya4u0] {
    border-color: var(--brand-line);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.field-input:disabled[b-b9wupya4u0] {
    background: var(--paper);
    color: var(--ink-muted);
    cursor: not-allowed;
}

.field-input[b-b9wupya4u0]::placeholder { color: var(--ink-muted); }

.field-input--error[b-b9wupya4u0] { border-color: var(--status-red); }

/*
   Un cuerpo más grande que el resto de los inputs, y a propósito: acá no se cargan dos palabras
   sino párrafos que después hay que poder releer. Es el mismo tamaño que usa el composer del chat,
   y deja de ser el único lugar del panel que se lee peor en desktop (13,5px) que en mobile (16px
   por la regla anti-zoom de iOS en app.css).
*/
.field-textarea[b-b9wupya4u0] {
    min-height: 80px;
    /* El JS lo agranda solo hasta acá; pasado ese alto scrollea adentro y no empuja el formulario. */
    max-height: 22em;
    font-size: var(--text-lg);
    line-height: 1.6;
}

.field-footer[b-b9wupya4u0] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.field-help[b-b9wupya4u0] { font-size: var(--text-sm); color: var(--ink-muted); }

.field-count[b-b9wupya4u0] {
    flex: none;
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: var(--ink-muted);
}

.field-count--full[b-b9wupya4u0] { color: var(--status-red); }
/* /Components/Shared/AppTextField.razor.rz.scp.css */
.field[b-wonae0cdby] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field-label[b-wonae0cdby] {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--ink);
}

.field-input[b-wonae0cdby] {
    width: 100%;
    padding: 9px 12px;
    background: var(--surface-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    font-family: var(--font);
    font-size: var(--text-md);
    color: var(--ink);
    outline: none;
    transition: border-color var(--transition), box-shadow var(--transition);
}

.field-input:focus[b-wonae0cdby] {
    border-color: var(--brand-line);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.field-input:disabled[b-wonae0cdby] {
    background: var(--paper);
    color: var(--ink-muted);
    cursor: not-allowed;
}

.field-input[b-wonae0cdby]::placeholder { color: var(--ink-muted); }

.field-input--error[b-wonae0cdby] { border-color: var(--status-red); }
.field-input--error:focus[b-wonae0cdby] { box-shadow: 0 0 0 3px var(--coral-soft); }

.field-help[b-wonae0cdby] { font-size: var(--text-sm); color: var(--ink-muted); }
/* /Components/Shared/AppToggle.razor.rz.scp.css */
.toggle-wrap[b-itoy9mo4nv] {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
}

.toggle-track[b-itoy9mo4nv] {
    width: 42px;
    height: 24px;
    background: var(--surface-3);
    border: 1px solid var(--line);
    border-radius: 12px;
    position: relative;
    transition: background var(--transition), border-color var(--transition);
    flex-shrink: 0;
}

.toggle-thumb[b-itoy9mo4nv] {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 16px;
    height: 16px;
    background: white;
    border-radius: 50%;
    transition: transform var(--transition);
    box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}

.toggle-input:checked ~ .toggle-track[b-itoy9mo4nv] { background: var(--brand); border-color: var(--brand); }
.toggle-input:checked ~ .toggle-track .toggle-thumb[b-itoy9mo4nv] { transform: translateX(18px); }
.toggle-input:disabled ~ .toggle-track[b-itoy9mo4nv] { opacity: 0.5; cursor: not-allowed; }

/* The real <input> is visually hidden, so the focus ring has to be forwarded to
   the track or the toggle is invisible to keyboard users. */
.toggle-input:focus-visible ~ .toggle-track[b-itoy9mo4nv] {
    outline: 2px solid var(--brand-text);
    outline-offset: 2px;
}

.toggle-wrap:hover .toggle-track[b-itoy9mo4nv] { border-color: var(--ink-muted); }

.toggle-label[b-itoy9mo4nv] {
    font-size: var(--text-md);
    font-weight: 500;
    color: var(--ink);
}
/* /Components/Shared/AudioPlayer.razor.rz.scp.css */
.ap-root[b-lgc2ik1p9j] {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 248px;
    max-width: 100%;
}

.ap-toggle[b-lgc2ik1p9j] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: none;
    background: var(--ap-btn-bg, var(--brand));
    color: var(--ap-btn-fg, var(--on-brand));
    cursor: pointer;
    flex-shrink: 0;
    box-shadow: var(--shadow-sm);
    transition: filter var(--transition), transform var(--transition);
}

.ap-toggle:hover[b-lgc2ik1p9j] {
    filter: brightness(1.08);
}

.ap-toggle:active[b-lgc2ik1p9j] {
    transform: scale(0.94);
}

.ap-toggle:focus-visible[b-lgc2ik1p9j] {
    outline: 2px solid var(--brand-line);
    outline-offset: 2px;
}

.ap-toggle svg[b-lgc2ik1p9j] {
    width: 17px;
    height: 17px;
}

.ap-icon-pause[b-lgc2ik1p9j] {
    display: none;
}

.ap-root--playing .ap-icon-play[b-lgc2ik1p9j] {
    display: none;
}

.ap-root--playing .ap-icon-pause[b-lgc2ik1p9j] {
    display: block;
}

.ap-wave[b-lgc2ik1p9j] {
    position: relative;
    flex: 1;
    min-width: 0;
    height: 26px;
    display: flex;
    align-items: center;
    gap: 1.5px;
    cursor: pointer;
}

.ap-bar[b-lgc2ik1p9j] {
    flex: 0 0 2.5px;
    width: 2.5px;
    height: calc(4px + var(--h, 0.5) * 22px);
    border-radius: 2px;
    background: var(--ap-wave-muted, var(--ink-muted));
    pointer-events: none;
    transition: background-color var(--transition);
}

.ap-bar--played[b-lgc2ik1p9j] {
    background: var(--ap-wave-fill, var(--brand));
}

.ap-time[b-lgc2ik1p9j] {
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: var(--ap-time-fg, var(--ink-muted));
    flex-shrink: 0;
    min-width: 30px;
    text-align: right;
}

/* Visually hidden but functional — audio playback doesn't need a visible
   native element; the same pattern already used for the hidden file input
   in MediaComposer.razor.css. */
.ap-audio[b-lgc2ik1p9j] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

@media (prefers-reduced-motion: reduce) {
    .ap-toggle[b-lgc2ik1p9j],
    .ap-bar[b-lgc2ik1p9j] {
        transition: none;
    }
}
/* /Components/Shared/BarChart.razor.rz.scp.css */
.chart[b-kfuyqta54k] {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.chart-svg[b-kfuyqta54k] {
    width: 100%;
    height: 140px;
    display: block;
    overflow: visible;
}

.bar[b-kfuyqta54k] {
    fill: var(--brand);
    opacity: 0.55;
    transition: opacity var(--transition-fast);
}

.chart-svg:hover .bar[b-kfuyqta54k] { opacity: 0.35; }
.chart-svg .bar:hover[b-kfuyqta54k] { opacity: 1; }

/* The peak is the one bar worth spotting at a glance — the busiest hour, the
   most expensive day. */
.bar--peak[b-kfuyqta54k] {
    fill: var(--brand);
    opacity: 1;
}

.chart-axis[b-kfuyqta54k] {
    display: flex;
    justify-content: space-between;
    padding-top: 2px;
    border-top: 1px solid var(--line);
}

.chart-axis-label[b-kfuyqta54k] {
    font-size: var(--text-2xs);
    color: var(--ink-muted);
}

.chart-empty[b-kfuyqta54k] {
    margin: 0;
    padding: 2rem 0;
    text-align: center;
    font-size: var(--text-base);
    color: var(--ink-muted);
}
/* /Components/Shared/Card.razor.rz.scp.css */
.app-card[b-kpm3oqe9oz] {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.app-card--padded[b-kpm3oqe9oz] {
    padding: 1.5rem;
}
/* /Components/Shared/ConversationListItem.razor.rz.scp.css */
.conv-item[b-ah24zaf23j] {
    /* Button reset — this is a <button> for the keyboard, styled as a row. */
    width: 100%;
    text-align: left;
    font: inherit;
    color: inherit;
    background: none;
    border: none;

    display: flex;
    align-items: center;
    gap: 13px;
    /* Left padding leaves room for the 4px accent bar so the content does not
       shift by 4px the moment a row is selected. */
    padding: 14px 20px 14px 24px;
    border-bottom: 1px solid var(--line);
    cursor: pointer;
    position: relative;
    transition: background var(--transition-fast);
}

/* The accent bar lives here permanently and is revealed by state, rather than
   being added on select — otherwise every selection reflows the row. */
.conv-item[b-ah24zaf23j]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: transparent;
    transition: background var(--transition-fast);
}

.conv-item:hover[b-ah24zaf23j] { background: var(--surface-hover); }

.conv-item:focus-visible[b-ah24zaf23j] {
    outline: 2px solid var(--brand-text);
    outline-offset: -2px;   /* inset: rows are flush, an outset ring would clip */
}

.conv-item--selected[b-ah24zaf23j],
.conv-item--selected:hover[b-ah24zaf23j] {
    background: var(--brand-soft);
}
.conv-item--selected[b-ah24zaf23j]::before { background: var(--brand); }

/* Waiting on a person — the amber takeover signal, same language as the bubble.
   Barra LLENA: hay un cliente esperando que alguien conteste. */
.conv-item--needs-reply[b-ah24zaf23j]::before { background: var(--coral); }

/* La IA pidió ayuda pero sigue contestando: nadie está esperando una respuesta, se espera una
   revisión. Se distingue por FORMA (barra a rayas, no llena) y no por otro tono de ámbar: --coral y
   --status-amber son prácticamente el mismo color en 4px de ancho, sobre todo en tema oscuro, así
   que dos estados opuestos se veían idénticos. La forma se lee incluso de reojo. */
.conv-item--needs-attention[b-ah24zaf23j]::before {
    background: repeating-linear-gradient(
        180deg,
        var(--status-amber) 0 6px,
        transparent 6px 12px);
}

/* Si pasan las dos cosas a la vez, manda la que tiene a alguien esperando. */
.conv-item--needs-reply.conv-item--needs-attention[b-ah24zaf23j]::before { background: var(--coral); }

.item-avatar[b-ah24zaf23j] {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-lg);
    background: var(--surface-3);
    border: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: background var(--transition), border-color var(--transition);
}

.conv-item--selected .item-avatar[b-ah24zaf23j] {
    background: var(--brand);
    border-color: var(--brand);
}

.avatar-initials[b-ah24zaf23j] {
    color: var(--brand-text);
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 600;
    transition: color var(--transition);
}

.conv-item--selected .avatar-initials[b-ah24zaf23j] { color: var(--on-brand); }

.item-body[b-ah24zaf23j] {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.item-top[b-ah24zaf23j] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.item-name[b-ah24zaf23j] {
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.item-time[b-ah24zaf23j] {
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: var(--ink-muted);
    flex-shrink: 0;
}

.item-bottom[b-ah24zaf23j] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.item-preview[b-ah24zaf23j] {
    font-size: var(--text-sm);
    color: var(--ink-soft);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
}

/* WhatsApp-style sent/delivered/read tick shown before our own last message.
   Read uses the recognizable blue accent; every other state stays neutral ink. */
.conv-tick[b-ah24zaf23j] {
    display: inline-block;
    margin-right: 3px;
    letter-spacing: -1px;
    color: var(--ink-muted);
}

.conv-tick--read[b-ah24zaf23j] {
    color: #34B7F1;
}

.conv-tick--failed[b-ah24zaf23j] {
    color: var(--coral-deep);
}

.item-badges[b-ah24zaf23j] {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Human-takeover conversation with an unanswered customer message. */
.conv-item--needs-reply .item-name[b-ah24zaf23j] { font-weight: 700; }

.conv-item--needs-reply .item-preview[b-ah24zaf23j] {
    color: var(--ink);
    font-weight: 600;
}

.unread-badge[b-ah24zaf23j] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--coral);
    color: var(--on-coral);
    font-size: var(--text-2xs);
    font-weight: 700;
    line-height: 1;
}

/* En un celular la fila más importante era la que menos mostraba: entre el avatar, el padding y
   dos o tres badges nowrap, el preview del mensaje se quedaba con un puñado de caracteres. Acá se
   recorta el chrome y se deja UN badge, que es lo que de verdad se scannea. */
@media (max-width: 600px) {
    .conv-item[b-ah24zaf23j] {
        gap: 10px;
        padding: 11px 12px 11px 16px;
    }

    .item-avatar[b-ah24zaf23j] {
        width: 34px;
        height: 34px;
    }

    /* El estado ya se ve en la barra lateral de color; en pantalla chica gana el contenido.
       Va con ::deep porque StatusBadge renderiza su propio root: sin eso la regla compila con el
       scope de ESTE componente y no matchea nada (la trampa que documenta el CLAUDE.md). */
    .item-badges[b-ah24zaf23j]  .status-badge { display: none; }

    .item-badges[b-ah24zaf23j]  .status-badge--human,
    .item-badges[b-ah24zaf23j]  .status-badge--attention { display: inline-flex; }
}
/* /Components/Shared/EmptyState.razor.rz.scp.css */
.empty-state[b-jx01n4d93a] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3.5rem 2rem;
    text-align: center;
    gap: 14px;
}

/* Large and quiet. An empty screen is an invitation to act, so the weight
   belongs on the title and the action — the icon just marks the spot. */
.empty-icon[b-jx01n4d93a] {
    width: 72px;
    height: 72px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-muted);
    margin-bottom: 4px;
}

.empty-icon svg[b-jx01n4d93a] {
    width: 30px;
    height: 30px;
}

.empty-title[b-jx01n4d93a] {
    font-family: var(--font-display);
    font-optical-sizing: auto;
    font-size: var(--text-3xl);
    font-weight: 600;
    letter-spacing: -0.015em;
    color: var(--ink);
}

.empty-description[b-jx01n4d93a] {
    font-size: var(--text-lg);
    color: var(--ink-soft);
    margin: 0;
    max-width: 340px;
    line-height: 1.6;
}

.empty-action[b-jx01n4d93a] { margin-top: 6px; }
/* /Components/Shared/MediaComposer.razor.rz.scp.css */
.mc-root[b-pzvik0vvwo] {
    width: 100%;
}

.mc-dropzone[b-pzvik0vvwo] {
    position: relative;
    transition: background var(--transition);
    border-radius: var(--radius-md);
}

.mc-dropzone--locked[b-pzvik0vvwo] {
    pointer-events: none;
}

.mc-dropzone--locked .mc-recording[b-pzvik0vvwo],
.mc-dropzone--locked .mc-recording-cancel[b-pzvik0vvwo],
.mc-dropzone--locked .mc-recording-send[b-pzvik0vvwo],
.mc-dropzone--locked .mc-attachment-remove[b-pzvik0vvwo] {
    pointer-events: auto;
}

/* Drag & drop overlay — .mc-dropzone--over is toggled by MediaComposer.razor.js.
   pointer-events: none keeps dragleave/drop landing on the dropzone itself. */
.mc-drop-overlay[b-pzvik0vvwo] {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    border: 2px dashed var(--brand-line);
    border-radius: var(--radius-md);
    background: linear-gradient(var(--brand-soft), var(--brand-soft)), var(--surface);
    color: var(--brand-text);
    font-size: var(--text-base);
    font-weight: 600;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition-fast);
}

.mc-drop-overlay svg[b-pzvik0vvwo] {
    width: 22px;
    height: 22px;
}

.mc-dropzone--over .mc-drop-overlay[b-pzvik0vvwo] {
    opacity: 1;
}

.mc-row[b-pzvik0vvwo] {
    display: flex;
    align-items: flex-end;
    gap: 10px;
}

.mc-input[b-pzvik0vvwo] {
    flex: 1;
    min-width: 0;
    min-height: 40px;
    padding: 8.5px 14px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    font-family: var(--font);
    font-size: var(--text-lg);
    color: var(--ink);
    outline: none;
    resize: none;
    line-height: 1.5;
    max-height: 8.5em;
    transition: border-color var(--transition), box-shadow var(--transition);
}

.mc-input:focus[b-pzvik0vvwo] {
    border-color: var(--brand-line);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.mc-input[b-pzvik0vvwo]::placeholder {
    color: var(--ink-muted);
}

.mc-input:disabled[b-pzvik0vvwo] {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ---- Attach button ---- */
.mc-attach[b-pzvik0vvwo] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--paper);
    color: var(--ink-soft);
    cursor: pointer;
    flex-shrink: 0;
    transition: border-color var(--transition), background var(--transition), color var(--transition);
}

.mc-attach:hover[b-pzvik0vvwo] {
    border-color: var(--brand-line);
    background: var(--brand-soft);
    color: var(--brand-text);
}

.mc-attach:focus-within[b-pzvik0vvwo] {
    border-color: var(--brand-line);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.mc-attach--disabled[b-pzvik0vvwo] {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

.mc-attach svg[b-pzvik0vvwo] {
    width: 18px;
    height: 18px;
}

/* Keep the native file input focusable (visually hidden, not display:none) —
   CSS isolation does not reach the InputFile child component. */
.mc-attach[b-pzvik0vvwo]  input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ---- Mic / recording / processing controls (share the attach button footprint) ---- */
.mc-mic[b-pzvik0vvwo],
.mc-send[b-pzvik0vvwo] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--paper);
    color: var(--ink-soft);
    cursor: pointer;
    flex-shrink: 0;
    transition: border-color var(--transition), background var(--transition), color var(--transition),
        opacity var(--transition), transform var(--transition), box-shadow var(--transition);
}

.mc-mic svg[b-pzvik0vvwo],
.mc-send svg[b-pzvik0vvwo] {
    width: 18px;
    height: 18px;
}

.mc-mic:hover:not(:disabled)[b-pzvik0vvwo] {
    border-color: var(--brand-line);
    background: var(--brand-soft);
    color: var(--brand-text);
    transform: scale(1.08) rotate(10deg);
    box-shadow: var(--shadow-sm);
}

.mc-mic:active:not(:disabled)[b-pzvik0vvwo] {
    transform: scale(0.92) rotate(0deg);
    transition-duration: 80ms;
}

.mc-send[b-pzvik0vvwo] {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--surface);
}

.mc-send:hover:not(:disabled)[b-pzvik0vvwo] {
    filter: brightness(1.06);
    transform: scale(1.06);
    box-shadow: var(--shadow-sm);
}

.mc-send:active:not(:disabled)[b-pzvik0vvwo] {
    transform: scale(0.94);
    transition-duration: 80ms;
}

.mc-mic:disabled[b-pzvik0vvwo],
.mc-send:disabled[b-pzvik0vvwo] {
    opacity: 0.45;
    cursor: not-allowed;
}

.mc-mic:focus-visible[b-pzvik0vvwo],
.mc-send:focus-visible[b-pzvik0vvwo],
.mc-attach:focus-visible[b-pzvik0vvwo],
.mc-recording-cancel:focus-visible[b-pzvik0vvwo],
.mc-recording-send:focus-visible[b-pzvik0vvwo],
.mc-attachment-remove:focus-visible[b-pzvik0vvwo] {
    outline: 2px solid var(--brand-line);
    outline-offset: 2px;
}

/* ---- Recording pill ---- */
.mc-recording[b-pzvik0vvwo] {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 40px;
    padding: 0 6px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 20px;
    flex-shrink: 0;
    box-shadow: var(--shadow-sm);
    animation: mc-slide-in-b-pzvik0vvwo 250ms var(--ease, ease-out);
}

@keyframes mc-slide-in-b-pzvik0vvwo {
    from { opacity: 0; transform: translateX(14px) scale(0.92); }
    to { opacity: 1; transform: translateX(0) scale(1); }
}

.mc-recording-cancel[b-pzvik0vvwo] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
    flex-shrink: 0;
    color: var(--ink-soft);
    transition: background var(--transition), color var(--transition), transform var(--transition);
}

.mc-recording-cancel:hover[b-pzvik0vvwo] {
    background: var(--coral-soft);
    color: var(--coral-deep);
    transform: scale(1.08);
}

.mc-recording-cancel:active[b-pzvik0vvwo] {
    transform: scale(0.92);
    transition-duration: 80ms;
}

/* The in-recording send: stopping IS sending — one gesture, like a real voice-note UI. */
.mc-recording-send[b-pzvik0vvwo] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 50%;
    background: var(--brand);
    color: var(--on-brand, var(--surface));
    cursor: pointer;
    flex-shrink: 0;
    box-shadow: 0 2px 8px var(--brand-soft);
    transition: background var(--transition), transform var(--transition), box-shadow var(--transition), filter var(--transition);
}

.mc-recording-send:hover[b-pzvik0vvwo] {
    filter: brightness(1.08);
    transform: scale(1.1);
    box-shadow: 0 3px 12px var(--brand-soft);
}

.mc-recording-send:active[b-pzvik0vvwo] {
    transform: scale(0.9);
    transition-duration: 80ms;
}

.mc-recording-send svg[b-pzvik0vvwo] {
    width: 14px;
    height: 14px;
}

.mc-recording-dot[b-pzvik0vvwo] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--coral-deep);
    box-shadow: 0 0 8px var(--coral-line, rgba(217, 79, 56, 0.5));
    animation: mc-pulse-b-pzvik0vvwo 1.2s ease-in-out infinite;
    flex-shrink: 0;
}

@keyframes mc-pulse-b-pzvik0vvwo {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.55; transform: scale(0.8); }
}

.mc-recording-time[b-pzvik0vvwo] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    min-width: 30px;
}

/* ---- Wave animation while recording ---- */
.mc-wave[b-pzvik0vvwo] {
    display: flex;
    align-items: center;
    gap: 3px;
    height: 20px;
    padding: 0 2px;
}

.mc-wave-bar[b-pzvik0vvwo] {
    width: 3px;
    height: 100%;
    background: var(--brand);
    border-radius: 2px;
    animation: mc-wave-b-pzvik0vvwo 0.6s ease-in-out infinite;
    transform-origin: center;
}

.mc-wave-bar:nth-child(1)[b-pzvik0vvwo] { animation-delay: 0s; }
.mc-wave-bar:nth-child(2)[b-pzvik0vvwo] { animation-delay: 0.1s; }
.mc-wave-bar:nth-child(3)[b-pzvik0vvwo] { animation-delay: 0.2s; }
.mc-wave-bar:nth-child(4)[b-pzvik0vvwo] { animation-delay: 0.3s; }
.mc-wave-bar:nth-child(5)[b-pzvik0vvwo] { animation-delay: 0.4s; }

@keyframes mc-wave-b-pzvik0vvwo {
    0%, 100% { transform: scaleY(0.3); }
    50% { transform: scaleY(1); }
}

/* ---- Processing indicator ---- */
.mc-processing[b-pzvik0vvwo] {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 40px;
    padding: 0 12px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 20px;
    color: var(--ink-muted);
    font-size: var(--text-sm);
    flex-shrink: 0;
}

.mc-spinner[b-pzvik0vvwo] {
    width: 14px;
    height: 14px;
    border: 2px solid var(--line);
    border-top-color: var(--brand);
    border-radius: 50%;
    animation: mc-spin-b-pzvik0vvwo 0.8s linear infinite;
}

@keyframes mc-spin-b-pzvik0vvwo {
    to { transform: rotate(360deg); }
}

/* ---- Reply strip (respondiendo a…) ---- */
.mc-reply[b-pzvik0vvwo] {
    display: flex;
    align-items: stretch;
    gap: 9px;
    margin-bottom: 9px;
    padding: 7px 9px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}

.mc-reply-bar[b-pzvik0vvwo] {
    width: 3px;
    border-radius: 2px;
    background: var(--brand);
    flex-shrink: 0;
}

.mc-reply-body[b-pzvik0vvwo] {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1;
}

.mc-reply-author[b-pzvik0vvwo] {
    font-size: var(--text-xs);
    font-weight: 700;
    color: var(--brand-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mc-reply-snippet[b-pzvik0vvwo] {
    font-size: var(--text-sm);
    color: var(--ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mc-reply-cancel[b-pzvik0vvwo] {
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--ink-soft);
    font-size: var(--text-lg);
    line-height: 1;
    padding: 0 6px;
    border-radius: 7px;
    align-self: center;
    flex-shrink: 0;
    transition: background var(--transition), color var(--transition);
}

.mc-reply-cancel:hover[b-pzvik0vvwo] {
    background: var(--line);
    color: var(--ink);
}

/* ---- Attachment preview strip ---- */
.mc-attachment[b-pzvik0vvwo] {
    display: flex;
    align-items: center;
    gap: 11px;
    margin-bottom: 9px;
    padding: 8px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}

.mc-attachment-thumb[b-pzvik0vvwo] {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: 8px;
    flex-shrink: 0;
    border: 1px solid var(--line);
}

.mc-attachment-info[b-pzvik0vvwo] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

.mc-attachment-name[b-pzvik0vvwo] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mc-attachment-hint[b-pzvik0vvwo] {
    font-size: var(--text-xs);
    color: var(--ink-muted);
}

.mc-attachment-remove[b-pzvik0vvwo] {
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--ink-soft);
    font-size: var(--text-lg);
    line-height: 1;
    padding: 5px 7px;
    border-radius: 7px;
    flex-shrink: 0;
    transition: background var(--transition), color var(--transition);
}

.mc-attachment-remove:hover:not(:disabled)[b-pzvik0vvwo] {
    background: var(--line);
    color: var(--ink);
}

.mc-attachment-remove:disabled[b-pzvik0vvwo] {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ---- Error message ---- */
.mc-error[b-pzvik0vvwo] {
    margin-bottom: 8px;
    padding: 8px 12px;
    background: var(--coral-soft);
    color: var(--coral-deep);
    font-size: var(--text-sm);
    border-radius: var(--radius-md);
}

/* ---- Responsive ---------------------------------------------------------
   La fila tiene cuatro elementos: adjuntar, el campo, el micrófono y enviar.
   Tres son de ancho fijo, así que en 360px el único que se achica es el campo
   de texto — que es justamente el que hay que poder usar.

   Se recuperan 12px bajando el gap, y se gastan en subir los botones a 44px.
   Suena contradictorio pero no lo es: el campo termina con el mismo ancho que
   antes y los tres botones dejan de ser blancos de 40px, que es donde se
   falla el micrófono y se manda el mensaje sin querer. */
@media (max-width: 600px) {
    .mc-row[b-pzvik0vvwo] { gap: 6px; }

    .mc-attach[b-pzvik0vvwo],
    .mc-mic[b-pzvik0vvwo],
    .mc-send[b-pzvik0vvwo] {
        width: 44px;
        height: 44px;
    }

    /* Igualado a los botones: con align-items:flex-end, 40 contra 44 deja el
       campo despegado del piso de la fila. */
    .mc-input[b-pzvik0vvwo] { min-height: 44px; }

    /* Los placeholders de estas pantallas son largos ("Escribí como cliente…
       (o mandá una foto / nota de voz)") y en una línea de ~200px se parten en
       dos, con la segunda cortada por la mitad contra el borde del campo.
       Recortado con puntos suspensivos se lee como una frase inacabada y no
       como un error de maquetado. Va sobre ::placeholder y no sobre el campo:
       el texto que la persona escribe tiene que seguir haciendo salto de
       línea normal. */
    .mc-input[b-pzvik0vvwo]::placeholder {
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
    }

    .mc-attachment-hint[b-pzvik0vvwo] { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .mc-dropzone[b-pzvik0vvwo],
    .mc-attach[b-pzvik0vvwo],
    .mc-mic[b-pzvik0vvwo],
    .mc-send[b-pzvik0vvwo],
    .mc-attachment-remove[b-pzvik0vvwo],
    .mc-recording-cancel[b-pzvik0vvwo],
    .mc-recording-send[b-pzvik0vvwo] {
        transition: none;
    }

    .mc-recording[b-pzvik0vvwo],
    .mc-recording-dot[b-pzvik0vvwo],
    .mc-wave-bar[b-pzvik0vvwo],
    .mc-spinner[b-pzvik0vvwo] {
        animation: none;
    }

    .mc-mic:hover:not(:disabled)[b-pzvik0vvwo],
    .mc-send:hover:not(:disabled)[b-pzvik0vvwo],
    .mc-recording-cancel:hover[b-pzvik0vvwo],
    .mc-recording-send:hover[b-pzvik0vvwo] {
        transform: none;
    }
}
/* /Components/Shared/MessageBubble.razor.rz.scp.css */
/* ============================================================
   THREE-VOICE CONVERSATION (the signature)
   customer · AI (house voice) · human agent (takeover)
   ============================================================ */

.bubble-wrap[b-cg2uzcfx0g] {
    display: flex;
    flex-direction: column;
    gap: 5px;
    max-width: 74%;
    margin-bottom: 10px;
}

.bubble-wrap--in[b-cg2uzcfx0g] {
    align-self: flex-start;
    align-items: flex-start;
}

.bubble-wrap--out[b-cg2uzcfx0g] {
    align-self: flex-end;
    align-items: flex-end;
}

.bubble-meta[b-cg2uzcfx0g] {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 0 6px;
}

/* Mono chip: the "who is talking" marker reads as machine metadata, which is
   exactly what it is — it should never look like part of the message. The icon
   inside carries the voice at a glance (sparkle = AI, person = takeover) so the
   colors don't have to do all the work. */
.bubble-sender[b-cg2uzcfx0g] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-muted);
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--surface-hover);
}

.bubble-sender svg[b-cg2uzcfx0g] {
    width: 11px;
    height: 11px;
    flex-shrink: 0;
}

.bubble-sender--ai[b-cg2uzcfx0g] {
    background: var(--brand-soft);
    color: var(--brand-text);
}

.bubble-sender--human[b-cg2uzcfx0g] {
    background: var(--coral-soft);
    color: var(--coral-deep);
}

.bubble-time[b-cg2uzcfx0g] {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: var(--ink-muted);
}

.bubble[b-cg2uzcfx0g] {
    padding: 11px 15px;
    /* 12px everywhere, 2px on the anchor corner — the corner that points at the
       speaker. Set per-variant below. */
    border-radius: var(--radius-xl);
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 8px;
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--transition);
}

.bubble-footer[b-cg2uzcfx0g] {
    display: flex;
    align-items: flex-end;
    gap: 8px;
}

/* Customer — neutral surface, the incoming voice. Anchored bottom-left. */
.bubble--customer[b-cg2uzcfx0g] {
    background: var(--surface);
    border: 1px solid var(--line);
    border-bottom-left-radius: var(--radius-sm);
    color: var(--ink);
}

/* AI — teal, the house voice. Anchored bottom-right. */
.bubble--ai[b-cg2uzcfx0g] {
    background: var(--brand);
    border-bottom-right-radius: var(--radius-sm);
    color: var(--on-brand);
}
.bubble--ai .bubble-content[b-cg2uzcfx0g] { color: var(--on-brand); }
.bubble--ai .bubble-time[b-cg2uzcfx0g] { color: var(--on-brand); opacity: 0.75; }

/* Human agent — solid amber. This is the one bubble an operator must be able to
   spot while scrolling fast, so it is a fill, not a tint: a person stepped in
   here and that is the most consequential fact in the thread. */
.bubble--human[b-cg2uzcfx0g] {
    background: var(--coral);
    border-bottom-right-radius: var(--radius-sm);
    color: var(--on-coral);
}
.bubble--human .bubble-content[b-cg2uzcfx0g] { color: var(--on-coral); }

/* --- WhatsApp quote (this message replies to an earlier one) ------------- */

.bubble-quote[b-cg2uzcfx0g] {
    display: flex;
    align-items: stretch;
    gap: 8px;
    padding: 6px 10px 6px 8px;
    border-radius: 8px;
    background: var(--surface-hover);
    overflow: hidden;
}

.bubble-quote--clickable[b-cg2uzcfx0g] {
    cursor: pointer;
}

.bubble-quote-bar[b-cg2uzcfx0g] {
    width: 3px;
    border-radius: 2px;
    background: var(--brand);
    flex-shrink: 0;
}

.bubble-quote-body[b-cg2uzcfx0g] {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.bubble-quote-author[b-cg2uzcfx0g] {
    font-size: var(--text-xs);
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bubble-quote-snippet[b-cg2uzcfx0g] {
    font-size: var(--text-sm);
    opacity: 0.8;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* On the filled bubbles the quote needs its own contrast plane. */
.bubble--ai .bubble-quote[b-cg2uzcfx0g] {
    background: rgba(0, 0, 0, 0.16);
}
.bubble--ai .bubble-quote-bar[b-cg2uzcfx0g] {
    background: rgba(255, 255, 255, 0.65);
}

.bubble--human .bubble-quote[b-cg2uzcfx0g] {
    background: rgba(0, 0, 0, 0.12);
}
.bubble--human .bubble-quote-bar[b-cg2uzcfx0g] {
    background: rgba(0, 0, 0, 0.45);
}

.bubble-content[b-cg2uzcfx0g] {
    margin: 0;
    font-size: var(--text-lg);
    line-height: 1.6;
    word-break: break-word;
    white-space: pre-line;
}
.bubble[b-cg2uzcfx0g]  .bubble-content strong {
    font-weight: 700;
}

.bubble[b-cg2uzcfx0g]  .bubble-link {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.bubble[b-cg2uzcfx0g]  .bubble-link:hover,
.bubble[b-cg2uzcfx0g]  .bubble-link:focus-visible {
    opacity: 0.85;
}

.bubble-status-icon[b-cg2uzcfx0g] {
    font-size: var(--text-xs);
    opacity: 0.75;
    flex-shrink: 0;
    align-self: flex-end;
    margin-bottom: 1px;
    letter-spacing: -1px;
}

/* Read/failed ticks carry meaning, so they get full opacity and the same colors
   the conversation list uses — a dimmed tint would defeat the point of coloring them. */
.bubble-status-icon--read[b-cg2uzcfx0g] {
    color: #34B7F1;
    opacity: 1;
}

/* A failed send is an error, not a takeover. This pointed at --coral-deep,
   which is now the amber handoff colour — a failure would have been drawn in
   the "a human stepped in" tone. */
.bubble-status-icon--failed[b-cg2uzcfx0g] {
    color: var(--status-red);
    opacity: 1;
}

/* On the teal fill, the theme red loses separation; lift it instead. */
.bubble--ai .bubble-status-icon--failed[b-cg2uzcfx0g] {
    color: #FFB4A2;
}

.bubble-image-btn[b-cg2uzcfx0g] {
    display: block;
    padding: 0;
    border: none;
    background: none;
    line-height: 0;
    cursor: zoom-in;
}

/* Fixed square thumbnail so every photo bubble is the same size regardless of
   the source image's aspect ratio. object-fit: cover needs both dimensions. */
.bubble-image[b-cg2uzcfx0g] {
    width: 200px;
    height: 200px;
    border-radius: 10px;
    object-fit: cover;
    display: block;
}

/* In-app image viewer (lightbox) */
.image-viewer-overlay[b-cg2uzcfx0g] {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4vmin;
    background: rgba(0, 0, 0, 0.82);
    cursor: zoom-out;
    outline: none;
}

.image-viewer-img[b-cg2uzcfx0g] {
    max-width: 92vw;
    max-height: 92vh;
    max-height: 92dvh;   /* 92vh se mete debajo de la barra de URL en móvil */
    object-fit: contain;
    border-radius: 8px;
    box-shadow: 0 12px 48px rgba(0, 0, 0, 0.5);
    cursor: default;
}

.image-viewer-close[b-cg2uzcfx0g] {
    position: fixed;
    top: 18px;
    right: 22px;
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 26px;
    line-height: 1;
    color: var(--on-brand);
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 50%;
    cursor: pointer;
}

.image-viewer-close:hover[b-cg2uzcfx0g] {
    background: rgba(0, 0, 0, 0.55);
}

/* Both filled bubbles need player chrome that reads on their own background —
   AudioPlayer.razor.css declares these --ap-* custom properties as override
   hooks with brand fallbacks; setting them here crosses the Blazor
   CSS-isolation boundary for free (custom properties inherit normally), so
   this file never needs to know AudioPlayer's internal markup/class names. */

/* Teal fill → light chrome. */
.bubble--ai[b-cg2uzcfx0g] {
    --ap-btn-bg: rgba(255, 255, 255, 0.22);
    --ap-btn-fg: var(--on-brand);
    --ap-wave-fill: var(--on-brand);
    --ap-wave-muted: rgba(255, 255, 255, 0.32);
    --ap-time-fg: rgba(255, 255, 255, 0.85);
}

/* Amber fill → dark chrome. Without the button pair below, the play button
   fell back to --brand and painted a teal circle on the amber bubble. */
.bubble--human[b-cg2uzcfx0g] {
    --ap-btn-bg: rgba(0, 0, 0, 0.20);
    --ap-btn-fg: var(--on-coral);
    --ap-wave-fill: var(--on-coral);
    --ap-wave-muted: rgba(0, 0, 0, 0.28);
    --ap-time-fg: rgba(0, 0, 0, 0.72);
}

/* --- Reactions ---------------------------------------------------------- */

/* Chips overlap the bubble's bottom edge the way WhatsApp shows them, so a
   reaction reads as attached to the message instead of as a new line of text. */
.bubble-reactions[b-cg2uzcfx0g] {
    display: flex;
    gap: 2px;
    margin-top: 4px;
    margin-bottom: -12px;
    position: relative;
    z-index: 1;
}

.reaction-chip[b-cg2uzcfx0g] {
    display: inline-flex;
    align-items: center;
    font-size: 13px;
    line-height: 1;
    padding: 3px 6px;
    border-radius: 999px;
    /* --border and --accent were never real tokens, so these silently fell back
       to a hardcoded emerald and a near-invisible black hairline. */
    background: var(--surface);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-sm);
}

.reaction-chip--ours[b-cg2uzcfx0g] {
    border-color: var(--brand);
}

/* --- Hover actions (react · reply · copy) ------------------------------- */

/* The bar stays invisible until the row is hovered or a button inside it is
   focused, so a long thread isn't a wall of icons — but keyboard users can still
   reach it, which display:none or visibility:hidden would prevent. */
.bubble-actions[b-cg2uzcfx0g] {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 999px;
    box-shadow: var(--shadow-sm);
    opacity: 0;
    transition: opacity 120ms ease-in-out;
}

.bubble-wrap:hover .bubble-actions[b-cg2uzcfx0g],
.bubble-actions:focus-within[b-cg2uzcfx0g] {
    opacity: 1;
}

.reaction-control[b-cg2uzcfx0g] {
    position: relative;
    display: flex;
    align-items: center;
}

.bubble-action[b-cg2uzcfx0g] {
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-muted);
    background: transparent;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.bubble-action svg[b-cg2uzcfx0g] {
    width: 14px;
    height: 14px;
}

.bubble-action:hover[b-cg2uzcfx0g] {
    background: var(--surface-hover);
    color: var(--ink);
}

.bubble-action-check[b-cg2uzcfx0g] {
    color: var(--status-green);
}

.reaction-picker[b-cg2uzcfx0g] {
    position: absolute;
    bottom: calc(100% + 6px);
    display: flex;
    gap: 2px;
    padding: 4px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 999px;
    box-shadow: var(--shadow-md);
    z-index: 10;
}

.bubble-wrap--out .reaction-picker[b-cg2uzcfx0g] {
    right: 0;
}

.bubble-wrap--in .reaction-picker[b-cg2uzcfx0g] {
    left: 0;
}

.reaction-option[b-cg2uzcfx0g] {
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    line-height: 1;
    background: transparent;
    border: none;
    border-radius: 50%;
    cursor: pointer;
}

.reaction-option:hover[b-cg2uzcfx0g] {
    background: var(--surface-hover);
    transform: scale(1.15);
}

.reaction-option--active[b-cg2uzcfx0g] {
    background: var(--status-green-bg);
}

/* ---- Responsive ---------------------------------------------------------
   El 74% existe para que se vea de un vistazo quién habla: cada burbuja deja
   libre el cuarto del lado contrario. En un teléfono ese cuarto son 90px que
   no sobran — el hilo pasa a ser una columna de tres o cuatro palabras por
   línea. La alineación a izquierda y derecha, más el color, ya distinguen las
   tres voces sin necesidad de tanto aire. */
@media (max-width: 600px) {
    .bubble-wrap[b-cg2uzcfx0g] { max-width: 88%; }

    .bubble[b-cg2uzcfx0g] { padding: 10px 13px; }

    /* La miniatura cuadrada se acomoda al ancho de la burbuja en vez de
       forzarlo: 200px fijos dentro de una burbuja más angosta la desbordan. */
    .bubble-image[b-cg2uzcfx0g] {
        width: min(200px, 100%);
        height: auto;
        aspect-ratio: 1;
    }
}
/* /Components/Shared/PageHeader.razor.rz.scp.css */
.page-header[b-841td31vd9] {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 1.75rem;
    gap: 1rem;
}

.page-header-left[b-841td31vd9] {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.page-header-title[b-841td31vd9] {
    font-family: var(--font-display);
    font-size: var(--text-4xl);
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1.05;
    color: var(--ink);
}

.page-header-subtitle[b-841td31vd9] {
    font-size: var(--text-lg);
    color: var(--ink-soft);
    margin: 0;
}

.page-header-actions[b-841td31vd9] {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-shrink: 0;
}

/* ---- Responsive ---------------------------------------------------------
   Título y acciones en la misma fila necesitan un ancho que en el teléfono no
   existe: el título usa --text-4xl (26px) y los botones tienen flex-shrink:0,
   así que lo que cede es el título, partiéndose en tres líneas al lado de un
   botón. Apilados, cada uno se queda con la fila entera. */
@media (max-width: 600px) {
    .page-header[b-841td31vd9] {
        flex-direction: column;
        align-items: stretch;
        gap: 0.85rem;
        margin-bottom: 1.25rem;
    }

    .page-header-title[b-841td31vd9] { font-size: var(--text-3xl); }

    /* Los botones se reparten el ancho en vez de amontonarse a la izquierda. */
    .page-header-actions[b-841td31vd9]  .app-btn { flex: 1 1 auto; justify-content: center; }
}
/* /Components/Shared/RuleListEditor.razor.rz.scp.css */
/* ── Lista de reglas ──
   Mismo patrón que la lista de sucursales en /devoluciones: una línea por ítem y un formulario
   inline para el que se está editando. Una regla por renglón es lo que hace que veinte reglas se
   lean como una lista y no como el muro de texto que eran cuando vivían en un solo campo.

   Este CSS vivía en AgentPage.razor.css y se mudó con el markup: las tres listas (reglas del
   negocio, escalado de ventas, escalado de devoluciones) tienen que verse iguales, y dos copias del
   mismo bloque en dos páginas divergen al primer retoque. */
.rules-head[b-zqou4egod9] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

/* Copia de .section-title de las páginas: está definido por página y con aislamiento de CSS no
   cruza hasta acá. Si cambia allá, cambia acá. */
.rules-title[b-zqou4egod9] {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 1rem;
}

.rules-hint[b-zqou4egod9] {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--ink-soft);
    max-width: 62ch;
    line-height: 1.5;
}

.rules-form[b-zqou4egod9] {
    padding: 1rem;
    margin-bottom: 1.25rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* El aviso de que la plataforma ya decide eso. Ámbar y no rojo a propósito: la regla se guarda
   igual, no está mal escrita — simplemente no va a hacer lo que el negocio espera. */
.rules-conflict[b-zqou4egod9] {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--status-amber);
    border-radius: var(--radius-md);
    background: var(--status-amber-bg);
    font-size: var(--text-sm);
    line-height: 1.5;
    color: var(--ink);
}

.rules-conflict-tag[b-zqou4egod9] {
    flex-shrink: 0;
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ink-soft);
}

.rules-when[b-zqou4egod9] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.rules-when-label[b-zqou4egod9] {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--ink);
}

.rules-when-options[b-zqou4egod9] {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.rules-triggers[b-zqou4egod9] {
    display: flex;
    align-items: flex-end;
    gap: 0.6rem;
}

.rules-triggers > :first-child[b-zqou4egod9] { flex: 1; min-width: 0; }

/* Aviso neutro, no de error: partir una lista pegada es lo correcto, solo hay que decirlo antes. */
.rules-split[b-zqou4egod9] {
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--brand-line);
    border-radius: var(--radius-md);
    background: var(--brand-soft);
    font-size: var(--text-sm);
    color: var(--brand-text);
}

.rules-error[b-zqou4egod9] {
    font-size: var(--text-sm);
    line-height: 1.5;
    color: var(--status-red);
}

.rules-actions[b-zqou4egod9] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.rules-list[b-zqou4egod9] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.rule[b-zqou4egod9] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    cursor: grab;
}

.rule:active[b-zqou4egod9] { cursor: grabbing; }

/* Los botones no son para arrastrar: con el cursor de agarre encima se lee como que hay que
   arrastrarlos, y son clics. */
.rule-actions[b-zqou4egod9] { cursor: default; }

.rule--off[b-zqou4egod9] { opacity: 0.55; }

/* La regla que se está arrastrando se atenúa, y la de destino muestra dónde va a caer. Sin esto el
   arrastre es invisible: el navegador dibuja el fantasma y nada más. */
.rule--dragging[b-zqou4egod9] { opacity: 0.4; }

.rule--dragover[b-zqou4egod9] {
    border-color: var(--brand);
    box-shadow: inset 0 2px 0 0 var(--brand);
}

/* El número es la posición real en el prompt, no una viñeta: la 1 es la que más se cumple. */
.rule-num[b-zqou4egod9] {
    flex-shrink: 0;
    min-width: 1.5rem;
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
    color: var(--ink-soft);
    text-align: right;
}

.rule-main[b-zqou4egod9] {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    min-width: 0;
    flex: 1;
}

/* Una línea por regla: si el texto es largo se recorta acá y se lee entero al editarla. Lo que
   importa de la lista es poder barrerla de un vistazo, no leerla completa. */
.rule-text[b-zqou4egod9] {
    /* Base 0 para que el texto de la regla sea lo PRIMERO que cede el espacio. Es el que se puede
       leer entero al editarla; el chip, en cambio, es la única pista de por qué una regla entró. */
    flex: 1 1 0;
    min-width: 0;
    font-size: var(--text-md);
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* El chip se limita por ANCHO, no por encogimiento. Con `flex-shrink: 0` una regla con diez
   palabras que la activan empujaba sobre los botones y se montaba encima; dejándolo encoger, en
   cambio, un chip corto como "Siempre" se recortaba a "Siemp…" sin ninguna necesidad, porque flex
   les saca a los dos por igual. El tope de ancho hace lo correcto en los dos casos: el chip corto
   queda entero y el largo se recorta con puntos suspensivos. Las palabras completas están en el
   `title` y al editar la regla. */
.rule-when[b-zqou4egod9] {
    flex: 0 0 auto;
    max-width: 38%;
    min-width: 0;
}

.rule-chip[b-zqou4egod9] {
    display: inline-block;
    max-width: 100%;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    font-size: var(--text-xs);
    color: var(--ink-soft);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
}

.rule-chip--always[b-zqou4egod9] {
    background: var(--brand-soft);
    color: var(--brand-text);
}

.rule-actions[b-zqou4egod9] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
}

/* Las flechas son la salida táctil, no la principal: el drag & drop de HTML5 no dispara con el
   dedo. En desktop se esconden — apretaban la fila y ahí el arrastre alcanza. */
.rule-move[b-zqou4egod9] {
    display: none;
    align-items: center;
    margin-right: 0.35rem;
}

@media (max-width: 900px) {
    .rule-move[b-zqou4egod9] { display: inline-flex; }
}

.rules-order-hint[b-zqou4egod9] {
    margin-bottom: 0.75rem;
}

@media (max-width: 600px) {
    .rules-head[b-zqou4egod9],
    .rule[b-zqou4egod9],
    .rules-triggers[b-zqou4egod9] {
        flex-direction: column;
        align-items: stretch;
    }

    /* El texto de la regla deja de recortarse: con el ítem apilado hay renglones de sobra, y en
       una pantalla angosta el recorte se comía casi toda la regla. */
    .rule-text[b-zqou4egod9] { white-space: normal; }
}
/* /Components/Shared/SkeletonBlock.razor.rz.scp.css */
.skeleton[b-od24om4k6p] {
    width: 100%;
    height: 12px;
    border-radius: var(--radius-sm);
    background: linear-gradient(
        90deg,
        var(--surface-3) 25%,
        var(--surface-hover) 50%,
        var(--surface-3) 75%
    );
    background-size: 200% 100%;
    animation: skeleton-sweep-b-od24om4k6p 1.4s var(--ease) infinite;
}

.skeleton--circle[b-od24om4k6p] {
    border-radius: 50%;
}

.skeleton--block[b-od24om4k6p] {
    height: 100%;
    border-radius: var(--radius-lg);
}

@keyframes skeleton-sweep-b-od24om4k6p {
    from { background-position: 200% 0; }
    to   { background-position: -200% 0; }
}

/* A pulsing placeholder is the exact thing vestibular-sensitive users ask to
   stop. Hold a static tone instead of animating. */
@media (prefers-reduced-motion: reduce) {
    .skeleton[b-od24om4k6p] {
        animation: none;
        background: var(--surface-3);
    }
}
/* /Components/Shared/StatusBadge.razor.rz.scp.css */
/* Mono uppercase pill: status is machine state, and reading it in the data
   voice keeps it from competing with the content next to it. The dot stays —
   it is the only part legible at a glance while scanning a long list. */
.status-badge[b-13ihqmbfyp] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 9px;
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    white-space: nowrap;
}

.status-badge[b-13ihqmbfyp]::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* AI active — the live house voice */
.status-badge--ai[b-13ihqmbfyp] { background: var(--brand-soft); color: var(--brand-text); }
.status-badge--ai[b-13ihqmbfyp]::before { background: var(--brand); animation: pulse-dot-b-13ihqmbfyp 2s infinite; }

/* Human takeover — coral */
.status-badge--human[b-13ihqmbfyp] { background: var(--coral-soft); color: var(--coral-deep); }
.status-badge--human[b-13ihqmbfyp]::before { background: var(--coral); }

/* La IA pidió ayuda y sigue contestando — ámbar: no es un traspaso, es un "mirá esto".
   El color va por token y NO por un hex fijo: un olivo hardcodeado sobre el fondo ámbar daba
   ~2,3:1 en tema oscuro, así que el único badge que el operador no se puede perder era justo el
   que desaparecía. --status-amber tiene un valor por tema. */
.status-badge--attention[b-13ihqmbfyp] { background: var(--status-amber-bg); color: var(--status-amber); }
.status-badge--attention[b-13ihqmbfyp]::before { background: var(--status-amber); }

/* Open — neutral stone */
.status-badge--open[b-13ihqmbfyp] { background: var(--status-blue-bg); color: var(--ink-soft); }
.status-badge--open[b-13ihqmbfyp]::before { background: var(--status-blue); }

.status-badge--pending[b-13ihqmbfyp] { background: var(--status-amber-bg); color: var(--status-amber); }
.status-badge--pending[b-13ihqmbfyp]::before { background: var(--status-amber); }

.status-badge--closed[b-13ihqmbfyp] { background: var(--surface-3); color: var(--ink-muted); }
.status-badge--closed[b-13ihqmbfyp]::before { background: var(--ink-muted); }

/* Message delivery states */
.status-badge--sent[b-13ihqmbfyp] { background: var(--status-blue-bg); color: var(--ink-soft); }
.status-badge--sent[b-13ihqmbfyp]::before { background: var(--status-blue); }

.status-badge--delivered[b-13ihqmbfyp] { background: var(--status-green-bg); color: var(--status-green); }
.status-badge--delivered[b-13ihqmbfyp]::before { background: var(--status-green); }

.status-badge--read[b-13ihqmbfyp] { background: var(--brand-soft); color: var(--brand-text); }
.status-badge--read[b-13ihqmbfyp]::before { background: var(--brand); }

.status-badge--failed[b-13ihqmbfyp] { background: var(--status-red-bg); color: var(--status-red); }
.status-badge--failed[b-13ihqmbfyp]::before { background: var(--status-red); }

@keyframes pulse-dot-b-13ihqmbfyp {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.45; transform: scale(0.85); }
}
/* /Components/Shared/ThemeToggle.razor.rz.scp.css */
/* Sits next to the business selector in the top bar, so it matches that
   control's height rather than inventing its own. Icon-only: a label would
   compete with the selector for attention and this is a preference, not an
   action anyone hunts for. */
.theme-toggle[b-mrm8eii2js] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--ink-soft);
    cursor: pointer;
    transition: background var(--transition-fast),
                color var(--transition-fast),
                border-color var(--transition-fast);
}

.theme-toggle:hover[b-mrm8eii2js] {
    background: var(--surface-hover);
    border-color: var(--ink-muted);
    color: var(--ink);
}

.theme-toggle:active[b-mrm8eii2js] {
    transform: translateY(1px);
}

.theme-toggle svg[b-mrm8eii2js] {
    display: block;
}
