/* ==========================================================================
   Reservín — Panel de administración
   Tema oscuro. Mobile-first. Vanilla CSS, cero dependencias.
   ========================================================================== */

:root {
  --bg: #0e1220;
  --surface: #171c2e;
  --border: #232a42;
  --text: #e8ebf5;
  --text-secondary: #8a93ad;
  --accent: #6c7bff;
  --success: #3ecf8e;
  --warning: #ffb454;
  --danger: #ff6b6b;

  --radius: 10px;
  --radius-sm: 7px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --shadow-soft: 0 4px 16px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.3);
  --shadow-lift: 0 12px 32px rgba(0, 0, 0, 0.45);

  --accent-wash: rgba(108, 123, 255, 0.12);
  --accent-wash-strong: rgba(108, 123, 255, 0.22);
  --success-wash: rgba(62, 207, 142, 0.14);
  /* Mismo verde de --success, mismo salto (+0.10) que --accent ya usa para su
     variante "strong" — no es un color nuevo, es la misma escala aplicada al
     tono que faltaba. La usa el resaltado de fin de semana del calendario
     (pedido del hotelero: "que resalte más" — ver .weekend más abajo). */
  --success-wash-strong: rgba(62, 207, 142, 0.24);
  --warning-wash: rgba(255, 180, 84, 0.14);
  --danger-wash: rgba(255, 107, 107, 0.14);
  --surface-hover: rgba(232, 235, 245, 0.04);
  --surface-alt: rgba(232, 235, 245, 0.03);

  --bottom-nav-h: 62px;
  --topbar-h: 56px;
}

/* ---------- Reset ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: anywhere;
}
h1, h2, h3, h4, p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; display: block; }
::selection { background: var(--accent-wash-strong); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: var(--accent); }

.app { min-height: 100%; }

/* ---------- Marca ---------- */
.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.brand-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-wash);
  flex-shrink: 0;
}

/* ---------- Botones ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 600;
  transition: background 0.15s, border-color 0.15s, opacity 0.15s, transform 0.05s;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-hover); border-color: #2c3450; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: #5b6bf5; border-color: #5b6bf5; }
.btn-danger { background: transparent; border-color: rgba(255, 107, 107, 0.4); color: var(--danger); }
.btn-danger:hover { background: var(--danger-wash); border-color: var(--danger); }
.btn-danger.solid { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn-danger.solid:hover { background: #ff5757; }
.btn-ghost { background: transparent; border-color: transparent; }
.btn-ghost:hover { background: var(--surface-hover); }
.btn-sm { padding: 6px 11px; font-size: 0.82rem; }
.btn-block { width: 100%; }
.btn-icon { padding: 8px; width: 36px; height: 36px; }
.icon { width: 18px; height: 18px; flex-shrink: 0; }
.icon-sm { width: 15px; height: 15px; }

/* ---------- Formularios ---------- */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-secondary);
}
.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; min-width: 0; }
.input, select.input, textarea.input {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  font-size: 0.92rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.input::placeholder { color: var(--text-secondary); opacity: 0.7; }
textarea.input { resize: vertical; min-height: 72px; }
select.input { appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238a93ad' stroke-width='2'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 32px;
}
.checkbox-row { display: flex; align-items: center; gap: 8px; font-size: 0.88rem; color: var(--text); }
.checkbox-row input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--accent); }
.form-error {
  background: var(--danger-wash);
  border: 1px solid rgba(255, 107, 107, 0.35);
  color: var(--danger);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 0.85rem;
  margin-bottom: 14px;
}
.form-hint { font-size: 0.78rem; color: var(--text-secondary); margin-top: -8px; margin-bottom: 14px; }
.switch { position: relative; display: inline-block; width: 40px; height: 23px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-track {
  position: absolute; inset: 0; background: var(--border); border-radius: 999px;
  transition: background 0.15s; cursor: pointer;
}
.switch-track::before {
  content: ""; position: absolute; width: 17px; height: 17px; left: 3px; top: 3px;
  background: var(--text); border-radius: 50%; transition: transform 0.15s;
}
.switch input:checked + .switch-track { background: var(--success); }
.switch input:checked + .switch-track::before { transform: translateX(17px); background: #0e1220; }
.switch input:disabled + .switch-track { opacity: 0.5; cursor: not-allowed; }

/* ---------- Login ---------- */
.login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background:
    radial-gradient(circle at 15% 10%, var(--accent-wash), transparent 45%),
    radial-gradient(circle at 85% 90%, var(--accent-wash), transparent 45%),
    var(--bg);
}
.login-card {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 32px 28px;
  box-shadow: var(--shadow-lift);
}
.login-card .brand { font-size: 1.35rem; justify-content: center; margin-bottom: 6px; }
.login-sub {
  text-align: center;
  color: var(--text-secondary);
  font-size: 0.85rem;
  margin-bottom: 26px;
}
.login-card form { margin-top: 6px; }
.login-card .btn-primary { margin-top: 4px; }

/* ---------- Layout autenticado ---------- */
.shell { min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
  height: var(--topbar-h);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0 14px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 30;
}
.topbar-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar-hotel {
  font-size: 0.82rem;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 38vw;
  padding-left: 10px;
  border-left: 1px solid var(--border);
}
.topbar-right { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.wa-indicator {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.78rem;
  color: var(--text-secondary);
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.wa-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--text-secondary); }
.wa-dot.ok { background: var(--success); box-shadow: 0 0 0 3px var(--success-wash); }
.wa-dot.warn { background: var(--warning); box-shadow: 0 0 0 3px var(--warning-wash); }
.wa-dot.bad { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-wash); }

.body-wrap { flex: 1; display: flex; min-height: 0; }

.sidebar { display: none; }

.view-root {
  flex: 1;
  min-width: 0;
  padding: 16px 14px calc(var(--bottom-nav-h) + 24px);
  max-width: 1180px;
  width: 100%;
  margin: 0 auto;
}

