/* LeagueBeacon shared commercial UI layer.

   Loaded after every feature stylesheet so the product-wide visual system
   (global shell, surfaces, buttons, chips, tables, section headers) resolves
   last without needing specificity hacks inside the feature files. Presentation
   only: no selector here changes markup contracts or behavior. */

/* ------------------------------------------------------------------ */
/* Global base                                                         */
/* ------------------------------------------------------------------ */

body {
  background-color: var(--paper);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::selection {
  background: rgba(37, 96, 230, .18);
}

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

button {
  border-radius: var(--r-xs);
}

input:not([type="radio"]):not([type="checkbox"]),
select,
textarea {
  border-radius: var(--r-sm);
  border-color: var(--line-strong);
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--blue);
  box-shadow: var(--shadow-focus);
}

.eyebrow {
  font-size: var(--fs-eyebrow);
  letter-spacing: 1.8px;
}

/* ------------------------------------------------------------------ */
/* Global shell: header, brand, primary navigation                     */
/* ------------------------------------------------------------------ */

.site-header {
  background: var(--grad-navy-flat);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
  box-shadow: 0 10px 30px rgba(8, 21, 39, .16);
}

/* Thin brand hairline under the header. The header is already
   `position: sticky` (workspace.css), so this anchors to it without
   changing the sticky behavior. */
.site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--grad-hairline);
  pointer-events: none;
}

.brand-row {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.sport-switch {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  padding: 3px;
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: 999px;
  background: rgba(255, 255, 255, .06);
}

.sport-switch[hidden] {
  display: none;
}

.sport-switch a {
  color: #d5e4f5;
  text-decoration: none;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .08em;
  line-height: 1;
  padding: 7px 11px;
  border-radius: 999px;
}

.sport-switch a[aria-current="page"] {
  background: #fff;
  color: #10243f;
}

.brand {
  color: #fff;
}

.brand > span:last-child > span {
  color: var(--cyan);
}

.beacon-mark i {
  background: var(--cyan);
}

.beacon-mark:before,
.beacon-mark:after,
.beacon-mark b:before {
  border-top-color: #9ee4ff;
}

.version {
  color: var(--on-dark-muted);
}

/* Most labels wrap to two lines at this size, and the inherited `normal`
   line-height set them almost touching. */
.app-nav a {
  color: #9db0cb;
  line-height: 1.35;
  letter-spacing: .6px;
  transition: color .15s ease, background-color .15s ease;
}

/* Desktop header has one row for the labels. 14px side padding plus .6px
   tracking wrapped every two-word item onto two lines inside a 76px bar. */
@media (min-width: 1051px) {
  .app-nav a {
    padding-left: 10px;
    padding-right: 10px;
    letter-spacing: .35px;
    white-space: nowrap;
  }
}

.app-nav a:hover {
  color: #fff;
  background: rgba(255, 255, 255, .07);
}

.app-nav a.active {
  color: #fff;
  background: rgba(95, 212, 244, .1);
  border-bottom-color: var(--cyan);
}

.beacon-signals-nav.has-signals .beacon-signals-nav-dot {
  background: var(--cyan);
}

.header-actions .feedback-button,
.header-actions .admin-link {
  border-radius: var(--r-sm);
  border-color: rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .06);
  color: #cfe0f7;
}

.header-actions .feedback-button:hover,
.header-actions .admin-link:hover {
  border-color: rgba(255, 255, 255, .34);
  background: rgba(255, 255, 255, .14);
  color: #fff;
}

.account-button {
  border: 0;
  border-radius: var(--r-sm);
  background: var(--grad-cta);
  color: #fff;
  box-shadow: 0 6px 16px rgba(37, 96, 230, .34);
}

.account-button:hover {
  background: var(--grad-cta-hover);
  color: #fff;
}

.account-button.signed-in {
  /* account.css floors SIGN IN at 88px so the short label does not
     collapse. MY ACCOUNT is already longer than that reserved slot;
     drop the floor so the button hugs the label plus its 14px padding. */
  min-width: auto;
  width: auto;
  flex-grow: 0;
  border: 1px solid rgba(148, 214, 255, .4);
  background: rgba(255, 255, 255, .08);
  color: #d6ebff;
  box-shadow: none;
}

