/* ============================================================
 * member-management.css — app component styles
 * ============================================================
 * Colours, spacing, radii, and type all come from the design system's --ds-*
 * tokens (generated from the token pipeline; the "members" brand is activated
 * by <html data-brand="members">). Components use the design system's
 * class-marker convention, ds-c-{name}, styled from the matching
 * --ds-{name}-* component tokens.
 *
 * The only literals left are values the token set does not model: unitless
 * line-height ratios, 50%/full-round shapes, the 1px hairline border the
 * card/table tokens already carry as widths, optical letter-spacing, and the
 * ch-based reading measure. Everything dimensional resolves from a token.
 * ============================================================ */

/* ── Utilities ── */
/* Tabular lining numerals — aligns columns of figures (amounts, counts, prices)
   so digits line up vertically and don't jitter as values change. Backed by the
   design-system token; the DS emits --ds-typography-numeric-tabular but ships the
   matching .ds-u-tabular-nums class only in the RCL, so a tokens-first consumer
   defines it locally (still no hardcoded values). */
.ds-u-tabular-nums { font-feature-settings: var(--ds-typography-numeric-tabular); }

/* ── DS-003: adjustments for the design-system RCL components we consume ──
   Layout/usage fixes for our app (not token overrides):
   - DsButton's icon slot expects a DS icon-font glyph we don't ship (we use our
     own SVG <Icon> in the button content instead), so collapse the empty slot to
     keep the label optically centered.
   - DsPageHeader centers its title row; we bottom-align the title with its
     subtitle so the heading and lead sit on the same baseline. */
.ds-c-btn__icon:empty { display: none; }
.ds-c-pageHeader__titleGroup { align-items: flex-end; }
/* Stat-filter cards become <button>s on interactive pages — reset native chrome (the .md-stat rule
   supplies the card's own border/background). Detail tabs (.md-tab) are reset with the tab strips below. */
button.md-stat { appearance: none; font: inherit; text-align: left; cursor: pointer; }
/* Table name-cell rendered as a <button> (interactive open) — look like the link it replaces. */
button.md-name { appearance: none; background: none; border: 0; padding: 0; font: inherit; text-align: left; cursor: pointer; }

/* ── Document baseline (semantic + typography tokens) ── */
html { box-sizing: border-box; }
*, *::before, *::after { box-sizing: inherit; }

body {
  margin: 0;
  font-family: var(--ds-typography-body-font-family);
  font-size: var(--ds-typography-body-font-size);
  line-height: var(--ds-typography-body-line-height);
  color: var(--ds-color-onSurface);
  background-color: var(--ds-color-pageBackground);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color 150ms ease, color 150ms ease;
}

h1, h2, h3 {
  font-family: var(--ds-typography-body-font-family);
  color: var(--ds-color-onSurface);
  margin: 0 0 var(--ds-space-sm);
}
h1 {
  font-size: var(--ds-typography-heading4-font-size);
  font-weight: var(--ds-typography-heading4-font-weight);
  line-height: var(--ds-typography-heading4-line-height);
  letter-spacing: -0.01em;
}
h2 {
  font-size: var(--ds-typography-heading5-font-size);
  font-weight: var(--ds-typography-heading5-font-weight);
  line-height: var(--ds-typography-heading5-line-height);
}

a { color: var(--ds-color-primary); text-decoration: none; }
a:hover { color: var(--ds-color-primaryHover); text-decoration: underline; }

code {
  color: var(--ds-color-primary);
  background: var(--ds-color-primarySubtle);
  font-size: var(--ds-typography-code-font-size);
  padding: var(--ds-space-hairline) var(--ds-space-xs);
  border-radius: var(--ds-radius-sm);
}

::selection { background: var(--ds-color-primarySubtle); color: var(--ds-color-onPrimarySubtle); }
:focus-visible { outline: 2px solid var(--ds-color-focusRing); outline-offset: 2px; }

.app-lead { color: var(--ds-color-onSurfaceVariant); max-width: 60ch; }

/* ── Club section nav — the PRIMARY nav, rendered vertically in the left sidebar (via a
      SectionOutlet in NavMenu), under the Home link. Token-styled from --ds-navigation-*,
      with a persistent active state. ── */
.club-nav {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-hairline);
  margin: var(--ds-space-xs) 0 0;
  padding: 0 var(--ds-space-sm);
}
.club-nav__item {
  display: block;
  padding: var(--ds-navigation-itemPaddingY) var(--ds-space-md);
  border-radius: var(--ds-navigation-itemRadius);
  color: var(--ds-navigation-itemColor);
  font-family: var(--ds-navigation-itemTypography-font-family);
  font-size: var(--ds-navigation-itemTypography-font-size);
  font-weight: var(--ds-navigation-itemTypography-font-weight);
  line-height: var(--ds-navigation-itemTypography-line-height);
  text-decoration: none;
}
.club-nav__item:hover {
  background: var(--ds-navigation-itemHover);
  color: var(--ds-navigation-itemColorHover);
  text-decoration: none;
}
.club-nav__item.is-active {
  background: var(--ds-navigation-itemActive);
  color: var(--ds-navigation-onItemActive);
}

