:root {
  --bg: #0f1115;
  --panel: #171b22;
  --panel-strong: #202632;
  --line: #2a3140;
  --text: #f4f7fb;
  --muted: #9da8bb;
  --accent: #6ea8fe;
  --accent-strong: #3d7bff;
  --success: #22c55e;
  --warning: #f59e0b;
  --danger: #ef4444;
  --shadow: 0 18px 45px rgba(0, 0, 0, 0.32);
  /* Saturated band fills for the scoreboard bar. The .pop-effort-band rules are
     light TEXT tints for the same bands and are deliberately separate values. */
  --band-below: #e5484d;
  --band-minimum: #f0883e;
  --band-above: #d9c34a;
  --band-well-above: #6ee7a0;
  --band-complete: #16a34a;
  /* Grey on purpose: "not due yet" is the absence of a grade, not a bad one. */
  --band-fresh: rgba(148, 163, 184, 0.34);
  font-family: Inter, "Segoe UI", Roboto, sans-serif;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: linear-gradient(180deg, #0b0d12 0%, #10131a 100%);
  color: var(--text);
}

/* Native dropdown menus must keep readable text even on a light OS theme. */
select {
  color-scheme: dark;
}

select option,
select optgroup {
  color: var(--text);
  background-color: var(--panel);
}

.app-shell {
  width: min(1400px, calc(100% - 32px));
  margin: 0 auto;
  padding: 18px 0 36px;
}

.hero,
.card {
  background: rgba(23, 27, 34, 0.92);
  border: 1px solid var(--line);
  border-radius: 20px;
  box-shadow: var(--shadow);
}

/* One compact bar: identity on the left, every destination and action on the
   right. It is chrome on every page, so it costs a row, not a screenful. */
.hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 16px;
  margin-bottom: 10px;
}

.hero-identity {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.hero-logo {
  width: 34px;
  height: 34px;
  object-fit: contain;
  flex-shrink: 0;
}

.hero h1 {
  font-size: 1.15rem;
  line-height: 1.2;
}

.eyebrow {
  margin: 0 0 3px;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.78rem;
  font-weight: 700;
}

.hero .hero-copy {
  margin: 1px 0 0;
  font-size: 0.8rem;
  max-width: 46ch;
}

h1,
h2 {
  margin: 0;
}

.hero-copy,
.section-copy {
  color: var(--muted);
  margin: 5px 0 0;
  max-width: 70ch;
  line-height: 1.4;
  font-size: 0.88rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-content: flex-start;
  justify-content: flex-end;
}

.page-nav {
  flex: 1 1 auto;
  min-width: 0;
  gap: 5px;
}

.page-nav-primary,
.page-nav-secondary {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  gap: 5px;
  justify-content: flex-end;
}

.page-nav .button {
  padding: 6px 10px;
  border-radius: 9px;
  font-size: 0.83rem;
  font-weight: 600;
}

.page-nav .button[aria-current="page"] {
  background: rgba(110, 168, 254, 0.18);
  border-color: rgba(110, 168, 254, 0.58);
  color: var(--text);
  box-shadow: inset 0 0 0 1px rgba(110, 168, 254, 0.18);
  pointer-events: none;
}

.sync-hint {
  width: 100%;
  font-size: 0.82rem;
}

.grid {
  display: grid;
  gap: 20px;
  margin-top: 20px;
}

.two-columns {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.card {
  padding: 14px 16px;
}

.section-heading {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  align-items: flex-start;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

.section-summary {
  display: grid;
  gap: 8px;
}

.section-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-start;
  margin-left: auto;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}

/* Summer-event summary has 5 metrics; keep them on a single row. */
#summer-event-summary-cards {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

.summary-card {
  background: var(--panel-strong);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 18px;
}

.summary-card strong {
  display: block;
  font-size: 1.75rem;
  margin-bottom: 8px;
}

.summary-card span {
  color: var(--muted);
}

.member-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

#member-overview .member-card {
  padding: 11px 13px;
  border-radius: 13px;
}

#member-overview .member-card h3 {
  margin: 6px 0 2px;
  font-size: 0.98rem;
}

#member-overview .member-status-edit {
  margin-top: 4px;
  gap: 2px;
}

#member-overview .member-status-edit .inline-select {
  padding: 4px 6px;
  font-size: 0.85rem;
}

/* Member directory: one line per member. Status is a coloured dot, and only an
   exception (penalty, giveaway due, paused) gets a word. */
#member-overview {
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 6px;
}

.member-chip {
  display: grid;
  gap: 5px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel-strong);
}

.member-chip.danger {
  border-color: rgba(239, 68, 68, 0.45);
}

.member-chip.warning {
  border-color: rgba(245, 158, 11, 0.45);
}

.member-chip.info {
  border-color: rgba(110, 168, 254, 0.45);
}

.member-chip-line {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  font-size: 0.85rem;
}

.member-chip-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--success);
}

.member-chip.danger .member-chip-dot {
  background: var(--danger);
}

.member-chip.warning .member-chip-dot {
  background: var(--warning);
}

.member-chip.info .member-chip-dot {
  background: var(--accent);
}

