/* ---------- MODERN ADMIN THEME: ALPINE GRANITE & PINE ---------- */
:root {
    --primary: #1b3022;      /* Deep Forest Pine */
    --primary-light: #2d4a3e;
    --secondary: #455a64;    /* Granite Stone */
    --accent: #a67c52;       /* Cedar Wood Wood */
    --dark: #121612;         /* Night Rock */
    --sidebar-bg: #0d120f;   /* Deepest Green-Black */
    --bg: #f4f7f6;
    --card-bg: #ffffff;
    --text: #2c332c;
    --text-muted: #607d8b;
    --white: #ffffff;
    --border: #e0e4e2;
    --radius: 0px;           /* Architectural sharp lines */
    --shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
    --sidebar-width: 260px;
    --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
    font-family: 'Inter', -apple-system, sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.6;
    overflow-x: hidden;
}

/* ---------- LAYOUT ---------- */
.admin-layout {
    display: flex;
    min-height: 100vh;
}

/* ---------- SIDEBAR ---------- */
.sidebar {
    width: var(--sidebar-width);
    background: var(--sidebar-bg);
    color: var(--white);
    position: fixed;
    height: 100vh;
    transition: var(--transition);
    z-index: 1000;
}

.sidebar-header {
    padding: 40px 25px;
    border-bottom: 1px solid rgba(255,255,255,0.05);
}

.sidebar-header h1 {
    font-family: 'Playfair Display', serif;
    font-size: 1.2rem;
    color: var(--accent);
    letter-spacing: 1px;
    display: flex;
    align-items: center;
    gap: 12px;
}

.nav-links {
    list-style: none;
    padding: 20px 15px;
}

.nav-links li { margin-bottom: 5px; }

.nav-links a {
    display: flex;
    align-items: center;
    padding: 12px 18px;
    color: #888;
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 500;
    border-radius: var(--radius);
    transition: var(--transition);
    text-transform: uppercase;
    letter-spacing: 1px;
}

.nav-links a i { width: 20px; font-size: 1rem; margin-right: 12px; }

.nav-links a:hover, .nav-links a.active {
    background: rgba(255,255,255,0.03);
    color: var(--white);
}

.nav-links a.active {
    color: var(--accent);
    border-left: 3px solid var(--accent);
    padding-left: 15px;
}

/* ---------- MAIN CONTENT ---------- */
.main-wrapper {
    flex: 1;
    margin-left: var(--sidebar-width);
    padding: 20px 24px;
    transition: var(--transition);
}

.top-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px; /* Reduced from 40px */
    border-bottom: 1px solid var(--border);
    padding-bottom: 10px; /* Reduced from 20px */
}

.top-header h2 {
    font-family: 'Playfair Display', serif;
    font-size: 1.5rem; /* Reduced from 2rem */
    color: var(--primary);
    font-weight: 700;
}

.user-nav {
    display: flex;
    align-items: center;
    gap: 20px;
}

.role-badge {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 2px;
    padding: 4px 12px;
    background: var(--primary);
    color: white;
    font-weight: 700;
}

/* ---------- UI COMPONENTS ---------- */
.card {
    background: var(--card-bg);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    border: 1px solid var(--border);
    margin-bottom: 30px;
    padding: 30px;
}

