/* ═══════════════════════════════════════════════════════════════
   FarsiChart - Modern Persian Music Rankings
   Clean, responsive, dark-themed design
   ═══════════════════════════════════════════════════════════════ */

/* ── Reset & Base ────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── NO PAGE MAY EVER SCROLL SIDEWAYS ─────────────────────────────────────────
   Loaded by EVERY page type (home, charts, artists, songs, feed, hubs, /status/,
   both languages), so this is the one place a site-wide invariant can live.

   2026-08-11: a /feed article measured 512px of content in a 375px viewport — the
   page slid under the header and the card ran off the screen. One grid item
   (.ff-lcard) with the default min-width:auto and a nowrap subtitle set a 472px
   floor, and everything above it inherited that width.

   That specific cause is fixed at source. These two rules are the standing net so
   the NEXT one is invisible to visitors instead of shipping:

   (a) clip the viewport horizontally. `clip`, never `hidden` — `hidden` turns the
       root into a scroll container and silently kills position:sticky on every
       descendant (the nav and the ad band both rely on it). `clip` does not.
   (b) let the page's top-level blocks shrink. A flex or grid item defaults to
       min-width:auto and refuses to go below its content, which is the mechanism
       behind essentially every instance of this bug. Harmless on ordinary blocks,
       where the computed minimum is already 0 — and it matters here because our ad
       partner sets `body { display:flex }` at runtime, turning every top-level
       section into a flex item we never wrote CSS for.

   Guarded by tests/no_horizontal_overflow_test.php. Do not remove either rule
   without re-measuring every template at 375px. */
html, body { overflow-x: clip; }
body { max-width: 100%; }
body > * { min-width: 0; }

:root {
  --bg-primary: #0a0a0a;
  --bg-secondary: #111111;
  --bg-card: #161616;
  --bg-hover: #1c1c1c;
  --bg-input: #1a1a1a;
  --border: #222222;
  --border-light: #2a2a2a;
  --text-primary: #f0f0f0;
  --text-secondary: #a0a0a0;
  --text-muted: #666666;
  --spotify-green: #1DB954;
  --spotify-green-hover: #1ed760;
  --spotify-green-dim: rgba(29, 185, 84, 0.1);
  --rj-red: #c62828;
  --rj-red-hover: #e53935;
  --rj-red-dim: rgba(198, 40, 40, 0.1);
  --accent: var(--spotify-green);
  --rank-up: #4caf50;
  --rank-down: #f44336;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --shadow: 0 2px 8px rgba(0,0,0,0.3);
  --shadow-lg: 0 8px 32px rgba(0,0,0,0.4);
  --transition: 0.2s ease;
  --max-width: 1000px;
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* ── Native Persian font on the Farsi locale (/fa) ──────────────────
   Redefining --font for the fa subtree swaps every `font-family: var(--font)`
   rule at once, so the whole Farsi UI uses Vazirmatn (the standard modern
   Persian web font) instead of the Latin Inter, which renders Farsi poorly. */
html[lang="fa"] {
  --font: 'Vazirmatn', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Tahoma, sans-serif;
}
html[lang="fa"] input,
html[lang="fa"] button,
html[lang="fa"] select,
html[lang="fa"] textarea {
  font-family: var(--font);   /* form controls don't inherit font by default */
}
/* Keep inherently left-to-right content (URLs, latin IDs) rendering LTR on the
   RTL page so slashes/dots aren't reordered into odd positions. */
html[lang="fa"] input[type="url"],
html[lang="fa"] input[type="email"],
html[lang="fa"] .ltr {
  direction: ltr;
  text-align: right;
  unicode-bidi: plaintext;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font);
  background: var(--bg-primary);
  color: var(--text-primary);
  line-height: 1.6;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.main-content { flex: 1; }

/* RTL support */
html[dir="rtl"] body { direction: rtl; }
html[dir="rtl"] .artist-info { flex-direction: row-reverse; }
html[dir="rtl"] .artist-link { flex-direction: row-reverse; }
html[dir="rtl"] .artist-avatar { margin: 0; }
html[dir="rtl"] .col-artist { text-align: right; }
html[dir="rtl"] .rank-arrow { margin-left: 0; margin-right: 4px; }

a { color: var(--text-primary); text-decoration: none; }
img { display: block; max-width: 100%; }

/* ── Header ──────────────────────────────────────────────────── */
.header {
  position: relative;
  z-index: 100;
  /* Elevated charcoal: lifted off the pure-black body, hairline divider + soft
     shadow so the bar reads as a clean raised surface (modern, minimal). */
  background: #121419;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset, 0 6px 20px -10px rgba(0, 0, 0, 0.7);
}

.header-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 20px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.logo-link {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.logo-img {
  width: 32px;
  height: 32px;
  border-radius: 6px;
}

.logo-text {
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.nav {
  display: flex;
  gap: 4px;
}

.nav-link {
  padding: 6px 14px;
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-secondary);
  transition: all var(--transition);
}

.nav-link:hover, .nav-link.active {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.lang-switch {
  display: flex;
  background: var(--bg-card);
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--border);
}

.lang-btn {
  font-family: var(--font);
  font-size: 0.75rem;
  font-weight: 600;
  padding: 4px 10px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: all var(--transition);
}

.lang-btn.active {
  background: var(--accent);
  color: #fff;
}

/* Compact Newsletter trigger shown in the header on mobile (the full nav, incl.
   the desktop Newsletter button, is hidden ≤768px). Hidden on desktop. */
.header-nl-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all var(--transition);
  flex-shrink: 0;
}
.header-nl-btn:hover, .header-nl-btn:active {
  color: var(--spotify-green);
  border-color: var(--spotify-green);
}

/* Compact Music link shown in the header on mobile (the full nav, incl. the
   desktop "Music" link, is hidden ≤768px). Hidden on desktop. Mirrors .header-nl-btn. */
.header-music-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all var(--transition);
  flex-shrink: 0;
}
.header-music-btn:hover, .header-music-btn:active {
  color: var(--spotify-green);
  border-color: var(--spotify-green);
}

/* Compact chart switcher shown in the header on mobile (≤768px) so you can jump
   between the Top Artists and Top Songs charts — replaces the lone music icon, which
   gave no way back to the artist chart. Hidden on desktop (the text nav handles it).
   Mirrors .lang-switch. The active segment marks the chart you are on. */
.chart-switch {
  display: none;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  flex-shrink: 0;
}
.chart-switch-btn {
  font-family: var(--font);
  font-size: 0.72rem;
  font-weight: 600;
  padding: 5px 10px;
  color: var(--text-muted);
  white-space: nowrap;
  transition: all var(--transition);
}
.chart-switch-btn.active {
  background: var(--accent);
  color: #fff;
}