/* ── Footer — quiet, token-styled, holds the privacy link ── */
.app-footer {
  margin-top: var(--ds-space-xl);
  padding-top: var(--ds-space-md);
  padding-bottom: var(--ds-space-md);
  border-top: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
  font-size: var(--ds-typography-labelSmall-font-size);
}
.app-footer a { color: var(--ds-color-onSurfaceVariant); }

/* ── Privacy page — readable measure + spaced sections ── */
.privacy { max-width: 60ch; }
.privacy section { margin-top: var(--ds-space-lg); }
.privacy h2 { margin-bottom: var(--ds-space-xs); }

/* ── Card — ds-c-card / --ds-card-* ── */
.ds-c-card {
  background: var(--ds-card-container);
  border: var(--ds-card-borderWidth) solid var(--ds-card-border);
  border-radius: var(--ds-card-radius);
  padding: var(--ds-card-padding);
  box-shadow: var(--ds-card-elevation);
}

/* ── Button — ds-c-button / --ds-button-* (+ secondary variant) ── */
.ds-c-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ds-button-gap);
  min-height: var(--ds-button-minHeight);
  padding: var(--ds-button-paddingY) var(--ds-button-paddingX);
  border-radius: var(--ds-button-radius);
  border: var(--ds-space-hairline) solid transparent;
  font-family: var(--ds-button-typography-font-family);
  font-size: var(--ds-button-typography-font-size);
  font-weight: var(--ds-button-typography-font-weight);
  line-height: var(--ds-button-typography-line-height);
  cursor: pointer;
  text-decoration: none;
  background: var(--ds-button-container);
  color: var(--ds-button-onContainer);
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.ds-c-button:hover { background: var(--ds-button-containerHover); color: var(--ds-button-onContainer); text-decoration: none; }
.ds-c-button:active { background: var(--ds-button-containerActive); }

.ds-c-button--secondary {
  background: var(--ds-buttonSecondary-container);
  color: var(--ds-buttonSecondary-onContainer);
  border-color: var(--ds-buttonSecondary-border);
}
.ds-c-button--secondary:hover {
  background: var(--ds-buttonSecondary-containerHover);
  color: var(--ds-buttonSecondary-onContainer);
  border-color: var(--ds-buttonSecondary-borderHover);
}
.ds-c-button--secondary:active { background: var(--ds-buttonSecondary-containerActive); }

/* Ghost variant — quiet tertiary actions (Remove / Cancel in lists) so the page's
   primary action stands out (UX review U4). */
.ds-c-button--ghost {
  background: transparent;
  color: var(--ds-color-onSurfaceVariant);
  border-color: transparent;
}
.ds-c-button--ghost:hover {
  background: var(--ds-color-surfaceContainer);
  color: var(--ds-color-onSurface);
  text-decoration: none;
}

/* Inline icon — currentColor, sized to the text (1em). No icon-font dependency (U7). */
.ds-icon { display: inline-block; vertical-align: -0.125em; flex: none; }

/* ── Page header — consistent title + actions block (UX review U3) ── */
.page-header { margin-bottom: var(--ds-space-lg); }
.page-header__bar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--ds-space-md);
  flex-wrap: wrap;
}
.page-header__heading { display: flex; align-items: center; gap: var(--ds-space-sm); flex-wrap: wrap; }
.page-header__bar h1 { margin: 0; }
.page-header__actions { display: flex; flex-wrap: wrap; gap: var(--ds-space-sm); align-items: center; }
.page-header .app-lead { margin-top: var(--ds-space-xs); margin-bottom: 0; }

/* ── Alert / callout — styled feedback instead of plain bold text (UX review U5) ── */
.ds-c-alert {
  display: flex;
  gap: var(--ds-space-sm);
  align-items: flex-start;
  padding: var(--ds-space-sm) var(--ds-space-md);
  margin: var(--ds-space-md) 0;
  border-radius: var(--ds-radius-md);
  border-left: var(--ds-alert-borderWidth) solid var(--ds-color-outline);
  background: var(--ds-color-surfaceContainer);
  color: var(--ds-color-onSurface);
}
.ds-c-alert__icon { flex: none; color: var(--ds-color-onSurfaceVariant); margin-top: var(--ds-space-hairline); }
.ds-c-alert--success { border-left-color: var(--ds-alert-borderSuccess); background: var(--ds-alert-containerSuccess); }
.ds-c-alert--success .ds-c-alert__icon { color: var(--ds-alert-iconSuccess); }
.ds-c-alert--error { border-left-color: var(--ds-alert-borderError); background: var(--ds-alert-containerError); }
.ds-c-alert--error .ds-c-alert__icon { color: var(--ds-alert-iconError); }
/* The warning variant was used before it was styled: MagicLinkConfirm.razor's "opened on a different
   device" banner (security-hardening Task 5) asks for ds-c-alert--warning, but only the success and
   error modifiers existed — so the one warning that whole fix rests on rendered as a neutral grey
   callout, reading as an informational note rather than "you may be signing into someone else's
   account". The --ds-alert-*Warning tokens were already generated for both themes; nothing but this
   rule was missing. */
.ds-c-alert--warning { border-left-color: var(--ds-alert-borderWarning); background: var(--ds-alert-containerWarning); }
.ds-c-alert--warning .ds-c-alert__icon { color: var(--ds-alert-iconWarning); }

