@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap');

:root {
  --bg: #fafaf8;
  --bg-card: #ffffff;
  --bg-surface: #f3f2ee;
  --bg-hover: #eeedea;
  --text: #1a1a18;
  --text-secondary: #6b6a66;
  --text-tertiary: #9d9c98;
  --border: rgba(0, 0, 0, 0.1);
  --border-hover: rgba(0, 0, 0, 0.2);
  --accent: #0f6e56;
  --accent-bg: #e1f5ee;
  --accent-text: #085041;
  --danger: #a32d2d;
  --danger-bg: #fcebeb;
  --danger-text: #791f1f;
  --warn: #854f0b;
  --warn-bg: #faeeda;
  --warn-text: #633806;
  --info: #185fa5;
  --info-bg: #e6f1fb;
  --info-text: #0c447c;
  /* Distinct from --accent (the teal confirmed/online already use) so "arrived" reads as
     its own signal — a guest who's been seated, not just a booking source/state label. */
  --success: #1e8e3e;
  --success-bg: #e3f6e8;
  --success-text: #1f7a3a;
  --radius: 10px;
  --radius-lg: 14px;
  --font-mono: 'JetBrains Mono', monospace;
  --tap: 44px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #161614;
    --bg-card: #1e1e1c;
    --bg-surface: #252523;
    --bg-hover: #2c2c2a;
    --text: #e8e7e3;
    --text-secondary: #a3a29e;
    --text-tertiary: #6b6a66;
    --border: rgba(255, 255, 255, 0.1);
    --border-hover: rgba(255, 255, 255, 0.2);
    --accent-bg: #085041;
    --accent-text: #9fe1cb;
    --danger-bg: #501313;
    --danger-text: #f7c1c1;
    --warn-bg: #412402;
    --warn-text: #fac775;
    --info-bg: #042c53;
    --info-text: #85b7eb;
    --success: #34a853;
    --success-bg: #10321a;
    --success-text: #7ee2a0;
  }
}

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

html,
body {
  height: 100%;
}

body {
  font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 16px;
  line-height: 1.5;
}

.hidden {
  display: none !important;
}

button,
input,
select,
textarea {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

/* ── Key screen ── */
#login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

.key-card {
  width: 100%;
  max-width: 380px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 2rem;
}

.key-card h1 {
  font-size: 20px;
  font-weight: 700;
  margin-bottom: 0.4rem;
}

.key-card p {
  color: var(--text-secondary);
  font-size: 14px;
  margin-bottom: 1.5rem;
}

.key-card .field-error {
  color: var(--danger);
  font-size: 13px;
  margin-top: 0.6rem;
  min-height: 1.2em;
}

/* ── Top bar ── */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  padding: 0.85rem 1.25rem;
}

.topbar-brand {
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.2px;
  margin-right: auto;
}

.topbar-brand .sub {
  display: block;
  font-size: 12px;
  font-weight: 400;
  color: var(--text-secondary);
}

.date-nav {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* Menu / Settings / Logout group. Inline on desktop; collapses behind #nav-toggle
   (the ☰ burger) on narrow screens — see the max-width media query below. */
.topbar-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* .topbar scope needed to outrank .btn's own display (equal class specificity otherwise). */
.topbar .nav-toggle {
  display: none;
}

/* The text label next to an icon button — only shown inside the open mobile dropdown. */
.nav-label {
  display: none;
}

.date-nav input[type='date'] {
  height: var(--tap);
  padding: 0 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-surface);
}

.btn {
  height: var(--tap);
  min-width: var(--tap);
  padding: 0 1rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg-surface);
  cursor: pointer;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  transition: background 0.12s, border-color 0.12s;
}

.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-hover);
}

