/* =============================================================================
   UltiGameMate — app-screen components
   Used by the app shell: sidebar, tab bar, dashboard, picks, scores.
   Loaded last, after tokens.css + style.css. Mirrors design/ugm.pen.
   ============================================================================= */

/* --- shell : sidebar + content (desktop) / stacked + tab bar (mobile) ------ */
.app-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  min-block-size: 100dvh;
  background: var(--bg-page);
}

@media (min-width: 64rem) {
  .app-shell {
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  }
}

.app-main {
  inline-size: 100%;
  max-inline-size: var(--w-app);
  margin-inline: auto;
  padding: clamp(1.25rem, 0.8rem + 2vw, 2.5rem) var(--pad-inline)
    calc(var(--tabbar-h) + var(--space-2xl));
  display: flex;
  flex-direction: column;
  gap: var(--gap-section);
  font-family: var(--font-body);
  font-size: var(--fz-body);
  line-height: var(--lh-body);
  color: var(--text-body);
}

/* Flex items default to min-width:auto, which refuses to shrink below a wide
   descendant's intrinsic width (e.g. .twrap table's min-inline-size) — that
   pushes .app-main, .app-shell and body wider than the viewport instead of
   letting .twrap's own overflow-x:auto scroll the table locally. Real page-
   level horizontal overflow on mobile is known to break position:fixed bars
   (the tab bar), so every screen-level child must be allowed to shrink. */
.app-main > * {
  min-inline-size: 0;
}

@media (min-width: 64rem) {
  .app-main {
    /* anchor content against the sidebar instead of centring it in a void */
    margin-inline: 0;
    padding-inline: clamp(2rem, 1rem + 3vw, 4rem);
    padding-block-end: var(--space-3xl);
  }
}

/* the picks screen needs the extra width for the fixture list */
body.app-select .app-main {
  max-inline-size: var(--w-app-wide);
}

/* admin screens hold wide data tables — give them more room than a normal
   app screen, but keep sparse tables from stretching edge to edge */
body[class^='admin'] .app-main {
  max-inline-size: 72rem;
}

/* --- admin form spacing ---------------------------------------------------
   Admin pages build forms out of bare label/input/select/textarea/button
   siblings (no field wrapper), and mix pages with a <form> and pages
   without one. Neither the generic `label + input` rule nor the
   `form :is(...) + :is(...)` rule reaches every case, so a control that is
   directly followed by the *next* field's label (or by an action button)
   gets no margin at all — fields and buttons end up touching. These rules
   give every admin page one consistent rhythm regardless of markup:
   space-xs between a label and its own control, space-lg before the next
   field or action button. */

/* inputs/selects/textareas are inline-block and .cta is inline-flex, so a
   margin alone doesn't reliably start a new line — it just shifts the next
   element within the same shared line box. Force fields onto their own
   line so the rhythm below is guaranteed rather than width-dependent.
   Covers admin AND app pages — profile.liquid uses the same bare
   label/input/button siblings admin forms do (leagues.liquid is the only
   app page that wraps fields in a div instead). */
:where(body[class^='admin'], body[class^='app'])
  :is(input, select, textarea):not([type='checkbox'], [type='radio']) {
  display: block;
}

:where(body[class^='admin'], body[class^='app']) label + :is(input, select, textarea) {
  margin-block-start: var(--space-xs);
}

:where(body[class^='admin'], body[class^='app'])
  :is(input, select, textarea, label)
  + :is(label, .cta, .btn, button) {
  margin-block-start: var(--space-lg);
}

/* The edit-match dialog has six action buttons of very different label
   lengths ("Lock" vs "Fetch data") — flex-wrap with
   justify-content:flex-end (the generic dialog-actions rule) right-justifies
   each wrapped row independently, which reads as ragged/disordered. A grid
   of even-width cells wraps predictably instead. */
body[class^='admin'] .dialog-actions {
  margin-block-start: var(--space-lg);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: var(--gap-sm);
}

