/* ============================================================
   LOOPIN — /mastering  (in-browser mastering tool)
   ============================================================ */
.masterpage { background: var(--bg); }

/* nav: "Loopin mastering" lockup + link out to the app */
.brand--tool { gap: 9px; }
.brand__tool {
  font-size: 1.06rem; font-weight: 400; letter-spacing: -0.01em;
  color: var(--ink-faint); padding-left: 10px; position: relative;
}
.brand__tool::before {
  content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 1px; height: 1em; background: var(--line-2);
}
.nav__right { display: flex; align-items: center; gap: 22px; }
.nav__link { font-size: .95rem; color: var(--ink-soft); display: inline-flex; align-items: center; gap: 5px; transition: color .2s var(--ease); }
.nav__link:hover { color: var(--ink); }
.nav__link--current { color: var(--ink); }
.nav__link--ext svg { width: 14px; height: 14px; opacity: .8; }
.nav__link--ext:hover svg { opacity: 1; }

.mp { padding-bottom: 40px; }

/* ── hero ── */
.mp-hero { padding: 60px 0 34px; text-align: center; }
.mp-eyebrow { display: inline-block; font-size: .78rem; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 20px; }
.mp-live { display: inline-flex; align-items: center; gap: 8px; margin-bottom: 20px; padding: 4px 11px; border: 1px solid var(--line); border-radius: 999px; background: var(--bg-2); color: var(--ink-soft); font-size: .78rem; font-weight: 500; }
.mp-live[hidden] { display: none; }
.mp-live__dot { width: 8px; height: 8px; border-radius: 50%; background: #22c55e; box-shadow: 0 0 0 0 rgba(34,197,94,.6); animation: mp-live-pulse 1.8s infinite; }
.mp-live b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
@keyframes mp-live-pulse { 0% { box-shadow: 0 0 0 0 rgba(34,197,94,.55); } 70% { box-shadow: 0 0 0 8px rgba(34,197,94,0); } 100% { box-shadow: 0 0 0 0 rgba(34,197,94,0); } }
@media (prefers-reduced-motion: reduce) { .mp-live__dot { animation: none; } }
.mp-hero__title { font-size: clamp(2.2rem, 5.5vw, 3.8rem); font-weight: var(--h1-weight); letter-spacing: var(--h1-tracking); line-height: 1.03; }
.mp-hero__sub { color: var(--ink-soft); font-size: 1.1rem; max-width: 560px; margin: 22px auto 0; line-height: 1.5; }

/* ── the tool shell ── */
.masterer {
  position: relative; margin-top: 16px;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--bg-2); overflow: hidden;
}
.masterer__status { text-align: center; color: var(--ink-faint); font-size: .9rem; padding: 0 20px 4px; min-height: 1.2em; }
.masterer.is-busy .masterer__status { color: var(--ink-soft); }

/* ── the daily cap, counting down ──
   Above the upload box in every state, because it is true in every state:
   nothing about mastering or previewing is held, only the download.

   [hidden] FIRST, before the display rule below. A class that sets `display`
   outranks the UA sheet's [hidden] rule, and the result is a banner that
   cannot be hidden — the same trap .btn and .player__fmt already carry a
   note about. */
.cooldown[hidden] { display: none; }
.cooldown {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px 18px;
  margin: 14px 14px 0; padding: 14px 18px;
  border: 1px solid var(--line-2); border-radius: var(--radius-lg);
  background: var(--surface);
}
.cooldown__main { flex: 1 1 240px; min-width: 0; }
.cooldown__title { font-size: 1rem; font-weight: 500; letter-spacing: -0.01em; }
.cooldown__sub { color: var(--ink-soft); font-size: .86rem; margin-top: 3px; }
.cooldown__clock {
  flex: none;
  /* Tabular figures so the seconds tick without the whole clock reflowing. */
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
  font-size: 1.5rem; font-weight: 500; letter-spacing: .01em; color: var(--ink);
}
.cooldown__cta { flex: none; }
.cooldown__cta[hidden] { display: none; }
@media (max-width: 560px) {
  .cooldown { margin: 12px 12px 0; padding: 13px 15px; }
  .cooldown__clock { font-size: 1.3rem; }
  .cooldown__cta { width: 100%; justify-content: center; }
}

/* ── the trial-offer banner — #cooldown's own version for the first 12
   hours of a cap, once mastering/limit-offer.js's popup has been dismissed
   once. Same slot, same shell rhythm as #cooldown above; --blue is scoped
   here exactly as .loffer and mastering/pricing.css already scope it to
   their own CTAs. */
.loffer-banner[hidden] { display: none; }
.loffer-banner {
  --blue: #3D7BFF; --blue-2: #5C8FFF;
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px 18px;
  margin: 14px 14px 0; padding: 14px 18px;
  border: 1px solid var(--line-2); border-radius: var(--radius-lg);
  background: var(--surface);
}
.loffer-banner__main { flex: 1 1 260px; min-width: 0; }
.loffer-banner__title { font-size: 1rem; font-weight: 500; letter-spacing: -0.01em; margin: 0; }
.loffer-banner__sub { color: var(--ink-soft); font-size: .86rem; margin: 3px 0 0; }
.loffer-banner__timer { flex: none; display: flex; align-items: center; gap: 6px; }
.loffer-banner__seg {
  background: var(--bg-2); border: 1px solid var(--line-2); border-radius: 8px;
  padding: 6px 10px; min-width: 40px; text-align: center;
}
.loffer-banner__n { font-size: 1.05rem; font-weight: 600; font-variant-numeric: tabular-nums; display: block; line-height: 1.1; }
.loffer-banner__l { font-size: 7px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-faint); }
.loffer-banner__colon { color: var(--ink-faint); font-weight: 600; }
.loffer-banner__cta {
  flex: none; font: inherit; font-size: .9rem; font-weight: 600; color: #fff;
  background: #3D7BFF; border: none; border-radius: 999px; padding: 10px 18px; cursor: pointer;
}
.loffer-banner__cta:hover { background: #5C8FFF; }
@media (max-width: 560px) {
  .loffer-banner { margin: 12px 12px 0; padding: 13px 15px; }
  .loffer-banner__cta { width: 100%; }
}

/* ── the shimmer ──
   A slow highlight travelling across a normal button. Deliberately soft: it
   is a nudge sitting in the header of a tool people are working in, not an
   advertisement, so it moves once every few seconds and never changes size,
   colour or position (nothing here can shift the layout around it).

   ::after rather than a background-position animation on the button itself,
   so the button keeps whatever background a theme gives it. */
.btn--shine { position: relative; overflow: hidden; isolation: isolate; }
.btn--shine::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(100deg,
    transparent 30%, rgba(255,255,255,.14) 46%, rgba(255,255,255,.22) 50%,
    rgba(255,255,255,.14) 54%, transparent 70%);
  transform: translateX(-100%);
  animation: btnShine 4.5s var(--ease) infinite;
}
@keyframes btnShine {
  0%   { transform: translateX(-100%); }
  /* One pass, then a long rest — the pause is what keeps it from reading as
     a loading state. */
  55%  { transform: translateX(100%); }
  100% { transform: translateX(100%); }
}
/* The nudge is the border and the words; the movement is decoration and the
   first thing to go for anyone who has asked for less of it. */
@media (prefers-reduced-motion: reduce) {
  .btn--shine::after { animation: none; opacity: 0; }
}

/* ── the membership badge ──
   What the Unlock button becomes once they have paid. Same slot, opposite
   job: that one was asking for something, this one confirms something they
   already own — so no shimmer, and a quieter treatment than a CTA.

   Hover or click reveals the details. Same show/hide mechanism as .acct__menu
   (opacity + visibility, not display) so it can transition, and the same
   :focus-within so a keyboard reaches it without a click. */
/* Premium surfaces: black with a dark-blue mesh. One definition, used by
   the "Unlimited Unlocked" pill, the "Get Unlimited Day Pass" button and the
   plan picker's accents, so they cannot drift apart. */
