/* ==========================================================================
   Sonava v2 — editorial redesign layer
   ==========================================================================

   Loaded AFTER style.css (and after social.css where that applies), so this
   file is a THEME, not a replacement. style.css still owns the layout of every
   screen the redesign does not restructure; without it, the forty-odd views
   that were never touched here would render unstyled. Everything below either
   redefines a token — which reskins those views for free — or restates one
   component in the new language.

   What changed, and why it is only these things:

   - Geometry. The old system was neumorphic: 20px radii and a double emboss on
     every surface. The new one is editorial print — hairline rules, near-square
     corners, flat planes, and a single soft drop shadow reserved for things
     that genuinely float (the player, the menu, the hero card). Because both
     are expressed through --radius and the --shadow-* family, flipping them at
     the token level restyles the whole site in one place.

   - Colour. Unchanged, on purpose. Every hue here is the hue style.css already
     shipped — the same --accent trio, the same warm pair, the same canvas and
     ink per theme. The reference design was a coral-on-black magazine; the coral
     role is played by --accent-1 and the black by Sonava's own --bg. Nothing
     was resampled from the reference.

   - Type. Latin display text (the wordmark, section numerals, index stamps)
     moves to Syne, and Latin numerals in editorial positions to Instrument
     Serif, both from the reference. Persian text stays on Vazirmatn, because
     neither of those faces has Persian glyphs at all and a fallback here would
     silently swap the whole site's body face on a Persian page.

   RTL: the reference is a left-to-right layout. Everything directional below is
   written in logical properties (inline-start/end, margin-inline) so the mirror
   is automatic rather than a second set of rules that drifts.

   CSP: this file exists because helmet's style-src has no 'unsafe-inline'. No
   rule here may be moved into a style="" attribute — it would be dropped
   silently, which is how the progress bars all rendered full once before.
   ========================================================================== */

:root {
  /* ---- geometry ----
     3px rather than 0: a true square corner on a raster screen aliases along
     the edge of every card, and at this size the eye still reads it as square
     while the renderer gets something to anti-alias. */
  --radius: 3px;
  --radius-sm: 2px;
  --radius-pill: 999px;

  /* Hairline rules do the work the emboss used to. One token, two jobs: the
     border on a surface and the divider between rows. */
  --v2-line: rgba(43, 50, 69, .13);
  --v2-line-strong: rgba(43, 50, 69, .26);

  /* The one hot accent, in the role the reference gave coral.

     #4f8cff is the reference's own value from the themed second revision, and
     it sits inside Sonava's existing accent family — one point off --accent-1
     (#4f7dfb) in light, a shade under --accent-2's neighbour in dark. It is
     written as a literal rather than as var(--accent-1) because the reference
     specifies it directly, and because the same value has to hold in both
     themes for the hot band to read as one colour across a theme switch. */
  --v2-hot: #4f8cff;
  --v2-hot-soft: rgba(79, 140, 255, .12);

  /* Ink text on the hot band, from the reference. A white label on #4f8cff is
     3.1:1 — under AA for the button-sized text that sits there. */
  --v2-hot-ink: #111522;

  /* A darker plane for full-bleed editorial bands (spotlight, submit). In
     light theme this is the one place the page goes dark, which is what gives
     the layout its rhythm. #202a39 is the reference's spotlight ground. */
  --v2-band: #202a39;
  --v2-band-ink: #eef2f7;

  /* The hero plate. Taken from the reference verbatim: four stops from a deep
     navy through the brand blue to a pale sky, which is what stops a fill this
     large from reading flat. */
  --v2-plate: linear-gradient(136deg, #18264e 4%, #365fc5 43%, #557fd9 76%, #9cbcff);

  /* ---- shadows ----
     The names are style.css's, so every existing rule that references them
     picks the new treatment up. They are no longer an emboss: a raised surface
     is now a hairline plus a soft, far-offset drop. */
  --shadow-out: 0 12px 34px rgba(43, 50, 69, .09);
  --shadow-out-lg: 0 22px 60px rgba(43, 50, 69, .13);
  --shadow-out-sm: 0 4px 14px rgba(43, 50, 69, .07);
  --shadow-soft: 0 2px 12px rgba(43, 50, 69, .06);
  --shadow-in: inset 0 0 0 1px var(--v2-line);

  /* ---- type ----
     Latin-only faces. Vazirmatn is listed last in each so a Persian character
     landing in one of these slots still renders rather than tofu. */
  --font-display-latin: 'Syne', 'Vazirmatn', sans-serif;
  --font-serif-latin: 'Instrument Serif', Georgia, 'Vazirmatn', serif;

  /* The page gutter and measure, from the reference. */
  --v2-wrap: 1180px;
  --v2-gutter: 32px;
}

:root[data-theme="dark"] {
  --v2-line: rgba(238, 242, 247, .12);
  --v2-line-strong: rgba(238, 242, 247, .24);
  --v2-hot-soft: rgba(79, 140, 255, .18);

  /* The reference's dark ground, adopted for this theme: #111522 against
     Sonava's own #171b26. The blue-black reads as the same family as the hot
     accent, which the slightly warmer original did not. */
  --bg: #111522;
  --surface: #1c2533;
  --surface-strong: #202a39;
  --text: #eef2f7;
  --text-muted: #b2bac7;
  --text-faint: #7e8999;

  --v2-band: #1a2231;
  --v2-band-ink: #eef2f7;

  /* Dark needs a heavier, tighter shadow: the same alphas over #171b26 are
     invisible, and the light theme's wide spread reads as grey haze. */
  --shadow-out: 0 14px 38px rgba(0, 0, 0, .5);
  --shadow-out-lg: 0 24px 64px rgba(0, 0, 0, .58);
  --shadow-out-sm: 0 4px 16px rgba(0, 0, 0, .42);
  --shadow-soft: 0 2px 14px rgba(0, 0, 0, .38);
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

/* The reference's paper grain.

   On html::after, not body::after — style.css already uses BOTH of body's
   pseudo-elements for the two drifting ambient blobs, and putting the grain on
   one of them silently deletes a blob. The root element's pseudo-elements are
   unused, so this costs nothing and leaves that system intact.

   Fixed rather than absolute so it does not stretch to the document height and
   resample on long pages, and pointer-events:none so it never eats a click.
   Screen blend in dark lifts the texture, multiply in light darkens it — the
   same effect on either ground. It does not move, so reduced motion leaves it
   alone: that preference asks for less motion, not less texture. */
html::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: .035;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 160 160' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.8'/%3E%3C/svg%3E");
}

:root[data-theme="dark"]::after {
  mix-blend-mode: screen;
  opacity: .045;
}

/* The ambient blobs stay, dialled well down and recoloured to the reference's
   two glows — an indigo top-right and a colder teal-blue bottom-left. At the
   old opacity they fought the hairline rules: a soft glow behind a 1px line
   makes the line look broken. */
body::before, body::after { opacity: calc(var(--blob-opacity) * .5); }
:root { --blob-1: rgba(77, 95, 191, .5); --blob-2: rgba(42, 92, 137, .42); }
:root[data-theme="dark"] { --blob-1: rgba(77, 95, 191, .55); --blob-2: rgba(42, 92, 137, .5); }

/* --------------------------------------------------------------------------
   Measure
   -------------------------------------------------------------------------- */

.page,
.nav-inner,
.site-footer .footer-inner {
  max-width: var(--v2-wrap);
}

.page {
  padding-inline: var(--v2-gutter);
  padding-block: 0 6rem;
}

.page-narrow { max-width: 680px; }

/* --------------------------------------------------------------------------
   Typography

   Persian and Latin are tracked differently on purpose. The reference's display
   type is set at -.075em, which on Arabic-script text pulls joined glyphs into
   each other and can break the connecting stroke outright. Persian headings
   therefore get 0 tracking and a taller line box (Vazirmatn's ascenders and
   descenders are deep, and .92 line-height clips them); only the Latin display
   elements, which are set in Syne, take the tight negative tracking.
   -------------------------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  letter-spacing: 0;
  color: var(--text);
}

.v2-latin {
  font-family: var(--font-display-latin);
  letter-spacing: -.04em;
  direction: ltr;
  unicode-bidi: isolate;
}

/* The editorial numeral — "۰۱", "04 — 26", the index stamps. Serif, small, and
   always isolated because a Latin numeral inside an RTL paragraph otherwise
   reorders around neighbouring punctuation. */
.v2-num {
  font-family: var(--font-serif-latin);
  direction: ltr;
  unicode-bidi: isolate;
  font-style: normal;
}

/* Section eyebrow: the small hot-coloured label above every heading in the
   reference. */
.v2-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  color: var(--v2-hot);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .12em;
  margin-bottom: .9rem;
}

