/* Modern Foundation & Design System */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
  --primary-color: #0f172a;    /* Deep Navy */
  --accent-color: #2563eb;     /* Sporty Blue */
  --success-color: #16a34a;    /* Goal Green */
  --bg-color: #f8fafc;         /* Soft Gray */
  --card-bg: #ffffff;          /* Pure White */
  --text-main: #1e293b;        /* Slate 800 */
  --text-muted: #64748b;       /* Slate 500 */
  --border-color: #e2e8f0;     /* Slate 200 */
  --radius: 12px;
  --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);

  /* ----------------------------------------------------------------------
     Type scale — ONE place to retune text sizes app-wide. Bump a token
     here and every element using it moves together (mobile + desktop).
     Use the semantic name, not the px value, so intent stays clear.
     A handful of tuned component values stay literal on purpose: the
     list "lead" score (15px), match-card team (15px) / vs-score (20px),
     decorative LIVE badges (9–10px), the public login-shell brand
     (26/15px) and glyphs (chevrons, the × close, the hamburger).
     -------------------------------------------------------------------- */
  --fs-xs:      11px;  /* dense data tables, fine print (footer meta) */
  --fs-label:   12px;  /* uppercase micro-labels, table <th>, status badges */
  --fs-meta:    13px;  /* secondary text: dates, row meta, descriptions, chips */
  --fs-body:    14px;  /* primary body text, list titles, buttons */
  --fs-ui:      16px;  /* form inputs (>=16px stops iOS zoom), section titles, nav */
  --fs-title:   18px;  /* overlay / modal headers */
  --fs-heading: 22px;  /* page headings, match headings, big scores */
  --fs-display: 28px;  /* score stepper value */
}

/* Global Reset & Typography */
body {
  background-color: var(--bg-color);
  color: var(--text-main);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  margin: 0;
  -webkit-font-smoothing: antialiased;
  /* Kill the default mobile WebKit tap-highlight rectangle. Replaced
     globally by tasteful :active feedback at the bottom of this file. */
  -webkit-tap-highlight-color: transparent;
}

h1, h2, h3, h4 {
  color: var(--primary-color);
  font-weight: 700;
  margin-top: 0;
}

/* Modern Card Wrapper (Replaces .box) */
.box, .card {
  background: var(--card-bg);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 24px;
  margin-bottom: 24px;
  border: none; /* Lighter look without hard borders */
}

/* Sidebar Overrides */
.sidebar {
  background-color: var(--primary-color) !important;
  color: white;
}

/* Responsive Table Wrapper */
.table-responsive {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin-bottom: 1rem;
}

.card {
  scroll-margin-top: 80px;
}

/* Mobile Stats List */
.stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid #f1f5f9;
}

.stat-label {
  color: #64748b;
  font-size: var(--fs-body);
  flex: 1;
}

.stat-value {
  font-weight: 700;
  color: #1e293b;
  text-align: right;
  flex: 1;
}

.stat-value.position {
  font-size: 24px;
  color: var(--primary-color);
}

.stats-divider {
  margin: 15px -8px 10px -8px;
  background: #f8fafc;
  padding: 6px 12px;
  font-size: var(--fs-label);
  color: #94a3b8;
  font-weight: 700;
  letter-spacing: 0.05em;
}

/* Live Overlay */
.live-overlay {
  display: block;
}

.live-overlay-header {
  display: none; /* Hidden on desktop */
}

/* Admin and userprofile layouts include the runningCompetitions partial
   ONLY to expose #live-overlay and toggleLiveOverlay() to the mobile-header
   LIVE pill. The inline desktop card render isn't wanted there — hide it. */
@media (min-width: 769px) {
  .live-overlay-host > .live-overlay {
    display: none;
  }
}

/* Bottom-sheet treatment for everything below the desktop rail breakpoint
   (1024px), not just phones. Capping at 768px left a 769–1023px gap where the
   overlay fell back to its base `display:block` and rendered the match cards
   in-flow — ballooning page height (huge empty over-scroll) on large phones /
   foldables / tablets. */
@media (max-width: 1023px) {
  .live-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100dvh;
    background: #f8fafc;
    z-index: 4000;
    display: none; /* Hide by default on mobile, triggered by JS */
    flex-direction: column;
    transform: translateY(100%);
    transition: transform 0.3s ease-in-out;
  }

  .live-overlay.open {
    transform: translateY(0);
    display: flex;
  }

  .live-overlay-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 20px;
    background: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.05);
    flex-shrink: 0;
  }

  .live-overlay-header h3 {
    margin: 0;
    font-size: var(--fs-title);
    color: var(--primary-color);
  }

  .close-overlay {
    background: #f1f5f9;
    border: none;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    font-size: var(--fs-title);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: #475569;
  }

  .live-overlay .match-cards-container {
    padding: 20px 16px;
    overflow-y: auto !important;
    flex: 1;
    display: block !important;
  }

  /* In the mobile bottom-sheet the cards stretch to the container width so
     they sit with equal gutters to both screen edges (the base 320px fixed
     width is for the desktop multi-column wrap / live-rail). Capped + centered
     on wider phones so a single card doesn't get uncomfortably long. */
  .live-overlay .match-card {
    width: 100%;
    max-width: 560px;
    margin: 0 auto 16px;
  }
  .live-overlay .match-card:last-child { margin-bottom: 0; }
}

.chart-mode-bar {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.chart-mode-btn {
  padding: 5px 14px;
  border-radius: 20px;
  border: 1px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-muted);
  font-size: var(--fs-meta);
  cursor: pointer;
  font-family: inherit;
  transition: border-color .15s, color .15s, background .15s;
}
.chart-mode-btn:hover  { border-color: var(--accent-color); color: var(--accent-color); }
.chart-mode-btn.active { background: var(--accent-color); border-color: var(--accent-color); color: #fff; font-weight: 600; }

.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 12px;
  font-size: var(--fs-meta);
  color: var(--text-muted);
}

.chart-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.chart-legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
}

/* "Verlauf" chart button in the Platzierung row. A bordered pill with an icon +
   label so it always reads as a tappable control — the bare icon was mistaken
   for decoration, and on touch there's no hover to hint at it. */
