/* ==========================================================================
   VideoTex — components.css
   Cards, rows, compact items, short tiles, the feed grid, shelves, avatars,
   skeletons, banners, empty states, rank numerals and section headers.

   Loaded AFTER tokens.css and chrome.css, BEFORE forms.css and page-*.css.
   Everything here builds on the tokens and utilities tokens.css already ships
   (.yt-row .yt-stack .yt-spacer .yt-pill .yt-icon-btn .yt-btn .yt-badge
   .yt-link .yt-clamp-* .yt-no-scrollbar .yt-t-*) — reuse those rather than
   redefining equivalents.

   SECTIONS
     1.  Feed grid ............ .yt-grid and the forced column ladder
     2.  Video card (grid) .... .yt-card and every .yt-card__* part
     3.  Card — row variant ... .yt-card--row  (search results)
     4.  Card — compact ....... .yt-card--compact  (watch sidebar / up next)
     5.  Short tile ........... .yt-short
     6.  Avatar ............... .yt-avatar
     7.  Shelf ................ .yt-shelf horizontal scroller
     8.  Skeleton ............. .yt-skeleton shimmer placeholder
     9.  Empty state .......... .yt-empty
     10. Queue banner ......... .yt-queue-banner
     11. Rank + section ....... .yt-rank .yt-section

   Non-token literals used here, and why (no token exists for them):
     #000                  letterbox behind a thumbnail image
     #fff                  text on the always-dark overlay badges
     rgba(255,255,255,.3)  watched-progress track over a thumbnail
     #0f0f0f               avatar initials: the circle's colour comes from
                           AVATAR_COLORS, which are light pastels in BOTH
                           themes, so the glyphs must be dark in both. A token
                           would flip to white under the light theme and vanish.
   ========================================================================== */


/* ==========================================================================
   1. FEED GRID

   Base is auto-fill so an unexpected container still lays out sensibly, then
   an ASCENDING min-width ladder forces YouTube's exact column counts. The
   ladder must stay ascending: equal specificity means the last match wins, so
   a descending list would make a 2560px viewport render two columns.
   ========================================================================== */

.yt-grid {
  display: grid;
  gap: 40px 16px;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
}

@media (min-width: 660px)  { .yt-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .yt-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1300px) { .yt-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1920px) { .yt-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 2560px) { .yt-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* tokens.css drops .yt-page's horizontal padding below 792px, which would
   leave the two-column band flush against both viewport edges. The grid
   supplies its own gutter for that band only. */
@media (max-width: 792px) {
  .yt-grid { padding-inline: 16px; }
}

/* Below 660px: one column, thumbnails full-bleed at radius 0 and the text
   inset — mobile YouTube. minmax(310px,…) cannot shrink under auto-fill, so
   the single column is declared explicitly rather than left to the base rule;
   otherwise a 320px viewport overflows (and tokens.css's overflow-x:hidden
   would silently clip it instead of showing the bug). */
@media (max-width: 659px) {
  .yt-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 16px 0;
    padding-inline: 0;
  }
  .yt-grid > .yt-card .yt-card__thumb { border-radius: 0; }
  .yt-grid > .yt-card .yt-card__meta { padding-inline: 12px; }
}

/* Shorts are 9:16, so they need a much narrower track than a 16:9 card. */
.yt-grid--shorts {
  gap: 24px 12px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
@media (min-width: 660px) { .yt-grid--shorts { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); } }
@media (max-width: 659px) {
  .yt-grid--shorts {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    padding-inline: 16px;
  }
}


/* ==========================================================================
   2. VIDEO CARD — grid layout

   Markup contract (partials/video_card.html):
     article.yt-card[data-pid]
       a.yt-card__thumb            -> img.yt-card__thumb-img
                                   OR span.yt-card__thumb-fallback (film icon)
                                      span.yt-card__duration | .yt-card__status
                                      span.yt-card__quality
                                      span.yt-card__progress > span.yt-card__progress-fill
       div.yt-card__meta           -> a.yt-card__avatar-link (avatar partial)
                                      div.yt-card__body
                                        h3.yt-card__title > a
                                        a.yt-card__channel
                                        div.yt-card__stats
                                      div.yt-card__menu
   ========================================================================== */

.yt-card {
  position: relative;
  display: block;
  min-width: 0;
}

