/* Dashboards — the shared dashboard widgets and the personal dashboard page.
   Consumed by components/dashboard-widgets.js (action queue, period rows,
   activity table, operations strip, stat strip), components/system-status-card.js,
   components/policy-index.js, features/schedule/next-periods.js and
   views/personal-dashboard.js; the stat strip also serves admin-health.js and
   staff-fte.js, the status dot admin-crud.js metricCardHtml and
   features/security-events. Loaded eagerly (index.html), so no view lists it
   in `styles`. The .dash-card frame itself is shared/base-ui.css. Colours are
   tokens, so the dark theme needs no override here. */
@layer components {

/* ── Stat tiles ───────────────────────────────────────────────────────────
   A row of summary values, each with a label and a sub line, rendered by
   components/dashboard-widgets.js on the role dashboards. */
.ms-context-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.ms-mini-stat {
  min-width: 0;
  background: var(--surface-sunk);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-decoration: none;
  color: inherit;
  transition: box-shadow .12s ease;
}
a.ms-mini-stat:hover { box-shadow: 0 4px 12px rgba(0,0,0,.08); }
.ms-mini-stat.cat-moss { background: var(--cat-moss-bg); }
.ms-mini-stat.cat-plum { background: var(--cat-plum-bg); }
.ms-mini-stat.cat-clay { background: var(--cat-clay-bg); }
.ms-mini-stat-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}
.ms-mini-stat-label > span { min-width: 0; overflow-wrap: anywhere; }
.ms-mini-stat.cat-moss .ms-mini-stat-label { color: var(--cat-moss); }
.ms-mini-stat.cat-plum .ms-mini-stat-label { color: var(--cat-plum); }
.ms-mini-stat.cat-clay .ms-mini-stat-label { color: var(--cat-clay); }
.ms-mini-stat-value { font-size: var(--text-xl); font-weight: 700; margin: 2px 0; }
.ms-mini-stat-sub { font-size: var(--text-2xs); color: var(--muted); }

/* Status dot (admin-crud.js metricCardHtml, the system card, security
   events): one 8px dot per tone. */
.security-status-dot { width: 8px; height: 8px; flex: 0 0 auto; border-radius: 50%; background: var(--muted); }
.security-status-green { background: var(--success); }
.security-status-amber { background: var(--warning); }
.security-status-blue { background: var(--primary); }
.security-status-red { background: var(--danger); }

/* Activity table detail (renderActivityTable) — the Audit Log page's own
   two-line clamp, shared here; the Audit Log's expanded state stays in
   views/admin.css. */
.audit-detail-text { display: -webkit-box; overflow: hidden; -webkit-line-clamp: 2; -webkit-box-orient: vertical; color: var(--muted); }

/* ── Dashboard widgets (components/dashboard-widgets.js) ───────────────── */
.dash-empty {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.dash-empty-icon {
  font-size: 1.5rem;
  color: var(--success);
  background: var(--success-bg);
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px;
  flex-shrink: 0;
}

/* Action-needed queue */
.dash-action {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--border);
}
.dash-action:last-child { border-bottom: none; }
.dash-action.tone-red   { border-left-color: var(--danger); }
.dash-action.tone-amber { border-left-color: var(--warning); }
.dash-action.tone-blue  { border-left-color: var(--info); }
.dash-action-msg { font-size: var(--text-sm); }
.dash-action .btn { flex-shrink: 0; }
/* Urgency chip in front of a queue message, tinted by the row's tone. */
.dash-when {
  display: inline-block;
  margin-right: var(--space-2);
  padding: 1px var(--space-2);
  border-radius: var(--r-pill);
  font-size: var(--text-xs);
  font-weight: 600;
  white-space: nowrap;
  background: var(--surface-sunk);
  color: var(--muted);
}
.dash-action.tone-red   .dash-when { background: var(--danger-bg);  color: var(--danger); }
.dash-action.tone-amber .dash-when { background: var(--warning-bg); color: var(--warning); }
.dash-action.tone-blue  .dash-when { background: var(--info-bg);    color: var(--info); }
/* Phone: message first, then a full-width button. */
@media (max-width: 600px) {
  .dash-queue .dash-action { flex-direction: column; align-items: stretch; gap: var(--space-2); padding: var(--space-3); }
  .dash-queue .dash-action .btn { width: 100%; min-height: 44px; justify-content: center; white-space: normal; }
}