.chart-icon-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: 1px solid var(--border-color, #e2e8f0);
  cursor: pointer;
  color: var(--text-muted, #64748b);
  padding: 3px 9px;
  margin-left: 8px;
  vertical-align: middle;
  line-height: 1;
  border-radius: 999px;
  font-size: var(--fs-label);
  font-weight: 600;
  transition: color 0.15s, background-color 0.15s, border-color 0.15s;
}
.chart-icon-btn-label { letter-spacing: 0.02em; }
.chart-icon-btn:hover {
  color: var(--primary-color, #2563eb);
  border-color: var(--primary-color, #2563eb);
  background-color: rgba(37, 99, 235, 0.07);
}

/* Chart history overlay — full-screen sheet on mobile, centered modal on desktop.
   Lives in the shared sheet (not mobile.css) because the overlay markup renders
   on every viewport; the desktop modal rule below would never fire otherwise. */
.chart-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 5000;
  align-items: flex-end;
}
.chart-overlay.open {
  display: flex;
}
.chart-overlay-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
}
.chart-overlay-panel {
  position: relative;
  background: var(--card-bg, #fff);
  width: 100%;
  max-height: 85vh;
  border-radius: 16px 16px 0 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: chartOverlaySlideUp 0.25s ease-out;
}
@keyframes chartOverlaySlideUp {
  from { transform: translateY(40px); opacity: 0.6; }
  to   { transform: translateY(0);    opacity: 1; }
}
.chart-overlay-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 20px;
  background: var(--card-bg, #fff);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  flex-shrink: 0;
}
.chart-overlay-header h3 {
  margin: 0;
  font-size: var(--fs-title);
  color: var(--primary-color, #2563eb);
}
.chart-overlay-body {
  overflow-y: auto;
  flex: 1;
  padding: 16px;
}

/* Desktop: centered modal instead of bottom sheet */
@media (min-width: 769px) {
  .chart-overlay {
    align-items: center;
    justify-content: center;
  }
  .chart-overlay-panel {
    width: min(680px, 90vw);
    border-radius: 12px;
    animation: chartOverlayFadeIn 0.2s ease-out;
  }
  @keyframes chartOverlayFadeIn {
    from { transform: scale(0.97); opacity: 0.5; }
    to   { transform: scale(1);    opacity: 1; }
  }
  /* The donate prompt is just a short paragraph + button — keep it compact. */
  .donate-overlay .chart-overlay-panel {
    width: min(440px, 90vw);
  }
}

/* Donate modal: tighter line-length than the chart sheet, with a soft CTA. */
.donate-overlay .chart-overlay-body p {
  margin: 0 0 18px;
  color: var(--text-color);
  line-height: 1.5;
}
.donate-cta {
  display: inline-block;
  padding: 10px 20px;
  border-radius: 8px;
  background: var(--brand-color, #2563eb);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
}
.donate-cta:hover {
  opacity: 0.9;
}

/* .desktop-only / .mobile-only are used ONLY by the list views (Ergebnisse,
   Ranking, Alle Tipps, anstehende Spiele). Those lists now render their mobile
   two-line card layout on every screen size, so apply the mobile visibility at
   all widths: the dense desktop-only columns stay hidden and the inline rank
   prefix shows — on desktop too. */
.desktop-only { display: none !important; }
.mobile-only  { display: inline !important; }

@media (max-width: 768px) {
  /* Page-title harmonization — views are inconsistent about which tag a page
     title uses (<h2> is the de-facto convention, a few use <h1>, the public
     shell uses .headline1). Pin them all to one size on mobile so every page
     reads the same; without this, bare <h1> falls back to the 32px browser
     default and <h2> to 24px. #ErrorExplanation h2 keeps its own small size
     (higher specificity). Sub-headings step down via h3. */
  h1, h2 { font-size: var(--fs-heading); }
  h3 { font-size: var(--fs-title); }

  .box, .card {
    padding: 12px 8px !important;
    margin-bottom: 12px;
    border-radius: 0;
    width: 100% !important;
    box-sizing: border-box;
  }

  /* Override legacy scaffold margins/paddings that create 'frame' */
  div.contents {
    margin: 0 !important;
    padding: 0 !important;
    width: 100% !important;
  }

  .main-wrapper {
    /* No horizontal frame; top clears the fixed mobile header. */
    padding: calc(var(--header-height) + 10px) 0 8px !important;
  }

  /* Force tables to be full width without forced scrolling */
  table, table.rankingTable, table.rankingTeam, table.bet, table.infoTable {
    width: 100% !important;
    min-width: 100% !important;
    max-width: 100% !important;
    font-size: var(--fs-xs) !important;
  }

  table th, table td,
  table.rankingTable th, table.rankingTable td,
  table.rankingTeam th, table.rankingTeam td,
  table.bet th, table.bet td,
  table.infoTable th, table.infoTable td {
    padding: 6px 2px !important;
    word-wrap: break-word;
  }

  /* Standings ("Aktuelle Tabellenstände") is a primary screen with only five
     short columns — it doesn't need the --fs-xs (11px) clamp the dense bet/info
     tables get above. It's not a busy list like the results tables, so it can
     carry a larger, header-like size: pin it to --fs-ui (the section-title /
     nav size) so it reads prominently while staying on the shared type scale. */
  table.rankingTeam,
  table.rankingTeam th,
  table.rankingTeam td {
    font-size: var(--fs-ui) !important;   /* 16px */
  }

  td.statsLink {
    width: auto !important; /* Remove fixed widths on specific columns */
    max-width: 100px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .table-responsive {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Tables inside a scrollable wrapper must be allowed to overflow.
     The "width/min/max: 100% !important" rules above clamp every other
     table to viewport width — explicitly unclamp here. */
  .table-responsive table,
  .table-responsive table.rankingTable,
  .table-responsive table.rankingTeam,
  .table-responsive table.bet,
  .table-responsive table.infoTable {
    width: auto !important;
    min-width: 100% !important;
    max-width: none !important;
  }
  .table-responsive th,
  .table-responsive td {
    white-space: nowrap !important;
    word-wrap: normal !important;
  }

  /* Statistics and news specific overrides */
  div.posting {
    width: 100% !important;
    box-sizing: border-box;
  }
}

.sidebar-header {
  border-bottom: 1px solid rgba(255,255,255,0.1) !important;
}

.sidebar-header h2 {
  color: white !important;
}

.sidebar-nav a {
  color: rgba(255,255,255,0.7) !important;
  font-weight: 500;
}

.sidebar-nav a:hover {
  background-color: rgba(255,255,255,0.1) !important;
  color: white !important;
}

/* OAuth / Social Sign-in Buttons */
.oauth-buttons {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
}

.oauth-buttons form {
  width: 100%;
  max-width: 320px;
}

.oauth-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  box-sizing: border-box;
  padding: 11px 18px;
  border-radius: 8px;
  border: none;
  cursor: pointer;
  font-weight: 600;
  font-family: inherit;
  font-size: var(--fs-body);
  transition: background 0.2s, box-shadow 0.2s;
}

.oauth-btn-google {
  background: #fff;
  color: #3c4043;
  border: 1.5px solid #dadce0;
  box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}

.oauth-btn-google:hover {
  background: #f8f9fa;
  box-shadow: 0 1px 6px rgba(0,0,0,0.14);
}

.oauth-btn-facebook {
  background: #1877F2;
  color: #fff;
}

.oauth-btn-facebook:hover {
  background: #166fe5;
  box-shadow: 0 2px 8px rgba(24,119,242,0.35);
}

.oauth-divider {
  text-align: center;
  position: relative;
  margin: 20px auto 25px;
  color: #778;
  font-size: var(--fs-meta);
  font-weight: 600;
}

.oauth-divider::before,
.oauth-divider::after {
  content: '';
  position: absolute;
  top: 50%;
  width: calc(50% - 24px);
  height: 1px;
  background: #ccd;
}

.oauth-divider::before { left: 0; }
.oauth-divider::after { right: 0; }

/* -----------------------------------------------------------------------
   Login page — Google-first with progressive disclosure: the e-mail/password
   form is revealed by the "Mit E-Mail anmelden" toggle. Consistent full-width
   controls, focus rings, password reveal and quiet secondary links.
   ----------------------------------------------------------------------- */
.login-intro {
  text-align: center;
  margin-bottom: 16px;
}
.login-heading {
  margin: 0;
  font-size: var(--fs-heading);
  color: var(--primary-color);
}
.login-tagline {
  margin: 4px 0 0;
  font-size: var(--fs-meta);
  color: var(--text-muted);
}

.login-card {
  max-width: 400px;
  margin: 0 auto;
}

/* Google button spans the card width (overrides the global 320px form cap). */
.login-card .oauth-buttons {
  align-items: stretch;
  margin-bottom: 12px;
}
.login-card .oauth-buttons form { max-width: none; }

/* Secondary "Mit E-Mail anmelden" toggle — outline button, full width. */
.login-email-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  box-sizing: border-box;
  padding: 11px 18px;
  border-radius: 8px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-main);
  font-family: inherit;
  font-weight: 600;
  font-size: var(--fs-body);
  cursor: pointer;
  transition: background 0.2s, box-shadow 0.2s;
}
.login-email-toggle:hover {
  background: var(--bg-color);
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.10);
}
/* Hidden once the e-mail form is revealed — a class, not the `hidden` attribute,
   since the explicit display above would override [hidden] { display: none }. */
.login-email-toggle.is-hidden { display: none; }

/* Hidden by default (progressive disclosure), revealed by the toggle adding
   .is-open. Note: hide via a CSS class — NOT the `hidden` attribute — so the
   no-JS rack_test driver (which ignores CSS) can still reach the fields. */
.login-email-form { display: none; margin-top: 12px; }
.login-email-form.is-open { display: block; }

.login-field { margin-bottom: 14px; }
.login-field label {
  display: block;
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--text-main);
  margin-bottom: 6px;
}
.login-field input[type="text"],
.login-field input[type="password"] {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 12px;
  font-size: var(--fs-ui);          /* 16px — avoids iOS zoom-on-focus */
  border: 1.5px solid var(--border-color);
  border-radius: 8px;
  background: var(--card-bg);
  color: var(--text-main);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.login-field input:focus {
  outline: none;
  border-color: var(--accent-color);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}

.login-password-wrap { position: relative; }
.login-password-wrap input { padding-right: 44px; }
.login-password-toggle {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: none;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: 6px;
}
.login-password-toggle:hover { color: var(--text-main); background: var(--bg-color); }
.login-password-toggle .eye-off { display: none; }
.login-password-toggle.is-on .eye-on { display: none; }
.login-password-toggle.is-on .eye-off { display: inline; }

.login-submit {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 18px;
  margin-top: 4px;
  border: none;
  border-radius: 8px;
  background: var(--accent-color);
  color: #fff;
  font-family: inherit;
  font-weight: 700;
  font-size: var(--fs-body);
  cursor: pointer;
  transition: background 0.2s, box-shadow 0.2s;
}
.login-submit:hover {
  background: #1d4fd8;
  box-shadow: 0 2px 10px rgba(37, 99, 235, 0.35);
}

.login-forgot { text-align: center; margin-top: 12px; }
.login-link-quiet {
  font-size: var(--fs-meta);
  color: var(--text-muted);
  text-decoration: none;
}
.login-link-quiet:hover { color: var(--text-main); text-decoration: underline; }

.login-register {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border-color);
  text-align: center;
  font-size: var(--fs-meta);
  color: var(--text-muted);
}
.login-link-cta {
  color: var(--accent-color);
  font-weight: 700;
  text-decoration: none;
}
.login-link-cta:hover { text-decoration: underline; }

.sidebar-nav a.active {
  background-color: var(--accent-color) !important;
  color: white !important;
  border-left: 4px solid white !important;
}

.sidebar-context {
  background-color: rgba(0,0,0,0.2) !important;
  border-bottom: 1px solid rgba(255,255,255,0.1) !important;
}

.sidebar-context span {
  color: rgba(255,255,255,0.5) !important;
}

.sidebar-footer {
  border-top: 1px solid rgba(255,255,255,0.1) !important;
}

.sidebar-footer a {
  color: rgba(255,255,255,0.5) !important;
}

.sidebar-footer a:hover {
  background-color: rgba(255, 255, 255, 0.08) !important;
  color: rgba(255, 255, 255, 0.85) !important;
}

.sidebar-footer a.active {
  background-color: var(--accent-color) !important;
  color: white !important;
  border-left: 4px solid white !important;
}

/* Tables Modernization */
table {
  border-collapse: collapse;
  width: 100%;
}

.runningComps, .rankingTeam, .infoTable, .userTable, .resultsTable {
  width: 100% !important;
  font-size: var(--fs-body);
  margin-bottom: 10px;
}

.clickable-row {
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

/* Only real pointer devices get the hover wash; on touch it sticks
   after a tap and reads as an ugly lingering highlight. */
@media (hover: hover) {
  .clickable-row:hover td {
    background-color: #f8fafc !important;
  }
}

.resultsTable td {
  vertical-align: middle;
  padding: 12px 8px;
}

.resultsTable .score {
  font-weight: 700;
  font-size: var(--fs-ui);
  color: var(--primary-color);
  text-align: center;
}

/* Sets the weight of the Tipp/Torwette/Punkte values in the card (these cells
   carry .points-col alongside .list2-c1/2/3). Alignment comes from .list2-c*. */
.resultsTable .points-col { font-weight: 600; }

.resultsTable .my-bet {
  color: var(--accent-color);
  font-weight: 700;
}

.resultsTable .wrong-bet {
  color: #ef4444; /* Red */
}

.resultsTable .right-bet {
  color: var(--success-color);
}

.runningComps td, .rankingTeam td, .infoTable td, .userTable td {
  padding: 10px 12px;
  border-bottom: 1px solid #f1f5f9;
}

.runningComps tr:nth-child(even), .rankingTeam tr:nth-child(even), .infoTable tr:nth-child(even) {
  background-color: #fafafa;
}

.rankingTeam th {
  background-color: var(--bg-color);
  color: var(--primary-color);
  font-weight: 600;
}

th {
  text-align: left;
  font-size: var(--fs-label);
  letter-spacing: 0.05em;
  color: var(--text-muted);
  padding: 12px 16px;
  border-bottom: 2px solid var(--border-color);
}

td {
  padding: 12px 16px;
  border-bottom: 1px solid #f1f5f9;
  white-space: nowrap;
}

tr:last-child td {
  border-bottom: none;
}

tr:hover td {
  background-color: #f8fafc;
}

/* Match Cards (for ongoing/upcoming matches) */
.match-cards-container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 10px;
  margin-bottom: 20px;
}

/* Shown in the overlay when nothing is live and nothing is upcoming in
   the next-24h window — the mobile "Spiele" pill always opens the sheet. */
.live-overlay-empty {
  width: 100%;
  padding: 24px 16px;
  text-align: center;
  color: #6b7280;
  font-size: var(--fs-ui);
}

.match-card {
  width: 320px;
  flex: 0 0 auto;
  background: white;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 16px;
  transition: all 0.2s ease;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  box-sizing: border-box;
}

.match-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: var(--accent-color);
  background-color: white;
}

