/* /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 */
/* Lo que muestra el ErrorBoundary cuando una pantalla se cae. Va en el lugar del contenido, para que
   se lea como "esta pantalla falló" y no como la app entera. */
.page-error[b-d0xna3yqt3] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 560px;
    margin: 2rem auto;
    padding: 1rem 1.25rem;
    border-radius: var(--radius-md);
    background: var(--status-red-bg);
    color: var(--ink);
    font-size: var(--text-md);
}

.page-error strong[b-d0xna3yqt3] {
    color: var(--status-red);
}

.page-error-actions[b-d0xna3yqt3] {
    display: flex;
    justify-content: flex-end;
    padding-top: 0.25rem;
}

.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);
}

/* El atajo para llenar el aviso de primer contacto. Es un <button> escrito EN la página y no un
   <AppButton> a propósito: así el selector se compila con el [b-…] de esta página y pega sobre el
   elemento real, sin ::deep y sin depender de dónde ponga su root un componente hijo. */
.suggest-row[b-bpeehdipa3] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    margin-top: -0.25rem;
}

.suggest-link[b-bpeehdipa3] {
    font: inherit;
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--brand-text);
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    text-decoration: underline;
}

.suggest-link:hover[b-bpeehdipa3] {
    color: var(--brand-hover);
}

.suggest-sample[b-bpeehdipa3] {
    font-size: var(--text-md);
    color: var(--ink-soft);
    /* Una sugerencia larga no puede empujar la tarjeta a lo ancho. */
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Los "casos típicos" del escalado. Se renderizan DENTRO de RuleListEditor (por su BeforeList),
   pero el marcado está escrito en esta página, así que lleva el [b-…] de AgentPage y estas reglas
   pegan sin ::deep. Son <button> nativos por lo mismo que .suggest-link: un <AppButton> pondría su
   propio root con otro scope y cualquier regla de acá sobre él quedaría muerta. */
.presets[b-bpeehdipa3] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 1rem;
}

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

.presets-row[b-bpeehdipa3] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    min-width: 0;
}

.preset-chip[b-bpeehdipa3] {
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--brand-text);
    background: var(--brand-soft);
    border: 1px solid var(--brand-line);
    border-radius: 999px;
    padding: 0.3rem 0.75rem;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--transition-fast);
}

.preset-chip:hover:not(:disabled)[b-bpeehdipa3] {
    background: var(--surface-hover);
}

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

.preset-chip:disabled[b-bpeehdipa3] {
    opacity: 0.6;
    cursor: default;
}

.presets-error[b-bpeehdipa3] {
    width: 100%;
    font-size: var(--text-sm);
    color: var(--status-red);
}

.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;
}

.save-error[b-bpeehdipa3] {
    font-size: var(--text-base);
    color: var(--status-red);
    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;
}

/* Chart and table stacked in one panel: the chart ends on its axis labels and the
   table starts on its header row, so without this they touch. */
.an-table-scroll--after-chart[b-qnr0t1lrlf] {
    margin-top: 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;
}

/* El filtro y el buscador se fueron a InboxFilterBar, que trae su propio CSS aislado. Acá no quedó
   nada: el componente ya se encarga de no irse de pantalla cuando se scrollea la bandeja, porque
   .conv-sidebar es una columna flex y sólo .conv-list tiene overflow. */

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

.conv-more[b-5ma7dah5tt] {
    display: flex;
    justify-content: center;
    padding: 12px 1rem 4px;
}

/* ---- 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); }

/* El bot derivó y dejó de responder, y todavía no lo agarró nadie. Ámbar y no coral: es "alguien
   tiene que atender esto", no "alguien ya lo está atendiendo". Y el punto NO pulsa — pulsar es lo
   que dice que hay algo vivo del otro lado, que es justamente lo que dejó de haber. */
.drive-state--paused[b-5ma7dah5tt] {
    background: var(--status-amber-bg);
    color: var(--status-amber);
}
.drive-state--paused .drive-dot[b-5ma7dah5tt] { background: var(--status-amber); }

@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;
}

/* Puerta a la historia anterior, arriba de la primera burbuja y adentro del scroll.
   flex-shrink: 0 porque .thread-messages es una columna flex y con pocos mensajes el botón
   se aplastaría hasta desaparecer. */
