/* ==========================================================================
   page-feeds.css — owned jointly by the four feed templates:

     trending.html      the numbered chart
     explore.html       category tiles + one shelf per category
     client_feed.html   history / watch later / liked / library, hydrated from
                        localStorage by js/feeds.js
     video_list.html    /videos/, the information-dense crawlable library

   Everything structural already exists and is reused rather than rebuilt:
   .yt-page .yt-row .yt-stack .yt-spacer .yt-pill .yt-btn .yt-icon-btn
   .yt-badge .yt-link .yt-alert (tokens.css / chrome.css), .yt-grid .yt-shelf
   .yt-card .yt-short .yt-avatar .yt-skeleton .yt-empty .yt-queue-banner
   .yt-rank .yt-section__head (components.css), .yt-segmented .yt-table
   .yt-table-wrap .yt-footer (forms.css).

   SECTIONS
     1. Shared feed chrome ..... .yt-feeds__*  (header, toolbar, notes)
     2. Trending ............... .yt-trending__*
     3. Explore ................ .yt-explore__*
     4. Client feeds ........... .yt-feeds__section, .yt-feeds__card
     5. Library ................ .yt-library__*

   Gutters: tokens.css drops .yt-page's horizontal padding below 792px so the
   card grid can go full bleed like mobile YouTube. Every block on these pages
   that is NOT a grid therefore restores its own 16px gutter at that width.
   Components that already do it themselves (.yt-queue-banner, .yt-section__head,
   .yt-grid, .yt-shelf) are left alone — doubling it would inset them twice.

   Non-token literals used here, and why (no token exists for them):
     56px / 48px            the header glyph circle and the tile icon circle
     128px                  the library row thumbnail width
     940px                  the library table's minimum width inside its own
                            horizontal scroller
     36px / 18px            the pagination button box and its radius, matching
                            .yt-pill's 36px capsule
     13px / 12px / 11px     text one and two steps under .yt-t-body
     72ch / 88ch / 96ch     measure caps on prose, so a 2560px viewport does
                            not produce 300-character lines
     rgba(255,78,69,.14)    hover tint for the destructive Clear-all button,
                            the same construction components.css uses for
                            .yt-badge--danger
     .24s / 6px             duration and travel of the card fade-in
   ========================================================================== */


/* ==========================================================================
   1. SHARED FEED CHROME

   All four pages open with the same header shape (glyph, title, one-line
   explanation, a trailing badge or button) and close with the same muted
   footnote, so the shell lives here once.
   ========================================================================== */

.yt-feeds {
  min-width: 0;
}

.yt-feeds__head {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 20px;
  min-width: 0;
}

.yt-feeds__glyph {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--yt-bg-chip);
  color: var(--yt-fg);
}

.yt-feeds__head-text {
  flex: 1 1 260px;
  min-width: 0;
}

.yt-feeds__sub {
  margin-top: 4px;
  max-width: 72ch;
  color: var(--yt-fg-secondary);
  font-size: 14px;
  line-height: 1.5;
  text-wrap: pretty;
}

.yt-feeds__window,
.yt-feeds__head-link,
.yt-feeds__head-cta {
  flex: 0 0 auto;
  align-self: center;
}

/* A short explanatory strip under the header — how a chart position is
   earned, what a category actually means. Deliberately quieter than
   .yt-alert: it is context, not a warning. */
.yt-feeds__note {
  margin-bottom: 24px;
  padding: 12px 16px;
  max-width: 96ch;
  border-radius: var(--yt-radius-md);
  background: var(--yt-bg-chip);
  color: var(--yt-fg-secondary);
  font-size: 13px;
  line-height: 1.55;
  text-wrap: pretty;
}
.yt-feeds__note strong { color: var(--yt-fg); font-weight: 500; }

.yt-feeds__foot {
  margin-top: 32px;
  max-width: 88ch;
  color: var(--yt-fg-secondary);
  font-size: 13px;
  line-height: 1.6;
  text-wrap: pretty;
}

/* .yt-queue-banner supplies its own gutter below 792px, so this wrapper only
   has to stop the flex/grid context from collapsing it. */
.yt-feeds__banner {
  min-width: 0;
}

.yt-feeds__toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--yt-border);
  min-width: 0;
}

.yt-feeds__count {
  min-width: 0;
  color: var(--yt-fg-secondary);
  font-size: 14px;
  line-height: 1.43;
}
.yt-feeds__count strong { color: var(--yt-fg); font-weight: 500; }

.yt-feeds__sort { flex: 0 0 auto; }

/* Destructive, so it reads as destructive — but it is still a ghost button
   rather than a filled one, because it sits in a toolbar and must not
   out-shout the content. */