.card-overlay-link {
  text-decoration: none;
  color: inherit;
  display: block;
}

.card-overlay-link:hover {
  background: none !important;
  color: inherit !important;
}

.match-card .live-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  background: #fee2e2;
  color: #ef4444;
  font-size: 10px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 99px;
  animation: pulse 2s infinite;
}

/* Half-time: a calmer amber badge, no pulse — the match is paused. */
.match-card .live-badge--pause {
  background: #fef3c7;
  color: #d97706;
  animation: none;
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}

.match-card .match-time {
  font-size: var(--fs-label);
  color: var(--text-muted);
  margin-bottom: 12px;
}

.match-card .teams-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 15px;
}

.match-card .team {
  flex: 1 1 0;
  min-width: 0;
  font-weight: 600;
  font-size: 15px;
}

.match-card .team:first-child { text-align: right; }
.match-card .team:last-child  { text-align: left; }

.match-card .vs-score {
  flex: 0 0 auto;
  font-size: 20px;
  font-weight: 800;
  color: var(--primary-color);
  min-width: 50px;
  text-align: center;
}

.match-card .bet-info {
  background: var(--bg-color);
  padding: 8px 12px;
  border-radius: 6px;
  font-size: var(--fs-meta);
  display: flex;
  justify-content: space-between;
}

/* Live/running card bet row — mirror the "Alle Tipps" overview: Tipp left,
   Torwette true-centred, Details right, with the same mini-labels and live
   correctness colouring (.bet-correct/.bet-wrong). */
.match-card .bet-info--cols {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  align-items: center;
  column-gap: 8px;
}
/* Neutral value colour matches the Alle Tipps / Ergebnisse lists (muted grey). */
.match-card .bet-info-tip   { grid-column: 1; text-align: left;   font-weight: 700; color: var(--text-muted); }
.match-card .bet-info-goals { grid-column: 2; text-align: center; font-weight: 700; color: var(--text-muted); }
/* Graded bets win over the muted neutral colour above (needs the extra class to
   out-specify it, just like the lists do). */
.match-card .bet-info-tip.bet-correct,
.match-card .bet-info-goals.bet-correct { color: var(--success-color, #16a34a); }
.match-card .bet-info-tip.bet-wrong,
.match-card .bet-info-goals.bet-wrong   { color: #ef4444; }
.match-card .bet-info-details {
  grid-column: 3; text-align: right;
  color: var(--text-muted);   /* inherits the row's --fs-meta so it matches Tipp/Torwette */
}
.match-card .bet-info-tip::before,
.match-card .bet-info-goals::before {
  content: attr(data-label);
  margin-right: 4px;
  font-size: var(--fs-label); font-weight: 600;
  color: var(--text-muted); opacity: 0.6;
}

.match-card .admin-actions {
  margin-top: 12px;
  text-align: right;
}

/* Tabs Navigation — segmented control (Anstehende / Ergebnisse).
   A recessed track holds two equal-width segments; the active one is a
   filled accent pill. Same visual language as .chart-mode-btn. */
.modern-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 20px;
  padding: 4px;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}

.modern-tabs a {
  flex: 1;
  text-align: center;
  text-decoration: none;
  color: var(--text-muted);
  font-weight: 600;
  padding: 9px 12px;
  border-radius: calc(var(--radius) - 5px);
  transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;
}

.modern-tabs a:hover {
  color: var(--accent-color);
}

.modern-tabs a.active {
  background-color: var(--accent-color);
  color: #fff;
  box-shadow: 0 1px 3px rgba(37, 99, 235, 0.35);
}

.modern-tabs a.active:hover {
  color: #fff;
}

/* Sort control bar — rounded "chips" above a list (Ranking / Ergebnisse /
   Alle Tipps). Pills (not a connected track) so they read as sort/filter,
   distinct from the segmented tab control. Shared by mobile + desktop. */
.sort-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}

.sort-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  text-decoration: none;
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--text-muted);
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  padding: 6px 12px;
  border-radius: 999px;
  transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}

.sort-chip:hover {
  border-color: var(--accent-color);
  color: var(--accent-color);
}

.sort-chip.active {
  background: var(--accent-color);
  border-color: var(--accent-color);
  color: #fff;
}

.sort-arrow {
  font-size: 10px;
  line-height: 1;
}

/* Clickable column headers (desktop-only affordance — list <thead> is hidden
   on mobile). Same sort params as the chips. */
.sort-header {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  white-space: nowrap;
}

.sort-header:hover { color: var(--accent-color); }
.sort-header.active { color: var(--accent-color); }

/* Buttons */
input[type="submit"], button {
  background-color: var(--accent-color);
  color: white;
  padding: 10px 20px;
  border-radius: var(--radius);
  border: none;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.1s, background-color 0.2s;
}

input[type="submit"]:hover, button:hover {
  background-color: #1d4ed8; /* Darker blue */
  transform: translateY(-1px);
}

/* Content Width Control */
.main-wrapper {
  max-width: 1400px;
  margin-left: var(--sidebar-width);
}

@media (max-width: 768px) {
  .main-wrapper {
    margin-left: 0;
    padding: 16px;
  }
}

/* -----------------------------------------------------------------------
   Right rail — desktop only. On pages that have live/today matches,
   public.html.erb adds .with-live-rail and renders an <aside class="live-rail">
   beside the main content. Reclaims the wasted right column without
   pushing the main content down.
   ----------------------------------------------------------------------- */
@media (min-width: 1024px) {
  .main-wrapper.with-live-rail {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 24px;
    padding-right: 24px;
    align-items: start;
  }

  .main-wrapper.with-live-rail .contents {
    min-width: 0;
  }

  .live-rail {
    position: sticky;
    top: 16px;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    padding: 16px 0;
  }

  /* The runningCompetitions partial wraps everything in
     #live-overlay.live-overlay — that element is positioned as a
     bottom-sheet on mobile. Inside the rail on desktop we neutralize
     those styles. */
  .live-rail .live-overlay {
    position: static;
    transform: none;
    display: block;
    background: transparent;
    height: auto;
    width: 100%;
  }

  .live-rail .live-overlay-header {
    display: none;
  }

  /* Stack cards vertically; narrow to fit the rail. */
  .live-rail .match-cards-container {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 0;
  }

  .live-rail .match-card {
    width: 100%;
    flex: 0 0 auto;
    padding: 12px 14px;
  }

  .live-rail .match-card .team        { font-size: 14px; }
  .live-rail .match-card .vs-score    { font-size: 16px; min-width: 50px; }
  .live-rail .match-card .match-time  { font-size: 11px; margin-bottom: 8px; }
  .live-rail .match-card .live-badge  { font-size: 9px; padding: 2px 6px; }
  .live-rail .match-card .bet-info    { font-size: 12px; padding: 6px 10px; }
  .live-rail .match-card .teams-row   { margin-bottom: 10px; }
  .live-rail .match-card .admin-actions { margin-top: 8px; }

  /* Quiet rail heading shown above the stack — injected via CSS, no
     markup change. */
  .live-rail::before {
    content: "Spiele heute";
    display: block;
    font-size: 11px;
    font-weight: 700;
    color: var(--text-muted);
    letter-spacing: 0.06em;
    padding: 0 4px 12px;
  }
}

/* Live / Confirmed toggle (rankings + group standings) */
.live-toggle { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.live-toggle-btn {
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--border-color);
  color: var(--text-main);
  text-decoration: none;
  font-weight: 500;
  font-size: var(--fs-body);
  background: var(--card-bg);
  transition: background 0.15s, border-color 0.15s;
}
.live-toggle-btn:hover  { border-color: var(--accent-color); }
.live-toggle-btn.active { background: var(--accent-color); color: #fff; border-color: var(--accent-color); }
.live-toggle-btn--live:hover  { border-color: #ef4444; }
.live-toggle-btn--live.active { background: #ef4444; color: #fff; border-color: #ef4444; }
.live-toggle-badge {
  font-size: var(--fs-label);
  color: #ef4444;
  font-weight: 600;
  letter-spacing: 0.02em;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.live-toggle-badge::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ef4444;
  animation: live-pulse 1.4s ease-in-out infinite;
}

/* Live-mode tinting — coral/red to match the LIVE badge */
.card.live-mode {
  background: linear-gradient(180deg, rgba(239, 68, 68, 0.06), var(--card-bg) 100px);
  border-top: 2px solid #ef4444;
  position: relative;
}
.card.live-mode::before {
  content: "";
  position: absolute;
  top: -2px; left: 0;
  width: 60px;
  height: 2px;
  background: #ef4444;
  animation: live-bar-pulse 1.6s ease-in-out infinite;
}
@keyframes live-bar-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 8px rgba(239, 68, 68, 0.5); }
  50%      { opacity: 0.4; box-shadow: 0 0 0 rgba(239, 68, 68, 0); }
}
table.live-mode { background: rgba(239, 68, 68, 0.03); }
.live-row,
.live-row > td  { background: rgba(239, 68, 68, 0.08); }

/* A group with a live match: tint the WHOLE standings table so it reads as a
   provisional "live" group, not just the two playing teams. Cells (not the tr)
   carry the tint because the striping colors sit on the row underneath. */
table.rankingTeam.group-live th,
table.rankingTeam.group-live td { background: rgba(239, 68, 68, 0.08); }

/* Ranking page: tint ALL rows in live mode, because relative ranking
   shifts even for users without bets when others gain points. */
.card.live-mode table.rankingTable tbody tr {
  background: rgba(239, 68, 68, 0.06);
}
/* Cells stay transparent so the grid container's tint fills the row evenly —
   tinting both tr and td double-stacks the alpha and leaves pale gaps. */
.card.live-mode table.rankingTable tbody tr > td {
  background: transparent;
}
.live-dot {
  color: #ef4444;
  animation: live-pulse 1.6s ease-in-out infinite;
  font-size: var(--fs-label);
}
@keyframes live-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* Live score on match cards */
.live-score {
  color: var(--accent-color);
  font-weight: 700;
}

/* -----------------------------------------------------------------------
   Modern .box — replaces the legacy blue-bordered pale-blue panel that
   wrapped Login / Profile / Wette platzieren / Admin lists. Adopts the
   same look as .card so the whole app reads as a single design system.
   ----------------------------------------------------------------------- */
.box {
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px 24px;
  margin-bottom: 20px;
}

/* -----------------------------------------------------------------------
   Flash messages (Rails flash[:notice] / flash[:alert])
   ----------------------------------------------------------------------- */
p.notice, p.alert {
  padding: 12px 16px;
  border-radius: 8px;
  border: 1px solid transparent;
  margin: 0 0 16px 0;
  font-weight: 500;
}
p.notice {
  background-color: #dcfce7;
  border-color: #bbf7d0;
  color: #15803d;
}
p.alert {
  background-color: #fee2e2;
  border-color: #fecaca;
  color: #b91c1c;
}

/* -----------------------------------------------------------------------
   Sidebar context (instance switcher) — fix dark-on-dark contrast.
   The native <select> inherited the sidebar's dark navy bg + dark text,
   which made it unreadable. Force readable colors.
   ----------------------------------------------------------------------- */
.sidebar-context select {
  width: 100%;
  padding: 8px 28px 8px 10px;
  background: rgba(255, 255, 255, 0.08);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  font-size: var(--fs-body);
  font-family: inherit;
  font-weight: 500;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s;
}

.sidebar-context select:hover {
  background-color: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.28);
}

