/* ---------------------------------------------------------------------------------------
   X02 scope note, 2026-09-13 — checked, not assumed.

   A sweep counted 23 sub-14px declarations in this file. Where each `ui-` class is actually
   RENDERED decides which of them the type floor reaches, and the answer is nearly all ops:

     .type-badge     player-facing (the EVENT / LEAGUE pill on /my/events) — FIXED
     .ui-toast-msg   <Toast /> is in PlayerLayout and PublicLayout, so every player and
                     public page — FIXED
     the rest        Pages/Leagues commissioner panels (CommissionerCommandCenter,
                     FinishWeekPanel, DiagnosticsDrawer, AttendanceExceptionPanel…),
                     Pages/Dev and Pages/DesignSystem. 52 of the 56 razor files using a
                     `ui-` class are under Pages/Leagues.

   The ops ones were NOT fixed here, and the stated reason was: "raising type inside them
   changes column widths that only driving those pages can verify."

   🟢 CLOSED 2026-09-14 by doing exactly that. The ops type-floor pass drove every audited ops
   route at 1280px and 390px as the Lake City club admin and measured computed geometry. The
   `ui-` kit turned out NOT to be confined to panels nobody looks at: on
   /leagues/{id}/rounds/{roundId} — the commissioner's weekly page — `.ui-badge` rendered at
   11.2px carrying "Final", "Attendance: Everyone in" and "Phase: Net scoring week - avg team
   handicap". Sentences, in a badge, 3px under the absolute floor.

   🔴 And the earlier note was checked against the WRONG page. The route table in
   ops-routes-one-h1.spec.ts pointed at /leagues/2/rounds/86, which is an EVENT round id, not
   one of league 2's league-round ids (25-28). That page renders four pieces of text and one
   H1, so it passed every guard by being empty. /leagues/2/rounds/28 renders 106 and is where
   the defect lived.

   The verification the old note asked for is now on the record: after the raise, zero elements
   under 13px on any audited ops route, and zero pages with horizontal overflow at either
   viewport. X03 (the 48px TOUCH floor on dense ops rows) is untouched and remains Matt's call.
   --------------------------------------------------------------------------------------- */

/* ============================================================
   BACK9OPS — COMPONENT CLASS LIBRARY  (components.css)
   All classes built exclusively on tokens from tokens.css.
   These are the ONLY classes Blazor UI components may use.

   NAMING CONVENTION: .ui-* prefix for all component classes.
   This prevents collision with Bootstrap and custom page CSS.

   LOAD ORDER: tokens.css → components.css → app.css

   SECTIONS (985 + additions):
     CARD · FORM SECTION · FORM FIELDS · BUTTONS · PAGE HEADER
     NAV ITEMS · BADGES · ALERT · EMPTY STATE · LOADING SKELETON
     TOAST · DATA TABLE · FILTER BAR · MODAL · STAT CARD · LAYOUT GRIDS
     — NEW BELOW —
     SECTION HEADER · CONTENT CONTAINER · BUTTON GROUP · ACTION CARD
     INFO CARD · ENTITY LIST ITEM · KEY-VALUE LIST · TIMELINE
     BREADCRUMBS · CONTEXT HEADER · STATE PAGES · FORM CHECKBOX/RADIO
     BADGE DOT · INLINE VALIDATION · METRIC TILE
   ============================================================ */


/* ════════════════════════════════════════════════════════════
   CARD
   Primary container for all content surfaces.
════════════════════════════════════════════════════════════ */

.ui-card {
  background:    var(--bg-surface);
  border:        1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow:    var(--shadow-sm);
  position:      relative;
  overflow:      hidden;
}

/* Default body padding (can be overridden with .ui-card--flush) */
.ui-card--padded {
  padding: var(--space-5) var(--space-6);
}

/* Hover lift — apply only when explicitly wanted */
.ui-card--hoverable {
  cursor:     pointer;
  transition: border-color var(--transition-fast),
              box-shadow   var(--transition-fast),
              transform    var(--transition-fast);
}

.ui-card--hoverable:hover {
  border-color: var(--border-default);
  box-shadow:   var(--shadow-lg);
  transform:    translateY(-1px);
}

.ui-card--hoverable:active {
  transform: translateY(0) scale(0.995);
}

/* Selectable card — used for format/option pickers */
.ui-card--selectable {
  cursor:     pointer;
  user-select: none;
  transition: border-color var(--transition-fast),
              background   var(--transition-fast),
              box-shadow   var(--transition-fast),
              transform    var(--transition-fast);
}

.ui-card--selectable:hover {
  border-color: var(--brand);
  background:   var(--brand-soft);
  transform:    translateY(-1px);
}

.ui-card--selectable:active {
  transform: translateY(0) scale(0.99);
}

.ui-card--selected {
  border-color: var(--brand) !important;
  background:   var(--brand-soft) !important;
  box-shadow:   0 0 0 1px var(--brand), var(--shadow-md) !important;
}

/* Checkmark on selected cards */
.ui-sel-check {
  position:        absolute;
  top:             var(--space-2);
  right:           var(--space-2);
  width:           20px;
  height:          20px;
  border-radius:   var(--radius-full);
  background:      var(--brand);
  color:           #fff;
  font-size:       var(--font-size-chip);
  display:         flex;
  align-items:     center;
  justify-content: center;
  animation:       ui-pop-in 150ms var(--transition-fast) both;
}

@keyframes ui-pop-in {
  from { opacity: 0; transform: scale(0.5); }
  to   { opacity: 1; transform: scale(1);   }
}

/* Flush card — no border, for full-bleed table containers */
.ui-card--flush { overflow: hidden; }


/* ════════════════════════════════════════════════════════════
   FORM SECTION
   Groups related form fields with a labelled header strip.
════════════════════════════════════════════════════════════ */

.ui-form-section {
  background:    var(--bg-surface);
  border:        1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow:    var(--shadow-sm);
  overflow:      hidden;
  margin-bottom: var(--space-5);
}

.ui-form-section:last-child { margin-bottom: 0; }

.ui-form-section-header {
  padding:        var(--space-3) var(--space-5);
  background:     var(--bg-elevated);
  border-bottom:  1px solid var(--border-subtle);
  font-size:      var(--font-size-chip);
  font-weight:    800;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color:          var(--text-secondary);
  display:        flex;
  align-items:    center;
  gap:            var(--space-2);
}

.ui-form-section-body {
  padding: var(--space-5) var(--space-5);
}


/* ════════════════════════════════════════════════════════════
   FORM FIELDS
   Label → Input → Hint/Error stack.
════════════════════════════════════════════════════════════ */

.ui-field {
  display:        flex;
  flex-direction: column;
  gap:            var(--space-1);
  margin-bottom:  var(--space-4);
}

.ui-field:last-child { margin-bottom: 0; }