.account-button.signed-in:hover {
  background: rgba(255, 255, 255, .16);
  color: #fff;
}

@media (max-width: 430px) {
  /* beta.css already shrinks header actions here. Keep that floor so
     the signed-in hug above does not re-reserve label width on mobile. */
  .account-button.signed-in {
    min-width: 0;
  }
}

/* "Workspace saved" / "Account synced" is app state, not a marketing message.
   It only earns header space once a league is open. The node stays in the DOM
   and setWorkspaceIndicator() keeps writing to it either way. */
body:not(:has(#dashboard:not(.hidden))) #workspace-status {
  display: none;
}

@media (max-width: 1050px) {
  .app-nav {
    border-top-color: rgba(255, 255, 255, .12);
  }
}

/* ------------------------------------------------------------------ */
/* Shared primitives                                                   */
/* ------------------------------------------------------------------ */

.lb-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0 0 var(--s-3);
  color: var(--blue);
  font-size: var(--fs-eyebrow);
  font-weight: 800;
  letter-spacing: 1.8px;
  text-transform: uppercase;
}

.lb-eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  border-radius: var(--r-pill);
  background: var(--grad-brand);
}

.lb-section-head {
  max-width: 660px;
  margin: 0 0 var(--s-8);
}

.lb-section-head h2 {
  margin: 0;
  color: var(--navy);
  font-size: var(--fs-3xl);
  line-height: 1.1;
  letter-spacing: -1.3px;
}

.lb-section-head p {
  margin: var(--s-4) 0 0;
  color: var(--muted);
  font-size: var(--fs-lg);
  line-height: 1.6;
}

.lb-card {
  padding: var(--s-6);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--grad-surface);
  box-shadow: var(--shadow-sm);
}

.lb-card h3 {
  margin: 0 0 var(--s-2);
  color: var(--navy);
  font-size: var(--fs-lg);
  letter-spacing: -.3px;
}

.lb-card p {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: 1.65;
}

.lb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 48px;
  padding: 0 var(--s-6);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 800;
  letter-spacing: .3px;
  text-decoration: none;
  cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}

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

.lb-btn-primary {
  background: var(--grad-cta);
  color: #fff;
  box-shadow: 0 10px 24px rgba(37, 96, 230, .3);
}

.lb-btn-primary:hover {
  background: var(--grad-cta-hover);
  box-shadow: 0 14px 30px rgba(37, 96, 230, .38);
}

.lb-btn-secondary {
  border-color: var(--line-strong);
  background: var(--white);
  color: var(--navy);
  box-shadow: var(--shadow-xs);
}

.lb-btn-secondary:hover {
  border-color: var(--blue);
  color: var(--blue);
}

.lb-btn-ghost {
  border-color: rgba(255, 255, 255, .3);
  background: rgba(255, 255, 255, .08);
  color: #fff;
}

.lb-btn-ghost:hover {
  border-color: rgba(255, 255, 255, .55);
  background: rgba(255, 255, 255, .16);
}

.lb-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface-muted);
  color: var(--muted);
  font-size: var(--fs-micro);
  font-weight: 800;
  letter-spacing: .5px;
  text-transform: uppercase;
  white-space: nowrap;
}

.lb-chip-brand {
  border-color: #c9dbff;
  background: var(--blue-soft);
  color: var(--blue);
}

.lb-chip-good {
  border-color: #b9e6d6;
  background: var(--good-soft);
  color: var(--good-ink);
}

.lb-chip-accent {
  border-color: #f4dcb0;
  background: var(--accent-soft);
  color: #8a5a10;
}

.lb-chip-dark {
  border-color: rgba(148, 214, 255, .32);
  background: rgba(95, 212, 244, .12);
  color: #bfe6ff;
}

/* ------------------------------------------------------------------ */
/* Product surfaces: dashboard shell, panels, tables                   */
/* ------------------------------------------------------------------ */

.dashboard-heading {
  position: relative;
  overflow: hidden;
  padding: var(--s-6);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--grad-surface);
  box-shadow: var(--shadow-sm);
}

.dashboard-heading::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 3px;
  background: var(--grad-brand);
}

.dashboard-heading h2 {
  color: var(--navy);
  font-size: var(--fs-3xl);
  letter-spacing: -1.3px;
}

.page-description {
  font-size: var(--fs-sm);
  line-height: 1.6;
}