/* .link (Cancel) has no button background, so it needs its own text
   centered within its stretched grid cell to match the solid .cta buttons
   either side of it. */
body[class^='admin'] .dialog-actions .link {
  justify-content: center;
}

/* leagues.liquid wraps each label+control pair in a plain <div> rather than
   leaving bare siblings, so the block-level div already forces a new line
   before whatever follows — it just has no gap. Give a field-wrapper div
   the same space-lg break before the next field or action button that
   bare-sibling forms get from the rule above. */
body[class^='app'] form > div + :is(div, .cta, .btn, button) {
  margin-block-start: var(--space-lg);
}

.app-main :is(h1, h2, h3) {
  margin: 0;
}

/* dense one-line UI rows keep the tighter leading */
.app-main :is(.page-head, .section-header, .stat-row, .round-tabs) {
  line-height: var(--lh-ui);
}

.app-screen {
  display: contents;
}

/* Vertical rhythm for app screens.
   select.liquid wraps content in <div class="app-screen"> (display:contents),
   so its children are direct .app-main flex items and inherit its gap.
   dashboard.liquid / scores.liquid wrap content in a plain <div id="*-screen">
   — give that the same column rhythm explicitly (global resets zero p/heading
   margins, so without this everything collapses together). */
.app-main > [id$='-screen']:not(.app-screen) {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* a section label hugs the block it introduces, with a larger break above it */
.app-main > [id$='-screen']:not(.app-screen) > .section-header {
  margin-block-start: var(--space-sm);
  margin-block-end: calc(var(--space-xs) - var(--space-lg));
}

/* a section-header + its content + optional trailing link/button, hidden as
   one unit until that section's data has loaded (see pages/*.js) so nothing
   pops in piecemeal or leaves a header/button floating above empty space */
.section-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* the header block gets a little extra air below it — applies to app-screen
   pages too (select.liquid) even though display:contents means .page-head
   ends up a direct .app-main flex item rather than this wrapper's */
.app-main > [id$='-screen'] > .page-head {
  margin-block-end: var(--space-2xs);
}

/* select.liquid's <div class="app-screen"> uses display:contents, so its
   children (including #pick-status) become direct .app-main flex items and
   inherit .app-main's much larger inter-section gap (--gap-section) instead
   of the --space-lg rhythm every other app screen uses around its status
   line. Cancel the difference so the gap above and below matches exactly. */
#pick-status {
  margin-block: calc(var(--space-lg) - var(--gap-section));
}

/* leagues/leaderboard/profile still use the older bare-<section> prose
   layout (no flex gap at all), so their status line only had the default
   paragraph margin and font-size — inconsistent with (and mostly smaller
   than) the rhythm above. The prose fallback's `section:not([class]) p`
   rule outranks .page-head__meta's class selector, so font-size/color have
   to be set here too (by id) to actually win. margin-block-start matches
   the 28px gap dashboard/scores get from their flex-gap + page-head margin. */
:is(#leagues-status, #leaderboard-status, #profile-status) {
  margin-block: calc(var(--space-lg) + var(--space-2xs)) var(--space-lg);
  font-size: var(--fz-sm);
  color: var(--text-secondary);
}

/* --- page header --------------------------------------------------------- */
.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs) var(--space-md);
}

.page-head__title {
  font-family: var(--font-display);
  font-size: var(--fz-2xl);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--text-heading);
}

.page-head__meta {
  font-size: var(--fz-sm);
  color: var(--text-secondary);
}

.round-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--pad-xs) var(--pad-md);
  border-radius: var(--radius-pill);
  background: var(--accent-wash);
  color: var(--accent-hi);
  font-family: var(--font-body);
  font-size: var(--fz-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

/* --- section header (green tick + label) ------------------------------- */
.section-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-block-start: var(--space-xs);
}

.section-header::before {
  content: '';
  inline-size: var(--icon-md);
  block-size: var(--space-3xs);
  flex: none;
  background: var(--accent);
  border-radius: var(--space-3xs);
}

