/* The Library pane: same shell as .groceries -- a pale scrolling field over the
   shared chrome, no chrome of its own. */
.library[hidden] {
  display: none;
}

/* .app-card-list sets its own display: flex, which otherwise outranks the browser's default
   [hidden] rule at equal specificity -- the same footgun as .groceries[hidden]
   exist to fix for their own panes. Without this, toggling the list's hidden attribute while
   switching to the detail view leaves it visibly stacked above the detail it was replaced by. */
.library-list[hidden],
.library-detail[hidden] {
  display: none;
}

.library-title:focus {
  outline: none;
}

/* The empty state's inline mark: the pane's own bookmark glyph at the icon-button size,
   in the empty line's own ink -- decoration beside the sentence, never a substitute
   for it. */
.library-empty-icon {
  display: inline-flex;
  vertical-align: -3px;
  margin-right: 0.35rem;
}

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

/* The search/filter card: a gap below it before the on-wall note, in place of the controls'
   own former bottom margin now that .app-card's own padding is the inset around them. */
.library-controls-card {
}

.library-controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-r2);
}

.library-controls .app-search {
  flex: 1 1 14rem;
}

/* The phone layout changes the controls to a column in styles-wall.css. This rule is
   repeated here because this stylesheet loads later: the desktop width basis must not
   become a vertical height for the search row. */
@media (max-width: 30rem) {
  .library-controls .app-search {
    flex: 0 0 auto;
  }
}

.library-search {
  min-height: var(--touch-min);
}

.library-status {
  margin: 0.3rem 0 0;
}

/* One card per saved source -- the card idiom, not the divider list, because a saved email
   and a saved photo are each a thing in their own right, exactly the reasoning a list row
   already gives. The whole card is the control: a plain reset button, not a link, since it
   opens an in-page detail view rather than navigating anywhere. */
.library-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  width: 100%;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.library-row:hover,
.library-row:focus-visible {
  border-color: var(--accent);
}

.library-row-main {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
  overflow-wrap: break-word;
}

/* Large text: the badge and the trailing date share the first line (the date keeps the right
   edge through .app-row-trailing's own auto margin) and the title/preview pair takes the full
   second line. Order only -- the normal-size DOM order (badge, main, date) stays the reading
   order at every size; appending the date beside the badge in markup would change the
   normal-size layout, so the swap is visual, at Large only. */
:root[data-text-size="large"] .library-row {
  flex-wrap: wrap;
}

:root[data-text-size="large"] .library-type-badge {
  order: -2;
}

:root[data-text-size="large"] .library-row > .app-row-trailing {
  order: -1;
}

:root[data-text-size="large"] .library-row-main {
  flex-basis: 100%;
}

.library-type-badge {
  flex: none;
  /* A type badge names a kind, so it reads a step heavier than an ordinary marker. */
  font-weight: var(--w-title);
  white-space: nowrap;
}

/* Back and title are the shared .app-back-bar's now; the entry itself is one .app-card. */
/* #library-detail is already the outer .app-card, so the entry inside it adds no second
   inset (or second surface): one level of padding, the outer card's own. */
.library-detail-card {
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
  overflow-wrap: anywhere;
}

.library-detail-body {
  margin: 0.6rem 0;
}

.library-field {
  margin: 0 0 0.3rem;
  font-size: var(--text-detail-body);
}

.library-gmail-link,
.library-link-url {
  display: inline-block;
  margin: 0.2rem 0 var(--space-r2);
}

.library-email-body,
.library-note-text {
  white-space: pre-wrap;
  margin: var(--space-r2) 0;
}

.library-attachment {
  display: block;
  margin: 0.2rem 0;
}

.library-omitted {
  margin: 0.1rem 0;
}

.library-image {
  max-width: 100%;
}

.library-linked-events {
  margin: 0.3rem 0;
  padding-left: 1.1rem;
  font-size: var(--text-detail-body);
}

.library-remove {
  margin-top: var(--space-r3);
  color: var(--library-note-ink);
  border-color: var(--library-remove-border);
}

/* Rundell OS: the page is one scroller on the shared card field; the app-page-header
   and app-page-body primitives own its title-to-block rhythm, so the pane sets no gap of
   its own. */

.agent-rundell-now {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

#agent-task-context {
  flex: none;
}

.agent-rundell-status:empty,
.agent-rundell-history:empty {
  display: none;
}

