﻿/* ---------- Create sheet ---------- */

.createhead {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 14px 14px 4px 20px;
}
.createhead h1 {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 4px;
  text-transform: uppercase;
  flex: 1;
}

.createbody {
  padding: 6px 20px calc(24px + var(--safe-bottom));
  /* Stretch to fill the sheet so the pager viewport covers the whole area
     between the tabs and the Generate button - swipes work everywhere. */
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}

/* Prompt/Lyrics: mock underline tabs, uppercase + tracked */
.createtabs .tabbar { margin-top: 10px; }
.createtabs .tabbar button {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 2.5px;
  text-transform: uppercase;
}

.formarea { margin-top: 8px; flex: 1 1 auto; display: flex; flex-direction: column; }

/* Prompt/Lyrics pager: horizontal finger-follow swiping between the two pages
   (makePager drives the track transform). Vertical gestures stay native so the
   sheet keeps scrolling; the gogen button sits OUTSIDE the pager. */
.form-viewport {
  position: relative;
  overflow: hidden;
  touch-action: pan-y;
  flex: 1 1 auto;
}
.form-track { display: flex; align-items: flex-start; will-change: transform; }
.form-page { flex: 0 0 100%; width: 100%; min-width: 0; }
.promptta, .lyricsta {
  resize: none;
  border-radius: 16px;
  line-height: 1.5;
  font-size: 14px;
}
.hint { font-size: 11px; color: var(--text-2); padding: 8px 4px; line-height: 1.5; }

/* Prompt card: one bordered card holding the textarea, the expand affordance
   and a footer (surprise me + char counter) - the mock's big input block. */
.promptcard {
  position: relative;
  margin-top: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
}
.promptcard .promptta {
  background: transparent;
  border: none;
  border-radius: 18px;
  padding: 16px 46px 6px 16px;
  font-size: 14px;
  line-height: 1.65;
  min-height: 120px;
}
.promptcard .promptta::placeholder {
  color: var(--muted);
  letter-spacing: 1.4px;
  font-size: 14px;
}
.promptcard .taexpand { top: 12px; right: 12px; }
.taexpand[hidden] { display: none; }
/* Footer right group: quiet Clear button + char counter */
.pcfootright { display: flex; align-items: center; gap: 14px; min-width: 0; }
.pclear {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--text-2);
  padding: 6px 2px;
}
.pclear svg { width: 12px; height: 12px; }
.pclear:active { color: var(--text); }
/* Hidden via visibility (NOT display:none): the button is the tallest item in
   the footer row, and removing it from layout shrank the card 8px on every
   clear - the box visibly jumped. Kept in flow it holds the row height, and
   the space-between footer looks identical in both states. */
.pclear[hidden] { visibility: hidden; }
.promptcard .pcfoot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px 13px;
}
/* Lyrics "I'll write mine" reuses the prompt card chrome (.promptcard) - the
   textarea just needs its own breathing room and no base input chrome. */
.promptcard .lyricsta {
  background: transparent;
  border: none;
  padding: 16px 46px 6px 16px;
  min-height: 150px;
  line-height: 1.65;
}
.surprisebtn {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--text-2);
}
.surprisebtn svg { width: 17px; height: 17px; flex-shrink: 0; }
.surprisebtn:active { color: var(--text); }
.pcount {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.5px;
  font-variant-numeric: tabular-nums;
}

/* Prompt Builder / Refine: spread to the sheet edges (mock), no divider */
.toolrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 14px;
  padding: 2px 6px;
}
.toolbtn {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  color: var(--text);
}
.toolbtn svg { width: 17px; height: 17px; flex-shrink: 0; }
.toolbtn:disabled { opacity: 0.5; }
.tooldiv { display: none; }

/* Advanced: a quiet text row under the tool row that opens the settings
   bottom sheet (slide-up + scrim - the app's standard reveal). The row
   mirrors the current values; the sheet carries the actual controls. */
