/* ==========================================================================
   TrainerPlatform - Component Library
   --------------------------------------------------------------------------
   Presentational primitives shared across the application. Every rule is
   token-driven, so all of it themes automatically.
   ========================================================================== */

/* ======================================================================
   LAYOUT PRIMITIVES
   ====================================================================== */
.tp-stack        { display: flex; flex-direction: column; gap: var(--tp-space-4); }
.tp-stack--tight { gap: var(--tp-space-2); }
.tp-stack--loose { gap: var(--tp-space-6); }

.tp-row {
  display: flex;
  align-items: center;
  gap: var(--tp-space-3);
  flex-wrap: wrap;
}

.tp-row--between { justify-content: space-between; }
.tp-row--end     { justify-content: flex-end; }
.tp-row--top     { align-items: flex-start; }

/* Auto-fitting grid - no breakpoint maths required. */
.tp-grid {
  display: grid;
  gap: var(--tp-space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}

.tp-grid--wide { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.tp-grid--narrow { grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); }

.tp-divider {
  height: var(--tp-border-thin);
  background: var(--tp-border-subtle);
  border: 0;
  margin: 0;
}

/* ======================================================================
   SURFACE / CARD
   ====================================================================== */
.tp-surface {
  background: var(--tp-bg-surface);
  border: var(--tp-border-thin) solid var(--tp-border-subtle);
  border-radius: var(--tp-radius-lg);
}

.tp-card {
  display: flex;
  flex-direction: column;
  background: var(--tp-bg-surface);
  border: var(--tp-border-thin) solid var(--tp-border-subtle);
  border-radius: var(--tp-radius-lg);
  box-shadow: var(--tp-shadow-xs);
  overflow: hidden;
}

.tp-card--flat        { box-shadow: none; }
.tp-card--raised     { box-shadow: var(--tp-shadow-md); }
.tp-card--borderless { border-color: transparent; }

/* An interactive card reacts; a static one must not pretend to. */
.tp-card--interactive {
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition:
    border-color var(--tp-duration-fast) var(--tp-ease-standard),
    box-shadow var(--tp-duration-base) var(--tp-ease-standard),
    transform var(--tp-duration-base) var(--tp-ease-standard);
}

.tp-card--interactive:hover {
  border-color: var(--tp-border-default);
  box-shadow: var(--tp-shadow-md);
  transform: translateY(-1px);
}

.tp-card--interactive:active { transform: translateY(0); }

.tp-card__header {
  display: flex;
  align-items: flex-start;
  gap: var(--tp-space-3);
  padding: var(--tp-space-4) var(--tp-space-5);
  border-bottom: var(--tp-border-thin) solid var(--tp-border-subtle);
}

.tp-card__header-text { flex: 1 1 auto; min-width: 0; }

.tp-card__title {
  font-size: var(--tp-text-base);
  font-weight: var(--tp-weight-semibold);
  color: var(--tp-text-primary);
  line-height: var(--tp-leading-snug);
}

.tp-card__subtitle {
  margin-top: var(--tp-space-1);
  font-size: var(--tp-text-sm);
  color: var(--tp-text-secondary);
}

.tp-card__actions { flex: 0 0 auto; display: flex; gap: var(--tp-space-2); }

.tp-card__body { padding: var(--tp-space-5); flex: 1 1 auto; min-width: 0; }
.tp-card__body--flush { padding: 0; }

.tp-card__footer {
  display: flex;
  align-items: center;
  gap: var(--tp-space-3);
  padding: var(--tp-space-3) var(--tp-space-5);
  border-top: var(--tp-border-thin) solid var(--tp-border-subtle);
  background: var(--tp-bg-surface-alt);
}

/* ======================================================================
   STAT CARD - a labelled metric. Value is the loudest element.
   ====================================================================== */
.tp-stat { display: flex; flex-direction: column; gap: var(--tp-space-2); }

.tp-stat__label {
  font-size: var(--tp-text-2xs);
  font-weight: var(--tp-weight-semibold);
  letter-spacing: var(--tp-tracking-caps);
  text-transform: uppercase;
  color: var(--tp-text-muted);
}

.tp-stat__value {
  font-size: var(--tp-text-3xl);
  font-weight: var(--tp-weight-semibold);
  line-height: var(--tp-leading-none);
  letter-spacing: var(--tp-tracking-tight);
  color: var(--tp-text-primary);
  font-variant-numeric: tabular-nums;
}

.tp-stat__meta { font-size: var(--tp-text-sm); color: var(--tp-text-secondary); }

.tp-stat__delta {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  font-size: var(--tp-text-sm);
  font-weight: var(--tp-weight-medium);
  font-variant-numeric: tabular-nums;
}

.tp-stat__delta--up   { color: var(--tp-success); }
.tp-stat__delta--down { color: var(--tp-danger); }
.tp-stat__delta--flat { color: var(--tp-text-muted); }

/* ======================================================================
   BUTTONS
   ====================================================================== */
.tp-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--tp-space-2);
  min-height: 2.5rem;
  padding: 0 var(--tp-space-4);
  border: var(--tp-border-thin) solid transparent;
  border-radius: var(--tp-radius-md);
  font-size: var(--tp-text-sm);
  font-weight: var(--tp-weight-semibold);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  transition:
    background-color var(--tp-duration-fast) var(--tp-ease-standard),
    border-color var(--tp-duration-fast) var(--tp-ease-standard),
    color var(--tp-duration-fast) var(--tp-ease-standard),
    box-shadow var(--tp-duration-fast) var(--tp-ease-standard);
}