.bottom-nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: var(--bottom-nav-h);
  display: flex;
  background: var(--surface);
  border-top: 1px solid var(--border);
  z-index: 30;
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: var(--text-secondary);
  font-size: 0.64rem;
  font-weight: 600;
  border: none;
  background: transparent;
  padding: 6px 2px;
  position: relative;
}
.nav-item.active { color: var(--accent); }
.nav-item .nav-badge {
  position: absolute;
  top: 2px;
  right: calc(50% - 18px);
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--danger);
  border: 2px solid var(--surface);
}

@media (min-width: 860px) {
  .view-root { padding: 28px 32px 32px; }
  .bottom-nav { display: none; }
  .sidebar {
    display: flex;
    flex-direction: column;
    width: 232px;
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    padding: 20px 14px;
    gap: 4px;
  }
  .sidebar .brand { padding: 0 10px; margin-bottom: 22px; }
  .sidebar-nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }
  .sidebar-link {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-size: 0.88rem;
    font-weight: 600;
    border: none;
    background: transparent;
    text-align: left;
    width: 100%;
    position: relative;
  }
  .sidebar-link:hover { background: var(--surface-hover); color: var(--text); }
  .sidebar-link.active { background: var(--accent-wash); color: var(--accent); }
  .sidebar-link .nav-badge {
    margin-left: auto;
    width: 8px; height: 8px; border-radius: 50%; background: var(--danger); flex-shrink: 0;
  }
  .sidebar-foot { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 10px; display: flex; flex-direction: column; gap: 10px; }
  .topbar-hotel-mobile { display: none; }
}
@media (max-width: 859.98px) {
  .sidebar-hotel-name { display: none; }
}

/* ---------- Tarjetas / secciones ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}
.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.section-head h1 { font-size: 1.2rem; font-weight: 700; }
.section-head h2 { font-size: 1rem; font-weight: 700; }
.section-sub { color: var(--text-secondary); font-size: 0.82rem; margin-top: 2px; }

.stat-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-bottom: 20px;
}
@media (min-width: 620px) { .stat-grid { grid-template-columns: repeat(4, 1fr); } }
.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.stat-card .stat-label { font-size: 0.75rem; color: var(--text-secondary); font-weight: 600; }
.stat-card .stat-value { font-size: 1.55rem; font-weight: 700; margin-top: 6px; letter-spacing: -0.01em; }
.stat-card .stat-extra { font-size: 0.74rem; color: var(--text-secondary); margin-top: 3px; }

.notice {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: 0.86rem;
  margin-bottom: 12px;
  border: 1px solid transparent;
}
.notice-warn { background: var(--warning-wash); border-color: rgba(255, 180, 84, 0.35); color: var(--warning); }
.notice-danger { background: var(--danger-wash); border-color: rgba(255, 107, 107, 0.35); color: var(--danger); }
.notice-info { background: var(--accent-wash); border-color: rgba(108, 123, 255, 0.35); color: var(--accent); }
.notice-success { background: var(--success-wash); border-color: rgba(62, 207, 142, 0.35); color: var(--success); }
.notice a { color: inherit; font-weight: 700; text-decoration: underline; }
.notice .icon { flex-shrink: 0; }

.two-col { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 760px) { .two-col { grid-template-columns: 1fr 1fr; } }

.list-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 4px;
  border-bottom: 1px solid var(--border);
}
.list-item:last-child { border-bottom: none; }
.list-item-main { min-width: 0; flex: 1; }
.list-item-title { font-weight: 600; font-size: 0.88rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-item-sub { font-size: 0.78rem; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-item-end { text-align: right; flex-shrink: 0; font-size: 0.82rem; }
.list-item-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.72rem;
  color: var(--accent);
  background: var(--accent-wash);
  padding: 2px 6px;
  border-radius: 5px;
  flex-shrink: 0;
}

/* ---------- Estados vacíos / carga / error ---------- */
.empty-state {
  text-align: center;
  padding: 42px 20px;
  color: var(--text-secondary);
}
.empty-state .icon { width: 34px; height: 34px; margin: 0 auto 12px; opacity: 0.55; }
.empty-state p { font-size: 0.88rem; }
.empty-state.small { padding: 24px 12px; }

.spinner-wrap { display: flex; align-items: center; justify-content: center; padding: 48px 0; }
.spinner {
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}
.spinner.sm { width: 16px; height: 16px; border-width: 2px; }
@keyframes spin { to { transform: rotate(360deg); } }

.error-state {
  text-align: center;
  padding: 40px 20px;
  color: var(--danger);
}
.error-state .icon { width: 30px; height: 30px; margin: 0 auto 10px; }
.error-state p { font-size: 0.88rem; margin-bottom: 14px; color: var(--text-secondary); }