.v2-eyebrow .v2-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--v2-hot);
  box-shadow: 0 0 0 4px var(--v2-hot-soft);
  flex: 0 0 auto;
}

.v2-eyebrow .v2-slash { color: var(--text-faint); }

/* The emphasised phrase inside a headline. The reference sets it in an italic
   serif; Persian has no italic, and faux-obliquing Arabic script is a
   well-known way to make it unreadable. The emphasis is carried by colour and
   weight instead, which is how Persian typography actually marks it. */
h1 em, h2 em, h3 em,
.v2-em {
  font-style: normal;
  font-weight: 800;
  color: var(--v2-hot);
}

/* Latin emphasis can have the real thing. */
.v2-latin em, .v2-em-latin {
  font-family: var(--font-serif-latin);
  font-style: italic;
  font-weight: 400;
  color: var(--v2-hot);
}

/* --------------------------------------------------------------------------
   Navigation

   The reference puts the wordmark, the links and the actions on one hairline
   rule with generous height and no surface behind it. The sticky bar stays —
   this site's player and search live up there and people reach for them
   mid-scroll — but the card treatment goes.
   -------------------------------------------------------------------------- */

.nav {
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(18px);
  box-shadow: none;
  border-bottom: 1px solid var(--v2-line);
}

.nav-inner {
  padding-block: 1.15rem;
  padding-inline: var(--v2-gutter);
  gap: 1.4rem;
}

.brand {
  font-family: var(--font-display-latin);
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: .16em;
  margin-inline-end: .5rem;
}

.brand-mark { width: 28px; height: 28px; }

/* Search loses its pill and its inset emboss and becomes a ruled field, which
   is what the reference does with every input on the page. */
.nav-search {
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  border-bottom: 1px solid var(--v2-line);
  padding-inline: 0;
}

.nav-search:focus-within { border-bottom-color: var(--v2-hot); }
.nav-search input { background: transparent; }

.nav-bell,
.theme-toggle,
.nav-toggler {
  border-radius: var(--radius-sm);
  box-shadow: none;
  border: 1px solid var(--v2-line);
  background: transparent;
  transition: border-color .18s ease, color .18s ease, background .18s ease;
}

.nav-bell:hover,
.theme-toggle:hover,
.nav-toggler:hover {
  border-color: var(--v2-hot);
  background: var(--v2-hot-soft);
}

/* --------------------------------------------------------------------------
   Buttons

   The reference has exactly three: a solid hot rectangle, a bordered circle,
   and an underlined text button. Sonava's .btn-accent / .btn-ghost / .btn-gold
   map onto the first and third; .btn-gold keeps the warm gradient because in
   this codebase warm means money, and repainting it hot would make a support
   button look like a navigation button.
   -------------------------------------------------------------------------- */

.btn {
  border-radius: var(--radius-sm);
  box-shadow: none;
  padding: .78rem 1.25rem;
  font-size: .85rem;
  font-weight: 700;
  letter-spacing: .01em;
  transition: transform .18s ease, background .18s ease, border-color .18s ease, color .18s ease;
}

.btn-accent {
  background: var(--v2-hot);
  color: #fff;
}

.btn-accent:hover {
  background: color-mix(in srgb, var(--v2-hot) 82%, #fff);
  box-shadow: none;
  transform: translateY(-2px);
}

.btn-ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--v2-line-strong);
}

.btn-ghost:hover {
  background: var(--v2-hot-soft);
  border-color: var(--v2-hot);
  box-shadow: none;
  transform: translateY(-2px);
}

.btn-gold { border-radius: var(--radius-sm); }
.btn-gold:hover { box-shadow: none; transform: translateY(-2px); }

.btn-lg { padding: .95rem 1.6rem; font-size: .92rem; }

/* The bordered circle from the reference's hero. */
.v2-round {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  flex: 0 0 auto;
  border: 1px solid var(--v2-line-strong);
  border-radius: 50%;
  color: var(--text);
  background: transparent;
  transition: border-color .18s ease, background .18s ease;
}

.v2-round:hover { border-color: var(--v2-hot); background: var(--v2-hot-soft); }

/* Underlined text button — used where the reference has "Play the radio". */
.v2-line-btn {
  display: inline-flex;
  align-items: center;
  gap: .65rem;
  padding: 0 0 .55rem;
  color: var(--text);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--v2-hot);
  font-weight: 700;
  font-size: .82rem;
  cursor: pointer;
}

.v2-line-btn .v2-line-btn-dot {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--v2-hot);
  color: #fff;
}

/* --------------------------------------------------------------------------
   Section headings — the reference's two-column head: title on one side,
   a short standfirst and a "view all" link on the other.
   -------------------------------------------------------------------------- */

.section-title {
  margin-top: 0;
  font-size: clamp(1.7rem, 3.4vw, 2.7rem);
  line-height: 1.3;
  font-weight: 800;
}

.section-sub {
  color: var(--text-muted);
  font-size: .92rem;
  line-height: 1.8;
  max-width: 34rem;
}

.v2-section-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 2rem;
  margin-top: 4.5rem;
  margin-bottom: 1.8rem;
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--v2-line);
}

.v2-section-head .v2-head-side {
  max-width: 20rem;
  text-align: start;
}

.v2-section-head .v2-head-side p {
  color: var(--text-muted);
  font-size: .82rem;
  line-height: 1.7;
  margin: 0;
}

.v2-section-head .v2-head-side a {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  margin-top: 1rem;
  color: var(--v2-hot);
  font-size: .78rem;
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   Filters — the reference's genre pills. Outlined, not filled; the active one
   is the only coloured thing in the row.
   -------------------------------------------------------------------------- */

.chip {
  background: transparent;
  box-shadow: none;
  border: 1px solid var(--v2-line);
  border-radius: var(--radius-pill);
  padding: .5rem .95rem;
  font-size: .78rem;
  transition: color .18s ease, border-color .18s ease, background .18s ease;
}

.chip:hover { color: var(--text); border-color: var(--v2-hot); background: var(--v2-hot-soft); }

.chip-active {
  background: var(--v2-hot-soft);
  border-color: var(--v2-hot);
  color: var(--v2-hot);
  box-shadow: none;
}

/* On a phone the row scrolls rather than wrapping to three lines, exactly as
   the reference does it. Scrollbar hidden because the row is short and an
   always-on bar under six pills reads as a broken element. */
@media (max-width: 680px) {
  .filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: .35rem;
    scrollbar-width: none;
  }
  .filters::-webkit-scrollbar { display: none; }
  .chip { flex: 0 0 auto; }
}