.btn-icon {
  padding: 0;
  width: var(--tap);
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.btn-primary:hover {
  background: #0c5a45;
  border-color: #0c5a45;
}

.btn-danger {
  background: var(--bg-card);
  border-color: var(--danger);
  color: var(--danger);
}

.btn-danger:hover {
  background: var(--danger-bg);
}

.btn-success {
  background: var(--bg-card);
  border-color: var(--success);
  color: var(--success);
}

.btn-success:hover {
  background: var(--success-bg);
}

.btn-cancel {
  background: none;
  border-color: var(--border);
  color: var(--text-secondary);
}

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

.btn-publish {
  background: var(--warn-bg);
  border-color: var(--warn);
  color: var(--warn-text);
}

.btn-publish:hover {
  background: var(--warn);
  color: #fff;
}

/* ── Main ── */
.main {
  padding: 1.25rem;
  max-width: 1400px;
  margin: 0 auto;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
  flex-wrap: wrap;
}

.page-title {
  font-size: 22px;
  font-weight: 700;
}

/* ── Slot summary strip ── */
.slot-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.slot-summary {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
}

.slot-summary .time {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 15px;
}

.slot-summary .count {
  color: var(--text-secondary);
  font-size: 13px;
  margin-top: 0.2rem;
}

.slot-summary.full .count {
  color: var(--danger);
  font-weight: 500;
}

.closed-banner {
  background: var(--bg-surface);
  border: 1px dashed var(--border-hover);
  border-radius: var(--radius);
  padding: 1.5rem;
  text-align: center;
  color: var(--text-secondary);
  font-weight: 500;
  margin-bottom: 1.5rem;
}

/* ── Slot columns ── */
.slot-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
  align-items: start;
}

.slot-column {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.slot-column-head {
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  background: var(--bg-surface);
}

.slot-column-head .time {
  font-family: var(--font-mono);
  font-weight: 500;
}

.slot-column-head .count {
  font-size: 13px;
  color: var(--text-secondary);
}

.slot-column-body {
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 60px;
}

.slot-empty {
  color: var(--text-tertiary);
  font-size: 13px;
  padding: 0.75rem;
  text-align: center;
}

/* ── Reservation row ── */
.res-row {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.7rem 0.8rem;
}

.res-row.is-inactive {
  opacity: 0.5;
}

/* Arrived is the opposite of dimmed — the guest is here, so the row stays at full
   strength with a green border/background instead of fading like a no-longer-relevant one. */
.res-row.is-arrived {
  border-color: var(--success);
  background: var(--success-bg);
}

.res-row-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.res-name {
  font-weight: 500;
}

/* Reservation whose PII was stripped after the retention window (see anonymize job). */
.res-anon {
  font-style: italic;
  opacity: 0.6;
}

/* Hidden debug panel (revealed by tapping the restaurant name 5×). */
.debug-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.debug-out {
  margin-top: 1.25rem;
  padding: 12px 14px;
  background: #11151a;
  color: #d7dde3;
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 240px;
  overflow: auto;
}

.res-party {
  font-family: var(--font-mono);
  color: var(--text-secondary);
  font-size: 13px;
  white-space: nowrap;
}

.res-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.35rem;
  font-size: 13px;
  color: var(--text-secondary);
}

.res-note {
  margin-top: 0.35rem;
  font-size: 13px;
  color: var(--text-secondary);
  font-style: italic;
}

.res-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.6rem;
}

.res-actions .btn {
  height: 36px;
  padding: 0 0.7rem;
  font-size: 13px;
}

/* ── Badges ── */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.badge-manual,
.badge-external {
  background: var(--info-bg);
  color: var(--info-text);
}

.badge-online,
.badge-confirmed {
  background: var(--accent-bg);
  color: var(--accent-text);
}

.badge-cancelled,
.badge-no_show {
  background: var(--danger-bg);
  color: var(--danger-text);
}

.badge-pending {
  background: var(--warn-bg);
  color: var(--warn-text);
}

.badge-expired {
  background: var(--bg-surface);
  color: var(--text-secondary);
}

.badge-arrived {
  background: var(--success-bg);
  color: var(--success-text);
}

/* ── Settings ── */
.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1.5rem;
}

.settings-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
}

.settings-card h2 {
  font-size: 16px;
  margin-bottom: 0.25rem;
}

