/* Overview Dashboard - Figma 600:17688.
   Colour values are tokens only: a hex outside eventkrowd_theme.css is a bug
   this project has a test for. */

.dashboard__header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-block-end: 1.5rem;
  /* HMS-1137 — at 390 the Export button ran off the right edge; wrapping lets
     title / picker / button stack instead of overflowing. */
  flex-wrap: wrap;
  position: relative;
}

/* HMS-1123 — the print note is taken out of the flex flow so its arrival in
   the print view never shifts the Period picker or Export button. It sits in
   the header's bottom margin. */
.dashboard__print-note {
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 0;
  margin: 0.25rem 0 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-inline-size: 100%;
}

.dashboard__title {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.dashboard__context {
  margin: 0 0 1.5rem;
  color: var(--wa-color-text-quiet);
}

.dashboard__empty {
  color: var(--wa-color-text-quiet);
}

.dashboard__snapshot-note {
  margin: 0.25rem 0 0.5rem;
}

.dashboard__section-title {
  margin: 2rem 0 1rem;
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.dashboard__sample-tag,
.stat-card__sample-tag,
.alert__sample-tag {
  display: inline-block;
  margin-inline-start: 0.5rem;
  padding: 0.0625rem 0.375rem;
  border: 1px solid var(--wa-color-neutral-border-normal);
  border-radius: 0.25rem;
  background: var(--wa-color-neutral-fill-quiet);
  color: var(--wa-color-text-quiet);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  vertical-align: middle;
}

/* ------------------------------------------------------------- stat cards */

.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.5rem;
  overflow: hidden;
  background: var(--wa-color-surface-default);
}

.stat-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 2rem;
  border-inline-end: 1px solid var(--wa-color-surface-border);
}

.stat-card:last-child {
  border-inline-end: none;
}

.stat-card__label {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--wa-color-text-normal);
}

.stat-card__content {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.stat-card__value {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--wa-color-text-normal);
}

/* A revenue card can now carry ONE FIGURE PER CURRENCY, because a multi-hotel
   event genuinely takes money in more than one and summing them would be a
   number in no unit. Two 1.5rem figures with margin:0 sit flush against each
   other and read as one wrapped value, so adjacent values get separated. */
.stat-card__value + .stat-card__value {
  margin-top: 0.25rem;
}

.stat-card__detail {
  margin: 0.25rem 0 0;
  font-size: 0.875rem;
  line-height: 1.2;
  color: var(--wa-color-text-quiet);
}

.stat-card__badge {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  /* auto margin keeps the badge at the right edge whether it shares the
     figure's row or wraps onto its own in a narrow card. */
  margin-inline-start: auto;
  width: 3rem;
  height: 3rem;
  border-radius: 0.375rem;
  font-size: 1.125rem;
}

.stat-card__badge--blue {
  background: var(--wa-color-blue-95);
  border: 1px solid var(--wa-color-blue-80);
  color: var(--wa-color-blue);
}

.stat-card__badge--green {
  background: var(--wa-color-green-95);
  border: 1px solid var(--wa-color-green-80);
  color: var(--wa-color-green);
}

.stat-card__badge--amber {
  background: var(--wa-color-yellow-95);
  border: 1px solid var(--wa-color-yellow-80);
  color: var(--wa-color-yellow-50);
}

/* ----------------------------------------------------------------- alerts */

.alerts {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-block-start: 1.5rem;
}

.alert {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border-radius: 0.375rem;
}

.alert--danger {
  background: var(--wa-color-red-95);
  color: var(--wa-color-red-20);
}

.alert--neutral {
  background: var(--wa-color-neutral-fill-quiet);
  color: var(--wa-color-text-normal);
}

.alert__text {
  flex: 1;
  margin: 0;
  font-size: 0.875rem;
}

/* ----------------------------------------------------------------- charts */

.charts__grid {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: 2rem;
}

.chart-card {
  padding: 1rem;
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.5rem;
  background: var(--wa-color-surface-default);
}

.chart-card__title {
  margin: 0 0 1rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--wa-color-text-normal);
}

.chart-card__canvas {
  display: block;
  width: 100%;
  height: 16rem;
}