/* ── Hero Section ────────────────────────────────────────────── */
.hero {
  background: linear-gradient(180deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
  padding: 28px 20px 16px;   /* 28px chip→top gap (was 48); tighter bottom → smaller gap to controls */
  text-align: center;
}

.hero-inner {
  max-width: var(--max-width);
  margin: 0 auto;
}

.hero-line1 {
  display: block;
  font-size: clamp(1.5rem, 4vw, 2.4rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.2;
}

.hero-line2 {
  display: block;
  font-size: clamp(1rem, 2.5vw, 1.3rem);
  font-weight: 500;
  color: var(--accent);
  margin-top: 4px;
}

.hero-sub {
  margin-top: 12px;
  font-size: 0.9rem;
  color: var(--text-secondary);
  max-width: 500px;
  margin-left: auto;
  margin-right: auto;
}

/* ── Last Updated Label ─────────────────────────────────────── */
.last-updated {
  display: inline-block;
  margin-top: 10px;
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--text-muted);
  letter-spacing: 0.03em;
  opacity: 0.7;
}

/* ── Chart-info popover — shared across all chart pages ─────── */
.chart-info-wrap{margin:12px 0 0;text-align:center}
.chart-info-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;border:1px solid var(--border);border-radius:999px;background:var(--bg-secondary);color:var(--text-secondary);font-size:.78rem;font-weight:600;cursor:pointer;transition:border-color .14s,color .14s;user-select:none;font-family:inherit;line-height:1.4}
.chart-info-btn:hover,.chart-info-btn[aria-expanded="true"]{border-color:var(--accent);color:var(--text-primary)}
.chart-info-ic{width:15px;height:15px;flex:0 0 auto}
.chart-info-popup{position:fixed;z-index:980;width:min(296px,calc(100vw - 24px));background:#0f0f0f;border:1px solid rgba(255,255,255,.1);border-radius:14px;padding:16px 18px;box-shadow:0 20px 60px rgba(0,0,0,.85);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s ease,visibility .18s ease;text-align:start}
.chart-info-popup.cip-open{opacity:1;visibility:visible;pointer-events:auto}
.chart-info-popup h3{font-size:.7rem;font-weight:700;color:rgba(255,255,255,.7);margin:0 0 4px;letter-spacing:.06em;text-transform:uppercase}
.chart-info-popup p{font-size:.78rem;line-height:1.64;color:rgba(255,255,255,.56);margin:0 0 12px}
.chart-info-popup p:last-child{margin:0}
.chart-info-popup .cip-rule{border:none;border-top:1px solid rgba(255,255,255,.07);margin:10px 0}
.chart-info-popup strong{color:rgba(255,255,255,.8);font-weight:600}

/* ── Controls (Filters + Platform Toggle) ────────────────────── */
.main-content {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 12px 20px 36px;   /* tighter top → smaller gap from the modal to the controls */
}

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

.category-filter {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

.cat-btn {
  font-family: var(--font);
  font-size: 0.8rem;
  font-weight: 500;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 50px;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: all var(--transition);
  white-space: nowrap;
}

.cat-btn:hover {
  border-color: var(--text-muted);
  color: var(--text-primary);
}

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

.platform-toggle {
  display: flex;
  gap: 4px;
  background: var(--bg-card);
  border-radius: 12px;
  padding: 4px;
  border: 1px solid var(--border-light);
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}

.platform-btn {
  font-family: var(--font);
  font-size: 0.85rem;
  font-weight: 600;
  padding: 8px 20px;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: all 0.25s ease;
  display: flex;
  align-items: center;
  gap: 7px;
}

.platform-btn:hover {
  color: var(--text-secondary);
  background: rgba(255,255,255,0.04);
}

.platform-btn.spotify.active {
  background: var(--spotify-green);
  color: #fff;
  box-shadow: 0 2px 12px rgba(29,185,84,0.3);
}

.platform-btn.radiojavan.active {
  background: var(--rj-red);
  color: #fff;
  box-shadow: 0 2px 12px rgba(198,40,40,0.3);
}

/* Trending "Spotify + RJ" (combined) toggle — neutral bright selected state so it
   reads as active without claiming one brand colour (the Spotify button stays green).
   Independent of any parent .*-mode class, so it works on the trending page. */
.platform-btn.combined.active {
  background: rgba(255,255,255,0.16);
  color: #fff;
  box-shadow: 0 2px 12px rgba(0,0,0,0.3);
}

.platform-btn svg { width: 14px; height: 14px; }

/* .rj-icon replaced by .rj-logo SVG */

/* ── Search ──────────────────────────────────────────────────── */
.search-container {
  margin-bottom: 16px;
}

.search-input {
  width: 100%;
  font-family: var(--font);
  font-size: 16px; /* Must be 16px+ to prevent iOS zoom on focus */
  padding: 10px 16px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  outline: none;
  transition: border-color var(--transition);
}

.search-input::placeholder { color: var(--text-muted); }
.search-input:focus { border-color: var(--accent); }

/* ── Sort Indicator ──────────────────────────────────────────── */
.sort-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 14px;
  padding: 10px 20px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: 0.85rem;
  color: var(--text-secondary);
  min-height: 40px;
}

.sort-indicator .sort-label {
  color: var(--text-muted);
  font-size: 0.8rem;
}

.sort-select {
  font-family: var(--font);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 4px 28px 4px 10px;
  cursor: pointer;
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%231DB954' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  transition: border-color var(--transition);
}

.sort-select:focus { border-color: var(--accent); }

.sort-select option {
  background: var(--bg-card);
  color: var(--text-primary);
}

/* ── Leaderboard Table ───────────────────────────────────────── */
.table-container {
  background: var(--bg-card);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  overflow-x: auto;
}

/* CLS fix (homepage only): the chart loads via JS, so reserve vertical space
   while it fills — otherwise the content below (submit section, footer) jumps
   down ~700px on load, which on desktop is a large Cumulative Layout Shift.
   Reserving ~70vh keeps that content below the fold during load, where shifts
   don't count. The loaded chart is far taller than 70vh, so this adds no gap in
   the steady state. Scoped to #leaderboard so the /music page is unaffected. */
#leaderboard .table-container { min-height: 70vh; }

.leaderboard-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
}