.league-context {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-4);
  padding: 6px 12px;
  border: 1px solid #c9dbff;
  border-radius: var(--r-pill);
  background: var(--blue-soft);
  color: var(--blue-strong);
  font-size: var(--fs-sm);
  font-weight: 800;
}

.controls select,
.controls input {
  border-radius: var(--r-sm);
}

.panel {
  border-radius: var(--r-md);
  border-color: var(--line);
  background: var(--white);
  box-shadow: var(--shadow-sm);
}

.panel-title {
  background: linear-gradient(180deg, #fbfdff 0%, #f4f8fd 100%);
  border-bottom-color: var(--line);
}

.panel-title h3 {
  color: var(--navy);
  font-size: var(--fs-base);
  font-weight: 850;
}

/* Several panels ship an intentionally empty index span; collapsing it
   removes the stray gap next to those headings. */
.panel-title > div > span:empty {
  display: none;
}

.panel-title > div > span:not(:empty) {
  display: inline-grid;
  place-items: center;
  min-width: 24px;
  height: 24px;
  border-radius: var(--r-xs);
  background: var(--blue-soft);
  color: var(--blue);
  font-size: var(--fs-micro);
  font-weight: 900;
}

.panel-title small {
  border: 1px solid #cfdefb;
  background: var(--blue-soft);
  color: var(--blue);
  letter-spacing: .5px;
}

thead {
  background: var(--surface-muted);
}

th {
  border-bottom: 1px solid var(--line-strong);
  font-weight: 850;
}

tbody tr:nth-child(2n) {
  background: #fbfcff;
}

tbody tr:hover,
tbody tr.selected {
  background: var(--blue-faint);
}

tbody tr.selected {
  box-shadow: inset 3px 0 0 var(--blue);
}

td:first-child {
  font-weight: 850;
}

/* ------------------------------------------------------------------ */
/* Status colour: text-safe green                                      */
/* ------------------------------------------------------------------ */

/* --good is a fill colour. Everywhere it is used as small label text on a
   light surface it lands near 3.1:1, so the whole set moves to --good-ink. */
.status.success,
.roster-status-badge.starter,
.roster-player-role.starter,
.package-status.ready > strong,
.trade-block-badge,
.verification-badge.verified,
.sleeper-linked-panel span,
.waiver-player-impact strong,
.recommended-move-modes b.upgrade,
.predictions-status-chip[data-status="graded"],
.outlook-panel .panel-title small.contender,
.team-focus-panel .panel-title small.contender,
.player-trend-change.up,
#market-badge.ready {
  color: var(--good-ink);
}

/* Same story for --muted on tinted surfaces: these land just under 4.5:1. */
.signal-placeholder,
.waiver-signal-label.monitor,
.trend-signal {
  color: var(--muted-strong);
}

.trend-signal.rebounding {
  color: var(--blue-strong);
}

/* ------------------------------------------------------------------ */
/* Logged-in page header                                               */
/* ------------------------------------------------------------------ */

/* The controls used to hang off the bottom of a much taller identity block,
   which read as a gap rather than a toolbar. */
.dashboard-heading {
  align-items: center;
  gap: var(--s-5) var(--s-8);
  padding: var(--s-6) var(--s-7);
}

.dashboard-heading h2 {
  margin: 0 0 6px;
}

.page-description {
  max-width: 64ch;
  margin: 0;
}

.league-context {
  margin-top: var(--s-5);
  padding: 7px 14px;
  font-size: var(--fs-base);
  letter-spacing: -.2px;
}

#league-meta {
  margin: var(--s-3) 0 0;
  font-size: var(--fs-xs);
}

.analysis-mode-badge {
  margin-top: var(--s-3);
}

.controls label {
  color: var(--muted);
  font-size: var(--fs-micro);
  letter-spacing: .9px;
}

.back-dashboard {
  border-radius: var(--r-pill);
}

/* ------------------------------------------------------------------ */
/* Signals                                                             */
/* ------------------------------------------------------------------ */

/* Each row is a ranked recommendation: chip, claim, reasoning, action. The
   category reads as a status pill so it matches the chips used everywhere
   else instead of floating as bare uppercase text. */
.beacon-signal-row {
  gap: 10px var(--s-5);
  padding: var(--s-4) var(--s-5);
  border-bottom-color: var(--line);
}

