/* The application's own additions. The design's three files are never modified; every rule here
 * is additive and token-based, so `site/assets/css/*` remains the visual contract.
 * Owner: docs/design/DESIGN-FLOW.md (S4, S6). */

/* The catalogue's pending hint. `visibility` rather than `display` keeps the reserved space, so a
 * request causes no reflow at all. htmx's own injected copy of these two rules is disabled in
 * app.js, which keeps the page usable under `style-src 'self'`. */
.catalog-indicator {
  font-size: var(--text-xs);
  color: var(--muted);
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.catalog-indicator.htmx-request {
  visibility: visible;
  opacity: 1;
}

/* The echoed term, when the empty state quotes what was searched. The design already sets
 * `.empty-state p`; these two declarations are the only additions. */
.empty-state__query {
  color: var(--ink);
  overflow-wrap: anywhere; /* a pasted token must not widen the page at 360px */
}

/* At phone widths a 56px fixed bubble cannot be placed clear of a 278px control column: measured
 * collisions with every filter control at 360px (docs/design/DESIGN-FLOW.md S6). The page's own
 * footer carries the same wa.me destination with a visible label, so the overlay is not drawn where
 * it cannot sit clear of a control. */
@media (max-width: 480px) {
  .whatsapp-float {
    display: none;
  }

  /* The export raises toasts to clear the bubble (pages.css:4235); with no bubble that leaves a
   * 70px hole. Restore the design's own offset (base.css:1257). */
  body:has(.whatsapp-float) .toast-region {
    bottom: 22px;
  }
}

/* AUD-15. Between 481 and 1367 px the fixed 56 px button sat inside the content column: measured
 * collisions were with filter controls up to 820 px, with course cards to 1200 px, and with footer
 * links across the range. Padding cannot clear a fixed overlay, because content scrolls beneath it,
 * so the layout reserves the button's strip and the content column ends left of it. The inset goes on
 * .container, not body, so full-bleed section backgrounds keep their width.
 *
 * 74px is the button's own footprint (56 wide, 18 from the edge); anything less put controls back
 * under it, measured at 60px. */
@media (min-width: 481px) and (max-width: 1367px) {
  .container {
    padding-right: calc(var(--sp-5) + 74px);
  }
}

/* The export switches the filter row to four columns at 1024px of viewport. Inside the inset range
 * that viewport is ~98px narrower than the row assumes, which clipped the last label ("Todos los
 * format"). Four columns come back once the content column is wide enough to carry them, which for
 * these tokens is a 1222px viewport. Below that the row keeps the two-column arrangement the design
 * already uses from 700px up, so nothing new appears - the switch just happens 198px later. */
@media (min-width: 1024px) and (max-width: 1221px) {
  .filter-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .filter-search {
    grid-column: 1 / -1;
  }
}

/* Live booking (D1.6). The state region sits where the export's confirm button is, so a conflict or
 * an uncertain result is announced next to the action instead of replacing the page. */
.booking-status {
  margin-top: var(--sp-3);
}

.booking-status:empty {
  display: none;
}

.booking-status .alert {
  margin: 0;
}

.booking-status .cluster {
  margin-top: var(--sp-3);
}

/* A day with no free slot is not a choice: the export styles `.is-empty` faintly, and the disabled
 * attribute has to look the same or the rail reads as available. */
.calendar-day:disabled,
.date-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.calendar-day:disabled:hover {
  border-color: transparent;
}

.date-btn:disabled:hover {
  border-color: var(--line);
}

.summary-reference {
  display: flex;
  gap: 8px;
  align-items: baseline;
  flex-wrap: wrap;
  margin-top: var(--sp-3);
  font-size: var(--text-sm);
}

.summary-reference strong {
  font-family: var(--font-mono, monospace);
  letter-spacing: 0.04em;
}