:root {
  --mesh-lavender:
    radial-gradient(120% 150% at 0% 0%, rgba(50, 110, 240, .6), transparent 55%),
    radial-gradient(100% 130% at 100% 100%, rgba(25, 60, 170, .7), transparent 60%),
    radial-gradient(80% 100% at 60% 0%, rgba(120, 170, 255, .28), transparent 60%),
    #070b16;
  --lavender-line: rgba(110, 160, 255, .38);
  --lavender-ink: #eaf2ff;
}
.plan .plan__btn { background: var(--mesh-lavender); border-color: var(--lavender-line); color: var(--lavender-ink); }
.plan .plan__btn:hover, .plan.is-open .plan__btn { background: var(--mesh-lavender); border-color: rgba(120, 170, 255, .7); filter: brightness(1.12); }
/* Every paying CTA on the tool page shares one colour: blue. */
.acct__unlock, .cooldown__cta { background: #3D7BFF; border: 1px solid #3D7BFF; color: #fff; }
.acct__unlock:hover, .cooldown__cta:hover { background: #5C8FFF; border-color: #5C8FFF; }

.plan { position: relative; display: flex; align-items: center; margin-left: 14px; }
.plan[hidden] { display: none; }
.plan__btn {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  font: inherit; font-size: .88rem; font-weight: 500; white-space: nowrap;
  padding: 7px 14px; border-radius: 999px; cursor: pointer;
  color: var(--ink); background: var(--surface); border: 1px solid var(--line-2);
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.plan__btn:hover, .plan.is-open .plan__btn { border-color: var(--ink-soft); background: var(--surface-2); }
.plan__crown { width: 15px; height: 15px; flex: none; color: var(--ink-soft); }

.plan__card {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 120;
  width: 274px; padding: 14px 16px 12px;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-2); box-shadow: 0 24px 48px -24px rgba(0,0,0,.6);
  opacity: 0; visibility: hidden; pointer-events: none; transform: translateY(-6px);
  transition: opacity .2s var(--ease), transform .2s var(--ease), visibility .2s;
  text-align: left;
}
/* The gap between button and card would otherwise end the hover halfway. */
.plan__card::before { content: ""; position: absolute; left: 0; right: 0; top: -10px; height: 10px; }
@media (hover: hover) {
  .plan:hover .plan__card, .plan:focus-within .plan__card { opacity: 1; visibility: visible; pointer-events: auto; transform: none; }
}
.plan.is-open .plan__card { opacity: 1; visibility: visible; pointer-events: auto; transform: none; }

.plan__head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 12px; }
.plan__name { font-size: .92rem; font-weight: 500; letter-spacing: -0.01em; }
.plan__state {
  margin-left: auto; flex: none; font-size: .7rem; letter-spacing: .06em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; background: rgba(120,200,140,.14); color: #7FCB93;
}
/* Anything that is not a healthy subscription — past_due, canceled, paused —
   has to look different from "active" or the badge reassures when it should
   be warning. */
.plan__state[data-state="warn"] { background: rgba(242,184,75,.16); color: #F2B84B; }
.plan__rows { display: grid; gap: 7px; font-size: .84rem; }
.plan__rows > div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.plan__rows dt { color: var(--ink-faint); }
.plan__rows dd { color: var(--ink); font-variant-numeric: tabular-nums; }
.plan__manage {
  display: block; margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--line);
  font-size: .84rem; color: var(--ink-soft); transition: color .2s var(--ease);
}
.plan__manage:hover { color: var(--ink); }

@media (max-width: 640px) {
  /* In the mobile panel the nav stacks, so the card sits inline underneath
     rather than floating off the right edge of a full-width row. */
  .plan { width: 100%; margin: 10px 0 4px; flex-direction: column; align-items: stretch; }
  .plan__btn { width: 100%; justify-content: center; }
  .plan__card {
    position: static; width: auto; margin-top: 8px; box-shadow: none;
    transform: none; transition: none;
    opacity: 1; visibility: visible; pointer-events: auto;
    display: none;
  }
  .plan.is-open .plan__card { display: block; }
}

/* "Unlock Unlimited" in the nav, immediately after the account name. */
.acct__unlock { flex: none; margin-left: 14px; white-space: nowrap; }
.acct__unlock[hidden] { display: none; }
@media (max-width: 640px) {
  /* In the mobile panel the nav stacks, so it becomes a full-width row like
     every other item rather than a chip floating beside the name. */
  .acct__unlock { width: 100%; margin: 10px 0 4px; justify-content: center; }
}

/* The download-quota ring — same slot as .acct__unlock above, same
   left margin, and never shown at the same time as it. */
.acct__quota {
  flex: none; margin-left: 14px; display: flex; align-items: center; gap: 11px;
  padding: 7px 16px 7px 7px; border-radius: 999px; white-space: nowrap;
  border: 1px solid var(--line-2); background: var(--surface);
  text-decoration: none; transition: border-color .2s, background .2s;
}
.acct__quota:hover { border-color: var(--ink-soft); background: var(--surface-2); }
.acct__quota[hidden] { display: none; }
.acct__quotaRing { position: relative; width: 34px; height: 34px; flex: none; }
.acct__quotaRing svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.acct__quotaTrack { fill: none; stroke: var(--line-2); stroke-width: 2.5; }
.acct__quotaFill {
  fill: none; stroke: var(--ink); stroke-width: 2.5; stroke-linecap: round;
  transition: stroke-dashoffset .4s var(--ease);
}
.acct__quotaNum {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--ink);
}
.acct__quotaLabel { font-size: 11.5px; line-height: 1.28; color: var(--ink-soft); }
@media (max-width: 640px) {
  .acct__quota { width: 100%; margin: 10px 0 4px; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) { .acct__quotaFill { transition: none; } }

/* ── dropzone ── */
.drop { cursor: pointer; }
.drop__inner {
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  min-height: 320px; padding: 50px 24px;
  border: 2px dashed var(--line-2); border-radius: var(--radius-lg); margin: 14px;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.drop.is-drag .drop__inner, .drop:hover .drop__inner { border-color: var(--ink-soft); background: rgba(255,255,255,.02); }
.drop__icon { display: grid; place-items: center; width: 56px; height: 56px; border-radius: 16px; background: var(--surface); border: 1px solid var(--line); color: var(--ink); margin-bottom: 22px; }
.drop__icon svg { width: 26px; height: 26px; }
.drop__title { font-size: 1.45rem; font-weight: 500; letter-spacing: -0.02em; }
.drop__sub { color: var(--ink-soft); margin-top: 10px; font-size: 1rem; }
.drop__browse { font: inherit; color: var(--ink); background: none; border: none; padding: 0 6px; margin: -10px 0; min-height: 44px; display: inline-flex; align-items: center; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.drop__note { color: var(--ink-faint); font-size: .82rem; margin-top: 22px; }

/* social proof — star rating + user count, just under the upload box */
.mp-rating {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 5px 10px; margin: 16px 0 2px;
}
#masterer[data-state="ready"] .mp-rating { display: none; }   /* empty state only */
.mp-rating__score { display: inline-flex; align-items: center; gap: 8px; }
.mp-rating__stars { display: inline-flex; gap: 3px; color: #F5C451; line-height: 0; }
.mp-rating__stars svg { width: 16px; height: 16px; display: block; }
.mp-rating__num { font-size: .95rem; font-weight: 600; color: var(--ink); line-height: 1; }
.mp-rating__text { font-size: .88rem; color: var(--ink-soft); }
/* wide screens: one line, "★★★★★ 4.9 · Trusted by …" */
.mp-rating__text::before { content: "· "; }
/* phones: stars and 4.9 on one line, the "Trusted by…" line under it */
@media (max-width: 640px) {
  .mp-rating { flex-direction: column; gap: 6px; }
  .mp-rating__text::before { content: none; }
  .mp-rating__text { text-align: center; }
}

/* ── workspace ── */
.ws { padding: 26px 26px 30px; }
.ws__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.ws__file { display: flex; flex-direction: column; min-width: 0; }
.ws__name { font-size: 1.12rem; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60vw; }
.ws__meta { font-size: .85rem; color: var(--ink-faint); margin-top: 2px; }
.ws__change { font-size: .9rem; color: var(--ink-soft); background: none; border: 1px solid var(--line-2); border-radius: 999px; padding: 7px 16px; cursor: pointer; transition: color .2s, border-color .2s; }
.ws__change:hover { color: var(--ink); border-color: var(--ink-soft); }

.ws__wave { width: 100%; height: 96px; display: block; margin: 22px 0; border-radius: 12px; background: var(--surface); }

/* ── player bar ── */
.player { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.player__play { width: 54px; height: 54px; border-radius: 50%; flex: none; display: grid; place-items: center; cursor: pointer; background: var(--ink); color: #0A0A0B; border: none; transition: transform .2s var(--ease), background .2s; }
.player__play:hover { transform: scale(1.05); background: #fff; }
.player__play svg { width: 22px; height: 22px; }
.player__play .ic-play { margin-left: 2px; }
.player__play .ic-pause { display: none; }
.masterer.is-playing .player__play .ic-play { display: none; }
.masterer.is-playing .player__play .ic-pause { display: block; }

.ab { display: inline-flex; padding: 4px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line); }
.ab__btn { font: inherit; font-size: .92rem; font-weight: 500; color: var(--ink-soft); background: none; border: none; border-radius: 999px; padding: 8px 18px; cursor: pointer; transition: color .2s, background .2s; }
.ab__btn.is-on { background: var(--ink); color: #0A0A0B; }

.player__dl { margin-left: auto; cursor: pointer; }
.player__dl small { display: block; font-size: .62rem; font-weight: 400; opacity: .7; }
.player__dl strong { font-size: 1.02rem; font-weight: 600; }
.player__dl.is-disabled { opacity: .5; pointer-events: none; }

/* ── presets ── */
.ws__h2 { font-size: 1.05rem; font-weight: 500; color: var(--ink-soft); letter-spacing: -0.01em; margin: 34px 0 16px; }
.presets { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.preset {
  position: relative;
  text-align: left; cursor: pointer; font: inherit; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px 18px 20px; display: flex; flex-direction: column; gap: 6px;
  transition: border-color .2s var(--ease), background .2s var(--ease), transform .2s var(--ease);
}
.preset:hover { border-color: var(--line-2); transform: translateY(-2px); }
.preset.is-on { border-color: var(--ink); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--ink); }
.preset__icon { color: var(--ink-soft); margin-bottom: 2px; transition: color .2s var(--ease); }
.preset__icon svg { width: 22px; height: 22px; display: block; }
.preset:hover .preset__icon, .preset.is-on .preset__icon { color: var(--ink); }
.preset__tags { font-size: .72rem; letter-spacing: .03em; color: var(--ink-faint); }
.preset__name { font-size: 1.25rem; font-weight: 500; letter-spacing: -0.02em; margin-top: 2px; }
.preset__desc { font-size: .9rem; color: var(--ink-soft); line-height: 1.4; }

/* ── spinners & loading states ── */
.spinner { display: inline-block; width: 18px; height: 18px; border: 2px solid var(--line-2); border-top-color: var(--ink); border-radius: 50%; animation: spin .8s linear infinite; }
.spinner--lg { width: 46px; height: 46px; border-width: 3px; }
@keyframes spin { to { transform: rotate(360deg); } }

/* first-upload loader panel */
.ws-load { min-height: 320px; margin: 14px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 4px; }
.ws-load[hidden] { display: none; }
.ws-load__title { font-size: 1.2rem; font-weight: 500; letter-spacing: -0.02em; margin-top: 26px; }
.ws-load__sub { color: var(--ink-soft); font-size: .95rem; }

/* per-feel loading: spinner on the picked card, the chain dims, meters pulse */
.preset.is-loading::after {
  content: ''; position: absolute; top: 14px; right: 14px; width: 16px; height: 16px;
  border: 2px solid var(--line-2); border-top-color: var(--ink); border-radius: 50%;
  animation: spin .8s linear infinite;
}
.preset.is-loading { border-color: var(--ink-soft); }
.masterer.is-loading .presets { opacity: .7; }
.masterer.is-loading .meter__to { animation: meterPulse 1s ease-in-out infinite; }
@keyframes meterPulse { 0%, 100% { opacity: .3; } 50% { opacity: .7; } }
@media (prefers-reduced-motion: reduce) {
  .spinner, .preset.is-loading::after { animation-duration: 1.6s; }
  .masterer.is-loading .meter__to { animation: none; opacity: .5; }
}

/* ── mono-check toggle ── */
.player__mono { font: inherit; font-size: .9rem; color: var(--ink-soft); background: none; border: 1px solid var(--line-2); border-radius: 999px; padding: 8px 16px; cursor: pointer; transition: color .2s, border-color .2s, background .2s; }
.player__mono:hover { color: var(--ink); border-color: var(--ink-soft); }
.player__mono.is-on { background: var(--ink); color: #0A0A0B; border-color: var(--ink); }

/* ── loudness-matched A/B toggle (engine v2, Phase 6) ── */
.player__abmatch { font: inherit; font-size: .9rem; color: var(--ink-soft); background: none; border: 1px solid var(--line-2); border-radius: 999px; padding: 8px 16px; cursor: pointer; transition: color .2s, border-color .2s, background .2s; }
.player__abmatch:hover { color: var(--ink); border-color: var(--ink-soft); }
.player__abmatch[aria-pressed="true"] { background: var(--ink); color: #0A0A0B; border-color: var(--ink); }

/* ── the unified result panel ──
   One card — a single border, a single background — holding the insight
   text, the live spectrum and the before/after meters together, since all
   three are evidence for the same result and used to read as three
   separately-boxed, disconnected pieces. Its children lose their own
   borders/backgrounds below and pick up a hairline divider between
   sections instead, so the seam reads as internal structure, not a gap
   between unrelated cards. */
.insightpanel {
  margin: 16px 0 14px; padding: 15px 15px 18px;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface);
}
.insight[hidden] { display: none; }
.insight {
  display: flex; align-items: center; gap: 12px;
}
.insight__mark {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--bg-2); border: 1px solid var(--line-2);
}
.insight__mark img { width: 18px; height: 18px; display: block; }
.insight__body { min-width: 0; }
.insight__text { font-size: .92rem; line-height: 1.45; color: var(--ink); }
/* The typewriter's cursor — only while text is actively being typed
   (mastering/engine-v2.js toggles this class), never a permanent fixture. */
.insight__text.is-typing::after {
  content: ""; display: inline-block; width: 2px; height: .95em;
  margin-left: 2px; background: var(--ink-soft); vertical-align: -0.15em;
  animation: insightCaret .85s step-end infinite;
}
@keyframes insightCaret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .insight__text.is-typing::after { animation: none; opacity: 0; }
}
@media (max-width: 560px) {
  .insightpanel { padding: 12px 13px 15px; }
  .insight { gap: 10px; }
  .insight__text { font-size: .88rem; }
}

/* ── real-time spectrum ──
   Inside .insightpanel: no border/background of its own, just a hairline
   divider above it separating it from the insight text. */
.ws__spectrum { width: 100%; height: 72px; display: block; margin: 16px 0 0; padding-top: 16px;
  border-top: 1px solid var(--line); color: var(--ink-soft); box-sizing: content-box; }
.masterer.is-playing .ws__spectrum { color: var(--ink); }

/* ── fine-tune macros ── */
.macros { margin: 22px 0 4px; }
.macros__head { display: flex; align-items: baseline; justify-content: space-between; }
.ws__h2--tight { margin: 18px 0 12px; }
.macros__reset { font: inherit; font-size: .82rem; color: var(--ink-faint); background: none; border: 1px solid var(--line-2);
  border-radius: 999px; padding: 5px 13px; cursor: pointer; transition: color .2s, border-color .2s; }
.macros__reset:hover { color: var(--ink); border-color: var(--ink-soft); }
.macros__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.macro { display: flex; flex-direction: column; gap: 8px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); padding: 13px 15px 15px; }
.macro__top { display: flex; align-items: baseline; justify-content: space-between; }
.macro__name { font-size: .74rem; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint); }
.macro__val { font-size: .92rem; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.macro.is-off { opacity: .42; }
.macro__range { -webkit-appearance: none; appearance: none; width: 100%; height: 3px; border-radius: 3px;
  background: var(--line-2); outline: none; cursor: pointer; }
.macro__range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 15px; height: 15px;
  border-radius: 50%; background: var(--ink); border: none; cursor: pointer; transition: transform .15s var(--ease); }
.macro__range::-webkit-slider-thumb:hover { transform: scale(1.18); }
.macro__range::-moz-range-thumb { width: 15px; height: 15px; border-radius: 50%; background: var(--ink); border: none; cursor: pointer; }
.macro__range:disabled { cursor: default; }
.macro__range:disabled::-webkit-slider-thumb { background: var(--ink-faint); cursor: default; }

/* ── waveform before/after diff legend ── */
.wavelegend { display: flex; flex-wrap: wrap; gap: 16px; margin: -12px 0 2px; padding: 0 2px; }
.wavelegend__item { display: inline-flex; align-items: center; gap: 7px; font-size: .76rem; color: var(--ink-faint); }
.wavelegend__sw { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.wavelegend__sw--base { background: rgba(244,243,241,0.42); }
.wavelegend__sw--add { background: var(--live); }
.wavelegend__sw--cut { background: #e8705c; }

/* ── before / after meters (carousel, mobile + desktop) ──
   Inside .insightpanel: a hairline divider above (same pattern as the
   spectrum), and each stat is a lighter inset tile (--bg-2 against the
   panel's own --surface) rather than a standalone card at the panel's own
   weight — the same nesting .insight__mark already uses inside .insight. */
.mcar { position: relative; margin: 16px 0 0; padding: 16px 40px 0; border-top: 1px solid var(--line); }
.meters { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; scroll-padding: 0; padding: 2px; }
.meters::-webkit-scrollbar { display: none; }
.meter { flex: 0 0 calc((100% - 20px) / 3); scroll-snap-align: start; box-sizing: border-box;
  border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--bg-2); padding: 14px 16px; display: flex; flex-direction: column; gap: 5px; }
/* nav arrows */
.mcar__nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center; border-radius: 50%; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--line-2); color: var(--ink-soft);
  transition: color .2s, border-color .2s, opacity .2s; }
.mcar__nav svg { width: 17px; height: 17px; }
.mcar__nav:hover { color: var(--ink); border-color: var(--ink-soft); }
.mcar__nav--prev { left: 0; }
.mcar__nav--next { right: 0; }
.mcar__nav[disabled] { opacity: 0; pointer-events: none; }
/* dots */
.mcar__dots { display: flex; justify-content: center; gap: 7px; margin: 12px 0 2px; }
.mcar__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line-2); border: none; padding: 0; cursor: pointer; transition: background .2s, transform .2s; }
.mcar__dot.is-on { background: var(--ink); transform: scale(1.25); }
@media (max-width: 980px) { .meter { flex-basis: calc((100% - 10px) / 2); } }
@media (max-width: 620px) { .meter { flex-basis: 78%; } .mcar { padding: 16px 0 0; } .mcar__nav { display: none; } }
.meter__label { font-size: .74rem; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint); }
.meter__vals { display: flex; align-items: baseline; gap: 8px; font-variant-numeric: tabular-nums; }
.meter__from { font-size: 1.05rem; color: var(--ink-soft); }
.meter__arr { font-size: .9rem; color: var(--ink-faint); }
.meter__to { font-size: 1.35rem; font-weight: 500; letter-spacing: -0.02em; color: var(--ink); }
.meter__unit { font-size: .72rem; color: var(--ink-faint); }