.section-header > span,
.section-header__label {
  font-family: var(--font-body);
  font-size: var(--fz-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-over);
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* --- generic stacks --------------------------------------------------- */
.stack-sm {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.hidden {
  display: none !important;
}

/* --- match card (fixture in Your Picks) ------------------------------ */
.match-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  border-radius: var(--radius-md);
  background: var(--bg-card);
}

.match-card--viewable {
  cursor: pointer;
}

.match-card__date {
  text-align: center;
  font-size: var(--fz-xs);
  color: var(--text-secondary);
}

.match-card__row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-md);
}

.match-card__team {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-body);
  font-size: var(--fz-md);
  font-weight: 600;
  color: var(--text-primary);
}

.match-card__team--home {
  justify-content: flex-end;
}

.match-card__team img {
  flex: none;
  inline-size: 18px;
  block-size: 18px;
}

.match-card__score {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-ui);
  font-size: var(--fz-lg);
  font-weight: 700;
  color: var(--text-primary);
}

.match-card__score span {
  color: var(--text-muted);
}

.match-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

/* Locked round: no Remove button, so the boost pill is the lone child —
   keep it aligned to the end of the row instead of dropping to the start. */
.match-card__foot > :only-child {
  margin-inline-start: auto;
}

/* Remove is shaped like the boost pill next to it, so the foot row keeps a
   constant height whether or not the "Attach <boost>" pill is present —
   arming a boost then doesn't grow every pick card and shove the page. */
.match-card__remove {
  display: inline-flex;
  align-items: center;
  padding: var(--pad-md) var(--pad-lg);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: none;
  font: inherit;
  font-size: var(--fz-sm);
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
  transition:
    color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.match-card__remove:is(:hover, :focus-visible) {
  color: var(--neg);
  border-color: var(--neg);
}

/* --- pick option (available match row) ----------------------------- */
.pick-option {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  inline-size: 100%;
  padding: var(--space-md);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  border: 1px solid transparent;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition:
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}

/* Row 1: the checkbox on the left, the trailing date / boost pill on the
   right. Row 2 (.pick-option__row) carries the teams + vs. */
.pick-option__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  min-block-size: 20px;
}

.pick-option:is(:hover, :focus-visible) {
  background: var(--bg-elevated);
}

.pick-option:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.pick-option--selected {
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
}

.pick-option--boosted {
  border-color: var(--gold);
}

.pick-option__check {
  flex: none;
  inline-size: 20px;
  block-size: 20px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-xs);
  background: var(--bg-input);
  border: 1.5px solid var(--line-strong);
  color: var(--accent-ink);
}

.pick-option--selected .pick-option__check {
  background: var(--accent);
  border-color: var(--accent);
}

.pick-option__check svg {
  inline-size: 12px;
  block-size: 12px;
  opacity: 0;
}

.pick-option--selected .pick-option__check svg {
  opacity: 1;
}

/* Row 2: same grid as .match-score-card__row so the vs badge sits in the
   exact centre column that a finished card's score badge does — the two
   card types stay aligned down the list. */
.pick-option__row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-md);
}

.pick-option__team {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  min-inline-size: 0;
  font-family: var(--font-body);
  font-size: var(--fz-sm);
  font-weight: 600;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

.pick-option__team--home {
  justify-content: flex-end;
  text-align: end;
}

/* Same treatment as .match-score-card__badge (dashboard/scores) so "v" reads
   identically everywhere it appears, instead of plain muted text here. */
.pick-option__vs {
  flex: none;
  padding: var(--pad-2xs) var(--pad-sm);
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--fz-xs);
  font-weight: 700;
}

.pick-option__team img {
  flex: none;
  inline-size: 18px;
  block-size: 18px;
}

.pick-option__date {
  font-size: var(--fz-xs);
  color: var(--text-secondary);
}

/* Same gold-pill language as .points-badge--boost / .boost-pill--active,
   not plain colored text — "a boost is applied" should look the same
   everywhere it's shown. */