/* ---------- Toasts ---------- */
.toast-container {
  position: fixed;
  top: 14px;
  right: 14px;
  left: 14px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  pointer-events: none;
}
@media (min-width: 500px) { .toast-container { left: auto; width: 340px; } }
.toast {
  pointer-events: auto;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-size: 0.85rem;
  box-shadow: var(--shadow-lift);
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.2s, transform 0.2s;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast-success { border-left-color: var(--success); }
.toast-error { border-left-color: var(--danger); }
.toast-info { border-left-color: var(--accent); }
.toast-warning { border-left-color: var(--warning); }

/* ---------- Modales / drawers ---------- */
.overlay {
  position: fixed; inset: 0;
  background: rgba(6, 8, 16, 0.6);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 100;
  padding: 0;
  animation: fadeIn 0.15s ease;
}
@media (min-width: 640px) { .overlay { align-items: center; padding: 20px; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px 14px 0 0;
  width: 100%;
  max-width: 480px;
  max-height: 88vh;
  overflow-y: auto;
  box-shadow: var(--shadow-lift);
  animation: slideUp 0.2s ease;
}
@media (min-width: 640px) { .modal { border-radius: 14px; } }
@keyframes slideUp { from { transform: translateY(24px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 1;
}
.modal-head h3 { font-size: 1.02rem; font-weight: 700; }
.modal-body { padding: 18px; }
.modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 14px 18px;
  border-top: 1px solid var(--border);
  position: sticky;
  bottom: 0;
  background: var(--surface);
}

.drawer-overlay {
  position: fixed; inset: 0;
  background: rgba(6, 8, 16, 0.6);
  z-index: 100;
  display: flex;
  justify-content: flex-end;
  animation: fadeIn 0.15s ease;
}
.drawer {
  background: var(--surface);
  border-left: 1px solid var(--border);
  width: 100%;
  max-width: 420px;
  height: 100%;
  overflow-y: auto;
  box-shadow: var(--shadow-lift);
  animation: slideLeft 0.2s ease;
}
@keyframes slideLeft { from { transform: translateX(24px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }

.kv-row { display: flex; justify-content: space-between; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 0.86rem; }
.kv-row:last-child { border-bottom: none; }
.kv-row .k { color: var(--text-secondary); }
.kv-row .v { font-weight: 600; text-align: right; }

/* ---------- Chips / badges ---------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  background: var(--surface-alt);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.chip-success { background: var(--success-wash); color: var(--success); border-color: rgba(62, 207, 142, 0.3); }
.chip-danger { background: var(--danger-wash); color: var(--danger); border-color: rgba(255, 107, 107, 0.3); }
.chip-warning { background: var(--warning-wash); color: var(--warning); border-color: rgba(255, 180, 84, 0.3); }
.chip-accent { background: var(--accent-wash); color: var(--accent); border-color: rgba(108, 123, 255, 0.3); }

.badge-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  background: var(--warning-wash);
  color: var(--warning);
}

/* ---------- Toolbar de filtros ---------- */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
  align-items: flex-end;
}
.toolbar .field { margin-bottom: 0; min-width: 140px; flex: 1 1 140px; }
.toolbar .field.grow { flex: 2 1 200px; }
.toolbar-actions { display: flex; gap: 10px; margin-left: auto; align-self: center; }

/* ---------- Tabla responsiva (reservas) ---------- */
.rtable { width: 100%; border-collapse: collapse; }
.rtable thead { display: none; }
.rtable tbody tr {
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 10px;
  padding: 6px 14px;
  cursor: pointer;
  transition: border-color 0.15s;
}
.rtable tbody tr:hover { border-color: var(--accent); }
.rtable td {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px dashed var(--border);
  font-size: 0.85rem;
  text-align: right;
}
.rtable td:last-child { border-bottom: none; }
.rtable td::before {
  content: attr(data-label);
  color: var(--text-secondary);
  font-size: 0.74rem;
  font-weight: 600;
  text-align: left;
}
.rtable td.cell-code::before { content: none; }
.rtable td.cell-code { justify-content: flex-start; padding-top: 12px; }

@media (min-width: 760px) {
  .rtable { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; border-spacing: 0; }
  .rtable thead { display: table-header-group; }
  .rtable thead th {
    text-align: left;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-secondary);
    background: var(--surface-alt);
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
  }
  .rtable tbody tr { display: table-row; border: none; border-radius: 0; margin: 0; padding: 0; border-bottom: 1px solid var(--border); }
  .rtable tbody tr:last-child { border-bottom: none; }
  .rtable tbody tr:hover { background: var(--surface-hover); }
  .rtable td {
    display: table-cell;
    padding: 12px 14px;
    border-bottom: none;
    text-align: left;
    font-size: 0.86rem;
  }
  .rtable td::before { content: none; }
  .rtable td.cell-code { padding-top: 12px; }
}

/* ---------- Habitaciones ---------- */
.room-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 640px) { .room-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .room-grid { grid-template-columns: repeat(3, 1fr); } }
.room-card { display: flex; flex-direction: column; gap: 10px; }
.room-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.room-card-head h3 { font-size: 1rem; font-weight: 700; }
.room-desc { font-size: 0.82rem; color: var(--text-secondary); }
.room-meta { display: flex; gap: 14px; font-size: 0.8rem; color: var(--text-secondary); flex-wrap: wrap; }
.room-meta strong { color: var(--text); }
.room-price { font-size: 1.15rem; font-weight: 700; color: var(--accent); }
.room-card-foot { display: flex; align-items: center; justify-content: space-between; border-top: 1px solid var(--border); padding-top: 10px; margin-top: 2px; }
.room-inactive { opacity: 0.55; }

/* ---------- Calendario (hoja de cálculo: reservadas + precio por día) ---------- */
.cal-savebar {
  position: sticky;
  top: var(--topbar-h);
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 12px;
  margin-bottom: 14px;
  box-shadow: var(--shadow-soft);
}
.cal-savebar-nav { display: flex; align-items: center; gap: 8px; }
.cal-month-label { font-weight: 700; font-size: 0.92rem; min-width: 128px; text-align: center; text-transform: capitalize; }
.cal-savebar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }

.cal-avisos { align-items: flex-start; gap: 10px; }
.cal-avisos-list { margin: 6px 0 0; padding-left: 18px; list-style: disc; }
.cal-avisos-list li { padding: 2px 0; font-size: 0.82rem; }

.cal-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  -webkit-overflow-scrolling: touch;
}
table.cal-table { border-collapse: separate; border-spacing: 0; width: 100%; }
.cal-table th, .cal-table td { border-bottom: 1px solid var(--border); border-right: 1px solid var(--border); }
.cal-table th {
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--text-secondary);
  padding: 8px 4px;
  text-align: center;
  min-width: 50px;
  background: var(--surface-alt);
  white-space: nowrap;
}
.cal-table th .dnum { display: block; font-size: 0.84rem; color: var(--text); }
.cal-table th .dow { display: block; font-weight: 600; opacity: 0.75; text-transform: uppercase; margin-top: 1px; }
/* Fin de semana (sábado/domingo): pedido del hotelero, "el color de sábado y
   domingo k resalte más" — es el día de más venta y hoy se pierde entre los
   demás. `weekend` la agrega app.js a `th` (encabezado) Y a cada `td.cal-cell`
   de las 4 filas (cupo/precio/reservadas/mantenimiento).
   Dos reglas a propósito, NO una:
     · `.weekend` (una sola clase, la especificidad MÁS BAJA de todo el
       calendario) alcanza para los `td.cal-cell`: esa clase base no trae
       `background` propio, así que cualquier estado real (override en
       warning-wash, mantenimiento, celda editada `cal-dirty`, todos con 2
       clases) la gana sin pelear.
     · `.cal-table th.weekend` existe APARTE porque `.cal-table th` (el
       encabezado base, más arriba) SÍ trae su propio `background` con type
       selector incluido — más específico que una `.weekend` sola, así que
       sin esta regla el encabezado nunca se pintaría (bug real, cazado
       mirando el DOM en el navegador, no solo leyendo el CSS).
   Es un tinte de FONDO nada más — nunca compite con el color de texto ni con
   `today` (mismo empate de especificidad que ya existía antes de este
   cambio; `today` sigue declarada después y sigue ganando). Reusa el token
   `success` (variante fuerte) que ya existe en la paleta (positivo/activo en
   el resto del panel) precisamente porque NO se usa en ninguna otra celda
   del calendario (el azul de foco/edición/hoy y el ámbar de override ya
   están ocupados) — así no se confunde con ningún estado existente ni hace
   falta inventar un color nuevo. Variante "strong" (no la base) porque el
   pedido es explícito: "que resalte MÁS" que hoy. */
