/* P344 — the song page on a phone (the phone layout, phone-layout.ts, D415; src/studio/phone-song). Top to bottom: the song's 56px
   top bar, the video docked in the page (never floating), the live chords row, the sheet's toolbar, the chart (the
   only part that scrolls) and the player bar. All of it is CSS on the shell the desktop uses, so the first painted
   frame is the phone's (no fit after paint, the lesson of #479). Outside the phone layout none of this applies: the phone hosts
   don't show and the player bar's box is no box at all.

   Heights at 390×844 (Full, P616): bar 56, video 12 + 201, chords 42, tabs 42, the tab's body 387, player bar 104. */

.st-shell__phone-bar,
.st-shell__phone-video,
.st-shell__phone-tools,
.st-shell__phone-capo,
.st-shell__phone-shapes,
.st-shell__phone-play,
.st-shell__phone-tab,
.ph-lyrics { display: none; }
.st-shell__playbar { display: contents; }
/* More's Share and Print say "Link copied" here (phone-song/share.ts); empty, as it always is outside the phone layout, it's no box. */
.ph-share-status:empty { display: none; }

@media (max-width: 640px), (max-width: 900px) and (min-height: 700px) {
  /* ---- The page: exactly the screen, nothing scrolls but the chart ---------------------------------------- */
  .studio-page:has(.st-shell[data-screen='song']) { height: 100dvh; overflow: hidden; }
  .studio-page:has(.st-shell[data-screen='song']) .app { height: 100dvh; min-height: 0; }
  .st-shell[data-screen='song'] { height: 100dvh; min-height: 0; }
  .st-shell[data-screen='song'] .st-shell__body { flex-direction: column; overflow: hidden; }
  /* The centre's parts and the sheet's panel stack as one column; visible, so the docked video's clip ignores it. */
  .st-shell[data-screen='song'] .st-shell__center { display: contents; overflow: visible; }

  .st-shell[data-screen='song'] :is(
    .st-shell__topbar, .st-shell__notifications, .st-shell__library, .st-shell__edge,
    .st-shell__now, .st-shell__split, .legal, .st-shell__mixer, .st-clip
  ) { display: none; }
  /* shell.css shows a switched-off panel's tab at (0,4,0); a phone has no panels to bring back, so it outranks that. */
  :root .st-shell[data-screen='song'][data-library='off'] .st-clip--library,
  :root .st-shell[data-screen='song'][data-sheet='off'] .st-clip--sheet,
  :root .st-shell[data-screen='song'][data-live='off'] .st-clip--liveChords,
  :root .st-shell[data-screen='song'][data-mixer='off'] .st-clip--mixer { display: none; }

  /* ---- Top bar: ‹, the song, New song, Video, ⋮ (40 px each, no gap) ------------------------------------------ */
  /* The page's one side gutter (P357): the video, the view row, the chart and the play bar share this left edge. No
     viewport-fit=cover, so Safari keeps the page inside the safe areas itself. */
  .st-shell[data-screen='song'] { --ph-gutter: 12px; }
  .st-shell[data-screen='song'] .st-shell__top { gap: 4px; height: 56px; padding: 0 12px 0 4px; }
  /* Sticky like the Dashboard's .db-head, though nothing scrolls: iOS 26 Safari softly blurs a non-fixed, non-sticky
     top edge under its status bar, which blurred the song's title (P350; WebKit bug 301756). A sticky bar gets a solid
     tint instead. */
  .st-shell[data-screen='song'] .st-shell__top { position: sticky; top: 0; }
  /* ‹ back first, then the shell's ☰ (chart/index.html), then the title: the bar's box steps aside so ‹ can lead. */
  .st-shell[data-screen='song'] .st-shell__phone-bar { display: contents; }
  .st-shell[data-screen='song'] .ph-bar__back { order: -1; }

  /* ---- The column, in order -------------------------------------------------------------------------------- */
  .st-shell[data-screen='song'] .st-shell__phone-video { order: 1; display: block; flex: none; }
  .st-shell[data-screen='song'] .st-shell__live { order: 2; display: block; flex: none; height: auto; min-height: 0; }
  .st-shell[data-screen='song'] .st-shell__phone-tools { order: 3; display: flex; flex: none; }
  /* Stems, Metronome and Cues (P616): their body in the chart's place, and the chart, Shapes and the lyrics offer give way. */
  .st-shell[data-screen='song'][data-phone-tab] .st-shell__phone-tab { order: 4; display: block; flex: 1 1 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 12px var(--ph-gutter); }
  .st-shell[data-screen='song'][data-phone-tab] :is(.st-shell__sheet-host, .st-shell__right):has(> [data-slot='sheet']),
  .st-shell[data-screen='song'][data-phone-tab] :is(.st-shell__phone-capo, .st-shell__phone-shapes, .ph-lyrics) { display: none; }
  .ph-tab-body[hidden] { display: none; }
  /* One column the screen's width: an auto column grew to the Stems lanes' waveform bars and pushed the speakers off screen. */
  .ph-tab-body { grid-template-columns: minmax(0, 1fr); }
  .ph-tab-body:is([data-tab='metronome'], [data-tab='cues']):not([hidden]) { display: grid; gap: 8px; }
  .ph-tab-body[data-tab='stems']:not([hidden]) { display: grid; gap: 12px; align-content: start; }
  /* Stems: lanes near the screen's edge (the user: "big margin on both sides"); the notch's inset still wins in landscape. */
  .st-shell[data-screen='song'][data-phone-tab='stems'] .st-shell__phone-tab { padding-inline: max(4px, env(safe-area-inset-left, 0px)) max(4px, env(safe-area-inset-right, 0px)); }
  .st-shell[data-screen='song'] :is(.st-shell__sheet-host, .st-shell__right):has(> [data-slot='sheet']) {
    order: 4;
    display: flex;
    flex: 1 1 0;
    width: auto;
    min-width: 0;
    min-height: 0;
    max-height: none;
    border: 0;
  }
  .st-shell[data-screen='song'] :is(.st-shell__sheet-host, .st-shell__right):not(:has(> [data-slot='sheet'])) { display: none; }
  .st-shell[data-screen='song'] .st-shell__playbar { order: 5; display: grid; flex: none; padding-bottom: env(safe-area-inset-bottom, 0px); }
  /* The home indicator: 0 in Safari's tab (no viewport-fit=cover), its height once installed full screen. */
  .st-shell[data-screen='song'] .st-shell__player { display: block; }

  /* ---- The video (src/studio/phone-song/video.ts) ----------------------------------------------------------- */
  /* Full: edge to edge right under the top bar, square, 16:9 (the user's call: no white beside or above it), at least
     YouTube's 200px (the player letterboxes anything narrower than 356). Compact and Hidden set their own below. */
  .ph-video__box { box-sizing: border-box; width: 100%; min-height: 200px; margin: 0; aspect-ratio: 16 / 9; border-radius: 0; background: #000; }
  /* A small iPad or a squat window (870×800): 16:9 across its width would take most of the screen, so the box stops at
     45% of it and the player letterboxes inside (YouTube's 200px still the least). */
  .ph-video__box { max-height: 45dvh; }
  /* The player docked over it (youtube.css, a fixed .yt-mini, not inside the box) is square too while Full; Compact keeps 10px. */
  :root:has(.st-shell[data-screen='song'][data-phone-video='full']) .yt-mini[data-mode='dock'] { border-radius: 0; }
}

@media (max-width: 640px), (max-width: 900px) and (min-height: 700px) {
  /* ---- Share's line (phone-song/share.ts): the cue toast's look, above the player bar and over a sheet --------- */
  .ph-share-status {
    position: fixed;
    bottom: calc(var(--ph-sheet-bottom, 108px) + 8px);
    left: 50%;
    z-index: 35;
    padding: 10px 14px;
    border-radius: 10px;
    outline: 1px solid var(--st-line-strong);
    outline-offset: -0.5px;
    background: var(--st-popover-bg);
    box-shadow: 0 12px 30px color-mix(in srgb, var(--st-shadow) 60%, transparent);
    color: var(--st-text);
    font: 400 14px/18px var(--st-font);
    text-align: center;
    width: max-content;
    max-width: calc(100% - 32px);
    transform: translateX(-50%);
    pointer-events: none;
  }

  /* ---- Top bar (phone-song/bar.ts) ------------------------------------------------------------------------- */
  .ph-bar__back { display: inline-grid; flex: none; place-items: center; width: 40px; height: 40px; border-radius: 10px; color: var(--st-text); }
  .ph-bar__back .st-icon { width: 22px; height: 22px; }
  .ph-bar__titles { flex: 1; min-width: 0; }
  .ph-bar__title,
  .ph-bar__artist { margin: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .ph-bar__title { color: var(--st-text-strong); font: 600 17px/22px var(--st-font); }
  /* A title too long for its line scrolls (bar.ts `marquee`): hold, slide one copy's width plus the gap, loop. Only the
     track moves (a transform), so nothing else shifts; under reduced motion the "…" stays. */
  .ph-bar__title-copy { display: none; }
  @media (prefers-reduced-motion: no-preference) {
    .ph-bar__title[data-marquee] { text-overflow: clip; }
    .ph-bar__title[data-marquee] .ph-bar__title-track { display: inline-flex; gap: 32px; animation: ph-marquee var(--ph-mq-dur, 12s) linear infinite; will-change: transform; }
    .ph-bar__title[data-marquee] .ph-bar__title-copy { display: inline; }
  }
  .ph-bar__artist { color: var(--st-text-dim); font: 400 13px/18px var(--st-font); }
  /* No ☰ on a song (the user's call): the menu is a ‹ back away, on the Dashboard and every other page. */
  .st-shell[data-screen='song'] .st-shell__top > .st-shell__menu { display: none; }
  .ph-bar__btn { flex: none; }
  .st-shell[data-screen='song'] .st-shell__top { gap: 0; }
  .st-shell[data-screen='song'] .ph-bar__titles { margin-right: 4px; }
  .st-shell[data-screen='song'] :is(.ph-bar__btn, .ph-bar__back) { width: 40px; height: 40px; }
  /* Add to collection (P415 T8): an icon in the bar, its words for a screen reader; In collection, it dims. */
  .ph-bar__collection { flex: none; width: 40px; height: 40px; padding: 0; justify-content: center; }
  .ph-bar__collection .st-btn__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .ph-bar__collection:disabled { opacity: 0.45; }
  .st-rail .ph-bar__btn[hidden] { display: none; }
  /* Accent while the video isn't Full, so the way back is plain; no tile (P616). */
  .st-rail .ph-bar__btn:is([data-mode='compact'], [data-mode='hidden']) { background: none; color: var(--st-accent); }

  /* ---- Video modes (phone-song/video.ts) ------------------------------------------------------------------- */
  .ph-video__chords { display: none; }
  .st-shell[data-phone-video='compact'] .ph-video__top { display: flex; gap: 12px; padding: 12px var(--ph-gutter); }
  .st-shell[data-phone-video='compact'] .ph-video__box { flex: none; width: 200px; height: 200px; min-height: 0; margin: 0; aspect-ratio: auto; border-radius: 10px; }
  .st-shell[data-phone-video='compact'] .ph-video__chords { display: flex; flex: 1; flex-direction: column; gap: 8px; min-width: 0; }
  .ph-video__card {
    position: relative;
    display: grid;
    flex: 1;
    place-items: center;
    min-height: 0;
    border: 1px solid color-mix(in srgb, var(--st-accent) 92%, transparent);
    border-radius: 14px;
    background: color-mix(in srgb, var(--st-accent) 16%, transparent);
  }
  .ph-video__now { color: var(--st-text-strong); font: 700 44px/1 Roboto, Arial, sans-serif; white-space: nowrap; }
  .ph-video__progress { position: absolute; right: 12px; bottom: 14px; left: 12px; }
  .ph-video__progress .live__progress-fill { background: var(--st-accent); }
  .ph-video__nexts { display: flex; flex: none; gap: 8px; height: 34px; }
  .ph-video__next {
    display: grid;
    flex: 1;
    place-items: center;
    min-width: 0;
    border: 1px solid color-mix(in srgb, var(--st-text-strong) 12%, transparent);
    border-radius: 10px;
    background: color-mix(in srgb, var(--st-text-strong) 5%, transparent);
    color: var(--st-text);
    font: 700 16px/1 Roboto, Arial, sans-serif;
    white-space: nowrap;
  }
  /* Hidden: the box stays laid out at no height, so the player keeps it and plays on unseen (card.ts data-off); nothing shows in its place. */
  .st-shell[data-phone-video='hidden'] .ph-video__top { height: 0; overflow: hidden; }
  .st-shell[data-phone-video='hidden'] .ph-video__box { min-height: 0; margin: 0; }

  /* ---- Song | Video (phone-song/video.ts, song-art.ts, P816): the pill over the player's top-right corner ---------- */
  .ph-video__box { position: relative; }
  /* Over the docked player (youtube.css .yt-mini, fixed at z-index 35). */
  .ph-side {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 36;
    display: flex;
    box-sizing: border-box;
    height: 26px;
    padding: 2px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    background: rgba(11, 11, 13, 0.7);
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.35);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
  }
  .ph-side__seg {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 0 9px;
    border: 0;
    border-radius: 999px;
    background: none;
    color: rgba(255, 255, 255, 0.75);
    font: 600 11px/1 var(--st-font);
    cursor: pointer;
  }
  /* Each half's tap area is 44px tall, beyond the pill's 26. */
  .ph-side__seg::after { content: ''; position: absolute; inset: -12px -4px; }
  .ph-side__seg[aria-checked='true'] { background: rgba(255, 255, 255, 0.18); color: #fff; }
  .ph-side__seg:disabled { opacity: 0.45; cursor: default; }
  .ph-side__offline { display: none; width: 11px; height: 11px; }
  .ph-side__seg:disabled .ph-side__offline { display: inline; }

  /* D849: a clear layer over YouTube's player takes every tap and does nothing (D866); under the pill (DOM order). */
  .ph-tap { position: absolute; inset: 0; z-index: 36; }
  .ph-video__box[data-off] > .ph-tap { display: none; }

  /* Song: the thumbnail cropped square at the left, 16px in, over a blurred, dimmed copy filling the box. */
  .ph-art { position: absolute; inset: 0; display: none; overflow: hidden; border-radius: inherit; background: #000; }
  .ph-video__box[data-side='song'] > .ph-art { display: block; }
  .ph-art__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: blur(24px) brightness(0.55); transform: scale(1.2); }
  /* The picture in its own shape (D836): portrait, square or 16:9, as tall as the box allows and clear of the pill. */
  /* The picture and the song's info beside it (P816 round 5b): 16px in at the left, 14px between, 12px from the right. */
  .ph-art__row { position: absolute; inset: 0; display: flex; align-items: center; gap: 14px; padding: 16px 12px 16px 16px; }
  /* Still at most the box less 136px wide (the row's padding takes 28 of it), so it stays clear of the pill. */
  .ph-art__img { flex: none; display: block; width: auto; height: auto; max-width: calc(100% - 108px); max-height: 100%; border-radius: 8px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); }
  /* Centred between 40px (under the pill) and 16px from the bottom; a column under 120px (16:9 art) keeps title, artist, key and BPM. */
  .ph-art__info { flex: 1 1 0; align-self: stretch; min-width: 0; display: flex; flex-direction: column; justify-content: safe center; padding-top: 24px; overflow: hidden; container-type: inline-size; color: #fff; font-family: var(--st-font); }
  .ph-art__name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font: 600 15px/1.25 var(--st-font); letter-spacing: -0.15px; }
  .ph-art__artist, .ph-art__writers { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .ph-art__artist { color: rgba(255, 255, 255, 0.7); font: 400 13px/18px var(--st-font); }
  .ph-art__chips { display: flex; flex-wrap: nowrap; gap: 4px; margin-top: 10px; overflow: hidden; }
  .ph-art__chip { box-sizing: border-box; display: inline-flex; align-items: center; height: 22px; padding: 0 7px; border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 6px; background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.85); font: 600 11px/1 var(--st-font); white-space: nowrap; }
  /* Tinted from the art's average colour (song-art.ts `keyTint`), amber until it is read. */
  .ph-art__key { border-color: var(--ph-key-border); background: var(--ph-key-fill); color: var(--ph-key-text); }
  button.ph-art__key { margin: 0; cursor: pointer; }
  .ph-art__more { display: flex; flex-direction: column; gap: 2px; margin-top: 9px; min-width: 0; }
  .ph-art__details { color: rgba(255, 255, 255, 0.55); font: 500 11px/14px var(--st-font); }
  .ph-art__writers { color: rgba(255, 255, 255, 0.4); font: 400 10.5px/13px var(--st-font); }
  .ph-art__info [hidden] { display: none; }
  @container (max-width: 119px) {
    .ph-art__meter, .ph-art__more { display: none; }
    /* The key and BPM chips on one row in a ~94px column. */
    .ph-art__chips { gap: 3px; }
    .ph-art__chip { padding: 0 5px; }
  }
  /* Still the bars until it is trimmed (song-art.ts), a moment after it loads: unseen till then. */
  .ph-art__img:not([data-shaped]) { visibility: hidden; }
  /* No Studio audio (D865): the cover, name and artist stay; the reason line and one button take the chips' and details' place (the box is ~170px tall). */
  .ph-art[data-no-audio] :is(.ph-art__chips, .ph-art__more) { display: none; }
  .ph-art__message { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin-top: 10px; min-width: 0; }
  .ph-art__message[hidden] { display: none; }
  .ph-art__title { color: rgba(255, 255, 255, 0.85); font: 500 12px/16px var(--st-font); }
  /* Over the dark artwork in either theme: the pill's dark glass. */
  .ph-art__action.st-btn--secondary { outline-color: rgba(255, 255, 255, 0.16); background: rgba(11, 11, 13, 0.7); color: #fff; }

  /* ---- Live chords: one compact 42px strip (P616: 56×34 chips, 6 px apart) of name-only cards (live/row.ts keeps the current one second) -------------- */
  .st-shell[data-screen='song'] [data-slot='live'].live {
    display: block;
    min-height: 0;
    padding: 0;
    border-radius: 0;
    outline: 0;
    background: none;
    overflow: visible;
    container-type: normal;
  }
  /* Compact's chords sit beside the player: the row gives way. */
  .st-shell[data-phone-video='compact'] [data-slot='live'].live { display: none; }
  .st-shell[data-screen='song'] [data-slot='live'] :is(.live__video, .live__head, .live__carousel, .live__lyrics) { display: none; }
  .st-shell[data-screen='song'] [data-slot='live'] :is(.live__stage, .live__body, .live__flow) { display: block; }
  .st-shell[data-screen='song'] [data-slot='live'] .live__row { display: flex; gap: 6px; box-sizing: border-box; height: 42px; padding: 4px var(--ph-gutter); scrollbar-width: none; }
  /* On the gutter, no blank before the first card: the playing card moves right until it reaches the centre, the row
     keeps it there, and at the end the row stops and the card moves on to the last (chips.ts `scrollPlan`). */
  .st-shell[data-screen='song'] [data-slot='live'] .live__chip { position: relative; justify-content: center; gap: 0; min-width: 56px; height: 34px; padding: 0 10px; box-sizing: border-box; }
  .st-shell[data-screen='song'] [data-slot='live'] .live__chip-name { font-size: 17px; }
  .st-shell[data-screen='song'] [data-slot='live'] .live__chip-time { display: none; }
  /* The chord's progress along the card's bottom edge, 3px and edge to edge like the section colour along its top (P676),
     so it keeps clear of the chord's name. */
  .st-shell[data-screen='song'] [data-slot='live'] .live__progress--chip { position: absolute; right: 0; bottom: 0; left: 0; width: auto; border-radius: 0 0 9px 9px; }

  /* ---- The tab bar under the chord strip (phone-song/controls.ts, P616): one rounded track that scrolls sideways,
     each tab an icon and a label, the chosen one a white pill with a red icon; More's ⋯ last. A fade at the right
     edge says there's more ------------------------------------------------------------------------------------------ */
  .st-shell[data-screen='song'] .st-shell__phone-tools { box-sizing: border-box; padding: 4px var(--ph-gutter); }
  .ph-tabs {
    display: flex;
    flex: 1;
    align-items: center;
    gap: 2px;
    min-width: 0;
    height: 34px;
    box-sizing: border-box;
    padding: 1px;
    overflow-x: auto;
    border: 1px solid var(--st-line);
    border-radius: 999px;
    background: var(--st-surface);
    scrollbar-width: none;
    mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  }
  .ph-tabs::-webkit-scrollbar { display: none; }
  .ph-tabs .ph-tabs__views { display: flex; flex: none; gap: 2px; padding: 0; border: 0; outline: 0; background: none; }
  .ph-tabs .ph-tabs__views .st-seg__item {
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 5px;
    height: 30px;
    padding: 0 12px;
    border: 0;
    border-radius: 999px;
    outline: 0;
    background: none;
    color: var(--st-text-dim);
    font: 500 13px/1 var(--st-font);
    white-space: nowrap;
  }
  .ph-tabs .ph-tabs__views .st-seg__item[aria-checked='true'] {
    background: var(--st-text-strong);
    box-shadow: 0 1px 4px rgb(0 0 0 / 0.25);
    color: var(--st-bg);
    font-weight: 600;
  }
  .ph-tabs .st-seg__item[aria-checked='true'] .ph-tabs__icon { color: var(--st-accent); }
  .ph-tabs .st-seg__item:focus-visible { outline: 2px solid var(--st-accent); outline-offset: -2px; }
  .ph-tabs__icon { flex: none; width: 14px; height: 14px; }
  /* The Instrument tab names the instrument and opens its sheet when tapped again (P405): a selector's chevron. */
  .ph-tabs__chevron { flex: none; width: 12px; height: 12px; margin-left: -2px; opacity: 0.7; }

  /* Chips: 40px on a 44px target. */
  .ph-chip {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 40px;
    box-sizing: border-box;
    padding: 0 12px;
    border: 1px solid var(--st-line);
    border-radius: 10px;
    background: transparent;
    color: var(--st-text-dim);
    font: 500 14px/1 var(--st-font);
    white-space: nowrap;
    touch-action: manipulation;
  }
  .ph-chip::before { position: absolute; inset: -3px 0; content: ''; }
  .ph-chip[hidden] { display: none; }
  .ph-chip .st-icon { width: 18px; height: 18px; color: var(--st-text-faint); }
  .ph-chip--menu { border-color: transparent; background: var(--st-surface-2); color: var(--st-text); }
  .ph-chip--menu .ph-chip__chevron { width: 14px; height: 14px; }

  /* ---- Shapes (P352): its own host in the sheet's place; the Capo strip over the sheet in the sheet views ------ */
  /* Hidden (no capo, capo-strip.ts) stays hidden: this display would beat the [hidden] default. Never under a page tab
     (Stems, Sections, Metronome, Cues): these rules come after its hide above and would win. */
  .st-shell[data-screen='song']:not([data-phone-tab]) .st-shell__phone-capo:not([hidden]) { order: 4; display: block; flex: none; }
  .st-shell[data-screen='song'][data-phone-view='shapes'] .st-shell__phone-capo { display: none; }
  .st-shell[data-screen='song'][data-phone-view='shapes']:not([data-phone-tab]) .st-shell__phone-shapes {
    order: 4;
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    overflow-y: auto; /* scroll only when the carousel can't fit, e.g. 360 wide with the video open */
    overscroll-behavior: contain;
    border-top: 1px solid var(--st-line);
    background: var(--st-bg);
  }
  .st-shell[data-screen='song'][data-phone-view='shapes'] :is(.st-shell__sheet-host, .st-shell__right):has(> [data-slot='sheet']) { display: none; }
  .st-shell[data-screen='song'] [data-slot='sheet'] :is(.sheet__head, .sheet__toolbar, .sheet__foot, .sheet__song) { display: none; }

  /* ---- Generate lyrics (P392, phone-song/lyrics-panel.ts): Lead and Lyrics of a song with an offer, in the sheet's place */
  .st-shell[data-screen='song'][data-phone-lyrics='offer'] :is(.st-shell__sheet-host, .st-shell__right):has(> [data-slot='sheet']),
  .st-shell[data-screen='song'][data-phone-lyrics='offer'] .st-shell__phone-capo { display: none; }
  .st-shell[data-screen='song']:not([data-phone-tab]) .ph-lyrics:not([hidden]) {
    order: 4;
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 0;
    padding: 16px 24px;
    overflow-y: auto;
    border-top: 1px solid var(--st-line);
    background: var(--st-bg);
    color: var(--st-text);
    font-family: var(--st-font);
    text-align: center;
  }
  .ph-lyrics__icon { display: grid; place-items: center; width: 48px; height: 48px; margin-bottom: 4px; border-radius: 50%; background: var(--st-accent-soft); color: var(--st-accent); }
  .ph-lyrics[data-tone='plain'] .ph-lyrics__icon { background: var(--st-surface-2); color: var(--st-text-dim); }
  .ph-lyrics__icon .st-icon { width: 22px; height: 22px; }
  .ph-lyrics__title { margin: 0; color: var(--st-text-strong); font: 600 17px/22px var(--st-font); }
  .ph-lyrics__body { max-width: 320px; margin: 0; color: var(--st-text-dim); font: 400 14px/20px var(--st-font); outline: 0; }
  .ph-lyrics .lyrics-offer { margin-top: 8px; flex-wrap: nowrap; }
  .ph-lyrics .lyrics-offer .st-btn { height: 44px; padding: 0 16px; font-size: 14px; }
  /* The body says the note's words; the laptop note beside the button would say them twice. */
  .ph-lyrics .lyrics-offer__note,
  .ph-lyrics .ph-lyrics__premium[hidden] { display: none; }
  .st-shell[data-screen='song'] [data-slot='sheet'] { border-top: 1px solid var(--st-line); background: var(--st-bg); }
  .st-shell[data-screen='song'] [data-slot='sheet'] .sheet__body { padding: 12px var(--ph-gutter); }
  /* Times, not bars (P350, D444): a Grid section says when it starts, not its bars (grid.ts `times` for the rest). */
  .st-shell[data-screen='song'] [data-slot='sheet'] .sheet__gblock .sheet__range { display: none; }

  /* ---- Player bar: the seek line with its times, then Key & tempo · −10 · play · +10 · Loop ---------------- */
  .st-shell[data-screen='song'] .st-shell__playbar { box-sizing: border-box; height: 104px; border: 0; background: none; }
  .st-shell__playbar > * { grid-area: 1 / 1; min-width: 0; min-height: 0; }
  .st-shell[data-screen='song'] .st-shell__playbar { grid-template: minmax(0, 1fr) / minmax(0, 1fr); }
  .st-shell[data-screen='song'] .pl-mini {
    display: grid;
    grid-template: 'now seek total' 36px 'controls controls controls' 1fr / minmax(35px, auto) minmax(0, 1fr) minmax(35px, auto);
    gap: 0 6px;
    height: 100%;
    box-sizing: border-box;
    row-gap: 6px;
    padding: 0 var(--ph-gutter) 12px;
    border-radius: 0;
    outline: 0;
    background: none;
  }
  .st-shell[data-screen='song'] .pl-mini__now { grid-area: now; align-self: center; color: var(--st-text-faint); font: 400 11px/1 var(--st-font-mono); }
  /* Both time columns are 12px padding + 35px + the 6px gap = 53px, where the Stems waveforms start and end (measured at 375 and 390 px) and the red line and the thumb sit on one vertical. */
  .st-shell[data-screen='song'] .pl-mini__total { grid-area: total; align-self: center; font-size: 11px; text-align: right; }
  .st-shell[data-screen='song'] .pl-mini .pl-progress { grid-area: seek; height: 36px; }
  .st-shell[data-screen='song'] .pl-mini .pl-progress__labels { display: none; }
  .st-shell[data-screen='song'] .pl-mini__controls { grid-area: controls; justify-self: center; gap: 22px; }
  .st-shell[data-screen='song'] .pl-mini .pl-btn--mini { width: 44px; height: 44px; }
  /* Play/pause (P350, frame 1; P616): a 56px red disc, a white icon, a soft glow and a 1px top highlight; no ring. Waiting or counting in: a white arc turns around a dim pause
     glyph, the disc at 75% (still with reduced motion). Pressed: 94% and a deeper red for 100ms. */
  .st-shell[data-screen='song'] .pl-mini .pl-play,
  .st-shell[data-screen='song'] .pl-mini .pl-play:hover {
    position: relative;
    width: 56px;
    height: 56px;
    border: 0;
    background: linear-gradient(180deg, #ff4d6d, #e11d48) padding-box;
    box-shadow: 0 6px 18px color-mix(in srgb, var(--st-accent) 40%, transparent), inset 0 1px 0 rgb(255 255 255 / 0.28);
    color: #fff;
    transition: transform 100ms ease-out, background 100ms ease-out, box-shadow 100ms ease-out;
  }
  .st-shell[data-screen='song'] .pl-mini .pl-play .st-icon { width: 24px; height: 24px; }
  .st-shell[data-screen='song'] .pl-mini .pl-play[data-state='play'] .st-icon { translate: 2px 0; }
  .st-shell[data-screen='song'] .pl-mini .pl-play:is([data-state='wait'], [data-state='count']) { background: linear-gradient(180deg, rgb(255 77 109 / 0.75), rgb(225 29 72 / 0.75)) padding-box; }
  .st-shell[data-screen='song'] .pl-mini .pl-play:is([data-state='wait'], [data-state='count']) .st-icon { width: 46px; height: 46px; }
  .st-shell[data-screen='song'] .pl-mini .pl-play:is([data-state='wait'], [data-state='count']) .st-icon path { stroke-width: 1.2; }
  .st-shell[data-screen='song'] .pl-mini .pl-play:is([data-state='wait'], [data-state='count'])::after {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 16px;
    height: 20px;
    background: linear-gradient(90deg, rgb(255 255 255 / 0.55) 0 5px, transparent 5px 11px, rgb(255 255 255 / 0.55) 11px);
    content: '';
  }
  .st-shell[data-screen='song'] .pl-mini .pl-play:active {
    transform: scale(0.94);
    background: linear-gradient(180deg, #e11d48, #be123c) padding-box;
    box-shadow: 0 3px 10px color-mix(in srgb, var(--st-accent) 40%, transparent), inset 0 1px 0 rgb(255 255 255 / 0.2);
  }
  .st-shell[data-screen='song'] .pl-mini :is(.pl-chip, .pl-volume--mini) { display: none; }
  /* Key & tempo and Loop sit in the controls' row, either side; the rest of the bar takes the taps. */
  .st-shell[data-screen='song'] .st-shell__phone-play { position: relative; z-index: 1; display: flex; align-self: end; justify-content: space-between; height: 62px; padding: 0 6px 12px; pointer-events: none; }
  .ph-play__btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 84px;
    padding: 0 6px;
    border: 0;
    border-radius: 14px;
    background: none;
    color: var(--st-text-dim);
    font: 500 9px/1 var(--st-font);
    cursor: pointer;
    pointer-events: auto;
  }
  .ph-play__btn .st-icon { width: 22px; height: 22px; }
  /* Key & tempo's "Em · 95" in place of an icon (D470). */
  .ph-play__value { color: var(--st-text); font: 600 12px/20px var(--st-font-mono); white-space: nowrap; }
  .ph-play__loop[data-looping='true'] { background: color-mix(in srgb, var(--st-loop) 22%, transparent); color: var(--st-loop); }

  /* ---- The Video sheet's choices ----------------------------------------------------------------------------- */
  .ph-choices { display: flex; flex-direction: column; gap: 8px; }
  .ph-choice {
    display: flex;
    align-items: center;
    gap: 14px;
    min-height: 60px;
    padding: 10px 14px;
    border: 1px solid var(--st-line);
    border-radius: 14px;
    background: var(--st-surface);
    color: var(--st-text);
    text-align: left;
    cursor: pointer;
  }
  .ph-choice__icon { flex: none; width: 20px; height: 20px; }
  .ph-choice__words { display: flex; flex: 1; flex-direction: column; gap: 3px; min-width: 0; }
  .ph-choice__label { color: var(--st-text-strong); font-size: 15px; font-weight: 600; }
  .ph-choice__note { color: var(--st-text-dim); font-size: 13px; }
  .ph-choice__dot { flex: none; box-sizing: border-box; width: 22px; height: 22px; border: 2px solid var(--st-line-strong); border-radius: 50%; }
  .ph-choice[aria-checked='true'] .ph-choice__dot { border: 6px solid var(--st-accent); }
}

/* ---- Looping on the chart (sheet/lead.ts setLoop): the loop's lines framed by pink A / B rules, the rest dimmed --- */
@media (max-width: 640px), (max-width: 900px) and (min-height: 700px) {
  .st-shell[data-screen='song'] .sheet__lead[data-looping='true'] .sheet__line:not([data-loop]) { opacity: 0.35; }
  /* A time from 10:00 is wider than the rail's 28px (sheet.css). */
  .st-shell[data-screen='song'] .sheet__barno { width: auto; min-width: 28px; }
  .st-shell[data-screen='song'] .sheet__lead[data-looping='true'] .sheet__line[data-loop] { position: relative; box-shadow: inset 3px 0 var(--st-loop); }
  .st-shell[data-screen='song'] .sheet__lead[data-looping='true'] .sheet__line:is([data-loop='a'], [data-loop='ab']) { margin-top: 30px; }
  .st-shell[data-screen='song'] .sheet__lead[data-looping='true'] .sheet__line:is([data-loop='b'], [data-loop='ab']) { margin-bottom: 30px; }
  .st-shell[data-screen='song'] .sheet__lead[data-looping='true'] .sheet__line:is([data-loop='a'], [data-loop='ab'])::before,
  .st-shell[data-screen='song'] .sheet__lead[data-looping='true'] .sheet__line:is([data-loop='b'], [data-loop='ab'])::after {
    position: absolute;
    right: 0;
    left: 0;
    height: 20px;
    padding-left: 26px;
    background: linear-gradient(var(--st-loop), var(--st-loop)) 0 50% / 20px 20px no-repeat, linear-gradient(color-mix(in srgb, var(--st-loop) 55%, transparent), color-mix(in srgb, var(--st-loop) 55%, transparent)) 28px 50% / 100% 1px no-repeat;
    color: var(--st-on-loop);
    font: 700 12px/20px var(--st-font);
    text-indent: -20px;
  }
  .st-shell[data-screen='song'] .sheet__lead[data-looping='true'] .sheet__line:is([data-loop='a'], [data-loop='ab'])::before { content: 'A'; bottom: calc(100% + 6px); }
  .st-shell[data-screen='song'] .sheet__lead[data-looping='true'] .sheet__line:is([data-loop='b'], [data-loop='ab'])::after { content: 'B'; top: calc(100% + 6px); }
}

/* The play bar's loading arc holds still with reduced motion (P350); the laptop's spinner is left as it is. */
@media (max-width: 640px), (max-width: 900px) and (min-height: 700px) {
  @media (prefers-reduced-motion: reduce) {
    .st-shell[data-screen='song'] .pl-mini .pl-play__spin { animation: none; }
  }
}

/* The phone song title's marquee (bar.ts): the first fifth holds still, then one copy's width plus the gap. */
@keyframes ph-marquee {
  0%, 20% { transform: translateX(0); }
  100% { transform: translateX(calc(-1 * var(--ph-mq-shift, 0px))); }
}

@media (max-width: 640px), (max-width: 900px) and (min-height: 700px) {
  /* ---- The song while it opens, and its failure (phone-song/opening.ts; the header's line is hidden here) ------ */
  .ph-open__box { position: relative; overflow: hidden; }
  .ph-open__thumb { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0.55; }
  .ph-open {
    position: relative;
    display: grid;
    gap: 10px;
    margin: 12px var(--ph-gutter) 0;
    padding: 14px 16px 16px;
    overflow: hidden;
    border: 1px solid var(--st-line-strong);
    border-radius: var(--st-radius-card);
    background: var(--st-panel);
    color: var(--st-text);
  }
  .ph-open__line { display: flex; align-items: center; gap: 10px; margin: 0; font: 500 15px/20px var(--st-font); font-variant-numeric: tabular-nums; }
  .ph-open__spin { flex: none; width: 18px; height: 18px; color: var(--st-accent); animation: st-spin 1s linear infinite; }
  .ph-open__text { flex: 1; min-width: 0; }
  .ph-open__count { flex: none; color: var(--st-text-dim); }
  .ph-open__dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--st-error); }
  /* player.css's running bar, without the header line's data-known switch. */
  .ph-open__bar .pl-load__fill { width: 30%; animation: pl-load-slide 1.2s ease-in-out infinite; }
  .ph-open__hint { margin: 0; color: var(--st-text-dim); font: 400 13px/18px var(--st-font); }
  .ph-open__hint[hidden] { display: none; }
  .ph-open__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }
  /* The skeleton stands in the chart's place: the row's host takes the chart's room, and the empty chart goes. */
  .st-shell[data-screen='song'] .st-shell__phone-tools:has(> .ph-open__skeleton) { flex: 1 1 0; height: auto; min-height: 0; overflow: hidden; }
  .st-shell[data-screen='song']:has(.ph-open__skeleton) :is(.st-shell__sheet-host, .st-shell__right) { display: none; }
  /* The card says a refusal here; the laptop's P286 card (shell.css, data-view='too-long') would sit cut off above it. */
  .st-shell[data-screen='song']:has(.ph-open, .ph-refused) .st-shell__split[data-view] { display: none; }
  /* A song the plan refused (P983): the one refusal card (api.css), under the song's bar. */
  .sp-card.api-refusal.ph-refused { width: auto; margin: 12px var(--ph-gutter) 0; padding: 16px; }
  .ph-refused .api-refusal__song { padding-bottom: 16px; margin-bottom: 16px; }
  .ph-refused .api-refusal__art.sp-card__art { width: 48px; height: 48px; }
  .ph-open__skeleton { display: grid; flex: 1; align-content: start; gap: 14px; padding: 20px var(--ph-gutter); }
  .ph-open__row { height: 14px; border-radius: 7px; background: var(--st-surface-2); }
  .ph-open__row:nth-child(3n + 1) { width: 72%; }
  .ph-open__row:nth-child(3n + 2) { width: 88%; }
  .ph-open__row:nth-child(3n) { width: 56%; }
  @media (prefers-reduced-motion: reduce) {
    .ph-open__spin, .ph-open__bar .pl-load__fill { animation: none; }
  }
}