/* ── Loading state — quiet shimmer instead of bare text (UX review U6) ── */
.ds-c-loading {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-sm);
  color: var(--ds-color-onSurfaceVariant);
}
.ds-c-loading::before {
  content: "";
  width: var(--ds-space-md);
  height: var(--ds-space-md);
  border-radius: 50%;
  border: 2px solid var(--ds-color-outlineVariant);
  border-top-color: var(--ds-color-primary);
  animation: ds-spin 0.7s linear infinite;
}
@keyframes ds-spin { to { transform: rotate(360deg); } }

/* Danger variant — destructive actions (GDPR erase). Error tokens; never brand. */
.ds-c-button--danger { background: var(--ds-color-error); color: var(--ds-color-onError); }
.ds-c-button--danger:hover { background: var(--ds-color-errorHover); color: var(--ds-color-onError); }
.ds-c-button--danger:active { background: var(--ds-color-errorActive); }

/* ── Members toolbar — export + bulk actions above the table ── */
.members-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ds-space-sm);
  margin-top: var(--ds-space-md);
}
.members-bulk { display: flex; gap: var(--ds-space-xs); margin: 0; }

/* ── Shared admin filter/search row (Members filter, Payments reference-code search, task-4
   review finding: the two were near-identical copy-paste) — a flex row of an input plus one or
   two buttons that wraps on narrow widths. Each page adds its own class only for the one thing
   that's genuinely page-specific: which side of the row carries the margin, since .members-filter
   sits below its page's header/bulk-action row (margin-top) while .payments-search sits directly
   above its table (margin-bottom). ── */
.admin-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ds-space-sm);
}
/* Inputs/selects here size to content, not the full-width default of .ds-c-input. */
.admin-filter-row .ds-c-input { width: auto; }
.admin-filter-row input[type="search"] { min-width: 16rem; flex: 1 1 16rem; }

.members-filter { margin-top: var(--ds-space-sm); }
.payments-search { margin-bottom: var(--ds-space-sm); }

/* ── Table — ds-c-table / --ds-table-* ── */
.ds-c-table { width: 100%; border-collapse: collapse; }
/* Selection column: just wide enough for the checkbox, centred. */
.member-select { width: var(--ds-space-lg); text-align: center; }
.member-select input { cursor: pointer; }
.ds-c-table thead th {
  text-align: left;
  background: var(--ds-table-headerContainer);
  color: var(--ds-table-headerText);
  font-size: var(--ds-typography-labelSmall-font-size);
  font-weight: var(--ds-typography-label-font-weight);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: var(--ds-table-cellPaddingY) var(--ds-table-cellPaddingX);
  border-bottom: var(--ds-table-borderWidth) solid var(--ds-table-border);
}
.ds-c-table tbody td {
  background: var(--ds-table-cellContainer);
  color: var(--ds-table-cellText);
  padding: var(--ds-table-cellPaddingY) var(--ds-table-cellPaddingX);
  border-bottom: var(--ds-table-borderWidth) solid var(--ds-table-border);
}
.ds-c-table tbody tr:hover td { background: var(--ds-table-rowHover); }
.ds-c-table tbody tr:last-child td { border-bottom: none; }
/* Keep avatars / chips / multi-line cells centred against single-line ones. */
.ds-c-table tbody td { vertical-align: middle; }

/* ── Status badge — ds-c-badge / --ds-badge-* + semantic state tokens ── */
.ds-c-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-xs);
  font-size: var(--ds-typography-labelSmall-font-size);
  font-weight: var(--ds-typography-label-font-weight);
  padding: var(--ds-space-xs) var(--ds-space-sm);
  border-radius: var(--ds-badge-radius);
}
.ds-c-badge::before { content: ""; width: var(--ds-space-sm); height: var(--ds-space-sm); border-radius: 50%; background: currentColor; }
.ds-c-badge--success { background: var(--ds-color-successSubtle); color: var(--ds-color-successStrong); }
.ds-c-badge--warning { background: var(--ds-color-warningSubtle); color: var(--ds-color-onWarningSubtle); }
.ds-c-badge--brand { background: var(--ds-color-primarySubtle); color: var(--ds-color-onPrimarySubtle); }
.ds-c-badge--neutral { background: var(--ds-color-surfaceContainer); color: var(--ds-color-onSurfaceVariant); }
/* A basket line that genuinely failed (person NOT signed up) — distinct from --warning
   (waitlisted, nothing wrong) so the member can tell the two apart at a glance. */
.ds-c-badge--error { background: var(--ds-color-errorSubtle); color: var(--ds-color-onErrorSubtle); }

/* ── Sidebar brand mark — navigation companyBadge tokens ── */
.app-brand { display: flex; align-items: center; gap: var(--ds-navigation-companyBadgeGap); text-decoration: none; }
.app-brand:hover { text-decoration: none; }
.app-brand__avatar {
  width: var(--ds-navigation-companyAvatarSize);
  height: var(--ds-navigation-companyAvatarSize);
  border-radius: var(--ds-radius-md);
  background: var(--ds-color-primary);
  color: var(--ds-color-onPrimary);
  display: grid;
  place-items: center;
  font-weight: var(--ds-typography-label-font-weight);
  flex: none;
}
.app-brand__name { display: block; font-weight: var(--ds-typography-label-font-weight); line-height: var(--ds-typography-bodySmall-line-height); color: var(--ds-navigation-companyBadgeText); }
.app-brand__sub { display: block; font-size: var(--ds-typography-caption-font-size); color: var(--ds-navigation-companyBadgeSubtext); }