.beacon-signal-row:hover,
.beacon-signal-row:focus-visible {
  background: var(--blue-faint);
  box-shadow: inset 3px 0 0 var(--blue);
}

.beacon-signal-row-type {
  align-self: start;
  margin-bottom: 5px;
  padding: 3px 9px;
  border: 1px solid #c9dbff;
  border-radius: var(--r-pill);
  background: var(--blue-soft);
  font-size: 9px;
  letter-spacing: .6px;
}

.beacon-signal-copy {
  align-items: start;
}

.beacon-signal-row b {
  padding: 9px 14px;
  border-radius: var(--r-sm);
  background: var(--grad-cta);
  box-shadow: 0 4px 12px rgba(37, 96, 230, .22);
}

.beacon-empty-signal,
.beacon-signal-overage {
  padding: var(--s-5) var(--s-6);
}

/* ------------------------------------------------------------------ */
/* Team Analysis                                                       */
/* ------------------------------------------------------------------ */

.league-format-summary div {
  background: var(--surface-muted);
}

/* One or two chips inside a full-width bordered white box read as an empty
   panel above Signals. The chips already carry their own outline. */
.team-action-strip {
  padding: 0;
  border: 0;
  background: none;
}

/* Rankings used to span the Needs Attention and Team Analysis rows. The
   analysis column is taller, so the extra height sat as empty paper under
   the table and above Roster. Team Analysis now takes its own full-width
   row, which also gives Season Read a readable measure. */
@media (min-width: 901px) {
  body[data-app-page="dashboard"] .dashboard-grid {
    grid-template-columns: minmax(0, 2.3fr) minmax(280px, 1fr);
    grid-template-areas:
      "rankings attention"
      "analysis analysis"
      "rostersection rostersection";
  }

  /* waivers.css / workspace.css set grid-column: auto after grid-area, which
     would collapse this back to the rankings track and re-squeeze Season Read. */
  body[data-app-page="dashboard"] .team-focus-panel {
    grid-column: 1 / -1;
  }

  body[data-app-page="dashboard"] .team-roster-section {
    grid-template-columns: minmax(0, 2.3fr) minmax(280px, 1fr);
  }
}

/* Full-width Team Analysis can keep the original two-up readout. Stack only
   when the page itself is already a single column. */
.team-focus-panel .outlook {
  grid-template-columns: minmax(0, 1.15fr) minmax(260px, .85fr);
}

.team-focus-panel .outlook-summary {
  border-right: 1px solid var(--line);
  border-bottom: 0;
}

