/* The community feeds' stylesheet: the panels, the cards (events, listings,
 * episodes, articles), the gold Featured boxes, the Find modals, the article
 * reader and the per-feed controls. Linked by the four feed pages (/events,
 * /market, /podcasts, /articles) and by the homepage, whose rails open the
 * same cards in a modal (rails-homepage, 2026-11). It was the inline block
 * of index.html until then; the tab chrome rules it still carries are dead
 * since the tabs went.
 *
 * ⚠️ Per-feed palette: each feed owns an accent, mirrored into --accent /
 * --accent-d / --tint off <body data-active-feed> so the shared chrome reads
 * one token. The homepage sets no active feed and keeps the Events default. */
:root {
  --podcasts-accent: #5e7d3a;  --podcasts-accent-d: #46602c;  --podcasts-tint: #eef3e2;
  --market-accent:   #d97b0e;  --market-accent-d:   #b8640a;  --market-tint:   #fbefda;
  --events-accent:   #2f6f8f;  --events-accent-d:   #245a75;  --events-tint:   #e6f0f5;
  --articles-accent: #7150a6;  --articles-accent-d: #573c86;  --articles-tint:   #efe9f6;
  --accent:   var(--events-accent);
  --accent-d: var(--events-accent-d);
  --tint:     var(--events-tint);
  --bg:       #ede3c8;   /* a few reused merch.css rules read it */
}
body[data-active-feed="events"]   { --accent: var(--events-accent);   --accent-d: var(--events-accent-d);   --tint: var(--events-tint); }
body[data-active-feed="market"]   { --accent: var(--market-accent);   --accent-d: var(--market-accent-d);   --tint: var(--market-tint); }
body[data-active-feed="podcasts"] { --accent: var(--podcasts-accent); --accent-d: var(--podcasts-accent-d); --tint: var(--podcasts-tint); }
body[data-active-feed="articles"] { --accent: var(--articles-accent); --accent-d: var(--articles-accent-d); --tint: var(--articles-tint); }

@keyframes skeleton-shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

/* ── Community Feeds section ── A title in the Explore section's style
   (the navy band and the membership chip that /feeds carried are gone,
   Reed 2026-09-06), then the tab chrome, then the tinted panels. #feeds
   is the URL's name for the section; scroll-margin-top clears the sticky
   nav when a feeds link scrolls it into view. */
/* The section sits on the same white as the latest episode; inside it,
   the tab chrome and the panels share ONE SHELL — a cream card with a
   border at the column's width (Reed, 2026-09-06: "some container or
   shell that makes it clear the tabs contain the filters and listings
   below them, not page-wide, almost like a really big card"). No
   per-feed tint: the feed's accent arrives through the tabs, the sub-row
   and the cards' own controls, and the white cards sit on the cream. */
#feeds { scroll-margin-top: 64px; background: var(--white); }
.feeds-shell-wrap {
  max-width: var(--feed-track);
  margin: 0 auto;
  padding: 0 1.25rem 2rem;
}
/* overflow: clip (not hidden) rounds the chrome's corners into the card
   without making the shell a scroll container, so the sticky chrome
   inside it still sticks to the nav. */
.feeds-shell,
.community-shell {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--cream);
  overflow: clip;
}
/* The Community wall wears the same shell (Reed, 2026-09-06), with the
   wall's own padding inside it. */
.community-shell { padding: 1.6rem 1.25rem 1.5rem; }
.feeds-title { padding-bottom: 0.9rem; }
.feeds-title .home-module-head { margin-bottom: 0; }

/* ── Feed chrome ────────────────────────────────────────────────
   The four tabs and, under them, the active tab's Featured / All
   sub-row, inside one bordered box at the panel column's width — the
   OnlyBoosts homepage's chrome (its index.html, 2026-09-03), carried
   back here: the box replaces the two full-bleed cream bands the tabs
   used to sit in. Sticky under the nav so the tabs stay reachable
   while scrolling a long feed.

   ⚠️ THE BOX IS AS WIDE AS THE PANEL COLUMN, AND THAT COLUMN IS THE
   LATEST EPISODE'S (Reed, 2026-09-06): --feed-track is the one column of
   `.featured-wrap` and `.home-module`, with the same 1.25rem sides.
   `.feed-panels-inner` is --feed-track wide INCLUDING its side padding
   (border-box), so `.feed-bar-inner` restates exactly that box and the
   chrome fills it; the three edges line up by the same arithmetic. */
/* One column for every section below the hero — the supporters page's
   (`.supporters-wrap`: 60rem incl. 1.25rem sides). Reed, 2026-09-06: at
   1100px the page read as too wide once the Community wall arrived. */
:root { --feed-track: 60rem; }
/* The desktop track is OnlyBoosts' (its --page-track, 2026-11-07): 72rem
   from 1100px up, Reed's ask of 2026-11-08 ("make it a bit wider"). The
   @media rule sits right after the base so it wins at equal specificity. */
@media (min-width: 1100px) { :root { --feed-track: 72rem; } }
/* The chrome is the shell's lid: it fills the shell's width, keeps only
   the hairline under the sub-row, and stays cream so that when it sticks
   under the nav it covers the panel scrolling beneath it. */
.feed-bar-wrap {
  position: sticky;
  top: 64px; /* height of #top-nav */
  z-index: 40;
  background: var(--cream);
  padding: 0;
}
.feed-bar-inner { max-width: none; margin: 0; padding: 0; }
.feed-chrome {
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  background: var(--cream);
}
.feed-tabs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}
.feed-tab {
  --tab: var(--muted);
  appearance: none;
  background: transparent;
  border: 0;
  border-top: 3px solid transparent;
  /* The seam runs all the way across, including under the selected tab:
     the tab and the selected sub-block below it are the same fill and
     touch, so without it the two tiers merge into one slab. Inside the
     accent column it is one step darker, a fold rather than a cut. */
  border-bottom: 1px solid var(--border);
  font: inherit;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.7rem 0.5rem 0.6rem;
  color: var(--muted);
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.feed-tab--events   { --tab: var(--events-accent); }
.feed-tab--market   { --tab: var(--market-accent); }
.feed-tab--podcasts { --tab: var(--podcasts-accent); }
.feed-tab--articles { --tab: var(--articles-accent); }

.feed-tab-icon {
  width: 22px;
  height: 22px;
  color: var(--tab);
  transition: color 0.15s;
}
.feed-tab-icon svg { width: 100%; height: 100%; display: block; }
.feed-tab-label {
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.feed-tab-sub {
  font-size: 0.72rem;
  color: var(--muted);
  opacity: 0.85;
}
.feed-tab:hover { background: rgba(0,0,0,0.03); }
.feed-tab:focus-visible {
  outline: 2px solid var(--tab);
  outline-offset: -2px;
}
.feed-tab[aria-selected="true"] {
  background: var(--tab);
  border-top-color: var(--tab);
  border-bottom-color: var(--accent-d);
  color: var(--white);
}
.feed-tab[aria-selected="true"] .feed-tab-icon,
.feed-tab[aria-selected="true"] .feed-tab-sub { color: #fff; opacity: 0.95; }

/* ══ THE SUB-ROW: Featured / All ══
   Which view of the tab, as blocks rather than as text. The same
   four-column grid as .feed-tabs, each group pinned to its own column,
   so the pair sits exactly under its tab and adds up to one tab's width
   whatever the gap at any breakpoint. Which group is on screen is CSS
   off body[data-active-feed], not JS, so a tab you come back to can
   never show another tab's pair. No gap and no per-block border: the
   blocks touch each other and the tab above, and the boundary between
   the pair is carried by the fill. */
.feed-subs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}
.feed-sub-group { display: none; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 0; }
.feed-sub-group[data-feed="events"]   { grid-column: 1; }
.feed-sub-group[data-feed="market"]   { grid-column: 2; }
.feed-sub-group[data-feed="podcasts"] { grid-column: 3; }
.feed-sub-group[data-feed="articles"] { grid-column: 4; }
body[data-active-feed="events"]   .feed-subs > [data-feed="events"],
body[data-active-feed="market"]   .feed-subs > [data-feed="market"],
body[data-active-feed="podcasts"] .feed-subs > [data-feed="podcasts"],
body[data-active-feed="articles"] .feed-subs > [data-feed="articles"] { display: grid; }
.feed-sub {
  appearance: none;
  border: 0;
  border-radius: 0;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  background: var(--cream-d);
  color: var(--muted);
  padding: 0.36rem 0.4rem 0.4rem;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.feed-sub:hover { color: var(--accent-d); }
.feed-sub:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* The selected block continues the tab's fill downward, so the tab and
   the view under it read as one column. */
.feed-sub[aria-selected="true"] { background: var(--accent); color: var(--white); }
.feed-sub[aria-selected="true"]:hover { color: var(--white); }

/* ══ THE TWO VIEWS ══
   Each renderer still paints one panel: the gold Featured box first,
   then the list and whatever controls it owns. The sub-row is a CSS
   switch over that DOM off body[data-feed-view], the same call the
   sub-row itself makes: Featured shows the box alone (plus loading
   skeletons and empty/error placeholders) and hides the head's
   controls; All hides the box. The Events head keeps its Create button
   in both views — only its range/type controls are the All view's. The
   other heads (title, count, sort, range, toggle) belong to All. A
   renderer's featured mount is a `*-featured-mount` wrapper around the
   box, which is why the selector reads the class substring. */
body[data-feed-view="featured"] .feed-panel [data-feed-list] > :not(.feat-box):not([class*="featured-mount"]):not(.feed-skeleton):not(.feed-placeholder) { display: none; }
/* Every panel head belongs to the All view, the Events one included since
   its Create button also sits beside Find in the Featured row (feeds.js
   featuredBox, Reed 2026-09-06). */
body[data-feed-view="featured"] .feed-panel > .feed-panel-head { display: none; }
body[data-feed-view="all"] .feed-panel .feat-box { display: none; }

/* ── Panels ── */
.feed-panels {
  background: transparent;
  min-height: 60vh;
}
.feed-panels-inner {
  max-width: none;
  margin: 0;
  padding: 1.5rem 1.5rem 2rem;
}
.feed-panel { display: none; }
.feed-panel.is-active { display: block; }

/* Panel intro row — feed name + a short "what am I looking at" line,
   plus a right-aligned live count once feeds hydrate. */
.feed-panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
}
.feed-panel-head h2 {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--accent-d);
}
.feed-panel-head p {
  margin-top: 0.15rem;
  font-size: 0.9rem;
  color: var(--muted);
  font-style: italic;
}
.feed-count {
  flex-shrink: 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--accent-d);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.15rem 0.7rem;
  white-space: nowrap;
}