.member-chip-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.member-chip-flag {
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 600;
  white-space: nowrap;
}

.member-chip-flag.danger {
  background: rgba(239, 68, 68, 0.16);
  color: #ffd0d0;
}

.member-chip-flag.warning {
  background: rgba(245, 158, 11, 0.16);
  color: #ffe3ad;
}

.member-chip-flag.info {
  background: rgba(110, 168, 254, 0.16);
  color: #d4e5ff;
}

.member-chip-stats {
  margin-left: auto;
  color: var(--muted);
  font-size: 0.76rem;
  white-space: nowrap;
}

.member-chip-stats b {
  color: var(--text);
}

.member-chip-editors {
  display: flex;
  gap: 5px;
}

.member-chip-editors .inline-select {
  flex: 1 1 0;
  min-width: 0;
  padding: 3px 5px;
  font-size: 0.76rem;
}

#member-overview .penalty-owed-card {
  grid-column: 1 / -1;
  padding: 12px 14px 14px;
}

/* The cycle reminder stays a one-line summary; the cycles page owns its detail. */
#member-overview .member-card.neutral.penalty-owed-card {
  padding: 8px 11px;
}

.penalty-inline-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}

.penalty-inline-list li {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.83rem;
}

.penalty-inline-member {
  font-weight: 600;
}

.penalty-inline-due {
  color: #fca5a5;
  font-size: 0.74rem;
}

/* Member directory: both stats labelled and the same weight. The old card made
   an unlabeled date its loudest element. */
.member-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 6px 0 0;
}

.member-stats > div {
  display: flex;
  align-items: baseline;
  gap: 5px;
}

.member-stats dt {
  color: var(--muted);
  font-size: 0.76rem;
}

.member-stats dd {
  margin: 0;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
}

.inline-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  align-self: flex-end;
  padding-bottom: 9px;
  color: var(--muted);
  font-size: 0.88rem;
  white-space: nowrap;
  cursor: pointer;
}

.inline-toggle input {
  accent-color: var(--accent);
  cursor: pointer;
}

.section-filters .button {
  align-self: flex-end;
}

#member-overview-summary {
  margin: 0 0 10px;
}

/* The card lives in the member grid, so `.member-card strong` (a 1.3rem block)
   would hit any bold text inside it. Nothing here emits <strong>, but keep the
   guard so a future edit can't reintroduce the blow-up. */
.penalty-owed-card strong {
  display: inline;
  margin: 0;
  font-size: inherit;
}

.penalty-card-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

#member-overview .penalty-owed-card .penalty-card-head h3 {
  margin: 0;
  font-size: 1.05rem;
}

.penalty-card-link {
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}

.penalty-card-link:hover {
  text-decoration: underline;
}

/* Members flow side by side, so the usual 2-3 penalties fill one row instead of
   stacking down the page. The cap only bites when a Steam refresh flips a batch
   of deadlines at once. */
.penalty-groups {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr));
  align-items: start;
  gap: 12px;
  margin-top: 12px;
  max-height: 560px;
  overflow: auto;
}

.penalty-group {
  display: grid;
  max-width: 250px;
  gap: 6px;
  align-content: start;
}

.penalty-group-name {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
}

.penalty-group-count {
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(239, 68, 68, 0.18);
  border: 1px solid rgba(239, 68, 68, 0.35);
  font-size: 0.75rem;
  font-weight: 600;
  color: #fca5a5;
}

.penalty-tiles {
  display: grid;
  gap: 8px;
}

.penalty-thumb-link {
  display: block;
  line-height: 0;
}

.penalty-thumb {
  display: block;
  width: 100%;
  aspect-ratio: 460 / 215;
  object-fit: cover;
  border-radius: 9px;
  background: linear-gradient(135deg, #1d2633 0%, #11161e 100%);
  border: 1px solid rgba(255, 255, 255, 0.04);
}

.penalty-thumb.placeholder {
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 0.8rem;
}

.penalty-tile {
  display: grid;
  gap: 7px;
  align-content: start;
  padding: 9px;
  border: 1px solid var(--line);
  border-left: 3px solid rgba(239, 68, 68, 0.65);
  border-radius: 12px;
  background: rgba(15, 17, 21, 0.55);
}

.penalty-tile-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

/* The badge is a fixed-width fact; only the title may wrap, and at most twice so
   a long store name can't make one tile taller than its neighbours. */
.penalty-tile-head .badge {
  flex: 0 0 auto;
  white-space: nowrap;
}

.penalty-tile-title {
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.penalty-tile-meta {
  font-size: 0.78rem;
  color: var(--muted);
}

.penalty-meters {
  display: grid;
  gap: 6px;
}

.penalty-meter {
  display: grid;
  gap: 3px;
}

.penalty-meter-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.76rem;
  color: var(--muted);
  white-space: nowrap;
}

.penalty-meter-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.penalty-meter-value {
  flex: 0 0 auto;
}

.penalty-meter-value {
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.penalty-meter-track {
  height: 5px;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.18);
  overflow: hidden;
}

.penalty-meter-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--danger);
}

.penalty-meter-fill.is-met {
  background: var(--success);
}

.penalty-meter-note {
  color: #fca5a5;
}