.weekend { background: var(--success-wash-strong); }
.cal-table th.weekend { background: var(--success-wash-strong); }
.cal-table th.today { background: var(--accent-wash-strong); }
.cal-table th.today .dnum, .cal-table th.today .dow { color: var(--accent); }

/* Corte de mes en la tira continua (2026-07-31, pedido del dueño del
   producto: "debe quedar más claro el mes... con el scroll infinito esto
   empeora mucho" — pasar de julio a agosto sin ninguna marca es justo donde
   alguien edita el mes equivocado). Dos señales, ninguna depende de hover
   (tableta no tiene tooltip) y ninguna pelea con lo que YA vive en esas
   mismas celdas (fin de semana = fondo, congelado = opacidad, override =
   fondo ámbar): un BORDE (no un fondo, así nunca compite por especificidad
   con esos otros estados) en el día 1° de cada mes, corrido a las 4 filas
   por app.js (calEsInicioMes) para que la línea baje pareja por toda la
   columna — y el nombre del mes escrito en el propio encabezado de ESE día,
   para no depender de la etiqueta pegajosa de la barra (que exige levantar
   la vista) ni de recordar ninguna convención. `!important` en el borde: con
   4 estados más pintando esa misma celda (weekend/is-past/override/dirty,
   hasta 2-3 clases a la vez) el corte de mes tiene que ganar SIEMPRE, es la
   pregunta que este cambio vino a resolver. */
.cal-table th.month-start, .cal-table td.cal-cell.month-start {
  border-left: 2px solid var(--accent) !important;
}
.cal-month-badge {
  display: block;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 1px;
}

/* Congelado: días ANTERIORES a hoy (pedido del hotelero, 2026-07-30: "no
   puedo cambiar la reserva más que del día de ahora para adelante... para
   atrás ya quedó congelado, aunque esté viendo todo el mes, para atrás
   nomás puedo ver, pero no puedo cambiar nada" — "hoy" SÍ es editable, ver
   panel/app.js::calEsPasado). Un tinte de OPACIDAD a propósito, no un
   background propio: así compone limpio encima de CUALQUIER estado que ya
   tuviera el día (fin de semana, override de precio/cupo, mantenimiento)
   sin pelearse con esas reglas por especificidad — se ve todo igual, nomás
   atenuado, tal como lo pidió. app.js agrega esta clase tanto al <th> del
   encabezado como a cada <td class="cal-cell"> de las 4 filas para ese día,
   y además pone disabled="" en los <input> editables (cupo/precio/
   mantenimiento) — el candado real es doble: HTML (disabled) + JS (los
   handlers de input/commit/pincel se salen temprano si la fecha ya pasó,
   ver calEsPasado en app.js); esto de aquí es solo la señal visual. */
.cal-cell.is-past { opacity: 0.55; }
.cal-table th.is-past { opacity: 0.55; }
/* Gana incluso dentro de una fila con el pincel armado (tr.cal-brush-armed
   .cal-input pone cursor:copy, 2 clases): un día pasado nunca debe invitar
   al clic de estampado con ese cursor, aunque el pincel de la fila SÍ tenga
   valor puesto — 3 clases > 2, gana sin pelear con el orden de la hoja. */
.cal-cell.is-past .cal-input { cursor: not-allowed; }
.cal-cell.is-past .cal-input:hover { background: transparent; }

/* Columna de etiquetas angosta a propósito (pedido del hotelero: "que quede
   más cortito para que no quede tan lejos") — así caben más días en pantalla
   sin scroll. Los textos largos truncan con ellipsis; el nombre del tipo
   conserva su title="" con el texto completo. */