/* Label */
.ui-label {
  font-size:      var(--font-size-sm, 14px);
  font-weight:    700;
  color:          var(--text-helper, var(--text-secondary));
  letter-spacing: 0.015em;
  line-height:    1.4;
  user-select:    none;
}

.ui-req {
  color:       var(--danger);
  margin-left: 2px;
}

/* Core input */
.ui-input,
.ui-select,
.ui-textarea {
  display:          block;
  width:            100%;
  padding:          10px 13px;
  background:       var(--bg-app);
  border:           1px solid var(--color-gray-400, var(--border-default));
  border-radius:    var(--radius-md);
  color:            var(--text-primary);
  font-size:        var(--font-size-base, 1rem);
  font-family:      var(--font-sans);
  line-height:      1.5;
  outline:          none;
  transition:       border-color var(--transition-fast),
                    box-shadow   var(--transition-fast),
                    background   var(--transition-fast);
}

.ui-input::placeholder,
.ui-textarea::placeholder {
  color:   var(--text-muted);
  opacity: 1;
}

.ui-input:hover:not(:disabled):not(:focus),
.ui-select:hover:not(:disabled):not(:focus),
.ui-textarea:hover:not(:disabled):not(:focus) {
  border-color: var(--border-strong);
}

.ui-input:focus,
.ui-select:focus,
.ui-textarea:focus {
  border-color: var(--brand);
  box-shadow:   0 0 0 3px var(--brand-ring);
  outline:      none;
}

.ui-input:disabled,
.ui-select:disabled,
.ui-textarea:disabled {
  opacity:    0.50;
  cursor:     not-allowed;
  background: rgba(255,255,255,0.02);
}

/* Select arrow */
.ui-select {
  background-image:    url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%2394A3B8' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  background-repeat:   no-repeat;
  background-position: right 0.75rem center;
  background-size:     16px 12px;
  padding-right:       2.5rem;
  cursor:              pointer;
  -webkit-appearance:  none;
  appearance:          none;
}

.ui-textarea { min-height: 80px; resize: vertical; }

/* Hint text */
.ui-hint {
  font-size:   var(--font-size-sm, 14px);
  color:       var(--text-helper, var(--text-secondary));
  line-height: 1.45;
}

/* Validation error */
.ui-err {
  font-size:   var(--font-size-sm, 14px);
  color:       var(--danger-text);
  line-height: 1.45;
  display:     flex;
  align-items: center;
  gap:         var(--space-1);
}

/* Error state on field */
.ui-field--error .ui-input,
.ui-field--error .ui-select,
.ui-field--error .ui-textarea {
  border-color: var(--danger);
}

.ui-field--error .ui-input:focus,
.ui-field--error .ui-select:focus,
.ui-field--error .ui-textarea:focus {
  box-shadow: 0 0 0 3px rgba(239,68,68,0.20);
}

.ui-field--error .ui-label { color: var(--danger-text); }

/* Input with leading icon */
.ui-input-wrap {
  position:    relative;
  display:     flex;
  align-items: stretch;
}

.ui-input-icon {
  position:       absolute;
  left:           11px;
  top:            50%;
  transform:      translateY(-50%);
  color:          var(--text-muted);
  font-size:      15px;
  pointer-events: none;
  z-index:        1;
  line-height:    1;
}

.ui-input-wrap .ui-input { padding-left: 34px; }

/* Two-column row */
.ui-row-2 {
  display:               grid;
  grid-template-columns: 1fr 1fr;
  gap:                   var(--space-5);
}

.ui-row-2 .ui-field { margin-bottom: 0; }

@media (max-width: 576px) {
  .ui-row-2 { grid-template-columns: 1fr; }
}


/* ════════════════════════════════════════════════════════════
   BUTTONS
   Shared base + variant modifiers.
════════════════════════════════════════════════════════════ */

.ui-btn {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  gap:             var(--space-2);
  min-height:      var(--touch-target-min, 48px);
  padding:         10px 16px;
  border-radius:   var(--radius-md);
  border:          none;
  font-size:       var(--font-size-base, 1rem);
  font-weight:     600;
  font-family:     var(--font-sans);
  line-height:     1;
  white-space:     nowrap;
  cursor:          pointer;
  text-decoration: none;
  position:        relative;
  transition:      background    var(--transition-fast),
                   border-color  var(--transition-fast),
                   transform     120ms ease,
                   box-shadow    var(--transition-fast),
                   opacity       var(--transition-fast);
  user-select:     none;
}

.ui-btn:focus-visible {
  outline:    none;
  box-shadow: var(--focus-ring);
}

.ui-btn:disabled,
.ui-btn[disabled] {
  opacity:        0.70;
  cursor:         not-allowed;
  pointer-events: none;
}

/* Size modifiers */
.ui-btn--sm  { min-height: var(--touch-target-min, 48px); padding: 8px 12px; font-size: var(--font-size-sm, 14px); border-radius: var(--radius-sm); }
.ui-btn--lg  { padding: 11px 22px; font-size: 0.9375rem; }
.ui-btn--full { width: 100%; }

/* Variants */
.ui-btn--primary {
  background: var(--brand);
  color:      #fff;
}

.ui-btn--primary:hover:not(:disabled) {
  background: var(--brand-hover);
  box-shadow: 0 4px 12px rgba(30,64,175,0.25);
}

.ui-btn--primary:active:not(:disabled) {
  background: var(--brand-active);
  transform:  scale(0.975);
  box-shadow: none;
}

.ui-btn--secondary {
  background:   var(--bg-elevated);
  color:        var(--text-secondary);
  border:       1px solid var(--border-default);
}

.ui-btn--secondary:hover:not(:disabled) {
  background:   rgba(255,255,255,0.07);
  border-color: var(--border-strong);
  color:        var(--text-primary);
}

.ui-btn--secondary:active:not(:disabled) {
  transform: scale(0.975);
}

.ui-btn--ghost {
  background: transparent;
  color:      var(--text-muted);
  border:     1px solid transparent;
}

.ui-btn--ghost:hover:not(:disabled) {
  background:   var(--bg-elevated);
  color:        var(--text-primary);
  border-color: var(--border-subtle);
}