.penalty-meter-note.is-met {
  color: var(--success);
}

.penalty-status {
  display: block;
  font-size: 0.8rem;
  color: var(--muted, #9fb0c6);
  opacity: 0.85;
}

.penalty-copy {
  display: grid;
  gap: 1px;
  justify-self: stretch;
  text-align: left;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px solid rgba(110, 168, 254, 0.35);
  background: #1a2233;
  color: #f4f7fb;
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}

.penalty-copy-title {
  font-weight: 600;
}

/* Spells out that the click loads the clipboard, so the paste is expected. */
.penalty-copy-hint {
  font-size: 0.72rem;
  color: var(--muted);
}

.penalty-copy.is-copied .penalty-copy-hint {
  color: #86efac;
}

.penalty-copy.is-failed .penalty-copy-hint {
  color: #fca5a5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.penalty-copy:hover {
  border-color: rgba(110, 168, 254, 0.6);
}

.penalty-copy.is-copied {
  border-color: rgba(34, 197, 94, 0.55);
  color: #86efac;
}

.penalty-copy.is-failed {
  border-color: rgba(239, 68, 68, 0.55);
  color: #fca5a5;
}

/* Long-form rules stay out of the way until asked for. */
.rule-details {
  display: inline;
}

.rule-details > summary {
  display: inline;
  margin-left: 6px;
  color: var(--accent);
  cursor: pointer;
  font-size: 0.82rem;
}

.rule-details[open] > summary {
  display: block;
  margin: 6px 0 4px;
}

.rule-details[open] {
  display: block;
  margin-top: 4px;
}

.penalty-page-groups {
  display: grid;
  gap: 18px;
}

/* One section per deadline, so each wave of penalties reads as a set. */
.penalty-date-group {
  display: grid;
  gap: 10px;
  padding: 13px 14px;
  border: 1px solid var(--line);
  border-left: 3px solid rgba(239, 68, 68, 0.5);
  border-radius: 14px;
  background: rgba(15, 17, 21, 0.4);
}

.penalty-date-group.settled {
  border-left-color: rgba(34, 197, 94, 0.5);
}

.penalty-date-heading {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.penalty-date-heading h3 {
  margin: 0;
  font-size: 1rem;
}

.penalty-date-heading .meta-line {
  margin-top: 0;
}

.penalty-tiles-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  align-items: start;
  gap: 10px;
}

.penalty-tile-member {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--accent);
}

.penalty-tile.settled {
  border-left-color: rgba(34, 197, 94, 0.6);
}

/* --- Penalties page ---------------------------------------------------- */

.penalties-summary-grid {
  margin-bottom: 14px;
}

/* The counts are the page's main filter, so they are buttons, not text. */
.penalties-summary-card {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--text);
  cursor: pointer;
  padding: 14px 16px;
}

.penalties-summary-card strong {
  font-size: 1.6rem;
  margin-bottom: 4px;
}

.penalties-summary-card:hover {
  border-color: rgba(110, 168, 254, 0.45);
}

.penalties-summary-card.is-active {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(110, 168, 254, 0.35);
}

.penalties-summary-card.danger strong {
  color: #ffd0d0;
}

.penalties-summary-card.warning strong {
  color: #ffe3ad;
}

.penalties-summary-card.success strong {
  color: #c7f9d6;
}

.penalties-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.penalties-controls-right {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-left: auto;
}

.segmented {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #0f131a;
}

.segmented-option {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted);
  border-radius: 9px;
  padding: 7px 13px;
  font: inherit;
  font-size: 0.86rem;
  cursor: pointer;
}

.segmented-option:hover {
  color: var(--text);
}

.segmented-option.is-active {
  background: rgba(110, 168, 254, 0.16);
  border: 1px solid rgba(110, 168, 254, 0.4);
  padding: 6px 12px;
  color: var(--text);
  font-weight: 600;
}

.pill.warning {
  background: rgba(245, 158, 11, 0.14);
  color: #ffe3ad;
  border-color: rgba(245, 158, 11, 0.35);
}

.pill.danger {
  background: rgba(239, 68, 68, 0.14);
  color: #ffd0d0;
  border-color: rgba(239, 68, 68, 0.35);
}

/* Meter inside a table cell: figures on top, bar underneath. */
.penalty-cell-meter {
  display: grid;
  gap: 4px;
  min-width: 96px;
}

.penalty-date-cell {
  white-space: nowrap;
}

.penalty-date-label {
  color: var(--muted);
  font-size: 0.78rem;
}

.penalty-row.settled td {
  background: rgba(34, 197, 94, 0.04);
}

.penalty-row.overdue td {
  background: rgba(239, 68, 68, 0.05);
}

.penalty-description {
  padding: 1px 6px;
  border-radius: 6px;
  background: rgba(148, 163, 184, 0.16);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.82rem;
  white-space: nowrap;
}

.table-action-button {
  padding: 4px 12px;
  font-size: 0.82rem;
  border-radius: 8px;
  border: 1px solid rgba(110, 168, 254, 0.35);
  background: #1a2233;
  color: #f4f7fb;
  cursor: pointer;
}

.table-action-button:hover {
  border-color: rgba(110, 168, 254, 0.6);
}