.tp-btn:disabled, .tp-btn[aria-disabled="true"] { opacity: 0.55; pointer-events: none; }

.tp-btn__icon { width: 1.125rem; height: 1.125rem; flex: 0 0 auto; }

/* --- sizes --- */
.tp-btn--sm { min-height: 2rem;   padding: 0 var(--tp-space-3); font-size: var(--tp-text-xs); }
.tp-btn--lg { min-height: 3rem;   padding: 0 var(--tp-space-5); font-size: var(--tp-text-base); }
.tp-btn--block { width: 100%; }

/* Icon-only: keep it square and give it an accessible name via aria-label. */
.tp-btn--icon { padding: 0; width: 2.5rem; min-height: 2.5rem; }
.tp-btn--icon.tp-btn--sm { width: 2rem; min-height: 2rem; }

/* --- variants --- */
.tp-btn--primary {
  background: var(--tp-brand);
  color: var(--tp-text-on-brand);
  box-shadow: var(--tp-shadow-xs);
}
.tp-btn--primary:hover  { background: var(--tp-brand-hover); color: var(--tp-text-on-brand); }
.tp-btn--primary:active { background: var(--tp-brand-active); box-shadow: none; }

.tp-btn--secondary {
  background: var(--tp-bg-surface);
  border-color: var(--tp-border-default);
  color: var(--tp-text-primary);
}
.tp-btn--secondary:hover  { background: var(--tp-bg-hover); border-color: var(--tp-border-strong); color: var(--tp-text-primary); }
.tp-btn--secondary:active { background: var(--tp-bg-active); }

.tp-btn--ghost { background: transparent; color: var(--tp-text-secondary); }
.tp-btn--ghost:hover  { background: var(--tp-bg-hover); color: var(--tp-text-primary); }
.tp-btn--ghost:active { background: var(--tp-bg-active); }

.tp-btn--danger { background: var(--tp-danger); color: #fff; }
.tp-btn--danger:hover  { background: var(--tp-danger-700); color: #fff; }

.tp-btn--link {
  background: transparent;
  color: var(--tp-text-link);
  min-height: auto;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.tp-btn--link:hover { color: var(--tp-brand-hover); }

/* ======================================================================
   BADGE / PILL
   ====================================================================== */
.tp-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem var(--tp-space-2);
  border: var(--tp-border-thin) solid transparent;
  border-radius: var(--tp-radius-pill);
  font-size: var(--tp-text-xs);
  font-weight: var(--tp-weight-semibold);
  line-height: 1.4;
  white-space: nowrap;
}

.tp-badge--neutral { background: var(--tp-bg-sunken);       color: var(--tp-text-secondary); border-color: var(--tp-border-subtle); }
.tp-badge--brand   { background: var(--tp-brand-subtle);    color: var(--tp-brand-on-subtle); }
.tp-badge--success { background: var(--tp-success-subtle);  color: var(--tp-success); }
.tp-badge--warning { background: var(--tp-warning-subtle);  color: var(--tp-warning-700); }
.tp-badge--danger  { background: var(--tp-danger-subtle);   color: var(--tp-danger); }
.tp-badge--info    { background: var(--tp-info-subtle);     color: var(--tp-info-700); }

/* A status dot carries meaning by shape as well as colour. */
.tp-badge__dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
}

/* ======================================================================
   ALERT
   ====================================================================== */
.tp-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--tp-space-3);
  padding: var(--tp-space-4);
  border: var(--tp-border-thin) solid transparent;
  border-radius: var(--tp-radius-md);
  font-size: var(--tp-text-sm);
  line-height: var(--tp-leading-snug);
}