.thread-older[b-5ma7dah5tt] {
    display: flex;
    justify-content: center;
    flex-shrink: 0;
    padding-bottom: 1rem;
}

.thread-older-btn[b-5ma7dah5tt] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink-soft);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    transition: background 120ms, color 120ms;
}

.thread-older-btn:hover:not(:disabled)[b-5ma7dah5tt] {
    background: var(--brand-soft);
    color: var(--brand-text);
}

.thread-older-btn:disabled[b-5ma7dah5tt] {
    cursor: default;
    opacity: 0.65;
}

/* 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;
}

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

/* El ancla del scroll: un <div> vacío escrito en esta página. scroll-margin deja aire arriba para
   que el título del editor no quede pegado al borde (o debajo de la barra superior). */
.kb-editor-anchor[b-3vq64ulbwa] {
    scroll-margin-top: 1rem;
}

.kb-editor-note[b-3vq64ulbwa] {
    margin: 0.2rem 0 0.9rem;
    font-size: var(--text-sm);
    color: var(--status-amber, #b45309);
    line-height: 1.45;
}

.kb-section-sub[b-3vq64ulbwa] {
    margin: 0.1rem 0 0;
    font-size: var(--text-sm);
    color: var(--ink-soft);
    line-height: 1.45;
    max-width: 60rem;
}

/* ── Preguntas que el bot no supo contestar ── */

.kb-q[b-3vq64ulbwa] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.9rem 0;
    border-top: 1px solid var(--line);
    min-width: 0;
}

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

.kb-q-meta[b-3vq64ulbwa] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

.kb-q-contact[b-3vq64ulbwa] {
    font-weight: 600;
    color: var(--ink);
    min-width: 0;
    overflow-wrap: anywhere;
}

.kb-q-tag[b-3vq64ulbwa] {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--brand-text);
    background: var(--brand-soft);
    border-radius: 999px;
    padding: 0.1rem 0.55rem;
}

.kb-q-block[b-3vq64ulbwa] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.kb-q-label[b-3vq64ulbwa] {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
}

.kb-q-text[b-3vq64ulbwa] {
    margin: 0;
    font-size: var(--text-md);
    color: var(--ink);
    line-height: 1.45;
    /* La respuesta de una persona viene en varios mensajes, uno por renglón. */
    white-space: pre-line;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 5;
    line-clamp: 5;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.kb-q-answer[b-3vq64ulbwa] {
    padding-left: 0.75rem;
    border-left: 3px solid var(--brand-line);
}

.kb-q-none[b-3vq64ulbwa] {
    color: var(--ink-muted);
    font-style: italic;
}

.kb-q-reason[b-3vq64ulbwa] {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.kb-q-actions[b-3vq64ulbwa] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.9rem;
    margin-top: 0.15rem;
}

/* Un <a> y no un botón: es navegación, y así se puede abrir en otra pestaña con el medio del mouse. */
.kb-q-link[b-3vq64ulbwa] {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--brand-text);
    text-decoration: underline;
}

.kb-q-link:hover[b-3vq64ulbwa] {
    color: var(--brand-hover);
}

/* ── Temas que el bot necesita ── */

.kb-topics[b-3vq64ulbwa] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.kb-topic[b-3vq64ulbwa] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.75rem 0;
    border-top: 1px solid var(--line);
    flex-wrap: wrap;
}

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

.kb-topic-mark[b-3vq64ulbwa] {
    flex-shrink: 0;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: var(--text-sm);
}

.kb-topic-mark.is-covered[b-3vq64ulbwa] {
    color: var(--status-green);
    background: var(--success-soft, rgba(22, 163, 74, 0.12));
}

