/* RCS application styles. Bootstrap does the heavy lifting; only
   app-specific rules live here (sticky toolbars, table chrome, …). */

/* Page shell (issue #56). Pages used to sit in a Bootstrap .container-xl,
   which caps at 1320px and threw away ~300px per side at 1920 and ~620px at
   2560 — space the tables want. Full-bleed instead, with the same 1rem gutter
   RCS-TS uses (its AppShell padding="md"), so the navbar brand and the page
   content share a left edge. --rcs-page-max is the knob if a cap is ever
   wanted back; narrow pages cap their own content with .rcs-maxw-* and stay
   left-aligned at the gutter (RCS-TS does the same — no re-centering). */
.rcs-page {
  --rcs-page-max: none;
  max-width: var(--rcs-page-max);
  padding-inline: 1rem;
}

/* Launchpad tiles (§6.1). Fixed-size tiles in a wrapping flex row, not a
   12-column grid: every section then shows the same tile whatever its count,
   instead of stretching two tiles across the full-bleed page. Sized so the
   whole grouped launchpad — 7 titled sections — clears a 1920x1080 window
   without scrolling, and still wraps to two tiles per row on a phone. */
.launchpad-tile {
  color: inherit;
  /* Narrow screens: share the row so two tiles still fit side by side. */
  flex: 1 1 8rem;
}

@media (min-width: 768px) {
  .launchpad-tile {
    /* Wide enough for the longest label ("Miele Service Managers") on one line. */
    flex: 0 0 12.5rem;
  }
}

.rcs-launchpad-heading {
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--bs-secondary-color);
  margin-bottom: 0.25rem;
}

.launchpad-tile .card-body {
  padding: 0.35rem 0.5rem;
}

.launchpad-tile .bi {
  font-size: 1.15rem;
  line-height: 1.1;
}

.launchpad-tile .card-title {
  font-size: 0.8125rem;
  line-height: 1.2;
}

.launchpad-tile:hover {
  border-color: var(--bs-primary);
  color: var(--bs-primary);
}

/* Short viewports (a 1366x768 laptop leaves ~630px once browser chrome is
   taken out) tighten further, so the launchpad still clears the fold there
   without cramping the roomier sizes. */
@media (max-height: 700px) {
  .rcs-launchpad-heading {
    margin-bottom: 0.125rem;
  }

  .launchpad-tile .card-body {
    padding: 0.15rem 0.5rem;
  }

  .launchpad-tile .bi {
    font-size: 1rem;
  }
}

/* Miele-branded modules (issue #26): red sampled from the Miele logo, white
   text — applied to launchpad tiles, navbar entries and the export button. */
:root {
  --miele-red: #e30613;
  --miele-red-dark: #c00510; /* hover/active shade */
}

.launchpad-tile.tile-brand-miele {
  background-color: var(--miele-red);
  border-color: var(--miele-red);
  color: #fff;
}

.launchpad-tile.tile-brand-miele:hover {
  background-color: var(--miele-red-dark);
  border-color: var(--miele-red-dark);
  color: #fff;
}

.navbar-nav .nav-link.nav-brand-miele {
  background-color: var(--miele-red);
  border-radius: var(--bs-border-radius);
  color: #fff;
}

.navbar-nav .nav-link.nav-brand-miele:hover,
.navbar-nav .nav-link.nav-brand-miele:focus {
  background-color: var(--miele-red-dark);
  color: #fff;
}

.dropdown-menu .dropdown-item.nav-brand-miele {
  background-color: var(--miele-red);
  color: #fff;
}

.dropdown-menu .dropdown-item.nav-brand-miele:hover,
.dropdown-menu .dropdown-item.nav-brand-miele:focus {
  background-color: var(--miele-red-dark);
  color: #fff;
}

.btn-miele {
  --bs-btn-bg: var(--miele-red);
  --bs-btn-border-color: var(--miele-red);
  --bs-btn-color: #fff;
  --bs-btn-hover-bg: var(--miele-red-dark);
  --bs-btn-hover-border-color: var(--miele-red-dark);
  --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: var(--miele-red-dark);
  --bs-btn-active-border-color: var(--miele-red-dark);
  --bs-btn-active-color: #fff;
}

.login-card {
  max-width: 420px;
}

/* Two-level header (issue #55): row 1 = brand + user menu, row 2 = the whole
   navigation. Row 2 hides below lg, where the offcanvas drawer takes over.
   The row deliberately wraps rather than scrolling: overflow-x also forces
   overflow-y, which would clip the dropdowns to the row. If the row ever
   outgrows the width, add data-bs-config='{"popperConfig":{"strategy":
   "fixed"}}' to each toggle instead of a scroll container. */
/* .navbar-nav zeroes --bs-nav-link-padding-x (Bootstrap restores it only
   inside a .navbar-expand-*, which neither of these is), so both the row and
   the drawer have to put the horizontal padding back themselves. */
.rcs-navrow .nav-link {
  white-space: nowrap;
  --bs-nav-link-padding-x: 0.65rem;
  --bs-nav-link-padding-y: 0.35rem;
}

/* Pull the row back by one link's padding so the first entry's text starts on
   the same left edge as the brand and the page gutter (issue #56). */
.rcs-navrow .navbar-nav {
  margin-left: -0.65rem;
}

.rcs-nav-drawer {
  --bs-offcanvas-width: 260px;
}

.rcs-nav-drawer .nav-link {
  --bs-nav-link-padding-x: 0.5rem;
}

.rcs-nav-drawer .rcs-nav-group-label {
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}