/* ── Language switcher — token-styled inline links (da · en) ── */
.lang-switcher { display: inline-flex; align-items: center; gap: var(--ds-space-xs); }
.lang-switcher__item {
  color: var(--ds-color-onSurfaceVariant);
  font-size: var(--ds-typography-labelSmall-font-size);
  font-weight: var(--ds-typography-label-font-weight);
  padding: var(--ds-space-hairline) var(--ds-space-xs);
  border-radius: var(--ds-radius-sm);
  text-decoration: none;
}
.lang-switcher__item:hover { color: var(--ds-color-primary); text-decoration: none; }
.lang-switcher__item.is-active { color: var(--ds-color-primary); background: var(--ds-color-primarySubtle); }
.lang-switcher__sep { color: var(--ds-color-outline); }

/* ── Form field + text input — token-styled (S5) ── */
.form-field { display: flex; flex-direction: column; gap: var(--ds-space-xs); }
/* Two-column field grid (season builder); collapses to one column when narrow. */
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--ds-space-md); }
.form-field--check { flex-direction: row; align-items: center; gap: var(--ds-space-sm); }
.form-field > span {
  font-size: var(--ds-typography-labelSmall-font-size);
  font-weight: var(--ds-typography-label-font-weight);
  color: var(--ds-color-onSurfaceVariant);
}
.ds-c-input {
  width: 100%;
  box-sizing: border-box;
  min-height: var(--ds-button-minHeight);
  padding: var(--ds-button-paddingY) var(--ds-button-paddingX);
  border-radius: var(--ds-radius-md);
  border: var(--ds-space-hairline) solid var(--ds-color-outline);
  background: var(--ds-color-surface);
  color: var(--ds-color-onSurface);
  font-family: var(--ds-typography-body-font-family);
  font-size: var(--ds-typography-body-font-size);
}
.ds-c-input:focus-visible { outline: 2px solid var(--ds-color-focusRing); outline-offset: 1px; border-color: var(--ds-color-primary); }
/* Per-field validation message (Blazor ValidationMessage) — small, error-coloured (U5). */
.validation-message {
  margin-top: var(--ds-space-xs);
  color: var(--ds-color-error);
  font-size: var(--ds-typography-labelSmall-font-size);
}
/* Invalid field gets an error border once the form has been validated. */
.ds-c-input.invalid { border-color: var(--ds-color-error); }

/* ── Club list (home) ── */
.club-list { list-style: none; margin: 0 0 var(--ds-space-md); padding: 0; display: flex; flex-direction: column; gap: var(--ds-space-sm); }
.club-list li { display: flex; align-items: center; gap: var(--ds-space-sm); }

/* ── Member row actions (dashboard) — small inline buttons, one form each ── */
.member-actions { display: flex; flex-wrap: wrap; gap: var(--ds-space-xs); }
.member-actions form { margin: 0; }
.member-actions .ds-c-button {
  min-height: auto;
  padding: var(--ds-space-hairline) var(--ds-space-sm);
  font-size: var(--ds-typography-labelSmall-font-size);
}
.member-actions__hint {
  color: var(--ds-color-onSurfaceSubtle);
  font-size: var(--ds-typography-labelSmall-font-size);
  font-style: italic;
}

/* ── Member detail — definition list + the GDPR action row ── */
.member-detail {
  display: grid;
  grid-template-columns: minmax(8rem, max-content) 1fr;
  gap: var(--ds-space-sm) var(--ds-space-lg);
  margin: 0;
}
.member-detail dt {
  color: var(--ds-color-onSurfaceVariant);
  font-size: var(--ds-typography-labelSmall-font-size);
  font-weight: var(--ds-typography-label-font-weight);
}
.member-detail dd { margin: 0; color: var(--ds-color-onSurface); }
.member-detail__actions { display: flex; flex-wrap: wrap; gap: var(--ds-space-sm); align-items: center; }
.member-detail__actions form { margin: 0; }

/* ── Track roster — leader/follower columns + member rows ── */
.roster-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: var(--ds-space-lg); }
.roster-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ds-space-xs); }
.roster-list li { display: flex; align-items: center; justify-content: space-between; gap: var(--ds-space-sm); }
.roster-cancel { margin: 0; }
.roster-pref { color: var(--ds-color-onSurfaceVariant); font-size: var(--ds-typography-labelSmall-font-size); }
/* Workspace member/doc lists — padded, separated rows so they read as proper rows, not bare text. */
.md-rows { gap: 0; }
.md-rows > li { padding: var(--ds-space-sm) var(--ds-space-xs); border-bottom: var(--ds-space-hairline) solid var(--ds-color-outlineVariant); }
.md-rows > li:last-child { border-bottom: 0; }
.md-rows > li:hover { background: var(--ds-color-surfaceContainerLow, var(--ds-color-surfaceContainer)); }