.kb-topic-mark.is-partial[b-3vq64ulbwa] {
    color: var(--status-amber, #b45309);
    background: var(--warning-soft, rgba(217, 119, 6, 0.12));
}

.kb-topic-mark.is-missing[b-3vq64ulbwa] {
    color: var(--status-red);
    background: var(--danger-soft, rgba(220, 38, 38, 0.1));
}

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

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

.kb-topic-status[b-3vq64ulbwa] {
    font-size: var(--text-sm);
    font-weight: 500;
    overflow-wrap: anywhere;
}

.kb-topic-status.is-covered[b-3vq64ulbwa] {
    color: var(--status-green);
}

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

.kb-topic-status.is-missing[b-3vq64ulbwa] {
    color: var(--status-red);
    font-weight: 700;
}

.kb-topic-why[b-3vq64ulbwa] {
    margin-top: 0.15rem;
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

.kb-topic-actions[b-3vq64ulbwa] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    flex-shrink: 0;
}

.kb-topics-note[b-3vq64ulbwa] {
    margin: 0.9rem 0 0;
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

@media (max-width: 600px) {
    .kb-item-actions[b-3vq64ulbwa],
    .kb-item-confirm[b-3vq64ulbwa] {
        width: 100%;
    }

    /* Las acciones del tema bajan abajo del texto, alineadas con él y no con la marca. */
    .kb-topic-actions[b-3vq64ulbwa] {
        width: 100%;
        padding-left: calc(1.6rem + 0.75rem);
    }
}
/* /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%; }
}

/* Texto explicativo arriba del interruptor de notificaciones. Existe porque "avisarme cuando la
   IA pida ayuda" no dice QUÉ va a llegar ni cada cuánto, y sin eso el primer reflejo ante un
   mail inesperado es apagarlo. */
.perfil-hint[b-bic8wrrqu7] {
    margin: 0 0 14px;
    color: var(--text-muted, #6b7280);
    font-size: 13px;
    line-height: 1.5;
}
/* /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/ContactTagPicker.razor.rz.scp.css */
/* La franja de etiquetas del hilo. Vive debajo del encabezado, en la misma zona donde ya aparece
   el motivo de una derivación: es información sobre el cliente, no una acción del chat. */
.ctp[b-xr6oxrn5b3] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px 10px;
    padding: 0.5rem 1.5rem;
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
}

.ctp-label[b-xr6oxrn5b3] {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-muted);
    flex-shrink: 0;
}

.ctp-current[b-xr6oxrn5b3] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
}

.ctp-empty[b-xr6oxrn5b3] {
    font-size: var(--text-sm);
    color: var(--ink-muted);
}

/* El ancla del popover. position: relative acá y no en .ctp, para que el panel se alinee con el
   botón y no con el borde de la franja. */
.ctp-anchor[b-xr6oxrn5b3] { position: relative; }

.ctp-add[b-xr6oxrn5b3] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px 3px 7px;
    border: 1px dashed var(--line);
    border-radius: var(--radius-pill);
    background: none;
    color: var(--ink-muted);
    font: inherit;
    font-size: var(--text-xs);
    font-weight: 650;
    cursor: pointer;
    transition: border-color var(--transition-fast), color var(--transition-fast);
}

/* Borde punteado a propósito: dice "acá va algo que todavía no está", que es distinto de un chip
   real. Es la misma señal que usa cualquier editor para un slot vacío. */
.ctp-add:hover[b-xr6oxrn5b3] {
    border-color: var(--brand-line);
    border-style: solid;
    color: var(--brand-text);
}

.ctp-add:focus-visible[b-xr6oxrn5b3] {
    outline: 2px solid var(--brand-text);
    outline-offset: 2px;
}

.ctp-backdrop[b-xr6oxrn5b3] {
    position: fixed;
    inset: 0;
    z-index: 30;
    border: none;
    padding: 0;
    background: none;
    cursor: default;
}

.ctp-pop[b-xr6oxrn5b3] {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 31;
    width: 260px;
    max-width: calc(100vw - 32px);
    padding: 6px;
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    background: var(--surface);
    box-shadow: var(--shadow-lg);
}

.ctp-list[b-xr6oxrn5b3] {
    list-style: none;
    margin: 0;
    padding: 0;
    /* Con el tope de 12 etiquetas nunca hay que scrollear mucho, pero el max-height evita que un
       popover llegue al borde de la pantalla en un teléfono apaisado. */
    max-height: 280px;
    overflow-y: auto;
}

.ctp-row[b-xr6oxrn5b3] {
    display: flex;
    align-items: center;
    gap: 2px;
}

.ctp-row-main[b-xr6oxrn5b3] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
    /* 40px: el mínimo táctil de WCAG 2.5.5 es 44 y la fila entera —con sus herramientas— lo
       alcanza. Toda la fila es el blanco, no un checkbox de 14px. */
    min-height: 40px;
    padding: 0 8px;
    border: none;
    border-radius: var(--radius-lg);
    background: none;
    color: var(--ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background var(--transition-fast);
}

.ctp-row-main:hover[b-xr6oxrn5b3] { background: var(--surface-hover); }