.member-card {
  background: var(--panel-strong);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 16px;
}

.member-card.negative {
  border-color: rgba(239, 68, 68, 0.45);
  box-shadow: inset 0 0 0 1px rgba(239, 68, 68, 0.12);
}

.member-card.neutral {
  border-color: rgba(245, 158, 11, 0.45);
  box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.12);
}

.member-card h3 {
  margin: 0 0 8px;
  font-size: 1rem;
}

.member-card strong {
  display: block;
  margin-top: 10px;
  font-size: 1.3rem;
}

.member-card-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.member-card-meta {
  display: grid;
  gap: 6px;
  margin-top: 10px;
  color: var(--muted);
  font-size: 0.84rem;
  line-height: 1.4;
}

.ratio-value {
  font-weight: 700;
}

.ratio-value.ratio-success {
  color: var(--success);
}

.ratio-value.ratio-warning {
  color: var(--warning);
}

.ratio-value.ratio-danger {
  color: var(--danger);
}

/* Wraps instead of scrolling sideways: the whole set is visible at once and the
   cards use the full width of the dashboard. */
.giveaway-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 12px;
}

.giveaway-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--panel-strong);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 10px;
  overflow: hidden;
}

.giveaway-card:hover {
  border-color: rgba(110, 168, 254, 0.4);
}

.giveaway-image-link {
  display: block;
  line-height: 0;
}

.giveaway-card-body {
  padding: 0;
  min-width: 0;
  display: grid;
  gap: 4px;
  align-content: start;
}

.giveaway-penalty-link {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin: 4px 0;
  padding: 5px 8px;
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: 8px;
  background: rgba(239, 68, 68, 0.12);
  color: #ffd0d0;
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.4;
  overflow-wrap: anywhere;
  text-decoration: none;
}

.giveaway-penalty-link.is-settled {
  border-color: rgba(34, 197, 94, 0.3);
  background: rgba(34, 197, 94, 0.12);
  color: #c7f9d6;
}

.giveaway-penalty-link.is-in-progress {
  border-color: rgba(244, 184, 83, 0.35);
  background: rgba(244, 184, 83, 0.1);
  color: #ffe2ad;
}

.penalty-tile.in-progress {
  border-color: rgba(244, 184, 83, 0.35);
}

.penalty-tile.in-progress .penalty-tile-head {
  flex-direction: column;
}

.penalty-tile.in-progress .penalty-tile-title {
  display: block;
}

a.giveaway-penalty-link:hover {
  text-decoration: underline;
}

.giveaway-winner {
  font-size: 0.8rem;
  color: var(--success);
}

.giveaway-winner::before {
  content: "Won by ";
  color: var(--muted);
}

.giveaway-winner.is-empty {
  color: var(--muted);
}

.giveaway-winner.is-empty::before {
  content: "";
}

.giveaway-creator {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.giveaway-image,
.game-thumb,
.giveaway-thumb {
  display: block;
  background: linear-gradient(135deg, #1d2633 0%, #11161e 100%);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 12px;
}

.giveaway-thumb {
  width: 140px;
  min-width: 140px;
  height: 60px;
  object-fit: cover;
}

/* The thumbnail set the row height at 94px across 100 rows. Half the size still
   identifies the game and lets the text decide how tall a row is. */
#summer-event-giveaways-table .giveaway-thumb {
  width: 96px;
  min-width: 96px;
  height: 45px;
}

.giveaway-thumb.placeholder {
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 0.8rem;
}

.giveaway-image {
  width: 100%;
  aspect-ratio: 460 / 215;
  object-fit: cover;
  border-radius: 10px;
}

/* 230x85 set a 106px floor under every PoP row regardless of its content. Half
   the size still identifies the game and lets the text decide the row height. */
.game-thumb {
  width: 112px;
  min-width: 112px;
  height: 52px;
  object-fit: cover;
}

.game-cell-body {
  min-width: 0;
}

.game-cell-title {
  font-weight: 600;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.giveaway-image.placeholder,
.game-thumb.placeholder {
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 0.8rem;
}

/* Two lines max, then ellipsis: long store titles used to push the card taller
   than its neighbours and break the grid's rhythm. */
.giveaway-title {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.giveaway-title a,
.linked-title {
  color: var(--text);
  text-decoration: none;
}

.giveaway-title a:hover,
.linked-title:hover {
  color: var(--accent);
}

.penalty-ga-link {
  margin-left: 6px;
  color: var(--muted);
  font-size: 0.8rem;
  text-decoration: none;
  white-space: nowrap;
}

.penalty-ga-link:hover {
  color: var(--accent);
  text-decoration: underline;
}

.giveaway-meta-line {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  color: var(--muted);
  font-size: 0.76rem;
}

.game-cell {
  display: flex;
  gap: 10px;
  align-items: center;
  min-width: 0;
}

.stack {
  display: grid;
  gap: 12px;
}

.sync-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

.sync-actions .button {
  padding: 6px 10px;
  font-size: 0.82rem;
}

/* The sync strip is the same component on every page: one line, always visible,
   showing when each source was last updated. */
.sync-card {
  padding: 9px 14px;
}

.sync-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
}

.sync-bar-title {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.sync-status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 16px;
  flex: 1 1 auto;
  min-width: 0;
}

/* The sync tools live in the header now, so the strip itself is one line. */
.hero-sync-actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-left: 10px;
  margin-left: 4px;
  border-left: 1px solid var(--line);
}

.hero-sync-actions .button {
  padding: 6px 10px;
  border-radius: 9px;
  font-size: 0.83rem;
}

.sync-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding-left: 9px;
  border-left: 2px solid var(--line);
  font-size: 0.8rem;
  white-space: nowrap;
}