.ui-btn--danger {
  /* --danger-strong, not --danger. White on #EF4444 is 3.76:1 and this is button text, so the
     4.5:1 threshold applies. There is nowhere lighter than #fff to go, so the fill is what moves.
     --danger keeps its meaning for borders and tints, where contrast is not the question. */
  background: var(--danger-strong, #B91C1C);
  color:      #fff;
}

.ui-btn--danger:hover:not(:disabled) {
  background: #DC2626;
  box-shadow: 0 4px 12px rgba(239,68,68,0.25);
}

.ui-btn--danger:active:not(:disabled) {
  transform: scale(0.975);
}

/* White on amber is 2.15:1 in dark (--warning is #F59E0B there) and 3.19:1 in light (#D97706).
   The same answer the status badges reach: the button keeps its amber fill and takes the ink
   that can be written on one — 8.81:1 on #F59E0B, 5.94:1 on #D97706. "Reopen Scoring" on the
   league week page is the control this was measured on. */
.ui-btn--warning {
  background: var(--warning, #D97706);
  color:      var(--b9-status-fill-ink);
  border:     none;
}

.ui-btn--warning:hover:not(:disabled) {
  opacity: .88;
  box-shadow: 0 4px 12px rgba(217,119,6,0.25);
}

.ui-btn--warning:active:not(:disabled) {
  transform: scale(0.975);
}

/* Icon button (square, icon only) */
.ui-btn--icon {
  min-width: var(--touch-target-min, 48px);
  min-height: var(--touch-target-min, 48px);
  padding:  0;
  border-radius: var(--radius-md);
}

.ui-btn--icon.ui-btn--sm  { min-width: var(--touch-target-min, 48px); min-height: var(--touch-target-min, 48px); }
.ui-btn--icon.ui-btn--lg  { min-width: var(--touch-target-min, 48px); min-height: var(--touch-target-min, 48px); }

/* Loading state */
.ui-btn--loading {
  pointer-events: none;
  opacity:        0.80;
}

.ui-btn--loading .ui-btn-text { opacity: 0; }

.ui-btn--loading::after {
  content:      '';
  position:     absolute;
  left:         50%;
  top:          50%;
  width:        16px;
  height:       16px;
  margin-left:  -8px;
  margin-top:   -8px;
  border:       2px solid rgba(255,255,255,0.30);
  border-top-color: #fff;
  border-radius: var(--radius-full);
  animation:    ui-spin 0.55s linear infinite;
}

@keyframes ui-spin {
  to { transform: rotate(360deg); }
}

/* Button group */
.ui-btn-group {
  display:  flex;
  gap:      var(--space-2);
  flex-wrap: wrap;
  align-items: center;
}

.ui-btn-group--end { justify-content: flex-end; }


/* ════════════════════════════════════════════════════════════
   PAGE HEADER
   Title + optional subtitle + right-aligned actions.
════════════════════════════════════════════════════════════ */

.ui-page-header {
  display:         flex;
  align-items:     flex-start;
  justify-content: space-between;
  gap:             var(--space-4);
  flex-wrap:       wrap;
  margin-bottom:   var(--space-6);
}

.ui-page-title {
  font-size:      1.375rem;
  font-weight:    800;
  color:          var(--text-primary);
  letter-spacing: -0.03em;
  margin:         0;
  line-height:    1.2;
}

.ui-page-sub {
  font-size:   0.875rem;
  color:       var(--text-secondary);
  margin-top:  var(--space-1);
  line-height: 1.55;
}

.ui-page-actions {
  display:     flex;
  align-items: center;
  gap:         var(--space-2);
  flex-wrap:   wrap;
  flex-shrink: 0;
}

@media (max-width: 576px) {
  .ui-page-header  { flex-direction: column; }
  .ui-page-actions { width: 100%; }
  .ui-page-actions .ui-btn { flex: 1; justify-content: center; }
}


/* ════════════════════════════════════════════════════════════
   NAV ITEMS  (used inside Sidebar component)
════════════════════════════════════════════════════════════ */

.ui-nav-section {
  padding:       var(--space-3) 0 var(--space-2);
}

.ui-nav-section-label {
  font-size:      var(--font-size-chip);
  font-weight:    700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color:          var(--text-secondary);
  padding:        0 var(--space-4);
  margin-bottom:  var(--space-1);
}

.ui-nav-item {
  display:      block;
  width:        100%;
  padding:      var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-size:    0.875rem;
  font-weight:  500;
  color:        var(--text-secondary);
  text-decoration: none;
  background:   transparent;
  border:       none;
  cursor:       pointer;
  transition:   background var(--transition-fast),
                color      var(--transition-fast);
  display:      flex;
  align-items:  center;
  gap:          var(--space-3);
  line-height:  1;
}

.ui-nav-item:hover {
  background: var(--bg-surface);
  color:      var(--text-primary);
}

.ui-nav-item--active {
  background: rgba(29,78,216,0.18) !important;
  color:      var(--text-primary) !important;
  font-weight: 600;
}

.ui-nav-item i {
  font-size:   1rem;
  flex-shrink: 0;
  opacity:     0.92;
  width:       18px;
  text-align:  center;
}

.ui-nav-item--active i { opacity: 1; color: var(--brand-text); }


/* ════════════════════════════════════════════════════════════
   BADGES / STATUS CHIPS
════════════════════════════════════════════════════════════ */

.ui-badge {
  display:        inline-flex;
  align-items:    center;
  gap:            var(--space-1);
  padding:        3px 10px;
  border-radius:  var(--radius-full);
  font-size:      var(--font-size-sm);
  font-weight:    700;
  white-space:    nowrap;
  letter-spacing: 0.02em;
  border:         1px solid transparent;
}

.ui-badge--neutral { background: rgba(255,255,255,0.07); color: var(--text-secondary); border-color: var(--border-subtle); }
.ui-badge--primary { background: var(--brand-soft);       color: var(--brand-text); border-color: rgba(29,78,216,0.25); }
.ui-badge--success { background: var(--success-soft);     color: var(--success-text); border-color: rgba(34,197,94,0.20); }
.ui-badge--warning { background: var(--warning-soft);     color: var(--warning-text); border-color: rgba(245,158,11,0.20); }
.ui-badge--danger  { background: var(--danger-soft);      color: var(--danger-text); border-color: rgba(239,68,68,0.20); }
.ui-badge--info    { background: var(--info-soft);         color: var(--info-text); border-color: rgba(56,189,248,0.18); }

/* ── Product type badges (EVENT / LEAGUE) ── */
/* One uppercase word saying which kind of thing a row is. Furniture, so the chip floor applies
   — but it was 0.65rem, which is 10.4px and under even that. UX audit X02, 2026-09-13.

   🔴 The selector carries `.badge.type-badge` as well, and that is load-bearing, not tidiness.
   The markup is `class="badge type-badge type-badge--event"`, and app.css now pins a `.badge`
   floor of 14px. Both selectors would be (0,1,0) and app.css loads LATER, so a bare `.type-badge`
   here would lose its own decision silently and this pill would quietly render at 14px. Winning on
   specificity keeps the choice where the comment explaining it lives. (components.css is a GLOBAL
   stylesheet; a scoped .razor.css does not need this, because scoped rules carry a [b-xxxxx]
   attribute and outrank app.css already.) */
.badge.type-badge,
.type-badge {
  display:        inline-flex;
  align-items:    center;
  padding:        2px 8px;
  border-radius:  4px;
  font-size:      var(--font-size-chip);
  font-weight:    700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border:         1px solid transparent;
  white-space:    nowrap;
  vertical-align: middle;
}
.type-badge--event  { background: var(--brand-soft); color: var(--brand-text); border-color: rgba(29,78,216,0.25); }
.type-badge--league { background: var(--b9-orange-soft); color: var(--b9-orange-text); border-color: rgba(234,88,12,0.28); }


/* ════════════════════════════════════════════════════════════
   ALERT / CALLOUT
════════════════════════════════════════════════════════════ */

.ui-alert {
  display:       flex;
  align-items:   flex-start;
  gap:           var(--space-3);
  padding:       var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  font-size:     0.875rem;
  line-height:   1.55;
  border:        1px solid transparent;
}

.ui-alert--danger  { background: var(--danger-soft);  border-color: rgba(239,68,68,0.20);  color: var(--danger-text); }
.ui-alert--success { background: var(--success-soft); border-color: rgba(34,197,94,0.20);  color: var(--success-text); }
.ui-alert--warning { background: var(--warning-soft); border-color: rgba(245,158,11,0.20); color: var(--warning-text); }
.ui-alert--info    { background: var(--info-soft);    border-color: rgba(56,189,248,0.18); color: var(--info-text); }

.ui-alert i { flex-shrink: 0; font-size: 1rem; margin-top: 1px; }


/* ════════════════════════════════════════════════════════════
   EMPTY STATE
════════════════════════════════════════════════════════════ */

.ui-empty {
  display:         flex;
  flex-direction:  column;
  align-items:     center;
  justify-content: center;
  text-align:      center;
  padding:         var(--space-16) var(--space-8);
}

.ui-empty-icon {
  font-size:     2.5rem;
  margin-bottom: var(--space-4);
  opacity:       0.30;
  color:         var(--text-muted);
}

.ui-empty-title {
  font-size:      1rem;
  font-weight:    700;
  color:          var(--text-primary);
  margin:         0 0 var(--space-2);
  letter-spacing: -0.01em;
}

.ui-empty-body {
  font-size:   0.875rem;
  color:       var(--text-secondary);
  max-width:   380px;
  margin:      0 auto var(--space-6);
  line-height: 1.65;
}


/* ════════════════════════════════════════════════════════════
   LOADING SKELETON
════════════════════════════════════════════════════════════ */

.ui-skeleton {
  background:    var(--bg-elevated);
  border-radius: var(--radius-md);
  animation:     ui-shimmer 1.4s ease-in-out infinite;
  display:       block;
}

@keyframes ui-shimmer {
  0%   { opacity: 0.5; }
  50%  { opacity: 1.0; }
  100% { opacity: 0.5; }
}

.ui-skeleton-text  { height: 14px; width: 100%; margin-bottom: var(--space-2); }
.ui-skeleton-title { height: 20px; width: 60%; margin-bottom: var(--space-3); }
.ui-skeleton-card  { height: 80px; width: 100%; border-radius: var(--radius-lg); }

.ui-skeleton-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-4);
}