/* ── styles preview (marketing showcase) ── */
.feels-sec { padding: 70px 0 10px; }
.feels-sec__title { font-size: clamp(1.7rem, 3.8vw, 2.5rem); font-weight: 500; letter-spacing: -0.035em; text-align: center; }
.feels-sec__sub { color: var(--ink-soft); text-align: center; max-width: 600px; margin: 14px auto 36px; line-height: 1.5; }
.feels { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.feel {
  position: relative; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(165deg, var(--surface-2), var(--surface));
  padding: 22px 20px 20px; display: flex; flex-direction: column; gap: 4px;
  transition: transform .25s var(--ease), border-color .25s var(--ease);
}
.feel:hover { transform: translateY(-3px); border-color: var(--line-2); }
.feel__icon { color: var(--ink-soft); margin-bottom: 12px; transition: color .25s var(--ease), transform .25s var(--ease); }
.feel__icon svg { width: 26px; height: 26px; display: block; }
.feel:hover .feel__icon { color: var(--ink); transform: translateY(-2px) scale(1.06); }
.feel__name { font-size: 1.18rem; font-weight: 500; letter-spacing: -0.02em; }
.feel__desc { font-size: .86rem; color: var(--ink-soft); }

/* ── what is mastering ── */
.mp-about { padding: 90px 0 30px; }
.mp-about__inner { max-width: 720px; margin: 0 auto; }
.mp-about__title { font-size: clamp(1.7rem, 3.6vw, 2.4rem); font-weight: 500; letter-spacing: -0.03em; margin-bottom: 22px; }
.mp-about h3 { font-size: 1.18rem; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); margin-top: 34px; margin-bottom: 10px; }
.mp-about p { color: var(--ink-soft); line-height: 1.7; margin-bottom: 18px; font-size: 1.05rem; }
.mp-about strong { color: var(--ink); font-weight: 500; }
.mp-about a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line-2); transition: text-decoration-color .2s; }
.mp-about a:hover { text-decoration-color: var(--ink); }
/* secondary topic headings inside the explainer — a step down from the lead
   title, separated by a hairline so each topic reads as its own section */