.pick-option__boost__pill {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-2xs);
  padding: var(--pad-2xs) var(--pad-md);
  border-radius: var(--radius-pill);
  background: var(--gold-wash);
  font-size: var(--fz-xs);
  font-weight: 700;
  color: var(--gold);
}

.pick-option__boost__pill svg {
  inline-size: 0.9em;
  block-size: 0.9em;
}

/* --- boost pills --------------------------------------------------- */
.boost-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: var(--space-xs);
}

.boost-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--pad-md) var(--pad-lg);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  border: 1px solid transparent;
  color: var(--text-body);
  font: inherit;
  font-size: var(--fz-sm);
  font-weight: 600;
  cursor: pointer;
  transition:
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.boost-pill svg {
  flex: none;
  inline-size: 14px;
  block-size: 14px;
  color: var(--gold);
}

.boost-pill:is(:hover, :focus-visible) {
  background: var(--bg-elevated);
}

.boost-pill:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.boost-pill__count {
  margin-inline-start: auto;
  padding: var(--pad-3xs) var(--pad-sm);
  border-radius: var(--radius-pill);
  background: var(--gold-wash);
  color: var(--gold);
  font-size: var(--fz-2xs);
  font-weight: 700;
}

.boost-pill--active {
  background: var(--gold-wash);
  border-color: var(--gold);
  color: var(--gold);
}

.boost-pill--active .boost-pill__count {
  background: var(--gold);
  color: var(--bg-sunken);
}

/* --- stat tiles -------------------------------------------------- */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(5.5rem, 1fr));
  gap: var(--space-xs);
}

.stat-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding: var(--space-md) var(--space-sm);
  border-radius: var(--radius-md);
  background: var(--bg-card);
}

.stat-tile__value {
  font-family: var(--font-ui);
  font-size: var(--fz-xl);
  font-weight: 700;
  line-height: 1;
  color: var(--text-primary);
}

.stat-tile__label {
  font-family: var(--font-body);
  font-size: var(--fz-2xs);
  letter-spacing: var(--tracking-over);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* --- round tabs ----------------------------------------------- */
.round-tabs {
  display: flex;
  gap: var(--space-2xs);
  overflow-x: auto;
  scrollbar-width: none;
  padding-block-end: var(--space-3xs);
}

.round-tabs::-webkit-scrollbar {
  display: none;
}

.round-tab {
  flex: none;
  padding: var(--pad-xs) var(--pad-lg);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  border: 1px solid transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--fz-sm);
  font-weight: 600;
  cursor: pointer;
}

.round-tab--active {
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  color: var(--accent-hi);
}

/* --- match score card (scores list) ------------------------- */
.match-score-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  inline-size: 100%;
  padding: var(--space-md);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  border: 0;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.match-score-card[disabled] {
  cursor: default;
}

.match-score-card:is(:hover, :focus-visible):not([disabled]) {
  background: var(--bg-elevated);
}

.match-score-card__row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-md);
}

.match-score-card__team {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-body);
  font-size: var(--fz-sm);
  font-weight: 600;
  color: var(--text-primary);
}

.match-score-card__team--home {
  justify-content: flex-end;
}

.match-score-card__team img {
  flex: none;
  inline-size: 18px;
  block-size: 18px;
}

.match-score-card__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-xs);
  padding: var(--pad-2xs) var(--pad-md);
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
  font-family: var(--font-ui);
  font-size: var(--fz-md);
  font-weight: 700;
  color: var(--text-primary);
}

.match-score-card__badge span {
  color: var(--text-muted);
}

.match-score-card__points {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
}

.match-score-card__date {
  text-align: center;
  font-size: var(--fz-xs);
  color: var(--text-secondary);
}

.points-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-2xs);
  padding: var(--pad-2xs) var(--pad-md);
  border-radius: var(--radius-pill);
  background: var(--pos-wash);
  color: var(--pos);
  font-size: var(--fz-xs);
  font-weight: 700;
}

.points-badge svg {
  inline-size: 0.9em;
  block-size: 0.9em;
}