.leaderboard-table th {
  background: var(--bg-secondary);
  padding: 12px 16px;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.leaderboard-table th.sortable { cursor: pointer; }
/* No hover color change - it conflicts with the active green highlight */

/* Active sort column header highlight */
.leaderboard-table th.sort-active {
  color: var(--accent);
}

.col-rank { width: 50px; text-align: center; }
.col-artist { text-align: left; }
.col-listeners { width: 170px; text-align: center; }
.col-followers { width: 130px; text-align: center; }

.leaderboard-table td {
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  font-size: 0.9rem;
  vertical-align: middle;
}

.leaderboard-table tr {
  transition: background var(--transition);
}

.leaderboard-table tbody tr:hover {
  background: var(--bg-hover);
}

.leaderboard-table tbody tr:last-child td {
  border-bottom: none;
}

/* Rank cell */
.cell-rank {
  text-align: center;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cell-rank .rank-number { display: inline; }

.rank-arrow {
  font-size: 0.5rem;
  margin-left: 2px;
  font-weight: 700;
  vertical-align: middle;
}

.rank-arrow.up { color: var(--rank-up); }
.rank-arrow.down { color: var(--rank-down); }

/* Total plays column for RJ */
.col-total { width: 130px; text-align: center; }

/* Top 3 ranks */
tr[data-rank="1"] .cell-rank .rank-number,
tr[data-rank="2"] .cell-rank .rank-number,
tr[data-rank="3"] .cell-rank .rank-number {
  color: var(--accent);
  font-weight: 800;
}

/* Artist cell */
.artist-info {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* avatar + name -> profile page; grows and lets the name ellipsis-truncate */
.artist-link {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
}

/* category + platform button group -> never shrinks, so the NAME truncates first */
.artist-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

/* small platform-logo button (Spotify / RadioJavan) -> opens the external profile */
.platform-jump {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  flex-shrink: 0;
  text-decoration: none;
  transition: background-color 0.15s ease, transform 0.15s ease;
}
.platform-jump:hover { background: var(--bg-hover); transform: translateY(-1px); }
/* Both platform marks (Spotify green, RadioJavan black) are flattened to the SAME
   muted gray so they blend into the dark rows instead of drawing the eye. The
   brightness(0) zeroes the source color; invert() sets the gray level. */
.platform-jump-logo { width: 16px; height: 16px; display: block; filter: brightness(0) invert(0.55); opacity: 0.6; }
.platform-jump:hover .platform-jump-logo { filter: brightness(0) invert(0.8); opacity: 0.95; }

.artist-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg-hover);
}

.artist-name {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.artist-name:hover { text-decoration: underline; }

.artist-category {
  display: inline-block;
  font-size: 0.55rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: rgba(255,255,255,0.06);
  padding: 1px 6px;
  border-radius: 3px;
  vertical-align: middle;
  opacity: 0.7;
}

/* Listeners/followers/plays cells -- CENTER aligned */
.cell-number {
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: var(--text-secondary);
}

/* ── Loading / Empty / Error States ──────────────────────────── */
.loading-state, .empty-state, .error-state {
  padding: 60px 20px;
  text-align: center;
  color: var(--text-muted);
}

.spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  margin: 0 auto 16px;
}

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

.hidden { display: none !important; }

.retry-btn {
  font-family: var(--font);
  margin-top: 12px;
  padding: 8px 20px;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 600;
}

/* ── Submit Artist Section ───────────────────────────────────── */
.submit-section {
  background: var(--bg-secondary);
  border-top: 1px solid var(--border);
  padding: 60px 20px;
}

.submit-inner {
  max-width: 560px;
  margin: 0 auto;
  text-align: center;
}

.submit-inner h2 {
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 8px;
}

.submit-desc {
  color: var(--text-secondary);
  font-size: 0.9rem;
  margin-bottom: 28px;
}

.submit-form {
  text-align: left;
}

.form-group {
  margin-bottom: 16px;
}

.form-group label {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--text-secondary);
}

.optional {
  font-weight: 400;
  color: var(--text-muted);
}

.form-input {
  width: 100%;
  font-family: var(--font);
  font-size: 0.9rem;
  padding: 10px 14px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  outline: none;
  transition: border-color var(--transition);
  appearance: none;
}

.form-input:focus { border-color: var(--accent); }
.form-input::placeholder { color: var(--text-muted); }

select.form-input {
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 36px;
}

.form-hint {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-bottom: 16px;
}

.submit-btn {
  width: 100%;
  font-family: var(--font);
  font-size: 0.95rem;
  font-weight: 600;
  padding: 12px;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--transition);
}

.submit-btn:hover { background: var(--spotify-green-hover); transform: translateY(-1px); }
.submit-btn:active { transform: translateY(0); }
.submit-btn:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }

.form-message {
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  text-align: center;
}

.form-message.success {
  background: rgba(76, 175, 80, 0.15);
  color: #4caf50;
  border: 1px solid rgba(76, 175, 80, 0.3);
}

.form-message.error {
  background: rgba(244, 67, 54, 0.15);
  color: #f44336;
  border: 1px solid rgba(244, 67, 54, 0.3);
}

/* ── Related Charts Nav (internal links) ───────────────────────── */
.related-charts {
  background: var(--bg-secondary);
  border-top: 1px solid var(--border);
  padding: 48px 20px;
}
.related-charts-inner {
  max-width: var(--max-width);
  margin: 0 auto;
}
.related-charts h2 {
  font-size: 1.4rem;
  font-weight: 700;
  text-align: center;
  margin-bottom: 6px;
}
.related-charts-sub {
  text-align: center;
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-bottom: 24px;
}
.related-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.related-card {
  display: block;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  text-decoration: none;
  transition: all 0.2s ease;
}
.related-card:hover {
  border-color: var(--accent);
  background: var(--bg-hover);
  transform: translateY(-2px);
}
.related-card h3 {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 4px;
}
.related-card span {
  font-size: 0.8rem;
  color: var(--text-muted);
}
@media (max-width: 768px) {
  .related-grid { grid-template-columns: 1fr 1fr; gap: 8px; }
  .related-card { padding: 12px 14px; }
  .related-card h3 { font-size: 0.85rem; }
  .related-card span { font-size: 0.72rem; }
}

/* ── Discover hubs (people-pages) — internal-link block between newsletter + footer.
   Uses --bg-primary so it reads as a content section, not a second banner, separating
   the in-page signup form above from the footer's newsletter form below. Reuses the
   .related-grid / .related-card visuals for consistency with the top hub nav. */
.discover-charts {
  background: var(--bg-primary);
  border-top: 1px solid var(--border);
  padding: 48px 20px;
}
.discover-charts-inner {
  max-width: var(--max-width);
  margin: 0 auto;
}
.discover-charts h2 {
  font-size: 1.4rem;
  font-weight: 700;
  text-align: center;
  margin-bottom: 6px;
  color: var(--text-primary);
}
.discover-charts-sub {
  text-align: center;
  color: var(--text-muted);
  font-size: 0.9rem;
  line-height: 1.6;
  max-width: 640px;
  margin: 0 auto 24px;
}
.discover-charts-sub strong { color: var(--text-secondary); font-weight: 600; }

/* SEO content links */
.seo-content a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 500;
}
.seo-content a:hover { text-decoration: underline; }

/* ── SEO Content Section ─────────────────────────────────────── */
.seo-content {
  background: var(--bg-primary);
  border-top: 1px solid var(--border);
  padding: 48px 20px;
}

.seo-inner {
  max-width: 720px;
  margin: 0 auto;
}

.seo-content h2 {
  font-size: 1.3rem;
  font-weight: 700;
  margin-bottom: 12px;
  color: var(--text-primary);
}

.seo-content h3 {
  font-size: 1rem;
  font-weight: 600;
  margin-top: 20px;
  margin-bottom: 8px;
  color: var(--text-secondary);
}

.seo-content p {
  font-size: 0.85rem;
  line-height: 1.7;
  color: var(--text-muted);
  margin-bottom: 8px;
}

.seo-content strong {
  color: var(--text-secondary);
  font-weight: 600;
}

/* ── Footer ──────────────────────────────────────────────────── */
.footer {
  background: var(--bg-secondary);
  border-top: 1px solid var(--border);
  padding: 40px 20px;
  text-align: center;
}

.footer-inner {
  max-width: var(--max-width);
  margin: 0 auto;
}

.footer-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-bottom: 8px;
}