.sidebar-context select:focus {
  outline: none;
  border-color: var(--accent-color);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.35);
}

/* Options drop back to a light bg so the OS-native dropdown is readable.
   (Browsers render <option> outside the select element, so this only
   affects the opened menu, not the closed control.) */
.sidebar-context select option,
.sidebar-context select optgroup {
  background: #ffffff;
  color: var(--text-main);
}

/* -----------------------------------------------------------------------
   Goal stepper — used on the bet placement form in place of native
   <select> dropdowns. Big tap targets, clear numeric focal point.
   ----------------------------------------------------------------------- */
.score-stepper-row {
  display: flex;
  gap: 16px;
  margin: 16px 0 20px;
  align-items: stretch;
  flex-wrap: wrap;
}

.score-stepper {
  flex: 1 1 140px;
  min-width: 140px;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.score-stepper-team {
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-align: center;
}

.score-stepper-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.score-stepper-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--border-color);
  background: var(--card-bg);
  color: var(--primary-color);
  font-size: var(--fs-heading);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: background-color 0.15s, border-color 0.15s, transform 0.05s;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) and (pointer: fine) {
  .score-stepper-btn:hover:not(:disabled) {
    border-color: var(--accent-color);
    color: var(--accent-color);
  }
}

.score-stepper-btn:active:not(:disabled) {
  transform: scale(0.95);
}
.score-stepper-btn:focus {
  outline: none;
  border-color: var(--border-color);
  color: var(--primary-color);
}

.score-stepper-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.score-stepper-value {
  width: 56px;
  font-size: var(--fs-display);
  font-weight: 800;
  color: var(--primary-color);
  text-align: center;
  font-variant-numeric: tabular-nums;
  border: none;
  background: transparent;
  padding: 0;
  appearance: textfield;
  -moz-appearance: textfield;
}

.score-stepper-value::-webkit-outer-spin-button,
.score-stepper-value::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.score-stepper-value:focus {
  outline: none;
  color: var(--accent-color);
}

@media (max-width: 480px) {
  .score-stepper {
    flex-basis: calc(50% - 8px);
    min-width: 0;
  }
}

/* Bet form header (match info + odds chips) */
.match-form {
  display: block;
}

.match-form-header {
  text-align: center;
  padding: 8px 0 16px;
}

.match-form-header-teams {
  font-size: var(--fs-heading);
  font-weight: 700;
  color: var(--primary-color);
  line-height: 1.25;
}

.match-form-header-vs {
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.08em;
  padding: 0 8px;
}

.match-form-header-meta {
  font-size: var(--fs-meta);
  color: var(--text-muted);
  margin-top: 4px;
}

.match-form-odds {
  display: inline-flex;
  gap: 8px;
  margin-top: 14px;
  padding: 8px 12px;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}

.match-form-odd {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-size: var(--fs-body);
  padding: 2px 8px;
}

.match-form-odd-label {
  font-weight: 700;
  color: var(--text-muted);
  font-size: var(--fs-label);
}

.match-form-odd-value {
  font-weight: 700;
  color: var(--primary-color);
  font-variant-numeric: tabular-nums;
}

.match-form-submit-row {
  margin-top: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
}

.match-form-submit-btn {
  background: var(--accent-color);
  color: #fff;
  border: none;
  border-radius: var(--radius);
  font-size: var(--fs-ui);
  font-weight: 700;
  padding: 12px 32px;
  cursor: pointer;
  min-width: 200px;
  transition: background 0.15s, transform 0.05s;
}