/* --------------------------------------------------------------------------
   Track cards

   The reference's card is not a card: it is a full-bleed square of art with the
   title set underneath on the page ground, and a play button that fades in on
   hover. The surface, the radius and the lift all go.
   -------------------------------------------------------------------------- */

.track-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(215px, 100%), 1fr));
  gap: 1.6rem 1.15rem;
}

.track-card {
  background: transparent;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
  min-width: 0;
}

.track-card:hover { box-shadow: none; transform: none; }

.cover {
  position: relative;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--surface);
}

/* A slow, small zoom on the art is the whole hover state now. It is on the
   image rather than the card so nothing around it moves — a card that lifts
   pushes its neighbours' baselines out of line in a dense grid. */
.cover img { transition: transform .5s cubic-bezier(.2, .7, .3, 1); }
.track-card:hover .cover img { transform: scale(1.045); }

.track-info { padding: .85rem .1rem 0; }

.track-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.5;
}

.track-artist { font-size: .82rem; }

.track-meta {
  margin-top: .7rem;
  padding-top: .6rem;
  border-top: 1px solid var(--v2-line);
  font-size: .72rem;
}

.tag {
  background: transparent;
  box-shadow: none;
  border: 1px solid var(--v2-line);
  border-radius: var(--radius-pill);
  padding: .1rem .55rem;
}

.empty-state {
  color: var(--text-muted);
  border: 1px dashed var(--v2-line-strong);
  border-radius: var(--radius-sm);
  padding: 2rem 1.5rem;
  text-align: center;
}

/* The full-cover "▶" veil duplicated the corner button the markup already
   carries, and two play affordances on one card is one too many. The corner
   button is the one the reference uses, and it is the one that is a real
   <button> with a label, so the veil goes. */
.cover::after { content: none; }

.card-play {
  inset-block-end: .7rem;
  inset-inline-end: .7rem;
  background: var(--surface-strong);
  color: var(--text);
  box-shadow: var(--shadow-out-sm);
  backdrop-filter: none;
  transform: translateY(6px);
}

.track-card:hover .card-play:hover,
.card-play:hover { background: var(--v2-hot); color: #fff; }

/* --------------------------------------------------------------------------
   Hero

   The reference's hero is a two-column spread: type on one side, a rotated
   art card inside two orbit rings on the other, with a floating annotation
   over the corner. Sonava's hero was centred with the brand mark above the
   headline; this restates it as the spread and moves the mark into the art.
   -------------------------------------------------------------------------- */

.hero {
  display: grid;
  grid-template-columns: 1fr 1.02fr;
  align-items: center;
  gap: 2.4rem;
  padding: 3.4rem 0 4.4rem;
  text-align: start;
}

.hero-copy { min-width: 0; }

.hero h1 {
  margin: 0 0 1.4rem;
  max-width: 15ch;
  font-size: clamp(2.6rem, 6vw, 4.6rem);
  line-height: 1.18;
  font-weight: 800;
  /* The gradient-clipped text and its drift animation both go. At this size on
     a hairline layout the fill washed the headline out, and the drift is the
     kind of always-on motion the reference deliberately does without. */
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--text);
  animation: none;
}

.hero p {
  max-width: 27rem;
  margin: 0 0 1.6rem;
  color: var(--text-muted);
  font-size: .98rem;
  line-height: 1.9;
}

.hero-actions {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  gap: .9rem;
  flex-wrap: wrap;
}

/* The reference's small two-line note beside the buttons. */
.hero-note {
  color: var(--text-faint);
  font-size: .68rem;
  line-height: 1.6;
}

/* ---- the art side ---- */

.hero-art-wrap {
  position: relative;
  min-height: 460px;
  display: grid;
  place-items: center;
}

/* Two rings, off-centre and counter-rotated, exactly as the reference has
   them. Decorative, so aria-hidden in the markup and no content here. */
.hero-orbit {
  position: absolute;
  border: 1px solid;
  border-radius: 50%;
  pointer-events: none;
}

.orbit-one {
  width: min(490px, 96%);
  height: 300px;
  top: 12%;
  inset-inline-end: -6%;
  transform: rotate(28deg);
  border-color: color-mix(in srgb, var(--accent-2) 45%, transparent);
}

.orbit-two {
  width: min(370px, 74%);
  height: 235px;
  top: 18%;
  inset-inline-end: 8%;
  transform: rotate(-18deg);
  border-color: color-mix(in srgb, var(--accent-0) 42%, transparent);
}

/* A very slow counter-drift. Transform-only, so it stays on the compositor and
   costs no layout; suppressed wholesale by the reduced-motion rule in
   style.css, which already targets every animation on the page. */
.hero-orbit { animation: v2-orbit 34s linear infinite; }
.orbit-two { animation-direction: reverse; animation-duration: 46s; }

@keyframes v2-orbit {
  from { transform: rotate(28deg); }
  to   { transform: rotate(388deg); }
}

.hero-art-card {
  position: relative;
  z-index: 2;
  width: min(340px, 78%);
  transform: rotate(4deg);
}

.hero-art-image {
  position: relative;
  overflow: hidden;
  aspect-ratio: .8;
  border-radius: var(--radius);
  background: var(--v2-plate);
  box-shadow: var(--shadow-out-lg);
  display: grid;
  place-items: center;
}

/* The brand mark, which used to sit above the headline, is now the subject of
   the plate. Same file, same float. */
.hero-art-image .hero-mark {
  position: relative;
  z-index: 1;
  width: 44%;
  margin: 0;
  filter: drop-shadow(0 10px 26px rgba(0, 0, 0, .3));
}

/* The reference's equaliser bars in the corner of the plate. Sized as a
   percentage of the plate so they hold their proportion when it shrinks. */
.hero-art-bars {
  position: absolute;
  inset-inline-end: 8%;
  top: 14%;
  display: flex;
  align-items: flex-end;
  gap: 5px;
  height: 30%;
}

.hero-art-bars i {
  display: block;
  width: 3px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .85);
  animation: v2-bar 1.5s ease-in-out infinite;
}

.hero-art-bars i:nth-child(1) { height: 40%; animation-delay: 0s; }
.hero-art-bars i:nth-child(2) { height: 76%; animation-delay: .18s; }
.hero-art-bars i:nth-child(3) { height: 55%; animation-delay: .36s; }
.hero-art-bars i:nth-child(4) { height: 95%; animation-delay: .12s; }
.hero-art-bars i:nth-child(5) { height: 60%; animation-delay: .3s; }

@keyframes v2-bar {
  0%, 100% { transform: scaleY(.55); }
  50%      { transform: scaleY(1); }
}

.art-stamp,
.art-caption {
  position: absolute;
  z-index: 1;
  color: #fff;
  font-size: .58rem;
  letter-spacing: .12em;
}

.art-stamp { top: 7%; inset-inline-start: 8%; }

.art-caption {
  bottom: 6%;
  inset-inline-start: 8%;
  font-size: .72rem;
  line-height: 1.5;
  letter-spacing: 0;
}

.hero-art-meta {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-top: .8rem;
  color: var(--text-faint);
  font-size: .6rem;
  letter-spacing: .1em;
}

/* The annotation card that overlaps the art. Rotated the other way from the
   plate so the two read as separate pieces of paper. */