.settings-card .hint {
  color: var(--text-secondary);
  font-size: 13px;
  margin-bottom: 1rem;
}

.settings-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.settings-list-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.6rem 0.75rem;
  background: var(--bg-surface);
  border-radius: var(--radius);
  font-size: 14px;
  transition: background 0.6s ease;
}

/* Briefly flashes when gotoStay() (app.js) scrolls to this row from a calendar click —
   same add-class-then-setTimeout-remove pattern as .toast.show, but as a transition
   rather than a fixed-position overlay. */
.settings-list-item.stay-row-highlight {
  background: var(--warn-bg);
  transition: background 0.15s ease;
}

.settings-list-item .reason {
  color: var(--text-secondary);
  font-size: 13px;
}

.settings-empty {
  color: var(--text-tertiary);
  font-size: 13px;
  padding: 0.5rem;
}

.settings-form {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: flex-end;
}

.settings-form .field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex: 1 1 130px;
}

.settings-form label {
  font-size: 12px;
  color: var(--text-secondary);
}

.settings-form input {
  height: var(--tap);
  padding: 0 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-surface);
  width: 100%;
}

/* ── Modal ── */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 1rem;
}

.modal {
  width: 100%;
  max-width: 480px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--bg-card);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
}

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

.modal-header h2 {
  font-size: 17px;
}

.modal-body {
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--border);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.field label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
}

.field input,
.field select,
.field textarea {
  height: var(--tap);
  padding: 0 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-surface);
  width: 100%;
}

.field textarea {
  height: auto;
  padding: 0.6rem 0.75rem;
  min-height: 70px;
  resize: vertical;
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.modal-error {
  color: var(--danger);
  font-size: 13px;
  min-height: 1.2em;
}

/* ── Menu management ── */
.hint {
  color: var(--text-secondary);
  font-size: 13px;
}

.page-header-actions {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}

#menu-hint {
  margin: -0.5rem 0 1.25rem;
}

.menu-category {
  margin-bottom: 1.25rem;
}

.menu-category-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.menu-category-head h2 {
  margin-bottom: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.menu-category-actions {
  display: flex;
  gap: 0.4rem;
}

.menu-item-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.menu-item-row {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.6rem 0.75rem;
  background: var(--bg-surface);
  border-radius: var(--radius);
}

.menu-item-row.is-inactive {
  opacity: 0.55;
}

/* Dim only the title of a hidden category, not its action buttons (which must stay usable). */
.menu-category.is-inactive .menu-category-head h2 {
  opacity: 0.55;
}

.menu-thumb {
  width: 56px;
  height: 56px;
  border-radius: var(--radius);
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg-hover);
}

.menu-thumb-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 10px;
  color: var(--text-tertiary);
  border: 1px dashed var(--border-hover);
}

.menu-item-info {
  flex: 1 1 auto;
  min-width: 0;
}

.menu-item-name {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  font-weight: 500;
}