@media (max-width: 900px) {
  .team-focus-panel .outlook {
    grid-template-columns: minmax(0, 1fr);
  }

  .team-focus-panel .outlook-summary {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
}

.outlook-priorities ol {
  margin: 0;
  padding-left: 18px;
}

.outlook-priorities li {
  line-height: 1.5;
}

.outlook-priorities li + li {
  margin-top: var(--s-3);
}

/* Belt and braces on the dead space: even with a short rail the rankings panel
   should size to its table rather than stretch to whatever the rail needs. */
body[data-app-page="dashboard"] .rankings-panel {
  align-self: start;
}

/* The coverage line ran together as one dense strip of 11px text. */
.rankings-depth-context {
  padding: var(--s-3) var(--s-5) var(--s-4);
}

.rankings-depth-context-list {
  gap: var(--s-2) var(--s-5);
}

.rankings-depth-context-list li {
  font-size: var(--fs-xs);
}

/* 27px in a column this narrow wrapped the team profile onto three lines. */
.outlook-profile strong {
  font-size: var(--fs-xl);
  letter-spacing: -.5px;
}

.outlook-stat,
.rank-position-grid div,
.market-metrics {
  border-radius: var(--r-sm);
  border-color: var(--line);
}

.outlook-stat {
  background: var(--surface-muted);
}

.rank-breakdown {
  border-radius: var(--r-md);
}

.team-action-chip {
  border-radius: var(--r-pill);
  border-color: var(--line-strong);
}

/* ------------------------------------------------------------------ */
/* Trade Center                                                        */
/* ------------------------------------------------------------------ */

/* .dashboard-grid is 1.25fr / .75fr with the default stretch alignment.
   Trade Partners and Trade partner details share one row, so the shorter
   partner list was painted as a tall empty white panel beside suggestions.
   Start-align the row so each panel sizes to its own content; do not cap
   or scroll the details column to hide the gap. */
body[data-app-page="trades"] .dashboard-grid {
  align-items: start;
}

.partners-panel {
  align-self: start;
  height: auto;
}

.partner-match-chip {
  border-radius: var(--r-md);
  border-color: var(--line);
  background: var(--surface-muted);
}

.partners .partner-match {
  color: var(--blue-strong);
}

.exchange-mark span {
  box-shadow: 0 6px 16px rgba(8, 21, 39, .28);
}

.side-heading > span {
  border-radius: var(--r-pill);
}

/* Three different toggle treatments used to sit inside one panel. */
.trade-side-controls,
.asset-filter-toolbar .roster-status-filters button,
.trade-side-controls button {
  border-radius: var(--r-sm);
}

.trade-side-controls {
  border-color: var(--line);
  background: var(--surface-muted);
}

.trade-side-controls button,
.roster-status-filters button {
  border-color: var(--line-strong);
  font-weight: 850;
}

.trade-side-controls button.active,
.roster-status-filters button.active {
  border-color: #a8c4f7;
  background: var(--blue-soft);
  box-shadow: var(--shadow-xs);
}

.package-summary {
  border-radius: 0 0 var(--r-md) var(--r-md);
}

.saved-trade {
  border-radius: var(--r-md);
  box-shadow: var(--shadow-xs);
}

.shortlist-empty {
  border-radius: var(--r-md);
}

/* ------------------------------------------------------------------ */
/* Waiver Wire                                                         */
/* ------------------------------------------------------------------ */

.waiver-signal-label {
  border: 1px solid transparent;
  font-weight: 850;
}

/* Above the 720px waiver breakpoint the name column absorbed every spare
   pixel and squeezed the signal into a clamped two-line 118px slot. Cap the
   name instead so the signal reads as one chip. */
@media (min-width: 721px) {
  .waiver-player {
    grid-template-columns: minmax(0, 1fr) minmax(0, 200px) 36px 86px;
  }

  .waiver-player .waiver-signal-label {
    display: inline-flex;
    justify-self: end;
    white-space: nowrap;
    -webkit-line-clamp: none;
  }
}

/* Below 430px the name was pinned to 74px while a 1fr track held nothing but
   the trend arrow, so every player name was truncated after one word. */
@media (max-width: 430px) {
  .waiver-player {
    grid-template-columns: minmax(0, 1fr) 48px;
  }
}

.waiver-signal-label.priority-add {
  border-color: #b9e6d6;
}

.waiver-signal-label.strong-fit,
.waiver-signal-label.potential-roster-upgrade {
  border-color: #c9dbff;
}

.waiver-signal-label.dynasty-stash {
  border-color: #f4dcb0;
}

.waiver-signal-label.monitor {
  border-color: var(--line);
}

.waiver-player:hover {
  background: var(--blue-faint);
}

.waiver-player-name strong {
  color: var(--navy);
  font-weight: 800;
}

.waiver-detail {
  background: var(--surface-sunken);
}

.waiver-detail-metrics div {
  border-radius: var(--r-sm);
  border-color: var(--line);
}

.recommended-move,
.waiver-signal-summary {
  border-radius: var(--r-md);
}

/* ------------------------------------------------------------------ */
/* Weekly Top 10                                                       */
/* ------------------------------------------------------------------ */

/* The predictions panel lays its own children edge to edge, so the blocks that
   are not full-bleed tables need the panel's inset to stop their borders from
   doubling up against the panel border. */
.predictions-header {
  margin: var(--s-5) var(--s-5) var(--s-4);
  padding: var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-muted);
}

.predictions-note,
.predictions-empty,
.predictions-accuracy,
.predictions-history-note {
  margin-left: var(--s-5);
  margin-right: var(--s-5);
}

.predictions-note {
  padding: 10px var(--s-4);
  border-left: 3px solid var(--blue);
  border-radius: var(--r-xs);
  background: var(--blue-faint);
  color: var(--ink);
}

.predictions-empty {
  padding: var(--s-6) var(--s-5) var(--s-7);
  text-align: center;
}