.sync-chip.success {
  border-left-color: rgba(34, 197, 94, 0.6);
}

.sync-chip.info {
  border-left-color: rgba(110, 168, 254, 0.6);
}

.sync-chip.warning {
  border-left-color: rgba(245, 158, 11, 0.6);
}

.sync-chip-label {
  color: var(--muted);
}

.sync-chip-value {
  color: var(--text);
  font-weight: 600;
}

.sync-chip-ago {
  color: var(--muted);
  font-size: 0.74rem;
}

.sync-collector-status .sync-collector-ok {
  color: var(--muted);
}

.sync-collector-status .sync-collector-warn {
  color: #f5b955;
  font-weight: 700;
  text-decoration: none;
}

.sync-collector-status a.sync-collector-warn:hover {
  text-decoration: underline;
}

.inline-filter {
  display: grid;
  gap: 6px;
  color: var(--muted);
  font-size: 0.88rem;
  min-width: 180px;
}

.inline-filter select {
  background: #0f131a;
  border: 1px solid #313948;
  color: var(--text);
  border-radius: 12px;
  padding: 9px 12px;
  font: inherit;
}

.inline-filter input {
  background: #0f131a;
  border: 1px solid #313948;
  color: var(--text);
  border-radius: 12px;
  padding: 9px 12px;
  font: inherit;
}

.alert-card {
  border: 1px solid var(--line);
  background: var(--panel-strong);
  border-left-width: 3px;
  border-radius: 12px;
  padding: 10px 12px;
}

.alert-card.warning {
  border-left-color: var(--warning);
}

.alert-card.danger {
  border-left-color: var(--danger);
}

.alert-card.info {
  border-left-color: var(--accent);
}

.alert-card.success {
  border-left-color: var(--success);
}

.alert-card h3 {
  margin: 0 0 6px;
  font-size: 0.98rem;
}

.alert-card p,
.alert-card ul {
  margin: 0;
  color: var(--muted);
  line-height: 1.4;
  font-size: 0.92rem;
}

.alert-card ul {
  padding-left: 18px;
}

.pill,
.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 999px;
  padding: 6px 10px;
  font-size: 0.78rem;
  font-weight: 700;
}

.pill {
  background: rgba(110, 168, 254, 0.14);
  color: var(--accent);
  border: 1px solid rgba(110, 168, 254, 0.32);
}

.badge {
  background: rgba(157, 168, 187, 0.12);
  color: var(--text);
  border: 1px solid rgba(157, 168, 187, 0.25);
}

.badge.success {
  color: #c7f9d6;
  background: rgba(34, 197, 94, 0.14);
  border-color: rgba(34, 197, 94, 0.3);
}

.badge.warning {
  color: #ffe3ad;
  background: rgba(245, 158, 11, 0.14);
  border-color: rgba(245, 158, 11, 0.3);
}

.badge.info {
  color: #d4e5ff;
  background: rgba(110, 168, 254, 0.14);
  border-color: rgba(110, 168, 254, 0.3);
}

.badge.danger {
  color: #ffd0d0;
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.3);
}

.button {
  border: 0;
  border-radius: 12px;
  padding: 10px 13px;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.15s ease, opacity 0.15s ease, background 0.15s ease;
}

.button:hover {
  transform: translateY(-1px);
}

.button.primary {
  color: white;
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
}

.button.secondary {
  color: var(--text);
  background: #252d3a;
  border: 1px solid #374050;
}

.button.danger {
  color: white;
  background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
}

.import-label {
  display: inline-flex;
  justify-content: center;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-bottom: 18px;
}