/* -- Thumbnail ------------------------------------------------------------ */
.yt-card__thumb {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--yt-radius-md);
  overflow: hidden;
  background: #000;
  /* Older engines that ignore aspect-ratio still need a floor, otherwise a
     lazy image that has not loaded yet collapses the card to nothing. */
  min-height: 1px;
}

.yt-card__thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The width/height attributes are 16:9, so this stretches to the box
     instead of driving it — no layout shift when the bytes arrive. */
  transition: transform var(--yt-transition);
}

/* Never a broken <img>: a video with no thumbnail yet gets a chip-coloured
   block with the film glyph, at exactly the same geometry. */
.yt-card__thumb-fallback {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  background: var(--yt-bg-chip);
  color: var(--yt-fg-secondary);
}
.yt-card__thumb-fallback .yt-icon { width: 40px; height: 40px; opacity: .8; }

/* app.js (VT.hoverPreview) injects a muted looping <video class="yt-card__
   preview"> into .yt-card__thumb after a dwell, and removes or [hidden]s it
   on leave. It is styled to fully cover the still image while present. */
.yt-card__preview {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}

/* -- Thumbnail overlays --------------------------------------------------- */
.yt-card__duration,
.yt-card__status {
  position: absolute;
  right: 4px;
  bottom: 4px;
  padding: 3px 4px;
  border-radius: 4px;
  background: var(--yt-badge-bg);
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: .02em;
  white-space: nowrap;
}

/* A not-ready video shows its pipeline state where the duration would be, so
   the card reads as pending rather than as broken. VT.observeStatus swaps the
   chip for a real duration once the transcode lands. */
.yt-card__status { display: inline-flex; align-items: center; gap: 4px; }
.yt-card__status--queued     { color: var(--yt-fg-secondary); }
.yt-card__status--uploading  { color: var(--yt-fg-secondary); }
.yt-card__status--processing { color: var(--yt-warning); }
.yt-card__status--failed     { color: var(--yt-danger); }

.yt-card__quality {
  position: absolute;
  top: 4px;
  right: 4px;
  padding: 2px 4px;
  border-radius: 3px;
  background: var(--yt-badge-bg);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: .04em;
  text-transform: uppercase;
}

/* Watched-progress bar. Rendered [hidden] by the template; app.js unhides it
   and sets the fill width from VT.store.progress. */
.yt-card__progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  background: rgba(255, 255, 255, .3);
}
.yt-card__progress-fill {
  display: block;
  width: 0;
  max-width: 100%;
  height: 100%;
  background: var(--yt-brand);
}

/* -- Meta row ------------------------------------------------------------- */
.yt-card__meta {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-top: 12px;
  min-width: 0;
}

.yt-card__avatar-link {
  flex: 0 0 auto;
  display: block;
  border-radius: 50%;
}

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

.yt-card__title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-bottom: 4px;
  color: var(--yt-fg);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.4;
  max-height: 2.8em; /* fallback for engines without -webkit-line-clamp */
  overflow-wrap: anywhere;
}
.yt-card__title a { color: inherit; }

.yt-card__channel {
  display: block;
  color: var(--yt-fg-secondary);
  font-size: 14px;
  line-height: 1.43;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color var(--yt-transition);
}
a.yt-card__channel:hover,
a.yt-card__channel:focus-visible { color: var(--yt-fg); }

.yt-card__stats {
  color: var(--yt-fg-secondary);
  font-size: 14px;
  line-height: 1.43;
}

/* Description snippet — used by the row variant and available to pages. */
.yt-card__desc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-top: 8px;
  color: var(--yt-fg-secondary);
  font-size: 12px;
  line-height: 1.5;
  max-height: 3em;
  overflow-wrap: anywhere;
}

/* -- "⋮" overflow menu --------------------------------------------------- */
.yt-card__menu {
  flex: 0 0 auto;
  align-self: flex-start;
  margin: -4px -6px 0 0;
}

/* Revealed on hover for pointer users, exactly like YouTube; always visible
   on touch, where there is no hover to reveal it. :focus-within keeps it
   reachable by keyboard even while transparent. */
@media (hover: hover) and (pointer: fine) {
  .yt-card__menu { opacity: 0; transition: opacity var(--yt-transition); }
  .yt-card:hover .yt-card__menu,
  .yt-card:focus-within .yt-card__menu,
  .yt-short:hover .yt-card__menu,
  .yt-short:focus-within .yt-card__menu { opacity: 1; }
}

/* Hover previews and thumbnail zoom are decoration, not information. */
@media (prefers-reduced-motion: reduce) {
  .yt-card__preview { display: none; }
  .yt-card__thumb-img { transition: none; }
}