.menu-item-desc {
  font-size: 13px;
  color: var(--text-secondary);
  margin-top: 0.15rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.menu-item-price {
  font-family: var(--font-mono);
  font-size: 14px;
  white-space: nowrap;
}

.menu-item-actions {
  display: flex;
  gap: 0.3rem;
  flex-shrink: 0;
}

.menu-item-actions .btn {
  height: 36px;
  width: 36px;
}

.badge-featured {
  background: var(--accent);
  color: #fff;
}

.menu-toggle-field {
  justify-content: center;
  gap: 0.4rem;
}

.menu-check {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 13px;
  font-weight: 400;
  color: var(--text);
}

.menu-check input {
  width: auto;
  height: auto;
}

.menu-image-picker {
  display: flex;
  gap: 0.85rem;
  align-items: center;
}

.menu-image-preview {
  width: 84px;
  height: 84px;
  border-radius: var(--radius);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.menu-image-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.menu-image-preview span {
  font-size: 11px;
  color: var(--text-tertiary);
}

.menu-image-buttons {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}

.menu-image-buttons input[type='file'] {
  font-size: 13px;
  max-width: 100%;
}

/* ── Toast ── */
.toast {
  position: fixed;
  bottom: 1.25rem;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--text);
  color: var(--bg);
  padding: 0.7rem 1.1rem;
  border-radius: var(--radius);
  font-size: 14px;
  opacity: 0;
  transition: opacity 0.2s, transform 0.2s;
  z-index: 200;
  max-width: 90vw;
}

.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.toast-error {
  background: var(--danger);
  color: #fff;
}

/* ── Misc ── */
.spinner-line {
  text-align: center;
  color: var(--text-tertiary);
  padding: 2rem;
}

@media (max-width: 640px) {
  /* Keep brand + burger on the first row; date-nav and Add-reservation wrap to full-width
     rows below. The Menu/Settings/Logout group collapses into a dropdown under the burger. */
  .topbar {
    align-items: center;
    row-gap: 0.75rem;
  }

  .topbar-brand {
    margin-right: auto;
  }

  .topbar .nav-toggle {
    display: inline-flex;
    order: 1;
  }

  .date-nav {
    order: 5;
    flex-basis: 100%;
    justify-content: space-between;
  }

  #add-res-btn {
    order: 6;
    flex-basis: 100%;
  }

  /* Dropdown panel anchored under the burger (the sticky .topbar is its positioning
     context). Hidden until #nav-toggle adds .open. Buttons already hidden by role
     (.hidden) simply don't appear. */
  .topbar-actions {
    order: 2;
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    right: 0.75rem;
    flex-direction: column;
    align-items: stretch;
    gap: 0.35rem;
    min-width: 190px;
    padding: 0.5rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
    z-index: 50;
  }

  .topbar-actions.open {
    display: flex;
  }

  .topbar-actions .btn {
    width: 100%;
    justify-content: flex-start;
  }

  .topbar-actions .btn-icon {
    padding: 0 1rem;
  }

  .nav-label {
    display: inline;
    margin-left: 0.5rem;
  }

  .field-row {
    grid-template-columns: 1fr;
  }
}

/* ── Day view: occupancy summary + agenda ── */
.day-summary {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 0.9rem 1rem;
  margin-bottom: 1.25rem;
  overflow: hidden;
}
.day-sum-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.dst-big { font-size: 15px; font-weight: 500; }
.dst-big b { font-variant-numeric: tabular-nums; }
.dst-leg { font-size: 12px; color: var(--text-tertiary); }

.occ { position: relative; margin-top: 0.9rem; padding-left: 26px; min-width: 0; }
.occ-axis { position: absolute; left: 0; top: 0; width: 24px; height: 88px; }
.occ-axis::after { content: ""; position: absolute; right: 0; top: 0; bottom: 0; width: 1px; background: var(--border-hover); }
.occ-tick { position: absolute; right: 0; transform: translateY(-50%); display: flex; align-items: center; gap: 3px; white-space: nowrap; }
.occ-tick i { width: 4px; height: 1px; background: var(--border-hover); display: inline-block; }
.occ-tick span { font-family: var(--font-mono); font-size: 9px; color: var(--text-tertiary); }
.occ-plot { position: relative; height: 88px; display: flex; align-items: flex-end; gap: 5px; min-width: 0; }
.occ-bar { flex: 1; height: 100%; display: flex; align-items: flex-end; justify-content: center; min-width: 0; }
.occ-track { width: 100%; max-width: 24px; height: 100%; background: var(--bg-surface); border: 1px solid var(--border); border-radius: 5px; display: flex; align-items: flex-end; overflow: hidden; }
.occ-fill { width: 100%; background: var(--accent); border-radius: 4px 4px 0 0; transition: height 0.35s ease; }
.occ-bar.empty .occ-fill { background: transparent; }
.occ-grid { position: absolute; inset: 0; pointer-events: none; }
.occ-gline { position: absolute; left: 0; right: 0; border-top: 1px dotted var(--border-hover); opacity: 0.6; }
.occ-x { display: flex; gap: 5px; margin-top: 6px; min-width: 0; }
.occ-xl { flex: 1; text-align: center; font-family: var(--font-mono); font-size: 9.5px; color: var(--text-tertiary); }