/* Loading skeletons + states (feed content wired up in a later phase). */
.feed-list { display: grid; gap: 0.6rem; }
/* The shared .embed-note card carries its own vertical margin; drop it
   inside a feed list so the grid gap is the only spacing between cards. */
.feed-list .embed-note { margin: 0; }
.feed-skeleton {
  height: 104px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: linear-gradient(90deg,
    rgba(0,0,0,0.03) 0%,
    rgba(0,0,0,0.08) 50%,
    rgba(0,0,0,0.03) 100%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
.feed-placeholder {
  background: var(--white);
  border: 1px dashed var(--border);
  border-radius: 12px;
  padding: 2.25rem 1.5rem;
  text-align: center;
  color: var(--muted);
}
.feed-placeholder strong {
  display: block;
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.1rem;
  color: var(--accent-d);
  margin-bottom: 0.35rem;
}

/* Collapsed "Past events / older posts" section under a feed's list. */
.feed-past {
  margin-top: 1.75rem;
  border-top: 1px solid var(--border);
  padding-top: 1.1rem;
}
.feed-past > summary {
  cursor: pointer;
  list-style: none;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--accent-d);
  padding: 0.3rem 0;
}
.feed-past > summary::-webkit-details-marker { display: none; }
.feed-past > summary::marker { content: ''; }
.feed-past > summary::before {
  content: '▸';
  font-size: 0.85em;
  transition: transform 0.15s;
}
.feed-past[open] > summary::before { transform: rotate(90deg); }
.feed-past .feed-list { margin-top: 1rem; }

/* ── Featured / Events section headers (Events tab) ──
   Non-collapsible labels that sit above the Featured and normal grids
   once an event has been boosted into the Featured section. */
.feed-section-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--accent-d);
  padding: 0.3rem 0;
}
/* The Featured Events box is the shared .feat-box (see Featured Articles);
   its Find button is the shared .feat-find, opened by the delegated
   .feed-find-btn click in the Find-modal controller below. The gap after
   the box comes from the box's own margin. */
.feat-box .feed-list { margin-top: 0; }
.featured-by-when { color: var(--muted); white-space: nowrap; }
.featured-by--anon { cursor: default; color: var(--muted); font-size: 0.75rem; display: inline-flex; gap: 0.35rem; }
/* The normal "Events" header, when present, follows the featured grid —
   give it breathing room from the cards above. */
.feed-list + .feed-section-head { margin-top: 1.6rem; }
.feed-section-head + .feed-list { margin-top: 0.8rem; }
/* Same spacing when a section renders its empty/sold-out box instead of a
   grid (Show Merch with an empty house catalog). */
.feed-section-head + .feed-placeholder { margin-top: 0.8rem; }
.feed-section-count {
  font-family: inherit;
  font-weight: 600;
  font-size: 0.8rem;
  color: var(--muted);
  background: rgba(0,0,0,0.05);
  border-radius: 999px;
  padding: 0.05rem 0.5rem;
}
.feed-section-head--featured { color: #a9761a; }
.feed-section-head--featured .feed-section-count {
  color: #a9761a;
  background: rgba(224,169,46,0.16);
}
.feed-section-star { font-size: 0.95em; line-height: 1; }

/* Featured Past Events collapsible — gold summary to match. */
.feed-past--featured > summary { color: #a9761a; }

/* ── Create / Find buttons (replace the Events panel title) ──
   Tight rectangles (not pills) so the pair packs small on mobile. Secondary
   style — orange is reserved for Boost/Promote, so these read as utility
   actions, not another boost CTA. */
.event-composer-btns { display: flex; gap: 0.4rem; }
.event-composer-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font: inherit;
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--accent-d);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 0.34rem 0.7rem;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.event-composer-btn:hover {
  background: var(--cream);
  border-color: var(--accent);
}
.event-composer-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.event-composer-btn .ecb-icon { font-size: 1em; line-height: 1; }

/* ── Find modal ──
   z-index sits above the sticky nav (100) but below the widget's meetup
   flow modals (200) — the modal closes as those open, so any overlap is
   brief and the flow modal always wins. */
.event-composer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: rgba(0,0,0,0.6);
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.event-composer-backdrop[hidden] { display: none; }
.event-composer-backdrop:not([hidden]) { display: flex; }
.event-composer-card {
  position: relative;
  width: 100%;
  max-width: 560px;
  background: var(--cream-d, #f6edd8);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.5rem 1.5rem 1.6rem;
  box-shadow: 0 25px 60px -12px rgba(0,0,0,0.45);
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
}
.event-composer-close {
  position: absolute;
  top: 0.7rem;
  right: 0.8rem;
  background: transparent;
  border: none;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
  padding: 0.15rem 0.4rem;
  border-radius: 6px;
}
.event-composer-close:hover { color: var(--accent-d); background: rgba(0,0,0,0.05); }
.event-composer-title {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--accent-d);
  margin-right: 1.5rem;
}
.event-composer-sub {
  margin-top: 0.3rem;
  margin-bottom: 1.1rem;
  font-size: 0.9rem;
  color: var(--muted);
}
/* ── Accordion of "find" flows (each expands a drawer inside the modal) ── */
.ec-accordion { display: flex; flex-direction: column; gap: 0.5rem; }
.ec-acc-item {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--cream);
  overflow: hidden;
}
.ec-acc-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: transparent;
  border: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  padding: 0.7rem 0.85rem;
  transition: background 0.15s;
}
.ec-acc-head:hover { background: #ffffff; }
.ec-acc-text { display: flex; flex-direction: column; gap: 0.1rem; flex: 1; min-width: 0; }
.ec-acc-title { font-weight: 700; color: var(--navy); font-size: 0.95rem; }
.ec-acc-sub { font-size: 0.78rem; color: var(--muted); line-height: 1.3; }
.ec-acc-caret {
  flex-shrink: 0;
  color: var(--muted);
  font-size: 0.85rem;
  transition: transform 0.15s;
}
.ec-acc-head[aria-expanded="true"] .ec-acc-caret { transform: rotate(90deg); }
.ec-acc-head[aria-expanded="true"] { background: #ffffff; }
.ec-acc-drawer {
  padding: 0.85rem;
  border-top: 1px solid var(--border);
  background: var(--white);
}
.ec-acc-placeholder { font-size: 0.85rem; color: var(--muted); font-style: italic; }

/* "See other versions of this event" — collapses re-posted duplicates.
   The toggle lives at the left of the card's action row (styled by
   .note-actions button); the panel of version cards drops in below,
   accent-ruled to tie it to the active feed. */
.versions-toggle .versions-caret {
  display: inline-block;
  font-size: 0.85em;
  transition: transform 0.15s;
}
.versions-toggle.is-open .versions-caret { transform: rotate(90deg); }
.event-versions-panel {
  margin-top: 0.7rem;
  padding-left: 0.8rem;
  border-left: 2px solid var(--accent);
  display: grid;
  gap: 0.6rem;
}
.event-versions-panel[hidden] { display: none; }

/* ── Marketplace cards ───────────────────────────────────────────
   A responsive grid of listing cards. The whole card is clickable →
   the /merch product modal (carousel + description + shipping).
   Classifieds carry an amber badge over the image naming what's
   missing to be checkout-ready (from the shared Gamma grader);
   Buy-Now items carry none — the "Add to cart" button says it all.
   The card image is the shared merch carousel (arrows via merch.css).
   Rendered by feeds-market.js. */
/* The Show Merch box is gone (2026-09-06): the house store's listings are
   standing features in the gold box, see feeds-market.js. */

/* "Community" in the Community Marketplace header links to /supporters —
   that page answers "whose listings are these?". Inherits the header's
   colour so it reads as part of the title, not as a stray link. */
.feed-section-link {
  color: inherit; text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 1px;
  transition: color 0.12s;
}
.feed-section-link:hover { color: var(--accent); }

/* "Manage / List Items" — shown in the Community Marketplace header for
   logged-in users, deep-links to their MyNostr marketplace. Pushed to the
   right edge of that header row; wraps on narrow screens. */
.market-manage-btn {
  margin-left: auto;
  flex-shrink: 0;
  display: inline-flex; align-items: center;
  padding: 0.4rem 0.85rem;
  font-size: 0.82rem; font-weight: 700;
  color: #fff; background: var(--accent-d);
  border-radius: 999px; text-decoration: none;
  white-space: nowrap;
  transition: background 0.12s;
}
.market-manage-btn:hover { background: var(--accent); }

.market-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(175px, 1fr));
  gap: 1rem;
}
.market-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.12s, box-shadow 0.12s;
}
.market-card:hover, .market-card:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 8px 22px rgba(0,0,0,0.12);
  outline: none;
}
/* contain (not cover) so the whole product image shows on a neutral
   backdrop — matches the merch storefront cards. Targets the plain
   <img> and the carousel's <img> alike. */