/* ==========================================================================
   3. CARD — ROW VARIANT  (search results, 360x202 thumbnail)

   article.yt-card.yt-card--row > a.yt-card__thumb + div.yt-card__meta
   ========================================================================== */

.yt-card--row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.yt-card--row .yt-card__thumb {
  /* 360x202 at the design width; max-width keeps a 320px viewport from
     overflowing before the stack breakpoint takes over. */
  flex: 0 0 360px;
  width: 360px;
  max-width: 100%;
  border-radius: var(--yt-radius-md);
}

.yt-card--row .yt-card__meta {
  flex: 1 1 auto;
  margin-top: 0;
  gap: 8px;
}

.yt-card--row .yt-card__title {
  font-size: 18px;
  font-weight: 400;
  line-height: 1.4;
  max-height: 2.8em;
  margin-bottom: 4px;
}

.yt-card--row .yt-card__stats { font-size: 12px; }

/* The 24px-avatar channel line sits between the meta line and the snippet. */
.yt-card__row-channel {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  min-width: 0;
  color: var(--yt-fg-secondary);
  font-size: 12px;
}
.yt-card__row-channel .yt-card__channel { font-size: 12px; }

@media (max-width: 1100px) {
  .yt-card--row .yt-card__thumb { flex-basis: 246px; width: 246px; }
  .yt-card--row .yt-card__title { font-size: 16px; }
  .yt-card--row .yt-card__desc { display: none; }
}

/* Below 660px the row becomes a stacked card with a full-bleed thumbnail. */
@media (max-width: 659px) {
  .yt-card--row {
    display: block;
    padding-bottom: 8px;
  }
  .yt-card--row .yt-card__thumb {
    width: 100%;
    flex-basis: auto;
    border-radius: 0;
  }
  .yt-card--row .yt-card__meta {
    margin-top: 12px;
    padding-inline: 12px;
  }
  .yt-card--row .yt-card__row-channel { margin-top: 8px; }
}


/* ==========================================================================
   4. CARD — COMPACT VARIANT  (watch sidebar / up next, 168x94 thumbnail)

   article.yt-card.yt-card--compact > a.yt-card__thumb + div.yt-card__meta
   ========================================================================== */

.yt-card--compact {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.yt-card--compact .yt-card__thumb {
  flex: 0 0 168px;
  width: 168px;
  max-width: 45%;
  aspect-ratio: 168 / 94;
  border-radius: var(--yt-radius-sm);
}

.yt-card--compact .yt-card__meta {
  flex: 1 1 auto;
  margin-top: 0;
  gap: 4px;
}

.yt-card--compact .yt-card__title {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  max-height: 2.8em;
  margin-bottom: 4px;
}

.yt-card--compact .yt-card__channel,
.yt-card--compact .yt-card__stats { font-size: 12px; }

.yt-card--compact .yt-card__duration,
.yt-card--compact .yt-card__status { font-size: 11px; padding: 2px 4px; }

.yt-card--compact .yt-card__menu { margin: -4px -4px 0 0; }



/* ==========================================================================
   5. SHORT TILE  (9:16 vertical)

   article.yt-short > a.yt-short__thumb + h3.yt-short__title + .yt-short__views
   The thumbnail reuses .yt-card__thumb-img / .yt-card__thumb-fallback and the
   overlay chips, which are all container-relative.
   ========================================================================== */

.yt-short {
  position: relative;
  display: block;
  min-width: 0;
}

.yt-short__thumb {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 9 / 16;
  border-radius: var(--yt-radius-md);
  overflow: hidden;
  background: #000;
  min-height: 1px;
}

.yt-short__title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-top: 8px;
  color: var(--yt-fg);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  max-height: 2.8em;
  overflow-wrap: anywhere;
}
.yt-short__title a { color: inherit; }

.yt-short__views {
  margin-top: 2px;
  color: var(--yt-fg-secondary);
  font-size: 12px;
  line-height: 1.43;
}

/* The overflow menu floats over the tile: there is no meta row to hold it. */
.yt-short > .yt-card__menu {
  position: absolute;
  top: 4px;
  right: 4px;
  margin: 0;
  z-index: 1;
  border-radius: 50%;
  background: var(--yt-badge-bg);
  color: #fff;
}


