body {
    background-color: #f4f6fb;
}

body .navbar ~ .container-fluid {
    margin-top: 0.5rem;
}

/* Estilos para mensajes de error de validación */
.invalid-feedback {
    color: #dc3545 !important;
    font-size: 0.875rem;
    margin-top: 0.25rem;
}

.form-control.is-invalid {
    border-color: #dc3545;
    box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
}

.form-control.is-invalid:focus {
    border-color: #dc3545;
    box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
}

.tb-start-admin .form-control:disabled,
.tb-start-admin .form-control[disabled] {
    cursor: not-allowed;
}

/* Estilo para tarjetas de formulario */
.form-card {
    background: white;
    border-radius: 15px;
    box-shadow: 0 5px 20px rgba(0,0,0,0.1);
    padding: 2rem;
}

/* Estilos de botones reutilizables */
.btn-primary {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    border: none;
    border-radius: 10px;
    color: white;
}

.btn-secondary {
    border-radius: 10px;
}

/* Estilos para botones de radio como botones con check */
.delivery-type-options,
.service-type-options,
.deposit-owner-options {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 15px;
}

/* Radios ocultos pero ENFOCABLES por teclado (no display:none, que los saca del
   tab order). El estado se ve en el label vía :checked + label. */
.delivery-type-options input[type="radio"],
.service-type-options input[type="radio"],
.deposit-owner-options input[type="radio"] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.delivery-type-options label,
.service-type-options label,
.deposit-owner-options label {
    display: inline-block;
    padding: 8px 32px 8px 16px; /* Aumentado el padding derecho para dar espacio al checkmark */
    background-color: #f8f9fa;
    border: 2px solid #dee2e6;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s ease;
    position: relative;
    font-weight: 500;
    margin: 0;
}

.delivery-type-options label:hover,
.service-type-options label:hover,
.deposit-owner-options label:hover {
    background-color: #e9ecef;
    border-color: #adb5bd;
}

.delivery-type-options input[type="radio"]:checked + label,
.service-type-options input[type="radio"]:checked + label,
.deposit-owner-options input[type="radio"]:checked + label {
    background-color: #0d6efd;
    border-color: #0d6efd;
    color: white;
}

.delivery-type-options input[type="radio"]:checked + label::after,
.service-type-options input[type="radio"]:checked + label::after,
.deposit-owner-options input[type="radio"]:checked + label::after {
    content: '✓';
    position: absolute;
    right: 12px; /* Aumentado de 8px a 12px para más separación */
    top: 50%;
    transform: translateY(-50%);
    font-weight: bold;
    font-size: 14px;
}

/* Foco de teclado sobre el radio oculto → anillo violeta en su label */
.delivery-type-options input[type="radio"]:focus-visible + label,
.service-type-options input[type="radio"]:focus-visible + label,
.frequency-options input[type="radio"]:focus-visible + label,
.deposit-owner-options input[type="radio"]:focus-visible + label {
    outline: 2px solid #6f42c1;
    outline-offset: 2px;
}

/* El anillo lo pinta el label; el radio en sí (visually-hidden) no lleva outline
   propio, si no el global :focus-visible dejaría una mota al lado. */
.delivery-type-options input[type="radio"]:focus-visible,
.service-type-options input[type="radio"]:focus-visible,
.frequency-options input[type="radio"]:focus-visible,
.deposit-owner-options input[type="radio"]:focus-visible {
    outline: none !important;
}

/* Estilos para el campo de frecuencia */
.frequency-field {
    transition: all 0.3s ease;
}

.frequency-row {
    transition: all 0.3s ease;
}

.frequency-row.show {
    display: block !important;
}

/* Estilos corregidos para los botones de radio de frecuencia */
.frequency-options {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 15px;
}

.frequency-options input[type="radio"] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.frequency-options label {
    display: inline-block;
    padding: 8px 16px;
    background-color: #f8f9fa;
    border: 2px solid #dee2e6;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s ease;
    position: relative;
    font-weight: 500;
    margin: 0;
    min-width: 80px;
    text-align: center;
}

.frequency-options label:hover {
    background-color: #e9ecef;
    border-color: #adb5bd;
}

.frequency-options input[type="radio"]:checked + label {
    background-color: #28a745;
    border-color: #28a745;
    color: white;
}

.frequency-options input[type="radio"]:checked + label::after {
    content: '✓';
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    font-weight: bold;
    font-size: 12px;
}

.frequency-message {
    margin-top: 10px;
    padding: 8px 12px;
    border-radius: 4px;
}

/* Ocultar el radio button "None" que aparece por defecto */
.frequency-options input[value=""] + label {
    display: none;
}

.hide {
    display: none !important;
}

.select2-dropdown.tb-select2-services-dropdown .select2-results__group {
    display: block;
    padding: 0.35rem 0.75rem;
    background-color: #f1f3f5;
    color: #495057;
    font-weight: 700;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    cursor: default;
}

/* Reset estructural: el theme bootstrap-5 identifica los wrappers de grupo con
   [role=group] (no con la clase BEM --group). Forzamos layout de bloque y reseteamos
   altura/padding del wrapper para que no desfase los items hijos. */
.select2-dropdown.tb-select2-services-dropdown .select2-results__option[role=group],
.select2-dropdown.tb-select2-services-dropdown .select2-results__option--group {
    padding: 0;
    min-height: 0;
    display: block;
}

.select2-dropdown.tb-select2-services-dropdown .select2-results__options,
.select2-dropdown.tb-select2-services-dropdown .select2-results__options--nested {
    display: block;
    margin: 0;
    padding: 0;
    list-style: none;
}

.select2-dropdown.tb-select2-services-dropdown .select2-results__options--nested .select2-results__option {
    padding-left: 1.25rem;
}

/* Fake header de categoría (option disabled con data-is-header="1").
   Forzamos padding 0 en el wrapper de Select2 para que el styling lo provee el contenido. */
.select2-dropdown.tb-select2-services-dropdown .select2-results__option[aria-disabled="true"]:has(.tb-service-header) {
    padding: 0;
    min-height: 0;
    background-color: transparent;
}

.select2-dropdown.tb-select2-services-dropdown .tb-service-header {
    padding: 0.4rem 0.75rem;
    background-color: #f1f3f5;
    color: #495057;
    font-weight: 700;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    cursor: default;
    user-select: none;
}

/* Garantizar altura coherente del item para evitar que items se solapen visualmente.
   IMPORTANTE: excluir los wrappers de grupo ([role=group] / --group) porque contienen
   el <ul> anidado adentro; darles min-height/padding propios desfasa los items hijos. */
.select2-dropdown.tb-select2-services-dropdown .select2-results__option:not([role=group]):not(.select2-results__option--group) {
    padding-top: 6px;
    padding-bottom: 6px;
    min-height: 32px;
    line-height: 1.35;
    font-size: 13px;
    box-sizing: border-box;
}

.select2-dropdown.tb-select2-services-dropdown .tb-service-option {
    min-width: 0;
}

.select2-dropdown.tb-select2-services-dropdown .tb-service-option__label {
    flex: 1 1 auto;
    min-width: 0;
    white-space: normal;
    overflow-wrap: anywhere;
    font-size: 13px;
}

/* Buscador dentro del dropdown de servicios: misma escala que las opciones. */
.select2-dropdown.tb-select2-services-dropdown .select2-search__field {
    font-size: 13px;
}

@media (min-width: 992px) {
    .d-lg-table {
        display: table-cell !important;
    }
}


/* Estilos para el menú offcanvas */
.offcanvas {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
    color: white;
}