.cal-table .cal-row-label, .cal-table th.corner {
  position: sticky;
  left: 0;
  z-index: 5;
  background: var(--surface);
  text-align: left;
  vertical-align: middle;
  padding: 8px 8px;
  min-width: 96px;
  max-width: 118px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cal-table th.corner { z-index: 6; background: var(--surface-alt); }
/* "(4)"/"(1050)" repetido en la etiqueta de Reserva/Precio junto al pincel —
   pedido del hotelero ("Reserva (4) y al dar click en un día se cambia a 4 la
   cantidad"), ver calBrushLabelUpdate/calGroupTpl en app.js. Mismo tono
   `accent` que el pincel armado de abajo: es una promesa del MISMO número. */
.cal-row-label-value { font-size: 0.7rem; font-weight: 700; color: var(--accent); white-space: nowrap; }

/* El nombre del tipo + su capacidad DEBE leerse completo ("Estándar Queen · 2
   personas"): la columna de etiquetas se angostó a propósito para que quepan más
   días, así que este encabezado se desborda sobre la celda vacía de al lado en
   vez de recortarse. `visible` gana al `overflow:hidden` de .cal-row-label. */
.cal-group-row .cal-group-label { font-weight: 700; color: var(--text); background: var(--surface-alt); border-top: 2px solid var(--border); overflow: visible; text-overflow: clip; z-index: 3; }
.cal-group-fill { background: var(--surface-alt); border-top: 2px solid var(--border); }

/* "Reservación (pagadas / total)" (2026-07-31, ver la nota grande en
   calReservadasCellTpl sobre el conflicto de orden con el hotelero real):
   el orden tiene que leerse EN LA ETIQUETA, siempre visible, sin depender de
   hover — en tableta el title="" nunca se ve. El nombre de la fila solo no
   cabía el paréntesis en una línea con el nowrap/ellipsis de base, así que
   esta fila puntual se libera de eso (mismo patrón que .cal-group-label
   arriba) y el paréntesis cae en su propio renglón chico. */
.cal-row-label-wrap { white-space: normal; overflow: visible; text-overflow: clip; }
.cal-row-sublabel { display: block; font-size: 0.62rem; font-weight: 600; color: var(--text-secondary); opacity: 0.85; line-height: 1.2; margin-top: 1px; }

.cal-cell {
  position: relative;
  text-align: center;
  padding: 4px;
  min-width: 50px;
  min-height: 44px;
  vertical-align: middle;
}
.cal-input {
  width: 100%;
  height: 34px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  text-align: center;
  font-size: 0.86rem;
  font-weight: 600;
  border-radius: var(--radius-sm);
  -moz-appearance: textfield;
}
.cal-input::-webkit-outer-spin-button, .cal-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cal-input:hover { background: var(--surface-hover); }
.cal-input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
/* "Reservación": SOLO LECTURA desde 2026-07-30 (ver calReservadasCellTpl en
   app.js) — ya no es un <input>, así que no lleva el chrome de campo editable
   (sin borde/fondo de .cal-input). Misma altura/centrado que las celdas
   editables de al lado para que la fila no salte de tamaño; color
   `text-secondary` (apagado) a propósito, la misma señal visual de "esto no
   se edita aquí" que ya usa el panel en otros lados (p. ej.
   .cal-cell-mantenimiento). `.cal-fija-note` (la notita "N fijas" que existía
   para explicar el `min=` del <input> viejo) se quitó por completo: sin campo
   editable no hay "parte fija vs. parte editable" que distinguir. */
.cal-value-readonly {
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text-secondary);
}
/* Nota chica bajo la fracción "pagadas/total" de "Reservación" (2026-07-31):
   YA NO es la fracción en sí (esa ahora es el número grande, ver
   .cal-value-readonly y la nota grande en calReservadasCellTpl) — es el total
   OCUPADO de verdad cuando difiere, por bloqueos manuales o de agencias
   (iCal) encima de las reservas del sistema. Tono `accent` (informativo), el
   mismo que ya usa el panel para "informativo" en notice-info/chip-accent. */
.cal-pagadas-note {
  display: block;
  font-size: 0.6rem;
  font-weight: 700;
  color: var(--accent);
  line-height: 1.2;
  margin-top: 1px;
}
.cal-cell-precio.is-override { background: var(--warning-wash); }
.cal-cell-precio.is-override .cal-input { color: var(--warning); font-weight: 700; }

/* "Reserva" (cupo): mismo tratamiento visual que el precio con override —
   el día tiene un valor propio en vez de heredar el default del tipo. */
.cal-cell-cupo.is-override { background: var(--warning-wash); }
.cal-cell-cupo.is-override .cal-input { color: var(--warning); font-weight: 700; }

/* Mantenimiento (fuera de servicio): fila atenuada y OPCIONAL — distinta de
   "Reservación" (venta) y "Precio". Solo se pinta si el hotel tiene
   features.mantenimiento activo (ver calGroupTpl en app.js); cuenta contra
   disponibilidad pero no es ocupación. */
.cal-table .cal-row-mantenimiento .cal-row-label { background: var(--surface-alt); font-style: italic; }
/* Dos clases a propósito (no solo `.cal-cell-mantenimiento`): sube la
   especificidad justo lo suficiente para ganarle siempre a `.weekend` (una
   sola clase, ver más arriba) sin importar el orden en la hoja — un cuarto en
   mantenimiento no deja de verse así por caer en sábado/domingo. */
.cal-cell.cal-cell-mantenimiento { background: var(--surface-alt); }
.cal-cell-mantenimiento .cal-input { color: var(--text-secondary); }
.cal-cell-mantenimiento .cal-input:hover,
.cal-cell-mantenimiento .cal-input:focus { color: var(--text); }

.cal-cell.cal-dirty { background: var(--accent-wash); box-shadow: inset 0 0 0 2px var(--accent); border-radius: 5px; }

/* Pincel de Reserva/Precio (pedido real del hotelero: escribir el valor UNA
   vez y luego solo dar clic en los días, en vez de borrar y teclear cada
   celda — ver calBrushControlTpl/calWireBrush en app.js). Vacío = clic
   normal en la celda, sin ningún cambio visual (por eso NADA de esto se
   activa si `.cal-brush-armed` no está puesto).

   Selector de 3 clases en el override de .cal-row-label a propósito: la
   regla base (`.cal-table .cal-row-label`, 2 clases) angostó la columna de
   etiquetas por pedido del hotelero ("que quede más cortito") con
   white-space:nowrap + ellipsis — eso es exactamente para UNA sola línea de
   texto. display:flex en .cal-brush ya fuerza su propio renglón (un bloque
   siempre rompe el flujo en línea, pase lo que pase con white-space), pero
   sin permitir el wrap aquí la fila completa (etiqueta + pincel) se seguiría
   tratando como una sola línea para efectos de recorte/ellipsis y el
   navegador podía (se comprobó en vivo) recortar el pincel en vez de
   mostrarlo en su propio renglón. 3 clases > 2 clases: gana siempre, sin
   depender del orden en la hoja. */