.card-title {
    font-family: 'Inter', sans-serif;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 2px;
    color: var(--primary);
    font-weight: 700;
    margin-bottom: 30px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

/* Tables */
.table-container {
    overflow-x: auto;
    /* A scroll container should also stop the page behind it from scrolling
       sideways when a gesture overshoots the end of the table. */
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
}

table {
    width: 100%;
    border-collapse: collapse;
}

th {
    text-align: left;
    padding: 15px;
    font-size: 0.7rem;
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 2px solid var(--bg);
    letter-spacing: 1px;
    font-weight: 700;
}

td {
    padding: 18px 15px;
    font-size: 0.9rem;
    border-bottom: 1px solid var(--bg);
}

tr:last-child td { border-bottom: none; }

/* Status Badges */
.status-pill {
    padding: 4px 12px;
    border-radius: 0px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
}

.status-confirmed { background: #e6f7ef; color: #10b981; }
.status-pending { background: #fff8eb; color: #f59e0b; }

/* Stats Grid */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 25px;
    margin-bottom: 40px;
}

.stat-item {
    background: white;
    padding: 25px;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    border-left: 4px solid var(--primary);
}

.stat-item .label {
    font-size: 0.7rem;
    text-transform: uppercase;
    color: var(--text-muted);
    display: block;
    letter-spacing: 1px;
    font-weight: 600;
}

.stat-item .value {
    font-size: 2rem;
    font-weight: 700;
    color: var(--primary);
    margin-top: 8px;
}

/* ---------- BUTTONS ---------- */
.btn {
    padding: 12px 24px;
    border-radius: var(--radius);
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 2px;
    cursor: pointer;
    transition: var(--transition);
    border: none;
}

.btn-primary { background: var(--primary); color: white; border: 1px solid var(--primary); }
.btn-primary:hover { background: transparent; color: var(--primary); }

.btn-sm { padding: 8px 16px; font-size: 0.65rem; }

.btn-danger { background: #fff5f5; color: #e74c3c; border: 1px solid #fed7d7; }
.btn-danger:hover { background: #e74c3c; color: white; }

.btn-outline { background: transparent; border: 1px solid var(--border); color: var(--primary); }
.btn-outline:hover { background: var(--primary); color: white; border-color: var(--primary); }

/* ---------- MODALS ---------- */
.modal {
    display: none;
    position: fixed;
    top: 0; left: 0; width: 100%; height: 100%;
    background: rgba(13, 18, 15, 0.8);
    backdrop-filter: blur(8px);
    z-index: 2000;
    align-items: center;
    justify-content: center;
}

.modal.active { display: flex; }

.modal-content {
    background: white;
    padding: 50px;
    width: 95%;
    max-width: 700px;
    max-height: 90vh;
    overflow-y: auto;
    position: relative;
    box-shadow: 0 30px 60px rgba(0,0,0,0.2);
}

.modal-header {
    margin-bottom: 40px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid var(--border);
    padding-bottom: 20px;
}

.modal-header h3 { font-family: 'Playfair Display', serif; font-size: 1.8rem; color: var(--primary); }

/* Modal Close Button */
.btn-close {
    background: none;
    border: none;
    font-size: 1.5rem;
    color: var(--text-muted);
    cursor: pointer;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: var(--transition);
    border-radius: 50%;
}

.btn-close:hover {
    background: #f1f5f9;
    color: var(--dark);
    transform: rotate(90deg);
}

/* Tab Navigation inside Modals */
.tabs-header {
    display: flex;
    border-bottom: 1px solid var(--border);
    margin-bottom: 30px;
    gap: 30px;
}

.tab-link {
    background: none;
    border: none;
    padding: 12px 0;
    cursor: pointer;
    font-weight: 700;
    color: var(--text-muted);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 2px;
    position: relative;
    transition: var(--transition);
}

.tab-link:hover { color: var(--primary); }

.tab-link.active { color: var(--accent); }

.tab-link.active::after {
    content: '';
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    height: 3px;
    background: var(--accent);
}

/* Form Caps labels */
.label-caps {
    font-weight: 800;
    font-size: 0.65rem;
    text-transform: uppercase;
    color: var(--text-muted);
    display: block;
    margin-bottom: 10px;
    letter-spacing: 1px;
}

.label-mini {
    font-weight: 700;
    font-size: 0.6rem;
    text-transform: uppercase;
    color: #94a3b8;
    display: block;
    margin-bottom: 6px;
    letter-spacing: 0.5px;
}

/* Form Control */
.form-group { margin-bottom: 25px; }
.form-group label { display: block; font-size: 0.7rem; text-transform: uppercase; font-weight: 700; color: var(--primary); margin-bottom: 10px; letter-spacing: 1px; }
.form-control {
    width: 100%;
    padding: 14px 18px;
    background: #f9fbf9;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-family: inherit;
    font-size: 0.95rem;
    transition: var(--transition);
}
.form-control:focus { outline: none; border-color: var(--accent); background: white; }

/* ---------- SECTIONS ---------- */
.content-section { display: none; }
.content-section.active { display: block; animation: fadeIn 0.5s ease; }

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(15px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ---------- RESPONSIVE ---------- */






/* ---------- CALENDAR COMPONENT REWRITE ---------- */
.calendar-wrapper {
    width: 100%;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: var(--shadow);
}

.calendar-header-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 30px; /* Reduced from 30px */
    background: white;
    border-bottom: 1px solid var(--border);
}

.calendar-header {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    background: #f8fafc;
    border-bottom: 1px solid var(--border);
}

.day-label {
    padding: 10px 5px; /* Reduced from 15px */
    text-align: center;
    font-size: 0.65rem;
    text-transform: uppercase;
    font-weight: 800;
    color: #64748b;
    letter-spacing: 1.5px;
}

.calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    grid-auto-rows: minmax(100px, auto); /* Reduced from 140px */
    background: var(--border);
    gap: 1px;
}

.calendar-day {
    background: var(--white);
    padding: 10px; /* Reduced from 15px */
    display: flex;
    flex-direction: column;
    gap: 5px; /* Reduced from 8px */
    transition: var(--transition);
    min-height: 100px; /* Reduced from 140px */
}

.calendar-day:hover { background: #fdfdfd; }
.calendar-day.other-month { background: #f1f5f9; opacity: 0.5; }

.day-number {
    font-size: 0.9rem;
    font-weight: 800;
    color: #1e293b;
    margin-bottom: 10px;
}

.calendar-day.today { background: #fffbeb; }
.calendar-day.today .day-number { color: var(--accent); position: relative; }
.calendar-day.today .day-number::after {
    content: 'HOY';
    font-size: 0.5rem;
    background: var(--accent);
    color: white;
    padding: 2px 4px;
    margin-left: 8px;
    vertical-align: middle;
}

.calendar-events { display: flex; flex-direction: column; gap: 6px; }

.cal-event {
    font-size: 0.7rem;
    padding: 6px 10px;
    border-radius: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    font-weight: 600;
    transition: all 0.2s;
    border: 1px solid transparent;
}

.cal-event:hover { transform: translateY(-1px); box-shadow: 0 4px 6px rgba(0,0,0,0.05); }

/* Status Colors - Refined */
.cal-event.confirmed { background: #dcfce7; color: #166534; border-color: #bbf7d0; }
.cal-event.pending_verification, .cal-event.awaiting_payment { background: #fef9c3; color: #854d0e; border-color: #fef08a; }
.cal-event.airbnb { background: #fee2e2; color: #991b1b; border-color: #fecaca; }
.cal-event.booking { background: #e0f2fe; color: #075985; border-color: #bae6fd; }

.calendar-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 25px;
    padding: 10px 30px; /* Reduced from 20px */
    background: #f8fafc;
    border-top: 1px solid var(--border);
}

.legend-item { display: flex; align-items: center; gap: 8px; font-size: 0.65rem; font-weight: 700; text-transform: uppercase; color: #64748b; }
.legend-dot { width: 8px; height: 8px; border-radius: 50%; border: 1px solid transparent; }
.legend-dot.confirmed { background: #dcfce7; border-color: #bbf7d0; }
.legend-dot.pending { background: #fef9c3; border-color: #fef08a; }
.legend-dot.airbnb { background: #fee2e2; border-color: #fecaca; }
.legend-dot.booking { background: #e0f2fe; border-color: #bae6fd; }

/* ---------- BOOKING DETAILS GRID ---------- */
.booking-details-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 30px;
}

.detail-group label {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 2px;
    color: var(--accent);
    margin-bottom: 8px;
    display: block;
    font-weight: 800;
}

.detail-value {
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--primary);
}
/* ==================== Utility classes (migrated from inline styles) ==================== */

/* Notifications */
.notification-wrapper { position: relative; margin-right: 15px; }
.notif-bell-btn { padding: 10px; border: none; font-size: 1.2rem; color: var(--primary); }
.notif-badge { display: none; position: absolute; top: 0; right: 0; background: #e74c3c; color: white; font-size: 0.6rem; padding: 2px 5px; border-radius: 10px; font-weight: 800; }
/* El overlay se abria y cerraba con dropdown.style.display, un estilo inline. Ahora
   el estado es una clase, que se puede animar, se puede comprobar en un test y no
   depende de que el script llegue a ejecutarse. */
.notif-dropdown.is-open { display: block; }

.notif-bell-btn { position: relative; }

.notif-bell-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.notif-badge[hidden] { display: none; }

.notif-dropdown { display: none; position: absolute; top: 100%; right: 0; width: 320px; background: white; border: 1px solid var(--border); box-shadow: 0 10px 30px rgba(0,0,0,0.1); z-index: 2000; margin-top: 10px; }
.notif-dropdown-header { padding: 15px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; background: var(--bg-soft); }
.notif-dropdown-header .notif-title { font-weight: 700; font-size: 0.8rem; text-transform: uppercase; }
.notif-dropdown-header .btn { padding: 4px 8px; font-size: 0.6rem; }
.notif-list { max-height: 400px; overflow-y: auto; }

/* Layout helpers */
.mb-20 { margin-bottom: 20px; }
.mb-25 { margin-bottom: 25px; }
.mb-30 { margin-bottom: 30px; }
.chart-box { height: 300px; padding: 20px; }
.edit-apt-head { margin-bottom: 25px; display: flex; align-items: center; gap: 15px; }
.edit-apt-head h3 { margin: 0; font-family: 'Playfair Display', serif; }

/* Appearance section */
.appearance-shell { padding: 0; overflow: hidden; border-radius: 12px; }
.appearance-bare { padding: 0; border: none; background: none; box-shadow: none; }
.appearance-grid { display: grid; grid-template-columns: minmax(360px, 420px) 1fr; height: calc(100vh - 180px); min-height: 600px; }
.appearance-form-side { padding: 30px; border-right: 1px solid var(--border); overflow-y: auto; background: white; }
.appearance-form-side .card-title { margin-bottom: 25px; }
.appearance-loading { text-align: center; padding: 50px; }
.appearance-preview-side { background: #f1f5f9; position: relative; display: flex; flex-direction: column; }
.appearance-preview-bar { background: #1e293b; color: white; padding: 12px 25px; font-size: 0.75rem; font-weight: 700; display: flex; justify-content: space-between; align-items: center; letter-spacing: 1px; }
.appearance-preview-bar .eye-icon { color: #818cf8; margin-right: 8px; }
.appearance-preview-actions { display: flex; gap: 12px; }
.appearance-preview-refresh { color: white; border-color: rgba(255,255,255,0.2); padding: 4px 10px; font-size: 0.7rem; }
.appearance-preview-stage { flex: 1; position: relative; padding: 20px; }
.appearance-preview-frame { width: 100%; height: 100%; background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 20px 50px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }
.appearance-preview-frame iframe { width: 100%; height: 100%; border: none; }

/* Modals (notification + confirm) */
.modal-box { max-width: 400px; text-align: center; padding: 40px; border-radius: 16px; position: relative; }
.modal-box .btn-close { position: absolute; top: 15px; right: 15px; width: 30px; height: 30px; }
.modal-box .btn-primary { width: 100%; margin-top: 20px; }
.confirm-icon { font-size: 3rem; color: #f59e0b; margin-bottom: 20px; }
.confirm-title { margin-bottom: 15px; font-family: 'Playfair Display', serif; color: #1e293b; }
.confirm-message { color: #64748b; margin-bottom: 25px; line-height: 1.6; }
.confirm-actions { display: flex; gap: 10px; justify-content: center; }
.confirm-actions .btn { flex: 1; padding: 12px; border-radius: 8px; }
.confirm-actions .btn-danger { background: #ef4444; color: white; border: none; font-weight: 600; }


/* Notification modal themes (set via data-notif-theme) */
.modal-content[data-notif-theme] { max-width: 400px; text-align: center; padding: 40px; border-radius: 16px; position: relative; }
.modal-content[data-notif-theme="error"] { background: #fef2f2; border: 1px solid #ef444433; }
.modal-content[data-notif-theme="success"] { background: #f0fdf4; border: 1px solid #10b98133; }
.modal-content[data-notif-theme="info"] { background: #eff6ff; border: 1px solid #6366f133; }
.modal-content[data-notif-theme] #notificationIcon i { font-size: 4rem; display: block; margin-bottom: 20px; }
.modal-content[data-notif-theme="error"] #notificationIcon i { color: #ef4444; }
.modal-content[data-notif-theme="success"] #notificationIcon i { color: #10b981; }
.modal-content[data-notif-theme="info"] #notificationIcon i { color: #6366f1; }
.modal-content[data-notif-theme] #notificationTitle { color: #1e293b; font-weight: 800; font-size: 1.25rem; }
.modal-content[data-notif-theme] #notificationMessage { color: #64748b; margin-top: 10px; line-height: 1.6; }

/* ---------- DASHBOARD INVENTORY ---------- */
.org-badge {
    font-size: 0.6rem;
    color: var(--accent);
    font-weight: 800;
    text-transform: uppercase;
    margin-top: 4px;
}

.btn-group {
    display: flex;
    gap: 5px;
}

.edit-tabs-container {
    padding: 0;
    overflow: hidden;
}

.edit-tabs-container .tab-link {
    background: none;
    border: none;
    padding: 20px 5px;
    cursor: pointer;
    font-weight: 700;
    color: #94a3b8;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 1px;
    position: relative;
    transition: 0.2s;
}

.edit-tabs-container .tab-link:hover {
    color: var(--primary);
}

.edit-tabs-container .tab-link.active {
    color: var(--accent);
}

.edit-tabs-container .tab-link.active::after {
    content: '';
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    height: 3px;
    background: var(--accent);
}

.lang-tabs-container {
    margin-bottom: 25px;
}

.lang-tabs-header {
    display: flex;
    border-bottom: 1px solid #e2e8f0;
    gap: 15px;
}

.lang-tab-link {
    background: none;
    border: none;
    padding: 10px 15px;
    cursor: pointer;
    font-weight: 600;
    color: #94a3b8;
    font-size: 0.8rem;
    display: flex;
    align-items: center;
    gap: 8px;
    border-radius: 6px;
    transition: 0.2s;
    border: 1px solid transparent;
}

.lang-tab-link img {
    width: 18px;
}

.lang-tab-link:hover {
    background: #f1f5f9;
}

.lang-tab-link.active {
    background: white;
    color: var(--primary);
    border-color: #e2e8f0;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.edit-form {
    padding: 40px;
}

.edit-grid-2 {
    display: grid;
    grid-template-columns: 1fr 300px;
    gap: 40px;
}

.edit-grid-4 {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
    margin-top: 25px;
}

.form-row-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    margin-top: 25px;
}

.image-upload-card {
    background: #f8fafc;
    padding: 20px;
    border-radius: 12px;
    border: 1px solid #e2e8f0;
    text-align: center;
}

.image-upload-card img {
    width: 100%;
    aspect-ratio: 4/3;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid #cbd5e1;
    margin-bottom: 15px;
}

.upload-label {
    width: 100%;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.upload-input {
    display: none;
}

.info-box {
    padding: 15px;
    border-radius: 8px;
    margin-bottom: 25px;
    font-size: 0.8rem;
    border: 1px solid;
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.info-box i {
    margin-top: 2px;
}

.info-box.info {
    background: #f1f5f9;
    color: #475569;
    border-color: #e2e8f0;
}

.info-box.features {
    background: #fdfcf0;
    color: #854d0e;
    border-color: #fef08a;
}

.info-box.prices {
    background: #f0fdf4;
    color: #166534;
    border-color: #bbf7d0;
}

.info-box.availability {
    background: #fff7ed;
    color: #9a3412;
    border-color: #ffedd5;
}

.info-box.sync {
    background: #eff6ff;
    color: #1e40af;
    border-color: #bfdbfe;
}

.features-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 15px;
}

.feature-card {
    display: flex;
    align-items: center;
    gap: 12px;
    background: #f8fafc;
    padding: 15px;
    border-radius: 8px;
    border: 1px solid #e2e8f0;
    cursor: pointer;
}

.feature-card .feature-icon {
    color: var(--accent);
    font-size: 1.1rem;
    width: 25px;
    text-align: center;
}

.feature-card .feature-label {
    font-size: 0.85rem;
    font-weight: 600;
}

.feature-card input[type="checkbox"] {
    width: auto;
}

.price-card {
    background: white;
    padding: 12px 15px;
    border-radius: 8px;
    border: 1px solid #e2e8f0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-shadow: 0 1px 3px rgba(0,0,0,0.02);
}

.price-card-actions {
    display: flex;
    align-items: center;
    gap: 15px;
}

.price-value {
    font-weight: 800;
    color: var(--accent);
    font-size: 1.1rem;
}

.block-card {
    background: white;
    padding: 12px 15px;
    border-radius: 8px;
    border: 1px solid #fee2e2;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-shadow: 0 1px 3px rgba(0,0,0,0.02);
}

.block-title {
    font-size: 0.8rem;
    font-weight: 700;
    color: #991b1b;
}

.block-dates {
    font-size: 0.7rem;
    color: #64748b;
}

.gallery-manager-v2 {
    padding: 0;
}

.gallery-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 25px;
}

.gallery-description {
    color: #64748b;
    font-size: 0.9rem;
    margin: 0;
}

.gallery-description strong {
    color: var(--text);
}

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 15px;
    min-height: 200px;
}

.gallery-card {
    position: relative;
    background: white;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0,0,0,0.05);
    border: 1px solid #e2e8f0;
    transition: all 0.2s;
}

.gallery-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.gallery-card-image {
    position: relative;
    aspect-ratio: 4/3;
    overflow: hidden;
}

.gallery-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.gallery-card-badge {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(16,185,129,0.9);
    color: white;
    font-size: 0.6rem;
    text-align: center;
    padding: 4px;
    font-weight: 800;
    letter-spacing: 1px;
}

.gallery-card-actions {
    display: flex;
    justify-content: center;
    gap: 8px;
    padding: 8px;
    background: #f8fafc;
}

.btn-icon {
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 4px;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #64748b;
    cursor: pointer;
    transition: 0.2s;
}

.btn-icon:hover:not(:disabled) {
    color: var(--accent);
    border-color: var(--accent);
}

.btn-icon.delete:hover:not(:disabled) {
    color: #ef4444;
    border-color: #ef4444;
}

.btn-icon:disabled {
    opacity: 0.2;
    cursor: not-allowed;
}

.sync-card {
    padding: 25px;
    border-radius: 12px;
    border: 1px solid;
}

.sync-card.import {
    background: #eff6ff;
    border-color: #bfdbfe;
}

.sync-card.export {
    background: #f8fafc;
    border-color: #e2e8f0;
}

.sync-card h4 {
    font-size: 0.8rem;
    text-transform: uppercase;
    margin-bottom: 20px;
    color: #1e40af;
    display: flex;
    align-items: center;
    gap: 8px;
}

.export-field {
    background: #fff;
    font-size: 0.7rem;
    font-family: monospace;
}

.save-bar {
    text-align: right;
    margin-top: 50px;
    padding-top: 30px;
    border-top: 1px solid #eee;
}

.save-btn {
    padding: 15px 50px;
    font-weight: 800;
    letter-spacing: 1px;
}

.empty-state {
    font-size: 0.8rem;
    color: #94a3b8;
    text-align: center;
    padding: 20px;
    border: 1px dashed #e2e8f0;
    border-radius: 8px;
}

.tab-content-item.hidden {
    display: none;
}

.mb-15 {
    margin-top: 15px;
}

.mb-20 {
    margin-top: 20px;
}

.btn-icon-sm {
    padding: 5px 8px;
    font-size: 0.6rem;
}

.spinner {
    color: var(--accent);
}

.gallery-empty {
    grid-column: 1/-1;
    text-align: center;
    padding: 40px;
    background: #f8fafc;
    border: 2px dashed #e2e8f0;
    border-radius: 12px;
    color: #94a3b8;
}

.gallery-empty-icon {
    display: block;
    margin-bottom: 15px;
    opacity: 0.5;
}

.gallery-manager-label {
    margin: 0;
    cursor: pointer;
}

.sync-description {
    font-size: 0.75rem;
    color: #64748b;
    margin-bottom: 15px;
}

.price-label {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--primary);
}

.price-dates {
    font-size: 0.7rem;
    color: #64748b;
}

.gallery-spinner {
    grid-column: 1/-1;
    text-align: center;
    padding: 50px;
}

.gallery-picker {
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid var(--border);
}

.gallery-picker-title {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--text-muted);
    font-weight: 700;
    margin-bottom: 12px;
}

.gallery-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
    gap: 10px;
}

.gallery-picker-item {
    aspect-ratio: 1;
    border-radius: 8px;
    overflow: hidden;
    border: 2px solid var(--border);
    cursor: pointer;
    transition: var(--transition);
    position: relative;
}

.gallery-picker-item:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.gallery-picker-item.selected {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(166, 124, 82, 0.2);
}

.gallery-picker-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ==========================================================================
   RESPONSIVE AND ACCESSIBILITY PASS
   --------------------------------------------------------------------------
   Everything above predates the audit. The problems were not "it does not
   respond at all" but a handful of layouts that were declared once and never
   revisited, plus two accessibility gaps that the 1024px breakpoint introduced
   rather than fixed.
   ========================================================================== */

/* --- Overflow containment -------------------------------------------------
   A grid or flex child defaults to min-width:auto, so a single long string (an
   email, a slug, a URL in a table cell) refuses to shrink below its content
   and pushes the whole page wider than the viewport. Declaring min-width:0 on
   the children is what actually makes the tables scroll inside their container
   instead of dragging the layout sideways. */
.table-container > table,
.edit-grid-2 > *,
.edit-grid-4 > *,
.form-row-2 > *,
.stats-grid > *,
.appearance-grid > * {
    min-width: 0;
}

/* Long unbroken values inside cells: emails, custom domains, image paths. */
.table-container td,
.table-container th {
    overflow-wrap: anywhere;
}

/* Keep the row label visible while the rest of a wide table scrolls. */


/* --- Grids that never collapsed -------------------------------------------
   .edit-grid-2, .edit-grid-4, .form-row-2 and .features-grid were declared
   with a fixed column count and had no breakpoint, so a phone got four
   columns of form fields 90px wide. */


/* ---------------------------------------------------------------------------
   Bandeja de mensajes.

   El mensaje entero ocupa media pantalla y empuja la tabla: se recorta a cuatro
   lineas y el texto sigue entero en el DOM, que es lo que se copia al
   seleccionar.
   --------------------------------------------------------------------------- */

.msg-text {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0 0 .35rem;
    max-width: 48ch;
}

.sub-block {
    display: block;
    margin-top: .15rem;
    font-size: .75rem;
    color: var(--muted);
}

.msg-reply {
    font-size: .78rem;
    color: var(--muted);
    overflow-wrap: anywhere;
}

.msg-reply:hover { color: var(--accent); }

/* ---------------------------------------------------------------------------
   Atajos de teclado.

   El boton esta en la barra de arriba al lado de las notificaciones: un atajo que
   solo existe si alguien lo lee no es un atajo, es un secreto. La lista la pinta
   el script leyendo los grupos del menu, asi que no puede describir atajos que no
   existan.
   --------------------------------------------------------------------------- */

.shortcuts-btn { flex: none; }

.shortcuts {
  position: fixed;
  inset: 0;
  z-index: 220;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(20, 24, 21, .5);
}

.shortcuts.is-open { display: flex; }

.shortcuts__panel {
  width: min(28rem, 100%);
  max-height: 80vh;
  overflow-y: auto;
  background: var(--card-bg, #fff);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .45);
}

.shortcuts__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

.shortcuts__title {
  margin: 0;
  font-size: 1.05rem;
}

.shortcuts__list { padding: .5rem .75rem; }

.shortcuts__row {
  display: flex;
  align-items: center;
  gap: .85rem;
  padding: .5rem .5rem;
}

/* El kbd tiene que tener tamano de tecla: un <span> con borde parece una etiqueta
   y no una tecla, y no dice pulsable. */
.shortcuts__row kbd {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9rem;
  min-height: 1.9rem;
  padding: 0 .45rem;
  background: var(--bg, #f6f5f2);
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 5px;
  font-family: inherit;
  font-size: .82rem;
  font-weight: 600;
  color: var(--ink, #2c332c);
}

.shortcuts__foot {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem .75rem;
  margin: 0;
  padding: .85rem 1.25rem;
  border-top: 1px solid var(--border);
  font-size: .78rem;
  color: var(--muted);
}

.shortcuts__count { font-weight: 600; }

@media (max-width: 768px) {
    .mobile-header { 
        display: flex !important; 
        position: fixed; 
        top: 0; 
        width: 100%; 
        z-index: 1100; 
        height: 52px; 
        background: var(--sidebar-bg);
        border-bottom: 1px solid rgba(255,255,255,0.08);
    }
    .sidebar { transform: translateX(-100%); top: 52px; height: calc(100vh - 52px); }
    .sidebar.mobile-active { transform: translateX(0); width: 260px; }
    .sidebar.mobile-active span { display: inline; }
    .main-wrapper { margin-left: 0; padding: 72px 10px 20px; }
    .stats-grid { grid-template-columns: 1fr; }
    
    /* Mobile header logo */
    .mobile-header .logo h1 {
        color: var(--accent);
        font-size: 0.95rem;
        letter-spacing: 0.5px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 180px;
    }
    .mobile-header .logo h1 i {
        color: var(--accent);
        font-size: 1rem;
    }
    #mobile-toggle {
        padding: 6px 10px;
        font-size: 0.7rem;
        border-color: rgba(255,255,255,0.15);
        color: #888;
    }
    
    /* Compact header */
    .top-header { 
        margin-bottom: 12px; 
        padding-bottom: 8px; 
        flex-wrap: wrap; 
        gap: 8px; 
    }
    .top-header h2 { 
        font-size: 1rem; 
        font-weight: 700; 
    }
    .user-nav { 
        gap: 6px; 
        flex-wrap: wrap; 
    }
    .role-badge { 
        font-size: 0.55rem; 
        padding: 3px 8px; 
        letter-spacing: 1px; 
    }
    #logoutBtn { 
        padding: 6px 10px; 
        font-size: 0.6rem; 
    }
    .notif-bell-btn { 
        padding: 6px; 
        font-size: 1rem; 
    }
    
    /* Compact cards */
    .card { 
        padding: 14px; 
        margin-bottom: 16px; 
    }
    .card-title { 
        font-size: 0.7rem; 
        margin-bottom: 12px; 
        letter-spacing: 1px; 
    }
    
    /* Compact tables */
    th { 
        padding: 8px 6px; 
        font-size: 0.6rem; 
    }
    td { 
        padding: 10px 6px; 
        font-size: 0.8rem; 
    }
    .btn-sm { 
        padding: 5px 8px; 
        font-size: 0.55rem; 
    }
    
    /* Nada se oculta ya en pantallas estrechas. Se ocultaban la primera, la tercera
       y la cuarta columna de los apartamentos, y ocultar una columna es borrarla.
       La tabla se apila con la etiqueta de su columna al lado, asi que se sigue
       viendo todo. Ver .table--stackable. */
    
    /* Compact org badge */
    .org-badge { 
        font-size: 0.55rem; 
        margin-top: 2px; 
    }
    
    /* Compact btn group */
    .btn-group { 
        gap: 4px; 
    }
    
    /* Section titles */
    .edit-apt-head h3 { 
        font-size: 1rem; 
    }
    
    /* Stats compact */
    .stat-item { 
        padding: 14px; 
    }
    .stat-item .value { 
        font-size: 1.4rem; 
    }
    
    /* Modal compact */
    .modal-content { 
        padding: 20px; 
        width: 98%; 
    }
    .modal-header h3 { 
        font-size: 1.2rem; 
    }
    
    /* Tabs compact */
    .tabs-header { 
        gap: 10px; 
        padding: 0 10px; 
        overflow-x: auto;
    }
    .tab-link { 
        font-size: 0.65rem; 
        padding: 10px 2px; 
        white-space: nowrap;
    }
    
    /* Language tabs compact - horizontal scroll */
    .lang-tabs-container {
        margin-bottom: 15px;
    }
    .lang-tabs-header {
        gap: 8px;
        overflow-x: auto;
        flex-wrap: nowrap;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .lang-tabs-header::-webkit-scrollbar {
        display: none;
    }
    .lang-tab-link {
        font-size: 0.7rem;
        padding: 8px 12px;
        white-space: nowrap;
        flex-shrink: 0;
    }
    .lang-tab-link img {
        width: 14px;
    }
    
    /* Calendar compact */
    .calendar-day { 
        min-height: 70px; 
        padding: 6px; 
    }
    .day-number { 
        font-size: 0.75rem; 
    }
    .cal-event { 
        font-size: 0.6rem; 
        padding: 3px 6px; 
    }
    .table-container thead th {
        position: sticky;
        top: 0;
        z-index: 2;
        background: var(--card-bg);
    }

    .table-container td:first-child,
    .table-container th:first-child {
        position: sticky;
        left: 0;
        z-index: 1;
        background: var(--card-bg);
        box-shadow: 1px 0 0 var(--border);
    }

    .table-container thead th:first-child {
        z-index: 3;
    }
    .edit-grid-2,
    .edit-grid-4,
    .form-row-2,
    .features-grid { grid-template-columns: 1fr; }
    .table-container thead th {
        position: sticky;
        top: 0;
        z-index: 2;
        background: var(--card-bg);
    }

    .table-container td:first-child,
    .table-container th:first-child {
        position: sticky;
        left: 0;
        z-index: 1;
        background: var(--card-bg);
        box-shadow: 1px 0 0 var(--border);
    }

    .table-container thead th:first-child {
        z-index: 3;
    }

    .edit-grid-2,
    .edit-grid-4,
    .form-row-2,
    .features-grid { grid-template-columns: 1fr; }

  /* En movil el cajon ocupa la pantalla y los grupos se leen de un vistazo. */
  .nav-group__label { padding-left: 15px; }
  .mobile-header { z-index: 60; }
  body.mobile-menu-open { overflow: hidden; }

  .table--stackable thead { display: none; }

  .table--stackable tbody tr {
    display: block;
    padding: 12px 14px;
    margin-bottom: 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: #fff;
  }

  .table--stackable tbody td {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 3px 0;
    border: 0;
  }

  /* La etiqueta es el nombre de la columna, que es lo que faltaba por completo. */
  .table--stackable tbody td::before {
    content: attr(data-label);
    flex: 0 0 38%;
    max-width: 38%;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #8b958f;
  }

  /* La celda que no tiene etiqueta —el boton de acciones— ocupa la fila entera. */
  .table--stackable tbody td:not([data-label]) { justify-content: flex-end; }
  .table--stackable tbody td[data-label=""]::before { content: none; }

  .table--stackable tbody td[data-label=""] { padding-top: 10px; }

  /* En movil el pulgar llega abajo: los avisos, tambien. */
  .toast-host { left: 1rem; right: 1rem; max-width: none; }
}/* --- Inline column definitions --------------------------------------------
   The appearance, coupon and booking forms set grid-template-columns through
   style attributes, which a media query cannot reach without !important. Those
   declarations moved to classes so the breakpoints below apply to them. */
.form-row {
    display: grid;
    gap: 15px;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

/* The address block: street takes the room, locality and region split the rest.
   auto-fit already collapses it, the explicit ratios just set the proportions. */
.form-row-address { grid-template-columns: 2fr 1fr 1fr; }
.form-row-triple { grid-template-columns: repeat(3, 1fr); }
.form-row-wide { gap: 20px; }

.stats-grid-3 { grid-template-columns: repeat(3, 1fr); }

@media (max-width: 900px) {
    .form-row-address,
    .form-row-triple,
    .stats-grid-3 { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 640px) {
    .form-row-address,
    .form-row-triple,
    .form-row-wide,
    .stats-grid-3 { grid-template-columns: 1fr; }
}

/* --- Touch targets --------------------------------------------------------
   32px is below the 44px minimum. It only matters where a coarse pointer is
   actually used, so it is scoped to that instead of penalising desktop. */
@media (pointer: coarse) {
    .nav-links a,
    .btn,
    .btn-sm,
    .form-control,
    .tab-btn,
    .icon-btn {
        min-height: 44px;
    }

    .nav-links a {
        align-items: center;
    }

    .nav-links a i {
        /* Re-centre the glyph once the label is the thing that is hidden. */
        margin-right: 0;
    }

    .close,
    .modal-close {
        min-width: 44px;
        min-height: 44px;
    }
}

/* --- Focus visibility -----------------------------------------------------
   The dashboard does not load the public styles.css, so it had no focus style
   of its own: keyboard users tabbed through the whole panel invisibly. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
}

/* The icon-only sidebar must not paint a ring around the whole <a> when the
   label is present but hidden. */
.nav-links a:focus-visible {
    outline-offset: -3px;
}

/* --- Collapsed sidebar ----------------------------------------------------
   At 1024px the labels were hidden with display:none, which also removes them
   from the accessibility tree, and the links carried no title, so the icons
   were the only thing left: unlabelled controls for anyone not using a mouse.
   The label is now clipped rather than removed, so it still names the link, and
   it surfaces as a tooltip on hover. */
@media (max-width: 1024px) {
    .stats-grid { grid-template-columns: repeat(2, 1fr); }
    .sidebar { width: 80px; }
    .main-wrapper { margin-left: 80px; padding: 20px 16px; }
    .appearance-grid { grid-template-columns: 1fr; height: auto; }
    .appearance-preview-side { min-height: 500px; }
    .top-header { flex-wrap: wrap; gap: 10px; }
    .top-header h2 { font-size: 1.2rem; }
    .user-nav { gap: 10px; }
    .card { padding: 20px; }
    th, td { padding: 10px 8px; }
    .btn-sm { padding: 6px 10px; font-size: 0.6rem; }
    /* Declared with a fixed column count and no breakpoint at all, so a tablet
       got four form fields about 150px wide. */
    .edit-grid-4 { grid-template-columns: repeat(2, 1fr); }
    .features-grid { grid-template-columns: repeat(2, 1fr); }
}

/* The icon-only rail applies from the tablet down to the point where the sidebar
   becomes an off-canvas drawer. Below that the drawer has room for the labels,
   and clipping them there would leave the open menu unlabelled. */
@media (max-width: 1024px) and (min-width: 769px) {
    /* The label used to be display:none, which also removed it from the
       accessibility tree, and no link had a title: twelve unlabelled icons.
       Clipping keeps the accessible name and adds a hover tooltip. */
    .sidebar-header span,
    .nav-links span {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .nav-links a {
        position: relative;
        justify-content: center;
        padding-left: 0;
        padding-right: 0;
    }

    .nav-links a[data-label]:hover::after,
    .nav-links a[data-label]:focus-visible::after {
        content: attr(data-label);
        position: absolute;
        left: calc(100% + 10px);
        top: 50%;
        transform: translateY(-50%);
        padding: 6px 10px;
        background: var(--dark);
        color: #fff;
        font-size: 0.75rem;
        white-space: nowrap;
        border-radius: 4px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
        z-index: 1200;
        pointer-events: none;
    }
}


/* --- Phones --------------------------------------------------------------- */
@media (max-width: 480px) {
    .main-wrapper { padding: 72px 8px 16px; }

    .card { padding: 14px; }

    .stats-grid { gap: 10px; }

    .top-header h2 { font-size: 1.05rem; }

    /* Full-width primary actions read better than a row of small ones. */
    .top-header .user-nav .btn,
    .form-actions .btn {
        flex: 1 1 auto;
    }

    .appearance-grid { grid-template-columns: 1fr; }

    /* The live preview iframe is useless below ~300px of height. */
    .appearance-preview-side { min-height: 320px; }
}

/* Very narrow phones: the calendar cannot show seven readable columns. */
@media (max-width: 380px) {
    .calendar-header,
    .calendar-grid {
        font-size: 0.6rem;
    }

    .calendar-header > *,
    .calendar-grid > * {
        padding: 4px 2px;
    }
}

/* --- Reduced motion ------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* --- Dark mode ------------------------------------------------------------
   The admin panel is the surface an operator stares at for a whole shift, and
   the palette is already tokenised. Brand colours are left alone: they are
   chosen to contrast against the light surfaces and are used as accents, not
   as backgrounds. */
@media (prefers-color-scheme: dark) {
    :root {
        --bg: #12161A;
        --card-bg: #1A2026;
        --text: #E6E9EA;
        --text-muted: #9AA5AD;
        --border: #2A323A;
        --dark: #0A0D10;
        --sidebar-bg: #0A0D10;
        --shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
    }

    body {
        background: var(--bg);
        color: var(--text);
    }

    .card,
    .stat-item,
    .modal-content,
    .table-container thead th,
    .table-container td:first-child,
    .table-container th:first-child,
    .form-control,
    .tab-content {
        background-color: var(--card-bg);
        color: var(--text);
    }

    .card,
    .stat-item,
    .modal-content {
        border-color: var(--border);
    }

    input,
    select,
    textarea {
        background-color: #141A1F;
        color: var(--text);
        border-color: var(--border);
    }

    .table-container thead th {
        color: var(--text-muted);
    }

    .nav-links a:hover,
    .tab-btn:hover {
        background: rgba(255, 255, 255, 0.05);
    }
}

/* --- Print ----------------------------------------------------------------
   Operators do print reservation lists and invoices from this panel. */
@media print {
    .sidebar,
    .mobile-header,
    .top-header .user-nav,
    .notification-wrapper,
    .btn,
    .tab-nav {
        display: none !important;
    }

    .main-wrapper {
        margin-left: 0 !important;
        padding: 0 !important;
    }

    .card {
        box-shadow: none;
        border: 1px solid #ccc;
        break-inside: avoid;
    }

    .table-container { overflow: visible; }
}

/* Was a <style nonce> block inside the dashboard template. It is theme, not
   markup, and it re-rendered on every navigation of the admin panel. */
/* --- SUPER ADMIN OVERRIDE THEME (INFRASTRUCTURE LOOK) --- */
    body.super-admin-mode {
    --primary: #0f172a;      /* Deep Slate */
    --primary-light: #1e293b;
    --accent: #6366f1;       /* Indigo */
    --sidebar-bg: #020617;   /* Black Slate */
    --bg: #f8fafc;
    }
    body.super-admin-mode .sidebar-header h1 {
    color: #818cf8;
    }
    body.super-admin-mode .sidebar-header h1 i {
    color: #6366f1;
    }
    body.super-admin-mode .stat-item {
    border-left-width: 0;
    border-top: 4px solid var(--accent);
    }
    body.super-admin-mode .role-badge {
    background: var(--accent);
    border-radius: 4px;
    }
    body.super-admin-mode .nav-links a.active {
    border-left-color: var(--accent);
    color: #818cf8;
    }

/* ---------------------------------------------------------------------------
   Notificaciones del panel.

   Estas reglas estaban como atributos style="" dentro de
   admin-dashboard.js. La CSP del proyecto no admite 'unsafe-inline' en
   style-src-attr, asi que cada una estaba siendo descartada por el navegador y el
   panel salia sin formato: sin separadores, sin tamano de texto y con el color
   de fondo descartado tambien. La diferencia entre leida y no leida, que antes
   venia de un ternario en el estilo, es ahora una clase.
   --------------------------------------------------------------------------- */

.notif-empty {
  padding: 20px;
  text-align: center;
  color: #999;
}

/* Es un <button>: un div con cursor:pointer no dice nada a un teclado ni a un
   lector de pantalla, y por eso hay que neutralizar el estilo de boton. */
.notif-item {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  padding: 15px;
  border: 0;
  border-bottom: 1px solid #eee;
  background: #fff;
  cursor: pointer;
  transition: background-color .15s;
}

.notif-item:hover { background: #f6f8f7; }

.notif-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.notif-item.is-unread { background: #f0fdf4; }

.notif-title {
  font-weight: 700;
  font-size: .8rem;
  color: var(--primary, #1b3022);
}

.notif-body { font-size: .75rem; color: #666; }

.notif-when { font-size: .6rem; color: #999; margin-top: 5px; }

/* ---------------------------------------------------------------------------
   Panel de autenticacion en dos pasos.

   Mismo origen que las notificaciones: eran atributos style="" dentro de
   admin-dashboard.js y la CSP los descartaba uno a uno. La diferencia entre
   activado y desactivado, que era un ternario con dos colores distintos
   escritos a mano, son ahora dos clases.
   --------------------------------------------------------------------------- */

.tfa { max-width: 600px; }

.tfa-card {
  background: #fff;
  border: 1px solid #e9ecef;
  border-radius: 10px;
  padding: 24px;
  margin-bottom: 20px;
}

.tfa-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.tfa-title { margin: 0 0 6px; font-size: 1.1rem; color: #1a1a2e; }
.tfa-title i { color: #1b3022; margin-right: .4rem; }
.tfa-sub { margin: 0; color: #666; font-size: .85rem; }

.tfa-pill {
  padding: 6px 14px;
  border-radius: 20px;
  font-size: .8rem;
  font-weight: 700;
  white-space: nowrap;
}
.tfa-pill.is-on { background: #d4edda; color: #155724; }
.tfa-pill.is-off { background: #f8d7da; color: #721c24; }

.tfa-actions { margin-top: 16px; }
.tfa-btn { display: inline-block; padding: 10px 20px; }
.tfa-btn.is-danger { border: 2px solid #ef4444; color: #ef4444; }
.tfa-btn.is-danger:hover { background: #ef4444; color: #fff; }

/* ---------------------------------------------------------------------------
   Calendario (calendar-widget.js) y formulario de huespedes (client-dashboard.js).

   Estaban como atributos style="" y la CSP los descartaba, asi que el boton de
   guardar no ocupaba el ancho de la caja, las notas de reserva no salian en
   cursiva y los tres desplegables de la fecha de nacimiento no se repartian la
   fila. En calendario.ejs.
   --------------------------------------------------------------------------- */

.cal-wide { width: 100%; }
.cal-gap { margin-top: 1rem; }
.cal-note { margin-top: .5rem; font-style: italic; }

/* ---------------------------------------------------------------------------
   Selector de plantilla del panel de apariencia.

   Era un <select> con cinco <option> escritos a mano en dashboard-admin.js,
   mientras la lista blanca del servidor tenia siete. verano y primavera estaban
   instalados y no se podian elegir. Ahora las tarjetas se pintan con la lista que
   devuelve /gestionar/api/settings/org, con su miniatura y su descripcion, para
   que elegir una plantilla no sea elegir a ciegas.

   Los estilos de este bloque tambien estaban en el atributo style, que la CSP
   descarta, asi que el selector salia sin separaciones ni rejilla.
   --------------------------------------------------------------------------- */

.ap-col {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.ap-h4 {
  margin: 0 0 15px;
  color: var(--primary);
  border-bottom: 1px solid #eee;
  padding-bottom: 8px;
}

.tpl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}

.tpl {
  display: grid;
  gap: 4px;
  padding: 8px;
  border: 1px solid #e2e6ea;
  border-radius: 10px;
  cursor: pointer;
  background: #fff;
  transition: border-color .2s, box-shadow .2s;
}

.tpl:hover { border-color: var(--primary); }

.tpl.is-on {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 18%, transparent);
}

.tpl input { position: absolute; opacity: 0; pointer-events: none; }

.tpl__img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 6px;
  display: block;
}

.tpl__label { font-weight: 600; font-size: .9rem; }

.tpl__blurb { font-size: .78rem; color: #667; line-height: 1.35; }

/* ---------------------------------------------------------------------------
   Reservas (dashboard-bookings.js).

   Los quince estilos de este fichero estaban en atributos style="" y la CSP los
   descartaba uno a uno: la celda de huesped sin negrita, las fechas sin tamano, el
   aviso de proteccion de datos sin caja y el icono del aviso sin nada. La franja
   de color de las tres tarjetas de estadisticas era un color escrito dentro del
   atributo, y ahora son tres clases, porque un color que vive en el script no se
   puede cambiar sin tocar JavaScript.

   En gestionar-dashboard-es.ejs.
   --------------------------------------------------------------------------- */

.bk-empty { text-align: center; padding: 40px; }

.bk-guest { font-weight: 700; }
.bk-guest-mail { font-size: .75rem; color: #666; }
.bk-date { font-size: .85rem; }
.bk-date-end { font-size: .7rem; color: #888; }

.bk-privacy {
  margin-top: 40px;
  padding: 30px;
  background: #f8fafc;
  border: 1px dashed #cbd5e1;
  border-radius: 12px;
  text-align: center;
  color: #64748b;
  font-size: .9rem;
}

.bk-privacy__icon {
  display: block;
  margin-bottom: 15px;
  font-size: 2rem;
  color: #94a3b8;
}

.bk-month {
  margin: 0;
  font-family: 'Playfair Display', serif;
  font-weight: 800;
  font-size: 1.8rem;
  color: var(--primary);
}

/* Las tres tarjetas de estadisticas globales. */
.stats-grid--spaced { margin-top: 20px; }

.stat-note { font-size: .7rem; color: #888; }

.stat-item--is-accent { border-top: 4px solid var(--accent); }
.stat-item--is-ok { border-top: 4px solid #34d399; }
.stat-item--is-warn { border-top: 4px solid #f59e0b; }

/* ---------------------------------------------------------------------------
   Cupones (dashboard-coupons.js), el aviso de precio de miramar y el mensaje de
   exito del registro.

   Otros siete estilos inline, los tres ficheros completos. El codigo del cupon
   llevaba el fondo, el padding y el color de la letra en el atributo, asi que se
   veía como texto normal; y el campo de escribir el cupon llevaba un
   text-transform que no se aplicaba, de modo que el codigo se escribia en
   minusculas donde se esperaba en mayusculas.
   --------------------------------------------------------------------------- */

.cp-code {
  background: var(--bg-soft);
  padding: 4px 8px;
  border-radius: 4px;
  font-weight: 800;
  color: var(--primary);
}

.cp-code-input { text-transform: uppercase; }

.cp-note { font-size: .75rem; color: #666; }

.cp-empty { text-align: center; padding: 40px; color: #999; }

.cp-actions { text-align: right; margin-top: 20px; }

/* El precio del apartamento no aparece hasta que hay fechas, y entonces no
   necesita margen: solo ocupa su propia linea. */
.price-note--flush { margin: 0; }

/* ==========================================================================
   Panel de administracion: vocabulario de los estilos que estaban inline.

   Los 47 estilos de dashboard-admin.js estaban en atributos style="", que la CSP
   descarta uno a uno. Se reconocen por lo que se veia: las casillas de opcion sin
   caja, el titulo de cada seccion sin su linea, la fila del boton pegada al
   borde de abajo, el codigo del cupon como texto normal, y la insignia del rol
   sin color, de modo que los tres roles se veian iguales.

   El nombre de cada clase es corto a proposito. Son objetos de un modulo que
   se lee entero de una vez, y nombres largos aqui solo anaden ruido sin ganar
   nada: lo que describe el bloque es el proposito, no cada propiedad.
   ========================================================================== */

/* --- tipografia y color --------------------------------------------------- */

.fw7-primary { font-weight: 700; color: var(--primary); }
.fw8-11-primary { font-weight: 800; font-size: 1.1rem; color: var(--primary); }
.xs-accent-ls { font-size: .7rem; color: var(--accent); letter-spacing: 1px; }
.xs-dim { font-size: .7rem; color: #ccc; }
.xs-dim2 { font-size: .75rem; color: #666; }
.xs-mb4 { font-size: .75rem; margin-bottom: 4px; }
.cl-admin { color: var(--accent); }
.cl-dim { color: #888; }

/* --- espaciado ------------------------------------------------------------ */

.mt10 { margin-top: 10px; }
.mt20 { margin-top: 20px; }
.mt-n10 { margin-top: -10px; }
.mb15 { margin-bottom: 15px; }
.mb20 { margin-bottom: 20px; }
.mb15-muted { margin-bottom: 15px; color: var(--text-muted); }
.mb20-primary { margin-bottom: 20px; color: var(--primary); }
.pad0 { padding: 0; }
.pad-x30 { padding: 12px 30px; }

/* --- alineacion y tamano -------------------------------------------------- */

.ta-c { text-align: center; }
.ta-r { text-align: right; }
.ta-r-mt20 { text-align: right; margin-top: 20px; }
.ta-r-mt30 { text-align: right; margin-top: 30px; }
.w-auto { width: auto; }
.scale12 { width: auto; transform: scale(1.2); }
.input-sm { height: 45px; padding: 5px; }
.scrollbox { max-height: 300px; overflow-y: auto; }
.hr-soft { margin: 30px 0; border: none; border-top: 1px solid var(--border); }

/* --- filas y grupos ------------------------------------------------------- */

.row5 { display: flex; gap: 5px; }
.row10 { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.row-between-xs {
  display: flex;
  justify-content: space-between;
  font-size: .65rem;
  color: #666;
  margin-top: 5px;
}

/* Una opcion de las que antes eran un label con el estilo puesto. */
.choice,
.choice-sm {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  border: 1px solid var(--border);
}
.choice { padding: 8px 12px; border-radius: 8px; margin-bottom: 10px; }
.choice-sm { padding: 8px 12px; border-radius: 8px; margin-bottom: 8px; }

.toggle-row,
.toggle-row-bordered {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  background: var(--bg-soft);
  padding: 15px;
}
.toggle-row { border-radius: 8px; margin-bottom: 10px; }
.toggle-row-bordered { border-radius: 8px; border: 1px solid var(--border); }

/* --- titulos de seccion --------------------------------------------------- */

.sec-h,
.sec-h-sm {
  margin-bottom: 15px;
  color: var(--primary);
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
}
.sec-h { font-size: 1.1rem; }
.sec-h-sm { font-size: .9rem; }

/* --- insignias de rol ----------------------------------------------------- */

/* El color estaba escrito dentro del atributo, a partir de un ternario sobre el
   rol. Con tres roles son tres clases, y cambiar el color de un rol deja de
   obligar a tocar JavaScript. */
.role-badge--superadmin { background: #6366f1; }
.role-badge--admin { background: var(--dark); }
.role-badge--other { background: #64748b; }

/* Stripe se muestra o no segun la configuracion. El display estaba resuelto a
   mano dentro del atributo; dos clases hacen lo mismo y se pueden usar en CSS. */
.st-on { display: block; }
.st-off { display: none; }

/* --- pie pegado y boton ancho --------------------------------------------- */

.sticky-foot {
  position: sticky;
  bottom: 0;
  background: white;
  padding: 20px 0;
  border-top: 1px solid #eee;
  margin-top: 20px;
}

.btn-block-wide {
  width: 100%;
  padding: 15px;
  font-weight: 800;
  letter-spacing: 1px;
}

/* Las cuatro tarjetas del mando central (dashboard-sections.js). El color de la
   franja estaba en el atributo de cada una, escrito a mano cuatro veces. */
.stat-item--is-danger { border-top: 4px solid #f87171; }

/* La organizacion a la que pertenece cada reserva, en la tabla de actividad. */
.org-tag { color: var(--accent); font-weight: 800; }

/* ---------------------------------------------------------------------------
   Estados de una vista: cargando, vacio y error.

   Los cuatro cargadores tenian `if (data.success)` y nada mas. apiFetch nunca
   lanza, devuelve { success: false, error }, asi que un fallo de red o de servidor
   no dejaba huella: la tabla se quedaba con lo que tuviera encima, y no habia
   manera de distinguir "no hay reservas" de "no se ha podido cargar".

   Y no habia estado de carga, de modo que una tabla vacia y una tabla que aun no
   ha llegado se veian igual, que es el peor sitio para confundirlas.

   El esqueleto tiene la forma del contenido real, no un spinner: el hueco que se ve
   es el que ocupa la tabla cuando llegue.
   --------------------------------------------------------------------------- */

@keyframes skel-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

.skel {
  display: block;
  border-radius: 4px;
  background: linear-gradient(90deg, #eef1ef 25%, #e2e7e4 37%, #eef1ef 63%);
  background-size: 400% 100%;
  animation: skel-pulse 1.4s ease-in-out infinite;
}

.skel--cell { height: 1rem; }

@media (prefers-reduced-motion: reduce) {
  .skel { animation: none; background: #eef1ef; }
}

/* Vacio y error comparten forma: centro, icono, texto y una accion. Que un estado
   de error se vea distinto de uno de vacio es lo que evita que alguien piense que
   la lista esta vacia cuando en realidad no se pudo cargar. */
.state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .75rem;
  padding: 2.5rem 1rem;
  text-align: center;
  color: #667;
}

.state i { font-size: 1.75rem; opacity: .35; }
.state p { margin: 0; font-size: .95rem; }

.state--error { color: #8a3b32; }
.state--error i { opacity: .55; }
.state--empty .btn { margin-top: .25rem; }

/* ---------------------------------------------------------------------------
   El menu.

   Doce secciones en una columna no caben en 390 px. En escritorio se colapsa a
   iconos y se recuerda, porque decidir como quieres trabajar no es un estado de la
   aplicacion. En movil son las mismas doce, pero en cuatro grupos, y se cierra al
   navegar ademas de al pulsar fuera.
   --------------------------------------------------------------------------- */

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.sidebar-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  margin: 0 15px 8px auto;
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--muted);
  cursor: pointer;
  transition: border-color .2s, color .2s;
}

.sidebar-toggle:hover { border-color: var(--accent); color: var(--accent); }
.sidebar-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Colapsado: se ven los iconos y el titulo sale por el title nativo. */
.sidebar.is-collapsed { --sidebar-width: 68px; }
.sidebar.is-collapsed .nav-group__label { display: none; }
.sidebar.is-collapsed .nav-links a span,
.sidebar.is-collapsed .nav-links a small { display: none; }
.sidebar.is-collapsed .nav-links a { justify-content: center; padding-left: 0; padding-right: 0; }
.sidebar.is-collapsed .sidebar-toggle i { transform: rotate(180deg); }
.sidebar.is-collapsed .sidebar-toggle { margin-inline: auto; }

.sidebar-toggle i { transition: transform .2s; }

.nav-group + .nav-group { margin-top: 14px; }

.nav-group__label {
  display: block;
  padding: 0 15px 4px;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #9aa5a0;
}

.nav-group__items { list-style: none; padding: 0; margin: 0; }

/* ---------------------------------------------------------------------------
   Tablas apiladas en pantallas estrechas.

   Antes se ocultaban columnas con display:none. Ocultar una columna es borrarla: en
   la tabla de reservas se iba justo la que identifica la reserva, y en la de
   apartamentos la del nombre. Con la etiqueta de la columna en cada celda, la
   misma tabla se apila y se sigue viendo todo.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   Avisos.

   Eran un modal con un boton de Aceptar al final de cada accion, con un alert()
   detras por si el modal no estaba. El aviso de un guardado bien hecho no pide
   confirmacion: informa y se va, y no roba el foco, que es lo que hacia el modal.
   --------------------------------------------------------------------------- */

.toast-host {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  max-width: min(24rem, calc(100vw - 2rem));
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  padding: .8rem .9rem;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, .3);
  font-size: .9rem;
  color: var(--ink, #2c332c);
  pointer-events: auto;
  animation: toast-in .22s ease-out;
}

@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } }

.toast--success { border-left-color: #34d399; }
.toast--error { border-left-color: #e05a4a; }
.toast--info { border-left-color: var(--accent); }

.toast i { flex: none; margin-top: .1rem; }
.toast--success i { color: #1f9d6b; }
.toast--error i { color: #e05a4a; }
.toast--info i { color: var(--accent); }

.toast span { flex: 1; }

.toast__close {
  flex: none;
  background: none;
  border: 0;
  padding: 0 2px;
  color: #9aa5a0;
  cursor: pointer;
  line-height: 1;
}
.toast__close:hover { color: var(--ink, #2c332c); }
.toast__close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