.offcanvas-header {
    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

.offcanvas-title {
    color: white !important;
    font-weight: bold;
}

.btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

/* El invert de arriba asume header oscuro y deja la X blanca → invisible sobre headers
   claros. El modal de video del onboarding tiene header blanco, así que restauramos la
   X oscura (mismo patrón que #appointmentModal). */
#tbVideoModal .btn-close {
    filter: none;
    opacity: 0.8;
}
#tbVideoModal .btn-close:hover {
    opacity: 1;
}

/* Estilos para los enlaces del menú lateral.
   #sidebarMenu se incluye porque el sidebar pasó de .offcanvas a .offcanvas-md. */
.offcanvas .nav-link,
#sidebarMenu .nav-link {
    color: rgba(255, 255, 255, 0.8) !important;
    padding: 12px 16px;
    border-radius: 8px;
    margin: 4px 0;
    transition: all 0.3s ease;
    display: flex;
    align-items: center;
}

.offcanvas .nav-link:hover,
#sidebarMenu .nav-link:hover {
    background-color: rgba(255, 255, 255, 0.1);
    color: white !important;
    transform: translateX(5px);
}

.offcanvas .nav-link.active,
#sidebarMenu .nav-link.active {
    background-color: rgba(255, 255, 255, 0.2);
    color: white !important;
    font-weight: bold;
}

.offcanvas .nav-link i,
#sidebarMenu .nav-link i {
    margin-right: 12px;
    width: 20px;
    text-align: center;
}

/* Estilo para la navbar principal */
.navbar {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.navbar-toggler {
    padding: 8px;
}

/* Accesibilidad — foco visible por teclado (WCAG 2.4.7). :focus-visible no se
   dispara con click/tap, así que el anillo violeta solo aparece navegando con
   teclado y no molesta al usuario de mouse. */
/* !important para vencer supresiones de framework (Bootstrap hace
   .form-control:focus { outline: 0 }) y garantizar el anillo en TODO control. */
:focus-visible {
    outline: 2px solid #6f42c1 !important;   /* anillo violeta sobre fondo claro */
    outline-offset: 2px !important;
}

/* Sobre superficies de marca (violeta) el anillo va en blanco para que contraste
   (el outline cae fuera del control, sobre el fondo del contenedor). */
/* Superficies de marca violeta (la topbar ya es blanca → usa el anillo violeta). */
#sidebarMenu :focus-visible,
.table-header :focus-visible,
.ob-header :focus-visible {
    outline-color: #fff !important;
}

.navbar-toggler:focus {
    box-shadow: none;             /* click no deja anillo; el de teclado lo da :focus-visible */
}

/* Dropdown del usuario - evitar cambios en height del navbar */
.navbar .dropdown-menu {
    position: absolute !important;
    top: 100% !important;
    right: 0 !important;
    left: auto !important;
    z-index: 1050;
    margin-top: 0.5rem;
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    border: 1px solid rgba(0, 0, 0, 0.1);
}

.navbar .dropdown {
    position: relative;
}

.table-modern {
    margin: 0;
    background: transparent;
}

.table-modern thead th {
    background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
    border: none;
    padding: 1.2rem 1rem;
    font-weight: 700;
    color: #495057;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-size: 0.85rem;
}

.table-modern tbody td {
    padding: 1rem;
    border: none;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    vertical-align: middle;
}

.table-modern tbody tr {
    transition: all 0.3s ease;
}

.table-modern tbody tr:hover {
    background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}


/* Card de tabla moderna */
.table-card {
    background: white;
    border-radius: 25px;
    overflow: hidden;
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    backdrop-filter: blur(10px);
}

.table-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 1.5rem 2rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.table-header h4 {
    margin: 0;
    font-weight: 700;
    font-size: 1.3rem;
}


.header,
.table-card,
.empty-state-modern {
    animation: fadeInUp 0.6s ease-out;
}

/* Estado vacío moderno */
.empty-state-modern {
    background: white;
    border-radius: 25px;
    padding: 4rem 2rem;
    text-align: center;
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    backdrop-filter: blur(10px);
}

.btn-primary-modern {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    border: none;
    border-radius: 15px;
    padding: 1rem 2rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1px;
    transition: all 0.3s ease;
    box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
}

.btn-primary-modern:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 35px rgba(102, 126, 234, 0.4);
    background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}


/* Input de búsqueda en header */
.search-input-header {
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 25px;
    padding: 0.75rem 1rem 0.75rem 3rem;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(10px);
    transition: all 0.3s ease;
    width: 250px;
}

.search-input-header:focus {
    border-color: rgba(255, 255, 255, 0.8);
    background: white;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    /* sin outline:none — el foco de teclado lo pinta :focus-visible (anillo blanco en la topbar) */
}


/* ACTION BTS */
/* Botones de acción */
.action-btn {
    width: 35px;
    height: 35px;
    border-radius: 10px;
    border: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0 0.25rem;
    transition: all 0.3s ease;
    font-size: 0.9rem;
}