.chart-card__caption {
  margin: 0.75rem 0 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

/* ----------------------------------------------------------------- tables */

.data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--wa-color-surface-default);
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.5rem;
}

.data-table th,
.data-table td {
  padding: 0.875rem 1rem;
  text-align: start;
  border-block-end: 1px solid var(--wa-color-surface-border);
}

.data-table thead th {
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--wa-color-text-quiet);
  background: var(--wa-color-neutral-fill-quiet);
}

/* Dashboard headers are 16px bold dark text (Figma); the generic quiet
   0.875rem style stays for the other data-table pages. */
.dashboard-table .data-table thead th {
  font-size: 1rem;
  color: var(--wa-color-text-normal);
}

.data-table tbody tr:last-child th,
.data-table tbody tr:last-child td {
  border-block-end: none;
}

.data-table__row-header {
  font-weight: 600;
  color: var(--wa-color-text-normal);
}

.status-pill {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border-radius: 1rem;
  font-size: 0.75rem;
  font-weight: 600;
}

.status-pill--ok {
  background: var(--wa-color-blue-95);
  color: var(--wa-color-blue-20);
}

.status-pill--warning {
  background: var(--wa-color-yellow-95);
  color: var(--wa-color-yellow-20);
}

.status-pill--critical {
  background: var(--wa-color-red-95);
  color: var(--wa-color-red-20);
}