.mp-about__h2 {
  font-size: clamp(1.34rem, 2.7vw, 1.72rem); font-weight: 500; letter-spacing: -0.022em;
  margin: 0 0 16px; padding-top: 34px; border-top: 1px solid var(--line);
}
.mp-about h3 + .mp-about__h2 { margin-top: 46px; }
.mp-about p + .mp-about__h2 { margin-top: 46px; }

/* comparison table — scrolls on its own so the page never moves sideways */
.mp-tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; margin: 0 0 18px; }
.mp-table { border-collapse: collapse; width: 100%; min-width: 520px; font-size: .95rem; }
.mp-table th, .mp-table td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--line); }
.mp-table thead th { font-weight: 500; color: var(--ink); background: var(--surface); white-space: nowrap; }
.mp-table tbody th { font-weight: 400; color: var(--ink-soft); white-space: nowrap; }
.mp-table td { color: var(--ink-soft); }
.mp-table tbody td:first-of-type { color: var(--ink); }
.mp-table tr:last-child th, .mp-table tr:last-child td { border-bottom: 0; }

/* ── download success modal ── */
.mq { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 24px; }
.mq[hidden] { display: none; }
.mq__scrim { position: absolute; inset: 0; background: rgba(5,5,6,.78); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); opacity: 0; transition: opacity .3s var(--ease); }
.mq__card {
  position: relative; z-index: 1; width: 100%; max-width: 460px; text-align: center;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 44px 36px 36px; box-shadow: 0 40px 120px rgba(0,0,0,.6);
  transform: translateY(14px) scale(.98); opacity: 0; transition: transform .35s var(--ease), opacity .35s var(--ease);
}
.mq.is-in .mq__scrim { opacity: 1; }
.mq.is-in .mq__card { transform: none; opacity: 1; }
.mq__close { position: absolute; top: 16px; right: 16px; width: 36px; height: 36px; display: grid; place-items: center; border: none; background: none; color: var(--ink-soft); cursor: pointer; border-radius: 50%; transition: color .2s, background .2s; }
.mq__close:hover { color: var(--ink); background: var(--surface); }
.mq__close svg { width: 18px; height: 18px; }
.mq__mark { position: relative; display: inline-grid; place-items: center; width: 72px; height: 72px; color: var(--ink); margin-bottom: 18px; }
.mq__mark svg:not(.mq__ring) { width: 40px; height: 40px; }
/* Stroke ring traced around the mark, tied to render progress
   (setProgress() in engine-v1.js/engine-v2.js sets mqRingFill's
   stroke-dashoffset) — not a separate loader, just this same mark with a
   progress indicator drawn around it. Sized with room between the ring
   and the 40px logo so it reads as a ring around the mark, not a collar
   tight against it. */
.mq__ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.mq__ringtrack { fill: none; stroke: var(--line-2); stroke-width: 3; }
.mq__ringfill {
  fill: none; stroke: var(--ink); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 201.06; stroke-dashoffset: 201.06;
  transition: stroke-dashoffset .15s linear;
}
@media (prefers-reduced-motion: reduce) { .mq__ringfill { transition: none; } }