.form-grid.compact {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.form-grid.wide {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.form-grid label {
  display: grid;
  gap: 8px;
  color: var(--muted);
  font-size: 0.92rem;
}

.form-grid input,
.form-grid select,
.form-grid textarea {
  width: 100%;
  background: #0f131a;
  border: 1px solid #313948;
  color: var(--text);
  border-radius: 12px;
  padding: 11px 12px;
  font: inherit;
}

.checkbox {
  align-self: end;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  color: var(--text);
}

.checkbox input {
  width: auto;
}

.span-2 {
  grid-column: span 2;
}

.table-wrap {
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  text-align: left;
  padding: 10px 10px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

th {
  color: var(--muted);
  font-size: 0.83rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

td small,
.muted {
  color: var(--muted);
}

.table-action {
  border: 0;
  background: transparent;
  color: #ff9f9f;
  cursor: pointer;
  font: inherit;
  font-weight: 700;
}

.meta-line {
  display: block;
  color: var(--muted);
  margin-top: 3px;
  font-size: 0.82rem;
  line-height: 1.35;
}

.value-stack {
  display: grid;
  gap: 4px;
}

.override-note {
  color: var(--accent);
}

.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.inline-action {
  appearance: none;
  border: 1px solid rgba(110, 168, 254, 0.35);
  background: rgba(110, 168, 254, 0.08);
  color: var(--accent);
  border-radius: 999px;
  padding: 5px 9px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
}

.inline-action:hover {
  background: rgba(110, 168, 254, 0.16);
}

.inline-select-wrap {
  display: block;
  max-width: 120px;
}

.compact-select-wrap {
  max-width: 110px;
}

.inline-select {
  width: 100%;
  background: #0f131a;
  border: 1px solid #313948;
  color: var(--text);
  border-radius: 10px;
  padding: 7px 10px;
  font: inherit;
}

/* Cap the width so the notes wrap inside the cell instead of stretching the whole
   table wider than the viewport. */
.status-notes-cell {
  min-width: 190px;
  max-width: 260px;
}

.status-notes-stack {
  display: grid;
  gap: 5px;
}

/* Badge, counted month and the edit button share one line: three stacked rows
   was most of this column's height. */
.status-notes-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.status-notes-line .meta-line {
  margin-top: 0;
}

.progress-row.success td {
  background: rgba(34, 197, 94, 0.05);
}

.progress-row.warning td {
  background: rgba(245, 158, 11, 0.05);
}

.progress-row.danger td {
  background: rgba(239, 68, 68, 0.05);
}

.progress-row.info td {
  background: rgba(96, 165, 250, 0.07);
}

.empty-state {
  display: grid;
  gap: 6px;
  place-items: center;
  text-align: center;
  padding: 28px 16px;
  border: 1px dashed var(--line);
  border-radius: 16px;
  color: var(--muted);
}

.table-wrap + .table-wrap {
  margin-top: 16px;
}

.dense-table th,
.dense-table td {
  padding: 6px 8px;
  vertical-align: middle;
}

/* A badge is a fixed label; wrapping it ("Final / snapshot") makes one column
   set the height of the whole row. */
.dense-table .badge {
  white-space: nowrap;
}

/* Full-width tables run long, so the header has to survive the scroll. */
.dense-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--panel-strong);
}

/* --- PoP effort ---------------------------------------------------------- */

.pop-effort-grid {
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 8px;
  margin: 10px 0 0;
}

.pop-effort-grid .summary-card {
  padding: 9px 12px;
}

.pop-effort-grid .summary-card strong {
  font-size: 1.3rem;
  margin-bottom: 2px;
}

.pop-effort-grid .summary-card span {
  font-size: 0.76rem;
}

/* A meter whose 100% mark is the requirement rather than the end of the bar, so
   fill past the tick shows how far over the minimum a win went. A bar that
   capped at the threshold could never say that. */
.pop-meter {
  display: grid;
  gap: 3px;
  min-width: 104px;
}

.pop-meter-value {
  font-size: 0.84rem;
  font-weight: 600;
  white-space: nowrap;
}

.pop-meter-track {
  position: relative;
  height: 5px;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.18);
}

.pop-meter-track .pop-meter-fill {
  border-radius: 999px;
}

.pop-meter-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--danger);
}

.pop-meter-fill.is-met {
  background: var(--success);
}

/* Every achievement earned: the game is fully completed. Amber is what the app
   already uses for that state (the "All achievements" badge), so the bar matches. */
.pop-meter-fill.is-complete {
  background: var(--warning);
}

/* The required minimum, sitting where it actually falls on the game: about 25%
   along for playtime, about 10% for achievements. */
.pop-meter-marker {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  background: var(--text);
  opacity: 0.7;
}

.pop-effort-cell {
  white-space: nowrap;
}

.pop-effort-band {
  font-size: 0.8rem;
  font-weight: 600;
}

.pop-effort-band.below {
  color: #fca5a5;
}

.pop-effort-band.minimum {
  color: #ffe3ad;
}

.pop-effort-band.above {
  color: #d4e5ff;
}

.pop-effort-band.well-above {
  color: #86efac;
}

/* Matches the amber completion bar: the game is finished, not merely exceeded. */
.pop-effort-warn {
  display: block;
  color: #ffe3ad;
}

.pop-effort-band.complete {
  color: #fcd34d;
  font-weight: 700;
}

/* --- Summer event standings ---------------------------------------------- */

.summer-standings {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 10px;
}

.summer-standing {
  display: grid;
  gap: 7px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel-strong);
}

.summer-standing.podium {
  border-color: rgba(245, 158, 11, 0.4);
}

.summer-standing.neutral {
  border-color: rgba(245, 158, 11, 0.45);
}

.summer-standing.negative {
  border-color: rgba(239, 68, 68, 0.45);
}

.summer-standing-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

/* Rank was implicit in card order; make the leaderboard position visible. */
.summer-rank {
  display: grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding: 0 5px;
  border-radius: 7px;
  background: rgba(157, 168, 187, 0.14);
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 700;
}

.summer-standing.podium .summer-rank {
  background: rgba(245, 158, 11, 0.2);
  color: #ffe3ad;
}