.yt-feeds__danger { color: var(--yt-danger); }
.yt-feeds__danger:hover { background: rgba(255, 78, 69, .14); }

/* The toolbar's own Clear-all. Quieter than .yt-feeds__danger at rest — it
   sits next to the count and the sort control, and a permanently red button
   in a toolbar reads as an error state — and it only turns destructive on
   hover/focus, where the intent is already there. It merely OPENS the confirm
   dialog, whose own button is the one that deletes. */
.yt-feeds__clear { flex: 0 0 auto; }
.yt-feeds__clear:hover,
.yt-feeds__clear:focus-visible {
  color: var(--yt-danger);
  background: rgba(255, 78, 69, .14);
}

@media (max-width: 792px) {
  .yt-feeds__head,
  .yt-feeds__foot { padding-inline: 16px; }
  .yt-feeds__note,
  .yt-feeds__toolbar { margin-inline: 16px; }
}


/* ==========================================================================
   2. TRENDING — a numbered chart of wide rows

   The numeral is a SIBLING of the card, not part of it: partials/video_row.html
   is shared with the search results and stays untouched, and the chart
   geometry lives entirely here.
   ========================================================================== */

.yt-trending { min-width: 0; }

/* The chart glyph is the one place a brand-red accent is right: it is the
   page's identity, exactly as .yt-shelf__title uses it for Shorts. */
.yt-trending .yt-feeds__glyph { color: var(--yt-brand); }

.yt-trending__list {
  display: flex;
  flex-direction: column;
  gap: 24px;
  min-width: 0;
}

.yt-trending__item {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  min-width: 0;
}

.yt-trending__card {
  flex: 1 1 auto;
  min-width: 0;
}

/* 660–792px: the row card is still side by side, but .yt-page has dropped its
   padding, so the whole item needs the gutter back. */
@media (min-width: 660px) and (max-width: 792px) {
  .yt-trending__item { padding-inline: 16px; }
}

/* Below 660px .yt-card--row becomes a stacked card with a full-bleed radius-0
   thumbnail. A rank column beside it would inset that thumbnail and break the
   full bleed, so the numeral moves above the card instead — aligned with the
   12px text inset components.css gives the stacked row. */
@media (max-width: 659px) {
  .yt-trending__list { gap: 16px; }
  .yt-trending__item { display: block; }
  .yt-trending__item .yt-rank--lg {
    min-width: 0;
    padding: 0 12px 4px;
    font-size: 20px;
    text-align: left;
  }
}


/* ==========================================================================
   3. EXPLORE — category tiles above one shelf per category
   ========================================================================== */

.yt-explore { min-width: 0; }

.yt-explore__tiles {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  margin-bottom: 32px;
  min-width: 0;
}

.yt-explore__tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 16px;
  border: 1px solid transparent;
  border-radius: var(--yt-radius-md);
  background: var(--yt-bg-chip);
  color: var(--yt-fg);
  transition: background var(--yt-transition), border-color var(--yt-transition);
}
.yt-explore__tile:hover {
  background: var(--yt-bg-hover);
  border-color: var(--yt-border);
}

.yt-explore__tile-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin-bottom: 10px;
  border-radius: 50%;
  /* --bg-elevated reads as a raised disc on --bg-chip in dark, and as a white
     disc on light grey in the light theme. Both directions stay legible. */
  background: var(--yt-bg-elevated);
  color: var(--yt-fg);
}