.points-badge--muted {
  background: var(--bg-elevated);
  color: var(--text-secondary);
}

/* Marks a standings total that includes provisional points from the round
   currently in progress (leaderboard / leagues / your-rank). */
.live-dot {
  font-size: var(--fz-2xs);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--accent-hi);
  vertical-align: 0.05em;
  margin-inline-start: var(--gap-2xs);
}

/* A boost that was actually applied to a match — gold, matching every other
   "boost is active" treatment in the app (.boost-pill--active, .boost-tag).
   Distinct from .points-badge--muted, which is for neutral states like
   "used up" in the boosts-remaining list. */
.points-badge--boost {
  background: var(--gold-wash);
  color: var(--gold);
}

/* --- score-breakdown rows + dialog ------------------------- */
.score-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 0.65em var(--space-md);
}

.score-row + .score-row {
  border-block-start: 1px solid var(--line);
}

.score-row__label {
  flex: 1;
  font-family: var(--font-body);
  font-size: var(--fz-sm);
  color: var(--text-secondary);
}

.score-row__value {
  font-family: var(--font-ui);
  font-size: var(--fz-sm);
  font-weight: 700;
  color: var(--text-primary);
}

.score-row--subtotal .score-row__value,
.score-row--subtotal .score-row__label {
  color: var(--text-primary);
  font-weight: 700;
}

.score-row--total {
  background: var(--accent-wash);
}

.score-row--total .score-row__label,
.score-row--total .score-row__value {
  color: var(--accent-hi);
  font-weight: 700;
}

.score-dialog {
  border: 0;
  padding: 0;
  inline-size: min(94vw, 26rem);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  color: var(--text-body);
  box-shadow: var(--shadow-lg);
}

.score-dialog::backdrop {
  background: rgb(0 0 0 / 0.6);
}

.score-dialog__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-md) var(--space-md) var(--space-sm);
  font-family: var(--font-body);
  font-size: var(--fz-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-over);
  text-transform: uppercase;
  color: var(--text-secondary);
}

.score-dialog__match {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md) var(--space-md);
}

.score-dialog__team {
  font-family: var(--font-body);
  font-size: var(--fz-md);
  font-weight: 600;
  color: var(--text-primary);
}

.score-dialog__team--home {
  text-align: end;
}

.score-dialog__score {
  font-family: var(--font-ui);
  font-size: var(--fz-lg);
  font-weight: 700;
  color: var(--text-primary);
}

.score-dialog__foot {
  margin: 0;
  padding: var(--space-md);
  text-align: center;
  font-size: var(--fz-sm);
}

.boost-tag {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-xs);
  margin: 0 var(--space-md) var(--space-sm);
  padding: var(--pad-xs) var(--pad-md);
  border-radius: var(--radius-pill);
  background: var(--gold-wash);
  color: var(--gold);
  font-size: var(--fz-xs);
  font-weight: 700;
}

.boost-tag svg {
  inline-size: 0.9em;
  block-size: 0.9em;
}

/* .icon-btn lives in style.css (shared: banner dismiss + dialog close) */

.link-muted {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-xs);
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fz-sm);
  color: var(--text-secondary);
  cursor: pointer;
}

.link-muted:is(:hover, :focus-visible) {
  color: var(--text-primary);
  text-decoration: underline;
}

/* --- Picks: two panes on desktop ----------------------------- */
.pick-layout {
  display: grid;
  gap: var(--gap-section);
}

.pick-layout__main,
.pick-layout__aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  min-inline-size: 0;
}

@media (min-width: 80rem) {
  .pick-layout {
    /* wide fixture list + fixed picks/boost rail */
    grid-template-columns: minmax(0, 1fr) 22rem;
    gap: var(--space-2xl);
    align-items: start;
  }

  .pick-layout__aside {
    /* Available matches — the wide left column */
    grid-column: 1;
    grid-row: 1;
  }

  .pick-layout__main {
    /* Your picks + boosts — sticky right rail */
    grid-column: 2;
    grid-row: 1;
    position: sticky;
    inset-block-start: var(--space-lg);
  }

  /* boosts stack in the narrow rail instead of wrapping their labels */
  .pick-layout__main .boost-grid {
    grid-template-columns: 1fr;
  }
}

