/*!
 * BanaTheme — F1c: reskin "Lagom limpio" (tokens claros + tipografia Roboto)
 * Tema hijo de Twenty-One. Esta hoja es una CAPA (skin) sobre Bootstrap 4.5 /
 * theme.css de Twenty-One: no reemplaza esas hojas, solo las restiliza.
 * Solo modo claro por ahora.
 */

/* ============================================================
   Tipografia: Roboto del sistema/plataforma (SIN CDN externo).
   No hay woff2 de Roboto auto-hospedado en este repo ni en el kit de
   Lagom2 (whmcs-actualizacion-y-diseno / lagom2-audit): ahi "Roboto"
   solo aparece como fallback dentro del stack de fuentes del sistema de
   Bootstrap (theme.css linea 41), nunca como @font-face propio con
   Google Fonts u otro CDN. Se replica ese mismo patron: en Android/Chrome
   OS el navegador ya trae Roboto como fuente nativa del SO y el stack la
   resuelve directo; en macOS/Windows/iOS cae al siguiente fallback nativo
   (-apple-system/system-ui), que es visualmente muy cercano y evita
   Google Fonts. El bloque @font-face de Montserrat se elimina: ya no se
   usa (unico consumidor era --bt-font); los woff2 quedan sin referenciar
   en fonts/ por si se necesita revertir.
   ============================================================ */

/* ============================================================
   Roboto auto-hospedado (mismo tipo que Lagom) — SIN CDN externo.
   woff2 en ../fonts/ (subset latin, cubre acentos y ñ ES/EN). Pesos
   300/400/500/700 para el look "fino" de Lagom. font-display: swap para
   no bloquear el render. Antes banatheme caia a la fuente del sistema
   (San Francisco en macOS) porque el @font-face se habia quitado.
   ============================================================ */
@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 300;
    font-display: swap;
    src: url('../fonts/roboto-300-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/roboto-400-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/roboto-500-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/roboto-700-latin.woff2') format('woff2');
}

/* ============================================================
   Tokens de marca (prefijo bt- para no colisionar con las variables
   --primary/--secondary/etc. que Bootstrap ya define en :root)
   ============================================================ */
:root {
    --bt-primary: #1062FE;

    /* Lagom2 real (medido en vivo, no de un archivo local): body #FFFFFF puro,
       sin gris de canvas — el area de contenido hereda blanco y las
       tarjetas/paneles se distinguen por sombra sutil (--bt-shadow de abajo),
       no por contraste de fondo gris. */
    --bt-bg: #FFFFFF;
    --bt-surface: #FFFFFF;
    --bt-border: #E7E9F0;
    --bt-text: #1B2430;
    --bt-text-2: #5E636E;
    /* #8A8F99 media 3.25:1 sobre blanco (WCAG), por debajo del minimo
       4.5:1 de texto normal — este token viste TODAS las etiquetas
       10.5px del tema (.bt-dm-metalabel, .bt-dm-statlabel,
       .bt-dm-ar-label, .bt-dd-lbl, .bt-tl-d, ~40 reglas). #6B7280 da
       4.83:1, cumple AA, mismo tono gris-azulado, sin cambio visual
       perceptible. */
    --bt-text-3: #6B7280;

    --bt-green: #10B981;
    /* Verde SOLO para botones (.btn-success): #fff sobre --bt-green da
       2.54:1, ilegible. #0a7a5c da 5.31:1 con texto blanco (AA). NO se
       toca --bt-green: sigue usandose tal cual en pildoras/textos
       (.bt-pill-green, .bt-dm-arswitch--on, etc.) donde el verde claro
       es el correcto. */
    --bt-green-btn: #0a7a5c;
    --bt-amber: #F79009;
    --bt-red: #D92D20;

    --bt-radius-sm: 6px;
    --bt-radius-md: 6px;
    --bt-radius-lg: 6px;

    /* Sombra Lagom2 medida en vivo (mismo valor para toda tarjeta/panel sobre
       el canvas blanco: .bt-panel, .bt-site, .bt-rows, .bt-more-card, stat
       tiles, hero...). Reemplaza la sombra anterior, mas plana, que dependia
       del contraste con el gris de fondo que ya no existe. */
    --bt-shadow: 0 0 1px rgba(0, 0, 0, .1), 0 2px 24px rgba(0, 0, 0, .08);

    /* PENDIENTE DE CONFIRMAR CON EL DUENO: mencion de un "borde degradado"
       de Lagom2 en tarjetas/contenedor. Revisado el material de referencia
       local disponible (whmcs-actualizacion-y-diseno/ y lagom2-audit/,
       incluido hooks/highlight_cancel.php completo) sin encontrar ningun
       border-image ni borde con gradiente real — solo bordes solidos
       (#E7E9F0 en tarjetas, colores solidos rotativos en .tiles a.tile
       border-top) y el degradado azul de la Tanda 13, que es la FRANJA
       superior (.bt-topstrip), no un borde de tarjeta. No se inventa un
       borde degradado sin verificarlo en vivo: las tarjetas se quedan con
       borde solido var(--bt-border) + la sombra de arriba hasta que se
       confirme el detalle exacto (que pagina/elemento, que colores). */
    /* 236px cortaba el logo "BanaHosting" (quedaba "BanaHostin"): con
       .bt-logo-img a max-height:42px y el aspect ratio real del PNG
       (430:80 = 5.375:1, ver TANDA de retina 2x en whmcs-actualizacion-y-
       diseno/hooks/highlight_cancel.php), el logo renderiza a ~226px de
       ancho; con el padding horizontal de .bt-logo (10px+10px=20px) el
       ancho util a 236px era de solo 216px -> ~10px de recorte, que
       coincide exacto con el bug reportado. A 264px el ancho util sube a
       244px, con margen de sobra (~18px) para el logo de 226px sin tener
       que reducirlo. Escritorio SOLO: la sidebar movil (drawer) vuelve a
       su ancho anterior via el media query mas abajo (.bt-sidebar en
       max-width:991.98px), no crece en movil. */
    --bt-sidebar-w: 264px;
    --bt-topstrip-h: 36px;

    --bt-font: Roboto, -apple-system, system-ui, "Helvetica Neue", Arial, sans-serif;

    /* Hover mas oscuro del primario (no hay gradiente de "light" real ya) */
    --bt-primary-hover: #0B4FD6;
}

/* ============================================================
   Base
   ============================================================ */
/* Peso base unificado con el font del sidebar (pedido del dueno 07-29):
   Roboto 300 + letter-spacing -.01em en TODO el tema, no solo el menu
   lateral. Los tamanos de cada lado NO se tocan, solo el peso; los pesos
   500/600/700 (botones, badges, nombres de dominio/producto, etc.) siguen
   explicitos en sus propias reglas y ganan por especificidad. */
body.bt-body {
    font-family: var(--bt-font);
    background: var(--bt-bg);
    color: var(--bt-text);
    font-weight: 300;
    letter-spacing: -.01em;
    /* Aire tipo Lagom (cuerpo 14px con interlineado ~24px). */
    line-height: 1.7;
}

/* Titulos mas finos, al estilo Lagom (su titulo principal usa peso 300 y
   los headings van livianos). Las paginas de auth (login/registro/reset)
   conservan su titulo bold propio via reglas mas especificas/posteriores. */
.bt-body h1, .bt-body h2, .bt-body h3, .bt-body h4, .bt-body h5, .bt-body h6 {
    font-family: var(--bt-font);
    /* 400 -> 300 (unificacion 07-29): mismo peso fino del sidebar. */
    font-weight: 300;
    letter-spacing: -.01em;
    color: var(--bt-text);
}

.bt-body a { color: var(--bt-primary); }
.bt-body a:hover { color: var(--bt-primary-hover); }

/* ============================================================
   Botones — capa sobre Bootstrap, no reemplaza .btn base
   ============================================================ */
.bt-body .btn {
    font-family: var(--bt-font);
    font-weight: 700;
    border-radius: var(--bt-radius-sm);
}

/* color:#fff es obligatorio aqui: ".bt-body a" (0,1,1, arriba) pinta TODO
   <a> de var(--bt-primary), y si ".bt-body .btn-primary" (0,2,0) no fija su
   propio color, un <a class="btn btn-primary"> hereda ese azul y queda
   texto azul sobre fondo azul (invisible). Bug real medido en vivo en
   Payment Methods (boton "Add New Credit Card"), pero afecta a CUALQUIER
   pagina heredada sin override propio (emails, quotes, addfunds,
   announcements, downloads...). Con color:#fff aqui ya no hace falta que
   cada pagina hija cargue su propio parche; los overrides mas especificos
   que ya pintaban blanco a proposito (.bt-dd-btn.btn-primary ~L2563,
   .bt-pd-mainacts .btn.btn-primary ~L2853) siguen ganando igual por
   especificidad/orden y no se tocan. */
.bt-body .btn-primary {
    background: var(--bt-primary);
    border-color: var(--bt-primary);
    color: #fff;
    box-shadow: none;
}
.bt-body .btn-primary:hover,
.bt-body .btn-primary:focus,
.bt-body .btn-primary:active {
    background: var(--bt-primary-hover);
    border-color: var(--bt-primary-hover);
    color: #fff;
}

.bt-body .btn-default,
.bt-body .btn-secondary,
.bt-body .btn-outline-secondary {
    background: var(--bt-surface);
    border-color: var(--bt-border);
    color: var(--bt-text-2);
}
.bt-body .btn-default:hover,
.bt-body .btn-secondary:hover,
.bt-body .btn-outline-secondary:hover {
    background: #F0F5FF;
    color: var(--bt-text);
    border-color: var(--bt-border);
}

/* Mismo patron de bug que .btn-primary arriba: fondo definido sin color,
   ".bt-body a" (0,1,1) pinta el texto azul encima si el elemento es un
   <a class="btn btn-success/btn-danger/btn-warning">. No es invisible
   (azul sobre verde/rojo/ambar, no azul sobre azul) pero es una mezcla de
   color rota y poco legible.
   OJO contraste (medido WCAG, auditoria posterior a este fix): #fff sobre
   --bt-green (#10B981) da 2.54:1 y #fff sobre --bt-amber (#F79009) da
   2.35:1 — ambos por debajo de 4.5:1, PEOR que el bug de arriba en vez de
   arreglarlo. .btn-success usa --bt-green-btn (#0a7a5c, 5.31:1 con #fff)
   SOLO para este boton, sin tocar --bt-green (se usa correcto en claro en
   pildoras/switches). .btn-warning usa texto oscuro #212529 (6.57:1 con
   --bt-amber), el mismo criterio que aplica Bootstrap por defecto a sus
   botones warning. .btn-danger (#fff sobre --bt-red = 4.83:1) SI cumple,
   se deja igual. */
.bt-body .btn-success { background-color: var(--bt-green-btn); border-color: var(--bt-green-btn); color: #fff; }
.bt-body .btn-success:hover,
.bt-body .btn-success:focus,
.bt-body .btn-success:active { color: #fff; }
.bt-body .btn-danger { background-color: var(--bt-red); border-color: var(--bt-red); color: #fff; }
.bt-body .btn-danger:hover,
.bt-body .btn-danger:focus,
.bt-body .btn-danger:active { color: #fff; }
.bt-body .btn-warning { background-color: var(--bt-amber); border-color: var(--bt-amber); color: #212529; }
.bt-body .btn-warning:hover,
.bt-body .btn-warning:focus,
.bt-body .btn-warning:active { color: #212529; }

/* .btn-info: el tema no define su propio fondo (usa el de Bootstrap), pero
   igual sufre el mismo patron: Bootstrap fija su color en ".btn-info"
   (0,1,0), y ".bt-body a" (0,1,1, arriba) tiene MAS especificidad y gana,
   pintando el texto azul del tema en vez del color nativo del boton. No se
   encontro ningun <a class="btn btn-info"> en las plantillas de este repo,
   pero el tema aplica a TODA pagina heredada de WHMCS (emails, quotes,
   addfunds, announcements, downloads...) donde si puede aparecer;
   se fija aqui de forma preventiva con el mismo color:#fff nativo de
   Bootstrap para no dejar la trampa activa. */
.bt-body .btn-info { color: #fff; }
.bt-body .btn-info:hover,
.bt-body .btn-info:focus,
.bt-body .btn-info:active { color: #fff; }

/* ============================================================
   Cards / paneles
   ============================================================ */
.bt-body .card {
    background: var(--bt-surface);
    border-color: var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
}
.bt-body .card-header {
    background: transparent;
    border-bottom-color: var(--bt-border);
    font-weight: 700;
}

/* ============================================================
   Formularios
   ============================================================ */
.bt-body .form-control {
    border-color: var(--bt-border);
    border-radius: var(--bt-radius-sm);
    font-family: var(--bt-font);
}
.bt-body .form-control:focus {
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 .2rem rgba(16, 98, 254, .16);
}
.bt-body .input-group-text {
    background: var(--bt-surface);
    border-color: var(--bt-border);
    color: var(--bt-text-2);
}
.bt-body .form-control-label,
.bt-body label {
    font-weight: 700;
    color: var(--bt-text-2);
}

/* ============================================================
   Tablas
   ============================================================ */
.bt-body .table thead th {
    color: var(--bt-text-2);
    border-bottom-color: var(--bt-border);
    font-weight: 700;
    text-transform: uppercase;
    font-size: 11.5px;
    letter-spacing: .04em;
}
.bt-body .table td,
.bt-body .table th {
    border-color: var(--bt-border);
}

/* ============================================================
   Alerts / badges / paginacion
   ============================================================ */
.bt-body .alert {
    border-radius: var(--bt-radius-sm);
    border-width: 1px;
}
.bt-body .alert-success { background-color: rgba(16, 185, 129, .1); border-color: rgba(16, 185, 129, .35); color: #0a7a5c; }
.bt-body .alert-danger { background-color: rgba(220, 38, 38, .08); border-color: rgba(220, 38, 38, .3); color: #a01d1d; }
.bt-body .alert-warning { background-color: rgba(217, 119, 6, .1); border-color: rgba(217, 119, 6, .3); color: #8a5c04; }
.bt-body .alert-info { background-color: rgba(6, 182, 212, .1); border-color: rgba(6, 182, 212, .3); color: #0a6b7d; }

.bt-body .badge { font-weight: 700; border-radius: 999px; }
.bt-body .badge-info { background-color: var(--bt-primary); }
.bt-body .badge-primary { background-color: var(--bt-primary); }

.bt-body .pagination .page-link {
    color: var(--bt-text-2);
    border-color: var(--bt-border);
    border-radius: var(--bt-radius-sm);
    margin: 0 2px;
}
.bt-body .pagination .page-item.active .page-link {
    background: var(--bt-primary);
    border-color: var(--bt-primary);
}

/* ============================================================
   Layout general — franja azul (fila 1, full-width) + sidebar fija + main
   (fila 2). .bt-shell es un flex-column con .bt-topstrip y .bt-app como
   las 2 filas; .bt-topstrip cruza TODO el ancho de la pantalla (tambien
   por encima del logo/sidebar) porque es hermana de .bt-app, no hija.
   ============================================================ */
.bt-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.bt-app {
    display: flex;
    align-items: flex-start;
    min-height: calc(100vh - var(--bt-topstrip-h));
}

.bt-sidebar {
    position: sticky;
    top: var(--bt-topstrip-h);
    flex: 0 0 var(--bt-sidebar-w);
    width: var(--bt-sidebar-w);
    height: calc(100vh - var(--bt-topstrip-h));
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Sidebar y contenido son AMBOS blancos ahora (--bt-surface = --bt-bg =
       #FFFFFF): sin el border-right de aqui se fundirian en una sola pieza.
       Ya existia este borde antes del cambio de fondo; se deja igual (mismo
       --bt-border #E7E9F0 que usa toda tarjeta) porque sigue siendo visible
       y suficiente sobre blanco puro — no hizo falta reforzarlo. */
    background: var(--bt-surface);
    border-right: 1px solid var(--bt-border);
    padding: 20px 12px;
    display: flex;
    flex-direction: column;
    gap: 18px;
    z-index: 1030;
}

.bt-main {
    flex: 1 1 auto;
    min-width: 0;
}

.bt-logo {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px 10px;
    text-decoration: none;
}
/* Logo ~25% mas grande (pedido del dueno): 34px -> 42px de alto, width:auto
   mantiene el aspect ratio (no se deforma). El padding de .bt-logo de
   arriba NO se toca, sigue dandole aire respecto a los bordes de la
   sidebar. */
.bt-logo-img { max-height: 42px; width: auto; }
.bt-logo-text {
    font-weight: 700;
    font-size: 19px;
    letter-spacing: -.02em;
    color: var(--bt-text);
}

.bt-nav-scroll { flex: 1 1 auto; overflow-y: auto; }

.bt-nav-list,
.bt-nav-sublist {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.bt-nav-item { display: block; }

/* Texto del menu lateral un punto mas grande (pedido del dueno): 13px ->
   14.5px, con padding vertical +2px (8px->10px) para que el item no se
   apriete con la letra mas grande; min-height del item (ver .bt-nav-link
   mas abajo) sube 40->44px para mantener un alto comodo. */
.bt-nav-link,
.bt-nav-sublink {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 10px 15px 10px 20px;
    border-radius: 4px;
    color: var(--bt-text-2);
    text-decoration: none;
    cursor: pointer;
    list-style: none;
}
.bt-nav-link::-webkit-details-marker { display: none; }

/* Bandita de color estilo Lagom (medida del Lagom2 real del dueno): border-left
   solido de 4px a TODO el alto del item (no un ::before corto centrado), con
   border-radius 4px conviviendo en el mismo elemento. Rotacion por POSICION del
   item (bt-band-0..bt-band-5, asignada en bt-navlist.tpl via $item@iteration mod
   6), no por nombre/seccion — asi cubre tambien items nuevos de addons sin
   mantenimiento. Solo los items de PRIMER nivel llevan banda; los subitems de un
   dropdown no la llevan. */
/* Tipografía de items de primer nivel unificada con .bt-sh h2 a pedido
   del dueno: fina (300) y mas grande (17px) en vez del 600/14.5px de antes. */
.bt-nav-link {
    min-height: 44px;
    border-left: 4px solid transparent;
    font-size: 16px;
    font-weight: 300;
    letter-spacing: -.01em;
}
.bt-band-0 { border-left-color: #3B82F6; }
.bt-band-1 { border-left-color: #10B981; }
.bt-band-2 { border-left-color: #F59E0B; }
.bt-band-3 { border-left-color: #8B5CF6; }
.bt-band-4 { border-left-color: #06B6D4; }
.bt-band-5 { border-left-color: #EC4899; }

.bt-nav-link:hover,
.bt-nav-sublink:hover {
    background: #F7F8FB;
    color: var(--bt-text);
    text-decoration: none;
}

/* font-weight 500 (antes 700): el fondo #F0F5FF + color azul ya distinguen
   el estado activo; 700 rompia el look fino pedido para el menu. */
.bt-nav-link.bt-active,
.bt-nav-sublink.bt-active {
    background: #F0F5FF;
    color: #4C7EDB;
    font-weight: 500;
}

/* Icono FontAwesome del item (pedido del dueno, look Lagom) — SOLO
   FontAwesome (el tema padre twenty-one ya lo carga), nunca la fuente
   propietaria lagom-small-icons de RSThemes. color:inherit (implicito,
   no se declara) hereda el color del propio .bt-nav-link/.bt-nav-sublink
   contenedor: gris normal, azul en :hover/.bt-active — sin reglas de
   color propias hace falta. El espacio hacia el texto lo da el
   gap:11px (~10px) que .bt-nav-link/.bt-nav-sublink ya tenian entre TODOS
   sus hijos (icono/label/badge/caret), no hace falta un margin-right
   aparte. Ancho fijo (no font-size) para que iconos de distinto ancho
   visual (fa-globe vs fa-circle) no desalineen el texto entre items. */
.bt-nav-icon {
    flex: 0 0 auto;
    width: 18px;
    font-size: 15px;
    text-align: center;
}
.bt-nav-icon-sub { width: 16px; font-size: 13px; }

.bt-nav-label { flex: 1 1 auto; }
.bt-nav-badge { flex: 0 0 auto; }
.bt-nav-caret { font-size: 10px; flex: 0 0 auto; color: var(--bt-text-3); transition: transform .15s ease; }
.bt-nav-group[open] > .bt-nav-link .bt-nav-caret { transform: rotate(180deg); }

.bt-nav-sublist { padding-left: 26px; margin-top: 2px; }
/* Tipografía fina unificada con .bt-sh h2 a pedido del dueno (proporcional
   al 17px de .bt-nav-link, un poco menor por ser subitem). */
.bt-nav-sublink { font-size: 14.5px; font-weight: 300; letter-spacing: -.01em; padding: 9px 12px; }
.bt-nav-divider { height: 1px; background: var(--bt-border); margin: 6px 10px; }

/* CSS MUERTO / HISTORICO (.bt-nav-scroll .bt-nav-group y
   .bt-nav-scroll .bt-nav-sublist de aqui abajo): eran del menu VIEJO de
   la sidebar, con sub-paneles que en escritorio llegaron a flotar
   (position:absolute) por encima del contenido, igual que sigue haciendo
   la franja superior (.bt-topstrip-nav .bt-nav-sublist, ese SI se usa y
   NO se toca). Ese menu YA NO existe en la sidebar: bt-navlist.tpl usa el
   acordeon .bt-nav-section/.bt-nav-section-body (ver mas abajo), asi que
   .bt-nav-scroll no contiene ningun .bt-nav-group/.bt-nav-sublist real.

   Pedido del dueno (07-31): sin comportamiento flotante en la sidebar, y
   que al desplegar TODOS los grupos del acordeon se pueda hacer scroll
   para verlos completos. Por eso se ELIMINO el bloque
   @media (min-width:992px) que aqui convertia estas reglas en panel
   flotante (position:absolute, box-shadow, reveal por :hover/[open], y el
   `overflow:visible` que rompia el scroll de .bt-sidebar/.bt-nav-scroll).
   Sin ese bloque, .bt-sidebar y .bt-nav-scroll mantienen su
   overflow-y:auto (lineas ~361/400) en TODOS los anchos, y el sidebar
   scrollea internamente cuando varios grupos abiertos superan el alto de
   la ventana. Las reglas que quedan abajo son inertes (sin
   .bt-nav-group/.bt-nav-sublist en la sidebar no aplican a nada real);
   se dejan porque no reintroducen overflow:visible ni position:absolute
   en la sidebar. */
.bt-nav-scroll .bt-nav-group { position: relative; }
.bt-nav-scroll .bt-nav-sublist {
    max-height: 0;
    overflow: hidden;
    transition: max-height .2s ease;
}
.bt-nav-scroll .bt-nav-group[open] > .bt-nav-sublist {
    max-height: 480px;
}
@media (max-width: 991.98px) {
    .bt-nav-scroll .bt-nav-group:hover > .bt-nav-sublist {
        /* En movil el hover no dispara realmente (tactil), pero si algun
           dispositivo hibrido con mouse+pantalla chica lo activara, se
           mantiene el mismo comportamiento en-flujo que [open], no el
           flotante de escritorio. */
        max-height: 480px;
    }
}
@media (prefers-reduced-motion: reduce) {
    .bt-nav-scroll .bt-nav-sublist { transition: none; }
}

/* Cabecera movil unificada (08-02): el boton deja de ser una tarjeta
   blanca flotando fixed sobre el contenido (posicion/fondo/borde/sombra
   de antes) y pasa a vivir EN FLUJO como primer hijo de .bt-topstrip (ver
   header.tpl), pintado como icono plano blanco sobre el degradado azul de
   la franja -- mismo color que el resto de iconos/texto de
   .bt-topstrip-actions. 44x44 (subido de 40x40): area tactil minima de
   accesibilidad; el icono en si sigue chico (fa-bars a font-size propio
   mas abajo), el padding lo da el propio boton centrado por flex. Sigue
   oculto en escritorio (display:none aqui; override a inline-flex SOLO en
   el media query movil mas abajo, mismo patron de siempre) porque ahi la
   sidebar es fija y no hace falta togglearla. */
.bt-sidebar-toggle {
    display: none;
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    border: none;
    background: transparent;
    color: #fff;
    padding: 0;
}
.bt-sidebar-toggle .fa-bars {
    font-size: 18px;
}

/* Titulo de pagina junto al boton hamburguesa, dentro de .bt-topstrip (ver
   header.tpl) -- SOLO movil (oculta en escritorio, donde la sidebar fija
   ya trae su propio logo via .bt-logo). display:none base / flex en el
   media query movil mas abajo, mismo patron que .bt-sidebar-toggle.
   min-width:0 es lo que permite que el text-overflow:ellipsis del titulo
   funcione dentro de un contenedor flex (sin el, un hijo flex nunca se
   encoge por debajo de su ancho de contenido natural); flex:0 1 auto +
   min-width:0 evitan que .bt-topstrip-actions (margin-left:auto) lo
   comprima a 0 cuando el grupo de la derecha aprieta.
   REMATE (08-02): la nube-logo (.bt-topstrip-brand-logo/-img) se retiro
   (decision del dueno, ver header.tpl) -- este contenedor ya solo trae el
   titulo; se conserva el nombre .bt-topstrip-brand para no ensanchar el
   diff. */
.bt-topstrip-brand {
    display: none;
    align-items: center;
    flex: 0 1 auto;
    margin-left: 8px;
    min-width: 0;
}
.bt-topstrip-brand-title {
    min-width: 0;
    max-width: 110px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #fff;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -.01em;
}

.bt-sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(23, 26, 46, .4);
    z-index: 1020;
    overscroll-behavior: contain;
}

/* ============================================================
   Franja superior fina — fila de utilidades a la derecha estilo Lagom
   (notificaciones, carrito, $secondaryNavbar, "Logged in as"/switch de
   cuenta/masquerade), mismo degradado azul primario y valores exactos de
   la Tanda 13 del kit lagom2-audit/whmcs-actualizacion-y-diseno
   (hooks/highlight_cancel.php: background-color #1062FE +
   linear-gradient(90deg,#1062FE 0%,#2E9BFA 55%,#4FC3FF 100%), texto/iconos
   blancos, hover blanco atenuado). Todos estos widgets vivian antes en la
   barra blanca .bt-topbar (retirada del todo, ver seccion Contenido mas
   abajo) — se movieron de contenedor, su markup/includes/JS quedan intactos (popover de
   notificaciones, switch de cuenta, masquerade), solo cambia el layout
   (fila en vez de bloque) y el color via las reglas de abajo. Todas usan
   selectores de 2-3 clases para ganarle por especificidad a las reglas
   base (.bt-nav-link, .bt-band-N, .bt-body .btn, .bt-body .input-group-text,
   .bt-body .badge-info, .bt-active-client .btn-active-client span) SIN
   !important — mismo patron que .bt-site-act.bt-site-act-main /
   .bt-hero-stats .bt-stat-tile de mas arriba en este archivo.
   ============================================================ */
/* Pedido del dueno: la franja se queda FIJA arriba al hacer scroll. Es
   hermana de .bt-app dentro de .bt-shell (flex-column, sin overflow
   propio) -> sticky top:0 la ancla al viewport (documento normal, sin
   contenedor con scroll interno propio, asi que no hace falta ningun
   overflow adicional en .bt-shell para que el sticky funcione). z-index
   1035, por encima de la sidebar (1030, ver .bt-sidebar) para que al
   scrollear la franja gane visualmente y no quede tapada; por debajo del
   boton hamburguesa (1050) y por debajo de .bt-sidebar-toggle en general.
   El dropdown que abre un item de la franja (.bt-topstrip-nav .bt-nav-
   sublist, z-index 1040) es descendiente de este elemento, asi que sigue
   pintandose por encima de la franja y del contenido sin tocarlo. */
/* Diagnostico en runtime (dueno): el grupo de utilidades quedaba con
   ~28px de hueco muerto respecto al borde derecho real de la franja. No
   habia ningun margin-right extra ni elemento invisible empujando (el
   justify-content:flex-end + el flex de .bt-topstrip-actions ya pegaban
   el grupo contra el limite de su padding correctamente) -- el padding-
   right de 28px en si mismo era mas grande de lo que el dueno queria
   ahi. Se reduce SOLO el lado derecho a 18px (dentro del rango pedido,
   16-20px); el izquierdo se deja en 28px (sigue a juego con el mismo
   gutter que usan .bt-content/.bt-breadcrumb en el resto del layout, no
   reportado como problema). */
.bt-topstrip {
    position: sticky;
    top: 0;
    z-index: 1035;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    height: var(--bt-topstrip-h);
    padding: 0 18px 0 28px;
    background-color: #1062FE;
    background-image: linear-gradient(90deg, #1062FE 0%, #2E9BFA 55%, #4FC3FF 100%);
}
/* Widgets compactos para caber en los 36px fijos de la franja (los mismos
   .btn/.input-group-text del tema traen padding vertical pensado para la
   barra blanca alta de antes) — solo tamano/padding, ningun include/JS se
   toca. */
.bt-topstrip-actions .btn {
    padding: 4px 10px;
    font-size: 12px;
    line-height: 1.3;
}
.bt-topstrip-actions .bt-active-client .input-group-text { padding: 4px 10px; font-size: 12px; }
/* Refuerzo (regresion reportada tras sumar el selector de idioma): el
   grupo entero volvia a despegarse del borde derecho. margin-left:auto
   fija el grupo contra el borde derecho de .bt-topstrip DIRECTAMENTE en
   el propio item flex, sin depender solo de justify-content:flex-end
   del padre (belt-and-suspenders: ambos mecanismos empujan en la misma
   direccion, no compiten entre si). flex-wrap:nowrap explicito (antes
   solo estaba en el media query movil) evita que, si el contenido crece
   por sumar items nuevos como .bt-lang-trigger, el grupo pase a 2 lineas
   en vez de desbordar/ajustarse en una sola fila -- una fila que
   envuelve pierde el alineado a la derecha por linea individual y da la
   apariencia de "hueco" que reporto el dueno. flex-shrink:0 para que el
   grupo no se comprima de forma rara si el contenido se acerca al ancho
   disponible. */
.bt-topstrip-actions {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    flex-shrink: 0;
    margin-left: auto;
    gap: 14px;
    min-width: 0;
}

/* --- $secondaryNavbar (Account "Hello, ...", Language, Currency...) --- */
.bt-topstrip-nav {
    display: flex;
    flex-direction: row;
    align-items: center;
    list-style: none;
    margin: 0;
    padding: 0;
    gap: 2px;
}
.bt-topstrip-nav .bt-nav-item { display: flex; align-items: center; }
.bt-topstrip-nav .bt-nav-group { position: relative; display: flex; align-items: center; }
.bt-topstrip-nav .bt-nav-link {
    min-height: 0;
    padding: 4px 10px;
    border-left: none;
    border-radius: var(--bt-radius-sm);
    font-size: 12px;
    color: #fff;
    white-space: nowrap;
}
.bt-topstrip-nav .bt-nav-link.bt-active { background: rgba(255, 255, 255, .12); color: #fff; }
.bt-topstrip-nav .bt-nav-link:hover,
.bt-topstrip-nav .bt-nav-link:focus {
    background: rgba(255, 255, 255, .08);
    color: rgba(255, 255, 255, .85);
}
.bt-topstrip-nav .bt-nav-caret { color: #fff; }
.bt-topstrip-nav .bt-nav-link:hover .bt-nav-caret,
.bt-topstrip-nav .bt-nav-link:focus .bt-nav-caret { color: rgba(255, 255, 255, .85); }

/* Dropdown de un item del strip (Account/Language/...): el panel cae sobre
   contenido claro, mismo estilo que .bt-more-card (superficie blanca, borde,
   sombra) — no hereda el fondo azul del strip. .bt-nav-sublink NO se toca
   aqui (clase distinta a .bt-nav-link): conserva su color oscuro de base,
   que es justo lo que hace falta sobre el panel blanco. */
/* Pedido del dueno: los desplegables de la franja se abren solos al pasar
   el mouse (hover), sin clic, solo en escritorio (>=992px, ver media
   query mas abajo). El toggle real sigue siendo el atributo nativo
   [open] de <details> (bt-navlist.tpl ya lo controla por clic; un script
   corto en footer.tpl lo AGREGA/QUITA tambien en mouseenter/mouseleave,
   gated a >=992px — en movil/tactil esos listeners no hacen nada y el
   clic nativo sigue igual que siempre). margin-top:0 (antes 4px) cierra
   el hueco visual entre el summary y el panel: ese hueco era zona
   "muerta" para el hover — el puntero lo cruza sin estar sobre NINGUN
   descendiente de <details>, lo que dispara mouseleave antes de tiempo.
   Sin hueco, el panel es continuo con el summary y no hace falta un
   pseudo-elemento puente aparte. opacity/transform con transicion corta
   (~150ms, ver @media prefers-reduced-motion mas abajo) en vez de
   depender solo del display nativo de <details> -- asi "desliza" en vez
   de aparecer de golpe. pointer-events:none mientras esta cerrado para
   que un panel que el navegador aun no termino de ocultar no bloquee
   clics en lo de abajo. */
.bt-topstrip-nav .bt-nav-sublist {
    position: absolute;
    top: 100%;
    right: 0;
    left: auto;
    min-width: 210px;
    margin-top: 0;
    padding: 6px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-md);
    box-shadow: var(--bt-shadow);
    z-index: 1040;
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity .15s ease, transform .15s ease;
}
/* Reveal por [open] (clic nativo, o el mismo atributo puesto por nuestro
   script de hover) Y por :hover directo del grupo (mejor esfuerzo/
   respaldo instantaneo por si el navegador permite mostrar el contenido
   de <details> sin el atributo [open] — donde no lo permita, el [open]
   de arriba, puesto por el script, sigue siendo el mecanismo real). Solo
   en escritorio: ver el media query de abajo que anula esto en movil. */
@media (min-width: 992px) {
    .bt-topstrip-nav .bt-nav-group[open] > .bt-nav-sublist,
    .bt-topstrip-nav .bt-nav-group:hover > .bt-nav-sublist {
        opacity: 1;
        transform: translateY(0);
        pointer-events: auto;
    }
}
@media (max-width: 991.98px) {
    /* Movil/tactil: SOLO clic (nativo de <details>), como siempre. Sin
       esta regla, [open] de arriba tambien aplicaria en movil (el
       selector no tiene su propio media query) y el panel ya vendria con
       opacity/transform correctos de todas formas -- se deja explicito
       para dejar constancia de que el hover no interviene aqui, nada que
       anular en la practica (":hover" no dispara solo con clic en
       tactil). */
    .bt-topstrip-nav .bt-nav-group[open] > .bt-nav-sublist {
        opacity: 1;
        transform: translateY(0);
        pointer-events: auto;
    }
    /* BUG reportado (verificado en 390x844): .bt-topstrip tiene
       overflow-x:auto + height:36px fijo (linea ~919; por spec CSS, un eje
       en no-visible obliga al otro a computar "auto" tambien, asi que
       recorta en vertical igual que si fuera overflow:auto), asi que un
       panel position:absolute (linea ~736) de ~450px de alto quedaba
       recortado por el overflow del PADRE, aunque [open]/opacity/transform
       de arriba ya lo daban por "visible". El intento a7e0053 saco el
       panel del contexto de recorte pasandolo a position:fixed SOLO en
       movil: funciona en Chromium, pero en iOS Safari (reportado por el
       dueno, no reproducible aqui) un position:fixed anidado dentro de un
       ancestro con overflow!=visible se sigue comportando como recortado/
       anclado al contenedor en vez de al viewport -- de ahi que el
       desplegable siguiera sin abrir ahi. NUEVA HIPOTESIS (66f4fee, que
       ponia display:list-item en <summary> creyendo que ese era el
       problema, quedo revertida en 66427d8 por no arreglar Safari y
       encima romper la bandera de idioma; no se repite ese enfoque):
       en vez de pelear con el posicionamiento, se quita el recorte del
       PADRE mientras el desplegable esta abierto (regla :has() mas abajo,
       en .bt-topstrip) y se vuelve el panel a position:absolute, que sin
       recorte de por medio es mas predecible entre navegadores que fixed.
       No se toca overflow-x:auto de .bt-topstrip en reposo (sigue
       haciendo falta para que los items de la franja puedan desplazarse en
       pantallas estrechas) ni el bloque de arriba que ya resuelve
       opacity/transform/pointer-events para [open]. z-index: BUG reportado
       por el dueno (390px, panel abierto) -- 1045 quedaba por DEBAJO de
       .bt-sidebar-toggle (hamburguesa, 1050), que se pintaba encima del
       panel y capturaba el clic (elementFromPoint devolvia el icono
       fa-bars, no el panel). PRIMER INTENTO (revertido, no funciono):
       subir el z-index de ESTE panel a 1060 no sirve de nada, porque
       .bt-topstrip (el padre, position:sticky + z-index:1035, ver mas
       abajo) crea su PROPIO contexto de apilamiento -- un descendiente
       solo puede competir en z-index DENTRO del contexto de su padre, no
       en el contexto raiz. Frente a .bt-sidebar-toggle (fixed, z-index
       1050, en el contexto raiz) lo que compite de verdad es la franja
       ENTERA con su 1035, no este panel; subir el hijo jamas puede ganar
       mientras el padre siga perdiendo. El fix real esta en la regla
       :has() de abajo, que sube el z-index del PADRE mientras el
       desplegable esta abierto. Este panel se deja en 1045 (valor previo
       al intento fallido) porque ya no hace falta mas: una vez que la
       franja gana su propio duelo de z-index, todo lo que hay dentro va
       con ella. */
    .bt-topstrip-nav .bt-nav-group[open] > .bt-nav-sublist {
        position: absolute;
        top: var(--bt-topstrip-h);
        left: 8px;
        right: 8px;
        width: auto;
        max-height: calc(100vh - var(--bt-topstrip-h) - 16px);
        overflow-y: auto;
        z-index: 1045;
    }
    /* Complemento de lo anterior: sin esto, .bt-topstrip (ancestro
       position:sticky, contenedor de posicionamiento del panel de arriba)
       sigue recortando el panel via overflow-x:auto aunque el panel ya
       este en absolute con las coordenadas correctas -- por eso el fix
       real es este :has(), no el position de arriba por si solo.
       z-index:1060 (AÑADIDO junto con overflow:visible, mismo :has()):
       .bt-topstrip es position:sticky + z-index:1035 (ver regla propia
       mas abajo), lo que la convierte en un contexto de apilamiento
       propio -- el panel de arriba es descendiente suyo y por tanto solo
       puede competir en z-index DENTRO de ese contexto, nunca en el
       contexto raiz del documento. Contra .bt-sidebar-toggle (fixed,
       z-index 1050, contexto raiz) lo que se compara de verdad es la
       franja completa (1035) contra la hamburguesa (1050), y la franja
       pierde aunque el panel interior diga 1060. Subir SOLO el z-index
       del padre mientras hay un desplegable [open] (via este mismo
       :has(), sin tocar el 1035 en reposo) resuelve la trampa: 1060 >
       1050 (hamburguesa), unico elemento del topstrip movil en el
       contexto raiz por encima de 1035. .bt-toast (1045, linea ~2710) es fixed/bottom y solo
       aparece en desktop (ver su propio comentario), sin solape posible
       con este dropdown movil; .bt-sidebar (1030, linea ~374) ya queda
       por debajo incluso en reposo. En reposo (sin [open]) la franja
       sigue en 1035, sin cambios. Soporte :has(): Safari/iOS 15.4+;
       donde no exista, esta regla simplemente no aplica y queda como
       estaba (sin empeorar nada). */
    .bt-topstrip:has(.bt-nav-group[open]) {
        overflow: visible;
        z-index: 1060;
    }
    /* BUG reportado por el dueno desde iPhone (390px), YA con el fix de
       arriba abierto en Safari: el panel se abre pero se sale por la
       derecha (medido: x=182, ancho=210 => borde derecho 392 > 390 de
       pantalla). Causa: al pasar el panel a position:absolute (arriba),
       su "containing block" para left/right ya no es .bt-topstrip sino
       .bt-topstrip-nav .bt-nav-group (linea ~693: position:relative), que
       es un grupo angosto pegado a la derecha de la franja -- left:8px y
       right:8px de arriba se resuelven contra ESE grupo estrecho, no
       contra el ancho completo de la franja, y el panel crece hacia la
       derecha y se desborda del viewport. Se neutraliza el relative del
       grupo SOLO en este media query (no toca escritorio, donde
       .bt-nav-sublist necesita el relative del grupo para su propio
       right:0/left:auto de la regla de linea ~736) para que el
       containing block pase a ser .bt-topstrip (position:sticky, ya
       positioned, ocupa el ancho completo) y left:8px/right:8px de arriba
       se resuelvan contra la franja entera, casi a pantalla completa.
       Verificado que dentro de .bt-nav-group no hay otro descendiente
       posicionado en absolute que dependa de este relative (el unico es
       .bt-nav-sublist, ya cubierto arriba con su propio position:absolute
       explicito) -- position:static no le quita el "positioned ancestor"
       a nadie mas. */
    .bt-topstrip-nav .bt-nav-group { position: static; }
}
@media (prefers-reduced-motion: reduce) {
    .bt-topstrip-nav .bt-nav-sublist { transition: none; }
}

/* --- Notificaciones: solo el boton visible en la franja cambia de color;
   #accountNotificationsContent (el panel que abre el popover del tema) NO
   se toca aqui a proposito, sigue con su superficie clara/texto oscuro
   nativos del tema.
   El boton nativo del tema (fuera de este contexto) apila icono/numero/
   label en columna, pensado para la barra blanca alta de antes; en los
   36px de la franja azul se ve apretado y feo. display:inline-flex +
   flex-direction:row fuerza TODOS sus hijos (el <i>, el numero de
   {count($clientAlerts)} -- un nodo de texto suelto, que flexbox trata
   como item anonimo -- y el <span> del label) a una sola fila
   centrada verticalmente, sin tocar el markup/JS del popover. --- */
.bt-topstrip-actions .bt-topbar-notifications > button.btn {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    color: #fff;
}
.bt-topstrip-actions .bt-topbar-notifications > button.btn i { color: #fff; }

/* --- Carrito: icono blanco, badge de contador en blanco solido con texto
   azul (sobre el propio degradado el badge-info azul quedaba invisible).
   Mismo fix de layout que notificaciones: el <a class="cart-btn"> del
   tema tambien apilaba icono/badge en columna -- se fuerza fila en
   linea, centrada. --- */
/* Diagnostico exacto en runtime (dueno): .cart-btn del tema base trae su
   propio overflow:hidden + width fija (~38px, boton "solo icono"
   cuadrado) -- eso era lo que de verdad recortaba el badge en semicirculo,
   no un tema de position. overflow:visible + width:auto (min-width:auto
   por si el ancho fijo viniera de ahi) dejan que el boton crezca al
   ancho real de su contenido (icono + badge + gap) en vez de recortarlo. */
.bt-topstrip-actions .cart-btn {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    overflow: visible;
    width: auto;
    min-width: auto;
    color: #fff;
}
.bt-topstrip-actions .cart-btn i { color: #fff; }
/* El badge salia CYAN (#22D3EE, color nativo de .badge-info) en vez de
   blanco: el selector anterior (.bt-topstrip-actions .cart-btn .badge-info,
   3 clases) no le alcanzaba para ganarle al del tema. Se sube a un
   selector con ID (#cartItemCount, el id real del span en el markup) que
   por regla de cascada le gana a CUALQUIER combinacion de clases sin
   necesidad de !important. display:inline-flex + centrado propio +
   ancho/alto minimos fijos (en vez de heredar el padding/line-height del
   badge nativo, pensado para otro contexto) arman un pill redondo
   completo, numero centrado, sin recortes -- ya no depende de position
   (el fix real de "cortado" fue el overflow/width de arriba). */
.bt-topstrip-actions #cartItemCount.badge-info {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    box-sizing: border-box;
    border-radius: 999px;
    background: #fff;
    color: var(--bt-primary);
    font-size: 10.5px;
    font-weight: 700;
    line-height: 1;
}

/* --- Notificaciones: NO se reutiliza el fix de #cartItemCount (badge
   badge-info, regla justo arriba) -- CORRECCION al gate (08-02): el dueno
   pidio "solo movil" para todo este trabajo de la franja. #cartItemCount
   ya llevaba badge/badge-info de ANTES de esta rama (cambio ajeno a esta
   tanda), pero para notificaciones -- nuevo en esta tanda -- usar esas
   clases GLOBALES de Bootstrap las activaria en TODOS los anchos (el
   .badge-info nativo del tema no es cosmetico neutro), asi que "no repetir
   la regla en escritorio" no habria bastado para dejar el escritorio
   intacto. En su lugar #notifCount lleva una clase propia del tema
   (.bt-notif-count, ver header.tpl) SIN ninguna clase de Bootstrap, y su
   aspecto se define UNICAMENTE dentro del media query movil (mas abajo,
   L~1250) -- fuera de ahi el <span> no tiene ninguna regla que lo toque,
   asi que en escritorio se renderiza como texto pelado (igual que antes
   de esta tanda: {count($clientAlerts)} suelto, blanco sobre el degradado
   azul, ver comentario de mas arriba). */

/* --- Selector de idioma/moneda: pedido del dueno (2a vuelta), pasa de
   abrir el modal #modalChooseLanguage (que se deja intacto en footer.tpl
   sin usar, fallback inofensivo) a ser un dropdown propio de hover
   integrado a la franja. Se reutiliza LA MISMA estructura/clases que ya
   usa $secondaryNavbar (.bt-nav-list.bt-topstrip-nav > .bt-nav-item >
   .bt-nav-group > .bt-nav-link/.bt-nav-sublist), asi hereda gratis TODO
   lo ya construido: colores blancos, hover, el reveal por [open]/:hover
   con transicion, el panel blanco con texto oscuro, y el script de
   footer.tpl que agrega/quita [open] en mouseenter/mouseleave (su
   querySelector ya es '.bt-topstrip-nav .bt-nav-group', que este nuevo
   grupo cumple sin tocar el script). Solo hace falta este ajuste minimo
   para el <span class="iti-flag ..."> (sprite de banderas del tema, con
   width/height fijos por pais): al ser hijo de .bt-nav-link (display:flex)
   ya se "blockifica" solo (regla de flexbox), pero le falta flex-shrink:0
   para que el gap:11px de .bt-nav-link no lo comprima junto al texto en
   los 12px de fuente compactos de la franja. */
.bt-topstrip-nav .bt-lang-trigger .iti-flag { flex-shrink: 0; }

/* --- "Logged in as: Nombre" + switch de cuenta + volver a admin --- */
/* Pedido del dueno (08-02): quitar el badge "Conectado como: <nombre>" de
   la franja -- es redundante con el saludo ("Hola, <nombre>") de al lado y
   ocupa espacio real en movil (93px medidos a 390px, ver header.tpl
   L296-336). Se ocultan puntualmente la etiqueta ".input-group-prepend"
   ("Conectado como:") y el enlace del nombre/empresa (".btn-active-client",
   el <a> que envuelve el <span> con el nombre) -- NO se oculta
   ".bt-active-client"/".btn-group" completo: dentro del MISMO .btn-group,
   header.tpl (L323-327) agrega un boton "Switch Account" (icono
   fa-random, SIN la clase .btn-active-client) para clientes con acceso a
   2+ cuentas (tblusers_clients), y opcionalmente un boton "volver a admin"
   (.btn-return-to-admin) cuando un admin esta enmascarado. Ocultar el
   .btn-group entero les quitaria la UNICA forma de cambiar de cuenta o
   volver al admin. Verificado en el propio header.tpl de este repo (NO
   existe una variante con .dropdown-toggle/.dropdown-menu para el caso
   multi-cuenta -- WHMCS aqui siempre renderiza el mismo <a> de nombre +,
   si aplica, el <a> de switch aparte -- asi que basta con apuntar a las
   clases especificas de la etiqueta y el enlace de nombre, sin tocar el
   resto del grupo).
   FIX 08-02 (2a vuelta): en escritorio seguia visible. Causa real: el
   propio header.tpl (L298) pone en .input-group-prepend las utilidades
   responsive de Bootstrap "d-none d-md-inline", que traen !important
   (.d-none{display:none!important}, .d-md-inline{display:inline!important}
   desde min-width:768px). Sin !important de nuestro lado, a partir de
   768px la utilidad d-md-inline (con !important) le ganaba a este
   display:none aunque tuviera mas especificidad -- por eso en movil
   desaparecia (ahi manda d-none, tambien con !important, y coincide con
   lo que queriamos) pero en escritorio quedaba visible. Se agrega
   !important de este lado, sin envolver en media query, para que la
   regla gane SIEMPRE (movil y escritorio) sin depender de que Bootstrap
   decida ocultarlo por su cuenta. .btn-active-client no trae utilidades
   d-*, por eso ese display:none ya funcionaba bien en todos los anchos y
   no necesita el !important. */
.bt-active-client .input-group-prepend {
    display: none !important;
}
.bt-active-client .btn-active-client {
    display: none;
}
/* Con la etiqueta y el nombre ocultos, para la mayoria de clientes (1 sola
   cuenta conocida, sin masquerade -- el 99,2% segun el comentario de
   header.tpl L311-322) el .btn-group interno se queda sin NINGUN boton
   visible (Switch Account solo aparece con 2+ cuentas o conteo
   desconocido; volver-a-admin solo con masquerade/admin). El input-group
   flex (.bt-active-client) y el btn-group anidado seguirian ocupando
   hueco/generando un espacio vacio en la franja aunque no muestren nada.
   Se colapsa el contenedor completo SOLO cuando no le queda ningun .btn
   visible aparte del nombre ya oculto (.btn-active-client); si hay
   Switch Account o volver-a-admin, :has() los detecta y el contenedor
   se queda como esta (visible, con esos botones). Progresivo: sin
   soporte de :has() (mismo patron ya usado en este archivo, ver el fix
   de Safari en .bt-topstrip-nav) simplemente no se colapsa el hueco
   vacio -- no rompe nada, solo deja de limpiarlo del todo. */
.bt-active-client:not(:has(.btn:not(.btn-active-client))) {
    display: none;
}
.bt-topstrip-actions .bt-active-client .input-group-text {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
}
.bt-topstrip-actions .bt-active-client .btn-active-client span { color: #fff; }
.bt-topstrip-actions .bt-active-client .btn {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
}
.bt-topstrip-actions .bt-active-client .btn:hover,
.bt-topstrip-actions .bt-active-client .btn:focus {
    background: rgba(255, 255, 255, .22);
    color: #fff;
}
.bt-topstrip-actions .bt-active-client i { color: #fff; }

@media (max-width: 991.98px) {
    /* Cabecera movil unificada (08-02): 36px -> 52px, una sola barra con
       boton+marca+acciones en vez de las 2 franjas inconexas de antes
       (topstrip azul + boton flotando encima). Esta variable ya gobierna
       TODO el offset del layout que arranca bajo la franja (.bt-app,
       .bt-sidebar sticky/fixed, el "top" del panel de idioma/moneda
       desplegado en linea ~761/794) asi que con solo subirla aqui, en
       movil, el resto se recoloca solo -- verificado leyendo cada uso de
       var(--bt-topstrip-h) en este archivo, ninguno tiene un valor
       hardcodeado en paralelo que haya que tocar a mano. Escritorio (fuera
       de este media query) se queda en 36px. */
    :root {
        --bt-topstrip-h: 52px;
    }
    .bt-topstrip {
        padding-left: 16px;
        padding-right: 16px;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .bt-topstrip-actions { flex-wrap: nowrap; }
    .bt-topstrip-nav { flex-wrap: nowrap; }
    .bt-sidebar-toggle { display: inline-flex; align-items: center; justify-content: center; }
    /* REMATE 2 (08-02): .bt-topstrip-brand ya NO se muestra en movil.
       Con max-width:40px el titulo de pagina se truncaba a "Áre…" (de
       "Área de cliente"), un fragmento que no informa de nada y ensucia la
       franja -- decision del dueno, reversible: se quita el titulo del
       todo en vez de intentar otro ancho. Se deja el override anterior
       (`display: flex`) SIN poner aqui, asi .bt-topstrip-brand hereda el
       `display: none` de la regla base (linea ~584) tambien en movil; el
       markup (header.tpl) NO se toca -- el <span> queda en el DOM oculto
       por CSS por si se recupera el titulo en el futuro con otro
       tratamiento (p.ej. icono en vez de texto). Con esto la barra movil
       queda [≡] ... [🔔][🛒][🏳][👤], igual que la referencia aprobada por
       el dueno (que tampoco lleva titulo). */

    /* Remate del gate de barra unica movil (08-02, medido a 390x844 por el
       dueno): con notificaciones (45px) + carrito (61px) + idioma (61px,
       ya icono-solo) + saludo (111px, "¡Hola, Nombre!" en texto) el grupo
       de acciones ocupaba 320px con gap:14px entre 4 items -- sumado al
       boton hamburguesa (44px) no dejaba margen para la marca, que se
       aplastaba a 0px de ancho.
       FIX: el saludo pasa a SOLO ICONO tambien (far fa-user, ver el
       fallback de includes/bt-topstrip.tpl -- SIN el fallback de texto
       recortado con ellipsis que habia antes: con icono garantizado en
       TODO item de nivel 1 ya no hace falta, y dejar texto truncado
       ademas del icono duplicaba la señal visual). RECALCULO final (tras
       el aro/pildora de accion, mas abajo, y el icono de cuenta SIN
       saludo): notificaciones ~52px (icono+numero de alertas, que sigue
       siendo texto suelto en el markup y no se puede ocultar sin perder
       informacion), carrito 44px (icono solo, badge ahora superpuesto),
       idioma 61px (sin cambios, bandera+caret), cuenta ~53px (icono+caret,
       mismo ancho que notificaciones por tener 2 elementos internos en vez
       de 1) -- suma de items = 52+44+61+53 = 210px.
       REMATE 2 (08-02): con el titulo fuera (ver arriba), ya no hace falta
       apretar el gap a 10px para hacerle hueco -- se deja SIN override
       aqui, hereda gap:14px de la regla base (.bt-topstrip-actions, linea
       ~691), mismo valor que escritorio. Comprobacion a los 2 anchos de
       referencia (padding 16+16=32, boton hamburguesa 44, brand ya en
       0px):
         390px: 210 + 3*14(gap) = 252 <= 390 - 32 - 44 = 314 -> sobran 62px
         360px: 210 + 3*14(gap) = 252 <= 360 - 32 - 44 = 284 -> sobran 32px
       A 360px ya NO hay overflow (antes sobraban ~4px de mas y se apoyaba
       en el overflow-x:auto de .bt-topstrip, linea ~1078, que se deja
       igual como red de seguridad pero deja de activarse en este calculo).

       ACTUALIZACION Fallo 1+2 (08-02, medido con Playwright 390x844 antes
       de este cambio: notificaciones 45x44, carrito 44x44, idioma 61x22,
       cuenta 51x44 -- suma 201px + 3*14(gap) = 243px). Tras Fallo 1
       (badge de notificaciones pasa a overlay igual que el carrito, ver
       comentario del aro mas abajo) su ancho visible deberia bajar de
       45px a ~44px (contenido = solo icono, igual que carrito). Tras
       Fallo 2 (idioma gana el aro/hitbox de 44x44 SIN perder el caret) su
       ALTO sube de 22 a 44px pero su ANCHO deberia mantenerse en ~61px
       (mismo contenido bandera+caret, mismo padding/gap -- el aro no
       recorta ni agranda el contenido, solo agrega el anillo visual y el
       piso de 44px de alto). Con esas dos estimaciones la suma de items
       pasaria de 201px a ~200px (44+44+61+51), practicamente igual --
       idioma NO se encoge a 44px (conserva su caret), asi que el ahorro de
       espacio es marginal, no el explicado en parrafos anteriores para
       cuando un item pasaba a icono-solo:
         390px: ~200 + 3*14(gap) = ~242 <= 390 - 32 - 44 = 314 -> sobran ~72px
         360px: ~200 + 3*14(gap) = ~242 <= 360 - 32 - 44 = 284 -> sobran ~42px
       Sigue sobrando margen a ambos anchos (mas que antes, por el ligero
       ahorro en notificaciones), pero estos numeros son CALCULO, no
       medicion en vivo -- no se pudo levantar Playwright para confirmar el
       render real tras este cambio; verificar a 390/360px antes de dar el
       ajuste por cerrado.
       Notificaciones/carrito NO se tocan en su funcion: ya son icono-solo
       en este ancho via las clases d-none/d-sm-inline de Bootstrap que
       trae header.tpl, y son ACCIONES (deben quedar siempre visibles), no
       adorno. En escritorio (min-width:992px, fuera de este media query)
       nada cambia: los textos se mantienen, incluido el saludo con
       nombre; .bt-topstrip-brand ya estaba oculto ahi desde antes (regla
       base display:none, linea ~584), asi que este cambio no tiene efecto
       en escritorio. */
    .bt-lang-trigger .bt-lang-trigger-text {
        display: none;
    }
    .bt-topstrip-nav .bt-nav-link:not(.bt-lang-trigger) .bt-nav-label {
        display: none;
    }

    /* Tratamiento visual SOLO MOVIL (08-02, aprobado por el dueno sobre
       una captura de referencia con barra clara + iconos oscuros dentro
       de aros finos): la franja pasa de degradado azul a fondo blanco
       DENTRO de este media query unicamente -- en escritorio (fuera de
       aqui) sigue con el degradado azul de la Tanda 13 (linea ~664), sin
       tocar. Si el resultado gusta en movil se evalua llevarlo tambien a
       escritorio en un cambio aparte, no ahora. `background:` (shorthand)
       resetea el background-image gradient heredado sin tener que
       nombrarlo aparte. El border-bottom es imprescindible: sin el, la
       franja blanca se funde con el contenido de abajo (tambien claro) --
       se reusa el token de borde del resto del tema (var(--bt-border),
       #E7E9F0) en vez de introducir un hex nuevo de un solo uso (el de
       referencia, #E3E8F0, es visualmente indistinguible). */
    .bt-topstrip {
        background: #FFFFFF;
        border-bottom: 1px solid var(--bt-border);
    }
    /* Iconos/texto pasan de blanco a oscuro (var(--bt-text), mismo token
       que el resto del tema, de sobra 4.5:1 sobre blanco). El icono de
       menu (fa-bars) se deja SIN aro -- es el control de navegacion
       principal (abre la sidebar), no una "accion" como notificaciones/
       carrito/cuenta; en la referencia del dueno tambien va suelto a la
       izquierda, separado visualmente del grupo de acciones circulares de
       la derecha. La bandera del selector de idioma NO se toca (sigue a
       color, es un sprite de pais, no un icono de fuente); su caret SI se
       oscurece junto con el resto (selector .bt-nav-caret, generico). */
    .bt-sidebar-toggle,
    .bt-topstrip-actions .btn,
    .bt-topstrip-actions .bt-topbar-notifications > button.btn i,
    .bt-topstrip-actions .cart-btn,
    .bt-topstrip-actions .cart-btn i,
    .bt-topstrip-nav .bt-nav-link,
    .bt-topstrip-nav .bt-nav-caret {
        color: var(--bt-text);
    }
    .bt-topstrip-nav .bt-nav-link.bt-active {
        background: rgba(16, 98, 254, .1);
        color: var(--bt-text);
    }
    .bt-topstrip-nav .bt-nav-link:hover,
    .bt-topstrip-nav .bt-nav-link:focus {
        background: rgba(16, 98, 254, .06);
        color: var(--bt-text);
    }
    .bt-topstrip-nav .bt-nav-link:hover .bt-nav-caret,
    .bt-topstrip-nav .bt-nav-link:focus .bt-nav-caret {
        color: var(--bt-text);
    }

    /* Badge del carrito invertido: el fix base (fondo blanco/numero azul,
       linea ~953) se penso para verse SOBRE el degradado azul; en la
       franja blanca de movil seria blanco sobre blanco, invisible. Mismo
       selector-por-id que arriba. Notificaciones NO comparte esta regla
       (CORRECCION al gate, 08-02: "solo movil", sin clases globales de
       Bootstrap) -- su badge (.bt-notif-count) es autonomo y ya nace
       invertido (fondo azul/numero blanco) en su propia regla, mas abajo,
       porque esa regla SOLO existe dentro de este media query. */
    .bt-topstrip-actions #cartItemCount.badge-info {
        background: var(--bt-primary);
        color: #fff;
    }

    /* Aros finos de accion (notificaciones/carrito/idioma/cuenta), estilo
       de la referencia aprobada: borde 1px var(--bt-border), fondo
       transparente, icono oscuro centrado. Area tactil 44x44
       (accesibilidad) SIN agrandar el aro visual: el aro real mide 40px
       via ::before centrado (inset:2px = (44-40)/2), la caja clicable (el
       propio boton/enlace/summary) es la que mide 44x44 --
       box-sizing:border-box para que ese 44x44 incluya el padding
       existente del tema sin desbordar.
       CARRITO y NOTIFICACIONES llegan a circulo real (icono solo visible,
       badge superpuesto como distintivo, ver mas abajo) -- hasta el 08-02
       notificaciones se quedaba como PILDORA (aro mas ancho que alto)
       porque su numero era texto suelto en el markup, sin badge propio que
       se pudiera superponer aparte (ver comentario historico que sustituye
       este). Fallo 1 (bug medido: contador invisible, blanco sobre blanco)
       lo envolvio en <span id="notifCount" class="bt-notif-count">
       (header.tpl, clase propia del tema -- CORRECCION al gate 08-02: NO
       badge/badge-info, ver comentario de L~975) -- con eso el contenido
       visible del boton en movil ya es SOLO el icono. CORRECCION 1 al gate
       (08-02, premisa falsa detectada): esto NO era cierto para toda la
       banda movil como se afirmaba aqui originalmente -- el label de texto
       (<span class="d-none d-sm-inline">) seguia viendose entre 576px y
       991.98px (.d-sm-inline se activa desde min-width:576px, mientras que
       este media query llega hasta max-width:991.98px; ambos anchos
       conviven en esa banda). header.tpl cambia esas 2 etiquetas
       (notificaciones y su gemela "nonotifications") de d-sm-inline a
       d-lg-inline (breakpoint 992px, confirmado en el Bootstrap 4.5.3 del
       tema padre: banatheme-ref-twenty-one/css/theme.css, regla
       "@media (min-width: 992px) { .d-lg-inline {...} }"), asi el label
       queda oculto en TODA la banda movil (0-991.98px) y solo reaparece en
       escritorio (>=992px) -- coherente con notificaciones/carrito/idioma/
       cuenta, los 4 ya icono-puro hasta ese mismo breakpoint. Con el label
       oculto en toda la banda, el aro pasa a circulo real (icono-solo)
       tambien en toda la banda, no solo <576px, asi que se suma a la MISMA
       regla de reposicionado (mas abajo).
       IDIOMA y CUENTA quedan como PILDORA (aro mas ancho que alto) porque
       cada uno lleva un segundo elemento visible pegado al icono/bandera:
       su caret (bt-nav-caret), que senala "esto abre un menu" -- ver
       comentario de includes/bt-topstrip.tpl, que ya documentaba el caret
       de CUENTA como una convencion tomada prestada precisamente del
       selector de idioma ("mismo indicador visual...que usa el selector de
       idioma"); quitarle el caret solo a idioma habria invertido esa
       referencia y roto la familia visual entre los 2 triggers de menu.
       Fallo 2 (bug medido: bandera 61x22, sin aro, unico item bajo el
       minimo tactil de 44px -- .bt-lang-trigger estaba EXCLUIDO de esta
       regla con :not(.bt-lang-trigger); el selector generico
       .bt-topstrip-nav .bt-nav-link ya cubre TODOS los items de nivel 1 de
       la franja -- $secondaryNavbar via includes/bt-topstrip.tpl Y el
       selector de idioma de header.tpl comparten la misma clase base
       .bt-nav-link -- asi que idioma se suma sin seleccion aparte, mismo
       aro/hitbox que cuenta. Se preserva el caret (bandera+caret, igual
       que icono+caret de cuenta) en vez de quitarlo: la bandera SIGUE
       siendo lo mas visible/lo que manda visualmente (es color, el caret
       es lineart fino), y honra la convencion ya documentada arriba.
       ADVERTENCIA (no verificable sin desplegar): el ancho final de
       .bt-lang-trigger en movil no se midio en vivo tras este cambio --
       por calculo de padding/gap (4px 10px + gap:11px, igual que antes) el
       contenido no deberia perder ancho respecto a los 61px ya medidos
       (solo gana alto, 22px -> 44px, y el aro visual); si al desplegar
       resulta mas angosto o mas ancho de lo estimado, reajustar aqui.
       min-width:44px (no width fijo) deja que crezca mas alla de 44px
       cuando su contenido lo pide, sin dejar de verse redondeado por los
       extremos (999px siempre da esquinas totalmente curvas, independiente
       del ancho final). */
    .bt-topstrip-actions .bt-topbar-notifications > button.btn,
    .bt-topstrip-actions .cart-btn,
    .bt-topstrip-nav .bt-nav-link {
        position: relative;
        box-sizing: border-box;
        min-width: 44px;
        height: 44px;
        justify-content: center;
    }
    .bt-topstrip-actions .bt-topbar-notifications > button.btn::before,
    .bt-topstrip-actions .cart-btn::before,
    .bt-topstrip-nav .bt-nav-link::before {
        content: '';
        position: absolute;
        inset: 2px;
        border: 1px solid var(--bt-border);
        border-radius: 999px;
        pointer-events: none;
    }
    /* Carrito Y notificaciones: el badge pasa de pildora EN LINEA junto al
       icono (gap:6px del boton, base rules lineas ~931 y ~910) a
       distintivo superpuesto arriba a la derecha del aro, patron estandar
       de "icono + contador" -- mismos <span id="cartItemCount">/
       <span id="notifCount"> del markup, solo se reposicionan (Fallo 1:
       antes de la chapa el numero de notificaciones no tenia badge propio
       que reposicionar, quedaba EN LINEA junto al icono -- ver comentario
       de mas arriba). gap:0 en ambos botones porque ya no hay 2 hijos en
       fila (el badge deja de ocupar espacio inline). */
    .bt-topstrip-actions .cart-btn,
    .bt-topstrip-actions .bt-topbar-notifications > button.btn {
        gap: 0;
    }
    .bt-topstrip-actions #cartItemCount.badge-info {
        position: absolute;
        top: 2px;
        right: 2px;
        min-width: 15px;
        height: 15px;
        font-size: 9px;
        padding: 0 3px;
    }
    /* Notificaciones: regla UNICA y AUTOCONTENIDA para #notifCount
       (.bt-notif-count) -- CORRECCION al gate (08-02): a diferencia del
       carrito (que reusa 3 reglas -- base fuera del media query en
       L~953, invertido en L~1236 y reposicionado arriba -- porque
       #cartItemCount ya llevaba badge/badge-info de ANTES de esta rama),
       notificaciones NO tiene ninguna regla fuera de este media query: el
       dueno pidio "solo movil" para todo este trabajo y .bt-notif-count no
       usa clases globales de Bootstrap, asi que en escritorio (fuera de
       aqui) el <span id="notifCount"> no tiene NINGUNA regla que lo
       toque -- se renderiza como texto pelado, exactamente igual que antes
       de esta tanda (ver comentario de L~975). Forma final = misma chapa
       superpuesta que el carrito ya tiene en movil (15x15, fuente 9px,
       fondo azul/numero blanco). */
    .bt-topstrip-actions .bt-notif-count {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        position: absolute;
        top: 2px;
        right: 2px;
        box-sizing: border-box;
        min-width: 15px;
        height: 15px;
        padding: 0 3px;
        border-radius: 999px;
        background: var(--bt-primary);
        color: #fff;
        font-size: 9px;
        font-weight: 700;
        line-height: 1;
    }

    /* El panel desplegable (idioma/cuenta) ya es blanco (var(--bt-surface),
       linea ~756) — con la franja tambien blanca ahora, se refuerza su
       separacion (sin tocar la regla .bt-topstrip:has(.bt-nav-group[open])
       de linea ~868, que solo gobierna overflow/z-index, no color): borde
       un punto mas oscuro que var(--bt-border) y sombra mas presente que
       var(--bt-shadow) para que el panel se lea como una capa flotante
       distinta de la franja, no como una continuacion de ella. */
    .bt-topstrip-nav .bt-nav-sublist {
        border-color: #D5DAE3;
        box-shadow: 0 8px 24px rgba(27, 36, 48, .16);
    }
}

/* ============================================================
   Topbar (.bt-topbar) y breadcrumb (.bt-breadcrumb): RETIRADOS del
   markup (pedido del dueno) — la barra blanca solo tenia el buscador de
   knowledgebase, que se quito, y sin el quedaba vacia (las utilidades
   reales viven en .bt-topstrip desde un cambio anterior); el breadcrumb
   "Portal Home / Client Area" tambien se quito. Estas reglas quedaban
   huerfanas asi que se eliminan; .bt-content suma su propio padding-top
   de aqui en mas (ver abajo) para no quedar pegado a la franja azul.
   ============================================================ */
.bt-active-client .btn-active-client span {
    font-weight: 700;
    color: var(--bt-text);
}

/* ============================================================
   Breadcrumb global (header.tpl, dentro de .bt-main, antes de
   #main-body.bt-content) — pedido del dueno: rastro de navegacion en TODAS
   las paginas ("Services > Bana Starter Deluxe SSD Ultra"), limpio (sin
   "Portal Home / Client Area", ver seccion RETIRADOS arriba). Mismo look
   que .bt-pd-crumb (clientareaproductdetails.tpl): gris chico, separador
   &rsaquo;, item actual oscuro. Se gatea por $templatefile en header.tpl
   para no duplicarse con .bt-pd-crumb/.bt-kb-crumb propios de esas
   paginas. Margen lateral 28px para alinear con el gutter de
   #main-body.bt-content (28px, ver abajo); se reduce a 16px en el mismo
   breakpoint 991.98px donde .bt-content tambien lo reduce (mas abajo). */
.bt-breadcrumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 20px 28px 14px;
    font-size: 12.5px;
    color: #757B87;
}
.bt-breadcrumb a {
    color: #757B87;
    text-decoration: none;
}
.bt-breadcrumb a:hover {
    color: #4C7EDB;
    text-decoration: none;
}
.bt-breadcrumb a:focus-visible {
    outline: 2px solid var(--bt-primary);
    outline-offset: 2px;
}
.bt-breadcrumb-sep {
    color: #757B87;
}
.bt-breadcrumb-cur {
    color: #2A2F3A;
}
/* Nota (08-02): el margin-left:68px que aqui despejaba el boton hamburguesa
   fixed se retira -- el boton ya no flota sobre el contenido (paso a vivir
   en flujo dentro de .bt-topstrip, ver header.tpl y .bt-sidebar-toggle mas
   arriba), asi que el breadcrumb ya no tiene nada que esquivar y usa el
   mismo margin-left que el resto del layout (28px, regla base de arriba)
   en todos los anchos. */

/* ============================================================
   Contenido
   ============================================================ */
/* El contenedor de contenido es <section id="main-body" class="bt-content">.
   El theme base (theme.min.css) lo fija con `section#main-body { padding:
   20px 0 }` — un selector de ID (especificidad 1,0,1) que le gana a
   `.bt-content` (0,1,0), por eso el padding lateral de .bt-content NO tomaba
   y el contenido quedaba pegado al sidebar (solo el gutter de 15px de
   Bootstrap en .primary-content). Se iguala la especificidad del id
   (#main-body.bt-content = 1,1,1) para que el respiro lateral —la
   separacion sidebar<->contenido— aplique de verdad.
   padding-top propio: el contenido arranca bajo la franja azul sticky. */
#main-body.bt-content {
    padding: 28px 28px 40px;
    max-width: 100%;
}

/* ============================================================
   Home: sidebar contextual de WHMCS (Your Info/Contacts/Shortcuts —
   $primarySidebar/$secondarySidebar de header.tpl) sobra en la home del
   dashboard (esos datos ya viven en Mi Cuenta). Se detecta la home por el
   wrapper .bt-home que clientareahome.tpl pone en todo su contenido;
   .container-fluid es el ancestro comun tanto de la columna del sidebar
   contextual (desktop, .col-lg-4) como de su copia para movil que footer.tpl
   renderiza aparte (.sidebar-secondary). Se oculta aqui via .bt-home; en
   dominios se oculta igual pero por su propio wrapper .bt-domains (ver
   clientareadomains.tpl). CORRECCION (auditoria 2026-07-29): la frase
   original decia que "en el resto de paginas (p.ej. cuenta) ese sidebar
   contextual se sigue necesitando" — es FALSA, se oculta igual en otras
   16 paginas via el mismo patron :has() con su propio wrapper (domdetails,
   services, product details, affiliates, invoices, tickets, ticketview,
   ticket submit, Y las de cuenta: details/contacts/profile/security/
   password/security-legacy/switch-account/paymentmethods — ver el resto de
   bloques ":has(.bt-X)" mas abajo en este archivo).
   ============================================================ */
.container-fluid:has(.bt-home) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-home) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    /* Anular el gutter de 15px de la columna Bootstrap: el respiro lateral
       lo da #main-body.bt-content, asi el hueco lateral iguala al de arriba
       (28px) en vez de sumar 15px extra pegados al sidebar. */
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-home) .sidebar-secondary {
    display: none;
}

.bt-content .card-sidebar .card-header {
    border-top-left-radius: var(--bt-radius-lg);
    border-top-right-radius: var(--bt-radius-lg);
}

.bt-footer {
    padding: 24px 28px 40px;
    color: var(--bt-text-3);
    font-size: 12px;
}
/* En desktop, alinear "Contact Us / Terms" al MISMO borde derecho que el
   copyright: el .nav-link de Bootstrap trae padding-right ~1rem que dejaba
   el texto del ultimo enlace ~16px a la izquierda del borde. */
@media (min-width: 992px) {
    .bt-footer .nav.justify-content-lg-end .nav-item:last-child .nav-link { padding-right: 0; }
}

/* ============================================================
   Shell de auth — layout "panel de marca (split)" (aprobado por el dueno),
   COMPARTIDO por login, clientregister, password-reset-container y
   two-factor-challenge/two-factor-new-backup-code (ver el gate
   {if $templatefile == 'login' || ...} en header.tpl/footer.tpl). Pagina a
   pantalla completa, sin el shell del area de cliente. .bt-shell-auth es
   el grid de 2 columnas — aside con degradado de marca (mismos colores que
   la franja/hero: #1062FE -> #4FC3FF) y columna derecha (.bt-auth-main)
   con el contenido de cada pagina centrado (.bt-auth-content). El formulario
   nativo del login (.bt-login-card, sin tocar names/ids/action/hCaptcha)
   vive dentro de esa columna igual que antes. Bajo 900px el aside se
   oculta y el logo movil propio de login (.bt-login-mobile-logo) toma su
   lugar arriba del formulario.
   ============================================================ */
.bt-shell-auth {
    display: grid;
    grid-template-columns: 3fr 7fr;
    width: 100%;
}

.bt-auth-main {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    overflow-y: auto;
    background: #fff;
}

.bt-auth-content {
    width: 100%;
    max-width: 600px;
    margin: 0 auto;
    padding: 40px 24px;
}

/* Modificador solo para register (clientregister): el formulario nativo
   trae mas campos que login/reset/2FA y se aprieta en 540px — con el
   panel de marca reducido a 2fr/5 (40%) hay espacio de sobra para darle
   mas ancho SOLO a esta pagina; login/reset/2FA se quedan en 540px
   centrados (ya se ven bien ahi). Clase condicional puesta en
   header.tpl via {if $templatefile == 'clientregister'}. */
.bt-auth-content--wide {
    max-width: 760px;
}

.bt-login-brand {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 56px 60px;
    color: #fff;
    background: linear-gradient(135deg, #1062FE, #4FC3FF);
}
.bt-login-brand::before {
    content: "";
    position: absolute;
    top: -160px;
    right: -160px;
    width: 520px;
    height: 520px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .10);
}
.bt-login-brand::after {
    content: "";
    position: absolute;
    bottom: -140px;
    left: -120px;
    width: 360px;
    height: 360px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .08);
}
.bt-login-brand > * {
    position: relative;
    z-index: 1;
}
/* Fuerza blanco en TODO el texto del panel de marca. El h2/p heredados de
   twenty-one/theme.min.css (reglas globales de encabezado/parrafo, mas
   especificas que el "color:#fff" de .bt-login-brand por cascada de orden)
   pintaban el titular en negro sobre el degradado azul. Prefijar con
   .bt-body sube la especificidad (misma leccion que ".bt-body a" (0,1,1)
   documentada arriba para ganarle a las reglas globales del tema padre)
   sin necesitar !important. (El titular era <h1> hasta la auditoria de
   accesibilidad que lo bajo a <h2>: el <h1> real de cada pagina de auth
   es el de su propio formulario, p.ej. login.tpl.) */
.bt-body .bt-login-brand,
.bt-body .bt-login-brand-logo,
.bt-body .bt-login-brand-name,
.bt-body .bt-login-brand-name small,
.bt-body .bt-login-brand-pitch h2,
.bt-body .bt-login-brand-pitch p,
.bt-body .bt-login-brand-feats,
.bt-body .bt-login-brand-feats li,
.bt-body .bt-login-brand-foot {
    color: #fff;
}

.bt-login-brand-logo {
    display: flex;
    align-items: center;
    gap: 12px;
    font-weight: 700;
    font-size: 22px;
}
.bt-login-brand-mark {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    background: rgba(255, 255, 255, .18);
    font-weight: 700;
    font-size: 16px;
}
.bt-login-brand-name small {
    display: block;
    margin-top: 2px;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .5px;
    opacity: .85;
}

.bt-login-brand-pitch h2 {
    max-width: 15ch;
    margin: 0 0 16px;
    font-size: 38px;
    font-weight: 700;
    line-height: 1.15;
}
.bt-login-brand-pitch p {
    max-width: 44ch;
    margin: 0 0 28px;
    font-size: 16px;
    line-height: 1.6;
    opacity: .92;
}

.bt-login-brand-feats {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 15px;
}
.bt-login-brand-feats li {
    display: flex;
    align-items: center;
    gap: 12px;
}
.bt-login-brand-ck {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .20);
    font-size: 12px;
}

.bt-login-brand-foot {
    /* Footer (copyright) fijado abajo, para que el texto principal
       (titular + ventajas) quede CENTRADO verticalmente en el panel. */
    position: absolute;
    left: 60px;
    right: 60px;
    bottom: 40px;
    font-size: 13px;
    opacity: .8;
}

.bt-login-panel {
    /* El centrado/padding/fondo blanco de la columna derecha ya los aporta
       el shell de auth compartido (.bt-auth-main/.bt-auth-content, ver
       arriba); aqui solo queda el ancho para que el card no se estire. */
    display: flex;
    justify-content: center;
    width: 100%;
}

.bt-login-formwrap {
    width: 100%;
    max-width: 520px;
}

.bt-login-mobile-logo { display: none; }

.bt-login-panel .bt-login-card {
    max-width: none;
    /* Marco suave para que el formulario se vea enmarcado/organizado sobre
       el blanco (antes iba suelto sin borde). Borde tenue + sombra sutil. */
    border: 1px solid rgba(16, 24, 40, 0.04);
    border-radius: var(--bt-radius-lg);
    box-shadow: 0 10px 30px rgba(16, 24, 40, 0.05);
    padding: 48px 46px;
    background: var(--bt-surface);
}

.bt-login-card {
    width: 100%;
    max-width: 420px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 36px 34px;
}

.bt-login-logo {
    display: flex;
    justify-content: center;
    margin-bottom: 18px;
}
.bt-login-logo img { max-height: 42px; }
.bt-login-logo .bt-logo-text { font-size: 18px; }

.bt-login-card h1 {
    /* Grande y bold como el demo Lagom ("Secure Client Login"); mismo font
       Roboto. */
    font-size: 30px;
    font-weight: 700;
    line-height: 1.15;
    text-align: center;
    margin-bottom: 6px;
}
.bt-login-card .bt-login-sub {
    text-align: center;
    color: var(--bt-text-2);
    font-size: 14px;
    margin-bottom: 28px;
}

/* Labels e inputs al estilo del demo Lagom: label gris, input alto y
   redondeado con un solo borde en el grupo (icono + campo integrados). */
.bt-login-card .form-control-label {
    font-size: 14px;
    color: var(--bt-text-2);
    /* 400 -> 300 (unificacion 07-29): mismo peso fino del sidebar. */
    font-weight: 300;
}
.bt-login-card .input-group-merge {
    border: 1px solid var(--bt-border);
    border-radius: 10px;
    background: #fff;
    overflow: hidden;
}
.bt-login-card .input-group-merge .form-control,
.bt-login-card .input-group-merge .input-group-text,
.bt-login-card .input-group-merge .btn {
    height: 52px;
    border: 0;
    background: transparent;
    box-shadow: none;
}
.bt-login-card .input-group-merge .form-control { font-size: 16px; }
.bt-login-card .input-group-merge:focus-within {
    border-color: #1062FE;
    box-shadow: 0 0 0 3px rgba(16, 98, 254, 0.12);
}

.bt-login-card .btn-primary {
    width: 100%;
    height: 52px;
    padding: 0 12px;
    border-radius: 10px;
    font-size: 16px;
    font-weight: 700;
}

.bt-login-footer {
    text-align: center;
    margin-top: 18px;
    font-size: 12.5px;
    color: var(--bt-text-2);
}

@media (max-width: 899.98px) {
    .bt-shell-auth { grid-template-columns: 1fr; }
    .bt-login-brand { display: none; }
    .bt-auth-content { padding: 28px 22px; }
    .bt-login-mobile-logo { display: flex; }
    /* register/recuperar-contraseña/2FA no traen logo movil propio (solo
       login.tpl lo tiene via .bt-login-mobile-logo dentro del form nativo);
       queda pendiente si se quiere anadir uno generico arriba de
       .bt-auth-content para esas paginas — no se aplica aqui por
       simplicidad, ver informe. */
}

/* ============================================================
   Responsive: sidebar colapsable < 992px
   ============================================================ */
@media (max-width: 991.98px) {
    /* .bt-sidebar-toggle { display: inline-flex; ... } ya se declara arriba
       (media query de .bt-topstrip, linea ~1075) junto con .bt-topstrip-brand
       -- no se repite aqui para no dejar 2 fuentes de verdad del mismo
       selector. */

    /* Con el drawer movil abierto (footer.tpl agrega/quita esta clase en
       <html> al togglear/cerrar/tecla Esc) el body de atras seguia
       scrolleable detras del overlay. Se aplica en html Y body (iOS Safari
       no respeta de forma fiable overflow:hidden solo en <html>). Vive
       DENTRO de este media query: si el usuario abre el drawer en movil y
       luego ensancha/rota a >=992px sin que footer.tpl la quite, la clase
       nunca deja sin scroll al escritorio porque la regla ya no aplica.
       Sin JS el toggle ni la clase existen, la sidebar/overlay no se abren
       -> degradacion intacta. */
    html.bt-nav-open,
    html.bt-nav-open body {
        overflow: hidden;
    }

    .bt-sidebar {
        /* El ancho nuevo (264px, ver --bt-sidebar-w en :root) es SOLO para
           la sidebar fija de escritorio; el drawer movil vuelve a su
           ancho anterior — no necesita el espacio extra que pedia el
           logo en la version fija, y mantenerlo angosto dejaba mas
           overlay visible/tocable a los lados al abrirlo. */
        width: 236px;
        position: fixed;
        left: 0;
        top: var(--bt-topstrip-h);
        transform: translateX(-100%);
        transition: transform .2s ease;
        box-shadow: var(--bt-shadow);
    }
    .bt-sidebar.bt-open { transform: translateX(0); }

    /* El drawer movil vuelve a 236px (arriba) y ya no tiene el margen extra
       que si tiene la sidebar fija de escritorio a 264px: el logo (430x80,
       ver --bt-sidebar-w en :root) desborda su contenedor y recorta la
       ultima letra de "BanaHosting" (medido en vivo: right:248px contra un
       ancho de 236px). Se limita al ancho disponible SOLO aqui (movil);
       max-height:42px de escritorio queda intacto fuera de este media
       query. */
    .bt-sidebar .bt-logo-img { max-width: 100%; }

    .bt-sidebar-overlay.bt-open { display: block; }

    /* #main-body.bt-content para ganarle al #main-body del theme base (id);
       .bt-content a secas no tomaba. */
    #main-body.bt-content { padding-left: 16px; padding-right: 16px; }
    .bt-footer { padding-left: 16px; padding-right: 16px; }

    /* Cabecera movil unificada (08-02): el boton hamburguesa ya NO flota
       fixed sobre el contenido (paso a vivir en flujo dentro de
       .bt-topstrip, ver header.tpl y .bt-sidebar-toggle mas arriba), asi
       que ya no hace falta el respiro extra de 64px que le reservaba
       sitio -- #main-body.bt-content vuelve al padding-top base (28px,
       ver regla propia mas arriba), igual que en escritorio. */
}

/* ============================================================
   Dashboard — F1b (clientareahome): hero, tarjetas de servicios,
   timeline de vencimientos, pago pendiente, soporte.
   ============================================================ */
.bt-home { max-width: 100%; }
/* Pedido del dueno: texto solido negro (var(--bt-text), #1B2430) de la home
   pasa a gris oscuro #3A4150 SIN tocar el token global --bt-text (que
   siguen usando el resto de paginas). Cubre por herencia todo el texto
   plano que no fija su propio color (nombres de tarjeta, monto a pagar,
   vencimientos...); los h2/h3 de .bt-sh/.bt-panel/.bt-more-card-hd, mas
   abajo, no heredan porque ".bt-body h1..h6" (misma especificidad 0,1,1
   por clase+tipo) los pisa directo — se repintan alli explicitamente. */
.bt-home { color: #4A5160; }

/* Hero llamativo (pedido del dueno): degradado diagonal de marca, mismos
   colores exactos que la franja azul superior y el logo (#1062FE ->
   #2E9BFA -> #4FC3FF, Tanda 13 de whmcs-actualizacion-y-diseno/hooks/
   highlight_cancel.php), pero en diagonal (120deg) para diferenciarlo de
   la franja horizontal (90deg) — mismo sistema de color, look propio. Ya
   NO lleva las 4 stat-tiles (Services/Domains/Invoices/Tickets): esos
   contadores ya viven en las tarjetas de Mis Webs/Mis Dominios/Mis
   Tickets de la fila triple, no hacia falta duplicarlos aqui. Todo el
   texto de dentro fuerza color blanco explicito (nunca heredar el gris
   de ".bt-body h1..h6"/".bt-hero-sub" que usaba el hero claro anterior —
   misma leccion de especificidad que .bt-body a documentada en este
   archivo). */
.bt-hero {
    position: relative;
    max-width: 100%;
    box-sizing: border-box;
    border-radius: 14px;
    padding: 32px 36px;
    overflow: hidden;
    margin: 12px 0 40px;
    background-color: #1062FE;
    background-image: linear-gradient(120deg, #1062FE 0%, #2E9BFA 55%, #4FC3FF 100%);
    box-shadow: 0 8px 28px rgba(16, 98, 254, .28);
}
/* Decoracion sutil: circulo translucido a la derecha, blanco muy bajo,
   puramente cosmetico (aria-hidden implicito: pseudo-elemento, no hay
   nodo real que un lector de pantalla anuncie). overflow:hidden de
   .bt-hero ya lo recorta a los bordes redondeados del hero. */
.bt-hero::after {
    content: "";
    position: absolute;
    top: -60px;
    right: -60px;
    width: 220px;
    height: 220px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .08);
    pointer-events: none;
}
.bt-hero-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 18px;
    position: relative;
    z-index: 1;
}
.bt-hero-main { min-width: 0; }
/* .bt-hero .bt-hero-title (dos clases, especificidad 0,2,0): hace falta
   para ganarle a ".bt-body h1, .bt-body h2, ... " (0,1,1 — clase + tipo
   h1) que fija el gris oscuro del tema para TODOS los encabezados; con
   un solo selector de clase (0,1,0) esa regla base gana igual pese a
   venir antes en el archivo, y el titulo del hero saldria en gris sobre
   el degradado azul en vez de blanco. Mismo patron de especificidad que
   .bt-site-act.bt-site-act-main / .bt-hero-stats .bt-stat-tile de este
   archivo. */
.bt-hero .bt-hero-title {
    font-size: 28px;
    font-weight: 700;
    letter-spacing: -.02em;
    margin: 0;
    color: #fff;
}
.bt-hero-sub { color: rgba(255, 255, 255, .9); font-size: 13.5px; margin: 8px 0 0; }
/* .bt-hero-chip (dos clases via .bt-hero-row .bt-hero-chip mas abajo no
   hace falta: una sola clase ya alcanza por especificidad frente a
   ".bt-body a" 0,1,1 porque este chip es un <span>, no un <a> — no
   compite con esa regla). Fondo blanco solido + texto azul primario:
   maximo contraste sobre el degradado, mismo tratamiento tanto si hay
   facturas pendientes como si la cuenta esta al dia (antes el estado
   "ok" era verde sutil; unificado a blanco/azul para que siempre
   resalte igual de bien sobre el hero). */
.bt-hero-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: #fff;
    border: none;
    border-radius: 999px;
    padding: 9px 16px;
    font-weight: 700;
    font-size: 12.5px;
    color: var(--bt-primary);
    white-space: nowrap;
}
/* .bt-hero-chip-warn ahora es <a href="...action=invoices"> (antes
   <span>, pedido del dueno: clicable a la lista de facturas). Selector
   de DOS clases (.bt-hero-chip.bt-hero-chip-warn, especificidad 0,2,0)
   para ganarle a ".bt-body a"/".bt-body a:hover" (0,1,1 / 0,2,1) — con
   una sola clase el chip heredaria el azul-link estandar y su color de
   hover en vez de quedarse blanco/azul como el resto del hero (misma
   leccion de especificidad que ".bt-hero .bt-hero-title" mas arriba).
   Sin subrayado (se ve como el pill de siempre, no como un link de
   texto) y con un hover sutil (sombra + opacidad leve) que avisa que es
   clicable sin cambiar de color. El box-shadow del hover no se recorta
   por el overflow:hidden de .bt-hero: el chip vive dentro del padding
   del hero (32/36px), muy lejos del borde para que un blur de 14px lo
   alcance. */
.bt-hero-chip.bt-hero-chip-warn {
    cursor: pointer;
    text-decoration: none;
    transition: box-shadow .15s ease, opacity .15s ease;
}
.bt-hero-chip.bt-hero-chip-warn:hover,
.bt-hero-chip.bt-hero-chip-warn:focus {
    text-decoration: none;
    box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
    opacity: .92;
}

.bt-section { margin-bottom: 40px; }
.bt-sh {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin: 0 0 18px;
}
/* color explicito: ".bt-body h2" (0,1,1) le gana por especificidad a la
   herencia de .bt-home, asi que sin esto el h2 se quedaria en var(--bt-text)
   pese al gris de .bt-home. */
.bt-sh h2 { font-size: 17px; font-weight: 300; letter-spacing: -.01em; margin: 0; color: #4A5160; }
.bt-sh a { color: var(--bt-primary); font-size: 12.5px; font-weight: 700; text-decoration: none; }

.bt-empty { color: var(--bt-text-3); font-size: 13px; margin: 0; }

.bt-empty-state {
    text-align: center;
    padding: 44px 20px;
    background: var(--bt-surface);
    border: 1px dashed var(--bt-border);
    border-radius: var(--bt-radius-lg);
}
.bt-empty-emoji { font-size: 40px; line-height: 1; margin-bottom: 12px; }
.bt-empty-state-text { color: var(--bt-text-2); font-size: 13.5px; margin: 0 0 18px; }
/* .bt-body .bt-empty-cta (dos clases, especificidad 0,2,0): mismo motivo
   que .bt-site-act.bt-site-act-main de arriba, gana por especificidad a
   ".bt-body a" (0,1,1). Azul sutil #4C7EDB/borde #CFE0FF, iteracion sobre
   el gris #757B87 que el dueno descarto (y sobre el azul primario fuerte
   #1062FE, tambien descartado) — usan estos 3 CTA los empty-states de
   Tus webs/Mis dominios/Tickets de la fila triple (Contratar/Registrar/
   Abrir ticket). */
.bt-body .bt-empty-cta {
    display: inline-block;
    background: transparent;
    border: 1px solid #CFE0FF;
    color: #4C7EDB;
    font-weight: 500;
    font-size: 13px;
    border-radius: var(--bt-radius-sm);
    padding: 10px 22px;
    text-decoration: none;
}
.bt-body .bt-empty-cta:hover {
    background: #F0F5FF;
    border-color: #A9C6FF;
    color: var(--bt-primary);
    text-decoration: none;
}

.bt-site {
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 24px;
    display: flex;
    flex-direction: column;
    /* flex:1 dentro de .bt-tri-stack (flex-column): si es la unica
       tarjeta de la columna (Mis Dominios/Mis Tickets cuando hay 1 item)
       crece para llenar todo el stack; si hay varias (Mis Webs, hasta 6),
       el espacio extra se reparte por igual entre ellas. flex-basis 0%
       (parte del shorthand flex:1) no arriesga recorte de contenido: la
       "automatic minimum size" de flexbox impide que un item se encoja
       por debajo de su alto minimo de contenido salvo overflow!=visible,
       que no se usa aqui. */
    flex: 1;
    gap: 16px;
}
.bt-site-hd { display: flex; align-items: center; gap: 14px; }
.bt-site-fav {
    width: 42px;
    height: 42px;
    border-radius: var(--bt-radius-sm);
    font-size: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    background: #EAF1FF;
}
.bt-site-id { min-width: 0; flex: 1 1 auto; }
.bt-site-dom {
    display: block;
    max-width: 100%;
    /* 600 -> 500 -> 400 (pedido del dueno): un punto mas fino, mismo tamaño. */
    font-weight: 400;
    font-size: 15px;
    letter-spacing: -.015em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* 400 -> 300 (unificacion 07-29): mismo peso fino del sidebar, mismo tamaño. */
.bt-site-plan { color: var(--bt-text-3); font-size: 12.5px; font-weight: 300; margin-top: 1px; }

.bt-pill {
    margin-left: auto;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    font-weight: 700;
    border-radius: 999px;
    padding: 4px 10px;
    white-space: nowrap;
}
.bt-pill-green { color: var(--bt-green); background: rgba(16, 185, 129, .1); }
.bt-pill-red { color: var(--bt-red); background: rgba(220, 38, 38, .1); }
.bt-pill-amber { color: var(--bt-amber); background: rgba(217, 119, 6, .1); }
.bt-pill-gray { color: var(--bt-text-2); background: rgba(120, 126, 160, .1); }
.bt-pill-blue { color: var(--bt-primary); background: rgba(16, 98, 254, .1); }

.bt-use { display: flex; flex-direction: column; gap: 8px; }
/* 400 -> 300 (unificacion 07-29): mismo peso fino del sidebar, mismo tamaño. */
.bt-use-u { font-size: 12.5px; color: var(--bt-text-2); font-weight: 300; }
/* .bt-use-none se queda en 400: a 11px (<12px) Roboto 300 se lava, riesgo
   de legibilidad (punto 5 del pedido). */
.bt-use-none { font-size: 11px; color: var(--bt-text-3); font-weight: 400; }
.bt-bar {
    height: 6px;
    border-radius: 99px;
    background: rgba(120, 126, 160, .16);
    margin-top: 4px;
    overflow: hidden;
}
.bt-bar-fill {
    height: 100%;
    border-radius: 99px;
    background: var(--bt-primary);
}
.bt-bar-fill-hot { background: var(--bt-amber); }

.bt-site-acts { display: flex; gap: 10px; margin-top: auto; }
.bt-site-acts .bt-site-act {
    flex: 1;
    text-align: center;
    border: 1px solid #CFE0FF;
    border-radius: var(--bt-radius-sm);
    padding: 9px 4px;
    font-size: 13px;
    font-weight: 500;
    color: #4C7EDB;
    text-decoration: none;
}
.bt-site-acts .bt-site-act:hover { color: var(--bt-primary); background: #F0F5FF; border-color: #A9C6FF; text-decoration: none; }
/* .bt-site-act.bt-site-act-main (dos clases, especificidad 0,2,0) para
   ganarle siempre a ".bt-body a" (0,1,1) — sigue haciendo falta con el azul
   sutil actual: sin esta especificidad el texto heredaria el azul #1062FE
   de ".bt-body a" igual (por coincidencia visual pareceria bien) pero NO
   el weight/border propios, y el :hover de ".bt-body a" (color mas oscuro,
   sin fondo) pisaria el fondo #F0F5FF de aqui. Iteracion: el dueno probo
   primero el azul primario fuerte #1062FE (demasiado "pop"), despues un
   gris suave #757B87 (lo descarto), y se quedo con este azul sutil
   #4C7EDB con borde #CFE0FF — el mismo borde "estilo Lagom" ya aprobado
   en los tiles de Product Details. Sin distincion fuerte entre botones:
   Aplica a Tus webs (Administrar), Mis dominios (Administrar) y Tickets
   (Ver ticket) — las 3 comparten esta clase. Ver tambien
   .bt-body .bt-empty-cta mas abajo, mismo tratamiento; .bt-body .bt-paybtn
   ahora lleva relleno azul claro #EAF1FF (mismo lenguaje que .bt-bubble-out),
   un paso mas lleno que los outline de arriba para conservar su jerarquia
   de CTA principal (es el CTA de pago, no una tarjeta de la fila triple).
   NOTA: los secundarios (.bt-site-acts .bt-site-act, arriba)
   y .bt-chat-cta (mas abajo) tambien necesitaron subir de una sola clase
   (0,1,0) a dos (0,2,0/0,2,1) por la misma razon — perdian contra
   ".bt-body a" y volvian a salir azules en vivo; que nadie los baje de
   nuevo a una sola clase. */
.bt-site-act.bt-site-act-main {
    border: 1px solid #CFE0FF;
    color: #4C7EDB;
    font-weight: 500;
    background: transparent;
}
.bt-site-act.bt-site-act-main:hover {
    background: #F0F5FF;
    border-color: #A9C6FF;
    color: var(--bt-primary);
}

/* ============================================================
   Fila de tres columnas: Tus webs / Mis dominios / Tickets de soporte.
   Cada columna es una pila vertical (.bt-tri-stack) de tarjetas RICAS
   (mismo lenguaje visual que .bt-site: blanco, sombra sutil, radio 6px),
   no rows planos — el dueno pidio recuperar la tarjeta de servicio con
   barra de renovacion + acciones y el mismo tratamiento para dominios y
   tickets. Colapsa a una columna en movil via auto-fit + minmax.
   ============================================================ */
.bt-tri {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
    gap: 30px;
    /* Pedido del dueno: las 3 columnas del MISMO alto, alineadas. "stretch"
       es el valor por defecto de align-items en grid, pero se deja
       explicito (reforzado) en vez de confiar en el default implicito. */
    align-items: stretch;
}
/* Columna = flex-column de alto completo (lo que le da el stretch del
   grid de arriba): cabecera arriba, tarjeta(s) en el medio, y
   .bt-tri-more empujado al fondo con margin-top:auto (ver abajo) para
   que el "Ver todos" de las 3 columnas quede en la misma linea inferior
   aunque el contenido de cada una tenga distinto alto. */
.bt-tri-col {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-width: 0;
}
.bt-tri-more { margin-top: auto; padding-top: 10px; text-align: right; }
.bt-tri-more a { color: #4C7EDB; font-size: 12.5px; font-weight: 700; text-decoration: none; }
.bt-tri-more a:hover { color: var(--bt-primary); }

/* Pila de tarjetas de una columna: crece en alto libremente (hasta 6 items
   en $btServices), cada tarjeta con su propio gap. flex:1 (dentro de
   .bt-tri-col, que ya es flex-column de alto completo por el stretch del
   grid .bt-tri) hace que el stack ocupe TODO el espacio entre la cabecera
   y el "Ver todos" — sin esto, aunque la columna midiera igual, el stack
   se quedaria en su alto natural y dejaria el hueco pegado abajo (antes
   del margin-top:auto de .bt-tri-more) en vez de dentro de la(s)
   tarjeta(s). */
.bt-tri-stack {
    display: flex;
    flex-direction: column;
    flex: 1;
    gap: 16px;
}

/* Cascaron comun de tarjeta rica (mismo que .bt-site ya traia): superficie
   blanca, borde fino, sombra sutil, radio 6px, columna con acciones al
   fondo (margin-top:auto en .bt-site-acts, reusado tambien por dominios/
   tickets). .bt-dcard (dominios) y .bt-tcard (tickets) son tarjetas MAS
   simples que .bt-site (sin favicon/plan) pero con el mismo cascaron y las
   mismas clases de pill/uso/acciones para no duplicar esas reglas. */
.bt-dcard,
.bt-tcard {
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 24px;
    display: flex;
    flex-direction: column;
    /* Mismo flex:1 que .bt-site, mismo motivo (ver comentario ahi):
       Mis Dominios (1 sola tarjeta) crece para igualar el alto de Mis
       Webs (la columna de referencia, normalmente la mas alta por su
       barra de renovacion + 2 botones); Mis Tickets reparte el sobrante
       entre sus tarjetas si hay varias. */
    flex: 1;
    gap: 16px;
}
.bt-dcard-hd,
.bt-tcard-hd { display: flex; align-items: center; gap: 14px; }
.bt-dcard-name,
.bt-tcard-title {
    min-width: 0;
    flex: 1 1 auto;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* 600 -> 500 -> 400 (pedido del dueno): un punto mas fino, mismo tamaño. */
    font-weight: 400;
    font-size: 14.5px;
    letter-spacing: -.01em;
}

.bt-empty-state-sm { padding: 26px 16px; }
.bt-empty-state-sm .bt-empty-state-text { margin-bottom: 12px; }

.bt-lower {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
    gap: 30px;
    margin-bottom: 40px;
}
.bt-panel {
    min-width: 0;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 28px;
}
/* Tipografía de títulos unificada con .bt-sh h2 a pedido del dueño.
   color explicito: mismo motivo que .bt-sh h2 (".bt-body h3" le gana a la
   herencia de .bt-home). */
.bt-panel h3 { font-size: 17px; font-weight: 300; letter-spacing: -.01em; margin: 0 0 18px; color: #4A5160; }

.bt-tl { display: flex; gap: 10px; flex-wrap: wrap; }
.bt-tl-ev {
    flex: 1 1 100px;
    border-radius: var(--bt-radius-sm);
    border: 1px dashed var(--bt-border);
    background: var(--bt-surface);
    padding: 12px;
    text-align: center;
}
.bt-tl-ev-hot { border: 1.5px solid var(--bt-amber); background: var(--bt-surface); }
.bt-tl-ev-hot .bt-tl-d { color: var(--bt-amber); }
.bt-tl-d { font-size: 10.5px; font-weight: 700; color: var(--bt-text-3); text-transform: uppercase; letter-spacing: .06em; }
/* 700 -> 500 (pedido del dueno): carater fino, mismo tamaño. No toca
   .bt-tl-ev-hot .bt-tl-d (ambar) ni .bt-tl-d. */
/* 400 -> 300 (unificacion 07-29): mismo peso fino del sidebar, mismo tamaño. */
.bt-tl-w { font-size: 12.5px; font-weight: 300; margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bt-tl-t { font-size: 10.5px; color: var(--bt-text-2); margin-top: 2px; }

.bt-pay { display: flex; flex-direction: column; }
/* 700 -> 600 (pedido del dueno): carater fino, mismo tamaño. Sin color
   propio: hereda el gris #3A4150 de .bt-home. */
.bt-pay-amt { font-size: 30px; font-weight: 500; letter-spacing: -.02em; }
.bt-pay-amt small { font-size: 12px; color: var(--bt-text-2); font-weight: 700; }
.bt-pay-amt small.bt-pay-overdue { color: var(--bt-red); font-weight: 700; }
/* Pedido del dueno ("mas moderno"): pildora + degradado sutil + lift al hover. */
/* degradado del hero #1062FE -> #4FC3FF, elegido por el dueño (mockup A);
   forma rectangular original (border-radius sm), no pildora. */
.bt-body .bt-paybtn {
    display: block;
    text-align: center;
    background: linear-gradient(135deg, #1062FE 0%, #4FC3FF 100%);
    color: #fff;
    border: none;
    font-weight: 700;
    font-size: 13px;
    border-radius: var(--bt-radius-sm);
    padding: 12px;
    text-decoration: none;
    box-shadow: 0 2px 8px rgba(16, 98, 254, .25);
    margin-top: 12px;
    transition: background .15s ease, box-shadow .15s ease, transform .15s ease;
}
.bt-body .bt-paybtn:hover {
    background: linear-gradient(135deg, #0B4FD6 0%, #38B6F8 100%);
    box-shadow: 0 4px 12px rgba(16, 98, 254, .30);
    transform: translateY(-1px);
    color: #fff;
    text-decoration: none;
}
.bt-body .bt-paybtn:active {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(16, 98, 254, .08);
}
@media (prefers-reduced-motion: reduce) {
    .bt-body .bt-paybtn,
    .bt-body .bt-paybtn:hover {
        transition: none;
        transform: none;
    }
}

.bt-chat { display: flex; flex-direction: column; gap: 10px; }
.bt-bubble { border-radius: var(--bt-radius-sm); padding: 10px 13px; font-size: 12px; max-width: 90%; }
/* var(--bt-text) -> #3A4150 (pedido del dueno, gris de la home): clase
   solo usada en la burbuja de chat de clientareahome.tpl, no hace falta
   scoping extra. */
.bt-bubble-in { background: #F7F8FB; color: #4A5160; }
.bt-bubble-out {
    background: #EAF1FF;
    color: #0B4FD6;
    align-self: flex-end;
}
.bt-body a.bt-chat-cta { color: #4C7EDB; font-weight: 700; font-size: 12.5px; text-decoration: none; margin-top: 4px; }
.bt-body a.bt-chat-cta:hover { color: var(--bt-primary); }

/* ============================================================
   "Mas" — HomePagePanels que no duplican las tarjetas propias del
   dashboard (tickets recientes, registrar dominio, afiliados, noticias,
   paneles de addons desconocidos). Grid de 2 columnas, compactas.
   ============================================================ */
.bt-more-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: 30px;
}
.bt-more-card {
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    overflow: hidden;
}
.bt-more-card-hd {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 16px 18px 12px;
    border-bottom: 1px solid var(--bt-border);
}
/* Tipografía de títulos unificada con .bt-sh h2 a pedido del dueño.
   color explicito: mismo motivo que .bt-sh h2 (".bt-body h3" le gana a la
   herencia de .bt-home). */
.bt-more-card-hd h3 {
    font-size: 17px;
    font-weight: 300;
    letter-spacing: -.01em;
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
    color: #4A5160;
}
.bt-more-card-act {
    flex: 0 0 auto;
    color: var(--bt-primary);
    font-size: 12px;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}
.bt-more-card-body {
    min-width: 0;
    padding: 14px 18px;
    max-height: 260px;
    overflow-y: auto;
    overflow-x: auto;
    font-size: 13px;
}
.bt-more-card-body .list-group-item { border-left: none; border-right: none; }
.bt-more-card-ft {
    padding: 10px 18px;
    border-top: 1px solid var(--bt-border);
    font-size: 12px;
}

/* ============================================================
   Mis Dominios (clientareadomains) — F6, tarjetas/filas modernas (mockup
   aprobado 07-25). Ver clientareadomains.tpl para el HTML/Smarty; aqui
   solo el skin, con prefijo .bt-dm- para no colisionar con nada de
   Twenty-One/Bootstrap. Igual que Home: sidebar contextual de WHMCS
   oculto SOLO aqui via el wrapper .bt-domains (mismo patron :has() que
   .bt-home, ver arriba).
   ============================================================ */
.container-fluid:has(.bt-domains) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-domains) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    /* Mismo criterio que en home: anular el gutter de 15px para que el
       respiro lateral lo controle #main-body.bt-content de forma uniforme. */
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-domains) .sidebar-secondary {
    display: none;
}
/* Domain Details: mismo patron — ocultar el sidebar contextual secundario
   (Manage/Quick Actions/Domain Information/Billing/Actions), que aqui sobra
   porque las acciones ya viven en la grilla de tarjetas; contenido a full. */
.container-fluid:has(.bt-domdetails) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-domdetails) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-domdetails) .sidebar-secondary {
    display: none;
}

/* ============================================================
   Mis Servicios (clientareaproducts) — mismo lenguaje visual que Mis
   Dominios (F6), reusa .bt-dm-* al maximo. Ver clientareaproducts.tpl.
   ============================================================ */
.container-fluid:has(.bt-services) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-services) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-services) .sidebar-secondary {
    display: none;
}
/* Sin checkbox/auto-renew/kebab: fila mas corta que la de dominios, con
   DOS columnas de meta (precio + proximo vencimiento) en vez de una. Mismo
   ajuste de minimos que .bt-dm-item de arriba (F1c-bis) para las fuentes
   mas grandes; la ultima columna (solo Manage, sin kebab) necesita menos
   piso que la de dominios. */
.bt-services .bt-dm-item {
    /* Rebalanceo (dueno, medido en vivo a 1278px): con NextDue 1.2fr y
       Estado sin fr propio, el hueco entre el contenido de NextDue y
       Estado quedaba enorme. Precio/NextDue/Estado pasan las TRES a 1fr
       para repartir la holgura pareja entre las 3 columnas de datos;
       Manage se queda auto (el boton no debe estirarse). El piso de
       Estado sube 112->120px (verificado con mock headless Playwright,
       "Transferred Away" mide ~114px de ancho real): con 1fr como MAXIMO
       de la pista (a diferencia de "auto", que crecia al contenido) un
       piso de 112px dejaba el estado mas largo envolver a 2 lineas a
       958px; 120px le da margen. */
    grid-template-columns: auto minmax(0, 2fr) minmax(116px, 1fr) minmax(126px, 1fr) minmax(120px, 1fr) minmax(90px, auto);
}
.bt-sv-cycle { color: var(--bt-text-3); font-size: 11px; font-weight: 400; }

.bt-dm svg { width: 1em; height: 1em; display: block; }
.bt-dm * { box-sizing: border-box; }

/* El respiro respecto al tope de la pagina y al sidebar ahora lo da
   #main-body.bt-content (uniforme con el home), asi que .bt-dm ya no
   agrega padding propio arriba/lados (antes 44px 40px que se SUMABA al de
   #main-body y hundia la lista). Solo conserva un poco abajo. */
.bt-dm { padding: 24px 0 30px; }
@media (max-width: 820px) {
    .bt-dm { padding: 12px 0 20px; }
}

.bt-dm-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}
.bt-dm-title { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.bt-dm-title h1, .bt-dm-title h2 { font-size: 20px; font-weight: 300; margin: 0; color: var(--bt-text); }
.bt-dm-title-ic {
    width: 38px;
    height: 38px;
    border-radius: 11px;
    background: linear-gradient(135deg, var(--bt-primary), #4FC3FF);
    color: #fff;
    display: grid;
    place-items: center;
    font-size: 17px;
}
.bt-dm-count { color: var(--bt-text-2); font-size: 13.5px; font-weight: 400; }

.bt-dm-headright { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.bt-dm-search { position: relative; }
.bt-dm-search-input {
    height: 40px;
    width: 230px;
    max-width: 60vw;
    border: 1.5px solid var(--bt-border);
    border-radius: 10px;
    padding: 0 14px 0 38px;
    font-size: 13.5px;
    font-family: var(--bt-font);
    background: var(--bt-surface);
    color: var(--bt-text);
}
.bt-dm-search-input:focus {
    outline: none;
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 3px rgba(16, 98, 254, .12);
}
.bt-dm-search-i {
    position: absolute;
    left: 13px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--bt-text-3);
    font-size: 14px;
    pointer-events: none;
}

.bt-dm-sortwrap { position: relative; }
.bt-dm-sort {
    height: 40px;
    max-width: 60vw;
    border: 1.5px solid var(--bt-border);
    border-radius: 10px;
    padding: 0 30px 0 14px;
    font-size: 13.5px;
    font-family: var(--bt-font);
    background: var(--bt-surface);
    color: var(--bt-text);
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238A8F99' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 14px;
    cursor: pointer;
}
.bt-dm-sort:focus {
    outline: none;
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 3px rgba(16, 98, 254, .12);
}

.bt-dm-headacts { display: flex; gap: 10px; flex-wrap: wrap; }

.bt-dm-toolbar { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }

/* Correccion del dueno: el azul sutil unificado con la home (commit
   55fd684) es SOLO para el nombre principal (.bt-dm-dom mas abajo) y el
   boton "Manage"/"Gestionar" por fila (.bt-dm-managebtn, ver mas abajo,
   con su icono via la regla scoped .bt-dm-managebtn .bt-dm-tbtn-i). La
   barra de acciones de arriba (Manage Nameservers / Edit Contact
   Information / Renew Domains / More) y sus items de kebab se QUEDAN en
   gris #757B87/var(--bt-text) como origen — no forman parte del pedido. */
.bt-dm-tbtn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 40px;
    padding: 0 16px;
    border: 1px solid var(--bt-border);
    border-radius: 10px;
    background: var(--bt-surface);
    color: #757B87;
    font-size: 13.5px;
    font-weight: 400;
    font-family: var(--bt-font);
    cursor: pointer;
    text-decoration: none;
    transition: border-color .15s, color .15s;
}
.bt-dm-tbtn:hover, .bt-dm-more[open] > .bt-dm-tbtn {
    border-color: var(--bt-primary);
    color: var(--bt-primary);
    text-decoration: none;
}
.bt-dm-tbtn-i { display: inline-flex; font-size: 15px; color: var(--bt-text-2); }
.bt-dm-tbtn:hover .bt-dm-tbtn-i, .bt-dm-more[open] > .bt-dm-tbtn .bt-dm-tbtn-i { color: var(--bt-primary); }

/* Boton primario (Registrar dominio): relleno con degradado, mismo tono
   que el icono de cabecera. Unico uso de gradiente-boton de la pagina. */
/* Doble clase (.bt-dm-tbtn.bt-dm-tbtn--primary = 0,2,0) para ganarle a
   `.bt-body a` (0,1,1) que si no pinta el texto azul sobre el fondo azul
   (invisible); el icono ya iba blanco por su propia regla. */
.bt-dm-tbtn.bt-dm-tbtn--primary,
.bt-body a.bt-dm-tbtn--primary {
    border-color: transparent;
    background: linear-gradient(135deg, var(--bt-primary), #274ee0);
    color: #fff;
    box-shadow: 0 8px 20px rgba(16, 98, 254, .22);
}
.bt-dm-tbtn.bt-dm-tbtn--primary:hover,
.bt-body a.bt-dm-tbtn--primary:hover {
    border-color: transparent;
    color: #fff;
    opacity: .92;
}
.bt-dm-tbtn--primary .bt-dm-tbtn-i,
.bt-dm-tbtn--primary:hover .bt-dm-tbtn-i { color: #fff; }

/* Botones grandes para el bloque "ordenar dominio" al pie */
.bt-dm-tbtn--lg { height: 48px; padding: 0 22px; font-size: 14.5px; border-radius: 12px; }
.bt-dm-tbtn--lg .bt-dm-tbtn-i { font-size: 17px; }

/* Bloque "¿Necesitas otro dominio?" al PIE de la lista — holgado */
.bt-dm-order {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    margin-top: 34px;
    padding: 28px 30px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
}
.bt-dm-order-title { font-size: 18px; font-weight: 300; margin: 0 0 4px; color: var(--bt-text); }
.bt-dm-order-sub { font-size: 13.5px; color: var(--bt-text-3); margin: 0; }
.bt-dm-order-acts { display: flex; gap: 14px; flex-wrap: wrap; }
/* Bloque "Servicios para tu dominio" al pie de la LISTA (reusa .bt-dd-*) */
.bt-dm-svc { margin-top: 30px; }
@media (max-width: 620px) {
    .bt-dm-order { flex-direction: column; align-items: stretch; text-align: left; }
    .bt-dm-order-acts { flex-direction: column; }
    .bt-dm-order-acts .bt-dm-tbtn--lg { justify-content: center; }
}

/* "More": <details> nativo, sin JS extra. summary ya trae su propia
   flecha en algunos navegadores; se quita para no duplicar con el icono
   de puntos suspensivos que ya usamos. */
.bt-dm-more { position: relative; }
.bt-dm-more > summary { list-style: none; }
.bt-dm-more > summary::-webkit-details-marker { display: none; }
.bt-dm-more-menu {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    min-width: 230px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 12px;
    box-shadow: 0 16px 40px rgba(16, 24, 40, .14);
    padding: 5px;
    z-index: 5;
}
.bt-dm-more-grouplabel {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--bt-text-3);
    padding: 8px 12px 4px;
}
.bt-dm-mi {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-radius: 9px;
    font-size: 13px;
    font-weight: 400;
    color: var(--bt-text);
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
}
.bt-dm-mi:hover { background: #F0F5FF; color: var(--bt-primary); text-decoration: none; }
.bt-dm-mi-i { display: inline-flex; font-size: 14px; color: var(--bt-text-2); }
.bt-dm-mi:hover .bt-dm-mi-i { color: var(--bt-primary); }

/* Lista de tarjetas (una por dominio), reemplaza a la tabla/DataTables.
   #btDmList vive dentro de #domainForm (los checkboxes siguen viajando
   en las acciones masivas), cada .bt-dm-item es una tarjeta clicable
   (clickableSafeRedirect) igual que antes lo era la <tr>. */
/* Lista de dominios como UNA sola tarjeta: un borde exterior para todo el
   conjunto y una linea divisoria entre dominios (mas limpio que una tarjeta
   con borde por cada dominio). overflow:hidden para que las esquinas
   redondeadas recorten el hover de la primera/ultima fila. */
.bt-dm-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    overflow: hidden;
}
.bt-dm-empty {
    padding: 32px 16px;
    text-align: center;
    color: var(--bt-text-2);
    font-size: 14px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
}
.bt-dm-item {
    /* Grid de columnas definidas para que cada dato tenga su espacio y se
       alineen entre filas — evita que todo quede apiñado a la derecha:
       [chk][globo][dominio 1.6fr][Next Due 1fr][Estado .9fr][Auto Renew][acciones].
       Auto Renew y acciones pasan de "auto" a minmax(Npx, auto): "auto" a
       secas solo garantiza que la columna encoja al minimo de SU contenido,
       pero no le pone un piso propio, asi que con las fuentes mas grandes
       (F1c-bis: Manage 12.5->13.5px, kebab 16->17px) esas dos columnas
       quedaban mas angostas de lo que necesitaban Estado/Next Due para
       respirar y toda la fila se apretaba a la derecha. El minimo explicito
       (medido con el label de Auto Renew en ambos idiomas y con
       Manage/Gestionar + kebab) fija un piso estable para que la columna no
       cambie de ancho fila a fila y quede centrada de forma consistente. */
    display: grid;
    /* Estado NO lleva fr propio (a diferencia de una version anterior):
       con un fr, la columna crecia con el espacio sobrante (contenido
       corto tipo "Active"/"Pending") y esa pildora quedaba con un hueco
       enorme a su derecha antes de Auto Renew, mientras Auto Renew (fija,
       sin fr) quedaba pegada a Manage — reparto no uniforme (pedido del
       dueno). Ahora Estado y Auto Renew son "auto" (se ajustan a su propio
       contenido/label, min medido con "Transferred Away" en ES/EN y con
       "Auto-renovacion" en ES) y el espacio sobrante lo absorben
       dominio/Next Due (fr). Verificado con mock headless (gridtest,
       Playwright) a ~1250px: hueco Estado->Auto Renew y Auto
       Renew->Manage quedan practicamente iguales con estados largos, y
       razonablemente parejos (no 3x como antes) con estados cortos. */
    /* Rebalanceo (dueno, medido en vivo a 1278px): con Next Due en 1.3fr y
       Estado/Auto Renew sin fr propio, el contenido de Next Due (~90px)
       quedaba nadando en una pista de 267px, dejando un hueco visual
       gigante entre la fecha y Estado mientras Estado/Auto Renew/Manage se
       apretaban a la derecha. Next Due/Estado/Auto Renew pasan las TRES a
       1fr para repartir la holgura pareja entre las 3 columnas de datos;
       nombre sube a 2fr (sigue siendo la columna mayor) y Acciones se
       queda auto (los botones no deben estirarse). El piso de Estado sube
       112->120px (verificado con mock headless Playwright, "Transferred
       Away" mide ~114px de ancho real): con 1fr como MAXIMO de la pista
       (a diferencia de "auto", que crecia al contenido) el piso viejo de
       112px dejaba ese estado envolver a 2 lineas a 958px; 120px le da
       margen. */
    grid-template-columns: auto auto minmax(0, 2fr) minmax(126px, 1fr) minmax(120px, 1fr) minmax(118px, 1fr) minmax(150px, auto);
    align-items: center;
    column-gap: 24px;
    padding: 16px 20px;
    cursor: pointer;
    transition: background .15s;
    /* Linea divisoria entre dominios (el ultimo no la lleva). El borde
       exterior lo pone ahora .bt-dm-list, no cada fila. */
    border-bottom: 1px solid var(--bt-border);
}
.bt-dm-item:last-child { border-bottom: none; }
.bt-dm-item:hover { background: rgba(16, 24, 40, .025); }

.bt-dm-chk { width: 17px; height: 17px; accent-color: var(--bt-primary); cursor: pointer; flex: 0 0 auto; }

.bt-dm-glob {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: #E6F7F9;
    color: #0BA5B7;
    display: grid;
    place-items: center;
    font-size: 17px;
    flex: 0 0 auto;
}

.bt-dm-idcol { min-width: 0; flex: 1 1 260px; }
/* Pedido del dueno: el nombre principal (dominio en Mis Dominios, producto
   en Mis Servicios — .bt-dm-dom se reusa para ambos, ver clientareadomains
   .tpl y clientareaproducts.tpl) resalta en el mismo azul sutil que el
   resto de la lista. Solo el nombre, sin fondo (es un enlace de texto, no
   un boton) — .bt-dm-sub (subtitulo/dominio secundario debajo) se queda en
   var(--bt-text-2), es dato secundario. */
.bt-dm-dom { font-weight: 300; font-size: 15px; color: #4C7EDB; text-decoration: none; }
.bt-dm-dom:hover { color: var(--bt-primary); text-decoration: none; }
.bt-dm-sub {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 3px;
    color: var(--bt-text-2);
    font-size: 13px;
    flex-wrap: wrap;
}
.bt-dm-meta { display: flex; flex-direction: column; gap: 3px; flex: 0 0 auto; min-width: 130px; }
.bt-dm-metalabel { font-size: 10.5px; font-weight: 400; color: var(--bt-text-3); text-transform: uppercase; letter-spacing: .4px; }
/* Texto de DATOS (no es un control clicable), se queda en el gris #757B87
   aunque los botones de accion de arriba pasaron al azul sutil — mismo
   criterio que la home, donde los metas tambien se quedaron grises. */
.bt-dm-metaval { font-size: 14px; font-weight: 300; color: #757B87; font-variant-numeric: tabular-nums; }

/* Alineacion IZQUIERDA (pedido del dueno, 2a vuelta): mismo criterio que
   .bt-dm-meta (Next Due/Price) arriba, que ya queda flush-izquierda sin
   declarar align-items (stretch por defecto en flex-direction:column,
   el texto/switch se pinta desde el borde izquierdo del track). Antes
   align-items:center centraba el switch bajo su label, desalineado
   ~18-33px del arranque de "AUTO RENEW"/"AUTO-RENOVACION" — se quita para
   que ambos arranquen en el mismo x, como una columna de tabla. */
.bt-dm-ar { display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }
.bt-dm-ar-label { white-space: nowrap; font-size: 10.5px; font-weight: 400; color: var(--bt-text-3); text-transform: uppercase; letter-spacing: .3px; }
.bt-dm-ar-na { color: var(--bt-text-3); font-weight: 400; }

/* Columna de Estado (pedido del dueno): mismo tipo de etiqueta que Next
   Due/Price/Auto Renew arriba, pero SIN reusar .bt-dm-meta directamente
   porque esa clase se oculta entera en movil (@media abajo) y la pildora
   de estado si debe seguir visible ahi — solo se oculta el label, igual
   que .bt-dm-ar-label. */
.bt-dm-statcol {
    display: flex;
    flex-direction: column;
    /* Alineacion IZQUIERDA (pedido del dueno, 2a vuelta): igual que
       .bt-dm-meta/.bt-dm-ar, sin declarar align-items (stretch por
       defecto), asi la pildora arranca flush-izquierda con su label
       STATUS/ESTADO en vez de centrarse en el track — antes el centrado
       dejaba la pildora "flotando" y desalineada ~5-9px del label segun
       el largo del texto de estado. El reparto de holgura entre columnas
       ya lo da el grid-template-columns de .bt-dm-item (fr equilibrados,
       ver comentario ahi), esta regla ya no necesita compensar nada por
       si sola. */
    gap: 3px;
    flex: 0 0 auto;
}
.bt-dm-statlabel { font-size: 10.5px; font-weight: 400; color: var(--bt-text-3); text-transform: uppercase; letter-spacing: .4px; }

.bt-dm-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

/* Kebab de acciones rapidas por tarjeta: mismo patron <details> sin
   librerias que .bt-dm-more del toolbar (ver mas arriba), un menu por
   dominio. .bt-dm-kebabbtn conserva el look decorativo original del
   span (boton cuadrado 34x34 con los 3 puntos), en gris — el azul sutil
   del pedido del dueno es solo para .bt-dm-dom y .bt-dm-managebtn, este
   kebab (y sus items .bt-dm-mi) se quedan como origen. */
.bt-dm-kebab { position: relative; flex: 0 0 auto; }
.bt-dm-kebab > summary { list-style: none; }
.bt-dm-kebab > summary::-webkit-details-marker { display: none; }
.bt-dm-kebabbtn {
    width: 34px;
    height: 34px;
    border: 1.5px solid var(--bt-border);
    border-radius: 9px;
    background: var(--bt-surface);
    color: var(--bt-text-2);
    /* Sin esta regla el "..." (svg 1em, ver .bt-dm svg mas abajo) heredaba
       el font-size del body (1rem = 16px); se fija explicito para poder
       subirlo 1px junto con el resto de controles de fila. */
    font-size: 17px;
    display: grid;
    place-items: center;
    cursor: pointer;
}
.bt-dm-kebabbtn:hover, .bt-dm-kebab[open] > .bt-dm-kebabbtn {
    border-color: var(--bt-primary);
    color: var(--bt-primary);
}
.bt-dm-kebab-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 210px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 12px;
    box-shadow: 0 16px 40px rgba(16, 24, 40, .14);
    padding: 5px;
    z-index: 6;
}

.bt-dm-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 16px;
    color: var(--bt-text-2);
    font-size: 13px;
    flex-wrap: wrap;
}
.bt-dm-pager { display: flex; gap: 6px; flex-wrap: wrap; }
.bt-dm-pg {
    min-width: 34px;
    height: 34px;
    padding: 0 10px;
    border: 1.5px solid var(--bt-border);
    border-radius: 8px;
    background: var(--bt-surface);
    color: var(--bt-text);
    font-size: 12.5px;
    font-weight: 700;
    font-family: var(--bt-font);
    cursor: pointer;
}
.bt-dm-pg:hover { border-color: var(--bt-primary); color: var(--bt-primary); }
.bt-dm-pg--on { background: var(--bt-primary); color: #fff; border-color: transparent; }
.bt-dm-pg:disabled { opacity: .45; cursor: default; }
.bt-dm-pg:disabled:hover { border-color: var(--bt-border); color: var(--bt-text); }
/* Elipsis de la ventana del paginador (span aria-hidden entre botones
   .bt-dm-pg, ver 86aa8e3): mismas altura/caja que .bt-dm-pg para quedar
   alineada en la misma linea base, pero sin apariencia de boton (sin
   borde/fondo/hover, cursor default). */
.bt-dm-pg-ellipsis {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 34px;
    padding: 0 4px;
    color: var(--bt-text-2);
    font-size: 12.5px;
    font-weight: 700;
    font-family: var(--bt-font);
    cursor: default;
}

@media (max-width: 820px) {
    .bt-dm-meta, .bt-dm-ar-label, .bt-dm-statlabel { display: none; }
    /* En movil volvemos a flex (el grid de columnas definidas es solo para
       escritorio) para que envuelva y el dominio ocupe todo el ancho. */
    .bt-dm-item { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; column-gap: 12px; }
    .bt-dm-idcol { flex: 1 1 100%; }
}

/* F1/F5 (mecanismo del switch, VERBATIM — no se toca el markup/JS, solo
   el skin): switch propio (sin librerias) para auto-renew inline.
   Estructura: button.bt-dm-arswitch > span.bt-dm-arswitch-track >
   span.bt-dm-arswitch-thumb. Submit 100% nativo: el boton es type=submit
   con el atributo HTML "form" apuntando a un <form> externo por dominio
   (ver clientareadomains.tpl) que recarga la pagina; ya no hay fetch/AJAX
   ni estado optimista, este boton solo pinta el estado server-rendered.
   :disabled se usa como anti doble-submit inline (onsubmit del form). */
.bt-dm-arswitch {
    position: relative;
    flex: 0 0 auto;
    width: 32px;
    height: 18px;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
}
.bt-dm-arswitch-track {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 999px;
    background: var(--bt-text-3);
    transition: background .15s ease;
}
.bt-dm-arswitch--on .bt-dm-arswitch-track { background: var(--bt-green); }
.bt-dm-arswitch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .3);
    transition: transform .15s ease;
}
.bt-dm-arswitch--on .bt-dm-arswitch-thumb { transform: translateX(14px); }
.bt-dm-arswitch:disabled { opacity: .55; cursor: wait; }
.bt-dm-arswitch:focus-visible { outline: 2px solid var(--bt-primary); outline-offset: 2px; }

/* F4 (Opcion B): toast propio para el aviso de fetch AJAX del switch de
   auto-renew (ver <script> bt-ar-ajax en clientareadomains.tpl). Solo
   texto (textContent), sin HTML/markup dinamico. z-index por encima del
   contenido normal pero por debajo del sidebar movil (1032) y el modal
   nativo (1050), no compite con ellos porque solo aparece en desktop
   scroll normal. */
.bt-toast {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
    z-index: 1045;
    max-width: min(92vw, 420px);
    padding: 10px 16px;
    border-radius: 8px;
    background: var(--bt-red);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.4;
    box-shadow: 0 4px 14px rgba(16, 24, 40, .25);
    text-align: center;
}

/* F3: aviso de vencimiento cercano (<=14 dias, Active), mismo tono ambar
   que la pildora "pending" para consistencia visual. */
.bt-dm-soon {
    display: inline-flex;
    align-items: center;
    margin-top: 4px;
    padding: 3px 9px;
    border-radius: 20px;
    font-size: 10.5px;
    font-weight: 700;
    white-space: nowrap;
    background: rgba(247, 144, 9, .14);
    color: #B45309;
}

.bt-dm-pill {
    /* Estado SIN fondo: solo texto de color, con el puntito indicador
       (mismo color) alineado con el texto. */
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 0;
    background: transparent;
    font-size: 13px;
    font-weight: 500;
    color: var(--bt-text-2);
}
.bt-dm-pill::before {
    content: "";
    flex: 0 0 auto;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
}
/* Colores de estado en tonos mas claros/modernos (paleta tipo Untitled UI),
   aun legibles como texto en negrita sobre blanco. El punto (::before) usa
   currentColor, asi que hereda cada tono. */
.bt-dm-pill--active { color: #17B26A; }
.bt-dm-pill--pending { color: #E0900D; }
.bt-dm-pill--expired,
.bt-dm-pill--cancelled,
.bt-dm-pill--terminated,
.bt-dm-pill--fraud { color: #F04438; }
.bt-dm-pill--suspended { color: #E0900D; }

/* Boton "Manage"/"Gestionar" por tarjeta. El link usa stopEventBubble
   (misma clase nativa del checkbox) para no disparar tambien el onclick
   de la tarjeta -> domaindetails. Azul sutil #4C7EDB/borde #CFE0FF, uno de
   los DOS unicos lugares de la lista que quedan en azul (el otro es el
   nombre principal, .bt-dm-dom mas arriba) — pedido explicito del dueno,
   la barra de acciones de arriba (.bt-dm-tbtn) volvio a gris. El icono
   interno reusa la clase compartida .bt-dm-tbtn-i (gris por defecto ahora
   que .bt-dm-tbtn volvio a gris), asi que se scopea aparte mas abajo para
   que siga a juego con el texto azul de este boton. */
.bt-dm-managebtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 14px;
    border: 1.5px solid #CFE0FF;
    border-radius: 8px;
    background: var(--bt-surface);
    color: #4C7EDB;
    font-size: 13.5px;
    font-weight: 400;
    font-family: var(--bt-font);
    text-decoration: none;
    white-space: nowrap;
    transition: border-color .15s, color .15s;
}
.bt-dm-managebtn:hover {
    background: #F0F5FF;
    border-color: #A9C6FF;
    color: var(--bt-primary);
    text-decoration: none;
}
/* Icono del boton Manage: .bt-dm-tbtn-i es compartida con la barra de
   acciones (que quedo gris), asi que aqui se scopea para que el icono
   siga el azul del texto de .bt-dm-managebtn en vez de heredar el gris. */
.bt-dm-managebtn .bt-dm-tbtn-i { color: #4C7EDB; }
.bt-dm-managebtn:hover .bt-dm-tbtn-i { color: var(--bt-primary); }

/* ============================================================
   Detalle de dominio (clientareadomaindetails) — rediseno de la vista
   #tabOverview a partir del mockup aprobado (domaindetails-mejorado.html):
   cabecera-resumen + grilla "Administrar {dominio}" + upsell. Prefijo
   propio .bt-dd-* (namespace paralelo a .bt-dm-* de la lista de
   dominios, misma pagina no las comparte). El pill de estado SI se
   reusa directo (.bt-dm-pill/--{modifier}, ya global) para no duplicar
   la logica de color de estado entre lista y detalle.
   ============================================================ */

/* Cabecera-resumen */
.bt-dd-summary { padding: 4px 0; margin-bottom: 30px; }
.bt-dd-summary .card-body { padding: 24px 26px; }
.bt-dd-sumtop { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.bt-dd-sumtop h1.bt-dd-domain { font-size: 22px; font-weight: 300; margin: 0; color: var(--bt-text); word-break: break-word; }
.bt-dd-meta { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bt-dd-spacer { flex: 1; }
.bt-dd-acts { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* Icono globo de la cabecera: mismos tonos teal hardcodeados que
   .bt-dm-glob. El token --bt-teal (alias literal de --bt-primary, sin
   valor propio) se borro en la limpieza de tokens degenerados; el teal
   real de este icono sigue hardcodeado aqui hasta que exista un token
   propio con el valor correcto. */
.bt-dd-glob {
    flex: 0 0 auto;
    width: 52px;
    height: 52px;
    border-radius: 13px;
    background: #E6F7F9;
    color: #0BA5B7;
    display: grid;
    place-items: center;
}
.bt-dd-glob svg { width: 25px; height: 25px; }

/* Toggle Auto Renew de la cabecera: button[type=submit] dentro de su
   propio <form> (id/sub=autorenew/autorenew=enable|disable, ver tpl),
   100% nativo — no es el switch bt-dm-arswitch de la lista (ese
   depende del atributo form=id externo del contrato bulkdomain). */
.bt-dd-tg {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    height: 40px;
    padding: 0 14px;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-sm);
    background: var(--bt-surface);
    cursor: pointer;
    font-family: var(--bt-font);
}
.bt-dd-tg-cap { font-size: 11px; font-weight: 500; letter-spacing: .4px; text-transform: uppercase; color: var(--bt-text-3); }
.bt-dd-tg-track { width: 32px; height: 18px; border-radius: 999px; background: var(--bt-text-3); position: relative; flex: 0 0 auto; }
.bt-dd-tg--on .bt-dd-tg-track { background: var(--bt-green); }
.bt-dd-tg-thumb { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); transition: transform .15s ease; }
.bt-dd-tg--on .bt-dd-tg-thumb { transform: translateX(14px); }

/* Botones Visitar/Renovar de la cabecera — capa fina sobre .btn base,
   solo alinea el icono SVG con el texto. */
.bt-dd-btn { display: inline-flex; align-items: center; gap: 8px; }
.bt-dd-btn svg { width: 16px; height: 16px; }
/* El boton primario (Renovar) debe llevar texto/icono BLANCO — sin esto
   heredaba el color azul del tema y quedaba texto azul sobre fondo azul
   (invisible). Icono usa currentColor, asi que tambien queda blanco. */
.bt-dd-btn.btn-primary, .bt-dd-btn.btn-primary svg { color: #fff; }
.bt-dd-btn.btn-primary:hover { color: #fff; background: var(--bt-primary-hover); border-color: var(--bt-primary-hover); }
/* Danger (Request Cancellation): texto/icono blanco — sin esto `.bt-body a`
   pinta el texto azul sobre el fondo rojo (poco legible). Doble clase para
   ganarle a `.bt-body a` (0,1,1). */
.bt-dd-btn.btn-danger, .bt-body a.bt-dd-btn.btn-danger,
.bt-dd-btn.btn-danger svg { color: #fff; }
.bt-dd-btn.btn-danger.disabled { color: #fff; opacity: .6; }

.bt-dd-sumfacts {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 22px;
    margin-top: 22px;
    padding-top: 20px;
    border-top: 1px solid var(--bt-border);
}
.bt-dd-sumfacts--ssl { margin-top: 0; padding-top: 16px; border-top: none; }
@media (max-width: 760px) { .bt-dd-sumfacts { grid-template-columns: repeat(2, 1fr); } }
.bt-dd-fact { display: flex; flex-direction: column; gap: 5px; }
.bt-dd-lbl { font-size: 10.5px; font-weight: 500; letter-spacing: .5px; text-transform: uppercase; color: var(--bt-text-3); }
.bt-dd-val { font-size: 14px; font-weight: 500; color: var(--bt-text-2); font-variant-numeric: tabular-nums; }
.bt-dd-ssl-inactive .bt-dd-val { color: var(--bt-text-3); }

/* Secciones (grilla de acciones + upsell) */
.bt-dd-sec { margin-bottom: 32px; }
.bt-dd-sechead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0 0 16px; flex-wrap: wrap; }
.bt-dd-sechead h2 { font-size: 18px; font-weight: 300; margin: 0; }
.bt-dd-hint { font-size: 12.5px; color: var(--bt-text-3); }

/* Grilla "Administrar {dominio}" */
.bt-dd-qgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
@media (max-width: 860px) { .bt-dd-qgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px) { .bt-dd-qgrid { grid-template-columns: 1fr; } }
.bt-dd-qcard {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 20px 18px 18px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    text-decoration: none;
    transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease;
    overflow: hidden;
}
.bt-dd-qcard::after {
    content: "";
    position: absolute;
    left: 0;
    top: 16px;
    bottom: 16px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: #0BA5B7;
    opacity: 0;
    transition: opacity .16s;
}
.bt-dd-qcard:hover { border-color: #CFE0FF; box-shadow: var(--bt-shadow); transform: translateY(-3px); text-decoration: none; }
.bt-dd-qcard:hover::after { opacity: 1; }
.bt-dd-qico { width: 44px; height: 44px; border-radius: 12px; background: #E6F7F9; color: #0BA5B7; display: grid; place-items: center; transition: background .16s, color .16s; }
.bt-dd-qico svg { width: 21px; height: 21px; }
.bt-dd-qcard:hover .bt-dd-qico { background: #0BA5B7; color: #fff; }
.bt-dd-qt { font-size: 14.5px; font-weight: 500; color: var(--bt-text); line-height: 1.25; }
.bt-dd-qd { font-size: 12px; color: var(--bt-text-3); line-height: 1.35; }

/* Upsell */
.bt-dd-ugrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 760px) { .bt-dd-ugrid { grid-template-columns: 1fr; } }
.bt-dd-ucard {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 17px 18px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    text-decoration: none;
    transition: border-color .16s, box-shadow .16s, transform .16s;
}
.bt-dd-ucard:hover { border-color: #CFE0FF; box-shadow: var(--bt-shadow); transform: translateY(-3px); text-decoration: none; }
.bt-dd-uico { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center; }
.bt-dd-uico svg { width: 20px; height: 20px; }
.bt-dd-uico--primary { background: rgba(16, 98, 254, .1); color: var(--bt-primary); }
/* Violeta hardcodeado a proposito: el token --bt-violet (alias literal
   de --bt-primary, sin valor propio) se borro en la limpieza de tokens
   degenerados; usar --bt-primary aqui pintaria la tarjeta VPS igual que
   la de Web Hosting. Se usa el mismo acento violeta del mockup aprobado
   hasta que exista un token propio con el valor correcto. */
.bt-dd-uico--violet { background: rgba(122, 90, 248, .12); color: #7A5AF8; }
.bt-dd-uico--green { background: rgba(16, 185, 129, .1); color: var(--bt-green); }
.bt-dd-utx { display: flex; flex-direction: column; min-width: 0; }
.bt-dd-ut { font-size: 14.5px; font-weight: 500; color: var(--bt-text); line-height: 1.2; }
.bt-dd-ud { font-size: 12px; color: var(--bt-text-3); margin-top: 2px; }
.bt-dd-ugo { margin-left: auto; color: var(--bt-text-3); font-size: 18px; transition: color .16s, transform .16s; }
.bt-dd-ucard:hover .bt-dd-ugo { color: var(--bt-primary); transform: translateX(3px); }

/* Link "Volver al resumen" en las tabs secundarias (autorenew/
   nameservers/reglock/release/addons). */
.bt-dd-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 14px;
    font-size: 13px;
    font-weight: 500;
    color: var(--bt-text-2);
    cursor: pointer;
}
.bt-dd-back:hover { color: var(--bt-primary); text-decoration: none;
}

/* ============================================================
   Detalle de producto de hosting (clientareaproductdetails) — rediseno
   de mockup aprobado (productdetails-mockup.html): cabecera-resumen +
   2 tarjetas [Dominio y DNS]/[Facturacion] + barra de acciones + grilla
   propia "Accesos del panel" (cPanel) o area real del modulo
   ($moduleclientarea, fallback para productos no-cPanel). Prefijo
   propio .bt-pd-*, reusa al maximo .bt-dd-* / .bt-dm-pill/tokens (misma
   cabecera-resumen que Domain Details: .bt-dd-summary/.bt-dd-sumtop/
   .bt-dd-glob/.bt-dd-meta/.bt-dd-spacer/.bt-dd-acts/.bt-dd-btn/
   .bt-dd-sec/.bt-dd-sechead/.bt-dd-hint se reusan TAL CUAL desde el
   .tpl, sin duplicar CSS aqui). Sidebar contextual oculto solo aqui via
   :has(.bt-pd), mismo patron que .bt-home/.bt-domains/.bt-domdetails.
   ============================================================ */
.container-fluid:has(.bt-pd) .col-lg-4.col-xl-3 {
    display: none !important;
}
.container-fluid:has(.bt-pd) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-pd) .sidebar-secondary {
    display: none !important;
}

.bt-pd svg { width: 1em; height: 1em; display: block; }
.bt-pd * { box-sizing: border-box; }
.bt-pd { padding: 24px 0 30px; }
@media (max-width: 820px) { .bt-pd { padding: 12px 0 20px; } }

/* Subtitulo dominio junto al pill de estado en la cabecera (la tarjeta
   .bt-dd-summary no trae esto porque en Domain Details el dominio YA ES
   el h1). */
.bt-pd-dom { font-size: 13px; color: var(--bt-text-3); }

/* Titulo del producto (h1.bt-dd-domain, reusado de Domain Details): 20/300
   #4A5160 pedido del dueno para esta pagina — se acota con .bt-pd para NO
   tocar el h1 de clientareadomaindetails.tpl (misma clase, otra pagina). */
.bt-pd .bt-dd-sumtop h1.bt-dd-domain { font-size: 20px; color: #4A5160; }

/* Fila de 2 tarjetas [Dominio y DNS] [Facturacion] */
.bt-pd-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 22px;
    align-items: stretch;
    margin-bottom: 26px;
}
@media (max-width: 820px) { .bt-pd-cols { grid-template-columns: 1fr; } }
.bt-pd-pad { padding: 22px 24px; }
/* 16/300 var(--bt-text) -> 17/300 #4A5160 (pedido del dueno, "mejor color
   y fonts"): mismo tratamiento fino que el resto de titulos de tarjeta. */
.bt-pd-pad h2 { font-size: 17px; font-weight: 300; margin: 0 0 14px; color: #4A5160; }
.bt-pd-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--bt-border-soft, var(--bt-border));
    font-size: 13px;
}
.bt-pd-row:last-of-type { border-bottom: 0; }
/* Label en var(--bt-text-2) (antes var(--bt-text-3), muy apagado); valor en
   #4A5160 peso 400 (antes var(--bt-text-2)/500) — pedido del dueno. */
.bt-pd-row .k { color: var(--bt-text-2); flex: 0 0 auto; }
.bt-pd-row .v { color: #4A5160; font-weight: 400; text-align: right; }
.bt-pd-row .v.bt-pd-danger { color: var(--bt-red); }
.bt-pd-note { font-size: 12px; color: var(--bt-text-3); margin: 14px 0 0; }
.bt-pd-cardacts { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
/* Si en .bt-pd-cols solo hay una tarjeta (la otra no se renderizo por
   {if}, p.ej. sin configurableoptions o sin lastupdate), ocupa el ancho
   completo en vez de dejar hueco vacio a la derecha. Mismo patron
   :has() ya usado en este archivo (linea 2689). */
.bt-pd-cols:has(> .card:only-child) { grid-template-columns: 1fr; }
/* "Ver facturas"/"Upgrade" de la tarjeta Facturacion: mismo lenguaje
   visual que los botones intermedios de la barra .bt-pd-mainacts (borde
   azul suave, texto #4C7EDB, hover mas claro) — antes heredaban el
   .btn.btn-default gris crudo de WHMCS porque esa regla vivia scopeada
   solo a .bt-pd-mainacts .btn.btn-default (linea ~2808) y no alcanzaba
   aqui. Mismos valores exactos, sin !important, solo re-scopeados a
   .bt-pd-cardacts. El icono usa stroke="currentColor" en el .tpl, asi
   que sigue el mismo azul sin regla aparte. */
.bt-pd-cardacts .btn.btn-default {
    background: #fff;
    border: 1px solid #CFE0FF;
    color: #4C7EDB;
    font-weight: 400;
    font-size: 13.5px;
    padding: 10px 16px;
    border-radius: 8px;
    transition: background .15s, border-color .15s, color .15s;
}
.bt-pd-cardacts .btn.btn-default:hover {
    background: #F0F5FF;
    border-color: #A9C6FF;
    color: var(--bt-primary);
}
/* "Upgrade" de la tarjeta Facturacion: pedido del dueno de destacarlo en
   verde degradado llamativo, mismo patron EXACTO que "Log in to cPanel"
   (.bt-pd-mainacts .btn.btn-primary, calcado a su vez de .bt-body
   .bt-paybtn) pero con el verde del tema #12B76A en vez del azul hero.
   Se distingue de "Ver facturas" (mismo .btn.btn-default) con la clase
   propia .bt-pd-upgradebtn añadida al <a> en el .tpl; la especificidad
   .bt-pd-cardacts .btn.bt-pd-upgradebtn gana sin !important a la regla
   azul sutil de arriba. El icono usa stroke="currentColor" en el .tpl,
   asi que queda blanco automaticamente, sin regla aparte. */
.bt-pd-cardacts .btn.bt-pd-upgradebtn {
    background: linear-gradient(135deg, #12B76A 0%, #34D399 100%);
    border: none;
    color: #fff;
    font-weight: 700;
    font-size: 13.5px;
    padding: 10px 16px;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(18, 183, 106, .25);
    transition: background .15s ease, box-shadow .15s ease, transform .15s ease;
}
.bt-pd-cardacts .btn.bt-pd-upgradebtn:hover {
    background: linear-gradient(135deg, #0E9355 0%, #2BBF83 100%);
    box-shadow: 0 4px 12px rgba(18, 183, 106, .30);
    transform: translateY(-1px);
    color: #fff;
}
.bt-pd-cardacts .btn.bt-pd-upgradebtn:active {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(18, 183, 106, .08);
}
@media (prefers-reduced-motion: reduce) {
    .bt-pd-cardacts .btn.bt-pd-upgradebtn,
    .bt-pd-cardacts .btn.bt-pd-upgradebtn:hover {
        transition: none;
        transform: none;
    }
}
/* Barra de progreso fina del tema para disco/ancho de banda (tarjeta
   "Resource usage") — riel gris, relleno degradado hero, ambar si
   ocupacion >80%. */
.bt-pd-usage-row { margin-bottom: 18px; }
.bt-pd-usage-row:last-of-type { margin-bottom: 0; }
.bt-pd-usage-top { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; margin-bottom: 8px; }
.bt-pd-usage-top .k { color: var(--bt-text-2); }
.bt-pd-usage-top .v { color: #4A5160; font-weight: 400; text-align: right; }
.bt-pd-meter { height: 6px; border-radius: 999px; background: #E7E9F0; overflow: hidden; }
.bt-pd-meter-fill { height: 100%; border-radius: 999px; background: linear-gradient(135deg, #1062FE 0%, #4FC3FF 100%); }
.bt-pd-meter-fill--warn { background: #F79009; }


/* Barra de opciones principales (Log in / Change Password / Upgrade /
   Unban IP / Cancel), justo debajo de la cabecera-resumen. Mismos
   botones .bt-dd-btn ya usados en el resto de la pagina, en fila. */
.bt-pd-mainacts {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 22px;
}
.bt-pd-mainacts .btn svg { width: 16px; height: 16px; }
/* Uniformar los 5 botones (pedido del dueno "mas vida y corporativo"):
   mismo tamaño/padding/radio/gap para toda la barra, sea cual sea el rol. */
.bt-pd-mainacts .btn {
    font-size: 13.5px;
    padding: 10px 16px;
    border-radius: 8px;
}
.bt-pd-mainacts .btn.disabled,
.bt-pd-mainacts .btn[disabled] {
    opacity: .6;
    cursor: default;
    pointer-events: none;
}

/* "Log in to cPanel" (accion principal): mismo patron EXACTO que
   .bt-body .bt-paybtn de la home — degradado hero, sombra, hover mas
   oscuro + lift, active asienta, sin transform agresivo con reduced-motion.
   Se sobreescribe .bt-dd-btn.btn-primary (blanco solido) porque esa regla
   es compartida con clientareadomaindetails.tpl; aqui se acota a la barra. */
.bt-pd-mainacts .btn.btn-primary {
    background: linear-gradient(135deg, #1062FE 0%, #4FC3FF 100%);
    border: none;
    color: #fff;
    font-weight: 700;
    box-shadow: 0 2px 8px rgba(16, 98, 254, .25);
    transition: background .15s ease, box-shadow .15s ease, transform .15s ease;
}
.bt-pd-mainacts .btn.btn-primary:hover {
    background: linear-gradient(135deg, #0B4FD6 0%, #38B6F8 100%);
    box-shadow: 0 4px 12px rgba(16, 98, 254, .30);
    transform: translateY(-1px);
    color: #fff;
}
.bt-pd-mainacts .btn.btn-primary:active {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(16, 98, 254, .08);
}
@media (prefers-reduced-motion: reduce) {
    .bt-pd-mainacts .btn.btn-primary,
    .bt-pd-mainacts .btn.btn-primary:hover {
        transition: none;
        transform: none;
    }
}

/* Botones intermedios (Webmail / Change Password / Unban IP): azul sutil
   ya aprobado para la lista (mismo tono que .bt-site-acts/.bt-pd-tile),
   borde #CFE0FF, texto #4C7EDB peso fino, hover #F0F5FF + #A9C6FF +
   var(--bt-primary). El icono usa currentColor (stroke="currentColor" en
   el .tpl) asi que sigue el mismo azul sin regla aparte. */
.bt-pd-mainacts .btn.btn-default {
    background: #fff;
    border: 1px solid #CFE0FF;
    color: #4C7EDB;
    font-weight: 400;
    transition: background .15s, border-color .15s, color .15s;
}
.bt-pd-mainacts .btn.btn-default:hover {
    background: #F0F5FF;
    border-color: #A9C6FF;
    color: var(--bt-primary);
}

/* "Request Cancellation": de rojo solido a outline suave — sigue leyendo
   peligro sin ser un bloque rojo. El estado "Cancellation requested"
   (span.disabled) hereda el mismo look, atenuado por .disabled de arriba.
   Especificidad reforzada con .bt-pd (0,4,0/1) para ganarle a
   ".bt-body a.bt-dd-btn.btn-danger { color:#fff }" (0,3,1), que sigue
   viva para clientareadomaindetails.tpl y no se toca. */
.bt-pd .bt-pd-mainacts .btn.btn-danger {
    background: transparent;
    border: 1px solid #FECDCA;
    color: #F04438;
    font-weight: 400;
    transition: background .15s, border-color .15s, color .15s;
}
.bt-pd .bt-pd-mainacts .btn.btn-danger svg { color: #F04438; }
.bt-pd .bt-pd-mainacts .btn.btn-danger:hover {
    background: #FEF3F2;
    border-color: #F04438;
    color: #F04438;
}
.bt-pd .bt-pd-mainacts .btn.btn-danger:hover svg { color: #F04438; }

/* Area real del modulo ($moduleclientarea, tal cual la emite la base —
   ver comentario en el .tpl). Reskin de las clases que YA trae la base
   de WHMCS: .modulebutton es la clase estandar que TODOS los modulos de
   servidor (cpanel, plesk, directadmin, etc.) ponen en sus
   input[type=submit]/input[type=button] de login/acciones (ver p.ej.
   modules/servers/cpanel/clientarea.tpl: "Login to cPanel"/"cPanel
   Webmail Login"). No se tocan sus name/value/atributos, solo el look. */
.bt-pd-modarea { padding: 22px 24px; }
.bt-pd-modarea form { display: inline-block; margin: 0 10px 10px 0; }
.bt-pd-modarea .modulebutton,
.bt-pd-modarea input[type="submit"],
.bt-pd-modarea input[type="button"],
.bt-pd-modarea button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 18px;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    background: var(--bt-surface);
    color: var(--bt-text);
    font-family: var(--bt-font);
    font-size: 13.5px;
    font-weight: 500;
    cursor: pointer;
    transition: border-color .15s, box-shadow .15s, transform .15s;
}
.bt-pd-modarea .modulebutton:hover,
.bt-pd-modarea input[type="submit"]:hover,
.bt-pd-modarea input[type="button"]:hover,
.bt-pd-modarea button:hover {
    border-color: #CFE0FF;
    box-shadow: var(--bt-shadow);
    transform: translateY(-2px);
}
/* Primer boton del area del modulo (normalmente "Login to cPanel"/SSO)
   destacado como accion primaria — heuristica de orden, no de contenido:
   la base siempre pone el login primero y las secundarias (webmail,
   etc.) despues. */
.bt-pd-modarea form:first-of-type .modulebutton,
.bt-pd-modarea form:first-of-type input[type="submit"] {
    background: var(--bt-primary);
    border-color: var(--bt-primary);
    color: #fff;
}
.bt-pd-modarea form:first-of-type .modulebutton:hover,
.bt-pd-modarea form:first-of-type input[type="submit"]:hover {
    background: var(--bt-primary-hover);
    border-color: var(--bt-primary-hover);
}

/* Tabs nativos restantes (Metrics/AdditionalInfo — ConfigOptions y
   ResourceUsage se promovieron a tarjetas .bt-pd-cols, ver arriba) — se
   conserva el mecanismo Bootstrap .nav-tabs/data-toggle="tab" tal cual
   la base, solo se envuelve en .card via .bt-pd-tabwrap para que
   combine con el resto de la pagina. */
.bt-pd-tabwrap { margin-bottom: 26px; }
.bt-pd-tabwrap .nav-tabs { border-bottom-color: var(--bt-border); }
.bt-pd-tabwrap .nav-link { color: var(--bt-text-2); }
.bt-pd-tabwrap .nav-link.active { color: var(--bt-primary); font-weight: 500; }
/* "Additional Info" (parcial nativo de twenty-one, #additionalinfo): la
   celda izquierda ({$field.name}) viene envuelta en <strong> del .tpl
   base y sale bold+negro. */
.bt-pd-tabwrap #additionalinfo strong { font-weight: 400; color: #4A5160; }

/* ============================================================
   Grilla propia "Accesos del panel" (.bt-pd-panelwrap) — reemplaza
   POR COMPLETO el bloque que armaba el modulo cPanel
   ({$tplOverviewTabOutput}: banner Sitejet, "Usage Statistics", "Quick
   Shortcuts", "Quick Create Email", "Billing Overview") — decision del
   dueno (2026-07-26): se descarta ese bloque, Sitejet queda fuera. Solo
   se usa {$tplOverviewTabOutput} como señal booleana de "es cPanel" en
   el .tpl. Reproduce el look de productdetails-mockup.html seccion
   "Accesos de cPanel" (.grp/.grp-t/.tiles/.tile) con prefijo propio
   .bt-pd-*, iconos SVG inline (sprite bt-pd-i-* del .tpl) y enlaces SSO
   reales (dosinglesignon=1&app=APPNAME, valores APPNAME ESTATICOS).
   ============================================================ */
.bt-pd-panelwrap { margin-bottom: 26px; }
.bt-pd-panelhead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}
/* "Panel access": mismo tratamiento 17/300 #4A5160 de los titulos de
   tarjeta (antes 18px, color heredado var(--bt-text)). */
.bt-pd-panelhead h2 { font-size: 17px; font-weight: 300; margin: 0; color: #4A5160; }
.bt-pd-search {
    display: flex;
    align-items: center;
    gap: 9px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 999px;
    padding: 9px 16px;
    min-width: 280px;
}
.bt-pd-search svg { width: 16px; height: 16px; color: var(--bt-text-3); }
.bt-pd-search input {
    border: 0;
    background: transparent;
    /* outline:0 en el <input> sin sustituto dejaba el foco por teclado
       totalmente invisible (auditoria de accesibilidad 2026-07-29). El
       anillo se pinta en el CONTENEDOR (:focus-within), no en el input
       suelto, para que rodee el pill completo en vez de solo el texto.
       outline transparente (en vez de "none") en el input mantiene el
       anillo del modo alto contraste de Windows, que ignora box-shadow. */
    outline: 2px solid transparent;
    font-family: var(--bt-font);
    font-size: 13.5px;
    color: var(--bt-text);
    width: 100%;
}
.bt-pd-search:focus-within {
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 3px rgba(16, 98, 254, .25);
}

.bt-pd-grp { margin-bottom: 22px; }
/* 600 -> 400 (pedido del dueno): que no se laven ni pesen, siguen
   separando seccion por mayusculas+tracking, no por negrita. */
.bt-pd-grp-t {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 11px;
    font-weight: 400;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--bt-text-3);
    margin: 0 0 12px;
}
.bt-pd-grp-t svg { width: 14px; height: 14px; color: var(--bt-primary); }

.bt-pd-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 12px;
}
.bt-pd-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 9px;
    text-align: center;
    padding: 12px 5px 10px;
    min-height: 92px;
    background: var(--bt-surface);
    border: 1px solid #CFE0FF;
    border-radius: 9px;
    color: var(--bt-text);
    text-decoration: none;
    transition: border-color .15s, background .15s, box-shadow .15s;
}
/* Vida en el hover (pedido del dueno): borde #A9C6FF + fondo #F7FAFF,
   transicion suave. Se retira el translateY(-2px) — elegante, sin
   transform agresivo. */
.bt-pd-tile:hover,
.bt-pd-tile:focus-visible {
    border-color: #A9C6FF;
    background: #F7FAFF;
    box-shadow: var(--bt-shadow);
    color: var(--bt-text);
    text-decoration: none;
}
/* Recuadro de fondo del icono retirado (los cpicons oficiales ya vienen
   a color, no necesitan chip teal detras) — se deja el wrapper solo
   para centrar/medir el <img>. */
.bt-pd-tile-i {
    width: 32px;
    height: 32px;
    background: transparent;
    display: grid;
    place-items: center;
}
.bt-pd-tile-i img { width: 32px; height: 32px; display: block; }
/* Ajuste del dueno 07-29: nombres de tile FINOS, sin negrita en ninguno de
   los 30 tiles — 12.5px/300 #4A5160 (antes 12px/500 var(--bt-text)). Una
   sola regla para las 30 instancias (todas comparten .bt-pd-tile-t, sin
   overrides por tile en el .tpl). */
.bt-pd-tile-t {
    font-size: 12.5px;
    font-weight: 300;
    color: #4A5160;
    line-height: 1.25;
}
@media (max-width: 900px) { .bt-pd-tiles { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 560px) { .bt-pd-tiles { grid-template-columns: repeat(3, 1fr); } }

/* ============================================================
   Afiliados (affiliates.tpl) — rediseño Variante A aprobado por el dueno.
   Prefijo propio .bt-af-*; reusa al maximo tokens y patrones ya existentes
   del tema (.bt-hero para el degradado, .bt-band-N para las banditas de
   color de los stat tiles, .bt-pd-row/.bt-pd-cardacts/.bt-pd-upgradebtn
   como referencia de estilo para tarjetas/boton verde). Sidebar
   contextual oculto solo aqui via :has(.bt-affiliates), mismo patron que
   .bt-home/.bt-domains/.bt-domdetails/.bt-services/.bt-pd.
   ============================================================ */
.container-fluid:has(.bt-affiliates) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-affiliates) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-affiliates) .sidebar-secondary {
    display: none;
}

.bt-affiliates svg { width: 1em; height: 1em; display: block; }
.bt-affiliates * { box-sizing: border-box; }
.bt-affiliates { padding: 24px 0 30px; }
@media (max-width: 820px) { .bt-affiliates { padding: 12px 0 20px; } }

/* Fila del link de referido + boton "Copiar enlace": caja blanca solida
   sobre el degradado del hero (mismo contraste que .bt-hero-chip), boton
   azul oscuro #0B2E77 pedido en el diseño (mas oscuro que el hero para
   que no se funda con el fondo). */
.bt-af-linkrow {
    display: flex;
    gap: 12px;
    margin-top: 22px;
    flex-wrap: wrap;
    position: relative;
    z-index: 1;
}
.bt-af-linkbox {
    flex: 1 1 320px;
    min-width: 0;
    background: #fff;
    border-radius: 10px;
    display: flex;
    align-items: center;
}
/* outline:0 en .bt-af-linkinput sin sustituto dejaba el foco por teclado
   invisible (auditoria de accesibilidad 2026-07-29) — mismo fix que
   .bt-pd-search: anillo en el contenedor via :focus-within, outline
   transparente (no "none") en el input para el modo alto contraste de
   Windows. */
.bt-af-linkbox:focus-within {
    box-shadow: 0 0 0 3px rgba(16, 98, 254, .35);
}
.bt-af-linkinput {
    width: 100%;
    border: 0;
    outline: 2px solid transparent;
    background: transparent;
    padding: 12px 14px;
    font-family: var(--bt-font);
    font-size: 13.5px;
    color: #1F2430;
}
.bt-af-copybtn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: #0B2E77;
    color: #fff;
    border: none;
    border-radius: 10px;
    padding: 0 20px;
    font-size: 13.5px;
    font-weight: 700;
    font-family: var(--bt-font);
    cursor: pointer;
    white-space: nowrap;
    transition: background .15s ease, transform .15s ease;
}
.bt-af-copybtn:hover { background: #092459; }
.bt-af-copybtn:active { transform: translateY(1px); }
/* Feedback "Copiado!"/"Copied!" (2s, sin libreria): mismo boton, fondo
   verde del tema. */
.bt-af-copybtn.bt-af-copybtn--done { background: #0E9355; }
@media (prefers-reduced-motion: reduce) {
    .bt-af-copybtn { transition: none; }
    .bt-af-copybtn:active { transform: none; }
}

/* 4 botones cuadrados translucidos de compartir (WhatsApp/X/Facebook/
   Email), mismo tratamiento translucido que .bt-hero-chip pero sin fondo
   solido — se apoyan sobre el degradado del hero. */
.bt-af-share {
    display: flex;
    gap: 10px;
    margin-top: 16px;
    position: relative;
    z-index: 1;
}
.bt-af-sharebtn {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: rgba(255, 255, 255, .16);
    color: #fff;
    display: grid;
    place-items: center;
    text-decoration: none;
    transition: background .15s ease;
}
.bt-af-sharebtn:hover,
.bt-af-sharebtn:focus-visible {
    background: rgba(255, 255, 255, .28);
    color: #fff;
    text-decoration: none;
}
.bt-af-sharebtn svg { width: 18px; height: 18px; }

/* 4 stat tiles con bandita de color izquierda (reusa .bt-band-0..3 de
   este archivo, definidas mas arriba en la seccion de bandas Lagom). */
.bt-af-tiles {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin: 26px 0;
}
@media (max-width: 820px) { .bt-af-tiles { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .bt-af-tiles { grid-template-columns: 1fr; } }
.bt-af-tile {
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-left: 4px solid;
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 16px 18px;
}
/* Causa raiz del bug reportado por el dueno (banda izquierda en negro):
   el shorthand "border-left: 4px solid" de arriba NO trae color propio,
   asi que resuelve a currentColor — y .bt-af-tile no fija su propio
   "color", asi que hereda el casi-negro var(--bt-text) del body. Las
   .bt-band-0..3 globales (definidas mas arriba en este archivo, seccion
   "Bandita de color estilo Lagom") solo tocan border-left-color con la
   MISMA especificidad (0,1,0) que .bt-af-tile; al estar declaradas
   ANTES en el archivo, el cascade las pierde frente al shorthand de
   .bt-af-tile que se declara despues y resetea border-left-color de
   vuelta a currentColor. Fix: selectores de 2 clases (especificidad
   0,2,0, le ganan al shorthand sin !important) que fijan el color
   EXACTO de cada bandita — mismos 4 valores que los numeros (commit
   337f4c1), no los de .bt-band-0..3 (esas se dejan intactas, las usa
   tambien el sidebar). */
.bt-af-tile.bt-band-0 { border-left-color: #1062FE; }
.bt-af-tile.bt-band-1 { border-left-color: #12B76A; }
.bt-af-tile.bt-band-2 { border-left-color: #F79009; }
.bt-af-tile.bt-band-3 { border-left-color: #7A5AF8; }
.bt-af-tile-n {
    font-size: 26px;
    font-weight: 500;
    color: #1F2430;
    font-variant-numeric: tabular-nums;
}
/* Pedido del dueno 07-29: el numero de cada tile toma el color de su
   propia bandita en vez del casi-negro por defecto. Se reutilizan las
   clases de banda ya presentes en el .tpl (.bt-af-tile.bt-band-0..3) en
   vez de duplicar el mapeo tile->color; los valores de texto son los
   4 exactos pedidos por el dueno, distintos de los de .bt-band-0..3
   definidas mas arriba (esas siguen fijando SOLO el border-left, no se
   tocan — se agrega aqui una regla aparte, mas especifica, solo para el
   color del numero dentro de un .bt-af-tile). Peso/tamano (26px/500) y
   labels grises quedan intactos (reglas de arriba/abajo, sin cambios). */
.bt-af-tile.bt-band-0 .bt-af-tile-n { color: #1062FE; }
.bt-af-tile.bt-band-1 .bt-af-tile-n { color: #12B76A; }
.bt-af-tile.bt-band-2 .bt-af-tile-n { color: #F79009; }
.bt-af-tile.bt-band-3 .bt-af-tile-n { color: #7A5AF8; }
.bt-af-tile-l { font-size: 12.5px; color: var(--bt-text-3); margin-top: 4px; }

/* Tarjeta generica reusada por "Camino a tu primer retiro" / "Resumen de
   comisiones" / "Tus referidos" — mismo lenguaje que .bt-body .card. */
.bt-af-card {
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    margin-bottom: 26px;
}
.bt-af-card-pad { padding: 22px 24px; }
.bt-af-card-pad h2 { font-size: 17px; font-weight: 300; margin: 0 0 14px; color: #4A5160; }

/* Barra de progreso "Camino a tu primer retiro": riel gris + relleno
   verde degradado, mismo par de colores que .bt-pd-cardacts .bt-pd-upgradebtn. */
.bt-af-meter {
    height: 10px;
    border-radius: 999px;
    background: #E7E9F0;
    overflow: hidden;
}
.bt-af-meter-fill {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, #12B76A 0%, #34D399 100%);
    transition: width .3s ease;
}
@media (prefers-reduced-motion: reduce) { .bt-af-meter-fill { transition: none; } }
.bt-af-progress-note { font-size: 12.5px; color: var(--bt-text-2); margin: 12px 0 18px; }

.bt-af-withdrawwrap { text-align: center; }
/* Boton "Solicitar retiro": verde degradado (patron bt-pd-upgradebtn)
   cuando $withdrawlevel lo permite; gris plano y deshabilitado cuando no
   llega al minimo (el .tpl agrega la clase "disabled" + atributo
   disabled nativos, mismo truco que la referencia). */
.bt-af-withdrawbtn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: linear-gradient(135deg, #12B76A 0%, #34D399 100%);
    border: none;
    color: #fff;
    font-weight: 700;
    font-size: 13.5px;
    font-family: var(--bt-font);
    padding: 12px 22px;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(18, 183, 106, .25);
    cursor: pointer;
    transition: background .15s ease, box-shadow .15s ease, transform .15s ease;
}
.bt-af-withdrawbtn:hover {
    background: linear-gradient(135deg, #0E9355 0%, #2BBF83 100%);
    box-shadow: 0 4px 12px rgba(18, 183, 106, .30);
    transform: translateY(-1px);
    color: #fff;
}
.bt-af-withdrawbtn:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(18, 183, 106, .08); }
.bt-af-withdrawbtn.disabled,
.bt-af-withdrawbtn[disabled] {
    background: #F2F4F7;
    color: #98A2B3;
    box-shadow: none;
    cursor: default;
    pointer-events: none;
    transform: none;
}
@media (prefers-reduced-motion: reduce) {
    .bt-af-withdrawbtn,
    .bt-af-withdrawbtn:hover { transition: none; transform: none; }
}
.bt-af-withdraw-hint { font-size: 12px; color: var(--bt-text-3); text-align: center; margin: 10px 0 0; }

/* Titulos de seccion sueltos (fuera de tarjeta): "Como funciona",
   "Enlazanos". */
.bt-af-section { margin-bottom: 30px; }
.bt-af-sectitle { font-size: 19px; font-weight: 300; margin: 0 0 16px; color: #1F2430; }

/* "Como funciona": 3 tarjetas con tag PASO 1/2/3 azul + icono en chip
   teal (mismos colores E6F7F9/#0BA5B7 que .bt-dd-qico). */
.bt-af-steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 18px;
}
@media (max-width: 820px) { .bt-af-steps { grid-template-columns: 1fr; } }
.bt-af-step {
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 20px 20px 18px;
}
.bt-af-step-tag {
    display: inline-block;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: #fff;
    background: var(--bt-primary);
    border-radius: 999px;
    padding: 4px 10px;
    margin-bottom: 14px;
}
.bt-af-step-ico {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    background: #E6F7F9;
    color: #0BA5B7;
    display: grid;
    place-items: center;
    margin-bottom: 14px;
}
.bt-af-step-ico svg { width: 21px; height: 21px; }
.bt-af-step h3 { font-size: 14.5px; font-weight: 400; margin: 0 0 6px; color: var(--bt-text); }
.bt-af-step p { font-size: 12.5px; color: var(--bt-text-3); margin: 0; line-height: 1.4; }

/* Filas clave-valor del "Resumen de comisiones", mismo patron que
   .bt-pd-row. */
.bt-af-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--bt-border-soft, var(--bt-border));
    font-size: 13px;
}
.bt-af-row:last-of-type { border-bottom: 0; }
.bt-af-row .k { color: var(--bt-text-2); }
.bt-af-row .v { color: #4A5160; font-weight: 400; text-align: right; }

/* ===== BT SHARED: FORMS + CARDS + ACCOUNT TABS ===== */
/* ============================================================
   Capa reutilizable para las paginas de formularios de cuenta que vienen
   (perfil/seguridad/contrasena/contactos/contact) y para cualquier tarjeta
   generica fuera de las secciones ya nombradas (dashboard/dominios/product
   details/afiliados). Es un SKIN encima de Bootstrap 4.5.3 (twenty-one), no
   lo reemplaza: .bt-form/.bt-card/.bt-btn son contenedores/clases propias
   que se anaden junto a las de Bootstrap en el markup de cada pagina, no en
   vez de ellas. Mismo lenguaje visual que Product Details (tarjetas blancas,
   borde #E7E9F0, radio 10px, azul primario #1062FE, azul sutil de accion
   #4C7EDB/#CFE0FF) para que las paginas nuevas no desentonen.

   Especificidad de los botones-enlace: igual que .bt-site-act.bt-site-act-
   main / .bt-site-acts .bt-site-act mas arriba, CUALQUIER <a> necesita
   especificidad >= (0,2,0) para ganarle a ".bt-body a" (0,1,1) — una sola
   clase (".bt-btn") NO basta para el color de texto en un <a>. Por eso la
   regla base de ".bt-btn" (ver mas abajo) repite el selector como
   ".bt-body a.bt-btn" (0,2,1) para el caso <a>, mismo patron que
   ".bt-body a.bt-dm-tbtn--primary" en la seccion de Domain Details. Asi
   ".bt-btn" es AUTOSUFICIENTE: trae su propio azul primario sin depender
   de un ancestro ".bt-form"/".bt-card". Los modificadores
   (".bt-btn.bt-btn--soft", ".bt-btn.bt-btn--danger-soft", 0,2,0) siguen
   pisando la base igual que antes. Que nadie baje un <a class="bt-btn"> a
   una sola clase sin este segundo selector, o volveria a salir azul plano
   de ".bt-body a" y perderia el fondo/color propios. */

/* ---- .bt-card: tarjeta generica ---- */
.bt-card {
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 24px 28px;
}
.bt-card + .bt-card { margin-top: 20px; }
.bt-card .bt-card-title {
    font-size: 17px;
    font-weight: 300;
    color: var(--bt-text);
    margin: 0 0 16px;
}

/* ---- .bt-form: formularios ---- */
.bt-form .bt-form-row { margin-bottom: 18px; }
.bt-form .bt-form-row:last-child { margin-bottom: 0; }
.bt-form label {
    display: block;
    font-size: 13px;
    font-weight: 400;
    color: var(--bt-text-2);
    margin-bottom: 6px;
}
.bt-form input[type="text"],
.bt-form input[type="email"],
.bt-form input[type="password"],
.bt-form input[type="tel"],
.bt-form input[type="number"],
.bt-form input[type="search"],
.bt-form select,
.bt-form textarea {
    width: 100%;
    height: 44px;
    padding: 0 14px;
    font-family: var(--bt-font);
    font-size: 14px;
    font-weight: 300;
    color: var(--bt-text);
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 8px;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.bt-form textarea {
    height: auto;
    min-height: 110px;
    padding-top: 12px;
    padding-bottom: 12px;
}
.bt-form input:focus,
.bt-form select:focus,
.bt-form textarea:focus {
    outline: none;
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 .2rem rgba(16, 98, 254, .16);
}
.bt-form .bt-help-text {
    display: block;
    font-size: 12.5px;
    color: var(--bt-text-3);
    margin-top: 6px;
}
/* Estados discretos: mismo tono que .bt-body .alert-* de arriba, sin
   recuadro completo — solo borde del campo + texto de ayuda coloreado. */
.bt-form .bt-form-row--error input,
.bt-form .bt-form-row--error select,
.bt-form .bt-form-row--error textarea { border-color: #F04438; }
.bt-form .bt-form-row--error .bt-help-text { color: #A01D1D; }
.bt-form .bt-form-row--success input,
.bt-form .bt-form-row--success select,
.bt-form .bt-form-row--success textarea { border-color: var(--bt-green); }
.bt-form .bt-form-row--success .bt-help-text { color: #0A7A5C; }

/* ---- .bt-btn: botones (ver nota de especificidad arriba) ----
   AUTOSUFICIENTE por diseno (FIX 2026-07-30, ver nota arriba): la clase
   base ya trae el aspecto primario del tema (fondo azul solido, texto
   blanco) sin depender de un ancestro .bt-form/.bt-card. Antes de este
   fix la base no declaraba background/color propios y CUALQUIER .bt-btn
   usado fuera de .bt-form/.bt-card salia con el gris de sistema del
   navegador — ya paso una vez en el buscador de Knowledgebase (parche ad-
   hoc .bt-btn.bt-kb-search-btn, ahora simplificado mas abajo porque la
   base ya lo cubre) y un reviewer lo habia predicho para el resto de
   paginas. Inventariados TODOS los usos de .bt-btn en el tema (07-30):
   los que ya vivian dentro de .bt-form/.bt-card seguian viendose azules
   (mismo resultado, sin cambio visual) y ninguno dependia de que la base
   fuera neutra. */
.bt-btn,
.bt-body a.bt-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 40px;
    padding: 0 18px;
    font-family: var(--bt-font);
    font-size: 13.5px;
    font-weight: 500;
    border-radius: var(--bt-radius-sm);
    border: 1px solid var(--bt-primary);
    background: var(--bt-primary);
    color: #fff;
    text-decoration: none;
    cursor: pointer;
    line-height: 1;
}
.bt-btn:hover,
.bt-body a.bt-btn:hover {
    background: var(--bt-primary-hover);
    border-color: var(--bt-primary-hover);
    color: #fff;
    text-decoration: none;
}
/* Los .bt-btn que llevan la clase w-hidden del theme base deben seguir
   ocultos — la cascada de hojas invierte el orden (incidente 2FA
   2026-07-29): theme.min.css (twenty-one) carga ANTES y banatheme.css
   DESPUES, misma especificidad (0,1,0) que .w-hidden{display:none}, asi
   que .bt-btn{display:inline-flex} gana y deja visibles y clicables los
   dos enlaces "Activar/Desactivar 2FA" a la vez. Especificidad 0,2,0, SIN
   !important (romperia los .show()/.hide() de jQuery del core).
   FIX 2026-07-30 (bug detectado por el fixture headless de .bt-btn):
   desde que la base repite el selector como ".bt-body a.bt-btn" (0,2,1,
   con su propio display:inline-flex) para el caso <a>, esa especificidad
   le gana a ".bt-btn.w-hidden" (0,2,0) y un <a class="bt-btn w-hidden">
   volvia a mostrarse. Mismo patron: se repite tambien como
   ".bt-body a.bt-btn.w-hidden" (0,3,1). */
.bt-btn.w-hidden,
.bt-body a.bt-btn.w-hidden { display: none; }

/* Azul sutil de accion secundaria (mismo lenguaje que .bt-site-act.bt-site-
   act-main de Product Details): #4C7EDB con borde #CFE0FF, hover fondo
   #F0F5FF/borde #A9C6FF.
   FIX 2026-07-30 (bug detectado por el fixture headless de .bt-btn, ver
   verificaciones): desde que la base ".bt-btn" es autosuficiente repite el
   selector como ".bt-body a.bt-btn" (0,2,1) para el caso <a> — eso ahora
   le GANA a ".bt-btn.bt-btn--soft" (0,2,0), asi que un <a class="bt-btn
   bt-btn--soft"> volvia a salir azul solido. Mismo patron: se repite el
   modificador tambien como ".bt-body a.bt-btn.bt-btn--soft" (0,3,1),
   mayor especificidad que la base para <a> Y para el resto de elementos. */
.bt-btn.bt-btn--soft,
.bt-body a.bt-btn.bt-btn--soft {
    background: transparent;
    border-color: #CFE0FF;
    color: #4C7EDB;
}
.bt-btn.bt-btn--soft:hover,
.bt-body a.bt-btn.bt-btn--soft:hover {
    background: #F0F5FF;
    border-color: #A9C6FF;
    color: var(--bt-primary);
}

/* Outline peligro discreto (cancelar/eliminar/cerrar sesiones) — nunca
   rojo solido de entrada, solo al hover confirma la intencion. Mismo fix
   de especificidad que --soft arriba. */
.bt-btn.bt-btn--danger-soft,
.bt-body a.bt-btn.bt-btn--danger-soft {
    background: transparent;
    border-color: #FECDCA;
    color: #F04438;
}
.bt-btn.bt-btn--danger-soft:hover,
.bt-body a.bt-btn.bt-btn--danger-soft:hover {
    background: #FEF3F2;
    border-color: #F04438;
    color: #B42318;
}

/* ---- .bt-ac-tabs: sub-nav de cuenta (includes/bt-actabs.tpl) ----
   Pildoras horizontales, scroll-x en movil (sin wrap: whitespace nowrap +
   overflow-x auto, sin scrollbar visible en la mayoria de navegadores via
   -webkit-overflow-scrolling touch). Especificidad de las pildoras-enlace:
   ".bt-ac-tabs .bt-ac-tab" (0,2,0), misma razon documentada arriba. */
.bt-ac-tabs {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 2px;
    margin-bottom: 24px;
    white-space: nowrap;
}
.bt-ac-tabs .bt-ac-tab {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    height: 36px;
    padding: 0 16px;
    border: 1px solid var(--bt-border);
    border-radius: 999px;
    font-size: 13px;
    font-weight: 400;
    color: var(--bt-text-2);
    background: var(--bt-surface);
    text-decoration: none;
}
.bt-ac-tabs .bt-ac-tab:hover {
    color: var(--bt-primary);
    background: #F0F5FF;
    border-color: #A9C6FF;
    text-decoration: none;
}
.bt-ac-tabs .bt-ac-tab.bt-ac-tab-active {
    color: #fff;
    background: var(--bt-primary);
    border-color: var(--bt-primary);
    font-weight: 500;
}

/* ===== BT SECTION: INVOICES+TICKETSLIST ===== */

/* CSS para clientareainvoices.tpl y supportticketslist.tpl. Reusa al
   maximo las clases globales .bt-dm-* ya desplegadas en banatheme.css
   (mismo patron de Mis Dominios F6 / Mis Servicios F7): tarjeta unica
   .bt-dm-list, filas .bt-dm-item en grid, columnas .bt-dm-idcol/-meta/
   -statcol/-actions, pildoras .bt-dm-pill, boton .bt-dm-managebtn,
   buscador/orden/paginador .bt-dm-search(-*)/-sort/-foot/-pager/-pg. Todo
   eso NO se repite aqui — solo lo especifico de estas 2 paginas:
     1) ocultar el sidebar contextual via :has() (mismo patron que
        .bt-domains/.bt-services/.bt-home);
     2) el grid-template-columns propio de cada pagina (numero de columnas
        distinto: facturas trae Creada+Vencimiento+Total+Estado, tickets
        trae Actualizado+Estado);
     3) modificadores de pildora .bt-dm-pill--{modifier} nuevos que no
        existen aun en banatheme.css (paid/unpaid/unpaid-overdue/payment-
        pending/collections/refunded/draft para facturas; tk-open/tk-
        answered/tk-customer-reply/tk-on-hold/tk-closed/tk-default para
        tickets, prefijo tk- para no chocar con los estados de dominio que
        ya usan open/closed en otro sentido... salvo que no existian, el
        prefijo es solo para dejar explicito que son estados de TICKET);
     4) un par de detalles minimos propios (numero de ticket, asunto no
        leido).
   El mobile (<=820px) NO necesita reglas nuevas: la media query global de
   banatheme.css ya oculta .bt-dm-meta/.bt-dm-statlabel/.bt-dm-ar-label y
   pasa .bt-dm-item a flex para CUALQUIER pagina que reuse esas mismas
   clases (domains/services/invoices/tickets por igual).

   OJO: nunca escribir un asterisco seguido de una barra (el cierre de
   comentario CSS) pegados dentro del TEXTO de un comentario — cierra el
   comentario antes de tiempo y el parser se traga la regla siguiente
   (incidente 2026-07-29: esta MISMA seccion tenia esa secuencia pegada a
   "-sort" mas arriba en la descripcion de .bt-dm-search, y eso hacia que
   el navegador descartara la regla siguiente como "recuperacion de
   error" — esa era la causa real del misterio del CSSOM que parecia un
   bug del selector :has(), no lo era). */

/* 1) Sidebar contextual oculto SOLO en estas paginas (mismo patron que
   .bt-domains/.bt-services ya en banatheme.css).
   La regla suelta .container-fluid:has(.bt-invoices) .col-lg-4.col-xl-3
   (identica en forma a sus 6 hermanas del resto del tema) es descartada
   de forma reproducible del CSSOM por el parser de Chromium — verificado
   en vivo 2026-07-29: el CSS servido es byte-correcto (hexdump limpio) y
   un insertRule() con el MISMO selector si aplica y oculta la columna,
   pero la regla tal cual queda en el archivo no llega a parsear. Causa
   raiz no diagnosticada (fuera de alcance). Fix pragmatico: agruparla con
   la regla hermana de .bt-tickets (que si parsea) en un solo selector
   compuesto — evita la regla suelta problematica sin depender de
   entender el quirk. Por la misma razon se suman aqui, a proposito, las
   hermanas .bt-tv (viewticket.tpl) y .bt-ts (supportticketsubmit-*.tpl)
   de la seccion TICKETS-VIEW+SUBMIT en vez de dejarlas sueltas o en su
   propio grupo aparte. */
.container-fluid:has(.bt-invoices) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-tickets) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-tv) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-ts) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-masspay) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-kb) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-quotes) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-emails) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-ann) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-dl) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-invoices) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-invoices) .sidebar-secondary {
    display: none;
}
.container-fluid:has(.bt-tickets) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-tickets) .sidebar-secondary {
    display: none;
}
.container-fluid:has(.bt-masspay) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-masspay) .sidebar-secondary {
    display: none;
}
.container-fluid:has(.bt-kb) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-kb) .sidebar-secondary {
    display: none;
}
.container-fluid:has(.bt-quotes) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-quotes) .sidebar-secondary {
    display: none;
}
.container-fluid:has(.bt-emails) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-emails) .sidebar-secondary {
    display: none;
}
/* .bt-ann (announcements.tpl) y .bt-dl (downloads.tpl/downloadscat.tpl):
   mismo patron de ocultar el sidebar contextual (widget nativo "By Month"/
   categorias que el core pinta ahi) — se reemplaza por completo con el
   contenido skinizado a ancho completo, igual que KB/facturas/tickets. */
.container-fluid:has(.bt-ann) .primary-content,
.container-fluid:has(.bt-dl) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-ann) .sidebar-secondary,
.container-fluid:has(.bt-dl) .sidebar-secondary {
    display: none;
}
/* .bt-affiliates NO necesita nada nuevo aqui: ya tiene su propio grupo
   :has(.bt-affiliates) desde el F1 y la tabla de referidos vive DENTRO de
   esa misma pagina, no es una pagina nueva. */

/* 2) Grid de columnas por pagina (mismo patron que .bt-services .bt-dm-item
   en banatheme.css: cada pagina reusa .bt-dm-item pero define su propio
   reparto de columnas segun sus datos).
   Facturas: [glob][# factura][Creada][Vencimiento][Total][Estado][CTA]. */
.bt-invoices .bt-dm-item {
    grid-template-columns: auto minmax(60px, .6fr) minmax(100px, 1fr) minmax(100px, 1fr) minmax(90px, 1fr) minmax(130px, 1fr) minmax(100px, auto);
}
/* Tickets: [glob][# + asunto (+depto sub)][Actualizado][Estado][CTA]. */
.bt-tickets .bt-dm-item {
    grid-template-columns: auto minmax(0, 2fr) minmax(140px, 1fr) minmax(130px, 1fr) minmax(110px, auto);
}
/* Presupuestos: [glob][# + asunto][Creado][Valido hasta][Estado][Ver +
   Descargar]. La columna de acciones lleva 2 botones (Ver + Descargar),
   por eso el piso minimo es mas generoso (200px), mismo criterio que
   .bt-paymentmethods .bt-dm-item (230px para 3 botones). */
.bt-quotes .bt-dm-item {
    grid-template-columns: auto minmax(0, 2fr) minmax(100px, 1fr) minmax(100px, 1fr) minmax(110px, 1fr) minmax(200px, auto);
}
/* Emails: [glob][asunto (+clip si tiene adjunto)][Enviado][Ver mensaje].
   Sin columna de estado (el nativo no trae ninguna). */
.bt-emails .bt-dm-item {
    grid-template-columns: auto minmax(0, 2fr) minmax(140px, 1fr) minmax(150px, auto);
}
/* Afiliados > "Tus referidos" (unica tabla nativa que quedaba en esa
   pagina): [glob][Producto+fecha][Importe][Comision][Estado]. Sin columna
   de acciones (el nativo no trae ningun link/boton por fila). */
.bt-af-referrals .bt-dm-item {
    grid-template-columns: auto minmax(0, 2fr) minmax(110px, 1fr) minmax(120px, 1fr) minmax(110px, 1fr);
}

.bt-tk-num { color: var(--bt-text-3); font-variant-numeric: tabular-nums; margin-right: 4px; }
/* Asunto no leido: mismo espiritu que el nativo (clase "unread" en
   ticket-subject), solo un poco mas de peso tipografico — el color ya es
   #4C7EDB via .bt-dm-dom, no se toca. */
.bt-tk-unread { font-weight: 500; }

/* 3) Colores de estado — texto de color con punto (::before via
   .bt-dm-pill, ya global), mismos valores hex que domains/services.
   Facturas (statusClass real de WHMCS, o "unpaid-overdue" calculado en el
   tpl cuando unpaid + normalisedDateDue vencida). */
.bt-dm-pill--paid { color: #17B26A; }
.bt-dm-pill--unpaid { color: #E0900D; }
.bt-dm-pill--unpaid-overdue { color: #F04438; }
.bt-dm-pill--payment-pending { color: #E0900D; }
.bt-dm-pill--collections { color: #F04438; }
.bt-dm-pill--refunded { color: #7A5AF8; }
.bt-dm-pill--draft { color: #757B87; }
/* .bt-dm-pill--cancelled YA existe en banatheme.css en rojo (para
   dominios: Cancelled ahi es un estado de baja severidad-alta, junto con
   Expired/Terminated/Fraud). Para facturas "Cancelled" es neutro (gris),
   asi que se pisa el color SOLO dentro de .bt-invoices: 2 clases > 1 en
   especificidad, gana sin tocar la regla global. */
.bt-invoices .bt-dm-pill--cancelled { color: #757B87; }

/* Tickets: colores fijos por nombre de estado (decision del dueno, NO por
   statusClass/statusColor nativos de departamento). Prefijo tk- exclusivo
   de esta pagina para no colisionar con ningun otro --modifier existente. */
.bt-dm-pill--tk-open { color: #1062FE; }
.bt-dm-pill--tk-answered { color: #17B26A; }
.bt-dm-pill--tk-customer-reply { color: #E0900D; }
.bt-dm-pill--tk-on-hold { color: #2E90FA; }
.bt-dm-pill--tk-in-progress { color: #7A5AF8; }
.bt-dm-pill--tk-closed { color: #757B87; }
/* Default para estados custom de departamento no reconocidos por el
   substring-match del tpl: azul, igual que "Open". */
.bt-dm-pill--tk-default { color: #1062FE; }

/* Presupuestos: mismo criterio que el prefijo tk- de tickets (evita
   chocar con los estados de dominio/factura que ya usan draft/accepted en
   otro sentido). Valores del enum nativo tblquotes.stage verificados
   contra templates/twenty-one/css/theme.css (.status-onhold/-delivered/
   -accepted/-lost/-dead): Draft, Delivered, On Hold, Accepted, Lost, Dead. */
.bt-dm-pill--qt-draft { color: #757B87; }
.bt-dm-pill--qt-onhold { color: #E0900D; }
.bt-dm-pill--qt-delivered { color: var(--bt-primary); }
.bt-dm-pill--qt-accepted { color: #17B26A; }
.bt-dm-pill--qt-lost,
.bt-dm-pill--qt-dead { color: #F04438; }
/* La tabla de "Tus referidos" en afiliados NO necesita pildoras nuevas:
   reusa las YA GLOBALES .bt-dm-pill--paid/--unpaid/--pending para los 3
   rawstatus reales de WHMCS (Paid/Unpaid/Pending) y cae a
   .bt-dm-pill--draft (gris, tambien ya global) para cualquier estado no
   reconocido — CERO clases nuevas aqui. */

/* ===== BT SECTION: CUENTA ===== */

/* Staging del re-skin de las 4 paginas de cuenta-datos: clientareadetails.tpl,
   account-contacts-manage.tpl, account-contacts-new.tpl, contact.tpl.
   Reusa integramente el lenguaje visual definido arriba en "BT SHARED: FORMS
   + CARDS + ACCOUNT TABS" (.bt-card/.bt-form/.bt-btn/.bt-ac-tabs, tokens
   --bt-*): aqui solo van los complementos especificos de estas 4 paginas
   que ese bloque compartido no cubre todavia. */

/* ---- Titulo de pagina (20/300) vs titulo de seccion .bt-card-title
   (17/300) ---- */
.bt-page-title {
    font-size: 20px;
    font-weight: 300;
    color: var(--bt-text);
    margin: 0 0 20px;
}

/* ---- Subtitulo bajo el h1 de contact.tpl (unica pagina de las 4 que no
   lleva sub-nav bt-actabs, necesita su propia intro corta) ---- */
.bt-card-subtitle {
    font-size: 14px;
    font-weight: 300;
    color: #4A5160;
    margin: 0 0 20px;
}

/* ---- Fila de acciones (submit/reset/eliminar) al pie de cada form ---- */
.bt-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    margin-top: 24px;
}

/* ---- Selector de contacto (account-contacts-manage/new.tpl): el
   <select onchange="submit()"> nativo + boton "Go" en una fila, mismo
   patron .bt-form (select estilado por .bt-form select ya definido). ---- */
.bt-contact-select-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
}
.bt-contact-select-row select {
    flex: 1 1 260px;
}

/* ---- Tarjeta de email preferences anidada dentro del <form class="bt-
   form"> de contactos (no puede usar el "+" adyacente de .bt-card porque
   su hermano anterior es un <div class="row">, no otro .bt-card). ---- */
.bt-card--nested {
    margin-top: 20px;
}

/* ---- Fila del captcha en contact.tpl: mismo criterio que la fila
   "text-center margin-bottom" que envolvia a includes/captcha.tpl en el
   nativo (_ref-twentyone/contact.tpl linea 47). ---- */
.bt-form-row--captcha {
    text-align: center;
    margin-bottom: 18px;
}

/* ---- Sidebar contextual oculto en estas 2 paginas (details/contacts): la
   navegacion la da la sub-nav includes/bt-actabs.tpl, mismo patron :has()
   que .bt-home/.bt-domains/.bt-pd/.bt-affiliates. contact.tpl NO lleva
   wrapper porque no es parte de la seccion de cuenta (pagina suelta de
   contacto a soporte), asi que conserva su sidebar contextual normal. ---- */
.container-fluid:has(.bt-details) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-contacts) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-details) .primary-content,
.container-fluid:has(.bt-contacts) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-details) .sidebar-secondary,
.container-fluid:has(.bt-contacts) .sidebar-secondary {
    display: none;
}

/* Staging del re-skin de la superficie de autenticacion de cuenta:
   user-profile.tpl, user-security.tpl, user-password.tpl,
   clientareasecurity.tpl. Reusa integramente el lenguaje visual definido en
   "BT SHARED: FORMS + CARDS + ACCOUNT TABS" (.bt-card/.bt-form/.bt-btn/
   .bt-ac-tabs, tokens --bt-*) y .bt-page-title (arriba, misma seccion de
   cuenta): aqui solo van los complementos especificos de estas 4 paginas
   que esos bloques compartidos no cubren todavia. */

/* ---- Ocultar sidebar contextual: mismo patron :has() que
   .bt-details/.bt-contacts / .bt-invoices/.bt-tickets — la navegacion la
   da la sub-nav bt-actabs. clientareasecurity.tpl (legado, SSO retirado
   2026-07-29) ahora tambien lleva la sub-nav y se agrega aqui via su
   wrapper .bt-security-legacy (token de clase distinto de .bt-security, no
   lo cubria la regla original). user-switch-account.tpl (.bt-switch-account,
   pantalla "Choose Account") se agrega al mismo grupo: es de la misma
   superficie de auth de cuenta y tampoco lleva sidebar contextual.
   account-paymentmethods*.tpl (.bt-paymentmethods, 3 plantillas: listado/
   gestion/contactos de facturacion) se agrega igual: misma sub-nav
   bt-actabs, sin sidebar contextual propio. ---- */
.container-fluid:has(.bt-profile) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-security) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-password) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-security-legacy) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-switch-account) .col-lg-4.col-xl-3,
.container-fluid:has(.bt-paymentmethods) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-profile) .primary-content,
.container-fluid:has(.bt-security) .primary-content,
.container-fluid:has(.bt-password) .primary-content,
.container-fluid:has(.bt-security-legacy) .primary-content,
.container-fluid:has(.bt-switch-account) .primary-content,
.container-fluid:has(.bt-paymentmethods) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
}
.container-fluid:has(.bt-profile) .sidebar-secondary,
.container-fluid:has(.bt-security) .sidebar-secondary,
.container-fluid:has(.bt-password) .sidebar-secondary,
.container-fluid:has(.bt-security-legacy) .sidebar-secondary,
.container-fluid:has(.bt-switch-account) .sidebar-secondary,
.container-fluid:has(.bt-paymentmethods) .sidebar-secondary {
    display: none;
}

/* ---- .bt-badge: estado de verificacion de email (userProfile.verified /
   .notVerified en user-profile.tpl). ---- */
.bt-badge {
    display: inline-flex;
    align-items: center;
    height: 24px;
    padding: 0 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
}
.bt-badge--success {
    background: #E6F4EC;
    color: #0A7A5C;
}
.bt-badge--muted {
    background: #F1F2F6;
    color: var(--bt-text-3);
}

/* ---- newPassword1/newPassword2: alinear medidor de fuerza + boton
   "generar contrasena" con el resto de .bt-form (user-password.tpl). ---- */
#newPassword1 .generate-password {
    width: 100%;
}

/* ---- clientareasecurity.tpl (legado, SSO retirado 2026-07-29): ya trae
   wrapper .bt-security-legacy y sub-nav bt-actabs (agregada al grupo :has()
   de arriba). Solo queda el parrafo del aviso, con el mismo estilo de
   ayuda que .bt-help-text usa en el resto del tema. ---- */
.bt-security-legacy .bt-help-text {
    font-size: 12.5px;
    color: var(--bt-text-3);
    margin-top: 12px;
    margin-bottom: 0;
}

/* ===== BT SECTION: TICKETS-VIEW+SUBMIT ===== */
/* ============================================================
   Ver Ticket (viewticket.tpl, wrapper .bt-tv) + Abrir Ticket
   (supportticketsubmit-*.tpl, wrapper .bt-ts). Reusa integramente la capa
   compartida "BT SHARED: FORMS + CARDS + ACCOUNT TABS" (.bt-card/.bt-form/
   .bt-btn, tokens --bt-*) y las burbujas de chat ya globales .bt-bubble/
   .bt-bubble-in/.bt-bubble-out (mismo lenguaje que el chat de soporte del
   home): aqui solo van los complementos especificos de estas paginas.

   ATENCION merge (ver incidente 2026-07-29 documentado junto a
   .bt-invoices/.bt-tickets en banatheme.css): una regla SUELTA
   ".container-fluid:has(.bt-X) .col-lg-4.col-xl-3" puede ser descartada
   por el parser aunque el byte a byte este limpio. Por eso .bt-tv y .bt-ts
   se agrupan en el selector compuesto de la seccion INVOICES+TICKETSLIST
   (ver punto 1 mas abajo) en vez de quedar sueltas o en grupo aparte.

   OJO: como el resto del archivo, nunca la secuencia asterisco-barra
   pegada a texto dentro de un comentario (cierra el comentario antes de
   tiempo y el parser descarta la regla siguiente). Revisado a mano en
   todo este archivo. */

/* ---- 1) Sidebar contextual oculto (mismo patron :has() que el resto del
   tema — sidebar generico $sidebar de WHMCS, sin datos propios de ticket,
   ver comentario de cabecera en viewticket.tpl). La regla que oculta la
   columna .col-lg-4.col-xl-3 se agrupa a proposito con sus hermanas de
   .bt-invoices/.bt-tickets en la seccion INVOICES+TICKETSLIST de este
   mismo archivo (evita repetir el quirk de parseo documentado ahi: una
   regla suelta con este selector puede quedar descartada del CSSOM). ---- */
.container-fluid:has(.bt-tv) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-tv) .sidebar-secondary { display: none; }
.container-fluid:has(.bt-ts) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-ts) .sidebar-secondary { display: none; }

/* ============================================================
   2) Ver Ticket (.bt-tv)
   ============================================================ */

/* ---- Cabecera-resumen, estilo .bt-dd-summary (numero/asunto/acciones) ---- */
.bt-tv-summary { margin-bottom: 20px; }
.bt-tv-summary-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}
.bt-tv-summary-heading { min-width: 0; }
/* El asunto es ahora el titulo grande de la tarjeta (antes era "View
   Ticket #TTL-xxx"); ese texto pasa a .bt-tv-summary-tid, secundario
   debajo. */
.bt-tv-summary-title {
    font-size: 19px;
    font-weight: 600;
    margin: 0;
    color: var(--bt-text);
    overflow-wrap: break-word;
}
.bt-tv-summary-tid { margin: 3px 0 0; font-size: 12.5px; color: var(--bt-text-3); }
.bt-tv-summary-acts { display: flex; gap: 10px; flex-wrap: wrap; }
.bt-tv-summary-acts .bt-btn svg { width: 15px; height: 15px; }
/* Fila compacta de metadatos: pildora de estado (reusa .bt-dm-pill/--tk-*
   ya globales, ver viewticket.tpl) + departamento. */
.bt-tv-summary-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 12px 0 0;
    font-size: 13px;
}
.bt-tv-summary-sep { color: var(--bt-text-3); }
.bt-tv-summary-dept { color: var(--bt-text-2); }

/* Ficha rica de metadatos (Fase 2, pedido del dueno 2026-07-31): sustituye
   .bt-tv-summary-meta arriba cuando hooks-src/banatheme_viewticket.php
   resuelve los datos extra (btTv* en viewticket.tpl); fail-safe, nunca las
   dos a la vez (ver {if $btTvStatus} en la plantilla). Rejilla formal de
   pares etiqueta/valor: 3 columnas en escritorio, 1 en movil (mismo
   breakpoint 760px que .bt-tv-msg mas abajo). */
.bt-tv-facts {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px 22px;
    margin: 14px 0 0;
}
.bt-tv-fact { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bt-tv-fact-label {
    font-size: 10.5px;
    font-weight: 400;
    color: var(--bt-text-3);
    text-transform: uppercase;
    letter-spacing: .4px;
}
.bt-tv-fact-value {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13.5px;
    color: var(--bt-text-2);
    overflow-wrap: break-word;
}
.bt-tv-fact-tag {
    display: inline-flex;
    align-items: center;
    padding: 1px 7px;
    border-radius: 20px;
    font-size: 10px;
    font-weight: 500;
    color: var(--bt-text-3);
    background: rgba(120, 126, 160, .1);
}
.bt-tv-fact-priority { font-weight: 500; }
.bt-tv-fact-priority--high { color: var(--bt-red); }
.bt-tv-fact-priority--medium { color: #E0900D; }
.bt-tv-fact-priority--low { color: var(--bt-text-3); }

/* ---- Hilo de conversacion, formal de ancho completo (pedido del dueno
   2026-07-31: NO parecer chat de mensajeria con burbujas izq/der). Cada
   mensaje es un bloque de ANCHO COMPLETO apilado, sin alineacion por
   lado ni forma de globo; se separan entre si con un borde inferior
   sutil var(--bt-border), igual lenguaje que el resto de listas/tarjetas
   del tema. .bt-bubble/.bt-bubble-in/.bt-bubble-out siguen definidas mas
   arriba en esta hoja para el chat de soporte del home
   (clientareahome.tpl) — no se tocan, ya NO se usan aqui.

   Distincion staff vs cliente (elegida entre las 2 opciones del pedido):
   banda izquierda de 3px azul #4C7EDB en los mensajes de staff, en vez de
   alternar 2 fondos tintados — con fondos alternos el hilo largo termina
   pareciendo tabla de rayas; con banda + un tinte de fondo apenas
   perceptible en staff, el ojo distingue el rol sin la sensacion de
   "chat con 2 colores". El cliente queda en blanco liso (mismo fondo que
   la tarjeta .bt-card contenedora), sin banda.

   Avatares circulares ELIMINADOS (pedido: decidir por limpieza formal):
   el rol ya lo indica el badge .requestor-badge nativo de la cabecera
   (ver contrato en viewticket.tpl), un icono redundante no aporta en un
   layout de documento de ancho completo. */
.bt-tv-thread {
    display: flex;
    flex-direction: column;
    margin-bottom: 20px;
}
.bt-tv-msg {
    padding: 16px 18px;
    border-bottom: 1px solid var(--bt-border);
}
.bt-tv-msg:last-child { border-bottom: none; }
.bt-tv-msg--staff {
    background: #FBFCFE;
    border-left: 3px solid #4C7EDB;
    padding-left: 15px; /* 18px - 3px de banda: mismo ancho de contenido que el cliente */
}

/* Cabecera de cada mensaje: nombre (peso 500) + badge de rol nativo +
   fecha. El string de {lang key="support.postedBy" ...} es intocable
   (orden fijo por el core, ver contrato de cabecera del archivo) asi que
   no se puede reordenar con flex — en vez de eso, .posted-on flota a la
   derecha (aparece antes que el badge en el DOM del lang string, por lo
   que el float lo ancla en el borde derecho con el badge inmediatamente
   a su izquierda). display:flow-root en el contenedor limpia esos
   floats sin clases de utilidad extra. */
.bt-tv-msg-meta {
    display: flow-root;
    font-size: 12.5px;
    margin-bottom: 10px;
}
/* max-width evita que un nombre largo empuje debajo del float:right de
   .posted-on en anchos estrechos (el texto simplemente hace wrap dentro
   de su propia columna en vez de invadir la zona de la fecha). */
.bt-tv-msg-meta .posted-by-name { font-weight: 500; color: var(--bt-text); max-width: 65%; display: inline-block; }
.bt-tv-msg-meta .posted-on { float: right; color: #757B87; }
.bt-tv-msg-meta .requestor-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .3px;
    background: rgba(16, 24, 40, .06);
    color: var(--bt-text-2);
}
/* Staff: badge azul suave (mismo par color ya usado en .bt-site-act-main
   de esta hoja: fondo #CFE0FF, texto #4C7EDB). Cliente: se queda con el
   gris discreto de arriba (decision: sin badge dedicado propio, el badge
   nativo ya cumple ese rol — ver contrato, no se puede reescribir su
   texto interno). */
.bt-tv-msg--staff .bt-tv-msg-meta .requestor-badge {
    background: #CFE0FF;
    color: #4C7EDB;
}
.bt-tv-msg-body {
    /* !important necesario: el div .message en viewticket.tpl lleva la
       clase Bootstrap p-3 (contrato intocable del core, ver cabecera del
       archivo), y el core define ".p-3 { padding: 1rem !important; }" —
       un !important ajeno gana siempre sobre una regla sin !important,
       sin importar especificidad ni orden de carga de las hojas. */
    padding: 0 !important;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--bt-text);
}
.bt-tv-msg-body p:last-child { margin-bottom: 0; }
/* Valoracion (rate reply) discreta: el core (theme.css de los temas
   nativos, seccion "Support Tickets") pone estrellas de 24px flotadas a la
   derecha. Aqui bajan a ~16px, sin float (se quedan al pie del mensaje
   del operador, que es el unico caso donde se muestran — ver
   {if $reply.id && $reply.admin && $ratingenabled} en viewticket.tpl),
   gris suave en reposo y ambar del tema en hover/activo. Solo CSS: el
   markup/ids/atributos del rating (ticketid/ticketkey/ticketreplyid) no
   se tocan. Selector con 3 clases (.bt-tv-msg .bt-tv-msg-body .rating...)
   a proposito para ganarle en especificidad al nativo ".ticket-reply
   .rating..." (0,2,0) sin depender del orden de carga de las hojas de
   estilo (mismo cuidado que la landmine 5.3 de este proyecto), sin usar
   !important.
   font-size EXPLICITO tambien en "... .rating span.star" (no solo en el
   contenedor .rating): QA en vivo (CSSOM real) confirmo que el nativo
   fija el tamano directo sobre span.star, no solo por herencia desde el
   contenedor. */
.bt-tv-msg .bt-tv-msg-body .rating,
.bt-tv-msg .bt-tv-msg-body .rating-done {
    float: none;
    padding: 0;
    margin-top: 8px;
    font-size: 16px;
}
.bt-tv-msg .bt-tv-msg-body .rating span.star,
.bt-tv-msg .bt-tv-msg-body .rating-done span.star {
    font-size: 16px;
}
.bt-tv-msg .bt-tv-msg-body .rating span.star:before,
.bt-tv-msg .bt-tv-msg-body .rating-done span.star:before {
    color: var(--bt-text-3);
}
.bt-tv-msg .bt-tv-msg-body .rating span.star:hover:before,
.bt-tv-msg .bt-tv-msg-body .rating span.star:hover ~ span.star:before,
.bt-tv-msg .bt-tv-msg-body .rating-done span.star.active:before {
    color: #E0900D;
}
.bt-tv-attachments {
    margin-top: 12px;
    /* !important necesario: el div .attachments en viewticket.tpl tambien
       lleva la clase Bootstrap p-3 (".p-3 { padding: 1rem !important; }"
       del core) — mismo caso que .bt-tv-msg-body arriba, un !important
       ajeno no se puede vencer sin !important propio. */
    padding-top: 10px !important;
    border-top: 1px solid var(--bt-border);
    font-size: 12.5px;
}
.bt-tv-attachments svg { width: 14px; height: 14px; vertical-align: -2px; }
.bt-tv-attachments .attachment-list { margin: 8px 0 0; padding: 0; list-style: none; }

@media (max-width: 760px) {
    .bt-tv-msg { padding: 13px 14px; }
    .bt-tv-msg--staff { padding-left: 11px; }
    .bt-tv-facts { grid-template-columns: 1fr; }
}

/* ---- Caja de respuesta, fija en el flujo (no sticky: el hilo puede ser
   largo y clavarla tapa mensajes en pantallas chicas — el boton
   "Responder" de la cabecera ya hace smoothScroll hasta aqui). ---- */
.bt-tv-replybox { margin-bottom: 20px; }
/* .bt-tv-textarea/.bt-tv-reply-acts son de viewticket.tpl (namespace
   .bt-tv-*); .bt-ts-textarea/.bt-ts-reply-acts son las mismas 2 reglas
   pero para supportticketsubmit-steptwo.tpl (namespace .bt-ts-*, fix gate
   07-29: antes steptwo usaba por error el prefijo bt-tv-). Selector
   agrupado EXPLICITO a proposito (mismo valor visual, paginas distintas)
   en vez de compartir una sola clase entre namespaces.
   .bt-tv-textarea baja a ~110px (rows="4" en la plantilla + este piso):
   el listener 'input' inline de viewticket.tpl crece la altura al
   escribir vía style.height, min-height solo evita que baje de 4 lineas.
   .bt-ts-textarea (steptwo, sin auto-crecimiento) se queda en 140px. */
.bt-tv-textarea { min-height: 110px; }
.bt-ts-textarea { min-height: 140px; }
.bt-tv-reply-acts,
.bt-ts-reply-acts { margin-top: 4px; }
/* Submit/Cancel del tema (.bt-btn/.bt-btn--soft) ya traen alto/radio/hover
   coherentes via la regla global de mas arriba (~L3614). Solo falta un
   gap explicito entre ambos: hoy dependen del espacio en blanco del
   markup entre los dos <input>, que es minimo e inconsistente segun
   como el HTML se compacte. text-center se mantiene (pedido del dueno,
   se ve bien centrado con la caja de texto arriba). */
.bt-tv-reply-acts .bt-btn + .bt-btn { margin-left: 10px; }

/* ---- Zona de adjuntos (custom-file + "+ Add More"), pedido del dueno
   2026-07-31: el "Browse" nativo de Bootstrap (::after del custom-file-
   label) traia el gris de sistema y un borde que no combinaba con el
   boton "+ Add More" junto a el, ni con el resto de inputs del tema.
   Reestilo puro CSS, sin tocar ganchos del core: NO se cambia name/id/
   clases custom-file-input/custom-file-label/file-upload/w-hidden que el
   JS del core clona/actualiza (ver contrato en viewticket.tpl), y no se
   toca display/opacity/position de .custom-file-input ni .w-hidden
   (landmine 5.5 — romperia el click del input o revelaria la fila-
   plantilla oculta). Selector ".attachment-group" (no ":first-of-type"
   ni un id) para que la fila clonada por el JS del core dentro de
   #fileUploadsContainer (que reusa .attachment-group/.custom-file, ver
   viewticket.tpl:717-740) herede el mismo aspecto sin CSS adicional. */
.attachment-group .custom-file,
.attachment-group .custom-file-input { height: 40px; }
/* line-height: 26px = 40px de alto - 2px de borde (1px arriba+abajo) -
   12px de padding-y de Bootstrap (.375rem arriba + .375rem abajo, con
   root font-size 16px sin override en este tema). Con eso el texto llena
   exacto el content-box sin desbordar (28px, el valor anterior, se salia
   2px del content-box real — bug detectado por reviewer 07-31). Un solo
   bloque para .custom-file-label (antes el height vivia separado en el
   selector agrupado de arriba junto con .custom-file/.custom-file-input;
   se fusiona aqui por limpieza, pedido del reviewer 07-31). */
.attachment-group .custom-file-label {
    height: 40px;
    line-height: 26px;
    border-color: var(--bt-border);
    color: #757B87;
    font-weight: 300;
}
/* Fondo azul suave del tema (mismo lenguaje que .bt-btn--soft) en vez del
   gris de sistema de Bootstrap; el radio del lado derecho ya lo zera
   Bootstrap por ser ".custom-file:not(:last-child)" dentro del
   input-group (misma logica que reparte con el boton "+ Add More").
   Bootstrap posiciona el ::after con top:0;right:0;bottom:0 pero le fija
   ademas un height propio (~36px, calculado para el alto default de
   Bootstrap) — al subir el label a 40px ese height viejo queda over-
   constrained (top+height ganan, bottom se ignora) y el ::after se
   ancla arriba dejando una franja de ~2-4px del fondo del label visible
   debajo del "Browse" (bug detectado por reviewer 07-31). Se pisa el
   height fijo con top/bottom simetricos (1px, el grosor del borde del
   label) + height:auto para que el ::after se estire solo y quede
   pixel-perfect sin importar el alto exacto que Bootstrap le hubiera
   puesto por defecto. */
.attachment-group .custom-file-label::after {
    top: 1px;
    right: 0;
    bottom: 1px;
    height: auto;
    background: #F0F5FF;
    color: #4C7EDB;
}
/* El boton "+ Add More" (.bt-btn--soft) trae borde azul suave (#CFE0FF)
   por defecto en TODO el tema; aqui, pegado al custom-file via el
   margin-left:-1px nativo de .input-group-append, ese azul contra el
   borde neutro (var(--bt-border)) del custom-file se leia como una
   costura partida en dos colores. Se neutraliza SOLO en este contexto
   (no se toca la regla global .bt-btn--soft) para que ambos controles se
   lean como una sola pieza. */
.attachment-group .input-group-append .bt-btn.bt-btn--soft { border-color: var(--bt-border); }
.attachment-group .input-group-append .bt-btn.bt-btn--soft:hover { border-color: #A9C6FF; }

/* Texto de extensiones/tamano permitido, hoy pegado justo debajo del
   input-group sin respiro. */
.bt-tv-replybox .text-muted > small {
    display: block;
    margin-top: 8px;
    font-size: 12px;
    color: var(--bt-text-3);
}

/* ---- CC recipients (destinatarios en copia), pedido del dueno
   2026-07-31 — portado de lagom2, viewticket.tpl no trae markup nativo en
   twenty-one (solo el JS, ver contrato en viewticket.tpl). Mismo lenguaje
   visual que .bt-tv-facts/.list-group ya usado en .bt-more-card-body. ---- */
.bt-tv-cc { margin-bottom: 20px; }
.bt-tv-cc-empty { margin: 10px 0 0; font-size: 13px; color: var(--bt-text-3); }
.bt-tv-cc-list { margin-top: 10px; }
.bt-tv-cc-list:empty { margin-top: 0; }
.bt-tv-cc-item {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-sm);
    margin-bottom: 6px;
}
.bt-tv-cc-item:last-child { margin-bottom: 0; }
.bt-tv-cc-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
}
.bt-tv-cc-email-text {
    font-size: 13.5px;
    color: var(--bt-text-2);
    overflow-wrap: break-word;
}
/* Boton de quitar, icono solo — color explicito en reposo y hover (misma
   disciplina de landmine 5.3 aunque sea un <button>, no un <a>). */
.bt-tv-cc-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 22px;
    height: 22px;
    padding: 0;
    background: none;
    border: none;
    color: var(--bt-text-3);
    cursor: pointer;
}
.bt-tv-cc-remove svg { width: 14px; height: 14px; }
.bt-tv-cc-remove:hover { color: var(--bt-red); }
/* Alta en linea: input + boton en la misma fila (form propio, sin
   .bt-form-row del formulario de respuesta de mas abajo). */
.bt-tv-cc-add {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}
.bt-tv-cc-add .form-control { flex: 1 1 auto; min-width: 0; }
.bt-tv-cc-add .bt-btn { flex: none; }

/* ---- Panel de pestanas Responder/CC/Adjuntos (pedido del dueno
   2026-07-31, "mejor que lagom"): antes .bt-tv-replybox y .bt-tv-cc eran
   2 .bt-card separadas, ahora conviven como .tab-pane dentro de UNA sola
   .bt-card (.bt-tv-tabs-panel) con .bt-tv-tabnav arriba. El switch entre
   panes lo maneja Bootstrap 4 del padre via [data-toggle="tab"] (ya
   cargado, cero JS propio anadido) — aqui solo se reestila la barra y los
   badges con los tokens del tema (azul #4C7EDB/#CFE0FF/#F0F5FF, gris
   #757B87 ya usados en el resto del archivo). Sin !important: se apoya en
   que estas reglas van DESPUES de Bootstrap en el cascade, mismo patron
   que .bt-tv-cc-item sobre .list-group-item mas arriba. ---- */
.bt-tv-tabnav {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    /* Movil (375px): "Adjuntos [N]" no cabe (medido en vivo, right:385px)
       -- con flex-wrap:nowrap + overflow-x:auto la barra se desplaza en
       vez de cortarse. Scrollbar oculta via scrollbar-width/::-webkit-
       scrollbar de abajo, desktop no cambia (nunca desborda su ancho). */
    gap: 4px;
    margin: 0 0 20px;
    padding: 0;
    border-bottom: 1px solid var(--bt-border);
    list-style: none;
    scrollbar-width: none;
}
.bt-tv-tabnav::-webkit-scrollbar { display: none; }
.bt-tv-tabnav .nav-item { flex: none; }
.bt-tv-tabnav .nav-link {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 10px 14px;
    font-size: 14px;
    font-weight: 500;
    color: #757B87;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: var(--bt-radius-sm) var(--bt-radius-sm) 0 0;
    white-space: nowrap;
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease;
}
.bt-tv-tabnav .nav-link:hover { color: var(--bt-text); background: #F7F8FA; text-decoration: none; }
.bt-tv-tabnav .nav-link.active {
    color: #4C7EDB;
    background: #F0F5FF;
    border-bottom-color: #4C7EDB;
}
.bt-tv-tabnav .nav-link.active:hover { background: #F0F5FF; }
@media (max-width: 480px) {
    .bt-tv-tabnav .nav-link { padding: 10px 10px; font-size: 13px; }
}
/* Badge de conteo (CC/Adjuntos): pastilla tenue en 0, azul suave activo
   (mismo lenguaje que .bt-dm-pill/.bt-notif-ico, ver cabecera de este
   archivo), nunca llamativo cuando esta en cero. */
.bt-tv-tab-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    color: #A6ACB6;
    background: #EDEFF2;
}
.bt-tv-tab-badge--active { color: #4C7EDB; background: #CFE0FF; }

/* ---- Pestana Adjuntos (nueva, tab-pane .bt-tv-tab-attachments-*): lista
   de $btTvAttachments (contrato con hooks-src/banatheme_viewticket.php),
   mismo lenguaje visual que .bt-tv-cc-item (list-group + item propio,
   borde suave, radio del tema). ---- */
.bt-tv-tab-attlist { margin: 0; padding: 0; list-style: none; }
.bt-tv-tab-attitem {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-sm);
    margin-bottom: 6px;
}
.bt-tv-tab-attitem:last-child { margin-bottom: 0; }
.bt-tv-tab-atticon { flex: none; width: 15px; height: 15px; color: #757B87; }
.bt-tv-tab-attname {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13.5px;
    color: var(--bt-text-2);
    overflow-wrap: break-word;
}
.bt-tv-tab-attdl {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 26px;
    height: 26px;
    color: #4C7EDB;
    border-radius: var(--bt-radius-sm);
}
.bt-tv-tab-attdl svg { width: 15px; height: 15px; }
.bt-tv-tab-attdl:hover { background: #F0F5FF; text-decoration: none; }
.bt-tv-tab-att-empty { margin: 10px 0 0; font-size: 13px; color: var(--bt-text-3); }

/* ---- Pildora de estado con color/nombre real de tblticketstatuses
   (pedido del dueno 2026-07-31, item 3). El color YA viene VALIDADO por
   regex hex estricta en hooks-src/banatheme_viewticket.php (nunca deriva
   de un string libre) antes de llegar aqui como variable CSS --bt-tv-st;
   esta clase generica solo la consume via currentColor, mismo patron que
   .bt-dm-pill--{modifier} ya globales (ver .bt-dm-pill mas arriba en esta
   hoja). Solo se aplica cuando el hook resolvio un color valido — el
   fallback whitelist .bt-dm-pill--tk-{class} de siempre sigue intacto en
   la plantilla cuando no hay color. ---- */
.bt-dm-pill--tk-custom { color: var(--bt-tv-st, var(--bt-text-2)); }

/* ---- Resumen imprimible (pedido del dueno 2026-07-31, item 2): oculto en
   pantalla (utilidad d-none del padre), visible solo con @media print
   (utilidad d-print-block del padre, mismo par que .d-print-none ya usado
   en este archivo). Solo layout de la tabla; el toggle de visibilidad NO
   es cosa nuestra, lo da Bootstrap. ---- */
.bt-tv-print-title { font-size: 16px; font-weight: 600; margin: 0 0 10px; }
.bt-tv-print-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.bt-tv-print-table th,
.bt-tv-print-table td {
    text-align: left;
    padding: 4px 10px 4px 0;
    vertical-align: top;
}
.bt-tv-print-table th { width: 140px; font-weight: 600; white-space: nowrap; }

/* ---- Tarjeta de identidad del solicitante en el form de Reply (pedido
   del dueno 2026-07-31, item 5): sustituye los 2 inputs Name/Email
   deshabilitados cuando $loggedin. Icono + nombre/email en gris
   secundario, mismo lenguaje visual que .bt-tv-fact-value. ---- */
.bt-tv-identity {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    background: var(--bt-surface-2, #F7F8FA);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-sm);
}
.bt-tv-identity-icon {
    flex: none;
    width: 20px;
    height: 20px;
    color: var(--bt-text-3);
}
.bt-tv-identity-info { display: flex; flex-direction: column; min-width: 0; }
.bt-tv-identity-name { font-size: 13.5px; font-weight: 500; color: var(--bt-text); }
.bt-tv-identity-email { font-size: 12.5px; color: var(--bt-text-3); overflow-wrap: break-word; }

/* ============================================================
   3) Abrir Ticket (.bt-ts) — paso 1 (tiles de departamento), paso 2
   (formulario), confirmacion y sugerencias de KB.
   ============================================================ */
/* Sin tope de ancho: el card llena el area de contenido como el resto de
   paginas del tema. El cap de 900px lo dejaba "chico en medio" en pantallas
   anchas (pedido del dueno 2026-07-31). */
.bt-ts-card { max-width: none; margin: 0; }
.bt-ts-head { margin-bottom: 22px; }
.bt-ts-title { font-size: 20px; font-weight: 300; margin: 0 0 4px; color: var(--bt-text); }
.bt-ts-sub { font-size: 13.5px; color: var(--bt-text-3); margin: 0; }

/* Tiles de departamento — mismo lenguaje visual que .bt-dd-qcard (Domain
   Details), prefijo bt-ts- propio de esta pagina. */
.bt-ts-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 16px;
}
.bt-ts-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 20px 18px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    text-decoration: none;
    transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.bt-ts-tile:hover {
    border-color: #CFE0FF;
    box-shadow: var(--bt-shadow);
    transform: translateY(-3px);
    text-decoration: none;
}
.bt-ts-tile-ic {
    width: 42px;
    height: 42px;
    border-radius: 12px;
    background: rgba(16, 98, 254, .1);
    color: var(--bt-primary);
    display: grid;
    place-items: center;
    font-size: 17px;
}
.bt-ts-tile-t { font-size: 14.5px; font-weight: 500; color: var(--bt-text); }
.bt-ts-tile-d { font-size: 12px; color: var(--bt-text-3); line-height: 1.4; }

/* Confirmacion (paso 3) */
.bt-ts-confirm-box {
    text-align: center;
    padding: 16px;
    border-radius: var(--bt-radius-sm);
    background: rgba(23, 178, 106, .1);
    color: #0A7A5C;
    margin-bottom: 16px;
}
.bt-ts-confirm-box .alert-link { color: #0A7A5C; text-decoration: underline; }
.bt-ts-confirm-desc { text-align: center; color: var(--bt-text-2); }

/* Sugerencias de base de conocimiento */
.bt-ts-kblist { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.bt-ts-kbitem {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 10px 14px;
    border: 1px solid var(--bt-border);
    border-radius: 8px;
    text-decoration: none;
    color: var(--bt-text);
}
.bt-ts-kbitem:hover { border-color: #CFE0FF; background: #F7FAFF; text-decoration: none; }
.bt-ts-kbitem-t { font-weight: 500; }
.bt-ts-kbitem-d { color: var(--bt-text-3); }

/* ===== BT SECTION: SWITCH ACCOUNT ===== */

/* Re-skin de "Choose Account" (user-switch-account.tpl). Reusa .bt-card y
   .bt-page-title (definidos arriba en "BT SECTION: CUENTA"); el grupo
   :has() que oculta el sidebar contextual para .bt-switch-account ya se
   agrego junto al de .bt-profile/.bt-security/.bt-password/
   .bt-security-legacy (mismo archivo, seccion "Ocultar sidebar
   contextual"), no se duplica aqui. Caso con 0/1 cuenta auto-envia o
   muestra un aviso corto; caso 2+ cuentas (los 1.343 clientes con
   multi-cuenta legado) muestra la lista completa restilada abajo. */
.bt-switch-account {
    max-width: 540px;
    margin: 0 auto;
}
/* .bt-swacct-card: mismo .bt-card compartido, este selector solo fija el
   ancho maximo del contenido interno (evita que el "Entrando..." de una
   sola linea quede demasiado ancho en pantallas grandes). */
.bt-swacct-card {
    text-align: left;
}
.bt-swacct-msg {
    font-size: 14px;
    font-weight: 300;
    color: #4A5160;
    margin: 0 0 16px;
}
.bt-swacct-msg:last-of-type { margin-bottom: 20px; }

/* Lista de cuentas: filas seleccionables, mismo lenguaje visual que
   .bt-dm-item (borde inferior + hover suave) pero sin heredar su grid de
   columnas (esta lista no tiene las mismas columnas que dominios/facturas). */
.bt-swacct-list {
    display: flex;
    flex-direction: column;
}
.bt-swacct-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 4px;
    border-bottom: 1px solid var(--bt-border);
    text-decoration: none;
    color: var(--bt-text);
}
.bt-swacct-item:last-child { border-bottom: none; }
.bt-swacct-item:hover { background: rgba(16, 24, 40, .025); text-decoration: none; color: var(--bt-text); }
/* Solo tratamiento visual (paridad con el nativo: opacity .5, SIN
   pointer-events:none) — una cuenta Closed SIGUE siendo clicable, es el
   servidor quien decide que hacer con ella (p.ej. pagar la ultima
   factura). La guarda ":not(.disabled)" del auto-envio (mas abajo) ya
   impide que el AUTO-click caiga en una cuenta cerrada; el click humano
   debe seguir funcionando igual que en el nativo. */
.bt-swacct-item.disabled {
    opacity: .5;
}
.bt-swacct-name { font-size: 14px; font-weight: 400; }
.bt-swacct-owner, .bt-swacct-status { flex-shrink: 0; }

/* ---- Anti-parpadeo del caso "1 sola cuenta" (mejora progresiva): con JS,
   el bloque nace oculto y solo se ve "Entrando..."/"Signing in..." mientras
   se dispara el auto-envio; si el auto-envio se abstiene (ver tpl: alerta
   nativa pendiente, cuenta Closed o sessionStorage no funcional) el propio
   JS quita ".bt-swacct-single" y se revela el selector manual normal. Sin
   JS, el <noscript><style> del .tpl neutraliza estas reglas y se ve el
   selector manual desde el primer render (paridad con el nativo). ---- */
.bt-swacct-entering { display: none; }
.bt-swacct-single .bt-swacct-entering { display: block; }
.bt-swacct-single .bt-swacct-intro,
.bt-swacct-single .bt-swacct-list {
    display: none;
}

/* ===== BT SECTION: PAYMENT METHODS ===== */
/* ============================================================
   Cuenta > Metodos de pago (account-paymentmethods.tpl/-manage.tpl/
   -billing-contacts.tpl, wrapper .bt-paymentmethods, sub-nav bt-actabs).
   El listado reusa el patron de filas .bt-dm-* ya usado en dominios/
   servicios/facturas (ver esas secciones para el resto de clases
   compartidas: .bt-dm-list/.bt-dm-item/.bt-dm-idcol/.bt-dm-dom/
   .bt-dm-sub/.bt-dm-statcol/.bt-dm-pill/.bt-dm-actions/.bt-dm-managebtn);
   aqui solo van los complementos especificos de esta pagina. El
   formulario de anadir/editar tarjeta se deja con el markup Bootstrap
   nativo casi intacto (contrato de datos de pago, ver comentario en el
   .tpl) — ya hereda un look razonable de .bt-body .card/.form-control/
   label definidos mas arriba en este archivo, sin tocar el markup. ============================================================ */

.bt-pm-intro {
    color: var(--bt-text-2);
    font-size: 13.5px;
    margin: 0 0 16px;
}

.bt-pm-addrow {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 20px;
}

/* Fila de metodo de pago: [glob][nombre+descripcion][estado][acciones],
   mismo patron que .bt-services/.bt-invoices .bt-dm-item (grid propio por
   pagina, ver comentario general en la seccion de dominios). Lista
   normalmente corta (pocas tarjetas/cuentas), asi que la columna de
   acciones lleva piso generoso para 3 botones (Set Default/Edit/Delete)
   sin que se amontonen. */
.bt-paymentmethods .bt-dm-item {
    grid-template-columns: auto minmax(0, 2fr) minmax(120px, 1fr) minmax(230px, auto);
}

/* .bt-dm-managebtn.disabled: el nativo usaba las clases de Bootstrap
   "btn btn-sm btn-default disabled" (bootstrap apaga pointer-events/baja
   opacidad via su propio .disabled); al pasar estos enlaces a
   .bt-dm-managebtn (sin "btn") se pierde ese comportamiento, asi que se
   repone aqui explicito para Set Default (ya por defecto/expirado) y
   Edit (RemoteBankAccount no editable) — mismo criterio (visual + no
   clicable) que tenia el boton nativo. */
.bt-dm-managebtn.disabled {
    opacity: .5;
    pointer-events: none;
    cursor: default;
}

/* Fix de especificidad pre-existente descubierto al reusar .bt-dm-managebtn
   aqui (afecta tambien a dominios/servicios/facturas/tickets, que ya usan
   este boton): ".bt-dm-managebtn" es una sola clase (0,1,0), y ".bt-body a"
   (0,1,1, arriba del todo en este archivo) tiene MAS especificidad, asi
   que le gana y pinta el boton "Manage"/"Gestionar" en azul solido
   var(--bt-primary) en vez del azul sutil #4C7EDB que la propia regla
   .bt-dm-managebtn declara (no es invisible como el bug de .btn-primary,
   pero rompe el diseño "azul sutil" pedido). Mismo patron ya documentado y
   usado en este archivo para .bt-dm-tbtn--primary (especificidad (0,1,1)
   via doble selector ".bt-body a.X"). Reportado al orquestador: este fix
   beneficia a TODAS las paginas que ya usaban .bt-dm-managebtn, no solo a
   esta. */
.bt-body a.bt-dm-managebtn { color: #4C7EDB; }
.bt-body a.bt-dm-managebtn:hover { color: var(--bt-primary); }

/* Fragmento de direcciones de facturacion (account-paymentmethods-
   billing-contacts.tpl, id="innerBillingContactsContainer" con clase
   .bt-pm-billingcontacts anadida SOLO ahi, ver comentario en ese .tpl):
   respiro vertical entre las opciones de direccion, sin tocar el markup
   funcional (radios/iCheck) del fragmento. */
.bt-pm-billingcontacts label.form-check-inline {
    display: block;
    margin: 0 0 10px;
    color: var(--bt-text-2);
    font-size: 13.5px;
}
.bt-pm-billingcontacts label.form-check-inline .name {
    color: var(--bt-text);
    font-weight: 400;
}

/* ===== BT SECTION: MASSPAY ===== */

/* CSS de masspay.tpl (pagar varias facturas de una vez). Reusa tokens/
   clases ya existentes (--bt-primary/--bt-text/--bt-border/--bt-surface/
   --bt-radius-lg/--bt-shadow, .bt-card, .bt-page-title, .bt-card-subtitle)
   — no se redefinen aqui. .bt-card + .bt-card { margin-top: 20px; } ya
   existe (seccion "BT SHARED: FORMS + CARDS + ACCOUNT TABS") y aplica solo
   con que .bt-mp-summary/.bt-mp-list/.bt-mp-gateway sean todas .bt-card
   hermanas directas, que ya lo son en el markup — no hace falta repetir esa
   regla aqui.

   Escala tipografica del proyecto: titulo 20/300 (.bt-page-title, clase ya
   existente, reusada via .bt-mp-title), nombre 15/300 (.bt-mp-inv-num),
   texto secundario 14/300 (.bt-mp-line-desc — no hay fecha/vencimiento en
   $invoiceitems, ver comentario de cabecera de masspay.tpl), importes 500
   (.bt-mp-line-amt/.bt-mp-tval/.bt-mp-total-val). */

/* ---- Cabecera-resumen (patron .bt-dd-summary) ----
   FIX 2026-07-30 (reporte del dueno: "distorsionado"/"carrito pegado al
   borde"): "padding: 4px 0" anulaba el horizontal de .bt-card (24px 28px)
   y dejaba el icono/importe a ~1px del borde de la tarjeta (medido en vivo
   con getBoundingClientRect). Se conserva la intencion vertical compacta
   pero el horizontal vuelve al mismo 28px que usa .bt-card / .bt-mp-list
   (hermana directa, sin override propio) para quedar coherente con el
   resto del panel. */
.bt-mp-summary { padding: 20px 28px 22px; }
.bt-mp-sumtop { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.bt-mp-glob {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: #F0F5FF;
    color: var(--bt-primary);
}
.bt-mp-glob svg { width: 22px; height: 22px; }
.bt-mp-summeta { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bt-mp-title { margin: 0; }
.bt-mp-desc { margin: 0; }
.bt-mp-spacer { flex: 1 1 auto; }
.bt-mp-totalbox { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.bt-mp-total-lbl {
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--bt-text-3);
}
.bt-mp-total-val {
    font-size: 24px;
    font-weight: 500;
    color: var(--bt-primary);
    font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
    .bt-mp-totalbox { align-items: flex-start; }
}

/* ---- Tarjeta lista de facturas ---- */
.bt-mp-listhead {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 16px;
}
.bt-mp-listtitle { font-size: 13px; font-weight: 500; color: var(--bt-text-2); }
.bt-mp-listcount {
    font-size: 12px;
    font-weight: 500;
    color: var(--bt-text-3);
    background: #F3F4F6;
    border-radius: 999px;
    padding: 1px 9px;
}

.bt-mp-invlist { display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px; }
.bt-mp-inv {
    border: 1px solid var(--bt-border);
    border-radius: 8px;
    padding: 14px 16px;
}
.bt-mp-inv-head { display: flex; align-items: center; gap: 10px; }
.bt-mp-inv-ic {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    flex: 0 0 auto;
    border-radius: 6px;
    background: #F3F4F6;
    color: var(--bt-text-3);
}
.bt-mp-inv-ic svg { width: 16px; height: 16px; }
/* nombre 15/300 */
.bt-mp-inv-num { font-size: 15px; font-weight: 300; color: var(--bt-text); }

.bt-mp-lines { margin-top: 8px; padding-left: 38px; display: flex; flex-direction: column; gap: 4px; }
.bt-mp-line { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
/* texto secundario 14/300 (no hay fecha/vencimiento disponibles en
   $invoiceitems, ver nota en masspay.tpl) */
.bt-mp-line-desc { font-size: 14px; font-weight: 300; color: var(--bt-text-2); }
.bt-mp-line-amt {
    font-size: 14px;
    font-weight: 500;
    color: var(--bt-text);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.bt-mp-empty {
    padding: 32px 16px;
    text-align: center;
    color: var(--bt-text-3);
    font-size: 14px;
}

/* ---- Desglose de totales ---- */
.bt-mp-totals {
    border-top: 1px solid var(--bt-border);
    margin-top: 4px;
    padding-top: 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.bt-mp-trow { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.bt-mp-tlbl { font-size: 13px; font-weight: 400; color: var(--bt-text-2); }
.bt-mp-tval {
    font-size: 14px;
    font-weight: 500;
    color: var(--bt-text);
    font-variant-numeric: tabular-nums;
}
.bt-mp-trow--total {
    border-top: 1px solid var(--bt-border);
    padding-top: 10px;
    margin-top: 2px;
}
.bt-mp-trow--total .bt-mp-tlbl { font-size: 14px; font-weight: 500; color: var(--bt-text); }
.bt-mp-trow--total .bt-mp-tval { font-size: 18px; color: var(--bt-primary); }

/* ---- Tarjeta de pasarela: SOLO el wrapper, el interior no se toca ---- */
.bt-mp-gateway { padding: 0; overflow: hidden; }
/* El nativo trae su propio .card/.card-header/.card-body dentro (sin
   tocar), asi que aqui solo se quita el padding del .bt-card exterior para
   que no se dupliquen los bordes/relleno de las dos tarjetas anidadas; el
   .card interior nativo ya trae su propio padding via Bootstrap. */
.bt-mp-gateway .row { margin: 0; }
.bt-mp-gateway .card.bg-default { border: none; box-shadow: none; }

@media (max-width: 640px) {
    .bt-mp-lines { padding-left: 0; }
}

/* ===== BT SECTION: KNOWLEDGEBASE ===== */

/* CSS de knowledgebase.tpl (portada) + knowledgebasecat.tpl (categoria/tag/
   busqueda) + knowledgebasearticle.tpl (articulo). Las 3 comparten el
   wrapper .bt-kb (gancho :has() para ocultar el sidebar contextual, ya
   agrupado arriba junto a .bt-invoices/.bt-tickets/.bt-tv/.bt-ts/
   .bt-masspay) y el mismo prefijo de clase .bt-kb-*. Reusa tokens/patrones
   ya existentes: .bt-card/.bt-btn/.bt-btn--soft, --bt-*, azul sutil
   #4C7EDB de enlaces de tarjeta (mismo valor que .bt-dm-dom/.bt-pd
   secondary), .bt-page-title/.bt-card-title para la escala tipografica.

   Motivo del reporte visual original: sidebar contextual descuadraba el
   layout, tarjetas de categoria desalineadas (altura distinta con/sin
   descripcion), badges azules solidos ajenos al tema, buscador nativo con
   boton cuadrado, titulos en azul primario brillante (heredado de
   .bt-body a) en vez del azul sutil de tarjeta, "Most Popular" con lista
   nativa e iconos genericos. Este bloque corrige los 7 puntos. */

.bt-kb svg { width: 1em; height: 1em; display: block; }
.bt-kb * { box-sizing: border-box; }
.bt-kb { padding: 24px 0 30px; }
@media (max-width: 820px) { .bt-kb { padding: 12px 0 20px; } }

/* ---- Breadcrumb (knowledgebasecat.tpl / knowledgebasearticle.tpl): mismo
   lenguaje que .bt-dd-crumb/.bt-pd-crumb (Domain/Product Details). ---- */
.bt-kb-crumb {
    font-size: 12.5px;
    color: var(--bt-text-3);
    margin: 0 0 16px;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.bt-kb-crumb a { color: var(--bt-text-3); text-decoration: none; }
.bt-kb-crumb a:hover { color: var(--bt-primary); text-decoration: none; }
.bt-kb-crumb-sep { color: var(--bt-text-3); }
.bt-kb-crumb-cur { color: var(--bt-text); }

/* ---- Buscador destacado: input 46px, radio 10px, foco azul con
   box-shadow, boton .bt-btn — reemplaza el input-group nativo con boton
   azul cuadrado. Form/name/id VERBATIM en el .tpl, solo el markup/clases
   alrededor cambia. ---- */
.bt-kb-search {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 26px;
}
.bt-kb-search-i {
    position: absolute;
    left: 16px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--bt-text-3);
    font-size: 16px;
    pointer-events: none;
}
.bt-kb-search-input {
    flex: 1 1 auto;
    height: 46px;
    min-width: 0;
    padding: 0 16px 0 42px;
    font-family: var(--bt-font);
    font-size: 14.5px;
    font-weight: 300;
    color: var(--bt-text);
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 10px;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.bt-kb-search-input:focus {
    outline: none;
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 .2rem rgba(16, 98, 254, .16);
}
/* FIX 2026-07-30 original (reporte del dueno, verificado en vivo con
   getComputedStyle: background rgb(239,239,239)/color negro = boton de
   sistema del navegador): .bt-kb-search NO es .bt-form ni .bt-card, y en
   ese momento la base ".bt-btn" no traia background/color propios. Ya
   NO hace falta el parche de color aqui — la base ".bt-btn" ahora es
   autosuficiente (ver "BT SHARED: FORMS + CARDS + ACCOUNT TABS"), este
   boton es un <button> asi que le llega directo. Solo queda el layout. */
.bt-kb-search-btn { height: 46px; padding: 0 24px; flex: 0 0 auto; }
@media (max-width: 480px) {
    .bt-kb-search { flex-wrap: wrap; }
    .bt-kb-search-input { flex: 1 1 100%; }
    .bt-kb-search-btn { flex: 1 1 100%; }
}

/* ---- Rejilla de categorias: tarjetas uniformes, alto homogeneo aunque
   una traiga descripcion y otra no (columna flex + pie con margin-top:auto
   en vez del .row/.col-xl-6 de Bootstrap del nativo, que dejaba huecos
   irregulares). auto-fill/minmax reparte tantas columnas como quepan sin
   depender de breakpoints fijos. ---- */
.bt-kb-cats {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 18px;
    margin-bottom: 28px;
}
.bt-kb-cat {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 20px 22px;
    color: inherit;
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.bt-kb-cat:hover {
    border-color: var(--bt-primary);
    box-shadow: 0 10px 26px rgba(16, 24, 40, .10);
    text-decoration: none;
    color: inherit;
}
.bt-kb-cat-head {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
}
/* "no tan azul" (pedido del dueno): cuadro del icono neutro (gris muy
   claro), icono en gris/azul apagado -- ya NO el azul saturado #E8EEFF/
   var(--bt-primary) de antes. */
.bt-kb-cat-ic {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border-radius: 10px;
    background: #EEF1F6;
    color: #757B87;
    font-size: 18px;
}
/* Titulo en gris oscuro sobrio en reposo; el azul de marca solo aparece al
   pasar el mouse por la tarjeta (.bt-kb-cat:hover), no de entrada. */
.bt-kb-cat-name {
    font-size: 15.5px;
    font-weight: 500;
    color: #2A2F3A;
    line-height: 1.3;
    min-width: 0;
    transition: color .15s ease;
}
.bt-kb-cat:hover .bt-kb-cat-name {
    color: #4C7EDB;
}
.bt-kb-cat-desc {
    font-size: 13px;
    font-weight: 300;
    color: var(--bt-text-2);
    line-height: 1.5;
    margin: 0 0 10px;
    flex: 1 1 auto;
}
.bt-kb-cat-foot {
    margin-top: auto;
    padding-top: 6px;
}
/* Conteo como texto discreto (gris de labels), NO badge solido azul. */
.bt-kb-cat-count {
    font-size: 12px;
    font-weight: 400;
    color: var(--bt-text-3);
}
/* Boton "Editar" de staff (editLink): oculto hasta hover de la tarjeta,
   igual espiritu que show-on-card-hover del nativo. */
.bt-kb-editbtn {
    height: 26px;
    padding: 0 10px;
    font-size: 11px;
    border-radius: 999px;
    margin-left: auto;
    flex: 0 0 auto;
    opacity: 0;
    transition: opacity .15s ease;
}
.bt-kb-cat:hover .bt-kb-editbtn,
.bt-kb-item:hover .bt-kb-editbtn { opacity: 1; }

/* ---- "Most Popular"/"Related": lista de filas limpias, mismo espiritu
   que .bt-dm-item (borde inferior + hover suave) pero mas simple (sin
   grid de columnas, esta lista no tiene datos tabulares). ---- */
.bt-kb-popular-title {
    display: flex;
    align-items: center;
    gap: 10px;
}
.bt-kb-popular-ic { color: var(--bt-text-3); font-size: 16px; }
.bt-kb-list { display: flex; flex-direction: column; }
.bt-kb-item {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 14px 4px;
    border-bottom: 1px solid var(--bt-border);
    color: inherit;
    text-decoration: none;
    transition: background .15s;
}
.bt-kb-item:last-child { border-bottom: none; }
.bt-kb-item:hover {
    background: rgba(16, 24, 40, .025);
    text-decoration: none;
    color: inherit;
}
.bt-kb-item-ic {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex: 0 0 auto;
    border-radius: 9px;
    background: #F1F2F6;
    color: var(--bt-text-3);
    font-size: 15px;
}
.bt-kb-item-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.bt-kb-item-title {
    display: flex;
    align-items: center;
    font-size: 14px;
    font-weight: 500;
    color: #4C7EDB;
    line-height: 1.3;
}
.bt-kb-item-excerpt {
    font-size: 12.5px;
    font-weight: 300;
    color: var(--bt-text-2);
    line-height: 1.4;
}
.bt-kb-empty {
    padding: 24px 4px;
    text-align: center;
    color: var(--bt-text-3);
    font-size: 13.5px;
}

/* ---- knowledgebasearticle.tpl: cabecera + meta + cuerpo legible ---- */
.bt-kb-article-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 4px;
}
.bt-kb-article-title { font-size: 20px; font-weight: 300; color: var(--bt-text); margin: 0; }
.bt-kb-printbtn { flex: 0 0 auto; }
.bt-kb-article-meta {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin: 14px 0 20px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--bt-border);
}
.bt-kb-tagpill {
    display: inline-flex;
    align-items: center;
    height: 24px;
    padding: 0 12px;
    border-radius: 999px;
    background: #F0F5FF;
    color: #4C7EDB;
    font-size: 12px;
    font-weight: 500;
}
.bt-kb-useful {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--bt-text-3);
}
/* Cuerpo del articulo: HTML del admin, se imprime tal cual (ver
   RESTRICCION ABSOLUTA en el .tpl) — aqui solo se acota ancho de lectura y
   se ajusta tipografia/espaciado de los elementos hijos que ese HTML pueda
   traer, sin tocar el contenido en si. */
.bt-kb-body {
    max-width: 72ch;
    font-size: 14.5px;
    font-weight: 300;
    line-height: 1.7;
    color: var(--bt-text);
}
.bt-kb-body :first-child { margin-top: 0; }
.bt-kb-body :last-child { margin-bottom: 0; }
.bt-kb-body p { margin: 0 0 16px; }
.bt-kb-body h1, .bt-kb-body h2, .bt-kb-body h3, .bt-kb-body h4 {
    font-weight: 500;
    color: var(--bt-text);
    margin: 24px 0 12px;
}
.bt-kb-body ul, .bt-kb-body ol { margin: 0 0 16px; padding-left: 22px; }
.bt-kb-body li { margin-bottom: 6px; }
.bt-kb-body img { max-width: 100%; height: auto; border-radius: 8px; }
.bt-kb-body pre, .bt-kb-body code {
    font-size: 13px;
    background: #F3F4F6;
    border-radius: 6px;
}
.bt-kb-body pre { padding: 14px 16px; overflow-x: auto; }
.bt-kb-body code { padding: 2px 6px; }
.bt-kb-body table { width: 100%; border-collapse: collapse; margin: 0 0 16px; font-size: 13.5px; }
.bt-kb-body table th, .bt-kb-body table td { border: 1px solid var(--bt-border); padding: 8px 10px; text-align: left; }

/* ---- Voto de utilidad: form nativo VERBATIM, solo restilizado ---- */
.bt-kb-vote { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--bt-border); }
.bt-kb-vote-title { font-size: 14px; font-weight: 500; color: var(--bt-text); margin: 0 0 14px; }
.bt-kb-vote-btns { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---- Pie: volver / editar (staff) ---- */
.bt-kb-foot { display: flex; align-items: center; gap: 12px; margin-top: 6px; }
.bt-kb-foot-edit { margin-left: auto; }

@media (max-width: 620px) {
    .bt-kb-article-head { flex-direction: column; align-items: stretch; }
    .bt-kb-vote-btns .bt-btn { flex: 1 1 auto; justify-content: center; }
}

/* ===== BT SECTION: QUOTES+EMAILS+AFFILIATES — complementos sin
   precedente exacto (fusionado desde staging, 2026-07-30) =====
   El resto de la fusion de presupuestos/emails/afiliados fue a los grupos
   compartidos ya existentes mas arriba (sidebar :has(), grid de columnas,
   pildoras --qt-*, .bt-dm-title h1/h2); aqui solo quedan los 3 puntos
   sin un bloque equivalente al que sumarse. */

/* El bloque de "Tus referidos" en affiliates.tpl NO esta envuelto en un
   .bt-dm de pagina completa (va anidado dentro de una tarjeta .bt-af-card
   existente), asi que no hereda el reset ".bt-dm svg { width:1em;
   height:1em; display:block }" / ".bt-dm * { box-sizing:border-box }" que
   SI tienen las paginas de lista completas. Sin esto los <svg> de
   cabecera/fila (icono de seccion + lupa del buscador) quedarian con el
   tamano intrinseco del navegador (enorme) y el grid de
   .bt-af-referrals .bt-dm-item podria desbordar por el box-sizing por
   defecto (content-box). Mismo reset pero scopeado a .bt-af-referrals. */
.bt-af-referrals svg { width: 1em; height: 1em; display: block; }
.bt-af-referrals * { box-sizing: border-box; }

/* Icono de clip (adjunto) en la fila de emails, mismo criterio de tamano
   que el precedente ya existente .bt-tv-attachments svg (adjuntos de un
   ticket). */
.bt-em-clip { display: inline-flex; margin-left: 6px; color: var(--bt-text-3); vertical-align: -2px; }
.bt-em-clip svg { width: 14px; height: 14px; }

/* El form de descarga nativo de presupuestos (dl.php, VERBATIM) queda
   dentro de .bt-dm-actions (flex row, gap 8px, ya global) junto al boton
   "Ver": un <form> es display:block por defecto y necesita quedar en
   linea con el boton hermano dentro de ese flex row. Y .bt-dm-managebtn
   nunca se habia usado antes sobre un <button> (solo sobre <a> en el
   resto del tema, ver account-paymentmethods.tpl) — se normaliza
   appearance/cursor para que un <button type="submit">/<button
   type="button"> con esta clase se vea IDENTICO al <a> ya estilado (sin
   el chrome nativo del navegador por debajo). */
.bt-qt-dlform { display: inline-flex; margin: 0; }
button.bt-dm-managebtn {
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    font-family: var(--bt-font);
}
/* ===== END BT SECTION: QUOTES+EMAILS+AFFILIATES ===== */

/* ===== BT SECTION: VIEWINVOICE (fusionado desde staging, 2026-07-30) =====
   Re-skin de viewinvoice.tpl (Ver factura). Reusa integramente los
   tokens --bt-* y los componentes ya globales (.bt-card, .bt-page-title,
   .bt-dm-pill/--{modifier}) definidos arriba en banatheme.css; aqui solo
   van los complementos especificos de esta pagina (prefijo bt-iv-,
   exclusivo, sin colisionar con .bt-invoices de clientareainvoices.tpl ni
   con .bt-dd-/.bt-mp- de las otras paginas).

   viewinvoice.tpl es standalone (no pasa por header.tpl, <body> no lleva
   la clase de shell habitual) — <body class="bt-body"> ya trae de arriba
   en este archivo la tipografia base y el fix de contraste de
   .btn-primary/.btn-default (evita texto invisible sobre fondo del mismo
   color, mismo problema ya resuelto para Payment Methods). Esas reglas
   son (0,1,1)/(0,2,0) y alcanzan tambien el boton de pago real
   ($paymentbutton) SIN tocar su HTML. */

.bt-invoice {
    max-width: 900px;
    margin: 32px auto;
    padding: 0 16px;
}
@media (max-width: 599px) {
    .bt-invoice { margin: 16px auto; }
}

.bt-invoice .bt-iv-alerts:empty { display: none; }
.bt-invoice .bt-iv-alerts { margin-bottom: 20px; }

/* ---- Cabecera-resumen (patron .bt-dd-summary / .bt-mp-summary) ---- */
.bt-invoice .bt-iv-summary { padding: 24px 28px; }

.bt-iv-sumtop {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}
.bt-iv-glob {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--bt-radius-md);
    background: rgba(16, 98, 254, .08);
    color: var(--bt-primary);
}
.bt-iv-glob svg { width: 20px; height: 20px; }

.bt-iv-summeta { min-width: 0; }
.bt-iv-logo { max-height: 32px; max-width: 220px; display: block; margin-bottom: 6px; }
.bt-iv-company {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: var(--bt-text-2);
    margin-bottom: 4px;
}
.bt-iv-title {
    margin: 0 0 8px;
    word-break: break-word;
}
/* $pagetitle ya trae el numero de factura embebido por el core (incluido
   el bug de idioma preexistente, ver comentario del tpl) — no se le
   agrega ni quita texto aqui, solo tipografia. */

.bt-iv-spacer { flex: 1 1 auto; min-width: 12px; }

.bt-iv-totalbox {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    text-align: right;
}
.bt-iv-total-lbl {
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--bt-text-3);
    margin-bottom: 4px;
}
.bt-iv-total-val {
    font-size: 24px;
    font-weight: 500;
    color: var(--bt-text);
}
/* Total secundario cuando el numero grande pasa a ser el balance parcial
   (fix 2026-07-30), mismo tono discreto que .bt-iv-total-lbl pero sin
   mayusculas (es un dato, no una etiqueta). */
.bt-iv-total-sub {
    display: block;
    font-size: 12px;
    color: var(--bt-text-3);
    margin-top: 4px;
}

.bt-iv-sumfacts {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--bt-border);
}
@media (max-width: 640px) {
    .bt-iv-sumfacts { grid-template-columns: repeat(2, 1fr); }
}
.bt-iv-fact { display: flex; flex-direction: column; gap: 3px; }
.bt-iv-lbl {
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--bt-text-3);
}
.bt-iv-val { font-size: 14px; color: var(--bt-text); }

.bt-iv-paycta { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--bt-border); }

/* ---- Grid de tarjetas: facturar a / datos del cliente / metodo de pago --- */
.bt-iv-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    margin-top: 20px;
}
@media (max-width: 860px) {
    .bt-iv-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 599px) {
    .bt-iv-grid { grid-template-columns: 1fr; }
}
.bt-invoice .bt-iv-card { padding: 20px 22px; }
.bt-iv-address {
    font-style: normal;
    font-size: 13.5px;
    line-height: 1.7;
    color: var(--bt-text-2);
}
.bt-iv-paymethod { font-size: 13.5px; color: var(--bt-text-2); }
.bt-iv-card .form-inline { flex-wrap: wrap; }
.bt-iv-card .custom-select { max-width: 100%; }
/* FIX 2026-07-30 (gate de seguridad): el wrapper nativo <span data-role=
   "paymethod-info"> se restauro tal cual (algun modulo de pasarela/hook
   podria depender de ese selector). small-text/float-sm-right venian
   pensadas para el layout de columnas Bootstrap del nativo — aqui el
   metodo de pago vive dentro de una tarjeta .bt-iv-card de ancho fijo, asi
   que se neutralizan SOLO por CSS (float:none, tamano heredado) sin tocar
   el HTML verbatim. */
.bt-iv-card [data-role="paymethod-info"] {
    display: block;
    float: none;
    font-size: inherit;
}

/* ---- Tarjetas de tabla (lineas de factura / transacciones) ---- */
.bt-invoice .bt-iv-items,
.bt-invoice .bt-iv-transactions { padding: 20px 22px; margin-top: 20px; }

.bt-iv-table { width: 100%; margin: 12px 0 0; border-collapse: collapse; }
.bt-iv-table thead td {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--bt-text-3);
    border: 0;
    border-bottom: 1px solid var(--bt-border);
    padding: 0 8px 8px;
}
.bt-iv-table tbody td {
    font-size: 13.5px;
    color: var(--bt-text);
    border: 0;
    border-bottom: 1px solid var(--bt-border);
    padding: 10px 8px;
}
.bt-iv-table tbody tr:last-child td { border-bottom: 0; }
.bt-iv-table td.text-right { text-align: right; }
/* .total-row: se pisa el fondo gris plano del invoice.min.css nativo por
   una fila mas discreta, alineada al lenguaje del tema (sin cambiar el
   valor/orden de la fila, solo su fondo/tipografia). */
.bt-iv-table td.total-row {
    background: transparent;
    font-weight: 400;
}
.bt-iv-trow--total td.total-row {
    border-top: 1px solid var(--bt-border);
    border-bottom: 0;
    font-size: 15px;
    font-weight: 500;
    color: var(--bt-text);
    padding-top: 14px;
}

.bt-iv-taxnote { font-size: 12px; color: var(--bt-text-3); margin: 10px 4px 0; }

/* .bt-dm-pill--cancelled global es rojo (pensado para dominios); en
   clientareainvoices.tpl se pisa a gris con ".bt-invoices .bt-dm-pill--
   cancelled" — aqui el wrapper es .bt-invoice (singular), asi que se
   replica el mismo pisado con el selector propio de esta pagina. */
.bt-invoice .bt-dm-pill--cancelled { color: #757B87; }

/* ---- Toolbar final (imprimir/descargar, contenido VERBATIM) ---- */
.bt-iv-toolbar { overflow: hidden; margin-top: 20px; }
/* Boton del tema aplicado SOLO por CSS sobre las clases ya presentes en
   el HTML verbatim (btn/btn-default) — especificidad (0,3,0), no se edita
   el <a> del nativo. */
.bt-invoice .bt-iv-toolbar .btn.btn-default,
.bt-invoice .payment-btn-container .btn.btn-default {
    background: var(--bt-surface);
    border-color: var(--bt-border);
    color: var(--bt-text-2);
    font-weight: 700;
    border-radius: var(--bt-radius-sm);
}
.bt-invoice .bt-iv-toolbar .btn.btn-default:hover,
.bt-invoice .payment-btn-container .btn.btn-default:hover {
    background: #F0F5FF;
    color: var(--bt-text);
    border-color: var(--bt-border);
}

.bt-iv-back-wrap { margin-top: 24px; }
/* Boton "Volver": no es parte del flujo de pago (plain <a>, sin
   name/action), se le aplican las clases del tema directamente. */
.bt-invoice .bt-iv-back {
    display: inline-block;
    font-weight: 700;
    border-radius: var(--bt-radius-sm);
    background: var(--bt-surface);
    border-color: var(--bt-border);
    color: var(--bt-text-2);
}
.bt-invoice .bt-iv-back:hover {
    background: #F0F5FF;
    color: var(--bt-text);
    border-color: var(--bt-border);
}

/* ---- Impresion: no pisar .d-print-none/@media print de invoice.min.css,
   solo aplanar el look de tarjeta para que no se corten bordes/sombras
   entre paginas. Los bloques verbatim ya llevan d-print-none propio (boton
   de pago, toolbar imprimir/descargar via los .btn dentro de ese div), asi
   que no hace falta ocultar nada mas aqui. ---- */
@media print {
    .bt-invoice { max-width: none; margin: 0; padding: 0; }
    .bt-invoice .bt-card {
        box-shadow: none;
        border: 1px solid #ccc;
        break-inside: avoid;
    }
}
/* ===== END BT SECTION: VIEWINVOICE ===== */

/* ===== STORE (skin scopeado) =====
   store/ es copia literal de twenty-one: 26 plantillas de entrada (comprar
   SSL, configurar producto, contratar addons) sin ninguna clase bt-*, con
   Bootstrap stock (row/col-*, card, btn, form-control, nav-link, tab-pane)
   y FontAwesome. Reescribir 26 .tpl a mano es fragil (formularios que
   mueven dinero) asi que en vez de eso se reutilizan los selectores UNICOS
   que YA existen en cada plantilla (verificado con grep en todo el repo:
   ninguno se usa fuera de store/) como scope:
     .store-order-container   -> order.tpl (configurar producto)
     .landing-page             -> ssl (todas), marketgoo, nordvpn, ox/index,
                                   sitebuilder/index, sitelock, sitelockvpn,
                                   spamexperts, threesixtymonitoring,
                                   weebly/index, xovinow, cpanelseo,
                                   codeguard (17 plantillas, CERO tpl
                                   tocados)
     .store-promoted-product   -> tarjeta de upsell dentro de order.tpl
     .wp-toolkit                -> addon/wp-toolkit-cpanel.tpl y -plesk.tpl
     .social-bee                -> socialbee/index.tpl
     .sitebuilder-upgrade-container / .weebly-upgrade-container
                                 -> paginas de "upgrade requerido"
     .dynamic-landing-page      -> dynamic/index.tpl (constructor de bloques
                                   promocionales; ya trae su propio
                                   dynamic-store.css, aqui solo alineamos
                                   tipografia/botones)
   (store/ se borro del repo 2026-08-02: eran copias byte a byte del vendor
   que interceptaban los .tpl originales de twenty-one, bloqueando parches
   de seguridad de WHMCS sin aportar nada — theme.yaml declara
   `parent: twenty-one` y el padre las sirve igual. Incluia
   store/ox/manage.tpl, unico .tpl que anadia un wrapper NUEVO propio,
   .bt-store-ox; sus reglas se retiraron de esta seccion junto con el .tpl.)

   .btn/.btn-primary/.card/.form-control YA se theman globalmente via
   ".bt-body .btn" etc. (ver seccion "Botones" arriba, linea ~167) porque
   .bt-body esta en <body> y esas reglas no llevan scope de plantilla: el
   store las hereda sin tocar nada. Lo que SI falta en todo el sitio (ni
   siquiera en .bt-pd-tabwrap) son navs/tabs (.nav-tabs/.nav-link/.tab-pane)
   y .custom-select, que store usa mucho (tabs de dominio, tabs de OX,
   selects de ciclo de facturacion) -> se cubren aqui de forma scopeada. */

.store-order-container .nav-tabs,
.store-order-container .responsive-tabs-sm,
.wp-toolkit .nav-tabs,
.wp-toolkit .responsive-tabs-sm {
    border-bottom-color: var(--bt-border);
}
.store-order-container .nav-link,
.wp-toolkit .nav-link {
    color: var(--bt-text-2);
    font-weight: 700;
    border-radius: var(--bt-radius-sm) var(--bt-radius-sm) 0 0;
}
.store-order-container .nav-link.active,
.wp-toolkit .nav-link.active {
    color: var(--bt-primary);
    border-color: var(--bt-border) var(--bt-border) #fff;
}
.store-order-container .nav-link:hover,
.wp-toolkit .nav-link:hover {
    color: var(--bt-primary);
}
.store-order-container .tab-content,
.wp-toolkit .tab-content {
    border-color: var(--bt-border);
}

.store-order-container .custom-select,
.wp-toolkit .custom-select,
.landing-page .custom-select {
    border-color: var(--bt-border);
    border-radius: var(--bt-radius-sm);
    font-family: var(--bt-font);
    color: var(--bt-text);
}
.store-order-container .custom-select:focus,
.wp-toolkit .custom-select:focus {
    border-color: var(--bt-primary);
}

/* domain-validation / eligibilidad (order.tpl): el verde/rojo nativo del
   tema en vez del verde/rojo generico de twenty-one */
.store-order-container .domain-validation.ok,
.store-order-container .domain-validation .fa-check {
    color: var(--bt-green-btn);
}
.store-order-container .domain-validation .fa-times {
    color: var(--bt-red);
}

/* Tarjeta de upsell de order.tpl: icono/tipografia consistentes con el
   resto del tema; color explicito en el link "mas info" implicito del CTA
   por la landmine de especificidad ".bt-body a" (0,1,1). */
.store-promoted-product h3 { color: var(--bt-text); }
.store-promoted-product h4 { color: var(--bt-text-2); font-weight: 400; }
.store-promoted-product .features { list-style: none; padding-left: 0; }
.store-promoted-product .features .fa-check-circle { color: var(--bt-primary); margin-right: 6px; }

/* ---- .landing-page: paginas promocionales de venta (SSL, marketgoo,
   nordvpn, sitelock, spamexperts, weebly, xovinow, sitebuilder, ox,
   threesixtymonitoring, cpanelseo, codeguard). Bootstrap stock -> tipografia
   y color del tema, sin tocar el grid. ---- */
.landing-page h2,
.landing-page h3,
.landing-page h4 {
    font-family: var(--bt-font);
    color: var(--bt-text);
}
.landing-page .hero {
    padding: 32px 0;
    color: var(--bt-text);
}
.landing-page .hero h3 { color: var(--bt-text-2); font-weight: 400; }
.landing-page p,
.landing-page .description { color: var(--bt-text-2); }

/* tarjetas "item" de comparativa (ssl/shared/certificate-item.tpl y
   equivalentes de otros addons): superficie/borde/radio/sombra del tema,
   mismo lenguaje que .card sin ser un .card real */
.landing-page .item,
.landing-page .content-block,
.landing-page .feature-block,
.landing-page .feature-wrapper {
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
}
.landing-page .item .btn,
.landing-page .content-block .btn,
.landing-page .feature-block .btn {
    color: #fff;
    background: var(--bt-primary);
    border-color: var(--bt-primary);
}
.landing-page .item .btn:hover,
.landing-page .content-block .btn:hover,
.landing-page .feature-block .btn:hover {
    background: var(--bt-primary-hover);
    border-color: var(--bt-primary-hover);
}
.landing-page .item-features .fa-check,
.landing-page .features__item .fa-check,
.landing-page .feature .fa-check {
    color: var(--bt-primary);
}
.landing-page .price { color: var(--bt-primary); font-weight: 700; }
.landing-page .standout {
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 1px var(--bt-primary);
}

/* .wp-toolkit / .social-bee / *-upgrade-container / .dynamic-landing-page:
   mismo trato basico de tipografia + botones primarios explicitos (evita
   que ".bt-body a" pinte de azul un <a class="btn btn-success"> sin color
   propio, landmine documentada arriba en la seccion de Botones). */
.wp-toolkit,
.social-bee,
.sitebuilder-upgrade-container,
.weebly-upgrade-container,
.dynamic-landing-page {
    color: var(--bt-text);
}
.wp-toolkit h2, .wp-toolkit h3, .wp-toolkit h4,
.social-bee h2, .social-bee h3, .social-bee h4,
.sitebuilder-upgrade-container h2, .sitebuilder-upgrade-container h3,
.weebly-upgrade-container h2, .weebly-upgrade-container h3,
.dynamic-landing-page h2, .dynamic-landing-page h3 {
    font-family: var(--bt-font);
    color: var(--bt-text);
}
.sitebuilder-upgrade-container .btn-success,
.weebly-upgrade-container .btn-success {
    color: #fff;
}

/* ===== END STORE (skin scopeado) ===== */

/* ===== SIDEBAR panel hosting =====
   Task 6 del plan docs/superpowers/plans/2026-07-30-sidebar-bh.md.
   Look tomado del mockup APROBADO ~/claude/z/sidebar-mockup.html, aplicado
   a las clases REALES que ya emite includes/bt-navlist.tpl (Task 4/5):
   .bt-nav-section/.bt-nav-section-toggle/.bt-nav-section-title/
   .bt-nav-caret/.bt-nav-section-body, .bt-nav-item/.bt-nav-link/
   .bt-nav-icon/.bt-nav-label/.bt-nav-badge, y el selector de servicio
   .bt-nav-svc-*.

   SCOPE: todo bajo ".bt-sidebar" (el <aside> real, ver header.tpl L301),
   nunca bajo ".bt-nav-list" a secas -- esa clase la comparte la franja
   superior (.bt-nav-list.bt-topstrip-nav, header.tpl L206/243), que NO se
   toca aqui (requisito duro "no sangrar a otras zonas").

   SUSTITUCION CONSCIENTE de reglas .bt-nav-* viejas (estilo Lagom/bandas
   de color, mas arriba en este mismo fichero: .bt-nav-link, .bt-nav-icon,
   .bt-nav-badge, .bt-nav-caret, .bt-band-N): esas reglas seguian pensadas
   para el navlist plano anterior. Aqui se sobreescriben SOLO dentro de
   ".bt-sidebar" con selectores mas especificos (".bt-sidebar .bt-nav-link"
   etc., especificidad 0,2,0 > 0,1,0 de las viejas) para dar el look de
   panel de hosting moderno sin togar la franja superior (que sigue las reglas viejas) ni el resto
   del sitio. Colores PROPIOS de esta seccion (no --bt-primary global, que
   sigue siendo #1062FE para botones/enlaces del resto del tema): variables
   locales --bt-navh-* solo dentro de ".bt-sidebar".

   Landmines respetadas: color explicito en cada item/enlace (nunca se deja
   heredar de ".bt-body a", que gana por especificidad 0,1,1); ningun "*­/"
   pegado a texto en estos comentarios; sin !important. */

.bt-sidebar {
    /* Paleta propia del sidebar, aprobada en el mockup -- no reusa
       --bt-primary global para no cambiar botones/enlaces del resto del
       tema. */
    /* Pedido del dueno 2026-07-31: fondo activo = MISMO azul que el hover (atado a --bt-navh-hover-bg) para que si un dia se ajusta el hover, el activo le siga. */
    --bt-navh-active-bg: var(--bt-navh-hover-bg);
    --bt-navh-active-fg: #4C7EDB;
    --bt-navh-hover-bg: #EEF4FE;
    --bt-navh-text: #2A2F3A;
    --bt-navh-text-2: #757B87;
    /* Sin esto, Roboto se renderiza mas pesado en macOS (efecto "bold"
       espurio vs. el mockup aprobado, que ya trae AA gris). */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* --- Items de nivel 1 (Inicio/Mi hosting/Dominios y los de cada seccion) --- */
.bt-sidebar .bt-nav-link {
    display: flex;
    align-items: center;
    gap: 12px;
    height: 44px;
    min-height: 44px;
    padding: 0 12px;
    border-radius: 10px;
    border-left: 0; /* pisa la bandita de color heredada (.bt-band-N) */
    color: var(--bt-navh-text); /* landmine: color explicito, nunca heredado */
    font-size: 14.5px;
    font-weight: 400;
    text-decoration: none;
    cursor: pointer;
    transition: background .13s ease, color .13s ease;
}
.bt-sidebar .bt-nav-link:hover,
.bt-sidebar .bt-nav-link:focus {
    background: var(--bt-navh-hover-bg);
    color: var(--bt-navh-active-fg);
    text-decoration: none;
}
.bt-sidebar .bt-nav-link:hover .bt-nav-icon,
.bt-sidebar .bt-nav-link:focus .bt-nav-icon {
    color: var(--bt-navh-active-fg);
}
.bt-sidebar .bt-nav-link.bt-active {
    background: var(--bt-navh-active-bg);
    color: var(--bt-navh-active-fg);
    font-weight: 500;
}
.bt-sidebar .bt-nav-link.bt-active .bt-nav-icon {
    color: var(--bt-navh-active-fg);
}
.bt-sidebar .bt-nav-link:focus-visible {
    outline: 2px solid var(--bt-navh-active-fg);
    outline-offset: 2px;
}

/* --- Iconos SVG inline (bt-icons.tpl): sin width/height propios, se fijan
   aqui a 20px; heredan color via currentColor del .bt-nav-link contenedor
   (gris por defecto, azul en hover/activo -- reglas de arriba). --- */
.bt-sidebar .bt-nav-icon {
    flex: 0 0 auto;
    width: 20px;
    font-size: inherit;
    text-align: center;
    color: var(--bt-navh-text-2);
}
.bt-sidebar .bt-nav-icon svg {
    width: 20px;
    height: 20px;
    display: block;
}

.bt-sidebar .bt-nav-label {
    flex: 1 1 auto;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.bt-sidebar .bt-nav-badge {
    flex: 0 0 auto;
    font-size: 10.5px;
    font-weight: 700;
    color: var(--bt-navh-active-fg);
    background: var(--bt-navh-hover-bg);
    padding: 2px 7px;
    border-radius: 999px;
}

/* --- Cabeceras de grupo plegables (.bt-nav-section-toggle) ---
   El plegado en si (Task 7, JS) solo necesita alternar una clase en el
   <li class="bt-nav-section">; aqui ya queda listo el hook visual:
   ".bt-nav-section.bt-nav-collapsed" oculta el body y rota el chevron.
   Sin JS: sin esa clase, todo permanece visible (degrada por diseno). */
.bt-sidebar .bt-nav-section + .bt-nav-section {
    margin-top: 10px;
}
.bt-sidebar .bt-nav-section-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 8px 12px 4px;
    background: none;
    border: 0;
    cursor: pointer;
    font: inherit;
}
.bt-sidebar .bt-nav-section-title {
    color: #9AA1AD; /* gris claro del mockup para labels de grupo (mas claro que --bt-navh-text-2) */
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}
.bt-sidebar .bt-nav-section-toggle .bt-nav-caret {
    color: var(--bt-navh-text-2);
    display: inline-flex;
    transition: transform .18s ease;
}
.bt-sidebar .bt-nav-section-toggle:focus-visible {
    outline: 2px solid var(--bt-navh-active-fg);
    outline-offset: 2px;
}
/* Hook de Task 7: clase que pondra el JS de plegado en el <li.bt-nav-section>. */
.bt-sidebar .bt-nav-section.bt-nav-collapsed .bt-nav-section-toggle .bt-nav-caret {
    transform: rotate(-90deg);
}
.bt-sidebar .bt-nav-section.bt-nav-collapsed > .bt-nav-section-body,
.bt-sidebar .bt-nav-section-body[hidden] {
    display: none;
}
.bt-sidebar .bt-nav-section-body {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* --- Selector de servicio de "Mi hosting" (.bt-nav-svc-*) --- */
.bt-sidebar .bt-nav-svc-current {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 40px;
    padding: 0 12px;
    margin: 0 4px 4px;
    border-radius: 10px;
    border: 1px solid var(--bt-border);
    background: var(--bt-surface);
    color: var(--bt-navh-text);
    cursor: pointer;
    list-style: none;
}
.bt-sidebar .bt-nav-svc-current::-webkit-details-marker { display: none; }
.bt-sidebar .bt-nav-svc-label {
    flex: 1 1 auto;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--bt-navh-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.bt-sidebar .bt-nav-svc-chevron {
    color: var(--bt-navh-text-2);
    display: inline-flex;
    flex: 0 0 auto;
    transition: transform .18s ease;
}
.bt-sidebar .bt-nav-svc-selector[open] > .bt-nav-svc-current .bt-nav-svc-chevron {
    transform: rotate(180deg);
}
.bt-sidebar .bt-nav-svc-toggle:focus-visible {
    outline: 2px solid var(--bt-navh-active-fg);
    outline-offset: 2px;
}
.bt-sidebar .bt-nav-svc-panel {
    margin: 0 4px 6px;
    padding: 8px;
    border-radius: 10px;
    border: 1px solid var(--bt-border);
    background: var(--bt-surface);
    box-shadow: var(--bt-shadow);
}
.bt-sidebar .bt-nav-svc-search-wrap { margin-bottom: 6px; }
.bt-sidebar .bt-nav-svc-search {
    width: 100%;
    height: 32px;
    padding: 0 10px;
    border-radius: 8px;
    border: 1px solid var(--bt-border);
    color: var(--bt-navh-text); /* landmine: color explicito en el input tambien */
    font-size: 13px;
    background: var(--bt-bg);
}
.bt-sidebar .bt-nav-svc-search:focus-visible {
    outline: 2px solid var(--bt-navh-active-fg);
    outline-offset: 2px;
}
.bt-sidebar .bt-nav-svc-options {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 220px;
    overflow-y: auto;
}
.bt-sidebar .bt-nav-svc-option-link {
    display: block;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--bt-navh-text);
    font-size: 13.5px;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.bt-sidebar .bt-nav-svc-option-link:hover,
.bt-sidebar .bt-nav-svc-option-link:focus {
    background: var(--bt-navh-hover-bg);
    color: var(--bt-navh-active-fg);
    text-decoration: none;
}
.bt-sidebar .bt-nav-svc-option-link:focus-visible {
    outline: 2px solid var(--bt-navh-active-fg);
    outline-offset: 2px;
}
.bt-sidebar .bt-nav-svc-option-active .bt-nav-svc-option-link {
    background: var(--bt-navh-active-bg);
    color: var(--bt-navh-active-fg);
    font-weight: 500;
}
.bt-sidebar .bt-nav-svc-more {
    margin-top: 4px;
    padding-top: 6px;
    border-top: 1px solid var(--bt-border);
    text-align: center;
}
.bt-sidebar .bt-nav-svc-more-text {
    margin: 0 0 4px;
    font-size: 11.5px;
    color: var(--bt-navh-text-2);
}
.bt-sidebar .bt-nav-svc-viewall {
    color: var(--bt-navh-active-fg); /* landmine: color explicito, no azul-link por defecto */
    font-size: 12.5px;
    font-weight: 500;
    text-decoration: none;
}
.bt-sidebar .bt-nav-svc-viewall:hover,
.bt-sidebar .bt-nav-svc-viewall:focus {
    text-decoration: underline;
}
.bt-sidebar .bt-nav-svc-viewall:focus-visible {
    outline: 2px solid var(--bt-navh-active-fg);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .bt-sidebar .bt-nav-link,
    .bt-sidebar .bt-nav-link .bt-nav-icon,
    .bt-sidebar .bt-nav-section-toggle .bt-nav-caret,
    .bt-sidebar .bt-nav-svc-chevron {
        transition: none;
    }
}

/* ===== END SIDEBAR panel hosting ===== */

/* ===== ANNOUNCEMENTS + DOWNLOADS ===== */
/* CSS de announcements.tpl (.bt-ann) y downloads.tpl/downloadscat.tpl
   (.bt-dl). Reusa tokens/patrones ya existentes: .bt-card/.bt-btn/
   .bt-btn--soft, --bt-*, azul sutil #4C7EDB de enlaces de tarjeta (mismo
   valor que .bt-kb-cat-name/.bt-kb-item-title), gris oscuro #2A2F3A para
   titulos en reposo (criterio "no tan azul" del dueno). El gancho :has()
   que oculta el sidebar contextual de estas 2 paginas ya vive arriba junto
   a .bt-kb/.bt-invoices/.bt-tickets/.bt-emails (ver comentario en ese
   grupo), no se repite aqui.

   Motivo del reporte visual original: Announcements y Downloads no tenian
   plantilla propia en banatheme y heredaban el look STOCK de twenty-one
   (list-group de Bootstrap, titulos en azul primario brillante via
   ".bt-body a" sin override, iconos FontAwesome que salen como
   cuadraditos vacios porque el tema no carga la fuente de iconos). Este
   bloque skiniza ambas paginas con SVG inline propios, sin fa-. */

.bt-ann svg, .bt-dl svg { width: 1em; height: 1em; display: block; }
.bt-ann *, .bt-dl * { box-sizing: border-box; }
.bt-ann { padding: 24px 0 30px; }
.bt-dl { padding: 24px 0 30px; }
@media (max-width: 820px) {
    .bt-ann { padding: 12px 0 20px; }
    .bt-dl { padding: 12px 0 20px; }
}

/* ---- Buscador de Downloads: mismo lenguaje que .bt-kb-search
   (knowledgebase.tpl) — input 46px, radio 10px, foco azul con box-shadow,
   boton .bt-btn en vez del input-group nativo con boton cuadrado. Form/
   name/id VERBATIM en el .tpl, solo el markup/clases alrededor cambia. ---- */
.bt-dl-search {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 26px;
}
.bt-dl-search-i {
    position: absolute;
    left: 16px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--bt-text-3);
    font-size: 16px;
    pointer-events: none;
}
.bt-dl-search-input {
    flex: 1 1 auto;
    height: 46px;
    min-width: 0;
    padding: 0 16px 0 42px;
    font-family: var(--bt-font);
    font-size: 14.5px;
    font-weight: 300;
    color: var(--bt-text);
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 10px;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.bt-dl-search-input:focus {
    outline: none;
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 .2rem rgba(16, 98, 254, .16);
}
.bt-dl-search-btn { height: 46px; padding: 0 24px; flex: 0 0 auto; }
@media (max-width: 480px) {
    .bt-dl-search { flex-wrap: wrap; }
    .bt-dl-search-input { flex: 1 1 100%; }
    .bt-dl-search-btn { flex: 1 1 100%; }
}

/* ---- Rejilla de categorias de Downloads: mismo lenguaje que .bt-kb-cat
   (tarjeta uniforme, alto homogeneo con/sin descripcion via flex + pie con
   margin-top:auto), en vez del .row/.col-xl-6 de Bootstrap del nativo. ---- */
.bt-dl-cats {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 18px;
    margin-bottom: 28px;
}
.bt-dl-cat {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 20px 22px;
    color: inherit;
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.bt-dl-cat:hover {
    border-color: var(--bt-primary);
    box-shadow: 0 10px 26px rgba(16, 24, 40, .10);
    text-decoration: none;
    color: inherit;
}
.bt-dl-cat-head {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
}
/* "no tan azul" (pedido del dueno): cuadro del icono neutro (gris muy
   claro), icono en gris apagado, NO el azul saturado del badge nativo. */
.bt-dl-cat-ic {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border-radius: 10px;
    background: #EEF1F6;
    color: #757B87;
    font-size: 18px;
}
/* Titulo en gris oscuro sobrio en reposo; el azul de marca solo aparece al
   pasar el mouse por la tarjeta, no de entrada (mismo criterio que
   .bt-kb-cat-name). */
.bt-dl-cat-name {
    font-size: 15.5px;
    font-weight: 500;
    color: #2A2F3A;
    line-height: 1.3;
    min-width: 0;
    flex: 1 1 auto;
    transition: color .15s ease;
}
.bt-dl-cat:hover .bt-dl-cat-name {
    color: #4C7EDB;
}
/* Conteo como texto discreto (gris de labels), NO badge solido azul
   flotante como el nativo (badge-info float-right). */
.bt-dl-cat-count {
    font-size: 12px;
    font-weight: 400;
    color: var(--bt-text-3);
    flex: 0 0 auto;
    white-space: nowrap;
}
.bt-dl-cat-desc {
    font-size: 13px;
    font-weight: 300;
    color: var(--bt-text-2);
    line-height: 1.5;
    margin: 0;
    flex: 1 1 auto;
}

/* ---- "Mas descargados"/"Archivos": lista de filas limpias, mismo
   espiritu que .bt-kb-list (borde inferior + hover suave). ---- */
.bt-dl-popular-title {
    display: flex;
    align-items: center;
    gap: 10px;
}
.bt-dl-popular-ic { color: var(--bt-text-3); font-size: 16px; }
.bt-dl-list { display: flex; flex-direction: column; }
.bt-dl-item {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 14px 4px;
    border-bottom: 1px solid var(--bt-border);
    color: inherit;
    text-decoration: none;
    transition: background .15s;
}
.bt-dl-item:last-child { border-bottom: none; }
.bt-dl-item:hover {
    background: rgba(16, 24, 40, .025);
    text-decoration: none;
    color: inherit;
}
.bt-dl-item-ic {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex: 0 0 auto;
    border-radius: 9px;
    background: #F1F2F6;
    color: var(--bt-text-3);
    font-size: 15px;
}
.bt-dl-item-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
/* landmine "color explicito en enlaces": .bt-dl-item ES el <a>, asi que
   ".bt-body a" (0,1,1) ya pintaria el texto de azul si no fijamos color
   propio en los hijos; .bt-dl-item-title fija #4C7EDB explicito (mismo
   valor que .bt-kb-item-title) para no depender del azul de link por
   defecto. */
.bt-dl-item-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 14px;
    font-weight: 500;
    color: #4C7EDB;
    line-height: 1.3;
}
/* Icono de tipo de archivo que YA entrega el core (via $download.type,
   reescrito con nuestra propia clase en el .tpl en vez de "pr-1" de
   Bootstrap) — solo se ajusta el espaciado/tamano aqui, el <img> en si es
   dato del core, no se toca. */
.bt-dl-item-typeicon { margin-right: 2px; max-height: 16px; vertical-align: middle; }
.bt-dl-item-desc {
    font-size: 12.5px;
    font-weight: 300;
    color: var(--bt-text-2);
    line-height: 1.4;
}
.bt-dl-item-size {
    font-size: 12px;
    font-weight: 300;
    color: var(--bt-text-3);
}
.bt-dl-item-size strong { font-weight: 500; color: var(--bt-text-2); }
/* Pildora "restringido" discreta (gris-ambar suave), NO el label-danger
   rojo solido del nativo. */
.bt-dl-lock {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 22px;
    padding: 0 9px;
    border-radius: 999px;
    background: rgba(217, 119, 6, .1);
    color: #8a5c04;
    font-size: 11px;
    font-weight: 500;
}
.bt-dl-empty {
    padding: 24px 4px;
    text-align: center;
    color: var(--bt-text-3);
    font-size: 13.5px;
}
.bt-dl-foot { margin-top: 20px; }

/* ---- Announcements: tarjeta por anuncio (mismo lenguaje visual que
   .bt-card), icono de megafono, fecha con icono de calendario, boton
   "seguir leyendo" con flecha SVG en vez del icono de Font Awesome del nativo. ---- */
.bt-ann-list {
    display: flex;
    flex-direction: column;
    gap: 20px;
    margin-bottom: 24px;
}
.bt-ann-item {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    padding: 22px 24px;
}
.bt-ann-item-ic {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border-radius: 10px;
    background: #EEF1F6;
    color: #757B87;
    font-size: 18px;
}
.bt-ann-item-body { flex: 1 1 auto; min-width: 0; }
.bt-ann-item-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}
.bt-ann-item-title {
    margin: 0;
    font-size: 17px;
    font-weight: 500;
    line-height: 1.3;
    min-width: 0;
}
/* landmine "color explicito en enlaces": titulo con <a> anidado dentro de
   .bt-ann-item-title, gris oscuro sobrio en reposo (nada de azul brillante
   grande del nativo), azul de marca SOLO al pasar el mouse. Se prefija con
   ".bt-body" para ganarle en especificidad a ".bt-body a" (0,1,1) —
   ".bt-body .bt-ann-item-title a" es (0,2,1), mismo patron que
   ".bt-body .bt-empty-cta"/".bt-body .bt-paybtn" ya usados en el tema. */
.bt-body .bt-ann-item-title a {
    color: #2A2F3A;
    text-decoration: none;
}
.bt-body .bt-ann-item-title a:hover,
.bt-body .bt-ann-item-title a:focus {
    color: #4C7EDB;
    text-decoration: none;
}
.bt-body .bt-ann-item-title a:focus-visible {
    outline: 2px solid var(--bt-primary);
    outline-offset: 2px;
}
/* Boton "Editar" de staff (editLink): oculto hasta pasar el mouse por la
   tarjeta, mismo espiritu que .bt-kb-editbtn (show-on-hover propio en vez
   del "show-on-hover" de Bootstrap del nativo). */
.bt-ann-editbtn {
    height: 26px;
    padding: 0 10px;
    font-size: 11px;
    border-radius: 999px;
    flex: 0 0 auto;
    opacity: 0;
    transition: opacity .15s ease;
}
.bt-ann-item:hover .bt-ann-editbtn,
.bt-ann-item:focus-within .bt-ann-editbtn { opacity: 1; }
.bt-ann-item-meta { margin: 8px 0 12px; }
.bt-ann-item-date {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--bt-text-3);
}
.bt-ann-item-date svg { width: 14px; height: 14px; }
.bt-ann-item-text {
    font-size: 14px;
    font-weight: 300;
    line-height: 1.7;
    color: var(--bt-text-2);
}
.bt-ann-item-text :first-child { margin-top: 0; }
.bt-ann-item-text :last-child { margin-bottom: 0; }
/* landmine "color explicito en enlaces": el cuerpo del anuncio es HTML del
   admin (mismo espiritu que .bt-kb-body) y puede traer <a> propios — se
   fija un azul discreto para que no salga el azul primario grande de
   ".bt-body a" sin querer, prefijado con .bt-body por el mismo motivo de
   especificidad de arriba. */
.bt-body .bt-ann-item-text a { color: #4C7EDB; }
.bt-body .bt-ann-item-text a:hover { color: var(--bt-primary); }
/* "Seguir leyendo": azul sutil de accion, NO boton solido -- mismo tono
   que .bt-kb-item-title, prefijado con .bt-body por el mismo motivo de
   especificidad (.bt-ann-more ES el <a>). */
.bt-body a.bt-ann-more {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 14px;
    font-size: 13px;
    font-weight: 500;
    color: #4C7EDB;
    text-decoration: none;
}
.bt-body a.bt-ann-more:hover,
.bt-body a.bt-ann-more:focus {
    color: var(--bt-primary);
    text-decoration: none;
}
.bt-body a.bt-ann-more:focus-visible {
    outline: 2px solid var(--bt-primary);
    outline-offset: 2px;
}
.bt-ann-more svg { width: 15px; height: 15px; }

@media (max-width: 640px) {
    .bt-ann-item { flex-direction: column; }
    .bt-ann-item-head { flex-wrap: wrap; }
}
/* ===== END ANNOUNCEMENTS + DOWNLOADS ===== */

/* ===== NOTIFICACIONES (popover topstrip) ===== */
/* La cascara del popover (.popover/.arrow/.popover-inner/.popover-header/
   .popover-body) la crea scripts.js del tema PADRE via Popper/Bootstrap
   con container:'body' -- el nodo cuelga directo de <body> (que lleva
   clase .bt-body), asi que ".bt-body .popover-user-notifications" si
   matchea aunque el popover no viva dentro de .bt-app. Todo lo de aca
   abajo va scopeado a esa clase para no filtrar a otros popovers del
   core que pudieran reusar la misma cascara. Bootstrap 4 pone
   .popover{max-width:276px}; theme.min.css del padre carga ANTES que
   este fichero, asi que a igual especificidad (0,2,0 vs su 0,1,0) le
   ganamos sin necesitar !important. */
.bt-body .popover-user-notifications {
    width: 340px;
    max-width: 340px;
    padding: 0;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 12px;
    box-shadow: var(--bt-shadow);
}
.bt-body .popover-user-notifications .arrow {
    /* La flechita del popover no encaja con el look de tarjeta flotante
       del resto del tema (mismo criterio que otros dropdowns propios). */
    display: none;
}
.bt-body .popover-user-notifications .popover-header:empty {
    /* El template del padre siempre trae un <h3 class="popover-header">
       vacio (el titulo real lo ponemos nosotros dentro del contenido, ver
       .bt-notif-head) -- si no se oculta deja un hueco en blanco arriba. */
    display: none;
}
.bt-body .popover-user-notifications .popover-body {
    padding: 0;
}
.bt-notif-head {
    padding: 14px 16px;
    font-size: 13px;
    font-weight: 500;
    color: #757B87;
    border-bottom: 1px solid var(--bt-border);
}

.bt-notif-list {
    max-height: 380px;
    overflow-y: auto;
    margin: 0;
    padding: 0;
    list-style: none;
    /* Scrollbar discreto (WebKit); en navegadores sin soporte se queda el
       nativo, no rompe nada. */
    scrollbar-width: thin;
}
.bt-notif-list::-webkit-scrollbar {
    width: 6px;
}
.bt-notif-list::-webkit-scrollbar-thumb {
    background: var(--bt-border);
    border-radius: 6px;
}

.bt-notif-list li {
    border-bottom: 1px solid var(--bt-border);
}
.bt-notif-list li:last-child {
    border-bottom: none;
}
/* Selector con clase propia para ganarle a ".bt-body a" (0,1,1) sin
   !important -- misma leccion de especificidad documentada arriba en
   este fichero (bt-empty-cta, bt-ann-more, etc). */
.bt-body .bt-notif-list li a {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    color: var(--bt-text);
    font-family: 'Roboto', sans-serif;
    font-size: 14px;
    text-decoration: none;
}
.bt-body .bt-notif-list li a:hover,
.bt-body .bt-notif-list li a:focus {
    background: #F0F5FF;
    color: var(--bt-text);
    text-decoration: none;
}
.bt-notif-list .message {
    flex: 1 1 auto;
    min-width: 0;
}

.bt-notif-ico {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    font-size: 14px;
}
.bt-notif-ico.bt-sev-danger {
    background: rgba(217, 45, 32, .1);
    color: var(--bt-red);
}
.bt-notif-ico.bt-sev-warning {
    background: rgba(247, 144, 9, .1);
    color: var(--bt-amber);
}
.bt-notif-ico.bt-sev-info {
    background: #CFE0FF;
    color: #4C7EDB;
}
.bt-notif-ico.bt-sev-success {
    background: rgba(16, 185, 129, .1);
    color: var(--bt-green);
}

.bt-notif-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 32px 20px;
    color: #757B87;
    font-size: 13.5px;
    text-align: center;
}
.bt-notif-empty i {
    font-size: 30px;
    color: var(--bt-border);
}
/* ===== END NOTIFICACIONES (popover topstrip) ===== */

/* ===== BT SECTION: CANCEL REQUEST (clientareacancelrequest.tpl) ===== */
/* ============================================================
   Reusa integramente el lenguaje visual compartido (.bt-card/.bt-form/
   .bt-btn/.bt-btn--soft/.bt-btn--danger-soft/.bt-page-title, tokens
   --bt-*, ver "BT SHARED: FORMS + CARDS + ACCOUNT TABS" arriba): aqui
   solo van los complementos propios de esta pagina (prefijo bt-cancel-).
   Pagina de una sola tarea, sin sub-nav bt-actabs (no es parte del
   bloque de cuenta), asi que oculta su sidebar contextual de producto con
   el mismo patron :has() que .bt-pd/.bt-domdetails. */

.container-fluid:has(.bt-cancel) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-cancel) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-cancel) .sidebar-secondary {
    display: none;
}

/* ---- Tarjeta-resumen "que se cancela" (antes un alert informativo) ---- */
.bt-cancel-summary {
    margin-bottom: 20px;
}
.bt-cancel-summary-line {
    font-size: 15px;
    color: var(--bt-text);
    margin: 0;
}
.bt-cancel-summary-domain {
    font-size: 13.5px;
    color: var(--bt-text-2);
    margin: 4px 0 0;
}

/* ---- Pantallas de estado ($invalid / $requested): mismo aire de
   tarjeta que el formulario, alert.tpl nativo sin tocar por dentro ---- */
.bt-cancel-status .alert {
    margin-bottom: 16px;
}
.bt-cancel-status-back {
    text-align: center;
    margin: 0;
}

/* ---- Aviso de dominio anexo (checkbox canceldomain): mismo tono de
   advertencia que .bt-form-row--error, sin caja alert completa ---- */
.bt-cancel-domain {
    padding: 14px 16px;
    border: 1px solid #FEDF89;
    background: rgba(247, 144, 9, .06);
    border-radius: var(--bt-radius-sm);
}
.bt-cancel-domain-title {
    font-size: 13.5px;
    font-weight: 500;
    color: var(--bt-text);
    margin: 0 0 6px;
}
.bt-cancel-domain-desc {
    font-size: 13px;
    color: var(--bt-text-2);
    margin: 0 0 10px;
}
.bt-cancel-domain-check {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 400;
    color: var(--bt-text);
    cursor: pointer;
    margin: 0;
}
.bt-cancel-domain-check input {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
}

/* ---- Tipo de cancelacion: de <select> escondido a 2 opciones visibles
   tipo radio-card, mismo campo name="type" con sus 2 value literales
   (ver contrato en el .tpl). En pantalla >= 480px van lado a lado; en
   movil se apilan (ver media query abajo). ---- */
.bt-cancel-type-label {
    display: block;
    font-size: 13px;
    color: var(--bt-text-2);
    margin-bottom: 8px;
}
.bt-cancel-type-options {
    display: flex;
    gap: 10px;
}
.bt-cancel-type-option {
    flex: 1 1 0;
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 12px 14px;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-sm);
    font-size: 13.5px;
    font-weight: 400;
    color: var(--bt-text);
    cursor: pointer;
    transition: border-color .15s ease;
}
/* Mismo peso visual para las 2 opciones: no hay "recomendada", solo el
   propio radio (y un borde apenas mas marcado) indican la seleccion. */
.bt-cancel-type-option:has(input:checked) {
    border-color: var(--bt-text-2);
}
.bt-cancel-type-option input {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    margin-top: 2px;
    accent-color: var(--bt-primary);
}
.bt-cancel-type-option-inner {
    display: flex;
    flex-direction: column;
    gap: 3px;
    line-height: 1.3;
}
.bt-cancel-type-option-title {
    color: var(--bt-text);
}
.bt-cancel-type-option-note {
    font-size: 12px;
    color: var(--bt-text-2);
    font-weight: 400;
}

/* ---- Acciones del formulario: volver primero (facil de encontrar),
   cancelar-servicio (destructivo) despues, nunca el mas llamativo. ---- */
.bt-cancel-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    margin-top: 24px;
}

@media (max-width: 480px) {
    .bt-cancel-type-options {
        flex-direction: column;
    }
}
/* ===== END BT SECTION: CANCEL REQUEST ===== */


/* ==========================================================================
   BLOQUE DOMINIOS (integrado 2026-08-02). Origen: _css-parts/, escritos por
   3 equipos en paralelo para no colisionar en este fichero. Cubre las 19
   plantillas de dominios vestidas esa noche. Prefijos: bt-dns-, bt-dc-, bt-dv-.
   ========================================================================== */

/* ---------- dominios-dns.css ---------- */
/* BanaTheme — DNS (7 paginas): dnsmanagement.tpl, dnsmanagementadd.tpl,
   dnsmanagementmodify.tpl, dnsmanagementview.tpl, dnsmanagementdsigner.tpl,
   domainmanagementdnssec.tpl, clientareadomaindns.tpl.

   Estas paginas editan DNS REAL de dominios de clientes con formularios
   name=/value=/id=/action= que el contrato de vestido PROHIBE tocar (ver
   cabecera de cada .tpl). Por eso el vestido aqui es DELIBERADAMENTE mas
   conservador que en paginas nuevas (user-password.tpl,
   clientareadomaindetails.tpl): el markup Bootstrap nativo (card/card-body/
   table/btn-primary/btn-success/btn-danger/form-control) se deja INTACTO —
   ya hereda el skin global de banatheme.css (".bt-body .card",
   ".bt-body .btn-primary", ".bt-body .form-control", etc., ver mas arriba en
   este archivo) sin tocar NINGUN atributo de las 7 plantillas. Mismo patron
   que account-paymentmethods*.tpl (ver su comentario: "se deja con el
   markup Bootstrap nativo casi intacto ... ya hereda un look razonable de
   .bt-body .card/.form-control/label").

   Lo unico que anaden las 7 plantillas es markup 100% NUEVO, sin tocar
   ningun name/value/id/action existente ni ninguna clase Bootstrap ya
   presente:
     1) un div wrapper raiz ".bt-dns-page" (para acotar este CSS sin pisar
        otras paginas que tambien usan .card/.table genericos);
     2) un div ".bt-dns-tablewrap" alrededor de cada <table> ya existente,
        para que en movil se pueda hacer scroll horizontal CONTENIDO en vez
        de desbordar la pagina (requisito explicito del encargo);
     3) en dnsmanagement.tpl, una clase ".bt-dns-actrow" en el UNICO <div>
        contenedor sin clase que envuelve los botones flotados de anadir
        registro/Google Apps (los <div style="float:left..."> internos NO se
        tocan, siguen exactamente igual).
   Prefijo propio: bt-dns-. */

/* ---- Tablas: scroll horizontal contenido en movil, la tabla NUNCA
   desborda la pagina. min-width fuerza el scroll en vez de comprimir
   columnas hasta ilegibilidad (host/valor de un registro DNS puede ser
   largo). Variante --form para las tablas-formulario de 2 columnas
   (add/modify/dsigner), mas angostas, que no necesitan tanto min-width. ---- */
.bt-dns-tablewrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin-bottom: 16px;
}
.bt-dns-tablewrap:last-child { margin-bottom: 0; }
.bt-dns-tablewrap > table {
    min-width: 640px;
    margin-bottom: 0;
}
.bt-dns-tablewrap--form > table { min-width: 480px; }

/* Inputs/textarea con atributo size=/cols= (add/modify/dsigner) se salen del
   contenedor en movil si el navegador respeta ese atributo como ancho en
   caracteres. Se fuerza ancho fluido por CSS SIN tocar el atributo HTML (es
   solo una pista de presentacion heredada del core, no un dato del
   formulario). */
.bt-dns-page input[size],
.bt-dns-page textarea[cols] {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

/* ---- card-title (h3.card-title, clientareadomaindns.tpl): el skin global
   de banatheme.css solo cubre .card-header, no .card-title — se afina aqui
   sin depender de .bt-card/.bt-card-title (evitamos duplicar el padding de
   .card + .card-body + .bt-card en una misma tarjeta). ---- */
.bt-dns-page .card-title {
    font-size: 17px;
    font-weight: 300;
    color: var(--bt-text);
}

/* ---- Etiquetas de estado (Bootstrap 3 legacy ".label*", usadas en
   dnsmanagement.tpl para Active/Suspended de cada registro): el skin global
   de banatheme.css solo cubre .badge/.badge-*, no .label* — sin este bloque
   salen como texto plano sin fondo/color. Mismos tonos que
   ".bt-body .alert-success/-danger" para no introducir un color nuevo. ---- */
.bt-dns-page .label {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1.4;
}
.bt-dns-page .label-success { background-color: rgba(16, 185, 129, .14); color: #0a7a5c; }
.bt-dns-page .label-danger,
.bt-dns-page .label-suspended { background-color: rgba(220, 38, 38, .1); color: #a01d1d; }
.bt-dns-page .label-default { background-color: rgba(107, 114, 128, .14); color: #4A5160; }

/* ---- Botones "outline" de fila (Modificar/Eliminar por registro en
   dnsmanagement.tpl): el skin global de banatheme.css solo cubre
   .btn-outline-secondary, no .btn-outline-primary/-danger — se afinan al
   tono del tema sin tocar la clase en el .tpl. ---- */
.bt-dns-page .btn-outline-primary {
    color: var(--bt-primary);
    border-color: var(--bt-primary);
}
.bt-dns-page .btn-outline-primary:hover,
.bt-dns-page .btn-outline-primary:focus {
    background: var(--bt-primary);
    border-color: var(--bt-primary);
    color: #fff;
}
.bt-dns-page .btn-outline-danger {
    color: var(--bt-red);
    border-color: var(--bt-red);
}
.bt-dns-page .btn-outline-danger:hover,
.bt-dns-page .btn-outline-danger:focus {
    background: var(--bt-red);
    border-color: var(--bt-red);
    color: #fff;
}

/* ---- Fila de acciones "anadir registro" / "Google Apps" (dnsmanagement.tpl,
   unico <div> sin clase de las 7 plantillas al que se le anadio una clase
   propia): los <div style="float:left..."> internos NO se tocan (siguen
   flotando como antes en desktop), aqui solo se evita que se amontonen en
   movil pasando el contenedor a flex-wrap y neutralizando el float heredado
   con !important (necesario: un estilo inline solo se puede vencer con
   !important, nunca con especificidad de selector). ---- */
.bt-dns-actrow {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.bt-dns-actrow > div {
    float: none !important;
    padding: 0 !important;
}

/* ---- Caja "verificar nameservers" (dnsmanagement.tpl, #dnscheck): la
   tabla de comparacion actuales/recomendados usa columnas al 50% con
   word-wrap ya inline — solo se asegura que quepa en el ancho movil del
   wrapper de scroll (misma .bt-dns-tablewrap de arriba, sin reglas extra). ---- */

/* ---------- dominios-contactos.css ---------- */
/* BanaTheme — CSS de las 6 paginas de "contactos y servidores de nombres de
   dominio" (F6-parte2): clientareadomainregisterns.tpl,
   clientareadomaincontactinfo.tpl, domainmanagementchildns.tpl,
   domainmanagementcontacts.tpl, domainmanagementcontactmod.tpl,
   domainmanagementcontactchange.tpl.

   Este fichero NO se enlaza directo, es un _css-parts/ pendiente de
   integrar en css/banatheme.css por el orquestador. Reusa integramente el
   lenguaje visual ya global (.bt-card/.bt-card-title/.bt-form/
   .bt-form-row/.bt-btn/.bt-btn--soft/.bt-btn--danger-soft/.bt-page-title,
   tokens --bt-*, ver css/banatheme.css) y solo agrega los complementos
   especificos de estas 6 paginas que esos bloques compartidos no cubren.
   Todo con prefijo propio bt-dc- (Domain Contacts) para no colisionar. */

/* ---- Ocultar sidebar contextual en las 2 paginas full-clientarea
   (clientareadomainregisterns.tpl / clientareadomaincontactinfo.tpl):
   mismo patron :has() que .bt-details/.bt-domdetails — estas paginas se
   llega a ellas desde la grilla "Administrar {dominio}" de
   clientareadomaindetails.tpl y no tienen sub-nav propia, asi que solo
   ocultamos el sidebar secundario para dejar el formulario a ancho
   completo. Las 4 paginas domainmanagement*.tpl NO pasan por
   clientarea.php (front controller RAA/IRTP aparte) y no tienen este
   layout, por eso no llevan esta regla. ---- */
.container-fluid:has(.bt-dc) .col-lg-4.col-xl-3 {
    display: none;
}
.container-fluid:has(.bt-dc) .primary-content {
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}
.container-fluid:has(.bt-dc) .sidebar-secondary {
    display: none;
}

/* ---- Contenedor comun: separacion entre tarjetas cuando hay varias
   seguidas fuera de .bt-card + .bt-card (que ya trae su propio margen). */
.bt-dc { padding: 8px 0 24px; }

/* ---- Cabecera de tarjeta con accion a la derecha (domainmanagementcontacts
   tabRegc: titulo+descripcion a la izquierda, boton "gestionar contacto" a
   la derecha). Colapsa a columna en movil. ---- */
.bt-dc-info-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.bt-dc-info-head .bt-card-title { margin-bottom: 4px; }
.bt-dc-info-head p { margin: 0; color: var(--bt-text-2, #4B5565); font-size: 13.5px; }
.bt-dc-info-headform { flex: 0 0 auto; }
@media (max-width: 480px) {
    .bt-dc-info-head { flex-direction: column; }
    .bt-dc-info-headform .bt-btn { width: 100%; }
}

/* ---- Tabla de solo-lectura (detalle de contacto WHOIS por rol) convertida
   a lista label/valor, legible a 390px sin desbordar. ---- */
.bt-dc-info {
    margin: 0;
    display: flex;
    flex-direction: column;
}
.bt-dc-info-row {
    display: grid;
    grid-template-columns: 160px 1fr;
    gap: 8px 16px;
    padding: 10px 0;
    border-bottom: 1px solid var(--bt-border, #E4E7EC);
}
.bt-dc-info-row:last-child { border-bottom: none; }
.bt-dc-info-row dt {
    font-weight: 500;
    color: var(--bt-text-2, #4B5565);
    font-size: 13.5px;
    margin: 0;
}
.bt-dc-info-row dd {
    margin: 0;
    color: var(--bt-text, #1B2430);
    font-size: 14px;
    word-break: break-word;
}
@media (max-width: 480px) {
    .bt-dc-info-row { grid-template-columns: 1fr; gap: 2px; padding: 8px 0; }
}

/* ---- WHOIS ID protection (privacidad WHOIS): mensaje de no-disponible +
   toggle de activar/desactivar, con el label de todo el bloque clicable. */
.bt-dc-whoisid-unavailable {
    text-align: center;
    padding: 16px 0;
    color: var(--bt-text-2, #4B5565);
}
.bt-dc-whoisid-toggle label {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-weight: 400;
    cursor: pointer;
}
.bt-dc-whoisid-toggle input[type="checkbox"] {
    margin-top: 3px;
    flex: 0 0 auto;
}

/* ---- Radios "disclose auth info" (domainmanagementcontactchange tabChange):
   2 opciones apiladas, cada una con su descripcion en small debajo. ---- */
.bt-dc-radiogroup { display: flex; flex-direction: column; gap: 14px; }
.bt-dc-radioitem { font-weight: 400; cursor: pointer; }
.bt-dc-radioitem input[type="radio"] { margin-right: 6px; }
.bt-dc-radioitem small { display: block; color: var(--bt-text-3, #757B87); margin-top: 2px; }

/* ---- Acuerdo CIRA (.dotca en tabCreate): caja de texto con scroll propio,
   se mantiene legible sin ancho fijo en px que desborde en movil. ---- */
.bt-dc-ciraagreement {
    border: 1px solid var(--bt-border, #E4E7EC);
    border-radius: var(--bt-radius, 8px);
    width: 100%;
    max-width: 480px;
    height: 200px;
    overflow: auto;
    padding: 10px 12px;
    font-size: 13px;
}
.bt-dc-ciracheck label { display: flex; align-items: center; gap: 8px; font-weight: 400; cursor: pointer; }

/* ---- Child nameservers (domainmanagementchildns): cada NS registrado trae
   2 columnas (cambiar hostname / cambiar+borrar IP), colapsan a 1 en
   movil igual que el resto del tema (breakpoint bootstrap .row/.col-md-6
   nativo, solo se agrega separacion entre bloques). ---- */
.bt-dc-childns-row {
    padding: 16px 0;
    border-top: 1px solid var(--bt-border, #E4E7EC);
}
.bt-dc-childns-row:first-child { border-top: none; padding-top: 0; }
.bt-dc-childns-row .bt-form-row:last-child { margin-bottom: 0; }

/* ---------- dominios-varios.css ---------- */
/* ============================================================
   BanaTheme — dominios-varios.css
   Cubre 6 paginas menores de dominios (equipo paralelo, rama
   feature/sidebar-bh):
     - domainforwarding.tpl              (.bt-dv-fwd)
     - clientareadomainemailforwarding.tpl (.bt-dv-emailfwd)
     - bulkdomainmanagement.tpl          (.bt-dv-bulk)
     - domain-pricing.tpl                (.bt-dv-pricing)
     - clientareadomainaddons.tpl        (.bt-dv-addons)
     - clientareadomaingetepp.tpl        (.bt-dv-epp)

   Fragmento AISLADO: no se integra solo en banatheme.css (lo hace el
   orquestador). Todas las clases nuevas usan el prefijo bt-dv- para no
   colisionar con bt-dm-/bt-dd-/bt-pd-/etc. ya usados por otras paginas
   de dominios. Reusa los componentes/tokens ya globales del tema
   (.bt-card/.bt-card-title/.bt-page-title/.bt-form/.bt-form-row/
   .bt-btn/.bt-btn--soft/.bt-btn--danger-soft, --bt-*) sin redefinirlos.
   ============================================================ */

/* ---- yes/no radio-cards, reusado por domainforwarding.tpl y
   bulkdomainmanagement.tpl (eleccion de nameservers) ---- */
.bt-dv-yesno {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}
.bt-dv-yesno-opt {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-md);
    font-size: 13.5px;
    font-weight: 400;
    color: var(--bt-text-2);
    cursor: pointer;
    margin: 0;
    transition: border-color .15s ease, color .15s ease;
}
.bt-dv-yesno-opt:has(input:checked) {
    border-color: var(--bt-primary);
    color: var(--bt-primary);
    font-weight: 500;
}
.bt-dv-yesno-opt input { margin: 0; }

/* ============================================================
   clientareadomaingetepp.tpl — trivial, solo margen inferior de la
   descripcion (el resto viene de .bt-card/.bt-card-title/alert.tpl
   nativos).
   ============================================================ */
.bt-dv-epp p { color: var(--bt-text-2); }

/* ============================================================
   clientareadomainaddons.tpl
   ============================================================ */
.bt-dv-addon-card .bt-card-title { text-align: center; }
.bt-dv-addons-back { margin-top: 16px; text-align: center; }

/* ============================================================
   clientareadomainemailforwarding.tpl
   ============================================================ */
.bt-dv-fwd-list { margin-bottom: 18px; }
.bt-dv-fwd-head {
    display: grid;
    grid-template-columns: 1fr 120px 1fr;
    gap: 10px;
    padding: 0 4px 8px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--bt-text-3);
}
.bt-dv-fwd-row {
    display: grid;
    grid-template-columns: 1fr 120px 1fr;
    gap: 10px;
    align-items: center;
    padding: 10px 4px;
    border-top: 1px solid var(--bt-border);
}
.bt-dv-fwd-row--new { border-style: dashed; }
.bt-dv-fwd-cell input {
    width: 100%;
    height: 40px;
    padding: 0 12px;
    font-family: var(--bt-font);
    font-size: 14px;
    color: var(--bt-text);
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 8px;
}
.bt-dv-fwd-cell input:focus {
    outline: none;
    border-color: var(--bt-primary);
    box-shadow: 0 0 0 .2rem rgba(16, 98, 254, .16);
}
.bt-dv-fwd-arrow {
    text-align: center;
    font-size: 12.5px;
    color: var(--bt-text-3);
    white-space: nowrap;
}
.bt-dv-fwd-lbl { display: none; }
.bt-dv-fwd-acts { margin-top: 18px; }

@media (max-width: 620px) {
    .bt-dv-fwd-head { display: none; }
    .bt-dv-fwd-row {
        grid-template-columns: 1fr;
        gap: 12px;
        padding: 14px 4px;
    }
    .bt-dv-fwd-arrow { text-align: left; }
    .bt-dv-fwd-lbl {
        display: block;
        font-size: 12px;
        font-weight: 500;
        color: var(--bt-text-3);
        margin-bottom: 4px;
    }
}

/* ============================================================
   domainforwarding.tpl
   ============================================================ */
.bt-dv-fwd-hint { color: var(--bt-text-2); font-size: 13px; margin: 0 0 10px; }
.bt-dv-fwd-delete { text-align: center; }
.bt-dv-fwd-dnscheck { margin: 16px 0; }

.bt-dv-fwd-nscols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin: 14px 0 20px;
}
.bt-dv-fwd-nscol {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px 14px;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-md);
    font-size: 13px;
    color: var(--bt-text-2);
}
.bt-dv-fwd-nscol-lbl {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .02em;
    margin: 0 0 4px;
}
.bt-dv-fwd-nscol-lbl--current { color: var(--bt-red); }
.bt-dv-fwd-nscol-lbl--recommended { color: var(--bt-green-btn); }
@media (max-width: 480px) {
    .bt-dv-fwd-nscols { grid-template-columns: 1fr; }
}

.bt-dv-fwd-arecs { margin-top: 10px; }
.bt-dv-fwd-arecs-head,
.bt-dv-fwd-arecs-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    padding: 8px 4px;
    font-size: 13px;
}
.bt-dv-fwd-arecs-head {
    font-weight: 600;
    color: var(--bt-text-3);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .02em;
}
.bt-dv-fwd-arecs-row { border-top: 1px solid var(--bt-border); color: var(--bt-text-2); word-break: break-word; }
@media (max-width: 599px) {
    .bt-dv-fwd-arecs-head { display: none; }
    .bt-dv-fwd-arecs-row { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   bulkdomainmanagement.tpl
   ============================================================ */
.bt-dv-bulk-domlist {
    list-style: none;
    margin: 0 0 20px;
    padding: 0;
    max-height: 260px;
    overflow-y: auto;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-md);
}
.bt-dv-bulk-domlist li {
    padding: 9px 14px;
    font-size: 13.5px;
    color: var(--bt-text);
    border-top: 1px solid var(--bt-border);
}
.bt-dv-bulk-domlist li:first-child { border-top: none; }

.bt-dv-bulk-nschoice { margin-bottom: 20px; }

.bt-dv-bulk-acts {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
}
/* Botones en columna a ancho de movil (regla del pedido: acciones en
   lote usables en pantalla chica, targets tactiles a lo ancho). */
@media (max-width: 480px) {
    .bt-dv-bulk-acts { flex-direction: column; }
    .bt-dv-bulk-acts .bt-btn { width: 100%; }
}

.bt-dv-bulk-whoischoice { margin-bottom: 14px; font-size: 13.5px; color: var(--bt-text-2); }
.bt-dv-bulk-whoischoice input { margin-right: 6px; }
.bt-dv-bulk-tabs { margin-top: 4px; }
.bt-dv-bulk-tabcontent { padding-top: 16px; }
/* Tabs por contacto (registrant/admin/tech/billing) horizontales con
   scroll contenido en vez de envolver/recortar en pantallas chicas —
   el mecanismo data-toggle=tab de Bootstrap no se toca, solo el layout
   del <ul class="nav-tabs">. */
@media (max-width: 620px) {
    .bt-dv-bulk-tabs {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .bt-dv-bulk-tabs .nav-item { flex: 0 0 auto; }
}

.bt-dv-bulk-back { margin-top: 16px; text-align: center; }

/* ============================================================
   domain-pricing.tpl — pagina comercial, prioridad alta
   ============================================================ */
.bt-dv-pricing-featured {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
    margin-bottom: 22px;
}
.bt-dv-pricing-featured-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 18px 12px;
    text-align: center;
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
}
.bt-dv-pricing-featured-img { height: 40px; display: flex; align-items: center; }
.bt-dv-pricing-featured-img img { max-height: 40px; max-width: 100%; }
.bt-dv-pricing-featured-price {
    font-size: 13.5px;
    font-weight: 500;
    color: var(--bt-text);
}
@media (max-width: 760px) {
    .bt-dv-pricing-featured { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 420px) {
    .bt-dv-pricing-featured { grid-template-columns: 1fr; }
}

.bt-dv-pricing-currency { text-align: right; margin-bottom: 12px; }
.bt-dv-pricing-currency select {
    height: 40px;
    padding: 0 12px;
    font-family: var(--bt-font);
    font-size: 13.5px;
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-sm);
    background: var(--bt-surface);
    color: var(--bt-text);
}

.bt-dv-pricing-h4 {
    font-size: 15px;
    font-weight: 500;
    margin: 0 0 10px;
}

.bt-dv-tldchips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 20px;
}
.bt-dv-tldchip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 6px 14px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--bt-text-2);
    background: var(--bt-surface);
    border: 1px solid var(--bt-border);
    border-radius: 999px;
    text-decoration: none;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.bt-dv-tldchip:hover {
    color: var(--bt-primary);
    border-color: var(--bt-primary);
    text-decoration: none;
}
/* .badge-success: clase que el JS nativo ANADE/QUITA al hacer click
   (ver comentario del contrato en domain-pricing.tpl) — se reusa como
   selector de estado activo, no se inventa una clase nueva para eso. */
.bt-dv-tldchip.badge-success {
    color: #fff;
    background: var(--bt-primary);
    border-color: var(--bt-primary);
}
.bt-dv-tldchip-count { opacity: .75; font-weight: 400; }

/* Tabla de precios: 7 columnas (TLD + categoria + 5 de precio/plazos) no
   caben en 390px — scroll horizontal CONTENIDO (nunca desborda la
   pagina) con la 1a columna (TLD) fija via position:sticky para no
   perder el contexto al desplazar. La tabla y su maquinaria DataTables
   no se tocan, solo el contenedor. */
.bt-dv-pricing-tablewrap {
    border: 1px solid var(--bt-border);
    border-radius: var(--bt-radius-lg);
    box-shadow: var(--bt-shadow);
    -webkit-overflow-scrolling: touch;
}
.bt-dv-pricing-tablewrap table.table-list {
    margin: 0;
    font-size: 13px;
}
.bt-dv-pricing-tablewrap table.table-list th,
.bt-dv-pricing-tablewrap table.table-list td {
    white-space: nowrap;
    vertical-align: middle;
    padding: 10px 14px;
}
.bt-dv-pricing-tablewrap table.table-list th {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--bt-text-3);
    text-transform: uppercase;
    letter-spacing: .02em;
    background: var(--bt-bg);
}
.bt-dv-pricing-tablewrap table.table-list td:first-child,
.bt-dv-pricing-tablewrap table.table-list th:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--bt-surface);
    font-weight: 500;
    box-shadow: 1px 0 0 var(--bt-border);
}
.bt-dv-pricing-tablewrap table.table-list td small {
    color: var(--bt-text-3);
}

.bt-dv-hot {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 8px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .02em;
    color: #fff;
    background: var(--bt-red);
    border-radius: 999px;
    vertical-align: middle;
}