.footer-logo { width: 24px; height: 24px; border-radius: 4px; }
.footer-name { font-weight: 700; font-size: 0.95rem; }

.footer-desc {
  font-size: 0.8rem;
  color: var(--text-muted);
  max-width: 400px;
  margin: 0 auto 16px;
}

.footer-links {
  display: flex;
  justify-content: center;
  gap: 16px;
  margin-bottom: 16px;
}

.footer-links a {
  color: var(--text-muted);
  transition: color var(--transition);
}

.footer-links a:hover { color: var(--text-primary); }

.footer-copy {
  font-size: 0.7rem;
  color: var(--text-muted);
}

.footer-maker {
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-top: 12px;
}

/* ── Responsive ──────────────────────────────────────────────── */
@media (max-width: 768px) {
  /* Logo nudged in from the edge (was 12px, felt cramped against the screen
     edge) and kept clear of the notch/rounded corner via safe-area insets. */
  .header-inner {
    padding-top: 0; padding-bottom: 0;
    padding-left: max(18px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
  }
  .nav { display: none; }
  .header-nl-btn { display: inline-flex; }
  .header-music-btn { display: inline-flex; }
  .chart-switch { display: flex; }
  .header-actions { gap: 8px; }

  .hero { padding: 20px 16px 16px; }

  .main-content { padding: 12px 12px 20px; }

  .controls {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    margin-bottom: 12px;
  }

  .category-filter {
    overflow-x: auto;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 4px;
    justify-content: center;
  }

  .platform-toggle {
    justify-content: center;
    padding: 5px;
    border-radius: 14px;
  }

  .platform-btn {
    padding: 10px 22px;
    font-size: 0.85rem;
  }

  /* Mobile table */
  .table-container { overflow-x: hidden; }
  .leaderboard-table { table-layout: fixed; width: 100%; }
  .col-rank { width: 46px; } /* fits 3-digit ranks (100+) + change arrow without overflow */
  /* JS renders only 3 columns on mobile: rank, artist, selected metric */

  .leaderboard-table th,
  .leaderboard-table td { padding: 8px 6px; }

  .leaderboard-table th {
    font-size: 0.6rem;
    letter-spacing: 0.03em;
  }

  .artist-avatar { width: 28px; height: 28px; }
  .artist-name { font-size: 0.82rem; }
  .artist-category { display: none; }
  .cell-number { font-size: 0.82rem; }
  .cell-rank { font-size: 0.8rem; }
  .rank-arrow { font-size: 0.5rem; }

  .sort-indicator { font-size: 0.75rem; padding: 8px 14px; }
  .sort-select { font-size: 0.8rem; }

  .submit-section { padding: 40px 16px; }
}

@media (max-width: 480px) {
  /* The 4-chart switch moved to the sticky pill below the header, freeing room —
     so the "FarsiChart" wordmark stays visible on phones (just a touch smaller so
     it never crowds the Newsletter + EN/FA cluster on the narrowest devices). */
  .logo-text { display: inline; font-size: 1rem; }
  .hero-sub { font-size: 0.8rem; }
  .col-listeners { width: 90px; }
  .leaderboard-table th { font-size: 0.55rem; }
  .artist-avatar { width: 26px; height: 26px; }
  .artist-name { font-size: 0.78rem; }
  .cell-number { font-size: 0.78rem; }
}

/* ── RJ Logo SVG ────────────────────────────────────────────── */
.rj-logo { width: 14px; height: 14px; }

/* ── Print ───────────────────────────────────────────────────── */
@media print {
  .header, .hero, .controls, .search-container, .submit-section, .footer { display: none; }
  body { background: white; color: black; }
  .table-container { border: 1px solid #ccc; }
}

@keyframes obFadeIn {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes obFadeOut {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(-16px); }
}

/* ── Onboarding mobile responsive ── */
@media (max-width: 480px) {
}

@media (max-width: 360px) {
}

@keyframes obSwitchPulse {
  0%, 100% { opacity: 0.4; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.15); }
}

@keyframes obPointerBounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}

/* Load More button (chart pagination) */
.load-more-wrap {
  text-align: center;
}

.load-more-btn {
  display: inline-block;
  margin: 20px auto 4px;
  min-height: 44px;
  padding: 12px 36px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: all var(--transition);
}

.load-more-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--bg-hover);
}

.load-more-btn:active { transform: translateY(1px); }