/* ── Member signup — track rows with an inline sign-up form ── */
.signup-tracks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ds-space-md); }
.signup-track { display: flex; align-items: center; justify-content: space-between; gap: var(--ds-space-md); flex-wrap: wrap; }
.signup-track__info { display: flex; flex-direction: column; gap: var(--ds-space-hairline); }
.signup-form { display: flex; gap: var(--ds-space-xs); margin: 0; align-items: center; }
.signup-form .ds-c-input { width: auto; }

/* ============================================================
 * App-wide UX pass — shared layout primitives + admin-list vocabulary.
 * These replace the per-page inline `style="margin-top:…; max-width:…"` literals
 * and make the Members-dashboard patterns reusable on every page. See
 * spec/app-ux-pass.md. Tokens-first throughout.
 * ============================================================ */

/* ── Page sections — one vertical rhythm for stacked cards (replaces per-card
      inline margin-top). Wrap a page's card stack in <div class="page-sections">. ── */
.page-sections { display: flex; flex-direction: column; gap: var(--ds-space-lg); }

/* Form card — a readable measure for single-column forms (replaces inline
   max-width: 48rem). List/table cards stay full width. */
.ds-c-card--form { max-width: 48rem; }

/* Section heading with breathing room above a new block (replaces inline
   margin-top on h2/h3 used as section dividers within a page). */
.section-title { margin-top: var(--ds-space-xl); }

/* Form actions row — submit-button spacing; --span makes a button fill a form grid
   row (replaces inline margin-top / grid-column: 1 / -1 on submit buttons). */
.form-actions { margin-top: var(--ds-space-md); }
.form-actions--span { grid-column: 1 / -1; }

/* Authored prose — preserves the line breaks the author typed (news posts, doc notes;
   replaces inline white-space: pre-wrap). */
.prose-body { white-space: pre-wrap; }

/* Vertical form stack — fieldsets/fields/submit spaced by one gap (replaces a column of
   inline margin-top literals inside a single form card). */
.form-stack { display: flex; flex-direction: column; gap: var(--ds-space-md); }
.form-stack > .form-actions { margin-top: 0; }

/* A wrapping row of buttons (e.g. several pay-method submit forms side by side). */
.button-row { display: flex; flex-wrap: wrap; gap: var(--ds-space-sm); }

/* Each API-key row on the Settings page, spaced from the previous. */
.settings-secret + .settings-secret { margin-top: var(--ds-space-md); }

/* ── Modal — create/edit forms open from a header button instead of sitting under the list
      (UX: don't push a growing list down). Static-SSR friendly: shown when a ?create query is
      present; the scrim + ✕ are plain links back to the list URL, so it works with no JS and is
      bookmarkable. Tokens-first. ── */
.ds-c-scrim {
  position: fixed; inset: 0; z-index: 40;
  background: var(--ds-overlay-scrim);
  backdrop-filter: blur(2px);
}
/* Modal shell (#17 UX pass): a fixed header + footer with a scrollable body between, so long forms
   keep the title and actions in view. Responsive width with a --lg variant for content-heavy forms;
   goes full-screen on phones. */
.ds-c-modal {
  position: fixed; z-index: 41; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: min(44rem, calc(100vw - 2 * var(--ds-space-lg)));
  max-height: calc(100dvh - 2 * var(--ds-space-xl));
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--ds-color-surface);
  border: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
  border-radius: var(--ds-radius-lg, var(--ds-radius-md));
  box-shadow: var(--ds-elevation-level-003);
}
.ds-c-modal--lg { width: min(60rem, calc(100vw - 2 * var(--ds-space-lg))); }
.ds-c-modal__head {
  flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--ds-space-md);
  margin: 0; padding: var(--ds-space-md) var(--ds-card-padding);
  border-bottom: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
}
.ds-c-modal__head h2 { margin: 0; font-size: var(--ds-typography-heading6-font-size); }
.ds-c-modal__body { overflow: auto; padding: var(--ds-card-padding); }
.ds-c-modal__close {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: var(--ds-radius-sm);
  font-size: var(--ds-typography-heading6-font-size); line-height: 1;
  color: var(--ds-color-onSurfaceVariant); text-decoration: none;
}
.ds-c-modal__close:hover { background: var(--ds-color-surfaceContainerHigh, var(--ds-color-surfaceContainer)); color: var(--ds-color-onSurface); text-decoration: none; }
/* Footer action bar — right-aligned, separated from the body. */
.ds-c-modal__foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--ds-space-sm);
  margin-top: var(--ds-space-lg); padding-top: var(--ds-space-md);
  border-top: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
}

@media (max-width: 640px) {
  .ds-c-modal, .ds-c-modal--lg {
    width: 100vw; height: 100dvh; max-height: 100dvh;
    top: 0; left: 0; transform: none; border: 0; border-radius: 0;
  }
}

/* ── Admin-list vocabulary (promoted from ClubDashboard.razor.css so every admin
      list — seasons, workshops, payments, subscriptions, projects — shares it). ── */

/* Horizontal tab strips — the section sub-nav (md-subnav, ProjectBoard views) and the in-page
   tabs (md-tabs, MemberDetail). Both render their items as <button>s (interactive switch), so the
   item reset below is required: the browser's native button border/fill otherwise leaks through as
   folder-tab boxes. Kept as one definition so the two strips stay visually identical. */