.dashboard-table__note {
  margin: 0.75rem 0 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

/* -------------------------------------------------------- header controls */

/* HMS-1137 — the select and the Custom from/to row sit on one line and wrap
   together at narrow widths (390px), the pickers' own labels aligning them. */
.dashboard__period-picker {
  margin: 0;
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.dashboard__period-range {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* display:flex above would defeat the hidden attribute the picker toggles. */
.dashboard__period-range[hidden] {
  display: none;
}

/* HMS-1137 — at 390 the flex gap squeezed the select to ~60px, hiding the
   whole value. 10rem keeps "Last 30 days" readable; harmless at wide widths
   where the select is already larger. */
.dashboard__period-picker wa-select {
  min-inline-size: 10rem;
}

/* HMS-1352 — the busy signal lives on the control that started the fetch:
   a small spinner appended to the Period form row while the frame reloads,
   instead of dimming the whole dashboard. period-picker's submit() marks the
   form .auto-submit--busy; the controller clears it on turbo:frame-load. */
.dashboard__period-picker.auto-submit--busy::after {
  content: "";
  align-self: center;
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  border: 2px solid var(--wa-color-surface-border);
  border-top-color: var(--wa-color-brand-fill-loud);
  border-radius: 50%;
  animation: dashboard-spin 0.8s linear infinite;
}

/* ------------------------------------------------------------------ alerts */

.dashboard__alerts {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-block-start: 1.5rem;
}

/* HMS-1353 — same type spec as .dashboard-table__title (1.125rem/700), but
   margin 0: the section is a 0.5rem-gap flex column, so the title-to-tag
   space is gap + the note's own 0.25rem margin-top = 0.75rem, matching the
   collapsed h2->note spacing in the tagged table sections. */
.dashboard__alerts-title {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

/* Same rhythm as the table sections (0.5rem tag->content): inside the flex
   column the note's own 0.5rem bottom margin would double the gap to 1rem,
   so it is zeroed here only. */
.dashboard__alerts .dashboard__snapshot-note {
  margin-block-end: 0;
}

/* wa-callout has no action slot; this flex span pins the trailing button to
   the right edge like the Figma alert rows. */
.dashboard__alert-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.dashboard__alert-text {
  flex: 1 1 auto;
  font-size: 0.875rem;
}

/* --------------------------------------------------------------- stat card extras */

/* min-content, not 0: a currency figure is one unbreakable string, and a
   shrinkable figure clips digits (a $1,685,593.50 exposure read "$1,685,593.5"
   under the badge). The figure may not shrink below its longest figure; the
   badge/sparkline wrap to a second row instead. */
.stat-card__figure {
  min-width: min-content;
}

/* Last resort for a figure longer than the whole card. */
.stat-card__value {
  overflow-wrap: anywhere;
}

.stat-card__delta {
  display: inline-block;
  margin-top: 0.25rem;
  padding: 0.125rem 0.5rem;
  border-radius: 1rem;
  font-size: 0.75rem;
  font-weight: 600;
  background: var(--wa-color-green-95);
  color: var(--wa-color-green-20);
}

.stat-card__delta--down {
  background: var(--wa-color-red-95);
  color: var(--wa-color-red-20);
}

.stat-card__sparkline {
  flex-shrink: 0;
  align-self: center;
}

/* ------------------------------------------------------------ chart extras */

.chart-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.chart-card__header .chart-card__title {
  margin: 0;
}

.chart-card__tabs {
  display: flex;
  gap: 0.25rem;
}

.chart-card__tab {
  padding: 0.25rem 0.75rem;
  border-radius: var(--wa-border-radius-m);
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
  text-decoration: none;
}

.chart-card__tab--active {
  background: var(--wa-color-brand-fill-quiet);
  color: var(--wa-color-text-normal);
  font-weight: 600;
}

.chart-card__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

.chart-card__legend li {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  /* HMS-688 — each row carries the slice detail as its tooltip. */
  cursor: help;
}

.chart-card__dot {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
}

/* Match the chart's own series tokens so the legend cannot drift from the
   rendered slices. */
.chart-card__dot--0 { background: var(--border-color-1); }
.chart-card__dot--1 { background: var(--border-color-2); }
.chart-card__dot--2 { background: var(--border-color-3); }
.chart-card__dot--3 { background: var(--border-color-4); }

/* HMS-1133 — wa-doughnut-chart fills slices with --fill-color-N, a 40% wash of
   the series colour, so slices read paler than the solid legend dots. Fill
   them solid so slice, legend dot and tooltip swatch are the same colour. */
wa-doughnut-chart.chart-card__canvas {
  --fill-color-1: var(--border-color-1);
  --fill-color-2: var(--border-color-2);
  --fill-color-3: var(--border-color-3);
  --fill-color-4: var(--border-color-4);
}

/* ------------------------------------------------------------- table extras */

.dashboard-table {
  margin-block-start: 2rem;
}

.dashboard-table__title {
  margin: 0 0 0.75rem;
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.dashboard-table__count {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

.dashboard-table__toolbar {
  display: flex;
  margin-bottom: 0.75rem;
}

.dashboard-table__search wa-input {
  width: min(20rem, 100%);
}

/* Table footer: per-page selector + count + numbered pager (Figma pattern,
   same as the contracts list footer). Pagy 43 series_nav emits .series-nav
   links with aria-current/aria-disabled, not .current/.gap classes. */
.dashboard-table__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1rem;
}

.dashboard-table__per-page {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--wa-color-neutral-on-normal);
}

.dashboard-table__per-page wa-select {
  width: 5.25rem;
}

.dashboard-table__pager .series-nav {
  display: flex;
  gap: 2px;
  align-items: center;
}

.dashboard-table__pager .series-nav a {
  min-width: 2rem;
  text-align: center;
  padding: 2px var(--wa-space-xs, 4px);
  border-radius: var(--wa-border-radius-m);
  color: var(--wa-color-text-normal);
  text-decoration: none;
  font-size: var(--wa-font-size-s, 0.875rem);
}

.dashboard-table__pager .series-nav a[href]:hover {
  background: var(--wa-color-surface-lowered);
}

.dashboard-table__pager .series-nav a[aria-current="page"] {
  background: var(--wa-color-brand-fill-loud);
  color: var(--wa-color-brand-on-loud);
}

.dashboard-table__pager .series-nav a[aria-disabled]:not([aria-current="page"]) {
  opacity: 0.4;
  cursor: default;
}

/* Sort links inside data-table headers keep the header's own type styles. */
.data-table thead th a {
  color: inherit;
  text-decoration: none;
}

/* Paired-carets sort indicator: both carets sit, the active one lights up. */
.sort-glyphs {
  display: inline-flex;
  flex-direction: column;
  line-height: 0.45;
  margin-inline-start: 0.25rem;
  font-size: 0.625rem;
  color: var(--wa-color-neutral-60);
  vertical-align: middle;
}
/* Negative margin stacks the carets tighter than line-height alone can. */
.sort-glyphs .fa-caret-up {
  margin-block-end: -0.15em;
}
.sort-glyphs--asc .fa-caret-up,
.sort-glyphs--desc .fa-caret-down {
  color: var(--wa-color-brand-40);
}

/* While a turbo-frame fetches (Stimulus toggles .turbo-frame--busy, or Turbo
   itself sets [busy] for form-driven frame fetches), dim the old rows and
   spin a loader so pagination never looks dead, and lock the controls so a
   second fetch cannot start while the first is in flight. */
turbo-frame.turbo-frame--busy,
turbo-frame[busy] {
  position: relative;
  display: block;
  cursor: progress;
}
turbo-frame.turbo-frame--busy > *,
turbo-frame[busy] > * {
  opacity: 0.4;
  pointer-events: none;
}
turbo-frame.turbo-frame--busy::after,
turbo-frame[busy]::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 2rem;
  height: 2rem;
  border: 3px solid var(--wa-color-surface-border);
  border-top-color: var(--wa-color-brand-fill-loud);
  border-radius: 50%;
  animation: dashboard-spin 0.8s linear infinite;
  pointer-events: none;
}
turbo-frame.turbo-frame--busy::before,
turbo-frame[busy]::before {
  content: "Updating…";
  position: absolute;
  inset: 0;
  margin: auto;
  margin-top: calc(50% + 1.5rem);
  width: max-content;
  height: max-content;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
  pointer-events: none;
  z-index: 1;
}
@keyframes dashboard-spin {
  to { transform: rotate(360deg); }
}

/* HMS-1352 — #dashboard-data is the whole dashboard (stat cards, alerts,
   charts AND both tables); the generic busy treatment faded every child to
   0.4 and centred a spinner plus "Updating…" on a viewport-tall frame, which
   QA read as a flicker and the overlay could sit outside the viewport. A
   period swap is atomic, so keep the old rows fully painted and let the
   picker form's spinner be the indicator. The pointer-events lock from the
   generic rule still applies; the nested table frames keep the dim+spinner. */
#dashboard-data.turbo-frame--busy > *,
#dashboard-data[busy] > * {
  opacity: 1;
}
#dashboard-data.turbo-frame--busy::before,
#dashboard-data.turbo-frame--busy::after,
#dashboard-data[busy]::before,
#dashboard-data[busy]::after {
  content: none;
}

/* "View matrix" action in the attrition table: light-blue fill, blue text.
   The theme defines no --wa-color-blue-* scale, so brand shades stand in. */
#attrition td wa-button::part(base) {
  background: var(--wa-color-brand-95);
  color: var(--wa-color-brand-30);
  border-color: var(--wa-color-brand-80);
}
#attrition td wa-button::part(base):hover {
  background: var(--wa-color-brand-90);
}

