:root {
  color-scheme: dark;
  --bg: #0b0b0d;
  --panel: #17171c;
  --panel2: #111115;
  --line: #2c2c33;
  --text: #f6f6f8;
  --muted: #92929e;
  --soft: #c8c8d0;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  overflow: hidden;
  background: radial-gradient(circle at 50% -20%,#252532,#0b0b0d 42%);
  color: var(--text);
  font-family: Inter,system-ui,sans-serif;
}

.shell {
  height: 100dvh;
  max-width: 1000px;
  margin: auto;
  overflow: hidden;
  display: grid;
  grid-template-rows: 60px auto minmax(0,1fr) auto;
  background: #0b0b0dcc;
}

.app-header,
.shell>main,
.shell>.composer-wrap {
  min-height: 0;
}

header {
  position: relative;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
  background: #0b0b0df2;
  backdrop-filter: blur(18px);
}

.logo {
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: #fff;
  color: #111;
  display: grid;
  place-items: center;
  font-weight: 800;
}

.grow {
  flex: 1;
}

.muted {
  color: var(--muted);
  font-size: 12px;
}

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

.nav button {
  display: flex;
  align-items: center;
  gap: 6px;
}

.nav button,
/* The primary action button. Extracted from .sidebar-new, whose rules live inside
   @media (min-width:1001px) because the sidebar is desktop-only — reusing that class
   anywhere else would leave the button unstyled on a phone. */

.button-primary {
  min-width: 116px;
  padding: 14px 16px;
  border: 0;
  border-radius: 14px;
  background: linear-gradient(145deg,#b39bf0,#9b7fe8);
  color: #1a1225;
  font: 700 14px/1 Inter,system-ui,sans-serif;
  text-align: center;
  cursor: pointer;
  transition: filter .18s,transform .18s;
}

/* A secondary action alongside a primary one: the same size and shape, so a row of
   buttons reads as one set, distinguished by weight rather than by dimensions. The
   minimum width is New Playlist's natural width, which is the widest of the short
   labels — so "Play" no longer sits at 61px beside a 116px sibling. */

.button-secondary {
  min-width: 116px;
  /* 13px + the 1px border == the primary's 14px, so the two are the same height.
     box-sizing is border-box globally, but these buttons size from their content. */
  padding: 13px 15px;
  border: 1px solid #4a4458;
  border-radius: 14px;
  background: #1f1d27;
  color: #ded9e8;
  font: 700 14px/1 Inter,system-ui,sans-serif;
  text-align: center;
  cursor: pointer;
  transition: filter .18s,transform .18s,background .18s;
}

.button-secondary:hover:not(:disabled) {
  background: #2a2635;
  transform: translateY(-1px);
}

.button-primary:disabled,
.button-secondary:disabled {
  opacity: .45;
  cursor: default;
  transform: none;
}

.button-primary:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

/* No padding override in a page header: the button keeps .button-primary's own 14px,
   so Add Playlist stands exactly as tall as New session. It sits beside a heading
   rather than filling a sidebar column, so only its width differs. */

.ghost {
  border: 1px solid var(--line);
  background: #17171c;
  color: #cfcfd5;
  border-radius: 999px;
  padding: 7px 11px;
  font-size: 12px;
  cursor: pointer;
}

.nav button.active {
  background: #f3f3f5;
  color: #111;
  border-color: #f3f3f5;
}

.chat-songs-nav svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

main {
  overflow: auto;
  padding: 20px 14px;
}

.view {
  display: none;
}

.view.active {
  display: block;
}

.feed {
  max-width: 720px;
  margin: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.feed.songs-only>:not(.track):not(.playback-scroll-space):not(.songs-empty) {
  display: none;
}

.songs-empty {
  min-height: 42vh;
  display: grid;
  place-content: center;
  gap: 7px;
  text-align: center;
  color: #d9d3df;
}

.songs-empty span {
  color: var(--muted);
  font-size: 12px;
}

.empty {
  text-align: center;
  padding-top: 15vh;
}

.empty h1 {
  font-size: clamp(28px,6vw,48px);
  margin: 0 0 10px;
}

.msg {
  max-width: 84%;
  line-height: 1.45;
  white-space: pre-wrap;
}

.user {
  align-self: flex-end;
  background: #eeeef2;
  color: #111;
  padding: 10px 14px;
  border-radius: 18px 18px 5px 18px;
}

.ai {
  align-self: flex-start;
  color: #ddd;
}

.track {
  border: 1px solid var(--line);
  background: linear-gradient(#18181d,#111115);
  padding: 14px;
  border-radius: 18px;
}

.track-top {
  display: flex;
  gap: 12px;
  align-items: center;
}

.track-open {
  cursor: pointer;
  min-width: 0;
  flex: 1;
}

.track-open strong {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cover {
  width: 54px;
  height: 54px;
  border-radius: 14px;
  background: linear-gradient(135deg,#c7aa76,#51475b);
  display: grid;
  place-items: center;
  font-size: 22px;
  flex: none;
  cursor: pointer;
}

.actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.actions button {
  width: 39px;
  height: 39px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: #202026;
  color: #fff;
  cursor: pointer;
}

.wave {
  flex: 1;
  height: 30px;
  background: repeating-linear-gradient(90deg,#555 0 3px,transparent 3px 7px);
  opacity: .55;
  border-radius: 8px;
}

.tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.tag {
  font-size: 11px;
  color: #bbb;
  background: #202026;
  border: 1px solid var(--line);
  padding: 5px 8px;
  border-radius: 999px;
}

.composer-wrap {
  padding: 8px 12px max(12px,env(safe-area-inset-bottom));
  background: linear-gradient(transparent,#0b0b0d 22%);
}

.composer-wrap.hidden {
  display: none;
}

.composer {
  max-width: 720px;
  margin: auto;
  display: grid;
  grid-template-columns: minmax(0,1fr) auto;
  gap: 8px;
  align-items: end;
  background: #18181d;
  border: 1px solid #33333b;
  border-radius: 20px;
  padding: 9px;
}

.input-column {
  min-width: 0;
}

.composer textarea {
  display: block;
  width: 100%;
  min-height: 46px;
  max-height: min(36vh,320px);
  resize: none;
  overflow-y: auto;
  border: 0;
  outline: 0;
  background: transparent;
  color: #fff;
  padding: 10px 10px 4px;
  font: inherit;
  font-size: 17px;
  line-height: 1.45;
}

.composer textarea::placeholder {
  color: #858590;
}

.composer button {
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: 14px;
  background: #fff;
  color: #111;
  font-size: 20px;
  margin-bottom: 1px;
  cursor: pointer;
}

.composer-meta {
  display: flex;
  justify-content: flex-end;
  padding: 0 10px 3px;
  min-height: 18px;
}

.char-count {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.char-count.near-limit {
  color: #d7b06a;
}

.library {
  max-width: 900px;
  margin: auto;
}

.library-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 16px;
  margin: 8px 0 20px;
}

.library-head h1 {
  margin: 0;
  font-size: 34px;
}

.library-grid {
  display: grid;
  grid-template-columns: repeat(2,minmax(0,1fr));
  gap: 12px;
}

.library-card {
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(145deg,#19191f,#111115);
  padding: 14px;
  cursor: pointer;
  display: grid;
  grid-template-columns: 64px minmax(0,1fr);
  gap: 12px;
  align-items: center;
}

.library-card:hover {
  border-color: #4a4a55;
}

.library-cover {
  width: 64px;
  height: 64px;
  border-radius: 16px;
  background: linear-gradient(135deg,#826f91,#c4a36c);
  display: grid;
  place-items: center;
  font-size: 25px;
}

.library-card h3 {
  margin: 0 0 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.library-meta {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
}

/* The library card's "..." — the same component the chat card and player use. It is
   positioned out of the two-column grid so it cannot stretch the row, and the card
   already carries .has-card-menu, which supplies position:relative. */

.library-card .card-menu {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #8b8494;
  cursor: pointer;
  transition: background .16s,color .16s;
}

.library-card .card-menu:hover,
.library-card .card-menu.active {
  background: #221f29;
  color: #e6e0ee;
}

.library-card .card-menu svg {
  width: 18px;
  height: 18px;
}

.library-card .commands-panel {
  top: 42px;
  right: 8px;
}

/* Keep the title clear of the button. */

.library-card .library-open {
  padding-right: 26px;
}


.detail {
  max-width: 860px;
  margin: auto;
}

.back {
  margin-bottom: 18px;
}

.hero {
  display: grid;
  grid-template-columns: 180px minmax(0,1fr);
  gap: 24px;
  align-items: end;
  padding: 20px 0 24px;
}

.hero-cover {
  width: 180px;
  height: 180px;
  border-radius: 28px;
  background: linear-gradient(135deg,#b39a6e,#50445e);
  display: grid;
  place-items: center;
  font-size: 64px;
  box-shadow: 0 20px 55px #0008;
}

.hero h1 {
  margin: 0 0 8px;
  font-size: clamp(30px,6vw,50px);
  line-height: 1.05;
}

/* One player, one playhead. The detail view keeps this element so its
   lip-sync and meter wiring stays valid, but never shows it: playback
   belongs to the app's single player. */

.hero-audio {
  display: none;
}

.detail-tags {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
  margin-top: 12px;
}

.tabs {
  display: flex;
  gap: 5px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 18px;
}

.tab {
  border: 0;
  background: transparent;
  color: var(--muted);
  padding: 11px 14px;
  border-bottom: 2px solid transparent;
  cursor: pointer;
}

.tab.active {
  color: #fff;
  border-bottom-color: #fff;
}

.tab-panel {
  display: none;
}

.tab-panel.active {
  display: block;
}

.lyrics {
  max-width: 680px;
  margin: 10px auto 50px;
  font-size: 21px;
  line-height: 1.8;
  white-space: pre-wrap;
  color: #f2f2f4;
}

.lyrics .section {
  margin: 28px 0;
}

.lyrics .section-name {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--muted);
  margin-bottom: 7px;
}

.details-grid {
  display: grid;
  grid-template-columns: 170px 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}

.details-grid>div {
  background: var(--panel2);
  padding: 12px;
}

.details-grid .label {
  color: var(--muted);
  font-size: 12px;
}

.dev-block {
  margin: 0 0 16px;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}

.dev-title {
  padding: 10px 13px;
  background: #1a1a20;
  color: #bdbdc6;
  font-size: 12px;
}

.dev-block pre {
  margin: 0;
  padding: 14px;
  white-space: pre-wrap;
  overflow: auto;
  font: 12px/1.55 ui-monospace,SFMono-Regular,Menlo,monospace;
  color: #dedee5;
  background: #101014;
}

.status {
  padding: 30px;
  text-align: center;
  color: var(--muted);
}

@media (max-width:700px) {
  .library-grid {
    grid-template-columns: 1fr;
  }
  .hero {
    grid-template-columns: 100px 1fr;
    gap: 16px;
  }
  .hero-cover {
    width: 100px;
    height: 100px;
    border-radius: 20px;
    font-size: 38px;
  }
  .details-grid {
    grid-template-columns: 120px 1fr;
  }
}

@media (max-width:600px) {
  header {
    padding: 0 9px;
  }
  .subtitle {
    display: none;
  }
  .provider {
    display: none;
  }
  main {
    padding: 16px 9px;
  }
  .msg {
    max-width: 92%;
  }
  .tags {
    display: none;
  }
  .composer-wrap {
    padding-left: 8px;
    padding-right: 8px;
  }
  .composer textarea {
    font-size: 17px;
    max-height: 42vh;
  }
  .nav button {
    padding: 7px 9px;
  }
  .chat-songs-nav span {
    display: none;
  }
  .lyrics {
    font-size: 19px;
  }
}

.generation-progress {
  display: flex;
  align-items: center;
  gap: 36px;
  align-self: stretch;
  border: 1px solid #393342;
  border-radius: 24px;
  padding: 25px 28px;
  background: radial-gradient(ellipse at 0% 0%,#382b4b88,transparent 65%),#15141b;
  min-width: 0;
}

.progress-scene {
  width: 108px;
  height: 124px;
  position: relative;
  flex: none;
}

.music-buddy {
  position: absolute;
  left: 19px;
  top: 36px;
  width: 72px;
  height: 66px;
  animation: ponder 3s ease-in-out infinite;
  transform-origin: 50% 80%;
}

.buddy-face {
  position: absolute;
  inset: 5px 5px 0;
  border-radius: 27px 27px 23px 23px;
  background: linear-gradient(135deg,#f0d7bd,#cbb3fa);
  box-shadow: inset -6px -5px 0 #6d539524,0 0 28px #b58bff26;
  display: flex;
  gap: 18px;
  justify-content: center;
  padding-top: 24px;
}

.eye {
  width: 5px;
  height: 8px;
  border-radius: 4px;
  background: #382943;
  animation: blink 5s infinite;
}

.smile {
  position: absolute;
  top: 38px;
  left: 27px;
  width: 10px;
  height: 6px;
  border-bottom: 2px solid #614875;
  border-radius: 50%;
}

.headphones {
  position: absolute;
  z-index: 2;
  inset: 0 -2px 15px;
  border: 5px solid #9478ba;
  border-bottom: 0;
  border-radius: 35px 35px 0 0;
}

.headphones:before,
.headphones:after {
  content: "";
  position: absolute;
  top: 28px;
  width: 12px;
  height: 23px;
  border-radius: 6px;
  background: #685277;
  border: 2px solid #ad94cd;
}

.headphones:before {
  left: -8px;
}

.headphones:after {
  right: -8px;
}

.buddy-shadow {
  position: absolute;
  left: 28px;
  bottom: 8px;
  width: 56px;
  height: 7px;
  background: #07050c88;
  filter: blur(3px);
}

.thought {
  position: absolute;
  color: #dfc4ff;
  animation: thought-drift 3s ease-in-out infinite;
}

.thought-one {
  left: 8px;
  top: 22px;
  font-size: 19px;
}

.thought-two {
  left: 61px;
  top: 2px;
  font-size: 17px;
  animation-delay: -1s;
}

.thought-three {
  right: 0;
  top: 22px;
  font-size: 22px;
  animation-delay: -2s;
}

.progress-content {
  min-width: 0;
  flex: 1;
}

.progress-eyebrow {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .16em;
  color: #b5a0cc;
  margin-bottom: 9px;
}

.progress-title {
  display: block;
  font-size: 19px;
  line-height: 1.3;
  color: #f5edff;
  letter-spacing: -.025em;
}

.progress-description {
  font-size: 13px;
  line-height: 1.55;
  color: #b4aebf;
  margin: 7px 0 15px;
}

.progress-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.progress-steps {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 10px;
  color: #88818f;
}

.progress-steps>span {
  border: 1px solid #39333f;
  border-radius: 20px;
  padding: 5px 9px;
}

.progress-steps .active {
  border-color: #a88ac7;
  color: #e6d1ff;
  background: #b58cff14;
}

.progress-steps .complete {
  color: #b7d5bf;
  border-color: #405549;
}

.progress-steps .complete:before {
  content: "✓ ";
}

.progress-steps .skipped {
  opacity: .6;
}

.progress-times {
  display: flex;
  gap: 13px;
  margin-left: auto;
  color: #a39aa9;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.progress-times b {
  color: #eee3f5;
  font-weight: 500;
  margin-left: 3px;
}

.composer button:disabled {
  opacity: .4;
  cursor: wait;
}

[data-stage=music] .music-buddy {
  animation: groove .85s ease-in-out infinite;
}

[data-stage=music] .thought {
  animation: note-dance 1.7s ease-out infinite;
}

[data-stage=music] .thought-two {
  animation-delay: -.6s;
}

[data-stage=music] .thought-three {
  animation-delay: -1.2s;
}

[data-stage=done] .music-buddy,
[data-stage=error] .music-buddy,
[data-stage=done] .eye,
[data-stage=error] .eye {
  animation: none;
}

[data-stage=done] .thought,
[data-stage=error] .thought {
  animation: none;
  opacity: .45;
}

[data-stage=done] {
  border-color: #354d3f;
}

[data-stage=error] {
  border-color: #6e474c;
}

[data-stage=error] .progress-title {
  color: #efb6b9;
}

@keyframes ponder {
  0%,
  100% {
    transform: translateY(0) rotate(-7deg);
  }
  50% {
    transform: translateY(-5px) rotate(5deg);
  }
}

@keyframes blink {
  0%,
  43%,
  47%,
  100% {
    transform: scaleY(1);
  }
  45% {
    transform: scaleY(.12);
  }
}

@keyframes thought-drift {
  0%,
  100% {
    transform: translateY(2px);
    opacity: .35;
  }
  50% {
    transform: translateY(-4px);
    opacity: 1;
  }
}

@keyframes groove {
  0%,
  100% {
    transform: translateY(0) rotate(-8deg);
  }
  50% {
    transform: translateY(-7px) rotate(8deg);
  }
}

@keyframes note-dance {
  0% {
    transform: translateY(9px) rotate(-12deg);
    opacity: 0;
  }
  45% {
    opacity: 1;
  }
  100% {
    transform: translateY(-15px) rotate(12deg);
    opacity: 0;
  }
}

@media (max-width:600px) {
  .generation-progress {
    gap: 20px;
    padding: 18px 14px;
  }
  .progress-scene {
    width: 72px;
    transform: scale(.78);
    transform-origin: center;
    margin-left: -10px;
    margin-right: -4px;
  }
  .progress-title {
    font-size: 17px;
  }
  .progress-eyebrow {
    font-size: 8px;
    letter-spacing: .1em;
  }
  .progress-meta {
    align-items: flex-start;
    gap: 7px;
  }
  .progress-steps {
    gap: 5px;
  }
  .progress-times {
    gap: 7px;
    font-size: 8px;
  }
  .progress-steps>span {
    padding: 5px 7px;
  }
}

@media (prefers-reduced-motion:reduce) {
  .generation-progress * {
    animation: none !important;
  }
}

/* Song cards and sticky player */

.track {
  overflow: hidden;
  transition: border-color .25s,box-shadow .25s,background .25s;
}

.track.expanded {
  border-color: #554766;
  box-shadow: 0 18px 55px #0005;
  background: radial-gradient(circle at 0 0,#32273e66,transparent 48%),linear-gradient(#19181f,#101014);
}

.track-top {
  position: relative;
}

.track-top .like {
  flex: none;
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
  box-shadow: none;
}

.track-top .like:hover {
  border: 0;
  background: transparent;
  transform: scale(1.08);
}

.track-top .share-toggle,
.track-top .menu-toggle {
  flex: none;
  width: 32px;
  height: 32px;
}

.chat-card .player,
.chat-card .lyrics-panel,
.chat-card .tags {
  display: none !important;
}

.chat-card {
  padding: 14px 16px;
}

.chat-card .track-top {
  align-items: center;
}

.track-top .track-open strong {
  font-size: 14px;
  line-height: 1.18;
}

.track-top .track-open .muted {
  font-size: 10px;
  line-height: 1.25;
  margin-top: 2px;
}

.chat-card .cover {
  width: 54px;
  height: 54px;
}

.chat-card.expanded {
  border-color: #554766;
}

.has-card-menu .commands-panel.open,
.chat-card .share-panel.open {
  display: block;
}

.cover {
  box-shadow: inset 0 0 0 1px #fff1,0 8px 24px #0004;
}

.playback-scroll-space {
  height: 0;
  flex: none;
  pointer-events: none;
}

.player {
  margin-top: 9px;
}

.transport {
  display: grid;
  grid-template-columns: minmax(172px,2fr) auto minmax(96px,1fr) 40px;
  gap: 8px;
  align-items: center;
}

.icon-btn {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid #35343c;
  background: #202026;
  color: #f8f7fb;
  cursor: pointer;
  transition: transform .18s,background .18s,border-color .18s;
}

.icon-btn:hover {
  transform: translateY(-1px);
  background: #292831;
  border-color: #4b4754;
}

.icon-btn:focus-visible,
.timeline-play:focus-visible,
.command:focus-visible,
.share-target:focus-visible,
.timeline:focus-visible {
  outline: 2px solid #c8a8f0;
  outline-offset: 2px;
}

.icon-btn svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.timeline-box {
  position: relative;
  min-width: 0;
  height: 40px;
  display: flex;
  align-items: center;
}

.timeline {
  --played: 0%;
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 40px;
  margin: 0;
  appearance: none;
  background: transparent;
  cursor: pointer;
}

.timeline-play {
  position: absolute;
  left: 0;
  top: 4px;
  z-index: 2;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 2px solid #f7efff;
  border-radius: 50%;
  background: linear-gradient(145deg,#f7efff,#bfa2e5);
  color: #201728;
  box-shadow: 0 5px 18px #b38dde55;
  cursor: grab;
  touch-action: none;
  transition: background .18s,box-shadow .18s;
}

.timeline-play:hover {
  background: linear-gradient(145deg,#fff,#cbb0eb);
  box-shadow: 0 6px 22px #c39bed77;
}

.timeline-play.dragging {
  cursor: grabbing;
  box-shadow: 0 4px 24px #d4b0ff99;
}

.timeline-play svg {
  width: 12px;
  height: 12px;
  fill: currentColor;
  stroke: none;
  pointer-events: none;
}

.timeline::-webkit-slider-runnable-track {
  height: 7px;
  border-radius: 99px;
  background: linear-gradient(90deg,#d7b8fb 0 var(--played),#3a3841 var(--played) 100%);
  box-shadow: inset 0 1px 2px #0007;
}

.timeline::-moz-range-track {
  height: 7px;
  border-radius: 99px;
  background: linear-gradient(90deg,#d7b8fb 0 var(--played),#3a3841 var(--played) 100%);
}

.timeline::-webkit-slider-thumb {
  appearance: none;
  width: 32px;
  height: 32px;
  margin-top: -12.5px;
  border: 0;
  background: transparent;
}

.timeline::-moz-range-thumb {
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
}

.time-readout {
  min-height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  border: 1px solid #35333c;
  border-radius: 9px;
  background: linear-gradient(#1e1d23,#151419);
  box-shadow: inset 0 1px 0 #ffffff0a,0 4px 12px #0003;
  color: #aaa4b1;
  font: 10px/1 ui-monospace,SFMono-Regular,Menlo,monospace;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.stereo-meter {
  width: 100%;
  min-width: 0;
  display: grid;
  grid-template-columns: 10px 1fr;
  gap: 3px 5px;
  align-items: center;
  color: #77727f;
  font: 8px/1 ui-monospace,monospace;
  letter-spacing: .05em;
}

.meter-track {
  height: 7px;
  border-radius: 9px;
  overflow: hidden;
  background: repeating-linear-gradient(90deg,#28272d 0 4px,transparent 4px 6px);
}

.meter-level {
  width: var(--level,2%);
  height: 100%;
  border-radius: inherit;
  background: repeating-linear-gradient(90deg,#8ee0ba 0 4px,transparent 4px 6px);
  filter: drop-shadow(0 0 4px #7bdcaf66);
  transition: width 70ms linear;
}

.meter-track.right .meter-level {
  background: repeating-linear-gradient(90deg,#d5b3fb 0 4px,transparent 4px 6px);
  filter: drop-shadow(0 0 4px #bd8df866);
}

.icon-btn.active {
  background: #dac0f3;
  color: #24192c;
  border-color: #ead9fb;
}

.like.liked {
  color: #c81450;
  background: transparent;
  border: 0;
}

.like.liked svg {
  fill: #c81450;
  stroke: #ff729e;
  stroke-width: 1.25;
  filter: drop-shadow(0 0 3px #ff477d99) drop-shadow(0 5px 8px #70052788);
  transform: scale(1.08);
}

.panel {
  display: none;
  margin-top: 13px;
  padding-top: 14px;
  border-top: 1px solid #302e36;
}

.panel.open {
  display: block;
  animation: panel-in .22s ease-out;
}

.panel-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.panel-heading strong {
  font-size: 13px;
}

.panel-heading span {
  font-size: 10px;
  color: #817c87;
}

.player-lyrics {
  height: min(340px,42vh);
  overflow: auto;
  padding: 118px 7px 118px 2px;
  color: #e9e5ed;
  font-size: 17px;
  line-height: 1.7;
  white-space: pre-wrap;
  perspective: 620px;
  scrollbar-width: none;
  overscroll-behavior: contain;
}

.player-lyrics::-webkit-scrollbar {
  display: none;
}

.player-lyrics .section {
  margin: 0 0 25px;
}

.player-lyrics .section:last-child {
  margin-bottom: 4px;
}

.player-lyrics .section-name {
  font-size: 9px;
  line-height: 1.4;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: #9b8ba9;
  margin-bottom: 6px;
  opacity: .35;
  transition: color 2.4s cubic-bezier(.4,0,.2,1),opacity 2.4s cubic-bezier(.4,0,.2,1);
}

.lyrics-follow-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: #baa6ca !important;
}

.lyrics-follow-status:before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #c9a7ef;
  box-shadow: 0 0 0 0 #c9a7ef66;
  animation: lyric-pulse 1.8s ease-out infinite;
}

.player-lyrics.lyrics-following {
  scroll-behavior: smooth;
  mask-image: linear-gradient(transparent,#000 16%,#000 84%,transparent);
}

.player-lyrics .lyric-line {
  display: block;
  padding: 3px 10px;
  border-left: 2px solid transparent;
  color: #807986;
  opacity: .08;
  font-size: 1em;
  transform-origin: left center;
  transform: translateY(12px) rotateX(-14deg) scale(.93);
  filter: blur(1px);
  transition: color 2.4s cubic-bezier(.4,0,.2,1),opacity 2.4s cubic-bezier(.4,0,.2,1),border-color 2.4s cubic-bezier(.4,0,.2,1),text-shadow 2.4s cubic-bezier(.4,0,.2,1),font-size 2.4s cubic-bezier(.4,0,.2,1),transform 2.4s cubic-bezier(.4,0,.2,1),filter 2.4s cubic-bezier(.4,0,.2,1);
}

.player-lyrics .lyric-line.lyric-past {
  transform: translateY(-12px) rotateX(14deg) scale(.93);
}

.player-lyrics .lyric-line.lyric-previous {
  color: #aaa2b0;
  opacity: .38;
  transform: translateY(-4px) rotateX(6deg) scale(.97);
  filter: blur(.2px);
}

.player-lyrics .lyric-line.lyric-next {
  color: #aaa2b0;
  opacity: .34;
  transform: translateY(4px) rotateX(-6deg) scale(.97);
  filter: blur(.2px);
}

.player-lyrics .lyric-line.active {
  color: #fff;
  opacity: 1;
  font-size: 1.25em;
  border-left-color: #caa7f2;
  text-shadow: 0 0 18px #c79bf655;
  transform: translateY(0) rotateX(0) scale(1);
  filter: none;
}

.player-lyrics .active-section .section-name {
  color: #c7aedf;
  opacity: 1;
}

.player-lyrics .lyric-gap,
.lyrics .lyric-gap {
  display: block;
  height: .7em;
}

.lyrics .lyric-line {
  display: block;
}

@keyframes lyric-pulse {
  70% {
    box-shadow: 0 0 0 7px #c9a7ef00;
  }
  100% {
    box-shadow: 0 0 0 0 #c9a7ef00;
  }
}

.share-grid {
  display: grid;
  grid-template-columns: repeat(7,minmax(66px,1fr));
  gap: 10px;
  overflow-x: auto;
  padding: 2px 1px 7px;
}

.share-target {
  min-width: 66px;
  border: 0;
  background: transparent;
  color: #c9c5cf;
  cursor: pointer;
  display: grid;
  justify-items: center;
  gap: 7px;
  font-size: 9px;
}

.share-bubble {
  width: 45px;
  height: 45px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #26242b;
  border: 1px solid #3b3842;
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  box-shadow: 0 7px 19px #0004;
  transition: transform .18s,filter .18s;
}

.share-bubble svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
}

.share-target:hover .share-bubble {
  transform: translateY(-2px);
  filter: brightness(1.15);
}

.share-bubble.copy {
  background: #655177;
}

.share-bubble.device {
  background: #ecebf0;
  color: #222;
}

.share-bubble.whatsapp {
  background: #25d366;
}

.share-bubble.telegram {
  background: #229ed9;
}

.share-bubble.facebook {
  background: #1877f2;
}

.share-bubble.x {
  background: #09090a;
}

.share-bubble.email {
  background: #b76d43;
}

.commands {
  display: flex;
  gap: 9px;
  overflow-x: auto;
  padding: 2px 1px 6px;
}

.command {
  min-width: max-content;
  border: 1px solid #383640;
  border-radius: 13px;
  background: #201f25;
  color: #eeebf1;
  padding: 11px 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}

.command:hover {
  background: #29272f;
  border-color: #514b5b;
}

.command:disabled {
  opacity: .45;
  cursor: not-allowed;
}

.command svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
}

.tray-status {
  min-height: 16px;
  margin-top: 8px;
  color: #a69eab;
  font-size: 11px;
}

.tags {
  margin-top: 10px;
}

@keyframes panel-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Song deletion */

.commands .command,
.delete-confirm button {
  height: 32px;
  padding: 0 11px;
  font: 700 10px/1 Inter,system-ui,sans-serif;
}

.command.delete-song {
  margin-left: auto;
  border-color: #7d263c;
  background: linear-gradient(145deg,#6e1830,#3d111e);
  color: #ffdce5;
}

.command.delete-song:hover {
  border-color: #e44d72;
  background: linear-gradient(145deg,#8b1d3b,#501326);
}

.delete-confirm {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 10px;
  padding: 10px 11px;
  border: 1px solid #68263a;
  border-radius: 13px;
  background: #2b1119;
  color: #f4dfe5;
  font-size: 11px;
}

.delete-confirm[hidden] {
  display: none;
}

.delete-confirm span {
  min-width: 0;
  flex: 1;
}

.delete-confirm button {
  flex: none;
  border-radius: 10px;
  cursor: pointer;
}

.delete-cancel {
  border: 1px solid #4e4248;
  background: #221f23;
  color: #ddd;
}

.delete-now {
  border: 1px solid #ef557a;
  background: #b20e3f;
  color: #fff;
}

.track.deleting {
  opacity: .52;
  pointer-events: none;
}

.track.deleted {
  opacity: 0;
  transform: scale(.97);
  transition: opacity .28s,transform .28s;
}

/* Director expressions */

.affinity-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
  flex: none;
}

.more-like {
  width: 0;
  height: 32px;
  display: grid;
  place-items: center;
  overflow: hidden;
  opacity: 0;
  transform: translateX(12px) scale(.72);
  padding: 0;
  border: 0 solid #773149;
  border-radius: 999px;
  background: radial-gradient(circle at 35% 30%,#4b2937,#20151c 72%);
  cursor: pointer;
  pointer-events: none;
  transition: width .62s cubic-bezier(.16,1,.3,1),border-width .2s,opacity .32s ease,transform .62s cubic-bezier(.16,1,.3,1),filter .2s,box-shadow .2s;
}

.more-like.visible {
  width: 42px;
  border-width: 1px;
  opacity: 1;
  transform: none;
  pointer-events: auto;
  box-shadow: inset 0 1px 0 #ffffff12,0 6px 18px #5b092b40;
  animation: more-like-reveal .78s cubic-bezier(.16,1,.3,1);
}

.more-like:hover {
  filter: brightness(1.2);
  transform: translateY(-1px) scale(1.04);
}

.more-like:focus-visible {
  outline: 2px solid #f0a8c3;
  outline-offset: 2px;
}

.more-like svg {
  width: 28px;
  height: 19px;
  overflow: visible;
}

.more-like .more-like-source {
  fill: #c60d48;
  stroke: #ff759f;
  stroke-width: 1.35;
  filter: drop-shadow(0 2px 3px #6b082b);
}

.more-like .more-like-next {
  fill: #21151b;
  stroke: #f5dbe4;
  stroke-width: 1.65;
}

.more-like .more-like-plus {
  fill: none;
  stroke: #fff;
  stroke-width: 2;
  stroke-linecap: round;
}

.like.liked {
  color: #bb0e42 !important;
}

.like.liked svg {
  fill: #b7083d !important;
  stroke: #e51e5b !important;
  stroke-width: 1.55 !important;
  filter: drop-shadow(0 0 4px #ff285fbb) drop-shadow(0 6px 9px #710528aa) !important;
  transform: scale(1.1) !important;
}

@keyframes more-like-reveal {
  0% {
    transform: translateX(12px) scale(.68);
  }
  62% {
    transform: translateX(-2px) scale(1.08);
  }
  100% {
    transform: none;
  }
}

.buddy-face {
  transform-origin: 50% 70%;
  transition: transform .55s ease,background .45s;
}

.eye {
  position: relative;
  overflow: visible;
  transition: transform .35s,height .25s;
}

.eye:after {
  content: "";
  position: absolute;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: #f8eefe;
  left: 1px;
  top: 1px;
  transition: transform .35s;
}

.brow {
  position: absolute;
  top: 18px;
  width: 12px;
  height: 4px;
  border-top: 2px solid #6b4d78;
  border-radius: 50%;
  opacity: .6;
  transition: transform .35s;
}

.brow-left {
  left: 13px;
}

.brow-right {
  right: 13px;
}

.cheek {
  position: absolute;
  top: 36px;
  width: 9px;
  height: 5px;
  border-radius: 50%;
  background: #d88caa55;
  opacity: 0;
  transition: opacity .35s;
}

.cheek-left {
  left: 9px;
}

.cheek-right {
  right: 9px;
}

[data-stage=connecting] .music-buddy {
  animation: peek 2.3s ease-in-out infinite;
}

[data-stage=connecting] .buddy-face {
  transform: rotate(-6deg) translateX(-2px);
}

[data-stage=director] .music-buddy {
  animation: listen 2.7s ease-in-out infinite;
}

[data-stage=director] .buddy-face {
  transform: rotate(7deg) translateX(3px);
}

[data-stage=director] .eye {
  transform: translateX(2px);
}

[data-stage=director] .eye:after {
  transform: translateX(1px);
}

[data-stage=director] .brow-right {
  transform: rotate(8deg);
}

[data-stage=music] .smile {
  width: 13px;
  left: 25px;
}

[data-stage=saving] .music-buddy {
  animation: nod 1.2s ease-in-out infinite;
}

[data-stage=saving] .eye {
  height: 4px;
  border-radius: 0 0 5px 5px;
}

[data-stage=saving] .smile {
  transform: rotate(-4deg);
}

[data-mood=patient] .music-buddy {
  animation-duration: 4.2s;
}

[data-mood=patient] .buddy-face {
  transform: rotate(-2deg);
}

[data-mood=focus] .eye {
  height: 6px;
  transform: translateX(2px);
}

[data-mood=focus] .brow {
  opacity: 1;
}

[data-mood=deep] .music-buddy {
  animation: deep-thought 3.6s ease-in-out infinite;
}

[data-mood=deep] .brow-left {
  transform: rotate(-8deg);
}

[data-mood=deep] .brow-right {
  transform: rotate(8deg);
}

[data-mood=groove] .music-buddy {
  animation: groove .72s ease-in-out infinite;
}

[data-stage=done] .buddy-face {
  transform: translateY(-2px);
}

[data-stage=done] .eye {
  height: 5px;
  border-radius: 0 0 6px 6px;
}

[data-stage=done] .smile {
  width: 17px;
  height: 9px;
  left: 23px;
  top: 36px;
  border-width: 3px;
}

[data-stage=done] .cheek {
  opacity: 1;
}

[data-stage=done] .thought-one {
  opacity: 1 !important;
  color: #a8e3b8;
}

[data-stage=done] .thought-one:after {
  content: "✓";
  font-size: 17px;
}

[data-stage=done] .thought-one {
  font-size: 0;
}

[data-stage=error] .brow-left {
  transform: rotate(14deg);
}

[data-stage=error] .brow-right {
  transform: rotate(-14deg);
}

[data-stage=error] .smile {
  top: 42px;
  border-bottom: 0;
  border-top: 2px solid #754f66;
}

@keyframes peek {
  0%,
  100% {
    transform: translateY(1px) rotate(-5deg);
  }
  50% {
    transform: translateY(-4px) rotate(2deg);
  }
}

@keyframes listen {
  0%,
  100% {
    transform: translateX(0) rotate(1deg);
  }
  50% {
    transform: translateX(4px) rotate(5deg);
  }
}

@keyframes nod {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(3px) rotate(2deg);
  }
}

@keyframes deep-thought {
  0%,
  100% {
    transform: translateY(1px) rotate(-2deg);
  }
  50% {
    transform: translateY(-2px) rotate(1deg);
  }
}

@media (max-width:600px) {
  .transport {
    grid-template-columns: minmax(82px,2fr) auto minmax(38px,1fr) 32px;
    gap: 5px;
  }
  .stereo-meter {
    grid-template-columns: 8px 1fr;
    gap: 3px;
  }
  .time-readout {
    font-size: 8px;
  }
  .share-grid {
    grid-template-columns: repeat(7,66px);
  }
  .player-lyrics {
    font-size: 16px;
  }
  .track {
    padding: 12px;
  }
  .icon-btn {
    width: 36px;
    height: 36px;
  }
  .track-top .like,
  .track-top .share-toggle,
  .track-top .menu-toggle {
    width: 32px;
    height: 32px;
  }
  .chat-card {
    padding: 11px;
  }
  .chat-card .cover {
    width: 54px;
    height: 54px;
  }
  .chat-card .affinity-actions,
  .track.global-full-card .affinity-actions {
    gap: 3px;
  }
}

@media (prefers-reduced-motion:reduce) {
  .panel.open,
  .more-like.visible {
    animation: none;
  }
  .more-like {
    transition: none;
  }
  .meter-level,
  .player-lyrics .lyric-line {
    transition: none;
  }
  .player-lyrics.lyrics-following {
    scroll-behavior: auto;
  }
  .lyrics-follow-status:before {
    animation: none;
  }
}

.player-lyrics {
  --lyric-slot-height: 64px;
  position: relative;
  height: calc(var(--lyric-slot-height)*5);
  overflow: hidden;
  padding: 0 7px 0 2px;
  perspective: none;
  scroll-behavior: auto;
  mask-image: none !important;
}

.player-lyrics.lyrics-following {
  scroll-behavior: auto;
}

.player-lyrics .section {
  position: relative;
  margin: 0;
}

.player-lyrics .section:last-child {
  margin-bottom: 0;
}

.player-lyrics:after {
  content: "";
  display: block;
  height: calc(var(--lyric-slot-height)*5);
  pointer-events: none;
}

.player-lyrics .section-name {
  display: none;
}

.lyrics-panel-heading {
  justify-content: flex-end;
  margin-bottom: 8px;
}

.lyrics-section-sticky {
  position: sticky;
  z-index: 3;
  top: 5px;
  display: block;
  width: max-content;
  height: 22px;
  margin: 0 3px -22px auto;
  padding: 4px 8px;
  border: 1px solid #4b4059;
  border-radius: 999px;
  background: #211c2aeb;
  color: #d8c2ed;
  font: 600 8px/1.4 Inter,system-ui,sans-serif;
  letter-spacing: .14em;
  text-align: right;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 5px 16px #0005;
  transition: background .2s,border-color .2s,color .2s,opacity .9s ease,transform 1.2s cubic-bezier(.22,1,.36,1);
}

.player-lyrics.lyrics-outro .lyrics-section-sticky {
  opacity: 0;
  transform: translateY(-10px);
  pointer-events: none;
}

.lyrics-section-sticky:hover {
  background: #30263c;
  border-color: #715b86;
  color: #f0e4fb;
}

.lyrics-section-sticky:focus-visible {
  outline: 2px solid #c8a8f0;
  outline-offset: 2px;
}

.lyrics-section-sticky:empty {
  display: none;
}

.player-lyrics .lyric-line {
  position: relative;
  z-index: 1;
  box-sizing: border-box;
  display: flex;
  height: var(--lyric-slot-height);
  min-height: var(--lyric-slot-height);
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  overflow: hidden;
  padding: 6px 10px;
  line-height: 1.18;
  transform: translateY(8px) scale(.95);
  filter: blur(.7px);
  transition: color 1.8s cubic-bezier(.22,1,.36,1),opacity 1.8s cubic-bezier(.22,1,.36,1),border-color 1.8s cubic-bezier(.22,1,.36,1),text-shadow 1.8s cubic-bezier(.22,1,.36,1),font-size 1.8s cubic-bezier(.22,1,.36,1),transform 1.8s cubic-bezier(.22,1,.36,1),filter 1.8s cubic-bezier(.22,1,.36,1);
}

.player-lyrics .lyric-line.lyric-past,
.player-lyrics .lyric-line.lyric-future {
  opacity: 0;
  transform: translateY(-6px) scale(.96);
  filter: blur(.5px);
}

.player-lyrics .lyric-line.lyric-future {
  transform: translateY(6px) scale(.96);
}

.player-lyrics .lyric-line.lyric-previous-two,
.player-lyrics .lyric-line.lyric-next-two {
  color: #938b99;
  opacity: .42;
  transform: translateY(0) scale(.96);
  filter: blur(.25px);
}

.player-lyrics .lyric-line.lyric-previous,
.player-lyrics .lyric-line.lyric-next {
  color: #bbb3c1;
  opacity: .68;
  transform: translateY(0) scale(.98);
  filter: none;
}

.player-lyrics .lyric-line.lyric-arriving {
  color: #bbb3c1;
  opacity: .68;
  transform: translateY(0) scale(.98);
  filter: none;
}

.player-lyrics .lyric-line.active {
  transform: translateY(0) scale(1);
  filter: none;
}

.lyric-original,
.lyric-translation {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lyric-translation {
  margin-top: 3px;
  color: #93879e;
  font-size: .64em;
  font-style: italic;
  line-height: 1.15;
  text-shadow: none;
}

.player-lyrics .lyric-line.active .lyric-translation {
  color: #cfbadf;
  opacity: .92;
}

.lyrics .lyric-line {
  margin-bottom: .55em;
}

.lyrics .lyric-translation {
  white-space: normal;
  color: #9e93a6;
  font-size: .68em;
  line-height: 1.35;
}

.player-lyrics .lyric-gap {
  display: none;
  height: 0;
}

@media (max-width:600px) {
  .player-lyrics {
    --lyric-slot-height: 62px;
  }
  .lyrics-section-sticky {
    padding-right: 1px;
  }
}

.brand-logo {
  width: 174px;
  height: 48px;
  flex: none;
  overflow: hidden;
  padding: 0;
  border: 0;
  background: #0c0c10;
  border-radius: 11px;
  cursor: pointer;
}

.brand-logo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

@media (max-width:600px) {
  .brand-logo {
    width: 138px;
    height: 42px;
  }
}

/* Song artwork: MusiCat can lean beyond the cover and perform on hover/playback. */

.track {
  overflow: visible;
}

.cover,
.library-cover,
.hero-cover {
  position: relative;
  isolation: isolate;
  overflow: visible;
  background: transparent;
  box-shadow: none;
}

.cover:before,
.library-cover:before,
.hero-cover:before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  background: radial-gradient(circle at 50% 35%,#423450,#17131e 72%);
  box-shadow: inset 0 0 0 1px #fff1,0 8px 24px #0004;
  opacity: 1;
  transform: scale(1);
  transition: opacity .72s ease,transform .82s cubic-bezier(.16,1,.3,1),box-shadow .72s ease;
}

.cover:is(:hover,
:focus-visible),
.track.is-playing .cover,
.library-cover:hover,
.hero-cover:is(:hover,
.is-playing) {
  z-index: 3;
}

.cover:is(:hover,
:focus-visible):before,
.track.is-playing .cover:before,
.library-cover:is(:hover,
:focus-visible):before,
.hero-cover:is(:hover,
.is-playing):before {
  opacity: .16;
  transform: scale(.86);
  box-shadow: inset 0 0 0 1px #fff0,0 4px 14px #0002;
}

.musicat-art {
  position: relative;
  z-index: 1;
  display: block;
  width: 98%;
  height: 98%;
  overflow: visible;
  opacity: 1;
  filter: drop-shadow(0 5px 7px #09060d88);
  transform-origin: 50% 72%;
  transition: transform .92s cubic-bezier(.16,1,.3,1),filter .78s ease,opacity .52s ease;
  will-change: transform;
}

.library-cover .musicat-art {
  width: 96%;
  height: 96%;
}

.hero-cover .musicat-art {
  width: 90%;
  height: 90%;
  filter: drop-shadow(0 16px 20px #09060daa);
}

.musicat-stage,
.musicat-character,
.musicat-note,
.musicat-ears,
.musicat-earcup,
.musicat-eye-open,
.musicat-eye-closed,
.musicat-pupils,
.musicat-mouth,
.musicat-mouth-open,
.musicat-mic,
.musicat-hand,
.musicat-effect {
  transform-box: fill-box;
  transform-origin: center;
}

.musicat-stage,
.musicat-character {
  will-change: transform;
}

.musicat-eye-open {
  animation: musicat-blink 5.1s ease-in-out infinite;
}

.musicat-pupils {
  animation: musicat-look 5.1s ease-in-out infinite;
}

.musicat-eye-closed,
.musicat-mouth-open,
.musicat-mic,
.musicat-hand,
.musicat-effect {
  opacity: 0;
}

.musicat-eye-open,
.musicat-eye-closed,
.musicat-mouth,
.musicat-hand,
.musicat-effect {
  transition: opacity .32s ease,transform .62s cubic-bezier(.22,1,.36,1);
}

.musicat-mouth-open {
  transition: opacity 70ms linear,transform 90ms ease-out;
}

.musicat-mic {
  transform: translate(7px,12px) rotate(8deg) scale(.72);
  transform-origin: 80px 78px;
  transition: opacity .28s ease,transform .46s cubic-bezier(.22,1,.36,1);
}

.musicat-hand-left {
  transform: translate(-5px,13px) scale(.68);
}

.musicat-hand-right {
  transform: translate(5px,13px) scale(.68);
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-art {
  transform: translateY(-12px) scale(1.42);
  filter: drop-shadow(0 15px 13px #09060ddd) drop-shadow(0 0 12px #b68ee266);
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-stage {
  animation: musicat-stage-curious 5.4s ease-in-out .92s infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-character {
  animation: musicat-curious-head 5.4s ease-in-out infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-pupils {
  animation: musicat-curious-look 5.4s ease-in-out infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-eye-open {
  animation: musicat-curious-open-eyes 5.4s ease-in-out infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-eye-closed {
  animation: musicat-curious-closed-eyes 5.4s ease-in-out infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-ears {
  animation: musicat-curious-ears 5.4s ease-in-out infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-note {
  animation: musicat-curious-note 5.4s ease-in-out infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-hand-left {
  animation: musicat-curious-wave 5.4s ease-in-out infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-hand-right {
  animation: musicat-curious-listen 5.4s ease-in-out infinite;
}

:is(.track:not(.is-playing) .cover:is(:hover,
:focus-visible),
.library-cover:is(:hover,
:focus-visible),
.hero-cover:not(.is-playing):hover) .musicat-effect {
  animation: musicat-curious-waveform 5.4s ease-in-out infinite;
}

.track.is-playing .cover .musicat-art,
.hero-cover.is-playing .musicat-art {
  transform: translateY(var(--musicat-lift,4px)) rotate(var(--musicat-lean,0deg)) scale(var(--musicat-scale,1.36));
  filter: drop-shadow(0 15px 13px #09060ddd) drop-shadow(0 0 var(--musicat-glow,10px) #b68ee288);
  transition: transform 90ms linear,filter .24s ease,opacity .52s ease;
}

.track.is-playing .musicat-character,
.hero-cover.is-playing .musicat-character {
  animation: musicat-enjoy var(--musicat-groove-cycle,2.8s) ease-in-out infinite;
}

.track.is-playing .musicat-host.is-singing .musicat-character,
.hero-cover.is-playing.is-singing .musicat-character {
  animation: musicat-singer-bow calc(var(--musicat-groove-cycle,2.8s)*1.35) cubic-bezier(.45,0,.25,1) infinite;
}

.track.is-playing .musicat-hand-left,
.hero-cover.is-playing .musicat-hand-left {
  opacity: 1;
  animation: musicat-conduct-left var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.track.is-playing .musicat-hand-right,
.hero-cover.is-playing .musicat-hand-right {
  opacity: 1;
  animation: musicat-conduct-right var(--musicat-beat-cycle,1.1s) ease-in-out var(--musicat-beat-delay,-.55s) infinite;
}

.track.is-playing .musicat-host.is-singing .musicat-mic,
.hero-cover.is-playing.is-singing .musicat-mic {
  opacity: 1;
  animation: musicat-mic-sing var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.track.is-playing .musicat-host.is-singing .musicat-hand-right,
.hero-cover.is-playing.is-singing .musicat-hand-right {
  animation: musicat-hold-mic var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.musicat-host.is-singing:not(.mouth-closed) .musicat-mouth {
  opacity: 0;
  transform: scaleX(.84) translateY(-1px);
}

.musicat-host.is-singing:not(.mouth-closed) .musicat-mouth-open {
  opacity: 1;
  transform: scale(var(--musicat-mouth-x,1),var(--musicat-mouth-y,1));
}

.musicat-host.is-singing.mouth-closed .musicat-mouth {
  opacity: 1;
  transform: scaleX(.92) translateY(-1px);
}

.musicat-host.is-singing.mouth-closed .musicat-mouth-open {
  opacity: 0;
  transform: scale(.55,.25);
}

.track.is-playing .musicat-eye-open,
.hero-cover.is-playing .musicat-eye-open {
  animation: musicat-play-open-eyes var(--musicat-groove-cycle,2.8s) ease-in-out infinite;
}

.track.is-playing .musicat-eye-closed,
.hero-cover.is-playing .musicat-eye-closed {
  animation: musicat-play-closed-eyes var(--musicat-groove-cycle,2.8s) ease-in-out infinite;
}

.track.is-playing .musicat-pupils,
.hero-cover.is-playing .musicat-pupils {
  animation: musicat-play-look var(--musicat-groove-cycle,2.8s) ease-in-out infinite;
}

.track.is-playing .musicat-ears,
.hero-cover.is-playing .musicat-ears {
  animation: musicat-ear-dance var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.track.is-playing .musicat-note,
.hero-cover.is-playing .musicat-note {
  animation: musicat-note-pulse var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.track.is-playing .musicat-earcup,
.hero-cover.is-playing .musicat-earcup {
  animation: musicat-earcup-glow var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.track.is-playing .musicat-effect,
.hero-cover.is-playing .musicat-effect {
  opacity: var(--musicat-wave-opacity,.7);
  animation: musicat-listening-wave var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.track.is-playing .musicat-effect-right,
.hero-cover.is-playing .musicat-effect-right {
  animation-delay: var(--musicat-beat-delay,-.55s);
}

.track.is-playing .musicat-host.peak-turn .musicat-stage,
.hero-cover.is-playing.peak-turn .musicat-stage {
  transform-style: preserve-3d;
  animation: musicat-peak-turn 1.85s cubic-bezier(.42,0,.18,1) both;
}

@keyframes musicat-blink {
  0%,
  40%,
  44%,
  100% {
    transform: scaleY(1);
  }
  42% {
    transform: scaleY(.08);
  }
}

@keyframes musicat-look {
  0%,
  22%,
  100% {
    transform: translateX(0);
  }
  28%,
  48% {
    transform: translateX(2px);
  }
  55%,
  76% {
    transform: translateX(-1px);
  }
}

@keyframes musicat-stage-curious {
  0%,
  100% {
    transform: none;
  }
  18% {
    transform: translateY(-2px) scale(1.025);
  }
  38% {
    transform: translateX(1.5px) rotate(1.5deg);
  }
  58% {
    transform: translateY(-3px) scale(1.015);
  }
  76% {
    transform: translateY(-1px) rotate(-1deg);
  }
  90% {
    transform: none;
  }
}

@keyframes musicat-curious-head {
  0%,
  16%,
  100% {
    transform: translateY(-1px) rotate(0);
  }
  30%,
  42% {
    transform: translateX(3px) rotate(4deg);
  }
  54%,
  62% {
    transform: translateY(-3px) rotate(0);
  }
  72% {
    transform: translateY(-1px) rotate(-2deg);
  }
  82% {
    transform: translateY(-3px) rotate(2deg);
  }
}

@keyframes musicat-curious-look {
  0%,
  18%,
  90%,
  100% {
    transform: translate(0,0);
  }
  28%,
  42% {
    transform: translateX(3.5px);
  }
  52%,
  60% {
    transform: translateY(-3px);
  }
  68%,
  82% {
    transform: translate(-1px,1px);
  }
}

@keyframes musicat-curious-open-eyes {
  0%,
  58%,
  88%,
  100% {
    opacity: 1;
    transform: scaleY(1);
  }
  64%,
  82% {
    opacity: 0;
    transform: scaleY(.15);
  }
}

@keyframes musicat-curious-closed-eyes {
  0%,
  58%,
  88%,
  100% {
    opacity: 0;
  }
  64%,
  82% {
    opacity: 1;
  }
}

@keyframes musicat-curious-ears {
  0%,
  44%,
  70%,
  100% {
    transform: translateY(0) scaleY(1);
  }
  52%,
  62% {
    transform: translateY(-2px) scaleY(1.08);
  }
  76% {
    transform: rotate(-1.5deg);
  }
}

@keyframes musicat-curious-note {
  0%,
  42%,
  100% {
    transform: translateY(0) rotate(0) scale(1);
  }
  50% {
    transform: translateY(-4px) rotate(-5deg) scale(1.08);
  }
  58% {
    transform: translateY(-1px) rotate(4deg) scale(1.03);
  }
}

@keyframes musicat-curious-wave {
  0%,
  4%,
  30%,
  100% {
    opacity: 0;
    transform: translate(-5px,13px) scale(.68);
  }
  9% {
    opacity: 1;
    transform: translate(-2px,1px) rotate(-16deg) scale(.96);
  }
  15% {
    opacity: 1;
    transform: translate(1px,-2px) rotate(13deg) scale(1);
  }
  23% {
    opacity: 1;
    transform: translate(-1px,1px) rotate(-9deg) scale(.96);
  }
}

@keyframes musicat-curious-listen {
  0%,
  58%,
  88%,
  100% {
    opacity: 0;
    transform: translate(5px,13px) scale(.68);
  }
  65%,
  82% {
    opacity: 1;
    transform: translate(-2px,-2px) rotate(-12deg) scale(.94);
  }
}

@keyframes musicat-curious-waveform {
  0%,
  61%,
  88%,
  100% {
    opacity: 0;
    transform: scale(.82);
  }
  68%,
  80% {
    opacity: 1;
    transform: scale(1.05);
  }
}

@keyframes musicat-stage-groove {
  0%,
  100% {
    transform: translate(-1px,-7px) rotate(-1deg) scale(1.22);
  }
  25% {
    transform: translate(0,-10px) rotate(1.5deg) scale(1.24);
  }
  50% {
    transform: translate(1px,-7px) rotate(1deg) scale(1.22);
  }
  75% {
    transform: translate(0,-10px) rotate(-1.5deg) scale(1.24);
  }
}

@keyframes musicat-enjoy {
  0%,
  100% {
    transform: translateX(-2px) rotate(-2deg);
  }
  25% {
    transform: translateY(-2px) rotate(1deg);
  }
  50% {
    transform: translateX(2px) rotate(2deg);
  }
  75% {
    transform: translateY(-2px) rotate(-1deg);
  }
}

@keyframes musicat-play-open-eyes {
  0%,
  12%,
  78%,
  100% {
    opacity: 1;
    transform: scaleY(1);
  }
  18%,
  70% {
    opacity: 0;
    transform: scaleY(.12);
  }
}

@keyframes musicat-play-closed-eyes {
  0%,
  12%,
  78%,
  100% {
    opacity: 0;
  }
  18%,
  70% {
    opacity: 1;
  }
}

@keyframes musicat-play-look {
  0%,
  78%,
  100% {
    transform: translateX(0);
  }
  84%,
  91% {
    transform: translateX(2px);
  }
}

@keyframes musicat-singer-bow {
  0%,
  16%,
  100% {
    transform: translate(0,0) rotate(0);
  }
  42%,
  64% {
    transform: translate(4px,5px) rotate(8deg);
  }
  54% {
    transform: translate(5px,7px) rotate(10deg);
  }
  82% {
    transform: translate(1px,1px) rotate(2deg);
  }
}

@keyframes musicat-mic-sing {
  0%,
  100% {
    transform: translate(0,0) rotate(-2deg) scale(1);
  }
  42%,
  64% {
    transform: translate(1px,1px) rotate(2deg) scale(var(--musicat-accent-scale,1));
  }
  54% {
    transform: translate(2px,2px) rotate(3deg) scale(var(--musicat-accent-scale,1));
  }
}

@keyframes musicat-conduct-left {
  0%,
  100% {
    opacity: .92;
    transform: translate(-1px,2px) rotate(-9deg) scale(.94);
  }
  50% {
    opacity: 1;
    transform: translate(2px,var(--musicat-paw-lift,-5px)) rotate(11deg) scale(var(--musicat-accent-scale,1));
  }
}

@keyframes musicat-conduct-right {
  0%,
  100% {
    opacity: .92;
    transform: translate(1px,2px) rotate(9deg) scale(.94);
  }
  50% {
    opacity: 1;
    transform: translate(-2px,var(--musicat-paw-lift,-5px)) rotate(-11deg) scale(var(--musicat-accent-scale,1));
  }
}

@keyframes musicat-hold-mic {
  0%,
  100% {
    opacity: 1;
    transform: translate(-6px,10px) rotate(-3deg) scale(.86);
  }
  42%,
  64% {
    opacity: 1;
    transform: translate(-6px,10px) rotate(1deg) scale(.9);
  }
  54% {
    opacity: 1;
    transform: translate(-6px,11px) rotate(2deg) scale(var(--musicat-accent-scale,.92));
  }
}

@keyframes musicat-ear-dance {
  0%,
  100% {
    transform: translateY(0) rotate(-1deg);
  }
  50% {
    transform: translateY(-2px) rotate(1deg);
  }
}

@keyframes musicat-note-pulse {
  0%,
  100% {
    transform: translateY(0) rotate(-3deg) scale(.98);
  }
  50% {
    transform: translateY(var(--musicat-note-lift,-4px)) rotate(3deg) scale(var(--musicat-note-scale,1.09));
  }
}

@keyframes musicat-earcup-glow {
  0%,
  100% {
    filter: drop-shadow(0 0 0 #b996ef00);
  }
  50% {
    filter: drop-shadow(0 0 var(--musicat-glow,4px) #c9a5ffdd);
  }
}

@keyframes musicat-listening-wave {
  0%,
  100% {
    opacity: .2;
    transform: scale(.88);
  }
  50% {
    opacity: var(--musicat-wave-opacity,.8);
    transform: scale(var(--musicat-wave-scale,1.05));
  }
}

@keyframes musicat-peak-turn {
  0% {
    transform: translateX(0) rotateY(0) scale(1);
  }
  12% {
    transform: translateX(-3px) rotateY(-28deg) scale(1.06);
  }
  45% {
    transform: translateX(-7px) rotateY(-175deg) scale(1.11);
  }
  72% {
    transform: translateX(-3px) rotateY(-292deg) scale(1.07);
  }
  88% {
    transform: translateX(1px) rotateY(-370deg) scale(1.025);
  }
  100% {
    transform: translateX(0) rotateY(-360deg) scale(1);
  }
}

@media (prefers-reduced-motion:reduce) {
  .musicat-art,
  .musicat-stage,
  .musicat-character,
  .musicat-note,
  .musicat-ears,
  .musicat-earcup,
  .musicat-eye-open,
  .musicat-eye-closed,
  .musicat-pupils,
  .musicat-mouth,
  .musicat-mouth-open,
  .musicat-mic,
  .musicat-hand,
  .musicat-effect {
    animation: none !important;
    transition: none !important;
  }
  .track.is-playing .cover .musicat-art,
  .hero-cover.is-playing .musicat-art {
    transform: translateY(4px) scale(1.36) !important;
  }
  .track.is-playing .musicat-host.is-singing .musicat-mic,
  .hero-cover.is-playing.is-singing .musicat-mic {
    opacity: 1;
    transform: none;
  }
}

/* During a vocal break, MusiCat moves from the sleeve into the lyrics stage. */

.lyrics-scene {
  position: relative;
  height: calc(var(--lyric-slot-height,64px)*5);
  overflow: hidden;
  border-radius: 16px;
  background: radial-gradient(circle at 50% 60%,#382a4855,transparent 52%);
}

.lyrics-scene .player-lyrics {
  height: 100%;
  transition: opacity .58s ease,transform .78s cubic-bezier(.22,1,.36,1),filter .58s ease;
}

.lyrics-instrumental-stage {
  position: absolute;
  z-index: 5;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transform: scale(.82) translateY(18px);
  filter: blur(7px);
  transition: opacity .66s ease,transform .9s cubic-bezier(.16,1,.3,1),filter .66s ease;
}

.lyrics-instrumental-stage:before {
  content: "";
  position: absolute;
  inset: 12% 22%;
  border-radius: 50%;
  background: radial-gradient(circle,#c79cf02b,transparent 68%);
  filter: blur(8px);
  animation: musicat-dance-aura 2.2s ease-in-out infinite;
}

.lyrics-instrumental-label {
  position: absolute;
  right: 12px;
  bottom: 10px;
  color: #a890b8;
  font: 700 8px/1 Inter,system-ui,sans-serif;
  letter-spacing: .17em;
  text-transform: uppercase;
}

.musicat-dancer-art {
  position: relative;
  z-index: 1;
  display: block;
  width: min(218px,48%);
  height: 96%;
  overflow: visible;
  filter: drop-shadow(0 18px 18px #08050caa) drop-shadow(0 0 17px #a978d74a);
  transform-origin: 50% 88%;
}

.musicat-dancer-body,
.musicat-dancer-head,
.musicat-dancer-tail,
.musicat-dancer-arm,
.musicat-dancer-note,
.musicat-dancer-shadow {
  transform-box: fill-box;
  transform-origin: center;
}

.lyrics-panel.instrumental-dance .player-lyrics {
  opacity: 0;
  transform: scale(.96) translateY(-8px);
  filter: blur(4px);
}

.lyrics-panel.instrumental-dance .lyrics-instrumental-stage {
  opacity: 1;
  transform: scale(1) translateY(0);
  filter: none;
}

.lyrics-panel.instrumental-dance .musicat-dancer-art {
  animation: musicat-dancer-bounce var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.lyrics-panel.instrumental-dance .musicat-dancer-head {
  animation: musicat-dancer-head var(--musicat-groove-cycle,2.8s) ease-in-out infinite;
}

.lyrics-panel.instrumental-dance .musicat-dancer-tail {
  animation: musicat-dancer-tail var(--musicat-groove-cycle,2.8s) ease-in-out infinite;
}

.lyrics-panel.instrumental-dance .musicat-dancer-arm-left {
  animation: musicat-dancer-arm-left var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.lyrics-panel.instrumental-dance .musicat-dancer-arm-right {
  animation: musicat-dancer-arm-right var(--musicat-beat-cycle,1.1s) ease-in-out var(--musicat-beat-delay,-.55s) infinite;
}

.lyrics-panel.instrumental-dance .musicat-dancer-note {
  animation: musicat-dancer-note var(--musicat-groove-cycle,2.8s) ease-in-out infinite;
}

.lyrics-panel.instrumental-dance .musicat-dancer-shadow {
  animation: musicat-dancer-shadow var(--musicat-beat-cycle,1.1s) ease-in-out infinite;
}

.track.is-playing .cover.in-lyrics:before {
  opacity: 1;
  transform: scale(1);
  box-shadow: inset 0 0 0 1px #fff1,0 8px 24px #0004;
}

.track.is-playing .cover.in-lyrics .musicat-art {
  opacity: 0;
  transform: translateY(8px) rotate(0) scale(.12);
  filter: blur(5px);
  transition: opacity .42s ease,transform .72s cubic-bezier(.7,0,.84,0),filter .42s ease;
}

@keyframes musicat-dancer-bounce {
  0%,
  100% {
    transform: translateY(2px) rotate(-1deg) scale(1);
  }
  50% {
    transform: translateY(-8px) rotate(1deg) scale(1.025);
  }
}

@keyframes musicat-dancer-head {
  0%,
  100% {
    transform: rotate(-4deg) translateX(-1px);
  }
  50% {
    transform: rotate(5deg) translateX(2px);
  }
}

@keyframes musicat-dancer-tail {
  0%,
  100% {
    transform: rotate(-9deg);
  }
  50% {
    transform: rotate(16deg);
  }
}

@keyframes musicat-dancer-arm-left {
  0%,
  100% {
    transform: rotate(14deg) translateY(1px);
  }
  50% {
    transform: rotate(-24deg) translateY(-5px);
  }
}

@keyframes musicat-dancer-arm-right {
  0%,
  100% {
    transform: rotate(-14deg) translateY(1px);
  }
  50% {
    transform: rotate(24deg) translateY(-5px);
  }
}

@keyframes musicat-dancer-note {
  0%,
  100% {
    transform: translateY(2px) rotate(-5deg) scale(.96);
    opacity: .65;
  }
  50% {
    transform: translateY(-6px) rotate(5deg) scale(1.08);
    opacity: 1;
  }
}

@keyframes musicat-dancer-shadow {
  0%,
  100% {
    transform: scaleX(1);
    opacity: .34;
  }
  50% {
    transform: scaleX(.78);
    opacity: .2;
  }
}

@keyframes musicat-dance-aura {
  0%,
  100% {
    transform: scale(.9);
    opacity: .45;
  }
  50% {
    transform: scale(1.1);
    opacity: .82;
  }
}

@media (max-width:600px) {
  .lyrics-scene {
    height: calc(62px*5);
  }
  .musicat-dancer-art {
    width: min(190px,58%);
  }
}

@media (prefers-reduced-motion:reduce) {
  .lyrics-instrumental-stage,
  .lyrics-scene .player-lyrics,
  .track.is-playing .cover.in-lyrics .musicat-art {
    transition: none !important;
  }
  .musicat-dancer-art,
  .musicat-dancer-art *,
  .lyrics-instrumental-stage:before {
    animation: none !important;
  }
}

.suggestions-panel {
  max-width: 720px;
  margin: 0 auto 9px;
  min-width: 0;
}

.suggestions-panel[hidden] {
  display: none;
}

.suggestions-heading {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 4px 7px;
}

.suggestions-heading strong {
  font-size: 12px;
  letter-spacing: .03em;
}

.suggestions-heading span {
  color: var(--muted);
  font-size: 11px;
}

.suggestion-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  padding: 1px 3px 7px;
  max-width: 100%;
}

.suggestion-chip {
  --chip-hue: 280;
  flex: none;
  max-width: 100%;
  border: 1px solid hsl(var(--chip-hue) 58% 55% / .55);
  background: linear-gradient(145deg,hsl(var(--chip-hue) 54% 24% / .92),hsl(calc(var(--chip-hue) + 22) 42% 13% / .96));
  color: hsl(var(--chip-hue) 75% 89%);
  box-shadow: inset 0 1px 0 #ffffff12,0 5px 15px hsl(var(--chip-hue) 70% 12% / .28);
  border-radius: 999px;
  padding: 8px 12px;
  cursor: pointer;
  font: 600 12px/1.2 Inter,system-ui,sans-serif;
  white-space: normal;
  transition: border-color .2s,background .2s,transform .2s;
  animation: suggestion-in .32s cubic-bezier(.22,1,.36,1) both;
}

.suggestion-chip:hover {
  border-color: hsl(var(--chip-hue) 78% 72% / .9);
  filter: saturate(1.2) brightness(1.12);
  transform: translateY(-2px);
}

.suggestion-chip.step {
  background: linear-gradient(145deg,hsl(var(--chip-hue) 58% 27% / .94),hsl(calc(var(--chip-hue) + 28) 46% 14% / .98));
}

.suggestion-loading {
  color: var(--muted);
  font-size: 12px;
  padding: 7px 5px;
}

.suggestion-question {
  margin: 1px 3px 8px;
  padding: 13px;
  border: 1px solid #4a3f55;
  border-radius: 16px;
  background: radial-gradient(circle at 4% 0,#30243c,#17151c 55%);
  box-shadow: 0 12px 30px #0005;
}

.suggestion-question[hidden] {
  display: none;
}

.suggestion-question-top {
  display: flex;
  align-items: start;
  gap: 10px;
}

.suggestion-question-copy {
  min-width: 0;
  flex: 1;
}

.suggestion-kicker {
  color: #c4a5e2;
  font-size: 10px;
  font-weight: 750;
  letter-spacing: .13em;
  text-transform: uppercase;
}

.suggestion-question label {
  display: block;
  margin-top: 4px;
  font-size: 15px;
  font-weight: 650;
  color: #f4eff8;
}

.suggestion-close {
  border: 0;
  background: transparent;
  color: #aaa;
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  padding: 1px 3px;
}

.suggestion-answer-row {
  display: grid;
  grid-template-columns: minmax(0,1fr) auto;
  gap: 7px;
  margin-top: 10px;
}

.suggestion-answer {
  min-width: 0;
  border: 1px solid #403949;
  border-radius: 12px;
  background: #0f0f13;
  color: #fff;
  padding: 10px 11px;
  font: 14px/1.35 Inter,system-ui,sans-serif;
  outline: none;
}

.suggestion-answer:focus {
  border-color: #b997de;
  box-shadow: 0 0 0 3px #b997de22;
}

.suggestion-use {
  border: 0;
  border-radius: 12px;
  background: linear-gradient(135deg,#e7d3ff,#b993e7);
  color: #211629;
  padding: 0 15px;
  font-weight: 750;
  cursor: pointer;
}

.suggestion-use:disabled {
  opacity: .55;
  cursor: wait;
}

.suggestion-status {
  min-height: 16px;
  margin: 6px 2px 0;
  color: #d9a9aa;
  font-size: 11px;
}

.suggestion-status:empty {
  display: none;
}

.composer-selections {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 4px 8px 1px;
}

.composer-selections[hidden] {
  display: none;
}

.composer-selection {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  border: 1px solid #715b86;
  border-radius: 999px;
  background: linear-gradient(145deg,#382b45,#241d2d);
  color: #eddef9;
  padding: 5px 7px 5px 10px;
  font: 650 11px/1.2 Inter,system-ui,sans-serif;
  animation: suggestion-in .34s cubic-bezier(.22,1,.36,1) both;
}

.composer-selection span:first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.composer-selection .remove-selection {
  border: 0;
  background: #aa8ac433;
  color: #e9d9f8;
  width: 17px;
  height: 17px;
  margin: 0;
  border-radius: 50%;
  padding: 0;
  display: grid;
  place-items: center;
  font: 13px/1 Inter,system-ui,sans-serif;
  cursor: pointer;
}

.composer-selection .remove-selection:hover {
  background: #c4a5df55;
}

.composer.has-selections textarea {
  min-height: 40px;
  padding-top: 6px;
}

.composer.ready {
  border-color: #665277;
  box-shadow: 0 0 0 1px #b792dc22;
}

.composer-ready-note {
  display: none;
  color: #bea7d0;
  font-size: 10px;
  margin-right: auto;
}

.composer.ready .composer-ready-note {
  display: inline;
}

@keyframes suggestion-in {
  from {
    opacity: 0;
    transform: translateY(5px) scale(.96);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (max-width:600px) {
  .suggestions-heading {
    padding-left: 2px;
  }
  .suggestions-heading span {
    display: none;
  }
  .suggestion-answer-row {
    grid-template-columns: 1fr;
  }
  .suggestion-use {
    min-height: 39px;
  }
}

/* Account and settings */

.account-trigger {
  height: 36px;
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid #37343f;
  border-radius: 999px;
  background: #19181e;
  color: #eeeaf2;
  padding: 3px 10px 3px 4px;
  cursor: pointer;
  transition: border-color .2s,background .2s,transform .2s;
}

.account-trigger:hover {
  border-color: #68577b;
  background: #24212b;
  transform: translateY(-1px);
}

.account-avatar {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: linear-gradient(145deg,#eedfff,#a67ed2);
  color: #24152f;
  font-size: 11px;
  font-weight: 850;
  letter-spacing: .02em;
  box-shadow: inset 0 1px 0 #fff8;
}

.account-label {
  max-width: 92px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 700;
}

.account-backdrop {
  position: fixed;
  z-index: 50;
  inset: 0;
  background: #05040899;
  backdrop-filter: blur(4px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .28s ease;
}

.account-backdrop.open {
  opacity: 1;
  pointer-events: auto;
}

.account-panel {
  position: fixed;
  z-index: 51;
  top: 12px;
  right: 12px;
  bottom: 12px;
  width: min(430px,calc(100vw - 24px));
  display: flex;
  flex-direction: column;
  border: 1px solid #41394c;
  border-radius: 25px;
  background: radial-gradient(circle at 85% 0,#39284c88,transparent 38%),linear-gradient(165deg,#1c1a22,#100f14 75%);
  box-shadow: 0 28px 90px #000c;
  transform: translateX(calc(100% + 28px));
  opacity: .6;
  transition: transform .42s cubic-bezier(.22,1,.36,1),opacity .28s;
  overflow: hidden;
}

.account-panel.open {
  transform: none;
  opacity: 1;
}

.account-panel-top {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 22px 22px 14px;
}

.account-panel-title {
  min-width: 0;
  flex: 1;
}

.account-kicker {
  color: #bfa4da;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .17em;
}

.account-panel h2 {
  margin: 4px 0 0;
  font-size: 27px;
  letter-spacing: -.04em;
}

.account-close {
  width: 34px;
  height: 34px;
  border: 1px solid #3b3741;
  border-radius: 50%;
  background: #211f26;
  color: #ddd;
  font-size: 20px;
  cursor: pointer;
}

.account-tabs {
  display: flex;
  gap: 7px;
  padding: 0 22px 15px;
  border-bottom: 1px solid #302d36;
}

.account-tab {
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #918b99;
  padding: 8px 12px;
  font: 700 11px/1 Inter,system-ui,sans-serif;
  cursor: pointer;
}

.account-tab.active {
  background: #eee7f4;
  color: #211725;
}

.account-content {
  overflow: auto;
  padding: 22px;
}

.account-pane[hidden] {
  display: none;
}

.profile-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 22px;
}

.profile-avatar {
  width: 58px;
  height: 58px;
  display: grid;
  place-items: center;
  flex: none;
  overflow: hidden;
  border-radius: 19px;
  background: linear-gradient(145deg,#f3e8ff,#a177cf);
  color: #25162e;
  font-size: 18px;
  font-weight: 900;
  box-shadow: 0 12px 28px #8d5eb33d;
}

.profile-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.profile-hero strong {
  display: block;
  font-size: 18px;
}

.profile-hero span {
  display: block;
  margin-top: 4px;
  color: #96909d;
  font-size: 12px;
  overflow-wrap: anywhere;
}

.verified-badge {
  display: inline-flex !important;
  width: max-content;
  align-items: center;
  gap: 5px;
  margin-top: 7px !important;
  border: 1px solid #38614e;
  border-radius: 999px;
  padding: 4px 7px;
  color: #a8e1c1 !important;
  background: #183126;
  font-size: 9px !important;
  font-weight: 800;
}

.account-form {
  display: grid;
  gap: 13px;
}

.account-field {
  display: grid;
  gap: 6px;
}

.account-field span {
  color: #aaa3b0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
}

.account-field input,
.account-field select {
  width: 100%;
  border: 1px solid #3a3541;
  border-radius: 12px;
  background: #111015;
  color: #fff;
  padding: 12px 13px;
  font: 14px/1.2 Inter,system-ui,sans-serif;
  outline: none;
}

.account-field input:focus,
.account-field select:focus {
  border-color: #b491d6;
  box-shadow: 0 0 0 3px #a77bce26;
}

.account-primary,
.account-secondary,
.account-danger,
.google-signin {
  height: 42px;
  border-radius: 13px;
  font-weight: 800;
  cursor: pointer;
}

.account-primary {
  border: 0;
  background: linear-gradient(135deg,#f0ddff,#b78dde);
  color: #24162c;
}

.account-secondary {
  border: 1px solid #45404c;
  background: #211f26;
  color: #eee;
}

.account-danger {
  border: 1px solid #713044;
  background: #32141d;
  color: #ffc8d5;
}

.google-signin {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1px solid #d8d4dc;
  background: #f8f7fa;
  color: #242126;
}

.google-signin:disabled,
.account-primary:disabled {
  opacity: .5;
  cursor: wait;
}

.google-mark {
  display: grid;
  place-items: center;
  width: 23px;
  height: 23px;
  border-radius: 50%;
  background: conic-gradient(from -45deg,#4285f4 0 25%,#34a853 0 50%,#fbbc05 0 75%,#ea4335 0);
  color: #fff;
  font: 900 13px/1 Inter,sans-serif;
}

.auth-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 13px 0;
  color: #746e7a;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .12em;
}

.auth-divider:before,
.auth-divider:after {
  content: "";
  height: 1px;
  flex: 1;
  background: #332f38;
}

.email-auth {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.email-auth .account-field {
  grid-column: 1/-1;
}

.email-auth button {
  width: 100%;
}

.auth-status {
  min-height: 18px;
  margin-top: 10px;
  color: #c5a7de;
  font-size: 11px;
  line-height: 1.45;
}

.auth-status.error {
  color: #e9a2b1;
}

.auth-status.success {
  color: #93dbb4;
}

.account-note {
  margin: 10px 1px 0;
  color: #827c89;
  font-size: 11px;
  line-height: 1.5;
}

.profile-actions {
  display: grid;
  gap: 9px;
}

.dna-card {
  margin: 0 0 17px;
  padding: 15px;
  border: 1px solid #463951;
  border-radius: 17px;
  background: radial-gradient(circle at 0 0,#392744,#17151d 65%);
}

.dna-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.dna-card strong {
  font-size: 13px;
}

.dna-card small {
  color: #a991bc;
}

.dna-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.dna-tag {
  border: 1px solid #5e4a6c;
  border-radius: 999px;
  background: #2c2234;
  color: #dfcbed;
  padding: 5px 8px;
  font-size: 9px;
}

.onboarding-progress {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  gap: 5px;
  margin-bottom: 20px;
}

.onboarding-progress i {
  height: 4px;
  border-radius: 99px;
  background: #302b36;
}

.onboarding-progress i.done {
  background: linear-gradient(90deg,#a97bd4,#8ee0ba);
}

.wizard-kicker {
  color: #b99ad3;
  font-size: 9px;
  font-weight: 850;
  letter-spacing: .15em;
}

.wizard-title {
  margin: 6px 0 7px;
  font-size: 23px;
  line-height: 1.08;
  letter-spacing: -.035em;
}

.wizard-copy {
  margin: 0 0 17px;
  color: #98919f;
  font-size: 12px;
  line-height: 1.5;
}

.wizard-fields {
  display: grid;
  gap: 12px;
}

.wizard-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.wizard-chip {
  border: 1px solid #403a48;
  border-radius: 999px;
  background: #1b1920;
  color: #bab3c0;
  padding: 8px 11px;
  font: 700 11px/1 Inter,system-ui,sans-serif;
  cursor: pointer;
  transition: .18s;
}

.wizard-chip:hover {
  border-color: #735c87;
  color: #eee;
}

.wizard-chip.selected {
  border-color: #bd92df;
  background: linear-gradient(145deg,#5b3e73,#30203f);
  color: #fff;
  box-shadow: 0 4px 14px #9b63c329;
}

.wizard-section-label {
  display: block;
  margin: 15px 0 8px;
  color: #bdb4c3;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .05em;
}

.wizard-choices {
  display: grid;
  gap: 8px;
}

.wizard-choice {
  display: grid;
  grid-template-columns: auto minmax(0,1fr);
  gap: 10px;
  align-items: center;
  padding: 12px;
  border: 1px solid #38333f;
  border-radius: 14px;
  background: #17151c;
  cursor: pointer;
}

.wizard-choice:has(input:checked) {
  border-color: #a77acf;
  background: #281d31;
}

.wizard-choice input {
  accent-color: #af80d8;
}

.wizard-choice strong {
  display: block;
  font-size: 12px;
}

.wizard-choice span {
  display: block;
  margin-top: 3px;
  color: #8f8797;
  font-size: 10px;
}

.wizard-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 9px;
  margin-top: 22px;
}

.wizard-actions button {
  min-width: 104px;
}

.wizard-error {
  min-height: 17px;
  margin-top: 9px;
  color: #e5a1b0;
  font-size: 10px;
}

.settings-list {
  display: grid;
  gap: 10px;
}

.setting-row {
  display: grid;
  grid-template-columns: minmax(0,1fr) auto;
  align-items: center;
  gap: 18px;
  padding: 15px;
  border: 1px solid #302d37;
  border-radius: 16px;
  background: #17161c;
}

.setting-copy strong {
  display: block;
  font-size: 13px;
}

.setting-copy span {
  display: block;
  margin-top: 4px;
  color: #8f8997;
  font-size: 11px;
  line-height: 1.4;
}

.setting-toggle {
  position: relative;
  width: 43px;
  height: 25px;
}

.setting-toggle input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.setting-toggle i {
  position: absolute;
  inset: 0;
  border-radius: 99px;
  background: #35313b;
  cursor: pointer;
  transition: background .22s;
}

.setting-toggle i:after {
  content: "";
  position: absolute;
  left: 3px;
  top: 3px;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: #ddd8e1;
  transition: transform .22s,background .22s;
}

.setting-toggle input:checked+i {
  background: #8f65b8;
}

.setting-toggle input:checked+i:after {
  transform: translateX(18px);
  background: #fff;
}

.setting-toggle input:focus-visible+i {
  outline: 2px solid #d2b3ef;
  outline-offset: 3px;
}

.settings-saved {
  min-height: 18px;
  margin-top: 13px;
  color: #ac93c2;
  font-size: 11px;
}

.hide-translations .lyric-translation {
  display: none !important;
}

body.reduce-character-motion .musicat-art,
body.reduce-character-motion .musicat-art *,
body.reduce-character-motion .musicat-dancer-art,
body.reduce-character-motion .musicat-dancer-art *,
body.reduce-character-motion .music-buddy,
body.reduce-character-motion .thought {
  animation: none !important;
  transition: none !important;
}

@media (max-width:720px) {
  .account-label {
    display: none;
  }
  .account-trigger {
    padding-right: 4px;
  }
  .provider {
    display: none;
  }
}

@media (max-width:600px) {
  header {
    gap: 7px;
  }
  .brand-logo {
    width: 112px;
  }
  .nav {
    gap: 4px;
  }
  .nav button {
    padding: 7px 8px;
  }
  .account-panel {
    top: 7px;
    right: 7px;
    bottom: 7px;
    width: calc(100vw - 14px);
    border-radius: 21px;
  }
  .account-content {
    padding: 18px;
  }
  .account-panel-top {
    padding: 19px 18px 13px;
  }
  .account-tabs {
    padding-left: 18px;
    padding-right: 18px;
  }
}

.genre-families {
  display: grid;
  grid-template-columns: repeat(3,minmax(0,1fr));
  gap: 7px;
}

.genre-family {
  --genre: #b78dde;
  min-width: 0;
  border: 1px solid color-mix(in srgb,var(--genre) 45%,#343039);
  border-radius: 12px;
  background: color-mix(in srgb,var(--genre) 11%,#17151c);
  color: #ded9e2;
  padding: 9px 5px;
  font: 800 10px/1 Inter,system-ui,sans-serif;
  cursor: pointer;
  transition: .2s;
}

.genre-family:hover,
.genre-family.active {
  border-color: var(--genre);
  background: color-mix(in srgb,var(--genre) 25%,#17151c);
  color: #fff;
  transform: translateY(-1px);
}

.genre-family-count {
  display: inline-grid;
  place-items: center;
  min-width: 15px;
  height: 15px;
  margin-left: 4px;
  border-radius: 99px;
  background: var(--genre);
  color: #161319;
  font-size: 8px;
}

.subgenre-panel {
  margin-top: 10px;
  padding: 12px;
  border: 1px solid color-mix(in srgb,var(--genre) 42%,#38333f);
  border-radius: 15px;
  background: color-mix(in srgb,var(--genre) 8%,#121116);
}

.subgenre-panel .wizard-chip {
  border-color: color-mix(in srgb,var(--genre) 40%,#403a48);
}

.subgenre-panel .wizard-chip.selected {
  border-color: var(--genre);
  background: color-mix(in srgb,var(--genre) 44%,#201924);
  box-shadow: 0 4px 14px color-mix(in srgb,var(--genre) 28%,transparent);
}

.wizard-count {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 12px;
  color: #aaa2b1;
  font-size: 10px;
}

.wizard-count strong {
  color: #eee;
  font-size: 12px;
}

.wizard-actions button:disabled {
  opacity: .35;
  cursor: not-allowed;
  filter: saturate(.4);
}

.global-player {
  position: relative;
  z-index: 12;
  min-height: 0;
  padding: 9px 14px 8px;
  border-bottom: 1px solid #292630;
  background: linear-gradient(180deg,#0e0d12f5,#0b0b0df0);
  backdrop-filter: blur(18px);
}

.global-player[hidden],
.global-player [hidden] {
  display: none !important;
}

.global-full {
  max-width: 748px;
  max-height: calc(100dvh - 70px);
  overflow: auto;
  margin: auto;
  padding: 0 2px 8px;
  scrollbar-width: thin;
}

.global-full-card {
  margin: 0;
  box-shadow: 0 15px 42px #0008;
  border-color: #4b4057;
}

.track.global-full-card .player-lyrics {
  height: min(300px,36vh);
}

.global-full-card .track-top {
  padding-right: 0;
}

.global-full-card .transport {
  grid-template-columns: minmax(172px,1fr) auto auto;
  gap: 11px;
}

.audio-visuals {
  height: 48px;
  display: flex;
  align-items: stretch;
  gap: 10px;
  padding: 3px 0;
}

.stereo-meter.vertical {
  width: 34px;
  min-width: 34px;
  height: 42px;
  display: grid;
  grid-template-columns: repeat(2,1fr);
  gap: 4px;
  color: #8d8794;
  font: 7px/1 ui-monospace,monospace;
}

.stereo-meter.vertical .meter-channel {
  display: grid;
  grid-template-rows: 1fr 8px;
  gap: 2px;
  text-align: center;
}

.stereo-meter.vertical .meter-track {
  position: relative;
  width: 10px;
  height: 31px;
  margin: auto;
  border-radius: 4px;
  background: repeating-linear-gradient(0deg,#2d2b32 0 3px,transparent 3px 5px);
}

.stereo-meter.vertical .meter-level {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: var(--level,2%);
  background: repeating-linear-gradient(0deg,#8ee0ba 0 3px,transparent 3px 5px);
  transition: height 70ms linear;
}

.stereo-meter.vertical .meter-track.right .meter-level {
  background: repeating-linear-gradient(0deg,#d5b3fb 0 3px,transparent 3px 5px);
}

.graphic-eq {
  height: 42px;
  width: 72px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 3px;
  padding: 4px 5px;
  border-left: 1px solid #302d36;
}

.graphic-eq i {
  width: 5px;
  height: var(--eq-height);
  border-radius: 4px;
  background: linear-gradient(#8ee0ba,#c696ef);
  opacity: .65;
  transform-origin: bottom;
}

.track.is-playing .graphic-eq i {
  animation: eq-dance var(--eq-speed,.72s) ease-in-out infinite alternate;
  animation-delay: var(--eq-delay,0s);
}

@keyframes eq-dance {
  to {
    height: calc(var(--eq-height)*.42);
    filter: brightness(1.3);
  }
}

.player-actions {
  display: flex;
  align-items: center;
  gap: 3px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid #2e2b34;
}

.player-stats {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-right: auto;
  color: #8f8997;
  font: 650 9px/1 Inter,system-ui,sans-serif;
  white-space: nowrap;
}

.player-stat {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.player-stat svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
}

.player-action {
  width: 31px;
  height: 31px;
  flex: none;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: #aaa2b4;
  padding: 0;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: color .2s,transform .2s,background .2s;
}

.player-action:hover {
  color: #f4eaff;
  transform: translateY(-1px);
  background: #ffffff0a;
}

.player-action span {
  display: none;
}

.player-action svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.player-action.remix {
  color: #b78cff;
}

.player-action.like.liked,
.player-action.dislike.disliked {
  color: #a982f1 !important;
}

.player-action.like.liked svg,
.player-action.dislike.disliked svg {
  fill: none !important;
  stroke: currentColor !important;
  filter: drop-shadow(0 0 4px #a982f177) !important;
  transform: none !important;
}

.player-action.saved.saved {
  color: #ff648d;
}

.player-action.saved.saved svg {
  fill: #e51854;
  stroke: #ff759a;
  filter: drop-shadow(0 0 5px #ed1e5b88);
}

.player-action.active {
  color: #d2aff8;
  background: #c79cf018;
}

.player-action:disabled {
  opacity: .35;
  cursor: not-allowed;
  transform: none;
}

/* The chat card and the player each have a dedicated Download button in their action
   row, so the menu's WAV item would be a duplicate there. A library card has no action
   row, so it is that card's only way to reach the WAV and must stay visible. */

.chat-card .commands-panel .download-wav,
.global-full-card .commands-panel .download-wav {
  display: none;
}

.chat-card .player-actions {
  display: none !important;
}

@media (max-width:680px) {
  .global-player {
    padding: 7px 9px;
  }
  .global-full {
    max-height: calc(100dvh - 64px);
  }
  .global-full-card {
    padding: 11px;
  }
  .global-full-card .transport {
    grid-template-columns: minmax(112px,1fr) auto auto;
    gap: 6px;
  }
  .global-full-card .icon-btn {
    width: 32px;
    height: 32px;
  }
  .graphic-eq {
    width: 55px;
    gap: 2px;
  }
  .player-actions {
    grid-template-columns: repeat(8,55px);
  }
}

/* Local player layout correction */

.global-player {
  max-height: min(48dvh,480px);
  overflow: hidden;
  transition: max-height .78s cubic-bezier(.22,1,.36,1),padding .62s cubic-bezier(.22,1,.36,1);
}

.global-full {
  max-height: min(48dvh,480px);
  transition: max-height .78s cubic-bezier(.22,1,.36,1);
}

.global-player.tray-open {
  max-height: calc(100dvh - 60px);
  overflow-y: auto;
}

.global-player.tray-open .global-full {
  max-height: none;
  overflow: visible;
}

/* Retired: the chips are how a song is started, so they stay available whatever the player's trays are doing. Restore by reinstating this rule. */

/* .global-player.tray-open~.composer-wrap .suggestions-panel{display:none} */

.composer-wrap {
  position: relative;
  z-index: 90;
  max-height: min(34dvh,270px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.global-full-card .track-top {
  min-height: 58px;
}

.track-top>.audio-visuals {
  height: 54px;
  flex: none;
  align-self: center;
}

.chat-card .track-top>.audio-visuals {
  display: none !important;
}

.global-full-card .transport {
  grid-template-columns: minmax(172px,1fr) auto;
}

.graphic-eq i {
  height: var(--eq-level,8%);
  animation: none !important;
  border-radius: 3px 3px 1px 1px;
  background: repeating-linear-gradient(0deg,#8ee0ba 0 3px,transparent 3px 5px);
  filter: drop-shadow(0 0 4px #7bdcaf44);
  transition: height 70ms linear,filter 70ms linear;
}

.track.is-playing .graphic-eq i {
  filter: brightness(1.25);
}

.track-open .muted,
.library-meta {
  display: block;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-card {
  position: relative;
  overflow: visible;
  padding-bottom: 24px;
}

.song-card-footer {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  pointer-events: none;
}

.song-reaction-control {
  position: relative;
  display: flex;
  align-items: center;
  gap: 5px;
  transform: translateY(18px);
  pointer-events: auto;
}

.song-reaction-selected,
.song-reaction-trigger {
  height: 29px;
  min-width: 29px;
  display: grid;
  place-items: center;
  border: 1px solid #3a3740;
  border-radius: 999px;
  background: #1b1a20;
  color: #aaa4af;
  box-shadow: 0 4px 13px #0007;
  cursor: pointer;
}

.song-reaction-selected {
  padding: 0 8px;
  font-size: 16px;
  color: #fff;
}

.song-reaction-selected[hidden] {
  display: none;
}

.song-reaction-trigger {
  font-size: 17px;
  filter: grayscale(1);
  transition: transform .18s,border-color .18s;
}

.song-reaction-trigger:hover {
  transform: scale(1.06);
  border-color: #706677;
}

.song-reaction-palette {
  position: absolute;
  left: 0;
  bottom: 37px;
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 6px;
  border: 1px solid #45414b;
  border-radius: 999px;
  background: #ece9e3;
  color: #222;
  box-shadow: 0 9px 28px #0009;
  opacity: 0;
  visibility: hidden;
  transform: translateY(5px) scale(.96);
  transform-origin: left bottom;
  transition: opacity .16s,transform .16s,visibility .16s;
  z-index: 20;
}

.song-reaction-control.open .song-reaction-palette {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.song-reaction {
  width: 31px;
  height: 31px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  font-size: 19px;
  filter: grayscale(1);
  opacity: .72;
  cursor: pointer;
  transition: transform .16s,filter .16s,opacity .16s;
}

.song-reaction:hover,
.song-reaction.selected {
  transform: scale(1.18);
  filter: none;
  opacity: 1;
}

.song-created {
  margin-left: auto;
  color: #7f7986;
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  pointer-events: auto;
}

.global-full-card .song-card-footer {
  display: none;
}

@media (max-width:680px) {
  .global-player,
  .global-full {
    max-height: min(44dvh,390px);
  }
  .composer-wrap {
    max-height: min(32dvh,230px);
  }
  .global-full-card .transport {
    grid-template-columns: minmax(100px,1fr) auto;
  }
  .track-top>.audio-visuals {
    gap: 5px;
  }
  .graphic-eq {
    width: 50px;
  }
  .stereo-meter.vertical {
    width: 29px;
    min-width: 29px;
  }
}

.composer-wrap {
  position: relative !important;
  left: auto;
  bottom: auto;
  transform: none;
  width: 100%;
  max-height: min(36dvh,300px);
  overflow-y: auto;
  z-index: 90;
}

.composer {
  box-shadow: 0 -12px 28px #0b0b0dcc;
}

main {
  padding-bottom: 20px;
}

@media (max-width:680px) {
  main {
    padding-bottom: 16px;
  }
  .composer-wrap {
    max-height: min(38dvh,270px);
  }
}

.app-header {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(100%,1000px);
  height: 60px;
  z-index: 100;
}

.app-header {
  grid-row: 1;
}

.shell>.global-player {
  grid-row: 2;
}

.shell>main {
  grid-row: 3;
}

.shell>.composer-wrap {
  grid-row: 4;
}

/* ---------------------------------------------------------------------------
   The player page's back control, in the header before the logo.

   It lives in <header> rather than inside the player so it reads as page
   navigation, alongside Chat and Library, instead of as a player control.
   `hidden` is honoured normally here: the attribute is toggled by
   openPlayerPage()/closePlayerPage(). ------------------------------------- */

.player-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  height: 36px;
  padding: 0 12px 0 9px;
  margin-right: 4px;
  border: 1px solid #37343f;
  border-radius: 999px;
  background: #19181e;
  color: #eeeaf2;
  cursor: pointer;
  font: 700 12px/1 Inter,system-ui,sans-serif;
  transition: border-color .2s,background .2s,transform .2s;
}

.player-back:hover {
  border-color: #68577b;
  background: #24212b;
  transform: translateY(-1px);
}

.player-back svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.player-back[hidden] {
  display: none;
}

/* On the phone player page the header carries Back and the logo only: the nav
   and the account button belong to the views behind it, and the page is left
   with Back. Phone only — the desktop header is unchanged. */

@media (max-width:1000px) {
  body.player-page .app-header .nav,
  body.player-page .app-header .provider,
  body.player-page .app-header .account-trigger {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
   The phone player page.

   Opening a song takes over the screen: the player, and nothing else. The feed
   and the composer are hidden rather than scrolled past, so the page is the
   player instead of the chat page with a player on top of it.

   These selectors match `.shell>main{grid-row:3}` above on specificity (0,2,0)
   — a bare `body.player-page main` would tie and lose on source order, which is
   why the rows are re-stated here rather than just `display:none`.

   Desktop is excluded: `openPlayerPage()` returns early above 1000px, and the
   two rules inside that media query already handle it. --------------------- */

/* ---------------------------------------------------------------------------
   The sticky player is retired.

   It was the in-chat strip: once a song played, the player stayed docked in the
   conversation on every view. The player page replaces it, so on a phone the
   player is shown only on that page.

   Retired, not deleted — `globalPlayer.hidden` is still managed exactly as
   before, and the markup and behaviour are untouched. Add the class
   `legacy-chat-player` to <body> to bring the strip back. --------------------- */

@media (max-width:1000px) {
  body:not(.player-page):not(.legacy-chat-player) .shell>.global-player {
    display: none;
  }
}

@media (max-width:1000px) {
  body.player-page .shell>main,
  body.player-page .shell>.composer-wrap {
    display: none;
  }
  /* The player takes the rows the feed and composer gave up, so it fills the
     screen under the fixed 60px header rather than sitting in a 277px band. */
  body.player-page .shell>.global-player {
    grid-row: 2/5;
    max-height: none;
    min-height: 0;
    overflow-y: auto;
    justify-content: flex-start;
    padding-bottom: max(16px,env(safe-area-inset-bottom));
  }
  /* The card is capped at 44dvh for the in-chat strip; on its own page there
     is nothing to share the screen with. */
  body.player-page .global-full {
    max-height: none;
  }
}

.composer-wrap {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 8px 12px max(10px,env(safe-area-inset-bottom));
}

.composer-wrap .composer {
  position: relative;
  left: auto;
  bottom: auto;
  transform: none;
  width: 100%;
  flex: none;
  z-index: 101;
}

.global-full-card {
  transition: max-height .78s cubic-bezier(.22,1,.36,1),padding .78s cubic-bezier(.22,1,.36,1);
}

.global-full-card .track-top {
  transition: min-height .78s cubic-bezier(.22,1,.36,1),row-gap .78s cubic-bezier(.22,1,.36,1);
}

.global-full-card .cover {
  transition: width .78s cubic-bezier(.22,1,.36,1),height .78s cubic-bezier(.22,1,.36,1),border-radius .78s cubic-bezier(.22,1,.36,1),background .78s ease,box-shadow .78s ease,transform .78s cubic-bezier(.22,1,.36,1);
}

.global-full-card .cover .musicat-art {
  transition: width .78s cubic-bezier(.22,1,.36,1),height .78s cubic-bezier(.22,1,.36,1),transform .78s cubic-bezier(.22,1,.36,1);
}

.global-full-card .track-open,
.global-full-card .audio-visuals {
  transition: opacity .42s ease,transform .78s cubic-bezier(.22,1,.36,1);
}

.global-full-card.performance-mode .track-top {
  display: grid;
  grid-template-columns: minmax(0,1fr) auto;
  grid-template-areas: "stage stage" "copy visuals";
}

.global-full-card/* Note rain — the backdrop MusiCat performs against. Only in performance mode,
only while playing: a static card with notes falling behind it would read as decoration rather than as performance. Pointer-events none throughout,
since the cover itself is the play button. */ .note-rain {
  position: absolute;
  inset: -14% -8% 0;
  z-index: 0;
  overflow: hidden;
  border-radius: 22px;
  opacity: 0;
  transition: opacity .9s ease;
  pointer-events: none;
}

.performance-mode .cover .note-rain {
  opacity: 1;
}

.note-rain .note {
  position: absolute;
  top: -16%;
  font-size: var(--size,17px);
  line-height: 1;
  color: var(--tint,#c9a7ef);
  opacity: 0;
  will-change: transform,opacity;
  filter: drop-shadow(0 0 7px currentColor);
  animation: note-fall var(--fall,6.5s) linear var(--delay,0s) infinite;
}

@keyframes note-fall {
  0% {
    transform: translate3d(0,-10%,0) rotate(var(--spin-from,-18deg)) scale(.82);
    opacity: 0;
  }
  12% {
    opacity: var(--peak,.72);
  }
  84% {
    opacity: var(--peak,.72);
  }
  100% {
    transform: translate3d(var(--drift,12px),340%,0) rotate(var(--spin-to,22deg)) scale(1.04);
    opacity: 0;
  }
}

/* A screen-reader hears the song, not a list of note glyphs; and anyone who
   asked for less motion gets a still backdrop rather than none at all. */

@media (prefers-reduced-motion:reduce) {
  .note-rain .note {
    animation: none;
    opacity: .2;
  }
}

.global-full-card.performance-mode .cover {
  grid-area: stage;
  width: min(310px,72%);
  height: 132px;
  justify-self: center;
  border-radius: 22px;
  overflow: visible;
  background: radial-gradient(ellipse at 50% 72%,#6f4f8655,transparent 64%);
  box-shadow: none;
}

.global-full-card.performance-mode .cover .musicat-art {
  width: 132px;
  height: 132px;
  transform: translateY(-4px) scale(1.08);
}

.global-full-card.performance-mode .track-open {
  grid-area: copy;
}

.global-full-card.performance-mode .audio-visuals {
  grid-area: visuals;
}

.global-full-card.performance-mode .track-top {
  row-gap: 5px;
}

.global-full-card.performance-mode .track-open {
  text-align: center;
  grid-column: 1/-1;
}

.global-full-card.performance-mode .audio-visuals {
  position: absolute;
  right: 12px;
  bottom: 0;
}

@media (max-width:600px) {
  .global-full-card.performance-mode .cover {
    height: 112px;
  }
  .global-full-card.performance-mode .cover .musicat-art {
    width: 116px;
    height: 116px;
  }
}

/* Music Director card */

.generation-progress {
  display: grid;
  grid-template-columns: 78px minmax(0,1fr) 104px;
  align-items: center;
  gap: 14px;
  padding: 15px 16px;
  border-radius: 18px;
  overflow: hidden;
  background: radial-gradient(circle at 9% 28%,#36284788,transparent 36%),linear-gradient(145deg,#191720,#111116);
}

.progress-scene {
  width: 78px;
  height: 78px;
  display: grid;
  place-items: center;
  position: relative;
}

.progress-musicat {
  width: 72px;
  height: 72px;
  display: grid;
  place-items: center;
  transform-origin: 50% 65%;
  transition: transform .42s cubic-bezier(.22,1,.36,1),filter .3s;
}

.progress-musicat .musicat-art {
  width: 76px;
  height: 76px;
  overflow: visible;
}

.progress-musicat .musicat-mic {
  display: none;
}

.progress-content {
  min-width: 0;
}

.progress-eyebrow {
  margin: 0 0 4px;
  font-size: 8px;
  line-height: 1.2;
  font-weight: 750;
  letter-spacing: .14em;
  color: #b89dce;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.progress-title {
  font-size: 14px;
  line-height: 1.18;
  font-weight: 750;
  color: #f6f2fa;
  letter-spacing: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.progress-description {
  margin: 3px 0 7px;
  font-size: 10px;
  line-height: 1.35;
  color: #9c96a4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.progress-meta {
  display: flex;
  align-items: center;
  min-width: 0;
}

.progress-steps {
  display: none;
}

.progress-times {
  margin: 0;
  display: flex;
  gap: 10px;
  color: #837b89;
  font-size: 9px;
}

.progress-times b {
  color: #cfc4d8;
  font-weight: 650;
}

.progress-creation {
  position: relative;
  width: 104px;
  height: 70px;
  border-left: 1px solid #2e2934;
  overflow: hidden;
}

.creation-orbit {
  position: absolute;
  left: 24px;
  top: 13px;
  width: 46px;
  height: 46px;
  border: 1px solid #554965;
  border-radius: 50%;
  animation: creation-orbit 5.6s linear infinite;
}

.creation-orbit:before,
.creation-orbit:after {
  content: "";
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #9ee9c2;
  box-shadow: 0 0 10px #7ce2b4;
}

.creation-orbit:before {
  left: -4px;
  top: 17px;
}

.creation-orbit:after {
  right: 2px;
  top: 1px;
  background: #d4a9f7;
  box-shadow: 0 0 10px #c295ef;
}

.creation-core {
  position: absolute;
  left: 40px;
  top: 29px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%,#fff,#c6a0eb 38%,#6e4f8c 72%);
  box-shadow: 0 0 18px #c09ae788;
  animation: creation-breathe 2.4s ease-in-out infinite;
}

.creation-note {
  position: absolute;
  color: #bca1d4;
  font-size: 13px;
  opacity: .34;
  animation: creation-note 2.8s ease-in-out infinite;
}

.creation-note.n1 {
  left: 12px;
  top: 11px;
}

.creation-note.n2 {
  right: 7px;
  top: 35px;
  animation-delay: -1.4s;
}

.creation-wave {
  position: absolute;
  left: 11px;
  right: 6px;
  bottom: 8px;
  height: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
}

.creation-wave i {
  width: 3px;
  height: var(--h);
  border-radius: 3px;
  background: repeating-linear-gradient(0deg,#8ee0ba 0 2px,transparent 2px 3px);
  animation: creation-wave .75s ease-in-out infinite alternate;
  animation-delay: var(--d);
}

.generation-progress[data-phase=planning] .progress-musicat {
  transform: perspective(160px) rotateY(-8deg) translateX(1px);
}

.generation-progress[data-phase=planning] .musicat-pupils {
  transform: translateX(2px);
  transition: transform .16s ease-out;
}

.generation-progress[data-phase=planning] .creation-wave {
  opacity: .22;
}

.generation-progress[data-phase=composing] .progress-musicat {
  transform: perspective(160px) rotateY(-5deg);
}

.generation-progress[data-phase=composing] .musicat-note {
  animation: director-note 1.7s ease-in-out infinite;
}

.generation-progress[data-phase=composing] .creation-note {
  opacity: .85;
  animation-duration: 1.65s;
}

.generation-progress[data-phase=generating] .progress-musicat {
  animation: director-listen 4.4s ease-in-out infinite;
}

.generation-progress[data-phase=generating] .musicat-eye-open {
  opacity: 0;
}

.generation-progress[data-phase=generating] .musicat-eye-closed {
  opacity: 1;
}

.generation-progress[data-phase=generating] .musicat-hand {
  opacity: 1;
}

.generation-progress[data-phase=generating] .musicat-hand-left {
  transform: translate(7px,-17px);
}

.generation-progress[data-phase=generating] .musicat-hand-right {
  transform: translate(-7px,-17px);
}

.generation-progress[data-phase=generating] .creation-orbit {
  animation-duration: 2.8s;
}

.generation-progress[data-phase=mixing] .musicat-hand {
  opacity: 1;
}

.generation-progress[data-phase=mixing] .musicat-hand-left {
  transform: translate(7px,-17px);
}

.generation-progress[data-phase=mixing] .musicat-hand-right {
  animation: director-tap 1.3s ease-in-out infinite;
}

.generation-progress[data-phase=mixing] .musicat-pupils {
  transform: translateX(2px);
}

.generation-progress[data-phase=mixing] .creation-wave i {
  animation-duration: .46s;
}

.generation-progress[data-phase=finalizing] .progress-musicat {
  transform: perspective(160px) rotateY(-7deg) scale(1.03);
  filter: drop-shadow(0 0 8px #c99af844);
}

.generation-progress[data-phase=finalizing] .creation-note.n2 {
  font-size: 18px;
  color: #d3adf2;
  opacity: 1;
}

.generation-progress[data-phase=ready] .progress-musicat {
  animation: director-ready 1.05s cubic-bezier(.22,1,.36,1) both;
}

.generation-progress[data-phase=ready] .musicat-mouth {
  opacity: 0;
}

.generation-progress[data-phase=ready] .musicat-mouth-open {
  opacity: 1;
}

.generation-progress[data-phase=ready] .creation-core {
  background: #9ee9c2;
  box-shadow: 0 0 22px #7ce2b4;
}

.generation-progress[data-phase=ready] .creation-orbit {
  animation-play-state: paused;
  border-color: #426655;
}

.generation-progress[data-stage=error] .progress-musicat {
  filter: saturate(.55);
}

.generation-progress.easter-drum .musicat-hand,
.generation-progress.easter-watch .musicat-hand-left {
  opacity: 1;
}

.generation-progress.easter-drum .musicat-hand-left {
  animation: easter-left-tap .7s ease-in-out 2;
}

.generation-progress.easter-drum .musicat-hand-right {
  animation: easter-right-tap .7s ease-in-out 2;
}

.generation-progress.easter-dance .progress-musicat {
  animation: easter-two-beat .9s ease-in-out 2;
}

.generation-progress.easter-watch .musicat-pupils {
  animation: easter-watch-eyes 2.2s ease-in-out;
}

.generation-progress.easter-watch .musicat-hand-left {
  animation: easter-watch-hand 2.2s ease-in-out;
}

@keyframes creation-orbit {
  to {
    transform: rotate(360deg);
  }
}

@keyframes creation-breathe {
  50% {
    transform: scale(1.22);
    filter: brightness(1.28);
  }
}

@keyframes creation-note {
  50% {
    transform: translateY(-5px);
    opacity: .9;
  }
}

@keyframes creation-wave {
  to {
    height: 4px;
    filter: brightness(1.35);
  }
}

@keyframes director-note {
  50% {
    transform: translateY(-2px) rotate(4deg);
  }
}

@keyframes director-listen {
  0%,
  100% {
    transform: translateX(-1px) rotate(-1deg);
  }
  50% {
    transform: translateX(2px) rotate(1deg);
  }
}

@keyframes director-tap {
  0%,
  70%,
  100% {
    transform: none;
  }
  82% {
    transform: translateY(-5px);
  }
  90% {
    transform: translateY(1px);
  }
}

@keyframes director-ready {
  0% {
    transform: rotateY(0) scale(.96);
  }
  45% {
    transform: rotateY(-10deg) scale(1.06);
  }
  100% {
    transform: rotateY(-6deg) scale(1);
  }
}

@keyframes easter-left-tap {
  50% {
    transform: translateY(7px) rotate(7deg);
  }
}

@keyframes easter-right-tap {
  50% {
    transform: translateY(7px) rotate(-7deg);
  }
}

@keyframes easter-two-beat {
  25% {
    transform: translateX(-3px) rotate(-3deg);
  }
  75% {
    transform: translateX(3px) rotate(3deg);
  }
}

@keyframes easter-watch-eyes {
  20%,
  65% {
    transform: translate(-2px,3px);
  }
}

@keyframes easter-watch-hand {
  25%,
  70% {
    transform: translate(13px,-2px);
  }
}

@media (max-width:600px) {
  .generation-progress {
    grid-template-columns: 62px minmax(0,1fr) 68px;
    gap: 9px;
    padding: 13px 11px;
  }
  .progress-scene {
    width: 62px;
    height: 66px;
    transform: none;
    margin: 0;
  }
  .progress-musicat,
  .progress-musicat .musicat-art {
    width: 62px;
    height: 62px;
  }
  .progress-creation {
    width: 68px;
  }
  .creation-orbit {
    left: 13px;
  }
  .creation-core {
    left: 29px;
  }
  .creation-note.n2 {
    display: none;
  }
  .progress-description {
    max-width: 100%;
  }
}

@media (prefers-reduced-motion:reduce) {
  .progress-musicat,
  .progress-musicat *,
  .progress-creation * {
    animation: none !important;
    transition: none !important;
  }
}

@media (prefers-reduced-motion:reduce) {
  .global-player,
  .global-full,
  .global-full-card,
  .global-full-card .track-top,
  .global-full-card .cover,
  .global-full-card .cover .musicat-art,
  .global-full-card .track-open,
  .global-full-card .audio-visuals {
    transition: none !important;
  }
}

/* ===========================================================================
   Desktop.

   Everything here is inside a min-width query, so the phone layout below
   1001px is untouched and cannot regress.

   The body grid holds exactly two items — the sidebar and the shell. The
   <script> tag is also a child of <body>, so it is taken out of flow
   explicitly: left in, it becomes a grid item and claims a column.

   The player is NOT moved in the DOM. It lives inside .shell and is owned by
   handlers that hold a reference to it, so the shell becomes the grid and the
   player takes a column there. Moving the element would detach it and restart
   playback.
   =========================================================================== */

.sidebar {
  display: none;
}

@media (min-width:1001px) {
  body {
    display: grid;
    grid-template-columns: var(--sidebar-w,272px) minmax(0,1fr);
    /* The topbar spans both columns; the sidebar and shell share the row beneath it.
       minmax(0,1fr) rather than 1fr, or a tall child stretches the row past the
       viewport instead of scrolling inside it. */
    grid-template-rows: var(--topbar-h,72px) minmax(0,1fr);
    grid-template-areas:
      "topbar topbar"
      "sidebar shell";
    height: 100dvh;
    overflow: hidden;
    /* The grips are absolutely positioned children; without this they would
       resolve against the viewport instead of the grid. */
    position: relative;
  }
  /* A script tag is a grid item unless told otherwise. */
  body>script {
    display: none;
  }
  .sidebar {
    grid-area: sidebar;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 16px 14px;
    min-height: 0;
    background: #0a0a0c;
    border-right: 1px solid #1e1c24;
    overflow: hidden;
  }

  /* The logo lives in the topbar now, directly above this column — a second copy
     here would be two logos within 60px of each other. */

  .sidebar-brand {
    display: none;
  }
  .sidebar-brand img {
    width: 132px;
    height: auto;
    margin: 2px 0 18px 8px;
  }
  .sidebar-new {
    margin-bottom: 18px;
    padding: 14px 16px;
    border: 0;
    border-radius: 14px;
    background: linear-gradient(145deg,#b39bf0,#9b7fe8);
    color: #1a1225;
    font: 700 14px/1 Inter,system-ui,sans-serif;
    cursor: pointer;
    transition: filter .18s,transform .18s;
  }
  .sidebar-new:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
  }
  .sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
  }
  .sidebar-link {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 12px 14px;
    border: 0;
    border-radius: 12px;
    background: transparent;
    color: #c9c4d2;
    font: 500 14px/1 Inter,system-ui,sans-serif;
    text-align: left;
    cursor: pointer;
    transition: background .16s,color .16s;
  }
  .sidebar-link:hover {
    background: #15141a;
    color: #f2eff7;
  }
  .sidebar-link.is-active {
    background: #1b1922;
    color: #fff;
  }
  .sidebar-link svg {
    width: 19px;
    height: 19px;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .sidebar-link svg.heart {
    stroke: #e4657f;
  }
  .sidebar-count {
    margin-left: auto;
    font-style: normal;
    font-size: 12px;
    color: #7d7689;
  }
  .sidebar-section {
    margin: 22px 0 8px 14px;
    font: 600 11px/1 Inter,system-ui,sans-serif;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: #6f6879;
  }
  .sidebar-recent {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 1px;
    scrollbar-width: thin;
  }
  .sidebar-recent::-webkit-scrollbar {
    width: 6px;
  }
  .sidebar-recent::-webkit-scrollbar-thumb {
    background: #2a2732;
    border-radius: 9px;
  }
  .recent-item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 8px 12px;
    border: 0;
    border-radius: 11px;
    background: transparent;
    color: #cdc7d6;
    font: 500 13px/1.3 Inter,system-ui,sans-serif;
    text-align: left;
    cursor: pointer;
    transition: background .16s;
  }
  .recent-item:hover {
    background: #15141a;
  }
  .recent-art {
    width: 30px;
    height: 30px;
    flex: none;
    border-radius: 8px;
    object-fit: cover;
    background: #211d2a;
  }
  .recent-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .recent-heart {
    flex: none;
    width: 14px;
    height: 14px;
    fill: #e4657f;
    stroke: none;
  }
  .sidebar-foot {
    display: flex;
    align-items: center;
    gap: 11px;
    margin-top: 14px;
    padding-top: 16px;
    border-top: 1px solid #1e1c24;
    color: #9a93a6;
    font: 500 12px/1.4 Inter,system-ui,sans-serif;
  }
  .sidebar-avatar {
    width: 36px;
    height: 36px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: #241f2e;
    color: #cbb6f0;
    font: 700 14px/1 Inter,system-ui,sans-serif;
  }
  .sidebar-foot strong {
    display: block;
    color: #e9e4f0;
    font-weight: 600;
    font-size: 13px;
  }
  /* The shell fills its column and loses the phone-width cap. Its own top bar
     is redundant once the sidebar carries navigation. */
  .shell {
    grid-area: shell;
    max-width: none;
    width: 100%;
    min-width: 0;
    /* The base rule is height:100dvh, from when the shell owned the whole viewport.
       It is a grid row beneath the topbar now, so it must fill its AREA — 100dvh
       here overflows by exactly the topbar's height. */
    height: 100%;
    min-height: 0;
    position: relative;
  }
  /* The shell header IS the desktop topbar now: it moves out of the shell's flow and
     into the body grid's first row, spanning the full width. */
  .app-header {
    display: flex;
    grid-area: topbar;
    position: static;
    transform: none;
    width: 100%;
    max-width: none;
    height: var(--topbar-h,72px);
    padding: 0 24px;
    gap: 12px;
    border-bottom: 1px solid #1e1c24;
    border-radius: 0;
  }
  main {
    padding: 26px 34px;
  }
  /* The library heading stays in view now that the shell header is gone. */
  .library-head {
    position: sticky;
    top: 0;
    z-index: 4;
    padding: 6px 0 14px;
    background: linear-gradient(180deg,#0b0b0d 72%,transparent);
  }
  .library-head h1 {
    font-size: 28px;
  }
}

@media (min-width:1001px) {
  /* The player gets its own column. The shell becomes the grid, because the
     player is its child — addressing it from the body grid did nothing. */
  /* .shell has six children: header, two account overlays, the player, main
     and the composer. Named areas rather than positions, so the overlays can
     be placed explicitly instead of being auto-flowed into a column. */
  .shell {
    grid-area: shell;
    display: grid;
    grid-template-columns: minmax(0,1fr) var(--player-w,392px);
    /* The base .shell declares FOUR rows (60px auto minmax(0,1fr) auto) for the
       phone layout. Leaving those in place while naming a two-row area grid
       meant the `player` area could not be formed against the real track list,
       so the player was auto-placed into row 2 — which is why it sat below the
       chat however it was aligned. Redeclare the rows here. */
    grid-template-rows: minmax(0,1fr) auto;
    grid-template-areas: "feed player" "composer player";
  }
  /* The pane keeps its column whether or not a song is loaded: a layout that
     reflows the chat every time playback starts is worse than a quiet empty pane,
     and the pane is where the player now lives permanently. */
  /* The pane is revealed by JS clearing `hidden` on desktop, not by overriding the
     attribute here: a CSS override would leave the attribute lying about the state,
     and assistive technology reads the attribute. */

  .global-player-empty {
    display: block;
    margin: auto;
    padding: 0 24px;
    color: var(--muted);
    font-size: 13px;
    line-height: 1.5;
    text-align: center;
  }

  .global-player:not([hidden]) .global-player-empty {
    display: none;
  }
  #main {
    grid-area: feed;
    min-height: 0;
  }
  #composerWrap {
    grid-area: composer;
  }
  /* Overlays sit above everything rather than taking a cell. */
  #accountBackdrop,
  #accountPanel {
    grid-area: 1/1/-1/-1;
  }
  .global-player {
    max-height: none;
    min-height: 0;
    overflow-y: auto;
    padding: 22px;
    border-bottom: 0;
    border-left: 1px solid #1e1c24;
    background: #0a0a0c;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  /* A wide screen shows the player already: a full-screen page would hide the
     conversation for nothing. */
  .player-back {
    display: none !important;
  }
  body.player-page .view {
    display: none;
  }
  body.player-page #chatView {
    display: flex;
  }
}

@media (min-width:1001px) {
  /* The player card was sized for a phone-width strip: a non-wrapping row of
     eight action buttons plus a 172px minimum on the transport gives it a hard
     floor of ~409px, which overflowed the 392px column and clipped the clock
     and download button off the viewport edge.

     Nothing here changes the phone layout — it is all inside the min-width
     query that introduces the column in the first place. */
  .global-player {
    padding: 18px 14px;
  }
  /* The phone caps this at min(48dvh,480px) so the strip cannot swallow the
     chat. The desktop column is full height and has nothing to share with, so
     the cap only clipped the action row off the bottom of the card. */
  .global-full {
    max-width: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
    max-height: none;
  }
  .global-full-card {
    padding: 14px;
  }
  /* Let the transport's flexible track shrink with the column. */
  .global-full-card .transport {
    grid-template-columns: minmax(0,1fr) auto;
    gap: 8px;
  }
  /* Wrap rather than overflow. */
  .global-full-card .player-actions {
    flex-wrap: wrap;
    justify-content: center;
    gap: 4px;
  }
  .track.global-full-card>.tags {
    display: none;
  }
  /* The chips sit under the avatar, so they centre with it rather than
     starting at the left edge of a column the avatar is centred in. */
  .global-full-card .card-tags {
    justify-content: center;
  }
  /* The card fills the pane so an open lyrics tray can reach its floor.
     .global-full and the card are blocks by default, so the height the pane
     offers never reached the tray. */
  .shell>.global-player>.global-full {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-self: stretch;
  }
  .global-full>#globalFullCard {
    flex: 1;
    min-height: 0;
    display: flex;
  }
  #globalFullCard>.global-full-card {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
  }
  /* The transport keeps its natural height so the tray takes the slack. */
  .global-full-card>.player {
    flex: none;
  }
  /* The column is full height, so the player sits at the top of it rather than
     floating in the middle. justify-content:center is what centred it. */
  /* Span both grid rows explicitly. `grid-area:player` was resolving to
     `2 / player` — the name was taken as a row line, so the player sat in the
     bottom row and floated at y609 however it was aligned internally. Explicit
     line numbers cannot be misread: column 2, rows 1 through the end. */
  /* Use the named area, like #main and #composerWrap do — those resolve
     correctly, while explicit line numbers kept coming back as row 2. The area
     spans both rows, so the player fills the column and its content starts at
     the top. */
  /* `.shell>.global-player{grid-row:2}` (line ~154) pins the phone grid's four
     children to explicit rows. It is outside any media query and outranks a
     plain `.global-player` selector, so it kept the player in row 2 — below the
     chat — no matter how the area or alignment was written. Match its
     specificity to release the pin on desktop. */
  .shell>.global-player {
    grid-area: player;
    align-self: stretch;
    justify-content: flex-start;
  }
  .shell>main {
    grid-area: feed;
  }
  .shell>.composer-wrap {
    grid-area: composer;
  }
  .global-full {
    margin-top: 0;
  }
  /* Performance mode gets a proper rectangular stage here: the column is tall
     and narrow, so the phone's 132px band leaves the avatar looking cramped.
     Roughly double the height, full column width, avatar scaled to match. */
  .global-full-card.performance-mode .cover {
    width: 100%;
    height: 268px;
    border-radius: 20px;
  }
  .global-full-card.performance-mode .cover .musicat-art {
    width: 236px;
    height: 236px;
    transform: translateY(-6px) scale(1.06);
  }
  /* In performance mode the visuals are absolutely positioned bottom-right,
     which overlapped the centred title in this narrow column. Put them back in
     flow below the copy. */
  /* Performance mode lays track-top out as "stage stage" / "copy visuals", so
     the title and the meters share a row. That row is too narrow in this
     column and the meters landed on top of the title. Stack them instead. */
  .global-full-card.performance-mode .track-top {
    grid-template-columns: minmax(0,1fr);
    grid-template-areas: "stage" "copy" "visuals";
  }
  .global-full-card.performance-mode .track-top>.audio-visuals {
    position: static;
    right: auto;
    bottom: auto;
    justify-content: center;
    margin-top: 8px;
  }
  .global-full-card.performance-mode .track-open {
    padding: 0 4px;
  }
}

/* A failed generation is a notice about the system, not a line of conversation.
   Styling it as a chat message put raw backend errors in MusiCat's voice. */

/* Centred in the conversation, like the system notice it is — not aligned to
   either speaker. One line, so it reads as an aside rather than a message. */

.generation-failed {
  display: block;
  width: auto;
  padding: 8px 14px;
  border: 1px solid #4a3340;
  border-radius: 999px;
  background: linear-gradient(#211a1f,#1a1519);
  color: #c9b9bf;
  font: 500 12px/1.5 Inter,system-ui,sans-serif;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.generation-failed-mark {
  width: 20px;
  height: 20px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #7a3d50;
  color: #fff;
  font: 700 12px/1 Inter,system-ui,sans-serif;
}

.generation-failed-copy {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.generation-failed-copy strong {
  font: 600 14px/1.3 Inter,system-ui,sans-serif;
}

.generation-failed-detail {
  color: #a9979e;
  font: 400 12px/1.45 ui-monospace,monospace;
  overflow-wrap: anywhere;
}

@media (min-width:1001px) {
  /* The pane holds exactly one player, so the card's list framing — a bordered,
     shadowed box inside another bordered box — describes a list that is not
     there. */
  .global-full-card {
    border: 0;
    background: transparent;
    box-shadow: none;
    margin: 0;
  }
  /* With a tray open the card grew to 936px inside an 840px pane, pushing the
     tags and footer below the fold. The transport and actions sit ABOVE the
     panels (inside .player), so they were never the part being lost.
     Let the card own the pane's height and give the open panel the leftover
     space, scrolling inside itself. */
  /* .global-full is display:block by default, so flex rules on the card did
     nothing and its max-height:100% resolved against an auto-height block.
     Make it a bounded flex column: that is what gives the card something to
     size against. */
  /* The pane is overflow:auto, so height:100% on a child resolves against the
     scrollable content box and never constrains anything — the card just grew
     and the pane scrolled. Stop the pane scrolling and make .global-full the
     flex child that absorbs the height instead. */
  /* The phone caps this at 100dvh-60px so a tray cannot outgrow the screen.
     The desktop pane is a grid cell of exactly the right height already, and
     the cap shrank it by 60px the moment a tray opened — the tray's background
     stopped 60px above the floor of the pane. */
  .global-player.tray-open {
    overflow: hidden;
    max-height: none;
  }
  /* The pane pads 18px and the card 14px, which held the tray 32px off the
     floor. The composer in the middle pane sits 12px up, so the card's padding
     stands down while a tray is open and the two line up. */
  .global-player.tray-open .global-full {
    padding-bottom: 0;
  }
  .global-player.tray-open .global-full-card {
    padding-bottom: 0;
  }
  .global-player.tray-open {
    padding-bottom: 12px;
  }
  .global-player.tray-open .global-full {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
  }
  /* There is an unnamed wrapper DIV between .global-full and the card, so the
     card is not .global-full's flex child — its flex:1 addressed a parent it
     does not have. The wrapper has to carry the chain through. */
  .global-player.tray-open .global-full>div {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
  }
  .global-player.tray-open .global-full-card {
    display: flex;
    flex-direction: column;
    min-height: 0;
    flex: 1;
  }
  .global-player.tray-open .track-top,
  .global-player.tray-open .player,
  .global-player.tray-open .tags,
  .global-player.tray-open .song-card-footer {
    flex: none;
  }
  .global-player.tray-open .panel.open {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  /* The lyrics sit inside .lyrics-scene, not directly in the panel, and
     `.lyrics-scene .player-lyrics{height:100%}` made them resolve against an
     unconstrained parent. The scene has to be a flex child too. */
  .global-player.tray-open .lyrics-scene {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    height: auto;
  }
  /* `.global-full-card .player-lyrics{height:min(300px,36vh)}` is a fixed
     height, which outranks flex sizing — the panel scrolled the pane instead of
     itself. Release it so the lyrics take the leftover space and scroll there. */
  .global-player.tray-open .global-full-card .player-lyrics {
    flex: 1;
    min-height: 0;
    height: auto;
    max-height: none;
    overflow-y: auto;
  }
}

/* The count belongs over the box, not inside it: within the input column it
   forced the textarea to reserve a row of height that never held text, so the
   box stood about twice as tall as the send button beside it. */

.composer-meta {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  max-width: 720px;
  margin: 0 auto;
  padding: 0 14px 3px;
  min-height: 13px;
}

.char-count {
  font-size: 10px;
  line-height: 1.2;
}

.composer-ready-note {
  font-size: 10px;
}

/* One row tall, matching the send button. updateComposer() grows it from
   scrollHeight as text wraps, so no min-height is set here — one would inflate
   scrollHeight and defeat the measurement. */

.composer textarea {
  min-height: 0;
  padding: 11px 10px 10px;
}

/* Playlists page. Follows the Library grid; only the "More" control is new. */

.playlist-more-wrap {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}

.playlist-card .library-cover {
  background: linear-gradient(135deg,#6f7fb3,#8a6ca8);
}

/* Song card: tags and a "..." menu.

   The chat card hid .tags, so a song in the feed showed only its title. The
   genre chips are what identify a song at a glance, and they now sit under the
   subtitle in the header block.

   The action row stays hidden entirely — playback belongs to the one player,
   and the overflow menu moved to the header. (An earlier revision styled
   .player-actions to show only the menu; that is superseded below and was
   removed rather than left as a rule the cascade silently discards.) */

.chat-card .tags {
  display: flex !important;
  margin-top: 10px;
}

/* The tags sit above the footer's reaction row, which is absolutely placed. */

.chat-card {
  padding-bottom: 30px;
}

/* Lyrics tray: the stage is always there, the separator reaches the edges.

   The radial gradient behind the lyrics only appeared when the tray opened,
   which read as a background switching on rather than as a stage the lyrics
   move onto. It is now painted whether or not the panel is open.

   The separator is a border on .panel, which sits inside the card's 14px
   padding — so the line stopped 14px short on each side and looked cut. A
   negative margin with matching padding pushes it out to the card's edges
   without moving the content. */

.lyrics-scene {
  background: radial-gradient(circle at 50% 60%,#382a4855,transparent 52%) !important;
}

.panel {
  margin-left: -14px;
  margin-right: -14px;
  padding-left: 14px;
  padding-right: 14px;
}

/* Resizable panes.

   A 9px grab strip holding the 1px divider line. It overlays the existing
   border rather than taking a grid column, so the panes keep their exact widths
   and no layout shifts when the grip appears.

   Hidden below the desktop breakpoint: the phone has one column to resize. */

.pane-grip {
  display: none;
}

@media (min-width:1001px) {
  .pane-grip {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    width: 9px;
    z-index: 60;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: col-resize;
    /* The strip is the hit area; the line is drawn inside it. */
    -webkit-appearance: none;
    appearance: none;
  }
  .pane-grip::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 4px;
    width: 1px;
    background: #1e1c24;
    transition: width .12s ease,background .12s ease,left .12s ease;
  }
  .pane-grip:hover::before,
  .pane-grip:focus-visible::before,
  .pane-grip.is-dragging::before {
    width: 3px;
    left: 3px;
    background: #b39bf0;
  }
  .pane-grip:focus-visible {
    outline: none;
  }
  /* Positioned on the boundary each one owns. */
  #gripSidebar {
    left: calc(var(--sidebar-w,272px) - 4px);
  }
  body.grip-active {
    cursor: col-resize;
    user-select: none;
  }
}

@media (min-width:1001px) {
  /* The player grip sits on the shell's inner boundary, so it is measured from
     the right edge rather than from the sidebar. */
  #gripPlayer {
    right: calc(var(--player-w,392px) - 4px);
    left: auto;
  }
}

@media (max-width:1300px) {
  /* No player column below this width, so nothing to resize. */
  #gripPlayer {
    display: none;
  }
}

/* The chat list never scrolls sideways.

   A single unbroken token — a pasted URL, or a run of 400 A's — set the feed's
   content width and dragged every card off to the left. The message must wrap
   inside its bubble instead of widening the column. */

main {
  overflow-x: hidden;
}

.feed {
  max-width: min(720px,100%);
  overflow-x: hidden;
}

.msg {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* The scrollbar itself stays out of sight; the list still scrolls. */

main {
  scrollbar-width: none;
}

main::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* Composer card.

   The composer and its chips sit in one raised card, and the chat scrolls
   behind it rather than stopping above it. The "+" opens and closes the chips
   panel, which is what the composer's own control should decide. */

.composer-wrap {
  background: linear-gradient(transparent,#0b0b0d 26%);
  pointer-events: none;
}

.composer-wrap>* {
  pointer-events: auto;
}

.suggestions-panel,
.composer-meta,
.composer {
  position: relative;
  z-index: 2;
}

/* One card holds the chips and the composer, and the chat scrolls behind it. */

.composer-card {
  max-width: 720px;
  margin: 0 auto;
  padding: 10px 10px 9px;
  border: 1px solid #33333b;
  border-radius: 22px;
  background: #141419;
  box-shadow: 0 14px 40px #0009;
}

.composer-card .suggestions-panel {
  margin: 0 0 9px;
}

.composer-card .composer {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0;
  align-items: end;
  grid-template-columns: auto minmax(0,1fr) auto;
}

.composer-card .composer-meta {
  padding: 0 4px 3px;
}

/* The "+" is a 34px control, sized against the send button, and it stays a
   plus: rotating it into an "x" reads as "close the composer", not "hide the
   chips". The open state is carried by colour instead. */

/* `.composer button{width:42px;height:42px}` matches this element too and wins
   on specificity, so the selector has to be at least as specific. */

.composer .chips-toggle,
.chips-toggle {
  width: 34px;
  height: 34px;
  min-width: 34px;
  flex: none;
  display: inline-grid;
  place-items: center;
  align-self: end;
  margin: 0 0 4px;
  padding: 0;
  border: 1px solid #33333b;
  border-radius: 11px;
  background: #1d1d23;
  color: #b9b3c4;
  font: 300 20px/1 Inter,system-ui,sans-serif;
  cursor: pointer;
  transition: background .16s,color .16s,border-color .16s;
}

.chips-toggle:hover {
  background: #26242e;
  color: #efeaf6;
}

.chips-toggle.is-open {
  border-color: #5b4d70;
  background: #241f2e;
  color: #d8c7f2;
}

body.chips-closed .suggestions-panel {
  display: none !important;
}

@media (min-width:1001px) {
  /* No line across the feed when nothing is playing: the pane it divides is
     collapsed, so the grip has no boundary to sit on. */
  /* The grip stays: the pane it divides is always present now. */
}

/* The right-hand separator exists only while the now-playing pane does. The
   :has() rule inside the 1301 query covers the collapsed-column case; this one
   covers every other state, including widths where the pane never appears. */

#gripPlayer {
  display: none;
}

@media (min-width:1001px) {
  .shell:has(.global-player:not([hidden])) #gripPlayer {
    display: block;
  }
}

/* Markup order inside .composer is: .input-column, "+", send. The example puts
   the "+" on the left, so it is placed explicitly rather than reordered in the
   HTML — the textarea should stay first for tab order and for screen readers. */

.composer-card .composer {
  grid-template-columns: auto minmax(0,1fr) auto;
}

.composer-card .chips-toggle {
  grid-column: 1;
  grid-row: 1;
}

.composer-card .input-column {
  grid-column: 2;
  grid-row: 1;
}

.composer-card .composer-send {
  grid-column: 3;
  grid-row: 1;
}

/* Chips get their own card, above the composer's. */

.chips-card {
  max-width: 720px;
  margin: 0 auto 8px;
  padding: 10px 12px;
  border: 1px solid #2b2933;
  border-radius: 18px;
  background: #131318;
  box-shadow: 0 10px 30px #0007;
}

.chips-card .suggestions-panel {
  margin: 0;
}

body.chips-closed .chips-card {
  display: none;
}

/* Message bubbles are narrower than the card and align to their own side:
   MusiCat's start at the card's left edge, the listener's end at its right. */

.feed {
  --bubble-inset: 52px;
}

.msg {
  max-width: calc(100% - var(--bubble-inset));
}

.msg.ai {
  align-self: flex-start;
  margin-right: var(--bubble-inset);
}

.msg.user {
  align-self: flex-end;
  margin-left: var(--bubble-inset);
}

.generation-failed {
  align-self: flex-start;
  margin-right: var(--bubble-inset);
  max-width: calc(100% - var(--bubble-inset));
}

/* .composer-wrap is a flex column, so a card with only max-width shrinks to
   its content instead of filling the row. */

.chips-card,
.composer-card {
  width: 100%;
  align-self: stretch;
}

/* No black band behind the cards.

   .composer-wrap painted a gradient to fade the chat out above the composer,
   and .composer carried an upward box-shadow for the same purpose. With the
   composer now a discrete card, both read as a dark slab sitting under it. The
   chat simply scrolls behind the card instead. */

.composer-wrap {
  background: none;
}

.composer-card .composer {
  box-shadow: none;
  background: transparent;
  border: 0;
}

.composer-card .composer-meta {
  background: none;
}

/* The inner textarea box is the card now, so it loses its own frame. */

.composer-card .input-column {
  background: transparent;
}

/* Chips shown inside a request message. */

.msg.user {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}

.msg-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  justify-content: flex-end;
}

.msg-chip {
  padding: 3px 9px;
  border-radius: 999px;
  background: #d7d2e4;
  color: #2a2533;
  font: 600 11px/1.5 Inter,system-ui,sans-serif;
}

.msg-text {
  display: block;
}

/* The cards track the column, not their contents.

   A flex item sizes to its content by default, so a long word in the textarea
   or a wide chip row could push the card wider or let it collapse narrower.
   Fixing the basis to the column width means the card only changes when the
   pane it sits in changes. */

.chips-card,
.composer-card {
  flex: 0 0 auto;
  width: 100%;
  max-width: 720px;
  min-width: 0;
}

.composer-card .input-column {
  min-width: 0;
}

.composer-card textarea {
  width: 100%;
  min-width: 0;
}

/* The listener's bubble ends short of the card's right edge, mirroring how
   MusiCat's starts short of the left. margin-left only pushed it off the other
   side, leaving it flush. */

.feed>.msg.user {
  margin-right: 0;
  align-self: flex-end;
}

.feed {
  padding-right: 0;
}

/* Song card header: avatar, title block, and the "..." on one baseline.

   The tags moved under the subtitle, where they read as part of the song's
   description rather than as a separate band across the card. */

.chat-card .track-top {
  align-items: center;
  gap: 12px;
}

.chat-card .track-open {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 5px;
}

.card-tags .tag {
  font-size: 10px;
  padding: 3px 8px;
}

/* The old bottom tag row and the actions-row menu are superseded. */

.chat-card>.tags {
  display: none !important;
}

.chat-card .player-actions {
  display: none !important;
}

/* The header "..." — vertically centred with the avatar and title. */

.has-card-menu .card-menu {
  width: 30px;
  height: 30px;
  flex: none;
  align-self: center;
  margin-left: auto;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #8b8494;
  cursor: pointer;
  transition: background .16s,color .16s;
}

.has-card-menu .card-menu:hover {
  background: #221f29;
  color: #e6e0ee;
}

.has-card-menu .card-menu svg {
  width: 18px;
  height: 18px;
}

/* A dropdown menu, not a tray: it floats over the card from the button rather
   than expanding the card and pushing the conversation down. */

.has-card-menu {
  position: relative;
}

.has-card-menu .commands-panel {
  position: absolute;
  top: 46px;
  right: 14px;
  z-index: 30;
  width: 212px;
  margin: 0;
  padding: 6px;
  border: 1px solid #3a3743;
  border-radius: 14px;
  background: #1a1921;
  box-shadow: 0 18px 44px #000a;
}

.has-card-menu .commands-panel .commands {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.has-card-menu .commands-panel .command {
  width: 100%;
  justify-content: flex-start;
  gap: 10px;
  padding: 9px 10px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: #d8d3e0;
  font: 500 13px/1 Inter,system-ui,sans-serif;
  text-align: left;
  cursor: pointer;
}

.has-card-menu .commands-panel .command:hover:not(:disabled) {
  background: #262331;
}

.has-card-menu .commands-panel .command:disabled {
  opacity: .45;
  cursor: default;
}

.has-card-menu .commands-panel .command svg {
  width: 16px;
  height: 16px;
  flex: none;
}

/* Song cards and system notices size to their content, with a ceiling below
   the composer card's width — a maximum, not a fixed width, so a short card
   stays short instead of stretching to a uniform block. */

.feed>.track,
.feed>.generation-failed,
.feed>.generation-progress {
  align-self: flex-start;
  width: auto;
  max-width: calc(100% - var(--bubble-inset));
}

/* Centre it in the column; the earlier rules aligned it to the start. */

.feed>.generation-failed {
  align-self: center;
  margin: 0 auto;
  max-width: calc(100% - var(--bubble-inset));
}

/* Belt and braces: the player's card is a clone of the chat card, so a menu that ever
   rides along in .track-top must not appear. The player builds its own menu into
   .player-actions from the same component, so this is scoped to the cloned position
   rather than to every .card-menu — a blanket rule would hide the real one. */

.track.global-full-card>.track-top>.card-menu,
.track.global-full-card>.commands-panel:not(.player-menu-panel) {
  display: none !important;
}

/* Why the send button is off. Red, under the card, only when it applies. */

.composer-block {
  max-width: 720px;
  margin: 6px auto 0;
  padding: 0 14px;
  color: #e2707f;
  font: 500 12px/1.4 Inter,system-ui,sans-serif;
  text-align: right;
}

.composer-send:disabled {
  opacity: .4;
  cursor: not-allowed;
}

/* ---------------------------------------------------------------------------
   Modal — the app's first. Centred, where the account panel is a right-edge
   sheet, because these are short forms rather than a settings surface.
   --------------------------------------------------------------------------- */

.modal-backdrop {
  position: fixed;
  z-index: 60;
  inset: 0;
  background: #05040899;
  backdrop-filter: blur(4px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .28s ease;
}

.modal-backdrop.open {
  opacity: 1;
  pointer-events: auto;
}

.modal {
  position: fixed;
  z-index: 61;
  top: 50%;
  left: 50%;
  width: min(620px,calc(100vw - 32px));
  min-width: min(340px,calc(100vw - 32px));
  max-width: calc(100vw - 32px);
  height: min(640px,calc(100dvh - 48px));
  min-height: 280px;
  max-height: calc(100dvh - 48px);
  display: flex;
  flex-direction: column;
  /* resize needs an overflow other than visible to take effect. The body scrolls
     inside, so clipping here costs nothing. */
  overflow: hidden;
  border: 1px solid #41394c;
  border-radius: 22px;
  background: radial-gradient(circle at 85% 0,#39284c88,transparent 38%),linear-gradient(165deg,#1c1a22,#100f14 75%);
  box-shadow: 0 28px 90px #000c;
  transform: translate(-50%,-46%);
  opacity: 0;
  pointer-events: none;
  transition: transform .3s cubic-bezier(.22,1,.36,1),opacity .22s;
}

/* Draggable from the bottom-right. The element is centred with a transform, so a drag
   grows it about its own centre — it stays put rather than walking off toward a
   corner. */

.modal.open {
  transform: translate(-50%,-50%);
  opacity: 1;
  pointer-events: auto;
  resize: both;
}

/* The native grip is nearly invisible on a dark panel, so one is drawn in the corner
   of the actions row, where there is always space for it. */

.modal-actions {
  position: relative;
}

.modal-actions:after {
  content: "";
  position: absolute;
  right: 5px;
  bottom: 5px;
  width: 11px;
  height: 11px;
  opacity: .5;
  pointer-events: none;
  background:
    linear-gradient(135deg,transparent 46%,#8b8494 46%,#8b8494 60%,transparent 60%),
    linear-gradient(135deg,transparent 72%,#8b8494 72%,#8b8494 86%,transparent 86%);
}

.modal-top {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 20px 20px 10px;
}

.modal-heading {
  min-width: 0;
  flex: 1;
}

.modal h2 {
  margin: 0;
  font-size: 21px;
  letter-spacing: -.03em;
}

.modal-subtitle {
  margin: 5px 0 0;
  overflow: hidden;
  color: var(--muted);
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.modal-close {
  width: 30px;
  height: 30px;
  flex: none;
  border: 1px solid #3b3741;
  border-radius: 50%;
  background: #211f26;
  color: #ddd;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

/* min-height:0 or the body cannot scroll inside the flex column. */

.modal-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 6px 20px 4px;
}

.modal-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 20px 18px;
}

.modal-status {
  flex: 1;
  min-width: 0;
  color: #e6a5a5;
  font-size: 12px;
}

/* A form's buttons follow the same dimension rules as the rest of the app: the shared
   116px minimum, 42px height and 14px radius. Cancel was a 61px pill beside a 124px
   confirm, which read as two unrelated controls rather than one pair. */

.modal-actions .modal-confirm {
  min-width: 116px;
  padding: 14px 16px;
  border: 0;
  border-radius: 14px;
  background: linear-gradient(145deg,#b39bf0,#9b7fe8);
  color: #1a1225;
  font: 700 14px/1 Inter,system-ui,sans-serif;
  text-align: center;
  cursor: pointer;
  transition: filter .18s,transform .18s;
}

.modal-actions .modal-confirm:hover:not(:disabled) {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

/* Beats .ghost, which is a small outline pill and sets its own padding and radius. */

.modal-actions .modal-cancel {
  min-width: 116px;
  padding: 13px 15px;
  border: 1px solid #4a4458;
  border-radius: 14px;
  background: #1f1d27;
  color: #ded9e8;
  font: 700 14px/1 Inter,system-ui,sans-serif;
  text-align: center;
  cursor: pointer;
  transition: filter .18s,transform .18s,background .18s;
}

.modal-actions .modal-cancel:hover:not(:disabled) {
  background: #2a2635;
  transform: translateY(-1px);
}

.modal-actions .modal-confirm:disabled,
.modal-actions .modal-cancel:disabled {
  opacity: .45;
  cursor: default;
  transform: none;
}

.modal-field {
  display: block;
  margin-bottom: 14px;
}

.modal-field > span {
  display: block;
  margin-bottom: 6px;
  color: #cfcbd8;
  font-size: 12px;
  font-weight: 600;
}

.modal-field em {
  color: var(--muted);
  font-style: normal;
  font-weight: 400;
}

.modal-field input[type=text],
.modal-field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #3a3743;
  border-radius: 11px;
  background: #16151b;
  color: #ece9f2;
  font: 400 14px/1.45 Inter,system-ui,sans-serif;
  resize: vertical;
}

.modal-field input[type=text]:focus,
.modal-field textarea:focus {
  outline: 2px solid #9b7fe8;
  outline-offset: 1px;
}

/* Kept beside the rules it overrides rather than in one of the six other
   reduced-motion blocks: a media override separated from its base rule is what
   made the by-concern CSS split unsafe. */

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

  .modal {
    transform: translate(-50%,-50%);
  }
}

/* The add-to-playlist picker. */

.playlist-picker {
  max-height: 260px;
  overflow-y: auto;
  margin-bottom: 12px;
  border: 1px solid #2c2933;
  border-radius: 12px;
  background: #141319;
}

.picker-status {
  padding: 16px 13px;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}

.playlist-option {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 13px;
  border: 0;
  border-bottom: 1px solid #221f29;
  background: transparent;
  color: #ddd8e6;
  font: 500 13px/1.3 Inter,system-ui,sans-serif;
  text-align: left;
  cursor: pointer;
}

.playlist-option:last-child {
  border-bottom: 0;
}

.playlist-option:hover:not(:disabled) {
  background: #201d29;
}

.playlist-option.selected {
  background: #2d2440;
  box-shadow: inset 3px 0 0 #9b7fe8;
}

.playlist-option:disabled {
  opacity: .5;
  cursor: default;
}

.playlist-option-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.playlist-option-meta {
  flex: none;
  color: var(--muted);
  font-size: 11px;
}

.playlist-create-inline {
  width: 100%;
  margin-bottom: 4px;
  padding: 9px 11px;
}

/* Playlist cover: the uploaded image, and its preview in the create form. */

/* Above the cover's decorative ::before, which paints a radial gradient at full
   opacity and only fades to .16 on hover — so an uploaded cover was visible only while
   the pointer was over it. The overlay is a backdrop for the MusiCat artwork; a real
   image replaces it rather than sitting under it. */

.playlist-cover-image {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  border-radius: 16px;
  object-fit: cover;
}

/* No backdrop at all behind a real cover: the image IS the artwork. */

.library-cover.has-cover-image:before {
  display: none;
}

/* `display:block` would override the hidden attribute, which is how the empty preview
   showed as a bordered square before any file was chosen. */

.playlist-image-preview:not([hidden]) {
  display: block;
  width: 84px;
  height: 84px;
  margin-bottom: 14px;
  border: 1px solid #3a3743;
  border-radius: 14px;
  object-fit: cover;
}

.modal-field input[type=file] {
  width: 100%;
  color: #cfcbd8;
  font: 400 13px/1.4 Inter,system-ui,sans-serif;
}

.modal-field input[type=file]::file-selector-button {
  margin-right: 10px;
  padding: 7px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #17171c;
  color: #cfcfd5;
  font-size: 12px;
  cursor: pointer;
}

.modal-field input[type=file]::file-selector-button:hover {
  background: #201d29;
}

/* Playlist card menu: a separator, and Delete in red.

   The separator sets the destructive item apart from the three that are not, so Delete
   is never the neighbour of a routine action. It hides with the button during the
   confirm step, or it would float above an explanation with nothing under it. */

.commands-panel .command-separator {
  height: 1px;
  margin: 5px 6px;
  background: #322e3c;
}

.commands-panel .command.command-danger {
  color: #ff7b7b;
}

.commands-panel .command.command-danger svg {
  stroke: currentColor;
}

.commands-panel .command.command-danger:hover:not(:disabled) {
  background: #3a1f26;
  color: #ff9a9a;
}

/* The playlist card's "..." matches the library card's placement. */

.playlist-card .card-menu {
  position: absolute;
  top: 8px;
  right: 8px;
}

.playlist-card .commands-panel {
  top: 42px;
  right: 8px;
}

/* Multi-select song picker: a count, a Clear, and a checkbox per row. */

.picker-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 7px;
}

.picker-count {
  color: var(--muted);
  font-size: 12px;
}

.picker-clear {
  padding: 5px 10px;
  font-size: 11px;
}

/* The box is drawn rather than an <input>, so the whole row stays one button: a nested
   checkbox would take its own click and split the hit target. */

.picker-check {
  width: 16px;
  height: 16px;
  flex: none;
  border: 1px solid #4a4658;
  border-radius: 5px;
  background: #1b1922;
  transition: background .14s,border-color .14s;
}

.playlist-option.selected .picker-check {
  border-color: #9b7fe8;
  background: #9b7fe8 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-6' fill='none' stroke='%231a1225' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/13px no-repeat;
}

.playlist-option:disabled .picker-check {
  border-style: dashed;
}

/* The name takes the slack so the check and the meta keep their size. */

.playlist-option .playlist-option-name {
  flex: 1;
}

/* On a phone the subtitle was winning the row and squeezing titles to "R…". The title
   is what someone picks a song by, so it keeps its width and the metadata yields. */

@media (max-width:600px) {
  .playlist-option {
    flex-wrap: wrap;
    row-gap: 2px;
  }

  .playlist-option .playlist-option-name {
    flex: 1 0 auto;
    max-width: calc(100% - 26px);
  }

  .playlist-option .playlist-option-meta {
    flex: 1 0 100%;
    margin-left: 26px;
    text-align: left;
  }
}

/* ---------------------------------------------------------------------------
   Collections — the shared grid/list used by Library, Playlists and a playlist.

   Both views render the SAME card markup and differ only here. Two templates
   would be two things to keep in step, and the row/tile distinction is layout,
   not content.
   --------------------------------------------------------------------------- */

.collection-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-bottom: 14px;
}

/* The page's own action sits left, the layout toggle right. */

.collection-toolbar > :first-child:not(.view-toggle) {
  margin-right: auto;
}

.view-toggle {
  display: inline-flex;
  flex: none;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #15141a;
}

.view-toggle-option {
  width: 32px;
  height: 28px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #8b8494;
  cursor: pointer;
  transition: background .16s,color .16s;
}

.view-toggle-option:hover {
  color: #e6e0ee;
}

.view-toggle-option.active {
  background: #2d2440;
  color: #d9c9ff;
}

.view-toggle-option svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
}

/* The grid icon's squares read better filled than outlined at 16px. */

.view-toggle-option svg rect {
  fill: currentColor;
  stroke: none;
}

.view-toggle-option svg circle {
  fill: currentColor;
  stroke: none;
}

.collection-items {
  display: grid;
  gap: 12px;
}

.collection-grid .collection-items {
  grid-template-columns: repeat(2,minmax(0,1fr));
}

/* List: one column, a shorter cover, and room for the title to breathe. */

.collection-list .collection-items {
  grid-template-columns: minmax(0,1fr);
  gap: 8px;
}

.collection-list .collection-card {
  grid-template-columns: 48px minmax(0,1fr);
  padding: 10px 12px;
  border-radius: 14px;
}

.collection-list .collection-card .library-cover {
  width: 48px;
  height: 48px;
  border-radius: 12px;
}

.collection-list .collection-card h3 {
  margin-bottom: 2px;
  font-size: 15px;
}

.collection-more-wrap {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}

@media (max-width:680px) {
  .collection-grid .collection-items {
    grid-template-columns: minmax(0,1fr);
  }
}

/* ---------------------------------------------------------------------------
   A single playlist's page.
   --------------------------------------------------------------------------- */

.playlist-page-head {
  margin-bottom: 20px;
}

.playlist-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 16px;
}

.playlist-back svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.playlist-page-identity {
  display: flex;
  align-items: flex-end;
  gap: 18px;
}

.playlist-page-cover {
  width: 132px;
  height: 132px;
  flex: none;
  position: relative;
  display: grid;
  place-items: center;
  border-radius: 20px;
  box-shadow: 0 16px 40px #0007;
}

.playlist-page-cover .playlist-cover-image {
  border-radius: 20px;
}

.playlist-page-copy {
  min-width: 0;
  flex: 1;
}

.playlist-page-copy h1 {
  margin: 4px 0 0;
  overflow-wrap: anywhere;
}

.playlist-page-description {
  margin: 8px 0 6px;
  max-width: 62ch;
  color: #c8c3d2;
  font-size: 13px;
  line-height: 1.55;
}

.playlist-page-actions {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
}

/* The layout toggle sits at the far end of the same row, so the page has one strip of
   controls rather than a second toolbar directly beneath the first. */

.playlist-page-actions .view-toggle {
  margin-left: auto;
}

@media (max-width:680px) {
  .playlist-page-identity {
    align-items: flex-start;
    gap: 14px;
  }

  .playlist-page-cover {
    width: 92px;
    height: 92px;
    border-radius: 16px;
  }

  .playlist-page-copy h1 {
    font-size: 25px;
  }
}

/* The playlist page hosts the toggle in its actions row, so the collection's own
   toolbar is not rendered and its spacing must not be assumed. */

.playlist-page-head + .collection .collection-items {
  margin-top: 4px;
}

/* ---------------------------------------------------------------------------
   Desktop topbar: search, notifications and account.

   The header spans both columns of the body grid, with the sidebar and shell
   beneath it. The logo lives here rather than in the sidebar, so there is one
   of it.
   --------------------------------------------------------------------------- */

.topbar-search {
  position: relative;
  display: none;
  flex: 1;
  align-items: center;
  max-width: 460px;
}

.topbar-search-icon {
  position: absolute;
  left: 11px;
  width: 15px;
  height: 15px;
  fill: none;
  stroke: #8b8494;
  stroke-width: 2;
  stroke-linecap: round;
  pointer-events: none;
}

.topbar-search input[type=search] {
  width: 100%;
  padding: 9px 32px 9px 34px;
  border: 1px solid #2c2933;
  border-radius: 999px;
  background: #15141a;
  color: #ece9f2;
  font: 400 13px/1 Inter,system-ui,sans-serif;
  /* Safari draws its own clear affordance and a magnifier; both duplicate ours. */
  appearance: none;
}

.topbar-search input[type=search]::-webkit-search-decoration,
.topbar-search input[type=search]::-webkit-search-cancel-button {
  appearance: none;
}

.topbar-search input[type=search]:focus {
  outline: 2px solid #9b7fe8;
  outline-offset: 1px;
}

.topbar-search-clear[hidden] {
  display: none;
}

.topbar-search-clear {
  position: absolute;
  right: 8px;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #2a2733;
  color: #cfcbd8;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.search-results {
  position: absolute;
  top: 40px;
  left: 0;
  right: 0;
  z-index: 120;
  max-height: 360px;
  overflow-y: auto;
  padding: 5px;
  border: 1px solid #3a3743;
  border-radius: 14px;
  background: #1a1921;
  box-shadow: 0 18px 44px #000a;
}

.search-group-label {
  padding: 7px 9px 4px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.search-result {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 9px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: #d8d3e0;
  font: 500 13px/1.3 Inter,system-ui,sans-serif;
  text-align: left;
  cursor: pointer;
}

.search-result:hover,
.search-result.active {
  background: #262331;
}

.search-result-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-result-meta {
  flex: none;
  color: var(--muted);
  font-size: 11px;
}

.search-empty {
  padding: 14px 10px;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}

.topbar-icon-button {
  position: relative;
  display: none;
  width: 36px;
  height: 36px;
  flex: none;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #b7b1c2;
  cursor: pointer;
  transition: background .16s,color .16s;
}

.topbar-icon-button:hover,
.topbar-icon-button[aria-expanded=true] {
  background: #221f29;
  color: #e6e0ee;
}

.topbar-icon-button svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.notification-dot {
  position: absolute;
  top: 7px;
  right: 8px;
  width: 8px;
  height: 8px;
  border: 2px solid #0a0a0c;
  border-radius: 50%;
  background: #ff648d;
}

.notification-tray {
  position: fixed;
  z-index: 120;
  top: 56px;
  right: 14px;
  width: min(340px,calc(100vw - 28px));
  max-height: min(440px,calc(100dvh - 80px));
  display: flex;
  flex-direction: column;
  border: 1px solid #3a3743;
  border-radius: 16px;
  background: #1a1921;
  box-shadow: 0 18px 44px #000a;
}

.notification-tray[hidden] {
  display: none;
}

.notification-tray-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 13px 14px 9px;
}

.notification-tray-head h2 {
  margin: 0;
  font-size: 15px;
}

.notification-clear {
  padding: 5px 10px;
  font-size: 11px;
}

.notification-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 7px 9px;
}

.notification-item {
  width: 100%;
  display: block;
  padding: 9px 9px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: #d8d3e0;
  font: 500 13px/1.35 Inter,system-ui,sans-serif;
  text-align: left;
  cursor: pointer;
}

.notification-item:hover {
  background: #262331;
}

.notification-item time {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 400;
}

.notification-empty {
  padding: 22px 12px;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}

@media (min-width:1001px) {
  .topbar-search,
  .topbar-icon-button {
    display: flex;
  }

  .topbar-icon-button {
    display: grid;
  }

  /* The logo anchors the bar; the nav and provider label belong to the phone
     header and would crowd a bar that now has search in it. */
  .app-header .nav,
  .app-header .provider,
  .app-header .grow {
    display: none;
  }

  /* Search takes the middle and the account controls sit at the right edge, which
     is where every other desktop app puts them. */

  /* Three equal columns centre the middle cell by construction. Absolute positioning
     was resolving against the wrong containing block and landed the box at the far
     right; a grid needs no containing block at all. */
  .app-header {
    display: grid;
    grid-template-columns: 1fr minmax(0,auto) 1fr;
    align-items: center;
  }

  .topbar-search {
    justify-self: center;
    width: min(620px,42vw);
    max-width: none;
  }

  .topbar-search input[type=search] {
    padding: 14px 42px 14px 46px;
    border-radius: 999px;
    font-size: 15px;
  }

  .topbar-search-icon {
    left: 17px;
    width: 19px;
    height: 19px;
  }

  .topbar-search-clear {
    right: 12px;
    width: 25px;
    height: 25px;
    font-size: 17px;
  }

  .search-results {
    top: 56px;
  }

  .topbar-icon-button {
    width: 50px;
    height: 50px;
  }

  .topbar-icon-button svg {
    width: 26px;
    height: 26px;
  }

  .notification-dot {
    top: 11px;
    right: 12px;
    width: 10px;
    height: 10px;
  }

  .app-header .account-trigger {
    padding: 7px 17px 7px 7px;
    gap: 11px;
    font-size: 15px;
  }

  .app-header .account-avatar {
    width: 38px;
    height: 38px;
    font-size: 15px;
  }

  .app-header .brand-logo {
    justify-self: start;
  }

  /* The bell and the account button share the last cell, so they are wrapped in a
     flex row rather than both claiming column 3 — two grid items in one cell stack
     on separate rows, which dropped the account button below the bar. */
  .app-header .topbar-end {
    grid-column: 3;
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .app-header .brand-logo {
    flex: none;
    margin-right: 6px;
  }

  /* 3:1 artwork, so 196px is 65px tall and still clears the 72px bar. The inherited
     object-fit:cover was cropping it against a shorter button; `contain` shows the
     whole wordmark. */
  .app-header .brand-logo {
    height: auto;
  }

  .app-header .brand-logo img {
    width: 196px;
    height: auto;
    object-fit: contain;
  }
}

/* Only the desktop pane shows an empty state; elsewhere a hidden player is hidden. */

.global-player-empty {
  display: none;
}

/* The account panel opens beneath the topbar rather than over it, so the button that
   opened it stays visible and its toggle state is legible. */

@media (min-width:1001px) {
  .account-panel {
    top: calc(var(--topbar-h,72px) + 8px);
    bottom: 12px;
  }

  .account-backdrop {
    top: var(--topbar-h,72px);
  }
}

/* The pane grips sit above the shell, but the account panel is a dialog above both.
   At z-60 against the panel's z-51 the player grip drew a line across it. */

.account-panel.open ~ .pane-grip,
body:has(.account-panel.open) .pane-grip {
  z-index: 40;
}

/* Always open, at every desktop width. Between 1001 and 1250 a full 392px pane would
   leave the chat under 400px — narrower than a phone — so the pane narrows instead of
   vanishing. The grip can still widen it. */

@media (min-width:1001px) and (max-width:1249px) {
  .shell {
    grid-template-columns: minmax(0,1fr) var(--player-w,300px);
  }
}

/* Song chips, shared by every card. The first genre is what identifies a song at a
   glance, so it carries the emphasis and the rest recede. */

/* Tinted by the genre's own family colour, the same way .genre-family is in the
   onboarding chooser — a genre should look the same wherever it appears rather than
   purple on a card and yellow in the composer. --genre is set inline per chip and
   falls back to the app's accent for a genre no family claims. */

.tag-primary {
  --genre: #b78dde;
  border-color: color-mix(in srgb,var(--genre) 60%,#343039);
  background: color-mix(in srgb,var(--genre) 18%,#17151c);
  color: color-mix(in srgb,var(--genre) 55%,#ffffff);
  font-weight: 700;
}

.tag-more {
  color: var(--muted);
  cursor: default;
}

/* On a collection card the row sits under the subtitle and must not push the tile
   taller than its cover, so the chips are a touch smaller than the chat card's. */

.collection-card .card-tags {
  margin-top: 7px;
  gap: 4px;
}

.collection-card .card-tags .tag {
  padding: 2px 7px;
  font-size: 10px;
}

/* Three rows in list view too: title, subtitle, chips. Laying them out side by side
   to keep the row short put the chips on the same line as the title, which reads as
   one long strip rather than as a song with attributes. */

.collection-list .collection-card .card-tags {
  margin-top: 6px;
}

/* A genre chip is a button now: it filters the library by that genre. */

.tag-genre {
  cursor: pointer;
  transition: filter .16s,transform .16s;
}

.tag-genre:hover {
  filter: brightness(1.25);
  transform: translateY(-1px);
}

.tag-genre:focus-visible {
  outline: 2px solid var(--genre,#9b7fe8);
  outline-offset: 2px;
}

/* What the list is currently narrowed to, and the way out of it. */

.collection-filter-note {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
  padding: 9px 14px;
  border: 1px solid #2c2933;
  border-radius: 12px;
  background: #15141a;
  color: var(--muted);
  font-size: 13px;
}

.collection-filter-clear {
  flex: none;
  padding: 5px 11px;
  font-size: 11px;
}

/* A hidden card must not hold its grid cell open. */

.collection-card[hidden] {
  display: none;
}