.md-subnav,
.md-tabs {
  display: flex;
  gap: var(--ds-space-xs);
  border-bottom: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
  margin-bottom: var(--ds-space-md);
}
.md-subnav__item,
.md-tab {
  appearance: none;
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
  padding: var(--ds-space-sm) var(--ds-space-md);
  text-decoration: none;
  color: var(--ds-color-onSurfaceVariant);
  border-bottom: 2px solid transparent;
  margin-bottom: calc(-1 * var(--ds-space-hairline));
}
.md-subnav__item:hover,
.md-tab:hover { color: var(--ds-color-onSurface); text-decoration: none; }
.md-subnav__item.is-active,
.md-tab--on { color: var(--ds-color-primary); border-bottom-color: var(--ds-color-primary); font-weight: var(--ds-typography-label-font-weight); }

/* Summary / status-filter strip */
.md-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--ds-space-md);
  margin: var(--ds-space-lg) 0 var(--ds-space-md);
}
.md-stat {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-xs);
  text-decoration: none;
  color: var(--ds-color-onSurface);
  border: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
}
.md-stat:hover { border-color: var(--ds-color-outline); text-decoration: none; }
.md-stat--on { border-color: var(--ds-color-primary); box-shadow: inset 0 -3px 0 var(--ds-color-primary); }
/* Static overview card — informational, not a filter link (no hover affordance). */
.md-stat--static { cursor: default; }
.md-stat--static:hover { border-color: var(--ds-color-outlineVariant); }
.md-stat__label { color: var(--ds-color-onSurfaceVariant); font-size: var(--ds-typography-bodySmall-font-size); text-transform: uppercase; letter-spacing: 0.04em; }
.md-stat__value { font-size: var(--ds-typography-heading3-font-size); font-weight: var(--ds-typography-heading3-font-weight); line-height: 1.1; }
.md-stat__sub { color: var(--ds-color-onSurfaceVariant); font-size: var(--ds-typography-bodySmall-font-size); }

/* Bulk-action bar */
.md-bulkbar {
  display: flex;
  align-items: center;
  gap: var(--ds-space-md);
  flex-wrap: wrap;
  padding: var(--ds-space-sm) var(--ds-space-md);
  margin-bottom: var(--ds-space-md);
  background-color: var(--ds-color-surfaceContainer, var(--ds-color-surface));
  border: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
  border-radius: var(--ds-radius-md);
}
.md-bulkbar__count { color: var(--ds-color-onSurfaceVariant); font-size: var(--ds-typography-bodySmall-font-size); }
.md-bulkbar.is-selecting { background-color: var(--ds-color-primaryContainer); border-color: var(--ds-color-primary); }
.md-bulkbar.is-selecting .md-bulkbar__count { color: var(--ds-color-onPrimaryContainer); font-weight: var(--ds-typography-label-font-weight); }

/* Table card — full content width (was capped at 60rem) */
.md-tablecard { margin-top: var(--ds-space-md); overflow: visible; }
.md-table { width: 100%; }
/* Click-to-sort column header: the <th>'s label is a <button> (reset native chrome, inherit the
   header type), with a caret showing the active direction. */
.md-sortable {
  appearance: none; background: none; border: none; cursor: pointer;
  font: inherit; color: inherit; text-align: inherit;
  padding: 0; display: inline-flex; align-items: center; gap: var(--ds-space-xs);
}
.md-sortable:hover { color: var(--ds-color-primary); }
.md-sortcaret { font-size: 0.7em; color: var(--ds-color-primary); }
/* Kebab action column — just wide enough for the ⋯ trigger. */
.md-actioncol { width: 3.5rem; text-align: right; }
/* Inline-button action column — hugs its buttons (content width), right-aligned. */
.md-actions { width: 1%; white-space: nowrap; text-align: right; }
/* Secondary columns (date / status / price / method) hug their content so the primary
   column (name/purpose) absorbs the slack — instead of every column sharing equal width. */
.md-col-fit { width: 1%; white-space: nowrap; }
/* Row buttons never wrap their label (e.g. Danish "Markér betalt"). */
.md-table .ds-c-button { white-space: nowrap; }
.md-muted { color: var(--ds-color-onSurfaceVariant); }

/* List-level progress (#17): a token-styled <progress> + a "done/total" caption. */
.md-progress { display: inline-flex; align-items: center; gap: var(--ds-space-xs); }
.md-progress__bar {
  -webkit-appearance: none; appearance: none;
  width: 4rem; height: 0.5rem; border: 0; border-radius: var(--ds-radius-full);
  background-color: var(--ds-color-surfaceContainerHighest, var(--ds-color-surfaceContainer)); overflow: hidden;
}
.md-progress__bar::-webkit-progress-bar { background-color: var(--ds-color-surfaceContainerHighest, var(--ds-color-surfaceContainer)); border-radius: var(--ds-radius-full); }
.md-progress__bar::-webkit-progress-value { background-color: var(--ds-color-primary); border-radius: var(--ds-radius-full); }
.md-progress__bar::-moz-progress-bar { background-color: var(--ds-color-primary); border-radius: var(--ds-radius-full); }
.md-progress__text { font-size: var(--ds-typography-bodySmall-font-size); white-space: nowrap; }