.cal-table .cal-row-cupo .cal-row-label,
.cal-table .cal-row-precio .cal-row-label {
  white-space: normal;
  line-height: 1.25;
}
.cal-brush {
  display: flex;
  align-items: center;
  gap: 3px;
  margin-top: 3px;
  flex-wrap: wrap; /* red de seguridad: si algún día no cupiera en una línea, se
                       apila en vez de desbordar la columna angosta (ver la
                       nota de 3 clases arriba) — hoy no debería hacer falta. */
}
/* .cal-brush-tag es un <button> real: un clic aquí vacía el pincel (ver
   calWireBrush/calBrushClear en app.js).

   NO LLEVA TEXTO EN NINGÚN ESTADO. El hotelero lo pidió en dos pasadas — antes
   decía "pincel" apagado y "vaciar" armado; primero quitó "pincel" ("para que
   quede en el mismo renglón") y después "quita la palabra vacío también, deja
   solo un espacio para después, si quiero agregar una palabra, poder hacerlo".
   El hueco es DELIBERADO y es suyo: él decidirá qué palabra va, o ninguna.

   Por eso `min-width` en vez de dejarlo colapsar a cero: el espacio se reserva
   AHORA para que el día que se le meta una palabra la tabla no se recorra de
   golpe, y para que el botón siga teniendo superficie que tocar — un botón de
   0px de ancho es un botón que no existe, sobre todo con el dedo. Si algún día
   vuelve a llevar texto, este min-width solo es un piso: no lo recorta. */
.cal-brush-tag {
  font: inherit;
  border: none;
  background: transparent;
  margin: 0;
  padding: 0;
  cursor: pointer;
  font-size: 0.56rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  opacity: 0.75;
  white-space: nowrap;
  min-width: 2.4em;
  min-height: 1.1em;
}
.cal-brush-tag:hover { opacity: 1; text-decoration: underline; }
.cal-brush-tag:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cal-brush-input {
  width: 30px;
  height: 20px;
  padding: 0 2px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg);
  color: var(--text);
  text-align: center;
  font-size: 0.7rem;
  font-weight: 700;
  -moz-appearance: textfield;
}
.cal-brush-input::-webkit-outer-spin-button, .cal-brush-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cal-brush-input-precio { width: 44px; }
.cal-brush-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-wash);
}
/* Armado (con valor puesto): el tag y el input se pintan de acento — realce
   SIEMPRE visible, no depende de hover — y las celdas de ESA fila cambian de
   cursor para avisar que el próximo clic va a estampar, no a editar a mano.
   `tr.cal-brush-armed .cal-input` (no .cal-cell) a propósito: el cursor es
   propiedad de con qué elemento interactúa el mouse (el <input>, que llena
   toda la celda), y a diferencia de background NUNCA se apila/pelea con
   .weekend, .is-override ni .cal-dirty — cero riesgo de especificidad aquí. */
.cal-brush.cal-brush-armed .cal-brush-tag { color: var(--accent); opacity: 1; }
.cal-brush.cal-brush-armed .cal-brush-input {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-wash);
}
tr.cal-brush-armed .cal-input { cursor: copy; }
/* Franja de acento en la etiqueta (columna `sticky`, ver arriba): a diferencia
   del cursor "copy" de la línea de encima, esto SÍ se ve sin necesidad de
   pasar el mouse por una celda — importa en pantallas táctiles (tablet/
   celular en la recepción) donde "cursor" no significa nada. Con el pincel
   precargado por default (ver calBrushControlTpl en app.js), esta franja es
   la señal de "esta fila va a estampar" que queda visible aunque el hotelero
   esté viendo los días de la derecha, no la etiqueta. */
tr.cal-brush-armed .cal-row-label { box-shadow: inset 3px 0 0 var(--accent); }

@media (max-width: 480px) {
  .cal-savebar-actions { width: 100%; justify-content: space-between; margin-left: 0; }
  .cal-savebar-nav { width: 100%; justify-content: center; }
}

/* ---------- Conversaciones (chat) ---------- */
.conv-wrap {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: calc(100vh - var(--topbar-h) - var(--bottom-nav-h) - 32px);
  min-height: 420px;
}
@media (min-width: 860px) {
  .conv-wrap { flex-direction: row; height: calc(100vh - var(--topbar-h) - 64px); }
}
.conv-list-pane {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-y: auto;
  flex-shrink: 0;
}
@media (min-width: 860px) { .conv-list-pane { width: 320px; } }
.conv-thread-pane {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}
.conv-wrap.thread-open .conv-list-pane { display: none; }
@media (min-width: 860px) { .conv-wrap.thread-open .conv-list-pane { display: block; } }
.conv-wrap:not(.thread-open) .conv-thread-pane { display: none; }
@media (min-width: 860px) { .conv-wrap:not(.thread-open) .conv-thread-pane { display: flex; } }