.summer-standing-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.summer-balance {
  margin-left: auto;
  font-size: 1.1rem;
  font-weight: 700;
  white-space: nowrap;
}

.summer-standing.negative .summer-balance {
  color: #fca5a5;
}

/* Balance relative to the leader, so rank reads as length and not just order. */
.summer-bar {
  height: 4px;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.16);
  overflow: hidden;
}

.summer-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

.summer-standing.podium .summer-bar-fill {
  background: var(--warning);
}

/* The balance is an equation; show the terms that add up to it. */
.summer-terms {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.summer-term {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-weight: 600;
}

.summer-term em {
  font-style: normal;
  font-weight: 400;
  font-size: 0.72rem;
  color: var(--muted);
}

.summer-term.plus {
  color: #86efac;
}

.summer-term.minus {
  color: #fca5a5;
}

.summer-standing-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 3px 11px;
  color: var(--muted);
  font-size: 0.73rem;
}

/* Cycle summary as tiles: the same five figures used to be one prose sentence. */
.cycle-summary-grid {
  grid-template-columns: 2fr repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}

.cycle-summary-card {
  padding: 10px 13px;
}

.cycle-summary-card strong {
  font-size: 1.35rem;
  margin-bottom: 2px;
}

.cycle-summary-card.wide strong {
  font-size: 0.95rem;
  line-height: 1.35;
}

.cycle-summary-card span {
  font-size: 0.78rem;
}

/* A select sized to a badge, so the Type column stays editable without costing
   the 8px per row a full-size control would add. */
.cell-select {
  max-width: 116px;
  padding: 2px 6px;
  border-radius: 999px;
  border: 1px solid rgba(157, 168, 187, 0.25);
  background: rgba(157, 168, 187, 0.12);
  color: var(--text);
  font: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  cursor: pointer;
}

.cell-select:hover {
  border-color: rgba(110, 168, 254, 0.5);
}

.cell-select.kind-extra {
  color: #ffe3ad;
  background: rgba(245, 158, 11, 0.14);
  border-color: rgba(245, 158, 11, 0.3);
}

.cell-select.kind-penalty {
  color: #ffd0d0;
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.3);
}

.cell-select.participation-paused {
  color: #ffe3ad;
  background: rgba(245, 158, 11, 0.14);
  border-color: rgba(245, 158, 11, 0.3);
}

.cell-select.kind-pop_free,
.cell-select.kind-summer_event {
  color: #d4e5ff;
  background: rgba(110, 168, 254, 0.14);
  border-color: rgba(110, 168, 254, 0.3);
}

/* Month bands replace the column that restated the month on every row. */
.table-group-row th {
  position: static;
  padding: 22px 8px 6px;
  text-align: left;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text);
  text-transform: none;
  letter-spacing: 0;
  background: transparent;
  border-bottom: 1px solid var(--line);
}

.dense-table .table-group-row:first-child th {
  padding-top: 2px;
}

/* The row closing a month gets no divider, so the gap above the next band reads
   as the separator instead of a doubled line. */
.table-group-row + tr td {
  border-top: 0;
}

/* One line per note instead of a bordered alert card each: two cards were 168px
   of a 360px header, and the winner's figures now live on their marked row. */
.cycle-note {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin: 0 0 5px;
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--muted);
}

.cycle-note:last-child {
  margin-bottom: 0;
}

.cycle-note strong {
  color: var(--text);
}

.cycle-note-label {
  flex: 0 0 auto;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.cycle-note.info .cycle-note-label {
  background: rgba(110, 168, 254, 0.16);
  color: #d4e5ff;
}

.cycle-note.warning .cycle-note-label {
  background: rgba(245, 158, 11, 0.16);
  color: #ffe3ad;
}

/* The Rule 9 leader used to be named only in an alert above the table. */
.cycle-rule9-mark {
  margin-left: 7px;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(245, 158, 11, 0.16);
  border: 1px solid rgba(245, 158, 11, 0.35);
  color: #ffe3ad;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.th-note {
  margin-left: 5px;
  color: var(--accent);
  font-size: 0.68rem;
  font-weight: 600;
}

/* Secondary figures sit inline instead of on their own block line: three stacked
   sub-values per row were most of this table's height. */
.cell-note {
  margin-left: 6px;
  color: var(--muted);
  font-size: 0.74rem;
  white-space: nowrap;
}

/* LUCKY / UNLUCKY are neutral rule states, not problems, so they get a quiet tag
   rather than a coloured badge competing with the real status. */
.cycle-luck-tag {
  margin-left: 6px;
  color: var(--muted);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.06em;
}

.cycle-row-paused td {
  opacity: 0.6;
}

.compact-meta-line {
  font-size: 0.76rem;
  line-height: 1.25;
}

.compact-alert p {
  font-size: 0.88rem;
}

#cycle-best-gifter-warning {
  margin-top: 4px;
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(11, 13, 18, 0.78);
  z-index: 50;
}

.modal-backdrop[hidden] {
  display: none;
}

.modal-card {
  width: min(460px, 100%);
  display: grid;
  gap: 14px;
  background: rgba(23, 27, 34, 0.98);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 20px;
  box-shadow: var(--shadow);
}