.advopen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  line-height: 15px;
  transition: opacity 0.15s ease;
}
/* .advrow (same specificity, later in this file) would win the padding war -
   this compound selector keeps the geometry: 10px left aligns the label with
   the tool row's icon column; 16px right aligns the meta with REFINE. */
.advrow.advopen {
  padding: 12px 6px 12px 10px;
}
.advopen:active { opacity: 0.6; }
.advopen .advlabel {
  padding: 0;
  font-size: 12px;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  color: var(--text);
}
.advmeta { display: flex; align-items: center; gap: 10px; }
.advval {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.5px;
  text-transform: none;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.advopen svg { width: 15px; height: 15px; color: var(--muted); }
.bubblesheet.advsheet {
  /* Like the prompt builder: a fixed shorter sheet keeps the create page
     (prompt card) visible above. Flex column + hidden sheet overflow so the
     grab + title stay PINNED while only .advbody scrolls under them. */
  height: 60vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.advsheet .ashead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 14px 2px;
}
.advsheet .ashead .bstitle { padding: 4px 0 8px; }
.advsheet .advbody {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior-y: none; /* clamp hard at the top edge: no chaining */
  padding: 0 4px 4px;
}
.advrow { padding: 13px 0; }
.advrow + .advrow { border-top: 1px solid var(--border); }
.advlabelrow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.advlabelrow .advlabel { padding: 0; }
.advlabel {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: #c9c9ce;
  padding: 2px 0 8px;
}
.sliderrow { display: flex; align-items: center; gap: 12px; }
.slidelabel {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
  flex-shrink: 0;
}

/* Monochrome range: strip the global input chrome, hairline track with a
   center notch (the slider is bipolar: -1 style .. +1 literal), white thumb */
.guidslider {
  -webkit-appearance: none;
  appearance: none;
  flex: 1;
  min-width: 0;
  height: 26px;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
  margin: 0;
}
.guidslider::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background:
    linear-gradient(90deg, transparent calc(50% - 1px), rgba(255, 255, 255, 0.55) calc(50% - 1px), rgba(255, 255, 255, 0.55) calc(50% + 1px), transparent calc(50% + 1px)),
    rgba(255, 255, 255, 0.16);
}
.guidslider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  margin-top: -7px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.55);
  transition: transform 0.15s ease;
}
.guidslider:active::-webkit-slider-thumb { transform: scale(1.18); }
.guidslider::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.16);
}
.guidslider::-moz-range-thumb { width: 18px; height: 18px; border: none; border-radius: 50%; background: #fff; }

/* Accidental-touch protection: the native input is inert - the wrapper owns
   the gesture and only answers to genuinely horizontal drags (touch-action
   pan-y hands vertical swipes straight back to the sheet's scroll). */
.guidwrap { touch-action: pan-y; }
.guidslider { pointer-events: none; }

/* Text-only option rows (lyrics modes, builder options, draft-sheet options):
   one tag language everywhere. Tags are the sheet's payload - large, airy,
   calm tracking; selection is color-only (no reflow), bold via text-stroke. */
.modes { display: flex; flex-wrap: nowrap; justify-content: center; gap: 0 4px; padding: 10px 0 4px; }
.pbopt, .pb-chips .chip, .dschips .chip {
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 10px 14px 10px 0;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #9a9aa0;
  flex-shrink: 1;
  transition: color 0.18s ease, transform 0.16s cubic-bezier(0.2, 0.7, 0.3, 1);
}
/* The three lyric modes must share ONE row - compact + nowrap */
.modes .pbopt {
  font-size: 11.5px;
  letter-spacing: 1.2px;
  padding: 10px 10px;
  white-space: nowrap;
  flex: 0 0 auto;
}
.pbopt.on, .pb-chips .chip.on, .dschips .chip.on {
  background: transparent;
  border-color: transparent;
  color: #fff;
  -webkit-text-stroke: 0.4px #fff;
}
.pbopt:active, .pb-chips .chip:active, .dschips .chip:active { transform: scale(0.96); }

/* Model selection cards (Advanced drawer): two large photographic cards -
   radio dot, name + one-liner on the left, a hairline divider, then a right
   column of icon features. Each model paints its own CSS-only backdrop art
   (Suno = violet nebula glow, Treblo = amber vinyl rings); the selected card
   gains a violet border + soft glow. */
.modelrow { padding-top: 12px; padding-bottom: 12px; }
.mchead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 0 10px;
}
.mctitle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text);
}
.mctitle svg { width: 14px; height: 14px; color: var(--text-2); }
.modelcards { display: flex; flex-direction: column; gap: 10px; }
/* Vertical card: name row (radio + big name), one-liner, then a hairline and
   a 3-column icon-over-label feature strip. Flat black - selection is a clean
   white border + slightly lifted surface, no gradients. */