/* ════════════════════════════════════════════════════════════
   TOAST NOTIFICATIONS
════════════════════════════════════════════════════════════ */

.ui-toast-wrap {
  position:       fixed;
  bottom:         var(--space-6);
  right:          var(--space-6);
  z-index:        var(--z-toast);
  display:        flex;
  flex-direction: column;
  gap:            var(--space-3);
  pointer-events: none;
}

.ui-toast {
  display:       flex;
  align-items:   flex-start;
  gap:           var(--space-3);
  min-width:     300px;
  max-width:     420px;
  padding:       var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  border:        1px solid transparent;
  box-shadow:    var(--shadow-xl);
  pointer-events: auto;
  animation:     ui-toast-in 220ms ease both;
  font-size:     0.875rem;
  line-height:   1.5;
}

@keyframes ui-toast-in {
  from { opacity: 0; transform: translateY(12px) scale(0.95); }
  to   { opacity: 1; transform: translateY(0)    scale(1);    }
}

.ui-toast--success { background: var(--bg-surface); border-color: var(--success); color: var(--text-primary); }
.ui-toast--danger  { background: var(--bg-surface); border-color: var(--danger);  color: var(--text-primary); }
.ui-toast--warning { background: var(--bg-surface); border-color: var(--warning); color: var(--text-primary); }
.ui-toast--info    { background: var(--bg-surface); border-color: var(--info);    color: var(--text-primary); }

.ui-toast-icon { flex-shrink: 0; font-size: 1.1rem; margin-top: 1px; }
.ui-toast--success .ui-toast-icon { color: var(--success); }
.ui-toast--danger  .ui-toast-icon { color: var(--danger); }
.ui-toast--warning .ui-toast-icon { color: var(--warning); }
.ui-toast--info    .ui-toast-icon { color: var(--info); }

.ui-toast-body { flex: 1; }
.ui-toast-title { font-weight: 700; margin-bottom: 1px; }
/* The sentence under a toast's title — "Saved", "We couldn't save that". <Toast /> is rendered
   by PlayerLayout and PublicLayout, so this reaches EVERY player and public page, and it is
   read at exactly the moment a golfer is checking whether the thing they just did worked.
   Was 13px. UX audit X02, 2026-09-13. */
.ui-toast-msg   { color: var(--text-secondary); font-size: var(--font-size-sm); }

/* Measured live 24x48 at 390px on 2026-09-15 — exactly half the touch floor, on the dismiss
   control of a banner that PlayerLayout and PublicLayout put over every player and public page.
   app.css's global `button { min-height: 48px }` buys the HEIGHT only; the only min-width:48px
   rules in the app are scoped to table cells and .ui-btn--icon, and this is neither, so nothing
   was ever going to raise the width. */
.ui-toast-dismiss {
  background:      transparent;
  border:          none;
  color:           var(--text-muted);
  cursor:          pointer;
  padding:         2px 4px;
  border-radius:   var(--radius-sm);
  font-size:       1rem;
  line-height:     1;
  flex-shrink:     0;
  min-width:       var(--touch-target-min, 48px);
  display:         flex;
  align-items:     center;
  justify-content: center;
  transition:      color var(--transition-fast);
}

.ui-toast-dismiss:hover { color: var(--text-primary); }


@media (max-width: 480px) {
  .ui-toast-wrap { left: var(--space-4); right: var(--space-4); bottom: var(--space-4); }
  .ui-toast { min-width: 0; }
}


/* ════════════════════════════════════════════════════════════
   DATA TABLE
   Generic table with token-based theming.
════════════════════════════════════════════════════════════ */

.ui-table-wrap {
  overflow-x:    auto;
  border-radius: var(--radius-lg);
  border:        1px solid var(--border-subtle);
  box-shadow:    var(--shadow-sm);
  background:    var(--bg-surface);
  transition:    border-color var(--transition-fast);
}

.ui-table-wrap:hover { border-color: var(--border-default); }

.ui-table {
  width:           100%;
  border-collapse: collapse;
  font-size:       0.875rem;
  color:           var(--text-primary);
}