.ctp-row-main:focus-visible[b-xr6oxrn5b3] {
    outline: 2px solid var(--brand-text);
    outline-offset: -2px;
}

.ctp-row.is-on .ctp-row-main[b-xr6oxrn5b3] { background: var(--brand-soft); }

.ctp-check[b-xr6oxrn5b3] {
    margin-left: auto;
    color: var(--brand-text);
    display: inline-flex;
}

.ctp-usage[b-xr6oxrn5b3] {
    margin-left: auto;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    color: var(--ink-muted);
    font-size: var(--text-2xs);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.ctp-row-tools[b-xr6oxrn5b3] {
    display: flex;
    gap: 1px;
    flex-shrink: 0;
}

.ctp-tool[b-xr6oxrn5b3] {
    width: 28px;
    height: 28px;
    border: none;
    border-radius: var(--radius-md);
    background: none;
    color: var(--ink-muted);
    font-size: var(--text-md);
    line-height: 1;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.ctp-tool:hover[b-xr6oxrn5b3] {
    background: var(--surface-hover);
    color: var(--ink);
}

.ctp-tool:focus-visible[b-xr6oxrn5b3] {
    outline: 2px solid var(--brand-text);
    outline-offset: -2px;
}

.ctp-tool--danger:hover[b-xr6oxrn5b3] {
    background: var(--status-red-bg);
    color: var(--status-red);
}

.ctp-foot[b-xr6oxrn5b3] {
    display: flex;
    gap: 4px;
    margin-top: 4px;
    padding-top: 6px;
    border-top: 1px solid var(--line);
}

.ctp-foot-btn[b-xr6oxrn5b3] {
    flex: 1;
    min-height: 34px;
    padding: 0 8px;
    border: none;
    border-radius: var(--radius-lg);
    background: none;
    color: var(--brand-text);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 650;
    cursor: pointer;
    transition: background var(--transition-fast);
}

.ctp-foot-btn:hover:not(:disabled)[b-xr6oxrn5b3] { background: var(--brand-soft); }

.ctp-foot-btn:disabled[b-xr6oxrn5b3] {
    cursor: default;
    color: var(--ink-muted);
}

.ctp-foot-btn:focus-visible[b-xr6oxrn5b3] {
    outline: 2px solid var(--brand-text);
    outline-offset: -2px;
}

/* ---- Formulario de crear/editar ---- */
.ctp-form[b-xr6oxrn5b3] {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 6px;
}

.ctp-swatches[b-xr6oxrn5b3] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Los siete colores, cada uno leyendo su token — ningún hex vive en este archivo, por el mismo
   motivo que en TagChip: un color escrito acá sería un lugar más donde calibrar el modo oscuro. */
.ctp-swatch[b-xr6oxrn5b3] {
    width: 26px;
    height: 26px;
    border: 2px solid transparent;
    border-radius: 50%;
    cursor: pointer;
    transition: transform var(--transition-fast), border-color var(--transition-fast);
}

.ctp-swatch:hover[b-xr6oxrn5b3] { transform: scale(1.12); }

.ctp-swatch:focus-visible[b-xr6oxrn5b3] {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
}

/* El elegido se marca con un anillo de tinta y no agrandándolo: sobre siete círculos del mismo
   tamaño, "uno más grande" se lee como hover y no como elección. */
.ctp-swatch.is-selected[b-xr6oxrn5b3] {
    border-color: var(--ink);
    transform: scale(1.12);
}

.ctp-swatch--0[b-xr6oxrn5b3] { background: var(--tag-0); }
.ctp-swatch--1[b-xr6oxrn5b3] { background: var(--tag-1); }
.ctp-swatch--2[b-xr6oxrn5b3] { background: var(--tag-2); }
.ctp-swatch--3[b-xr6oxrn5b3] { background: var(--tag-3); }
.ctp-swatch--4[b-xr6oxrn5b3] { background: var(--tag-4); }
.ctp-swatch--5[b-xr6oxrn5b3] { background: var(--tag-5); }
.ctp-swatch--6[b-xr6oxrn5b3] { background: var(--tag-6); }

.ctp-actions[b-xr6oxrn5b3] {
    display: flex;
    gap: 6px;
}

.ctp-note[b-xr6oxrn5b3] {
    padding: 8px 10px;
    color: var(--ink-soft);
    font-size: var(--text-sm);
    line-height: 1.45;
}

.ctp-error[b-xr6oxrn5b3] {
    margin-top: 4px;
    padding: 7px 10px;
    border-radius: var(--radius-lg);
    background: var(--status-red-bg);
    color: var(--status-red);
    font-size: var(--text-sm);
    line-height: 1.4;
}

/* ---- Teléfono ----
   El popover se ancla a la izquierda del botón y con 260px de ancho se saldría de pantalla cuando
   el botón queda cerca del borde derecho. Acá se ancla al borde opuesto. */
@media (max-width: 600px) {
    .ctp[b-xr6oxrn5b3] {
        padding: 0.5rem 0.75rem;
        gap: 4px 8px;
    }

    .ctp-pop[b-xr6oxrn5b3] {
        left: auto;
        right: 0;
    }
}
/* /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);
}

/* Mismo criterio que en la burbuja: entregado y leído comparten glifo, así que el color no puede
   ser lo único que los distinga. */
.conv-tick--read[b-ah24zaf23j] {
    color: #34B7F1;
    font-weight: 700;
}

.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;
}

/* Tercer renglón: etiquetas del cliente y de quién es el chat. Sólo se renderiza cuando hay algo,
   así que una bandeja sin etiquetas ni asignaciones se ve exactamente como antes — la fila no
   crece "por si acaso".

   nowrap y overflow oculto: con el tope de 3 etiquetas por cliente esto entra en 360px, pero un
   nombre largo sumado a un operador puede pasarse, y lo que NO puede pasar es que la fila crezca a
   dos renglones y la lista deje de tener filas parejas. */
.item-meta[b-ah24zaf23j] {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 1px;
    overflow: hidden;
}

.item-owner[b-ah24zaf23j] {
    flex-shrink: 0;
    margin-left: auto;
    padding-left: 4px;
    font-size: var(--text-2xs);
    font-weight: 600;
    color: var(--ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 40%;
}

.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/InboxFilterBar.razor.rz.scp.css */
/* La barra vive entre el encabezado y la lista, y su presupuesto es el alto que le saca a la
   bandeja. Todo lo de acá está calibrado para que, plegada, ocupe dos renglones. */
.ifb[b-ennyh1hw4r] {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 1.4rem;
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
}

/* ---- Buscador ---- */
.ifb-search[b-ennyh1hw4r] {
    position: relative;
    display: flex;
    align-items: center;
}

.ifb-search-icon[b-ennyh1hw4r] {
    position: absolute;
    left: 10px;
    color: var(--ink-muted);
    pointer-events: none;
}

.ifb-search-input[b-ennyh1hw4r] {
    width: 100%;
    font: inherit;
    /* 16px y no menos: abajo de eso, iOS hace zoom al enfocar el campo y descuadra la pantalla.
       Es la misma razón por la que app.css fuerza ese tamaño en el resto de los inputs. */
    font-size: 16px;
    padding: 7px 10px 7px 32px;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    color: inherit;
}

.ifb-search-input:focus-visible[b-ennyh1hw4r] {
    outline: 2px solid var(--brand-text);
    outline-offset: -1px;
    border-color: transparent;
}

.ifb-search-input[b-ennyh1hw4r]::placeholder { color: var(--ink-muted); }

/* Chrome dibuja su propia X de "search" y queda encimada con el padding del ícono. */
.ifb-search-input[b-ennyh1hw4r]::-webkit-search-cancel-button { cursor: pointer; }

@media (min-width: 900px) {
    /* En escritorio el zoom de iOS no existe y 16px se ve enorme al lado del resto del panel. */
    .ifb-search-input[b-ennyh1hw4r] { font-size: 13px; }
}

/* ---- Chips de estado ----
   En el TELÉFONO scrollean en horizontal en vez de envolver: envolviendo, seis chips ocupan tres
   renglones y la barra se come la lista, que es lo que el vendedor vino a mirar. El scroll además
   conserva el orden, así lo urgente queda siempre a la izquierda, donde el ojo cae.

   ⚠️ En ESCRITORIO envuelven, y eso arregla un bug que reportó el comerciante con una captura:
   sólo podía apretar los dos primeros chips. Este bloque estaba escrito desde el teléfono y
   aplicado a las dos pantallas, cuando el gesto que lo hace funcionar existe en una sola. Los seis
   chips miden ~790px en fila y el sidebar es una columna FIJA de 360px (320px abajo de 1100), o
   sea ~314px de contenido: "Con una persona", "La IA responde" y "Cerradas" quedaban afuera. Y
   `scrollbar-width: none` + `::-webkit-scrollbar { display: none }` les sacaba además la barra,
   que en escritorio es el único modo de llegar Y el único indicio de que hay más. Con un mouse
   común no hay dedo que arrastre: quedaba shift+rueda, que nadie descubre.

   Y no se arregla con una pantalla más grande, que es lo que lo vuelve un bug y no una
   incomodidad: esos 360px son FIJOS, así que en un monitor 4K falta exactamente lo mismo.

   El umbral es 900px porque es el MISMO del layout (Conversations.razor.css): ahí el sidebar deja
   de ser una columna angosta al lado del hilo y pasa a ocupar la pantalla entera. O sea que no
   separa "chico" de "grande" — separa "hay dedo" de "hay mouse", que es justo la condición de la
   que depende el scroll.

   Cuesta dos renglones de alto y se pagan: el argumento ya está escrito más abajo para las
   facetas, "un filtro que no se puede leer no se aprieta". Uno que no se puede ALCANZAR vale
   todavía menos, y eran tres de seis. */
.ifb-chips[b-ennyh1hw4r] {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    /* Sin esto, los chips se aplastan hasta que "Con una persona" dice "Con una…". */
    scrollbar-width: none;
    padding-bottom: 2px;
    /* Deja el chip elegido alineado al borde cuando se lo toca desde el teclado o el dedo. */
    scroll-snap-type: x proximity;
}

.ifb-chips[b-ennyh1hw4r]::-webkit-scrollbar { display: none; }

/* Escritorio: columna fija y sin dedo, así que envuelven. Se apaga TODO el aparato de scroll y no
   sólo se prende el wrap, porque un contenedor de scroll sin desbordamiento igual recorta el
   outline del :focus-visible — y estos chips se navegan con el teclado. */
@media (min-width: 901px) {
    .ifb-chips[b-ennyh1hw4r] {
        flex-wrap: wrap;
        overflow-x: visible;
        scroll-snap-type: none;
        padding-bottom: 0;
    }
}

.ifb-chip[b-ennyh1hw4r] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
    scroll-snap-align: start;
    padding: 5px 10px 5px 11px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--ink-soft);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast),
                border-color var(--transition-fast);
}

