/* Change A: communal mobile layout. Video, track and chat share one phone screen (Post Radio #154, design "Change A").
   The desktop layout (rail with stacked Chat / Tracklist, segmented control, room-aside card) is unchanged. The phone
   breakpoint is `(max-width:719px),(max-height:559.98px)` (kept from the existing app layout). The FloatingNav tabs
   (Room / Chat / Tracklist) are gone; one Tracklist / Chat pill in the header switches `data-mobile-tab` between the
   two views; chat and the tracklist share a flex panel area. The `#host-controls` card lives only on the tracklist
   view. The avatar stack, mobile state strip and aside presence stay off on phones. */

@media (max-width:719px),(max-height:559.98px) {
  /* The page is a full-height flex column. No page scroll: the panel area is the only scroll region. */
  #live{display:flex;flex-direction:column;height:var(--phone-vvh,100dvh);min-height:0;overflow:hidden}
  /* Locked like an app: the page never scrolls or rubber-bands; .chat-list is the only scroll region (CJ, 2026-10-09). */
  html,body{height:100%;overflow:hidden;overscroll-behavior:none}
  body{position:fixed;inset:0;width:100%}
  [data-keyboard="open"] #live{position:fixed;top:var(--phone-vvtop,0px);left:0;right:0;height:var(--phone-vvh,100dvh);z-index:20}
  /* Keyboard open (data-keyboard flips from documentElement.clientHeight, df8f41f): header, video, chat and composer
     only. The strip under the video is hidden, not clipped; #backstage keeps its form. */
  [data-keyboard="open"] #live .room-main{flex:0 1 auto;min-height:0}
  [data-keyboard="open"] #live .media-frame{flex:0 1 auto;min-height:120px;max-height:max(120px,calc(var(--phone-vvh,100dvh) - 320px))}
  [data-keyboard="open"] #live .listen-card>.track-block,[data-keyboard="open"] #live .room-main>.countdown,[data-keyboard="open"] #live .room-main>.claim-slot{display:none}
  [data-keyboard="open"] #live .room-main>.sync-status-slot,[data-keyboard="open"] #live #tap-listen,[data-keyboard="open"] #live #host-controls{display:none}
  [data-keyboard="open"] #live .room-aside{flex:1 1 auto;min-height:150px}

  /* Header: logo mark only (no wordmark on a phone); station name takes the free space; a Tracklist toggle replaces
     the old spacer, meta line, share button, avatar stack and probe badge. Static, not sticky: a sticky header could
     paint over the provider player (compliance finding 7). */
  .channel-header{position:relative;top:auto;z-index:5;flex:0 0 auto;display:flex;align-items:center;gap:10px;padding:calc(env(safe-area-inset-top,0px) + 12px) 16px 12px;background:var(--lr-page);border-bottom:1px solid var(--lr-rule);margin:0}
  .channel-wordmark,.channel-divider,.channel-header .channel-meta,.avatar-stack-slot,.share-button,.probe-badge,.channel-spacer{display:none}
  /* The room header area still says how many are listening (issue #177): the compact count, not the whole meta line. */
  .channel-header .channel-presence{display:inline-block;flex:0 0 auto;font:600 13px var(--lr-font-ui);color:var(--lr-ink-2);white-space:nowrap}
  .channel-header .channel-name{font-family:var(--lr-font-display);font-weight:800;font-size:19px;letter-spacing:-.025em;line-height:1.1;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .channel-live .live-indicator{font-size:14px}
  .brand-logo{width:28px;height:28px;flex:0 0 auto}
  .brand-logo canvas{width:28px;height:28px}
  .account-button{padding:0;min-width:40px;width:40px;height:40px}
  .account-button-label{display:none}

  /* Tracklist / Chat toggle in the header: 40px pill, hidden on desktop. The pill stays 40px tall (44px would grow
     the header row); its hit area stretches to var(--lr-tap) by the ::before in 06-shell-nav.css. */
  .phone-tab-toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;min-height:40px;padding:0 14px;border:1.5px solid var(--lr-rule-3);border-radius:var(--lr-radius-pill);background:var(--lr-card);color:var(--lr-ink);font:600 14px var(--lr-font-ui);cursor:pointer}
  .phone-tab-toggle[aria-pressed="true"]{background:var(--lr-ink);color:var(--lr-page);border-color:var(--lr-ink)}
  .phone-tab-toggle:focus-visible{outline:3px solid var(--focus);outline-offset:2px}

  /* The now-playing strip and the room-aside presence row are gone on phones: chat carries the conversation.
     The old side-column status card is also hidden on phones; the hero's status row is the single source. */
  #mobile-state-strip{display:none}
  .aside-presence{display:none}
  .aside-status{display:none}

  /* The whole <main> stays a column; .main gives the room main and the panel area their own rows. The room main
     stays in flow on BOTH chat and tracklist: on chat it carries the video and the playhead row above the panel
     area, on tracklist it adds the host controls card and reserves the video above. Hiding the whole section
     would drop the video on chat, defeating Change A's "video, track and chat on one screen" promise. The room
     main can shrink (flex:0 1 auto) only while the keyboard is open ([data-keyboard="open"], see the top of this
     block); with it closed the column keeps its content size. */
  #live .main{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:0}
  /* The room main sizes to its content (video + title + playhead + status). The 45vh cap from the first phone
     redesign clipped the playhead, backstage and banners; the panel area below now flexes to fill the rest. */
  .room-main{display:flex;flex-direction:column;flex:0 0 auto;min-height:0;overflow:hidden}
  .room-main > .listen-card{flex:0 1 auto;min-height:0}
  /* Banners and the claim card lost their side margins in the redesign; restore them. */
  .room-main>.countdown,.room-main>.claim-card,.room-main>.claim-slot>.claim-card{margin-left:16px;margin-right:16px}
  .countdown{flex-direction:column;align-items:stretch;gap:6px}
  .claim-slot:not(:empty){margin-top:16px}
  /* Backstage form lives inside .room-main; when it is visible let the main scroll or take full height so the show
     name, join setting, handle link and queue are not clipped by a height cap. */
  #live:has(#backstage:not([hidden])) .room-main{overflow:auto;max-height:none}
  /* The mobile-state strip is gone on phones; it must not leave an empty band under the header. */
  #mobile-state-strip{display:none}

  /* Video frame and stage: pinned under the header, 16px side padding, never scrolls away. The frame respects the
     shorter axis so a landscape phone (≈950×430) keeps the video at ≤50vh and leaves room for the panel area below;
     the aspect-ratio rule means width follows when height is clamped, so the box centres inside the page. */
  .listen-card{padding:16px 16px 0;background:transparent;border:0;box-shadow:none;overflow:visible}
  .media-frame{position:relative;width:100%;max-height:50vh;aspect-ratio:16/9;margin-left:auto;margin-right:auto;background:var(--lr-track);border-radius:var(--lr-radius-media);overflow:hidden;flex-shrink:0}
  .media-stage{position:absolute;inset:0;width:100%;height:100%}

  /* Track strip: padding 14/16/12, bottom rule, h1 base 28px, artist line 16px. The #now-title span keeps its
     per-data-size phone size from 04-room-design.css (32/38/48px); the fitter in app/title-fit.mjs measures the
     span itself and shrinks it only when it does not fit, so nothing is clamped or ellipsized. */
  .track-block{padding:14px 16px 12px;border-bottom:1px solid var(--lr-rule);margin-top:0;flex-shrink:0}
  .track-block #room-title{margin:0;font:800 28px/1.15 var(--lr-font-display);letter-spacing:-.035em;color:var(--lr-ink);overflow-wrap:break-word}
  .track-block .hero-artist{margin:4px 0 0;font:500 16px var(--lr-font-ui);color:var(--lr-ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

  /* Off-air block (the strip becomes "Nothing on the air"): */
  .track-block #room-title[data-size="off"]{font:800 28px/1.15 var(--lr-font-display)}

  /* Playhead row: elapsed · PhaseLine (32px, the one flexible column) · remaining · pause · mute, all on one row
     whatever the item count: the first two are explicit columns and anything further (listener pause, host pause)
     flows into an auto column, so no per-case column count is needed. Hidden items (display:none / [hidden]) take
     no column. Listener row never has the room pause; host-while-live adds its pause as another auto column. Each
     control is a 44px round button, restyled only. The pause-hint lives where the rule below puts it (fixed so it
     never goes off screen). */
  .playhead{display:grid;grid-template-columns:auto minmax(0,1fr);grid-auto-flow:column;grid-auto-columns:auto;align-items:center;gap:10px;margin-top:8px;font:400 14px var(--lr-font-time);color:var(--lr-ink-2)}
  .playhead .phase-line{min-width:0;height:32px;display:block}
  .playhead .phase-line canvas{height:32px}
  .playhead #elapsed,.playhead #timeline-remaining{min-width:0;white-space:nowrap}
  .playhead #timeline-remaining{color:var(--lr-ink-3)}
  .playhead .playhead-pause{display:inline-flex;align-items:center;justify-content:center}
  .round-button{min-width:44px;min-height:44px;width:44px;height:44px;display:inline-flex;align-items:center;justify-content:center;padding:0;border:1.5px solid var(--lr-rule-3);border-radius:50%;background:var(--lr-card);color:var(--lr-ink);cursor:pointer;flex:0 0 auto}
  .round-button:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
  .round-button[aria-pressed="true"]{background:var(--lr-ink);color:var(--lr-page);border-color:var(--lr-ink)}
  .round-button svg{width:20px;height:20px}
  .playhead .playhead-pause #pause-hint{position:fixed;bottom:auto}

  /* Status row: only states that carry information show it (listener ≠ synced; host = paused / off). Title only on
     phones (no detail line), 48px primary button. 08-sync-motion.css owns the open/close via grid-template-rows;
     the row lives inside .sync-status-clip which carries min-height:0 and overflow:hidden, so the section can
     collapse past its own padding and border. Touching display here would defeat the slide. */
  .sync-status-slot{flex:0 0 auto}
  .sync-status-slot .sync-status{margin:0;padding:10px 16px;border-bottom:1px solid var(--lr-rule)}
  .sync-status-slot .sync-status[data-state="idle"] .sync-glyph{display:none}
  .sync-status-slot .sync-status[data-state="idle"]{gap:0}
  .sync-status-slot .sync-glyph{width:24px;height:24px}
  .sync-status-slot .sync-glyph canvas{width:24px;height:24px}
  .sync-status-slot .sync-status-copy{min-width:0}
  .sync-status-slot .sync-title{font:700 15px var(--lr-font-ui);color:var(--lr-ink);letter-spacing:0;text-transform:none}
  .sync-status-slot .sync-primary{min-height:48px;padding:0 22px;border:0;border-radius:var(--lr-radius-pill);background:var(--lr-red);color:var(--lr-on-red);font:600 16px var(--lr-font-ui);box-shadow:var(--lr-shadow-press)}

  /* Panel area: chat messages or the tracklist, flex:1 so it takes the remaining space; the composer bar is fixed to
     the viewport bottom. The host card sits in the tracklist view, above the tracklist. */
  .room-aside{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;background:transparent;border:0;position:static;top:auto;align-self:auto;overflow:visible;max-height:none;height:auto;margin:0;border-radius:0}

  /* Chat messages region: fills the panel area and the newest message sits above the composer; the list scrolls
     inside chat-body and is stuck to the bottom. The reaction layer covers the area. The chat column is a flex
     column so the composer (chat-actions) sits at the bottom and chat-body takes the rest of the height. */
  #live[data-mobile-tab="chat"] .room-aside .chat{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;border:0;border-radius:0;background:transparent;padding:0;margin:0;position:relative}
  #live[data-mobile-tab="chat"] .room-aside .chat-body{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;position:relative;overflow:hidden}
  #live[data-mobile-tab="chat"] .room-aside .chat-list{display:flex;flex-direction:column;gap:10px;justify-content:flex-end;flex:1 1 auto;min-height:0;padding:12px 16px;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  #live[data-mobile-tab="chat"] .room-aside .chat-list::-webkit-scrollbar{display:none}
  #live[data-mobile-tab="chat"] .room-aside .reaction-layer{position:absolute;inset:0;overflow:hidden;pointer-events:none}

  /* Composer bar (chat-actions): the last flex child of the chat column, sized to remain. Putting it in the flex
     column keeps it above the keyboard when the column height follows the visual viewport later; the chat-list
     above it (flex:1, min-height:0) shrinks, so the composer never overlaps the last message. */
  .chat-actions{flex:0 0 auto;display:flex;align-items:center;gap:8px;padding:10px 16px;padding-bottom:max(10px,env(safe-area-inset-bottom,0px));background:var(--lr-page);border-top:1px solid var(--lr-rule)}
  .chat-actions .chat-foot{flex:1 1 auto;min-width:0;padding:0;border-top:0;background:transparent}
  .chat-actions .chat-foot .chat-input{flex:1 1 12ch;min-width:9ch;width:auto;height:50px;padding:0 18px;border:1.5px solid var(--lr-rule);border-radius:999px;background:var(--lr-field);color:var(--lr-ink);font:400 16px var(--lr-font-ui)}
  .chat-actions .chat-foot .chat-input::placeholder{color:var(--lr-ink-3)}
  .chat-actions .chat-foot .chat-send{height:50px;min-width:64px;padding:0 20px;border:0;border-radius:var(--lr-radius-pill);background:var(--lr-ink);color:var(--lr-page);font:600 16px var(--lr-font-ui)}
  .chat-actions .chat-signin{flex:1;min-width:0;margin:0;align-self:center}
  .chat-actions .heart-slot{display:flex;align-items:center;flex:none}
  .chat-actions .heart-slot:empty,.chat-actions .heart-slot[hidden]{display:none}

  /* The chat column flexes its three children: chat-body (flex:1, the scroll list) sits between the agent/follow host
     band and the composer, so the composer is always the last row and never overlaps the messages. */
  #live[data-mobile-tab="chat"] .room-aside .chat-body{flex:1 1 auto}
  #live[data-mobile-tab="chat"] .room-aside .chat{flex:1 1 auto}

  /* Tracklist view: the panel area shows the host card (host only) then the tracklist. The tracklist gets a margin
     so its rows do not touch the screen edge (CJ, 2026-10-06 iPhone review). */
  #live[data-mobile-tab="tracklist"] .room-aside{order:1}
  #live[data-mobile-tab="tracklist"] .aside-tracklist{display:flex;flex-direction:column;flex:1 1 auto;min-height:120px;padding:0 16px var(--lr-space-4);overflow-y:auto;overscroll-behavior:contain}
  #live[data-mobile-tab="tracklist"] .aside-tracklist .tracklist-head{padding:14px 0 8px}
  #live[data-mobile-tab="tracklist"] .aside-tracklist .powered-by{margin-top:auto;padding:8px 0 0}
  /* Each panel hides on the other tab so the column shows one panel at a time. Only on phones: at 720px+ the rail
     keeps both panels visible regardless of the tab value (desktop rail is a column, not a single-panel switch). */
  #live[data-mobile-tab="chat"] .room-aside .aside-tracklist{display:none}
  #live[data-mobile-tab="tracklist"] .room-aside .chat,#live[data-mobile-tab="tracklist"] .room-aside .chat-mutes{display:none}
  /* Restore the tracklist in its tab: 02-grain-chat.css hides .room-aside .tracklist on desktop, and the override
     was dropped when Change A moved phone rules here (#154 A1). The panel already scrolls; this just makes the
     list visible again (#160 item 7). */
  #live[data-mobile-tab="tracklist"] .room-aside .tracklist{display:grid}
  #live[data-mobile-tab="tracklist"] .room-aside .tracklist-wrap{display:block}

  /* The host controls are phone-only inside the tracklist view: above the tracklist. Listeners never see them. The
     card has its own scroll so a long queue cannot push the video off the screen (defect 1, brief). */
  #host-controls{display:none}
  #live[data-mobile-tab="tracklist"] #host-controls:not([hidden]){display:flex;flex-direction:column;order:0;
    flex:0 0 auto;max-height:40vh;overflow-y:auto;overscroll-behavior:contain;margin:16px 16px 0;
    border-radius:var(--lr-radius-card);background:var(--lr-card);box-shadow:var(--lr-shadow-card);padding:14px 16px 16px}

  /* Status row stays above the panel area on phones; the page itself has no padding-bottom now that the composer
     lives in the flex column. */
  .shell{padding:0}
  #live[data-mobile-tab="chat"] .shell,#live[data-mobile-tab="tracklist"] .shell{padding-bottom:0}
  /* The Listen live button lives in the status row at the end of .room-main, above the panel area. The old fixed
     positioning overlapped the chat list; keeping it in flow lets the panel area flex below it. */
  #tap-listen:not([hidden]){position:static;width:100%;margin:0}

  /* Short screens (under 700px tall): the strip collapses to one line — title, PhaseLine and mute only. Built, not
   # optional (liner-integration.md, "Short screens" departure). The CSS attribute selector keeps this out of the
   # way on every other viewport. The video frame also shrinks: on a landscape phone (≈930×430) the natural 16:9
   # frame would push the panel area below the fold, so the cap is max(30vh,200px) here (never below 200px, leaves
   # room for the strip + panel area + composer). The composer is also more compact on a short viewport so the
   * chat list above it still has the 60px minimum the brief asks for. */
  @media (max-height:699.98px) {
    .media-frame{max-height:max(30vh,200px)}
    .track-block .hero-artist{display:none}
    .track-block{padding:8px 12px 8px}
    .track-block #room-title{font-size:22px}
    /* The #now-title span inside the h1 keeps its 32/38/48px data-size sizes from 04-room-design.css:122-125;
       pin it to the same 22px design size here (09 loads after 04 and 07, equal specificity wins). */
    .track-block #now-title,.track-block #now-title[data-size]{font-size:22px}
    .playhead{margin-top:4px}
    .playhead .playhead-pause{display:none}
    .chat-actions{padding:4px 12px;padding-bottom:max(4px,env(safe-area-inset-bottom,0px))}
    .chat-actions .chat-foot .chat-input{height:36px;padding:0 12px;font-size:16px}
    .chat-actions .chat-foot .chat-send{height:36px;min-width:48px;padding:0 12px;font-size:14px}
    .chat-actions .heart-slot{width:36px;height:36px}
    .chat-actions .heart-button{width:36px;height:36px}
  }

  /* Landscape phone (≈932×430): the tracklist panel keeps a 60px floor and loses the desktop 44vh cap so it can
     fill its panel. */
  @media (max-height:559.98px) {
    #live[data-mobile-tab="tracklist"] .aside-tracklist{min-height:60px}
    .room-aside .aside-tracklist{max-height:none}
  }

  /* Sideways phone: a video item fills the visual viewport so the player is never squeezed below the 200px
     minimum. Music items, portrait phones, and the "tap to listen" prompt keep the normal stacked layout.
     In landscape the page scrolls so the Listen live button, mute and pause are never covered by the chat panel;
     the panel area yields to a capped height so the page does not grow wildly. After the first tap on a video item
     the fullscreen rule below restores the fixed viewport. */
  @media (orientation:landscape) and (max-height:559.98px) {
    #live{height:auto;min-height:var(--phone-vvh,100dvh);overflow:visible}
    /* Landscape scrolls the page by design (the lock above is portrait-only in effect). */
    html,body{position:static;height:auto;overflow:auto;overscroll-behavior:auto}
    .room-aside{flex:0 0 auto;height:min(40vh,200px);min-height:60px}
    .room-main{overflow:visible}
    /* Compact the hero strip in landscape: less top padding and an inline status row so the room main fits above
       the chat strip without clipping controls. */
    .listen-card{padding-top:4px}
    .sync-status-slot .sync-status{padding:4px 16px;grid-template-columns:auto minmax(0,1fr) auto;gap:10px}
    .sync-status-slot .sync-primary{grid-column:auto;width:auto;margin-top:0}
    /* The short-screen rule hides the listener pause to save vertical space; before the first tap it must show.
       The playhead flows extra items into auto columns, so restoring the pause needs no column override. */
    body:has(#tap-listen:not([hidden])) .playhead .playhead-pause{display:inline-flex}
    /* Safari hides its bars only when the user scrolls the page, so the page gets scroll room; #173. */
    body:has(#artwork-slot[data-presentation="video"]):not(:has(#tap-listen:not([hidden]))) #live{height:calc(100lvh + 80px);overflow:hidden}
    body:has(#artwork-slot[data-presentation="video"]):not(:has(#tap-listen:not([hidden]))) .media-frame{
      position:fixed; inset:0; width:100vw; height:var(--phone-vvh,100dvh); max-height:none; aspect-ratio:auto;
      border-radius:0; z-index:6; background:#000;
      padding:env(safe-area-inset-top,0px) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px);
      box-sizing:border-box;
    }
    body:has(#artwork-slot[data-presentation="video"]):not(:has(#tap-listen:not([hidden]))) .media-frame .media-stage,
    body:has(#artwork-slot[data-presentation="video"]):not(:has(#tap-listen:not([hidden]))) .media-frame .media-stage iframe{
      position:absolute; inset:0; width:100%; height:100%;
    }
    body:has(#artwork-slot[data-presentation="video"]):not(:has(#tap-listen:not([hidden]))) .media-frame .media-stage iframe{
      width:100% !important; height:100% !important;
    }
  }
}

/* Phone toggle is hidden on desktop (the rail carries Chat / Tracklist via the SegmentedControl there). */
.phone-tab-toggle{font-family:var(--lr-font-ui)}