.modal-copy,
.modal-error {
  margin: 0;
  line-height: 1.45;
}

.modal-copy {
  color: var(--muted);
}

.modal-error {
  color: #ffd0d0;
}

.modal-field {
  display: grid;
  gap: 8px;
  color: var(--muted);
  font-size: 0.92rem;
}

.modal-field input {
  width: 100%;
  background: #0f131a;
  border: 1px solid #313948;
  color: var(--text);
  border-radius: 12px;
  padding: 11px 12px;
  font: inherit;
}

.modal-field input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.modal-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: flex-end;
}

@media (max-width: 1080px) {
  .two-columns,
  .summary-grid,
  #summer-event-summary-cards,
  .member-grid,
  .form-grid.wide {
    grid-template-columns: 1fr;
  }

  .span-2 {
    grid-column: auto;
  }

}

@media (max-width: 760px) {
  .app-shell {
    width: min(100% - 20px, 100%);
    padding-top: 12px;
  }

  .hero {
    flex-direction: column;
  }

  .hero-actions {
    justify-content: stretch;
  }

  .hero-actions .button,
  .hero-actions .import-label,
  .sync-actions .button,
  .sync-actions a.button {
    width: 100%;
  }

  .form-grid,
  .form-grid.compact {
    grid-template-columns: 1fr;
  }

  .section-filters {
    width: 100%;
    margin-left: 0;
  }

  .game-thumb {
    width: 88px;
    min-width: 88px;
    height: 41px;
  }

  .giveaway-grid {
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  }
}

/* --- Active users scoreboard ------------------------------------------------
   One row per member; the bar is their mix of effort bands normalized to 100%,
   so the page compares how people play rather than how much they have won. */
.score-group {
  display: grid;
  gap: 8px;
  margin-bottom: 14px;
}

.score-board {
  display: grid;
  gap: 4px;
}

.score-row {
  display: grid;
  grid-template-columns: 26px minmax(110px, 1fr) 74px minmax(160px, 2.6fr) 44px 62px 46px;
  align-items: center;
  gap: 10px;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel-strong);
  font-size: 0.85rem;
}

.score-row.podium {
  border-color: rgba(245, 158, 11, 0.45);
}

.score-rank {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.score-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The rating is the one number to read; everything else supports it. */
.score-rating {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 1rem;
  text-align: right;
}

.score-rating.is-unranked {
  color: var(--muted);
  font-weight: 500;
}

/* Right-aligned tabular figures so the numbers form readable columns down the
   page instead of drifting with each name length. */
.score-num {
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
  text-align: right;
  white-space: nowrap;
}

.score-head {
  background: none;
  border-color: transparent;
  padding-bottom: 0;
  color: var(--muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.score-head .score-rating {
  font-size: 0.66rem;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: 0.02em;
}

.score-bar-head {
  font-size: 0.72rem;
}

.score-rating em,
.score-total em {
  margin-left: 3px;
  color: var(--muted);
  font-size: 0.7rem;
  font-style: normal;
  font-weight: 500;
}

.score-bar {
  display: flex;
  height: 10px;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.16);
  overflow: hidden;
}

.score-group .score-bar {
  height: 12px;
}

.score-bar.is-empty {
  opacity: 0.4;
}

.score-seg {
  height: 100%;
  transition: opacity 0.12s ease;
}

/* Picking a band drops the rest back so the chosen one is comparable across
   rows, which a stacked bar otherwise makes impossible. */
.score-seg.is-dimmed {
  opacity: 0.16;
}

.score-seg.below { background: var(--band-below); }
.score-seg.minimum { background: var(--band-minimum); }
.score-seg.above { background: var(--band-above); }
.score-seg.well-above { background: var(--band-well-above); }
.score-seg.complete { background: var(--band-complete); }
.score-seg.fresh { background: var(--band-fresh); }

.score-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 0.78rem;
  color: var(--muted);
}

.score-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}

.score-legend-item:hover {
  border-color: var(--line);
}

.score-legend-item.is-active {
  border-color: var(--accent);
  background: rgba(110, 168, 254, 0.12);
  color: var(--text);
}

.score-legend-item b {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.score-swatch {
  width: 9px;
  height: 9px;
  border-radius: 3px;
}

.score-swatch.below { background: var(--band-below); }
.score-swatch.minimum { background: var(--band-minimum); }
.score-swatch.above { background: var(--band-above); }
.score-swatch.well-above { background: var(--band-well-above); }
.score-swatch.complete { background: var(--band-complete); }
.score-swatch.fresh { background: var(--band-fresh); }

.score-scope {
  margin: 0;
  color: var(--muted);
  font-size: 0.78rem;
}

.score-scope strong {
  color: var(--text);
}

@media (max-width: 720px) {
  /* Two lines: identity and rating first, then the bar and its counts. */
  .score-row {
    grid-template-columns: 26px 1fr 74px 62px;
    row-gap: 6px;
  }

  .score-bar {
    grid-column: 1 / -1;
  }

  /* Playtime drops out first; wins and achv carry the row. */
  .score-head,
  .score-row .score-num:nth-of-type(2) {
    display: none;
  }
}