/* Fixed layout so the cutoffs and attrition columns start at the same
   offsets; the Actions column gets one width in both. */
.dashboard-table .data-table { table-layout: fixed; }
/* The global .admin-table-wrap table { min-width: max-content } would push
   the fixed-layout table past its wrap and clip the Actions column, so
   replace it with a fixed floor: wide enough that phones scroll the wrap
   instead of overlapping columns, narrow enough to fit at 1024. */
.dashboard-table .admin-table-wrap .data-table { min-width: 44rem; }
#cutoffs th:last-child, #attrition th:last-child { width: 11rem; }

/* "Approve release" (a button_to, so a native button): light-green fill,
   dark-green text, trailing check, per Figma. */
.dashboard-table__approve {
  border: 1px solid var(--wa-color-success-border-normal);
  border-radius: var(--wa-border-radius-m);
  background: var(--wa-color-success-fill-quiet);
  color: var(--wa-color-success-on-quiet);
  font: inherit;
  font-weight: 600;
  font-size: var(--wa-font-size-s);
  padding: 0.3rem 0.75rem;
  cursor: pointer;
  white-space: nowrap;
}
.dashboard-table__approve:hover {
  background: var(--wa-color-success-fill-normal);
}

@media (max-width: 60rem) {
  .charts__grid {
    grid-template-columns: 1fr;
  }
}