.market-card-media { position: relative; aspect-ratio: 1 / 1; background: var(--white); }
.market-card-media img { width: 100%; height: 100%; object-fit: contain; padding: 0.4rem; box-sizing: border-box; display: block; }
.market-card-noimg {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  font-size: 2.1rem; opacity: 0.5;
}
.market-badge {
  position: absolute; top: 0.45rem; left: 0.45rem;
  max-width: calc(100% - 0.9rem);
  padding: 0.15rem 0.45rem;
  font-size: 0.66rem; font-weight: 600;
  border-radius: 999px;
  color: #fff; background: var(--market-accent-d);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.market-card-body { display: flex; flex-direction: column; gap: 0.2rem; padding: 0.6rem 0.65rem 0.65rem; flex: 1; }
.market-card-title { margin: 0; font-size: 0.9rem; line-height: 1.25; color: var(--text); }
.market-seller { display: flex; align-items: center; gap: 0.35rem; min-width: 0; }
.market-seller-pfp { width: 18px; height: 18px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.market-seller-pfp--none {
  display: flex; align-items: center; justify-content: center;
  background: var(--cream-d); color: var(--muted); font-size: 0.62rem; font-weight: 700;
}
.market-seller-name { font-size: 0.72rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.market-card-price { font-size: 0.9rem; font-weight: 700; color: var(--accent-d); }
.market-card-sats { font-weight: 500; color: var(--muted); font-size: 0.8em; }
.market-card-summary {
  margin: 0.1rem 0 0; font-size: 0.78rem; color: var(--muted); line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.market-card-actions { margin-top: auto; padding-top: 0.45rem; }
.market-btn {
  width: 100%;
  padding: 0.4rem 0.6rem;
  font-size: 0.82rem; font-weight: 700;
  border: 1px solid transparent; border-radius: 7px;
  cursor: pointer;
}
.market-btn--buy { background: var(--green-d); color: #fff; }
.market-btn--buy:hover { background: var(--green); }
.market-btn--buy:disabled { opacity: 0.6; cursor: default; }
.market-btn--contact { background: transparent; color: var(--accent-d); border-color: var(--border); }
.market-btn--contact:hover { background: var(--tint); }

/* ⋮ menu inside the product detail modal (copy naddr + view elsewhere).
   Pinned top-right, just left of the modal's ✕ close button. */
.market-menu-wrap { position: absolute; top: 0.75rem; right: 3.25rem; z-index: 4; }
.market-menu-btn {
  width: 34px; height: 34px; border-radius: 50%;
  border: none; background: rgba(0,0,0,0.55); color: #fff; cursor: pointer;
  font-size: 1.1rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.market-menu-btn:hover { background: rgba(0,0,0,0.75); }
.market-menu {
  display: none;
  position: absolute; top: 40px; right: 0;
  min-width: 190px;
  background: var(--white);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.18);
  padding: 0.35rem;
}
.market-menu-wrap.open .market-menu { display: block; }
.market-menu-item {
  display: block; width: 100%; box-sizing: border-box;
  text-align: left; padding: 0.45rem 0.6rem;
  font: inherit; font-size: 0.85rem; color: var(--text);
  background: transparent; border: none; border-radius: 6px;
  cursor: pointer; text-decoration: none;
}
.market-menu-item:hover { background: var(--tint); }
.market-menu-label {
  padding: 0.4rem 0.6rem 0.2rem;
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted);
}

/* Contact-seller DM modal */
.market-modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(30, 22, 10, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
}
.market-modal {
  position: relative;
  width: 100%; max-width: 420px;
  background: var(--white);
  border: 1px solid var(--border); border-radius: 14px;
  padding: 1.2rem 1.2rem 1rem;
}
.market-modal-close {
  position: absolute; top: 0.6rem; right: 0.6rem;
  width: 2rem; height: 2rem;
  background: transparent; border: none; cursor: pointer;
  font-size: 1rem; color: var(--muted); line-height: 1;
}
.market-modal-title { margin: 0 1.6rem 0.3rem 0; font-size: 1.1rem; color: var(--text); }
.market-modal-sub { margin: 0 0 0.7rem; font-size: 0.82rem; color: var(--muted); }
.market-dm-input {
  width: 100%; box-sizing: border-box;
  padding: 0.6rem; font: inherit; font-size: 0.9rem;
  border: 1px solid var(--border); border-radius: 8px;
  resize: vertical;
}
.market-dm-status { min-height: 1.2rem; margin: 0.5rem 0; font-size: 0.82rem; color: var(--muted); }
.market-modal-actions { display: flex; justify-content: flex-end; }
.market-modal-actions .market-btn { width: auto; padding-left: 1.2rem; padding-right: 1.2rem; }

/* ── Podcast Boosts cards ─────────────────────────────────────────
   Episodes the community has boosted on Nostr. The card head shows the
   art, show name, the episode title (a link to the Fountain episode), a
   meta row of booster avatars / recency / sats, and a ⋮ menu of
   show-level subscribe links. A low-profile drawer bar under the head
   toggles the inline boost thread. Rendered by feeds-podcasts.js. */
/* Air-date range buttons + sort dropdown in the panel head (they replace
   the episode-count pill). */
.pcast-controls {
  display: flex; align-items: center; gap: 0.5rem;
  flex-shrink: 0; align-self: center;
}
/* 1W / 1M / All — deliberately borderless and touching: the faint tint on
   the selected segment is the only chrome, and it's what reveals that the
   neighbours are buttons with the same footprint. */
.pcast-range { display: flex; flex-shrink: 0; }
.pcast-range-btn {
  /* Near-square: the min-width and the vertical padding are tuned to land
     the box at roughly 32x30, so the three read as one tight block. */
  min-width: 2rem; padding: 0.5rem 0.35rem;
  font: inherit; font-size: 0.72rem; font-weight: 700; line-height: 1.2;
  color: var(--muted); background: transparent;
  border: none; border-radius: 6px; cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
/* Tint of the active feed's accent. The solid --tint is the fallback for
   engines without color-mix; it lands in the same place visually. */
.pcast-range-btn:hover {
  color: var(--accent-d);
  background: var(--tint);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.pcast-range-btn.is-active {
  color: var(--accent-d);
  background: var(--tint);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.pcast-sort { position: relative; flex-shrink: 0; align-self: center; }
.pcast-sort-btn {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 0.3rem 0.7rem; font: inherit; font-size: 0.78rem; font-weight: 600;
  color: var(--text); background: var(--white);
  border: 1px solid var(--border); border-radius: 999px; cursor: pointer;
  white-space: nowrap; transition: border-color 0.12s, background 0.12s;
}
.pcast-sort-btn:hover { border-color: var(--accent); background: var(--tint); }
.pcast-sort-tag { color: var(--muted); }
.pcast-sort-cur { color: var(--accent-d); font-weight: 700; }
.pcast-sort-caret { color: var(--muted); font-size: 0.85em; }
.pcast-sort-menu {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 6;
  min-width: 175px; background: var(--white);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.18); padding: 0.35rem;
}
.pcast-sort-menu[hidden] { display: none; }
.pcast-sort-item {
  display: block; width: 100%; text-align: left;
  padding: 0.45rem 0.6rem; font: inherit; font-size: 0.85rem; font-weight: 600;
  color: var(--text); background: transparent; border: none; border-radius: 6px; cursor: pointer;
}
.pcast-sort-item:hover { background: var(--tint); color: var(--accent-d); }
.pcast-sort-item.is-active { color: var(--accent-d); background: var(--tint); }
.pcast-sort-item.is-active::after { content: ' ✓'; float: right; }
/* Events type dropdown — squarer corners than the podcast sort pill. */
.feed-type-sort .pcast-sort-btn { border-radius: 7px; }
.feed-type-sort .pcast-sort-menu { border-radius: 8px; }

/* minmax(0,1fr) — without the 0 min, a grid item's min-width is its
   content, so long shownotes/URLs would blow the column (and card) far
   wider than the container. */
.pcast-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.6rem; }
.pcast-card {
  min-width: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  /* No overflow:hidden here — it would clip the ⋮ subscribe dropdown when
     it opens past the bottom of the card. The media clips its own corners,
     and the drawer rounds its bottom corners when it's the last child. */
  transition: box-shadow 0.12s, border-color 0.12s;
}
.pcast-card:hover { box-shadow: 0 6px 18px rgba(0,0,0,0.08); }
.pcast-card.is-open { border-color: var(--accent); box-shadow: 0 6px 18px rgba(0,0,0,0.10); }
.pcast-card-head {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  /* tight right padding so the ⋮ menu hugs the corner */
  padding: 0.7rem 0.4rem 0.5rem 0.7rem;
}
.pcast-card-media {
  display: block; /* also correct when the media is an <a> link */
  flex-shrink: 0;
  width: 68px; height: 68px;
  border-radius: 8px; overflow: hidden;
  background: var(--tint);
}
a.pcast-card-media { cursor: pointer; }
a.pcast-card-media:hover { box-shadow: 0 0 0 2px var(--podcasts-accent); }
.pcast-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pcast-card-media--none {
  display: flex; align-items: center; justify-content: center;
  font-size: 1.7rem; opacity: 0.55;
}
.pcast-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; justify-content: center; }
.pcast-show {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--accent-d);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
a.pcast-show-link { text-decoration: none; cursor: pointer; display: block; }
a.pcast-show-link:hover { text-decoration: underline; }
.pcast-title {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 0.98rem; font-weight: 700; line-height: 1.25; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pcast-meta {
  display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap;
  margin-top: 0.25rem; font-size: 0.78rem; color: var(--muted);
}

/* Shownotes teaser (first ~2 lines) + a links row ("see full description"
   and a compact "Listen on Fountain") beneath it. */
.pcast-desc {
  margin: 0.35rem 0 0; font-size: 0.82rem; line-height: 1.4; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere; word-break: break-word;
}
.pcast-links { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin-top: 0.35rem; }
.pcast-fountain-link {
  font-size: 0.78rem; font-weight: 700; color: var(--accent-d); text-decoration: none; white-space: nowrap;
}
.pcast-fountain-link:hover { text-decoration: underline; }

/* Inline audio player. */
.pcast-player-row { padding: 0.1rem 0.7rem 0.2rem; }
.pcast-player { width: 100%; display: block; }

/* Download + Boost action buttons. */
.pcast-card-buttons {
  display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
  padding: 0.4rem 0.7rem 0.65rem;
}
.pcast-btn {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.5rem 0.95rem;
  font: inherit; font-size: 0.85rem; font-weight: 700;
  border: 1px solid transparent; border-radius: 999px; cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.pcast-btn-boost { color: #fff; background: #f7931a; border-color: #f7931a; }
.pcast-btn-boost:hover { background: #d97b0e; border-color: #d97b0e; }
.pcast-btn-bolt { display: inline-flex; width: 15px; height: 15px; }
.pcast-btn-bolt svg { width: 100%; height: 100%; display: block; }
.pcast-btn-download { color: var(--accent-d); background: var(--white); border-color: var(--border); }
.pcast-btn-download:hover { background: var(--tint); border-color: var(--accent); }
.pcast-btn-download:disabled { opacity: 0.6; cursor: default; }
.pcast-dot { opacity: 0.6; }
.pcast-sats { font-weight: 700; color: var(--accent-d); white-space: nowrap; }
.pcast-bolt { font-size: 0.85em; }

/* Avatars — stacked on cards, single on modal rows. Size via --pcast-av. */
.pcast-avatars { display: inline-flex; align-items: center; }
.pcast-avatars .pcast-avatar + .pcast-avatar { margin-left: -8px; }
.pcast-avatar {
  width: var(--pcast-av, 26px); height: var(--pcast-av, 26px);
  border-radius: 50%; object-fit: cover; flex-shrink: 0;
  border: 2px solid var(--white); background: var(--tint);
  box-sizing: border-box;
}
.pcast-avatar--none {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--cream-d); color: var(--muted);
  font-size: 0.6rem; font-weight: 700;
}
.pcast-avatar.is-interactive { cursor: pointer; }
.pcast-avatar.is-interactive:hover { border-color: var(--accent); }
.pcast-avatar.is-interactive:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.pcast-more-wrap { display: flex; justify-content: center; margin-top: 1.1rem; }
.pcast-more-group { display: flex; flex-direction: column; align-items: center; gap: 0.4rem; }
.pcast-more-count { font-size: 0.75rem; color: var(--muted); }
.pcast-showmore {
  padding: 0.5rem 1.4rem;
  font: inherit; font-size: 0.85rem; font-weight: 700;
  color: var(--accent-d); background: var(--white);
  border: 1px solid var(--border); border-radius: 999px; cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.pcast-showmore:hover { background: var(--tint); border-color: var(--accent); }

/* Episode title links out to the Fountain episode. */
.pcast-title-link { color: var(--text); text-decoration: none; }
.pcast-title-link:hover { color: var(--accent-d); text-decoration: underline; }

/* Media column: episode art with the air date tucked directly beneath it. */
.pcast-media-col { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; flex-shrink: 0; }
.pcast-card-aired { font-size: 0.66rem; color: var(--muted); white-space: nowrap; text-align: center; }

/* ⋮ subscribe menu on the card head (top-right) — show-level app links. */
.pcast-cardmenu { position: relative; flex-shrink: 0; align-self: flex-start; }
.pcast-cardmenu-btn {
  width: 30px; height: 30px; border-radius: 50%;
  border: none; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 1.2rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.pcast-cardmenu-btn:hover { background: var(--tint); color: var(--text); }
.pcast-cardmenu-menu {
  position: absolute; top: 34px; right: 0; z-index: 6;
  min-width: 190px;
  background: var(--white);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.18);
  padding: 0.35rem;
}
.pcast-cardmenu-menu[hidden] { display: none; }
.pcast-cardmenu-label {
  padding: 0.4rem 0.6rem 0.25rem;
  font-size: 0.66rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted);
}
.pcast-cardmenu-item {
  display: block; padding: 0.45rem 0.6rem;
  font-size: 0.85rem; font-weight: 600; color: var(--text);
  text-decoration: none; border-radius: 6px;
}
.pcast-cardmenu-item:hover { background: var(--tint); color: var(--accent-d); }

/* ── Boost drawer — a low-profile full-width toggle under the head. ── */
.pcast-drawer {
  display: flex; align-items: center; gap: 0.4rem; width: 100%;
  padding: 0.45rem 0.7rem 0.5rem;
  font: inherit; font-size: 0.78rem; font-weight: 600;
  color: var(--muted); background: transparent;
  border: none; border-top: 1px solid var(--border);
  cursor: pointer; text-align: left;
  transition: color 0.12s, background 0.12s;
}
.pcast-drawer:hover { color: var(--accent-d); background: rgba(0,0,0,0.02); }
.pcast-drawer:last-child { border-radius: 0 0 10px 10px; }
.pcast-drawer-caret { font-size: 0.85em; transition: transform 0.18s; }
/* Booster faces + total sats, sitting just after the "N boosts" label. */
.pcast-drawer-meta { display: inline-flex; align-items: center; gap: 0.5rem; }
.pcast-drawer-meta .pcast-sats { font-weight: 700; color: var(--accent-d); white-space: nowrap; }
.pcast-card.is-open .pcast-drawer > .pcast-drawer-caret { transform: rotate(180deg); }

/* "Hide boosts" control at the bottom of a card's thread. */
.pcast-drawer-close {
  justify-self: start;
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.35rem 0;
  font: inherit; font-size: 0.8rem; font-weight: 700;
  color: var(--muted); background: transparent; border: none; cursor: pointer;
}
.pcast-drawer-close:hover { text-decoration: underline; color: var(--accent-d); }

/* Thread footer: "see all boosts" (Boost Me Bitch) on the left, hide on the right. */
.pcast-details-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; flex-wrap: wrap;
}
.pcast-seeall {
  font-size: 0.8rem; font-weight: 700; color: var(--accent-d); text-decoration: none;
}
.pcast-seeall:hover { text-decoration: underline; }

/* ── Inline boost details — indented under the card like a child/thread,
   marked by a left accent rule and kept tight vertically. ── */
.pcast-details {
  display: grid; gap: 0.6rem;
  margin: 0 0.7rem 0.85rem 3.3rem;
  padding: 0.15rem 0 0.15rem 0.95rem;
  border-left: 2px solid var(--accent);
}
.pcast-details[hidden] { display: none; }
.pcast-boost { border-top: 1px solid var(--border); padding-top: 0.6rem; }
.pcast-boost:first-child { border-top: none; padding-top: 0; }
.pcast-boost-head { display: flex; align-items: center; gap: 0.55rem; }
.pcast-boost-who { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.pcast-boost-name {
  align-self: flex-start;
  font: inherit; font-size: 0.9rem; font-weight: 700; color: var(--text);
  background: transparent; border: none; padding: 0; cursor: pointer;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pcast-boost-name:hover { color: var(--accent-d); text-decoration: underline; }
.pcast-boost-when { font-size: 0.74rem; color: var(--muted); }
.pcast-boost-sats { flex-shrink: 0; font-size: 0.88rem; font-weight: 700; color: var(--accent-d); white-space: nowrap; }
.pcast-boost-msg {
  margin-top: 0.3rem; font-size: 0.88rem; line-height: 1.35; color: var(--text);
  white-space: pre-wrap; word-break: break-word;
}
.pcast-boost-msg a { color: var(--accent-d); }
/* Shared reply/repost/like/zap bar (boost-actions.css) under each comment —
   scoped-down here: no divider line, smaller + tighter than the boosts page. */
.pcast-boost .note-actions {
  margin-top: 0.15rem; padding-top: 0; border-top: none; gap: 0.05rem;
}
.pcast-boost .note-actions button { font-size: 0.72rem; padding: 0.2rem 0.4rem; gap: 0.25rem; }
.pcast-boost .note-actions .lb-icon { font-size: 0.82rem; }

/* Per-boost ⋮ overflow menu */
.pcast-more { position: relative; flex-shrink: 0; }
.pcast-more-btn {
  width: 30px; height: 30px; border-radius: 50%;
  border: none; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 1.1rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.pcast-more-btn:hover { background: var(--tint); color: var(--text); }
.pcast-more-menu {
  position: absolute; top: 34px; right: 0; z-index: 5;
  min-width: 160px;
  background: var(--white);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.18);
  padding: 0.35rem;
}
.pcast-more-menu[hidden] { display: none; }
.pcast-more-item {
  display: block; width: 100%; box-sizing: border-box; text-align: left;
  padding: 0.45rem 0.6rem; font: inherit; font-size: 0.85rem; color: var(--text);
  background: transparent; border: none; border-radius: 6px; cursor: pointer;
}
.pcast-more-item:hover { background: var(--tint); }

/* Copy toast */
.pcast-toast {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translate(-50%, 1rem);
  z-index: 1100;
  background: var(--text, #1e160a); color: #fff;
  padding: 0.55rem 1.1rem; border-radius: 999px;
  font-size: 0.85rem; font-weight: 600;
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
  opacity: 0; pointer-events: none;
  transition: opacity 0.18s, transform 0.18s;
}
.pcast-toast.is-visible { opacity: 1; transform: translate(-50%, 0); }
.pcast-toast.is-error { background: #9b2c2c; }

/* ── Articles cards ───────────────────────────────────────────────
   NIP-23 long-form articles. Each card shows the cover, title, an
   author byline (clickable avatar + name → copy npub), a one-line
   summary, and a foot row with a "Read Full Article" link + a ⋮ menu
   (copy naddr). Rendered by feeds-articles.js. */
.art-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.6rem; }
.art-card {
  position: relative;
  display: flex; gap: 0.85rem; align-items: flex-start;
  min-width: 0; padding: 0.8rem;
  background: var(--white); border: 1px solid var(--border);
  border-radius: 10px;
  transition: box-shadow 0.12s, border-color 0.12s;
}
.art-card:hover { box-shadow: 0 6px 18px rgba(0,0,0,0.08); }
.art-card-media {
  flex-shrink: 0; width: 92px; height: 92px;
  border-radius: 8px; overflow: hidden; background: var(--tint);
}
.art-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.art-card-media--none {
  display: flex; align-items: center; justify-content: center;
  font-size: 1.9rem; opacity: 0.5;
}
.art-card-media--link { cursor: pointer; }
.art-card-media--link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.art-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.3rem; }
.art-title {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.05rem; font-weight: 700; line-height: 1.25; color: var(--text);
  padding-right: 1.6rem; /* clear the corner ⋮ menu */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.art-title-link { cursor: pointer; }
.art-title-link:hover { text-decoration: underline; }
.art-title-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.art-byline { display: flex; align-items: center; gap: 0.45rem; font-size: 0.78rem; color: var(--muted); }
.art-byline-name {
  font: inherit; font-weight: 600; color: var(--accent-d);
  background: none; border: none; padding: 0; cursor: pointer;
  max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.art-byline-name:hover { text-decoration: underline; }
.art-dot { opacity: 0.6; }
.art-byline-when { white-space: nowrap; }
.art-summary {
  margin: 0; font-size: 0.85rem; line-height: 1.4; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;
}

/* Foot row: Read link (left) + ⋮ menu (right). */
.art-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 0.15rem; }
.art-read {
  font: inherit; font-size: 0.82rem; font-weight: 700; color: var(--accent-d);
  background: none; border: none; padding: 0; cursor: pointer;
}
.art-read:hover { text-decoration: underline; }
.art-more { position: absolute; top: 0.5rem; right: 0.5rem; }
.art-more-btn {
  width: 28px; height: 28px; border-radius: 50%;
  border: none; background: transparent; color: var(--muted); cursor: pointer;
  font-size: 1.1rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.art-more-btn:hover { background: var(--tint); color: var(--text); }
.art-more-menu {
  position: absolute; top: 32px; right: 0; z-index: 6; min-width: 180px;
  background: var(--white); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.18); padding: 0.35rem;
}
.art-more-menu[hidden] { display: none; }
.art-more-item {
  display: block; width: 100%; box-sizing: border-box; text-align: left;
  padding: 0.45rem 0.6rem; font: inherit; font-size: 0.85rem; color: var(--text);
  background: transparent; border: none; border-radius: 6px; cursor: pointer;
}
.art-more-item:hover { background: var(--tint); }

/* Author avatar — sized via --art-av on the element. */
.art-avatar {
  width: var(--art-av, 26px); height: var(--art-av, 26px);
  border-radius: 50%; object-fit: cover; flex-shrink: 0;
  background: var(--tint); box-sizing: border-box;
}
.art-avatar--none {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--cream-d); color: var(--muted);
  font-size: 0.62rem; font-weight: 700; line-height: 1;
}
.art-avatar--btn { cursor: pointer; transition: box-shadow 0.12s; }
.art-avatar--btn:hover { box-shadow: 0 0 0 2px var(--accent); }

/* Copy toast (self-contained; mirrors the podcasts feed's toast). */
.art-toast, .market-toast {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translate(-50%, 1rem);
  z-index: 1100; background: var(--text, #1e160a); color: #fff;
  padding: 0.55rem 1.1rem; border-radius: 999px;
  font-size: 0.85rem; font-weight: 600; box-shadow: 0 8px 24px rgba(0,0,0,0.25);
  opacity: 0; pointer-events: none; transition: opacity 0.18s, transform 0.18s;
}
.art-toast.is-visible, .market-toast.is-visible { opacity: 1; transform: translate(-50%, 0); }
.art-toast.is-error, .market-toast.is-error { background: #9b2c2c; }

/* Load-more (shared shape with the podcasts feed's control). */
.art-more-wrap { margin-top: 0.6rem; }
.art-more-group { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; }
.art-showmore {
  padding: 0.5rem 1.3rem; font: inherit; font-size: 0.85rem; font-weight: 700;
  color: var(--accent-d); background: var(--white);
  border: 1px solid var(--border); border-radius: 999px; cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.art-showmore:hover { background: var(--tint); border-color: var(--accent); }
.art-more-count { font-size: 0.75rem; color: var(--muted); }

/* ── Featured Articles ────────────────────────────────────────────
   Featured Events is a bare header over a grid; this section is a
   bounded gold container instead, because it owns a range filter the
   feed below it does not obey. The 1W/1M/All control sits INSIDE the
   border, so the filter's scope is stated by the layout rather than by
   a label. Gold is #e0a92e — the same accent as boosted event cards
   and top-tier supporter rings — deliberately not the tab's purple
   accent, which belongs to page-level chrome. */
/* ⚠️ THE GOLD BOX IS GONE (Reed, 2026-09-06): the Featured view is its
   own sub-tab, so the container that used to mark "the featured slot"
   inside the feed marked nothing. .feat-box stays as the structural
   wrapper the view switch keys on, unstyled; its head keeps only the
   Find button, pinned right, since the sub-tab already says "Featured".
   The gold itself survives on the cards (hairlines, credit, buttons). */
.feat-box {
  --gold: #e0a92e;
  --gold-d: #a9761a;
  margin: 0 0 1.5rem;
  padding: 0;
  min-width: 0;
  max-width: 100%;
}
.feat-head {
  display: flex; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; gap: 0.5rem 0.9rem; margin-bottom: 0.8rem;
}
.feat-head .feat-title { display: none; }
/* Nothing inside a panel may be wider than its column: on a phone the
   shell clips at its own edge (overflow: clip), so a card that outgrows
   the column reads as spilling out of the card. Grid children default to
   min-content width unless told otherwise, and a long unbroken word in
   a title or a boost message can still push past that. */
.feed-panel, [data-feed-list], [data-feed-list] > *, [class*="featured-mount"],
.feat-list, .feat-list > *, .pcast-list > *, .art-list > *, .market-grid > * {
  min-width: 0; max-width: 100%;
}
.pcast-card, .art-card, .market-card, .feat-box { overflow-wrap: anywhere; }
.pcast-player { max-width: 100%; }
.pcast-details { min-width: 0; }
.feat-title {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.02rem; font-weight: 700; color: var(--gold-d);
}
.feat-count {
  font-family: var(--sans, inherit); font-size: 0.72rem; font-weight: 700;
  color: var(--gold-d); background: rgba(224,169,46,0.18);
  padding: 0.05rem 0.42rem; border-radius: 999px;
}
/* The row fills the width; Create Event sits at the left, Find at the
   right (Reed, 2026-09-06). */
.feat-actions {
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  flex: 1 1 auto;
}
.feat-actions > .feat-find { margin-left: auto; }

/* Range pills — same near-square shape as the page-level .pcast-range
   control, but gold-on-gold so they read as part of the box. */
.feat-range { display: flex; flex-shrink: 0; }
.feat-range-btn {
  min-width: 2rem; padding: 0.5rem 0.35rem;
  font: inherit; font-size: 0.72rem; font-weight: 700; line-height: 1.2;
  color: var(--gold-d); background: transparent;
  border: none; border-radius: 6px; cursor: pointer; opacity: 0.6;
  transition: background 0.12s, opacity 0.12s;
}
.feat-range-btn:hover { opacity: 1; background: rgba(224,169,46,0.14); }
.feat-range-btn.is-active {
  opacity: 1; background: rgba(224,169,46,0.28);
}

.feat-find {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.35rem 0.7rem; font: inherit; font-size: 0.78rem; font-weight: 600;
  color: var(--gold-d); background: var(--white);
  border: 1px solid var(--gold); border-radius: 999px; cursor: pointer;
  white-space: nowrap; transition: background 0.12s;
}
.feat-find:hover { background: rgba(224,169,46,0.14); }

.feat-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.6rem; }
.feat-empty { margin: 0; font-size: 0.85rem; color: var(--muted); }
.feat-more {
  display: block; margin: 0.7rem auto 0;
  padding: 0.42rem 1.1rem; font: inherit; font-size: 0.8rem; font-weight: 700;
  color: var(--gold-d); background: var(--white);
  border: 1px solid var(--gold); border-radius: 999px; cursor: pointer;
  transition: background 0.12s;
}
.feat-more:hover { background: rgba(224,169,46,0.14); }

/* A featured card inside the box gets a static gold hairline, not the
   pulsing halo the Events tab puts on boosted cards — the container is
   already carrying the gold, and five pulsing cards is noise. */
.art-card--featured { border-color: var(--gold); }
.art-card--featured:hover { box-shadow: 0 6px 18px rgba(224,169,46,0.22); }

/* "Feature" — the boost-this-into-Featured action, in the card foot where
   the featured cards carry their booster credit. Orange fill + white bolt
   SVG (house convention for orange-background buttons; never the ⚡
   emoji). */
.art-feature {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.3rem 0.7rem; font: inherit; font-size: 0.78rem; font-weight: 700;
  color: #fff; background: var(--orange);
  border: none; border-radius: 999px; cursor: pointer;
  transition: background 0.12s;
}
.art-feature:hover { background: var(--orange-d); }
.art-feature:disabled { opacity: 0.6; cursor: default; }
.feat-bolt { width: 0.9em; height: 0.9em; flex-shrink: 0; }

/* "Featured by (pfp) Name · 3d ago" — sits where the Feature button is on
   an unfeatured card. Muted so it reads as a credit, not an action; the
   relative age is what makes the range filter legible. */
.feat-by {
  display: inline-flex; align-items: center; gap: 0.35rem;
  max-width: 60%; padding: 0; font: inherit; font-size: 0.75rem;
  color: var(--muted); background: none; border: none;
}
.feat-by-label { flex-shrink: 0; }
/* Only the person is the link / copy button; the label and age are text. */
.feat-by-who {
  display: inline-flex; align-items: center; gap: 0.35rem; min-width: 0;
  padding: 0; font: inherit; color: inherit; background: none; border: none;
  cursor: pointer; text-decoration: none;
}
.feat-by-name {
  font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.feat-by-who:hover .feat-by-name { color: var(--gold-d); }
.feat-by-when { flex-shrink: 0; white-space: nowrap; }

/* ── "Find an Article to Feature" modal ───────────────────────────
   Reuses the event composer's backdrop/card chrome so both Find modals
   are one thing; the body is a single paste box, since an article is
   always addressable by naddr. */
.ffind-help { margin: 0 0 0.8rem; font-size: 0.85rem; color: var(--muted); line-height: 1.45; }
.ffind-row { display: flex; gap: 0.5rem; }
.ffind-input {
  flex: 1; min-width: 0; padding: 0.55rem 0.7rem;
  font: inherit; font-size: 0.85rem; color: var(--text);
  background: var(--white); border: 1px solid var(--border); border-radius: 8px;
}
.ffind-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.ffind-go {
  padding: 0.55rem 1.1rem; font: inherit; font-size: 0.82rem; font-weight: 700;
  color: #fff; background: var(--accent); border: none; border-radius: 8px;
  cursor: pointer; white-space: nowrap;
}
.ffind-go:disabled { opacity: 0.6; cursor: default; }
.ffind-status { margin: 0.7rem 0 0; font-size: 0.82rem; color: var(--muted); }
.ffind-status:empty { display: none; }
.ffind-result:not(:empty) { margin-top: 0.9rem; }
.ffind-preview {
  display: flex; gap: 0.75rem; align-items: flex-start;
  padding: 0.7rem; border: 1px solid var(--gold, #e0a92e); border-radius: 10px;
  background: rgba(224,169,46,0.05);
}
.ffind-preview-media {
  flex-shrink: 0; width: 68px; height: 68px; border-radius: 8px;
  overflow: hidden; background: var(--tint);
}
.ffind-preview-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ffind-preview-media--none {
  display: flex; align-items: center; justify-content: center; font-size: 1.5rem; opacity: 0.5;
}
.ffind-preview-body { min-width: 0; }
.ffind-preview-title {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 0.98rem; font-weight: 700; line-height: 1.25; color: var(--text);
}
.ffind-preview-meta {
  display: flex; align-items: center; gap: 0.35rem; margin-top: 0.2rem;
  font-size: 0.76rem; color: var(--muted);
}
.ffind-preview-summary {
  margin: 0.35rem 0 0; font-size: 0.82rem; line-height: 1.4; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;
}
.ffind-feature { margin-top: 0.8rem; padding: 0.5rem 1.1rem; font-size: 0.85rem; }

/* ── Featured Listings (Marketplace tab) ──────────────────────────
   Same gold box as Featured Articles; the cards are the market grid's
   own tiles with a gold hairline. The Feature button sits under the
   Add-to-cart / Contact button, full width like it. */
.market-featured-mount .feat-box { margin-bottom: 1.2rem; }
.market-card--featured { border-color: var(--gold, #e0a92e); }
.market-card--featured:hover { box-shadow: 0 8px 22px rgba(224,169,46,0.24); }
.market-card-actions { display: flex; flex-direction: column; gap: 0.35rem; }
.market-btn--feature {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem;
  color: #fff; background: var(--orange); border-color: var(--orange);
}
.market-btn--feature:hover { background: var(--orange-d); border-color: var(--orange-d); }
.market-btn--feature:disabled { opacity: 0.6; cursor: default; }
.market-btn--feature .feat-bolt { width: 0.9em; height: 0.9em; flex-shrink: 0; }
.market-btn--feature.ffind-feature { width: auto; }
.market-card-actions .feat-by { max-width: 100%; justify-content: center; }
.market-card-actions .feat-by .market-seller-pfp { width: 16px; height: 16px; }

/* ── Featured Episodes (Podcast Boosts tab) ───────────────────────
   The gold box again; featured episode cards keep their full layout
   (player, drawer) with a gold hairline. The Feature button is gold
   rather than orange here because it sits beside the orange "Boost
   episode" button: on this page gold means "the featured slot", and
   two orange bolts side by side would read as one action twice. */
.pcast-featured-mount .feat-box { margin-bottom: 1.2rem; }
.pcast-featured-mount .feat-list { gap: 0.9rem; }
.pcast-card--featured { border-color: var(--gold, #e0a92e); box-shadow: 0 0 0 1px rgba(224,169,46,0.18); }
.pcast-btn-feature { color: #fff; background: #e0a92e; border-color: #e0a92e; }
.pcast-btn-feature:hover { background: #c9931f; border-color: #c9931f; }
.pcast-btn-feature:disabled { opacity: 0.6; cursor: default; }
.pcast-btn-feature .feat-bolt { width: 15px; height: 15px; }
.pcast-card-buttons .feat-by { margin-left: auto; max-width: 55%; }
.pcast-card-buttons .feat-by img,
.pcast-card-buttons .feat-by .pcast-avatar { width: 18px; height: 18px; border-radius: 50%; object-fit: cover; }

/* "Find an Episode to Feature": a Podcast Index search. Shows come back
   as a list; picking one lists its recent episodes; each episode row
   carries its own Feature button. */
.ffind-list { display: flex; flex-direction: column; gap: 0.4rem; margin-top: 0.9rem; max-height: 50vh; overflow-y: auto; }
.ffind-row-item {
  display: flex; align-items: center; gap: 0.65rem; width: 100%; text-align: left;
  padding: 0.5rem 0.6rem; font: inherit; color: var(--text);
  background: var(--white); border: 1px solid var(--border); border-radius: 10px; cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.ffind-row-item:hover { border-color: var(--gold, #e0a92e); background: rgba(224,169,46,0.05); }
.ffind-row-item--static { cursor: default; }
.ffind-row-item--static:hover { border-color: var(--border); background: var(--white); }
.ffind-row-media {
  flex-shrink: 0; width: 44px; height: 44px; border-radius: 8px; overflow: hidden; background: var(--tint);
  display: flex; align-items: center; justify-content: center; font-size: 1.2rem; opacity: 0.9;
}
.ffind-row-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ffind-row-body { min-width: 0; flex: 1; }
.ffind-row-title { font-size: 0.88rem; font-weight: 700; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.ffind-row-meta { font-size: 0.74rem; color: var(--muted); margin-top: 0.15rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ffind-row-action { flex-shrink: 0; padding: 0.4rem 0.75rem; font-size: 0.78rem; }
.ffind-back {
  display: inline-flex; align-items: center; gap: 0.3rem; margin: 0.8rem 0 0;
  padding: 0; font: inherit; font-size: 0.8rem; font-weight: 600; color: var(--muted);
  background: none; border: none; cursor: pointer;
}
.ffind-back:hover { color: var(--text); }

/* ── Shared feed toggle pill (panel head) ─────────────────────────
   A default-off switch that widens a feed. Used by the Articles tab
   ("Include short articles") and the Events tab ("Include virtual
   events"). Accent is contextual via body[data-active-feed]. */
.art-toolbar { display: flex; align-items: center; align-self: center; }
.feed-head-controls { display: flex; align-items: center; gap: 0.85rem; flex-shrink: 0; flex-wrap: wrap; }
.feed-toggle {
  display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer;
  user-select: none;
}
.feed-toggle-input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.feed-toggle-track {
  position: relative; flex-shrink: 0;
  width: 38px; height: 22px; border-radius: 999px;
  background: var(--border); transition: background 0.15s;
}
.feed-toggle-thumb {
  position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--white); box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  transition: transform 0.15s;
}
.feed-toggle-input:checked + .feed-toggle-track { background: var(--accent); }
.feed-toggle-input:checked + .feed-toggle-track .feed-toggle-thumb { transform: translateX(16px); }
.feed-toggle-input:focus-visible + .feed-toggle-track { outline: 2px solid var(--accent); outline-offset: 2px; }
.feed-toggle-label { font-size: 0.82rem; font-weight: 600; color: var(--text); white-space: nowrap; }

/* ── Article reader (full-width in-panel takeover) ────────────────
   When a card is opened, the list + panel head hide and this renders
   in their place: a back bar, cover, title, byline, summary, then the
   sanitized markdown body (.art-prose). Mirrors MyNostr's reader. */
.art-reader {
  position: relative;
  max-width: 720px; margin: 0 auto; padding: 0.25rem 0 2rem;
  animation: art-fade 0.16s ease-out;
}
@keyframes art-fade { from { opacity: 0; } to { opacity: 1; } }
/* Floating back pill (left) + ⋮ (right). position:fixed, NOT sticky: a
   global `overflow-x:hidden` on <body> makes it a non-scrolling scroll-
   container, which breaks position:sticky for its descendants. JS
   (positionFloatingControls) sets top/left each scroll so they hug the
   article column's gutters and never rise above the article top. */
.art-reader-back {
  position: fixed; z-index: 45;
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.45rem 0.9rem; font: inherit; font-size: 0.82rem; font-weight: 700;
  color: var(--accent-d); background: var(--white);
  border: 1px solid var(--border); border-radius: 999px; cursor: pointer;
  box-shadow: 0 2px 12px rgba(0,0,0,0.14);
  transition: background 0.12s, border-color 0.12s;
}
.art-reader-back:hover { border-color: var(--accent); background: var(--tint); }
/* ⋮ is pinned to the article's top-right (absolute, scrolls away with the
   article) — not floating like the back pill. */
.art-reader-more { position: absolute; top: 0.5rem; right: 0.5rem; z-index: 5; }
.art-reader-more .art-more-btn {
  width: 34px; height: 34px; color: var(--accent-d);
  background: var(--white); border: 1px solid var(--border);
  box-shadow: 0 2px 12px rgba(0,0,0,0.14);
}
.art-reader-more .art-more-btn:hover { background: var(--tint); }
.art-reader-cover {
  width: 100%; aspect-ratio: 16 / 9; margin-bottom: 1.1rem;
  border-radius: 12px; overflow: hidden; background: var(--tint);
  border: 1px solid var(--border);
}
.art-reader-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.art-reader-title {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.9rem; font-weight: 800; line-height: 1.15; color: var(--text);
  margin: 0 0 0.7rem;
}
.art-reader-byline { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.9rem; }
.art-reader-who { display: flex; flex-direction: column; }
.art-reader-name {
  align-self: flex-start; font: inherit; font-size: 0.92rem; font-weight: 700; color: var(--text);
  background: none; border: none; padding: 0; cursor: pointer;
}
.art-reader-name:hover { text-decoration: underline; }
.art-reader-when { font-size: 0.78rem; color: var(--muted); }
.art-reader-summary {
  margin: 0 0 1.4rem; padding: 0 0 1.1rem;
  border-bottom: 1px solid var(--border);
  font-size: 1.05rem; line-height: 1.55; color: var(--muted); font-style: italic;
}
/* Interaction bar (reply / repost / like / zap) at the foot — the shared
   .note-actions bar from boost-actions.css, left-aligned, no divider line. */
.art-reader-foot { margin-top: 2rem; }
.art-reader-foot .note-actions {
  justify-content: flex-start; gap: 0.4rem;
  margin-top: 0; padding-top: 0; border-top: none;
}

/* ── Prose typography for the markdown body ──
   Light-theme reimplementation of MyNostr's `prose prose-invert` look:
   comfortable measure, generous vertical rhythm, styled headings /
   lists / quotes / code / tables. */
.art-prose { font-size: 1.02rem; line-height: 1.7; color: var(--text); overflow-wrap: anywhere; }
.art-prose > :first-child { margin-top: 0; }
.art-prose p { margin: 0 0 1.15rem; }
.art-prose h1, .art-prose h2, .art-prose h3, .art-prose h4 {
  font-family: 'Playfair Display', Georgia, serif;
  line-height: 1.25; color: var(--text); margin: 2rem 0 0.8rem; font-weight: 700;
}
.art-prose h1 { font-size: 1.6rem; }
.art-prose h2 { font-size: 1.35rem; }
.art-prose h3 { font-size: 1.15rem; }
.art-prose h4 { font-size: 1.02rem; }
.art-prose a { color: var(--accent-d); text-decoration: underline; text-underline-offset: 2px; }
.art-prose a:hover { color: var(--accent); }
/* Inline nostr @-mentions (npub/nprofile) — match the note-body chip look. */
.art-prose a.nostr-mention { color: var(--orange); font-weight: 600; text-decoration: none; }
.art-prose a.nostr-mention:hover { text-decoration: underline; }
.art-prose ul, .art-prose ol { margin: 0 0 1.15rem; padding-left: 1.4rem; }
.art-prose li { margin: 0.3rem 0; }
.art-prose li > ul, .art-prose li > ol { margin: 0.3rem 0; }
.art-prose blockquote {
  margin: 0 0 1.15rem; padding: 0.35rem 0 0.35rem 1rem;
  border-left: 3px solid var(--accent); color: var(--muted); font-style: italic;
}
.art-prose img {
  display: block; max-width: 100%; height: auto;
  margin: 1.2rem auto; border-radius: 8px; max-height: 70vh; object-fit: contain;
}
.art-prose hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
.art-prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.88em; background: var(--tint); color: var(--accent-d);
  padding: 0.1em 0.35em; border-radius: 5px;
}
.art-prose pre {
  margin: 0 0 1.15rem; padding: 0.9rem 1rem; overflow-x: auto;
  background: var(--tint); border: 1px solid var(--border); border-radius: 8px;
}
.art-prose pre code { background: none; color: var(--text); padding: 0; font-size: 0.85rem; }
.art-prose table {
  width: 100%; border-collapse: collapse; margin: 0 0 1.15rem; font-size: 0.92rem;
  display: block; overflow-x: auto;
}
.art-prose th, .art-prose td { border: 1px solid var(--border); padding: 0.45rem 0.7rem; text-align: left; }
.art-prose th { background: var(--tint); font-weight: 700; }
.art-prose-fallback { white-space: pre-wrap; overflow-wrap: anywhere; }

/* ── Mobile: tabs become a scrollable chip row ── */
@media (max-width: 640px) {
  .feed-bar-wrap { top: 56px; } /* nav shrinks on mobile */
  /* The shell loses its sides and radius on a phone: the tabs are chips
     there, with room around them already. */
  .feeds-shell-wrap { padding: 0 0 2rem; }
  .feeds-shell, .community-shell { border-left: 0; border-right: 0; border-radius: 0; }
  .community-shell { padding: 1.25rem 1rem; }
  .community-module { padding-left: 0; padding-right: 0; }
  .community-module .home-module-head { padding: 0 1rem; }
  /* Icon-only chips that all fit across the row (no horizontal scroll):
     four tabs and four words do not fit in 375px. */
  .feed-tabs {
    gap: 0.5rem;
    padding: 0.6rem 0.85rem 0.5rem;
  }
  .feed-tab {
    flex-direction: row;
    justify-content: center;
    gap: 0;
    border-top: 0;
    border: 1px solid var(--tab);
    border-radius: 999px;
    padding: 0.5rem 0;
    color: var(--tab);
  }
  .feed-tab-icon { width: 22px; height: 22px; }
  /* Hide the text visually but keep it for screen readers (the icon is
     aria-hidden, so this stays the tab's accessible name). */
  .feed-tab-label {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  .feed-tab-sub { display: none; }
  .feed-tab[aria-selected="true"] { border-color: var(--tab); }
  /* With icon-only chips the "under its tab" alignment has nothing to
     align with, and a pair squeezed into a quarter of the row is two
     unreadable blocks, so the active group spans the whole row. */
  .feed-subs { padding: 0 0.85rem 0.5rem; }
  .feed-sub-group[data-feed] { grid-column: 1 / -1; }
  .feed-sub { font-size: 0.8rem; padding: 0.4rem 0.2rem 0.44rem; }
  .feed-panels-inner { padding: 1.5rem 1rem 2.5rem; }
  /* Shallower child indent on narrow screens. */
  .pcast-details { margin-left: 2.1rem; padding-left: 0.7rem; }
  /* Articles: smaller cover thumb + tighter reader headings. */
  .art-card-media { width: 72px; height: 72px; }
  .art-reader-title { font-size: 1.5rem; }
  .art-prose { font-size: 1rem; }
  .feat-actions { margin-left: auto; }
  .feat-find { font-size: 0.74rem; padding: 0.3rem 0.6rem; }
  /* The card foot runs out of room for "Read Full Article" plus a booster
     credit, so let the two stack rather than squeezing the name to nothing. */
  .art-card-foot { flex-wrap: wrap; gap: 0.35rem 0.5rem; }
  .feat-by { max-width: 100%; }
  /* Events head: keep the range buttons + type dropdown at the top-right
     beside the Create button (align-items:flex-start top-aligns them).
     flex-wrap is a safety net for very narrow screens where the controls
     can't fit beside the title. */
  .feed-panel-head { flex-wrap: wrap; align-items: flex-start; }
  .feed-head-controls {
    flex-direction: column;
    align-items: flex-end;
    gap: 0.55rem;
  }
  /* Podcast Boosts: the title block is too wide to share a row here, so the
     range buttons + sort pill wrap onto their own line together. Left-
     aligned they'd sit at the panel's left edge, and the sort menu's
     right-anchored popover (min-width 175px) would open past the left edge
     of the screen — so pin the group right. */
  .pcast-controls { margin-left: auto; }
}

/* ── The feed pages (rails-homepage, 2026-11) ──
   No Featured / All switch any more: <body data-feed-view="page"> shows the
   gold box and the list together, the box first and each item once (the
   renderers leave a featured item out of the list). The Events box paints
   its own Create Event beside Find, so the panel head's copy is hidden. */
body[data-feed-view="page"] #panel-events .feed-panel-head .event-composer-btns { display: none; }