/* ==========================================================================
   6. AVATAR

   partials/avatar.html is owned by another agent. These rules work for any of
   the three ways it can carry a size, in order of preference:
     style="--yt-avatar-size:36px"   (best: text scales with the circle)
     style="width:36px;height:36px"  (inline wins over the var-driven box)
     nothing                         (falls back to 36px)
   Never sets a background colour itself — the partial passes the deterministic
   per-channel colour inline, from Channel.avatar_color / the avatar_hue filter.
   ========================================================================== */

.yt-avatar {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: var(--yt-avatar-size, 36px);
  height: var(--yt-avatar-size, 36px);
  border-radius: 50%;
  overflow: hidden;
  background: var(--yt-bg-chip);
  color: #0f0f0f;
  font-size: calc(var(--yt-avatar-size, 36px) * .42);
  font-weight: 500;
  line-height: 1;
  text-transform: uppercase;
  text-decoration: none;
  user-select: none;
}

.yt-avatar img,
.yt-avatar svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.yt-avatar__initials {
  display: block;
  font-size: inherit;
  font-weight: 500;
  letter-spacing: .02em;
  /* avatar.html sets the pixel font-size inline (0.4 x the circle), so this
     inherits rather than fighting it. The colour is a deliberate literal: see
     the file header. */
  color: inherit;
}

/* Size modifiers, for callers that would rather not compute an inline value. */
.yt-avatar--xs { --yt-avatar-size: 24px; }
.yt-avatar--sm { --yt-avatar-size: 32px; }
.yt-avatar--md { --yt-avatar-size: 40px; }
.yt-avatar--lg { --yt-avatar-size: 48px; }
.yt-avatar--xl { --yt-avatar-size: 80px; }
.yt-avatar--hero { --yt-avatar-size: 136px; font-weight: 700; }


/* ==========================================================================
   7. SHELF — titled horizontal scroller

   section.yt-shelf
     div.yt-shelf__head   -> h2.yt-shelf__title, "View all" link,
                             button.yt-shelf__arrow[data-vt-shelf-prev|next]
     div.yt-shelf__track  -> the cards, .yt-no-scrollbar

   Arrows live in the header (as YouTube's home shelves do) rather than
   floating over the track: no magic vertical offset to keep in sync with the
   card geometry, and they never cover a thumbnail.
   ========================================================================== */

.yt-shelf {
  margin-bottom: 40px;
  min-width: 0;
}

.yt-shelf__head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  min-width: 0;
}
@media (max-width: 792px) { .yt-shelf__head { padding-inline: 16px; } }

.yt-shelf__title {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.yt-shelf__title .yt-icon { flex: 0 0 auto; color: var(--yt-brand); }

.yt-shelf__track {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  padding-bottom: 4px;
}
@media (max-width: 792px) {
  .yt-shelf__track { padding-inline: 16px; scroll-padding-inline: 16px; }
}

/* Every direct child is a fixed-width slide. 310px matches the grid's card
   width so a shelf card and a grid card are the same size. */
.yt-shelf__track > * {
  flex: 0 0 310px;
  max-width: 78vw;
  scroll-snap-align: start;
}
@media (max-width: 659px) { .yt-shelf__track > * { flex-basis: 260px; } }

.yt-shelf--shorts .yt-shelf__track > * { flex: 0 0 180px; max-width: 45vw; }
@media (max-width: 659px) { .yt-shelf--shorts .yt-shelf__track > * { flex-basis: 150px; } }

.yt-shelf__arrow {
  /* Composed with .yt-icon-btn from tokens.css for the 40px circle. */
  flex: 0 0 auto;
  border: 1px solid var(--yt-border);
  background: var(--yt-bg-elevated);
}
.yt-shelf__arrow:hover { background: var(--yt-bg-hover); }
.yt-shelf__arrow[disabled],
.yt-shelf__arrow[aria-disabled="true"] { opacity: .35; cursor: default; }
.yt-shelf__arrow[disabled]:hover { background: var(--yt-bg-elevated); }

/* Touch scrolls by swipe; the arrows only take space there. */
@media (max-width: 792px) {
  .yt-shelf__arrow { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .yt-shelf__track { scroll-behavior: auto; scroll-snap-type: none; }
}


/* ==========================================================================
   8. SKELETON — shimmer placeholder matching the card geometry
   ========================================================================== */

@keyframes yt-skeleton-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .55; }
}

.yt-skeleton { display: block; min-width: 0; }