.ui-table thead th {
  background:     var(--bg-elevated);
  color:          var(--text-secondary);
  font-size:      var(--font-size-sm);
  font-weight:    800;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  padding:        var(--space-2) var(--space-4);
  border-bottom:  1px solid var(--border-subtle);
  white-space:    nowrap;
  text-align:     left;
}

.ui-table tbody td {
  padding:        10px var(--space-4);
  border-bottom:  1px solid var(--border-subtle);
  vertical-align: middle;
}

.ui-table tbody tr:last-child td { border-bottom: none; }

.ui-table tbody tr:hover td { background: rgba(255,255,255,0.03); }


/* ════════════════════════════════════════════════════════════
   FILTER BAR / TOOLBAR
════════════════════════════════════════════════════════════ */

.ui-toolbar {
  display:       flex;
  align-items:   center;
  gap:           var(--space-3);
  flex-wrap:     wrap;
  padding:       var(--space-3) var(--space-4);
  background:    var(--bg-elevated);
  border:        1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  margin-bottom: var(--space-4);
}

.ui-toolbar-search {
  position:  relative;
  flex:      1;
  min-width: 160px;
}

.ui-toolbar-search-icon {
  position:  absolute;
  left:      10px;
  top:       50%;
  transform: translateY(-50%);
  color:     var(--text-muted);
  font-size: 0.875rem;
}

.ui-toolbar-search .ui-input { padding-left: 32px; }


/* ════════════════════════════════════════════════════════════
   MODAL
════════════════════════════════════════════════════════════ */

.ui-overlay {
  position:   fixed;
  inset:      0;
  background: rgba(2,6,23,0.65);
  backdrop-filter: blur(3px);
  z-index:    var(--z-overlay);
  display:    flex;
  align-items: center;
  justify-content: center;
  padding:    var(--space-4);
}

.ui-modal {
  background:     var(--bg-surface);
  border:         1px solid var(--border-default);
  border-radius:  var(--radius-xl);
  box-shadow:     var(--shadow-xl);
  width:          100%;
  max-width:      var(--modal-max-w);
  max-height:     90vh;
  overflow-y:     auto;
  display:        flex;
  flex-direction: column;
  z-index:        var(--z-modal);
  animation:      ui-modal-in 200ms ease both;
}

@keyframes ui-modal-in {
  from { opacity: 0; transform: scale(0.96) translateY(8px); }
  to   { opacity: 1; transform: scale(1)    translateY(0);   }
}

.ui-modal-header {
  display:       flex;
  align-items:   center;
  gap:           var(--space-3);
  padding:       var(--space-5) var(--space-6) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  flex-shrink:   0;
}

.ui-modal-title {
  font-size:   1rem;
  font-weight: 800;
  color:       var(--text-primary);
  margin:      0;
  flex:        1;
  letter-spacing: -0.01em;
}

.ui-modal-body {
  padding: var(--space-5) var(--space-6);
  flex:    1;
}

.ui-modal-footer {
  display:         flex;
  justify-content: flex-end;
  gap:             var(--space-2);
  padding:         var(--space-4) var(--space-6) var(--space-5);
  border-top:      1px solid var(--border-subtle);
  flex-shrink:     0;
}

/* ── Back-compat modal aliases ──────────────────────────────────
   Five legacy league/commissioner dialogs use class names that
   predate the canonical .ui-overlay / .ui-modal-header / -footer
   system: .ui-modal-backdrop, .ui-modal-head, .ui-modal-foot,
   .ui-modal-actions. Those names are defined NOWHERE else, so the
   dialogs rendered with no dimmed/centered backdrop and unstyled
   header/footer — appearing "transparent" because the panel bg
   (--bg-surface) melts into the page. These aliases map the legacy
   names onto the canonical modal styles.
   Consumers (verified — no other component references these names):
   ScorecardsPanel, FinishWeekPanel, PairingsPanel,
   AutoCreateTeamsModal, HandicapHelpModal.
   Because the selectors are otherwise unused, these rules cannot
   regress any currently-working surface. */

/* Backdrop → canonical overlay (all 5 modals) */
.ui-modal-backdrop {
  position:        fixed;
  inset:           0;
  background:      rgba(2,6,23,0.65);
  backdrop-filter: blur(3px);
  z-index:         var(--z-overlay);
  display:         flex;
  align-items:     center;
  justify-content: center;
  padding:         var(--space-4);
}

/* Header → canonical header (AutoCreateTeamsModal, HandicapHelpModal).
   space-between pushes the close button to the right, since these
   modals use .ui-heading-2 rather than the flex:1 .ui-modal-title. */
.ui-modal-head {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             var(--space-3);
  padding:         var(--space-5) var(--space-6) var(--space-4);
  border-bottom:   1px solid var(--border-subtle);
  flex-shrink:     0;
}

/* Footer → canonical footer.
   .ui-modal-foot: AutoCreateTeamsModal, HandicapHelpModal.
   .ui-modal-actions: ScorecardsPanel, FinishWeekPanel, PairingsPanel. */
.ui-modal-foot,
.ui-modal-actions {
  display:         flex;
  align-items:     center;
  justify-content: flex-end;
  gap:             var(--space-2);
  padding:         var(--space-4) var(--space-6) var(--space-5);
  border-top:      1px solid var(--border-subtle);
  flex-shrink:     0;
}

/* The three confirm-dialog panels (ScorecardsPanel, FinishWeekPanel,
   PairingsPanel) place content directly inside .ui-modal with no
   .ui-modal-body wrapper. Give that bare content the same inset the
   canonical .ui-modal-body provides. These selectors match only
   DIRECT children of .ui-modal; the two wrapped modals nest their
   content inside .ui-modal-head/-body/-foot and are unaffected. */
.ui-modal > .ui-heading-3 {
  margin:  0;
  padding: var(--space-5) var(--space-6) var(--space-2);
}
.ui-modal > p,
.ui-modal > .ui-alert,
.ui-modal > .ui-list {
  margin-left:  var(--space-6);
  margin-right: var(--space-6);
}


/* ════════════════════════════════════════════════════════════
   STAT / METRIC CARD
════════════════════════════════════════════════════════════ */

.ui-stat {
  background:    var(--bg-surface);
  border:        1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow:    var(--shadow-sm);
  padding:       var(--space-5) var(--space-6);
  display:       flex;
  flex-direction: column;
  gap:           var(--space-1);
  position:      relative;
  overflow:      hidden;
  transition:    border-color var(--transition-fast),
                 box-shadow   var(--transition-fast),
                 transform    var(--transition-fast);
}

.ui-stat:hover {
  border-color: var(--border-default);
  box-shadow:   var(--shadow-lg);
  transform:    translateY(-1px);
}

.ui-stat-label {
  font-size:      var(--font-size-chip);
  font-weight:    700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color:          var(--text-muted);
}