.modelcard {
  display: flex;
  flex-direction: column;
  gap: 5px;
  width: 100%;
  text-align: left;
  background: #0b0b0e;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 16px;
  padding: 14px 16px 12px;
  transition: border-color 0.16s ease, background 0.16s ease;
}
.modelcard:active { background: #121218; }
.modelcard.sel {
  border-color: #fff;
  background: #111117;
}
.mctop { display: flex; align-items: center; gap: 11px; }
.mcradio {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.45);
  flex-shrink: 0;
  transition: border-color 0.16s ease, background 0.16s ease;
}
.modelcard.sel .mcradio { border-color: #fff; background: radial-gradient(circle, #fff 0 4.5px, transparent 5px); }
.mcname {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #fff;
}
.mcsub { font-size: 10.5px; line-height: 1.35; color: #c9c9ce; }
.mcfeats {
  display: flex;
  margin-top: 7px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.mcf {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.mcf svg { width: 15px; height: 15px; color: #d2d2d8; flex-shrink: 0; }
.mcf i {
  font-style: normal;
  font-size: 9px;
  line-height: 1.3;
  text-align: center;
  letter-spacing: 0.2px;
  color: #e2e2e6;
  white-space: nowrap;
}

/* Song length: 2x2 mini-cards - one visual language with the model cards
   above (flat black surface, white selection). */
.lengrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 2px;
}
.lencard {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  background: #0b0b0e;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  padding: 10px 13px;
  transition: border-color 0.16s ease, background 0.16s ease;
}
.lencard.sel {
  border-color: #fff;
  background: #111117;
}
.lencard:active { background: #121218; }
.lcname {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: #fff;
}
.lcsub { font-size: 9.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* Avoid-styles input (negative tags, both engines) - matches the model-card
   surface; focus picks up the selection violet. */
.neginput {
  display: block;
  width: 100%;
  box-sizing: border-box;
  background: #0a0a0e;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  padding: 12px 14px;
  outline: none;
  transition: border-color 0.16s ease;
}
.neginput::placeholder { color: var(--muted); }
.neginput:focus { border-color: rgba(255, 255, 255, 0.45); }

/* Avoid-styles quick picks: tappable tag suggestions that toggle into the
   input - the text stays fully editable and the chips re-sync from it. */
.negchips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }
.negchip {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.13);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.4px;
  color: var(--text-2);
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.negchip.on {
  background: rgba(255, 255, 255, 0.13);
  border-color: rgba(255, 255, 255, 0.75);
  color: #fff;
}
.negchip:active { opacity: 0.7; }

.formfoot { padding-top: 14px; }
.gogen span, .gogen {
  text-transform: uppercase;
  letter-spacing: 3px;
  font-size: 13px;
}
.gogen svg { width: 17px; height: 17px; }

/* Prompt Builder / Refine row under the prompt textarea (legacy ghost row) */
.prow { display: flex; gap: 8px; margin-top: 10px; }
.prow .ghostbtn { flex: 1; padding: 11px 10px; font-size: 13px; gap: 4px; }
.prow .ghostbtn svg { width: 15px; height: 15px; flex-shrink: 0; }
.prow .ghostbtn:disabled { opacity: 0.55; }

/* ---------- Prompt Builder sheet (~48vh, prompt field above stays visible) ---------- */

/* Transparent tap-catcher: click outside closes, but the prompt above the
   sheet is NOT dimmed - it must stay readable while building. */
.pbcatcher {
  position: absolute;
  inset: 0;
  z-index: 54; /* above .sheet (53) */
  background: transparent;
}

.buildersheet {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 48vh;
  display: flex;
  flex-direction: column;
  /* Same tone family as the prompt card, a step above the black form behind
     it; the hairline top edge is the same edge language as the mini bar. */
  background: #101013;
  border-top: 1px solid var(--border);
  border-radius: 22px 22px 0 0;
  padding: 8px 0 calc(12px + var(--safe-bottom));
  z-index: 55;
  transform: translateY(105%);
  transition: transform 0.26s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.buildersheet.open { transform: translateY(0); }
.buildersheet .grab {
  width: 36px; height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.22);
  margin: 2px auto 8px;
  flex-shrink: 0;
}

/* Sheet type scale (small -> large): group labels 10px captions, tabs 11px
   nav, tags 13px content, title 13px/800. The tags are the payload - they get
   the biggest size and the calmest tracking; everything else steps down. */
.pbhead { padding: 0 16px 6px; flex-shrink: 0; display: flex; align-items: center; }
.pbtitle { font-size: 15px; font-weight: 700; flex: 1; letter-spacing: 3px; text-transform: uppercase; }
.pbclear {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-2);
  padding: 6px 2px;
}
.pbclear:active { color: var(--text); }


.pb-tabs {
  position: relative; /* hosts the sliding .pbind underline */
  display: flex;
  gap: 2px;
  overflow-x: auto;
  padding: 0 16px;
  flex-shrink: 0;
  scrollbar-width: none;
  border-bottom: 1px solid var(--border);
}
.pb-tabs::-webkit-scrollbar { display: none; }
.pbpill {
  flex-shrink: 0;
  padding: 12px 13px 13px;
  border-radius: 0;
  background: transparent;
  color: var(--text-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  border: none;
}
.pbpill.on {
  background: transparent;
  color: #fff;
  font-weight: 800;
}
.pbpill:active { color: var(--text); }
/* Sliding pill underline (same rubber-band language as .tabind, but
   pixel-positioned: pills hug their labels and the row scrolls). The bar
   spans the pill minus a small inset; --stretch pushes it past the edges. */
.pb-tabs .pbind {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 2px;
  pointer-events: none;
  transition:
    transform 0.32s cubic-bezier(0.3, 1.25, 0.4, 1),
    width 0.32s cubic-bezier(0.3, 1.25, 0.4, 1),
    --stretch 0.34s cubic-bezier(0.3, 1.35, 0.45, 1);
  will-change: transform, width;
}
.pb-tabs .pbind::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(4px - var(--stretch, 0) * 6px);
  right: calc(4px - var(--stretch, 0) * 6px);
  border-radius: 1px 1px 0 0;
  background: #fff;
}
.pb-tabs .pbind.notrans { transition: none; }
.pb-tabs .pbind.pulse::before { animation: pbindpulse 0.36s cubic-bezier(0.3, 0.9, 0.35, 1); }
@keyframes pbindpulse {
  0% { left: 4px; right: 4px; }
  38% { left: -2px; right: -2px; }
  70% { left: 5px; right: 5px; }
  100% { left: 4px; right: 4px; }
}

/* Horizontal pager viewport - custom transform-based paging (one page per
   swipe); pages pan vertically natively, horizontal gestures belong to JS. */
.pb-pages {
  flex: 1;
  min-height: 0;
  position: relative;
  overflow: hidden;
  touch-action: pan-y;
}
.pb-track {
  display: flex;
  height: 100%;
  will-change: transform;
  transition: transform 0.26s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.pb-page {
  flex: 0 0 100%;
  width: 100%;
  overflow-y: auto;
  padding: 8px 16px 6px;
}

/* Group labels: small muted captions ABOVE the tags (same treatment as the
   draft sheet's labels below). */
.pb-gname {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--muted);
  padding: 16px 0 2px;
}
.pb-chips { display: flex; flex-wrap: wrap; gap: 2px; }
.pb-chips .chip { padding: 10px 12px; font-size: 11.5px; }

/* ---------- Fullscreen text editor (prompt / lyrics) ---------- */

.tawrap { position: relative; }
.taexpand {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-2);
  background: rgba(0, 0, 0, 0.28);
}
.taexpand svg { width: 16px; height: 16px; }

.fsedit {
  position: absolute;
  inset: 0;
  z-index: 57;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  padding-top: var(--safe-top);
  transform: translateY(100%);
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.fsedit.open { transform: translateY(0); }
.fshead { display: flex; align-items: center; gap: 8px; padding: 12px 14px 8px 12px; }
.fstitle { font-size: 17px; font-weight: 800; flex: 1; }
.fscount { font-size: 11px; color: var(--text-2); font-weight: 600; white-space: nowrap; }
.fsdone { font-weight: 700; color: #fff; font-size: 14px; padding: 8px 10px; }
.fsta {
  flex: 1;
  width: auto;
  margin: 4px 16px calc(16px + var(--safe-bottom));
  font-size: 15px;
  line-height: 1.6;
  resize: none;
  border-radius: 16px;
  padding: 14px;
  background: var(--surface);
}

/* ---------- Draft Lyrics builder sheet ---------- */

.draftsheet {
  height: 56vh;
  z-index: 56; /* above the scrim (55), same layer as bubblesheets */
}

/* Compose mode (Optional idea focused): the sheet fills the visible area,
   tabs/pages hide, the text gets the whole space. */
.draftsheet.editing { height: 100%; border-radius: 0; }
.draftsheet.editing .grab,
.draftsheet.editing .pb-tabs,
.draftsheet.editing .pb-pages { display: none; }
.draftsheet .pbhead { display: flex; align-items: center; }
.draftsheet .pbheadtxt { flex: 1; min-width: 0; }
.ds-done {
  display: none;
  font-weight: 700;
  color: #fff;
  font-size: 14px;
  padding: 8px 10px;
}
.draftsheet.editing .ds-done { display: block; }

/* Tap-target look of the idea box on the Theme page */
.ds-idea-open {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px 12px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
  min-height: 58px;
  display: flex;
  align-items: flex-start;
}
.ds-idea-open.empty { color: var(--text-2); opacity: 0.7; }

/* The real textarea, only visible while composing */
.ds-idea-edit { display: none; }
.draftsheet.editing .ds-idea-edit {
  display: block;
  flex: 1;
  width: auto;
  min-height: 0;
  margin: 4px 0 8px;
  font-size: 15px;
  line-height: 1.6;
  resize: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 12px 14px;
  color: var(--text);
}
.draftsheet.editing .dsfoot { border-top: none; padding-top: 0; }

.ds-note { font-size: 11px; color: var(--muted); padding: 2px 0 8px; line-height: 1.4; }
.ds-striphint { font-size: 11px; color: var(--muted); padding: 4px 2px; }
.ds-fieldlabel {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--muted);
  padding: 12px 0 4px;
}
.ds-grouplabel { font-size: 10px; font-weight: 600; letter-spacing: 1.4px; text-transform: uppercase; color: var(--muted); padding: 14px 0 2px; }
.dschips { display: flex; flex-wrap: wrap; gap: 2px; }
.dschips .chip.off { opacity: 0.35; }

/* Structure strip: tap a tag to append, tap a strip item to remove it */
.ds-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-content: flex-start;
  margin: 10px 0 0;
  padding: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  min-height: 46px;
  max-height: 96px;
  overflow-y: auto;
}
.ds-stripitem {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.4);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  border-radius: 50px;
  padding: 5px 10px;
}
.ds-stripitem .x { font-size: 11px; color: var(--text-2); }
.ds-striphint { font-size: 11px; color: var(--muted); padding: 4px 2px; }
.ds-striptools { display: flex; align-items: center; justify-content: space-between; padding: 8px 0 0; }
.ds-undobtn {
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  border-radius: 50px;
  padding: 7px 14px;
  background: var(--surface);
}


/* Sticky footer: live one-line summary + the action */
.dsfoot {
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  padding: 8px 16px calc(12px + var(--safe-bottom));
}
.dssummary {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-bottom: 8px;
  min-height: 12px;
}

/* ---------- Run cards (Create progress + Profile) ---------- */
/* Row-shaped on purpose: cover disc + title + sub, so the finish transition
   folds a "row" away instead of swapping layouts. */

.runcards { display: flex; flex-direction: column; gap: 10px; margin-bottom: 6px; }
/* Profile's Songs tab always renders the container (update target for live run
   cards) - an empty one must take zero space or its rows sit lower than Liked. */
.runcards:empty { margin-bottom: 0; }

.runcard, .failcard {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 8px 12px 8px 16px;
  overflow: hidden;
}
.failcard { flex-wrap: wrap; row-gap: 2px; }
.failcard .sub.failmsg { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }

/* A generating track is a NORMAL song row "in the making": identical row
   anatomy (gap/padding match .row exactly), a skeleton cover tile, and three
   bouncing dots on the right. Quiet on purpose - no icons, no sweep chrome. */
.runcard.gencard {
  background: transparent;
  border: none;
  border-radius: 0;
  gap: 10px;
  padding: 9px 12px 9px 16px;
}
/* right slot while generating: three softly bouncing dots (typing rhythm) */
.runside {
  width: 40px; height: 40px;
  flex-shrink: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}
.runside.gendots {
  flex-direction: row;
  gap: 4px;
}
.runside.gendots i {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--text-2);
  animation: gendot 1.2s ease-in-out infinite;
}
.runside.gendots i:nth-child(2) { animation-delay: 0.15s; }
.runside.gendots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes gendot {
  0%, 100% { opacity: 0.35; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(-3px); }
}

.runcard.entering, .failcard.entering { animation: cardenter 0.4s cubic-bezier(0.2, 0.8, 0.3, 1); }
@keyframes cardenter {
  from { opacity: 0; transform: translateY(10px) scale(0.98); }
}

/* finished/dismissed cards fold away (height set inline by collapseCard) */
.runcard.collapse, .failcard.collapse {
  height: 0 !important;
  opacity: 0;
  padding-top: 0;
  padding-bottom: 0;
  border-top-width: 0;
  border-bottom-width: 0;
  overflow: hidden;
  pointer-events: none;
  transition:
    height 0.32s ease,
    opacity 0.26s ease 0.04s,
    padding 0.32s ease,
    border 0.32s ease,
    margin 0.32s ease;
}
.runcard.collapse.eatbelow, .failcard.collapse.eatbelow { margin-bottom: -10px; }
.runcard.collapse.eatabove, .failcard.collapse.eatabove { margin-top: -10px; }

/* cover: a quiet skeleton tile while generating (shimmer inside the tile
   only), the AI art fades over it the moment it lands */
.runcover {
  width: 48px; height: 48px;
  border-radius: 6px;
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--elevated);
  color: var(--text-2);
}
.runcover.genskel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.09) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: gskelsweep 1.6s ease-in-out infinite;
}
@keyframes gskelsweep { to { transform: translateX(100%); } }
.runcover > svg { width: 24px; height: 24px; position: relative; }
.runcover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; animation: coverfade 0.45s ease; }
.runcover.faildisc { background: rgba(248, 113, 113, 0.12); color: var(--danger); }
@keyframes coverfade { from { opacity: 0; } }

.failrow { flex-basis: 100%; display: flex; gap: 10px; margin: 4px 0 6px; }
.failrow .retrybtn {
  background: #fff;
  color: #000;
  font-weight: 700;
  font-size: 12px;
  border-radius: 50px;
  padding: 8px 18px;
}
.failrow .dismissbtn {
  border: 1px solid var(--border);
  color: var(--text-2);
  font-weight: 700;
  font-size: 12px;
  border-radius: 50px;
  padding: 8px 18px;
}

/* create sheet badge on the nav disc */
.navcreate .disc { position: relative; }
.navcreate .badge {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--bg);
}