/* Kebab row-actions (native <details> — works without JS) */
.md-kebab { position: relative; display: inline-block; }
.md-kebab__btn {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: var(--ds-radius-sm);
  font-size: var(--ds-typography-heading6-font-size); line-height: 1; color: var(--ds-color-onSurfaceVariant);
}
.md-kebab__btn::-webkit-details-marker { display: none; }
.md-kebab__btn:hover { background-color: var(--ds-color-surfaceContainerHigh, var(--ds-color-surfaceContainer)); }
.md-kebab[open] .md-kebab__btn { background-color: var(--ds-color-surfaceContainerHigh, var(--ds-color-surfaceContainer)); }
.md-kebab__menu {
  position: absolute; z-index: 10; top: calc(100% + var(--ds-space-xs)); right: 0; min-width: 11rem;
  display: flex; flex-direction: column;
  background-color: var(--ds-color-surface); border: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
  border-radius: var(--ds-radius-md); box-shadow: var(--ds-elevation-level-002);
  padding: var(--ds-space-xs);
}
.md-kebab__menu form { display: block; margin: 0; }
.md-kebab__item {
  width: 100%; text-align: left; border: 0; background: transparent; cursor: pointer; font: inherit;
  padding: var(--ds-space-xs) var(--ds-space-sm); border-radius: var(--ds-radius-sm); color: var(--ds-color-onSurface);
  display: inline-flex; align-items: center; gap: var(--ds-space-xs); text-decoration: none;
}
.md-kebab__item:hover { background-color: var(--ds-color-surfaceContainerHigh, var(--ds-color-surfaceContainer)); text-decoration: none; }
.md-kebab__item--danger { color: var(--ds-color-error); }

/* Pager */
.md-pager {
  display: flex;
  align-items: center;
  gap: var(--ds-space-sm);
  padding: var(--ds-space-md);
  border-top: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
  font-size: var(--ds-typography-bodySmall-font-size);
}
.md-pager__spacer { flex: 1; }

/* ── Project workspace shell (#17 Phase 3) ── */
.board-back { margin: 0 0 var(--ds-space-xs); font-size: var(--ds-typography-bodySmall-font-size); }
.board-back a { color: var(--ds-color-onSurfaceVariant); text-decoration: none; }
.board-back a:hover { color: var(--ds-color-onSurface); }
/* Project overview strip: status + member count + task progress above the tabs. */
.project-summary { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ds-space-md); margin-bottom: var(--ds-space-md); }
.project-summary__item { display: inline-flex; align-items: center; gap: var(--ds-space-xs); color: var(--ds-color-onSurfaceVariant); font-size: var(--ds-typography-bodySmall-font-size); }
/* A small chip sitting inline with text (priority on a list row, type on a doc). */
.md-inline-chip { margin-left: var(--ds-space-xs); }
/* Assignee cell: avatar + name on one line. */
.task-assignee { display: inline-flex; align-items: center; gap: var(--ds-space-xs); }
/* Docs: "+ Add link / + Add note" buttons sit above the list (create lives in a modal, not under it). */
.docs-toolbar { display: flex; flex-wrap: wrap; gap: var(--ds-space-sm); margin-bottom: var(--ds-space-md); }
/* Long-form text areas (news/newsletter body, task description) — roomy, comfortable line-height. */
.prose-input { min-height: 12rem; line-height: var(--ds-typography-body-line-height, 1.5); resize: vertical; }

/* ── Kanban board (projects) — extracted from ProjectBoard inline styles ── */
.board-toolbar { display: flex; gap: var(--ds-space-sm); align-items: center; margin-bottom: var(--ds-space-md); flex-wrap: wrap; }
.board-toolbar__spacer { flex: 1; }
.board-columns { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--ds-space-md); align-items: start; }

/* Column: a tinted lane with a labelled header + task count. */
.board-col { background: var(--ds-color-surfaceContainerLow, var(--ds-color-surfaceContainer)); }
.board-col__head { display: flex; align-items: center; gap: var(--ds-space-sm); margin-bottom: var(--ds-space-sm); }
.board-col__title { margin: 0; font-size: var(--ds-typography-heading6-font-size); }
.board-col__count {
  margin-left: auto; min-width: 1.5rem; height: 1.5rem; padding: 0 var(--ds-space-xs);
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--ds-radius-full); background: var(--ds-color-surfaceContainerHighest, var(--ds-color-surfaceContainer));
  color: var(--ds-color-onSurfaceVariant); font-size: var(--ds-typography-bodySmall-font-size); font-weight: var(--ds-typography-label-font-weight);
}
.board-col__empty { color: var(--ds-color-onSurfaceVariant); padding: var(--ds-space-sm); margin: 0; }