.btn-view {
    background: linear-gradient(135deg, #17a2b8 0%, #138496 100%);
    color: white;
}

.btn-edit {
    background: linear-gradient(135deg, #ffc107 0%, #e0a800 100%);
    color: white;
}

.btn-delete {
    background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
    color: white;
}

.action-btn:hover {
    transform: translateY(-2px) scale(1.05);
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

/* MODAL */
.modal-header.bg-success {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

/* Modales que tenían header claro (con la X invisible por el filter global de
   .btn-close) → header violeta y X blanca visible, consistente con el resto. */
#cancelAppointmentModal .modal-header,
#personCancelPackAppointmentModal .modal-header,
#entityModal .modal-header,
#appointmentModal .modal-header,
#newClinicalNoteModal .modal-header,
#appointmentNoteModal .modal-header,
#deleteNoteModal .modal-header,
#removeAllServicesModal .modal-header,
#serviceDaysModal .modal-header,
[id^="editClinicalNoteModal"] .modal-header,
[id^="patientPack"] .modal-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: #fff;
    border-bottom: none;
    border-radius: 16px 16px 0 0;
}
#cancelAppointmentModal .modal-header .modal-title,
#personCancelPackAppointmentModal .modal-header .modal-title,
#entityModal .modal-header .modal-title,
#appointmentModal .modal-header .modal-title,
#newClinicalNoteModal .modal-header .modal-title,
#appointmentNoteModal .modal-header .modal-title,
#deleteNoteModal .modal-header .modal-title,
#removeAllServicesModal .modal-header .modal-title,
#serviceDaysModal .modal-header .modal-title,
[id^="editClinicalNoteModal"] .modal-header .modal-title,
[id^="patientPack"] .modal-header .modal-title {
    color: #fff;
}
/* El header violeta redondea sus esquinas superiores 16px, pero el .modal-content
   traía el radio por defecto (~8px) → asomaba el fondo blanco en las esquinas
   (el «reborde blanco»). Igualamos el radio del content y recortamos el sobrante. */
#cancelAppointmentModal .modal-content,
#personCancelPackAppointmentModal .modal-content,
#newClinicalNoteModal .modal-content,
#appointmentNoteModal .modal-content,
#deleteNoteModal .modal-content,
#removeAllServicesModal .modal-content,
#serviceDaysModal .modal-content,
[id^="editClinicalNoteModal"] .modal-content {
    border-radius: 16px;
    overflow: hidden;
}
/* Solo radius (sin overflow:hidden) para no clipar dropdowns/select2 del contenido
   AJAX; el header también redondea 16px, así que las esquinas igual quedan prolijas. */
#entityModal .modal-content,
#appointmentModal .modal-content,
[id^="patientPack"] .modal-content { border-radius: 16px; }

/* ── Footer ESTÁNDAR de los modales de #entityFormModal (cliente, local, servicio…) ──
   Botonera SIEMPRE en 1 línea (Bootstrap .modal-footer envuelve por defecto → en
   celular apilaba). En desktop es un .modal-footer normal al pie (alineado a la
   derecha). En hoja completa (mobile) se fija STICKY AL RAS: el footer queda
   siempre visible y el contenido del medio scrollea.
   Uso: <div class="modal-footer tb-form-footer">Cancelar + Guardar</div> */
.tb-form-footer { flex-wrap: nowrap; }
.tb-form-footer .btn { white-space: nowrap; }
@media (max-width: 767.98px) {
    /* Hoja completa: esquinas al ras y el body sin padding inferior para que el
       footer sticky quede pegado al borde (sin franja transparente). */
    #entityFormModal .modal-content { border-radius: 0 !important; }
    #entityFormBody { padding-bottom: 0 !important; }
    #entityFormModal .modal-footer.tb-form-footer {
        position: sticky;
        bottom: 0;
        background: #fff;
        border-top: 1px solid #eef0f4;
        margin: 0 -1.5rem;
        padding: 0.85rem 1.25rem calc(0.85rem + env(safe-area-inset-bottom));
        z-index: 3;
    }
}
@media (max-width: 400px) {
    .tb-form-footer .btn { padding: 8px 12px; font-size: 0.9rem; }
}

.action-buttons {
    display: flex;
}

.modal.show .modal-dialog.modal-xl {
    max-width: 80%;
    margin: auto;
}

@media (max-width: 992px) {
    .hide-lg {
        display: none !important;
    }
}
@media (max-width: 768px) {
    .hide-md {
        display: none !important;
    }
}
@media (max-width: 576px) {
    .hide-sm {
        display: none !important;
    }
    .table-modern thead th {
        padding: 10px;
    }
}
@media (max-width: 460px) {
    .action-buttons {
        flex-direction: column;
    }
    .navbar-brand .logo-container span {
        display: none;
    }
    .modal.show .modal-dialog.modal-xl {
        max-width: 90%;
    }
}

.beauty-card {
    border-radius: 15px;
    box-shadow: 0 10px 20px rgba(0,0,0,0.1);
    border: none;
    transition: transform 0.3s ease;
}
.beauty-card:hover {
    transform: translateY(-5px);
}
.btn-beauty {
    /* Violeta de marca (mismo que los CTAs primarios del onboarding) en vez del rosa, que
       leía como alerta para un CTA positivo ("compartí tu link para recibir citas"). */
    background: linear-gradient(135deg, #667eea, #764ba2);
    border: none;
    border-radius: 8px;
    padding: 10px 20px;
    font-weight: 600;
    color: white;
    transition: all 0.3s;
    height: 68px;
}
.btn-beauty:hover {
    background: linear-gradient(135deg, #764ba2, #667eea);
    transform: scale(1.05);
    color: white;
}

.tb-payment-banner {
    background: #dc3545;
    color: #fff;
    padding: 10px 16px;
    font-size: 14px;
    line-height: 1.4;
    box-shadow: 0 2px 6px rgba(0,0,0,.15);
}
.tb-payment-banner-inner {
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}
.tb-payment-banner-cta {
    color: #fff;
    background: rgba(0,0,0,.18);
    border: 1px solid rgba(255,255,255,.35);
    padding: 6px 12px;
    border-radius: 999px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    margin-left: auto;
    transition: background .15s ease;
}
.tb-payment-banner-cta:hover {
    color: #fff;
    background: rgba(0,0,0,.32);
}
@media (max-width: 576px) {
    .tb-payment-banner { font-size: 13px; }
    /* Apilado da 44px de alto real; al lado del texto quedaba de 90px de ancho y no se podía
       tocar bien. */
    .tb-payment-banner-cta { margin-left: 0; width: 100%; text-align: center; padding: 11px 12px; }
}

/* Banner de trial (amarillo) */
.tb-trial-banner {
    background: #ffc107;
    color: #4d3800;
    padding: 10px 16px;
    font-size: 14px;
    line-height: 1.4;
    box-shadow: 0 2px 6px rgba(0,0,0,.12);
}
.tb-trial-banner-inner {
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}
/* El texto empuja el CTA + la X a la derecha, haya o no CTA. */
.tb-trial-banner-inner > span {
    margin-right: auto;
}
.tb-trial-banner-cta {
    color: #4d3800;
    background: rgba(0,0,0,.10);
    border: 1px solid rgba(0,0,0,.20);
    padding: 6px 12px;
    border-radius: 999px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: background .15s ease;
}
.tb-trial-banner-cta:hover {
    color: #4d3800;
    background: rgba(0,0,0,.18);
}
.tb-trial-banner-close {
    background: transparent;
    border: none;
    color: #4d3800;
    opacity: .7;
    cursor: pointer;
    padding: 4px 6px;
    line-height: 1;
    font-size: 16px;
}
.tb-trial-banner-close:hover { opacity: 1; }
@media (max-width: 576px) {
    .tb-trial-banner { font-size: 13px; }
    /* Línea completa: al lado del texto el tap target queda demasiado angosto. */
    .tb-trial-banner-cta { margin-left: 0; width: 100%; text-align: center; padding: 10px 12px; }
}

.tb-wa-wrap {
    position: fixed;
    right: 0;
    bottom: 20px;
    z-index: 1030;
}
.tb-wa-btn {
    position: relative;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: #25D366;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    box-shadow: 0 6px 16px rgba(0,0,0,.2);
    transition: transform .15s ease, box-shadow .15s ease;
}
.tb-wa-btn::before {
    content: attr(data-label);
    position: absolute;
    right: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    background: rgba(255, 255, 255, 0.96);
    color: #075E54;
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 999px;
    padding: 6px 10px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 6px 14px rgba(0,0,0,.15);
    pointer-events: none;
    opacity: 0;
    transition: opacity .15s ease;
}
.tb-wa-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 22px rgba(0,0,0,.25);
}
@media (hover: hover) {
    .tb-wa-btn:hover::before { opacity: 1; }
}
.tb-wa-icon {
    color: #fff;
    font-size: 22px;
    line-height: 1;
}
body.modal-open .tb-wa-wrap { display: none; }
/* Mobile logueado (con bottom nav): el soporte por WhatsApp vive dentro de "Más",
   así que ocultamos el flotante para no amontonar el borde inferior. En páginas
   anónimas (sin bottom nav) el flotante se mantiene. */
@media (max-width: 767.98px) {
    body:has(.tb-bottom-nav) .tb-wa-wrap { display: none; }
}
@media (max-width: 480px) {
    .tb-wa-wrap { bottom: 14px; }
    .tb-wa-btn { width: 44px; height: 44px; }
    .tb-wa-icon { font-size: 20px; }
}

/* ===== ONBOARDING PANEL STYLES ===== */

/* ---------- Toggle button ---------- */
#onboardingToggleDesktop,
#onboardingToggleMobile {
    background: linear-gradient(135deg, #ff8f1f 0%, #ff5e3a 100%);
    color: white;
    border: none;
    border-radius: 8px;
    font-weight: 700;
    font-size: 0.8rem;
    box-shadow: 0 2px 12px rgba(255, 110, 40, 0.6);
}

.onboarding-progress-circle {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(255,255,255,0.25);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 10px;
    font-weight: 700;
    flex-shrink: 0;
}

/* Nombre propio (no "pulse" genérico, que choca con otros @keyframes) y suma un leve
   scale al glow para que el latido se note (solo box-shadow se veía casi estático). */
@keyframes tb-onboarding-pulse {
  0%   { transform: scale(1);    box-shadow: 0 2px 12px rgba(255,110,40,0.5); }
  50%  { transform: scale(1.06); box-shadow: 0 5px 22px rgba(255,110,40,0.9); }
  100% { transform: scale(1);    box-shadow: 0 2px 12px rgba(255,110,40,0.5); }
}
#onboardingToggleDesktop,
#onboardingToggleMobile {
  animation: tb-onboarding-pulse 2s infinite ease-in-out;
}

/* El de mobile ocupa TODO el ancho (`w-100`), así que escalarlo un 6% lo saca del viewport: la
   página entera queda scrolleando de costado 7px en cada pantalla del panel mientras la empresa
   está en onboarding. Ahí late sólo con el glow, que es lo que se ve igual. */
@keyframes tb-onboarding-pulse-glow {
  0%   { box-shadow: 0 2px 12px rgba(255,110,40,0.5); }
  50%  { box-shadow: 0 5px 22px rgba(255,110,40,0.9); }
  100% { box-shadow: 0 2px 12px rgba(255,110,40,0.5); }
}
#onboardingToggleMobile {
  animation-name: tb-onboarding-pulse-glow;
}

/* ---------- Panel ---------- */
.onboarding-panel {
    position: fixed;
    top: 56px;
    right: -420px;
    width: 400px;
    max-height: calc(100vh - 60px);
    background: #f8f9fc;
    box-shadow: -6px 0 32px rgba(0,0,0,0.14);
    z-index: 1050;
    transition: right 0.32s cubic-bezier(0.4, 0, 0.2, 1);
    overflow-y: auto;
    overflow-x: hidden;
    display: flex;
    flex-direction: column;
}

.onboarding-panel.active { right: 0; }

/* ---------- Header ---------- */
.ob-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    padding: 1.25rem 1.25rem 1rem;
    position: sticky;
    top: 0;
    z-index: 10;
    flex-shrink: 0;
}