.tp-alert__icon { width: 1.25rem; height: 1.25rem; flex: 0 0 auto; margin-top: 0.05rem; }
.tp-alert__content { flex: 1 1 auto; min-width: 0; }
.tp-alert__title { font-weight: var(--tp-weight-semibold); margin-bottom: var(--tp-space-1); }

.tp-alert--info    { background: var(--tp-info-subtle);    color: var(--tp-text-primary); border-color: color-mix(in srgb, var(--tp-info) 35%, transparent); }
.tp-alert--success { background: var(--tp-success-subtle); color: var(--tp-text-primary); border-color: color-mix(in srgb, var(--tp-success) 35%, transparent); }
.tp-alert--warning { background: var(--tp-warning-subtle); color: var(--tp-text-primary); border-color: color-mix(in srgb, var(--tp-warning) 40%, transparent); }
.tp-alert--danger  { background: var(--tp-danger-subtle);  color: var(--tp-text-primary); border-color: color-mix(in srgb, var(--tp-danger) 35%, transparent); }

.tp-alert__icon--info    { color: var(--tp-info); }
.tp-alert__icon--success { color: var(--tp-success); }
.tp-alert__icon--warning { color: var(--tp-warning-700); }
.tp-alert__icon--danger  { color: var(--tp-danger); }

/* ======================================================================
   FORMS
   ====================================================================== */
.tp-field { display: flex; flex-direction: column; gap: var(--tp-space-2); }

.tp-field__label {
  font-size: var(--tp-text-sm);
  font-weight: var(--tp-weight-medium);
  color: var(--tp-text-primary);
}

.tp-field__required {
  color: var(--tp-danger);
  margin-left: 0.15rem;
}

.tp-field__hint { font-size: var(--tp-text-xs); color: var(--tp-text-muted); line-height: var(--tp-leading-snug); }

.tp-field__error {
  font-size: var(--tp-text-xs);
  font-weight: var(--tp-weight-medium);
  color: var(--tp-danger);
  line-height: var(--tp-leading-snug);
}

/* Inputs. `.tp-input` is applied to Blazor's InputText/InputNumber/etc. */
.tp-input,
.tp-select,
.tp-textarea {
  width: 100%;
  min-height: 2.5rem;
  padding: var(--tp-space-2) var(--tp-space-3);
  background: var(--tp-bg-surface);
  color: var(--tp-text-primary);
  border: var(--tp-border-thin) solid var(--tp-border-default);
  border-radius: var(--tp-radius-md);
  font-size: var(--tp-text-sm);
  transition:
    border-color var(--tp-duration-fast) var(--tp-ease-standard),
    box-shadow var(--tp-duration-fast) var(--tp-ease-standard);
}

.tp-textarea { min-height: 6rem; line-height: var(--tp-leading-normal); }

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

.tp-input:hover, .tp-select:hover, .tp-textarea:hover { border-color: var(--tp-border-strong); }

.tp-input:focus-visible,
.tp-select:focus-visible,
.tp-textarea:focus-visible {
  outline: none;
  border-color: var(--tp-brand);
  box-shadow: 0 0 0 var(--tp-focus-ring-width) var(--tp-focus-ring);
}

.tp-input:disabled, .tp-select:disabled, .tp-textarea:disabled {
  background: var(--tp-bg-sunken);
  color: var(--tp-text-muted);
}

/*
  Blazor's EditForm adds `modified`/`invalid`/`valid` classes. Only surface the
  error state once the field has actually been touched.
*/
.tp-input.invalid, .tp-select.invalid, .tp-textarea.invalid,
.tp-input[aria-invalid="true"] {
  border-color: var(--tp-danger);
}

.tp-input.invalid:focus-visible,
.tp-textarea.invalid:focus-visible {
  box-shadow: 0 0 0 var(--tp-focus-ring-width) color-mix(in srgb, var(--tp-danger) 35%, transparent);
}

/* Blazor's ValidationMessage renders this class. */
.validation-message {
  font-size: var(--tp-text-xs);
  font-weight: var(--tp-weight-medium);
  color: var(--tp-danger);
}

.validation-errors { margin: 0; padding-left: var(--tp-space-5); }