.agent-rundell-suggestions {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* The Agent page's suggestions: each row is its own card-like surface (badge, copy that
   wraps up to three lines, a small × at the right). */
.agent-suggestion-list-page .agent-suggestion-page {
  grid-template-columns: minmax(0, 1fr) var(--touch-min);
  grid-template-areas: "try dismiss";
  gap: 0;
  min-height: 53px;
  margin: 0;
  padding: 11px var(--space-xs) 11px var(--space-xl); /* right side is the 44px × column's own room */
  background: var(--agent-page-row);
  border: 1px solid var(--line);
  border-radius: var(--radius-surface);
}

.agent-suggestion-page .agent-suggestion-try {
  grid-area: try;
  grid-template-columns: 34px minmax(0, 1fr);
  align-items: center;
  gap: 11px;
}

.agent-suggestion-page .agent-suggestion-dismiss {
  grid-area: dismiss;
  align-self: center;
  justify-self: end;
}

.agent-suggestion-page .agent-suggestion-badge {
  width: 34px;
  height: 34px;
  color: var(--agent-gold-ink);
  background: var(--agent-gold-badge);
  border-radius: var(--radius-control);
}

.agent-suggestion-page .agent-suggestion-badge svg {
  width: 18px;
  height: 18px;
}

.agent-suggestion-page .agent-suggestion-text {
  font-size: var(--text-caption);
  white-space: normal;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

.agent-history-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-md);
  min-height: var(--touch-min);
  padding: var(--space-md) var(--space-xl);
  border-radius: 0;
}

.agent-rundell-history button,
#books-queue li button {
  min-height: var(--touch-min);
}

.agent-history-row svg {
  width: 16px;
  height: 16px;
  color: var(--agent-gold-ink);
}

.agent-rundell-more {
  align-self: center;
  margin: var(--card-gap) auto 0;
}

/* The "Load more" button once IntersectionObserver is watching it (see autoPageOnScroll in
   chat.js): an inert one-pixel marker at the foot of the list, never a control. */
button.paging-sentinel.app-quiet-button {
  height: 1px;
  min-height: 0;
  padding: 0;
  border-width: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

/* Music */

/* The Music pane: the pane is the scroller on the shared card
   field and every text element carries a shared type class, so nothing here sets a size.
   The transport buttons reuse .podcast-control, the app's one transport circle. The
   gold-and-blue card round drops the section markers' shared destination tint with
   Podcasts (SURFACES: "cards are equal") -- Up next, Playlists and Played all sit directly
   on the wallpaper as labels for the card below them now, so they read in the shared label
   treatment instead. */
/* Play is a compact square icon button in the open playlist's title row. */
.music-play {
  display: grid;
  place-items: center;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  padding: 0;
}

.music-status {
  margin: 0;
}

.music-failure {
  margin: 0;
}

/* The playlist detail's own slot is written only when something fails, and keeps no box
   while empty. */
.music-failure:empty {
  display: none;
}

/* The disconnected state is the one state that asks for something (tap Connect), so its
   status sentence reads in ink rather than the shared status line's muted caption -- the
   same one-declaration step up .app-notice takes over .app-inset content. */
.music[data-state="disconnected"] .music-status {
  color: var(--ink);
}

/* The unconfigured page's one control: the shared filled button stretched across the page body,
   in the place of the feature sections it stands in for. It names no display, so the browser's
   own [hidden] rule keeps it off in every other state. */
.music-queue,
.audio-up-next-list,
.music-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.audio-up-next-row,
.music-queue-item {
  padding: 0.3rem 0;
}

/* The divider list owns the boundary; the shared row stays flat and keeps its own wash out. */
.audio-up-next-row {
  border-radius: 0;
}

.audio-up-next-row:hover,
.audio-up-next-row:focus-visible {
  background: transparent;
}

/* The actions slot uses the shared .app-row-actions rule. The sub-heading over the shuffle rows
   is a quiet label, not a row. */

.music-queue-subhead {
  margin: var(--space-r2) 0 0.1rem;
}

/* An editable row is one line: handle, the tappable text, remove. The handle and dragging
   look come from the .podcast-queue-* rules. */
.audio-up-next-main {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  color: inherit;
  background: none;
  border: 0;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.audio-up-next-main > span:not(.app-row-title):not(.app-row-meta) {
  display: block;
}

/* One line at every text size: art, the track's text (the only part allowed to shrink) and
   the trailing icon action. nowrap is what keeps the overflow toggle beside the text at
   Large instead of dropping it to a line of its own. */
.music-row,
.music-song-item {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.6rem;
  padding: var(--space-r2) 0;
}

.music-art {
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-control);
  object-fit: cover;
}

.music-row-text {
  flex: 1 1 10rem;
  min-width: 0;
}

/* Play's icon face: sized and coloured like every other inline-SVG button in
   the app (.icon-button svg, .message-clear svg), scoped to this class rather than
   added to .icon-button itself -- these stay .app-primary-button/.app-quiet-button, not
   the transparent .icon-button family, so their selected/hover/focus/disabled styling is
   exactly what it always was. */
.music-play svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A playlist track's overflow menu: the shared icon-button toggle (aria-haspopup/
   aria-expanded, an .app-inset-shaped menu hanging below its trigger), so the one
   destructive action is demoted out of the row's face without a second overflow
   component being invented. */