.ob-header-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 0.875rem;
}

.ob-title {
    color: white;
    font-weight: 700;
    font-size: 1.05rem;
    margin: 0 0 3px 0;
}

.ob-subtitle {
    color: rgba(255,255,255,0.8);
    font-size: 0.775rem;
    margin: 0;
    line-height: 1.4;
}

.ob-close-btn {
    background: rgba(255,255,255,0.2);
    border: none;
    color: white;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
    font-size: 0.85rem;
    transition: background 0.15s;
    margin-left: 0.5rem;
}
.ob-close-btn:hover { background: rgba(255,255,255,0.35); }

.ob-progress-row {
    display: flex;
    align-items: center;
    gap: 0.625rem;
}

.ob-progress-bar-wrap {
    flex: 1;
    height: 6px;
    background: rgba(255,255,255,0.25);
    border-radius: 99px;
    overflow: hidden;
}

.ob-progress-bar-fill {
    height: 100%;
    background: white;
    border-radius: 99px;
    transition: width 0.55s cubic-bezier(0.4, 0, 0.2, 1);
}

.ob-progress-label {
    color: white;
    font-size: 0.75rem;
    font-weight: 700;
    white-space: nowrap;
    min-width: 28px;
    text-align: right;
}

/* ---------- Steps list ---------- */
.ob-steps {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* ---------- Step base ---------- */
.ob-step {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: white;
    border: 1.5px solid #e5e7eb;
    border-radius: 12px;
    padding: 0.875rem 1rem;
    transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s, opacity 0.2s;
    position: relative;
}

/* ---------- Step number badge ---------- */
.ob-step-num {
    position: absolute;
    top: -8px;
    left: 12px;
    background: #6b7280;
    color: white;
    font-size: 0.6rem;
    font-weight: 700;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid #f8f9fc;
}

/* ---------- Step icon ---------- */
.ob-step-icon {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.9rem;
    flex-shrink: 0;
    background: #f3f4f6;
    color: #5b6373;
}

/* ---------- Step body ---------- */
.ob-step-body {
    flex: 1;
    min-width: 0;
}

.ob-step-title {
    font-weight: 600;
    font-size: 0.85rem;
    color: #1f2937;
    line-height: 1.3;
    margin-bottom: 2px;
}

.ob-step-desc {
    font-size: 0.72rem;
    color: #5b6373;
    line-height: 1.3;
}

.ob-step-time {
    font-size: 0.68rem;
    color: #c4b5fd;
    margin-top: 3px;
    display: none;
}

/* ---------- Step button ---------- */
.ob-step-btn {
    flex-shrink: 0;
    font-size: 0.75rem;
    padding: 0.3rem 0.8rem;
    border-radius: 6px;
    font-weight: 600;
    min-width: 60px;
    text-align: center;
    white-space: nowrap;
}

/* ---------- State: done ---------- */
.ob-step--done {
    background: #f0fdf4;
    border-color: #bbf7d0;
}
.ob-step--done .ob-step-num { background: #22c55e; }
.ob-step--done .ob-step-icon { background: #dcfce7; color: #16a34a; }
.ob-step--done .ob-step-title { color: #15803d; }
.ob-step--done .ob-step-desc { color: #86efac; }

/* ---------- State: current (next step to do) ---------- */
.ob-step--current {
    border-color: #667eea;
    box-shadow: 0 4px 16px rgba(102,126,234,0.18);
    transform: none;
}
.ob-step--current .ob-step-num { background: linear-gradient(135deg,#667eea,#764ba2); }
.ob-step--current .ob-step-icon {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    box-shadow: 0 2px 8px rgba(102,126,234,0.35);
}
.ob-step--current .ob-step-title { color: #4338ca; }
.ob-step--current .ob-step-desc { color: #6b7280; }
.ob-step--current .ob-step-time { display: block; }
.ob-step--current:hover {
    box-shadow: 0 6px 20px rgba(102,126,234,0.25);
    transform: translateY(-1px);
}

/* ---------- State: locked ---------- */
.ob-step--locked {
    opacity: 0.45;
    cursor: default;
}
.ob-step--locked .ob-step-icon { background: #f3f4f6; color: #d1d5db; }
.ob-step--locked .ob-step-title { color: #5b6373; }
.ob-step--locked .ob-step-time { display: none !important; }

/* ---------- State: completed (dinamically set) ---------- */
.ob-step--done-dyn {
    background: #f0fdf4;
    border-color: #bbf7d0;
}
.ob-step--done-dyn .ob-step-num { background: #22c55e; }
.ob-step--done-dyn .ob-step-icon { background: #dcfce7; color: #16a34a; }
.ob-step--done-dyn .ob-step-title { color: #15803d; }

/* ---------- Cierre: lo que queda después del onboarding ----------
   Aparece recién con los pasos completos. No es un paso más (no lleva número ni ✓): es el
   traspaso del panel al trabajo que sigue, que es donde el producto empieza a servir. */
.ob-next {
    margin: 16px;
    padding: 16px;
    border: 1px solid #ddd6fe;
    border-radius: 12px;
    background: linear-gradient(180deg, #f5f3ff 0%, #ffffff 100%);
}
.ob-next__title {
    font-weight: 700;
    font-size: 1.05rem;
    color: #4c1d95;
    margin-bottom: 4px;
}
.ob-next__desc {
    font-size: .9rem;
    color: #475569;
    margin-bottom: 10px;
}
.ob-next__list {
    margin: 0 0 14px;
    padding-left: 18px;
    font-size: .9rem;
    color: #334155;
}
.ob-next__list li + li {
    margin-top: 8px;
}

/* ---------- WhatsApp bot tip ---------- */
.ob-bot-tip {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    background: rgba(37, 211, 102, 0.10);
    border-top: 1px solid rgba(37, 211, 102, 0.25);
    padding: 14px 16px;
}
.ob-bot-tip-icon {
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: #25D366;
    color: #fff;
    font-size: 17px;
}
.ob-bot-tip-body { flex: 1; min-width: 0; }
.ob-bot-tip-title {
    font-size: 0.82rem;
    font-weight: 700;
    color: #15803d;
    margin-bottom: 2px;
}
.ob-bot-tip-desc {
    font-size: 0.78rem;
    color: #6b7280;
    line-height: 1.4;
    margin-bottom: 6px;
}
.ob-bot-tip-link {
    font-size: 0.78rem;
    font-weight: 700;
    color: #198754;
    text-decoration: underline;
}
.ob-bot-tip-link:hover { color: #146c43; }

/* ---------- Overlay ---------- */
.onboarding-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15,23,42,0.4);
    z-index: 1040;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}
.onboarding-overlay.active { opacity: 1; visibility: visible; }

/* ---------- Responsive ---------- */
@media (max-width: 768px) {
    .onboarding-panel {
        width: 100%;
        right: -100%;
        top: 56px;
        max-height: calc(100vh - 56px);
        border-radius: 0;
    }
    .ob-step-title { font-size: 0.82rem; }
}

/* ---------- Driver.js overrides ---------- */
.driver-overlay { background-color: rgba(0,0,0,0.18) !important; }

.driver-popover {
    z-index: 999999999 !important;
    box-shadow: 0 8px 32px rgba(0,0,0,0.22) !important;
    border-radius: 12px !important;
    border: none !important;
    min-width: 260px !important;
    max-width: 320px !important;
}

.driver-popover-title {
    font-weight: 700 !important;
    font-size: 0.95rem !important;
    color: #1f2937 !important;
}

.driver-popover-description {
    font-size: 0.84rem !important;
    line-height: 1.55 !important;
    color: #4b5563 !important;
}

.driver-popover-footer { border-top: 1px solid #f3f4f6 !important; padding-top: 10px !important; }

.driver-popover-footer button {
    text-shadow: none !important;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
    color: white !important;
    border: none !important;
    padding: 8px 20px !important;
    border-radius: 7px !important;
    font-weight: 600 !important;
    font-size: 0.82rem !important;
    cursor: pointer !important;
    transition: opacity 0.15s !important;
}
.driver-popover-footer button:hover { opacity: 0.85 !important; }

@keyframes tb-pulse-glow {
    0%,100% { box-shadow: 0 0 0 4px rgba(102,126,234,0.3); }
    50%      { box-shadow: 0 0 0 7px rgba(102,126,234,0.15); }
}

.tb-review-invite-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.25);
    z-index: 20000;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
}

.tb-review-invite-backdrop.show {
    opacity: 1;
    pointer-events: auto;
}

.tb-review-invite-panel {
    position: fixed;
    z-index: 20001;
    opacity: 0;
    transform: translateY(6px);
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
}

.tb-review-invite-panel.show {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.tb-review-invite-panel.is-mobile {
    left: 12px;
    right: 12px;
    bottom: 12px;
    top: auto;
}

.tb-review-invite-card {
    background: white;
    border-radius: 16px;
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.18);
    border: 1px solid rgba(15, 23, 42, 0.08);
    overflow: hidden;
    min-width: 280px;
}

.tb-review-invite-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px;
    border-bottom: 1px solid rgba(15, 23, 42, 0.06);
}

.tb-review-invite-title {
    font-weight: 700;
    font-size: 18px;
}

.tb-review-invite-close {
    border: none;
    background: transparent;
    color: #64748b;
    padding: 6px 8px;
    border-radius: 10px;
}

.tb-review-invite-option {
    width: 100%;
    border: none;
    background: transparent;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
}

.tb-review-invite-option:active {
    background: rgba(15, 23, 42, 0.04);
}

.tb-review-invite-icon {
    width: 44px;
    height: 36px;
    border-radius: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
}

.tb-review-invite-icon.whatsapp {
    background: linear-gradient(135deg, #25D366 0%, #128C7E 100%);
    color: white;
}

.tb-review-invite-icon.link {
    background: rgba(148, 163, 184, 0.22);
    color: #0f172a;
}

.tb-review-invite-label {
    font-weight: 600;
    font-size: 18px;
    color: #0f172a;
}

.tb-toast {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: 92px;
    background: rgba(15, 23, 42, 0.92);
    color: white;
    padding: 10px 14px;
    border-radius: 12px;
    z-index: 25000;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    /* Envuelve en varias líneas en vez de recortar con «…».
       Antes era `white-space: nowrap` + `text-overflow: ellipsis`, o sea UNA línea: en 375px un
       aviso de 298 caracteres necesitaba 2200px de ancho y se veían 48 (medido). Todo lo que los
       avisos del destacado explican —que falta la foto, cuál ocupa la portada, cuáles son los dos
       destacados que hay que destildar— quedaba del otro lado de los puntos suspensivos.
       Un toast corto se ve idéntico: entra en una línea igual. */
    /* `width: max-content` es imprescindible junto con `left: 50%`: sin ancho propio, el ancho
       disponible de un `fixed` que arranca en el 50% es SÓLO lo que queda a la derecha (187px en un
       teléfono de 375), y el aviso largo quedaba de media pantalla de ancho y 366px de alto. Con
       max-content pide lo que necesita y el max-width lo frena. */
    width: max-content;
    max-width: min(calc(100vw - 24px), 460px);
    white-space: normal;
    /* Alineado y no centrado: un aviso de 5 líneas centrado obliga a buscar dónde empieza cada una.
       Un aviso corto se ve igual, porque la caja le queda justa al texto. */
    text-align: start;
    line-height: 1.35;
}

.tb-toast.show {
    opacity: 1;
}

.tb-toast.is-error {
    background: rgba(220, 53, 69, 0.95);
}

.tb-clipboard-helper {
    position: fixed;
    top: -1000px;
    left: -1000px;
}

.tb-preview-mobile {
    display: flex;
    justify-content: center;
}
.tb-device-frame {
    position: relative;
    width: 100%;
    max-width: 380px;
    aspect-ratio: 9 / 19.5;
    border-radius: 24px;
    overflow: hidden;
    box-shadow: 0 18px 48px rgba(15, 23, 42, 0.18);
    border: 1px solid rgba(15, 23, 42, 0.08);
    background: #fff;
}
.tb-device-frame iframe {
    width: 100%;
    height: 100%;
    border: 0;
}
/* Compensar navbar fijo en mobile */
@media (max-width: 991px) {
  .tb-start-admin {
    padding-top: 100px;
  }
}
.tb-start-admin__layout {
    display: grid;
    grid-template-columns: 1fr 380px;
    gap: 24px;
    align-items: start;
}
@media (max-width: 991px) {
  .tb-start-admin__layout {
    grid-template-columns: 1fr;
  }
  .tb-start-admin__preview-column {
    display: none;
  }
}
@media (max-width: 991px) {
  .tb-start-admin {
    padding-top: 80px;
  }
}
.tb-start-admin__preview-column {
    position: sticky;
    top: 72px;
}
.tb-start-admin__preview-btn {
    display: none;
}
@media (max-width: 991px) {
    .tb-start-admin__layout {
        grid-template-columns: 1fr;
    }
    .tb-start-admin__preview-column {
        display: none;
    }
    .tb-start-admin__preview-btn {
        display: inline-flex;
        align-items: center;
        gap: 6px;
    }
  .tb-start-admin__main {
    width: 100%;
    min-width: 0;
  }
}

/* Editor start-page: estilo visual compacto */
.tb-style-option {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 14px;
    border: 1px solid rgba(15,23,42,.12);
    border-radius: 12px;
    cursor: pointer;
    user-select: none;
    background: #fff;
    color: #0f172a;
    font-weight: 600;
}
.tb-style-option.is-selected {
    border-color: var(--primary-color);
    box-shadow: 0 6px 16px rgba(15,23,42,.08);
}
.tb-style-option__input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.tb-style-option__label {
    display: inline-block;
}

.tb-color-row { gap: 12px; }
.tb-color-item {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 220px;
    flex: 1 1 220px;
}
.tb-color-row {
    flex-wrap: wrap;
}
@media (max-width: 991px) {
  .tb-color-item {
    min-width: 0;
    flex: 1 1 100%;
  }
}
.tb-color-item__picker {
    display: flex;
    align-items: center;
    gap: 10px;
}
.tb-start-admin {
    max-width: 1320px;
    margin: 0 auto;
    padding: 24px 16px 80px;
}
.tb-sticky-save {
    position: sticky;
    bottom: 0;
    background: var(--bs-body-bg);
    border-top: 1px solid var(--bs-border-color);
    padding: 12px 0;
    text-align: right;
    z-index: 10;
    margin-top: 16px;
}
.tb-color-hex {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
    font-size: 13px;
    color: rgba(15,23,42,.7);
}

/* Secciones ordenables */
.tb-sortable-item {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 6px;
    margin-bottom: 4px;
    border: 1px solid transparent;
    transition: background 0.1s, border-color 0.1s;
}
.tb-drag-handle {
    cursor: grab;
    color: #adb5bd;
    padding-top: 2px;
    flex-shrink: 0;
}
.tb-drag-handle:active {
    cursor: grabbing;
}
.tb-sortable-item.is-dragging {
    opacity: 0.4;
}
.tb-sortable-item.drag-over {
    background: rgba(13,110,253,.06);
    border-color: rgba(13,110,253,.25);
}

/* Image upload trigger */
.tb-hidden-file-input {
    width: 0.1px;
    height: 0.1px;
    opacity: 0;
    overflow: hidden;
    position: absolute;
    z-index: -1;
}
.tb-image-add-row {
    display: flex;
    align-items: center;
    gap: 12px;
}
.tb-image-upload-loading {
    display: flex;
    align-items: center;
    gap: 8px;
}
.tb-file-input-wrapper {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.tb-file-select-btn {
    white-space: nowrap;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tb-file-preview {
    align-items: center;
    gap: 8px;
}
.tb-file-preview-img {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid rgba(0, 0, 0, .12);
    flex-shrink: 0;
}
.tb-file-preview-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 160px;
}

/* Galería visual con thumbnails */
.tb-thumb-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}
@media (min-width: 768px) {
    .tb-thumb-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}
.tb-thumb {
    position: relative;
    border-radius: 18px;
    overflow: hidden;
    border: 1px solid rgba(15,23,42,.12);
    background: #fff;
}
.tb-thumb__media {
    aspect-ratio: 16 / 9;
    background: rgba(15,23,42,.04);
}
.tb-thumb__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.tb-thumb__overlay {
    position: absolute;
    bottom: 8px;
    right: 8px;
    display: flex;
    gap: 6px;
}

#sidebarMenu .navbar-nav > li.sidebar-group:first-child .sidebar-group-label {
    margin-top: 0;
}
#sidebarMenu .sidebar-group-label {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.75;
    margin: 20px 0 8px;
    padding: 0 1rem;
}

#sidebarMenu {
    background: var(--tb-sidebar-bg);
    color: rgba(255, 255, 255, 0.92);
    border-right: none;
    /* Offcanvas mobile: 85% del ancho, tope 320px (sobrescribe el default 400px de BS) */
    --bs-offcanvas-width: min(85vw, 320px);
}

#sidebarMenu .offcanvas-header {
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

#sidebarMenu .btn-close {
    filter: invert(1) grayscale(1);
    opacity: 0.9;
}

#sidebarMenu .btn-close:hover {
    opacity: 1;
}

/* Marca del drawer (solo mobile): favicon + "TurnoBoost" en blanco sobre el violeta.
   Oculta en desktop por d-md-none (el topbar ya trae la marca). */
.tb-sidebar-brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 800;
    font-size: 15px;
    color: #fff;
    text-decoration: none;
}
.tb-sidebar-brand:hover { color: #fff; }
.tb-sidebar-brand img { border-radius: 6px; flex-shrink: 0; }

#sidebarMenu .navbar-nav .nav-link {
    color: rgba(255, 255, 255, 0.90);
    border-radius: 12px;
    padding: 10px 12px;
    margin: 4px 10px;
    font-weight: 600;
    display: flex;
    align-items: flex-start;
}

#sidebarMenu .navbar-nav .nav-link i {
    width: 18px;
    margin-right: 10px;
    opacity: 0.95;
    flex-shrink: 0;
    margin-top: 3px;
}

#sidebarMenu .nav-link-content {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

#sidebarMenu .nav-link-desc {
    font-size: 11px;
    font-weight: 400;
    opacity: 0.65;
    margin-top: 2px;
    line-height: 1.3;
}

/* ── Empty state hint ────────────────────────────────────────── */
.tb-empty-hint {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    background: #f8f9ff;
    border: 1px solid #e0e3f5;
    border-radius: 14px;
    padding: 1.25rem 1.5rem;
    margin: 0.5rem 0 1rem;
}

.tb-empty-hint--inline {
    margin: 0.5rem 1rem 0.5rem;
}

.tb-empty-hint__icon {
    width: 40px;
    height: 40px;
    border-radius: 12px;
    background: rgba(79, 70, 229, 0.1);
    color: #4f46e5;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    flex-shrink: 0;
}

.tb-empty-hint__body {
    flex: 1;
}

.tb-empty-hint__title {
    font-weight: 700;
    font-size: 0.95rem;
    color: #212529;
    margin-bottom: 0.35rem;
}

.tb-empty-hint__text {
    font-size: 0.85rem;
    color: #6c757d;
    line-height: 1.5;
    margin-bottom: 0.75rem;
}

/* ── Feature discovery: badge dot in sidebar ────────────────── */
.nav-badge {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #f59e0b;
    margin-left: 5px;
    flex-shrink: 0;
    position: relative;
    top: -1px;
}

/* ── "Beta": una pantalla recién estrenada ──────────────────────
   Chip claro, para que funcione igual sobre el violeta del sidebar y sobre el fondo de
   una pantalla. Dice en texto lo que un puntito no puede decir, y baja la expectativa
   sin esconder nada. */
.tb-beta {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: #fdf1dc;
    color: #8a5b00;
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
}

/* ── Feature discovery: first-visit banner on page ──────────── */
.tb-first-visit-banner {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    background: rgba(79, 70, 229, 0.06);
    border: 1px solid rgba(79, 70, 229, 0.18);
    border-radius: 12px;
    padding: 0.875rem 1rem;
    margin-bottom: 1rem;
}

.tb-fvb-icon {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: rgba(79, 70, 229, 0.12);
    color: #4f46e5;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    flex-shrink: 0;
}

.tb-fvb-body {
    flex: 1;
    min-width: 0;
}

.tb-fvb-title {
    font-weight: 700;
    font-size: 0.875rem;
    color: #212529;
    margin-bottom: 2px;
}

.tb-fvb-text {
    font-size: 0.8rem;
    color: #6c757d;
    line-height: 1.45;
    margin: 0;
}

.tb-first-visit-banner .btn-close {
    flex-shrink: 0;
    opacity: 0.4;
    font-size: 0.7rem;
    margin-top: 2px;
}

.tb-first-visit-banner .btn-close:hover {
    opacity: 0.7;
}

#sidebarMenu .navbar-nav .nav-link:hover {
    background: rgba(255, 255, 255, 0.10);
    color: #ffffff;
}

#sidebarMenu .navbar-nav .nav-link.active {
    background: rgba(255, 255, 255, 0.18);
    color: #ffffff;
}

#sidebarMenu .sidebar-group-label {
    color: rgba(255, 255, 255, 0.75);
    opacity: 1;
}

.tb-website-dropdown {
    min-width: 320px;
}

.tb-website-quick-card {
    border-radius: 12px;
}

.tb-website-quick-icon {
    width: 28px;
    height: 28px;
    background: #eaf4ff;
    color: #1f6feb;
}

.tb-mobile-website-card {
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

.tb-mobile-website-header,
.tb-mobile-website-link {
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.15);
}

.tb-mobile-website-urlbox {
    background: rgba(255, 255, 255, 0.18);
    color: #fff;
    border-radius: 10px;
    padding: 10px 12px;
    margin-top: 8px;
    border: 1px solid rgba(255, 255, 255, 0.25);
}

.tb-mobile-website-wa-icon {
    color: #25D366;
}

/* ═══════════════════════════════════════════════════════════════════
   App shell — navegación primaria como columna fija (≥768) u offcanvas (<768)
   El mismo #sidebarMenu es .offcanvas-md: BS lo trata como offcanvas por
   debajo de 768px y como bloque estático a partir de ahí.
   ═══════════════════════════════════════════════════════════════════ */
:root {
    --tb-topbar-h: 56px;
    --tb-bottom-nav-h: 60px;      /* alto de la bottom nav de mobile; la esquivan otras pantallas */
    --tb-sidebar-w: 216px;        /* expandido  */
    --tb-sidebar-w-icons: 58px;   /* solo íconos */
    --tb-sb-w: 216px;             /* ancho actual del sidebar (lo setea el estado; default expandido) */
    --tb-sidebar-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

/* Topbar fija: siempre visible al scrollear. z entre sidebar (1030) y el backdrop
   del offcanvas (1040) → navbar > sidebar, y el offcanvas la tapa. */
.tb-topbar {
    position: sticky;
    top: 0;
    z-index: 1035;
}

/* Topbar BLANCA (el violeta queda solo para sidebar/offcanvas). */
.navbar.tb-topbar {
    background: #fff !important;          /* vence el gradiente violeta de .navbar */
    border-bottom: 1px solid #e6e8f0;
    box-shadow: none;
    height: var(--tb-topbar-h);          /* altura fija: alinea con el header del sidebar */
}
.navbar.tb-topbar .navbar-nav .nav-link,
.tb-topbar-title {
    color: #1f2430;                       /* contenido oscuro sobre blanco */
}
.navbar.tb-topbar .navbar-nav .nav-link:hover {
    color: #4338ca;                       /* violeta de marca al hover */
}
.tb-topbar-title {
    font-weight: 600;
    font-size: 1.05rem;
    line-height: 1;
}
/* Hamburguesa como botón redondeado suave (per mockup). */
.tb-topbar-toggle {
    border: none;
    background: #f1f0fb;
    border-radius: 10px;
    padding: 8px 10px;
}
.tb-topbar-toggle:hover {
    background: #e7e5f8;
}
/* Marca en el topbar (la hamburguesa se movió al header del sidebar): texto oscuro
   sobre la topbar blanca. */
/* Marca clickable → dashboard, en violeta de marca (para que NO se lea como el
   título de sección/navegación de al lado). */
.tb-topbar-brand { display: inline-flex; align-items: center; text-decoration: none; }
.tb-topbar-brand .logo-container { font-weight: 700; color: #667eea; }
.tb-topbar-brand .logo-container span { color: #667eea; }
.tb-topbar-brand:hover .logo-container span { color: #764ba2; }

/* Un poco de aire entre los controles de la derecha de la topbar (Página de reserva /
   campana / admin) — venían pegados (navbar-nav con gap-0). */
.tb-topbar .content-right { gap: 0.5rem; align-items: center; }
.tb-topbar .content-right .navbar-nav { gap: 0.35rem; }

/* Mobile: mantener la topbar en UNA sola fila (si no, campana + admin se salían fuera
   del header de 56px). Se oculta la marca (ya vive en el sidebar y en la bottom-nav) y
   el título trunca si hace falta. GLOBAL (aplica a todas las páginas). */
@media (max-width: 767.98px) {
    .navbar.tb-topbar > .container { flex-wrap: nowrap; }
    .tb-topbar-brand { display: none; }
    .tb-topbar-title {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}
/* La hamburguesa ahora vive en el header del sidebar (violeta): ícono blanco + fondo translúcido. */
#sidebarMenu .tb-sidebar-toggle { background: rgba(255, 255, 255, 0.15); }
#sidebarMenu .tb-sidebar-toggle:hover { background: rgba(255, 255, 255, 0.28); }
#sidebarMenu .tb-sidebar-toggle .navbar-toggler-icon {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255,255,255,0.9%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}
/* En mobile (offcanvas) la ☰ se oculta y queda solo la X: la mando a la derecha (convención). */
#sidebarMenu .offcanvas-header .btn-close { margin-left: auto; }

.tb-shell {
    align-items: flex-start;      /* que el sidebar no se estire a la altura de main */
}

.tb-main {
    flex: 1 1 auto;
    min-width: 0;                 /* clave: deja que el contenido ancho scrollee, no empuje el sidebar */
    padding-top: 0.5rem;
}

/* ── ≥768px: sidebar como COLUMNA FIJA full-height (logo arriba). El contenido
   (topbar + banners + main) se corre con padding-left = ancho del sidebar, que se
   sincroniza vía --tb-sb-w. El violeta queda solo acá (y en el offcanvas). ── */
@media (min-width: 768px) {
    #sidebarMenu.offcanvas-md {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        width: var(--tb-sb-w);
        overflow-y: auto;
        overflow-x: hidden;
        visibility: visible !important;   /* por si BS deja el estado inicial del offcanvas */
        transform: none !important;
        background: var(--tb-sidebar-bg) !important;   /* vence el transparent!important de BS en ≥md */
        transition: width 0.2s ease;
        z-index: 1030;
    }
    #sidebarMenu.offcanvas-md .offcanvas-body {
        display: block;                   /* BS lo pone flex/padding:0 a ≥md; lo devuelvo a columna */
        flex-grow: 1;
        padding: 0.5rem 0 1rem;
        overflow: visible;
        background: transparent !important;
    }
    /* En desktop el logo del sidebar (offcanvas-header) SÍ se muestra; el botón de
       cerrar es solo para el offcanvas mobile. */
    /* Misma altura que el topbar → su línea inferior queda alineada con la del topbar. */
    #sidebarMenu.offcanvas-md .offcanvas-header {
        display: flex;
        height: var(--tb-topbar-h);
        min-height: var(--tb-topbar-h);
        padding-top: 0;
        padding-bottom: 0;
        align-items: center;
    }
    #sidebarMenu.offcanvas-md .offcanvas-header .btn-close { display: none; }

    /* Correr el contenido para dejar lugar al sidebar fijo. */
    body.tb-app { padding-left: var(--tb-sb-w); transition: padding-left 0.2s ease; }

    /* Ancho actual del sidebar por estado forzado. */
    body.tb-nav-collapsed { --tb-sb-w: var(--tb-sidebar-w-icons); }
    body.tb-nav-expanded  { --tb-sb-w: var(--tb-sidebar-w); }
}

/* Default por breakpoint (sin preferencia): 768–1199 íconos, ≥1200 expandido. */
@media (min-width: 768px) and (max-width: 1199.98px) {
    body:not(.tb-nav-expanded) { --tb-sb-w: var(--tb-sidebar-w-icons); }
}
@media (min-width: 1200px) {
    body:not(.tb-nav-collapsed) { --tb-sb-w: var(--tb-sidebar-w); }
}

@media (prefers-reduced-motion: reduce) {
    #sidebarMenu.offcanvas-md { transition: none; }
    body.tb-app { transition: none; }
}

/* La presentación "modo íconos" se repite en dos @media (colapsado ≥768 y default
   768–1199) a propósito: contextos de media query distintos que CSS plano no puede
   compartir. Que el default lo resuelva el CSS evita el salto visual en la carga. */
@media (min-width: 768px) {
    body.tb-nav-collapsed #sidebarMenu.offcanvas-md .nav-link-content,
    body.tb-nav-collapsed #sidebarMenu.offcanvas-md .sidebar-group-label,
    body.tb-nav-collapsed #sidebarMenu.offcanvas-md .offcanvas-header .logo-container span { display: none; }
    body.tb-nav-collapsed #sidebarMenu.offcanvas-md .offcanvas-header { justify-content: center; padding-left: 0; padding-right: 0; }
    body.tb-nav-collapsed #sidebarMenu.offcanvas-md .navbar-nav .nav-link {
        justify-content: center;
        padding: 10px 0;
        margin: 4px 8px;
    }
    body.tb-nav-collapsed #sidebarMenu.offcanvas-md .navbar-nav .nav-link i {
        margin-right: 0;
        margin-top: 0;
    }
}
@media (min-width: 768px) and (max-width: 1199.98px) {
    body:not(.tb-nav-expanded) #sidebarMenu.offcanvas-md .nav-link-content,
    body:not(.tb-nav-expanded) #sidebarMenu.offcanvas-md .sidebar-group-label,
    body:not(.tb-nav-expanded) #sidebarMenu.offcanvas-md .offcanvas-header .logo-container span { display: none; }
    body:not(.tb-nav-expanded) #sidebarMenu.offcanvas-md .offcanvas-header { justify-content: center; padding-left: 0; padding-right: 0; }
    body:not(.tb-nav-expanded) #sidebarMenu.offcanvas-md .navbar-nav .nav-link {
        justify-content: center;
        padding: 10px 0;
        margin: 4px 8px;
    }
    body:not(.tb-nav-expanded) #sidebarMenu.offcanvas-md .navbar-nav .nav-link i {
        margin-right: 0;
        margin-top: 0;
    }
}