.ifb-chip:hover[b-ennyh1hw4r] {
    background: var(--surface-hover);
    color: var(--ink);
}

.ifb-chip:focus-visible[b-ennyh1hw4r] {
    outline: 2px solid var(--brand-text);
    outline-offset: 1px;
}

.ifb-chip.is-selected[b-ennyh1hw4r] {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--on-brand);
}

/* El contador. Vive dentro del chip y con su propio fondo para que se lea como un número y no como
   parte del nombre — "Piden ayuda 3" sin separar se lee "Piden ayuda3". */
.ifb-chip-count[b-ennyh1hw4r] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 17px;
    padding: 0 4px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    color: var(--ink-muted);
    font-size: var(--text-2xs);
    font-weight: 700;
    line-height: 16px;
}

.ifb-chip.is-selected .ifb-chip-count[b-ennyh1hw4r] {
    background: rgba(255, 255, 255, 0.22);
    color: var(--on-brand);
}

/* "Piden ayuda" CON algo adentro es lo único de esta barra que pide una acción AHORA, así que su
   número se pinta con la señal de traspaso —el mismo ámbar que la fila y el header del hilo— en vez
   de quedar en gris junto a los demás. Quién lleva la clase lo decide el componente, porque el CSS
   no sabe leer un número y un cero en ámbar sería una alarma sobre algo que está bien. */