/* Checkbox / radio rows */
.tp-check {
  display: flex;
  align-items: flex-start;
  gap: var(--tp-space-3);
  font-size: var(--tp-text-sm);
  color: var(--tp-text-primary);
}

.tp-check__input {
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.15rem;
  flex: 0 0 auto;
  accent-color: var(--tp-brand);
}

/* A grouped form region with a heading. */
.tp-fieldset { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--tp-space-4); }
.tp-fieldset__legend {
  padding: 0;
  font-size: var(--tp-text-base);
  font-weight: var(--tp-weight-semibold);
  color: var(--tp-text-primary);
}

/* ======================================================================
   DIALOG - Blazor-state driven, no JS and no Bootstrap JS bundle.
   ====================================================================== */
.tp-dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--tp-z-dialog);
  display: grid;
  place-items: center;
  padding: var(--tp-space-4);
  background: rgb(2 6 23 / 0.55);
  backdrop-filter: blur(3px);
  animation: tp-fade-in var(--tp-duration-base) var(--tp-ease-standard);
}

.tp-dialog {
  width: 100%;
  max-width: 32rem;
  max-height: calc(100dvh - var(--tp-space-8));
  display: flex;
  flex-direction: column;
  background: var(--tp-bg-surface);
  border: var(--tp-border-thin) solid var(--tp-border-subtle);
  border-radius: var(--tp-radius-xl);
  box-shadow: var(--tp-shadow-xl);
  animation: tp-dialog-in var(--tp-duration-base) var(--tp-ease-emphasis);
  overflow: hidden;
}

.tp-dialog--sm { max-width: 24rem; }
.tp-dialog--lg { max-width: 48rem; }

.tp-dialog__header {
  display: flex;
  align-items: flex-start;
  gap: var(--tp-space-3);
  padding: var(--tp-space-5) var(--tp-space-5) var(--tp-space-3);
}

.tp-dialog__title {
  flex: 1 1 auto;
  font-size: var(--tp-text-lg);
  font-weight: var(--tp-weight-semibold);
  color: var(--tp-text-primary);
  min-width: 0;
}

.tp-dialog__body {
  padding: 0 var(--tp-space-5) var(--tp-space-5);
  overflow-y: auto;
  flex: 1 1 auto;
  color: var(--tp-text-secondary);
  font-size: var(--tp-text-sm);
  line-height: var(--tp-leading-normal);
}

.tp-dialog__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--tp-space-2);
  padding: var(--tp-space-4) var(--tp-space-5);
  border-top: var(--tp-border-thin) solid var(--tp-border-subtle);
  background: var(--tp-bg-surface-alt);
}

/* On small screens a dialog reads better docked to the bottom. */
@media (max-width: 36rem) {
  .tp-dialog-backdrop { place-items: end center; padding: 0; }
  .tp-dialog {
    max-width: none;
    border-radius: var(--tp-radius-xl) var(--tp-radius-xl) 0 0;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    animation: tp-sheet-in var(--tp-duration-base) var(--tp-ease-emphasis);
  }
}

@keyframes tp-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes tp-dialog-in {
  from { opacity: 0; transform: translateY(0.75rem) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes tp-sheet-in {
  from { transform: translateY(100%); }
  to   { transform: none; }
}

/* ======================================================================
   EMPTY STATE
   ====================================================================== */
.tp-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--tp-space-3);
  padding: var(--tp-space-8) var(--tp-space-5);
}

.tp-empty__icon {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--tp-radius-pill);
  background: var(--tp-bg-sunken);
  color: var(--tp-text-muted);
}

.tp-empty__title { font-size: var(--tp-text-base); font-weight: var(--tp-weight-semibold); color: var(--tp-text-primary); }
.tp-empty__description { font-size: var(--tp-text-sm); color: var(--tp-text-secondary); max-width: 34ch; text-wrap: pretty; }

/* ======================================================================
   SPINNER
   ====================================================================== */
.tp-spinner {
  display: inline-block;
  width: 1.1rem;
  height: 1.1rem;
  border: var(--tp-border-thick) solid color-mix(in srgb, currentColor 25%, transparent);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: tp-spin 650ms linear infinite;
}

.tp-spinner--lg { width: 2rem; height: 2rem; }

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

/* ======================================================================
   AVATAR
   ====================================================================== */
.tp-avatar {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--tp-brand-subtle);
  color: var(--tp-brand-on-subtle);
  font-size: var(--tp-text-xs);
  font-weight: var(--tp-weight-semibold);
  text-transform: uppercase;
  overflow: hidden;
}