/* ── ≥768px: la columna ya está visible, así que los disparadores del offcanvas
   (p. ej. el botón "Más" del dashboard) sobran y quedarían muertos por el guard.
   Los ocultamos. La hamburguesa NO cae acá porque ya no lleva data-bs-target. ── */
@media (min-width: 768px) {
    [data-bs-toggle="offcanvas"][data-bs-target="#sidebarMenu"] {
        display: none !important;
    }
}

/* ═══════════════════════════════════════════════════════════════════
   Bottom nav (mobile) — el equivalente del sidebar fijo en <768px
   ═══════════════════════════════════════════════════════════════════ */
.tb-bottom-nav {
    display: none;                 /* solo aparece <768 (abajo) */
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    /* La altura como variable porque otras pantallas tienen que esquivarla: la barra de guardado de
       /servicios/orden se apoya justo arriba. Con el número escrito en los dos lados, cambiarlo acá
       dejaba "Guardar orden" tapado justo cuando hay cambios sin guardar. */
    height: var(--tb-bottom-nav-h);
    background: #fff;
    border-top: 1px solid #e9ecef;
    z-index: 1030;                 /* nivel del sidebar; bajo topbar (1035) y backdrop del offcanvas (1040) */
    justify-content: space-around;
    align-items: center;
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.08);
    padding-bottom: env(safe-area-inset-bottom);   /* respeta notch/gesto iOS */
}