@media (max-width: 640px), (max-width: 900px) and (min-height: 700px) {
  /* ---- The Stems tab's card and split progress (phone/stems-view.ts, P616, D602) --------------------------- */
  .psv-none__icon { width: 28px; height: 28px; color: var(--st-accent); }
  .psv-none__title { display: inline-flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; }
  .psv-none__text { max-width: 300px; margin: 0; color: var(--st-text-dim); font: 400 13px/1.45 var(--st-font); text-align: center; }
  .psv-none__split { gap: 8px; }
  .psv-none__split .st-icon { width: 18px; height: 18px; }
  .psv-progress { display: grid; grid-template-columns: 1fr auto; gap: 8px 12px; margin-bottom: 8px; }
  .psv-progress__words { color: var(--st-text-strong); font: 600 14px/18px var(--st-font); }
  .psv-progress__pct { color: var(--st-text-dim); font: 400 13px/18px var(--st-font); font-variant-numeric: tabular-nums; }
  .psv-progress__bar { grid-column: 1 / -1; height: 4px; overflow: hidden; border-radius: 2px; background: var(--st-surface-2); }
  .psv-progress__fill { display: block; height: 100%; border-radius: inherit; background: var(--st-accent); transition: width 300ms ease-out; }

  /* ---- Keep screen on and the Metronome card's lines (phone/sounds-sheet.ts, cues-mount.ts) ----------------- */
  .ph-snd-head__words { display: flex; flex: 1; flex-direction: column; gap: 2px; min-width: 0; }
  .ph-snd-head__words .ph-snd-head__name { flex: none; }
  .ph-snd-head__sub { color: var(--st-text-dim); font: 400 13px/17px var(--st-font); }
  .ph-snd-stack { display: grid; gap: 8px; padding: 6px 0; }
  .ph-snd-stack[data-off='true'] { opacity: 0.5; }

  /* ---- Download (phone-song/download-sheet.ts, P616): toggle chips, then WAV | MP3 and the red button ------- */
  .ph-dl { display: grid; gap: 8px; }
  .ph-dl__song { margin: -8px 0 4px; color: var(--st-text-dim); font: 400 14px/18px var(--st-font); }
  .ph-dl__row { display: grid; grid-auto-columns: 1fr; grid-auto-flow: column; gap: 8px; }
  .ph-dl__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .ph-dl-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    height: 42px;
    box-sizing: border-box;
    padding: 0 10px 0 12px;
    border: 1px solid var(--st-line);
    border-radius: 12px;
    background: var(--st-surface-2);
    color: var(--st-text);
    font: 500 13px/1 var(--st-font);
    cursor: pointer;
  }
  .ph-dl-chip[aria-pressed='true'] { border-color: var(--st-accent); background: var(--st-accent-soft); color: var(--st-text-strong); }
  .ph-dl-chip:disabled,
  .ph-dl-chip[data-locked] { color: var(--st-text-faint); }
  .ph-dl-chip:disabled { opacity: 0.5; cursor: default; }
  .ph-dl-chip__icon { flex: none; width: 16px; height: 16px; }
  .ph-dl-chip[aria-pressed='true'] .ph-dl-chip__icon { color: var(--st-accent); }
  .ph-dl-chip__label { flex: 1; min-width: 0; overflow: hidden; text-align: left; text-overflow: ellipsis; white-space: nowrap; }
  .ph-dl-chip__check { flex: none; width: 14px; height: 14px; color: var(--st-accent); visibility: hidden; }
  .ph-dl-chip[aria-pressed='true'] .ph-dl-chip__check { visibility: visible; }
  .ph-dl-chip .pc-badge { flex: none; transform: scale(0.85); transform-origin: right center; }
  .ph-dl__note { margin: 0; color: var(--st-text-dim); font: 400 13px/18px var(--st-font); }
  .ph-dl__foot { display: flex; gap: 10px; margin-top: 4px; }
  .ph-dl-format { display: flex; flex: none; gap: 2px; padding: 3px; border-radius: 12px; background: var(--st-surface-2); }
  .ph-dl-format__item { display: inline-flex; align-items: center; gap: 4px; height: 38px; padding: 0 12px; border: 0; border-radius: 9px; background: none; color: var(--st-text-dim); font: 600 14px/1 var(--st-font); cursor: pointer; }
  .ph-dl-format__item[aria-checked='true'] { background: var(--st-bg); color: var(--st-text-strong); }
  .ph-dl-format__lock { width: 14px; height: 14px; color: var(--pc-gold, #f5c66b); }
  .ph-dl__go { flex: 1; height: 44px; }
  .ph-dl__status { min-height: 18px; margin: 0; color: var(--st-text-dim); font: 400 13px/18px var(--st-font); }
  .ph-dl__status:empty { display: none; }

  /* P684 Save as PDF (phone-song/pdf-sheet.ts): the pages stacked, then Share and Download. */
  .ph-pdf { display: grid; gap: 10px; }
  .ph-pdf__page { display: block; width: 100%; height: auto; box-sizing: border-box; border: 1px solid var(--st-line); border-radius: 4px; background: #fff; }
  /* Share sits on the title bar's centre line beside Download and ✕ (32px), a touch taller as the main action. */
  .ph-pdf__actions { display: flex; flex: none; align-items: center; gap: 4px; }
  .ph-pdf__go { height: 36px; padding: 0 14px; gap: 6px; font-size: 14px; font-weight: 600; }
  .ph-pdf__go .st-icon { width: 16px; height: 16px; }
  .ph-pdf__note { margin: 0; color: var(--st-text-dim); font: 400 13px/18px var(--st-font); text-align: center; }
}
