/* owner.css — inherited wholesale from cmd/app/static/app.css so the owner portal keeps
   the same visual language as the admin dashboard while living in its own binary/domain
   (see cmd/owner). Not yet trimmed down to only the classes owner templates use — a safe
   future cleanup, not a correctness concern. */
:root {
  --bg: #f4f6f8;
  --panel-bg: #ffffff;
  --border: #dde3e8;
  --text: #1f2933;
  --muted: #667380;
  --brand: #1f4e5f;
  --brand-light: #e6eef0;
  --ok: #1a7f4b;
  --ok-bg: #e5f6ec;
  --off-bg: #eceff1;
  --off: #5b6673;
  --error: #b3261e;
  --error-bg: #fbe7e5;

  /* Semantic accents — related to but distinct from the public site's warm
     green (hugo-site) and the guest portal's warm palette. Used by meaning,
     not decoration: gold for money, green for people, teal stays technical. */
  --money: #a8721c;
  --money-bg: #fbf1de;
  --people: #2f6f4f;
  --people-bg: #e7f2ec;
}

* { box-sizing: border-box; }

body {
  font-family: var(--db-font-body, system-ui), -apple-system, "Segoe UI", sans-serif;
  margin: 0;
  color: var(--text);
  background: var(--bg);
}

h1 {
  font-family: var(--db-font-display, Georgia), serif;
  font-weight: 600;
  font-size: 1.6rem;
  margin: 0 0 0.25rem;
}

.property-header {
  background-size: cover;
  background-position: center;
  border-radius: 12px;
  padding: 1.5rem 1.75rem;
  margin-bottom: 1.5rem;
}
.property-header[style*="background-image"] {
  color: #fff;
}
.property-header[style*="background-image"] h1,
.property-header[style*="background-image"] .muted {
  color: #fff;
}
.property-header[style*="background-image"] a {
  color: #fff;
  text-decoration: underline;
}
h2 {
  font-family: var(--db-font-display, Georgia), serif;
  font-weight: 600;
  font-size: 1.15rem;
  margin: 0 0 0.75rem;
  color: var(--brand);
}

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

.muted { color: var(--muted); }

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