.tb-bottom-nav-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    color: #6c757d;
    text-decoration: none;
    font-size: 0.65rem;
    font-weight: 600;
    flex: 1;
    padding: 6px 4px;
    border: none;
    background: none;
    cursor: pointer;
    transition: color 0.2s;
}

.tb-bottom-nav-item i {
    font-size: 1.1rem;
}

.tb-bottom-nav-item.active,
.tb-bottom-nav-item:hover {
    color: #6f42c1;
}

@media (max-width: 767.98px) {
    .tb-bottom-nav { display: flex; }
    /* Ocultar la bottom nav cuando el teclado está abierto (lo marca el JS). */
    body.tb-keyboard-open .tb-bottom-nav { display: none; }
    /* Reservar espacio para que la bottom nav no tape el contenido. */
    .tb-main { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
    /* Con la bottom nav, "Más" es la única entrada al menú → fuera la hamburguesa. */
    #tbNavToggle { display: none; }
}

/* ═══ Botones flex: centrar el icono ═══
   Bootstrap no le pone `align-items` a `.btn`, así que un botón con `d-flex`/`d-inline-flex` deja
   sus hijos en `stretch`: el <i> se estira al line-height del botón (24px) mientras el glifo se
   dibuja en el line-height propio del icono (16px), y queda 4px arriba del centro. Medido en el
   header de Servicios: centro del botón 183,3px, centro del glifo 179,3px.
   Va acá y no en cada pantalla porque son 29 botones así repartidos en los templates. */
.btn.d-flex,
.btn.d-inline-flex,
.btn.d-sm-inline-flex,
.btn.d-md-flex,
.btn.d-md-inline-flex {
    align-items: center;
}

/* ═══ Encabezado de página reutilizable (_page_header.html.twig) ═══ */
.tb-page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    /* Panel blanco (como el prototipo), no un header pelado sobre el gris. */
    background: #fff;
    border: 1px solid #eef0f4;
    border-radius: 16px;
    padding: 20px 24px;
    box-shadow: 0 4px 18px rgba(20, 20, 50, 0.06);
    margin-bottom: 20px;
}
.tb-page-header__lead {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    min-width: 0;
}
.tb-page-header__icon {
    width: 52px;
    height: 52px;
    flex-shrink: 0;
    border-radius: 14px;
    background: rgba(102, 126, 234, 0.12);
    color: #667eea;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.35rem;
}
.tb-page-header__title {
    font-size: 26px;
    font-weight: 800;
    color: #1f2430;
    margin: 0;
    line-height: 1.15;
}
.tb-page-header__subtitle {
    font-size: 0.9rem;
    color: #5b6373;
    margin: 2px 0 0;
}
.tb-page-header__actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}