.predictions-history-note {
  margin-top: 0;
  margin-bottom: var(--s-4);
  padding: 10px var(--s-4);
  border: 1px solid #cfdefb;
  border-radius: var(--r-sm);
  background: var(--blue-faint);
  color: var(--muted-strong);
  font-size: var(--fs-sm);
  line-height: 1.45;
}

.predictions-empty.is-history {
  margin-bottom: var(--s-5);
  padding: var(--s-5);
  border: 1px solid #cfdefb;
  border-radius: var(--r-md);
  background: var(--blue-faint);
  color: var(--ink);
  text-align: left;
  font-size: var(--fs-sm);
  line-height: 1.5;
}

.predictions-empty.is-history strong {
  display: block;
  margin-bottom: 6px;
  color: var(--navy);
  font-size: var(--fs-base);
  font-weight: 800;
}

/* app.js only unhides #predictions-empty when no official board exists for the
   week, so the table below it is guaranteed to be nothing but a column header.
   Leaving that header visible reads as a clipped table. */
.predictions-panel:has(#predictions-empty:not(.hidden)) > .table-wrap {
  display: none;
}

.predictions-context strong {
  color: var(--navy);
  font-size: var(--fs-xl);
  letter-spacing: -.5px;
}

.predictions-status-chip {
  border: 1px solid var(--line);
  background: var(--white);
}

.predictions-status-chip[data-status="graded"] {
  border-color: #b9e6d6;
  background: var(--good-soft);
}

.predictions-status-chip[data-status="frozen"] {
  border-color: #cfdefb;
  background: var(--blue-soft);
}

.predictions-status-chip[data-status="partial"] {
  border-color: #f4dcb0;
  background: var(--accent-soft);
}

.predictions-view-toggle,
.predictions-category-tabs {
  width: fit-content;
  max-width: 100%;
  padding: 3px;
  border-radius: var(--r-sm);
  background: #e6ecf6;
}

.predictions-view-toggle button,
.predictions-category-tabs button {
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: #4e5f79;
  font-weight: 850;
}

.predictions-view-toggle button:hover,
.predictions-category-tabs button:hover {
  background: rgba(255, 255, 255, .7);
  color: var(--blue);
}

.predictions-view-toggle button.active,
.predictions-category-tabs button.active {
  background: var(--white);
  color: var(--blue);
  box-shadow: var(--shadow-xs);
}

.predictions-week-nav button {
  border-color: var(--line-strong);
  border-radius: var(--r-sm);
}

.predictions-accuracy-grid {
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-xs);
}

.predictions-accuracy-card strong {
  color: var(--navy);
  font-size: var(--fs-xl);
}

.predictions-accuracy-card[data-accuracy-category].is-active {
  background: var(--blue-faint);
}

.predictions-top10-badge {
  border-radius: var(--r-pill);
}

/* ------------------------------------------------------------------ */
/* Account, subscription, and pricing entry points                     */
/* ------------------------------------------------------------------ */

.account-dialog,
.feedback-dialog,
.rating-prompt-dialog {
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}

.account-dialog h2 {
  color: var(--navy);
  font-size: var(--fs-2xl);
  letter-spacing: -.9px;
}

/* Section headings inside the account dialog carry the same brand rule the
   marketing eyebrows use, so Subscription reads as a section rather than a
   slightly bolder paragraph. */
.account-dialog h3 {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--navy);
  font-size: var(--fs-base);
}

.account-dialog h3::before {
  content: "";
  flex: 0 0 auto;
  width: 18px;
  height: 2px;
  border-radius: var(--r-pill);
  background: var(--grad-brand);
}

.auth-form button,
.sign-out-button,
.verification-action {
  border-radius: var(--r-sm);
}

.auth-form button {
  background: var(--grad-cta);
  box-shadow: 0 8px 18px rgba(37, 96, 230, .24);
}

.auth-form button:hover {
  background: var(--grad-cta-hover);
}

/* Current plan reads as the anchor card, matching the public pricing grid. */
.billing-plan-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-md);
  border-color: #cfdefb;
  background: linear-gradient(135deg, var(--blue-faint) 0%, #eaf1ff 100%);
  box-shadow: var(--shadow-xs);
}

.billing-plan-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--grad-brand);
}

.billing-plan-card strong {
  color: var(--navy);
  font-size: var(--fs-2xl);
  letter-spacing: -1px;
}