/* Help button */
.help-btn {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #1e1e1e;
  border: 1px solid #2a2a2a;
  color: #888;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}

.help-btn:hover {
  background: #1DB954;
  color: #fff;
  border-color: #1DB954;
}

/* RJ logo image */
.rj-logo-img {
  width: 16px;
  height: 16px;
  filter: brightness(0) invert(0.5);
}

.platform-btn.radiojavan.active .rj-logo-img {
  filter: brightness(0) invert(1);
}

/* ── AI Citable Rankings Snapshot ────────────────────────────────
   Server-rendered by router.php. This is the "answer box" that
   Google AI Overviews, Perplexity, ChatGPT & Bing Copilot cite.
   Designed to read as an authoritative, dated, sourced summary. */
.ai-snapshot {
  background:
    radial-gradient(120% 100% at 0% 0%, rgba(29,185,84,0.07) 0%, transparent 55%),
    var(--bg-secondary);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 48px 20px;
}

.ai-snapshot-inner {
  max-width: 720px;
  margin: 0 auto;
  position: relative;
  padding-left: 18px;
  border-left: 3px solid var(--accent);
}

.ai-snapshot h2 {
  font-size: 1.32rem;
  font-weight: 800;
  line-height: 1.3;
  margin-bottom: 12px;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}

.ai-snapshot h3 {
  font-size: 0.92rem;
  font-weight: 700;
  margin: 22px 0 12px;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ai-snapshot p {
  font-size: 0.95rem;
  line-height: 1.75;
  color: var(--text-secondary);
  margin-bottom: 10px;
}

.ai-snapshot p strong { color: var(--text-primary); font-weight: 700; }

.ai-snapshot time {
  color: var(--accent);
  font-weight: 600;
  white-space: nowrap;
}

.ai-ranking-list {
  counter-reset: airank;
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  gap: 2px;
}

.ai-ranking-list li {
  counter-increment: airank;
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 9px 14px 9px 10px;
  border-radius: var(--radius-sm);
  font-size: 0.93rem;
  color: var(--text-secondary);
  transition: background var(--transition);
}

.ai-ranking-list li:nth-child(odd) { background: rgba(255,255,255,0.018); }
.ai-ranking-list li:hover { background: var(--bg-hover); }

.ai-ranking-list li::before {
  content: counter(airank);
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--bg-primary);
  background: var(--accent);
  border-radius: 50%;
  transform: translateY(2px);
}

.ai-ranking-list li:nth-child(1)::before { background: #FFD24A; color: #2a1f00; }
.ai-ranking-list li:nth-child(2)::before { background: #D6DCE4; color: #1a1f24; }
.ai-ranking-list li:nth-child(3)::before { background: #E0915A; color: #2a1500; }

.ai-ranking-list li strong { color: var(--text-primary); font-weight: 700; }

.snap-genre {
  color: var(--text-muted);
  font-size: 0.8rem;
  font-weight: 500;
  margin-left: auto;
  padding-left: 10px;
  white-space: nowrap;
}

.ai-snapshot-source {
  margin-top: 18px;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text-muted);
  border-top: 1px dashed var(--border-light);
  padding-top: 14px;
}

@media (max-width: 600px) {
  .ai-snapshot { padding: 36px 16px; }
  .ai-snapshot h2 { font-size: 1.12rem; }
  .ai-snapshot-inner { padding-left: 14px; }
  .ai-ranking-list li { flex-wrap: wrap; font-size: 0.88rem; }
  .snap-genre { margin-left: 36px; padding-left: 0; }
}

/* ── Footer newsletter signup + Pro link ─────────────────────── */
.footer-newsletter { max-width: 420px; margin: 18px auto 6px; text-align: center; }
.footer-nl-label { display: block; font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 8px; font-weight: 500; }
.footer-nl-row { display: flex; gap: 8px; }
.footer-nl-input {
  flex: 1; min-width: 0; font-family: var(--font); font-size: 0.85rem; padding: 9px 12px;
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-primary); outline: none; transition: border-color var(--transition);
}
.footer-nl-input:focus { border-color: var(--accent); }
.footer-nl-input::placeholder { color: var(--text-muted); }
.footer-nl-btn {
  font-family: var(--font); font-size: 0.85rem; font-weight: 600; padding: 9px 18px;
  background: var(--accent); color: #fff; border: none; border-radius: var(--radius-sm);
  cursor: pointer; transition: opacity var(--transition); white-space: nowrap;
}
.footer-nl-btn:hover { opacity: 0.9; }
.footer-nl-btn:disabled { opacity: 0.6; cursor: default; }
.footer-nl-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.footer-nl-msg { font-size: 0.78rem; margin-top: 8px; }
.footer-nl-msg.success { color: var(--rank-up); }
.footer-nl-msg.error { color: var(--rank-down); }
.footer-nl-privacy { font-size: 0.68rem; color: var(--text-muted); margin-top: 8px; opacity: 0.75; }
.footer-pro { margin-top: 14px; }
.footer-pro a { font-size: 0.8rem; color: var(--accent); font-weight: 600; }
.footer-pro a:hover { text-decoration: underline; }
@media (max-width: 480px) { .footer-nl-row { flex-direction: column; } }

/* ── Footer CTA (replaces the old inline newsletter form) ──────── */
.footer-cta { display: flex; flex-direction: column; align-items: center; gap: 10px; margin: 18px auto 6px; }
.footer-subscribe-link {
  font-family: var(--font); font-size: 0.9rem; font-weight: 600; padding: 10px 22px;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 50px;
  color: var(--text-primary); cursor: pointer; transition: all var(--transition);
}
.footer-subscribe-link:hover { border-color: var(--spotify-green); color: var(--spotify-green); }
.footer-pro-link { font-size: 0.8rem; color: var(--accent); font-weight: 600; }
.footer-pro-link:hover { text-decoration: underline; }

/* ═══════════════════════════════════════════════════════════════
   Reusable Signup Widget (js/signup.js) — dark, on-brand, RTL-aware
   Covers: nav Subscribe button, slim homepage/artist banner, the widget
   internals (Email/Phone toggle, inputs, submit), intl-tel-input dark
   overrides, and the celebratory success panel + animated checkmark.
   ═══════════════════════════════════════════════════════════════ */

/* ── Nav "Subscribe" button (desktop only) ─────────────────────── */
.nav-subscribe-btn {
  font-family: var(--font);
  font-size: 0.78rem;
  font-weight: 600;
  padding: 5px 14px;
  margin: 0 2px;
  border: 1px solid var(--spotify-green);
  border-radius: 50px;
  background: var(--spotify-green-dim);
  color: var(--spotify-green);
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--transition);
}
.nav-subscribe-btn:hover {
  background: var(--spotify-green);
  color: #fff;
}
/* The nav itself is hidden on mobile (≤768px), but guard the button explicitly
   in case it is ever placed outside .nav. */
@media (max-width: 768px) {
  .nav-subscribe-btn { display: none !important; }
}
/* RTL: flip the small left margin so it sits correctly after the prior nav item. */
html[dir="rtl"] .nav-subscribe-btn { margin: 0 2px; }

/* ── Slim signup banner (homepage + artist page) ───────────────── */
.fc-signup-banner {
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(29,185,84,0.10) 0%, transparent 55%),
    var(--bg-secondary);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 32px 20px;
}
.fc-signup-banner-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
}
.fc-signup-pitch { flex: 1 1 320px; min-width: 0; }
.fc-signup-pitch h2 {
  font-size: 1.3rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  margin-bottom: 6px;
}
.fc-signup-pitch p {
  font-size: 0.9rem;
  color: var(--text-secondary);
  line-height: 1.55;
  max-width: 460px;
}
.fc-signup-banner .fc-signup-form { flex: 1 1 340px; min-width: 0; max-width: 460px; }