/* Roosters card: one row per live period — name, status, one bar, one action. */
.dash-period-row {
  display: grid;
  grid-template-columns: minmax(8rem, 1fr) 9rem minmax(12rem, 2.2fr) 14rem;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.dash-period-row:last-child { border-bottom: none; }
.dash-period-row > .badge { justify-self: start; }
.dash-period-row > .btn { justify-self: end; }
.dash-period-row--gap { background: var(--surface-sunk); color: var(--muted); }
.dash-period-name { display: flex; flex-direction: column; min-width: 0; font-size: var(--text-sm); }
.dash-period-name > span { color: var(--muted); }
.dash-period-measure { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.dash-period-empty { margin: 0; padding: var(--space-3) var(--space-4); }
.dash-bar { height: 6px; border-radius: var(--r-pill); background: var(--surface-sunk); overflow: hidden; }
.dash-bar > span { display: block; height: 100%; border-radius: inherit; background: var(--primary); }
.dash-bar--info    > span { background: var(--info); }
.dash-bar--success > span { background: var(--success); }
.dash-bar--warning > span { background: var(--warning); }
.dash-bar--danger  > span { background: var(--danger); }
/* Still loading: a hatched track, never an empty bar that reads as 0 %. */
.dash-bar--pending {
  background: repeating-linear-gradient(-45deg, var(--surface-sunk) 0 6px, var(--border) 6px 12px);
}
.dash-bar-label { font-size: var(--text-xs); color: var(--muted); overflow-wrap: anywhere; }
.dash-bar-unavailable { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); color: var(--warning); font-weight: 600; }

/* A card that folds (recent activity on a phone). The summary is the header;
   the header link sits beside it and is hidden with the content when folded. */
.dash-fold { display: block; position: relative; }
.dash-fold > summary { list-style: none; cursor: pointer; }
.dash-fold > summary::-webkit-details-marker { display: none; }
.dash-fold > summary h2::before { content: "▸"; color: var(--muted); font-size: var(--text-xs); }
.dash-fold[open] > summary h2::before { content: "▾"; }
.dash-fold:not([open]) > summary { border-bottom: 0; }
.dash-fold-link { position: absolute; top: var(--space-3); right: var(--space-4); font-size: var(--text-sm); }

/* "Vandaag & morgen" strip (dashboard-widgets.js renderOperationsStrip) on the
   stat tiles of reports.css: tone follows state, two columns on a phone. */
.dash-ops { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-6); }
.dash-ops > .dash-ops-tiles { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: var(--space-3); margin: 0; }
.dash-ops .ms-mini-stat { border: 1px solid transparent; }
.dash-ops .ms-mini-stat-value small { font-size: var(--text-sm); font-weight: 400; color: var(--muted); }
.dash-ops .ms-mini-stat-sub { font-size: var(--text-xs); overflow-wrap: anywhere; }
.dash-ops .ms-mini-stat-cta { color: var(--primary); font-weight: 600; }
.dash-ops .ms-mini-stat > .btn { align-self: flex-start; margin-top: var(--space-1); }
.dash-ops .ms-mini-stat--critical { background: var(--danger-bg); border-color: var(--danger); }
.dash-ops .ms-mini-stat--critical .ms-mini-stat-label,
.dash-ops .ms-mini-stat--critical .ms-mini-stat-value { color: var(--danger); }
.dash-ops .ms-mini-stat--warning { background: var(--warning-bg); }
.dash-ops .ms-mini-stat--warning .ms-mini-stat-label,
.dash-ops .ms-mini-stat--warning .ms-mini-stat-value { color: var(--warning); }
.dash-ops .ms-mini-stat--info { background: var(--info-bg); }
.dash-ops .ms-mini-stat--info .ms-mini-stat-value { color: var(--info); }
.dash-ops .ms-mini-stat--ok .ms-mini-stat-value { color: var(--success); }
.dash-ops .ms-mini-stat--pending .ms-mini-stat-value { color: var(--muted); }
.dash-ops .ms-mini-stat--failed { border: 1px dashed var(--warning); }
.dash-ops .ms-mini-stat--failed .ms-mini-stat-sub { color: var(--warning); font-weight: 600; }
.dash-ops--clear {
  flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-4); border-radius: var(--radius);
  background: var(--success-bg); color: var(--success); font-size: var(--text-sm); font-weight: 600;
}
.dash-ops--clear > svg { flex: none; }
.dash-ops--clear > span { flex: 1 1 0; min-width: 12rem; }
.dash-ops--clear > a { margin-left: auto; font-weight: 400; }
@media (max-width: 600px) {
  .dash-ops > .dash-ops-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-ops .ms-mini-stat { padding: var(--space-3); }
}

@media (max-width: 600px) {
  .dash-period-row { grid-template-columns: minmax(0, 1fr) auto; padding: var(--space-3); }
  .dash-period-measure, .dash-period-row > .btn { grid-column: 1 / -1; }
  .dash-period-row > .badge { justify-self: end; }
  .dash-period-row > .btn { justify-self: stretch; min-height: 44px; justify-content: center; white-space: normal; }
}