.ui-stat-value {
  font-size:      1.875rem;
  font-weight:    800;
  color:          var(--text-primary);
  line-height:    1;
  letter-spacing: -0.04em;
}

.ui-stat-delta {
  font-size:   var(--font-size-sm);
  font-weight: 500;
  color:       var(--text-secondary);
}

.ui-stat-icon {
  position:        absolute;
  top:             var(--space-4);
  right:           var(--space-4);
  width:           38px;
  height:          38px;
  border-radius:   var(--radius-md);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       1.1rem;
}

/* Accent top border + icon color variants */
.ui-stat--blue  { border-top: 2px solid var(--brand); }
.ui-stat--green { border-top: 2px solid var(--success); }
.ui-stat--amber { border-top: 2px solid var(--warning); }
.ui-stat--red   { border-top: 2px solid var(--danger); }

.ui-stat--blue  .ui-stat-icon { background: var(--brand-soft);   color: var(--b9-primary-text); }
.ui-stat--green .ui-stat-icon { background: var(--success-soft); color: var(--success); }
.ui-stat--amber .ui-stat-icon { background: var(--warning-soft); color: var(--warning); }
.ui-stat--red   .ui-stat-icon { background: var(--danger-soft);  color: var(--danger); }


/* ════════════════════════════════════════════════════════════
   LAYOUT GRIDS
════════════════════════════════════════════════════════════ */

.ui-grid-stats {
  display:               grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap:                   var(--space-4);
}

.ui-grid-cards {
  display:               grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap:                   var(--space-4);
}

@media (max-width: 640px) {
  .ui-grid-stats { grid-template-columns: 1fr 1fr; }
  .ui-grid-cards { grid-template-columns: 1fr; }
}

@media (max-width: 400px) {
  .ui-grid-stats { grid-template-columns: 1fr; }
}


/* ════════════════════════════════════════════════════════════
   SECTION HEADER
════════════════════════════════════════════════════════════ */

.ui-section-header {
  display:         flex;
  align-items:     flex-start;
  justify-content: space-between;
  gap:             var(--space-4);
  flex-wrap:       wrap;
  margin-bottom:   var(--space-5);
}
.ui-section-title {
  font-size:      1rem;
  font-weight:    800;
  color:          var(--text-primary);
  letter-spacing: -0.02em;
  margin:         0 0 var(--space-1);
  line-height:    1.2;
}
.ui-section-sub {
  font-size:   var(--font-size-sm);
  color:       var(--text-secondary);
  margin:      0;
  line-height: 1.55;
}
.ui-section-actions {
  display:     flex;
  align-items: center;
  gap:         var(--space-2);
  flex-shrink: 0;
}


/* ════════════════════════════════════════════════════════════
   CONTENT CONTAINER
════════════════════════════════════════════════════════════ */

.ui-container {
  width:     100%;
  max-width: 1280px;
  margin:    0 auto;
  padding:   0 var(--space-6);
}
.ui-container--narrow { max-width: 720px; }
.ui-container--mid    { max-width: 960px; }
.ui-container--wide   { max-width: 1440px; }
@media (max-width: 640px) { .ui-container { padding: 0 var(--space-4); } }


/* ════════════════════════════════════════════════════════════
   BUTTON GROUP
════════════════════════════════════════════════════════════ */

.ui-btn-group {
  display:       inline-flex;
  align-items:   stretch;
  gap:           1px;
  background:    var(--border-subtle);
  border-radius: var(--radius-md);
  overflow:      hidden;
}
.ui-btn-group .ui-btn             { border-radius: 0; border: none; }
.ui-btn-group .ui-btn:first-child { border-radius: var(--radius-md) 0 0 var(--radius-md); }
.ui-btn-group .ui-btn:last-child  { border-radius: 0 var(--radius-md) var(--radius-md) 0; }
.ui-btn-group .ui-btn--full       { flex: 1; }


/* ════════════════════════════════════════════════════════════
   ACTION CARD
════════════════════════════════════════════════════════════ */

.ui-action-card {
  background:    var(--bg-surface);
  border:        1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow:    var(--shadow-sm);
  padding:       var(--space-4) var(--space-5);
  display:       flex;
  align-items:   flex-start;
  gap:           var(--space-4);
  transition:    border-color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
}
.ui-action-card--hoverable           { cursor: pointer; }
.ui-action-card--hoverable:hover     { border-color: var(--border-default); box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.ui-action-card-icon {
  flex-shrink: 0; width: 40px; height: 40px; border-radius: var(--radius-md);
  background: var(--brand-soft); color: var(--brand-text);
  display: flex; align-items: center; justify-content: center; font-size: 1.125rem;
}
.ui-action-card-body    { flex: 1; min-width: 0; }
.ui-action-card-title   { font-size: 0.9375rem; font-weight: 700; color: var(--text-primary); letter-spacing: -0.01em; }
.ui-action-card-desc    { font-size: var(--font-size-sm); color: var(--text-secondary); margin: var(--space-1) 0 0; line-height: 1.5; }
.ui-action-card-arrow {
  flex-shrink: 0; width: 32px; height: 32px; border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); text-decoration: none; align-self: center;
  transition: color var(--transition-fast), background var(--transition-fast);
}
.ui-action-card-arrow:hover  { color: var(--brand-text); background: var(--brand-soft); }
.ui-action-card-actions      { flex-shrink: 0; align-self: center; }


/* ════════════════════════════════════════════════════════════
   INFO CARD
════════════════════════════════════════════════════════════ */

.ui-info-card {
  background: var(--bg-surface); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm);
}
.ui-info-card-header {
  padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-subtle);
  display: flex; align-items: center; gap: var(--space-3);
}
.ui-info-card-icon {
  flex-shrink: 0; width: 36px; height: 36px; border-radius: var(--radius-md);
  background: var(--bg-elevated); color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
}
.ui-info-card-meta  { flex: 1; min-width: 0; }
.ui-info-card-title { font-size: 0.9375rem; font-weight: 700; color: var(--text-primary); margin: 0; }
.ui-info-card-sub   { font-size: var(--font-size-sm); color: var(--text-muted); margin: 2px 0 0; }
.ui-info-card-body  { padding: var(--space-4) var(--space-5); }


/* ════════════════════════════════════════════════════════════
   ENTITY LIST ITEM
════════════════════════════════════════════════════════════ */