.yt-explore__tile-label {
  font-size: 16px;
  font-weight: 500;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.yt-explore__tile-count {
  color: var(--yt-fg-secondary);
  font-size: 12px;
  line-height: 1.4;
}

/* One line only: a 200-character title must not make one tile twice as tall
   as its neighbours. */
.yt-explore__tile-latest {
  margin-top: 4px;
  overflow: hidden;
  color: var(--yt-fg-secondary);
  font-size: 12px;
  line-height: 1.4;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.yt-explore__row { min-width: 0; }

@media (max-width: 792px) {
  .yt-explore__tiles { padding-inline: 16px; }
}
@media (max-width: 659px) {
  .yt-explore__tiles { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .yt-explore__tile { padding: 12px; }
  .yt-explore__tile-icon { width: 40px; height: 40px; margin-bottom: 8px; }
}


/* ==========================================================================
   4. CLIENT FEEDS — history / watch later / liked / library

   The markup is chrome only; js/feeds.js clones the page's card <template>
   once per localStorage entry. Sections ship [hidden] and are revealed by the
   script, so a store that turns out to be empty never flashes an empty shelf.
   ========================================================================== */

.yt-feeds--client { min-width: 0; }

.yt-feeds__skeleton { min-width: 0; }

.yt-feeds__section {
  margin-bottom: 40px;
  min-width: 0;
}
.yt-feeds__section:last-of-type { margin-bottom: 0; }

.yt-feeds__section-count {
  color: var(--yt-fg-secondary);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.yt-feeds__blocked,
.yt-feeds__noscript { margin-bottom: 20px; }

@media (max-width: 792px) {
  .yt-feeds__blocked,
  .yt-feeds__noscript { margin-inline: 16px; }
}

/* A stored entry carries a channel NAME but no channel colour: the palette
   (models.AVATAR_COLORS) lives on the server and is not a design token, so a
   client-rendered avatar cannot reproduce the deterministic hue. It stays a
   neutral circle — and the colour has to be restated because components.css
   sets .yt-avatar's text to a dark literal, which is correct on the pastel
   server palette and invisible on this neutral chip background. */
.yt-feeds__card .yt-avatar { color: var(--yt-fg-secondary); }

/* Added by feeds.js to each card it appends. */
.yt-feeds__appear { animation: yt-feeds-appear .24s ease both; }

@keyframes yt-feeds-appear {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* tokens.css already neutralises animations under reduced motion; restated so
   this file stays correct if it is ever read on its own. */
@media (prefers-reduced-motion: reduce) {
  .yt-feeds__appear { animation: none; }
}


/* ==========================================================================
   5. LIBRARY — /videos/

   A real table, wrapped in .yt-table-wrap. The wrapper is what keeps the wide
   layout honest: the table scrolls inside its own box, so the page body never
   scrolls sideways at 320px.
   ========================================================================== */

.yt-library { min-width: 0; }

.yt-library__ffmpeg { margin-bottom: 24px; }

.yt-library__wrap { margin-bottom: 24px; }

/* Eight columns with a 128px thumbnail need more room than forms.css's
   generic 560px floor. Scoped to the wrapper, exactly as forms.css scopes
   its own floor, so a missing wrapper squashes the columns instead of
   pushing the whole document into horizontal scroll. */
.yt-table-wrap > .yt-library__table { min-width: 940px; }

/* The video cell is a <th scope="row"> for real row-header semantics, which
   would otherwise render bold. */
.yt-library__cell-video {
  min-width: 320px;
  font-weight: 400;
}

.yt-library__video {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-width: 0;
}

/* Composed with .yt-card__thumb, which supplies the 16:9 box, the overflow
   clip, the black letterbox and every overlay chip. Only the size and the
   corner radius change. */
.yt-library__thumb {
  flex: 0 0 128px;
  width: 128px;
  border-radius: var(--yt-radius-sm);
}

.yt-library__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.yt-library__title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  max-height: 2.8em;
  color: var(--yt-fg);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.yt-library__title:hover { color: var(--yt-accent); }

.yt-library__byline {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
  color: var(--yt-fg-secondary);
  font-size: 12px;
  line-height: 1.4;
}

.yt-library__channel,
.yt-library__category {
  max-width: 22ch;
  overflow: hidden;
  color: var(--yt-fg-secondary);
  text-overflow: ellipsis;
  white-space: nowrap;
}
a.yt-library__channel:hover,
a.yt-library__category:hover { color: var(--yt-fg); }

.yt-library__dims {
  display: block;
  margin-top: 2px;
  color: var(--yt-fg-secondary);
  font-size: 11px;
}

/* An em dash for a value ffprobe has not measured. Muted, so a column of them
   does not read as data. */
.yt-library__unknown { color: var(--yt-fg-secondary); }

.yt-library__actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* -- Pagination ----------------------------------------------------------
   Real anchors built with {% query_replace %}: this page works with JS off. */

.yt-library__pager {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}

.yt-library__pager-step[aria-disabled="true"] {
  opacity: .45;
  cursor: default;
}
.yt-library__pager-step[aria-disabled="true"]:hover { background: transparent; }

.yt-library__pages {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px;
  min-width: 0;
}

.yt-library__page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 36px;
  padding: 0 8px;
  border-radius: 18px;
  color: var(--yt-fg);
  font-size: 14px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  transition: background var(--yt-transition);
}
a.yt-library__page:hover { background: var(--yt-bg-hover); }

.yt-library__page--current {
  background: var(--yt-bg-chip-active);
  color: var(--yt-fg-inverse);
}

.yt-library__gap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 36px;
  color: var(--yt-fg-secondary);
}

@media (max-width: 792px) {
  .yt-library__ffmpeg,
  .yt-library__wrap { margin-inline: 16px; }
  .yt-library__pager { padding-inline: 16px; }
}

@media (max-width: 659px) {
  .yt-library__cell-video { min-width: 260px; }
  .yt-library__thumb { flex-basis: 96px; width: 96px; }
}