.match-form-submit-btn:hover { background: #1d4ed8; }
.match-form-submit-btn:active { transform: scale(0.98); }

.match-form-cancel-btn {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  font-size: var(--fs-ui);
  font-weight: 600;
  padding: 12px 24px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}
.match-form-cancel-btn:hover {
  background: var(--bg-secondary);
  color: var(--text-primary);
}

.match-form-back-row {
  margin-top: 18px;
  text-align: center;
}

.match-form-back-link {
  color: var(--text-muted);
  font-size: var(--fs-body);
  text-decoration: none;
}

.match-form-back-link:hover {
  color: var(--accent-color);
  background: transparent;
}

/* Match-form generic field (label + control beneath, full width) */
.match-form-field {
  margin: 14px 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.match-form-field--inline {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

.match-form-field-label {
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.04em;
}

.match-form-select {
  padding: 10px 12px;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  font-family: inherit;
  font-size: var(--fs-ui);   /* 16px: also stops iOS Safari zoom-on-focus */
  background: var(--card-bg);
  color: var(--text-main);
  cursor: pointer;
}

.match-form-select:focus {
  outline: none;
  border-color: var(--accent-color);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}

/* Odds entry — 1 / X / 2 cells in a responsive row */
.quote-row {
  display: flex;
  gap: 12px;
  margin: 16px 0 20px;
  flex-wrap: wrap;
}

.quote-cell {
  flex: 1 1 140px;
  min-width: 0;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
}

.quote-label {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-align: center;
  line-height: 1.3;
}

.quote-input {
  width: 100%;
  max-width: 110px;
  padding: 10px 8px;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  font-size: var(--fs-heading);
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--primary-color);
  background: var(--card-bg);
  box-sizing: border-box;
}

.quote-input:focus {
  outline: none;
  border-color: var(--accent-color);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}

@media (max-width: 480px) {
  .quote-cell {
    flex-basis: 100%;
  }
}

/* -----------------------------------------------------------------------
   Public shell — login, register, password assistance. No sidebar, so
   give the card a comfortable centered layout with breathing room.
   ----------------------------------------------------------------------- */
.public-body {
  margin: 0;
  background: var(--bg-color);
  min-height: 100vh;
}

.public-shell {
  max-width: 520px;
  margin: 0 auto;
  padding: 48px 24px 32px;
  box-sizing: border-box;
}

.public-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  margin-bottom: 28px;
}

.public-brand .logo {
  display: inline-flex;
  flex-shrink: 0;
}

.public-brand-text {
  line-height: 1.2;
}

.public-brand-text .headline1 {
  font-size: 26px;
  font-weight: 800;
  color: var(--primary-color);
}

.public-brand-text .headline2 {
  font-size: 15px;
  font-weight: 500;
  color: var(--text-muted);
  margin-top: 2px;
  padding-left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

/* Small tournament emblem shown next to TOURNAMENT_NAME (login + sidebar).
   A tournament marker, kept secondary to the WettUndGwinn badge. */
.tournament-emblem {
  height: 22px;
  width: auto;
  flex-shrink: 0;
}

.public-content {
  /* Inherits .box styling from yielded views */
}

@media (max-width: 520px) {
  .public-shell {
    padding: 28px 16px 24px;
  }
  .public-brand {
    gap: 12px;
  }
  .public-brand-text .headline1 {
    font-size: 22px;
  }
}

/* -----------------------------------------------------------------------
   Tap feedback — replaces the default mobile WebKit tap-highlight
   rectangle (disabled via body { -webkit-tap-highlight-color }) with
   tasteful, element-appropriate :active states.

   Three patterns:
     - Buttons / pills  : transform: scale(0.97)        (bouncy press)
     - Cards            : transform: scale(0.99)        (subtle press)
     - Nav links        : background-color brighten     (highlight)
     - Inline links     : opacity 0.6                   (quiet dip)
   ----------------------------------------------------------------------- */

/* Buttons & pill-shaped tappables — bouncy press */
button:active,
input[type="submit"]:active,
.oauth-btn:active,
.mobile-live-link:active,
.live-toggle-btn:active,
.chart-mode-btn:active,
.close-overlay:active,
.match-form-back-link:active {
  transform: scale(0.97);
}

/* Hamburger uses color shift instead of scale (small icon) */
.mobile-header .hamburger:active {
  color: var(--accent-color);
}

/* Match cards — subtle press-down without losing the hover lift */
.match-card:active {
  transform: scale(0.99);
}

/* Sidebar nav items — brighten on press */
.sidebar-nav a:active,
.sidebar-footer a:active {
  background-color: rgba(255, 255, 255, 0.14) !important;
}

/* Active items already styled with accent bg — darken slightly on press */
.sidebar-nav a.active:active,
.sidebar-footer a.active:active {
  background-color: #1d4ed8 !important;
}

/* Tab links (tournament: Anstehende / Ergebnisse) */
.modern-tabs a:active,
.tab-link:active {
  opacity: 0.6;
}

/* Inline links — short, quiet opacity dip */
a:active {
  opacity: 0.7;
}

/* -----------------------------------------------------------------------
   betsAll — match header card + distribution strip + compact search
   ----------------------------------------------------------------------- */
/* betsAll header mirrors the shared match-form header (centered, navy title,
   muted separator, meta beneath) used on the bet / result-entry pages. */
.bets-match-header {
  text-align: center;
  padding: 8px 0 16px;
}

.bets-match-label {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--text-muted, #64748b);
  letter-spacing: 0.05em;
  margin: 0 0 4px;
}

.bets-match-title {
  font-size: var(--fs-heading);
  font-weight: 700;
  color: var(--primary-color);
  margin: 0 0 2px;
  line-height: 1.25;
}

.bets-match-sep {
  font-weight: 600;
  color: var(--text-muted);
  padding: 0 6px;
}

.bets-match-date {
  font-size: var(--fs-meta);
  color: var(--text-muted, #64748b);
  margin: 0 0 12px;
}

/* Provisional-standings hint on a live betsAll page (reuses .live-toggle-badge). */
.bets-live-hint { margin: 0 0 12px; }

/* Soft-grey bordered panel grouping the result/live score and the
   distribution+odds grid — same surface treatment as .score-stepper /
   .quote-cell on the sibling match pages. */
.bets-match-data {
  max-width: 360px;
  margin: 0 auto;
  padding: 12px 14px;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  text-align: left;
}

.bets-match-result {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

/* Divider only when the distribution grid follows the score row. */
.bets-match-result:not(:last-child) {
  padding-bottom: 10px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--border-color);
}

.bets-result-score {
  font-size: var(--fs-heading);
  font-weight: 800;
  color: var(--primary-color, #1a56db);
}

.bets-result-meta {
  font-size: var(--fs-meta);
  color: var(--text-muted, #64748b);
}

/* Tippverteilung + Quoten as an aligned grid: row labels on the left, the
   1 / X / 2 columns locked so the two rows line up. The column matching the
   actual result is highlighted (bold green). */
.bets-odds-grid {
  display: grid;
  grid-template-columns: auto 1fr 1fr 1fr;
  gap: 6px 10px;
  align-items: center;
}
.bets-odds-head {
  text-align: center;
  font-weight: 700;
  font-size: var(--fs-meta);
  color: var(--text-muted);
}
.bets-odds-rowlabel {
  font-size: var(--fs-meta);
  color: var(--text-muted);
  white-space: nowrap;
  padding-right: 4px;
}
.bets-odds-cell {
  text-align: center;
  font-size: var(--fs-body);
  font-variant-numeric: tabular-nums;
  color: var(--text-main);
}
.bets-odds-head.is-win { color: var(--success-color); }
.bets-odds-cell.is-win { color: var(--success-color); font-weight: 700; }

/* -----------------------------------------------------------------------
   Punktewertung (user_stats) — centered title, hero figures and a stat list
   in the same soft-grey bordered panel used by betsAll (.bets-match-data).
   ----------------------------------------------------------------------- */
.user-stats-panel {
  margin: 0 0 16px;
  padding: 0 14px 2px;
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}

/* Dedicated Punktewertung page: a centered narrow column with breathing room
   before the results list. */
.user-stats-panel--narrow {
  max-width: 360px;
  margin: 0 auto 22px;
}

/* Sub-heading inside the panel (e.g. "Highlights" on the home widget). */
.user-stats-subhead {
  padding: 10px 0 4px;
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

/* Player links in the value column sit quietly (accent, no underline). */
.user-stat-value a { color: var(--accent-color); text-decoration: none; }
.user-stat-value a:hover { text-decoration: underline; }

.user-stats-hero {
  display: flex;
  justify-content: space-around;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border-color);
}

.user-stats-hero-fig {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.user-stats-hero-value {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-heading);
  font-weight: 800;
  line-height: 1.1;
  color: var(--primary-color);
  font-variant-numeric: tabular-nums;
}

.user-stats-hero-label {
  font-size: var(--fs-label);
  color: var(--text-muted);
  letter-spacing: 0.03em;
}

.user-stat-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 0;
  border-bottom: 1px solid var(--border-color);
}
.user-stat-row:last-child { border-bottom: none; }

.user-stat-label {
  font-size: var(--fs-meta);
  color: var(--text-muted);
}
.user-stat-value {
  font-size: var(--fs-body);
  font-weight: 700;
  color: var(--text-main);
  font-variant-numeric: tabular-nums;
}

/* Bet row semantic color classes (supplement the old id="green/red") */
.bet-correct { color: var(--success-color, #16a34a); }
.bet-wrong   { color: #ef4444; }

/* Clickable row pressed state */
.clickable-row:active td {
  background-color: #f1f5f9 !important;
}

/* -----------------------------------------------------------------------
   Pending matches list  (replaces old <table> in _list_pending.html.erb)
   ----------------------------------------------------------------------- */
.pending-list {
  width: 100%;
}

.pending-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 4px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  cursor: pointer;
}

.pending-row:hover {
  background: #f8fafc;
}

.pending-row:nth-child(even) {
  background: rgba(0, 0, 0, 0.02);
}

.pending-row:nth-child(even):hover {
  background: #f1f5f9;
}

.pending-matchup {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  font-size: var(--fs-body);
  font-weight: 600;
}

.pending-team {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex-shrink: 1;
}

.pending-sep {
  flex-shrink: 0;
  color: var(--text-muted, #64748b);
}

.pending-meta {
  flex-shrink: 0;
  display: flex;
  gap: 8px;
  align-items: center;
  color: var(--text-muted, #64748b);
  font-size: var(--fs-label);
  white-space: nowrap;
}

.pending-group {
  font-weight: 700;
}

/* Call-to-action on line 2, pushed to the right edge of the meta row */
.pending-hint {
  margin-left: auto;
  font-weight: 700;
  white-space: nowrap;
}
.pending-hint--new  { color: var(--accent-color, #2563eb); }   /* needs a tip */
.pending-hint--edit { color: var(--text-muted, #94a3b8); }       /* already tipped */

.pending-action {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}

.pending-tip-badge {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary, #1e293b);
  white-space: nowrap;
}

/* Chevron affordance — the whole row is the click target, no inline link */
.pending-chevron {
  color: var(--text-muted, #cbd5e1);
  font-size: 20px;
  line-height: 1;
  flex-shrink: 0;
}

/* Active/pressed state for pending rows */
.pending-row:active {
  background: #f1f5f9 !important;
}

/* Make sure the press is snappy — short transitions where missing */
.match-card,
.mobile-live-link,
.oauth-btn,
.live-toggle-btn,
.chart-mode-btn,
.close-overlay,
.match-form-back-link {
  transition: transform 0.05s ease-out, background-color 0.15s, opacity 0.15s, box-shadow 0.2s;
}

/* ============================================================================
   Unified form fields  (login, registration, profile, group create/edit)
   ----------------------------------------------------------------------------
   The legacy forms rendered bare browser-default inputs — tiny fixed-width
   boxes, monospace textareas. One field look for every text input/textarea,
   wrapped in :where() so it carries ZERO specificity: the specialised fields
   (.quote-input, .bets-search-input, .score-stepper-value, .match-form-select,
   .sidebar-context select) keep their own styling without needing !important.
   ========================================================================== */
:where(
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  input[type="tel"],
  input[type="url"],
  input[type="number"],
  textarea
) {
  width: 100%;
  max-width: 420px;
  box-sizing: border-box;
  margin-top: 4px;
  padding: 11px 13px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--card-bg);
  color: var(--text-main);
  font-family: inherit;
  font-size: var(--fs-ui);  /* 16px — >=16px stops iOS Safari zoom-on-focus */
  line-height: 1.4;
  transition: border-color 0.15s, box-shadow 0.15s;
}

:where(
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  input[type="tel"],
  input[type="url"],
  input[type="number"],
  textarea
):focus {
  outline: none;
  border-color: var(--accent-color);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}

textarea { min-height: 92px; resize: vertical; line-height: 1.5; }

/* Locked fields — prefilled, non-editable (e.g. name/email from an OAuth
   provider). Greyed out so it reads as "given, can't change" at a glance. */
.field-locked {
  background: var(--bg-color);
  color: var(--text-muted);
  cursor: not-allowed;
}
.field-locked-tag {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--text-muted);
  margin-left: 6px;
}

/* Form labels sit quietly above their field. */
.box label,
.box .separator > label { font-weight: 600; color: var(--text-main); }

/* ============================================================================
   .button — anchors styled as buttons (link_to ..., class: 'button').
   Mirrors the native submit-button look so action links read as real buttons
   everywhere they're used (profile hub, group management, account).
   submit_tag/button already inherit the base button rule above.
   ========================================================================== */
a.button,
.button {
  display: inline-block;
  background-color: var(--accent-color);
  color: #fff;
  padding: 10px 20px;
  border-radius: var(--radius);
  border: none;
  font-weight: 600;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
  transition: transform 0.1s, background-color 0.2s;
}
a.button:hover,
.button:hover {
  background-color: #1d4ed8;
  color: #fff;
  transform: translateY(-1px);
}

/* Secondary (outline) variant — used for the admin "Geld-Gruppe" action and
   "Abbrechen" links so the primary action stays visually dominant. */
.button--secondary,
a.button--secondary,
input[type="submit"].button--secondary,
button.button--secondary {
  background-color: var(--card-bg);
  color: var(--accent-color);
  border: 1px solid var(--border-color);
}
.button--secondary:hover,
a.button--secondary:hover,
input[type="submit"].button--secondary:hover,
button.button--secondary:hover {
  background-color: #f1f5f9;
  color: var(--accent-color);
  border-color: var(--accent-color);
}

/* Danger variant — destructive actions (delete group / cancel request). */
.button--danger,
a.button--danger,
input[type="submit"].button--danger,
button.button--danger {
  background-color: #dc2626;
  color: #fff;
  border: none;
}
.button--danger:hover,
a.button--danger:hover,
input[type="submit"].button--danger:hover,
button.button--danger:hover {
  background-color: #b91c1c;
  color: #fff;
}

/* ============================================================================
   Pool picker (registration) — a tappable selectable-card list, replacing the
   cramped 3-column table. Each pool is a full-width row the whole label taps.
   ========================================================================== */
.pool-choice-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
}
.pool-choice {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--card-bg);
  cursor: pointer;
  transition: border-color 0.15s, background-color 0.15s;
}
.pool-choice:has(input:checked) {
  border-color: var(--accent-color);
  background: rgba(37, 99, 235, 0.04);
}
.pool-choice--locked { cursor: default; }
.pool-choice input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  flex-shrink: 0;
  accent-color: var(--accent-color);
}
.pool-choice-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pool-choice-name { font-weight: 700; color: var(--text-main); }
.pool-choice-tag {
  font-size: var(--fs-label); font-weight: 600; color: var(--text-muted);
  margin-left: 6px; white-space: nowrap;
}
.pool-choice-desc { font-size: var(--fs-meta); color: var(--text-muted); }
.pool-choice-meta { font-size: var(--fs-label); color: var(--text-muted); font-weight: 600; }
.pool-choice-hint { font-size: var(--fs-meta); color: var(--text-muted); margin-top: 8px; line-height: 1.4; }

/* ----------------------------------------------------------------------------
   Pool browse — shared "browse & join free pools" treatment used by BOTH the
   registration picker (.pool-choice-list of checkboxes) and the profile "My
   Groups" join list (.group-card-list of join cards). The search field on top
   keeps a long list manageable, so the list itself just flows naturally (no
   height cap / inner scroll area).
   ---------------------------------------------------------------------------- */
.pool-browse { margin-top: 4px; }
.pool-filter {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 12px;
  margin-bottom: 10px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  font-size: var(--fs-meta);
}
.pool-filter:focus { outline: none; border-color: var(--accent-color); }
.pool-browse-empty { font-size: var(--fs-meta); color: var(--text-muted); margin-top: 10px; }
/* The search filter hides non-matching items via the `hidden` attribute. Several
   filtered items (.pool-choice, .member-row, .dm-contact) are display:flex, which
   out-ranks the UA [hidden] rule, so force the hide at higher specificity. Targets
   the actual filter hook attribute (data-pool-name) so it covers every list. */
[data-pool-name][hidden] { display: none; }

/* ============================================================================
   Group cards (Meine Gruppen) — replaces the wide multi-column table that
   overflowed on mobile. One card per membership/pool; flows vertically and
   stays readable at any width.
   ========================================================================== */
.group-card-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 8px;
}
.group-section-title {
  font-size: var(--fs-ui);
  font-weight: 700;
  color: var(--text-muted);
  margin: 22px 0 10px;
}
.group-card {
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 14px 16px;
  background: var(--card-bg);
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.1s;
}
.group-card:hover {
  border-color: var(--accent-color);
  box-shadow: 0 2px 10px rgba(15, 23, 42, 0.06);
}
.group-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}
/* Right column of the header: status badges with the settings cog tucked
   directly beneath them, right-aligned. */
.group-card-head-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  flex-shrink: 0;
}
.group-card-name { font-weight: 700; font-size: var(--fs-ui); color: var(--text-main); }
.group-card-status {
  flex-shrink: 0;
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.status--admin   { background: rgba(37, 99, 235, 0.12);  color: #1d4ed8; }
.status--member  { background: rgba(22, 163, 74, 0.12);  color: #15803d; }
.status--pending { background: rgba(245, 158, 11, 0.15); color: #b45309; }
.status--none    { background: #f1f5f9;                  color: var(--text-muted); }
.status--private { background: rgba(71, 85, 105, 0.12);  color: #475569; }
.status--money   { background: rgba(217, 119, 6, 0.14);  color: #b45309; }
/* Holds the status pill plus any attribute badges (e.g. "Privat", "Geld-Gruppe") on the right. */
.group-card-badges { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.group-card-desc { margin: 8px 0 0; font-size: var(--fs-body); color: var(--text-muted); }
.group-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
  font-size: var(--fs-meta);
  color: var(--text-muted);
}
/* Soft stat chips echoing the user-stats panel look. */
.group-card-meta > span {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  padding: 3px 10px;
}
.group-card-meta strong { color: var(--text-main); font-weight: 700; }

/* Action row: a 2-column grid on mobile (4 buttons => clean 2x2 block) that
   relaxes into a single natural-width row on wider cards. Every action — link
   or form submit — is forced to the same width/height so the set reads as one. */
/* Membership toggle only — compact buttons, left-aligned, never full width. */
.group-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}
.group-card-actions > * { margin: 0; min-width: 0; }
.group-card-actions > form { display: inline-flex; }
/* Modifiers list the input[type=submit]/button forms too, otherwise the global
   `input[type="submit"], button` rule (higher specificity) wins. */
.button--compact,
a.button--compact,
input[type="submit"].button--compact,
button.button--compact {
  width: auto;
  padding: 7px 16px;
  font-size: var(--fs-meta);
}
/* A softer "destructive" style than the solid red bar — used for leave / cancel
   so it reads as secondary, not alarming. */
.button--ghost-danger,
a.button--ghost-danger,
input[type="submit"].button--ghost-danger,
button.button--ghost-danger {
  background-color: transparent;
  color: #b91c1c;
  border: 1px solid rgba(185, 28, 28, 0.35);
}
.button--ghost-danger:hover,
a.button--ghost-danger:hover,
input[type="submit"].button--ghost-danger:hover,
button.button--ghost-danger:hover {
  background-color: rgba(185, 28, 28, 0.06);
  color: #b91c1c;
  border-color: #b91c1c;
}

/* Per-card admin menu behind a compact settings cog (right column of the
   header, under the badge). Native <details> — the body is an absolute
   dropdown so opening it doesn't reflow the card. */
.card-menu { position: relative; }
.card-menu > summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  box-sizing: border-box;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: var(--fs-meta);
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  border: 1px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-muted);
  cursor: pointer;
}
.card-menu > summary .card-menu-cog { font-size: 15px; line-height: 1; }
.card-menu > summary:hover { color: var(--accent-color); border-color: var(--accent-color); }
.card-menu > summary::-webkit-details-marker { display: none; }
.card-menu > summary::marker { content: ""; }
.card-menu[open] > summary { border-color: var(--accent-color); color: var(--accent-color); }
.card-menu-body {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 30;
  min-width: 210px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);
}
.card-menu-body form { margin: 0; }
/* The submit-button menu item ("Gruppe löschen") needs the input/button forms
   listed too, to beat the global `input[type="submit"], button` rule. */
.card-menu-item,
a.card-menu-item,
input[type="submit"].card-menu-item,
button.card-menu-item {
  display: block;
  box-sizing: border-box;
  width: 100%;
  text-align: left;
  padding: 9px 12px;
  border: none;
  background-color: transparent;
  border-radius: 8px;
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--text-main);
  text-decoration: none;
  cursor: pointer;
}
.card-menu-item:hover,
input[type="submit"].card-menu-item:hover,
button.card-menu-item:hover { background-color: var(--bg-color); }
.card-menu-item--danger,
input[type="submit"].card-menu-item--danger,
button.card-menu-item--danger { color: #b91c1c; }
.group-card-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 20px;
}
/* Pinned above the lists so "create a group" stays reachable no matter how
   many memberships/pools push the rest of the page down. */
.group-card-cta--top { margin-top: 6px; margin-bottom: 18px; }

/* ============================================================================
   Admin selection lists (group management: accept join requests, invite
   players). Per-instance section -> tappable checkbox rows -> action buttons.
   Replaces the legacy fixed-width <table style="width:40%"> layouts.
   ========================================================================== */
.admin-section { margin-bottom: 24px; }
.admin-section + .admin-section { border-top: 1px solid var(--border-color); padding-top: 18px; }
.admin-section-title {
  font-size: var(--fs-ui);
  font-weight: 700;
  color: var(--text-main);
  margin: 0 0 4px;
}
.admin-section-meta { margin: 0 0 12px; font-size: var(--fs-meta); color: var(--text-muted); }
.admin-empty { margin: 8px 0; color: var(--text-muted); font-style: italic; }

.select-list { display: flex; flex-direction: column; gap: 8px; }
.select-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--card-bg);
  cursor: pointer;
  transition: border-color 0.15s, background-color 0.15s;
}
.select-row:has(input:checked) {
  border-color: var(--accent-color);
  background: rgba(37, 99, 235, 0.04);
}
.select-row input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin: 0;
  flex-shrink: 0;
  accent-color: var(--accent-color);
}
.select-row .sel-name { font-weight: 600; color: var(--text-main); min-width: 0; }
.select-row .sel-status { margin-left: auto; font-size: var(--fs-label); font-weight: 600; white-space: nowrap; }
.select-row .sel-status.is-muted { color: var(--text-muted); }
.select-row .sel-status.is-accent { color: var(--accent-color); }

/* Action button row for admin forms (mirrors .group-card-actions). */
.admin-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.admin-actions form { margin: 0; }

/* Two equal-size actions on one row (accept / delete a join request). */
.admin-actions--row { flex-wrap: nowrap; align-items: stretch; }
.admin-actions--row > input[type="submit"] { flex: 1 1 0; width: auto; min-width: 0; }

/* Filter input above a long select-list (invite players). */
.select-filter { width: 100%; max-width: 420px; margin-bottom: 10px; }
.select-scroll { max-height: 360px; overflow-y: auto; }

/* Member list (Mitglieder page) — one row per member with an inline action. */
.member-list { display: flex; flex-direction: column; gap: 8px; }
.member-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  /* Uniform row height across all member lists (admin / DM picker / follow
     picker): name-only rows would otherwise be shorter than rows carrying a
     button or tag. border-box so min-height counts the padding. */
  box-sizing: border-box;
  min-height: 52px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--card-bg);
}
.member-row .mem-name { font-weight: 600; color: var(--text-main); min-width: 0; }
.member-row .mem-tag {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(37, 99, 235, 0.12);
  color: #1d4ed8;
}
.member-row .mem-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--fs-meta);
  color: var(--text-main);
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 2px 8px;
}
.member-row form { margin: 0; }
.button--small { padding: 6px 12px; font-size: var(--fs-meta); width: auto; }