/* Card: a raised tile. A left accent rail flags urgent (High) work. */
.board-card {
  border: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
  border-radius: var(--ds-radius-md);
  padding: var(--ds-space-sm);
  margin-top: var(--ds-space-sm);
  background: var(--ds-color-surface);
  box-shadow: var(--ds-elevation-level-001);
  display: flex; flex-direction: column; gap: var(--ds-space-xs);
}
.board-card[draggable="true"] { cursor: grab; }
.board-card__head { display: flex; align-items: flex-start; gap: var(--ds-space-xs); }
.board-card__spacer { flex: 1; }
.board-card__title { font-size: var(--ds-typography-body-font-size); line-height: 1.3; }
/* "New task" toolbar above the board/list. */
.tasks-toolbar { display: flex; justify-content: flex-end; margin-bottom: var(--ds-space-md); }
/* Team "add member" form — a touch of space above the row it follows. */
.team-add { margin-top: var(--ds-space-sm); }
.board-card__chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ds-space-xs); margin: 0; }
.board-card__assignee { color: var(--ds-color-onSurfaceVariant); font-size: var(--ds-typography-bodySmall-font-size); }
.board-card__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ds-space-xs); margin-top: var(--ds-space-xs); }
.board-card__actions .signup-form { display: flex; gap: var(--ds-space-xs); align-items: center; margin: 0; }
.board-card__actions .ds-c-input { min-width: 6rem; }

/* Assignee avatar — initials in a tinted disc. */
.task-avatar {
  flex: none; width: 1.75rem; height: 1.75rem; border-radius: var(--ds-radius-full);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ds-color-primaryContainer, var(--ds-color-surfaceContainerHighest));
  color: var(--ds-color-onPrimaryContainer, var(--ds-color-onSurface));
  font-size: var(--ds-typography-bodySmall-font-size); font-weight: var(--ds-typography-label-font-weight);
}

/* ── Global chat drawer (#17): a floating toggle + a right-side slide-in panel ── */
.chat-fab {
  position: fixed; right: var(--ds-space-lg); bottom: var(--ds-space-lg); z-index: 38;
  width: 3.25rem; height: 3.25rem; border-radius: var(--ds-radius-full); border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.4rem;
  background: var(--ds-color-primary); color: var(--ds-color-onPrimary);
  box-shadow: var(--ds-elevation-level-003);
}
.chat-fab:hover { background: var(--ds-color-primaryHover, var(--ds-color-primary)); }
.chat-drawer {
  position: fixed; top: 0; right: 0; z-index: 39; height: 100dvh;
  width: min(24rem, 100vw); transform: translateX(100%); transition: transform 0.2s ease;
  display: flex; flex-direction: column;
  background: var(--ds-color-surface);
  border-left: var(--ds-space-hairline) solid var(--ds-color-outlineVariant);
  box-shadow: var(--ds-elevation-level-003);
}
.chat-drawer.is-open { transform: translateX(0); }
.chat-drawer__head { flex: none; display: flex; align-items: center; justify-content: space-between; padding: var(--ds-space-md) var(--ds-card-padding); border-bottom: var(--ds-space-hairline) solid var(--ds-color-outlineVariant); }
.chat-drawer__channels { flex: none; display: flex; flex-wrap: wrap; gap: var(--ds-space-xs); padding: var(--ds-space-sm) var(--ds-card-padding); border-bottom: var(--ds-space-hairline) solid var(--ds-color-outlineVariant); }
.chat-drawer__channel {
  border: var(--ds-space-hairline) solid var(--ds-color-outlineVariant); background: var(--ds-color-surface);
  border-radius: var(--ds-radius-full); padding: var(--ds-space-xs) var(--ds-space-sm);
  font-size: var(--ds-typography-bodySmall-font-size); cursor: pointer; color: var(--ds-color-onSurfaceVariant);
}
.chat-drawer__channel.is-active { background: var(--ds-color-primaryContainer); color: var(--ds-color-onPrimaryContainer); border-color: transparent; }
.chat-drawer__body { flex: 1; overflow: auto; padding: var(--ds-card-padding); }

/* ── Chat panel — extracted from ChatPanel inline styles ── */
.chat-log {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--ds-space-sm);
  max-height: 24rem; overflow-y: auto;
}
.chat-input-row { display: flex; gap: var(--ds-space-sm); margin-top: var(--ds-space-md); }
.chat-input { flex: 1; }

/* ── Track cards (EVENT-001 / task-4-schedule-on-the-track) — one card per level track,
   each carrying its own dates/venue/price. Replaces the old season-wide flattened dates
   table: two tracks can legally share a date now, so a date's Remove button only makes
   sense scoped under its own track. ── */
.md-tracks { display: flex; flex-direction: column; gap: var(--ds-space-md); }
.md-track__header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--ds-space-md); flex-wrap: wrap; }
.md-track__title { display: flex; align-items: center; gap: var(--ds-space-sm); flex-wrap: wrap; }
.md-track__title h3 { margin: 0; }
.md-track__meta {
  display: flex; flex-wrap: wrap; gap: var(--ds-space-md); margin-top: var(--ds-space-xs);
  color: var(--ds-color-onSurfaceVariant); font-size: var(--ds-typography-bodySmall-font-size);
}
.md-track__dates { margin-top: var(--ds-space-md); }
.md-track__forms {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--ds-space-md); margin-top: var(--ds-space-md);
}
/* Nested track forms give up the app-wide 48rem form measure — three sit side by side here. */
.md-track__forms .ds-c-card--form { max-width: none; }

@media (max-width: 720px) {
  .md-stats { grid-template-columns: repeat(2, 1fr); }
  .board-columns { grid-template-columns: 1fr; }
}