.floating-note {
  position: absolute;
  z-index: 3;
  inset-inline-start: 0;
  bottom: 8%;
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  max-width: 13rem;
  padding: .85rem 1rem;
  color: var(--text);
  background: var(--surface-strong);
  border: 1px solid var(--v2-line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-out);
  font-size: .68rem;
  line-height: 1.6;
  transform: rotate(-3deg);
}

.floating-note b { color: var(--v2-hot); font-weight: 700; }

.hero-index {
  position: absolute;
  inset-inline-end: 0;
  bottom: 2%;
  display: flex;
  align-items: center;
  gap: .6rem;
  color: var(--v2-hot);
  font-size: .62rem;
  letter-spacing: .16em;
}

.hero-index span {
  width: 45px;
  height: 1px;
  background: var(--v2-hot);
}

/* --------------------------------------------------------------------------
   Signal strip — the three-up rule-separated band under the hero.
   -------------------------------------------------------------------------- */

.signal-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--v2-line);
  border-bottom: 1px solid var(--v2-line);
  padding: 1.4rem 0;
}

.signal-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-inline: 1.5rem;
  border-inline-end: 1px solid var(--v2-line);
}

.signal-item:first-child { padding-inline-start: 0; }
.signal-item:last-child { border-inline-end: 0; padding-inline-end: 0; }

.signal-number {
  color: var(--v2-hot);
  font-family: var(--font-serif-latin);
  font-size: .85rem;
  direction: ltr;
}

.signal-item b { display: block; font-size: .82rem; font-weight: 700; }
.signal-item small { display: block; margin-top: .25rem; color: var(--text-muted); font-size: .72rem; }

/* --------------------------------------------------------------------------
   Spotlight — the full-bleed image band with copy alongside. The reference
   uses it for its radio show; here it carries whatever the page's feature
   block is (live activity on the home page, the artist on /artists).
   -------------------------------------------------------------------------- */

.spotlight {
  display: grid;
  grid-template-columns: 1.12fr .88fr;
  min-height: 460px;
  margin: 5rem 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--v2-band);
  color: var(--v2-band-ink);
}

.spotlight h2,
.spotlight h3 { color: var(--v2-band-ink); }

.spotlight-image {
  position: relative;
  overflow: hidden;
  min-height: 300px;
  background: var(--v2-plate);
}

.spotlight-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* The reference ships a red-lit concert photograph and a warm studio
     portrait, and turns both blue in CSS rather than by re-shooting them:
     desaturate, rotate the hue into the brand's range, then restore contrast.
     Without the hue rotation the one warm image on the page fights every other
     colour in the layout.

     200deg rather than the reference's 165: the stage lighting in this
     photograph is almost pure red, and 165 lands it on cyan — green-blue, next
     to a page whose every other accent is #4f8cff. 200 puts the same light on
     azure, which is the colour the reference was reaching for. */
  filter: saturate(.55) hue-rotate(200deg) contrast(1.05);
}

.image-overlay {
  position: absolute;
  inset: 0;
  /* Two stops: a horizontal fade into the copy column so the join is not a
     hard edge, and a vertical one so the corner stamps stay legible over a
     bright photograph. */
  background:
    linear-gradient(to var(--v2-fade-dir, left), transparent 52%, var(--v2-band) 100%),
    linear-gradient(0deg, rgba(15, 18, 28, .45), transparent 55%);
}

.spotlight-tag {
  position: absolute;
  top: 1.4rem;
  inset-inline-start: 1.5rem;
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .45rem .7rem;
  color: #fff;
  background: rgba(15, 18, 28, .7);
  border-radius: var(--radius-sm);
  font-size: .62rem;
  letter-spacing: .09em;
}

.image-number {
  position: absolute;
  inset-inline-end: 1.4rem;
  bottom: 1.2rem;
  color: #fff;
  font-family: var(--font-serif-latin);
  font-size: .8rem;
  direction: ltr;
}

.spotlight-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: 3rem 3.2rem;
  min-width: 0;
}

.spotlight-copy p {
  max-width: 22rem;
  margin: 0;
  color: color-mix(in srgb, var(--v2-band-ink) 72%, transparent);
  font-size: .88rem;
  line-height: 1.85;
}

.spotlight-copy .v2-line-btn { color: var(--v2-band-ink); margin-top: 1.8rem; }

.spotlight-footer {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  margin-top: 2.6rem;
  color: color-mix(in srgb, var(--v2-band-ink) 60%, transparent);
  font-size: .7rem;
}

.spotlight-footer span { display: inline-flex; align-items: center; gap: .4rem; }

/* --------------------------------------------------------------------------
   Artist feature — copy and a duotone portrait, reversed from the spotlight so
   the two bands do not read as the same module twice.
   -------------------------------------------------------------------------- */

.artist-feature {
  display: grid;
  grid-template-columns: .84fr 1.16fr;
  align-items: center;
  gap: 4rem;
  margin: 5rem 0;
}

.artist-copy p {
  max-width: 22rem;
  color: var(--text-muted);
  font-size: .88rem;
  line-height: 1.85;
}

.inline-link {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  margin-top: 1.5rem;
  color: var(--v2-hot);
  font-size: .78rem;
  font-weight: 700;
}

.artist-image {
  position: relative;
  min-height: 360px;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--v2-band);
}

/* Greyscale plus screen blend is what gives the reference its duotone: the
   photograph becomes a luminance mask over the band colour rather than a
   picture in a box. */
.artist-image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 44%;
  /* Same reasoning as the spotlight image: desaturate hard, push the residual
     hue into the brand range, then let screen blend turn it into a duotone
     over the band colour rather than a photograph in a box. */
  filter: saturate(.35) hue-rotate(200deg) contrast(1.12);
  mix-blend-mode: screen;
  opacity: .62;
}

.artist-image::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, color-mix(in srgb, var(--accent-2) 22%, transparent), rgba(18, 20, 32, .5));
}

.artist-quote {
  position: absolute;
  z-index: 2;
  top: 1.8rem;
  inset-inline-start: 2rem;
  max-width: 20rem;
  color: #fff;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2.2vw, 1.6rem);
  font-weight: 700;
  line-height: 1.6;
}

.artist-credit {
  position: absolute;
  z-index: 2;
  inset-inline-end: 1.9rem;
  bottom: 1.7rem;
  color: #fff;
  font-family: var(--font-display);
  font-size: 1.05rem;
  line-height: 1.5;
  text-align: end;
}