/* ═══ Listado de servicios (scopeado a .services-container) ═══ */
/* Fila: sin lift en hover, solo fondo tenue (pisa el translateY global de .table-modern). */
#servicesTableBody tr.service-row:hover {
    transform: none;
    background: #f8f9ff;
}
/* Botones de acción ≥40px con área táctil cómoda. */
.services-container .action-btn {
    width: 40px;
    height: 40px;
    font-size: 1rem;
}
/* "Reactivar" (verde) para servicios inactivos. */
.services-container .btn-reactivate {
    background: linear-gradient(135deg, #28a745 0%, #1e7e34 100%);
    color: #fff;
}
/* Columna Prof. en 0 = sin profesionales → alerta (no se puede reservar online). */
.services-container .professionals-count.is-zero {
    color: #dc3545;
    font-weight: 700;
}

/* Los destacados actuales en Configuración: sólo lectura, porque se marcan en /servicios.
   Es una lista y no dos inputs deshabilitados a propósito: un select gris invita a intentar
   cambiarlo y después a preguntar por qué no se puede. */
.featured-current {
    display: grid;
    gap: 6px;
}

.featured-current__row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}

.featured-current__slot {
    font-size: 13px;
    font-weight: 600;
    color: #64748b;
    min-width: 96px;
}

.featured-current__name {
    font-weight: 600;
    color: #0f172a;
}

.featured-current__empty {
    color: #94a3b8;
    font-style: italic;
}

/* "Mi abono" cuando hay algo que pagar: un destino, dos estados. El chip es la señal de que
   hay una acción pendiente; el ítem aparte diciendo "Pagar" ocuparía lugar y, con la cuenta al
   día, sembraría la duda de si se debe algo. */
.nav-link--due { color: #ffd7d7 !important; }
.nav-link--due i { color: #ff9d9d; }
.nav-link-chip {
    margin-left: auto;
    background: #b4232c;
    color: #fff;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .02em;
    padding: 2px 8px;
    border-radius: 999px;
    flex: none;
}