.ui-entity-item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  transition: background var(--transition-fast);
}
.ui-entity-item:last-child          { border-bottom: none; }
.ui-entity-item--clickable          { cursor: pointer; }
.ui-entity-item--clickable:hover    { background: rgba(255,255,255,0.025); }
.ui-entity-icon {
  flex-shrink: 0; width: 36px; height: 36px; border-radius: var(--radius-md);
  background: var(--bg-elevated); color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
}
.ui-entity-main  { flex: 1; min-width: 0; }
.ui-entity-title { font-size: 0.875rem; font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-entity-meta  { font-size: var(--font-size-sm); color: var(--text-muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-entity-aside { flex-shrink: 0; text-align: right; }
.ui-entity-actions { flex-shrink: 0; display: flex; align-items: center; gap: var(--space-1); }


/* ════════════════════════════════════════════════════════════
   KEY-VALUE LIST
════════════════════════════════════════════════════════════ */

.ui-kv-list { display: flex; flex-direction: column; gap: var(--space-2); }
.ui-kv-item { display: flex; align-items: baseline; gap: var(--space-2); font-size: 0.875rem; flex-wrap: wrap; }
.ui-kv-key  { font-size: var(--font-size-sm); font-weight: 600; color: var(--text-muted); min-width: 120px; flex-shrink: 0; }
.ui-kv-value { color: var(--text-primary); flex: 1; }
.ui-kv-list--grid { display: grid; grid-template-columns: auto 1fr; column-gap: var(--space-5); row-gap: var(--space-2); align-items: baseline; }
.ui-kv-list--grid .ui-kv-item { display: contents; }


/* ════════════════════════════════════════════════════════════
   TIMELINE
════════════════════════════════════════════════════════════ */

.ui-timeline { display: flex; flex-direction: column; }
.ui-timeline-item { display: flex; gap: var(--space-4); position: relative; padding-bottom: var(--space-5); }
.ui-timeline-item:last-child { padding-bottom: 0; }
.ui-timeline-item:not(:last-child)::before {
  content: ''; position: absolute; left: 17px; top: 36px; bottom: 0; width: 2px; background: var(--border-subtle);
}
.ui-timeline-icon {
  flex-shrink: 0; width: 36px; height: 36px; border-radius: var(--radius-full);
  background: var(--bg-elevated); border: 2px solid var(--border-subtle);
  color: var(--text-secondary); display: flex; align-items: center; justify-content: center; font-size: 0.9rem; z-index: 1;
}
.ui-timeline-icon--success { background: var(--success-soft); border-color: var(--success); color: var(--success); }
.ui-timeline-icon--warning { background: var(--warning-soft); border-color: var(--warning); color: var(--warning); }
.ui-timeline-icon--danger  { background: var(--danger-soft);  border-color: var(--danger);  color: var(--danger);  }
.ui-timeline-icon--brand   { background: var(--brand-soft);   border-color: var(--brand);   color: var(--brand-text); }
.ui-timeline-content { flex: 1; min-width: 0; padding-top: var(--space-1); }
.ui-timeline-title { font-size: 0.875rem; font-weight: 600; color: var(--text-primary); }
.ui-timeline-desc  { font-size: var(--font-size-sm); color: var(--text-secondary); margin-top: var(--space-1); line-height: 1.5; }
.ui-timeline-time  { font-size: var(--font-size-sm); color: var(--text-muted); margin-top: var(--space-1); font-variant-numeric: tabular-nums; }


/* ════════════════════════════════════════════════════════════
   BREADCRUMBS
════════════════════════════════════════════════════════════ */

.ui-breadcrumbs { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-1); font-size: var(--font-size-sm); color: var(--text-muted); margin-bottom: var(--space-3); }
.ui-bc-item { color: var(--text-muted); text-decoration: none; transition: color var(--transition-fast); white-space: nowrap; }
.ui-bc-item:hover      { color: var(--text-primary); }
.ui-bc-item--current   { color: var(--text-secondary); font-weight: 500; }
/* --border-default is a DIVIDER tint (rgba(255,255,255,0.10)); as writing it measured 1.23:1 on the
   page and 1.32:1 on an elevated surface — the separator was not subtle, it was absent, so the
   breadcrumb lost its structure. --text-muted is what .ui-breadcrumbs and .ui-bc-item already use.
   Found by BackgroundTintTokensAreNotUsedAsTextGuardTests while fixing the same bug elsewhere. */
.ui-bc-sep             { color: var(--text-muted); font-size: var(--font-size-chip); user-select: none; }


/* ════════════════════════════════════════════════════════════
   CONTEXT HEADER
════════════════════════════════════════════════════════════ */

.ui-context-header {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  background: var(--bg-elevated); border-bottom: 1px solid var(--border-subtle); min-height: 52px;
}
.ui-context-icon {
  flex-shrink: 0; width: 36px; height: 36px; border-radius: var(--radius-md);
  background: var(--brand-soft); color: var(--brand-text);
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
}
.ui-context-info    { flex: 1; min-width: 0; }
.ui-context-title   { font-size: 0.9375rem; font-weight: 700; color: var(--text-primary); letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-context-sub     { font-size: var(--font-size-sm); color: var(--text-muted); margin-top: 1px; }
.ui-context-actions { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }


/* ════════════════════════════════════════════════════════════
   STATE PAGES
════════════════════════════════════════════════════════════ */

.ui-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: var(--space-16) var(--space-8); min-height: 360px;
}
.ui-state--compact { padding: var(--space-10) var(--space-6); min-height: 240px; }
.ui-state-icon {
  width: 72px; height: 72px; border-radius: var(--radius-full);
  display: flex; align-items: center; justify-content: center; font-size: 2rem; margin-bottom: var(--space-5);
}
.ui-state-icon--error   { background: var(--danger-soft);  color: var(--danger);     }
.ui-state-icon--success { background: var(--success-soft); color: var(--success);    }
.ui-state-icon--warning { background: var(--warning-soft); color: var(--warning);    }
.ui-state-icon--info    { background: var(--info-soft);    color: var(--info);       }
.ui-state-icon--neutral { background: var(--bg-elevated);  color: var(--text-muted); }
.ui-state-icon--brand   { background: var(--brand-soft);   color: var(--brand-text); }
.ui-state-title { font-size: 1.25rem; font-weight: 800; color: var(--text-primary); letter-spacing: -0.025em; margin: 0 0 var(--space-2); }
.ui-state-desc  { font-size: 0.9rem; color: var(--text-secondary); max-width: 440px; line-height: 1.65; margin: 0 auto var(--space-6); }
.ui-state-actions { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; justify-content: center; }


/* ════════════════════════════════════════════════════════════
   FORM CHECKBOX & RADIO
════════════════════════════════════════════════════════════ */

.ui-check { display: flex; align-items: flex-start; gap: var(--space-3); cursor: pointer; font-size: 0.875rem; line-height: 1.4; }
.ui-check-input {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; border: 2px solid var(--border-default); border-radius: var(--radius-sm);
  background: transparent; cursor: pointer; flex-shrink: 0; margin-top: 2px;
  transition: border-color var(--transition-fast), background var(--transition-fast);
  position: relative; display: inline-flex; align-items: center; justify-content: center;
}
.ui-check-input:checked              { background: var(--brand); border-color: var(--brand); }
.ui-check-input:checked::after       { content: ''; width: 5px; height: 9px; border: 2px solid #fff; border-top: none; border-left: none; transform: rotate(42deg) translate(0,-1px); display: block; }
.ui-check-input:focus-visible        { outline: 2px solid var(--brand); outline-offset: 2px; }
.ui-check-label                      { color: var(--text-primary); flex: 1; }
.ui-check-hint                       { display: block; color: var(--text-muted); font-size: var(--font-size-sm); margin-top: 2px; }

.ui-radio { display: flex; align-items: flex-start; gap: var(--space-3); cursor: pointer; font-size: 0.875rem; line-height: 1.4; }
.ui-radio-input {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; border: 2px solid var(--border-default); border-radius: 50%;
  background: transparent; cursor: pointer; flex-shrink: 0; margin-top: 2px;
  transition: border-color var(--transition-fast), background var(--transition-fast); position: relative;
}
.ui-radio-input:checked::after { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--brand); position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); display: block; }
.ui-radio-input:checked        { border-color: var(--brand); background: var(--brand-soft); }
.ui-radio-input:focus-visible  { outline: 2px solid var(--brand); outline-offset: 2px; }
.ui-radio-group         { display: flex; flex-direction: column; gap: var(--space-3); }
.ui-radio-group--inline { flex-direction: row; flex-wrap: wrap; gap: var(--space-4); }


/* ════════════════════════════════════════════════════════════
   BADGE DOT  (used inside StatusBadge)
════════════════════════════════════════════════════════════ */

.ui-badge-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; display: inline-block; }