.artist-credit span {
  display: block;
  color: color-mix(in srgb, var(--accent-0) 90%, #fff);
  font-size: .64rem;
  letter-spacing: .1em;
}

/* --------------------------------------------------------------------------
   Notes band — the newsletter signup, split by a rule.
   -------------------------------------------------------------------------- */

.notes-band {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 4rem;
  padding: 3.6rem 0;
  border-top: 1px solid var(--v2-line);
}

.notes-copy p {
  max-width: 24rem;
  color: var(--text-muted);
  font-size: .88rem;
  line-height: 1.85;
}

.signup-wrap {
  padding-inline-start: 3.2rem;
  border-inline-start: 1px solid var(--v2-line);
}

.signup-form { max-width: 24rem; }

.signup-form label {
  display: block;
  margin-bottom: .7rem;
  color: var(--text-muted);
  font-size: .7rem;
}

/* The ruled input from the reference: no box, no fill, just a baseline that
   lights up on focus. */
.signup-row {
  display: flex;
  align-items: center;
  gap: .5rem;
  border-bottom: 1px solid var(--v2-line-strong);
  transition: border-color .18s ease;
}

.signup-row:focus-within { border-bottom-color: var(--v2-hot); }

.signup-row input {
  flex: 1;
  min-width: 0;
  padding: .7rem 0;
  color: var(--text);
  background: transparent;
  border: 0;
  outline: 0;
  box-shadow: none;
  font-size: .9rem;
}

.signup-row button {
  color: var(--v2-hot);
  background: none;
  border: 0;
  padding: .3rem;
  cursor: pointer;
}

.signup-form small { display: block; margin-top: .8rem; color: var(--text-faint); font-size: .68rem; }

/* --------------------------------------------------------------------------
   Submit band — the full-bleed coloured call to action that closes the page.

   Full-bleed inside a max-width parent without a wrapper element: the negative
   inline margin plus matching padding is the standard trick, and it is written
   in logical properties so it bleeds the same way under RTL.
   -------------------------------------------------------------------------- */

.submit-band {
  margin-inline: calc(50% - 50vw);
  padding-inline: calc(50vw - 50% + var(--v2-gutter));
  margin-block: 4rem 0;
  background: var(--v2-hot);
  color: var(--v2-hot-ink);
}

.submit-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 3rem;
  flex-wrap: wrap;
  max-width: var(--v2-wrap);
  margin-inline: auto;
  min-height: 260px;
  padding-block: 3rem;
}

.submit-band h2 { color: var(--v2-hot-ink); }
.submit-band .v2-eyebrow { color: rgba(17, 21, 34, .68); }
.submit-band .v2-eyebrow .v2-dot { background: var(--v2-hot-ink); box-shadow: 0 0 0 4px rgba(17, 21, 34, .14); }

.submit-side { max-width: 24rem; }

.submit-side p {
  margin: 0 0 1.4rem;
  color: rgba(17, 21, 34, .78);
  font-size: .88rem;
  line-height: 1.8;
}

/* On the hot band the primary button has to invert — a hot button on a hot
   ground is invisible. The reference uses its ink for exactly this. */
.submit-band .btn-accent {
  background: var(--v2-hot-ink);
  color: #eef2f7;
}

.submit-band .btn-accent:hover { background: #1c2533; }

/* --------------------------------------------------------------------------
   Forms

   Every input on the site becomes the ruled field from the reference: no fill,
   no inset emboss, a baseline that lights up on focus. The focus ring is kept
   as a real ring rather than only a colour change — a colour-only focus state
   fails WCAG 2.4.11 and is the first thing to disappear in high contrast mode.
   -------------------------------------------------------------------------- */

input, textarea, select {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--v2-line-strong);
  border-radius: 0;
  box-shadow: none;
  padding: .7rem .2rem;
  transition: border-color .18s ease;
}

input:hover, textarea:hover, select:hover { border-bottom-color: var(--v2-line-strong); }

input:focus, textarea:focus, select:focus {
  outline: 2px solid var(--v2-hot);
  outline-offset: 3px;
  box-shadow: none;
  border-bottom-color: var(--v2-hot);
}

/* Checkboxes, radios and range inputs must keep their native box — the rule
   above would flatten a checkbox into a line. */
input[type="checkbox"],
input[type="radio"] {
  border-bottom: 0;
  padding: 0;
  accent-color: var(--v2-hot);
}

input[type="range"] {
  border-bottom: 0;
  padding: 0;
  accent-color: var(--v2-hot);
}

input[type="file"] { border-bottom: 0; padding: .4rem 0; }

.form label { font-size: .8rem; letter-spacing: .01em; }

.role-card {
  background: transparent;
  border: 1px solid var(--v2-line);
  border-radius: var(--radius-sm);
  box-shadow: none;
  transition: border-color .18s ease, background .18s ease;
}

.role-card:hover { border-color: var(--v2-hot); }

.role-card:has(input:checked) {
  box-shadow: none;
  border-color: var(--v2-hot);
  background: var(--v2-hot-soft);
}

/* The auth card is one of the few surfaces that still floats: it is a single
   focused object on an otherwise empty page, which is exactly the case the
   drop shadow is reserved for. */
.auth-card {
  border-radius: var(--radius);
  border: 1px solid var(--v2-line);
  box-shadow: var(--shadow-out-lg);
  padding: 2.4rem 2.2rem;
  max-width: 30rem;
}

/* --------------------------------------------------------------------------
   Alerts — a hairline left rule in the alert's own colour rather than a tinted
   card. Written as an inline-start border so it mirrors under RTL.
   -------------------------------------------------------------------------- */

.alert {
  background: transparent;
  box-shadow: none;
  border: 1px solid var(--v2-line);
  border-inline-start: 3px solid var(--v2-line-strong);
  border-radius: var(--radius-sm);
  padding: .85rem 1.1rem;
}

.alert-error { border-inline-start-color: var(--error); }
.alert-success { border-inline-start-color: var(--success); }
.alert-pending { border-inline-start-color: var(--warm-2); }

/* --------------------------------------------------------------------------
   Panels, tiles and every other raised surface style.css defines. One rule
   flattens the lot; the tokens above already changed their shadows, this
   changes their edge.
   -------------------------------------------------------------------------- */

.panel-card,
.panel-head,
.tile,
.stat-card,
.comment,
.playlist-card,
.tier-card,
.player-card,
.quick-tile,
.mini-stat {
  border: 1px solid var(--v2-line);
  border-radius: var(--radius);
  box-shadow: none;
  background: var(--surface);
}

.panel-card:hover,
.playlist-card:hover,
.quick-tile:hover { border-color: var(--v2-line-strong); box-shadow: none; }

/* --------------------------------------------------------------------------
   Presence pill + activity feed
   -------------------------------------------------------------------------- */

.presence-pill {
  background: transparent;
  border: 1px solid var(--v2-line);
  box-shadow: none;
  font-size: .76rem;
  padding: .45rem 1rem;
}

.home-layout {
  grid-template-columns: 1fr 300px;
  gap: 3rem;
  /* Clear the signal strip above it. Without this the grid butts flush against
     the strip's bottom border — both columns start at its exact bottom edge —
     and the bold "آخرین فعالیت‌ها" heading in the sidebar reads as jammed onto
     the ruled line above it. Every other section on the page gets its air from
     .v2-section-head's top margin; the layout grid had none of its own. */
  margin-top: 2.75rem;
}

.home-sidebar {
  position: sticky;
  top: 6rem;
  padding-inline-start: 2.4rem;
  border-inline-start: 1px solid var(--v2-line);
}

.home-sidebar .section-title { font-size: 1.05rem; margin-bottom: 1rem; }

.activity-feed { display: flex; flex-direction: column; }

/* The feed becomes a ruled list rather than a stack of small cards. The
   background and radius have to be reset explicitly — style.css gives each
   item a surface, and a token change alone leaves fifteen little slabs down
   the sidebar. */
.activity-item {
  display: block;
  padding: .8rem 0;
  background: transparent;
  border-radius: 0;
  box-shadow: none;
  border-bottom: 1px solid var(--v2-line);
  color: var(--text-muted);
  font-size: .8rem;
  line-height: 1.7;
  transition: color .18s ease;
}

.activity-item:last-child { border-bottom: 0; }
.activity-item:hover { color: var(--text); }

/* --------------------------------------------------------------------------
   Player bar

   The reference's mini player: a floating slab with a hairline, detached from
   both edges. The existing bar is a full-width strip pinned to the bottom.
   Only the frame changes — every control inside it keeps the ids and classes
   public/js/player.js drives, because that file is untouched by this redesign.
   -------------------------------------------------------------------------- */