.yt-skeleton__thumb,
.yt-skeleton__line,
.yt-skeleton__avatar {
  /* Flat block with an opacity pulse — no sweeping sheen. */
  background-color: var(--yt-skeleton);
  animation: yt-skeleton-pulse 1.6s ease-in-out infinite;
}

.yt-skeleton__thumb {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--yt-radius-md);
}
.yt-skeleton__thumb--vertical { aspect-ratio: 9 / 16; }
.yt-skeleton__thumb--compact { aspect-ratio: 168 / 94; border-radius: var(--yt-radius-sm); }

.yt-skeleton__meta {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-top: 12px;
}
.yt-skeleton__avatar {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 50%;
}
.yt-skeleton__lines { flex: 1 1 auto; min-width: 0; }

.yt-skeleton__line {
  height: 12px;
  border-radius: 4px;
  margin-bottom: 8px;
}
.yt-skeleton__line:last-child { margin-bottom: 0; }
.yt-skeleton__line--title { height: 16px; width: 100%; }
.yt-skeleton__line--half  { width: 60%; }
.yt-skeleton__line--short { width: 40%; }

/* tokens.css's reduced-motion block only shortens animations, which would
   freeze the sheen gradient mid-sweep. Kill the gradient outright so the
   placeholder is a flat block. */
@media (prefers-reduced-motion: reduce) {
  .yt-skeleton__thumb,
  .yt-skeleton__line,
  .yt-skeleton__avatar {
    animation: none;
    background-image: none;
    background-color: var(--yt-skeleton);
  }
}


/* ==========================================================================
   9. EMPTY STATE
   ========================================================================== */

.yt-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  max-width: 460px;
  margin: 0 auto;
  padding: 72px 24px;
  text-align: center;
}

.yt-empty__icon {
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  margin-bottom: 12px;
  border-radius: 50%;
  background: var(--yt-bg-chip);
  color: var(--yt-fg-secondary);
}
.yt-empty__icon .yt-icon { width: 44px; height: 44px; }

.yt-empty__title {
  color: var(--yt-fg);
  font-size: 20px;
  font-weight: 500;
  line-height: 1.3;
}

.yt-empty__sub {
  color: var(--yt-fg-secondary);
  font-size: 14px;
  line-height: 1.5;
  text-wrap: pretty;
}

.yt-empty .yt-btn { margin-top: 12px; }

@media (max-width: 659px) { .yt-empty { padding: 48px 16px; } }


/* ==========================================================================
   10. QUEUE BANNER

   "N videos processing" strip. The template renders nothing at all when the
   count is zero or missing, so there is no empty-state styling to write.
   ========================================================================== */

.yt-queue-banner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-bottom: 24px;
  padding: 10px 16px;
  border: 1px solid var(--yt-border);
  border-radius: var(--yt-radius-md);
  background: var(--yt-bg-elevated);
  color: var(--yt-fg-secondary);
  font-size: 14px;
  line-height: 1.43;
}
.yt-queue-banner strong { color: var(--yt-fg); font-weight: 500; }

.yt-queue-banner__icon {
  display: inline-flex;
  flex: 0 0 auto;
  color: var(--yt-accent);
  animation: yt-queue-spin 1.1s linear infinite;
}
@keyframes yt-queue-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .yt-queue-banner__icon { animation: none; }
}

@media (max-width: 792px) { .yt-queue-banner { margin-inline: 16px; } }


/* ==========================================================================
   11. RANK NUMERAL + GENERIC SECTION

   .yt-rank is the "#1 / #2" numeral trending and popular lists put ahead of a
   row. .yt-section / .yt-section__head is the plain titled block every page
   uses for a vertical (non-scrolling) list.
   ========================================================================== */

.yt-rank {
  flex: 0 0 auto;
  min-width: 32px;
  padding-top: 2px;
  color: var(--yt-fg-secondary);
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  text-align: center;
}
.yt-rank--lg { min-width: 48px; font-size: 28px; }
/* The top three read as a podium, like YouTube's Trending list. */
.yt-rank--top { color: var(--yt-fg); }

.yt-section { margin-bottom: 40px; min-width: 0; }
.yt-section:last-child { margin-bottom: 0; }

.yt-section__head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  min-width: 0;
}
.yt-section__head h1,
.yt-section__head h2,
.yt-section__head h3 {
  min-width: 0;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
  overflow-wrap: anywhere;
}
.yt-section__head--ruled {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--yt-border);
}
@media (max-width: 792px) { .yt-section__head { padding-inline: 16px; } }