.tp-avatar--sm { width: 1.5rem; height: 1.5rem; font-size: var(--tp-text-2xs); }
.tp-avatar--lg { width: 2.75rem; height: 2.75rem; font-size: var(--tp-text-sm); }

/* ======================================================================
   USER MENU (sidebar footer / topbar)
   ====================================================================== */
.tp-user-tile {
  display: flex;
  align-items: center;
  gap: var(--tp-space-3);
  width: 100%;
  padding: var(--tp-space-2);
  border: var(--tp-border-thin) solid transparent;
  border-radius: var(--tp-radius-md);
  background: transparent;
  color: var(--tp-text-primary);
  text-align: left;
  text-decoration: none;
  transition: background-color var(--tp-duration-fast) var(--tp-ease-standard);
}

.tp-user-tile:hover { background: var(--tp-bg-hover); color: var(--tp-text-primary); }

.tp-user-tile__text { min-width: 0; flex: 1 1 auto; }

.tp-user-tile__name {
  font-size: var(--tp-text-sm);
  font-weight: var(--tp-weight-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tp-user-tile__meta {
  font-size: var(--tp-text-xs);
  color: var(--tp-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ======================================================================
   TABLE
   ====================================================================== */
.tp-table-wrap {
  width: 100%;
  overflow-x: auto;
  border-radius: var(--tp-radius-lg);
}

.tp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--tp-text-sm);
}

.tp-table th {
  padding: var(--tp-space-3) var(--tp-space-4);
  text-align: left;
  font-size: var(--tp-text-2xs);
  font-weight: var(--tp-weight-semibold);
  letter-spacing: var(--tp-tracking-caps);
  text-transform: uppercase;
  color: var(--tp-text-muted);
  background: var(--tp-bg-surface-alt);
  border-bottom: var(--tp-border-thin) solid var(--tp-border-subtle);
  white-space: nowrap;
}

.tp-table td {
  padding: var(--tp-space-3) var(--tp-space-4);
  border-bottom: var(--tp-border-thin) solid var(--tp-border-subtle);
  color: var(--tp-text-primary);
  vertical-align: middle;
}

.tp-table tbody tr:last-child td { border-bottom: 0; }
.tp-table tbody tr:hover td { background: var(--tp-bg-hover); }
.tp-table .tp-table__numeric { text-align: right; font-variant-numeric: tabular-nums; }

/* ======================================================================
   THEME SWITCH - a no-JS form posting to /theme
   ====================================================================== */
.tp-theme-switch { display: inline-flex; gap: 0; }

.tp-theme-switch__group {
  display: inline-flex;
  padding: 0.15rem;
  gap: 0.15rem;
  background: var(--tp-bg-sunken);
  border: var(--tp-border-thin) solid var(--tp-border-subtle);
  border-radius: var(--tp-radius-pill);
}

.tp-theme-switch__btn {
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--tp-text-muted);
  transition:
    background-color var(--tp-duration-fast) var(--tp-ease-standard),
    color var(--tp-duration-fast) var(--tp-ease-standard);
}

.tp-theme-switch__btn:hover { color: var(--tp-text-primary); }

/*
  The selected option is derived purely from the data-theme attribute the server
  stamps on <html>. That keeps the control stateless on the client and means the
  correct option is highlighted on first paint, with no JavaScript involved.
*/
:root[data-theme="light"] .tp-theme-switch__btn[data-theme-value="light"],
:root[data-theme="dark"]  .tp-theme-switch__btn[data-theme-value="dark"],
:root:not([data-theme])   .tp-theme-switch__btn[data-theme-value="system"] {
  background: var(--tp-bg-surface);
  color: var(--tp-brand);
  box-shadow: var(--tp-shadow-xs);
}

.tp-theme-switch__icon { width: 1rem; height: 1rem; }

/* ======================================================================
   COLOUR / TOKEN SWATCHES - used by the design system reference page
   ====================================================================== */
.tp-swatch { display: flex; flex-direction: column; gap: var(--tp-space-2); }

.tp-swatch__chip {
  height: 3.5rem;
  border-radius: var(--tp-radius-md);
  border: var(--tp-border-thin) solid var(--tp-border-subtle);
}

.tp-swatch__name { font-size: var(--tp-text-xs); font-weight: var(--tp-weight-medium); }
.tp-swatch__token { font-family: var(--tp-font-mono); font-size: var(--tp-text-2xs); color: var(--tp-text-muted); }