.player-bar {
  inset-inline: 1.4rem;
  bottom: 1.2rem;
  border: 1px solid var(--v2-line);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--surface-strong) 92%, transparent);
  backdrop-filter: blur(18px);
  box-shadow: var(--shadow-out-lg);
}

.pb-toggle {
  border-radius: 50%;
  background: var(--v2-hot);
  color: #fff;
  box-shadow: none;
}

.pb-toggle:hover { background: color-mix(in srgb, var(--v2-hot) 82%, #fff); }

.pb-skip,
.pb-close {
  background: transparent;
  box-shadow: none;
  border: 0;
  color: var(--text-muted);
  transition: color .18s ease;
}

.pb-skip:hover, .pb-close:hover { color: var(--text); }

.pb-cover { border-radius: var(--radius-sm); overflow: hidden; }
.pb-title { font-weight: 700; font-size: .85rem; }
.pb-artist { color: var(--text-muted); font-size: .72rem; }

@media (max-width: 680px) {
  .player-bar { inset-inline: .6rem; bottom: .6rem; }
}

/* --------------------------------------------------------------------------
   Footer

   The reference replaces the single centred line with a brand column and three
   link columns over a rule. The existing markup is one flat row of links, so
   the columns are built in the markup (footer.ejs) and this styles them; the
   flat row remains styled for any view that still renders it.
   -------------------------------------------------------------------------- */

.site-footer {
  text-align: start;
  border-top: 1px solid var(--v2-line);
  margin-top: 4rem;
  padding: 3.4rem var(--v2-gutter) 8rem;
}

.footer-inner {
  display: grid;
  grid-template-columns: 1fr 1.5fr;
  gap: 4rem;
  max-width: var(--v2-wrap);
  margin-inline: auto;
}

.footer-brand .brand { font-size: 1rem; }

.footer-brand p {
  margin-top: 1.1rem;
  max-width: 16rem;
  color: var(--text-faint);
  font-size: .76rem;
  line-height: 1.7;
}

.footer-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}

.footer-cols b {
  display: block;
  margin-bottom: 1rem;
  color: var(--v2-hot);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .08em;
}

.footer-cols .footer-link {
  display: block;
  margin-bottom: .65rem;
  padding: 0;
  color: var(--text-muted);
  font-size: .78rem;
  text-decoration: none;
  text-align: start;
}

.footer-cols .footer-link:hover { color: var(--text); }

.footer-bottom {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--v2-line);
  color: var(--text-faint);
  font-size: .68rem;
}

.footer-bottom .tiny-heart { color: var(--v2-hot); }

/* --------------------------------------------------------------------------
   Scroll reveal

   style.css already hides .on-scroll under .js and reveals it from an
   IntersectionObserver in footer.ejs. The reference's entrance is a shorter,
   flatter rise than the existing 18px, so only the distance and easing change
   here — the mechanism, and its reduced-motion escape hatch, are untouched.
   -------------------------------------------------------------------------- */

.js .on-scroll { transform: translateY(12px); }

/* --------------------------------------------------------------------------
   Responsive

   Two breakpoints, matching the reference: 900px collapses the two-column
   spreads to tighter proportions, 680px stacks everything.
   -------------------------------------------------------------------------- */

@media (max-width: 1024px) {
  :root { --v2-gutter: 24px; }

  .home-layout { grid-template-columns: 1fr; gap: 2.5rem; }

  .home-sidebar {
    position: static;
    padding-inline-start: 0;
    padding-top: 2rem;
    border-inline-start: 0;
    border-top: 1px solid var(--v2-line);
  }
}

@media (max-width: 900px) {
  .hero { grid-template-columns: .95fr 1.05fr; gap: .8rem; }
  .hero-art-wrap { min-height: 400px; }
  .artist-feature { gap: 2.5rem; }
  .notes-band { gap: 2.5rem; }
  .signup-wrap { padding-inline-start: 2rem; }
}