.ifb-chip--alert:not(.is-selected)[b-ennyh1hw4r] {
    border-color: var(--coral-line);
}

.ifb-chip--alert:not(.is-selected) .ifb-chip-count[b-ennyh1hw4r] {
    background: var(--status-amber-bg);
    color: var(--status-amber);
}

/* ---- Más filtros / limpiar ---- */
.ifb-more[b-ennyh1hw4r] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    /* Renglón de servicio: no compite con los chips. */
    min-height: 20px;
}

.ifb-more-btn[b-ennyh1hw4r],
.ifb-clear[b-ennyh1hw4r] {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 0;
    border: none;
    background: none;
    color: var(--ink-muted);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    transition: color var(--transition-fast);
}

.ifb-more-btn:hover:not(:disabled)[b-ennyh1hw4r],
.ifb-clear:hover[b-ennyh1hw4r] { color: var(--brand-text); }

.ifb-more-btn:focus-visible[b-ennyh1hw4r],
.ifb-clear:focus-visible[b-ennyh1hw4r] {
    outline: 2px solid var(--brand-text);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* Deshabilitado mientras haya una faceta puesta: plegarlas escondería un filtro activo, que es
   exactamente cómo se llega a "mi bandeja está vacía y no sé por qué". La salida es "Limpiar
   todo", que está al lado. */
.ifb-more-btn:disabled[b-ennyh1hw4r] {
    cursor: default;
    color: var(--brand-text);
}

.ifb-clear[b-ennyh1hw4r] { color: var(--coral-deep); }

/* ---- Las dos facetas ----
   Una por renglón, y no mitad y mitad. La columna de la bandeja mide 360px FIJOS en escritorio
   (.conv-sidebar), o sea ~313px de contenido: partida al medio deja 153px por desplegable, y
   "Cualquier operador" entra como "Cualquier opera…". Un filtro que no se puede leer no se
   aprieta. El renglón de más sólo aparece con las facetas ABIERTAS, así que el presupuesto de dos
   renglones de la barra plegada no se mueve. */
.ifb-facets[b-ennyh1hw4r] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* ⚠️ `::deep` Y nombrar `.app-select`: hacen falta las dos cosas, y es la trampa que este repo ya
   documenta para <Card>.

   AppSelect renderiza su propio <div> root, que lleva SU scope y no el de este componente, así que
   la regla que había acá —`.ifb-facets > * { flex: 1 1 0; min-width: 0 }`— compilaba a
   `.ifb-facets > *[b-xxx]` y no matcheaba NADA: muerta en silencio. Con ella muerta mandaba
   `.app-select--pill { min-width: 200px }`, o sea dos desplegables pidiendo 406px dentro de una
   columna de 313px — y las facetas se salían por debajo del hilo. Lo reportó el comerciante el
   2026-09-21 con una captura. ConversationListItem ya lo resuelve así para StatusBadge.

   Nombrar la clase además le gana en especificidad al min-width del propio AppSelect, que se
   bundlea después y con `> *` habría ganado igual.

   Y achicarlo no pierde nada: `.app-select-value` ya recorta con ellipsis. Es el mismo argumento
   que AppSelect escribe en su media query de 600px —"un piso que el contenedor no puede respetar"—
   sólo que acá el disparador no es el viewport sino el ancho fijo de la columna, así que ese
   media query no podía cubrirlo. */
.ifb-facets[b-ennyh1hw4r]  .app-select {
    min-width: 0;
}

/* ---- Teléfono ----
   Mismo criterio que el resto de la lista abajo de 600px: se recorta el chrome, nunca el dato. Los
   chips siguen enteros —un chip a medio leer no se puede apretar con confianza— y lo que cede es el
   padding de la barra. */
@media (max-width: 600px) {
    .ifb[b-ennyh1hw4r] {
        padding: 8px 12px;
        gap: 7px;
    }
}
/* /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.

   Entregado y leído comparten el mismo glifo (✓✓), así que el color es lo ÚNICO que los separa y
   tiene que verse: por eso además del celeste va en negrita. Con el color solo, la diferencia
   dependía de distinguir dos tonos de un tilde de 11px. */
.bubble-status-icon--read[b-cg2uzcfx0g] {
    color: #34B7F1;
    opacity: 1;
    font-weight: 700;
}

/* Y sobre el relleno teal de la burbuja de la IA el celeste de WhatsApp queda casi encima del
   fondo: ahí se aclara, igual que ya se hacía con el rojo del fallo. Sin esto, en la mitad de las
   burbujas del panel —las del bot— leído y entregado se veían idénticos. */
.bubble--ai .bubble-status-icon--read[b-cg2uzcfx0g] {
    color: #C9F0FF;
}

/* 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;
}

/* Unlike a photo, a video is not cropped to a square: a clip the customer filmed
   is usually vertical, and cropping it would hide exactly the part being shown.
   Fixed width, natural aspect ratio, capped height so a 9:16 clip does not take
   over the thread; the black letterbox is what the native controls sit on. */
.bubble-video[b-cg2uzcfx0g] {
    width: 260px;
    max-width: 100%;
    max-height: 340px;
    border-radius: 10px;
    background: #000;
    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;
    }

    .bubble-video[b-cg2uzcfx0g] {
        width: min(260px, 100%);
        max-height: 60vh;
    }
}
/* /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); }

/* El bot se derivó solo y dejó de contestar: nadie lo agarró todavía. */
.status-badge--paused[b-13ihqmbfyp] { background: var(--status-amber-bg); color: var(--status-amber); }
.status-badge--paused[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/TagChip.razor.rz.scp.css */
/* El color no se escribe en ninguna regla: cada modificador sólo redirige dos variables locales a
   los tokens --tag-N de app.css, que ya están calibrados para tema claro y oscuro. Así el chip
   tiene UNA definición de forma y siete de color, en vez de siete copias de la forma. */
.tag-chip[b-lgc35rpof2] {
    --chip: var(--tag-0);
    --chip-soft: var(--tag-0-soft);

    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: var(--chip-soft);
    color: var(--chip);
    font-size: var(--text-xs);
    font-weight: 650;
    line-height: 1.5;
    white-space: nowrap;
}

.tag-chip--0[b-lgc35rpof2] { --chip: var(--tag-0); --chip-soft: var(--tag-0-soft); }
.tag-chip--1[b-lgc35rpof2] { --chip: var(--tag-1); --chip-soft: var(--tag-1-soft); }
.tag-chip--2[b-lgc35rpof2] { --chip: var(--tag-2); --chip-soft: var(--tag-2-soft); }
.tag-chip--3[b-lgc35rpof2] { --chip: var(--tag-3); --chip-soft: var(--tag-3-soft); }
.tag-chip--4[b-lgc35rpof2] { --chip: var(--tag-4); --chip-soft: var(--tag-4-soft); }
.tag-chip--5[b-lgc35rpof2] { --chip: var(--tag-5); --chip-soft: var(--tag-5-soft); }
.tag-chip--6[b-lgc35rpof2] { --chip: var(--tag-6); --chip-soft: var(--tag-6-soft); }

/* El punto es lo único que se pinta con el color pleno. Sobre el fondo tenue no hay texto blanco
   en ninguna parte, así que no hace falta un token "on-tag" y no hay contraste que calibrar. */
.tag-chip-dot[b-lgc35rpof2] {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--chip);
    flex-shrink: 0;
}