/* Profitranks grid (money-pool prize distribution). Keep the inline-edit grid
   inside the card on mobile: small fraction inputs (the global field style would
   otherwise blow them up to full width), compact cells, horizontal-scroll safety
   net via the .table-responsive wrapper in the view. */
table.profitranks { width: 100%; }
table.profitranks input[type="text"] {
  width: 64px;
  max-width: 64px;
  min-width: 0;
  margin: 0;
  padding: 6px 8px;
  font-size: var(--fs-body);
  text-align: right;
}
@media (max-width: 768px) {
  table.profitranks { font-size: var(--fs-body); }
  table.profitranks th,
  table.profitranks td { padding: 6px 6px; }
}

/* ============================================================================
   Profile area — shared vocabulary so the hub, account and notifications
   pages read as the same family as the group cards (Meine Gruppen) and the
   rest of the modernized app. Everything below is mobile-first and uses the
   design tokens; no fixed-width tables, no inline styles.
   ========================================================================== */

/* A short muted lead paragraph under a page heading. */
.profile-lead { margin: 0 0 4px; color: var(--text-muted); font-size: var(--fs-body); }

/* --- Hub: tappable settings rows (icon · label/sublabel · chevron) --------- */
.profile-nav { display: flex; flex-direction: column; gap: 10px; }
.profile-nav-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--card-bg);
  text-decoration: none;
  color: var(--text-main);
  transition: border-color 0.15s, background-color 0.15s;
}
.profile-nav-item:hover { border-color: var(--accent-color); background: rgba(37, 99, 235, 0.04); }
.profile-nav-icon { font-size: var(--fs-heading); line-height: 1; flex-shrink: 0; }
.profile-nav-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.profile-nav-label { font-weight: 700; font-size: var(--fs-ui); }
.profile-nav-sub { font-size: var(--fs-meta); color: var(--text-muted); }
.profile-nav-chevron { margin-left: auto; color: var(--text-muted); flex-shrink: 0; font-size: var(--fs-ui); }
/* De-emphasized row sitting on its own at the bottom (logout). */
.profile-nav-item--quiet { color: var(--text-muted); }
.profile-nav-item--quiet .profile-nav-label { font-weight: 600; color: var(--text-muted); }