@media (max-width: 680px) {
  :root { --v2-gutter: 18px; }

  .nav-inner { padding-block: .85rem; gap: .8rem; }

  .hero {
    display: block;
    padding: 2.2rem 0 3rem;
  }

  .hero h1 { max-width: none; }

  .hero-art-wrap { min-height: 380px; margin-top: 2.2rem; }
  .hero-art-card { width: 66%; }
  .floating-note { bottom: 4%; max-width: 11rem; }
  .hero-index { bottom: 0; }
  .orbit-one { inset-inline-end: -22%; }
  .orbit-two { inset-inline-end: -10%; }

  /* The strip becomes three ruled rows rather than three columns; a
     three-column grid at this width gives each item about 90px, which is
     narrower than the words in it. */
  .signal-strip { display: block; padding: 0; }

  .signal-item,
  .signal-item:first-child,
  .signal-item:last-child {
    padding: 1.1rem 0;
    border-inline-end: 0;
    border-bottom: 1px solid var(--v2-line);
  }

  .signal-item:last-child { border-bottom: 0; }

  .v2-section-head { display: block; margin-top: 3rem; }
  .v2-section-head .v2-head-side { max-width: none; margin-top: 1.2rem; }

  .track-grid { grid-template-columns: repeat(2, 1fr); gap: 1.5rem .8rem; }
  .track-title { font-size: .88rem; }
  .track-meta { font-size: .66rem; }

  .spotlight { display: block; margin: 3rem 0; }
  .spotlight-image { min-height: 260px; }
  .spotlight-copy { padding: 2.4rem 1.5rem 2rem; }
  .spotlight-footer { margin-top: 2rem; }

  .artist-feature { display: flex; flex-direction: column-reverse; gap: 2rem; margin: 3rem 0; }
  .artist-image { width: 100%; min-height: 320px; }
  .artist-quote { font-size: 1.15rem; inset-inline-start: 1.4rem; top: 1.4rem; }

  .notes-band { display: block; padding: 2.6rem 0; }

  .signup-wrap {
    margin-top: 2rem;
    padding: 2rem 0 0;
    border-inline-start: 0;
    border-top: 1px solid var(--v2-line);
  }

  .submit-inner { display: block; min-height: 0; padding-block: 2.6rem; }
  .submit-side { margin-top: 1.6rem; max-width: none; }

  .site-footer { padding-bottom: 7rem; }
  .footer-inner { display: block; }
  .footer-cols { margin-top: 2.6rem; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
  .footer-bottom { margin-top: 2.4rem; }
}

/* Very narrow phones: three footer columns at 320px give each about 85px,
   which breaks "سوال‌های پرتکرار" across four lines. */
@media (max-width: 380px) {
  .footer-cols { grid-template-columns: repeat(2, 1fr); gap: 1.4rem 1rem; }
  .track-grid { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Reduced motion

   style.css already zeroes every animation and transition under
   [data-motion="reduced"], which covers the orbits, the bars and the reveal.
   What it cannot do is stop a rotated element from being rotated, and the
   orbits' resting transform is part of their keyframes — so they are pinned
   here, otherwise they snap to 0deg and sit as two flat ellipses.
   -------------------------------------------------------------------------- */

:root[data-motion="reduced"] .orbit-one { transform: rotate(28deg); }
:root[data-motion="reduced"] .orbit-two { transform: rotate(-18deg); }
:root[data-motion="reduced"] .hero-art-bars i { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .hero-orbit,
  .hero-art-bars i,
  .hero-art-image .hero-mark { animation: none; }
  .orbit-one { transform: rotate(28deg); }
  .orbit-two { transform: rotate(-18deg); }
}

/* --------------------------------------------------------------------------
   Print — the grain, the orbits and the fixed player are all ink the reader
   did not ask for.
   -------------------------------------------------------------------------- */

@media print {
  body::after, body::before,
  .hero-orbit, .player-bar, .floating-note { display: none !important; }
  .spotlight, .submit-band { background: none; color: #000; }
}

/* The corner numeral on a track card's art, from the reference. Sits over the
   image, so it needs its own contrast — a plain white numeral vanishes on pale
   cover art. The shadow is cheaper than a scrim and does not dim the artwork. */
.track-art-label {
  position: absolute;
  z-index: 1;
  top: .6rem;
  inset-inline-start: .6rem;
  color: rgba(255, 255, 255, .92);
  font-size: .62rem;
  letter-spacing: .13em;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .55);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Horizontal overflow guard

   The hero orbits are rotated ellipses positioned past the edge of their
   column — that is the effect — and a transformed element still contributes to
   the scroll area. On a 390px screen they pushed the document 116px wider,
   which under RTL scrolls the whole page sideways.

   `overflow-x: clip`, not `hidden`: clip does not create a scroll container, so
   `position: sticky` on the nav keeps working. `hidden` here silently kills the
   sticky header, which is the trap this note exists to record.
   -------------------------------------------------------------------------- */

html, body { overflow-x: clip; }

/* --------------------------------------------------------------------------
   The two promotional blocks at the foot of the shelf. Both were centred
   surface cards; in the new language they are ruled bands that sit on the page
   ground, which is also what stops them competing with the hot submit band a
   screen further down.
   -------------------------------------------------------------------------- */

.app-promo,
.discover-cta {
  background: transparent;
  border: 1px solid var(--v2-line);
  border-radius: var(--radius);
  box-shadow: none;
}

.app-promo {
  justify-content: space-between;
  text-align: start;
  padding: 1.4rem 1.6rem;
  margin-top: 3rem;
}

.app-promo-text { display: flex; flex-direction: column; gap: .25rem; }
.app-promo-text strong { font-size: .95rem; }
.app-promo-text span { color: var(--text-muted); font-size: .8rem; }

.discover-cta {
  margin-top: 1.2rem;
  padding: 2.2rem 1.8rem;
  text-align: center;
}

.discover-cta h3 {
  font-size: clamp(1.2rem, 2.6vw, 1.7rem);
  font-weight: 800;
  margin-bottom: .7rem;
}

.discover-cta p {
  max-width: 32rem;
  margin: 0 auto 1.4rem;
  color: var(--text-muted);
  font-size: .86rem;
  line-height: 1.8;
}

/* The search row keeps its ruled field; the button sits on the same baseline
   rather than floating above it. */
.discover-search { align-items: end; gap: .8rem; }

/* --------------------------------------------------------------------------
   Wordmark

   Syne at 800 with .16em tracking read as blocky next to the mark — technical
   rather than musical. Instrument Serif is already loaded for the editorial
   numerals, so this costs no extra request, and a serif masthead beside a
   geometric symbol is the oldest trick in magazine identity: the two do
   different jobs instead of competing. Tracking comes almost all the way back
   in, because a serif set wide loses its rhythm.
   -------------------------------------------------------------------------- */

.brand-name {
  font-family: var(--font-serif-latin);
  font-weight: 400;
  font-size: 1.5em;
  letter-spacing: .015em;
  line-height: 1;
  /* Optical alignment: the serif sits slightly high against the mark's centre
     because its cap height is shorter than the geometric glyph beside it. */
  transform: translateY(.04em);
}

.footer-brand .brand-name { font-size: 1.45em; }

/* --------------------------------------------------------------------------
   Auth pages

   The old card was a hard-edged white slab with a bare "ورود به Sonava" label
   on it. This is softer in every dimension that does not cost clarity: rounder
   corners, a warmer greeting, room above for the mascot to lean over the top,
   and generous spacing between the three things you actually do here.
   -------------------------------------------------------------------------- */

.auth-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 12rem);
  /* Space for the mascot, which is pulled up out of the card's top edge. */
  padding-top: 5.5rem;
}

.auth-card-friendly {
  position: relative;
  width: min(30rem, 100%);
  margin: 0;
  padding: 0 2.2rem 2.4rem;
  border-radius: 26px;
  background: var(--surface-strong);
  border: 1px solid var(--v2-line);
  box-shadow: var(--shadow-out-lg);
  overflow: visible;
}

.auth-head { text-align: center; margin-bottom: 1.6rem; }

.auth-head h1 {
  font-size: clamp(1.6rem, 4vw, 2.1rem);
  font-weight: 800;
  margin: 0 0 .5rem;
}

.auth-lede {
  margin: 0;
  color: var(--text-muted);
  font-size: .88rem;
  line-height: 1.8;
}

/* ---- fields ----
   Softer than the ruled inputs the rest of the site uses. This is the one
   screen where a visitor is asked to type something they might get wrong, and
   a field with an edge is easier to aim at than a line. */

.auth-card-friendly .field {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.auth-card-friendly .field-label {
  color: var(--text-muted);
  font-size: .78rem;
  font-weight: 600;
}

.auth-card-friendly input[type="email"],
.auth-card-friendly input[type="text"],
.auth-card-friendly input[type="password"] {
  width: 100%;
  padding: .85rem 1rem;
  border: 1px solid var(--v2-line-strong);
  border-radius: 14px;
  background: var(--surface);
  transition: border-color .18s ease, background .18s ease;
}

.auth-card-friendly input:focus {
  border-color: var(--v2-hot);
  background: var(--surface-strong);
}

.auth-card-friendly input::placeholder { color: var(--text-faint); }

/* The reveal button sits inside the field's inline-end padding. */
.field-with-action { position: relative; display: block; }
.field-with-action input { padding-inline-end: 3rem; }

.pw-toggle {
  position: absolute;
  inset-inline-end: .45rem;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition: background .18s ease;
}

.pw-toggle:hover { background: var(--v2-hot-soft); }

.caps-warning {
  margin: 0;
  min-height: 1.1rem;
  color: var(--warm-2);
  font-size: .74rem;
}

.caps-warning:empty { min-height: 0; }

/* ---- OAuth ---- */

.oauth-list { display: flex; flex-direction: column; gap: .6rem; }

.oauth-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  padding: .82rem 1rem;
  border: 1px solid var(--v2-line-strong);
  border-radius: 14px;
  box-shadow: none;
  background: var(--surface);
  font-size: .85rem;
  font-weight: 600;
  transition: border-color .18s ease, background .18s ease, transform .18s ease;
}

.oauth-btn:hover {
  border-color: var(--v2-hot);
  background: var(--v2-hot-soft);
  box-shadow: none;
  transform: translateY(-2px);
}

.oauth-divider {
  display: flex;
  align-items: center;
  gap: .8rem;
  margin: 1.3rem 0;
  color: var(--text-faint);
  font-size: .74rem;
}

.oauth-divider::before,
.oauth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--v2-line);
}

.auth-card-friendly .btn-block {
  margin-top: .4rem;
  padding-block: .95rem;
  border-radius: 14px;
  font-size: .95rem;
}

.auth-switch { text-align: center; font-size: .82rem; margin-top: .9rem; }
.auth-switch a { color: var(--v2-hot); font-weight: 600; }

@media (max-width: 680px) {
  .auth-page { padding-top: 4rem; min-height: 0; }
  .auth-card-friendly { padding-inline: 1.4rem; }
}

/* --------------------------------------------------------------------------
   Corrections found by walking the site after the token swap.

   Each of these is a place where flattening a surface at the token level was
   right for the general case and wrong for one specific element.
   -------------------------------------------------------------------------- */