.rcs-navrow .bi-lock-fill,
.rcs-nav-drawer .bi-lock-fill {
  font-size: 0.75em;
  opacity: 0.6;
}

/* Active page: a theme-aware grey fill (not the Bootstrap primary), so dark
   mode comes free from --bs-secondary-bg. */
.rcs-navrow .nav-link.active,
.rcs-nav-drawer .nav-link.active,
.dropdown-menu .dropdown-item.active {
  background-color: var(--bs-secondary-bg);
  border-radius: var(--bs-border-radius);
  color: var(--bs-emphasis-color);
}

/* Miele identity wins over the active fill, in both themes. */
.navbar-nav .nav-link.nav-brand-miele.active,
.dropdown-menu .dropdown-item.nav-brand-miele.active {
  background-color: var(--miele-red-dark);
  color: #fff;
}

/* Version stamp stacked under the RCS brand (navbar + login heading). */
.rcs-app-version {
  display: block;
  font-size: 0.7rem;
  font-weight: 400;
  color: var(--bs-secondary-color);
}

/* Table regions (§3.8): long lists scroll inside the panel; the toolbar and
   header row stay pinned (spec §9). */
.rcs-table-scroll {
  max-height: 60vh;
  overflow-y: auto;
}

.rcs-table-scroll thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background-color: var(--bs-body-bg);
  box-shadow: inset 0 -1px 0 var(--bs-border-color);
}

/* Sizing utilities: narrow forms/panels and short embedded lists
   (templates never use inline styles — djlint H021). */
.rcs-maxw-32 {
  max-width: 32rem;
}

.rcs-maxw-36 {
  max-width: 36rem;
}

.rcs-maxw-48 {
  max-width: 48rem;
}

.rcs-scroll-12 {
  max-height: 12rem;
}

.rcs-scroll-14 {
  max-height: 14rem;
}

[data-rcs-table] tbody tr[data-id] {
  cursor: pointer;
}

/* Selected row: primary tint, distinct from (and stable under) the gray
   hover highlight. The second selector out-specifies .table-hover's rule. */
[data-rcs-table] tbody tr.table-active > *,
.table-hover > tbody > tr.table-active:hover > * {
  --bs-table-bg-state: rgba(var(--bs-primary-rgb), 0.18);
}

/* The focusable table panel (keyboard navigation target). */
.rcs-table-scroll:focus-visible {
  outline: 2px solid rgba(var(--bs-primary-rgb), 0.5);
  outline-offset: -2px;
}

/* Markdown render area: keep embedded content inside the dialog. */
.rcs-markdown img {
  max-width: 100%;
}

.rcs-markdown > :last-child {
  margin-bottom: 0;
}

/* Alpine x-cloak: hide confirm-state controls until Alpine initializes. */
[x-cloak] {
  display: none !important;
}

/* Stacked dialogs (#modal-host-2) run without a Bootstrap backdrop — the
   modal element itself dims the parent dialog underneath. */
#modal-host-2 .modal {
  background-color: rgba(0, 0, 0, 0.35);
}

/* CRUD dialogs wrap header/body/footer in a <form>, which breaks Bootstrap's
   modal-dialog-scrollable flex chain: tall forms clipped their footer (the
   Save/Cancel row). Make the form the flex column that owns the scroll. */
.modal-content > form {
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 100%;
  overflow: hidden;
}

.modal-content > form > .modal-body {
  overflow-y: auto;
}

/* Toolbar buttons: disabled actions drop to grey so the enabled ones stand
   out in color (spec feedback I7). */
.rcs-toolbar .btn:disabled {
  --bs-btn-disabled-color: var(--bs-secondary-color);
  --bs-btn-disabled-bg: transparent;
  --bs-btn-disabled-border-color: var(--bs-border-color);
}

/* Filter Apply buttons show their in-flight spinner (htmx-request marks the
   issuing element) so a slow search never reads as "nothing happened". */
[data-rcs-apply] .spinner-border {
  display: none;
}

[data-rcs-apply].htmx-request .spinner-border {
  display: inline-block;
}

/* Keyboard-shortcut hints appended to toolbar buttons by app.js (I2). */
.rcs-kbd {
  font-size: 0.72em;
  padding: 0.1em 0.3em;
  background-color: rgba(0, 0, 0, 0.14);
  border-radius: 0.25em;
}

/* Numeric inputs that take decimals suppress the up/down spinner — spinners
   stay on integer-only fields (I4). */
input.rcs-no-spin::-webkit-outer-spin-button,
input.rcs-no-spin::-webkit-inner-spin-button {
  appearance: none;
  margin: 0;
}

input.rcs-no-spin {
  appearance: textfield;
}

/* Searchable pickers (issue #17): while the dropdown is open show only the
   typed query — the selected item would otherwise concatenate with it
   ("CAT015 - SAMEP S.a.s. gibi"). It reappears when the dropdown closes.
   Keyed on dropdown-active, not input-active: the control input keeps focus
   after picking an option, which would leave the value invisible.
   position: absolute takes the hidden item out of flow so the query starts at
   the left edge of the box. */
.ts-wrapper.single.dropdown-active .item {
  visibility: hidden;
  position: absolute;
}

/* Auto-apply preference (issue #40): applies are programmatic, so the Apply
   button and the stale banner are noise. display:none still receives the
   programmatic .click(); !important beats the banner's x-show inline style. */
body[data-rcs-autoapply="1"] [data-rcs-apply],
body[data-rcs-autoapply="1"] [data-rcs-stale] {
  display: none !important;
}