.sidebar {
  width: 220px;
  flex: 0 0 220px;
  background: var(--brand);
  color: #fff;
  padding: 1.5rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.sidebar .brand {
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.sidebar .brand img { flex: none; width: auto; }

.sidebar nav {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.sidebar nav a {
  color: #dde9ec;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.sidebar nav a i {
  width: 1.1em;
  text-align: center;
  opacity: 0.9;
}

.sidebar nav a:hover {
  background: rgba(255, 255, 255, 0.12);
  text-decoration: none;
}

/* "Réserver" button — same treatment as cmd/desk's "+ Nouveau" (.nav-new):
   the one action in this sidebar, set apart from the plain link list below
   it instead of blending in as just another row. */
.nav-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
  padding: 0.6rem 0.9rem;
  border-radius: 8px;
  background: var(--db-sand);
  color: var(--db-tide-deep);
  font-family: var(--db-font-body);
  font-size: 0.9rem;
  font-weight: 700;
}
.nav-cta:hover { background: var(--db-sand-deep); color: #fff; text-decoration: none; }

/* Grouped-nav section labels — split the flat sidebar link list into
   logical areas (Opérations / Finances / Propriétés / Propriétaires /
   Intégrations) without changing the link markup or hover behaviour. */
.sidebar nav .nav-section {
  margin-top: 0.9rem;
  padding: 0 0.6rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: rgba(255, 255, 255, 0.55);
}
.sidebar nav .nav-section:first-child { margin-top: 0; }

.content {
  flex: 1;
  padding: 2rem 2.5rem;
  max-width: 1100px;
  min-width: 0;
}

/* Mobile navigation: below 900px, the sidebar is replaced entirely by the
   bottom tab bar (.tab-bar, see design.css + nav.html) — no off-canvas
   drawer. */
@media (max-width: 899px) {
  .app-shell { flex-direction: column; }
  .sidebar { display: none; }
  .content {
    padding: 1rem;
    max-width: 100%;
    padding-bottom: calc(1rem + 64px + env(safe-area-inset-bottom, 0px));
  }

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

  .field-grid { grid-template-columns: 1fr; }
  form input, form select, form textarea { min-width: 0; width: 100%; }
  .field input, .field select, .field textarea { max-width: 100%; }
}

@media (min-width: 481px) and (max-width: 899px) {
  .cards { grid-template-columns: repeat(2, 1fr); }
}

/* Cards row */
.cards {
  display: grid;
  /* See the same note in cmd/desk/static/app.css: a nowrap monospace
     amount needs ~200px or the € is clipped off the card. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: 1rem;
  margin: 1.5rem 0;
}

.card {
  background: var(--panel-bg);
  border: 1px solid transparent;
  border-radius: var(--radius-lg, 16px);
  padding: 1rem 1.2rem;
  box-shadow: var(--db-shadow-sm, none);
}

.card-value {
  font-family: var(--db-font-mono, inherit);
  font-variant-numeric: tabular-nums;
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--brand);
  white-space: nowrap;
}

.bookings-table td:nth-child(2),
.bookings-table td:nth-child(3),
.bookings-table td:nth-child(4) {
  white-space: nowrap;
}

/* Monetary amount cells across every financial table (bookings, finances
   history, owners list, upcoming reservations, etc.) — always right-aligned
   and non-wrapping so figures stay scannable in a column. */
.amount, th.amount {
  text-align: right;
  white-space: nowrap;
}
td.amount {
  font-family: var(--db-font-mono, inherit);
  font-variant-numeric: tabular-nums;
}

.card-label {
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 0.2rem;
}

.card-link {
  display: block;
  transition: border-color .15s ease, transform .15s ease;
}
.card-link:hover {
  text-decoration: none;
  border-color: var(--brand);
  transform: translateY(-1px);
}
.card-alert {
  border-color: var(--error);
  background: var(--error-bg);
}
.card-alert .card-value {
  color: var(--error);
}

/* Semantic card variants — meaning, not decoration */
.card-money {
  border-color: #eaceA0;
  background: var(--money-bg);
}
.card-money .card-value { color: var(--money); }

.card-people {
  border-color: #bfdccb;
  background: var(--people-bg);
}
.card-people .card-value { color: var(--people); }

.over-budget { color: var(--error); }

.panel-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
}
.panel-header h2 { margin: 0; }
.panel-header .inline-form { gap: 0.5rem; }

.inline-form {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 0.8rem;
  margin: 0;
}
.inline-form label {
  display: flex;
  flex-direction: column;
  font-size: 0.85rem;
  gap: 0.25rem;
  margin: 0;
}
.inline-form input, .inline-form select { min-width: 140px; }
.inline-form button { margin-top: 0; }

details {
  margin-top: 1rem;
  border-top: 1px solid var(--border);
  padding-top: 0.8rem;
}
details summary {
  cursor: pointer;
  color: var(--brand);
  font-weight: 600;
  margin-bottom: 0.6rem;
}

/* Panels */
.panel {
  background: var(--panel-bg);
  border: 1px solid transparent;
  border-radius: var(--radius-lg, 16px);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--db-shadow-sm, none);
}

.empty-state {
  color: var(--muted);
  font-style: italic;
}

/* Tables */
.row-thumb {
  display: block;
  width: 44px;
  height: 44px;
  border-radius: 6px;
  background-size: cover;
  background-position: center;
  background-color: var(--off-bg);
}

.table-wrap { overflow-x: auto; margin: 0.5rem 0; }
.table-wrap table { margin: 0; }
table { border-collapse: collapse; width: 100%; margin: 0.5rem 0; }
th, td { border: 1px solid var(--border); padding: 0.5rem 0.7rem; text-align: left; font-size: 0.92rem; vertical-align: top; }
td .inline-form { flex-wrap: nowrap; }
td.review-text { max-width: 26rem; }
th {
  background: var(--brand-light);
  color: var(--brand);
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
tr:nth-child(even) td { background: #fafcfd; }

/* Properties list — grouped by pricing tier, one panel per group */
.badge-count {
  background: var(--brand-light);
  color: var(--brand);
  font-variant-numeric: tabular-nums;
}
.property-table th { border-top: none; border-bottom-width: 2px; letter-spacing: 0.02em; text-transform: uppercase; font-size: 0.75rem; }
.property-table td { border-left: none; border-right: none; }
.property-table tr:last-child td { border-bottom: none; }
.property-table .cell-thumb { width: 3.2rem; padding-right: 0; }
.property-table .row-thumb { width: 56px; height: 56px; box-shadow: 0 1px 3px rgba(0,0,0,0.12); }
.property-table .cell-name a { font-weight: 600; font-size: 1rem; color: var(--text, #1b2a33); }
.property-table tbody tr { transition: background-color 0.12s ease; }
.property-table tbody tr:hover td { background: var(--brand-light); }

@media (max-width: 640px) {
  /* Card layout: hide the header row and lay each <td> out as a labeled
     block row instead of a table cell, so property rows read as compact
     cards rather than forcing horizontal scroll on a phone. */
  .property-table, .property-table tbody, .property-table tr, .property-table td { display: block; width: 100%; }
  .property-table thead { display: none; }
  .property-table tr {
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 0.8rem;
    padding: 0.6rem 0.8rem;
    position: relative;
  }
  .property-table tr:hover td { background: none; }
  .property-table td { border: none; padding: 0.3rem 0; display: flex; justify-content: space-between; align-items: center; gap: 0.6rem; }
  .property-table td[data-label]:not([data-label=""])::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    flex: 0 0 auto;
  }
  .property-table .cell-thumb {
    position: absolute;
    top: 0.6rem;
    right: 0.8rem;
    width: auto;
    padding: 0;
  }
  .property-table .cell-name { padding-right: 4.2rem; }
  .property-table .cell-name::before { display: none; }
  .property-table .cell-name a { font-size: 1.05rem; }
  .property-table .row-thumb { width: 48px; height: 48px; }
}

/* Booking option picker (/properties/{id}/bookings/new) — same
   table-becomes-cards technique as .property-table, adapted for a
   checkbox+label header row and a quantity input instead of plain text. */
@media (max-width: 640px) {
  /* Grid, not flex-wrap: with flex-wrap, line-breaking decisions are made
     from each item's un-shrunk (max-content) width, so a long option name
     could get pushed to its own line instead of just wrapping its text —
     a real bug caught in testing. Grid with explicit column/span placement
     has no such ambiguity: checkbox+name always share row 1 (columns 1/2),
     each detail row (price, unit, quantity) explicitly spans both columns
     and grid auto-placement stacks them on their own row, regardless of
     text length. */
  .option-table, .option-table tbody { display: block; width: 100%; }
  .option-table thead { display: none; }
  .option-table tr {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 0.6rem;
    row-gap: 0.35rem;
    align-items: center;
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 0.8rem;
    padding: 0.7rem 0.9rem;
  }
  .option-table td { border: none; padding: 0; }
  .option-table .cell-check { grid-column: 1; }
  .option-table .cell-name { grid-column: 2; }
  .option-table .cell-check input[type="checkbox"] { width: 1.3rem; min-width: 0; height: 1.3rem; }
  .option-table .cell-name label { font-weight: 600; font-size: 1rem; }
  .option-table td:not(.cell-check):not(.cell-name) {
    grid-column: 1 / -1;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.6rem;
    border-top: 1px dashed var(--border);
    padding-top: 0.5rem;
  }
  .option-table td[data-label]:not([data-label=""])::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
  }
  .option-table td input[type="number"] { min-width: 0; max-width: 6rem; }
}

/* Badges */
.heatmap {
  display: grid;
  grid-template-columns: repeat(6, 1.9rem);
  gap: 4px;
}
.heatmap-weekgrid {
  grid-template-columns: repeat(7, 2rem);
  max-width: none;
  gap: 3px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 1px;
  width: max-content;
}
.heatmap-cell {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
  font-size: 0.68rem;
  color: var(--muted);
  background: var(--off-bg);
  cursor: default;
}
.heatmap-weekgrid .heatmap-cell { border-radius: 0; }
.heatmap-blank { background: var(--card, #fff); }
.heatmap-cal { width: max-content; }
.heatmap-cal-dow,
.heatmap-cal-row {
  display: grid;
  grid-template-columns: 4.5rem repeat(7, 2rem);
  gap: 3px;
  align-items: center;
}
.heatmap-cal-dow {
  font-size: 0.7rem;
  color: var(--muted);
  text-align: center;
  margin-bottom: 3px;
}
.heatmap-cal-row {
  margin-bottom: 3px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 1px;
}
.heatmap-cal-month {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--brand);
  text-transform: capitalize;
  background: var(--card, #fff);
  padding-right: 0.4rem;
  text-align: right;
}
.heatmap-cal-row .heatmap-cell { border-radius: 0; }
.heatmap-cell.level-1 { background: #cfe4e9; color: var(--brand); }
.heatmap-cell.level-2 { background: #8fc0ca; color: #fff; }
.heatmap-cell.level-3 { background: #4f97a6; color: #fff; }
.heatmap-cell.level-4 { background: var(--brand); color: #fff; }
.heatmap-legend {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  margin-top: 0.7rem;
  font-size: 0.78rem;
  color: var(--muted);
}
.heatmap-legend .heatmap-cell { width: 1rem; height: 1rem; aspect-ratio: unset; flex: 0 0 auto; }

.cc-grid { border-collapse: collapse; }
.cc-grid th, .cc-grid td { border: 1px solid var(--border); padding: 0; text-align:center; font-size:.78rem; }
.cc-grid th { background: var(--brand-light); color: var(--brand); font-weight:600; padding:.25rem .3rem; white-space:nowrap; }
.cc-grid th.weekend { background:#fbf3e6; }
.cc-propcell { text-align:left !important; padding:.35rem .6rem !important; white-space:nowrap; background:#fff; position:sticky; left:0; z-index:1; }
.cc-propcell a { display:flex; align-items:center; gap:.5rem; color: var(--ink, #222); font-weight:600; font-size:.85rem; }
.cc-propcell .row-thumb { width:28px; height:28px; flex:none; }
.cc-cell { width:2.4rem; height:1.9rem; }
.cc-cell.free { background: var(--ok-bg); }
.cc-cell.booked { background: var(--error-bg); }
.cc-legend { display:flex; align-items:center; gap:1.2rem; font-size:.85rem; color:var(--muted); margin: .25rem 0 1rem; }
.cc-legend span.swatch { display:inline-block; width:1rem; height:1rem; border-radius:3px; vertical-align:middle; margin-right:.35rem; }

@media (max-width: 600px) {
  /* Smaller touch-friendly cells and tighter thumbnails so a cleaner on a
     phone can scan a week's occupancy without excessive horizontal scroll
     inside .table-wrap; the sticky property column stays put while
     scrolling through the days. */
  .cc-cell { width: 2rem; height: 2rem; }
  .cc-propcell { max-width: 9.5rem; overflow: hidden; text-overflow: ellipsis; }
  .cc-propcell a { font-size: .8rem; }
  .cc-propcell .row-thumb { width: 22px; height: 22px; }
  .cc-grid th { font-size: .7rem; padding: .2rem; }
  .cc-legend { flex-direction: column; align-items: flex-start; gap: .4rem; }
}

.notice {
  display: block;
  padding: 0.6rem 1rem;
  border-radius: 8px;
  font-size: 0.88rem;
  margin-bottom: 1rem;
}
.notice-ok { background: var(--ok-bg); color: var(--ok); }
.notice-error { background: var(--error-bg); color: var(--error); }

.badge {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
}
.badge-ok { background: var(--ok-bg); color: var(--ok); }
.badge-off { background: var(--off-bg); color: var(--off); }
.badge-error { background: var(--error-bg); color: var(--error); }
.badge-notify { background: var(--db-pending-mist); color: var(--db-pending); }

/* Forms */
fieldset { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 1.25rem; padding: 1.1rem 1.3rem 1.3rem; background: #fbfcfd; }
fieldset:last-of-type { margin-bottom: 0; }
legend { padding: 0 0.5rem; color: var(--brand); font-weight: 700; font-size: 0.95rem; }
form label { display: block; margin: 0.5rem 0; font-size: 0.92rem; }
/* Checkboxes/radios are excluded from this whole rule, not just the
   height rule below — min-width:200px was leaking onto them too (a
   checkbox stretched to a 200px-wide invisible hit target, shoving its
   label 190-ish px away from it) since ":not(...)" was only applied to
   the height rule, never to this one. */
form input:not([type="checkbox"]):not([type="radio"]), form select, form textarea {
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 10px);
  min-width: 200px;
  font: inherit;
  background: #fff;
  transition: border-color .15s ease, box-shadow .15s ease;
}
/* Consistent height across text/date/number inputs and <select> — browsers
   size these differently by default (native select chrome in particular),
   which is what made form rows look uneven. Checkboxes/radios are excluded
   entirely: they have their own small fixed sizing elsewhere and would
   otherwise inherit this height and lose their native look. */
form input:not([type="checkbox"]):not([type="radio"]),
form select,
form textarea {
  min-height: 2.6rem;
  line-height: 1.3;
  -webkit-appearance: none;
  appearance: none;
}
/* Native <select> chevron, since appearance:none above (needed to make
   selects match text inputs' height/border consistently across browsers)
   also removes the default one. */
form select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%23667380'%3E%3Cpath fill-rule='evenodd' d='M5.23 7.21a.75.75 0 011.06.02L10 11.19l3.71-3.96a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z' clip-rule='evenodd'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  background-size: 1.1em;
  padding-right: 2rem;
}
form input:focus, form select:focus, form textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-light);
}
form textarea { min-width: 100%; max-width: 100%; }

/* Field groups: a labelled control plus optional helper/hint text underneath */
.field { margin: 0.9rem 0; }
.field:first-child { margin-top: 0; }
.field label,
.field > .field-label {
  display: block;
  font-weight: 600;
  font-size: 0.88rem;
  margin-bottom: 0.3rem;
  color: var(--text);
}
.field input, .field select, .field textarea { width: 100%; max-width: 340px; }
.field input[type="checkbox"] { width: auto; max-width: none; }
.field-optional { font-size: 0.8rem; font-weight: 400; color: var(--db-ink-faint, var(--muted)); }
.field-wide input, .field-wide select, .field-wide textarea { max-width: 100%; }
.field-hint { display: block; color: var(--muted); font-size: 0.8rem; margin-top: 0.3rem; }

.field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.4rem 1.2rem;
}
.field-grid .field { margin: 0.5rem 0; }
/* Capped, not "none": auto-fill gives a lone field on its own row the full
   row width (1fr of a single column spanning the whole grid), ballooning
   it far wider than its siblings above just because of where it happened
   to wrap to — same visual cap as the plain (non-grid) .field class keeps
   every input a consistent, predictable width regardless of row position. */
.field-grid .field input, .field-grid .field select { width: 100%; max-width: 340px; }

/* Fixed 2-column layout (e.g. amount+status pairs) regardless of viewport
   width, instead of .field-grid's default auto-fill reflow. */
.field-grid-2col { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 480px) {
  .field-grid-2col { grid-template-columns: 1fr; }
}

.checkbox-field { display: flex; align-items: flex-start; gap: 0.5rem; font-weight: 500; }
.checkbox-field input { margin-top: 0.2rem; }

/* Checkbox/tag grids (amenities, tags) */
.check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.5rem 1rem;
}
.check-item {
  display: block;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  font-size: 0.9rem;
  cursor: pointer;
}
.check-item input[type="checkbox"] { vertical-align: top; margin: 0.15rem 0.5rem 0 0; }
.check-label { display: inline; }
.check-item:has(input:checked) { border-color: var(--brand); background: var(--brand-light); }

/* Photo gallery grids (property Images page + /media library) — mirrors
   .check-grid's card sizing/spacing, sized for thumbnails instead of text. */
.img-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1rem;
}
.img-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}
.img-card img { display: block; width: 100%; height: 130px; object-fit: cover; }
.img-card video { display: block; width: 100%; height: 130px; object-fit: cover; background: #1f2430; }
.img-card-video-badge { position: relative; }
.img-card-video-badge::after { content: "\f03d"; font-family: "Font Awesome 6 Free"; font-weight: 900; position: absolute; top: 0.4rem; right: 0.5rem; color: #fff; background: rgba(0,0,0,0.55); border-radius: 0.25rem; padding: 0.15rem 0.35rem; font-size: 0.75rem; pointer-events: none; }
.img-card-body { padding: 0.5rem 0.6rem; font-size: 0.82rem; }
.img-card-flags { display: flex; gap: 0.7rem; margin: 0.3rem 0; }
.img-card-flags form { display: inline; }
.img-card-flags label { display: inline-flex !important; align-items: center; gap: 0.25rem; cursor: pointer; margin: 0 !important; }
.img-card-flags input[type="radio"] { min-width: 0; width: auto; padding: 0; border: none; }
.img-card-actions { margin-top: 0.3rem; }

/* Booking property picker (/bookings/new) — clickable thumbnail cards,
   grouped by pricing tier like /properties, instead of a dropdown. */
.picker-card {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.picker-card:hover {
  text-decoration: none;
  border-color: var(--brand);
  transform: translateY(-2px);
}
.picker-card-noimg {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 130px;
  background: var(--off-bg);
  color: var(--muted);
  font-size: 1.6rem;
}

button, .btn {
  margin-top: 0.9rem;
  padding: 0.6rem 1.3rem;
  background: var(--brand);
  color: #fff;
  border: none;
  border-radius: 7px;
  cursor: pointer;
  font-size: 0.92rem;
  font-weight: 600;
  transition: background .15s ease, transform .1s ease;
}
button:hover, .btn:hover { background: #163b48; }
button:active, .btn:active { transform: translateY(1px); }

.btn-secondary {
  background: #fff;
  color: var(--brand);
  border: 1px solid var(--border);
}
.btn-secondary:hover { background: var(--brand-light); }

.btn-danger {
  background: var(--error-bg);
  color: var(--error);
  border: 1px solid #f3c8c4;
}
.btn-danger:hover { background: #f7d6d3; }

.btn-small { margin-top: 0; padding: 0.35rem 0.75rem; font-size: 0.82rem; }

.form-actions { margin-top: 1.3rem; display: flex; gap: 0.7rem; align-items: center; }

section.panel ul, section.panel ol { padding-left: 1.3rem; }
section.panel li { margin-bottom: 0.4rem; }

/* Customer communication thread (mirrors the guest portal message list) */
.messages { display: flex; flex-direction: column; gap: 0.6rem; margin: 0.75rem 0; }
.message { border-radius: 8px; padding: 0.6rem 0.9rem; max-width: 70%; }
.message-guest { background: var(--off-bg); align-self: flex-start; }
.message-concierge { background: var(--brand-light); align-self: flex-end; }
.message-meta { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.78rem; color: var(--muted); margin-bottom: 0.2rem; }
.message-body { white-space: pre-wrap; }

/* Mes documents — download list (see cmd/owner/documents.go). */
.download-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 1rem; }
.download-list li { display: grid; gap: 0.35rem; }
.download-list .btn { justify-self: start; }

/* An input paired with an inline action button (SIRET lookup — see
   siret-lookup.js). Replaces a repeated inline style="display:flex" and
   keeps the button from stretching to the input's height in a grid cell. */
.input-action { display: flex; gap: 0.5rem; align-items: stretch; }
.input-action input { flex: 1 1 auto; min-width: 0; }
.input-action button { flex: 0 0 auto; white-space: nowrap; }

/* Monetary amounts (see internal/money and the "eur" template helper).
   nowrap keeps the € with its number and stops a thousands separator
   becoming a line break; tabular-nums gives every digit the same advance so
   a right-aligned column lines up on the decimal comma. */
.money { white-space: nowrap; font-variant-numeric: tabular-nums; }
td.amount, th.amount, .amount { text-align: right; }
td.amount .money, td.amount { font-variant-numeric: tabular-nums; }

/* ============================================================================
   Redesign component layer — ported from cmd/desk/static/desk.css (same
   markup, same class names, so the two dashboards read as one product) and
   duplicated here rather than shared, same convention as design.css's own
   per-binary copies noted at the top of this file: separate binaries, no
   build step to share a static file between them. desk.css's own tokens
   (--db-*, fonts) already arrive for free via the shared design.css this
   page also loads — only the component rules themselves need porting.
   ============================================================================ */

/* ------------------------------------------------------------ db-hero */
.db-hero {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 2rem;
  margin-bottom: 2rem;
  font-family: var(--db-font-body);
}
.db-hero-eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--db-sand-deep);
  margin-bottom: 0.5rem;
}
.db-hero h1 {
  font-family: var(--db-font-display);
  font-size: 2.05rem;
  font-weight: 600;
  color: var(--db-ink);
  letter-spacing: -0.01em;
  margin: 0;
  text-wrap: balance;
}
.db-hero-meta { font-size: 0.88rem; color: var(--db-ink-soft); margin-top: 0.4rem; }

/* ------------------------------------------------------------- db-kpis */
.db-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px;
  background: var(--db-line);
  border: 1px solid var(--db-line);
  border-radius: 14px;
  overflow: hidden;
  margin-bottom: 2.25rem;
  box-shadow: var(--db-shadow-sm);
  font-family: var(--db-font-body);
}
.db-kpi {
  background: var(--db-surface);
  padding: 1.2rem 1.3rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  text-decoration: none;
  color: inherit;
  transition: background 0.12s ease;
}
.db-kpi:hover { background: var(--db-surface-2); }
.db-kpi-label { font-size: 0.74rem; color: var(--db-ink-soft); font-weight: 500; }
.db-kpi-value {
  font-family: var(--db-font-display);
  font-size: 1.75rem;
  font-weight: 600;
  color: var(--db-ink);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.db-kpi-trend { font-family: var(--db-font-mono); font-size: 0.74rem; font-weight: 500; color: var(--db-ink-faint); }
.db-kpi-trend.warn { color: var(--db-pending); }
.db-kpi.money .db-kpi-value { color: var(--db-sand-deep); }

/* -------------------------------------------------------- section head */
.db-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 1rem;
  font-family: var(--db-font-body);
}
.db-section-head h2 {
  font-family: var(--db-font-display);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--db-ink);
  margin: 0;
}
.db-section-head .db-count { font-size: 0.82rem; color: var(--db-ink-faint); }

/* ---------------------------------------------------------- db-priority */
.db-priority {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--db-line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--db-surface);
  box-shadow: var(--db-shadow-sm);
  margin-bottom: 2.25rem;
}
.db-priority-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 1.2rem 0.9rem 1rem;
  text-decoration: none;
  color: inherit;
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--db-line-soft);
  font-family: var(--db-font-body);
  transition: background 0.12s ease;
}
.db-priority-row:last-child { border-bottom: none; }
.db-priority-row:hover { background: var(--db-surface-2); }
.db-priority-row.sev-critical { border-left-color: var(--db-critical); }
.db-priority-row.sev-pending { border-left-color: var(--db-pending); }
.db-row-icon {
  width: 34px; height: 34px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  flex: none;
  font-size: 0.95rem;
}
.sev-critical .db-row-icon { background: var(--db-critical-mist); color: var(--db-critical); }
.sev-pending .db-row-icon { background: var(--db-pending-mist); color: var(--db-pending); }
.db-row-text { flex: 1; min-width: 0; }
.db-row-title { font-weight: 600; font-size: 0.92rem; color: var(--db-ink); }
.db-row-sub { font-size: 0.8rem; color: var(--db-ink-soft); margin-top: 0.1rem; }
.db-row-chev { color: var(--db-ink-faint); flex: none; font-size: 0.85rem; }
.db-empty { padding: 1.1rem 1.2rem; margin: 0; color: var(--db-ink-soft); font-size: 0.9rem; display: flex; align-items: center; gap: 0.5rem; }
.db-empty i { color: var(--db-ok); }

/* --------------------------------------------------------- property tiles */
.property-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1rem;
  margin: 1rem 0 1.75rem;
}
.property-tile {
  background: var(--db-surface);
  border: 1px solid var(--db-line);
  border-radius: var(--radius-lg, 16px);
  overflow: hidden;
  box-shadow: var(--db-shadow-sm);
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.property-tile:hover { box-shadow: var(--db-shadow-md); transform: translateY(-2px); text-decoration: none; }
.property-tile-thumb {
  aspect-ratio: 16/10;
  background-size: cover;
  background-position: center;
  background-color: var(--db-tide-mist);
}
.property-tile-noimg { display: flex; align-items: center; justify-content: center; color: var(--db-tide-mid); font-size: 1.8rem; }
.property-tile-body { padding: 0.9rem 1.1rem 1.1rem; display: flex; flex-direction: column; gap: 0.3rem; }
.property-tile-body strong { font-family: var(--db-font-display); font-size: 1.02rem; color: var(--db-ink); }

/* ---------------------------------------- /bookings picker property cards
   Full-width row per property (photo left, key figures right) rather than
   the plain tile grid above — an owner with several properties uses this
   as a status board, not just a "pick one" menu, so it leads with the
   figures a hospitality dashboard leads with: occupancy and revenue for
   the year, who's arriving next, the keylock code (needed on the spot for
   a cleaner/handyman), and anything unpaid. */
.property-card-list { display: flex; flex-direction: column; gap: 0.9rem; margin: 1rem 0 1.75rem; }
.property-card {
  display: flex; align-items: stretch; gap: 0;
  background: var(--db-surface);
  border: 1px solid var(--db-line);
  border-radius: var(--radius-lg, 16px);
  overflow: hidden;
  box-shadow: var(--db-shadow-sm);
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.property-card:hover { box-shadow: var(--db-shadow-md); transform: translateY(-2px); text-decoration: none; }
.property-card-thumb {
  flex: 0 0 220px;
  background-size: cover;
  background-position: center;
  background-color: var(--db-tide-mist);
}
.property-card-noimg { display: flex; align-items: center; justify-content: center; color: var(--db-tide-mid); font-size: 2rem; }
.property-card-body { flex: 1; min-width: 0; padding: 1.1rem 1.3rem; display: flex; flex-direction: column; gap: 0.7rem; justify-content: center; }
.property-card-head strong { display: block; font-family: var(--db-font-display); font-size: 1.1rem; color: var(--db-ink); }
.property-card-head .muted { font-size: 0.85rem; }
.property-card-stats { display: flex; flex-wrap: wrap; gap: 1.6rem; }
.property-card-stat { display: flex; flex-direction: column; gap: 0.15rem; min-width: 90px; }
.property-card-stat-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--db-ink-faint); }
.property-card-stat-label i { color: var(--db-tide); margin-right: 0.2rem; }
.property-card-stat-value { font-weight: 700; font-size: 1rem; color: var(--db-ink); font-variant-numeric: tabular-nums; }
.property-card-stat-alert { color: var(--db-warn, #b45309); }
.property-card-chev { align-self: center; flex: none; color: var(--db-ink-faint); font-size: 1rem; padding: 0 1.2rem; }
@media (max-width: 720px) {
  .property-card { flex-direction: column; }
  .property-card-thumb { flex-basis: auto; aspect-ratio: 16/9; }
  .property-card-chev { display: none; }
  .property-card-stats { gap: 1rem 1.4rem; }
}

/* Property hero banner — property detail page, mirrors cmd/desk's own
   .property-header treatment (photo background, white text over it). */
.property-header {
  background-size: cover;
  background-position: center;
  background-color: var(--db-tide-mist);
  border-radius: var(--radius-lg, 16px);
  padding: 1.75rem 2rem;
  margin-bottom: 1.5rem;
  min-height: 140px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.property-header[style*="background-image"] { color: #fff; }
.property-header[style*="background-image"] h1 { color: #fff; }
.property-header[style*="background-image"] .db-hero-meta { color: rgba(255,255,255,0.85); }
.property-header .db-hero { margin-bottom: 0; }

/* ------------------------------------------------------------ acct-tabs */
/* The account tab strip that lived here is gone: it is design.css's shared
   .tabs component now — the same one cmd/desk renders — so the two binaries
   stop maintaining two strips that were identical by intention and drifted
   anyway. See that file's "Tabs" header, including why neither scrolls
   horizontally any more. */

/* ------------------------------------------------------------ status-card */
/* /compte/paiements — Stripe and bank connection status side by side, so
   an owner sees their whole money-flow health in one glance instead of
   reading two separate paragraphs in sequence. */
.status-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem; margin: 1rem 0 1.5rem; }
.status-card {
  background: var(--db-surface);
  border: 1px solid var(--db-line);
  border-radius: var(--radius-lg, 16px);
  padding: 1.2rem 1.3rem;
  box-shadow: var(--db-shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.status-card-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.status-card-title { display: flex; align-items: center; gap: 0.6rem; font-family: var(--db-font-display); font-weight: 600; font-size: 1.02rem; color: var(--db-ink); }
.status-card-title i { color: var(--db-tide); font-size: 1.1rem; }
.status-card.is-ok { border-color: var(--db-ok); background: var(--db-ok-mist); }
.status-card.is-pending { border-color: var(--db-pending); background: var(--db-pending-mist); }
.status-card.is-error { border-color: var(--db-critical); background: var(--db-critical-mist); }
.status-card-desc { font-size: 0.85rem; color: var(--db-ink-soft); line-height: 1.4; margin: 0; }
.status-card-actions { margin-top: 0.2rem; }

/* /messages — one status-card per property thread, clickable. */
a.msg-thread-card { text-decoration: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; }
a.msg-thread-card:hover { border-color: var(--db-tide-mid); box-shadow: var(--db-shadow-md, 0 4px 16px rgba(20,30,25,0.1)); }

/* /messages/{id} — chat-bubble thread, same visual language as the guest
   portal's own message thread (cmd/guest/static/guest.css's .message-*),
   reimplemented with this app's db-* tokens; an owner's own messages sit
   right-aligned like the guest's, SUBA's replies left-aligned. */
.msg-thread { display: flex; flex-direction: column; gap: 0.75rem; margin: 1rem 0 1.5rem; }
.msg-bubble { border-radius: 14px; padding: 0.75rem 1rem; max-width: 85%; }
.msg-bubble.msg-owner { background: var(--db-tide-mist); align-self: flex-end; margin-left: auto; }
.msg-bubble.msg-concierge { background: var(--db-surface-2); align-self: flex-start; border: 1px solid var(--db-line); }
.msg-bubble-meta { display: flex; justify-content: space-between; gap: 0.75rem; font-size: 0.74rem; color: var(--db-ink-faint); margin-bottom: 0.3rem; }
.msg-bubble-body { white-space: pre-wrap; color: var(--db-ink); font-size: 0.92rem; line-height: 1.45; }
.msg-reply-form { display: flex; flex-direction: column; gap: 0.6rem; }

/* --------------------------------------------------------- owner calendar */
/* Read-only 2-month availability grid (property detail page) — same visual
   vocabulary as the public site's Airbnb-style date picker
   (hugo-site/layouts/partials/booking-quick-dates-script.html's .ab-cal-*
   classes) but server-rendered, no JS: an owner views this, never picks a
   range on it. */
.owner-cal-months { display: flex; flex-wrap: wrap; gap: 2rem; margin: 1rem 0 1.5rem; }
.owner-cal-month { flex: 1 1 260px; min-width: 240px; }
.owner-cal-month-title { text-align: center; font-weight: 700; font-family: var(--db-font-display); font-size: 0.98rem; margin-bottom: 0.6rem; text-transform: capitalize; color: var(--db-ink); }
.owner-cal-dow { display: grid; grid-template-columns: repeat(7,1fr); text-align: center; font-size: 0.7rem; color: var(--db-ink-faint); margin-bottom: 0.3rem; }
/* minmax(0,1fr) — see .blk-cal-days's comment for why bare 1fr is unsafe
   with aspect-ratio children. */
.owner-cal-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.owner-cal-day {
  aspect-ratio: 1; border-radius: 50%;
  font-size: 0.82rem; display: flex; align-items: center; justify-content: center;
  color: var(--db-ink);
  min-width: 0; width: 100%;
}
.owner-cal-day.blank { visibility: hidden; }
.owner-cal-day.past { color: var(--db-ink-faint); }
.owner-cal-day.booked { background: var(--db-tide); color: #fff; font-weight: 600; }
.owner-cal-day.blocked { background: var(--db-sand-mist); color: var(--db-sand-deep); font-weight: 600; }
.owner-cal-legend { display: flex; flex-wrap: wrap; gap: 1rem; font-size: 0.8rem; color: var(--db-ink-soft); margin-bottom: 1.5rem; }
.owner-cal-legend span { display: inline-flex; align-items: center; gap: 0.4rem; }
.owner-cal-legend i { width: 0.85rem; height: 0.85rem; border-radius: 50%; display: inline-block; }
.owner-cal-legend .sw-booked { background: var(--db-tide); }
.owner-cal-legend .sw-blocked { background: var(--db-sand-mist); border: 1px solid var(--db-sand-deep); }

/* Accueil's one-month-per-property glance — .owner-cal-month's flex:1 1
   260px otherwise stretches a lone month to the full panel width on a wide
   desktop screen, blowing each day cell up to ~100px (aspect-ratio:1
   follows the grid column width): oversized and "in your face" instead of
   a quick glance. Capping the row's own width keeps it a compact widget,
   left-aligned like the rest of the panel's content rather than stretched
   or centered as an isolated block. */
.owner-cal-months-compact { max-width: 300px; }
.owner-cal-months-compact .owner-cal-day { font-size: 0.76rem; }

/* /bookings/{id} — three months, bird's-eye: a scannable quarter at a
   glance rather than two months worth zooming into. Square cells with no
   gap read as one continuous grid (a hairline outline stands in for the
   gap so nights are still visually separated), and everything shrinks to
   match since the point is overview, not a per-day click target. */
.owner-cal-months-trio { max-width: 640px; gap: 1.25rem; }
.owner-cal-months-trio .owner-cal-month { flex: 1 1 180px; min-width: 160px; }
.owner-cal-months-trio .owner-cal-days { gap: 0; }
.owner-cal-months-trio .owner-cal-day {
  border-radius: 2px;
  font-size: 0.68rem;
  outline: 1px solid var(--db-line-soft, var(--db-line));
  outline-offset: -1px;
}
.owner-cal-months-trio .owner-cal-day.blank { outline: none; }
.owner-cal-months-trio .owner-cal-month-title { font-size: 0.82rem; }
.owner-cal-months-trio .owner-cal-dow { font-size: 0.6rem; }
@media (max-width: 640px) {
  .owner-cal-months-trio { flex-direction: row; flex-wrap: wrap; }
  .owner-cal-months-trio .owner-cal-month { flex: 1 1 140px; }
}

/* Maintenance — a "quoted" row needs the owner's own accept/decline before
   anything else can happen; same left-accent language as db-priority's
   sev-pending, applied directly to the table row rather than a separate
   duplicate list. */
.row-needs-response td:first-child { box-shadow: inset 3px 0 0 var(--db-pending); }
.table-cards .row-needs-response { box-shadow: inset 3px 0 0 var(--db-pending); }

/* ----------------------------------------------------- block-dates picker */
/* Interactive twin of .owner-cal-* above (/block/{id}) — same visual
   vocabulary as the public site's Airbnb-style date picker
   (hugo-site/layouts/partials/booking-quick-dates-script.html's .ab-cal-*
   classes), reimplemented with the app's own tokens since this page has no
   access to the Hugo site's stylesheet. Unlike .owner-cal-*, days here are
   real buttons: clickable, hoverable, and able to show a start/end/in-range
   selection. */
.blk-cal-months { position: relative; display: flex; flex-wrap: wrap; gap: 2rem; margin: 1rem 0 1.5rem; }
.blk-cal-month { flex: 1 1 260px; min-width: 240px; padding-top: 2.2rem; }
.blk-cal-nav {
  position: absolute; top: 0; width: 1.8rem; height: 1.8rem; border-radius: 50%;
  border: 1px solid var(--db-line); background: var(--db-surface); color: var(--db-ink);
  cursor: pointer; font-size: 1.1rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.blk-cal-prev { left: 0; }
.blk-cal-next { right: 0; }
.blk-cal-month-title { text-align: center; font-weight: 700; font-family: var(--db-font-display); font-size: 0.98rem; margin-bottom: 0.6rem; text-transform: capitalize; color: var(--db-ink); }
.blk-cal-dow { display: grid; grid-template-columns: repeat(7,1fr); text-align: center; font-size: 0.7rem; color: var(--db-ink-faint); margin-bottom: 0.3rem; }
/* minmax(0,1fr), not bare 1fr: a bare 1fr track's implicit minimum is
   auto (its content's min-content size), and a <button>'s default
   padding/min-width plus aspect-ratio:1 pushed some tracks' min-content
   past an equal 1/7 share — the grid honored that floor instead of
   shrinking evenly, so columns went uneven and the whole row overflowed
   its box. minmax(0,1fr) removes that floor so all 7 columns are always
   exactly equal, matching a real CSS Grid day picker. */
.blk-cal-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.blk-cal-day {
  aspect-ratio: 1; border: none; background: none; border-radius: 50%;
  font-size: 0.85rem; font-family: inherit; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: var(--db-ink);
  padding: 0; margin: 0; min-width: 0; width: 100%;
}
.blk-cal-day:hover:not(.disabled):not(.range-start):not(.range-end) { background: var(--db-panel-alt, var(--bg)); }
.blk-cal-day.disabled { color: var(--db-ink-faint); cursor: default; }
.blk-cal-day.booked { color: var(--db-ink-faint); cursor: not-allowed; text-decoration: line-through; }
.blk-cal-day.in-range { background: var(--db-panel-alt, var(--bg)); border-radius: 0; }
.blk-cal-day.range-start, .blk-cal-day.range-end { background: var(--db-tide); color: #fff; }
/* Today, independent of any selection — see .blk-cal-legend-today. Uses
   box-shadow (inset-free, just an outline-like ring) rather than border so
   it doesn't shift the circle's size the way a real border would. */
.blk-cal-day.today:not(.range-start):not(.range-end) { box-shadow: inset 0 0 0 2px var(--db-tide); font-weight: 700; }
.blk-cal-blank { visibility: hidden; }
@media (max-width: 640px) {
  .blk-cal-months { flex-direction: column; gap: 1.5rem; }
}

textarea.blk-textarea {
  width: 100%; min-height: 6rem; resize: vertical;
  font: inherit; padding: 0.7rem 0.85rem;
  border: 1.5px solid var(--db-line); border-radius: var(--radius-md, 10px);
  background: var(--db-surface); color: var(--db-ink);
}
textarea.blk-textarea:focus-visible { outline: 2px solid var(--db-tide); outline-offset: 1px; }

.blk-submit-row { display: flex; align-items: center; gap: 1rem; margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--db-line); }
.blk-submit-hint { font-size: 0.82rem; color: var(--db-ink-faint); }

/* Dates field — the same Airbnb-style segment-button + popover pattern as
   the public site's own date picker (hugo-site/assets/css/style.css's
   .ab-segment/.ab-popover, reused for a property's booking sidebar as
   .bp-ab-segment/.bp-dates-field), reimplemented with this app's tokens: a
   compact trigger showing the current selection, opening a calendar
   popover on click instead of an always-expanded grid sitting in the page. */
/* Dates + arrival time share a row — a full-width date button with a
   narrow field-grid box stacked underneath it wasted the row's own free
   space and left the two controls looking unrelated in width and height. */
.blk-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.8rem; }
.blk-row .blk-dates-field { flex: 1 1 260px; }
.blk-time-seg {
  display: flex; align-items: center; gap: 0.6rem; flex: 0 0 150px;
  border: 1.5px solid var(--db-line); border-radius: var(--radius-md, 10px);
  background: var(--db-surface); padding: 0.75rem 1rem;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.blk-time-seg:focus-within { border-color: var(--db-tide-mid); background: var(--db-surface-2); }
.blk-time-seg i { color: var(--db-tide); font-size: 1.05rem; }
/* A <select>, not a native type="time" input — that one shows as 12-hour
   "05:00 PM" regardless of the page being entirely in French, since
   type="time" follows the browser/OS locale rather than lang="fr". A fixed
   list of arrival slots is also just more honest: SUBA staff needs a
   realistic window, not a claim of minute-level precision. */
.blk-time-seg select {
  border: none; background: transparent; padding: 0; margin: 0;
  min-width: 0; min-height: 0; width: 100%; font: inherit; color: var(--db-ink);
  appearance: none; -webkit-appearance: none; cursor: pointer;
}
.blk-time-seg select:focus { outline: none; box-shadow: none; }
@media (max-width: 480px) {
  .blk-time-seg { flex-basis: 100%; }
}

/* Property photo next to the hero title — the only property identifier
   used to be a small caps eyebrow line; a thumbnail grounds the page in
   what's actually being booked, the way a real booking flow always keeps
   the subject in view. */
.blk-hero-thumb {
  width: 84px; height: 84px; border-radius: var(--radius-md, 10px);
  object-fit: cover; flex: none;
  box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,0.12));
}

/* Calendar legend — struck-through "booked" dates and a highlighted
   "today" cell used to have no explanation on screen at all. */
.blk-cal-legend {
  display: flex; flex-wrap: wrap; gap: 0.3rem 1.1rem;
  margin: 0.7rem 0 0; padding-top: 0.7rem; border-top: 1px solid var(--db-line);
  font-size: 0.78rem; color: var(--db-ink-soft);
}
.blk-cal-legend-item { display: inline-flex; align-items: center; gap: 0.4rem; }
.blk-cal-legend-swatch { width: 0.9rem; height: 0.9rem; border-radius: 4px; flex: none; }
.blk-cal-legend-today { border: 2px solid var(--db-tide); background: var(--db-surface); }
.blk-cal-legend-booked { background: var(--db-panel-alt, var(--bg)); position: relative; }
.blk-cal-legend-booked::after {
  content: ""; position: absolute; left: 10%; right: 10%; top: 50%;
  border-top: 1.5px solid var(--db-ink-faint);
}

.blk-dates-field { position: relative; max-width: 420px; }
.blk-dates-seg {
  width: 100%; display: flex; align-items: center; gap: 0.6rem;
  text-align: left; cursor: pointer; font-family: inherit;
  border: 1.5px solid var(--db-line); border-radius: var(--radius-md, 10px);
  background: var(--db-surface); padding: 0.75rem 1rem; margin-top: 0;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.blk-dates-seg:hover, .blk-dates-seg[aria-expanded="true"] { border-color: var(--db-tide-mid); background: var(--db-surface-2); }
.blk-dates-seg i.fa-calendar-days { color: var(--db-tide); font-size: 1.05rem; }
.blk-dates-seg-text { display: flex; flex-direction: column; gap: 0.1rem; }
.blk-dates-seg-value { font-size: 0.85rem; color: var(--db-ink-soft); }
.blk-dates-seg[aria-expanded="true"] .blk-dates-seg-value { color: var(--db-ink); }
.blk-dates-seg-chev { margin-left: auto; color: var(--db-ink-faint); font-size: 0.8rem; }

.blk-popover {
  position: absolute; top: calc(100% + 0.6rem); left: 0; z-index: 30;
  /* Explicit width rather than shrink-to-fit: an absolutely positioned
     auto-width box wrapping a flex row of flex-grow children sizes
     inconsistently across browsers (Safari in particular sizes it to the
     available width of its containing block instead of its content),
     which blew this popover up to nearly the full panel width. A fixed
     width removes the ambiguity outright. */
  width: min(600px, 90vw);
  box-sizing: border-box;
  background: var(--db-surface); border: 1px solid var(--db-line); border-radius: 14px;
  box-shadow: 0 12px 36px rgba(20,30,25,0.16);
  padding: 1.2rem;
}
.blk-popover.hidden { display: none; }
.blk-popover .blk-cal-months { margin: 0; }
.blk-pop-actions { display: flex; justify-content: space-between; align-items: center; margin-top: 1rem; padding-top: 0.8rem; border-top: 1px solid var(--db-line); }
.blk-pop-clear { background: none; border: none; text-decoration: underline; color: var(--db-ink); font-size: 0.88rem; cursor: pointer; font-family: inherit; padding: 0.3rem; }
.blk-pop-done { margin: 0; padding: 0.55rem 1.3rem; }

@media (max-width: 640px) {
  .blk-dates-field { max-width: none; }
  .blk-popover { left: 0; width: calc(100vw - 2.4rem); max-width: 420px; padding: 0.8rem; }
  /* One month at a time, not two stacked — the stacked pair made the
     popover taller than the viewport on a phone. */
  .blk-cal-months > div:nth-of-type(2) { display: none; }
  .blk-cal-months { gap: 0; margin: 0; }
  .blk-cal-month { padding-top: 1.8rem; min-width: 0; }
  .blk-cal-nav { width: 1.5rem; height: 1.5rem; font-size: 1rem; }
  .blk-cal-month-title { margin-bottom: 0.4rem; font-size: 0.9rem; }
  .blk-cal-day { font-size: 0.8rem; }
}

/* Code de boîte à clés, pour un séjour que le propriétaire prend lui-même.
   Même parti pris que côté client : lu debout devant une porte, donc grand,
   monospace, et seul dans son bloc. */
.owner-lockbox {
  display: flex; flex-direction: column; gap: 0.15rem;
  margin: 0 0 1rem; padding: 0.9rem 1.1rem;
  background: var(--brand-light, #eef3f4);
  border-radius: 12px;
}
.owner-lockbox-where { font-size: 0.82rem; color: var(--muted); }
.owner-lockbox-label {
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--muted);
}
.owner-lockbox-code {
  font-family: var(--db-font-mono, ui-monospace, monospace);
  font-size: 2rem; font-weight: 700; letter-spacing: 0.22em;
  line-height: 1.15; color: var(--brand);
}

/* /compte/proprietes — the same code, inline in a table cell rather than
   its own standalone block: an owner here is looking it up (for a
   handyman, a cleaner), not reading it off a door. */
.owner-lockbox-inline {
  font-family: var(--db-font-mono, ui-monospace, monospace);
  font-size: 0.95rem; font-weight: 700; letter-spacing: 0.12em;
  color: var(--brand);
}
.owner-lockbox-inline i { font-size: 0.85em; margin-right: 0.3em; letter-spacing: 0; color: var(--db-tide-mid, var(--brand)); }

/* Accueil's "À traiter" — ported from cmd/desk's own dashboard domain cards
   (desk.css's .db-domain*) so the two apps' "here's what needs a decision"
   panel reads as the same product. Same always-render-three-cards
   philosophy: a card stays in its slot whether or not it currently has
   anything to say, drained of emphasis (.is-clear) rather than removed. */
.db-domains { display: flex; flex-direction: column; gap: 0.85rem; margin: 1rem 0 1.5rem; }
.db-domain {
  display: flex; flex-direction: column; gap: 0.7rem;
  padding: 1rem 1.1rem;
  background: var(--db-surface);
  border: 1px solid var(--db-line);
  border-radius: 12px;
  box-shadow: var(--db-shadow-sm);
  font-family: var(--db-font-body);
}
.db-domain.is-clear { background: none; box-shadow: none; border-color: var(--db-line-soft); }
.db-domain-head { display: flex; align-items: center; gap: 0.6rem; }
.db-domain-head h3 { flex: 1; margin: 0; font-size: 0.95rem; font-weight: 700; font-family: var(--db-font-body); }
.db-domain-icon {
  width: 1.9rem; height: 1.9rem; border-radius: 8px; flex: none;
  display: grid; place-items: center;
  background: var(--db-tide-mist); color: var(--db-tide); font-size: 0.82rem;
}
.db-domain.is-clear .db-domain-icon { background: var(--db-stone-deep); color: var(--db-ink-faint); }
.db-domain-chip {
  flex: none; min-width: 1.5rem; padding: 0.05rem 0.5rem; border-radius: 999px;
  font-family: var(--db-font-mono); font-size: 0.74rem; font-weight: 700; text-align: center;
  background: var(--db-pending-mist); color: var(--db-pending);
  font-variant-numeric: tabular-nums;
}
.db-domain-chip.clear { background: var(--db-ok-mist); color: var(--db-ok); }
.db-domain-lines { display: flex; flex-direction: column; margin-top: -0.15rem; }
.db-domain-line {
  display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem;
  padding: 0.32rem 0; border-bottom: 1px solid var(--db-line-soft);
  font-size: 0.85rem; color: var(--db-ink-soft); text-decoration: none;
}
.db-domain-line:last-child { border-bottom: 0; }
.db-domain-line:hover { color: var(--db-tide); text-decoration: none; }
.db-domain-line b { font-family: var(--db-font-mono); font-weight: 600; color: var(--db-pending); font-variant-numeric: tabular-nums; }
.db-domain-clear { margin: 0; font-size: 0.84rem; color: var(--db-ink-faint); }
.db-domain-foot { margin-top: auto; font-size: 0.8rem; font-weight: 600; color: var(--db-tide); text-decoration: none; }
.db-domain-foot:hover { text-decoration: underline; }

/* ============================================================================
   Accueil rework — ported wholesale from cmd/desk's own dashboard
   (desk.css's "Priorités du jour" bands), same class names on purpose: the
   two apps' home pages should read as one product, not two skins on the
   same idea. See dashboard.html/dashboard.go/dashboard_bands.go for the
   originals this mirrors.
   ============================================================================ */
.db-hero-summary { margin: 0.35rem 0 0; font-size: 0.95rem; color: var(--db-ink-soft); font-family: var(--db-font-body); }
.db-hero-date { text-align: right; font-size: 0.82rem; color: var(--db-ink-faint); white-space: nowrap; }
.db-hero-date strong {
  display: block; font-family: var(--db-font-display); font-size: 1.05rem;
  color: var(--db-ink); font-weight: 600; text-transform: capitalize;
}

/* ---- band 1: Aujourd'hui -------------------------------------------------- */
.db-today {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1px; background: var(--db-line); border: 1px solid var(--db-line);
  border-radius: 14px; overflow: hidden; box-shadow: var(--db-shadow-sm);
  margin-bottom: 2.25rem; font-family: var(--db-font-body);
}
.db-slot { background: var(--db-surface); padding: 1rem 1.15rem; display: flex; flex-direction: column; gap: 0.55rem; min-width: 0; }
.db-slot-head {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--db-ink-faint);
}
.db-slot-head b {
  margin-left: auto; font-family: var(--db-font-mono); font-size: 1.05rem;
  color: var(--db-ink); letter-spacing: 0; font-variant-numeric: tabular-nums;
}
.db-dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; flex: none; }
.db-dot.inhouse { background: var(--db-tide); }
.db-dot.upcoming { background: var(--db-ok); }
.db-slot-item { display: flex; flex-direction: column; line-height: 1.35; min-width: 0; }
a.db-slot-item.is-link {
  padding: 0.25rem 0.55rem; margin: 0 -0.55rem; border-radius: 6px;
  color: inherit; text-decoration: none; transition: background-color 0.12s ease;
}
a.db-slot-item.is-link:hover { background: var(--db-tide-mist); text-decoration: none; }
a.db-slot-item.is-link:hover .db-slot-title { color: var(--db-tide); }
a.db-slot-item.is-link:focus-visible { outline: 2px solid var(--db-tide); outline-offset: -2px; }
.db-slot-title { font-size: 0.87rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.db-slot-sub { font-size: 0.77rem; color: var(--db-ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.db-slot-more { font-size: 0.78rem; font-weight: 600; color: var(--db-tide); text-decoration: none; margin-top: auto; }
.db-slot-more:hover { text-decoration: underline; }
.db-slot-empty { margin: 0; font-size: 0.83rem; color: var(--db-ink-faint); }

/* ---- band 3: month figures ------------------------------------------------ */
.db-figs {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1px; background: var(--db-line);
  border: 1px solid var(--db-line); border-radius: 12px; overflow: hidden;
  box-shadow: var(--db-shadow-sm); font-family: var(--db-font-body);
}
.db-fig { background: var(--db-surface); padding: 0.9rem 1.05rem; display: flex; flex-direction: column; gap: 0.25rem; text-decoration: none; color: inherit; }
.db-fig:hover { background: var(--db-surface-2); text-decoration: none; }
.db-fig-label { font-size: 0.74rem; color: var(--db-ink-soft); }
.db-fig-value {
  font-family: var(--db-font-display); font-size: 1.5rem; font-weight: 600; line-height: 1;
  white-space: nowrap; color: var(--db-ink); font-variant-numeric: tabular-nums;
}
.db-fig-value.money { color: var(--db-sand-deep); }
.db-fig-sub { font-family: var(--db-font-mono); font-size: 0.72rem; color: var(--db-ink-faint); }