/* --- mobile tab bar ---------------------------------------- */
.tabbar {
  position: fixed;
  inset-block-end: var(--space-sm);
  inset-inline: var(--space-sm);
  z-index: 20;
  display: flex;
  padding: var(--space-2xs);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--bg-elevated) 92%, transparent);
  backdrop-filter: blur(12px);
  box-shadow: var(--shadow-lg);
}

@media (min-width: 64rem) {
  .tabbar {
    display: none;
  }
}

.tabbar__item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3xs);
  padding: var(--pad-sm) 0;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  text-decoration: none;
  font-family: var(--font-body);
  font-size: var(--fz-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.tabbar__item svg {
  inline-size: var(--icon-md);
  block-size: var(--icon-md);
}

.tabbar__item--active {
  background: var(--accent);
  color: var(--accent-ink);
}

/* --- desktop sidebar ------------------------------------- */
.sidebar {
  display: none;
}

@media (min-width: 64rem) {
  .sidebar {
    position: sticky;
    inset-block-start: 0;
    block-size: 100dvh;
    display: flex;
    flex-direction: column;
    gap: var(--space-xl);
    padding: var(--space-xl) var(--space-md) var(--space-md);
    background: var(--bg-sunken);
  }
}

.sidebar__logo {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: var(--fz-md);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  color: var(--text-primary);
}

.sidebar__logo :is(svg, img) {
  inline-size: 1.6rem;
  block-size: 1.6rem;
  border-radius: var(--radius-xs);
  color: var(--accent-hi);
}

.sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.sidebar__item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--pad-md) var(--pad-md);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-family: var(--font-body);
  font-size: var(--fz-sm);
  font-weight: 600;
  color: var(--text-secondary);
}

.sidebar__item svg {
  inline-size: var(--icon-md);
  block-size: var(--icon-md);
}

.sidebar__item:is(:hover, :focus-visible) {
  background: var(--bg-card);
  color: var(--text-primary);
}

.sidebar__item--active {
  background: var(--accent-wash);
  color: var(--accent-hi);
}

.sidebar__spacer {
  flex: 1;
}

.sidebar__profile {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  text-decoration: none;
  font-size: var(--fz-sm);
  color: var(--text-body);
}

.sidebar__profile--active {
  background: var(--accent-wash);
  color: var(--accent-hi);
}

.sidebar__avatar {
  flex: none;
  inline-size: 30px;
  block-size: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font-ui);
  font-weight: 700;
}

/* --- club autosuggest (src/js/clubCombobox.js) ---------------------------
   The wrapper is the positioning context for the popup; it sits inside a
   .column, so the input keeps the shared form styling untouched. */
.combobox {
  position: relative;
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
}

.combobox__list {
  position: absolute;
  inset-block-start: calc(100% + var(--space-3xs));
  inset-inline: 0;
  z-index: 30;
  max-inline-size: 30rem;
  max-block-size: 17rem;
  overflow-y: auto;
  margin: 0;
  padding: var(--space-3xs);
  list-style: none;
  border: var(--border-hairline) solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
  box-shadow: var(--shadow-lg);
}

.combobox__option {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--pad-sm) var(--pad-md);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--fz-sm);
  color: var(--text-primary);
}

.combobox__option[aria-selected='true'],
.combobox__option:hover {
  background: var(--accent);
  color: var(--accent-ink);
}

.combobox__crest {
  flex: none;
  object-fit: contain;
}

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

.combobox__short {
  margin-inline-start: auto;
  padding-inline-start: var(--space-xs);
  font-size: var(--fz-xs);
  color: var(--text-muted);
}

.combobox__option[aria-selected='true'] .combobox__short,
.combobox__option:hover .combobox__short {
  color: inherit;
  opacity: 0.75;
}