/* ── The widget itself ─────────────────────────────────────────── */
.fc-signup {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.fc-input {
  width: 100%;
  font-family: var(--font);
  font-size: 16px; /* 16px+ prevents iOS zoom-on-focus */
  padding: 11px 14px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  outline: none;
  transition: border-color var(--transition);
  appearance: none;
  -webkit-appearance: none;
}
.fc-input:focus { border-color: var(--spotify-green); }
.fc-input::placeholder { color: var(--text-muted); }

/* Email | Phone segmented toggle */
.fc-toggle {
  display: flex;
  gap: 3px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 3px;
}
.fc-toggle-btn {
  flex: 1 1 0;
  font-family: var(--font);
  font-size: 0.82rem;
  font-weight: 600;
  padding: 8px 14px;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: all var(--transition);
}
.fc-toggle-btn:hover { color: var(--text-secondary); }
.fc-toggle-btn.is-active {
  background: var(--spotify-green);
  color: #fff;
  box-shadow: 0 2px 10px rgba(29,185,84,0.25);
}

.fc-contact-wrap { width: 100%; }

/* Visually-hidden honeypot (kept in flow, off-screen). */
/* Honeypot: hidden with the scroll-safe sr-only pattern (NOT left:-9999px, which
   created real horizontal scroll into empty space on RTL/Farsi pages). Still a
   real, named, fillable input, so bots trip it exactly as before. */
.fc-hp {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  border: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  opacity: 0 !important;
}

/* Submit button */
.fc-submit {
  width: 100%;
  font-family: var(--font);
  font-size: 0.95rem;
  font-weight: 700;
  padding: 13px;
  background: var(--spotify-green);
  color: #fff;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--transition);
  box-shadow: 0 2px 16px rgba(29,185,84,0.25);
}
.fc-submit:hover { background: var(--spotify-green-hover); transform: translateY(-1px); }
.fc-submit:active { transform: translateY(0); }
.fc-submit:disabled { opacity: 0.6; cursor: default; transform: none; }

/* Inline message */
.fc-msg {
  font-size: 0.82rem;
  margin-top: 2px;
  text-align: center;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
}
.fc-msg.success { color: var(--rank-up); background: rgba(76,175,80,0.12); }
.fc-msg.error { color: var(--rank-down); background: rgba(244,67,54,0.12); }

/* Already-subscribed note (prepended to any form when the visitor has signed up
   before). Subtle, on-brand, non-blocking — the form below stays fully usable. */
.fc-already {
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.45;
  color: var(--spotify-green);
  background: var(--spotify-green-dim);
  border: 1px solid rgba(29,185,84,0.28);
  border-radius: var(--radius-md);
  padding: 9px 12px;
  text-align: center;
}

/* Compact variant (inside the slim banner): toggle + contact + button on one
   tidy column but a touch tighter; still stacks safely on mobile. */
.fc-signup--compact { gap: 8px; }
.fc-signup--compact .fc-input,
.fc-signup--compact .fc-submit { padding: 10px 14px; }

/* ── intl-tel-input dark-theme overrides (v23) ─────────────────── */
.fc-signup .iti { width: 100%; display: block; }
.fc-signup .iti__tel-input,
.fc-signup input.iti__tel-input {
  width: 100%;
}
/* Selected country / flag container (v23 uses .iti__selected-country; older
   builds use .iti__selected-flag — style both for safety). */
.fc-signup .iti__selected-country,
.fc-signup .iti__selected-flag {
  background: var(--bg-card);
  border-radius: var(--radius-md) 0 0 var(--radius-md);
}
.fc-signup .iti__selected-country:hover,
.fc-signup .iti__selected-flag:hover,
.fc-signup .iti__selected-country-primary:hover {
  background: var(--bg-hover);
}
.fc-signup .iti__selected-dial-code { color: var(--text-secondary); }
.fc-signup .iti__arrow { border-top-color: var(--text-muted); }
.fc-signup .iti__arrow--up { border-bottom-color: var(--text-muted); }

/* Country dropdown list */
.fc-signup .iti__dropdown-content,
.iti__dropdown-content,
.iti--container .iti__country-list,
.fc-signup .iti__country-list {
  background: var(--bg-card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  color: var(--text-primary);
}
.iti__country,
.fc-signup .iti__country {
  color: var(--text-primary);
  padding: 8px 12px;
}
.iti__country.iti__highlight,
.iti__country:hover {
  background: var(--bg-hover);
}
.iti__dial-code { color: var(--text-muted); }
.iti__search-input,
.fc-signup .iti__search-input {
  background: var(--bg-input);
  color: var(--text-primary);
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 9px 12px;
  /* 16px keeps iOS from zooming the viewport when the country-search box
     auto-focuses (the mobile country picker was unusable because of this). */
  font-size: 16px;
}
.iti__search-input::placeholder { color: var(--text-muted); }
/* Divider between preferred + full list */
.iti__divider { border-bottom-color: var(--border); }
/* The mobile fullscreen country picker is appended to <body> at z-index 1060,
   which is BELOW the signup modal (.ob-overlay = 9999) — so opened from inside
   the modal it rendered behind it (the arrow flipped but nothing was visible /
   clickable). Lift the picker container above the modal. */
.iti--container { z-index: 10001 !important; }

/* ── Success panel + animated checkmark ────────────────────────── */
.fc-signup-done {
  text-align: center;
  padding: 18px 8px 8px;
  animation: fcDoneIn 0.45s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes fcDoneIn {
  from { opacity: 0; transform: translateY(10px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.fc-check-wrap {
  width: 72px;
  height: 72px;
  margin: 0 auto 16px;
  border-radius: 50%;
  background: var(--spotify-green-dim);
  display: flex;
  align-items: center;
  justify-content: center;
}
.fc-check { width: 48px; height: 48px; }
.fc-check-circle {
  stroke: var(--spotify-green);
  stroke-width: 2.5;
  stroke-dasharray: 151;
  stroke-dashoffset: 151;
  animation: fcCircle 0.5s ease-out 0.05s forwards;
}
.fc-check-tick {
  stroke: var(--spotify-green);
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
  animation: fcTick 0.35s cubic-bezier(0.65, 0, 0.45, 1) 0.45s forwards;
}
@keyframes fcCircle { to { stroke-dashoffset: 0; } }
@keyframes fcTick { to { stroke-dashoffset: 0; } }
.fc-done-title {
  font-size: 1.4rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin-bottom: 6px;
}
.fc-done-sub {
  font-size: 0.9rem;
  color: var(--text-secondary);
  line-height: 1.55;
  max-width: 340px;
  margin: 0 auto;
}
@media (prefers-reduced-motion: reduce) {
  .fc-signup-done,
  .fc-check-circle,
  .fc-check-tick { animation: none; }
  .fc-check-circle, .fc-check-tick { stroke-dashoffset: 0; }
}

/* ── RTL awareness for the widget ──────────────────────────────── */
/* The banner lays out pitch + form as a flex row; on RTL the inherited
   direction reverses the order so the pitch sits on the right (reading start)
   and the form on the left. Make the whole widget RTL so labels/placeholders
   read naturally; the email/tel VALUES are forced back to LTR below. */
html[dir="rtl"] .fc-signup-banner-inner { direction: rtl; }
html[dir="rtl"] .fc-signup-pitch h2,
html[dir="rtl"] .fc-signup-pitch p { text-align: right; }
html[dir="rtl"] .fc-signup { direction: rtl; }
html[dir="rtl"] .fc-already { text-align: center; }
html[dir="rtl"] .fc-done-sub,
html[dir="rtl"] .fc-msg { text-align: center; }

/* Name + location are free text — let them flow RTL with right-aligned
   placeholders so Persian reads naturally. */
html[dir="rtl"] .fc-input-name,
html[dir="rtl"] .fc-input-location {
  direction: rtl;
  text-align: right;
}

/* Email | Phone segmented toggle: buttons fill the row evenly, so the visual
   flip is automatic under RTL; just keep each label centered. */
html[dir="rtl"] .fc-toggle-btn { text-align: center; }

/* Submit button label centered (it's full-width). */
html[dir="rtl"] .fc-submit { text-align: center; }

/* Keep email + tel typed VALUES LTR even on the RTL page (so you@…, +1… and
   digits render in the correct order). Align them to the field start — which is
   the right edge on the RTL page — so the placeholder reads from the right. */
html[dir="rtl"] .fc-input-email,
html[dir="rtl"] .fc-input-tel,
html[dir="rtl"] .fc-signup .iti__tel-input {
  direction: ltr;
  text-align: right;
  unicode-bidi: plaintext;
}
/* On RTL, intl-tel-input's flag/dial-code sits on the right; round that corner
   instead and keep the country selector itself LTR (flag + +code order). */
html[dir="rtl"] .fc-signup .iti,
html[dir="rtl"] .fc-signup .iti--separate-dial-code { direction: ltr; }
html[dir="rtl"] .fc-signup .iti__selected-country,
html[dir="rtl"] .fc-signup .iti__selected-flag {
  border-radius: var(--radius-md) 0 0 var(--radius-md);
}

/* ── Banner responsive (stack vertically; safe down to 360px) ──── */
@media (max-width: 768px) {
  .fc-signup-banner { padding: 24px 16px; }
  .fc-signup-banner-inner { flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 16px; }
  /* In a column the children's flex-basis becomes HEIGHT, so the desktop
     `flex: 1 1 320px/340px` forced the pitch to 320px tall — leaving a big
     empty gap above the form. Reset to natural content height on mobile. */
  .fc-signup-pitch,
  .fc-signup-banner .fc-signup-form { flex: 0 0 auto; }
  .fc-signup-pitch { text-align: center; }
  .fc-signup-pitch p { margin-left: auto; margin-right: auto; }
  .fc-signup-banner .fc-signup-form { max-width: 100%; }
}
@media (max-width: 360px) {
  .fc-signup-pitch h2 { font-size: 1.15rem; }
  .fc-toggle-btn { padding: 8px 8px; font-size: 0.78rem; }
  .fc-done-title { font-size: 1.2rem; }
}

/* Print: hide the marketing banner. */
@media print { .fc-signup-banner { display: none; } }

/* ════════════════════════════════════════════════════════════════
   Page Identity Themes
   Homepage / Top Artists : unchanged (no body class)
   Top Songs (.page-songs) : dark-green background + green accent
   New Releases (.page-new) : dark-purple background + purple accent
   Trending Now (.page-trending): dark-gold background + gold accent

   The gradient is applied on the body so it covers the nav bar,
   the banner, and the hero in one continuous sweep — 720px fades
   to pure black by the time the chart table starts.
   .header / .hero / .tr-hero are set to transparent so the body
   gradient shows through without a second competing background.
   Platform source badges (--spotify-green / --rj-red) are never
   overridden and always keep their native brand colours.
   ════════════════════════════════════════════════════════════════ */

/* ── Top Songs: dark-green glow starting below nav ───────────── */
body.page-songs{
  /* 0–56px = solid black (behind nav, matching its own bg).
     Hard stop at 56px = nav bottom → page colour begins immediately.
     Fades back to black by 780px (well past banner+hero). */
  background:linear-gradient(180deg,#0a0a0a 56px,#091a0d 56px,#0a0a0a 780px);
}
body.page-songs .hero{background:transparent}

/* ── New Releases: dark-purple glow starting below nav ───────── */
body.page-new{
  --accent:#8b5cf6;
  background:linear-gradient(180deg,#0a0a0a 56px,#0e0a1c 56px,#0a0a0a 780px);
}
body.page-new .hero{background:transparent}
/* Force purple accent in both Spotify and RJ platform modes */
body.page-new .main-content,
body.page-new .main-content.spotify-mode,
body.page-new .main-content.rj-mode{--accent:#8b5cf6}
/* Purple sort-select chevron arrow */
body.page-new .sort-select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%238b5cf6' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
}

/* ── Trending Now: dark-gold glow starting below nav ─────────── */
body.page-trending{
  --accent:#d4a017;
  background:linear-gradient(180deg,#0a0a0a 56px,#1a1200 56px,#0a0a0a 780px);
}
/* Override the explicit --accent + background set inline on
   .tr-hero / .tr-wrap / .tr-seo (higher specificity wins). */
body.page-trending .tr-hero{background:transparent;--accent:#d4a017}
body.page-trending .tr-wrap{--accent:#d4a017}
body.page-trending .tr-seo{--accent:#d4a017}
/* Top-3 row heatmap: green → gold */
body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="1"]{background:linear-gradient(90deg,rgba(212,160,23,.12) 0%,transparent 52%)}
body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="2"]{background:linear-gradient(90deg,rgba(212,160,23,.07) 0%,transparent 52%)}
body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="3"]{background:linear-gradient(90deg,rgba(212,160,23,.04) 0%,transparent 52%)}
html[dir="rtl"] body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="1"]{background:linear-gradient(270deg,rgba(212,160,23,.12) 0%,transparent 52%)}
html[dir="rtl"] body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="2"]{background:linear-gradient(270deg,rgba(212,160,23,.07) 0%,transparent 52%)}
html[dir="rtl"] body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="3"]{background:linear-gradient(270deg,rgba(212,160,23,.04) 0%,transparent 52%)}
body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="1"]:hover,
body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="2"]:hover,
body.page-trending .tr-wrap .leaderboard-table tbody tr[data-rank="3"]:hover{background:rgba(212,160,23,.09)}
/* Trending info button hover: green → gold */
body.page-trending .tr-info-btn:hover,
body.page-trending .tr-info-btn:focus{outline:none;border-color:#d4a017;color:#d4a017}
/* Gold sort-select chevron arrow */
body.page-trending .sort-select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%23d4a017' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
}

/* ── Ad banner: transparent so body page gradient shows through ─ */
/* monetize_lib.php injects background:#111 on .fc-ad-band via a scoped
   inline <style> with specificity (1,1,0). Override with (1,2,1) to win. */
body.page-songs #fc-slot-music_top.fc-ad-band,
body.page-new #fc-slot-music_top.fc-ad-band,
body.page-trending #fc-slot-music_trending_top.fc-ad-band{background:transparent}

/* ════════════════════════════════════════════════════════════════════════════
   Shared site footer (inc/footer.php → fc_site_footer) — premium + responsive.
   One footer on every page: newsletter band + brand/link columns + legal bar.
   ════════════════════════════════════════════════════════════════════════════ */
.site-footer{ margin-top:48px; background:linear-gradient(180deg,#0c0e12 0%,#090a0d 100%);
  border-top:1px solid rgba(255,255,255,.07); box-shadow:0 -1px 0 rgba(255,255,255,.02) inset; }
.site-footer-inner{ max-width:var(--max-width); margin:0 auto; padding:40px 20px 26px; box-sizing:border-box; }

/* Newsletter band */
.ftr-news{ display:flex; align-items:center; justify-content:space-between; gap:26px; flex-wrap:wrap;
  background:linear-gradient(135deg,rgba(29,185,84,.10),rgba(29,185,84,.03)); border:1px solid rgba(29,185,84,.22);
  border-radius:18px; padding:22px 26px; margin-bottom:40px; }
.ftr-news-copy{ flex:1 1 300px; min-width:0; }
.ftr-news-copy h2{ font-size:1.18rem; font-weight:700; color:var(--text-primary); margin:0 0 5px; letter-spacing:-.01em; }
.ftr-news-copy p{ font-size:.85rem; color:var(--text-secondary); margin:0; line-height:1.5; }
.ftr-news .fc-signup-form{ flex:1 1 360px; min-width:0; max-width:440px; }

/* Brand + link columns */
.ftr-cols{ display:flex; gap:48px; flex-wrap:wrap; align-items:flex-start; padding-bottom:28px; border-bottom:1px solid rgba(255,255,255,.06); }
.ftr-brand{ flex:2 1 280px; min-width:0; }
.ftr-logo{ display:inline-flex; align-items:center; gap:9px; text-decoration:none; color:var(--text-primary); }
.ftr-logo img{ border-radius:6px; }
.ftr-logo span{ font-size:1.1rem; font-weight:700; letter-spacing:-.02em; }
.ftr-tag{ margin:12px 0 14px; font-size:.85rem; line-height:1.6; color:var(--text-secondary); max-width:340px; }
.ftr-social{ display:inline-flex; align-items:center; justify-content:center; width:38px; height:38px; border-radius:10px;
  border:1px solid rgba(255,255,255,.1); color:var(--text-secondary); transition:color .16s,border-color .16s,background .16s; }
.ftr-social:hover{ color:#fff; border-color:rgba(29,185,84,.5); background:rgba(29,185,84,.1); }
.ftr-col{ flex:1 1 150px; min-width:120px; display:flex; flex-direction:column; }
.ftr-col h3{ font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:var(--text-muted); margin:0 0 13px; }
.ftr-col a{ font-size:.88rem; color:var(--text-secondary); text-decoration:none; padding:5px 0; transition:color .14s; width:fit-content; }
.ftr-col a:hover{ color:var(--spotify-green,#1db954); }

/* SEO blurb + legal bottom bar */
.ftr-seo{ font-size:.76rem; line-height:1.7; color:var(--text-muted); margin:24px 0 0; max-width:900px; }
.ftr-seo strong{ color:var(--text-secondary); font-weight:600; }
.ftr-bottom{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-top:20px; padding-top:18px; border-top:1px solid rgba(255,255,255,.06); }
.ftr-bottom p{ margin:0; font-size:.76rem; color:var(--text-muted); }
.ftr-made{ opacity:.85; }
html[dir="rtl"] .ftr-tag{ margin-inline-start:0; margin-inline-end:auto; }

@media (max-width:768px){
  .site-footer-inner{ padding:30px 16px 22px; }
  .ftr-news{ padding:18px 18px; margin-bottom:28px; }
  .ftr-cols{ gap:26px; }
  .ftr-brand{ flex-basis:100%; }
  .ftr-col{ flex:1 1 40%; }
  .ftr-bottom{ flex-direction:column; align-items:flex-start; gap:6px; }
}
@media (max-width:480px){ .ftr-col{ flex-basis:100%; } }

/* ══ TAIL SEARCH: "Beyond the Top 300" ══════════════════════════════════════
   LIVES HERE, NOT IN music.php. That file has TWO complete renders with TWO
   <style> blocks; I put this in the wrong one twice, and each time the divider
   shipped completely unstyled — 23px tall, zero-width rules, label hard against
   the left edge. chart.css is loaded by BOTH renders, so there is no wrong one.
/* "BEYOND THE TOP 300" — a hairline divider, centred, rule on each side.
   Shown only when a search reaches past the chart. It is a signpost, not a
   section: one 34px row, a 1px rule, 11px uppercase label at 55% opacity. The
   rules use flex:1 1 0 (not `auto`) — with `auto` the pseudo-elements size to
   their empty content and never grow, which is why the first attempt rendered
   the label hard against the left edge with no lines at all.
   No margins: a <tr> cannot carry them reliably, so the breathing room is
   padding INSIDE the row and it can never collide with the rows either side. */
/* The divider is a SIGNPOST, not a row: no hover, no cursor, no selection.
   It is a <tr> inside the chart's tbody, so `.leaderboard-table tbody tr:hover`
   lit it up on mouseover exactly like a real song - it looked clickable and it
   is not. pointer-events:none makes the mouse pass straight through (killing
   the hover tint, the text cursor and any drag-select in one go); user-select
   keeps a stray double-click from highlighting the label. */
.fc-beyond{pointer-events:none;user-select:none;-webkit-user-select:none}
.leaderboard-table tbody tr.fc-beyond:hover{background:transparent}
.fc-beyond td{padding:0!important;border:0!important;background:transparent!important}
.fc-beyond-in{display:flex;align-items:center;gap:12px;padding:10px 16px 8px;min-height:34px}
.fc-beyond-in::before,.fc-beyond-in::after{content:"";flex:1 1 0;height:1px;
  background:rgba(255,255,255,.09)}
.fc-beyond-lb{flex:0 0 auto;font-size:.66rem;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;color:rgba(255,255,255,.42);white-space:nowrap;
  font-variant-numeric:tabular-nums}
/* Persian sets no uppercase and needs its natural tracking to stay readable. */
html[dir="rtl"] .fc-beyond-lb{text-transform:none;letter-spacing:0;font-size:.72rem}
@media(max-width:480px){
  .fc-beyond-in{gap:9px;padding:9px 12px 7px;min-height:30px}
  .fc-beyond-lb{font-size:.58rem;letter-spacing:.06em}
  html[dir="rtl"] .fc-beyond-lb{font-size:.66rem}
}
/* A tail row IS a chart row — the server renders it with the same helpers. Only
   the rank is muted, because that number is a catalogue position, not a placing. */
.fc-tail .rank-number{color:rgba(255,255,255,.38);font-weight:700}

/* LONG TITLES MUST ELLIPSIZE, NOT RUN OVER THE PLAY COUNT.
   .artist-name already carried nowrap + ellipsis, but ellipsis needs a width to
   clip against and it never had one: .song-text is a COLUMN flexbox, so its
   children size to their own content on the cross axis and simply overflow it.
   Measured on /fa/music: a 191px cell holding a 360px title and a 196px credit
   line, both painted straight across the number column.
   The top 300 never exposed this — its longest title is 119px — but the deep
   catalogue is full of "(Ft A, B, & C)" credits, so the tail search hit it on
   its first query. Clamping here (not on .fc-tail) means a long title entering
   the chart proper is covered by the same rule. */
.song-info .song-text{min-width:0;overflow:hidden}
.song-info .song-title-row{max-width:100%;min-width:0}
.song-info .song-title-row .artist-name{min-width:0;flex:0 1 auto}
/* The platform logos are the point of the row — the title yields, not them. */
.song-info .song-title-row .platform-jump{flex:0 0 auto}
/* min-width was `auto` here, which is what stopped the credit line shrinking. */
.song-info .song-by{max-width:100%;min-width:0}

/* ON AN RTL PAGE, A CLIPPED TITLE MUST LOSE ITS TAIL, NOT ITS NAME.
   text-overflow puts the ellipsis at the end of the INLINE direction, and on
   /fa/* that direction is RTL. A Latin title is bidi-reordered inside that RTL
   line, so the clip ate the front: "Residam Be Tash (Ft Koorosh, Behzad Leito,
   & Catchybeatz)" rendered as "...Catchybeatz)" - every one of the 14 tail rows
   showing its featured-artist tail and hiding the song, which is the one word
   the reader is scanning for.
   `unicode-bidi: plaintext` resolves each title's direction from its own first
   strong character, so a Latin title clips at its right and a Persian one at
   its left. text-align keeps both hugging the RTL edge of the cell either way. */
html[dir="rtl"] .song-info .song-title-row .artist-name,
html[dir="rtl"] .song-info .song-by{unicode-bidi:plaintext;text-align:right}
/* The credit line needs it for the same reason and loses more by going
   without: a pure-Latin credit clipped to "...rta, Sepehr Khalse & PDC"
   drops the PRIMARY artist and leaves the featured ones, which reads as a
   different song. Mixed credits ("Arta (fa-text)") resolve LTR off their
   first strong character, so the lead artist survives there too. */