.mq__eyebrow { font-size: .8rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.mq__title { font-size: clamp(1.7rem, 4vw, 2.2rem); font-weight: 500; letter-spacing: -0.03em; margin: 8px 0 14px; }
.mq__sub { color: var(--ink-soft); font-size: 1.02rem; line-height: 1.55; max-width: 360px; margin: 0 auto 26px; }
/* Same weight as .mq__title (500) — a headline, not a bolded label. */
.mq__facthead { display: block; font-weight: 500; color: var(--ink); margin-bottom: 6px; }
.mq__actions { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.mq__actions .btn--store { width: 100%; max-width: 280px; justify-content: center; }
/* Same treatment as the rest of the site's disabled buttons (.pmodal__submit,
   .iwidget__cta) — present the whole time, just inert until there is
   something to act on. */
.mq__actions button:disabled { opacity: .4; cursor: default; pointer-events: none; }
.mq__ghost { font: inherit; font-size: .98rem; color: var(--ink-soft); background: none; border: none; cursor: pointer; padding: 4px 8px; transition: color .2s; }
.mq__ghost:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .mq__scrim, .mq__card { transition: none; } }

/* faq cta */
.faqs__cta { text-align: center; margin-top: 30px; color: var(--ink-soft); font-size: .95rem; }
.faqs__cta a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* ── responsive ── */
@media (max-width: 760px) {
  .presets { grid-template-columns: 1fr 1fr; }
  .feels { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
  .presets { grid-template-columns: 1fr; }
  .feels { grid-template-columns: 1fr 1fr; gap: 10px; }
  .player__dl { margin-left: 0; width: 100%; justify-content: center; }
  .player { gap: 12px; }
}

/* The generic hamburger + panel mechanics (.nav__burger, .nav__right's
   mobile collapse) now live in styles.css, shared by every page's header.
   This block covers only what's unique to mastering's header: hiding the
   second wordmark, and the account-chip's mobile layout. */
@media (max-width: 640px) {
  .brand__tool { display: none; }     /* the mark alone reads as "the app" without a second wordmark */

  .nav__right .acct__signin {
    width: 100%; padding: 13px 0; border-bottom: 1px solid var(--line);
  }
  .nav__right .acct { width: 100%; }
  .nav__right .acct__me { width: 100%; }
  .nav__right .acct__chip { width: 100%; padding: 13px 0; border-bottom: 1px solid var(--line); }
  .nav__right .acct__menu { position: static; opacity: 1; visibility: visible; pointer-events: auto; transform: none; box-shadow: none; border: none; padding: 8px 0 4px; background: none; backdrop-filter: none; display: none; }
  .nav__right .acct__me.is-open .acct__menu { display: block; }
}

/* ============================================================
   SIGNUP GATE — shown only when an anonymous visitor asks for a
   second master inside the window. Same card language as the
   success modal (.mq) on a wide screen; a bottom sheet on a phone,
   which is where a thumb already is. The tone is a nudge, not a
   toll gate — this person has already had a master out of us.
   ============================================================ */
.mgate { position: fixed; inset: 0; z-index: 210; display: flex; align-items: center; justify-content: center; padding: 24px; }
.mgate[hidden] { display: none; }
.mgate__scrim { position: absolute; inset: 0; background: rgba(5,5,6,.78); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); opacity: 0; transition: opacity .3s var(--ease); }
.mgate__card {
  position: relative; z-index: 1; width: 100%; max-width: 420px; text-align: center;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 40px 32px 32px; box-shadow: 0 40px 120px rgba(0,0,0,.6);
  transform: translateY(14px) scale(.98); opacity: 0; transition: transform .35s var(--ease), opacity .35s var(--ease);
}
.mgate.is-in .mgate__scrim { opacity: 1; }
.mgate.is-in .mgate__card { transform: none; opacity: 1; }
/* Same treatment as the download-success popup's .mq__mark (the brand mark
   itself, no boxed background) rather than the boxed-icon look this used
   to have — one look for "this is Loopin" across both popups. */
.mgate__close { position: absolute; top: 16px; right: 16px; width: 36px; height: 36px; display: grid; place-items: center; border: none; background: none; color: var(--ink-soft); cursor: pointer; border-radius: 50%; transition: color .2s, background .2s; }
.mgate__close:hover { color: var(--ink); background: var(--surface); }
.mgate__close svg { width: 18px; height: 18px; }
.mgate__mark { display: inline-grid; place-items: center; width: 56px; height: 56px; color: var(--ink); margin-bottom: 18px; }
.mgate__mark svg { width: 40px; height: 40px; }
.mgate__title { font-size: clamp(1.5rem, 4vw, 1.9rem); font-weight: 500; letter-spacing: -0.03em; line-height: 1.2; margin: 0 0 12px; }
/* The ask-at-download sheet (flag "Account at download"): headline, one line, one button, only the cross to leave. */
.mgate__card--ask { padding: 52px 36px 44px; }
.mgate__card--ask .mgate__mark { margin-bottom: 14px; }
.mgate__card--ask .mgate__title { margin-bottom: 10px; text-wrap: balance; }
.mgate__card--ask .mgate__body { margin-bottom: 28px; }
.mgate__body { color: var(--ink-soft); font-size: 1.02rem; line-height: 1.55; max-width: 320px; margin: 0 auto 24px; }
.mgate__actions { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.mgate__note { color: var(--ink-faint); font-size: .86rem; margin-top: 14px; }
.mgate__err { color: var(--error); font-size: .88rem; margin-top: 14px; }
.mgate__ghost { font: inherit; font-size: .98rem; color: var(--ink-soft); background: none; border: none; cursor: pointer; padding: 6px 10px; transition: color .2s; }
.mgate__ghost:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* Google's button, to Google's brand rules: their mark on white, unaltered. */
.btn--google {
  width: 100%; max-width: 300px; justify-content: center;
  background: #FFFFFF; color: #1F1F1F; border-color: #FFFFFF; font-weight: 500;
}
.btn--google:hover { background: #F2F2F2; }
.btn--google svg { width: 18px; height: 18px; flex: none; }
.btn--google.is-busy { opacity: .6; pointer-events: none; }
/* `.btn` sets display:inline-flex, which outranks the UA rule for [hidden] —
   without this the Google button stays on screen when the gate hides it for
   someone who is already signed in. */
.btn[hidden] { display: none; }

/* On a phone the card becomes a sheet: full width, docked, thumb-height,
   and clear of the home indicator. */
@media (max-width: 640px) {
  .mgate { align-items: flex-end; padding: 0; }
  .mgate__card {
    max-width: none; border-radius: 24px 24px 0 0; border-bottom: none;
    padding: 24px 22px max(20px, env(safe-area-inset-bottom));
    transform: translateY(100%); box-shadow: 0 -20px 60px rgba(0,0,0,.5);
  }
  .mgate.is-in .mgate__card { transform: none; }
  .mgate__card::before { content: ""; display: block; width: 40px; height: 4px; border-radius: 4px; background: var(--line-2); margin: -6px auto 16px; }
  /* The 320px cap on .mgate__body was written for the centred desktop card;
     on a full-bleed sheet it leaves the same text ragged inside a narrow
     column with dead space on both sides. Full width lets it wrap evenly. */
  .mgate__mark { width: 44px; height: 44px; margin-bottom: 12px; }
  .mgate__mark svg { width: 32px; height: 32px; }
  .mgate__title { font-size: 1.32rem; margin-bottom: 7px; }
  .mgate__card--ask { padding: 28px 22px max(26px, env(safe-area-inset-bottom)); }
  .mgate__card--ask .mgate__body { margin-bottom: 22px; }
  .mgate__body { max-width: none; font-size: .94rem; line-height: 1.45; margin-bottom: 18px; }
  .mgate__actions { gap: 9px; }
  .mgate__note { font-size: .8rem; margin-top: 10px; }
  .btn--google { max-width: none; padding: 14px 22px; }
}
@media (prefers-reduced-motion: reduce) { .mgate__scrim, .mgate__card { transition: none; } }

/* ============================================================
   ADD TO HOME SCREEN — a sticky bar, offered after the first
   successful download and never before it. Sits above the home
   indicator, never over the player controls (the page gets
   matching bottom padding while it is up).
   ============================================================ */
.mhs {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 190;
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
  background: rgba(16,15,18,.94); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
  transform: translateY(110%); transition: transform .35s var(--ease);
}
.mhs[hidden] { display: none; }
.mhs.is-in { transform: none; }
.mhs__row { display: flex; align-items: center; gap: 12px; max-width: 560px; margin: 0 auto; }
.mhs__icon { flex: none; width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center; background: var(--surface); border: 1px solid var(--line); }
.mhs__icon svg { width: 22px; height: 22px; color: var(--ink); }
.mhs__text { flex: 1 1 auto; min-width: 0; }
.mhs__title { font-size: .96rem; font-weight: 500; letter-spacing: -0.01em; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mhs__sub { font-size: .82rem; color: var(--ink-soft); line-height: 1.3; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mhs__add { flex: none; white-space: nowrap; padding: 10px 16px; font-size: .9rem; background: var(--accent); color: #0A0A0B; border-color: var(--accent); font-weight: 600; }
.mhs__add:hover { background: #fff; }
.mhs__add-short { display: none; }
.mhs__close { flex: none; width: 30px; height: 30px; display: grid; place-items: center; border: none; background: none; color: var(--ink-faint); cursor: pointer; border-radius: 50%; }
.mhs__close:hover { color: var(--ink); background: var(--surface); }
.mhs__close svg { width: 15px; height: 15px; }

/* iOS has no install API, so the button reveals the real two steps instead of
   pretending to install something. Hidden everywhere the browser can do it. */
.mhs__steps { display: none; max-width: 560px; margin: 12px auto 2px; padding-top: 12px; border-top: 1px solid var(--line); }
.mhs.is-steps .mhs__steps { display: block; }
.mhs__step { display: flex; align-items: center; gap: 9px; font-size: .87rem; color: var(--ink-soft); padding: 3px 0; }
.mhs__step svg { width: 16px; height: 16px; flex: none; color: var(--ink); }
.mhs__step b { color: var(--ink); font-weight: 500; }

/* Keep the bar off the page's own controls while it is showing. */
body.has-hs-cta { padding-bottom: 92px; }

/* Compact: a smaller icon, one line of copy instead of two, and a short
   button label — the full sentence and the sub-line were fighting the
   button for room on a narrow phone. */
@media (max-width: 480px) {
  .mhs { padding: 9px 12px calc(9px + env(safe-area-inset-bottom)); }
  .mhs__row { gap: 8px; }
  .mhs__icon { width: 30px; height: 30px; border-radius: 8px; }
  .mhs__icon svg { width: 15px; height: 15px; }
  .mhs__title { font-size: .84rem; }
  .mhs__sub { display: none; }
  .mhs__add { padding: 8px 12px; font-size: .84rem; }
  .mhs__add-full { display: none; }
  .mhs__add-short { display: inline; }
  .mhs__close { width: 26px; height: 26px; }
  .mhs__close svg { width: 13px; height: 13px; }
  body.has-hs-cta { padding-bottom: 64px; }
}

@media (prefers-reduced-motion: reduce) { .mhs { transition: none; } }

/* ============================================================
   ACCOUNT — nav, top right. Understated on purpose: signing in
   is an offer, not the point of the page. Both states start
   hidden and JS reveals the right one, so the nav never flashes
   "Sign in" at somebody who already is.
   ============================================================ */
.acct { position: relative; display: flex; align-items: center; }
.acct[hidden] { display: none; }

/* Signed out: plain text, same weight as the links beside it. */
.acct__signin { font: inherit; font-size: .95rem; background: none; border: none; padding: 0; cursor: pointer; color: var(--ink-soft); transition: color .2s var(--ease); }
.acct__signin:hover { color: var(--ink); }
.acct__signin[hidden] { display: none; }

/* Signed in: their picture, their first name. */
.acct__me { position: relative; }
.acct__me[hidden] { display: none; }
.acct__chip {
  display: inline-flex; align-items: center; gap: 8px;
  font: inherit; font-size: .95rem; color: var(--ink-soft);
  background: none; border: none; padding: 4px 2px; cursor: pointer;
  transition: color .2s var(--ease);
}
.acct__chip:hover, .acct__me:hover .acct__chip { color: var(--ink); }
.acct__avatar { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; border: 1px solid var(--line-2); flex: none; }
.acct__avatar[hidden] { display: none; }
/* Fallback when there is no picture — first letter on a plain disc. */
.acct__initial {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--surface-2); border: 1px solid var(--line-2);
  color: var(--ink); font-size: .8rem; font-weight: 500; text-transform: uppercase;
}
.acct__initial:empty { display: none; }
.acct__name { max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The menu. Opens on hover on a pointer device and on click everywhere —
   hover alone would be unreachable on a touchscreen. The padding-top bridges
   the gap so the pointer can travel from chip to menu without it closing. */
.acct__menu {
  position: absolute; top: 100%; right: 0; margin-top: 8px; min-width: 190px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 12px; box-shadow: 0 20px 50px rgba(0,0,0,.5);
  opacity: 0; visibility: hidden; transform: translateY(-4px);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility .18s;
  z-index: 60;
}
.acct__menu::before { content: ""; position: absolute; left: 0; right: 0; top: -10px; height: 10px; }
@media (hover: hover) {
  .acct__me:hover .acct__menu, .acct__me:focus-within .acct__menu { opacity: 1; visibility: visible; transform: none; }
}
.acct__me.is-open .acct__menu { opacity: 1; visibility: visible; transform: none; }
.acct__email { font-size: .82rem; color: var(--ink-faint); margin-bottom: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct__item {
  display: flex; align-items: center; gap: 10px; font: inherit; font-size: .92rem; width: 100%; text-align: left;
  background: none; border: none; padding: 7px 8px; margin: 0 -8px;
  border-radius: 9px; color: var(--ink-soft); cursor: pointer; text-decoration: none;
  transition: color .2s, background .2s;
}
.acct__item:hover { color: var(--ink); background: var(--surface-2); }
.acct__item--out { margin-bottom: -4px; }
.acct__itemIcon { flex: none; width: 16px; height: 16px; color: var(--ink-faint); transition: color .2s; }
.acct__item:hover .acct__itemIcon { color: var(--ink-soft); }

/* On a phone the nav is tight — the name goes, the picture stays. */
@media (max-width: 620px) {
  .acct__name { display: none; }
  .acct__menu { right: -6px; }
}
@media (prefers-reduced-motion: reduce) { .acct__menu { transition: none; } }

/* ============================================================
   ARTIST PROFILE — the post-login popup (mandatory, once) and
   "My profile" (the same card, reopened as an ordinary editable
   sheet). Deliberately lighter than the signup gate's scrim: the
   mastering page should still read as visible behind it, since
   this is a detail to fill in, not a decision to make.
   ============================================================ */
.pmodal { position: fixed; inset: 0; z-index: 220; display: flex; align-items: center; justify-content: center; padding: 24px; }
.pmodal[hidden] { display: none; }
.pmodal__scrim { position: absolute; inset: 0; background: rgba(5,5,6,.55); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); opacity: 0; transition: opacity .3s var(--ease); }
.pmodal__card {
  position: relative; z-index: 1; width: 100%; max-width: 440px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 30px 28px 26px; box-shadow: 0 40px 120px rgba(0,0,0,.6);
  max-height: min(640px, 88vh); max-height: min(640px, 88dvh); overflow-y: auto;
  transform: translateY(14px) scale(.98); opacity: 0; transition: transform .32s var(--ease), opacity .32s var(--ease);
}
.pmodal.is-in .pmodal__scrim { opacity: 1; }
.pmodal.is-in .pmodal__card { transform: none; opacity: 1; }

.pmodal__title { font-size: clamp(1.35rem, 3.4vw, 1.6rem); font-weight: 500; letter-spacing: -0.02em; margin: 0 0 6px; }
.pmodal__sub { color: var(--ink-soft); font-size: .95rem; line-height: 1.5; margin: 0 0 22px; }

.pmodal__field { margin-bottom: 18px; }
.pmodal__field:last-of-type { margin-bottom: 6px; }
.pmodal__label { font-size: .84rem; font-weight: 500; color: var(--ink-soft); margin-bottom: 9px; }
.pmodal__label--optional span { font-weight: 400; color: var(--ink-faint); text-transform: none; letter-spacing: 0; }

.pmodal__input {
  width: 100%; font: inherit; font-size: .98rem; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: 14px;
  padding: 12px 14px; transition: border-color .2s var(--ease);
}
.pmodal__input::placeholder { color: var(--ink-faint); }
.pmodal__input:focus { outline: none; border-color: var(--ink-soft); }
.pmodal__input--other { margin-top: 8px; }

/* Country combobox panel — position:fixed, positioned in JS via the input's
   getBoundingClientRect() (see mastering/countries.js mountPicker), so it
   escapes .pmodal__card's own overflow:auto instead of being clipped by it. */
.ccombo__panel {
  position: fixed; z-index: 300; min-width: 220px; max-height: 280px;
  overflow-y: auto; padding: 6px;
  background: rgba(20,19,24,.98); border: 1px solid var(--line-2); border-radius: 14px;
  box-shadow: 0 24px 60px -18px rgba(0,0,0,.75);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.ccombo__panel[hidden] { display: none; }
.ccombo__opt {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 9px;
  font-size: .92rem; color: var(--ink); cursor: pointer;
}
.ccombo__opt:hover, .ccombo__opt.is-active { background: rgba(255,255,255,.08); }
.ccombo__flag { flex: none; font-size: 1.05em; }
.ccombo__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ccombo__empty { padding: 10px; font-size: .88rem; color: var(--ink-faint); text-align: center; }

/* Pill chips — compact, thumb-friendly, one class for both the multi-select
   roles and the single-select sources; only the click handler differs. */
.pmodal__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.pchip {
  font: inherit; font-size: .88rem; color: var(--ink-soft);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: 999px;
  padding: 8px 15px; cursor: pointer; transition: color .18s, background .18s, border-color .18s;
}
.pchip:hover { border-color: var(--ink-soft); color: var(--ink); }
.pchip.is-on { background: var(--accent); border-color: var(--accent); color: #0A0A0B; font-weight: 500; }

.pmodal__err { color: var(--error); font-size: .86rem; margin: 4px 0 0; }

.pmodal__actions { margin-top: 22px; }
.pmodal__submit { width: 100%; justify-content: center; background: var(--accent); color: #0A0A0B; border-color: var(--accent); font-weight: 600; }
.pmodal__submit:hover { background: #fff; }
.pmodal__submit:disabled { opacity: .4; cursor: default; pointer-events: none; }

@media (prefers-reduced-motion: reduce) { .pmodal__scrim, .pmodal__card { transition: none; } }

/* Mobile: a bottom sheet, same shape as the signup gate's. */
@media (max-width: 640px) {
  .pmodal { align-items: flex-end; padding: 0; }
  .pmodal__card {
    max-width: none; border-radius: 22px 22px 0 0; border-bottom: none;
    padding: 26px 20px max(22px, env(safe-area-inset-bottom));
    max-height: min(680px, 86vh); max-height: min(680px, 86dvh);
    transform: translateY(100%); box-shadow: 0 -20px 60px rgba(0,0,0,.5);
  }
  .pmodal.is-in .pmodal__card { transform: none; }
  .pmodal__card::before { content: ""; display: block; width: 44px; height: 5px; border-radius: 5px; background: var(--line-2); margin: -8px auto 16px; }
}

/* ============================================================
   WELCOME / UPGRADE — the once-per-lifetime "2 downloads/day, or go
   Unlimited" popup (mastering/welcome-popup.js). Dismissible, unlike
   .pmodal above: scrim click, Escape and the close button all work. The
   card itself is its own self-contained object — a hairline gradient
   border, a restrained blurred halo, a real shadow — rather than the flatter
   .pmodal__card/.imodal__card shell the rest of this file's popups use.

   No bold anywhere in here — font-weight tops out at 500 on every element,
   by design, not oversight. */
.wmodal { position: fixed; inset: 0; z-index: 220; display: flex; align-items: center; justify-content: center; padding: 24px; }
.wmodal[hidden] { display: none; }
.wmodal__scrim { position: absolute; inset: 0; background: rgba(5,5,6,.55); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); opacity: 0; transition: opacity .3s var(--ease); cursor: pointer; }

.wm {
  position: relative; z-index: 1; width: 100%; max-width: 380px; isolation: isolate;
  border-radius: 20px; padding: 1px;
  background: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.05) 40%, rgba(255,255,255,.05));
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.6), 0 8px 24px -8px rgba(0,0,0,.5);
  transform: translateY(14px) scale(.98); opacity: 0; transition: transform .32s var(--ease), opacity .32s var(--ease);
}
.wmodal.is-in .wmodal__scrim { opacity: 1; }
.wmodal.is-in .wm { transform: none; opacity: 1; }

.wm__inner {
  position: relative; overflow: hidden; border-radius: 19px;
  background: var(--bg-2); padding: 36px 30px 28px; text-align: center;
}
.wm__halo {
  position: absolute; top: -70px; left: 50%; transform: translateX(-50%);
  width: 220px; height: 160px; border-radius: 50%; filter: blur(46px);
  opacity: .5; pointer-events: none;
}
.wm__halo--mono { background: radial-gradient(circle, rgba(255,255,255,.5), transparent 70%); }
.wm__halo--gold { background: radial-gradient(circle, rgba(255,255,255,.35), transparent 70%); }

.wm__close {
  position: absolute; top: 14px; right: 14px; width: 30px; height: 30px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center; color: var(--ink-faint);
  font-size: 15px; line-height: 1; cursor: pointer; border: none; background: none; z-index: 2;
  transition: background .15s, color .15s;
}
.wm__close:hover { background: rgba(255,255,255,.06); color: var(--ink-soft); }

.wm__mark { width: 30px; height: auto; margin: 0 auto 16px; display: block; color: var(--ink); position: relative; z-index: 1; }

.wm__eyebrow {
  position: relative; z-index: 1;
  display: inline-flex; font-size: .78rem; font-weight: 500; color: var(--ink-soft);
  letter-spacing: .01em; margin: 0 0 22px;
}

.wm__stat { position: relative; z-index: 1; display: flex; align-items: baseline; justify-content: center; margin: 0 0 4px; }
.wm__statN { font-size: 4.4rem; font-weight: 500; letter-spacing: -.035em; line-height: .95; font-variant-numeric: tabular-nums; }
.wm__statLabel { position: relative; z-index: 1; font-size: .92rem; font-weight: 500; margin: 0 0 12px; }

.wm__sub { position: relative; z-index: 1; font-size: .87rem; color: var(--ink-soft); line-height: 1.5; margin: 0 0 26px; }
.wm__sub strong { color: var(--ink); font-weight: 500; }

.wm__primary {
  position: relative; z-index: 1; display: block; width: 100%;
  background: linear-gradient(180deg, #fff, #E7E6E3);
  color: #0A0A0B; border: none; border-radius: 999px;
  padding: 13px; font: inherit; font-size: .93rem; font-weight: 500; cursor: pointer;
  box-shadow: 0 1px 0 rgba(255,255,255,.4) inset, 0 8px 20px -8px rgba(0,0,0,.5);
  margin: 0 0 14px;
  transition: transform .15s;
}
.wm__primary:hover { transform: translateY(-1px); }

.wm__quiet {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 5px;
  font: inherit; font-size: .83rem; color: var(--ink-faint);
  background: none; border: none; cursor: pointer; padding: 0;
}
.wm__quiet strong { color: var(--ink-soft); font-weight: 500; }
.wm__quiet:hover strong { color: var(--ink); }

@media (prefers-reduced-motion: reduce) { .wmodal__scrim, .wm { transition: none; } }
@media (max-width: 480px) {
  .wm__inner { padding: 32px 22px 24px; }
}

/* ============================================================
   "MY PROFILE" — /mastering/profile, an ordinary page. Reuses the same
   field styling as the popup above (.pmodal__field, .pmodal__label,
   .pmodal__input, .pmodal__chips, .pchip, .pmodal__err,
   .pmodal__submit) so the two never look like different products; only
   the page shell around them differs, since this one isn't fixed over
   the mastering tool.
   ============================================================ */
.ppage { max-width: 560px; margin: 0 auto; padding: 56px 24px 88px; }
.ppage__back {
  display: inline-flex; align-items: center; gap: 6px; color: var(--ink-soft);
  font-size: .88rem; text-decoration: none; margin-bottom: 26px; transition: color .2s;
}
.ppage__back:hover { color: var(--ink); }
.ppage__back svg { width: 15px; height: 15px; }
/* The page's own name — "Profile" — separate from any card. A settings
   page has a title; a popup never did, which is exactly the distinction
   this redesign draws. */
.ppage__pagetitle { font-size: clamp(1.8rem, 4.6vw, 2.4rem); font-weight: var(--h1-weight); letter-spacing: var(--h1-tracking); line-height: 1.05; margin: 0 0 28px; }
.ppage__card {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 34px 32px;
}
.ppage__card + .ppage__card { margin-top: 20px; }
.ppage__title { font-size: clamp(1.5rem, 4vw, 1.9rem); font-weight: 500; letter-spacing: -0.02em; margin: 0 0 6px; }
/* A section heading inside a card — smaller than .ppage__title, which is
   now only ever the identity card's own name (below), not a page title. */
.ppage__h2 { font-size: 1.05rem; font-weight: 600; letter-spacing: -.01em; margin: 0 0 4px; }
.ppage__sub { color: var(--ink-soft); font-size: .95rem; line-height: 1.5; margin: 0 0 28px; }
.ppage__msg { font-size: .88rem; margin-top: 16px; min-height: 1.2em; }
.ppage__msg--ok { color: var(--accent); }
.ppage__msg--err { color: var(--error); }
.ppage__loading, .ppage__signedout { color: var(--ink-soft); font-size: .95rem; padding: 40px 0; text-align: center; }

/* ---- identity card: who you are, not the onboarding survey ------------- */
.ppage__identity { display: flex; align-items: center; gap: 16px; }
.ppage__avatar {
  width: 56px; height: 56px; border-radius: 50%; flex: none; overflow: hidden;
  display: grid; place-items: center;
  background: var(--surface-2); border: 1px solid var(--line-2);
  color: var(--ink); font-size: 1.25rem; font-weight: 600; text-transform: uppercase;
}
.ppage__avatar img { width: 100%; height: 100%; object-fit: cover; }
.ppage__idmeta { flex: 1; min-width: 0; }
.ppage__name { margin: 0; font-size: 1.2rem; font-weight: 600; letter-spacing: -.01em; overflow-wrap: break-word; }
.ppage__email { margin: 4px 0 0; font-size: .88rem; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ppage__since { margin: 2px 0 0; font-size: .8rem; color: var(--ink-faint); }
.ppage__pill {
  flex: none; align-self: flex-start; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(61, 220, 132, .12); color: var(--accent);
}
.ppage__pill--free { background: var(--surface-2); color: var(--ink-faint); }

@media (max-width: 640px) {
  .ppage { padding: 36px 16px 64px; }
  .ppage__card { padding: 24px 20px; }
  .ppage__identity { flex-wrap: wrap; }
}

/* ============================================================
   LOOPIN INSIDER — the second-visit popup (dismissible, unlike .pmodal
   above) and the widget it shares with "My profile". Same shell language
   as .pmodal so it still reads as part of the same product, but this one
   has a close button and a scrim that actually closes it.
   ============================================================ */
.imodal { position: fixed; inset: 0; z-index: 220; display: flex; align-items: center; justify-content: center; padding: 24px; }
.imodal[hidden] { display: none; }
.imodal__scrim { position: absolute; inset: 0; background: rgba(5,5,6,.55); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); opacity: 0; transition: opacity .3s var(--ease); cursor: pointer; }
.imodal__card {
  position: relative; z-index: 1; width: 100%; max-width: 440px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 30px 28px 26px; box-shadow: 0 40px 120px rgba(0,0,0,.6);
  max-height: min(640px, 88vh); max-height: min(640px, 88dvh); overflow-y: auto;
  transform: translateY(14px) scale(.98); opacity: 0; transition: transform .32s var(--ease), opacity .32s var(--ease);
}
.imodal.is-in .imodal__scrim { opacity: 1; }
.imodal.is-in .imodal__card { transform: none; opacity: 1; }
.imodal__close {
  position: absolute; top: 16px; right: 16px; width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center; background: none; border: none; color: var(--ink-soft); cursor: pointer;
  transition: color .2s, background .2s;
}
.imodal__close:hover { color: var(--ink); background: var(--surface-2); }
.imodal__close svg { width: 16px; height: 16px; }
@media (prefers-reduced-motion: reduce) { .imodal__scrim, .imodal__card { transition: none; } }
@media (max-width: 640px) {
  .imodal { align-items: flex-end; padding: 0; }
  .imodal__card {
    max-width: none; border-radius: 22px 22px 0 0; border-bottom: none;
    padding: 26px 20px max(22px, env(safe-area-inset-bottom));
    transform: translateY(100%); box-shadow: 0 -20px 60px rgba(0,0,0,.5);
  }
  .imodal.is-in .imodal__card { transform: none; }
}

/* ---- the widget itself: apply banner / waitlist progress / power user -- */
.iwidget__mark { display: block; width: 34px; height: auto; margin: 0 0 14px; }
.iwidget__title { margin: 0 0 4px; font-size: 1.15rem; font-weight: 600; letter-spacing: -.01em; }
.iwidget__subtitle { margin: 0 0 10px; font-size: .92rem; font-weight: 500; color: var(--ink-soft); }
.iwidget__body { margin: 0 0 18px; font-size: .92rem; line-height: 1.55; color: var(--ink-soft); }
.iwidget__bar { height: 8px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line-2); overflow: hidden; }
.iwidget__fill { height: 100%; border-radius: 999px; background: var(--accent); transition: width .4s var(--ease); }
.iwidget__count { margin: 8px 0 0; font-size: .82rem; color: var(--ink-faint); }
.iwidget__cta { width: 100%; justify-content: center; margin-top: 18px; background: var(--accent); color: #0A0A0B; border-color: var(--accent); font-weight: 600; }
.iwidget__cta:hover { background: #fff; }
.iwidget__cta:disabled { opacity: .5; cursor: default; pointer-events: none; }
/* The confirmed, "you're in" state — a beat between the click and the panel
   moving on, secondary/outline rather than the filled accent of the ask. */
.iwidget__cta--done {
  background: none; color: var(--accent); border-color: var(--accent);
  opacity: 1; pointer-events: none;
}
.iwidget__err { color: var(--error); font-size: .82rem; margin: 10px 0 0; text-align: center; }
.iwidget__err[hidden] { display: none; }

.iwidget--power .iwidget__title { color: var(--accent); }
.iwidget--power .iwidget__body { margin-bottom: 0; }


/* ---- download format, Unlimited only ------------------------------------
   Sits beside the Download button and is revealed by the engine when the
   account has MP3. Mirrors .player__mono / .player__abmatch so it reads as
   part of the same transport row rather than a bolted-on upsell. */
.player__fmt[hidden] { display: none; }   /* the class sets display, which
     outranks the UA rule for [hidden] — same trap as .btn above (line ~399).
     Without this the MP3 toggle is visible to every free visitor. */
.player__fmt { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--mp-line, #26262c); border-radius: 999px; }
.player__fmt button {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: 12px; letter-spacing: .02em;
  color: var(--mp-mut, #9A9AA2); padding: 5px 12px; border-radius: 999px;
  transition: background .16s ease, color .16s ease;
}
.player__fmt button.is-on { background: var(--mp-panel2, #1c1c21); color: var(--mp-txt, #ECECEE); }
.player__fmt button:focus-visible { outline: 2px solid var(--mp-accent, #FF6B5E); outline-offset: 2px; }

/* ── a rejected upload says why, where you are looking (mastering/input-check.js) ── */
.drop__error { margin: 14px auto 0; max-width: 460px; padding: 10px 14px; border: 1px solid rgba(255,107,107,.45); border-radius: 12px;
  background: rgba(255,107,107,.08); color: #ffb4b4; font-size: .92rem; line-height: 1.4; text-align: center; }
.drop__error[hidden] { display: none; }

/* ---- "did you like this master?" thumbs (mastering/master-feedback.js) ---- */
.insight__fb { margin-left: auto; display: flex; align-items: center; gap: 6px; flex: none; }
.insight__thanks { font-size: .8rem; color: var(--ink-soft); white-space: nowrap; margin-right: 6px; }
.insight__thanks[hidden] { display: none; }
.fbbtn {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--line-2); background: transparent; color: var(--ink-soft);
  transition: border-color .2s var(--ease), color .2s var(--ease), background .2s var(--ease);
}
.fbbtn svg { width: 16px; height: 16px; }
.fbbtn:hover { border-color: var(--ink); color: var(--ink); }
.fbbtn:focus-visible { outline: none; border-color: var(--ink); box-shadow: 0 0 0 2px var(--ink); }
.fbbtn.is-on { background: var(--ink); border-color: var(--ink); color: var(--bg, #0b0b0d); }
.insight__why { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0 42px; }
.insight__why[hidden] { display: none; }
.insight__why button {
  font: inherit; font-size: .78rem; padding: 6px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line-2); background: transparent; color: var(--ink);
}
.insight__why button:hover { border-color: var(--ink); }
.insight__why button.is-on { background: var(--ink); color: var(--bg, #0b0b0d); border-color: var(--ink); }
@media (max-width: 560px) {
  .insight { flex-wrap: wrap; }
  .insight__fb { margin-left: 42px; }
  .insight__why { margin-left: 0; }
}

/* ---- waveform playhead + click-to-seek (engine v3) ---- */
.ws__playhead { position: absolute; width: 2px; margin-left: -1px; background: var(--ink); border-radius: 1px; pointer-events: none; box-shadow: 0 0 0 1px rgba(0,0,0,.35); }
.ws__playhead[hidden] { display: none; }
.ws__playhead__t {
  position: absolute; top: -22px; left: 50%; transform: translateX(-50%); white-space: nowrap;
  font-size: .72rem; font-variant-numeric: tabular-nums; color: var(--ink); background: var(--surface-2, #1c1c21);
  border: 1px solid var(--line-2); border-radius: 999px; padding: 1px 8px;
}
.ws__wave:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--ink); }

/* ---- "What artists say": three always-moving rows (mastering/reviews.js) ---- */
.rv { padding: 56px 0 14px; overflow: hidden; }
.rv__title { font-size: clamp(1.5rem, 3.2vw, 2.1rem); font-weight: 500; letter-spacing: -0.03em; text-align: center; }
.rv__sub { color: var(--ink-soft); text-align: center; max-width: 560px; margin: 12px auto 30px; line-height: 1.5; padding: 0 16px; }
.rv__rows { display: grid; gap: 14px; -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.rv__row { overflow-x: auto; scrollbar-width: none; }
.rv__row::-webkit-scrollbar { display: none; }
.rv__row.is-looping { overflow: hidden; }
.rv__track { display: flex; gap: 14px; width: max-content; list-style: none; margin: 0; padding: 0 7px; }
.rv__row.is-looping .rv__track { animation: rv-left var(--rv-dur, 90s) linear infinite; will-change: transform; }
.rv__row.is-looping[data-rv-dir="right"] .rv__track { animation-name: rv-right; }
.rv__row--2.is-looping .rv__track { animation-duration: calc(var(--rv-dur, 90s) * 1.15); }
.rv__row--3.is-looping .rv__track { animation-duration: calc(var(--rv-dur, 90s) * .9); }
.rv__row:hover .rv__track, .rv__row:focus-within .rv__track { animation-play-state: paused; }
@keyframes rv-left { to { transform: translateX(-50%); } }
@keyframes rv-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
.rv__card { flex: none; width: 320px; }
.rv__card figure { margin: 0; height: 100%; display: flex; flex-direction: column; justify-content: space-between; gap: 16px; padding: 18px 20px; border: 1px solid var(--line); border-radius: var(--radius-lg, 18px); background: var(--surface); }
.rv__card blockquote { margin: 0; }
.rv__card blockquote p { margin: 0; font-size: .9rem; line-height: 1.5; color: var(--ink); display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
.rv__card figcaption { display: flex; align-items: center; gap: 11px; }
.rv__img { flex: none; width: 36px; height: 36px; border-radius: 50%; object-fit: cover; background: var(--surface-2, #1c1c21); }
.rv__img--init { display: grid; place-items: center; font-size: .72rem; font-weight: 600; letter-spacing: .02em; color: var(--ink-soft); border: 1px solid var(--line-2); }
.rv__who { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.rv__name { font-size: .85rem; font-weight: 500; color: var(--ink); }
.rv__role { font-size: .76rem; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 560px) { .rv { padding-top: 40px; } .rv__card { width: 272px; } .rv__card figure { padding: 16px; } }

/* Tax policy line under the prices in the two upgrade popups. */
.loffer__fine, .wm__fine { margin: 6px 0 0; font-size: .74rem; line-height: 1.4; color: var(--ink-soft); text-align: center; }

/* The signed-in greeting above the headline (mastering/greeting.js): a plain white line, copy by the visitor's own time
   of day. `html.li-hint` (set in <head> by consent.js for a signed-in browser) reserves its line, so the headline
   does not move when it appears. */
.mp-greet { width: fit-content; max-width: 100%; margin: 0 auto 16px; text-align: center; font-size: clamp(1.15rem, 2.6vw, 1.55rem); font-weight: 450;
  letter-spacing: -.01em; line-height: 1.25; color: #fff; }
.mp-greet__emoji { font-style: normal; }
.mp-greet[hidden] { display: none; }
html[lang="en"].li-hint .mp-greet[hidden] { display: block; visibility: hidden; min-height: 1.25em; }
@media (prefers-reduced-motion: no-preference) { .mp-greet.is-on { animation: mpGreetIn .5s ease both; } }
@keyframes mpGreetIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* Lists inside the on-page article (how-to steps, the mix-and-master checklist): same voice as the paragraphs. */
.mp-about ol, .mp-about ul { margin: 0 0 18px; padding-left: 1.3em; color: var(--ink-soft); }
.mp-about li { margin: 0 0 10px; line-height: 1.6; }
.mp-about li strong { color: var(--ink); font-weight: 500; }