.billing-plan-card span {
  color: var(--blue-strong);
}

.billing-offer {
  border-radius: var(--r-md);
  border-color: var(--line);
  transition: border-color .15s ease, box-shadow .15s ease;
}

.billing-offer small {
  color: var(--navy);
  font-size: var(--fs-sm);
  font-weight: 800;
}

.billing-offer:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-xs);
}

.billing-offer strong {
  color: var(--navy);
}

.founding-offer {
  border-color: #f0d5a6;
  background: var(--accent-soft);
}

/* Every upgrade action uses the same primary button; the Founding Member card
   keeps its amber surface as the only differentiator. */
.billing-offer .verification-action,
.founding-offer .verification-action {
  border-color: transparent;
  background: var(--grad-cta);
  color: #fff;
}

.billing-offer .verification-action:hover,
.founding-offer .verification-action:hover {
  background: var(--grad-cta-hover);
  color: #fff;
}

.verification-action {
  border-color: #c3d6f8;
}

.account-identity,
.sleeper-linked-panel,
.sleeper-link-challenge,
.billing-offer {
  border-radius: var(--r-md);
}

/* Player Trends season groups must stack even though players.css lays
   .player-history-stats as a wrapping row. Without this, rushing and
   receiving chips sit on one horizontal line in a wide detail pane.
   The points chip is a direct child span; keep it content-sized. */
.player-history-stats {
  flex-direction: column;
  align-items: flex-start;
}

.player-history-stats > span {
  align-self: flex-start;
  width: max-content;
  max-width: 100%;
}

.player-history-stat-line,
.player-history-stat-group {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  flex: 0 0 auto;
  width: 100%;
  min-width: 0;
}

/* ------------------------------------------------------------------ */
/* Site footer                                                         */
/* ------------------------------------------------------------------ */

.lb-footer {
  padding: var(--s-9) max(5vw, 28px) var(--s-7);
  background: var(--grad-navy-flat);
  color: var(--on-dark-muted);
}

.lb-footer-top {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
  gap: var(--s-8);
  padding-bottom: var(--s-7);
  border-bottom: 1px solid rgba(255, 255, 255, .1);
}

.lb-footer-brand strong {
  display: block;
  color: #fff;
  font-size: var(--fs-lg);
  letter-spacing: -.4px;
}

.lb-footer-brand p {
  max-width: 380px;
  margin: var(--s-3) 0 var(--s-4);
  font-size: var(--fs-sm);
  line-height: 1.7;
}

.lb-footer-col h3 {
  margin: 0 0 var(--s-3);
  color: #fff;
  font-size: var(--fs-micro);
  font-weight: 800;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}

.lb-footer-col ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lb-footer-col li {
  margin-bottom: var(--s-2);
  font-size: var(--fs-sm);
  line-height: 1.6;
}

.lb-footer-col a {
  color: var(--on-dark-muted);
  text-decoration: none;
}

.lb-footer-col a:hover {
  color: #fff;
}

.lb-footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-6);
  justify-content: space-between;
  padding-top: var(--s-5);
  font-size: var(--fs-xs);
}

.lb-footer-bottom p {
  margin: 0;
  max-width: 640px;
  line-height: 1.6;
}

.lb-footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
}

.lb-footer-legal a {
  color: var(--on-dark);
  font-weight: 750;
  text-decoration: none;
}

.lb-footer-legal a:hover {
  color: var(--cyan);
}

@media (max-width: 900px) {
  .lb-footer-top {
    grid-template-columns: 1fr;
    gap: var(--s-6);
  }
}

/* ------------------------------------------------------------------ */
/* Dark feature surfaces                                               */
/* ------------------------------------------------------------------ */

/* --blue and --muted are tuned for the light surfaces they appear on almost
   everywhere. These two panels are the only dark backgrounds the feature
   stylesheets own, so they need the on-dark ramp instead. */
.package-summary details > summary {
  color: var(--cyan);
}

.draft-live-room .signal-placeholder {
  color: var(--on-dark-muted);
}

/* ------------------------------------------------------------------ */
/* Motion preferences                                                  */
/* ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .lb-btn,
  .app-nav a,
  .billing-offer {
    transition: none;
  }

  .lb-btn:hover {
    transform: none;
  }
}