.conv-row {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.conv-row:hover { background: var(--surface-hover); }
.conv-row.selected { background: var(--accent-wash); }
.conv-avatar {
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--accent-wash-strong);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.85rem;
  flex-shrink: 0;
}
.conv-row-main { min-width: 0; flex: 1; }
.conv-row-top { display: flex; justify-content: space-between; gap: 6px; }
.conv-row-name { font-weight: 700; font-size: 0.87rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv-row-time { font-size: 0.7rem; color: var(--text-secondary); flex-shrink: 0; }
.conv-row-bottom { display: flex; justify-content: space-between; align-items: center; gap: 6px; margin-top: 2px; }
.conv-row-preview { font-size: 0.78rem; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.conv-unread {
  min-width: 18px; height: 18px; border-radius: 999px; background: var(--accent);
  color: #fff; font-size: 0.65rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center; padding: 0 5px; flex-shrink: 0;
}

.thread-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.thread-head-name { font-weight: 700; font-size: 0.92rem; }
.thread-head-phone { font-size: 0.74rem; color: var(--text-secondary); }
.thread-head-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }

.thread-body { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.bubble-row { display: flex; }
.bubble-row.in { justify-content: flex-start; }
.bubble-row.out { justify-content: flex-end; }
.bubble {
  max-width: 78%;
  padding: 9px 12px;
  border-radius: 13px;
  font-size: 0.86rem;
  white-space: pre-wrap;
  word-break: break-word;
}
.bubble-row.in .bubble { background: var(--surface-alt); border: 1px solid var(--border); border-bottom-left-radius: 3px; }
.bubble-row.out .bubble { background: var(--accent-wash-strong); border: 1px solid rgba(108, 123, 255, 0.3); border-bottom-right-radius: 3px; }
.bubble-origin { font-size: 0.63rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; color: var(--text-secondary); margin-bottom: 3px; }
.bubble-time { font-size: 0.62rem; color: var(--text-secondary); margin-top: 4px; text-align: right; }

.thread-foot { border-top: 1px solid var(--border); padding: 10px 12px; flex-shrink: 0; }
.thread-foot-notice { margin: 0 0 10px; }
.thread-input-row { display: flex; gap: 8px; align-items: flex-end; }
.thread-input-row textarea { flex: 1; min-height: 40px; max-height: 110px; }

/* ---------- WhatsApp ---------- */
.wa-panel { max-width: 460px; text-align: center; padding: 34px 24px; }
.wa-status-icon { width: 56px; height: 56px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 16px; }
.wa-status-icon.ok { background: var(--success-wash); color: var(--success); }
.wa-status-icon.warn { background: var(--warning-wash); color: var(--warning); }
.wa-status-icon.bad { background: var(--danger-wash); color: var(--danger); }
.wa-status-icon .icon { width: 28px; height: 28px; }
.wa-panel h2 { font-size: 1.1rem; margin-bottom: 8px; }
.wa-panel p.desc { color: var(--text-secondary); font-size: 0.87rem; margin-bottom: 18px; }
.wa-number { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1rem; font-weight: 700; margin-bottom: 4px; }
.wa-qr-box { background: #fff; padding: 14px; border-radius: 12px; display: inline-block; margin: 0 auto 16px; }
.wa-qr-box img { width: 220px; height: 220px; image-rendering: pixelated; }
.wa-qr-steps { text-align: left; font-size: 0.8rem; color: var(--text-secondary); background: var(--surface-alt); border-radius: var(--radius-sm); padding: 12px 14px; margin-top: 4px; }
.wa-qr-steps li { padding: 3px 0; }
.wa-qr-steps li::before { content: "• "; color: var(--accent); font-weight: 700; }
/* "Cambiar de número": acción secundaria y deliberadamente discreta — desconecta
   el bot, así que no compite visualmente con el botón de vincular. */
.wa-cambiar-btn { margin-top: 12px; color: var(--text-secondary); }
.wa-cambiar-btn:hover { color: var(--text); border-color: var(--danger); }

/* ---------- Cobranza del operador (admin.html) ---------- */
/* Misma paleta y mismos componentes que el panel del hotelero: es otra puerta,
   no otro producto. Solo lo que la vista de cartera necesita de más. */
/* text-align: left explícito: la celda de la tabla alinea a la derecha en móvil
   y el slug se veía descolgado debajo del nombre del hotel. */
.admin-slug { font-size: 0.72rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; text-align: left; }
.admin-td-accion { text-align: right; }
@media (min-width: 760px) { .admin-td-accion { text-align: right; white-space: nowrap; } }
.admin-aviso-llave { margin-top: 16px; text-align: left; font-size: 0.8rem; }
.admin-aviso-pie { margin-top: 26px; }
.admin-deposito { margin-bottom: 12px; }
.admin-deposito-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 12px; }
.admin-deposito-monto { font-size: 1.3rem; font-weight: 800; color: var(--accent); }
.admin-deposito-acciones { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.admin-deposito-pie { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 10px; display: flex; justify-content: flex-end; }
.admin-sin-candidatos { font-size: 0.82rem; margin-top: 4px; }

/* ---------- Misc ---------- */
.mt-0 { margin-top: 0; }
.text-secondary { color: var(--text-secondary); }
.text-center { text-align: center; }
.hidden { display: none !important; }
.stack-gap { display: flex; flex-direction: column; gap: 10px; }
.desglose-list { border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; margin-top: 4px; }
.desglose-list .kv-row { padding: 8px 12px; }
.success-box { text-align: center; padding: 10px 4px 4px; }
.success-box .icon-big { width: 46px; height: 46px; color: var(--success); margin: 0 auto 12px; }
.success-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1.5rem; font-weight: 800; letter-spacing: 0.04em; color: var(--accent); margin-bottom: 4px; }
.success-total { font-size: 1.1rem; font-weight: 700; margin-bottom: 14px; }

/* ---------- Habitaciones: fotos ---------- */
.room-fotos { display: flex; gap: 8px; flex-wrap: wrap; margin: 2px 0 4px; }
.room-foto-thumb {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--border);
  flex-shrink: 0;
}
.room-foto-thumb img { width: 100%; height: 100%; object-fit: cover; }
.room-foto-del {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 8, 16, 0.7);
  color: #fff;
  border: none;
  padding: 0;
}
.room-foto-del .icon { width: 11px; height: 11px; }
.room-foto-del:hover { background: var(--danger); }
.room-foto-add {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--text-secondary);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-size: 0.64rem;
  font-weight: 600;
  flex-shrink: 0;
}
.room-foto-add:hover { border-color: var(--accent); color: var(--accent); }
.room-foto-add .icon { width: 15px; height: 15px; }