/* .tile-primary is the one filled tile in the account grid — the primary
   action, white text on the brand gradient. The blanket .tile rule above sets
   a pale surface at the same specificity and, being later in the file, won it:
   white text on a near-white ground. It reads as a disabled tile, which is
   exactly what it looked like. */
.tile-primary {
  background: var(--v2-hot);
  color: #fff;
  border-color: transparent;
}

.tile-primary .tile-count,
.tile-primary .tile-label { color: #fff; }
.tile-primary:hover { background: color-mix(in srgb, var(--v2-hot) 84%, #fff); border-color: transparent; }

/* .section-title carries two jobs. In an editorial head it is a display line
   and wants the full clamp; as the heading of a sub-section inside a page —
   "نظرات (۰)" above a comment box — that size is absurd. The big treatment is
   therefore scoped to the places that are actually mastheads, and everything
   else gets a normal heading. */
.section-title { font-size: clamp(1.15rem, 1.8vw, 1.4rem); }

.v2-section-head .section-title,
.hero .section-title,
.spotlight-copy .section-title,
.artist-copy .section-title,
.notes-copy .section-title,
.submit-inner .section-title {
  font-size: clamp(1.7rem, 3.4vw, 2.7rem);
}

/* A ruled input and a filled button do not share a baseline on their own: the
   input's text sits on its own bottom rule, the button's box is centred on the
   row. align-items:end lines the two bottoms up, which is what the eye reads
   as "on the same line". */
.comment-form,
.discover-search { align-items: end; }
.comment-form input,
.comment-form textarea { flex: 1; min-width: 0; }

/* Textareas keep an outline — a multi-line field with only a bottom rule gives
   no clue how tall it is until you overflow it. */
textarea {
  border: 1px solid var(--v2-line-strong);
  border-radius: var(--radius-sm);
  padding: .75rem .9rem;
}

/* Tables read as data, not as cards: rules between rows, nothing around them.
   Used by the admin console, the API docs and the monetization ledger. */
table { border-collapse: collapse; width: 100%; }

th, td {
  padding: .7rem .6rem;
  border-bottom: 1px solid var(--v2-line);
  text-align: start;
}

th {
  color: var(--text-muted);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .04em;
}

/* Code and pre in the API reference. A filled block with a hairline, because
   a code sample genuinely is a different kind of surface from the prose. */
pre, code {
  background: var(--surface);
  border: 1px solid var(--v2-line);
  border-radius: var(--radius-sm);
}

pre { padding: 1rem 1.1rem; overflow-x: auto; }
code { padding: .1rem .35rem; }
pre code { border: 0; padding: 0; background: none; }

/* The subscription tiers. The recommended one keeps a coloured edge rather
   than a shadow — a raised card in a flat layout is the only thing on screen
   that looks like a mistake. */
.tier-card.tier-featured,
.tier-card[data-featured] { border-color: var(--v2-hot); box-shadow: none; }

.tier-badge {
  border: 1px solid var(--v2-line-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  box-shadow: none;
  padding: .3rem .8rem;
  font-size: .72rem;
}

/* Modals stay raised — they are the one element that genuinely is in front of
   the page — but lose the 20px+ radius so they belong to the same system. */
.modal, .modal-body {
  border-radius: var(--radius);
  border: 1px solid var(--v2-line);
}

/* Avatars stay round. The global radius change would otherwise turn every
   profile picture into a near-square, which reads as a broken image. */
.avatar-sm, .avatar-lg, .avatar-fallback { border-radius: 50%; }

/* --------------------------------------------------------------------------
   Icons

   Stroked SVG on currentColor, replacing the emoji this design started with.
   `display:block` and the flex alignment matter more than they look: an inline
   SVG sits on the text baseline and leaves a descender gap under it, which is
   what made every icon-and-label pair look a pixel low.
   -------------------------------------------------------------------------- */

.ico {
  display: block;
  flex: 0 0 auto;
}

/* Icons that are the whole content of a button need the button to centre them
   rather than treat them as a line of text. */
.nav-search button,
.nav-bell,
.theme-toggle,
.pw-toggle,
.pb-close,
.pb-volume > .ico {
  display: inline-grid;
  place-items: center;
}

/* Solid icons: a few read better filled than stroked at small sizes — a heart
   outline at 14px is mostly hole. */
.ico-fill { fill: currentColor; stroke: none; }

/* The verified tick, which was a ✔ character in a colour that the emoji font
   overrode on Android. */
.badge-check .ico { color: var(--accent-2); }

/* The "made with care" line pairs an icon with text, so it needs to be a flex
   row — the SVG is display:block and would otherwise drop onto its own line. */
.footer-made { display: inline-flex; align-items: center; gap: .35rem; }

/* Track-card meta: each figure is an icon plus a number. */
.track-meta span { display: inline-flex; align-items: center; gap: .3rem; }

/* The cover fallback is an icon now rather than a 2.2rem emoji, so it needs a
   colour of its own — currentColor here is the card's body text, which is far
   too strong for a placeholder. */
.cover-fallback { color: var(--accent-2); }

/* Editorial section tags and links that pair an icon with a label. */
.spotlight-tag,
.spotlight-footer span,
.inline-link,
.floating-note { align-items: center; }

.floating-note { align-items: flex-start; }
.floating-note .ico { color: var(--v2-hot); margin-top: .15rem; }
.spotlight-footer .ico { color: var(--v2-hot); }
.spotlight-tag .ico { color: var(--accent-0); }

/* The Turnstile widget on the redesigned sign-in card.

   Cloudflare renders it in an iframe at a fixed 300x65, so it cannot be
   restyled — only placed. Centred with room either side, because left-aligned
   in an otherwise centred card it reads as a stray element, and it is the one
   thing on this page whose width the layout does not control. */
.auth-card-friendly .turnstile-wrap {
  display: flex;
  justify-content: center;
  margin: .4rem 0 .2rem;
}

/* At 390px the 300px widget plus the card's 1.4rem gutters is 345px — it fits,
   but only just, so the card's padding is what has to give rather than the
   widget overflowing. */
@media (max-width: 360px) {
  .auth-card-friendly { padding-inline: 1rem; }
}

/* Activity rows carry a timestamp now. Two lines rather than one: the sidebar
   is 300px and the sentence already wraps, so pushing the time onto the end of
   it would produce a ragged third line more often than not. */
.activity-item { display: flex; flex-direction: column; gap: .25rem; }
.activity-text { display: block; }

.activity-when {
  display: block;
  color: var(--text-faint);
  font-size: .68rem;
}

/* "Did you mean" — shown only when a search found nothing and the tolerant
   matcher had near-misses. Deliberately quiet: these are guesses, so they read
   as offers rather than as results. */
.search-didyoumean { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 8px; max-width: 520px; }
.search-didyoumean a {
  display: flex; align-items: baseline; gap: 10px; justify-content: space-between;
  padding: 11px 14px; border-radius: 14px; text-decoration: none;
  background: var(--surface-strong); box-shadow: var(--shadow-out);
  transition: transform .16s ease, box-shadow .16s ease;
}
.search-didyoumean a:hover { transform: translateY(-1px); box-shadow: var(--shadow-out-lg, var(--shadow-out)); }
.search-didyoumean .dym-title { font-weight: 700; color: var(--text); }
.search-didyoumean .dym-artist { font-size: .85rem; color: var(--text-dim); }

/* Creator-mode switch in settings. */
.role-form { margin-top: 4px; }
.role-warn { color: var(--danger, #dc2626); }