/* --- Notifications: stacked toggle rows (replaces overflowing table) -------- */
.notif-list { display: flex; flex-direction: column; gap: 10px; }
.notif-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background: var(--card-bg);
}
.notif-row-body { min-width: 0; flex: 1; }
.notif-row-label { font-weight: 700; color: var(--text-main); font-size: var(--fs-body); }
.notif-row-hint { margin: 2px 0 0; font-size: var(--fs-meta); color: var(--text-muted); }
.notif-row-toggles { display: flex; gap: 12px; flex-shrink: 0; }
/* Each channel toggle: a stacked icon-label + checkbox the whole block taps. */
.notif-toggle {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-label);
  color: var(--text-muted);
  cursor: pointer;
  min-width: 44px;
}
.notif-toggle input[type="checkbox"] {
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--accent-color);
}
.notif-toggle.is-na { color: #cbd5e1; cursor: default; }
/* Push toggle when browser notifications aren't active on this device. */
.notif-toggle.is-disabled { opacity: 0.4; cursor: not-allowed; }
.notif-toggle.is-disabled input[type="checkbox"] { cursor: not-allowed; }
.notif-toggle-dash { font-size: var(--fs-ui); line-height: 22px; }

/* --- Account & forms: framed sub-sections inside the card ------------------ */
.profile-section {
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 16px;
}
.profile-section:last-child { margin-bottom: 0; }
.profile-section > h3 { margin: 0 0 12px; font-size: var(--fs-ui); }
.profile-section--danger { border-color: rgba(220, 38, 38, 0.35); background: rgba(220, 38, 38, 0.03); }
.profile-section--danger > h3 { color: #dc2626; }
/* Field group inside a form section (label above a full-width control). */
.field-group { margin-bottom: 14px; }
.field-group:last-child { margin-bottom: 0; }
.field-group > label,
.field-group > .field-label { display: block; font-weight: 600; color: var(--text-main); margin-bottom: 6px; }
.field-group small { display: block; color: var(--text-muted); font-size: var(--fs-meta); margin-bottom: 6px; }
.field-group input[type="text"],
.field-group input[type="email"],
.field-group textarea { width: 100%; }
.field-readout { margin: 0; color: var(--text-main); }
.field-readout + .field-readout { margin-top: 6px; }

/* ============================================================================
   News / landing page (home#news) — bring the stats header, admin news
   postings and the social blog onto the design system. The stats list and
   the Verlauf chart were already modernized; this aligns the rest.
   ========================================================================== */

/* Stats card header: small muted label + the player's name as a tappable
   heading (links to the full stats page) — no more raw underlined link. */
.stats-header { margin-bottom: 16px; text-align: center; }
.stats-header-label {
  display: block;
  font-size: var(--fs-label);
  letter-spacing: 0.05em;
  font-weight: 700;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.stats-header-name {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-heading);
  font-weight: 700;
  color: var(--primary-color);
  text-decoration: none;
}
.stats-header-name:hover { color: var(--accent-color); }
.stats-header-arrow { color: var(--text-muted); font-weight: 400; }
/* "Verlauf" trigger centered in the panel header. The pill carries a left
   margin for its old inline use — reset it here so it sits truly centred. */
.stats-header-actions { display: flex; justify-content: center; margin-top: 10px; }
.stats-header-actions .chart-icon-btn { margin-left: 0; }

/* Player links inside the stats list (Highlights rows) — accent, not the
   default underlined hyperlink, so they sit quietly in the value column. */
.stat-value a { color: var(--accent-color); text-decoration: none; }
.stat-value a:hover { text-decoration: underline; }

/* Admin news postings rendered as tinted alert banners (info/warning/attention). */
.news-item {
  border-left: 3px solid var(--border-color);
  border-radius: 8px;
  background: #f8fafc;
  padding: 12px 14px;
  margin-bottom: 10px;
}
.news-item:last-child { margin-bottom: 0; }
.news-item-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.news-item-tag {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 1px 8px;
  border-radius: 999px;
}
.news-item-date { font-size: var(--fs-meta); color: var(--text-muted); }
.news-item-body { font-size: var(--fs-body); color: var(--text-main); line-height: 1.5; }
.news-item--info      { border-left-color: var(--accent-color); background: rgba(37, 99, 235, 0.05); }
.news-item--info .news-item-tag      { background: rgba(37, 99, 235, 0.12);  color: #1d4ed8; }
.news-item--warning   { border-left-color: #f59e0b; background: rgba(245, 158, 11, 0.07); }
.news-item--warning .news-item-tag   { background: rgba(245, 158, 11, 0.15); color: #b45309; }
.news-item--attention { border-left-color: #dc2626; background: rgba(220, 38, 38, 0.05); }
.news-item--attention .news-item-tag { background: rgba(220, 38, 38, 0.12);  color: #b91c1c; }

/* Social blog: posting form + postings list (was fully inline-styled). */
.blog-input-card textarea { width: 100%; box-sizing: border-box; }
.blog-input-card .button { margin-top: 10px; }
/* Chat card: segmented Beiträge/Nachrichten toggle + swappable panels.
   The tab buttons reuse the .modern-tabs track look (Anstehende/Ergebnisse). */
.chat-tabs { margin-bottom: 16px; }
.chat-tab {
  flex: 1;
  text-align: center;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--fs-body);
  padding: 9px 12px;
  border-radius: calc(var(--radius) - 5px);
  transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;
}
.chat-tab:hover { color: var(--accent-color); }
.chat-tab.active {
  background-color: var(--accent-color);
  color: #fff;
  box-shadow: 0 1px 3px rgba(37, 99, 235, 0.35);
}
.chat-panel { display: none; }
.chat-panel.is-active { display: block; }
.chat-card .button { margin-top: 10px; }
.chat-card textarea { width: 100%; box-sizing: border-box; }
/* Feed sits below the composer, separated by a hairline. */
.blog-feed { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border-color); }
.blog-load-more {
  display: block;
  width: 100%;
  margin-top: 14px;
  padding: 10px;
  background: none;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: var(--fs-meta);
  cursor: pointer;
}
.blog-load-more:hover { background: rgba(0, 0, 0, 0.04); color: var(--text-main); }
.blog-postings { display: flex; flex-direction: column; }
.blog-post { padding: 12px 0; border-bottom: 1px solid var(--border-color); }
.blog-post:first-child { padding-top: 0; }
.blog-post:last-child { border-bottom: none; padding-bottom: 0; }
.blog-post-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.blog-post-avatar {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--primary-color);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: var(--fs-meta);
  line-height: 1;
  text-transform: uppercase;
}
.blog-post-meta {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.blog-post-author {
  font-weight: 700;
  color: var(--text-main);
  font-size: var(--fs-body);
  text-decoration: none;
}
.blog-post-author:hover { text-decoration: underline; }
.blog-post-time { font-size: var(--fs-meta); color: var(--text-muted); white-space: nowrap; }
.blog-post-body { font-size: var(--fs-body); color: var(--text-main); line-height: 1.5; word-wrap: break-word; }
.blog-post-actions { margin-left: auto; display: flex; align-items: center; gap: 2px; }
.blog-post-delete { display: inline-flex; margin: 0; }
.blog-post-icon-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: var(--fs-body);
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 6px;
}
.blog-post-icon-btn:hover { color: var(--text-main); background: rgba(0, 0, 0, 0.06); }
.blog-post-delete .blog-post-icon-btn:hover { color: #dc2626; background: rgba(220, 38, 38, 0.08); }
.blog-post.is-editing .blog-post-body { display: none; }
.blog-edit-form { margin-top: 8px; }
.blog-edit-buttons { display: flex; gap: 8px; margin-top: 8px; }
.blog-empty { padding: 8px 0; }
.pagination-wrapper { margin-top: 16px; }

/* Mini WYSIWYG editor (shared/_wysiwyg) + the formatting it can produce. */
.wysiwyg {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  overflow: hidden;
  background: var(--card-bg, #fff);
}
.wysiwyg-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border-color);
  background: rgba(0, 0, 0, 0.02);
}
.wysiwyg-btn {
  min-width: 30px;
  height: 28px;
  padding: 0 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  cursor: pointer;
  font-size: var(--fs-body);
  color: var(--text-main);
  line-height: 1;
}
.wysiwyg-btn:hover { background: rgba(0, 0, 0, 0.06); }
.wysiwyg-btn.is-active {
  background: var(--accent-color);
  border-color: var(--accent-color);
  color: #fff;
}
.wysiwyg-colors { display: inline-flex; gap: 4px; padding: 0 4px; }
.wysiwyg-color {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.15);
  cursor: pointer;
  padding: 0;
}
/* Reset-to-default swatch: a plain black circle like the preset swatches. */
.wysiwyg-color--default { background: #000; }
/* Active swatch gets an accent ring (white inner gap keeps it legible). */
.wysiwyg-color.is-active {
  box-shadow: 0 0 0 1px #fff, 0 0 0 3px var(--accent-color);
}
.wysiwyg-editor {
  min-height: 72px;
  max-height: 260px;
  overflow-y: auto;
  padding: 10px 12px;
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--text-main);
  outline: none;
}
.wysiwyg-editor:empty::before {
  content: attr(data-placeholder);
  color: var(--text-muted);
}
.wysiwyg-editor ul, .blog-post-body ul, .dm-bubble ul { margin: 4px 0; padding-left: 22px; }

/* Inline formatting palette (must match RichTextHelper::ALLOWED_CLASSES). */
.fmt-c-red    { color: #dc2626; }
.fmt-c-blue   { color: #2563eb; }
.fmt-c-green  { color: #16a34a; }
.fmt-c-orange { color: #ea580c; }
.fmt-c-purple { color: #7c3aed; }
.mention { color: var(--primary-color); font-weight: 600; }

/* @mention autocomplete dropdown (appended to <body> by wysiwyg.js). */
.mention-menu {
  z-index: 2000;
  min-width: 200px;
  max-width: 280px;
  background: #fff;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  font-size: var(--fs-body);
}
.mention-item {
  display: flex;
  flex-direction: column;
  padding: 6px 10px;
  cursor: pointer;
}
.mention-item.is-active, .mention-item:hover { background: rgba(0, 0, 0, 0.06); }
.mention-item-name { color: var(--text-main); font-weight: 600; }
.mention-item-user { color: var(--text-muted); font-size: var(--fs-meta); }

/* Emoji reactions row. */
.reactions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.reaction-form { margin: 0; display: inline-flex; }
.reaction-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: none;
  cursor: pointer;
  font-size: var(--fs-meta);
  line-height: 1.6;
}
.reaction-btn:hover { background: rgba(0, 0, 0, 0.05); }
.reaction-btn.is-mine { border-color: var(--primary-color); background: rgba(233, 69, 96, 0.10); }
.reaction-btn.is-zero { opacity: 0.55; }
.reaction-btn.is-zero:hover { opacity: 1; }
.reaction-count { font-weight: 700; color: var(--text-main); }

/* Replies (one level) + reply affordances. */
.blog-replies {
  margin: 10px 0 0 18px;
  padding-left: 12px;
  border-left: 2px solid var(--border-color);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.blog-reply { padding: 0; border-bottom: none; }
.blog-reply .blog-post-avatar { width: 26px; height: 26px; }
.blog-reply-actions { margin-top: 6px; }
.blog-link-btn {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--primary-color);
  font-size: var(--fs-meta);
  font-weight: 600;
}
.blog-link-btn:hover { text-decoration: underline; }
.blog-reply-form { margin-top: 8px; }

/* Sidebar unread badge / generic count pill. */
.nav-badge {
  display: inline-block;
  min-width: 18px;
  padding: 0 6px;
  margin-left: 4px;
  border-radius: 999px;
  background: var(--primary-color);
  color: #fff;
  font-size: var(--fs-label);
  font-weight: 700;
  line-height: 18px;
  text-align: center;
  vertical-align: middle;
}

/* ---- Direct messages ---------------------------------------------------- */
.dm-inbox { display: flex; flex-direction: column; }
.dm-inbox-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--border-color);
  text-decoration: none;
  color: inherit;
}
.dm-inbox-row:last-child { border-bottom: none; }
.dm-inbox-row:hover { background: rgba(0, 0, 0, 0.03); }
.dm-avatar {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--primary-color);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  text-transform: uppercase;
}
.dm-inbox-main { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.dm-inbox-name { font-weight: 700; color: var(--text-main); }
.dm-inbox-preview {
  color: var(--text-muted);
  font-size: var(--fs-meta);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dm-inbox-time { font-size: var(--fs-meta); color: var(--text-muted); white-space: nowrap; }
.dm-inbox-row.is-unread .dm-inbox-name,
.dm-inbox-row.is-unread .dm-inbox-preview { color: var(--text-main); font-weight: 700; }

.dm-thread-header { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.dm-thread-header h2 { margin: 0; }
.dm-back { font-size: var(--fs-meta); color: var(--primary-color); text-decoration: none; }
.dm-back:hover { text-decoration: underline; }
.dm-thread {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 55vh;
  overflow-y: auto;
  padding: 4px 2px 12px;
}
.dm-empty { padding: 12px 0; }
.dm-bubble { max-width: 78%; padding: 8px 12px; border-radius: 14px; }
.dm-bubble-body { font-size: var(--fs-body); line-height: 1.45; word-wrap: break-word; }
.dm-bubble-time { font-size: var(--fs-label); color: var(--text-muted); margin-top: 2px; text-align: right; }
.dm-in  { align-self: flex-start; background: #f1f3f5; color: var(--text-main); border-bottom-left-radius: 4px; }
.dm-out { align-self: flex-end; background: rgba(233, 69, 96, 0.12); border-bottom-right-radius: 4px; }
.dm-out .dm-bubble-time { color: var(--text-muted); }
.dm-compose { margin-top: 12px; }
.dm-compose .button { margin-top: 8px; }

/* ---- Inbox: collapsible sections, new-message picker, per-row menu ---- */
.dm-section, .dm-new { margin-bottom: 12px; }
.dm-section > summary, .dm-new-summary, .dm-row-menu > summary {
  cursor: pointer;
  list-style: none;            /* hide default disclosure marker */
}
.dm-section > summary::-webkit-details-marker,
.dm-new-summary::-webkit-details-marker,
.dm-row-menu > summary::-webkit-details-marker { display: none; }

.dm-section > summary {
  font-weight: 700;
  color: var(--text-main);
  padding: 8px 0;
  border-bottom: 1px solid var(--border-color);
}
.dm-count { color: var(--text-muted); font-weight: 600; }
.dm-hint { padding: 10px 2px; }

/* "Neue Nachricht" button (the picker's summary) */
.dm-new-summary {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  background: var(--accent-color);
  color: #fff;
  font-weight: 600;
  font-size: var(--fs-meta);
  border-radius: 999px;
}
.dm-new-summary:hover { filter: brightness(1.05); }
.dm-new-body { margin-top: 10px; }
.dm-search {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 12px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  margin-bottom: 8px;
}
.dm-contacts { max-height: 280px; overflow-y: auto; }
.dm-contact {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 4px;
  text-decoration: none;
  color: var(--text-main);
  border-bottom: 1px solid var(--border-color);
}
.dm-contact:last-child { border-bottom: none; }
.dm-contact:hover { background: rgba(0, 0, 0, 0.03); }
.dm-contact .dm-avatar { width: 32px; height: 32px; }

/* Active-follow banner on the bet form: "Du folgst X" with a ✕ to revert. */
.follow-status {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; margin-bottom: 10px;
  background: var(--accent-soft, rgba(37, 99, 235, 0.10));
  border-radius: var(--radius);
  font-size: var(--fs-meta);
}
/* display:flex above would otherwise beat the [hidden] default, so the banner
   never hides — keep the attribute authoritative. */
.follow-status[hidden] { display: none; }
.follow-status strong { font-weight: 700; }
.follow-clear {
  margin-left: auto; flex-shrink: 0;
  border: none; background: transparent; cursor: pointer;
  font-size: 15px; line-height: 1; color: var(--text-muted, #64748b);
  padding: 4px 7px; border-radius: 999px;
}
.follow-clear:hover { background: rgba(0, 0, 0, 0.08); color: var(--text-primary, #1e293b); }

/* Follow-picker toggle: a consistent grey pill (not the accent-blue DM style),
   the same whether or not a follow is active, with a chevron that flips when the
   section is expanded. */
/* Secondary-action look matching the form's "Abbrechen" button
   (.match-form-cancel-btn): transparent, neutral border, muted text. */
.follow-picker[hidden] { display: none; }
.follow-picker .dm-new-summary {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border-color);
}
.follow-picker .dm-new-summary:hover {
  background: var(--bg-secondary);
  color: var(--text-primary);
}
/* Reuse the app's chevron glyph/size (.pending-chevron): "›" at 20px, rotated to
   point down when collapsed and up when expanded. */
.follow-picker .dm-new-summary::after {
  content: "›";
  display: inline-block;
  margin-left: 8px;
  font-size: 20px;
  line-height: 1;
  color: var(--text-muted, #64748b);
  transform: rotate(90deg);
  transition: transform 0.15s ease;
}
.follow-picker[open] .dm-new-summary::after { transform: rotate(-90deg); }

/* Compact pickers (DM "Neue Nachricht" + bet follow picker) reuse the
   group-admin member list (.member-row) as one harmonised searchable user list:
   capped height, no underline on link rows, hover affordance. */
.dm-new .member-list { max-height: 300px; overflow-y: auto; }
.dm-new .member-row { text-decoration: none; }
.dm-new .member-row:hover { background: rgba(0, 0, 0, 0.03); }

/* The follow picker uses the list as a single-select: the native radio is
   hidden; the checked row is highlighted and ticked. */
/* position:relative contains the hidden absolute radio inside its row. Without
   it the radio anchors to the document and, with many members, the stack of
   off-flow radios stretches page height far past the (clipped) 300px list —
   ballooning the bet page when the picker is open. */
.follow-picker .follow-row { cursor: pointer; position: relative; }
.follow-picker .follow-row input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.follow-picker .follow-row:has(input:checked) {
  border-color: var(--accent-color);
  background: var(--accent-soft, rgba(37, 99, 235, 0.10));
}
.follow-picker .follow-row:has(input:checked) .mem-name { font-weight: 700; }
.follow-picker .follow-row:has(input:checked)::after {
  content: "✓"; margin-left: auto; color: var(--accent-color); font-weight: 700;
}

/* Inline per-row actions: direct mute icon + hide text (no hidden ⋯ menu). */
.dm-inbox-row-wrap { display: flex; align-items: center; }
.dm-inbox-row-wrap .dm-inbox-row { flex: 1; min-width: 0; }
.dm-row-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.dm-act-form { margin: 0; }
.dm-icon-btn {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 6px;
  font-size: 1.1em;
  line-height: 1;
  opacity: 0.55;                 /* a bell on every row stays quiet… */
}
.dm-icon-btn:hover, .dm-icon-btn.is-muted { opacity: 1; }   /* …loud when muted */
.dm-text-btn {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 6px;
  font-size: var(--fs-meta);
  color: var(--accent-color);
}
.dm-text-btn:hover { text-decoration: underline; }

/* Thread: back button shares the compose row, right-aligned next to Senden. */
.dm-compose-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 8px; }
.dm-compose-actions .button { margin-top: 0; }