/* ---------- Ajustes ---------- */
.ajustes-sections { display: flex; flex-direction: column; gap: 14px; margin-bottom: 18px; }

/* Ancho legible para los campos de texto/hora (pedido real del hotelero,
   llamada 2026-07-29: "el ancho de columna más corto para que queden más
   pegados" — hoy se estiran al ancho completo de la tarjeta y se ven
   desperdigados). No se toca el ancho de la tarjeta en sí, solo el de sus
   campos, así el bloque se lee compacto sin dejar la tarjeta angosta. */
.ajustes-narrow { max-width: 540px; }

/* Check-in/check-out "más pegados": sin este override, cada .field de
   .field-row ocupa 50% de .ajustes-narrow (flex:1 heredado) aunque el input
   de hora ya sea angosto, dejando un hueco muerto entre ambos. */
.field-row .field.field-time { flex: 0 0 auto; }

/* Los campos de HORA deben verse visiblemente más angostos que los de texto
   (mismo pedido de arriba): sin esto, input[type=time].input hereda
   width:100% de .input y se estira al ancho de su columna. 150px (no menos):
   en locale de 12h (AM/PM, ej. navegador en inglés) el control nativo pide
   ~135px de ancho real y con menos se recorta el "p. m." — comprobado en
   vivo contra el panel desplegado, no es solo una preferencia visual. */
input[type="time"].input { width: auto; min-width: 100px; max-width: 150px; }
select.input.input-dia { width: auto; min-width: 130px; max-width: 158px; }

/* Avisos y reportes por WhatsApp: switch + título/ayuda + controles (hora, y
   en el semanal también el día) — "switch + hora juntos" cuando quepan;
   mobile-first, se van a su propia línea en pantalla chica (flex-wrap). */
.ajustes-reporte { padding: 12px 0; border-bottom: 1px solid var(--border); }
.ajustes-reporte:first-child { padding-top: 2px; }
.ajustes-reporte:last-child { border-bottom: none; padding-bottom: 2px; }
.ajustes-reporte-main { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; }
.ajustes-reporte-text { flex: 1 1 170px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ajustes-reporte-title { font-weight: 600; font-size: 0.88rem; }
.ajustes-reporte-hint { font-size: 0.76rem; color: var(--text-secondary); }
.ajustes-reporte-controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
@media (max-width: 480px) { .ajustes-reporte-controls { margin-left: 0; } }

.input-suffix { position: relative; display: flex; align-items: center; }
.input-suffix input.input { padding-right: 34px; }
.input-suffix-label {
  position: absolute;
  right: 12px;
  color: var(--text-secondary);
  font-size: 0.82rem;
  font-weight: 600;
  pointer-events: none;
}
.copy-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
}
.copy-link {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78rem;
  color: var(--text);
}
.copy-link:hover { color: var(--accent); text-decoration: underline; }
.ajustes-ical-item { padding: 14px 0; border-bottom: 1px solid var(--border); }
.ajustes-ical-item:first-child { padding-top: 2px; }
.ajustes-ical-item:last-child { border-bottom: none; padding-bottom: 2px; }
.ajustes-ical-name { font-weight: 700; font-size: 0.92rem; margin-bottom: 10px; }
.ajustes-save-bar { margin-top: 4px; }
@media (min-width: 860px) { .ajustes-save-bar { max-width: 280px; margin-left: auto; } }

/* ---------- Habitaciones: personas adicionales ---------- */
.room-extra-note { font-size: 0.74rem; color: var(--text-secondary); margin-top: -4px; }
.modal-section-title {
  font-size: 0.86rem;
  font-weight: 700;
  margin: 4px 0 12px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

/* ---------- Servicios ---------- */
.servicio-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 640px) { .servicio-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .servicio-grid { grid-template-columns: repeat(3, 1fr); } }
.servicio-card { display: flex; flex-direction: column; gap: 10px; }
.servicio-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.servicio-card-head h3 { font-size: 1rem; font-weight: 700; }
.servicio-card-actions { display: flex; gap: 2px; flex-shrink: 0; }
.servicio-desc { font-size: 0.82rem; color: var(--text-secondary); }
.servicio-price { font-size: 1.15rem; font-weight: 700; color: var(--accent); }
.servicio-card-foot { display: flex; align-items: center; justify-content: space-between; border-top: 1px solid var(--border); padding-top: 10px; margin-top: 2px; }
.servicio-inactive { opacity: 0.55; }
.btn-icon-danger:hover { color: var(--danger); background: var(--danger-wash); border-color: rgba(255, 107, 107, 0.35); }

/* ---------- Reservas: desglose con extras ---------- */
.reserva-total-destacado { padding-top: 12px; padding-bottom: 4px; }
.reserva-total-destacado .k { color: var(--text); font-weight: 700; font-size: 0.92rem; }
.reserva-total-destacado .v { color: var(--accent); font-size: 1.2rem; font-weight: 800; }
.servicios-check-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 170px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  background: var(--bg);
}
.servicios-check-item { margin: 0; }
.success-extras-note { font-size: 0.8rem; color: var(--text-secondary); margin-top: -8px; margin-bottom: 14px; }

/* ---- Logo del hotel (Ajustes) ---- */
.logo-preview {
  background: var(--bg, #0e1220);
  border: 1px solid var(--border, #232a42);
  border-radius: 10px;
  padding: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 96px;
  margin-bottom: 12px;
}
.logo-preview img { max-width: 100%; max-height: 120px; object-fit: contain; }
.logo-acciones { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---- Aviso de canal en el tablero ---- */
.aviso-desde { color: var(--text-secondary, #8a93ad); font-size: 0.92em; }