/* ════════════════════════════════════════════════════════════
   INLINE VALIDATION MESSAGE
════════════════════════════════════════════════════════════ */

.ui-validation-msg          { font-size: var(--font-size-sm); display: flex; align-items: center; gap: var(--space-1); padding: 2px 0; }
.ui-validation-msg--error   { color: var(--danger-text);  }
.ui-validation-msg--success { color: var(--success-text); }
.ui-validation-msg--hint    { color: var(--text-muted);   }


/* ════════════════════════════════════════════════════════════
   METRIC TILE  (bolder KPI variant)
════════════════════════════════════════════════════════════ */

.ui-metric         { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-5) var(--space-6); }
.ui-metric-value   { font-size: 2.5rem; font-weight: 900; color: var(--text-primary); line-height: 1; letter-spacing: -0.05em; font-variant-numeric: tabular-nums; }
.ui-metric-label   { font-size: var(--font-size-chip); font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em; color: var(--text-muted); }
.ui-metric-subtext { font-size: var(--font-size-sm); color: var(--text-secondary); margin-top: var(--space-1); }


/* ════════════════════════════════════════════════════════════
   ADMIN COMMAND CENTER LAYOUT
════════════════════════════════════════════════════════════ */

.admin-cc-layout   { display: flex; flex-direction: column; }
.admin-cc-breadcrumb { padding: var(--space-3) var(--space-5); }
.admin-cc-header   { position: sticky; top: 0; z-index: 10; }
.admin-cc-tabs     { padding: 0 var(--space-5); overflow-x: auto; }
.admin-cc-content  { flex: 1; padding: var(--space-5); }

/* Tab bar  */
.ui-tab-bar { display: flex; gap: 2px; border-bottom: 1px solid var(--border-subtle); }
.ui-tab {
  padding: var(--space-2) var(--space-4); font-size: 0.875rem; font-weight: 600;
  color: var(--text-secondary); border: none; background: transparent; cursor: pointer;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color var(--transition-fast), border-color var(--transition-fast);
  white-space: nowrap; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.ui-tab:hover      { color: var(--text-primary); background: var(--bg-elevated); }
.ui-tab--active    { color: var(--brand-text); border-bottom-color: var(--brand); }


/* ════════════════════════════════════════════════════════════
   PUBLIC EVENT HERO
════════════════════════════════════════════════════════════ */

.public-event-hero { background: linear-gradient(160deg, var(--bg-base) 0%, var(--bg-surface) 100%); }
.public-event-hero-head {
  max-width: 800px; margin: 0 auto; text-align: center;
  padding: var(--space-16) var(--space-6) var(--space-10);
}
.public-event-hero-title {
  font-size: clamp(1.75rem, 5vw, 3rem); font-weight: 900; color: var(--text-primary);
  letter-spacing: -0.04em; margin: 0 0 var(--space-3); line-height: 1.1;
}
.public-event-hero-meta {
  display: flex; align-items: center; justify-content: center; gap: var(--space-4);
  flex-wrap: wrap; font-size: 0.9375rem; color: var(--text-secondary);
}
.public-event-hero-meta span { display: flex; align-items: center; gap: var(--space-2); }
.public-event-hero-body      { padding: 0 var(--space-6) var(--space-10); max-width: 1100px; margin: 0 auto; }

/* Live pulse animation */
@keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:.35; } }


/* ════════════════════════════════════════════════════════════
   BOOTSTRAP TABLE — APP-WIDE DARK-THEME READABILITY FIX
   Bootstrap's .table resolves cell text color through a 3-deep
   CSS-variable chain: --bs-table-color-state → -type → -color.
   In dark contexts the chain can fail to inherit --bs-body-color
   correctly, producing near-black text on dark card backgrounds.
   This block explicitly pins all tbody/tfoot cells to our design
   tokens so EVERY Bootstrap table in the app is readable on both
   themes without per-component workarounds.
════════════════════════════════════════════════════════════ */

/* Tbody and tfoot cells — explicit token, not variable chain */
.table > tbody > * > *,
.table > tfoot > * > * {
    color: var(--text-primary);
    border-bottom-color: var(--border-subtle);
}

/* Thead without an explicit .table-dark — muted label style */
.table > thead:not(.table-dark) > * > th,
.table > thead:not(.table-dark) > * > td {
    color: var(--text-secondary);
    background-color: var(--bg-elevated);
    border-bottom-color: var(--border-subtle);
}

/* .text-muted inside any table cell stays secondary */
.table .text-muted {
    color: var(--text-secondary) !important;
}

/* Subtle row hover — makes long lists scannable */
.table > tbody > tr:hover > * {
    background-color: rgba(255, 255, 255, 0.04) !important;
}

/* Light-mode: invert hover tint direction */
html[data-theme="light"] .table > tbody > tr:hover > * {
    background-color: rgba(0, 0, 0, 0.03) !important;
}

/* ── Entity-table wrapper: horizontal scroll containment (mobile) ──────
   Several pages wrap wide data tables in .etable-wrap, but Blazor CSS
   isolation means a page that declares the class WITHOUT styling it in its
   own .razor.css gets an unstyled div — and the table then widens the whole
   page on phones (seen on /admin/admins, /admin/users, /settings/{id}/audit).
   This global rule makes every .etable-wrap a sanctioned scroll container,
   matching what the pages that do style it already do. */
.etable-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