.music-overflow {
  position: relative;
  display: flex;
  flex: none;
}

.music-overflow-menu {
  position: absolute;
  top: calc(100% + 0.15rem);
  right: 0;
  z-index: 5;
  min-width: 11rem;
  /* Tighter than the shared inset, for the same reason the review menu is: a column of
     full-width buttons that bring their own padding. */
  padding: 0.2rem;
  border: 1px solid var(--line);
}

.music-overflow-menu[hidden] {
  display: none;
}

.music-overflow-menu button {
  display: block;
  width: 100%;
  color: var(--ink);
  text-align: left;
}

/* The two library sections at the foot of the Music pane -- Agent Kit's own Playlists and
   Played, read-and-play only -- and the disclosure rows the Playlists list is built from.
   The lists are .app-divider-list rows inside an .app-card; only the genuinely new shapes
   are styled here. */

.music-library-sync-toggle {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* A playlist row's title/meta pair, as the navigation control it is: an .app-row button
   that opens the playlist's own detail view. .app-row supplies the pressable row face; this
   only stacks the pair, shares the line with the row's controls and drops the row padding
   (the li carries it). */
.music-row-toggle {
  flex: 1 1 0;
  min-width: 0;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 0.1rem;
  min-height: var(--touch-min);
  padding: 0;
}

/* The open playlist's title row: the heading on the wall, with its Play control on the same line. */
.music-detail-header {
  display: flex;
  align-items: center;
  gap: var(--space-r2);
  margin: 0 0 var(--card-gap);
}

.music-detail-header > .app-toolbar-title {
  color: var(--ink-heading);
  font-size: var(--text-section);
  text-shadow: var(--text-shadow-on-wall);
}

.music-detail-actions {
  display: flex;
  flex: none;
  gap: 0.4rem;
}

.music-row-actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--space-r2);
  margin-left: auto;
  justify-content: flex-end;
}

/* The row's 44px touch targets do not shrink fractionally when the line is tight. */
.music-row-actions > * {
  flex: none;
}

.music-shuffle-switch {
  display: flex;
  align-items: center;
  min-height: var(--touch-min);
}

.music-shuffle-switch > * {
  flex: none;
}

.music-shuffle-switch label {
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
  justify-content: center;
}

.music-shuffle-switch .timers-switch-track::after {
  display: none;
}

.music-shuffle-switch .timers-switch input:checked + .timers-switch-track {
  background: var(--line);
}

.music-shuffle-switch .timers-switch-track svg {
  position: absolute;
  top: 0.2rem;
  left: 0.2rem;
  width: var(--space-r4);
  height: var(--space-r4);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--muted);
  transition: transform var(--motion-press, 0.12s) ease, color var(--motion-press, 0.12s) ease;
}

.music-shuffle-switch .timers-switch input:checked + .timers-switch-track svg {
  transform: translateX(1rem);
  color: var(--accent);
}

.android-setup {
  margin-top: var(--card-gap);
}

.android-setup-unsupported,
.android-setup-unpublished,
.android-setup-account,
.android-setup-device {
  margin: 0 0 var(--card-gap);
}

.android-setup-account {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-r2);
}

/* The event detail's link back to the source it was extracted from -- present only when
   the event carries one. Sits with the detail's other fields, not beside the title. */
.agenda-event-source {
  margin: 0.3rem 0;
}