.day-group { margin-bottom: 0.25rem; }
/* Pins just under the sticky .topbar (whose real height varies, see syncTopbarHeight in
   app.js) while its own group is on screen, so the current arrival time stays visible as
   you scroll through a long day — then the next group's header takes its place. */
.day-group-head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.75rem 0.15rem 0.5rem;
  position: sticky;
  top: var(--topbar-h, 60px);
  background: var(--bg);
  z-index: 5;
}
.day-group-head .dgt { font-family: var(--font-mono); font-weight: 600; font-size: 15px; }
.day-group-head .dgc { font-size: 12px; color: var(--text-tertiary); }
.day-group-head::after { content: ""; flex: 1; height: 1px; background: var(--border); align-self: center; }
.day-group-body { display: flex; flex-direction: column; gap: 0.5rem; }

/* On laptops/desktops, pack a busy time slot's reservations into columns instead of one
   full-width card per row. auto-fit collapses empty tracks, so a slot with a single booking
   still spans the full width (same as before); 2+ bookings split into equal columns. */
@media (min-width: 1024px) {
  .day-group-body {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    align-items: start;
  }
  /* Narrower cards can't hold all five action buttons on one line — let them wrap. */
  .day-group-body .res-actions {
    flex-wrap: wrap;
  }
}

@media (max-width: 640px) {
  .occ { padding-left: 22px; }
  .occ-axis { width: 20px; height: 78px; }
  .occ-plot { height: 78px; gap: 3px; }
  .occ-track { max-width: 20px; }
  .occ-x { gap: 3px; }
}

/* ── Villa calendar: month-at-a-time per-villa occupancy grid ── */
.vcal-header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.25rem;
}
.vcal-header h2 {
  flex: 1;
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* Own scroll container (not the page) so a 28-31 column grid never widens the page itself
   — the villa-name column stays pinned via position:sticky while the days scroll under it. */
.vcal-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.vcal-grid {
  display: grid;
  grid-template-columns: 130px repeat(var(--vcal-cols, 31), minmax(28px, 1fr));
  gap: 2px;
  padding: 6px;
  background: var(--bg-card);
  min-width: max-content;
}

.vcal-corner {
  position: sticky;
  left: 0;
  background: var(--bg-card);
  z-index: 2;
}

.vcal-daynum {
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-tertiary);
  padding: 3px 0;
}
.vcal-daynum.vcal-today {
  color: var(--accent);
  font-weight: 700;
}

.vcal-unit-name {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--bg-card);
  display: flex;
  align-items: center;
  padding: 0 0.5rem;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}

.vcal-cell {
  height: 26px;
  border-radius: 4px;
  background: var(--bg-surface);
}
.vcal-cell.vcal-pending,
.vcal-cell.vcal-confirmed,
.vcal-cell.vcal-external {
  cursor: pointer;
}
.vcal-cell.vcal-pending {
  background: var(--warn-bg);
  border: 1px solid var(--warn);
}
.vcal-cell.vcal-confirmed {
  background: var(--accent-bg);
  border: 1px solid var(--accent);
}
/* Loggia-synced block — a third, distinct color from pending/confirmed so the owner can
   tell "blocked via Loggia" apart from a direct guest booking at a glance (a Loggia gap
   might be worth asking the property manager about; a direct-guest slot obviously isn't). */
.vcal-cell.vcal-external {
  background: var(--info-bg);
  border: 1px solid var(--info);
}

@media (max-width: 640px) {
  .vcal-unit-name { font-size: 12px; padding: 0 0.4rem; }
  .vcal-cell { height: 22px; }
  .vcal-grid { grid-template-columns: 100px repeat(var(--vcal-cols, 31), minmax(24px, 1fr)); }
}