/* ── Systeem card (components/system-status-card.js) and the verdict line it
   shares with admin-health.js. Counters over threshold get an amber outline. */
.system-card-body { padding: var(--space-3) var(--space-4) 0; container: system-card / inline-size; }
.system-card-body > .load-unavailable { margin-bottom: 0; }
.system-verdict { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-3); font-size: var(--text-sm); }
.system-verdict .badge { margin: 0; }
/* Five counters in one row when the card is wide, else two by two with the
   last one (lockouts) across the full width, never a lone half cell. */
.system-counters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.system-counter:last-child:nth-child(odd) { grid-column: 1 / -1; }
@container system-card (min-width: 50rem) {
  .system-counters { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .system-counter:last-child:nth-child(odd) { grid-column: auto; }
}
.system-counter {
  display: flex; flex-direction: column; gap: var(--space-1); min-width: 0;
  padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius);
}
.system-counter--attention { border-color: var(--warning); box-shadow: inset 0 0 0 1px var(--warning); }
.system-counter-label { font-size: var(--text-xs); color: var(--muted); }
.system-counter > strong { font-size: var(--text-lg); }
.system-counter--attention > strong { color: var(--warning); }
.system-counter-sub { font-size: var(--text-xs); color: var(--muted); overflow-wrap: anywhere; }
.system-card-footer {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-2) var(--space-4); padding: var(--space-3) var(--space-4);
}
.system-card-footer > [data-system-inventory] { flex: 1 1 16rem; }
.system-test-alert { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
/* The policy index reads as a link; opened, its list takes the full footer row. */
.policy-index > summary { cursor: pointer; color: var(--primary); font-size: var(--text-sm); }
.policy-index[open] { flex-basis: 100%; }
.policy-index > ul { margin: var(--space-2) 0 0; padding-left: var(--space-5); font-size: var(--text-sm); }
/* Phone: one compact row per counter — label and detail left, value right. */
@media (max-width: 600px) {
  .system-card-body { padding: var(--space-3) var(--space-3) 0; }
  .system-card-footer { padding: var(--space-3); }
  .system-counters { grid-template-columns: 1fr; gap: var(--space-2); }
  .system-counter { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: var(--space-3); padding: var(--space-2) var(--space-3); }
  .system-counter > strong { grid-column: 2; grid-row: 1 / span 2; font-size: var(--text-base); text-align: right; }
}

/* ── Personal dashboard (Vandaag) ────────────────────────────────────────
   Two columns on desktop: now and the coming weeks on the left, things to
   act on on the right. On a narrow screen the columns dissolve and the
   blocks reorder: hero, to do, coming weeks, the rest. */
.personal-dashboard {
  display: grid;
  grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr);
  gap: var(--space-4) var(--space-6);
  align-items: start;
}
.pd-main, .pd-side { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.personal-dashboard .ms-hero { margin-bottom: 0; }
.pd-todo > .card, .personal-dashboard .dash-card { margin-bottom: 0; }
@media (max-width: 800px) {
  .personal-dashboard { display: flex; flex-direction: column; }
  .pd-main, .pd-side { display: contents; }
  .pd-main > *, .pd-side > * { width: 100%; }
  .pd-main > :first-child { order: 1; }
  .pd-todo { order: 2; }
  .pd-schedule { order: 3; }
  .pd-training, .next-periods { order: 4; }
  .pd-balances { order: 5; }
  .pd-notices { order: 6; }
}
/* Hero actions (shared/schedule-upcoming.css) sit beside the shift on
   desktop and below it on a phone. */
.personal-dashboard .ms-hero { flex-direction: row; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-3); }

/* The sickness banner above the two columns (features/leave/sick-banner.js):
   the shared action-needed notice as an inline card; on a phone its choices
   wrap under the message at touch size. */
.pd-sick-banner { margin-bottom: var(--space-4); }
.pd-sick-banner .action-needed { position: relative; flex-wrap: wrap; padding: var(--space-3) var(--space-4); border-radius: var(--radius); overflow: hidden; }
@media (max-width: 600px) {
  .pd-sick-banner .banner-action { flex: 1 1 auto; min-height: 44px; }
}

/* The two-week list: folded behind a summary on a phone. */
.pd-upcoming > summary { cursor: pointer; font-weight: 600; font-size: var(--text-sm); min-height: 44px; display: flex; align-items: center; }
.pd-upcoming[open] > summary { margin-bottom: var(--space-2); }

/* "Volgende roosters": a .fact-list whose values are status badges. */
.next-periods-list dt { color: var(--text); }
.next-periods-list dd { font-weight: 400; }

.pd-schedule .schedule-legend { margin-top: var(--space-2); }

} /* @layer components */