.tag-chip-name[b-lgc35rpof2] {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Dentro de una lista que ya se tiñe al seleccionar, el fondo del chip se pelea con el de la fila
   y el resultado es barro. Ahí queda el punto y el nombre, que es lo que de verdad identifica. */
.tag-chip--plain[b-lgc35rpof2] {
    background: none;
    padding-left: 0;
    padding-right: 0;
    color: inherit;
}

/* La fila de la bandeja: el chip comparte renglón con el preview del mensaje, y el mensaje es lo
   que el vendedor lee. Todo lo que se puede recortar sin perder el nombre, se recorta. */
.tag-chip--sm[b-lgc35rpof2] {
    gap: 4px;
    padding: 1px 6px;
    font-size: var(--text-2xs);
    font-weight: 700;
}

.tag-chip--sm .tag-chip-dot[b-lgc35rpof2] {
    width: 5px;
    height: 5px;
}

.tag-chip-remove[b-lgc35rpof2] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 18px y no 44: no es un control primario, y acá el mínimo táctil se cumple de otra forma —
       la lista del picker tiene su propia fila de 44px para poner y sacar con el dedo. Este "×" es
       el atajo de escritorio sobre un chip que ya está a la vista. */
    width: 14px;
    height: 14px;
    margin-left: 1px;
    margin-right: -3px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: none;
    color: inherit;
    opacity: 0.6;
    cursor: pointer;
    transition: opacity var(--transition-fast), background var(--transition-fast);
}

.tag-chip-remove:hover[b-lgc35rpof2] {
    opacity: 1;
    background: var(--chip-soft);
}

.tag-chip-remove:focus-visible[b-lgc35rpof2] {
    opacity: 1;
    outline: 2px solid currentColor;
    outline-offset: 1px;
}
/* /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;
}
