/* FeedLynx — Theme & Components (layout via Tailwind CDN) */

/* Twemoji — cross-platform emoji rendering */
img.emoji { height: 1em; width: 1em; margin: 0 .05em 0 .1em; vertical-align: -0.1em; display: inline; }

/* ==================== THEME VARIABLES ==================== */
:root {
  --bg: #f4f4f5; --bg-card: #ffffff; --bg-subtle: #fafafa;
  --text: #18181b; --text-secondary: #3f3f46; --text-muted: #71717a;
  --border: #e4e4e7; --border-light: #f4f4f5;
  /* Mobile chrome heights — single source of truth for topbar / bottom-bar
     and the drawer that sits between them. Bottombar excludes the iOS
     safe-area inset; consumers add `env(safe-area-inset-bottom)` when they
     need the total. Don't reuse 100vh / 100dvh in the drawer — mobile vh
     fluctuates with the browser URL bar. */
  --app-topbar-h: 3.5rem;
  --app-bottombar-h: 4.25rem;
  --accent: #006FEE; --accent-hover: #005BC4; --accent-light: #EDF5FF; --accent-soft: rgba(0,111,238,0.08);
  --success: #17C964; --success-light: #E8FAF0;
  --error: #F31260; --error-light: #FEE7EF;
  --warning: #F5A524; --warning-light: #FEFCE8; --warning-text: #92400E;
  --cat-cybersecurity: #F31260; --cat-tech: #006FEE; --cat-tech_news: #006FEE;
  --cat-crypto: #F5A524; --cat-crypto_bitcoin: #F5A524;
  --cat-ai: #7828C8; --cat-artificial_intelligence: #7828C8;
  --cat-privacy: #17C964; --cat-privacy_rights: #17C964;
  --cat-programming: #06B6D4; --cat-devops: #6366F1; --cat-devops_cloud: #6366F1;
  --cat-linux: #F97316; --cat-linux_opensource: #F97316;
  --cat-sport: #E11D48; --cat-finance: #0D9488; --cat-other: #71717a;
  --cat-world_news: #64748b; --cat-science: #a855f7; --cat-gaming: #7c3aed; --cat-business: #0ea5e9;
  --cat-design_ux: #ec4899; --cat-data_science: #14b8a6; --cat-networking_sysadmin: #3b82f6;
  --cat-mobile: #f59e0b; --cat-real_estate: #84cc16; --cat-statistics: #06b6d4;
  --cat-news_us: #3b82f6; --cat-news_uk: #6366f1; --cat-news_italia: #22c55e;
  --cat-news_deutschland: #f59e0b; --cat-news_france: #3b82f6; --cat-news_espana: #ef4444;
  --cat-news_nederland: #f97316; --cat-news_portugal: #22c55e; --cat-news_brasil: #22c55e;
  --cat-news_japan: #e11d48; --cat-news_india: #f97316; --cat-news_australia: #0ea5e9;
  --cat-news_schweiz: #ef4444; --cat-news_svizzera_italiana: #ef4444; --cat-news_russia: #6366f1;
  --cat-tech_italia: #22c55e; --cat-tech_dach: #f59e0b; --cat-tech_france: #3b82f6; --cat-tech_espana: #ef4444;
  /* Badge backgrounds (light mode) */
  --badge-cybersecurity-bg: #FEE7EF; --badge-cybersecurity-fg: #be123c;
  --badge-tech-bg: #EDF5FF; --badge-tech-fg: #1d4ed8;
  --badge-crypto-bg: #FEF9C3; --badge-crypto-fg: #92400E;
  --badge-ai-bg: #F3E8FF; --badge-ai-fg: #6b21a8;
  --badge-privacy-bg: #DCFCE7; --badge-privacy-fg: #166534;
  --badge-programming-bg: #CFFAFE; --badge-programming-fg: #155E75;
  --badge-devops-bg: #E0E7FF; --badge-devops-fg: #4338ca;
  --badge-linux-bg: #FFEDD5; --badge-linux-fg: #9A3412;
  --badge-sport-bg: #FFE4E6; --badge-sport-fg: #be123c;
  --badge-finance-bg: #CCFBF1; --badge-finance-fg: #115e59;
}
[data-theme="dark"] {
  --bg: #09090b; --bg-card: #18181b; --bg-subtle: #1e1e22;
  --text: #fafafa; --text-secondary: #d4d4d8; --text-muted: #a1a1aa;
  --border: #27272a; --border-light: #1e1e22;
  --accent: #3B82F6; --accent-hover: #60A5FA; --accent-light: #172554; --accent-soft: rgba(59,130,246,0.1);
  --success-light: #052e16; --error-light: #450a0a; --warning-light: #422006; --warning-text: #fbbf24;
  --badge-cybersecurity-bg: #450a0a; --badge-cybersecurity-fg: #fb7185;
  --badge-tech-bg: #172554; --badge-tech-fg: #60a5fa;
  --badge-crypto-bg: #422006; --badge-crypto-fg: #fbbf24;
  --badge-ai-bg: #2e1065; --badge-ai-fg: #c084fc;
  --badge-privacy-bg: #052e16; --badge-privacy-fg: #4ade80;
  --badge-programming-bg: #083344; --badge-programming-fg: #22d3ee;
  --badge-devops-bg: #1e1b4b; --badge-devops-fg: #a5b4fc;
  --badge-linux-bg: #431407; --badge-linux-fg: #fb923c;
  --badge-finance-bg: #042f2e; --badge-finance-fg: #2dd4bf;
}

/* ==================== BASE ==================== */
html { scroll-behavior: smooth; scroll-padding-top: 4.5rem; }
body { background: var(--bg); color: var(--text); -webkit-font-smoothing: antialiased; font-size: 0.9rem; overflow-x: hidden; }

/* ======================================================= */
/* ====== Global app shell (persistent left sidebar) ====== */
/* ======================================================= */
.app-body { overflow-x: hidden; }
.app-shell {
  display: grid;
  grid-template-columns: 270px 1fr;
  min-height: 100vh;
}
/* Onboarding hides the sidebar (base.html omits components/nav.html on
   /onboarding) so the grid must collapse to a single 1fr column —
   otherwise the main content is squeezed into the right ~70% of the
   viewport with empty space where the sidebar used to be. */
.app-shell-onboarding { grid-template-columns: 1fr !important; }
.app-main-wrap { min-width: 0; display: flex; flex-direction: column; }
.app-main {
  flex: 1; min-width: 0;
  padding: 1.5rem 2rem;
  width: 100%;
  box-sizing: border-box;
}
.app-main.max-w-screen-2xl,
.app-main.max-w-6xl,
.app-main.max-w-5xl,
.app-main.max-w-4xl {
  margin-left: auto; margin-right: auto;
}

/* Mobile header bar (hamburger + brand) — hidden on desktop. Fixed (not
   sticky) so it shares the same coordinate origin as the bottom-bar and
   the drawer; sticky drifts under iOS/Chrome dynamic URL bar. Height is
   fixed via the shared variable so the drawer can anchor to it exactly. */
.app-mobile-bar {
  display: none; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.85rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--app-topbar-h); box-sizing: border-box;
  z-index: 50;
}
.app-mobile-hamburger {
  width: 36px; height: 36px; display: inline-flex;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--border);
  border-radius: 8px; color: var(--text); cursor: pointer;
}
/* Page title in the top bar — replaces the FeedLynx brand on mobile.
   The page's .disc-hero-search stays in its natural position below the
   page header (consistent with desktop and the Flutter app). */
.app-mobile-title {
  flex: 1; min-width: 0;
  font-weight: 700; font-size: 0.95rem; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.app-mobile-title .page-title-icon {
  width: 16px; height: 16px; flex-shrink: 0; color: var(--accent);
}

/* === Newsletter picker dropdown ===
   Native <details>/<summary> in the dashboard H1. Replaces the
   horizontal chip strip we used to render above the hero. Works
   in-page on desktop AND in the cloned mobile top bar. */
.np-nl-picker {
  display: inline-block;
  position: relative;
}
.np-nl-picker[open] .np-nl-chev { transform: rotate(180deg); }
.np-nl-summary {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
  padding: 0.15rem 0.45rem;
  margin: -0.15rem -0.45rem;
  border-radius: 8px;
  transition: background 0.15s;
}
.np-nl-summary::-webkit-details-marker { display: none; }
.np-nl-summary:hover { background: var(--bg-subtle); }
.np-nl-chev {
  color: var(--text-muted);
  flex-shrink: 0;
  transition: transform 0.15s;
}
.np-nl-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 200px;
  max-width: 320px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  padding: 0.35rem;
  z-index: 60;
}
.np-nl-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.7rem;
  border-radius: 6px;
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}
.np-nl-item:hover { background: var(--bg-subtle); }
.np-nl-item-active {
  background: var(--accent-soft);
  color: var(--accent);
}
.np-nl-item-badge {
  background: var(--accent);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  flex-shrink: 0;
}
/* In the cloned mobile top bar, .app-mobile-title has overflow:hidden
   for text-ellipsis on long titles — which would clip the absolutely-
   positioned menu. Switch to position:fixed so the menu escapes the
   overflow context and anchors to the viewport just below the top bar. */
.app-mobile-title .np-nl-menu {
  position: fixed;
  top: calc(var(--app-topbar-h, 3.25rem) + 4px);
  right: 0.5rem;
  left: auto;
  z-index: 60;
}
/* Action toolbar relocated into the top bar on mobile. Visible overflow
   so child dropdowns (.bf-dropdown) aren't clipped — chips are icon-only
   here so 4-5 buttons fit naturally without needing horizontal scroll. */
.app-mobile-actions {
  display: inline-flex; align-items: center; gap: 0.3rem;
  flex-shrink: 0;
}
.app-mobile-actions:empty { display: none; }
/* Anchor the "Send" / "More actions" dropdown to the right edge of the
   viewport (just below the top bar) so it doesn't get clipped by the
   compact top-bar flex row. */
.app-mobile-actions .bf-dropdown {
  position: fixed;
  top: calc(var(--app-topbar-h, 3.25rem) + 4px);
  right: 0.5rem;
  left: auto;
  z-index: 51;
}
/* The moved .following-hero-actions doesn't need its own grid/spacing
   anymore — it just lays out its buttons horizontally. */
.app-mobile-actions .following-hero-actions {
  display: inline-flex; align-items: center; gap: 0.25rem;
  margin: 0; padding: 0; flex-wrap: nowrap;
}
/* Compact the action buttons: icon-only, smaller padding, drop the
   text label and the PRO badge that don't fit in the top bar. */
.app-mobile-actions .lf-chip {
  padding: 0.3rem 0.5rem;
  min-height: 0;
  font-size: 0;            /* hides whitespace; SVGs render fine */
  gap: 0;
}
.app-mobile-actions .lf-chip > span,
.app-mobile-actions .lf-chip .tier-badge-pro,
.app-mobile-actions .following-hero-count {
  display: none;
}
.app-mobile-actions .lf-chip svg {
  width: 14px; height: 14px;
}

/* ---- Sidebar ---- */
.app-sidebar {
  position: sticky; top: 0;
  align-self: start;
  height: 100vh; max-height: 100vh;
  display: flex; flex-direction: column;
  background: var(--bg-subtle);
  border-right: 1px solid var(--border);
  overflow: hidden; /* Children manage their own scroll */
}
.app-sidebar-brand {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 1.1rem 1rem;
  text-decoration: none; color: var(--text);
  font-weight: 800; font-size: 1.05rem; letter-spacing: -0.01em;
  border-bottom: 1px solid var(--border);
  background: var(--bg-subtle);
  flex: 0 0 auto;
}
.app-sidebar-logo { width: 24px; height: 24px; }
/* Close-drawer button — only visible on mobile (≤900px, when the sidebar
   behaves as a drawer). Floats top-right in the brand row. */
.app-sidebar-close {
  display: none;
  position: absolute; top: 0.55rem; right: 0.55rem;
  width: 36px; height: 36px; z-index: 5;
  background: transparent; border: 1px solid transparent; border-radius: 8px;
  color: var(--text-muted); cursor: pointer;
  align-items: center; justify-content: center;
}
.app-sidebar-close:hover { background: var(--bg-subtle); color: var(--text); }
@media (max-width: 900px) {
  .app-sidebar-close { display: inline-flex; }
}

.app-sidebar-nav {
  display: flex; flex-direction: column; gap: 2px;
  padding: 0.65rem 0.5rem;
}
.app-nav-link {
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.55rem 0.75rem;
  font-size: 0.88rem; font-weight: 500; color: var(--text);
  border-radius: 6px;
  text-decoration: none; transition: background 0.1s;
}
.app-nav-link:hover { background: var(--bg-card); }
.app-nav-link.active {
  background: var(--accent-soft); color: var(--accent); font-weight: 600;
}
.app-nav-link svg { flex-shrink: 0; opacity: 0.85; }
.app-nav-link.active svg { opacity: 1; }
.app-nav-link span { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-nav-badge {
  font-size: 0.55em; font-weight: 700; margin-left: 0.2rem;
  opacity: 0.55; letter-spacing: 0.03em;
}

/* Sidebar body: UNIQUE scrollable container. Header (.app-sidebar-brand)
   and footer (.app-sidebar-user) sit OUTSIDE this wrapper and remain
   pinned at the edges of the sidebar in every viewport state. */
.app-sidebar-body {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

/* Subscriptions / discovery sections — static flex items inside
   .app-sidebar-body. They no longer own their own scroll: the body
   wrapper handles the entire vertical scroll for the sidebar. */
.app-sidebar-sub {
  padding: 0.5rem 0;
  border-top: 1px solid var(--border);
  margin-top: 0.5rem;
  flex: 0 0 auto;
}
.app-sidebar-sub-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.6rem 1rem 0.4rem;
  font-size: 0.65rem; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-muted);
}
.app-sidebar-sub-edit {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); padding: 0.2rem; display: inline-flex;
  border-radius: 4px; transition: all 0.12s;
}
.app-sidebar-sub-edit:hover { color: var(--accent); background: var(--bg-card); }
/* "Subscriptions" header becomes a link to /discover (recovered the primary nav slot) */
.app-sidebar-sub-title-link {
  display: inline-flex; align-items: center; gap: 0.3rem;
  color: var(--text-muted); text-decoration: none;
  font: inherit; /* inherit the uppercase + weight from parent head */
  padding: 0.1rem 0; border-radius: 3px;
  transition: color 0.12s;
}
.app-sidebar-sub-title-link svg { opacity: 0; transition: opacity 0.12s, transform 0.12s; }
.app-sidebar-sub-title-link:hover { color: var(--accent); }
.app-sidebar-sub-title-link:hover svg { opacity: 1; transform: translateX(2px); }
.app-sidebar-sub-title-link.active { color: var(--accent); }
.app-sidebar-sub-title-link.active svg { opacity: 1; }

/* ===== Discovery promo card (sidebar) =====
   Always-visible card that promotes the feeds catalog. Uses a soft accent
   gradient + accent border so it pops against the rest of the sidebar
   without being loud. Goal: make adding feeds feel inviting, not optional.
   Replaces the previous collapsed <details> pattern. */
.app-sidebar-discovery {
  flex: 0 0 auto;
  margin: 0.4rem 0.6rem 0.6rem;
  padding: 0.55rem 0.6rem 0.55rem;
  background: linear-gradient(155deg,
    color-mix(in srgb, var(--accent) 10%, transparent) 0%,
    color-mix(in srgb, var(--accent) 3%, transparent) 60%,
    transparent 100%);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 10px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.app-sidebar-discovery:hover {
  border-color: color-mix(in srgb, var(--accent) 38%, transparent);
  box-shadow: 0 2px 12px color-mix(in srgb, var(--accent) 14%, transparent);
}

/* Header: compass icon + "Discover" + total-count badge on the right. */
.app-sidebar-discovery-head {
  display: flex; align-items: center; gap: 0.45rem;
  padding: 0.1rem 0.05rem 0.1rem;
  text-decoration: none; color: var(--text);
  font-weight: 600; font-size: 0.85rem;
  letter-spacing: 0.01em;
  transition: color 0.12s ease;
}
.app-sidebar-discovery-head:hover { color: var(--accent); }
.app-sidebar-discovery-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
  flex-shrink: 0;
}
.app-sidebar-discovery-title { flex: 1 1 auto; }
.app-sidebar-discovery-count {
  font-size: 0.68rem; font-weight: 700;
  padding: 0.12rem 0.42rem;
  background: var(--accent); color: var(--accent-contrast, #fff);
  border-radius: 999px;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

.app-sidebar-discovery-tagline {
  margin: 0.3rem 0 0.45rem;
  font-size: 0.7rem; color: var(--text-muted);
  line-height: 1.35;
}

/* Recommended rows — denser than subscriptions, category chip on row 2. */
.app-sidebar-discovery .app-sidebar-recommended {
  padding: 0; margin: 0 0 0.45rem; list-style: none;
}
.fs-feed-item--recommend {
  position: relative;
  padding: 0 !important; margin: 0 !important;
  border-radius: 6px;
  transition: background 0.12s ease;
}
.fs-feed-item--recommend:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.fs-feed-item--recommend .fs-feed-link {
  display: flex; align-items: center; gap: 0.45rem;
  padding: 0.32rem 30px 0.32rem 0.4rem;
  text-decoration: none; color: var(--text);
}
.fs-feed-item--recommend .fs-feed-favicon {
  width: 16px; height: 16px; flex-shrink: 0;
  border-radius: 3px;
}
.fs-feed-recommend-text {
  display: flex; flex-direction: column;
  min-width: 0; flex: 1 1 auto;
  line-height: 1.15;
}
.fs-feed-item--recommend .fs-feed-name {
  font-size: 0.78rem; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fs-feed-recommend-cat {
  font-size: 0.62rem; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.04em;
  margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Quick-add "+" — always visible (was hover-only before, so users
   couldn't tell it existed). Sits on the right; click adds without
   leaving the page. */
.fs-feed-recommend-add {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; padding: 0; line-height: 1;
  font-weight: 700; font-size: 1rem;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: none;
  border-radius: 999px; cursor: pointer;
  opacity: 0.95;
  transition: background 0.12s, transform 0.1s, opacity 0.12s;
}
.fs-feed-recommend-add:hover {
  background: var(--accent); color: var(--accent-contrast, #fff);
  transform: translateY(-50%) scale(1.08);
}
.fs-feed-recommend-add:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.fs-feed-recommend-add:disabled { opacity: 1; cursor: default; }

/* Bottom CTA — always visible. Solid accent button-style link to push
   users into the full catalog. The chevron and feed count are part of
   the affordance. */
.app-sidebar-discovery-cta {
  display: flex; align-items: center; justify-content: center;
  gap: 0.32rem;
  padding: 0.4rem 0.5rem;
  font-size: 0.72rem; font-weight: 600;
  text-decoration: none;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  border-radius: 6px;
  transition: background 0.12s, color 0.12s, transform 0.1s;
}
.app-sidebar-discovery-cta strong {
  font-weight: 700;
  margin: 0 1px;
}
.app-sidebar-discovery-cta svg {
  transition: transform 0.15s ease;
}
.app-sidebar-discovery-cta:hover {
  background: var(--accent);
  color: var(--accent-contrast, #fff);
  border-color: var(--accent);
}
.app-sidebar-discovery-cta:hover svg {
  transform: translateX(2px);
}

/* ===== Sidebar Primary nav — pill row with expanding active tab =====
   All 5 destinations render as icon-only pills. The active one grows
   wider to reveal its label in accent colour. Inspired by the iOS dock /
   modern segmented control patterns. */
.app-sidebar-nav--horizontal {
  display: flex !important;
  flex-direction: row !important;
  justify-content: space-around; align-items: center;
  gap: 0.2rem;
  padding: 0.35rem 0.4rem 0.55rem;
  /* No border-bottom — the adjacent .app-sidebar-sub owns the divider
     (border-top) so we don't double it up. */
}
.app-sidebar-nav--horizontal .app-nav-link {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.5rem;
  color: var(--text-muted); text-decoration: none;
  border-radius: 10px;
  transition: color 0.18s, background 0.18s;
}
/* Labels hidden entirely — the nav is a clean 5-icon row. Kept in the
   DOM for accessibility (aria/title/tooltip). */
.app-sidebar-nav--horizontal .app-nav-link span { display: none; }
.app-sidebar-nav--horizontal .app-nav-link:hover {
  color: var(--text); background: var(--bg-subtle);
}
.app-sidebar-nav--horizontal .app-nav-link.active {
  color: var(--accent); background: var(--accent-soft);
}
/* Brief uses a colored PNG logo — desaturate + reduce opacity when
   inactive so it blends with the other muted icons, full color only
   when active. */
.app-sidebar-nav--horizontal .app-nav-link img.app-nav-logo-img {
  filter: grayscale(1);
  opacity: 0.55;
  transition: filter 0.18s, opacity 0.18s;
}
.app-sidebar-nav--horizontal .app-nav-link:hover img.app-nav-logo-img {
  opacity: 0.85;
}
.app-sidebar-nav--horizontal .app-nav-link.active img.app-nav-logo-img {
  filter: none; opacity: 1;
}

/* Page title icons — small icon inline with the h1 so you can tell
   at a glance which page you're on. Matches the sidebar nav icons. */
.following-hero-title .page-title-icon,
.page-title .page-title-icon {
  display: inline-block; vertical-align: -4px;
  margin-right: 0.4rem; color: var(--accent); opacity: 0.9;
}

/* Brief hero toolbar — action pills live in the header actions slot
   and should flow as a wrapping row on narrow viewports. */
.bf-hero-toolbar {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.3rem; justify-content: flex-end;
}
.bf-hero-toolbar .lf-chip { font-size: 0.72rem; }
.bf-hero-toolbar .bf-more-wrap { position: relative; }

/* Generic utility used to replace inline style="display:none". */
.u-hidden { display: none !important; }

/* Favicon shown in live-feed row/card/story meta — hard-size it so
   broken/oversized raster favicons don't balloon the row height. */
.lf-meta-fav,
.lf-row-fav {
  width: 16px !important; height: 16px !important;
  border-radius: 3px; flex-shrink: 0;
  object-fit: contain;
  background: var(--bg-subtle, transparent);
}
.lf-row-fav { margin-top: 2px; }
/* Compact row: align favicon with the title baseline. */
.lf-row { align-items: flex-start; }

/* Card view — favicon inline with the title. */
.lf-card-title-row {
  display: flex; align-items: flex-start; gap: 0.4rem;
  margin-bottom: 0.15rem;
}
.lf-card-title-row .lf-meta-fav { margin-top: 3px; }

/* Brief mobile-only search: shown on <=768px, hidden on desktop
   since the hero toolbar already fits without being cramped. */
.bf-mobile-search { display: none; }
@media (max-width: 768px) {
  .bf-mobile-search { display: flex; margin-bottom: 0.5rem; }
  /* In-page Brief hero is itself hidden on mobile (the title + actions
     are promoted to the top bar). Keep the icon scoped-hide so it
     doesn't render twice if the hero ever surfaces again. The cloned
     copy inside #app-mobile-title is unaffected. */
  .following-hero-title .bf-title-icon { display: none; }
}
.bf-title-icon { vertical-align: -4px; margin-right: 0.4rem; border-radius: 4px; }
/* In the Flutter app the brief search lives in the native top bar
   (rendered by main.dart), so hide the in-page mobile search here
   to avoid showing it twice. The desktop hero (Brief title + Share /
   Audio / Send / Brief actions) stays visible — it's exactly the
   layout the user wants on Flutter too. */
body.is-flutter .bf-mobile-search { display: none !important; }

/* Flutter WebView has its own native AppBar (hamburger + page title + unread
   badge), so the web `.app-mobile-bar` is redundant and would leave a 3.5rem
   empty strip above the content (gray gap reported as a UX bug on Apr 29).
   Both the bar itself and the padding-top compensation on `.app-main-wrap`
   need to go when running inside the app. */
body.is-flutter .app-mobile-bar { display: none !important; }
body.is-flutter .app-main-wrap { padding-top: 0 !important; }

/* The Flutter top bar already shows the FeedLynx logo + name on the
   Brief tab, so the in-page brief hero header doesn't need its own
   logo. Hiding it also fixes a wrap/overlap bug where the icon was
   pushing the "Brief" title onto a second line. Web browsers (mobile
   + desktop) keep the logo since they don't have the Flutter app bar. */
body.is-flutter .following-hero-title .page-title-icon { display: none !important; }

/* bf-dropdown sits above the animated news-ticker beneath the hero. */
.bf-dropdown { z-index: 30; }

/* Generate-briefing button: AI gradient; locked variant used on
   welcome-step-2 until the user fetches articles. */
.btn-ai {
  background: linear-gradient(135deg, #6366F1, #0EA5E9);
  border: none;
  color: #fff;
}
.btn-ai--locked {
  background: var(--bg-subtle);
  color: var(--text-muted);
  cursor: not-allowed;
}
.btn-ai--locked:hover { filter: none; }

/* Sources pills inherit .sources styles from elsewhere; reset any
   transparent-on-white regressions inside the Brief hero card. */
.np-hero .sources a {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}

/* WCAG tap-target — bump .lf-act on mobile to 36px minimum. */
@media (max-width: 768px) {
  .np-actions .lf-act,
  .np-hero-actions .lf-act {
    min-width: 36px;
    min-height: 36px;
    padding: 0.45rem;
  }
}
.app-sidebar-nav--horizontal .app-nav-link svg,
.app-sidebar-nav--horizontal .app-nav-link img {
  width: 18px; height: 18px; flex-shrink: 0;
}
.app-sidebar-nav--horizontal .app-nav-link--center img { border-radius: 4px; }

/* Follow auto-feeds surface as a "Following" synthetic category in the
   subscription tree. Star icon distinguishes them from real RSS
   subscriptions and hints they're AI-curated. Local experiment. */
.fs-folder-icon--star { color: #F5A623; }
.fs-feed-favicon--follow {
  color: #F5A623;
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
}
.fs-feed-item--follow .fs-feed-name {
  color: color-mix(in srgb, var(--text) 85%, #F5A623 15%);
}
/* /discover feed card flash when arrived via ?feed=<url> from the
   sidebar Recommended list — draws the user's eye to the right card. */
.disc-feed-card--focused {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  animation: disc-feed-card-pulse 1.2s ease-out 1;
}
@keyframes disc-feed-card-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 40%, transparent); }
  70%  { box-shadow: 0 0 0 14px color-mix(in srgb, var(--accent) 0%, transparent); }
  100% { box-shadow: none; }
}
/* Single-feed pin banner — shown on /discover?feed=URL when the user
   tapped a sidebar recommendation. Hides the rest of the catalog and
   surfaces a one-click "Show all feeds" escape. */
.disc-pin-banner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; flex-wrap: wrap;
  margin: 0.75rem 0 1rem;
  padding: 0.65rem 0.85rem;
  background: var(--accent-light);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
  border-radius: 10px;
  color: var(--text);
  font-size: 0.92rem;
}
.disc-pin-banner strong { color: var(--accent); font-weight: 600; }
.disc-pin-clear {
  display: inline-flex; align-items: center; gap: 0.4rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.82rem; font-weight: 500;
  padding: 0.32rem 0.7rem;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.disc-pin-clear:hover {
  background: var(--bg);
  border-color: var(--accent);
  color: var(--accent);
}
.disc-pin-clear span { font-size: 1rem; line-height: 1; opacity: 0.7; }
.app-sidebar-tree { padding: 0 0.5rem; }
.app-sidebar-tree .fs-folder { margin: 0; }
.app-sidebar-tree .fs-folder-flat { /* no <details> wrapper; simple row */ }
.app-sidebar-tree .fs-folder-head {
  padding: 0.15rem 0.35rem; font-size: 0.82rem;
  display: flex; align-items: center; gap: 0.15rem;
  list-style: none; border-radius: 5px; position: relative;
}
.app-sidebar-tree .fs-folder-head::-webkit-details-marker { display: none; }
/* Chevron toggle: its own hover + click target */
.app-sidebar-tree .fs-folder-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 22px; flex-shrink: 0;
  color: var(--text-muted); cursor: pointer;
  border-radius: 4px;
}
.app-sidebar-tree .fs-folder-toggle:hover { background: var(--bg-subtle); color: var(--text); }
.app-sidebar-tree .fs-folder-toggle-placeholder {
  display: inline-block; width: 18px; flex-shrink: 0;
}
.app-sidebar-tree .fs-folder-chevron {
  flex-shrink: 0; transition: transform 0.15s;
  color: var(--text-muted);
}
.app-sidebar-tree details[open] .fs-folder-chevron { transform: rotate(0deg); }
.app-sidebar-tree details:not([open]) .fs-folder-chevron { transform: rotate(-90deg); }
/* Folder link: the clickable name that filters the live feed */
.app-sidebar-tree .fs-folder-link {
  display: flex; align-items: center; gap: 0.45rem;
  flex: 1 1 auto; min-width: 0;
  padding: 0.3rem 0.4rem; border-radius: 5px;
  color: var(--text); text-decoration: none;
  transition: background 0.1s;
}
.app-sidebar-tree .fs-folder-link:hover { background: var(--bg-card); }
.app-sidebar-tree .fs-folder-link.active {
  background: var(--accent-soft); color: var(--accent);
}
.app-sidebar-tree .fs-folder-link.active .fs-folder-name,
.app-sidebar-tree .fs-folder-link.active .fs-folder-icon { color: var(--accent); }
.app-sidebar-tree .fs-folder-icon { color: var(--text-muted); flex-shrink: 0; }
.app-sidebar-tree .fs-folder-name {
  flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-weight: 600;
}
.app-sidebar-tree .fs-folder-count {
  font-size: 0.7rem; color: var(--text-muted);
  flex-shrink: 0; padding: 0.05rem 0.4rem; margin-left: auto;
  background: var(--bg); border-radius: 9999px;
}
.app-sidebar-tree .fs-folder-link.active .fs-folder-count {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--accent);
}
.app-sidebar-tree .fs-folder-kebab {
  flex-shrink: 0; background: transparent; border: none; cursor: pointer;
  padding: 0.2rem 0.25rem; margin: 0 -0.15rem 0 0;
  border-radius: 4px; color: var(--text-muted);
  opacity: 0; transition: opacity 0.12s, background 0.12s, color 0.12s;
  display: inline-flex; align-items: center; justify-content: center;
}
.app-sidebar-tree .fs-folder-head:hover .fs-folder-kebab,
.app-sidebar-tree .fs-folder-kebab:focus-visible { opacity: 1; }
.app-sidebar-tree .fs-folder-kebab:hover { background: var(--bg-subtle); color: var(--text); }
.app-sidebar-tree .fs-feed-list {
  list-style: none; margin: 0; padding: 0 0 0 0.9rem;
}
.app-sidebar-tree .fs-feed-item {
  display: flex; align-items: center; gap: 0.1rem;
  padding: 0; margin: 1px 0; cursor: default;
  position: relative;
}
.app-sidebar-tree .fs-feed-item:hover { background: transparent; }
.app-sidebar-tree .fs-feed-kebab {
  flex-shrink: 0; background: transparent; border: none; cursor: pointer;
  padding: 0.25rem 0.3rem; border-radius: 4px;
  color: var(--text-muted); opacity: 0;
  transition: opacity 0.12s, background 0.12s, color 0.12s;
  display: inline-flex; align-items: center; justify-content: center;
}
.app-sidebar-tree .fs-feed-item:hover .fs-feed-kebab,
.app-sidebar-tree .fs-feed-item:focus-within .fs-feed-kebab,
.app-sidebar-tree .fs-feed-kebab:focus-visible { opacity: 1; }
.app-sidebar-tree .fs-feed-kebab:hover { background: var(--bg-subtle); color: var(--text); }
/* Touch devices: always show kebabs (no :hover on tap devices). */
@media (hover: none), (max-width: 767px) {
  .app-sidebar-tree .fs-feed-kebab,
  .app-sidebar-tree .fs-folder-kebab { opacity: 1; }
}
/* Empty-folder placeholder message */
.app-sidebar-tree .fs-feed-list-empty {
  font-size: 0.72rem; color: var(--text-muted);
  padding: 0.3rem 0.5rem 0.4rem; font-style: italic;
}
.fs-feed-link {
  display: flex; align-items: center; gap: 0.45rem;
  padding: 0.32rem 0.5rem;
  border-radius: 5px;
  font-size: 0.82rem; color: var(--text); text-decoration: none;
  min-width: 0; flex: 1 1 auto; transition: background 0.1s;
}
.fs-feed-link:hover { background: var(--bg-card); }
.fs-feed-link.active {
  background: var(--accent-soft); color: var(--accent); font-weight: 600;
}
.fs-feed-link.active .fs-feed-name { color: var(--accent); }
.fs-feed-link .fs-feed-favicon {
  width: 14px; height: 14px; flex-shrink: 0;
  border-radius: 3px; background: var(--bg);
}
.fs-feed-link .fs-feed-name {
  flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fs-feed-unread {
  font-size: 0.65rem; font-weight: 700; color: var(--accent);
  background: var(--accent-soft);
  padding: 0.08rem 0.4rem; border-radius: 9999px;
  min-width: 1.2rem; text-align: center; flex-shrink: 0;
}

.app-sidebar-spacer { display: none; }
.app-sidebar-foot-nav {
  border-top: 1px solid var(--border);
  padding: 0.5rem 0.5rem 0.25rem;
  flex-shrink: 0;
  background: var(--bg-subtle);
}
.app-sidebar-user { flex-shrink: 0; }

.app-sidebar-user {
  padding: 0.75rem 0.85rem;
  border-top: 1px solid var(--border);
  display: flex; align-items: center; gap: 0.5rem;
  /* Tier-modulated background — the variables get overridden by the
     tier modifier below. Default = no tint (Free). */
  background: transparent;
  position: relative;
  transition: background 0.25s ease;
}
.app-sidebar-user-info {
  display: flex; align-items: center; gap: 0.55rem;
  flex: 1; min-width: 0;
}

/* Subtle tier wash + coloured top accent line on the sidebar footer.
   Lower-alpha than the brand chip — the footer should breathe the
   tier, not shout it. */
.app-sidebar-user--bottom-pro {
  background: linear-gradient(180deg,
    color-mix(in srgb, #6366F1 4%, transparent) 0%,
    color-mix(in srgb, #3B82F6 7%, transparent) 100%);
  border-top: 2px solid transparent;
  border-image: linear-gradient(90deg, #6366F1, #3B82F6) 1;
}
[data-theme="dark"] .app-sidebar-user--bottom-pro {
  background: linear-gradient(180deg,
    color-mix(in srgb, #6366F1 10%, transparent) 0%,
    color-mix(in srgb, #3B82F6 14%, transparent) 100%);
}
.app-sidebar-user--bottom-enterprise {
  background: linear-gradient(180deg,
    color-mix(in srgb, #F59E0B 5%, transparent) 0%,
    color-mix(in srgb, #D97706 9%, transparent) 100%);
  border-top: 2px solid transparent;
  border-image: linear-gradient(90deg, #F59E0B, #D97706) 1;
}
[data-theme="dark"] .app-sidebar-user--bottom-enterprise {
  background: linear-gradient(180deg,
    color-mix(in srgb, #F59E0B 12%, transparent) 0%,
    color-mix(in srgb, #D97706 17%, transparent) 100%);
}

/* === Mini avatar === Small clean initial bubble. Kept neutral so the
   aurora bg is the tier signal — no halo, no gradient on the bubble. */
.app-sidebar-avatar-mini {
  width: 26px; height: 26px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.74rem;
  letter-spacing: 0.02em;
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
[data-theme="dark"] .app-sidebar-avatar-mini {
  background: color-mix(in srgb, var(--bg-card) 70%, transparent);
}

/* Rotating tier-coloured ring around the mini avatar — conic gradient
   masked into a thin donut so it sits cleanly outside the bubble. */
.app-sidebar-user--bottom-pro .app-sidebar-avatar-mini,
.app-sidebar-user--bottom-enterprise .app-sidebar-avatar-mini {
  position: relative;
  overflow: visible;
  border-color: transparent;
}
.app-sidebar-user--bottom-pro .app-sidebar-avatar-mini::before,
.app-sidebar-user--bottom-enterprise .app-sidebar-avatar-mini::before {
  content: ""; position: absolute; inset: -3px;
  border-radius: 50%;
  pointer-events: none;
  -webkit-mask: radial-gradient(circle closest-side, transparent 80%, black 84%);
          mask: radial-gradient(circle closest-side, transparent 80%, black 84%);
  animation: tier-halo-spin 6s linear infinite;
  z-index: -1;
}
.app-sidebar-user--bottom-pro .app-sidebar-avatar-mini::before {
  background: conic-gradient(from 0deg,
    #6366F1 0%, #3B82F6 25%, #06B6D4 50%, #3B82F6 75%, #6366F1 100%);
}
.app-sidebar-user--bottom-enterprise .app-sidebar-avatar-mini::before {
  background: conic-gradient(from 0deg,
    #FBBF24 0%, #F59E0B 25%, #D97706 50%, #B45309 75%, #FBBF24 100%);
}
@keyframes tier-halo-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .app-sidebar-user--bottom-pro .app-sidebar-avatar-mini::before,
  .app-sidebar-user--bottom-enterprise .app-sidebar-avatar-mini::before { animation: none; }
}


/* === Danger zone (account closure) ===
   Last section on /settings — red accent so it can't be confused with
   a regular form. Inputs stay neutral; the section head + submit
   button carry the warning weight. */
.set-section--danger {
  border-color: color-mix(in srgb, #dc2626 35%, var(--border));
}
.set-section-head--danger {
  color: #b91c1c;
  background: linear-gradient(180deg,
    color-mix(in srgb, #dc2626 12%, var(--bg-card)),
    var(--bg-card) 100%) !important;
}
.set-section-head--danger svg { color: #b91c1c; }
[data-theme="dark"] .set-section-head--danger { color: #fca5a5; }
[data-theme="dark"] .set-section-head--danger svg { color: #fca5a5; }
.set-form--danger input[name="confirm_text"] {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}
.set-actions--danger { display: flex; justify-content: flex-end; }
.set-form--danger .btn-danger:hover { filter: brightness(0.92); }
.set-danger-reason {
  width: 100%;
  min-height: 76px;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--text);
  font-family: inherit;
  font-size: 0.85rem;
  line-height: 1.45;
  resize: vertical;
}
.set-danger-reason:focus {
  outline: none;
  border-color: color-mix(in srgb, #dc2626 45%, var(--border));
  box-shadow: 0 0 0 3px color-mix(in srgb, #dc2626 12%, transparent);
}
.set-label-hint { font-weight: 400; color: var(--text-muted); }
.set-label-hint--block { display: block; margin: 0.25rem 0 0.6rem; font-size: 0.82rem; }
.set-label-block { font-size: 0.88rem; font-weight: 600; color: var(--text); margin: 0 0 0.15rem; }

/* Churn-survey radio list — single-column on mobile, two on desktop. */
.set-churn-reasons {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem 1rem;
}
.set-churn-reasons li { margin: 0; }
.set-churn-reasons label {
  display: flex; align-items: flex-start; gap: 0.55rem;
  font-size: 0.85rem; line-height: 1.4; color: var(--text);
  padding: 0.45rem 0.6rem; border-radius: 8px;
  cursor: pointer; transition: background 0.12s;
}
.set-churn-reasons label:hover { background: var(--bg-subtle); }
.set-churn-reasons input[type="radio"] {
  margin-top: 0.18rem; flex-shrink: 0;
  accent-color: #dc2626;
}
@media (max-width: 640px) {
  .set-churn-reasons { grid-template-columns: 1fr; }
}

/* Live char counter shown under churn-survey textareas. */
.set-char-count { font-size: 0.72rem; color: var(--text-muted);
  margin: 0.25rem 0 0; text-align: right; font-variant-numeric: tabular-nums; }
.app-sidebar-user-text { min-width: 0; line-height: 1.2; }
.app-sidebar-user-name {
  font-size: 0.82rem; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.app-sidebar-user-actions {
  display: flex; align-items: center; gap: 0.25rem; flex-shrink: 0;
  position: relative; /* anchor for kebab popover */
}
.app-icon-btn {
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent;
  border-radius: 6px; color: var(--text-muted); cursor: pointer; transition: all 0.12s;
  text-decoration: none;
}
.app-icon-btn:hover { background: var(--bg-card); color: var(--text); border-color: var(--border); }
.app-icon-btn.active { background: var(--accent-soft); color: var(--accent); border-color: transparent; }

/* Kebab-collapsed bottom-left action icons.
   When `is-collapsed` (= total icons > 3), the secondary group is hidden
   inline and rendered as a popover above the kebab when toggled open.
   Theme stays inline because it's the highest-frequency action. */
.app-sidebar-user-actions.is-collapsed .app-sidebar-secondary-icons {
  display: none;
  position: absolute;
  bottom: calc(100% + 0.4rem); right: 0;
  flex-direction: row; gap: 0.25rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.35rem;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
  z-index: 50;
}
.app-sidebar-user-actions.is-collapsed.is-open .app-sidebar-secondary-icons {
  display: inline-flex;
}
.app-sidebar-kebab[aria-expanded="true"] {
  background: var(--bg-card); color: var(--text); border-color: var(--border);
}

/* Mobile drawer */
.app-sidebar-backdrop {
  display: none; position: fixed; inset: 0; z-index: 90;
  background: rgba(0,0,0,0.35);
}
.app-sidebar-backdrop.open { display: block; }

/* ===== Mobile bottom bar — 5 primary destinations ===== */
.bottom-bar {
  display: none; /* shown only on mobile/tablet via media query below */
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: var(--bg-card); border-top: 1px solid var(--border);
  /* Force the bar to the variable height so the drawer's `bottom` anchor
     matches exactly. box-sizing: border-box keeps padding/border inside. */
  height: calc(var(--app-bottombar-h) + env(safe-area-inset-bottom, 0px));
  box-sizing: border-box;
  padding: 0.25rem 0;
  padding-bottom: calc(0.25rem + env(safe-area-inset-bottom, 0px));
  justify-content: space-around; align-items: stretch;
}
.bottom-bar-item {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 0.15rem;
  flex: 1; padding: 0.35rem 0;
  color: var(--text-muted) !important;
  text-decoration: none !important;
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.01em;
  transition: color 0.15s; -webkit-tap-highlight-color: transparent;
}
.bottom-bar-item svg { width: 22px; height: 22px; stroke-width: 1.8; }
.bottom-bar-item:hover { color: var(--text) !important; }
.bottom-bar-item.active { color: var(--accent) !important; font-weight: 600; }
.bottom-bar-item.active svg { stroke: var(--accent); }
/* Brief (center) entry — logo replaces the SVG icon */
.bottom-bar-center { position: relative; }
.bottom-bar-logo {
  width: 26px; height: 26px; object-fit: contain;
  filter: grayscale(1) brightness(0.6) opacity(0.55);
  transition: filter 0.15s;
}
.bottom-bar-center.active .bottom-bar-logo { filter: none; }
[data-theme="dark"] .bottom-bar-logo { filter: grayscale(1) brightness(2) opacity(0.5); }
[data-theme="dark"] .bottom-bar-center.active .bottom-bar-logo { filter: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .bottom-bar-logo { filter: grayscale(1) brightness(2) opacity(0.5); }
  :root:not([data-theme="light"]) .bottom-bar-center.active .bottom-bar-logo { filter: none; }
}
/* Show on mobile/tablet — same breakpoint as the drawer sidebar so on
   desktop we have the left sidebar and on mobile we have the bottom bar. */
@media (max-width: 900px) {
  .bottom-bar { display: flex; }
  body { padding-bottom: calc(var(--app-bottombar-h) + env(safe-area-inset-bottom, 0px)); }
}

@media (max-width: 900px) {
  .app-shell { grid-template-columns: 1fr; }
  /* Topbar is now position:fixed (see base rule) so the main content needs
     padding-top equal to the topbar height — otherwise the first chunk of
     page content slides under it. */
  .app-main-wrap { padding-top: var(--app-topbar-h); }
  /* Drawer sits BETWEEN the mobile top bar and the bottom bar — both stay
     visible while the drawer is open (Flutter-app parity). Anchored via
     top+bottom, never height:100vh — mobile 100vh includes the URL bar
     and would let the panel overflow under the bottom nav when it
     collapses on scroll. */
  .app-sidebar {
    position: fixed; left: 0;
    top: var(--app-topbar-h);
    bottom: calc(var(--app-bottombar-h) + env(safe-area-inset-bottom, 0px));
    width: 280px; max-width: 85vw;
    /* Clear desktop rule's `height: 100vh; max-height: 100vh; align-self: start`
       — on mobile the drawer is fixed-positioned and must FILL the gap
       between top and bottom anchors, not shrink-to-fit the flex children.
       align-self:start on a fixed grid item triggers shrink-to-fit in
       Chromium, hence the explicit override. */
    height: auto; max-height: none; align-self: stretch;
    transform: translateX(-100%); transition: transform 0.25s ease;
    z-index: 40; /* below topbar (50) and bottom-bar (60) */
  }
  .app-sidebar.open { transform: translateX(0); box-shadow: 4px 0 30px rgba(0,0,0,0.2); }
  .app-sidebar-backdrop {
    /* Dim only the area between top/bottom bars, same vertical extent as
       the drawer itself, so the bars remain clearly interactive. */
    top: var(--app-topbar-h);
    bottom: calc(var(--app-bottombar-h) + env(safe-area-inset-bottom, 0px));
    inset: unset; left: 0; right: 0;
    position: fixed;
    z-index: 30;
  }
  .app-mobile-bar { display: flex; }
  .app-main { padding: 1rem; }

  /* On mobile we promote the page H1 + action toolbar into the top bar
     (via JS) and drop the subtitle. The whole .following-hero is hidden
     so the page content starts directly with the search bar (or the
     chat bar on /dashboard), reclaiming vertical space. */
  .following-hero { display: none; }

  /* Primary nav is redundant with the bottom bar — hide it. The FeedLynx
     brand in the drawer stays (mobile web needs some identity inside the
     drawer when opened); the Flutter app hides it separately in its CSS
     injection since its native top bar already shows branding. */
  /* `!important` here mirrors the base rule's `display: flex !important` —
     without it the base wins and the horizontal Primary nav (Live, Following,
     Brief, Bookmarks, Discover) duplicates the mobile bottom-bar. */
  .app-sidebar > .app-sidebar-nav[aria-label="Primary"] { display: none !important; }
  .app-sidebar-sub { border-top: none; margin-top: 0; padding-top: 0.25rem; }

  /* The sidebar's overflow:hidden is already declared on the base rule —
     don't redeclare. Subscriptions / discovery / spacer all live inside
     .app-sidebar-body which is the single scrollable area. Header and
     footer (brand + user-card) are flex:0 0 auto and pinned at the
     edges; they never scroll. */
  .app-sidebar-foot-nav, .app-sidebar-user { flex: 0 0 auto; background: transparent; }
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: none; }
/* Override Tailwind text-xs/text-sm to be slightly larger for readability */
.text-xs { font-size: 0.8rem !important; }
.text-sm { font-size: 0.9rem !important; }
::selection { background: var(--accent-soft); }

/* ==================== FORMS ==================== */
input, select, textarea {
  background: var(--bg-card); border: 1px solid var(--border); color: var(--text);
  border-radius: 8px; padding: 0.6rem 0.9rem !important; font-size: 0.875rem;
  width: 100%; transition: border-color 0.2s; font-family: inherit;
}
input[type="checkbox"], input[type="radio"] { width: auto; padding: 0 !important; accent-color: var(--accent); }
input:focus, select:focus, textarea:focus {
  border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-soft);
}
input[type="range"] { border: none; padding: 0 !important; background: none; box-shadow: none; accent-color: var(--accent); }
input[type="file"] { border: none; padding: 0.25rem 0 !important; background: none; }
label { font-size: 0.875rem; font-weight: 500; display: block; margin-bottom: 0.25rem; }
code { font-size: 0.8rem; background: var(--bg-subtle); padding: 0.15rem 0.4rem; border-radius: 4px; }

/* ==================== BUTTONS ==================== */
.btn {
  display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 500;
  border-radius: 8px; cursor: pointer; transition: all 0.2s; border: none;
  font-size: 0.875rem; padding: 0.5rem 1rem; font-family: inherit;
  text-decoration: none !important; white-space: nowrap; color: var(--text);
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); }
.btn-outline { background: transparent; border: 1px solid var(--border); }
.btn-outline:hover:not(:disabled) { background: var(--bg-subtle); border-color: var(--text-muted); }
.btn-ghost { background: transparent; color: var(--text-muted); padding: 0.4rem 0.6rem; }
.btn-ghost:hover { color: var(--text); background: var(--bg-subtle); }
.btn-danger { background: var(--error); color: #fff; }
.btn-success { background: #15803d; color: #fff; border: 1px solid #15803d; }
.btn-success:hover:not(:disabled) { background: #166534; border-color: #166534; }
[data-theme="dark"] .btn-success { background: #16a34a; border-color: #16a34a; }
[data-theme="dark"] .btn-success:hover:not(:disabled) { background: #15803d; border-color: #15803d; }
.btn-sm { font-size: 0.85rem; padding: 0.35rem 0.75rem; }
.btn-xs { font-size: 0.85rem; padding: 0.25rem 0.55rem; }
.btn-lg { font-size: 1rem; padding: 0.65rem 1.5rem; }

/* ==================== BADGES ==================== */
.badge {
  display: inline-block; font-size: 0.8rem; font-weight: 600; padding: 0.15rem 0.5rem;
  border-radius: 9999px; background: var(--bg-subtle); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.02em; white-space: nowrap;
}
.badge-success { background: var(--success-light); color: var(--success); }
.badge-error { background: var(--error-light); color: var(--error); }
.badge-score { background: var(--accent-light); color: var(--accent); }
.badge-admin { background: var(--accent-light); color: var(--accent); }
.badge-cybersecurity { background: var(--badge-cybersecurity-bg); color: var(--badge-cybersecurity-fg); }
.badge-tech, .badge-tech_news { background: var(--badge-tech-bg); color: var(--badge-tech-fg); }
.badge-crypto, .badge-crypto_bitcoin { background: var(--badge-crypto-bg); color: var(--badge-crypto-fg); }
.badge-ai, .badge-artificial_intelligence { background: var(--badge-ai-bg); color: var(--badge-ai-fg); }
.badge-privacy, .badge-privacy_rights { background: var(--badge-privacy-bg); color: var(--badge-privacy-fg); }
.badge-programming { background: var(--badge-programming-bg); color: var(--badge-programming-fg); }
.badge-devops, .badge-devops_cloud { background: var(--badge-devops-bg); color: var(--badge-devops-fg); }
.badge-linux, .badge-linux_opensource { background: var(--badge-linux-bg); color: var(--badge-linux-fg); }
.badge-finance { background: var(--badge-finance-bg); color: var(--badge-finance-fg); }

/* ==================== ALERTS ==================== */
.alert {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 0.75rem 1rem; border-radius: 10px; font-size: 0.875rem;
  border: 1px solid var(--border); background: var(--bg-card);
}
.alert-success { background: var(--success-light); border-color: var(--success); color: var(--success); }
.alert-error { background: var(--error-light); border-color: var(--error); color: var(--error); }
.alert-warning { background: var(--warning-light); border-color: var(--warning); color: var(--warning-text); }
.alert-info { background: var(--accent-light); border-color: var(--accent); color: var(--accent); }
.alert-close { background: none; border: none; font-size: 1.2rem; cursor: pointer; color: inherit; }

/* Flash messages (fixed overlay, no layout shift) */
.fl-flash-container {
  position: fixed; top: 3.75rem; left: 50%; transform: translateX(-50%);
  z-index: 1000; width: 100%; max-width: 480px; padding: 0 1rem;
  transition: opacity 0.4s; pointer-events: none;
}
.fl-flash-container.fl-flash-hide { opacity: 0; }
.fl-flash {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.6rem 1rem; border-radius: 10px; font-size: 0.8rem; font-weight: 500;
  margin-bottom: 0.35rem; pointer-events: auto;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  background: var(--bg-card); border: 1px solid var(--border); color: var(--text);
}
.fl-flash button {
  background: none; border: none; font-size: 1.1rem; cursor: pointer;
  color: inherit; opacity: 0.5; padding: 0 0.2rem; line-height: 1;
}
.fl-flash button:hover { opacity: 1; }
.fl-flash-success { background: var(--success-light); border-color: var(--success); color: var(--success); }
.fl-flash-error { background: var(--error-light); border-color: var(--error); color: var(--error); }
.fl-flash-warning { background: var(--warning-light); border-color: var(--warning); color: var(--warning-text); }
.fl-flash-info { background: var(--accent-light); border-color: var(--accent); color: var(--accent); }

/* ==================== TABLES ==================== */
.table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.table th { text-align: left; padding: 0.6rem 0.75rem; border-bottom: 2px solid var(--border); font-weight: 600; font-size: 0.82rem; text-transform: uppercase; color: var(--text-muted); letter-spacing: 0.03em; }
.table td { padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--border-light); vertical-align: middle; }
.table tr:hover td { background: var(--bg-subtle); }

/* ==================== TEXT & UTILITIES ==================== */
.text-muted { color: var(--text-muted) !important; }
.text-success { color: var(--success) !important; }
.text-error { color: var(--error) !important; }
.dot { display: inline-block; width: 4px; height: 4px; border-radius: 50%; background: var(--text-muted); vertical-align: middle; margin: 0 0.4rem; }
.collapsed { display: none !important; }
.url-cell { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; }
@keyframes spin { to { transform: rotate(360deg); } }
.spin { animation: spin 1s linear infinite; }

/* ==================== NAVIGATION ==================== */
.nav { background: var(--bg-card); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 50; }
.nav-link { display: block; padding: 0.5rem 0.75rem; border-radius: 8px; font-size: 0.9rem; font-weight: 500; color: var(--text) !important; text-decoration: none !important; }
.nav-link:hover { background: var(--bg-subtle); }
.nav-link.active { color: var(--accent) !important; background: var(--accent-soft); font-weight: 600; }
.theme-toggle { background: none; border: 1px solid var(--border); border-radius: 6px; padding: 0.3rem; cursor: pointer; color: var(--text-muted); display: flex; align-items: center; }
.theme-toggle:hover { color: var(--text); border-color: var(--text-muted); }

/* Desktop horizontal nav menu */
.nav-menu-desktop {
  display: none;
}
.nav-mobile-settings {
  display: flex;
  align-items: center;
  color: var(--text-muted);
  padding: 0.25rem;
  border-radius: 8px;
  text-decoration: none !important;
}
.nav-mobile-settings:hover { color: var(--text); background: var(--bg-subtle); }
@media (min-width: 1024px) {
  .nav-menu-desktop {
    display: flex !important;
    flex-direction: row;
    align-items: center;
    gap: 0.25rem;
  }
  .nav-menu-desktop .nav-bottom {
    margin-left: 0.75rem;
    padding-left: 0.75rem;
    border-left: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  .nav-mobile-settings { display: none !important; }
  .nav-tier-mobile { display: none !important; }
}

/* Bottom-bar styles live in the canonical block above (search "===== Mobile
   bottom bar"). The duplicate definition that used to live here re-declared
   `.bottom-bar { display: none }` AFTER the @media (max-width: 900px) show
   rule, so on mobile the bar was hidden by source-order specificity. Removed. */

/* ==================== BRIEFING ==================== */
.briefing-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
  padding: 1.25rem; border-left: 3px solid var(--text-muted);
}
.briefing-card[data-category="cybersecurity"] { border-left-color: var(--cat-cybersecurity); }
.briefing-card[data-category="tech"], .briefing-card[data-category="tech_news"] { border-left-color: var(--cat-tech); }
.briefing-card[data-category="crypto"], .briefing-card[data-category="crypto_bitcoin"] { border-left-color: var(--cat-crypto); }
.briefing-card[data-category="ai"], .briefing-card[data-category="artificial_intelligence"] { border-left-color: var(--cat-ai); }
.briefing-card[data-category="privacy"], .briefing-card[data-category="privacy_rights"] { border-left-color: var(--cat-privacy); }
.briefing-card[data-category="programming"] { border-left-color: var(--cat-programming); }
.briefing-card[data-category="devops"], .briefing-card[data-category="devops_cloud"] { border-left-color: var(--cat-devops); }
.briefing-card[data-category="linux"], .briefing-card[data-category="linux_opensource"] { border-left-color: var(--cat-linux); }
.briefing-card[data-category="finance"] { border-left-color: var(--cat-finance); }
.sources { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.75rem; }
.sources a { font-size: 0.82rem; color: var(--accent) !important; background: var(--accent-light); padding: 0.2rem 0.6rem; border-radius: 6px; text-decoration: none !important; display: inline-flex; align-items: center; gap: 0.25rem; }
.sources a::after { content: ''; display: inline-block; width: 10px; height: 10px; opacity: 0.5; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cline x1='10' y1='14' x2='21' y2='3'/%3E%3C/svg%3E") no-repeat center; }
.sources a:hover { background: var(--accent-soft); }
.np-src-favicon {
  width: 14px; height: 14px;
  flex-shrink: 0;
  border-radius: 3px;
  object-fit: contain;
  background: #fff;
  /* If DuckDuckGo returns 404 for a host, the inline onerror="this.remove()"
     on the <img> drops the element from the DOM — no broken-image glyph,
     no layout shift beyond the 14px gap collapsing. */
}
.story-actions { display: inline-flex; align-items: center; gap: 0.2rem; margin-left: 0.25rem; }
.story-action-btn {
  background: none; border: 1px solid var(--border); border-radius: 6px;
  padding: 0.2rem 0.35rem; cursor: pointer; color: var(--text-muted);
  display: inline-flex; align-items: center; justify-content: center;
  transition: all 0.15s; line-height: 1;
}
.story-action-btn:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.story-action-btn.active { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.story-action-btn.active svg { fill: currentColor; }
.story-action-btn.active-down { border-color: var(--error); color: var(--error); background: rgba(239,68,68,0.08); }
.story-action-btn.active-down svg { fill: currentColor; }

/* ==================== BRIEFING (redesigned) ==================== */
.bf-container { max-width: 100%; }
.bf-header { margin: 0.75rem 0 1rem; padding-bottom: 0.75rem; border-bottom: 1px solid var(--border); }
.bf-edition-date { font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent); margin-bottom: 0.15rem; }
.bf-edition-stats { font-size: 0.78rem; color: var(--text-muted); }
.bf-edition-intro { font-size: 0.88rem; color: var(--text-secondary); line-height: 1.55; margin: 0.5rem 0 0; font-style: italic; }
.bf-section { margin-bottom: 1rem; }

/* More actions dropdown */
.bf-more-wrap { position: relative; }
.bf-dropdown { display: none; position: absolute; right: 0; top: calc(100% + 4px);
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
  padding: 0.35rem; min-width: 180px; box-shadow: 0 4px 16px rgba(0,0,0,0.12); z-index: 40; }
.bf-dropdown.visible { display: block; }
.bf-dropdown button, .bf-dropdown a { display: flex; align-items: center; gap: 0.5rem; width: 100%;
  padding: 0.5rem 0.75rem; font-size: 0.82rem; color: var(--text); border: none; background: none;
  cursor: pointer; border-radius: 6px; text-decoration: none; }
.bf-dropdown button:hover, .bf-dropdown a:hover { background: var(--bg-subtle); }

/* Audio player */
.bf-audio-card { display: flex; align-items: center; gap: 0.75rem; padding: 0.6rem 1rem;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 6%, var(--bg-card)), var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--accent) 15%, var(--border));
  border-radius: 10px; margin-bottom: 0.75rem; }
.bf-audio-label { font-size: 0.7rem; font-weight: 600; color: var(--accent); text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap; }

/* Followed updates */
.bf-followed-section { background: color-mix(in srgb, var(--accent) 3%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--accent) 12%, var(--border));
  border-radius: 12px; padding: 0.75rem; margin-bottom: 1rem; }
.bf-followed-header { display: flex; align-items: center; gap: 0.4rem; font-size: 0.78rem;
  font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--accent); margin-bottom: 0.5rem; }

/* Dynamic importance score */
.bf-score { font-weight: 700; font-size: 0.72rem; min-width: 1.5rem; text-align: center; border-radius: 6px; }
.bf-score-high { background: var(--accent); color: #fff; }
.bf-score-mid { background: var(--accent-light); color: var(--accent); }
.bf-score-low { background: var(--bg-subtle); color: var(--text-muted); }

/* Story cards with counter + category border */
#bf-stories { counter-reset: story-counter; }
.bf-story-card { background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 10px; padding: 0.85rem; margin-bottom: 0.6rem; transition: all 0.15s; }
.bf-story-card:hover { border-color: var(--text-muted); }

/* Hero stories (first 2) */
.bf-story-hero { padding: 1rem; margin-bottom: 0.75rem; overflow: hidden; }
.bf-story-hero .bf-story-thumb { width: 100%; height: 200px; float: none; margin: 0 0 0.75rem 0;
  border-radius: 10px; object-fit: cover; transition: transform 0.6s ease, object-position 0.6s ease; }
.bf-story-hero:hover .bf-story-thumb { transform: scale(1.05); object-position: center 30%; }
.bf-story-hero .bf-story-title { font-size: 1.1rem; font-weight: 700; -webkit-line-clamp: 3; line-height: 1.3; }
.bf-story-hero .bf-story-summary { font-size: 0.88rem; -webkit-line-clamp: 5; line-height: 1.55; }

/* Story content */
.bf-story-body { overflow: hidden; counter-increment: story-counter; }
.bf-story-thumb { float: left; width: 120px; height: 90px; border-radius: 8px; object-fit: cover;
  margin: 0.2rem 1rem 0.5rem 0; transition: transform 0.4s ease; }
.bf-story-card:hover .bf-story-thumb { transform: scale(1.03); }
.bf-story-content { min-width: 0; }
.bf-story-badges { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-bottom: 0.3rem; }
.bf-story-badges::before { content: counter(story-counter); display: inline-flex; align-items: center; justify-content: center;
  width: 1.35rem; height: 1.35rem; border-radius: 50%; background: var(--bg-subtle); color: var(--text-muted);
  font-size: 0.65rem; font-weight: 700; flex-shrink: 0; }
.bf-story-title { font-size: 0.92rem; font-weight: 600; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden; margin-bottom: 0.2rem; cursor: pointer; text-decoration: none; color: inherit; }
.bf-story-title:hover { color: var(--accent); }
.bf-story-summary { font-size: 0.88rem; color: var(--text-secondary); margin: 0.4rem 0 0;
  line-height: 1.6; display: -webkit-box; -webkit-line-clamp: 3;
  -webkit-box-orient: vertical; overflow: hidden; cursor: pointer; position: relative; }
.bf-story-summary.truncated:not(.expanded)::after,
.np-hero-summary.truncated:not(.expanded)::after,
.np-card-summary.truncated:not(.expanded)::after {
  content: 'Read more'; position: absolute; bottom: 0; right: 0;
  padding-left: 2.5rem; font-size: 0.78rem; font-weight: 600; color: var(--accent);
  background: linear-gradient(to right, transparent, var(--bg-card) 40%); }
.bf-story-summary.expanded { display: block !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; overflow: visible !important; max-height: none !important; }
.bf-story-summary.expanded::after,
.np-hero-summary.expanded::after,
.np-card-summary.expanded::after { display: none !important; }
/* The hero/card summaries need position:relative so the "Read more" badge
   anchors to the bottom-right of the truncated text instead of the page. */
.np-hero-summary, .np-card-summary { position: relative; }
.bf-story-actions-row { display: flex; justify-content: flex-end; padding-top: 0.4rem;
  border-top: 1px solid var(--border-light); margin-top: 0.5rem; }
.bf-story-actions-row .lf-act { min-width: 2.25rem; min-height: 2.25rem; }

/* Nav prev/next */
.bf-nav { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem;
  margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.bf-nav-link { display: flex; align-items: center; gap: 0.4rem; padding: 0.6rem 0.85rem;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
  text-decoration: none; color: inherit; transition: all 0.15s; }
.bf-nav-link:hover { border-color: var(--accent); transform: translateY(-1px); }
.bf-nav-link-next { text-align: right; }
.bf-nav-label { font-size: 0.78rem; font-weight: 600; }

@media (max-width: 767px) {
  .bf-story-hero .bf-story-thumb { height: 160px; }
  .bf-story-thumb { width: 90px; height: 68px; }
  .bf-story-actions-row .lf-act { min-width: 2rem; min-height: 2rem; }
}

/* ==================== TIMELINE ==================== */
.timeline-container { background: var(--bg-subtle); border-radius: 8px; }
.timeline { position: relative; padding-left: 1.5rem; }
.timeline::before {
  content: ''; position: absolute; left: 5px; top: 0; bottom: 0;
  width: 2px; background: var(--border);
}
.timeline-entry { position: relative; padding-bottom: 1.25rem; }
.timeline-entry:last-child { padding-bottom: 0; }
.timeline-dot {
  position: absolute; left: -1.5rem; top: 0.15rem;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg-card);
  z-index: 1;
}
.timeline-content { padding-left: 0.25rem; }

/* ==================== DASHBOARD ==================== */
.line-clamp-1 { display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.metric-divider { width: 1px; height: 2rem; background: var(--border); }
.category-bar-track { flex: 1; height: 6px; background: var(--bg-subtle); border-radius: 3px; overflow: hidden; }
.category-bar-fill { height: 100%; border-radius: 3px; }
.log-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--success); }
.log-dot-error { background: var(--error); }

/* ==================== SEARCH TABS ==================== */
.search-tab { background: transparent; color: var(--text-muted); border: none; cursor: pointer; transition: all 0.15s; }
.search-tab:hover { color: var(--text); background: var(--bg-subtle); }
.search-tab.active { background: var(--accent); color: #fff; }

/* ==================== NEWS TICKER ==================== */
.news-ticker-wrap {
  display: flex; align-items: center; gap: 0;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 10px; overflow: hidden; height: 2.75rem;
}
.news-ticker-label {
  display: flex; align-items: center; gap: 0.35rem;
  padding: 0 0.75rem; font-size: 0.82rem; font-weight: 700;
  letter-spacing: 0.08em; color: #fff; white-space: nowrap;
  background: #DC2626; height: 100%; flex-shrink: 0;
  text-decoration: none;
}
.news-ticker-label:hover { text-decoration: none; color: #fff; }
.news-ticker-track {
  flex: 1; overflow: hidden; position: relative; height: 100%;
  mask-image: linear-gradient(to right, transparent 0%, black 3%, black 97%, transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 3%, black 97%, transparent 100%);
}
.news-ticker-content {
  display: flex; align-items: center; gap: 2rem;
  white-space: nowrap; height: 100%;
  animation: ticker-scroll 60s linear infinite;
  width: max-content;
}
.news-ticker-content:hover { animation-play-state: paused; }
.ticker-item {
  display: inline-flex; align-items: center; gap: 0.4rem;
  text-decoration: none !important; color: var(--text); font-size: 0.8rem;
  flex-shrink: 0;
}
.ticker-item:hover .ticker-title { color: var(--accent); }
.ticker-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); flex-shrink: 0; opacity: 0.7;
}
.ticker-title { font-weight: 600; }
.ticker-source { color: var(--text-muted); font-size: 0.78rem; }
@keyframes ticker-scroll {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

/* ==================== SHARED PAGE LAYOUT ==================== */
.page-header { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0; }
.page-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.35rem 0; gap: 0.75rem;
}
.page-toolbar-left { display: flex; align-items: center; gap: 0.5rem; }
.page-toolbar-right { display: flex; align-items: center; gap: 0.4rem; }
.page-title { font-size: 1.15rem; font-weight: 700; color: var(--text); margin: 0; letter-spacing: -0.01em; }
.page-subtitle { font-size: 0.82rem; color: var(--text-muted); }
@media (max-width: 640px) { .page-subtitle { display: none; } }
.page-count {
  font-size: 0.82rem; font-weight: 700; background: var(--accent);
  color: #fff; padding: 0.1rem 0.55rem; border-radius: 9999px; min-width: 1.2rem;
  text-align: center; line-height: 1.4; white-space: nowrap; flex-shrink: 0;
}
.page-hamburger {
  display: none; background: none; border: none; color: var(--text-muted);
  cursor: pointer; padding: 0.25rem; border-radius: 6px;
}
.page-hamburger:hover { background: var(--bg-subtle); color: var(--text); }
.page-shell { }
/* 3-column Feedlane-style: flat sub-nav column + roomy content column.
   The global app-sidebar provides the outer-most column. */
.page-shell-sidebar {
  display: grid; grid-template-columns: 220px minmax(0, 1fr);
  gap: 0; align-items: start;
  /* Cancel .app-main's padding so the grid spans edge-to-edge; each column
     then manages its own padding (matches /feeds content rhythm). */
  margin: -1.5rem -2rem 0;
}
.page-main {
  min-width: 0;
  padding: 1.5rem 2rem;  /* matches .app-main padding used on /feeds, /live, etc. */
  display: flex; flex-direction: column; gap: 0.85rem;
}
@media (max-width: 767px) {
  .page-shell-sidebar { margin: -1rem -1rem 0; }
  .page-main { padding: 1rem; gap: 0.6rem; }
}
.page-sidebar {
  position: sticky; top: 0; z-index: 30;
  background: transparent; border: none; border-right: 1px solid var(--border);
  padding: 1.5rem 0;  /* match .page-main padding-top so nav aligns with the H1 */
  height: 100vh; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: var(--border) transparent;
}
.page-sb-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 1rem 0.75rem;
}
.page-sb-title { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); }
/* Close button floats top-right on mobile now that the sb-head is gone */
.page-sidebar > .page-sb-close {
  position: absolute; top: 0.75rem; right: 0.5rem;
}
.page-backdrop { display: none; }
.page-content { padding-top: 1rem; }
/* Mobile: drop the settings sub-nav entirely — the settings page is a single
   scrolling column on narrow screens, the sub-nav would just take room. */
@media (max-width: 767px) {
  .page-shell-sidebar { grid-template-columns: 1fr; }
  .page-sidebar,
  .page-backdrop,
  .page-hamburger-mobile { display: none !important; }
  .page-main { padding: 0 0.5rem; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .page-shell-sidebar { grid-template-columns: 180px 1fr; }
}

/* ==================== SETTINGS LAYOUT ==================== */
/* Card-style sections — same visual language as /feeds .disc-feed-card
   and .cat-card: rounded card with bg-card, border, padding, subtle hover. */
.set-section {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 12px; padding: 0; margin: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
  overflow: hidden;
}
.set-section:hover { border-color: color-mix(in srgb, var(--accent) 25%, var(--border)); }
.set-section input, .set-section select, .set-section textarea { background: var(--bg); }
.set-section-head {
  display: flex; align-items: center; gap: 0.55rem;
  padding: 0.95rem 1.25rem;
  font-size: 0.95rem; font-weight: 700; color: var(--text);
  border-bottom: 1px solid var(--border-light);
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--accent-soft) 35%, var(--bg-card)),
    var(--bg-card) 100%);
}
.set-section-head svg {
  color: var(--accent); width: 16px; height: 16px; flex-shrink: 0;
}
.set-desc {
  font-size: 0.82rem; color: var(--text-muted); line-height: 1.45;
  padding: 0.85rem 1.25rem 0; margin: 0;
}
/* When .set-desc is the only/last child of a .set-section (e.g.
   "Linked Accounts" with no provider configured) it must add its own
   bottom padding — otherwise the text sticks to the card border. */
.set-section > .set-desc:last-child { padding-bottom: 1rem; }
.set-desc-empty { padding-bottom: 1rem; }
.set-form {
  display: flex; flex-direction: column; gap: 0.9rem;
  padding: 1rem 1.25rem 1.15rem;
}
/* Class-level `display:flex/grid/block` rules outrank the user-agent
   stylesheet's `[hidden] { display:none }`. Force the `hidden` attribute
   back to its expected behavior on any settings element. */
.set-form[hidden],
.set-actions[hidden],
.set-section [hidden] { display: none !important; }

/* Danger-zone stage-1 CTA strip — sits inside the section, right-aligned. */
.set-danger-stage1 { padding: 0.5rem 1.25rem 1.15rem;
  display: flex; justify-content: flex-end; }

/* ========== Danger-zone churn-survey modal ==========
   Fixed overlay with backdrop. Card scrolls on small viewports. */
.set-danger-modal {
  position: fixed; inset: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
}
.set-danger-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(2px);
}
.set-danger-modal-card {
  position: relative; z-index: 1;
  width: min(560px, 100%);
  max-height: calc(100vh - 2rem);
  display: flex; flex-direction: column;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 24px 60px -10px rgba(0,0,0,0.45);
  overflow: hidden;
}
.set-danger-modal-head {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.set-danger-modal-head h3 {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 1rem; font-weight: 700; margin: 0;
  color: #b91c1c; letter-spacing: -0.01em; flex: 1;
}
[data-theme="dark"] .set-danger-modal-head h3 { color: #fca5a5; }
.set-danger-modal-close {
  background: transparent; border: none; cursor: pointer;
  font-size: 1.4rem; line-height: 1; color: var(--text-muted);
  padding: 0.15rem 0.45rem; border-radius: 6px;
  transition: background 0.12s, color 0.12s;
}
.set-danger-modal-close:hover { background: var(--bg-subtle); color: var(--text); }
.set-danger-modal-form {
  display: flex; flex-direction: column; gap: 0.9rem;
  padding: 1.1rem 1.25rem 0;
  overflow-y: auto;
}
.set-danger-modal-form label:not(.set-churn-reasons label) {
  font-size: 0.78rem; font-weight: 600; color: var(--text);
  margin-bottom: 0.25rem; display: block;
}
.set-danger-modal-form input[type=password],
.set-danger-modal-form input[type=text] {
  width: 100%; padding: 0.5rem 0.7rem;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg); color: var(--text);
  font-family: inherit; font-size: 0.9rem;
}
.set-danger-modal-foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 0.5rem;
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--border);
  margin: 0.5rem -1.25rem 0;
  background: var(--bg-subtle);
  flex-shrink: 0;
}
/* Field label above its input. Scope out inline labels (.set-row-main,
   .set-switch, .set-cat-chip, .set-toggle-label) that must stay flex-inline,
   regardless of nesting depth inside the form. */
.set-form label:not(.set-row-main):not(.set-switch):not(.set-toggle-label):not(.set-cat-chip):not(.notif-channel-toggle) {
  font-size: 0.78rem; font-weight: 600; color: var(--text);
  margin-bottom: 0.25rem; display: block;
}
.set-form .set-hint { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.2rem; }
.set-tier-lock, .set-2fa-status, .set-oauth-row {
  padding: 1rem 1.25rem 1.15rem;
}
.set-tier-lock p { margin: 0; font-size: 0.85rem; color: var(--text-muted); }

/* Locked toggle row (e.g. Telegram on free tier) — dim the title to hint disabled. */
.set-toggle-row-locked strong { opacity: 0.75; }
.set-panel {
  background: var(--bg-subtle); border: 1px solid var(--border-light);
  border-radius: 10px; padding: 0.85rem;
}
.set-actions {
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
  padding-top: 0.15rem;
}
.set-inline-group { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; }
.set-inline-group label { font-size: 0.8rem; font-weight: 400; margin: 0; }

/* Briefing category focus multi-select — chip-style checkboxes */
.set-category-focus { display: flex; flex-direction: column; gap: 0.35rem; }
.set-cat-grid {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  max-height: 240px; overflow-y: auto;
  padding: 0.5rem; margin-top: 0.15rem;
  background: var(--bg-subtle); border: 1px solid var(--border-light); border-radius: 8px;
}
.set-cat-chip {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.3rem 0.7rem; font-size: 0.78rem;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--bg-card); cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  user-select: none; margin: 0;
}
.set-cat-chip input { position: absolute; opacity: 0; pointer-events: none; }
.set-cat-chip:hover { border-color: var(--accent); color: var(--accent); }
.set-cat-chip:has(input:checked) {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600;
}

/* Brief Composer — per-category weight + max sliders */
.composer-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 0.85rem;
}
.composer-row {
  background: var(--bg); border: 1px solid var(--border-light);
  border-radius: 10px; padding: 0.85rem 1rem;
  display: flex; flex-direction: column; gap: 0.7rem;
  transition: border-color 0.15s, opacity 0.15s;
}
.composer-row:hover { border-color: var(--border); }
.composer-row-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem;
  padding-bottom: 0.4rem; border-bottom: 1px dashed var(--border-light);
}
.composer-row-name {
  font-size: 0.88rem; font-weight: 600; color: var(--text);
  text-transform: capitalize; letter-spacing: 0.01em;
}
.composer-row-meta {
  font-size: 0.7rem; color: var(--text-muted); font-weight: 500;
}
.composer-row-controls {
  display: flex; flex-direction: column; gap: 0.7rem;
}
.composer-control {
  display: flex; flex-direction: column; gap: 0.3rem; margin: 0;
}
.composer-control-label {
  display: flex; align-items: baseline; justify-content: space-between;
  font-size: 0.74rem; color: var(--text-muted); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.composer-control-label strong {
  color: var(--accent); font-weight: 700; font-size: 0.9rem;
  font-variant-numeric: tabular-nums; text-transform: none;
}
.composer-control input[type="range"] {
  width: 100%; accent-color: var(--accent); cursor: pointer; margin: 0;
  height: 4px;
}
.composer-max-row {
  display: flex; align-items: center; gap: 0.5rem;
}
.composer-max-input {
  width: 72px; padding: 0.32rem 0.5rem; font-size: 0.85rem;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg-card); color: var(--text);
  font-variant-numeric: tabular-nums; text-align: center;
}
.composer-row:has(input[name="composer_weight"][value="0"]) {
  opacity: 0.5;
}
.composer-row:has(input[name="composer_weight"][value="0"]) .composer-row-name::after {
  content: ' · excluded';
  font-size: 0.7rem; color: var(--text-muted);
  text-transform: lowercase; font-weight: 500; letter-spacing: 0;
}

/* Toggle switch (shared) */
.set-switch { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; flex-shrink: 0; }
.set-switch input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.set-switch-track { display: inline-block; width: 38px; height: 20px; background: var(--border); border-radius: 10px;
    position: relative; transition: background 0.2s; }
.set-switch-thumb { position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
    background: #fff; transition: transform 0.2s; box-shadow: 0 1px 2px rgba(0,0,0,0.15); }
.set-switch input:checked + .set-switch-track { background: var(--accent); }
.set-switch input:checked + .set-switch-track .set-switch-thumb { transform: translateX(18px); }

/* Toggle row (label + switch) */
.set-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }

/* Toggle label (inline with text) */
.set-toggle-label { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; font-weight: 400;
    cursor: pointer; margin: 0; }
.set-toggle-label input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.set-toggle-label input:checked + .set-switch-track { background: var(--accent); }
.set-toggle-label input:checked + .set-switch-track .set-switch-thumb { transform: translateX(18px); }

/* Pill radio group (theme selector etc.) */
.set-pill-label {
  display: flex; align-items: center; padding: 0.35rem 0.75rem; font-size: 0.78rem; font-weight: 600;
  color: var(--text-muted); background: var(--bg-subtle); border: 1px solid var(--border);
  border-radius: 8px 0 0 8px; border-right: none;
}
.set-pill-group { display: inline-flex; gap: 0; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.set-pill { margin: 0; cursor: pointer; }
.set-pill input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.set-pill span {
  display: block; padding: 0.35rem 0.85rem; font-size: 0.78rem; font-weight: 500;
  color: var(--text-muted); transition: all 0.15s; border-right: 1px solid var(--border);
}
.set-pill:last-child span { border-right: none; }
.set-pill:hover span { background: var(--bg-subtle); color: var(--text); }
.set-pill input:checked + span { background: var(--accent); color: #fff; }
.set-usage {
  font-size: 0.82rem; color: var(--text-muted);
  background: var(--bg-subtle); border: 1px solid var(--border-light);
  border-radius: 8px; padding: 0.6rem 0.85rem;
}
.set-trial {
  font-size: 0.78rem; border-radius: 8px; padding: 0.6rem 0.85rem;
  border: 1px solid var(--accent); background: var(--accent-soft);
}
.set-trial-ended {
  border-color: var(--error); background: var(--error-light);
}

.settings-content { padding-bottom: 2rem; }
.settings-alert-inline {
  display: inline-flex; align-items: center; gap: 0.4rem;
}
/* Settings helper classes (replace inline styles) */
.set-hint-active { margin-top: 0.5rem; }
.set-hint-tight  { margin: 0.15rem 0 0; }
.set-divider-block {
  border-top: 1px solid var(--border); padding-top: 1rem; margin-top: 0.5rem;
}
.set-toggle-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; margin-bottom: 0.75rem;
}
.set-briefing-chips {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  align-items: center; margin-bottom: 0.5rem;
}
.set-briefing-add {
  display: flex; gap: 0.5rem; align-items: center;
}
.set-briefing-add input[type="time"] { width: auto; }
.set-time-chip {
  display: inline-flex; align-items: center; gap: 0.3em;
  padding: 0.25em 0.6em; font-size: 0.85rem;
  background: var(--bg-subtle); border: 1px solid var(--border);
  border-radius: 999px; color: var(--text);
}
.set-time-chip-x {
  cursor: pointer; font-weight: bold; opacity: 0.7;
  transition: opacity 0.12s;
}
.set-time-chip-x:hover { opacity: 1; }
.set-day-chips {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  align-items: center; margin: 0.25rem 0 0.5rem;
}
.set-day-chip {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.4rem; padding: 0.4em 0.7em;
  font-size: 0.85rem; font-weight: 600;
  background: var(--bg-subtle); border: 1px solid var(--border);
  border-radius: 999px; color: var(--text);
  cursor: pointer; transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.set-day-chip:hover { background: var(--bg-hover, var(--bg-subtle)); }
.set-day-chip.is-on {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.set-day-chip.is-on:hover { filter: brightness(1.05); }
.set-day-presets {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  margin-bottom: 0.4rem;
}
.set-day-preset {
  -webkit-appearance: none; appearance: none;
  font-size: 0.75rem; font-weight: 500;
  padding: 0.25em 0.65em;
  background: transparent; border: 1px solid var(--border);
  border-radius: 999px; color: var(--text-muted);
  cursor: pointer;
}
.set-day-preset:hover { color: var(--text); border-color: var(--accent); }
.set-cap-hint {
  font-size: 0.75rem; color: var(--text-muted); margin-top: 0.25rem;
}
.set-upgrade-btn { margin-top: 0.5rem; }
.set-label-meta { font-weight: 400; font-size: 0.75rem; color: var(--text-muted); }
.set-select-narrow { max-width: 300px; }
.set-test-row {
  display: flex; align-items: center; gap: 0.5rem;
  margin-top: 0.75rem;
}
.notif-tier-hint {
  font-size: 0.75rem; color: var(--text-muted);
  margin: 0.25rem 0 0 2.5rem;
}
.notif-tier-hint a { color: var(--accent); }
.link-accent { color: var(--accent); }
.set-2fa-status {
  display: flex; align-items: center; gap: 0.75rem;
  margin-bottom: 0.75rem; flex-wrap: wrap;
}
.set-badge-success {
  background: var(--success); color: #fff;
  padding: 0.25rem 0.75rem; border-radius: 999px;
  font-size: 0.75rem; font-weight: 600;
}
.set-or-divider {
  text-align: center; color: var(--text-muted);
  font-size: 0.75rem; margin: 0.25rem 0;
}
.set-oauth-row {
  display: flex; align-items: center; gap: 0.75rem;
  margin-bottom: 0.75rem; flex-wrap: wrap;
}
.set-oauth-label { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; }
.set-oauth-link { display: inline-flex; align-items: center; gap: 0.5rem; }
/* Sub-nav close button — shown only on mobile */
.page-sb-close {
  display: none; width: 32px; height: 32px;
  align-items: center; justify-content: center;
  background: transparent; border: none;
  color: var(--text-muted); cursor: pointer; border-radius: 6px;
}
.page-sb-close:hover { background: var(--bg-subtle); color: var(--text); }
@media (max-width: 1023px) {
  .page-sb-close { display: inline-flex; }
}
/* Mobile-only hamburger for the settings sub-nav drawer. Kept out of the
   hero so the hero markup is identical to every other page. */
.page-hamburger-mobile {
  display: none;
  align-items: center; gap: 0.4rem;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 6px; padding: 0.4rem 0.65rem;
  color: var(--text-muted); cursor: pointer; font: inherit; font-size: 0.78rem;
}
.page-hamburger-mobile:hover { background: var(--bg-subtle); color: var(--text); }
@media (max-width: 1023px) {
  .page-hamburger-mobile { display: inline-flex; width: fit-content; }
}
.settings-hero-row {
  display: flex; align-items: flex-start; gap: 0.75rem;
}
.settings-hero-textwrap { flex: 1; min-width: 0; }
.settings-hero-title {
  font-size: 1.45rem; font-weight: 700; margin: 0 0 0.15rem;
  letter-spacing: -0.01em;
}
.settings-hero-sub {
  font-size: 0.85rem; color: var(--text-muted); margin: 0; line-height: 1.4;
}
.settings-hero-plan {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em;
  padding: 0.3rem 0.65rem; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent);
  align-self: center;
}

.settings-nav-link {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.48rem 1rem; border-radius: 6px;
  font-size: 0.84rem; font-weight: 500;
  color: var(--text-muted); text-decoration: none !important;
  transition: all 0.12s; white-space: nowrap;
  margin: 0.1rem 0.5rem;
}
.settings-nav-link:hover { color: var(--text); background: var(--bg-subtle); text-decoration: none !important; }
.settings-nav-link.active { color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.settings-nav-link svg { flex-shrink: 0; opacity: 0.7; width: 15px; height: 15px; }
.settings-nav-link.active svg { opacity: 1; }
.settings-nav-divider { height: 1px; background: var(--border); margin: 0.6rem 1rem; }
.settings-section-header {
  display: flex; align-items: center; gap: 0.5rem;
  margin-bottom: 1rem; padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border-light);
}
.settings-section-header h2 { font-size: 1rem; font-weight: 600; margin: 0; }
.settings-section-header svg { color: var(--accent); flex-shrink: 0; }

/* .notif-channel-* removed — replaced by the shared .set-row pattern. */

/* ==================== ONBOARDING ==================== */
.provider-card { border: 2px solid var(--border); border-radius: 10px; padding: 1rem; cursor: pointer; text-align: center; transition: all 0.2s; }
.provider-card:hover { border-color: var(--text-muted); }
.provider-card.selected { border-color: var(--accent); background: var(--accent-light); }
.provider-card input[type="radio"] { display: none; }

/* ==================== AUTH NAV (login, register, etc.) ==================== */
.auth-nav {
  background: var(--bg-card); border-bottom: 1px solid var(--border);
}

/* ==================== LANDING PAGE ==================== */
.landing-body { background: var(--bg); color: var(--text); }
.landing-hero-sub { color: var(--text-muted); }
.landing-pill { background: var(--accent-light); color: var(--accent); }
.landing-stat-num { color: var(--accent); }
.landing-stat-label { color: var(--text-muted); }
.landing-step, .landing-feature {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
}
.landing-step-icon { background: var(--accent-light); color: var(--accent); }
.landing-step p, .landing-feature p { color: var(--text-muted); }
.landing-cta {
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  color: #fff; border-radius: 16px;
}
.landing-cta p { color: rgba(255,255,255,0.8); }
.landing-cta-btn {
  background: #fff; color: var(--accent); font-weight: 600;
  border-radius: 12px; padding: 0.75rem 1.5rem; text-decoration: none;
  display: inline-block; transition: background 0.2s;
}
.landing-cta-btn:hover { background: rgba(255,255,255,0.9); text-decoration: none; }
.landing-footer { color: var(--text-muted); }
.landing-footer a { color: var(--text-muted); text-decoration: none; }
.landing-footer a:hover { color: var(--text); text-decoration: none; }
.landing-footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 2rem; }
@media (max-width: 767px) {
  .landing-footer-grid { grid-template-columns: 1fr 1fr; gap: 1.5rem; }
  .auth-nav .landing-nav-links { display: none; }
}
.landing-nav-link {
  padding: 0.5rem 1rem; font-size: 0.875rem; font-weight: 500;
  border-radius: 8px; border: 1px solid var(--border);
  color: var(--text); text-decoration: none; transition: background 0.2s;
}
.landing-nav-link:hover { background: var(--bg-subtle); text-decoration: none; }
.landing-nav-primary {
  padding: 0.5rem 1rem; font-size: 0.875rem; font-weight: 500;
  border-radius: 8px; background: var(--accent); color: #fff;
  text-decoration: none; transition: background 0.2s;
}
.landing-nav-primary:hover { background: var(--accent-hover); text-decoration: none; }

/* ==================== STORY SHARING ==================== */

#story-share-popup {
  display: none; position: absolute; z-index: 40;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 10px; padding: 0.5rem; min-width: 160px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
}
#story-share-popup.visible { display: block; }
#story-share-popup button {
  display: flex; align-items: center; gap: 0.5rem; width: 100%;
  background: none; border: none; padding: 0.5rem 0.75rem;
  font-size: 0.85rem; color: var(--text); cursor: pointer;
  border-radius: 6px; font-family: inherit;
}
#story-share-popup button:hover { background: var(--bg-subtle); }

/* ==================== RESPONSIVE ==================== */
@media (max-width: 767px) {
  .hide-mobile { display: none !important; }
  /* Better tap targets on mobile */
  .btn { min-height: 2.5rem; }
  .btn-sm { min-height: 2rem; }
  .btn-xs { min-height: 1.75rem; min-width: 2.25rem; padding: 0.3rem 0.6rem; }
  /* Briefing action buttons — bigger touch targets */
  .briefing-card .bookmark-btn,
  .briefing-card .follow-btn { min-width: 2.5rem; min-height: 2.5rem; font-size: 1rem; }
  .briefing-card .story-action-btn { min-width: 2.2rem; min-height: 2.2rem; padding: 0.3rem 0.4rem; }
  .briefing-card .rating-buttons { gap: 0.35rem; display: inline-flex; }
  /* Briefing card padding */
  .briefing-card { padding: 1rem; }
  /* Landing hero text sizing */
  .landing-hero-title { font-size: 2rem; }
}
@media (max-width: 480px) {
  /* Stack action buttons on very small screens */
  .landing-hero-actions { flex-direction: column; align-items: stretch; }
  .landing-hero-actions a { text-align: center; }
}

/* ==================== IMAGE PLACEHOLDERS ==================== */
.story-thumb { width: 72px; height: 72px; }
.story-thumb-sm { width: 48px; height: 48px; }
.story-thumb-placeholder {
  width: 72px; height: 72px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); border-radius: 10px;
  color: var(--accent); opacity: 0.5;
}
.story-thumb-placeholder-sm { width: 48px; height: 48px; border-radius: 8px; }
.story-thumb-placeholder-md { width: 56px; height: 56px; border-radius: 8px; }

/* ==================== LIVE FEED ==================== */
/* Layout — single-column now (global app-sidebar handles feed nav). */
.lf-layout-single { display: block; margin: 0; }
/* Inherit the hero/search/toolbar gap from .following-layout since .lf-main
   sits between them on /live (unlike /feeds which has no wrapper). */
.lf-main {
  min-width: 0; padding: 0;
  display: flex; flex-direction: column; gap: 0.85rem;
}
@media (max-width: 767px) {
  .lf-main { gap: 0.6rem; }
}
.lf-feed-chip {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.2rem 0.55rem; margin-left: 0.5rem;
  background: var(--accent-soft); color: var(--accent);
  border-radius: 999px; font-size: 0.72rem; font-weight: 600;
  line-height: 1; max-width: 240px;
}
.lf-feed-chip svg { flex-shrink: 0; }
.lf-feed-chip-clear {
  margin-left: 0.15rem; color: inherit; opacity: 0.7;
  font-size: 0.95rem; line-height: 1; text-decoration: none;
  padding: 0 0.15rem; border-radius: 50%;
}
.lf-feed-chip-clear:hover { opacity: 1; }

/* --- Sidebar (Feedlane-style: flat, transparent, border-right only) --- */
.lf-sidebar {
  position: sticky; top: 4rem; z-index: 30;
  background: transparent; border: none; border-right: 1px solid var(--border);
  padding: 0; height: calc(100vh - 5rem); overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: var(--border) transparent;
}
.lf-sb-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.85rem 1rem; position: sticky; top: 0;
  background: var(--bg); z-index: 1;
  border-bottom: 1px solid var(--border);
}
.lf-sb-title {
  font-size: 0.72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-muted);
}
.lf-sb-toggle-all {
  font-size: 0.65rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--accent); background: none; border: 1px solid var(--border); cursor: pointer;
  padding: 0.2rem 0.5rem; border-radius: 4px; transition: all 0.1s;
}
.lf-sb-toggle-all:hover { background: var(--accent-soft); border-color: var(--accent); }
.lf-sb-cat {
  padding: 0.85rem 0.8rem 0.3rem; font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); opacity: 0.8;
}
.lf-sb-feed {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.4rem 0.8rem; font-size: 0.85rem; color: var(--text);
  cursor: pointer; transition: background 0.12s;
  border-radius: 4px; margin: 0 0.35rem;
}
.lf-sb-feed:hover { background: var(--bg-subtle); }
.lf-sb-feed-off { opacity: 0.45; }
.lf-sb-feed-off:hover { opacity: 0.75; }
.lf-sb-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  background: var(--border); transition: background 0.15s;
}
.lf-sb-dot.on { background: var(--success); }
.lf-sb-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
.lf-sb-unread {
  font-size: 0.65rem; font-weight: 700; color: var(--accent); background: var(--accent-soft);
  padding: 0.1rem 0.45rem; border-radius: 9999px; min-width: 1.2rem; text-align: center;
  line-height: 1.4; flex-shrink: 0;
}
.lf-sb-feed-read { opacity: 0.4; }
.lf-sb-feed-read:hover { opacity: 0.7; }
/* Close button — visible only on mobile */
.lf-sb-close {
  display: none; background: none; border: none; color: var(--text-muted);
  cursor: pointer; padding: 0.25rem; border-radius: 6px; line-height: 1;
}
.lf-sb-close:hover { background: var(--bg-subtle); color: var(--text); }
.lf-backdrop { display: none; }

/* --- Search status line (result count below the shared search bar) --- */
.lf-search-status { font-size: 0.75rem; color: var(--text-muted); padding: 0.25rem 0.25rem 0; }

/* --- Sticky header (categories + unified toolbar) --- */
.lf-sticky-header {
  position: sticky; top: 0; background: var(--bg); z-index: 20;
}
.lf-toolbar {
  display: flex; align-items: center; justify-content: flex-start;
  padding: 0.35rem 0 0.5rem; gap: 0.4rem; flex-wrap: wrap;
}
.lf-toolbar-actions {
  display: inline-flex; align-items: center; gap: 0.3rem;
  flex-shrink: 0; margin-left: auto;
}

/* --- Segmented control (view + sort) --- */
.lf-toolbar-seg {
  display: inline-flex; align-items: stretch; gap: 1px;
  padding: 2px; border-radius: 7px;
  background: var(--bg-subtle); border: 1px solid var(--border);
}
.lf-seg-btn {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.22rem 0.5rem; font-size: 0.74rem; font-weight: 500;
  border-radius: 5px; border: none;
  background: transparent; color: var(--text-muted);
  cursor: pointer; transition: all 0.12s; white-space: nowrap;
  font-family: inherit;
}
.lf-seg-btn:hover { background: var(--bg-card); color: var(--text); }
.lf-seg-btn.active {
  background: var(--bg-card); color: var(--accent);
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
  font-weight: 600;
}
.lf-seg-btn:disabled, .lf-seg-btn.disabled {
  opacity: 0.35; cursor: not-allowed;
}
.lf-seg-btn:disabled:hover { background: transparent; color: var(--text-muted); }
.lf-seg-btn svg { opacity: 0.75; flex-shrink: 0; width: 12px; height: 12px; }
.lf-seg-btn.active svg { opacity: 1; }

/* --- Icon-only action buttons on the Live toolbar (Show read / Mark read) --- */
.lf-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 7px; border: 1px solid var(--border);
  background: var(--bg-card); color: var(--text-muted);
  cursor: pointer; font-family: inherit;
  transition: all 0.12s; flex-shrink: 0;
}
.lf-icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.lf-icon-btn.active {
  background: var(--accent-soft); color: var(--accent); border-color: var(--accent);
}
.lf-icon-btn--primary {
  background: var(--accent); color: #fff; border-color: var(--accent);
}
.lf-icon-btn--primary:hover {
  background: var(--accent); color: #fff; border-color: var(--accent);
  filter: brightness(0.95);
}
.lf-icon-btn svg { flex-shrink: 0; }
/* Hide the Show-read label text — button is icon-only, label stays for a11y. */
.lf-icon-btn .sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* --- Actions (show-read toggle + mark all read) — shared w/ other pages --- */
.lf-chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.28rem 0.55rem; font-size: 0.74rem; font-weight: 500;
  border-radius: 6px; border: 1px solid var(--border);
  background: var(--bg-card); color: var(--text-muted);
  cursor: pointer; transition: all 0.12s; white-space: nowrap;
  font-family: inherit;
}
.lf-chip:hover { border-color: var(--accent); color: var(--accent); }
.lf-chip.active { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
.lf-chip svg { opacity: 0.7; flex-shrink: 0; width: 12px; height: 12px; }
.lf-chip-primary {
  background: var(--accent); color: #fff; border-color: var(--accent);
}
.lf-chip-primary:hover {
  background: var(--accent-hover, var(--accent)); color: #fff;
  filter: brightness(0.95); border-color: var(--accent);
}
.lf-chip-primary svg { opacity: 0.9; }

/* --- Legacy rules (kept for safety on dead code paths) --- */
.lf-toolbar-left { display: none; }
.lf-toolbar-right { display: none; }
.lf-hamburger { display: none; }
.lf-title { font-size: 1.15rem; font-weight: 700; color: var(--text); margin: 0; }
.lf-count {
  font-size: 0.82rem; font-weight: 700; background: var(--accent);
  color: #fff; padding: 0.1rem 0.45rem; border-radius: 9999px;
  min-width: 1.2rem; text-align: center; line-height: 1.4;
}

/* Category filtering now happens via the global sidebar folder links.
   The in-page chip bar (.lf-cats) is gone; these rules are kept minimal
   for any legacy callers. */

/* --- Date headers --- */
.lf-date-header {
  padding: 0.65rem 0 0.35rem; font-size: 0.82rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted);
  border-bottom: 1px solid var(--border); margin: 0.25rem 0 0.5rem;
}

/* --- Article rows --- */
.lf-row {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.75rem; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 10px; margin-bottom: 0.35rem;
  transition: all 0.1s; position: relative;
}
.lf-row:hover { border-color: var(--border-hover, var(--text-muted)); }
/* Read state: instead of dimming the whole row (which made text hard
   to read) we mute the title + summary to --text-muted and thin the
   font-weight. Contrast stays WCAG-legible while the row still looks
   visibly "done" compared to an unread neighbour. */
.lf-row.is-read { opacity: 1; }
.lf-row.is-read .lf-row-title { color: var(--text-muted); font-weight: 400; }
.lf-row.is-read .lf-row-summary,
.lf-row.is-read .lf-row-meta { color: var(--text-muted); }
.lf-row.is-read .lf-row-dot { background: transparent; border: 1px solid var(--border); }
.lf-row.is-read:hover .lf-row-title { color: var(--text); }
.lf-row-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; background: var(--text-muted); }
.lf-row-content { flex: 1; min-width: 0; }
.lf-row-title-row { display: flex; align-items: baseline; gap: 0.5rem; }
.lf-row-title {
  font-size: 0.82rem; font-weight: 500; color: var(--text);
  text-decoration: none; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lf-row-title:hover { color: var(--accent); }
.lf-row-meta {
  display: flex; align-items: center; gap: 0.35rem;
  font-size: 0.78rem; color: var(--text-muted); margin-top: 0.1rem;
}
.lf-row-meta .badge { font-size: 0.72rem; padding: 0.1rem 0.4rem; }

/* --- Row actions (hover) --- */
.lf-row-actions {
  display: flex; align-items: center; gap: 0.15rem;
  opacity: 0; transition: opacity 0.15s; flex-shrink: 0;
  background: var(--bg-subtle); border-radius: 6px; padding: 0.1rem 0.2rem;
}
.lf-row:hover .lf-row-actions, .lf-row:focus-within .lf-row-actions { opacity: 1; }
.lf-act {
  background: none; border: none; cursor: pointer;
  font-size: 0.78rem; padding: 0.2rem 0.35rem; border-radius: 4px;
  color: var(--text-muted); transition: all 0.12s; line-height: 1;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.lf-act.on { color: var(--accent); }
.lf-act.lf-act-down.on { color: var(--error); }
.lf-act:focus:not(:focus-visible) { color: inherit; background: none; outline: none; }
.lf-act.on:focus:not(:focus-visible) { color: var(--accent); }
.lf-act.lf-act-down.on:focus:not(:focus-visible) { color: var(--error); }
@media (hover: hover) {
  .lf-act:hover { color: var(--accent); background: var(--accent-soft); }
  .lf-act.lf-act-down:hover { color: var(--error); background: rgba(239,68,68,0.08); }
}
.lf-act:active { background: var(--accent-soft); }
.lf-act.lf-act-down:active { background: rgba(239,68,68,0.08); }

/* --- Card view (expanded) --- */
.lf-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
  padding: 0.75rem; margin-bottom: 0.5rem; transition: all 0.15s;
}
.lf-card:hover { border-color: var(--text-muted); }
/* Read state on expanded cards — same approach as .lf-row.is-read. */
.lf-card.is-read { opacity: 1; background: var(--bg-subtle, var(--bg-card)); }
.lf-card.is-read .lf-card-title { color: var(--text-muted); font-weight: 500; }
.lf-card.is-read .lf-card-summary,
.lf-card.is-read .lf-card-meta { color: var(--text-muted); }
.lf-card.is-read:hover .lf-card-title { color: var(--text); }

/* Card thumbnail: always-present wrapper with a colored placeholder
   (category tint + feed favicon) underneath the real image — so feeds
   without image_url, or feeds whose image URL 404s, still look like
   a uniform card grid instead of a visually-broken list. */
.lf-card-thumb-wrap {
  float: right;
  width: 100px; height: 72px;
  margin: 0 0 0.5rem 0.75rem;
  position: relative;
  border-radius: 8px;
  overflow: hidden;
  background: color-mix(in srgb, var(--cat-color, var(--accent)) 18%, var(--bg-subtle, var(--bg-card)));
  flex-shrink: 0;
}
.lf-card-thumb-placeholder {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--cat-color, var(--accent)) 22%, var(--bg-card)),
    color-mix(in srgb, var(--cat-color, var(--accent)) 8%, var(--bg-card)));
}
.lf-card-thumb-fav {
  width: 32px; height: 32px; border-radius: 6px;
  background: var(--bg-card); padding: 4px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
.lf-card-thumb-letter {
  font-size: 1.4rem; font-weight: 700;
  color: var(--cat-color, var(--accent));
  font-family: var(--font-family-sans, system-ui);
}
/* Make the real image cover the placeholder when it loads successfully. */
.lf-card-thumb-wrap .lf-card-thumb {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  float: none; margin: 0;
  border-radius: 0;
}

/* ============== Reader view (list | preview split) ============== */
.lf-reader-wrap {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
  min-height: calc(100vh - 14rem);
}
.lf-reader-list {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-card);
  max-height: calc(100vh - 14rem);
  overflow-y: auto;
}
.lf-rd-item {
  display: flex; gap: 0.55rem; align-items: flex-start;
  padding: 0.55rem 0.65rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.1s;
  border-left: 3px solid transparent;
}
.lf-rd-item:hover { background: var(--bg-subtle, var(--bg-card)); }
.lf-rd-item.selected {
  background: var(--accent-soft, color-mix(in srgb, var(--accent) 10%, transparent));
  border-left-color: var(--accent);
}
.lf-rd-item.is-read .lf-rd-title { color: var(--text-muted); font-weight: 400; }
.lf-rd-item.is-read .lf-rd-meta { color: var(--text-muted); }
.lf-rd-fav {
  width: 16px; height: 16px; border-radius: 3px;
  flex-shrink: 0; margin-top: 2px;
}
.lf-rd-body { flex: 1; min-width: 0; }
.lf-rd-title {
  font-size: 0.82rem; font-weight: 500; color: var(--text);
  line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.lf-rd-meta {
  font-size: 0.72rem; color: var(--text-muted);
  margin-top: 0.2rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.lf-reader-pane {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-card);
  padding: 1.25rem;
  min-height: 200px;
  max-height: calc(100vh - 14rem);
  overflow-y: auto;
  position: sticky; top: 0.5rem;
}
.lf-rd-pane-empty {
  color: var(--text-muted);
  font-size: 0.9rem;
  text-align: center;
  padding: 3rem 1rem;
}
.lf-rd-pane-img {
  width: 100%; max-height: 280px; object-fit: cover;
  border-radius: 8px; margin-bottom: 1rem;
}
.lf-rd-pane-meta {
  font-size: 0.78rem; color: var(--text-muted);
  margin-bottom: 0.5rem;
  display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap;
}
.lf-rd-pane-title { font-size: 1.25rem; line-height: 1.3; margin: 0 0 0.75rem; }
.lf-rd-pane-title a { color: var(--text); text-decoration: none; }
.lf-rd-pane-title a:hover { color: var(--accent); }
.lf-rd-pane-summary {
  font-size: 0.92rem; line-height: 1.55; color: var(--text-secondary, var(--text));
  margin-bottom: 1rem;
  white-space: pre-wrap; word-wrap: break-word;
}
.lf-rd-pane-open { display: inline-block; margin-bottom: 1rem; }
.lf-rd-pane-actions {
  display: flex; gap: 0.4rem; flex-wrap: wrap;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}
/* Actions must stay visible in the pane — they live inside
   .lf-row-actions which is opacity:0 by default (hover-reveal on row). */
.lf-rd-pane-actions .lf-row-actions { opacity: 1; background: none; padding: 0; }
.lf-rd-pane-actions .lf-act {
  min-width: 2.25rem; min-height: 2.25rem;
  font-size: 0.92rem; padding: 0.4rem 0.55rem;
}

/* Mobile fallback: split layout doesn't fit on phones/tablets, so
   collapse to the list-only view. The preview still works as a
   bottom-anchored panel if the user picks an item — but the default
   view is the list to preserve vertical space. */
@media (max-width: 1023px) {
  .lf-reader-wrap { grid-template-columns: 1fr; }
  .lf-reader-pane { position: static; max-height: none; }
  /* Reader view (list + preview) is not practical on narrow screens —
     hide the toggle button so users can't accidentally pick it. JS
     auto-falls-back to 'stories' when loaded on a phone. */
  #view-btn-reader, .lf-seg-btn[data-view="reader"] { display: none !important; }
}
.lf-card-body { overflow: hidden; }
.lf-card-thumb {
  float: right; width: 100px; height: 72px; border-radius: 8px; object-fit: cover;
  margin: 0 0 0.5rem 0.75rem;
}
.lf-card-info { min-width: 0; }
.lf-card-title {
  font-size: 0.88rem; font-weight: 600; color: var(--text);
  text-decoration: none; line-height: 1.35; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.lf-card-title:hover { color: var(--accent); }
.lf-card-summary {
  font-size: 0.82rem; color: var(--text-secondary); margin: 0.3rem 0 0;
  line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}
.lf-card-actions {
  display: flex; justify-content: flex-end; padding-top: 0.35rem;
  border-top: 1px solid var(--border-light); margin-top: 0.5rem;
}
.lf-card-actions .lf-row-actions { opacity: 1; background: none; }

/* --- Follow action styling --- */
.lf-act.lf-act-follow { font-size: 0.8rem; }
@media (hover: hover) { .lf-act.lf-act-follow:hover { color: var(--accent); background: var(--accent-soft); } }
.lf-act.lf-act-follow.on { color: var(--accent); }

/* --- Popular: Add feed & Hide buttons --- */
.lf-act.lf-act-addfeed { font-size: 0.9rem; font-weight: 700; }
.lf-act.lf-act-addfeed.on { color: var(--accent); }
@media (hover: hover) { .lf-act.lf-act-addfeed:hover { color: var(--accent); background: var(--accent-soft); } }
.lf-act.lf-act-hide { font-size: 0.75rem; }
@media (hover: hover) { .lf-act.lf-act-hide:hover { color: var(--error); background: rgba(239,68,68,0.08); } }

/* --- States --- */
.lf-loading { text-align: center; padding: 1.5rem 0; color: var(--text-muted); font-size: 0.8rem; display: flex; align-items: center; justify-content: center; gap: 0.5rem; }
.lf-end {
  text-align: center; padding: 3rem 1rem 8rem; color: var(--text-muted);
}
/* Inline confirm dialog */
.lf-confirm-overlay {
  position: fixed; inset: 0; z-index: 1200; background: rgba(0,0,0,0.35);
  display: flex; align-items: center; justify-content: center;
  animation: fadeIn 0.15s ease;
}
.lf-confirm-box {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
  padding: 1.25rem 1.5rem; max-width: 320px; width: 90%;
  box-shadow: 0 8px 30px rgba(0,0,0,0.15);
}
.lf-confirm-box p { font-size: 0.88rem; font-weight: 500; color: var(--text); margin: 0 0 1rem; text-align: center; }
.lf-confirm-box .lf-confirm-sub {
  font-size: 0.78rem; font-weight: 400; color: var(--text-muted); margin: -0.5rem 0 1rem;
}
.lf-confirm-actions { display: flex; gap: 0.5rem; justify-content: center; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.lf-empty {
  text-align: center; padding: 1rem; color: var(--text-muted);
  min-height: 50vh; display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.lf-empty svg { margin: 0 auto 0.75rem; opacity: 0.2; }
.lf-empty p { font-size: 0.85rem; margin: 0; }

/* --- Mobile --- */
@media (max-width: 767px) {
  .lf-layout { grid-template-columns: 1fr; }
  .lf-sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; z-index: 200;
    width: 260px; border-right: none; border-radius: 0;
    box-shadow: 4px 0 30px rgba(0,0,0,0.2);
    transform: translateX(-100%); transition: transform 0.25s ease;
    height: 100vh;
  }
  .lf-sidebar.open { transform: translateX(0); }
  .lf-backdrop {
    display: block; position: fixed; inset: 0; z-index: 199;
    background: rgba(0,0,0,0.4); opacity: 0; pointer-events: none;
    transition: opacity 0.25s;
  }
  .lf-backdrop.open { opacity: 1; pointer-events: auto; }
  .lf-hamburger { display: flex; }
  .lf-sb-close { display: flex; }
  .lf-main { padding: 0 0.5rem; }
  .lf-sticky-header { top: calc(3.5rem + 1px); }
  /* Tighten toolbar on phones: hide text labels on icon-first buttons. */
  .lf-toolbar { gap: 0.4rem; padding: 0.5rem 0; }
  .lf-seg-btn { padding: 0.3rem 0.5rem; }
  .lf-seg-btn span { display: none; }
  .lf-toolbar-actions .lf-chip span { display: none; }
  .lf-toolbar-actions .lf-chip { padding: 0.35rem 0.5rem; gap: 0; }
  .lf-toolbar-seg { flex-shrink: 0; }
  .disc-hero-search input { padding: 0.55rem 2.25rem 0.55rem 2.25rem !important; font-size: 0.85rem; }
  .lf-row { flex-wrap: wrap; }
  .lf-row-title { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; width: 100%; }
  /* Always show actions on mobile (no hover), bottom-right of card */
  .lf-row-actions { opacity: 1; background: none; flex-basis: 100%; justify-content: flex-end; padding-top: 0.15rem; }
  /* Bigger touch targets on mobile for ALL action buttons */
  .lf-act { min-width: 2rem; min-height: 2rem; font-size: 0.85rem; padding: 0.3rem 0.4rem; }
  /* Card view mobile tweaks */
  .lf-card-thumb { width: 72px; height: 54px; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .lf-layout { grid-template-columns: 240px 1fr; gap: 1rem; }
}
/* Landscape mobile: hide sidebar, compact nav, force cards view */
@media (max-height: 500px) and (orientation: landscape) {
  .lf-layout { grid-template-columns: 1fr; }
  .lf-sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; z-index: 200;
    width: 260px; border-right: none;
    box-shadow: 4px 0 30px rgba(0,0,0,0.2);
    transform: translateX(-100%); transition: transform 0.25s ease;
    height: 100vh;
  }
  .lf-sidebar.open { transform: translateX(0); }
  .lf-hamburger { display: flex; }
  .lf-sb-close { display: flex; }
  .lf-main { padding: 0 0.5rem; }
  /* Compact navbar */
  .nav-menu-desktop { gap: 0.1rem !important; }
  .nav-link { font-size: 0.75rem !important; padding: 0.35rem 0.5rem !important; }
  .nav-menu-desktop .nav-bottom { margin-left: 0.35rem; padding-left: 0.35rem; }
}

/* ==================== CATALOG CARDS ==================== */
.cat-divider { display: flex; align-items: center; gap: 0.75rem; padding: 1.25rem 0 0.5rem;
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); }
.cat-divider-line { flex: 1; height: 1px; background: var(--border); }
.cat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem; }
@media (max-width: 640px) { .cat-grid { grid-template-columns: 1fr; } }

.cat-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
  overflow: hidden; transition: border-color 0.2s, box-shadow 0.2s; }
.cat-card:hover { border-color: color-mix(in srgb, var(--cat-color) 40%, var(--border));
  box-shadow: 0 2px 12px color-mix(in srgb, var(--cat-color) 6%, transparent); }

.cat-card-head { display: flex; align-items: center; gap: 0.6rem; padding: 0.7rem 0.85rem;
  cursor: pointer; transition: background 0.15s;
  background: linear-gradient(135deg, color-mix(in srgb, var(--cat-color) 8%, var(--bg-card)), var(--bg-card) 70%); }
.cat-card-head:hover { background: linear-gradient(135deg, color-mix(in srgb, var(--cat-color) 14%, var(--bg-card)), var(--bg-card) 70%); }

.cat-icon-circle { width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center;
  justify-content: center; flex-shrink: 0;
  background: color-mix(in srgb, var(--cat-color) 12%, var(--bg-card)); color: var(--cat-color); }
.cat-card-meta { flex: 1; min-width: 0; }
.cat-card-title { font-size: 0.95rem; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cat-card-desc { font-size: 0.82rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cat-card-count { font-size: 0.7rem; font-weight: 500; padding: 0.15rem 0.45rem; border-radius: 999px;
  background: color-mix(in srgb, var(--cat-color) 10%, var(--bg-subtle)); color: var(--cat-color); flex-shrink: 0; }
.cat-chevron { color: var(--text-muted); flex-shrink: 0; transition: transform 0.2s; }
.cat-card.open .cat-chevron { transform: rotate(180deg); }

.cat-card-feeds { max-height: 0; overflow: hidden; transition: max-height 0.3s ease, opacity 0.2s ease; opacity: 0; }
.cat-card.open .cat-card-feeds { max-height: 2000px; opacity: 1; }

.cat-feed { display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.85rem;
  margin: 0.15rem 0.4rem; border-radius: 8px; transition: background 0.1s; }
.cat-feed:hover { background: var(--bg-subtle); }
.cat-feed-dot { width: 5px; height: 5px; border-radius: 50%; flex-shrink: 0;
  background: var(--cat-color); opacity: 0.5; }
/* Pending first-fetch state: bright, pulsing so the user sees that the feed
   is being loaded right now (not a silent error). */
.cat-feed-dot-pending { opacity: 1; animation: cat-feed-dot-pulse 1.1s ease-in-out infinite; }
@keyframes cat-feed-dot-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--warning, #f59e0b) 70%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--warning, #f59e0b) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--warning, #f59e0b) 0%, transparent); }
}
.cat-feed-info { flex: 1; min-width: 0; overflow: hidden; }
.cat-feed-name { font-size: 0.9rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cat-feed-desc { font-size: 0.82rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Subscribe button (used to be "+ Add") — now the primary call-to-action
   in each catalog card, so it uses the category accent colour as fill. */
.cat-btn-add {
  font-size: 0.82rem; font-weight: 600; padding: 0.4rem 0.9rem;
  border-radius: 8px; cursor: pointer; flex-shrink: 0;
  background: var(--cat-color, var(--accent));
  color: #fff;
  border: 1px solid var(--cat-color, var(--accent));
  box-shadow: 0 1px 2px color-mix(in srgb, var(--cat-color, var(--accent)) 30%, transparent);
  transition: filter 0.12s, transform 0.06s;
}
.cat-btn-add:hover { filter: brightness(1.08); }
.cat-btn-add:active { transform: translateY(1px); }
.cat-btn-add:disabled { opacity: 0.55; cursor: not-allowed; }
.cat-btn-remove { font-size: 0.75rem; padding: 0.2rem 0.5rem; border-radius: 6px; cursor: pointer;
  background: transparent; border: 1px solid var(--border); color: var(--text-muted); transition: all 0.15s; flex-shrink: 0; }
.cat-btn-remove:hover { background: var(--error); color: #fff; border-color: var(--error); }

/* Subscribed state: kebab with Unfollow action (no text pill).
   Mirrors the /followed topic card kebab pattern. */
.disc-feed-actions {
  display: inline-flex; align-items: center; gap: 0.25rem;
  flex-shrink: 0; position: relative;
}
.disc-feed-menu-btn {
  width: 28px; height: 28px; display: inline-flex;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent;
  border-radius: 6px; color: var(--text-muted); cursor: pointer;
  transition: all 0.12s;
}
.disc-feed-menu-btn:hover {
  background: var(--bg-subtle); color: var(--text); border-color: var(--border);
}
.disc-feed-menu-pop {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 10;
  min-width: 150px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.08);
  padding: 0.25rem;
}
.disc-feed-menu-pop[hidden] { display: none; }
.disc-feed-menu-pop button {
  display: block; width: 100%; text-align: left;
  padding: 0.5rem 0.7rem; font-size: 0.85rem;
  background: transparent; border: none; color: var(--error);
  cursor: pointer; border-radius: 6px; font-family: inherit;
}
.disc-feed-menu-pop button:hover { background: var(--bg-subtle); }

/* Onboarding feed rows with toggle */
.ob-feed-row { display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.85rem;
  margin: 0.15rem 0.4rem; border-radius: 8px; cursor: pointer; transition: background 0.1s; }
.ob-feed-row:hover { background: var(--bg-subtle); }
.ob-select-all { display: flex; align-items: center; cursor: pointer; flex-shrink: 0; }
.ob-cat-grid { grid-template-columns: 1fr !important; }

/* Spinner for loading states */
.spinner {
  display: inline-block; width: 14px; height: 14px;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: spin 0.6s linear infinite;
  vertical-align: middle;
}

/* ==================== DISCOVER / CATALOG ==================== */
/* Smart search hero — shared by /discover AND /live */
.disc-hero-search { position: relative; width: 100%; box-sizing: border-box; }
.disc-hero-search input { width: 100%; padding: 0.7rem 2.5rem 0.7rem 2.5rem !important; font-size: 0.9rem;
  border: 1px solid var(--border); border-radius: 10px; background: var(--bg-card);
  box-shadow: 0 1px 4px rgba(0,0,0,0.04); transition: border-color 0.2s, box-shadow 0.2s; color: var(--text); }
.disc-hero-search input::placeholder { color: var(--text-muted); }
.disc-hero-search input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft), 0 1px 4px rgba(0,0,0,0.04); outline: none; }
.disc-hero-icon { position: absolute; left: 0.75rem; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; display: inline-flex; }
.disc-hero-clear {
  position: absolute; right: 0.55rem; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer; color: var(--text-muted);
  padding: 0.25rem; border-radius: 4px; display: inline-flex;
  align-items: center; justify-content: center;
}
.disc-hero-clear:hover { background: var(--bg-subtle); color: var(--text); }
.disc-url-detect { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.6rem 1rem; background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
  border-radius: 10px; font-size: 0.82rem; color: var(--accent); font-weight: 500;
  flex-wrap: wrap; /* prevent select + Subscribe from crashing into the message on mobile */ }
.disc-url-detect > * { min-width: 0; }
/* Make the inline form (select + Subscribe) behave as a row that can grow
   on wide screens and wrap below the message on narrow ones. */
#url-detect-form { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
#url-detect-form .disc-cat-select { max-width: 160px; }
@media (max-width: 480px) {
  .disc-url-detect #url-detect-msg { flex-basis: 100%; }
  #url-detect-form { flex-basis: 100%; justify-content: flex-end; }
  #url-detect-form .disc-cat-select { flex: 1 1 auto; max-width: none; }
}

/* Your feeds collapsible */
.disc-your-feeds { background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.disc-your-head { display: flex; align-items: center; justify-content: space-between; padding: 0.65rem 1rem;
  cursor: pointer; font-size: 0.85rem; font-weight: 600; list-style: none; }
.disc-your-head::-webkit-details-marker { display: none; }
.disc-your-count { font-size: 0.7rem; background: var(--accent); color: #fff; padding: 0.15rem 0.45rem;
  border-radius: 999px; margin-left: 0.3rem; font-weight: 500; }
.disc-your-list { border-top: 1px solid var(--border); }

/* Your feeds — category groups */
.disc-my-cat { border-bottom: 1px solid var(--border-light); }
.disc-my-cat:last-child { border-bottom: none; }
.disc-my-cat-head { display: flex; align-items: center; justify-content: space-between; padding: 0.5rem 1rem;
  cursor: pointer; font-size: 0.85rem; }
.disc-my-cat-name { font-weight: 500; }
.disc-my-cat-name em { font-style: normal; color: var(--text-muted); font-size: 0.75rem; margin-left: 0.25rem; }
.disc-my-chevron { color: var(--text-muted); transition: transform 0.2s; }
.disc-my-cat.open .disc-my-chevron { transform: rotate(180deg); }
.disc-my-feeds { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; }
.disc-my-cat.open .disc-my-feeds { max-height: 2000px; }
.disc-my-row { display: flex; align-items: center; gap: 0.5rem; padding: 0.55rem 1rem 0.55rem 1.5rem; font-size: 0.9rem; }
.disc-my-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.disc-my-info { flex: 1; min-width: 0; }
.disc-my-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 500; }
.disc-btn-rm { font-size: 0.8rem; padding: 0.2rem 0.55rem; border-radius: 6px; cursor: pointer;
  background: none; border: 1px solid var(--border); color: var(--text-muted); transition: all 0.15s; flex-shrink: 0; }
.disc-btn-rm:hover { background: var(--error); color: #fff; border-color: var(--error); }

/* Preview cards shown under a discovered feed so the user can see the
   kind of content it publishes before subscribing. */
.disc-preview-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem;
  margin-top: 0.5rem; width: 100%;
}
@media (max-width: 768px) {
  .disc-preview-grid { grid-template-columns: 1fr; }
}
.disc-preview-card {
  display: flex; flex-direction: column; gap: 0.4rem;
  padding: 0.6rem; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 8px;
  color: inherit; text-decoration: none !important;
  transition: border-color 0.15s, transform 0.1s;
  min-width: 0;
}
.disc-preview-card:hover { border-color: var(--accent); }
.disc-preview-img {
  width: 100%; height: 96px; object-fit: cover;
  border-radius: 6px; background: var(--bg-subtle);
}
.disc-preview-body { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
.disc-preview-title {
  font-size: 0.82rem; font-weight: 600; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.disc-preview-summary {
  font-size: 0.72rem; color: var(--text-muted); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.disc-preview-meta { font-size: 0.7rem; color: var(--text-muted); margin-top: auto; }

/* ================================================================= */
/* ======== /discover (Feeds) — email-style 2-pane layout ======== */
/* ================================================================= */
.feeds-shell {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 1.5rem;
  align-items: start;
}
.feeds-main { min-width: 0; display: flex; flex-direction: column; gap: 1rem; }

.feeds-sidebar {
  position: sticky; top: 4rem;
  align-self: start;
  background: transparent;
  border: none;
  border-right: 1px solid var(--border);
  border-radius: 0;
  display: flex; flex-direction: column;
  max-height: calc(100vh - 5rem);
  min-width: 0;
}
.feeds-sidebar-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--border);
}
.feeds-sidebar-title {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-muted);
}
.feeds-sidebar-count {
  font-size: 0.68rem; padding: 0.1rem 0.4rem;
  background: var(--bg-subtle); border-radius: 999px;
  color: var(--text-muted);
}
.feeds-sidebar-new {
  width: 26px; height: 26px; display: inline-flex;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent; border-radius: 4px;
  color: var(--text-muted); cursor: pointer; transition: all 0.12s;
}
.feeds-sidebar-new:hover { background: var(--bg-subtle); color: var(--accent); border-color: var(--border); }

.feeds-sidebar-tree {
  flex: 1; overflow-y: auto; padding: 0.5rem 0.4rem;
  min-height: 80px;
}
.feeds-sidebar-foot {
  display: flex; gap: 0.75rem; align-items: center;
  padding: 0.6rem 0.85rem;
  border-top: 1px solid var(--border);
  font-size: 0.72rem; color: var(--text-muted);
}
.fs-foot-link {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--text-muted); text-decoration: none; font-family: inherit;
  font-size: 0.72rem;
}
.fs-foot-link:hover { color: var(--accent); }

/* Folders */
.fs-folder { margin: 0; }
.fs-folder summary { list-style: none; cursor: pointer; }
.fs-folder summary::-webkit-details-marker { display: none; }
.fs-folder-head {
  display: flex; align-items: center; gap: 0.4rem;
  padding: 0.45rem 0.6rem; border-radius: 4px;
  font-size: 0.85rem; color: var(--text); font-weight: 500;
  min-width: 0;
}
.fs-folder-head:hover { background: var(--bg-subtle); }
.fs-folder-chevron { flex-shrink: 0; transition: transform 0.15s; color: var(--text-muted); }
.fs-folder[open] > summary .fs-folder-chevron { transform: rotate(180deg); }
.fs-folder-icon { flex-shrink: 0; color: var(--accent); }
.fs-folder-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fs-folder-count { font-size: 0.7rem; color: var(--text-muted); padding: 0 0.3rem; }
.fs-folder-menu-btn {
  width: 22px; height: 22px; display: inline-flex;
  align-items: center; justify-content: center; flex-shrink: 0;
  background: transparent; border: 1px solid transparent; border-radius: 5px;
  color: var(--text-muted); cursor: pointer; opacity: 0; transition: opacity 0.12s;
}
.fs-folder-head:hover .fs-folder-menu-btn,
.fs-folder-menu-btn:focus-visible { opacity: 1; }
.fs-folder-menu-btn:hover { background: var(--bg); border-color: var(--border); color: var(--text); }

/* Feeds inside a folder */
.fs-feed-list {
  list-style: none; padding: 0 0 0 1.35rem; margin: 0;
}
.fs-feed-item {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.4rem 0.6rem; border-radius: 4px;
  font-size: 0.84rem; color: var(--text); position: relative;
  min-width: 0; cursor: default;
}
.fs-feed-item:hover { background: var(--bg-subtle); }
.fs-feed-menu-btn {
  width: 18px; height: 18px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; border-radius: 4px;
  color: var(--text-muted); cursor: pointer; opacity: 0; transition: opacity 0.12s;
}
.fs-feed-item:hover .fs-feed-menu-btn,
.fs-feed-menu-btn:focus-visible { opacity: 1; }
.fs-feed-menu-btn:hover { background: var(--bg); color: var(--text); }
.fs-feed-favicon {
  width: 18px; height: 18px; flex-shrink: 0;
  border-radius: 3px; background: var(--bg-subtle);
  object-fit: cover;
}
.fs-feed-favicon--empty { background: var(--bg-subtle); }
.fs-feed-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fs-feed-dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
}
.fs-feed-dot--pending { background: var(--warning, #f59e0b); animation: cat-feed-dot-pulse 1.2s ease-in-out infinite; }
.fs-feed-dot--error { background: var(--error); }

.fs-empty {
  padding: 1.5rem 1rem; text-align: center;
  color: var(--text-muted); font-size: 0.8rem; line-height: 1.4;
}
.fs-empty p { margin: 0 0 0.3rem; }

/* Folder popup menu */
.fs-folder-menu {
  min-width: 200px; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.12);
  padding: 0.25rem; z-index: 1000;
}
.fs-folder-menu button {
  display: block; width: 100%; text-align: left;
  padding: 0.5rem 0.7rem; font-size: 0.85rem;
  background: transparent; border: none; color: var(--text);
  cursor: pointer; border-radius: 6px; font-family: inherit;
}
.fs-folder-menu button:hover { background: var(--bg-subtle); }
.fs-folder-menu button.fs-danger { color: var(--error); }

/* Modal — feed edit */
.fe-modal {
  position: fixed; inset: 0; z-index: 1100;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
}
.fe-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(0,0,0,0.4);
}
.fe-modal-box {
  position: relative; z-index: 1;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: 0 8px 40px rgba(0,0,0,0.2);
  width: 100%; max-width: 480px; max-height: 90vh;
  overflow: auto;
}
.fe-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1rem 1.25rem; border-bottom: 1px solid var(--border);
}
.fe-modal-head h3 { margin: 0; font-size: 1rem; font-weight: 700; }
.fe-modal-close {
  width: 32px; height: 32px; display: inline-flex;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent; border-radius: 8px;
  color: var(--text-muted); cursor: pointer;
}
.fe-modal-close:hover { background: var(--bg-subtle); color: var(--text); }
.fe-modal-form {
  padding: 1rem 1.25rem; display: flex; flex-direction: column; gap: 0.75rem;
}
.fe-modal-form label {
  display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.85rem;
}
.fe-modal-form label span { font-size: 0.75rem; color: var(--text-muted); font-weight: 600; }
.fe-modal-form input, .fe-modal-form select {
  width: 100%; font-size: 0.9rem;
  padding: 0.5rem 0.65rem; border: 1px solid var(--border);
  border-radius: 8px; background: var(--bg);
}
.fe-modal-form input:focus, .fe-modal-form select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.fe-modal-form input[readonly] {
  background: var(--bg-subtle); color: var(--text-muted);
  cursor: default; border-style: dashed;
}
.fe-modal-form input[readonly]:focus {
  box-shadow: none; border-color: var(--border);
}
.fe-error { font-size: 0.8rem; color: var(--error); margin: 0; }
.fe-hint { font-size: 0.75rem; color: var(--text-muted); margin: 0; line-height: 1.4; }
.fe-modal-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem; padding-top: 0.5rem;
}
.fe-modal-foot-right { display: inline-flex; gap: 0.5rem; }

/* Mobile: drawer for the sidebar */
.feeds-sidebar-backdrop {
  display: none; position: fixed; inset: 0; z-index: 90;
  background: rgba(0,0,0,0.35);
}
.feeds-sidebar-backdrop.open { display: block; }
.feeds-sidebar-toggle {
  display: none; width: 36px; height: 36px; flex-shrink: 0;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--border);
  border-radius: 8px; color: var(--text-muted); cursor: pointer;
  margin-top: 4px;
}
.feeds-sidebar-toggle:hover { background: var(--bg-subtle); color: var(--text); }
.feeds-main-title-wrap { display: flex; align-items: flex-start; gap: 0.6rem; min-width: 0; }

@media (max-width: 900px) {
  .feeds-shell { grid-template-columns: 1fr; }
  .feeds-sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: 280px; max-width: 85vw; max-height: none;
    border-radius: 0; border-right: 1px solid var(--border);
    transform: translateX(-100%); transition: transform 0.25s ease;
    z-index: 100;
  }
  .feeds-sidebar.open { transform: translateX(0); }
  .feeds-sidebar-toggle { display: inline-flex; }
}

/* ---- Discover page: chip-tag filter + flat feed-card grid ----
   On desktop the bar wraps on multiple rows so every tag stays clickable
   without horizontal scrolling (which is awkward with a mouse). On mobile
   we switch to a single scrollable row because touch-drag handles that
   natively and saves vertical space on small screens. */
/* ============================================================
   Calm mode (universal, 2026-05) — when the user toggles
   "Calm mode" in /settings, the body gets data-calm-mode="true"
   and these rules hide every numeric counter across the app:
     - sidebar feed unread counts ("99+" pills)
     - folder counts in the sidebar tree
     - tier-bar quotas on the dashboard ("16/200 Feeds")
     - discover catalog count badges
     - briefings hub total/pending counters
   The articles themselves stay accessible — calm mode is purely
   visual. Toggle off → counters reappear with no data lost.
   Validated request from r/rss community ("Current" reader).
   ============================================================ */
body[data-calm-mode="true"] .fs-feed-unread,
body[data-calm-mode="true"] .fs-folder-count,
body[data-calm-mode="true"] .app-sidebar-discovery-count,
body[data-calm-mode="true"] .dash-tier-bar,
body[data-calm-mode="true"] .following-hero-count,
body[data-calm-mode="true"] .brief-pill-pending em,
body[data-calm-mode="true"] .disc-tag-count,
body[data-calm-mode="true"] .disc-feed-card .disc-feed-meta,
body[data-calm-mode="true"] .briefings-pager-count {
  display: none !important;
}
/* Pending pill keeps its color but loses the (count) — the
   "pending" word stays so the user still sees there's review work,
   just not the anxiety-inducing number. */
body[data-calm-mode="true"] .brief-pill-pending::before {
  content: 'pending';
  text-transform: lowercase;
}
body[data-calm-mode="true"] .brief-pill-pending {
  font-size: 0;
}
body[data-calm-mode="true"] .brief-pill-pending::before {
  font-size: 0.78rem;
}

/* Starter Kits — curated bundles surfaced above the catalog tagbar.
   The grid auto-fits, so 2-6 kits render cleanly across viewports
   without media queries. Hidden once a user has 30+ feeds (template
   gate) — at that point they're past the discovery phase. */
.starter-kits {
  margin: 0.75rem 0 1.5rem;
}
.starter-kits-head {
  display: flex; align-items: baseline; gap: 0.6rem;
  margin-bottom: 0.6rem; flex-wrap: wrap;
}
.starter-kits-head h2 {
  font-size: 1.05rem; font-weight: 700; margin: 0;
}
.starter-kits-head p {
  margin: 0; color: var(--text-muted); font-size: 0.8rem;
}
/* Wrapper hosts the strip + the prev/next nav buttons + edge fade
   gradients. Position relative so absolute children anchor here. */
.starter-kits-strip-wrap {
  position: relative;
}
/* Edge fade gradients — visual hint that there's more off-screen.
   Pointer-events: none so they don't intercept clicks on the cards
   underneath. */
.starter-kits-strip-wrap::before,
.starter-kits-strip-wrap::after {
  content: "";
  position: absolute; top: 0; bottom: 0;
  width: 36px; pointer-events: none; z-index: 2;
  transition: opacity 0.15s;
}
.starter-kits-strip-wrap::before {
  left: 0;
  background: linear-gradient(to right, var(--bg) 0%, transparent 100%);
}
.starter-kits-strip-wrap::after {
  right: 0;
  background: linear-gradient(to left, var(--bg) 0%, transparent 100%);
}
/* Prev/next arrow buttons — circular, overlay the strip edges.
   Visible only on viewports with hover (desktop); on touch screens
   the user swipes naturally. JS toggles [hidden] when at the
   start/end so they don't suggest scrolling that won't happen. */
.starter-kits-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  z-index: 3;
  width: 36px; height: 36px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  background: var(--bg-card); color: var(--text);
  border: 1px solid var(--border);
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  cursor: pointer; padding: 0;
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
}
.starter-kits-nav:hover {
  background: var(--accent); color: #fff;
  border-color: var(--accent);
  transform: translateY(-50%) scale(1.06);
}
.starter-kits-nav[hidden] { display: none !important; }
.starter-kits-nav-prev { left: 0; }
.starter-kits-nav-next { right: 0; }
@media (hover: hover) and (pointer: fine) {
  .starter-kits-nav:not([hidden]) { display: flex; }
}
/* Single horizontal scrolling row — same pattern as the dashboard
   edition chip strip. 15 kits don't fit on one screen by design;
   the user swipes/scrolls horizontally. Hidden scrollbar, scroll-
   snap so each card lands cleanly at the left edge. */
.starter-kits-grid {
  display: flex; gap: 0.65rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Negative margin lets the strip bleed to the viewport edges,
     hinting that there's more content off-screen. Counter padding
     restores the inner spacing. */
  margin-left: -0.75rem;
  margin-right: -0.75rem;
  padding: 0.25rem 0.75rem 0.5rem;
}
.starter-kits-grid::-webkit-scrollbar { display: none; }
.starter-kit-card {
  display: flex; flex-direction: column; gap: 0.5rem;
  padding: 0.85rem 1rem; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 12px;
  transition: border-color 0.15s, transform 0.15s;
  flex: 0 0 260px;     /* fixed card width — predictable horizontal rhythm */
  scroll-snap-align: start;
}
.starter-kit-card:hover { border-color: var(--accent); transform: translateY(-1px); }
.starter-kit-head {
  display: flex; align-items: center; gap: 0.5rem;
}
.starter-kit-icon {
  font-size: 1.4rem; line-height: 1; flex-shrink: 0;
  width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
  background: var(--bg-subtle); border-radius: 8px;
}
.starter-kit-name {
  font-size: 0.95rem; font-weight: 700; margin: 0;
  color: var(--text);
}
.starter-kit-desc {
  font-size: 0.8rem; color: var(--text-muted); margin: 0;
  line-height: 1.4; flex-grow: 1;
}
.starter-kit-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem; padding-top: 0.4rem; margin-top: auto;
  border-top: 1px dashed var(--border);
}
.starter-kit-count {
  font-size: 0.72rem; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.starter-kit-add { white-space: nowrap; flex-shrink: 0; }
@media (max-width: 600px) {
  .starter-kit-card { flex-basis: 240px; }
}

.disc-tagbar {
  display: flex; flex-wrap: wrap; gap: 0.35rem;
  padding: 0.5rem 0; margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: var(--bg);
  z-index: 5;
}
@media (max-width: 768px) {
  .disc-tagbar {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .disc-tagbar::-webkit-scrollbar { display: none; }
}
.disc-tag {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.35rem 0.75rem; font-size: 0.8rem; font-weight: 500;
  border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg-card); color: var(--text-muted);
  cursor: pointer; white-space: nowrap; transition: all 0.12s;
  flex-shrink: 0;
}
.disc-tag:hover { border-color: var(--accent); color: var(--accent); }
.disc-tag.active {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}
.disc-tag-count {
  font-size: 0.65rem; padding: 0 0.3rem; background: var(--bg-subtle);
  border-radius: 999px; color: inherit; opacity: 0.7;
}
.disc-tag.active .disc-tag-count { background: var(--bg-card); opacity: 1; }

/* Hashtag shortcut chips — quick filters that drop their term into the
   search box. Smaller and visually distinct from the macro-category chips
   so the user reads them as "filters within the catalog" not "categories". */
.disc-hashbar {
  display: flex; flex-wrap: wrap; gap: 0.3rem;
  padding: 0.4rem 0; margin-bottom: 0.4rem;
}
@media (max-width: 768px) {
  .disc-hashbar {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .disc-hashbar::-webkit-scrollbar { display: none; }
}
.disc-hashtag {
  font-size: 0.72rem; padding: 0.2rem 0.55rem;
  border-radius: 999px; border: 1px solid var(--border);
  background: transparent; color: var(--text-muted);
  cursor: pointer; white-space: nowrap; transition: all 0.12s;
  flex-shrink: 0; font-family: inherit;
}
.disc-hashtag:hover { color: var(--accent); border-color: var(--accent); }
.disc-hashtag.active {
  background: var(--accent); color: #fff; border-color: var(--accent);
}

.disc-feeds-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.9rem;
}
@media (max-width: 768px) { .disc-feeds-grid { grid-template-columns: 1fr; gap: 0.7rem; } }
.disc-feed-card {
  display: flex; flex-direction: column; gap: 0.55rem;
  padding: 0.95rem 1rem; background: var(--bg-card);
  border: 1px solid color-mix(in srgb, var(--border) 140%, var(--text) 3%);
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.025);
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.1s;
  min-width: 0; overflow: hidden;
}
.disc-feed-card:hover {
  border-color: color-mix(in srgb, var(--accent) 50%, var(--border));
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05);
}
/* Selected state (onboarding catalog toggle checked) — accent border +
   soft tint so the card visually "lights up" without shifting layout. */
.ob-feed-card:has(.ob-feed-cb:checked) {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent-soft) 60%, var(--bg-card));
  box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 15%, transparent);
}
.disc-feed-head {
  display: flex; align-items: flex-start; gap: 0.6rem;
  min-width: 0;
}
.disc-feed-icon {
  width: 36px; height: 36px; flex-shrink: 0;
  border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--cat-color, var(--accent)) 15%, transparent);
  color: var(--cat-color, var(--accent));
  overflow: hidden; position: relative;
}
.disc-feed-icon svg { width: 16px; height: 16px; }
.disc-feed-favicon {
  width: 100%; height: 100%; object-fit: cover; border-radius: 8px;
  background: #fff;
}
/* Category svg acts as a fallback: hidden while the favicon is present,
   shown when the onerror handler adds .no-favicon (or if there is no URL). */
.disc-feed-icon-fallback { display: none; align-items: center; justify-content: center; }
.disc-feed-icon.no-favicon .disc-feed-icon-fallback,
.disc-feed-icon:not(:has(.disc-feed-favicon)) .disc-feed-icon-fallback {
  display: inline-flex;
}
.disc-feed-text { flex: 1; min-width: 0; overflow: hidden; }
.disc-feed-name { font-size: 0.9rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.disc-feed-desc {
  font-size: 0.78rem; color: var(--text-muted); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; margin-top: 0.1rem;
}
.disc-feed-cat {
  font-size: 0.65rem; color: var(--text-muted); text-transform: uppercase;
  letter-spacing: 0.04em; margin-top: 0.25rem; opacity: 0.7;
}
.disc-feed-url {
  display: block; font-size: 0.72rem; color: var(--text-muted);
  margin-top: 0.2rem; overflow-wrap: anywhere; word-break: break-word;
  text-decoration: none !important; opacity: 0.75;
  max-width: 100%;
}
.disc-feed-url:hover { color: var(--accent); opacity: 1; }
.disc-feed-preview-slot { min-width: 0; overflow: hidden; }

/* ================================================================= */
/* ============= /followed page — senior-UX redesign ============= */
/* ================================================================= */

.following-layout {
  display: flex; flex-direction: column; gap: 0.85rem;
}

/* Compact hero (desktop + mobile friendly). The title row is a single
   horizontal line: title + count + actions. The optional subtitle goes
   below, and collapses on narrow viewports to save vertical real-estate. */
.following-hero { padding: 0; }
.following-hero-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; flex-wrap: nowrap;
}
.following-hero-title {
  font-size: 1.35rem; font-weight: 800; letter-spacing: -0.01em;
  margin: 0; color: var(--text); line-height: 1.15;
}
.following-hero-sub {
  font-size: 0.82rem; color: var(--text-muted);
  margin: 0.3rem 0 0; line-height: 1.4;
}
.following-hero-sub a { color: var(--accent); text-decoration: none; }
.following-hero-sub a:hover { text-decoration: underline; }
.following-hero-sub strong { color: var(--text); font-weight: 600; }
.following-hero-count {
  display: inline-flex; align-items: baseline; gap: 0.2rem;
  padding: 0.28rem 0.6rem;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 999px; font-size: 0.75rem; color: var(--text-muted);
  white-space: nowrap; font-weight: 500;
}
.following-hero-count strong {
  color: var(--accent); font-size: 0.9rem; font-weight: 700;
}
.following-hero-text { flex: 1; min-width: 0; }
.following-hero-actions {
  display: inline-flex; align-items: center; gap: 0.4rem;
  flex-shrink: 0; flex-wrap: nowrap; justify-content: flex-end;
}

/* Obsolete — replaced by .page-hamburger-mobile outside the hero. Keep
   empty selectors so old caches don't 404 on rules. */
.settings-hero-titlerow { display: contents; }

/* --- Mobile: drop the subtitle so the hero is a single tight row --- */
@media (max-width: 767px) {
  .following-layout { gap: 0.6rem; }
  .following-hero-title { font-size: 1.15rem; }
  .following-hero-sub { display: none; }
  .following-hero-count {
    padding: 0.2rem 0.5rem; font-size: 0.7rem;
  }
  .following-hero-count strong { font-size: 0.82rem; }
}
@media (min-width: 1024px) {
  .following-hero-title { font-size: 1.5rem; }
}

/* Legacy settings-hero styles removed — hero now uses .following-hero only. */

/* ===== "Follow a new topic" CTA — prominent card with accent-tinted CTA ===== */
.follow-new-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 12px; overflow: hidden;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.follow-new-card:hover {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
  box-shadow: 0 2px 10px rgba(0,0,0,0.04);
}
.follow-new-summary {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.9rem 1rem; cursor: pointer; list-style: none;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--accent-soft) 70%, transparent),
    color-mix(in srgb, var(--accent-soft) 20%, transparent));
  transition: background 0.15s;
}
.follow-new-summary::-webkit-details-marker { display: none; }
.follow-new-summary::marker { content: ''; }
.follow-new-card[open] .follow-new-summary {
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--border);
}
.follow-new-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex-shrink: 0;
  background: var(--accent); color: #fff; border-radius: 8px;
}
.follow-new-label { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.follow-new-title {
  font-size: 0.92rem; font-weight: 700; color: var(--text);
}
.follow-new-hint {
  font-size: 0.75rem; color: var(--text-muted); line-height: 1.3;
}
.follow-new-chevron {
  color: var(--text-muted); flex-shrink: 0;
  transition: transform 0.2s;
}
.follow-new-card[open] .follow-new-chevron { transform: rotate(180deg); }
.follow-new-card .follow-custom-form {
  padding: 1rem 1.1rem 1.15rem;
  display: flex; flex-direction: column; gap: 0.9rem;
}

/* ============= Follow a topic form (top of /followed) ============= */
.follow-custom-field {
  display: flex; flex-direction: column; gap: 0.4rem;
}
.follow-custom-field > label {
  font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); margin: 0;
}
.follow-custom-input {
  width: 100%; font-size: 0.9rem;
  padding: 0.55rem 0.7rem; border-radius: 8px;
  border: 1px solid var(--border); background: var(--bg);
  color: var(--text); min-width: 0;
}
.follow-custom-input:focus {
  border-color: var(--accent); outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.follow-custom-row {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: stretch;
}
.follow-custom-input--kw { flex: 1 1 240px; }
.follow-custom-actions {
  display: flex; justify-content: flex-end;
  padding-top: 0.35rem; border-top: 1px solid var(--border-light);
}
.follow-custom-desc {
  font-size: 0.75rem; color: var(--text-muted);
  margin: 0.35rem 0 0; line-height: 1.4;
}
.follow-custom-desc code {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.9em; padding: 0.05rem 0.3rem;
  background: var(--bg-subtle); border-radius: 3px;
  color: var(--text);
}
.follow-custom-warning {
  font-size: 0.75rem; color: var(--warning, #b45309);
  margin: 0.35rem 0 0; line-height: 1.4;
}
.follow-custom-error {
  font-size: 0.78rem; color: var(--error);
  margin: 0.5rem 0 0 1.1rem;
}
.follow-op-toggle {
  display: inline-flex; border: 1px solid var(--border); border-radius: 8px;
  overflow: hidden; font-size: 0.78rem; background: var(--bg);
  flex-shrink: 0;
}
.follow-op-toggle label {
  display: inline-flex; align-items: center; padding: 0 0.65rem; height: 100%;
  cursor: pointer; color: var(--text-muted); transition: all 0.12s;
  font-weight: 600; letter-spacing: 0.02em;
}
.follow-op-toggle label + label { border-left: 1px solid var(--border); }
.follow-op-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.follow-op-toggle label:has(input:checked) {
  background: var(--accent-soft); color: var(--accent);
}

.follow-advanced summary {
  font-size: 0.78rem; color: var(--text-muted); cursor: pointer;
  padding: 0.25rem 0;
}
.follow-advanced summary:hover { color: var(--text); }

/* Segmented control that switches between "Keywords" and "Advanced" mode
   inside a single form block. Clicking converts the value in place. */
.follow-mode-toggle {
  display: inline-flex; background: var(--bg-subtle);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 2px; font-size: 0.78rem;
  margin-bottom: 0.1rem;
}
.follow-mode-toggle button {
  padding: 0.3rem 0.75rem; border: none; border-radius: 6px;
  background: transparent; color: var(--text-muted); cursor: pointer;
  font-weight: 600; transition: all 0.12s; font-family: inherit;
}
.follow-mode-toggle button.active {
  background: var(--bg-card); color: var(--text);
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
.follow-mode-toggle button:hover:not(.active) { color: var(--text); }

/* ==================================================================
   Follow topic cards — 4-zone stratified layout for clear hierarchy:
     Zone 1  HEAD     accent-tinted band (title + meta + kebab)
     Zone 2  TRACKING subtle bg, labeled, shows the query pills/string
     Zone 3  TABS     plain bg-card, strong active indicator
     Zone 4  CONTENT  default bg, article flow
   ================================================================== */
.following-list { display: flex; flex-direction: column; gap: 1rem; }
.follow-topic-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 14px; overflow: hidden; min-width: 0;
  transition: opacity 0.3s, border-color 0.15s, box-shadow 0.15s;
}
.follow-topic-card:hover {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
  box-shadow: 0 2px 12px rgba(0,0,0,0.05);
}

/* ---- Zone 1: HEAD ---- */
.follow-topic-head {
  display: flex; align-items: flex-start; gap: 0.5rem;
  padding: 1rem 1rem 0.85rem;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--accent-soft) 55%, transparent),
    color-mix(in srgb, var(--accent-soft) 15%, transparent) 60%,
    transparent);
  border-bottom: 1px solid var(--border-light);
  min-width: 0;
}
.follow-topic-title-block { flex: 1; min-width: 0; }
.follow-topic-title {
  font-size: 1.2rem; font-weight: 700; color: var(--text);
  margin: 0 0 0.45rem; line-height: 1.2; word-break: break-word;
  letter-spacing: -0.01em;
}
.follow-topic-meta {
  display: flex; flex-wrap: wrap; gap: 0.35rem 0.75rem; align-items: center;
  font-size: 0.73rem; color: var(--text-muted);
}
.follow-topic-date {
  display: inline-flex; align-items: center; gap: 0.3rem;
  opacity: 0.9;
}
.follow-topic-date svg { opacity: 0.7; }
.follow-topic-link {
  color: var(--accent); text-decoration: none; font-weight: 600;
}
.follow-topic-link:hover { text-decoration: underline; }

/* Kebab (…) menu */
.follow-topic-menu { position: relative; flex-shrink: 0; }
.follow-topic-menu-btn {
  width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent; border-radius: 8px;
  color: var(--text-muted); cursor: pointer; transition: all 0.12s;
}
.follow-topic-menu-btn:hover { background: var(--bg-card); color: var(--text); border-color: var(--border); }
.follow-topic-menu-pop {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 10;
  min-width: 140px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.08);
  padding: 0.25rem;
}
.follow-topic-menu-pop button {
  display: block; width: 100%; text-align: left;
  padding: 0.5rem 0.7rem; font-size: 0.85rem;
  background: transparent; border: none; color: var(--error);
  cursor: pointer; border-radius: 6px;
}
.follow-topic-menu-pop button:hover { background: var(--bg-subtle); }

/* ---- Zone 2: TRACKING (query summary) ---- */
.follow-kw-zone {
  display: flex; align-items: flex-start; gap: 0.75rem;
  padding: 0.75rem 1rem 0.85rem;
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--border-light);
}
.follow-kw-label {
  font-size: 0.65rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted);
  padding-top: 0.3rem; flex-shrink: 0;
}
.follow-kw-block {
  display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center;
  flex: 1; min-width: 0;
}
.follow-kw-pill {
  font-size: 0.76rem; font-weight: 500;
  padding: 0.22rem 0.55rem; border-radius: 999px;
  background: var(--bg-card); color: var(--text);
  border: 1px solid var(--border);
}
.follow-kw-op {
  font-size: 0.66rem; font-weight: 700; color: var(--accent);
  letter-spacing: 0.08em;
  padding: 0.12rem 0.35rem; border-radius: 4px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.follow-kw-query {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.78rem; color: var(--text);
  background: var(--bg-card); border: 1px solid var(--border);
  padding: 0.45rem 0.65rem; border-radius: 6px;
  word-break: break-all; width: 100%;
  border-left: 3px solid var(--accent);
  display: block;
}

/* ---- Zone 3: TABS ---- */
.follow-tabs {
  display: flex; align-items: center; gap: 0;
  border-bottom: 1px solid var(--border);
  background: var(--bg-card);
  overflow-x: auto; scrollbar-width: none;
  padding: 0 0.35rem;
}
.follow-tabs::-webkit-scrollbar { display: none; }
.follow-tab {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.75rem 0.85rem; min-height: 44px;
  background: transparent; border: none;
  color: var(--text-muted); font-size: 0.82rem; font-weight: 600;
  cursor: pointer; white-space: nowrap; transition: all 0.12s;
  font-family: inherit;
  position: relative;
}
.follow-tab::after {
  content: ''; position: absolute; left: 0.3rem; right: 0.3rem; bottom: -1px;
  height: 2px; background: transparent; border-radius: 2px 2px 0 0;
  transition: background 0.15s;
}
.follow-tab:hover { color: var(--text); }
.follow-tab.active { color: var(--accent); }
.follow-tab.active::after { background: var(--accent); }
.follow-tab svg { opacity: 0.85; flex-shrink: 0; }
.follow-tab.active svg { opacity: 1; }

/* ---- Zone 4: CONTENT ---- */
.follow-tab-panel { padding: 1rem 1.1rem 1.15rem; min-width: 0; overflow: hidden; }
.follow-tab-empty {
  display: flex; flex-direction: column; gap: 0.35rem;
  padding: 1.5rem 1rem; text-align: center; color: var(--text-muted);
}
.follow-tab-empty strong { color: var(--text); font-size: 0.95rem; font-weight: 600; }
.follow-tab-empty p { font-size: 0.82rem; margin: 0; line-height: 1.4; }

/* ============= Bookmark cards (same visual language) ============= */
.bookmark-card {
  display: flex; align-items: flex-start; gap: 0.75rem;
  padding: 0.85rem 1rem;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 12px; transition: border-color 0.15s, box-shadow 0.15s;
  min-width: 0;
}
.bookmark-card:hover {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
  box-shadow: 0 2px 10px rgba(0,0,0,0.04);
}
.bookmark-favicon {
  width: 28px; height: 28px; flex-shrink: 0;
  border-radius: 6px; overflow: hidden;
  background: var(--bg-subtle);
  display: flex; align-items: center; justify-content: center;
}
.bookmark-favicon img { width: 100%; height: 100%; object-fit: cover; }
.bookmark-body { flex: 1; min-width: 0; }
.bookmark-title {
  display: block; font-size: 0.92rem; font-weight: 600;
  color: var(--text); line-height: 1.35; text-decoration: none;
  word-break: break-word;
}
.bookmark-title:hover { color: var(--accent); }
.bookmark-meta {
  display: flex; flex-wrap: wrap; gap: 0.4rem 0.65rem; align-items: center;
  font-size: 0.72rem; color: var(--text-muted); margin-top: 0.3rem;
}
.bookmark-source { font-weight: 500; }
.bookmark-date { opacity: 0.85; }

.bookmark-pager {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 1rem; padding: 1rem 0; font-size: 0.85rem;
}
.bookmark-pager > :first-child { justify-self: start; }
.bookmark-pager > :last-child { justify-self: end; }
.bookmark-pager-info { color: var(--text-muted); }

/* Empty state (no topics) */
.follow-empty {
  text-align: center; padding: 3rem 1.5rem;
  background: var(--bg-card); border: 1px dashed var(--border);
  border-radius: 14px;
}
.follow-empty svg { color: var(--text-muted); opacity: 0.3; margin: 0 auto 0.75rem; display: block; }
.follow-empty h2 { font-size: 1.15rem; font-weight: 700; margin: 0 0 0.4rem; }
.follow-empty p { color: var(--text-muted); font-size: 0.88rem; margin: 0; max-width: 42ch; margin-left: auto; margin-right: auto; line-height: 1.45; }
/* Compact variant for "no search matches" under a full list */
.follow-empty-inline { padding: 1.75rem 1rem; background: transparent; border: none; }

/* Mobile tweaks */
@media (max-width: 640px) {
  .follow-topic-head { padding: 0.85rem 0.85rem 0.7rem; }
  .follow-kw-zone { padding: 0.6rem 0.85rem 0.7rem; gap: 0.5rem; flex-wrap: wrap; }
  .follow-kw-label { padding-top: 0; }
  .follow-tab { padding: 0.65rem 0.75rem; font-size: 0.78rem; min-height: 40px; }
  .follow-tab-panel { padding: 0.9rem 0.9rem 1rem; }
  .follow-topic-title { font-size: 1.05rem; }
  .follow-new-summary { padding: 0.75rem 0.85rem; gap: 0.6rem; }
  .follow-new-icon { width: 28px; height: 28px; }
  .follow-new-title { font-size: 0.88rem; }
  .follow-new-hint { font-size: 0.72rem; }
}

/* ============= Expandable panes under each topic card ============= */
.follow-pane {
  margin-top: 0.75rem; padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  min-width: 0; overflow: hidden;
}

.follow-sources-note {
  font-size: 0.75rem; color: var(--text);
  padding: 0.5rem 0.7rem;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  margin-bottom: 0.6rem;
  line-height: 1.4;
}
.disc-feed-preview-slot { min-height: 1px; }
.disc-feed-preview-slot .disc-preview-grid { margin-top: 0; }
.disc-feed-preview-skeleton {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem;
}
.disc-feed-preview-skeleton > div {
  height: 90px; background: var(--bg-subtle); border-radius: 6px;
  animation: disc-skel-pulse 1.6s ease-in-out infinite;
}
@keyframes disc-skel-pulse { 0%, 100% { opacity: 0.6; } 50% { opacity: 1; } }

/* Eye-icon button on each catalog feed row that reveals a lazy-loaded
   preview underneath. */
.cat-btn-preview {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; flex-shrink: 0;
  border: 1px solid var(--border); border-radius: 6px;
  background: none; color: var(--text-muted); cursor: pointer;
  transition: all 0.12s;
}
.cat-btn-preview:hover { border-color: var(--accent); color: var(--accent); }
.cat-btn-preview.active { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.cat-btn-preview:disabled { opacity: 0.5; cursor: not-allowed; }
/* The expanded preview block sits between two <div class="cat-feed"> rows.
   Slight indent so it visually belongs to the feed above it. */
.cat-feed-preview {
  padding: 0.4rem 0 0.5rem 1.2rem;
  margin-bottom: 0.25rem;
  border-left: 2px solid var(--border-light);
}

/* Shared small utility chip used inside cat-divider for non-destructive
   actions like Rename, Export, Import. Same geometry as .disc-btn-rm but
   a neutral (accent) hover instead of the red used for destructive ones. */
.disc-btn-util { font-size: 0.8rem; padding: 0.35rem 0.6rem; border-radius: 6px; cursor: pointer;
  background: none; border: 1px solid var(--border); color: var(--text-muted);
  transition: all 0.15s; flex-shrink: 0; display: inline-flex; align-items: center;
  gap: 0.35rem; white-space: nowrap;
  text-decoration: none !important; line-height: 1.2; font-family: inherit; font-weight: 500;
  text-transform: none; letter-spacing: normal;
}
.disc-btn-util svg { flex-shrink: 0; opacity: 0.8; }
.disc-btn-util:hover { border-color: var(--accent); color: var(--accent); background: var(--bg-card); }
.disc-btn-util:hover svg { opacity: 1; }
.disc-btn-util-form { display: inline-flex; margin: 0; }
.disc-btn-util.active { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
.disc-btn-util--primary {
  background: var(--accent); color: #fff !important; border-color: var(--accent);
}
.disc-btn-util--primary:hover {
  background: var(--accent); color: #fff !important; border-color: var(--accent);
  filter: brightness(0.95);
}
.disc-btn-util--primary svg { opacity: 0.9; }
.disc-scan-list { display: flex; flex-direction: column; gap: 0.4rem; width: 100%; }
.disc-alert-compact { margin: 0.5rem 0; font-size: 0.78rem; padding: 0.45rem 0.65rem; }
.disc-subscribe-btn { font-weight: 600; }
.disc-scan-status { color: var(--text-muted); font-size: 0.78rem; }
.social-feed-add { padding: 0.75rem; }
.social-feed-form { display: flex; gap: 0.35rem; }
.social-feed-input { flex: 1; min-width: 0; font-size: 0.82rem; }
.social-feed-hint { font-size: 0.75rem; margin: 0.3rem 0 0; }

/* Custom add form */
.disc-custom-add { background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 1rem; }
.disc-custom-form { display: grid; grid-template-columns: 1fr 1.5fr 1fr auto; gap: 0.5rem; align-items: center; }
@media (max-width: 640px) { .disc-custom-form { grid-template-columns: 1fr; } }
.disc-custom-form input { font-size: 0.875rem; }
.disc-section-label {
  font-size: 0.82rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-muted);
  padding: 0.65rem 0 0.25rem; border-bottom: 1px solid var(--border);
  margin-bottom: 0.75rem;
}
/* Recommended banner */
.disc-recommended {
  background: linear-gradient(135deg, var(--accent-soft) 0%, transparent 60%);
  border: 1px solid color-mix(in srgb, var(--accent) 15%, var(--border));
  border-radius: 12px; padding: 1rem 1.25rem;
}
.disc-recommended .disc-section-label { color: var(--accent); border-bottom-color: color-mix(in srgb, var(--accent) 20%, transparent); }
/* Category card */
.disc-cat {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden; transition: border-color 0.15s;
}
.disc-cat:hover { border-color: var(--text-muted); }
.disc-cat-head {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.7rem 0.85rem; cursor: pointer; transition: background 0.1s;
}
.disc-cat-head:hover { background: var(--bg-subtle); }
.disc-cat-icon { font-size: 1.15rem; line-height: 1; flex-shrink: 0; }
.disc-cat-info { flex: 1; min-width: 0; }
.disc-cat-name { font-size: 0.82rem; font-weight: 600; color: var(--text); }
.disc-cat-name span { font-weight: 400; color: var(--text-muted); font-size: 0.8rem; margin-left: 0.3rem; }
.disc-cat-desc { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.1rem; line-height: 1.3; }
.disc-cat-chevron {
  color: var(--text-muted); flex-shrink: 0; transition: transform 0.25s ease;
}
.disc-cat.open .disc-cat-chevron { transform: rotate(180deg); }
/* Feed list inside category */
.disc-cat-feeds {
  max-height: 0; overflow: hidden; transition: max-height 0.35s ease;
}
.disc-cat.open .disc-cat-feeds { max-height: 2000px; }
.disc-cat-feeds-inner { border-top: 1px solid var(--border); }
.disc-feed {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.45rem 0.85rem; border-bottom: 1px solid var(--border-light);
  transition: background 0.1s;
}
.disc-feed:last-child { border-bottom: none; }
.disc-feed:hover { background: var(--bg-subtle); }
.disc-feed-dot {
  width: 5px; height: 5px; border-radius: 50%; flex-shrink: 0;
  background: var(--text-muted); opacity: 0.5;
}
.disc-feed-info { flex: 1; min-width: 0; overflow: hidden; }
.disc-feed-name { font-size: 0.8rem; font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.disc-feed-desc { font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.disc-feed .btn { flex-shrink: 0; }
.disc-cat-select {
  font-size: 0.82rem; padding: 0.2rem 0.4rem !important; border-radius: 5px;
  border: 1px solid var(--border); background: var(--bg-card); color: var(--text-muted);
  max-width: 130px; width: auto; flex-shrink: 0; cursor: pointer;
}
.disc-cat-select:hover { border-color: var(--accent); color: var(--text); }
/* Popular row */
.disc-popular {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.6rem 0.75rem; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 10px; margin-bottom: 0.4rem; transition: all 0.15s;
}
.disc-popular:hover { border-color: var(--text-muted); }
.disc-popular-info { flex: 1; min-width: 0; display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; overflow: hidden; }
.disc-popular-name { font-size: 0.82rem; font-weight: 500; color: var(--text); }
.disc-popular-url { font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 250px; }
@media (max-width: 767px) {
  .disc-popular-url { display: none; }
  .disc-recommended { padding: 0.75rem; }
}

/* ==================== INTEREST TILES (shared: onboarding + discover) ==================== */
.ob-interest-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.6rem; }
.ob-interest { display: flex; flex-direction: column; align-items: center; gap: 0.2rem; padding: 0.9rem 0.5rem;
    border: 2px solid var(--border); border-radius: 10px; background: var(--bg-card); cursor: pointer;
    transition: all 0.2s; position: relative; text-align: center; font: inherit; color: var(--text); }
.ob-interest:hover { border-color: var(--text-muted); background: var(--bg-subtle); }
.ob-interest.selected { border-color: var(--accent); background: var(--accent-light); }
.ob-interest.expanded { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ob-interest-icon { font-size: 1.5rem; line-height: 1; }
.ob-interest-name { font-size: 0.78rem; font-weight: 600; line-height: 1.2; }
.ob-interest-count { font-size: 0.62rem; color: var(--text-muted); }
.ob-interest-check { display: none; position: absolute; top: 0.35rem; right: 0.35rem; color: var(--accent); }
.ob-interest.selected .ob-interest-check { display: block; }
/* Detail panel (expanded feeds) */
.ob-detail { margin-top: 0.5rem; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-card); overflow: hidden; }
.ob-detail-head { display: flex; justify-content: space-between; align-items: center;
    padding: 0.6rem 1rem; border-bottom: 1px solid var(--border); background: var(--bg-subtle); }
.ob-detail-title { font-weight: 600; font-size: 0.82rem; }
.ob-detail-all { display: flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; cursor: pointer; white-space: nowrap; }
.ob-detail-feeds { padding: 0.4rem 0.5rem; display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.15rem; }
.ob-detail-feed { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.5rem; border-radius: 6px;
    cursor: pointer; font-weight: normal; }
.ob-detail-feed:hover { background: var(--bg-subtle); }
.ob-detail-feed-info { display: flex; flex-direction: column; min-width: 0; }
.ob-detail-feed-info strong { font-size: 0.78rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ob-detail-feed-info span { font-size: 0.82rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Category groups */
.ob-group { margin-bottom: 1.25rem; }
.ob-group-header { font-size: 0.8rem; font-weight: 700; color: var(--text-muted); text-transform: uppercase;
    letter-spacing: 0.06em; margin-bottom: 0.5rem; padding-left: 0.15rem; }
/* Discover detail feed row (with Add button) */
.disc-detail-feed { display: flex; align-items: center; gap: 0.5rem; padding: 0.45rem 0.5rem; border-radius: 6px; overflow: hidden; }
.disc-detail-feed:hover { background: var(--bg-subtle); }
.disc-detail-feed .ob-detail-feed-info { flex: 1; min-width: 0; overflow: hidden; }
.disc-detail-feed .btn { flex-shrink: 0; }
@media (max-width: 640px) {
    .ob-interest-grid { grid-template-columns: repeat(3, 1fr); }
    .ob-detail-feeds { grid-template-columns: 1fr; }
}

/* ==================== TOAST NOTIFICATIONS ==================== */
#fl-toast-container {
  position: fixed; bottom: 1.25rem; right: 1.25rem; z-index: 9999;
  display: flex; flex-direction: column-reverse; gap: 0.5rem;
  pointer-events: none; max-width: 360px; width: 100%;
}
.fl-toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: 0.65rem;
  padding: 0.75rem 1rem; border-radius: 12px;
  background: var(--bg-card); border: 1px solid var(--border);
  box-shadow: 0 8px 30px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08);
  transform: translateX(120%); opacity: 0;
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.25s ease;
}
.fl-toast.show { transform: translateX(0); opacity: 1; }
.fl-toast-icon {
  flex-shrink: 0; width: 34px; height: 34px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
}
.fl-toast-fetch .fl-toast-icon { background: rgba(14, 165, 233, 0.12); color: #0ea5e9; }
.fl-toast-briefing .fl-toast-icon { background: rgba(139, 92, 246, 0.12); color: #8b5cf6; }
.fl-toast-info .fl-toast-icon { background: var(--bg-subtle); color: var(--text-muted); }
.fl-toast-body { flex: 1; min-width: 0; }
.fl-toast-title { font-size: 0.8rem; font-weight: 600; color: var(--text); line-height: 1.3; }
.fl-toast-text { font-size: 0.8rem; color: var(--text-muted); margin-top: 0.1rem; }
.fl-toast-close {
  flex-shrink: 0; background: none; border: none; color: var(--text-muted);
  font-size: 1.1rem; padding: 0; line-height: 1; cursor: pointer; opacity: 0.5;
}
.fl-toast-close:hover { opacity: 1; }
@media (max-width: 480px) {
  #fl-toast-container { left: 0.75rem; right: 0.75rem; bottom: 0.75rem; max-width: none; }
}
@media (max-width: 767px) {
  #fl-toast-container { bottom: calc(3.75rem + env(safe-area-inset-bottom, 0px)); }
}

/* ==================== COOKIE BANNER ==================== */
.cookie-banner {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 9999;
  background: var(--bg-card); border-top: 1px solid var(--border);
  padding: 0.75rem 1rem; font-size: 0.8rem; color: var(--text-muted);
}
@media (max-width: 767px) {
  .cookie-banner { bottom: calc(3.25rem + env(safe-area-inset-bottom, 0px)); }
}

/* ==================== PWA INSTALL BANNER ==================== */
/* `display: flex` outranks the HTML `hidden` attribute, so the banner
   stayed in the DOM, transparent (opacity:0) and pointer-active over the
   bottom-right of the viewport — silently swallowing clicks on whatever
   sat under it (e.g. the danger-zone "Close my account" button).
   Two safeguards: force-hide when `[hidden]`, and disable pointer events
   in the off state so even a malformed render can't trap clicks. */
.pwa-install-banner[hidden] { display: none !important; }
.pwa-install-banner {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 9998;
  display: flex; align-items: center; gap: 0.75rem;
  width: min(380px, calc(100vw - 2rem));
  padding: 0.7rem 0.85rem 0.7rem 0.7rem;
  background: var(--bg-card); color: var(--text);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.18), 0 2px 6px rgba(0,0,0,0.06);
  opacity: 0; transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.pwa-install-banner.show { opacity: 1; transform: translateY(0); pointer-events: auto; }
.pwa-install-icon {
  flex-shrink: 0; width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.pwa-install-icon img { width: 24px; height: 24px; }
.pwa-install-body { flex: 1; min-width: 0; }
.pwa-install-title { font-size: 0.85rem; font-weight: 700; line-height: 1.2; }
.pwa-install-text {
  font-size: 0.72rem; color: var(--text-muted);
  margin-top: 0.15rem; line-height: 1.3;
}
.pwa-install-actions {
  display: flex; align-items: center; gap: 0.35rem; flex-shrink: 0;
}
.pwa-install-cta {
  background: var(--accent); color: white;
  border: 0; border-radius: 8px;
  padding: 0.42rem 0.85rem;
  font-size: 0.78rem; font-weight: 600; cursor: pointer;
  transition: filter 0.12s ease;
}
.pwa-install-cta:hover { filter: brightness(1.08); }
.pwa-install-later {
  background: transparent; color: var(--text-muted);
  border: 0; cursor: pointer;
  padding: 0.42rem 0.6rem;
  font-size: 0.75rem; font-weight: 500;
}
.pwa-install-later:hover { color: var(--text); }
.pwa-install-close {
  position: absolute; top: 4px; right: 6px;
  background: transparent; border: 0; cursor: pointer;
  color: var(--text-muted); font-size: 1.1rem; line-height: 1;
  padding: 2px 6px;
}
.pwa-install-close:hover { color: var(--text); }
@media (max-width: 600px) {
  .pwa-install-banner {
    right: 0.5rem; left: 0.5rem; width: auto;
    /* Sit ABOVE the mobile bottom bar (--app-bottombar-h) plus a small
       gap, otherwise the banner overlaps the bar's tap targets. */
    bottom: calc(var(--app-bottombar-h) + 0.5rem + env(safe-area-inset-bottom, 0px));
  }
  .pwa-install-actions { gap: 0.25rem; }
  .pwa-install-later { display: none; }
}
/* When the off-canvas sidebar is open, the PWA banner (z-index 9998) sits
   on top of the drawer's user-card actions (theme / settings / logout) and
   absorbs taps. Hide it for the duration of the drawer interaction — it
   re-appears when the user closes the drawer. */
body.app-sidebar-open .pwa-install-banner { display: none !important; }

/* ==================== ARTICLE READER (Bottom Sheet) ==================== */
.reader-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 1000;
  opacity: 0; pointer-events: none; transition: opacity 0.25s;
}
.reader-backdrop.open { opacity: 1; pointer-events: auto; }

.reader-sheet {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 1001;
  background: var(--bg-card); border-radius: 16px 16px 0 0;
  box-shadow: 0 -4px 24px rgba(0,0,0,0.15);
  max-height: 85vh; display: flex; flex-direction: column;
  transform: translateY(100%); transition: transform 0.3s ease;
}
.reader-sheet.open { transform: translateY(0); }

.reader-handle {
  display: flex; justify-content: center; padding: 0.6rem 0 0.3rem;
  cursor: pointer; flex-shrink: 0;
}
.reader-handle span {
  width: 36px; height: 4px; border-radius: 2px;
  background: var(--border); display: block;
}

.reader-header {
  padding: 0 1rem 0.6rem; border-bottom: 1px solid var(--border);
  display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem;
  flex-shrink: 0;
}
.reader-title {
  font-size: 0.95rem; font-weight: 600; line-height: 1.35;
  margin: 0; flex: 1; min-width: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.reader-actions {
  display: flex; gap: 0.4rem; flex-shrink: 0; align-items: center;
}
.reader-close-btn {
  padding: 0.25rem; min-width: 2rem; min-height: 2rem;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; color: var(--text-muted);
}
.reader-close-btn:hover { color: var(--text); background: var(--bg-hover); }

.reader-body {
  flex: 1; overflow-y: auto; padding: 1rem;
  -webkit-overflow-scrolling: touch;
}

.reader-text {
  font-size: var(--reading-font-size, 0.95rem); line-height: 1.65; color: var(--text-secondary);
  white-space: pre-wrap; word-wrap: break-word;
}
.reader-summary { margin-bottom: 1rem; }
.reader-summary .badge {
  margin-bottom: 0.5rem; background: var(--accent-light); color: var(--accent);
}
.reader-meta {
  font-size: 0.75rem; color: var(--text-muted); margin-top: 0.5rem;
}
.reader-original {
  margin-top: 1rem; border-top: 1px solid var(--border); padding-top: 0.75rem;
}
.reader-original summary {
  font-size: 0.82rem; color: var(--text-muted); cursor: pointer;
  margin-bottom: 0.5rem;
}
.reader-error {
  color: var(--error); font-size: 0.88rem; padding: 1rem 0;
}

.reader-loading {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 2rem 0; color: var(--text-muted); font-size: 0.88rem;
}
.reader-spinner {
  width: 20px; height: 20px; border: 2px solid var(--border);
  border-top-color: var(--accent); border-radius: 50%;
  animation: reader-spin 0.6s linear infinite;
}
@keyframes reader-spin { to { transform: rotate(360deg); } }

/* Read button styling in live feed */
.lf-act-read { font-size: 0.82rem; }
@media (hover: hover) { .lf-act-read:hover { color: var(--accent); background: var(--accent-soft); } }

/* Desktop: wider sheet, centered */
@media (min-width: 768px) {
  .reader-sheet {
    left: 50%; right: auto; width: 680px;
    transform: translate(-50%, 100%); border-radius: 16px 16px 0 0;
  }
  .reader-sheet.open { transform: translate(-50%, 0); }
}

/* ==================== TIER SYSTEM ==================== */
.tier-badge-pro {
  display: inline-block; padding: 1px 7px; border-radius: 4px;
  font-size: 0.65rem; font-weight: 700; letter-spacing: 0.05em;
  background: linear-gradient(135deg, #7828C8, #006FEE); color: #fff;
  vertical-align: middle; margin-left: 6px; text-transform: uppercase;
}
.tier-badge-free {
  display: inline-block; padding: 1px 7px; border-radius: 4px;
  font-size: 0.65rem; font-weight: 700; letter-spacing: 0.05em;
  background: var(--bg-subtle); color: var(--text-muted);
  border: 1px solid var(--border); vertical-align: middle; margin-left: 6px;
  text-transform: uppercase;
}
.set-tier-lock {
  padding: 1rem 1.25rem; border-radius: 8px;
  background: var(--accent-soft); border: 1px dashed var(--accent);
  color: var(--text-secondary); font-size: 0.88rem; line-height: 1.5;
}
.set-tier-lock p { margin: 0; }
.set-tier-disabled { opacity: 0.5; pointer-events: none; }
.tier-usage {
  font-size: 0.78rem; color: var(--text-muted); font-weight: 500;
}
.tier-usage-bar {
  height: 4px; border-radius: 2px; background: var(--border);
  margin-top: 4px; overflow: hidden;
}
.tier-usage-fill {
  height: 100%; border-radius: 2px; background: var(--accent);
  transition: width 0.3s ease;
}

/* Inline tier tag on the /settings hero. Sits at the tail of the H1
   like a journal masthead's edition tag — adds zero new vertical space
   on desktop. Free is a neutral outlined chip; Pro / Enterprise are
   premium pills with an animated multi-stop gradient, a soft outer
   halo, a slow sheen sweep, and a tier glyph (star for Pro, gem for
   Enterprise). This is the "I'm paying, gratify me" surface. */
.set-tier-tag {
  display: inline-flex; align-items: center; gap: 0.35rem;
  margin-left: 0.75rem;
  padding: 3px 10px 3px 9px;
  font-size: 0.62rem; font-weight: 800;
  letter-spacing: 0.08em; text-transform: uppercase;
  border-radius: 999px;
  text-decoration: none;
  vertical-align: middle;
  position: relative; top: -2px;
  overflow: hidden;
  isolation: isolate;
  transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
  white-space: nowrap;
}
.set-tier-tag:hover { transform: translateY(-1px); filter: brightness(1.1) saturate(1.1); }
.set-tier-tag > * { position: relative; z-index: 1; }
.set-tier-tag-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex-shrink: 0;
}
.set-tier-tag-glyph {
  flex-shrink: 0;
  filter: drop-shadow(0 0 4px rgba(255,255,255,0.55));
}
.set-tier-tag-name { line-height: 1; }
.set-tier-tag-sep { opacity: 0.55; font-weight: 600; padding: 0 1px; }
.set-tier-tag-meta {
  display: inline-flex; align-items: center; gap: 3px;
  letter-spacing: 0.04em; font-weight: 700; opacity: 0.97;
  text-transform: none; font-size: 0.66rem;
}
.set-tier-tag-infinity { opacity: 0.95; flex-shrink: 0; }
.set-tier-tag-arrow {
  margin-left: 0.05rem; opacity: 0.85; flex-shrink: 0;
  transition: transform 0.2s ease;
}
.set-tier-tag:hover .set-tier-tag-arrow { transform: translateX(2px); opacity: 1; }

/* The diagonal sheen layer — sits absolutely behind the text and
   slides left→right every ~6 seconds. Hidden on Free (just an outlined
   chip — nothing to shine on). */
.set-tier-tag-sheen {
  position: absolute; inset: 0;
  background: linear-gradient(110deg,
    transparent 0%,
    rgba(255,255,255,0) 35%,
    rgba(255,255,255,0.45) 50%,
    rgba(255,255,255,0) 65%,
    transparent 100%);
  transform: translateX(-100%);
  pointer-events: none;
  z-index: 0;
}
.set-tier-tag--pro .set-tier-tag-sheen,
.set-tier-tag--enterprise .set-tier-tag-sheen {
  animation: set-tier-sheen 6s ease-in-out 1.5s infinite;
}

/* Free → outlined, muted (calls for the upgrade) */
.set-tier-tag--free {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  box-shadow: none;
}
.set-tier-tag--free:hover { color: var(--accent); border-color: var(--accent); }

/* Pro → animated indigo → blue → cyan gradient. The background-position
   shifts slowly so the hue feels alive without being distracting.
   Stacked glows (tight + wide) for depth. */
.set-tier-tag--pro {
  color: #fff;
  background: linear-gradient(120deg, #6366F1 0%, #3B82F6 45%, #06B6D4 100%);
  background-size: 220% 100%;
  background-position: 0% 50%;
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.18) inset,
    0 2px 4px -1px rgba(99,102,241,0.45),
    0 8px 22px -6px rgba(99,102,241,0.6);
  animation: set-tier-glow-pro 4.5s ease-in-out infinite;
}

/* Enterprise → animated amber → bronze → gold gradient. Heavier glow
   than Pro to signal "highest tier". Subtle warm halo + inner sheen. */
.set-tier-tag--enterprise {
  color: #fff;
  background: linear-gradient(120deg, #FBBF24 0%, #F59E0B 35%, #D97706 70%, #B45309 100%);
  background-size: 220% 100%;
  background-position: 0% 50%;
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.22) inset,
    0 2px 4px -1px rgba(245,158,11,0.55),
    0 10px 28px -6px rgba(245,158,11,0.7);
  animation: set-tier-glow-ent 4.5s ease-in-out infinite;
}

@keyframes set-tier-sheen {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(120%); }
  100% { transform: translateX(120%); }
}
@keyframes set-tier-glow-pro {
  0%, 100% { background-position: 0% 50%;
    box-shadow:
      0 0 0 1px rgba(255,255,255,0.18) inset,
      0 2px 4px -1px rgba(99,102,241,0.45),
      0 8px 22px -6px rgba(99,102,241,0.6);
  }
  50% { background-position: 100% 50%;
    box-shadow:
      0 0 0 1px rgba(255,255,255,0.28) inset,
      0 2px 6px -1px rgba(59,130,246,0.55),
      0 10px 28px -6px rgba(6,182,212,0.55);
  }
}
@keyframes set-tier-glow-ent {
  0%, 100% { background-position: 0% 50%;
    box-shadow:
      0 0 0 1px rgba(255,255,255,0.22) inset,
      0 2px 4px -1px rgba(245,158,11,0.55),
      0 10px 28px -6px rgba(245,158,11,0.7);
  }
  50% { background-position: 100% 50%;
    box-shadow:
      0 0 0 1px rgba(255,255,255,0.32) inset,
      0 2px 6px -1px rgba(251,191,36,0.6),
      0 12px 32px -6px rgba(180,83,9,0.6);
  }
}

@media (prefers-reduced-motion: reduce) {
  .set-tier-tag--pro,
  .set-tier-tag--enterprise { animation: none; background-position: 0% 50%; }
  .set-tier-tag-sheen { animation: none !important; opacity: 0; }
}

/* === Holographic foil — cursor-tracking glare + 3D parallax tilt ===
   Applied to Pro / Enterprise chips, both on the /settings hero and in
   the sidebar footer. CSS custom properties drive the effect; a tiny
   JS in base.html updates --foil-x/y/rx/ry on mousemove. Hover-only —
   on touch devices the chip stays flat, the existing sheen + glow
   already do plenty.
   Defaults make it a no-op without JS: x/y centred, rotations zero. */
.set-tier-tag--pro,
.set-tier-tag--enterprise,
.app-sidebar-user-plan--pro,
.app-sidebar-user-plan--enterprise {
  --foil-x: 50%;
  --foil-y: 50%;
  --foil-rx: 0deg;
  --foil-ry: 0deg;
  transform-style: preserve-3d;
  will-change: transform;
}
.set-tier-tag--pro,
.set-tier-tag--enterprise {
  transition: transform 0.2s ease, filter 0.2s ease, box-shadow 0.2s ease;
}
.app-sidebar-user-plan--pro,
.app-sidebar-user-plan--enterprise {
  transition: transform 0.2s ease, filter 0.2s ease, box-shadow 0.2s ease;
}
@media (hover: hover) and (pointer: fine) {
  .set-tier-tag--pro:hover,
  .set-tier-tag--enterprise:hover,
  .app-sidebar-user-plan--pro:hover,
  .app-sidebar-user-plan--enterprise:hover {
    transform:
      perspective(420px)
      rotateX(var(--foil-rx))
      rotateY(var(--foil-ry))
      translateY(-1px);
  }
  /* Cursor-tracked glare layer. Different colour from the auto-sheen
     so they don't overlap monotonously: this one is bright white +
     screen blend, the auto-sheen is wider and softer. */
  .set-tier-tag--pro::after,
  .set-tier-tag--enterprise::after,
  .app-sidebar-user-plan--pro::after,
  .app-sidebar-user-plan--enterprise::after {
    content: ""; position: absolute; inset: 0;
    border-radius: inherit;
    background: radial-gradient(
      circle 60px at var(--foil-x) var(--foil-y),
      rgba(255,255,255,0.72) 0%,
      rgba(255,255,255,0.30) 18%,
      rgba(255,255,255,0.05) 38%,
      transparent 60%);
    mix-blend-mode: screen;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    z-index: 2;
  }
  .set-tier-tag--pro:hover::after,
  .set-tier-tag--enterprise:hover::after,
  .app-sidebar-user-plan--pro:hover::after,
  .app-sidebar-user-plan--enterprise:hover::after {
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .set-tier-tag--pro:hover,
  .set-tier-tag--enterprise:hover,
  .app-sidebar-user-plan--pro:hover,
  .app-sidebar-user-plan--enterprise:hover { transform: translateY(-1px); }
}

/* === Top-of-viewport tier stripe ===
   Thin 2px gradient line sitting at the very top of every page. Sub-
   liminal brand signal: present on every screen without being in the
   way. Hidden for Free (`.tier-stripe--free` reverts to display:none). */
.tier-stripe {
  position: fixed; top: 0; left: 0; right: 0;
  height: 2px; z-index: 9999;
  pointer-events: none;
  display: none;
}
.tier-stripe--pro {
  display: block;
  background: linear-gradient(90deg, #6366F1 0%, #3B82F6 50%, #06B6D4 100%);
  background-size: 200% 100%;
  background-position: 0% 50%;
  animation: tier-stripe-pan 8s linear infinite;
  box-shadow: 0 0 8px rgba(99,102,241,0.55);
}
.tier-stripe--enterprise {
  display: block;
  background: linear-gradient(90deg, #FBBF24 0%, #F59E0B 35%, #D97706 70%, #B45309 100%);
  background-size: 200% 100%;
  background-position: 0% 50%;
  animation: tier-stripe-pan 8s linear infinite;
  box-shadow: 0 0 10px rgba(245,158,11,0.6);
}
@keyframes tier-stripe-pan {
  0%   { background-position: 0%   50%; }
  100% { background-position: 200% 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .tier-stripe { animation: none !important; background-position: 0% 50%; }
}

/* === Conic-gradient halo around the sidebar avatar ===
   A rotating ring rendered as a single ::before whose conic gradient
   is masked into a donut shape (radial mask) — that way we don't need
   to fight z-index stacking with the avatar's own background. The
   avatar element keeps its colored fill on top; the ring sits in the
   3px halo around it. */

/* === Sidebar brand glow ===
   Tiny tier-coloured glow under the FeedLynx logo at the top of the
   sidebar — same idea as the top stripe but localised to the brand
   mark. Subtle "this account is tier-Pro/Enterprise" everywhere. */
.app-sidebar--pro .app-sidebar-brand-mark,
.app-sidebar--enterprise .app-sidebar-brand-mark {
  position: relative;
}
.app-sidebar--pro .app-sidebar-brand-mark::after,
.app-sidebar--enterprise .app-sidebar-brand-mark::after {
  content: ""; position: absolute; inset: -4px;
  border-radius: inherit;
  z-index: -1;
  opacity: 0.6;
  filter: blur(6px);
  pointer-events: none;
}
.app-sidebar--pro .app-sidebar-brand-mark::after {
  background: radial-gradient(circle, #3B82F6 0%, transparent 70%);
}
.app-sidebar--enterprise .app-sidebar-brand-mark::after {
  background: radial-gradient(circle, #F59E0B 0%, transparent 70%);
}

/* ===========================================================
   === PAGE ATMOSPHERE  ======================================
   Fixed radial gradients at TR + BL corners of the viewport
   for paying users. The page literally lives inside the tier
   colour. Sized in vw so they scale with viewport; alpha tuned
   per theme so they read without washing out content. ======= */
.app-body[data-tier="pro"]::before,
.app-body[data-tier="enterprise"]::before {
  content: ""; position: fixed; inset: 0;
  z-index: -1; pointer-events: none;
  background:
    radial-gradient(36vw 32vh at 100% 0%, var(--tier-wash, transparent) 0%, transparent 65%),
    radial-gradient(40vw 36vh at 0%   100%, var(--tier-wash, transparent) 0%, transparent 65%);
}
.app-body[data-tier="pro"]      { --tier-wash: rgba(99, 102, 241, 0.085); }
.app-body[data-tier="enterprise"] { --tier-wash: rgba(245, 158, 11, 0.110); }
[data-theme="dark"] .app-body[data-tier="pro"]      { --tier-wash: rgba(99, 102, 241, 0.18); }
[data-theme="dark"] .app-body[data-tier="enterprise"] { --tier-wash: rgba(245, 158, 11, 0.22); }

/* === Tier wordmark next to the FeedLynx brand ===
   Same "premium pill" treatment as the /settings hero tag and the
   former footer chip — animated multi-stop gradient (4.5s glow loop),
   diagonal sheen sweep (~6s), cursor-tracked glare on hover (3D
   parallax tilt). It's omnipresent in the chrome, so it shines just
   enough to read as premium without being a constant distraction. */
.app-sidebar-brand-tier {
  display: inline-flex; align-items: center; gap: 0.25rem;
  margin-left: 0.4rem;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 0.58rem; font-weight: 800;
  letter-spacing: 0.09em; text-transform: uppercase;
  line-height: 1.4;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  text-decoration: none;
  --foil-x: 50%;
  --foil-y: 50%;
  --foil-rx: 0deg;
  --foil-ry: 0deg;
  transform-style: preserve-3d;
  transition: transform 0.2s ease, filter 0.2s ease, box-shadow 0.2s ease;
}
.app-sidebar-brand-tier > * { position: relative; z-index: 1; }
.app-sidebar-brand-tier-label { line-height: 1; }
.app-sidebar-brand-tier--pro {
  background: linear-gradient(120deg, #6366F1 0%, #3B82F6 45%, #06B6D4 100%);
  background-size: 220% 100%;
  background-position: 0% 50%;
  color: #fff;
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.18) inset,
    0 2px 4px -1px rgba(99,102,241,0.45),
    0 6px 16px -6px rgba(99,102,241,0.6);
  animation: set-tier-glow-pro 4.5s ease-in-out infinite;
}
.app-sidebar-brand-tier--enterprise {
  background: linear-gradient(120deg, #FBBF24 0%, #F59E0B 35%, #D97706 70%, #B45309 100%);
  background-size: 220% 100%;
  background-position: 0% 50%;
  color: #fff;
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.22) inset,
    0 2px 4px -1px rgba(245,158,11,0.55),
    0 8px 22px -6px rgba(245,158,11,0.7);
  animation: set-tier-glow-ent 4.5s ease-in-out infinite;
}
/* Auto-sweep sheen: a single bright diagonal stripe that crosses the
   chip every ~6s. Identical to the /settings tag's sheen so the two
   chips visually rhyme. */
.app-sidebar-brand-tier-sheen {
  position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(110deg,
    transparent 0%,
    rgba(255,255,255,0) 35%,
    rgba(255,255,255,0.45) 50%,
    rgba(255,255,255,0) 65%,
    transparent 100%);
  transform: translateX(-100%);
  pointer-events: none;
  animation: set-tier-sheen 6s ease-in-out 1.5s infinite;
}
/* Cursor-tracked glare on hover (matches the holographic foil applied
   to other tier chips). JS in base.html updates --foil-x/y/rx/ry. */
@media (hover: hover) and (pointer: fine) {
  .app-sidebar-brand-tier:hover {
    transform:
      perspective(420px)
      rotateX(var(--foil-rx))
      rotateY(var(--foil-ry))
      translateY(-1px);
  }
  .app-sidebar-brand-tier::after {
    content: ""; position: absolute; inset: 0;
    border-radius: inherit;
    background: radial-gradient(
      circle 60px at var(--foil-x) var(--foil-y),
      rgba(255,255,255,0.72) 0%,
      rgba(255,255,255,0.30) 18%,
      rgba(255,255,255,0.05) 38%,
      transparent 60%);
    mix-blend-mode: screen;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    z-index: 2;
  }
  .app-sidebar-brand-tier:hover::after { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .app-sidebar-brand-tier { animation: none; background-position: 0% 50%; }
  .app-sidebar-brand-tier-sheen { animation: none !important; opacity: 0; }
}

/* === Tier-themed scrollbar ===
   Tones the main scroll thumb to the tier palette so even the chrome
   chassis carries the colour. WebKit only — Firefox falls back to
   `scrollbar-color` further below. */
.app-body[data-tier="pro"]::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, #6366F1, #3B82F6);
  border-radius: 8px;
}
.app-body[data-tier="enterprise"]::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, #F59E0B, #D97706);
  border-radius: 8px;
}
.app-body[data-tier="pro"]::-webkit-scrollbar-thumb:hover { filter: brightness(1.1); }
.app-body[data-tier="enterprise"]::-webkit-scrollbar-thumb:hover { filter: brightness(1.1); }
.app-body[data-tier="pro"] { scrollbar-color: #6366F1 transparent; }
.app-body[data-tier="enterprise"] { scrollbar-color: #F59E0B transparent; }

/* Sub-line companion: renewal date for Pro/Enterprise, upgrade link
   for Free. Reuses the page subtitle row so it doesn't add a new line
   on desktop (flows inline after the existing sub text). */
.set-hero-sub-meta {
  display: inline-flex; align-items: center;
  margin-left: 0.4rem;
  color: var(--text-muted);
  font-size: 0.82rem;
}
.set-hero-sub-meta::before {
  content: '·';
  margin-right: 0.5rem;
  opacity: 0.5;
}
.set-hero-sub-link {
  color: var(--accent); text-decoration: none; font-weight: 600;
}
.set-hero-sub-link:hover { text-decoration: underline; }

@media (max-width: 600px) {
  .set-tier-tag {
    margin-left: 0.5rem;
    font-size: 0.58rem;
    padding: 2px 7px 2px 8px;
    top: -3px;
  }
  .set-tier-tag-meta { font-size: 0.6rem; }
  .set-tier-tag-arrow { display: none; }
}

/* Mobile top bar — the hero is hidden and the H1 children are cloned
   into .app-mobile-title. Strip the tier tag down to just the badge
   (no expiry/active suffix, no arrow) so it fits next to the title
   without crowding the hamburger and any newsletter picker.
   Margin shrinks too: the cloned title row is much tighter than the
   in-page H1. */
.app-mobile-title .set-tier-tag {
  margin-left: 0.4rem;
  padding: 1px 6px;
  font-size: 0.54rem;
  top: 0;
  letter-spacing: 0.06em;
}
.app-mobile-title .set-tier-tag-sep,
.app-mobile-title .set-tier-tag-meta,
.app-mobile-title .set-tier-tag-arrow { display: none; }
.app-mobile-title .set-tier-tag-dot {
  width: 4px; height: 4px;
}
.tier-usage-fill.warn { background: var(--warning); }
.tier-usage-fill.full { background: var(--error); }
.dash-tier-card {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-radius: 10px;
  background: var(--bg-card); border: 1px solid var(--border);
  margin-bottom: 16px;
}
.dash-tier-card .tier-plan-name {
  font-size: 1rem; font-weight: 700; text-transform: uppercase;
}
.dash-tier-card .tier-plan-name.pro {
  background: linear-gradient(135deg, #7828C8, #006FEE);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  background-clip: text;
}
.dash-tier-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; border-radius: 10px;
  background: var(--bg-card); border: 1px solid var(--border);
  margin-bottom: 16px;
}
.dash-tier-stats {
  display: flex; gap: 12px; flex: 1; justify-content: center;
  font-size: 0.78rem; color: var(--text-muted);
}
.dash-tier-stats span {
  display: inline-flex; align-items: center; gap: 3px; white-space: nowrap;
}
.dash-tier-stats svg { opacity: 0.6; flex-shrink: 0; }
.dash-tier-byo {
  font-size: 0.65rem; color: var(--accent); white-space: nowrap;
  border: 1px solid var(--accent); border-radius: 4px; padding: 1px 5px;
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em;
}
@media (max-width: 767px) {
  .dash-tier-stats { gap: 6px; font-size: 0.72rem; }
  .dash-tier-stats em { display: none; }
}

/* ==================== STORIES VIEW ==================== */
body.stories-active { overflow: hidden; }
@media (max-width: 767px) {
  body.stories-active > footer { display: none !important; }
}
.lf-stories {
  position: relative;
  height: var(--stories-h, calc(100dvh - 12rem));
  overflow: hidden;
}
.lf-story {
  position: absolute; inset: 0;
  border-radius: 12px; overflow: hidden;
  background: var(--bg-card); border: 1px solid var(--border);
  display: none;
  transition: transform 0.3s ease, opacity 0.3s ease;
}
.lf-story.lf-story-active { display: block; }
.lf-story.is-read { opacity: 0.7; }
/* Progress bar container */
.lf-story-progress {
  position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; gap: 3px; padding: 6px 8px;
}
.lf-story-progress-seg {
  flex: 1; height: 3px; border-radius: 2px;
  background: rgba(255,255,255,0.3); overflow: hidden;
}
.lf-story-progress-fill {
  height: 100%; width: 0%; border-radius: 2px;
  background: #fff; transition: width 0.1s linear;
}
.lf-story-progress-seg.done .lf-story-progress-fill { width: 100%; }
.lf-story-progress-seg.active .lf-story-progress-fill { /* width set by JS */ }
/* Tap zones */
.lf-story-tap-left, .lf-story-tap-right {
  position: absolute; top: 0; bottom: 0; z-index: 4; cursor: pointer;
}
.lf-story-tap-left { left: 0; width: 30%; }
.lf-story-tap-right { right: 0; width: 70%; }
/* Counter badge */
.lf-story-counter {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  z-index: 6; font-size: 0.65rem; color: rgba(255,255,255,0.7);
  background: rgba(0,0,0,0.3); padding: 2px 8px; border-radius: 10px;
  backdrop-filter: blur(4px);
}
.lf-story-img {
  position: absolute; inset: 0; object-fit: cover; width: 100%; height: 100%;
  z-index: 0;
}
.lf-story-gradient {
  position: absolute; bottom: 0; left: 0; right: 0; height: 65%;
  background: linear-gradient(transparent, rgba(0,0,0,0.88));
  z-index: 1;
}
.lf-story-fallback {
  position: absolute; inset: 0; z-index: 0;
}
.lf-story-content {
  position: absolute; bottom: 0; left: 0; right: 0;
  padding: 1.5rem; color: #fff; z-index: 5;
}
.lf-story-title {
  font-size: 1.35rem; font-weight: 700; line-height: 1.3; margin-bottom: 0.5rem;
  text-shadow: 0 2px 8px rgba(0,0,0,0.5);
}
.lf-story-title a { color: inherit; text-decoration: none; }
.lf-story-title a:hover { text-decoration: underline; }
.lf-story-summary {
  font-size: 0.85rem; line-height: 1.4; opacity: 0.9; margin-bottom: 0.75rem;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  text-shadow: 0 1px 4px rgba(0,0,0,0.4);
}
.lf-story-meta {
  font-size: 0.75rem; opacity: 0.8; display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
}
.lf-story-meta .badge { font-size: 0.75rem; }
.lf-story-actions {
  position: absolute; bottom: 6rem; right: 0.75rem; z-index: 5;
  display: flex; flex-direction: column; gap: 0.5rem;
}
.lf-story-actions .lf-act {
  background: rgba(0,0,0,0.45); color: #fff; border: none; border-radius: 50%;
  width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
  cursor: pointer; font-size: 0.8rem; backdrop-filter: blur(4px);
  transition: background 0.15s;
}
.lf-story-actions .lf-act:hover { background: rgba(0,0,0,0.65); }
.lf-story-actions .lf-act.on { color: var(--accent); }
.lf-story-actions .lf-act.lf-act-down.on { color: var(--error); }
/* Category gradient fallback colors */
.lf-story-fallback-cybersecurity { background: linear-gradient(135deg, #1a0a1e, #4a1942, #F31260); }
.lf-story-fallback-tech, .lf-story-fallback-tech_news { background: linear-gradient(135deg, #0a1628, #1a3a6b, #006FEE); }
.lf-story-fallback-crypto, .lf-story-fallback-crypto_bitcoin { background: linear-gradient(135deg, #1a1408, #5a4520, #F5A524); }
.lf-story-fallback-ai, .lf-story-fallback-artificial_intelligence { background: linear-gradient(135deg, #140a28, #3a1a6b, #7828C8); }
.lf-story-fallback-privacy, .lf-story-fallback-privacy_rights { background: linear-gradient(135deg, #061a10, #1a5a30, #17C964); }
.lf-story-fallback-programming { background: linear-gradient(135deg, #061a1e, #155E75, #06B6D4); }
.lf-story-fallback-devops, .lf-story-fallback-devops_cloud { background: linear-gradient(135deg, #0e0e28, #2a2a6b, #6366F1); }
.lf-story-fallback-linux, .lf-story-fallback-linux_opensource { background: linear-gradient(135deg, #1a0e06, #6b3a1a, #F97316); }
.lf-story-fallback-sport { background: linear-gradient(135deg, #1a0610, #7f1d1d, #E11D48); }
.lf-story-fallback-finance { background: linear-gradient(135deg, #061a18, #0D9488, #14b8a6); }
.lf-story-fallback-other { background: linear-gradient(135deg, #1a1a1e, #3f3f46, #71717a); }

/* Stories sort toggle chips */
.lf-stories-sort {
  display: flex; gap: 0.35rem; padding: 0.5rem 0;
}
.lf-stories-sort .lf-chip { font-size: 0.72rem; padding: 0.2rem 0.6rem; }

/* Accessibility: reduced motion */
@media (prefers-reduced-motion: reduce) {
  .news-ticker-content { animation: none !important; overflow-x: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ==================== NEWSPAPER ==================== */

/* Masthead */
.np-masthead { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 0; border-bottom: 1px solid var(--border); margin-bottom: 0.5rem; gap: 0.75rem; }
.np-masthead-left { display: flex; align-items: baseline; gap: 0.75rem; flex-wrap: wrap; min-width: 0; }
.np-masthead-title { font-size: 1.1rem; font-weight: 900; letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap; }
.np-masthead-date { font-size: 0.78rem; color: var(--text-muted); font-weight: 500; white-space: nowrap; }
.np-masthead-stats { font-size: 0.72rem; color: var(--text-muted); white-space: nowrap; }
.np-masthead-intro { display: none; }
.np-masthead-toolbar { display: flex; gap: 0.35rem; flex-shrink: 0; flex-wrap: wrap; }
.np-chip-ai { background: linear-gradient(135deg, #6366F1, #0EA5E9); border-color: transparent; color: #fff; }
.np-chip-ai:hover { filter: brightness(1.1); border-color: transparent; color: #fff; }

/* Ticker */
/* Live feed headlines (4 cards) */
.np-live { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.75rem; margin-bottom: 1.25rem; padding: 0.75rem 0; border-bottom: 1px solid var(--border); }
.np-live-card { display: flex; flex-direction: column; text-decoration: none; color: var(--text); border-radius: 8px; overflow: hidden; transition: transform 0.2s, box-shadow 0.2s; }
.np-live-card:hover { transform: translateY(-2px); box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
.np-live-img-wrap { height: 80px; overflow: hidden; border-radius: 8px; }
.np-live-img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s ease; }
.np-live-card:hover .np-live-img { transform: scale(1.08) translateX(3%); }
.np-live-body { padding: 0.4rem 0; }
.np-live-feed { font-size: 0.65rem; color: var(--accent); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; display: block; margin-bottom: 0.15rem; }
.np-live-title { font-size: 0.8rem; font-weight: 600; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
@media (max-width: 767px) { .np-live { grid-template-columns: repeat(2, 1fr); } }

/* Category filter (sticky) */
.np-cats { display: flex; gap: 0.35rem; padding: 0.5rem 0; overflow-x: auto; position: sticky; top: 60px; z-index: 20; background: var(--bg); border-bottom: 1px solid var(--border); scrollbar-width: none; }
.np-cats::-webkit-scrollbar { display: none; }

/* Hero story — image top, content below on card */
.np-hero { background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; margin-bottom: 1rem; }
.np-hero-img { width: 100%; height: 280px; object-fit: cover; display: block; transition: transform 0.6s ease; }
.np-hero:hover .np-hero-img { transform: scale(1.03); }
.np-hero-fallback { display: none; }
.np-hero-overlay { display: none; }
.np-hero-content { padding: 1.25rem; }
.np-hero-cat { font-size: 0.75rem; }
.np-hero-title { font-size: 1.5rem; font-weight: 800; line-height: 1.2; margin: 0.4rem 0; display: block; color: var(--text); text-decoration: none; }
.np-hero-title:hover { color: var(--accent); }
.np-hero-summary { font-size: 0.9rem; color: var(--text-muted); line-height: 1.6; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; cursor: pointer; margin: 0; }
.np-hero-summary.expanded { display: block !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; overflow: visible !important; }
.np-hero-actions { margin-top: 0.5rem; }
@media (max-width: 767px) {
  .np-hero-img { height: 180px; }
  .np-hero-title { font-size: 1.15rem; }
  .np-hero-content { padding: 0.85rem; }
}

/* Duo (stories 2-3) */
.np-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1.5rem; }
.np-duo-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; transition: box-shadow 0.15s; }
.np-duo-card:hover { box-shadow: 0 2px 12px rgba(0,0,0,0.06); }
.np-duo-img { width: 100%; height: 160px; object-fit: cover; display: block; }
.np-duo-body { padding: 0.85rem; }
.np-duo-title { font-size: 1rem; font-weight: 700; line-height: 1.3; margin: 0.35rem 0; display: block; color: inherit; text-decoration: none; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.np-duo-title:hover { color: var(--accent); }
.np-duo-summary { font-size: 0.85rem; color: var(--text-muted); line-height: 1.5; -webkit-line-clamp: 2; -webkit-box-orient: vertical; display: -webkit-box; overflow: hidden; cursor: pointer; margin: 0; }
.np-duo-summary.expanded { display: block !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; overflow: visible !important; }
@media (max-width: 767px) { .np-duo { grid-template-columns: 1fr; } .np-duo-img { height: 140px; } }

/* Story grid (continuous 2-col, dividers span full width) */
.np-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem; margin-bottom: 0.5rem; }
.np-divider { display: flex; align-items: center; gap: 0.75rem; padding: 1.25rem 0 0.5rem; grid-column: 1 / -1; }
.np-divider-line { flex: 1; height: 1px; background: var(--border); }
@media (max-width: 767px) { .np-grid { grid-template-columns: 1fr; } }

/* Story card */
.np-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px; padding: 0.85rem; display: flex; gap: 0.75rem; transition: box-shadow 0.15s; }
.np-card:hover { box-shadow: 0 2px 12px rgba(0,0,0,0.06); }
.np-card-thumb { width: 100px; height: 70px; object-fit: cover; border-radius: 6px; flex-shrink: 0; }
.np-card-body { flex: 1; min-width: 0; }
.np-card-title { font-size: 0.9rem; font-weight: 600; line-height: 1.35; margin-bottom: 0.25rem; display: block; color: inherit; text-decoration: none; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; cursor: pointer; }
.np-card-title:hover { color: var(--accent); }
/* Read more: drop the line-clamp when toggleSummary marks the title
   .expanded — pairs with the corresponding rule on summary. */
.bf-story-title.expanded,
.np-hero-title.expanded,
.np-duo-title.expanded,
.np-card-title.expanded { -webkit-line-clamp: unset; line-clamp: unset; overflow: visible; }
.np-card-summary { font-size: 0.82rem; color: var(--text-muted); line-height: 1.5; -webkit-line-clamp: 2; -webkit-box-orient: vertical; display: -webkit-box; overflow: hidden; cursor: pointer; margin: 0; }
.np-card-summary.expanded { display: block !important; -webkit-line-clamp: unset !important; -webkit-box-orient: unset !important; overflow: visible !important; }

/* Actions row */
.np-actions { display: flex; gap: 0.5rem; margin-top: 0.35rem; align-items: center; }

/* Brief draft editor — story-level Edit/Remove chrome + modal.
   Only active when body has .is-pending-draft (added by JS when the
   #np-edit-marker element is present, which is server-rendered only
   when active_briefing.approval_status == 'pending'). */
.np-edit-chrome { position: absolute; top: 0.55rem; right: 0.55rem;
  display: flex; gap: 0.3rem; z-index: 5;
  opacity: 0; pointer-events: none; transition: opacity 0.18s; }
body.is-pending-draft .np-hero,
body.is-pending-draft .np-duo-card,
body.is-pending-draft .np-card { position: relative; }
body.is-pending-draft .np-hero:hover .np-edit-chrome,
body.is-pending-draft .np-duo-card:hover .np-edit-chrome,
body.is-pending-draft .np-card:hover .np-edit-chrome,
body.is-pending-draft .np-edit-chrome:focus-within { opacity: 1; pointer-events: auto; }
@media (max-width: 768px) {
  /* Always-on on touch devices — no hover state */
  body.is-pending-draft .np-edit-chrome { opacity: 1; pointer-events: auto; }
}
.np-edit-btn { font-size: 0.72rem; font-weight: 600; padding: 0.25rem 0.6rem;
  border-radius: 6px; border: 1px solid var(--border);
  background: var(--bg-card); color: var(--text-secondary);
  cursor: pointer; transition: all 0.12s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.np-edit-btn:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.np-edit-btn-danger { color: #b91c1c; }
.np-edit-btn-danger:hover { background: #b91c1c; color: #fff; border-color: #b91c1c; }
/* Move-up / move-down arrows: tighter footprint than the text buttons
   so the chrome row doesn't grow too wide on the hero card. */
.np-edit-btn-move { padding: 0.15rem 0.45rem; font-size: 0.85rem; font-weight: 700;
  font-variant-numeric: tabular-nums; min-width: 26px; }
/* Wave 6 (2026-05-13): chrome buttons are icon-only — single 28×28 box
   so the chrome row stays compact on the hero card and works on touch. */
.np-edit-btn-icon { width: 28px; height: 28px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; }
.np-edit-btn-icon svg { display: block; }

/* Image hamburger dropdown. The wrap is the anchor for absolute
   positioning; the menu floats below the button. */
.np-img-menu-wrap { position: relative; display: inline-block; }
.np-img-menu { position: absolute; top: calc(100% + 4px); right: 0;
  min-width: 220px; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  padding: 4px; z-index: 20;
  display: none; }
.np-img-menu.is-open { display: block; }
.np-img-menu button { display: flex; align-items: center; gap: 0.55rem;
  width: 100%; padding: 0.5rem 0.7rem; border: 0; background: transparent;
  font-size: 0.78rem; color: var(--text-primary); text-align: left;
  border-radius: 6px; cursor: pointer; font-family: inherit; }
.np-img-menu button:hover { background: var(--bg-hover, rgba(0,0,0,0.04)); }
.np-img-menu button svg { flex-shrink: 0; color: var(--text-secondary); }

.np-edit-modal { position: fixed; inset: 0; z-index: 9000;
  background: rgba(0,0,0,0.55); display: flex; align-items: center; justify-content: center;
  padding: 1rem; }
.np-edit-modal[hidden] { display: none; }
.np-edit-modal-card { background: var(--bg-card); border-radius: 12px;
  width: 100%; max-width: 560px; max-height: calc(100vh - 2rem);
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,0.35); }
.np-edit-modal-head { display: flex; align-items: center; justify-content: space-between;
  padding: 0.85rem 1.1rem; border-bottom: 1px solid var(--border); }
.np-edit-modal-head h3 { margin: 0; font-size: 1rem; font-weight: 600; }
.np-edit-close { background: transparent; border: 0; font-size: 1.5rem; line-height: 1;
  cursor: pointer; color: var(--text-muted); padding: 0 0.25rem; }
.np-edit-close:hover { color: var(--text); }
.np-edit-modal-body { padding: 1rem 1.1rem; overflow-y: auto; display: flex; flex-direction: column; gap: 0.85rem; }
.np-edit-modal-body label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; color: var(--text-secondary); }
.np-edit-modal-body input,
.np-edit-modal-body textarea { width: 100%; padding: 0.55rem 0.7rem; border-radius: 8px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
  font-family: inherit; font-size: 0.92rem; line-height: 1.45; resize: vertical; }
.np-edit-modal-body input:focus,
.np-edit-modal-body textarea:focus { outline: none; border-color: var(--accent); }
.np-edit-modal-actions { display: flex; gap: 0.5rem; justify-content: flex-end;
  padding: 0.75rem 1.1rem; border-top: 1px solid var(--border); background: var(--bg-subtle); align-items: center; }
.approve-banner-hint { display: block; font-size: 0.78rem; color: var(--text-muted); margin-top: 0.15rem; font-style: italic; }

/* Replace modal — wider card so titles + summaries fit without horizontal cut. */
.np-replace-card { max-width: 720px; }
.np-replace-search { padding: 0.75rem 1.1rem; border-bottom: 1px solid var(--border); background: var(--bg-subtle); }
.np-replace-search input { width: 100%; padding: 0.55rem 0.7rem; border-radius: 8px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text); font-size: 0.92rem; }
.np-replace-search input:focus { outline: none; border-color: var(--accent); }
.np-replace-list { flex: 1 1 auto; overflow-y: auto; padding: 0.5rem 0.5rem; max-height: 60vh;
  display: flex; flex-direction: column; gap: 0.35rem; }
.np-replace-item { width: 100%; text-align: left; padding: 0.7rem 0.85rem;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
  cursor: pointer; transition: border-color 0.15s, background 0.15s;
  display: flex; flex-direction: column; gap: 0.3rem; font-family: inherit; }
.np-replace-item:hover { border-color: var(--accent); background: var(--accent-soft); }
.np-replace-item-top { display: flex; gap: 0.6rem; align-items: baseline; flex-wrap: wrap;
  justify-content: space-between; }
.np-replace-item-title { font-weight: 600; color: var(--text); font-size: 0.95rem; line-height: 1.3; flex: 1 1 65%; }
.np-replace-item-meta { font-size: 0.74rem; color: var(--text-muted); white-space: nowrap; flex: 0 0 auto; }
.np-replace-item-summary { margin: 0; font-size: 0.83rem; color: var(--text-secondary); line-height: 1.45; }

/* Past editions */
.np-past { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid var(--border); }
.dash-past-card { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1rem;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; text-decoration: none; color: inherit; transition: all 0.15s; }
.dash-past-card:hover { border-color: var(--accent); transform: translateX(2px); }
.dash-past-card-meta { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; min-width: 0; }
.dash-past-card-nl { font-size: 0.72rem; padding: 0.1rem 0.5rem; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent); font-weight: 600; line-height: 1.4; }
.dash-past-card-status { font-size: 0.66rem; padding: 0.08rem 0.45rem; border-radius: 999px;
  font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; line-height: 1.5; }
.dash-past-card-status-pending { background: rgba(245,158,11,0.15); color: #b45309; }
.dash-past-card-status-rejected { background: rgba(239,68,68,0.15); color: #b91c1c; }
[data-theme="dark"] .dash-past-card-status-pending { background: rgba(245,158,11,0.2); color: #fbbf24; }
[data-theme="dark"] .dash-past-card-status-rejected { background: rgba(239,68,68,0.2); color: #f87171; }

/* (Dashboard edition tabs removed — superseded by the .np-nl-picker
   dropdown integrated into the page title, see definitions near the
   top of this file alongside .app-mobile-title.) */
[data-theme="dark"] .dash-edition-chip-badge { background: rgba(245,158,11,0.22); color: #fbbf24; }

/* Mobile: tighter padding so 3-4 chips fit on screen, plus ensure the
   strip doesn't bleed beyond the page padding (uses negative margin
   trick to extend to viewport edges, hinting at scrollability). */
@media (max-width: 600px) {
    .dash-edition-tabs {
        margin-left: -0.75rem;
        margin-right: -0.75rem;
        padding-left: 0.75rem;
        padding-right: 0.75rem;
    }
    .dash-edition-chip { padding: 0.45rem 0.75rem; font-size: 0.8rem; }
    .dash-edition-chip-name { max-width: 140px; }
}

/* Dark mode adjustments */
[data-theme="dark"] .np-hero { background: #18181b; }
[data-theme="dark"] .np-card:hover, [data-theme="dark"] .np-duo-card:hover { box-shadow: 0 2px 12px rgba(0,0,0,0.2); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .np-hero { background: #18181b; }
  :root:not([data-theme="light"]) .np-card:hover, :root:not([data-theme="light"]) .np-duo-card:hover { box-shadow: 0 2px 12px rgba(0,0,0,0.2); }
}

/* Mobile adjustments */
@media (max-width: 640px) {
  .np-masthead { flex-wrap: wrap; }
  .np-masthead-stats { display: none; }
  .np-masthead-title { font-size: 0.95rem; }
  .np-masthead-toolbar { gap: 0.25rem; }
  .np-masthead-toolbar .lf-chip span { display: none; }
  .np-masthead-toolbar .lf-chip { padding: 0.35rem; gap: 0; min-width: 34px; min-height: 34px; justify-content: center; font-size: 0; }
  .np-masthead-toolbar .lf-chip svg { width: 14px; height: 14px; }
  .np-masthead-toolbar .lf-chip .spinner { width: 14px; height: 14px; border-width: 2px; }
  .np-card-thumb { width: 72px; height: 54px; }
  .np-actions .lf-act { min-width: 2rem; min-height: 2rem; }
}


/* ======================== Newsletters CRUD ======================== */

.nl-list { display: flex; flex-direction: column; gap: 0.5rem; }
.nl-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; padding: 0.85rem 1rem;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
    transition: border-color 0.15s;
}
.nl-row:hover { border-color: var(--accent); }
.nl-row-main { flex: 1; min-width: 0; }
.nl-row-title { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.nl-row-slug { font-size: 0.8rem; color: var(--text-muted); font-family: monospace; }
.nl-row-meta { font-size: 0.82rem; color: var(--text-muted); margin-top: 0.25rem;
    display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.nl-row-hint { font-size: 0.85rem; color: var(--text-muted); margin-top: 0.35rem; font-style: italic; }
.nl-row-actions { display: flex; gap: 0.4rem; flex-shrink: 0; align-items: center; flex-wrap: wrap; }

/* ── Feeds editor (newsletter_edit.html) ───────────────────────────
   Pre-2026-05 the editor showed a flat list of every feed with a
   per-row "Global / This newsletter" select. That works for 5 feeds,
   not for 200. The list is now grouped by category (mirroring the
   sidebar) with checkboxes, per-folder Select-all/None buttons, and a
   global toolbar — bulk operations call the dedicated bulk-assign
   endpoint. */
.nl-feeds-toolbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 0.75rem; padding: 0.55rem 0.85rem;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-subtle);
    margin-bottom: 0.6rem; flex-wrap: wrap;
}
.nl-feeds-toolbar-info { font-size: 0.85rem; color: var(--text-muted); display: flex; align-items: center; gap: 0.35rem; }
.nl-feeds-toolbar-info strong { color: var(--text); font-variant-numeric: tabular-nums; }
.nl-feeds-toolbar-sep { opacity: 0.4; }
.nl-feeds-toolbar-actions { display: flex; gap: 0.4rem; flex-shrink: 0; }

.nl-feed-groups { display: flex; flex-direction: column; gap: 0.4rem; }
/* Each <details> is its own block — explicit `position: relative` +
   isolation guarantees the rotating chevron's transform doesn't create
   a stacking context that bleeds into the next folder.
   Removed the max-height/overflow that the toolbar used to enforce —
   when several folders were open the inner scroll container could
   visually clip the next folder, making it look like accordions were
   overlapping. The page-level scroll handles long lists fine. */
.nl-feed-group { border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-card); overflow: hidden;
    position: relative; isolation: isolate; }
.nl-feed-group[open] { border-color: var(--border); }
.nl-feed-group-head {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.55rem 0.75rem; cursor: pointer;
    list-style: none; user-select: none;
    transition: background 0.12s;
}
.nl-feed-group-head::-webkit-details-marker { display: none; } /* hide native triangle */
.nl-feed-group-head:hover { background: var(--bg-subtle); }
.nl-feed-group-chevron { display: inline-flex; transition: transform 0.15s; color: var(--text-muted); }
.nl-feed-group[open] .nl-feed-group-chevron { transform: rotate(0deg); }
.nl-feed-group:not([open]) .nl-feed-group-chevron { transform: rotate(-90deg); }
.nl-feed-group-folder { color: var(--text-muted); flex-shrink: 0; }
.nl-feed-group-name { font-weight: 600; font-size: 0.92rem; color: var(--text); }
.nl-feed-group-count { font-size: 0.75rem; color: var(--text-muted);
    font-variant-numeric: tabular-nums; background: var(--bg-subtle);
    padding: 0.1rem 0.4rem; border-radius: 999px; }
.nl-feed-group-actions { margin-left: auto; display: flex; gap: 0.3rem; }
.nl-feed-group-actions .btn-xs { padding: 0.18rem 0.5rem; font-size: 0.72rem; }
.nl-feed-group-body { border-top: 1px solid var(--border); display: flex; flex-direction: column; }

.nl-feed-row {
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.45rem 0.85rem 0.45rem 1.65rem;
    border-bottom: 1px solid var(--border);
    cursor: pointer; transition: background 0.1s;
}
.nl-feed-row:last-child { border-bottom: none; }
.nl-feed-row:hover { background: var(--bg-subtle); }
.nl-feed-row-locked { opacity: 0.55; cursor: not-allowed; }
.nl-feed-row-locked:hover { background: transparent; }
.nl-feed-check { flex-shrink: 0; width: 16px; height: 16px; cursor: pointer; accent-color: var(--accent); }
.nl-feed-row-locked .nl-feed-check { cursor: not-allowed; }
.nl-feed-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.nl-feed-info strong { font-size: 0.88rem; font-weight: 500; }
.nl-feed-url { font-size: 0.72rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nl-feed-url code { background: transparent; padding: 0; }
.badge-warn { background: rgba(245,158,11,0.18); color: #b45309; border: 1px solid rgba(245,158,11,0.3);
    padding: 0.05rem 0.4rem; border-radius: 999px; font-size: 0.65rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.02em; }
[data-theme="dark"] .badge-warn { background: rgba(245,158,11,0.22); color: #fbbf24; }

/* Inline indicator for feeds that aren't pinned to any newsletter but feed
   every brief by virtue of being global. Surfaces the "X is feeding this
   brief even though the checkbox is empty" case that confused Giuseppe on
   2026-05-15 (the Garlasco/Science leak). */
.badge-global { background: rgba(59,130,246,0.14); color: #1d4ed8;
    border: 1px solid rgba(59,130,246,0.3);
    padding: 0.05rem 0.4rem; border-radius: 999px; font-size: 0.65rem;
    font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em; }
[data-theme="dark"] .badge-global { background: rgba(96,165,250,0.22); color: #93c5fd;
    border-color: rgba(96,165,250,0.35); }

/* Soft secondary in the feeds toolbar so the "X exclusive · Y global"
   subcount doesn't compete visually with the headline number. */
.nl-feeds-toolbar-detail { color: var(--text-muted); font-size: 0.78rem;
    margin-left: 0.4rem; }
.nl-feeds-toolbar-detail span { font-variant-numeric: tabular-nums; }

/* Followed stories per-newsletter opt-out list (newsletter_edit). Visual
   parity with the feeds editor: same row paddings, same checkbox accent,
   same locked-row treatment. No accordion since follows are usually a
   handful per user. */
.nl-follows-list { display: flex; flex-direction: column;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-card); overflow: hidden; }
.nl-follow-row {
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.55rem 0.85rem;
    border-bottom: 1px solid var(--border);
    cursor: pointer; transition: background 0.1s;
}
.nl-follow-row:last-child { border-bottom: none; }
.nl-follow-row:hover { background: var(--bg-subtle); }
.nl-follow-row-locked { opacity: 0.55; cursor: not-allowed; }
.nl-follow-row-locked:hover { background: transparent; }
.nl-follow-check { flex-shrink: 0; width: 16px; height: 16px;
    cursor: pointer; accent-color: var(--accent); }
.nl-follow-row-locked .nl-follow-check { cursor: not-allowed; }
.nl-follow-info { flex: 1; min-width: 0; display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.nl-follow-info strong { font-size: 0.9rem; font-weight: 500; }

@media (max-width: 640px) {
    .nl-row { flex-direction: column; align-items: stretch; }
    .nl-row-actions { justify-content: flex-end; }
    .nl-feed-group-actions { width: 100%; margin-left: 0; margin-top: 0.3rem; justify-content: flex-end; }
    .nl-feed-group-head { flex-wrap: wrap; }
    .nl-feed-row { padding-left: 0.85rem; }
}

/* Newsletter edit page (/newsletters/{id}/edit) */
.nl-back-link { display: inline-block; margin-bottom: 0.5rem; }
.nl-toggle-row { margin-top: 0; }
.badge-default { background: var(--accent-light); color: var(--accent); }
.badge-paused { background: var(--bg-muted, var(--bg-card)); color: var(--text-muted);
    border: 1px solid var(--border); }

/* Followed-story scope badges + menu sections (wave 4) */
.badge-scope {
    background: var(--accent-light);
    color: var(--accent);
    border: 1px solid var(--accent);
}
.badge-scope-global {
    background: var(--bg-muted, var(--bg-subtle));
    color: var(--text-muted);
    border: 1px solid var(--border);
}
.follow-menu-section {
    padding: 0.4rem 0.85rem 0.2rem;
    font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--text-muted); font-weight: 700;
}
.follow-menu-divider {
    height: 1px; background: var(--border); margin: 0.3rem 0;
}

/* Newsletter list row meta — scannable pills instead of text dots */
.nl-meta-pill {
    display: inline-block;
    padding: 0.12rem 0.5rem;
    border-radius: 999px;
    background: var(--bg-muted, var(--bg-subtle));
    color: var(--text-muted);
    font-size: 0.78rem;
    line-height: 1.5;
}
.nl-inline-form { display: inline; }

/* Wave 5 — Send-to-list section (newsletter edit) */
.badge-enterprise {
    background: linear-gradient(135deg, var(--accent), var(--accent-light));
    color: var(--bg-card); padding: 0.12rem 0.5rem; border-radius: 999px;
    font-size: 0.65rem; font-weight: 700; letter-spacing: 0.05em;
    text-transform: uppercase; margin-left: 0.35rem; vertical-align: middle;
}
.nl-smtp-block {
    margin-top: 0.5rem; padding: 0.85rem 1rem;
    background: var(--bg-subtle); border-radius: 8px;
    transition: opacity 0.15s;
}
.nl-smtp-block.is-disabled {
    opacity: 0.5; pointer-events: none;
}
.nl-subhead {
    margin: 0.5rem 0 0.4rem; font-size: 0.85rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted);
}
.nl-subhead:first-child { margin-top: 0; }
#recipient-count-hint.is-over-cap { color: var(--error); font-weight: 700; }
.smtp-test-result {
    margin-left: 0.65rem; font-size: 0.85rem;
}
.smtp-test-result.is-pending { color: var(--text-muted); }
.smtp-test-result.is-ok { color: var(--success); }
.smtp-test-result.is-error { color: var(--error); }

/* Wave 5 — Approve banner on /briefing/{id} */
.alert-approve {
    background: var(--warning-light, #fff7e6);
    border: 1px solid var(--warning, #f59e0b);
    color: var(--text);
    display: flex; align-items: center; justify-content: space-between;
    gap: 0.85rem; padding: 0.6rem 0.85rem;
    border-radius: 8px; margin-bottom: 0.75rem;
}
.approve-banner-text {
    display: flex; align-items: center; gap: 0.5rem; flex: 1; min-width: 0;
}
.approve-banner-actions {
    display: flex; gap: 0.5rem; flex-shrink: 0;
}
.np-status-pill {
    font-size: 0.85rem; padding: 0.4rem 0.75rem; gap: 0.4rem;
}
/* Keep checkmark + label on a single line. Without this, the .alert
   flex container could wrap the inner span on narrow widths (mobile +
   chip strip eating horizontal room) — the SVG would land above the
   text instead of next to it, eating an extra line of vertical space. */
.np-status-pill > span {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex: 1 1 auto;
    min-width: 0;
}
.np-status-pill svg { flex-shrink: 0; vertical-align: middle; margin: 0; }

/* Brand color swatch (newsletter edit page) — visual preview of the hex
   value typed in the input. background is set inline by onBrandColorChange
   because the value is user-driven and bound to live input state. */
.brand-color-swatch {
    display: inline-block;
    width: 28px; height: 28px;
    border-radius: 6px;
    border: 1px solid var(--border);
    margin-left: 0.5rem;
    vertical-align: middle;
}
.brand-color-swatch.is-empty {
    background: repeating-linear-gradient(45deg,
        var(--bg-subtle) 0 4px, var(--bg-card) 4px 8px) !important;
}

/* Per-newsletter brand kicker — only rendered when brand.name != FeedLynx,
   so Default brief keeps its current header. --brand-primary is set
   inline on the hero from `brand.primary_color`. */
.np-brand-row {
    display: flex; align-items: center; gap: 0.65rem;
    padding-bottom: 0.35rem; margin-bottom: 0.55rem;
    border-bottom: 2px solid var(--brand-primary, var(--accent));
}
.np-brand-logo {
    width: 28px; height: 28px; border-radius: 4px;
    object-fit: contain; background: transparent;
}
.np-brand-kicker {
    font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase;
    font-weight: 700; color: var(--brand-primary, var(--accent));
}
.np-brand-tagline {
    font-size: 0.78rem; color: var(--text-muted); font-style: italic;
}
@media (max-width: 640px) {
    .np-brand-tagline { display: none; }
}

/* Schedule "What will happen" live preview */
.schedule-preview {
    margin-top: 0.5rem;
    padding: 0.65rem 0.85rem;
    border-radius: 8px;
    background: var(--accent-light, var(--bg-subtle));
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.45;
    border-left: 3px solid var(--accent, var(--border));
}
.schedule-preview-label { display: block; font-size: 0.78rem;
    text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted);
    margin-bottom: 0.15rem; }

/* ============================================================
   Briefings hub (/newsletters)
   ============================================================ */
.briefings-hub { display: flex; flex-direction: column; gap: 1.5rem; }
/* ============================================================
   Tier-aware premium cues (subtle, no base-color override).
   Activated by data-tier on <body> set by base.html.
   ============================================================ */

/* Pro — a soft accent line under the hero icon. Just enough to signal
   "this is a paid tier" without changing the visual hierarchy. */
body[data-tier="pro"] .following-hero-title .page-title-icon,
body[data-tier="enterprise"] .following-hero-title .page-title-icon {
  position: relative;
}
body[data-tier="pro"] .following-hero-title .page-title-icon::after,
body[data-tier="enterprise"] .following-hero-title .page-title-icon::after {
  content: ""; display: block; height: 2px;
  margin-top: 4px; border-radius: 2px;
}
body[data-tier="pro"] .following-hero-title .page-title-icon::after {
  background: linear-gradient(90deg, var(--accent) 0%, transparent 100%);
}
body[data-tier="enterprise"] .following-hero-title .page-title-icon::after {
  background: linear-gradient(90deg, #d4af37 0%, var(--accent) 60%, transparent 100%);
}

/* Enterprise — refined card elevation. Slightly warmer border (a hint of
   gold-mixed-with-accent) plus a soft layered shadow on cards/sections.
   Hover lifts a touch more than the default. */
body[data-tier="enterprise"] .briefings-card,
body[data-tier="enterprise"] .set-section {
  border-color: color-mix(in srgb, #d4af37 8%, var(--border));
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 0 0 1px rgba(212, 175, 55, 0.04) inset;
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
body[data-tier="enterprise"] .briefings-card:hover {
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.08), 0 0 0 1px rgba(212, 175, 55, 0.10) inset;
  transform: translateY(-1px);
}
[data-theme="dark"] body[data-tier="enterprise"] .briefings-card,
[data-theme="dark"] body[data-tier="enterprise"] .set-section {
  border-color: color-mix(in srgb, #d4af37 12%, var(--border));
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(212, 175, 55, 0.05) inset;
}

/* Enterprise — subtle premium pill on the hero count. Picks up the same
   warm accent so the user identity tier badge and the page-level chrome
   feel like they're from the same family. */
body[data-tier="enterprise"] .following-hero-count strong {
  background: linear-gradient(135deg, #d4af37 10%, var(--accent) 90%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

/* Settings horizontal pill nav (replaces the old left sidebar). Same
   pattern as the briefings hub filter chips: scroll-x on mobile, sticky
   active state. The active pill is set client-side via the IntersectionObserver
   in the settings.html bottom script (deep-links land in the right pill). */
.settings-pillnav { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; padding: 0.25rem 0; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
.settings-pill { display: inline-flex; align-items: center; padding: 0.4rem 0.85rem; border-radius: 999px; font-size: 0.84rem; font-weight: 500; color: var(--text-secondary); background: var(--bg-card); border: 1px solid var(--border, #e4e4e7); text-decoration: none; white-space: nowrap; transition: background 0.15s, color 0.15s, border-color 0.15s; }
.settings-pill:hover { background: var(--bg-subtle); color: var(--text); }
.settings-pill.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.settings-pill.active:hover { background: var(--accent-hover); color: #fff; }
.settings-pill-link { color: var(--accent); border-color: var(--accent-soft); }
.settings-pill-sep { color: var(--border, #e4e4e7); padding: 0 0.3rem; font-size: 0.85rem; user-select: none; }
@media (max-width: 640px) {
    .settings-pillnav { flex-wrap: nowrap; padding-bottom: 0.5rem; }
    .settings-pill-sep { display: none; }
}

.brief-pill-pending { background: rgba(245,158,11,0.15); color: #b45309; border: 1px solid rgba(245,158,11,0.3); font-weight: 600; text-decoration: none; padding: 0.2rem 0.65rem; border-radius: 999px; font-size: 0.78rem; line-height: 1.4; }
.brief-pill-pending:hover { background: rgba(245,158,11,0.25); }
[data-theme="dark"] .brief-pill-pending { background: rgba(245,158,11,0.2); color: #fbbf24; border-color: rgba(245,158,11,0.4); }

.briefings-section { display: flex; flex-direction: column; gap: 0.85rem; }
.briefings-section-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
.briefings-section-title { font-size: 1.05rem; font-weight: 600; margin: 0; color: var(--text); }
.briefings-section-note { font-size: 0.88rem; color: var(--text-muted); padding: 0.65rem 0.9rem; background: var(--bg-subtle); border-radius: 8px; margin: 0; }

/* Configured cards (Enterprise) */
.briefings-cards { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.briefings-card { background: var(--bg-card); border: 1px solid var(--border, #e4e4e7); border-radius: 12px; padding: 0.95rem 1rem; display: flex; flex-direction: column; gap: 0.7rem; }
.briefings-card-paused { opacity: 0.65; }
.briefings-card-head { display: flex; justify-content: space-between; align-items: flex-start; }
.briefings-card-title-wrap { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.briefings-card-title { font-size: 1rem; font-weight: 600; margin: 0; line-height: 1.3; }
.briefings-card-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 0.35rem 0.7rem; margin: 0; font-size: 0.84rem; }
.briefings-card-meta dt { color: var(--text-muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; margin: 0; }
.briefings-card-meta dd { color: var(--text); margin: 0; }
.briefings-card-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }
.briefings-card-delete { margin: 0; }

.briefings-create { background: var(--bg-subtle); border: 1px dashed var(--border, #e4e4e7); border-radius: 12px; padding: 0; }
.briefings-create-summary { padding: 0.85rem 1rem; cursor: pointer; font-weight: 500; color: var(--accent); user-select: none; }
.briefings-create-form { padding: 0 1rem 1rem; }
.briefings-create-row { display: grid; gap: 0.65rem; grid-template-columns: 1fr 1fr auto; align-items: end; }
.briefings-create-row label { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.85rem; }
.briefings-label { color: var(--text-muted); font-size: 0.78rem; }
@media (max-width: 640px) {
    .briefings-create-row { grid-template-columns: 1fr; }
}

/* Pills for inline status indicators on cards */
.brief-pill { display: inline-block; padding: 0.1rem 0.5rem; font-size: 0.7rem; border-radius: 999px; line-height: 1.4; font-weight: 500; }
.brief-pill-muted { background: var(--bg-subtle); color: var(--text-muted); border: 1px solid var(--border, #e4e4e7); }

/* Filter chips */
.briefings-filters { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; padding: 0.25rem 0; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
.brief-chip { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.35rem 0.75rem; border-radius: 999px; font-size: 0.82rem; font-weight: 500; color: var(--text-secondary); background: var(--bg-card); border: 1px solid var(--border, #e4e4e7); text-decoration: none; white-space: nowrap; transition: background 0.15s, color 0.15s; }
.brief-chip:hover { background: var(--bg-subtle); }
.brief-chip-active { background: var(--accent); color: #fff; border-color: var(--accent); }
.brief-chip-active:hover { background: var(--accent-hover); }
.brief-chip em { font-style: normal; opacity: 0.8; }
.brief-chip-status { color: var(--text-muted); }
.brief-chip-sep { color: var(--border, #e4e4e7); padding: 0 0.3rem; }
@media (max-width: 640px) {
    .briefings-filters { flex-wrap: nowrap; padding-bottom: 0.5rem; }
    .brief-chip-sep { display: none; }
}

/* Brief list */
.briefings-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.briefings-row { background: var(--bg-card); border: 1px solid var(--border, #e4e4e7); border-radius: 10px; overflow: hidden; transition: border-color 0.15s, background 0.15s; position: relative; }
.briefings-row:hover { border-color: var(--accent); }
.briefings-row-pending { border-left: 4px solid #f59e0b; background: linear-gradient(0deg, var(--bg-card), var(--bg-card)) padding-box; }
.briefings-row-rejected { opacity: 0.65; }
.briefings-row-link { display: flex; flex-direction: column; gap: 0.3rem; padding: 0.85rem 1rem; text-decoration: none; color: var(--text); position: relative; }
.briefings-row-meta { display: flex; align-items: center; gap: 0.4rem; font-size: 0.92rem; flex-wrap: wrap; }
.briefings-row-newsletter { font-weight: 600; color: var(--text); }
.briefings-row-sep { color: var(--text-muted); }
.briefings-row-time { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.briefings-row-stats { display: flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; color: var(--text-muted); flex-wrap: wrap; }
/* Stat chips: every direct <span> inside the stats row becomes an
   inline-flex so the inline SVG icon (audio speaker) aligns with the
   following text label instead of floating on top of it. Without this,
   the SVG's default `inline` baseline sometimes collides with the
   "Audio" / "Sent" text on certain font/zoom combos. */
.briefings-row-stats > span { display: inline-flex; align-items: center; gap: 0.25rem; line-height: 1.2; }
.briefings-row-stats > span > svg { flex-shrink: 0; }
.briefings-row-stat-sep { opacity: 0.5; }
.brief-status-pill { position: absolute; top: 0.85rem; right: 1rem; padding: 0.15rem 0.55rem; border-radius: 999px; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.brief-status-pending { background: rgba(245, 158, 11, 0.15); color: #b45309; }
.brief-status-approved { background: rgba(34, 197, 94, 0.15); color: #15803d; }
.brief-status-rejected { background: rgba(239, 68, 68, 0.15); color: #b91c1c; }
[data-theme="dark"] .brief-status-pending { background: rgba(245, 158, 11, 0.2); color: #fbbf24; }
[data-theme="dark"] .brief-status-approved { background: rgba(34, 197, 94, 0.2); color: #4ade80; }
[data-theme="dark"] .brief-status-rejected { background: rgba(239, 68, 68, 0.2); color: #f87171; }
.briefings-row-actions { display: flex; gap: 0.5rem; padding: 0 1rem 0.85rem; flex-wrap: wrap; border-top: 1px dashed var(--border, #e4e4e7); padding-top: 0.65rem; margin-top: -0.3rem; }
@media (max-width: 640px) {
    .briefings-row-link { padding: 0.75rem 0.85rem; }
    .brief-status-pill { position: static; align-self: flex-start; margin-top: 0.2rem; }
    .briefings-row-actions { padding: 0.65rem 0.85rem; }
    .briefings-row-actions .btn { flex: 1 1 auto; min-height: 44px; }
}

/* Empty state */
.briefings-empty { padding: 1.5rem 1.25rem; text-align: center; background: var(--bg-subtle); border-radius: 12px; color: var(--text-muted); display: flex; flex-direction: column; align-items: center; gap: 0.85rem; }
.briefings-empty p { margin: 0; }

/* Pager */
.briefings-pager { display: flex; align-items: center; justify-content: space-between; padding: 0.65rem 0.25rem 0; gap: 0.75rem; flex-wrap: wrap; }
.briefings-pager-count { font-size: 0.8rem; color: var(--text-muted); }
@media (max-width: 640px) {
    .briefings-pager { flex-direction: column; }
    .briefings-pager .btn { width: 100%; }
}

/* Toast (shared with hub interactions) */
.briefings-toast { position: fixed; bottom: 1.5rem; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--text); color: var(--bg); padding: 0.7rem 1.1rem; border-radius: 8px; font-size: 0.9rem; opacity: 0; transition: transform 0.25s, opacity 0.25s; z-index: 9999; pointer-events: none; max-width: calc(100% - 2rem); box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
.briefings-toast-show { opacity: 1; transform: translateX(-50%) translateY(0); }
.briefings-toast-error { background: #b91c1c; color: #fff; }

/* Outline danger button (used for Reject) */
.btn-danger-outline { background: transparent; color: #b91c1c; border: 1px solid #b91c1c; }
.btn-danger-outline:hover { background: #b91c1c; color: #fff; }
[data-theme="dark"] .btn-danger-outline { color: #f87171; border-color: #f87171; }

/* === Dashboard Chat panel ===
   Default state: just the .disc-hero-search-style input (compact,
   reads like a familiar search bar). On submit, the .np-chat-body
   panel expands above the input with the conversation. */

.np-chat-body[hidden] { display: none !important; }

.np-chat {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0.75rem 0 1.25rem;
}
.np-chat.is-expanded {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0.65rem 0.85rem 0.85rem;
  gap: 0.75rem;
}

/* Rotating gradient border around the dashboard chat input.
   Uses a CSS @property-animated conic gradient so the rotation lives
   *in* the gradient itself — no transform on a pseudo, which means
   the corners never poke out of the rounded rectangle.
   Browsers without @property support fall back to a static gradient. */
@property --np-chat-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
.np-chat-search.disc-hero-search {
  /* The container itself becomes the 2px ring. The actual input below
     opts out of its own border + box-shadow so only the rotating ring
     reads as the frame. Defaults are the Free / neutral palette; tier
     overrides swap the gradient colours further down. */
  padding: 2px;
  border-radius: 12px;
  background:
    conic-gradient(from var(--np-chat-angle, 0deg),
      var(--accent) 0%, color-mix(in srgb, var(--accent) 60%, transparent) 50%, var(--accent) 100%);
  animation: np-chat-spin 5s linear infinite;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--accent) 10%, transparent),
    0 6px 24px -8px color-mix(in srgb, var(--accent) 35%, transparent);
}
/* Pro: indigo → blue → cyan. */
.app-body[data-tier="pro"] .np-chat-search.disc-hero-search {
  background:
    conic-gradient(from var(--np-chat-angle, 0deg),
      #6366F1 0%, #3B82F6 25%, #06B6D4 50%, #3B82F6 75%, #6366F1 100%);
  box-shadow:
    0 0 0 1px rgba(99,102,241,0.10),
    0 6px 24px -8px rgba(59,130,246,0.40);
}
.np-chat-search.disc-hero-search input {
  border: none !important;
  border-radius: 10px !important;
  background: var(--bg-card) !important;
  box-shadow: none !important;
}
.np-chat-search.disc-hero-search input:focus {
  border: none !important;
  box-shadow: 0 0 0 1px rgba(99,102,241,0.18) inset !important;
}
.np-chat-search.disc-hero-search .disc-hero-icon { left: 0.95rem; }
@keyframes np-chat-spin {
  to { --np-chat-angle: 360deg; }
}
/* Enterprise gets amber→bronze, Pro inherits the default (indigo→cyan).
   Free also keeps the default. Body data-tier attribute is set by the
   base.html on every authed page. */
.app-body[data-tier="enterprise"] .np-chat-search.disc-hero-search {
  background:
    conic-gradient(from var(--np-chat-angle, 0deg),
      #FBBF24 0%, #F59E0B 25%, #D97706 50%, #B45309 75%, #FBBF24 100%);
  box-shadow:
    0 0 0 1px rgba(245,158,11,0.10),
    0 6px 24px -8px rgba(217,119,6,0.4);
}
@media (prefers-reduced-motion: reduce) {
  .np-chat-search.disc-hero-search { animation: none; }
}

/* Search-bar style input — reuses .disc-hero-search shell. The send
   button sits on the right of the input like a clear-X would. */
.np-chat-search.disc-hero-search input {
  /* room for the chat-bubble icon on the left and two buttons (web toggle +
     send) on the right, matching the .disc-hero-search clear-button pattern */
  padding-right: 4.8rem !important;
}
.np-chat-send-inline {
  position: absolute;
  right: 0.4rem;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--text-muted);
  border: 0;
  border-radius: 8px;
  width: 1.9rem;
  height: 1.9rem;
  padding: 0;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, transform 0.05s, opacity 0.15s;
}
.np-chat-send-inline:hover:not(:disabled) {
  background: var(--bg-subtle);
  color: var(--accent);
}
.np-chat-send-inline:active:not(:disabled) { transform: translateY(-50%) scale(0.94); }
.np-chat-send-inline:disabled { opacity: 0.5; cursor: not-allowed; }

/* Web search toggle (🌐) inside the chat input bar.
   States — OFF: outline grey; ON: filled accent.
   Matches the .np-chat-send-inline sibling for size/padding. */
.np-chat-web-toggle {
    position: absolute;
    right: 2.6rem;   /* just left of .np-chat-send-inline (0.4rem + 1.9rem + 0.3rem gap) */
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    border-radius: 8px;
    cursor: pointer;
    padding: 0;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.np-chat-web-toggle:hover {
    color: var(--text);
    background: color-mix(in srgb, var(--text-muted) 8%, transparent);
}
.np-chat-web-toggle.is-on {
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}
.np-chat-web-toggle:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--accent) 50%, transparent);
    outline-offset: 1px;
}

/* Conversation body — hidden until the user submits the first question */
.np-chat-body {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.np-chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.np-chat-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-muted);
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.np-chat-brand-icon {
  color: var(--accent);
  flex-shrink: 0;
}
.np-chat-actions { display: inline-flex; gap: 0.25rem; }
.np-chat-icon-btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  width: 1.85rem;
  height: 1.85rem;
  padding: 0;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.np-chat-icon-btn:hover {
  background: var(--bg-subtle);
  color: var(--text);
}

/* Conversation log */
.np-chat-log {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  max-height: 380px;
  overflow-y: auto;
  padding-right: 0.15rem;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.np-chat-log:empty { display: none; }
.np-chat-msg { display: flex; }
.np-chat-msg-user { justify-content: flex-end; }
.np-chat-msg-assistant { justify-content: flex-start; }
.np-chat-bubble {
  max-width: 86%;
  padding: 0.55rem 0.85rem;
  border-radius: 14px;
  font-size: 0.9rem;
  line-height: 1.5;
  word-wrap: break-word;
}
.np-chat-msg-user .np-chat-bubble {
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 6px;
}
.np-chat-msg-assistant .np-chat-bubble {
  background: var(--bg-subtle);
  color: var(--text);
  border: 1px solid var(--border);
  border-bottom-left-radius: 6px;
}
.np-chat-bubble p { margin: 0 0 0.4rem; }
.np-chat-bubble p:last-child { margin-bottom: 0; }
.np-chat-bubble ul, .np-chat-bubble ol { margin: 0.2rem 0 0.4rem; padding-left: 1.1rem; }
.np-chat-bubble a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.np-chat-msg-assistant .np-chat-bubble a { color: var(--accent); }

.np-chat-meta {
  font-size: 0.75rem;
  color: var(--text-muted);
  min-height: 1em;
}

[data-theme="dark"] .btn-danger-outline:hover { background: #b91c1c; color: #fff; border-color: #b91c1c; }

/* ==================== Interest-led wizard ==================== */
/* Modern SaaS aesthetic — system fonts, accent-blue, soft shadows.
   All colors via CSS vars → light + dark via [data-theme] inherited. */

body.is-onboarding .ob-layout {
  max-width: 720px; margin: 0 auto;
  padding: 1.25rem 1rem 7rem;
  background-image:
    radial-gradient(900px circle at 50% -100px,
                    var(--accent-soft) 0%, transparent 55%);
  background-attachment: fixed;
}

/* ─── Top bar (brand + step counter) ─── */
.ob-topbar {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 2.25rem; padding: 0 0.1rem;
}
.ob-brand {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-weight: 700; font-size: 0.95rem; letter-spacing: -0.01em;
}
.ob-brand-mark {
  width: 24px; height: 24px; display: inline-block; flex-shrink: 0;
  object-fit: contain;
}
.ob-step-counter {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-size: 0.78rem; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.ob-step-counter strong { color: var(--text); font-weight: 600; }
.ob-step-track { display: inline-flex; gap: 4px; margin-left: 0.4rem; }
.ob-step-dot { width: 18px; height: 3px; border-radius: 2px; background: var(--border); }
.ob-step-dot.is-active { background: var(--accent); }

/* ─── Hero ─── */
.ob-hero { text-align: center; margin-bottom: 2.25rem; padding: 0.5rem 0.25rem 0; }
.ob-eyebrow {
  display: inline-block;
  font-size: 0.7rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--accent); padding: 0.3rem 0.75rem;
  background: var(--accent-soft); border-radius: 999px;
  margin-bottom: 1rem;
}
.ob-hero .ob-title {
  font-size: clamp(1.85rem, 5vw, 2.5rem);
  font-weight: 700; letter-spacing: -0.025em; line-height: 1.1;
  margin: 0;
}
.ob-title-accent {
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ob-lede {
  margin: 0.85rem auto 0; max-width: 38ch;
  color: var(--text-muted); font-size: 0.95rem;
}

/* ─── Section caption above chip grid ─── */
.ob-section-head {
  display: flex; justify-content: space-between; align-items: baseline;
  margin: 1.75rem 0 0.85rem; padding: 0 0.1rem;
}
.ob-section-title { font-size: 0.92rem; font-weight: 600; }
.ob-section-hint { font-size: 0.78rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ob-section-hint b { color: var(--accent); font-weight: 600; }

/* ─── Chip grid: 2 cols desktop / 1 col mobile, multi-line, no truncate ─── */
.ob-chip-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem;
}
.ob-chip {
  position: relative;
  display: grid; grid-template-columns: 38px 1fr; gap: 0.7rem;
  align-items: start;
  padding: 0.85rem 0.95rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
  text-align: left;
  color: inherit;
  font: inherit;
  transition: border-color 0.15s, background 0.15s, transform 0.08s, box-shadow 0.15s;
  min-height: 60px;
}
.ob-chip:hover {
  border-color: var(--text-muted);
  box-shadow: 0 4px 14px -2px rgba(0,0,0,0.08);
  transform: translateY(-1px);
}
[data-theme="dark"] .ob-chip:hover {
  box-shadow: 0 4px 14px -2px rgba(0,0,0,0.4);
}
.ob-chip.is-selected {
  background: linear-gradient(135deg,
              var(--accent-soft) 0%,
              color-mix(in srgb, var(--bg-card) 92%, var(--accent)) 100%);
  border-color: var(--accent);
  box-shadow: 0 8px 24px -4px color-mix(in srgb, var(--accent) 25%, transparent);
}
.ob-chip:active { transform: translateY(0); }
.ob-chip-emoji {
  width: 38px; height: 38px; display: grid; place-items: center;
  font-size: 1.3rem; line-height: 1;
  background: var(--bg-subtle); border-radius: 10px;
  transition: background 0.15s, transform 0.2s;
}
.ob-chip.is-selected .ob-chip-emoji {
  background: var(--bg-card);
  transform: scale(1.06) rotate(-3deg);
}
.ob-chip-text { min-width: 0; }
.ob-chip-label {
  display: block;
  font-weight: 600; font-size: 0.93rem; line-height: 1.25;
  color: var(--text);
  /* multi-line allowed — NO ellipsis */
  white-space: normal; overflow: visible;
}
.ob-chip-sub {
  display: block; margin-top: 0.25rem;
  font-size: 0.74rem; color: var(--text-muted);
  letter-spacing: 0.01em; font-variant-numeric: tabular-nums;
  /* Hashtag preview line can also wrap if needed */
  white-space: normal; overflow: visible;
}
.ob-chip-check {
  position: absolute; top: 10px; right: 10px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--accent); color: #fff;
  display: none; place-items: center;
  box-shadow: 0 2px 6px color-mix(in srgb, var(--accent) 40%, transparent);
}
.ob-chip.is-selected .ob-chip-check { display: grid; }

/* ─── Counter card (big number) ─── */
.ob-counter-card {
  margin-top: 1.4rem; padding: 1.3rem 1.25rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 1.1rem; align-items: center;
}
.ob-counter-number {
  font-size: 3.2rem; font-weight: 700;
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  -webkit-background-clip: text; background-clip: text; color: transparent;
  line-height: 0.95; letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}
.ob-counter-meta strong {
  display: block; font-weight: 600; font-size: 0.98rem;
  margin-bottom: 0.15rem;
}
.ob-counter-meta span {
  font-size: 0.78rem; color: var(--text-muted);
}
.ob-customize-toggle {
  font: inherit; font-size: 0.83rem; font-weight: 500;
  background: var(--bg-subtle); color: var(--text);
  border: 1px solid var(--border);
  padding: 0.55rem 0.85rem; border-radius: 8px;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 0.4rem;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.ob-customize-toggle:hover {
  background: var(--accent-soft); border-color: var(--accent);
  color: var(--accent);
}
.ob-customize-toggle .ob-toggle-caret { transition: transform 0.2s ease; }
.ob-customize-toggle.is-open .ob-toggle-caret { transform: rotate(180deg); }

/* ─── Feed list (collapsible) ─── */
.ob-feed-list {
  margin-top: 0.6rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0.4rem;
  max-height: 320px; overflow-y: auto;
}
.ob-feed-row {
  display: grid; grid-template-columns: 22px 1fr auto;
  gap: 0.6rem; align-items: center;
  padding: 0.55rem 0.65rem; border-radius: 8px;
  cursor: pointer; transition: background 0.12s ease;
}
.ob-feed-row:hover { background: var(--bg-subtle); }
.ob-feed-row input { accent-color: var(--accent); cursor: pointer; }
.ob-feed-name { font-size: 0.88rem; font-weight: 500; color: var(--text); }
.ob-feed-source {
  font-size: 0.72rem; color: var(--text-muted);
  background: var(--bg-subtle);
  padding: 0.18rem 0.5rem; border-radius: 999px;
  white-space: nowrap;
}

.ob-empty-warn {
  margin: 0.65rem 0 0; padding: 0.6rem 0.85rem;
  border-radius: 10px;
  background: color-mix(in srgb, var(--warning, #F5A524) 12%, transparent);
  color: var(--warning, #92400E); font-size: 0.82rem;
}
[data-theme="dark"] .ob-empty-warn { color: var(--warning-text, #fbbf24); }

/* ─── Language picker card ─── */
.ob-lang-card {
  margin-top: 1.4rem; padding: 1.15rem 1.25rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
  display: grid; grid-template-columns: 1fr auto;
  gap: 1rem; align-items: center;
}
.ob-lang-text strong {
  display: block; font-weight: 600; font-size: 0.94rem; margin-bottom: 0.15rem;
}
.ob-lang-text span { font-size: 0.78rem; color: var(--text-muted); }
.ob-lang-select {
  font: inherit; font-size: 0.88rem; font-weight: 500;
  padding: 0.55rem 0.85rem; padding-right: 2rem;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-subtle)
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='none' stroke='%2371717a' stroke-width='1.5' d='M1 1l4 4 4-4'/></svg>")
    no-repeat right 0.7rem center;
  appearance: none; -webkit-appearance: none;
  color: var(--text); cursor: pointer;
  transition: border-color 0.15s, background-color 0.15s;
}
.ob-lang-select:hover { border-color: var(--text-muted); }
.ob-lang-select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ─── Pro trial disclosure (sits just above the sticky launch bar) ─── */
.ob-trial-note {
  margin: 1.4rem 0 0; padding: 0.7rem 1rem;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  border-radius: 12px;
  font-size: 0.83rem; line-height: 1.4;
  color: var(--text);
  display: flex; align-items: center; gap: 0.55rem;
  flex-wrap: wrap;
}
.ob-trial-note strong { color: var(--accent); font-weight: 600; }
.ob-trial-icon {
  font-size: 1.05rem; line-height: 1;
  flex-shrink: 0;
}

/* ─── Launch bar (sticky) ─── */
.ob-launch-bar {
  position: sticky; bottom: 1rem; z-index: 5;
  margin-top: 1.6rem; padding: 0.85rem 1rem;
  background: color-mix(in srgb, var(--bg-card) 95%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 16px 40px -8px rgba(0,0,0,0.12);
  display: flex; justify-content: flex-end; align-items: center;
  gap: 0.75rem; flex-wrap: wrap;
}
[data-theme="dark"] .ob-launch-bar { box-shadow: 0 16px 40px -8px rgba(0,0,0,0.5); }
.ob-launch-btn {
  font: inherit; font-size: 0.92rem; font-weight: 600;
  color: #fff;
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  border: none; padding: 0.7rem 1.3rem; border-radius: 10px;
  cursor: pointer; letter-spacing: -0.01em;
  display: inline-flex; align-items: center; gap: 0.5rem;
  box-shadow: 0 8px 24px -4px color-mix(in srgb, var(--accent) 30%, transparent);
  transition: transform 0.12s, box-shadow 0.15s, opacity 0.15s;
}
.ob-launch-btn:hover:not([disabled]) {
  transform: translateY(-1px);
  box-shadow: 0 12px 28px -6px color-mix(in srgb, var(--accent) 40%, transparent);
}
.ob-launch-btn[disabled] {
  opacity: 0.45; cursor: not-allowed;
  transform: none; box-shadow: none;
}

/* ─── Mobile ─── */
@media (max-width: 540px) {
  body.is-onboarding .ob-layout { padding: 1rem 0.85rem 6.5rem; }
  .ob-topbar { margin-bottom: 1.75rem; }
  .ob-chip-grid { grid-template-columns: 1fr; }
  .ob-hero .ob-title { font-size: 1.75rem; }
  .ob-counter-card { grid-template-columns: auto 1fr; gap: 0.85rem; padding: 1.1rem; }
  .ob-counter-number { font-size: 2.5rem; }
  .ob-customize-toggle { grid-column: 1 / -1; margin-top: 0.4rem; justify-content: center; }
  .ob-lang-card { grid-template-columns: 1fr; }
  .ob-launch-bar {
    grid-template-columns: 1fr; bottom: 0.5rem;
    padding-bottom: max(0.85rem, env(safe-area-inset-bottom));
  }
}

/* ===================== API Access (settings) =====================
   The card sits inside .set-section so it picks up section chrome
   automatically. The list rows mirror the "Linked Accounts" pattern
   (label + meta + right-aligned action) but render via JS, so the
   server-rendered <ul> only carries a placeholder. */
/* Pad custom children to match .set-form / .set-oauth-row indent
   (1.25rem horizontal) so the card chrome stays consistent. */
#s-api-access .set-actions {
  padding: 0.25rem 1.25rem 1.15rem;
}
#s-api-access .api-tokens-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 0.75rem 1.25rem 0.75rem;
}
#s-api-access .api-tokens-counter {
  color: var(--text-muted); font-size: 0.85rem;
}
#s-api-access .api-tokens-list {
  list-style: none; padding: 0; margin: 0;
  border-top: 1px solid var(--border-light);
}
#s-api-access .api-tokens-list li {
  padding: 0.75rem 1.25rem;
  border-bottom: 1px solid var(--border-light);
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem;
}
#s-api-access .api-tokens-list li:last-child { border-bottom: 0; }
#s-api-access .api-tokens-list .name {
  font-weight: 600; color: var(--text);
}
#s-api-access .api-tokens-list .meta {
  color: var(--text-muted); font-size: 0.8rem; margin-top: 0.15rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
#s-api-access .api-tokens-empty {
  color: var(--text-muted); font-style: italic;
  border-bottom: 0 !important;
  justify-content: flex-start !important;
}
#s-api-access > .set-hint {
  padding: 0.75rem 1.25rem 1.15rem;
  margin: 0; font-size: 0.78rem; color: var(--text-muted);
  border-top: 1px solid var(--border-light);
}

/* Modal — fixed overlay above everything else. Hidden via the [hidden]
   attribute on the wrapper, no inline style needed. */
.api-tokens-modal {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex; align-items: center; justify-content: center;
  z-index: 9999; padding: 1rem;
}
.api-tokens-modal[hidden] { display: none; }
.api-tokens-modal-content {
  background: var(--bg-card); color: var(--text);
  border: 1px solid var(--border); border-radius: 0.75rem;
  padding: 1.5rem; max-width: 560px; width: 100%;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
}
.api-tokens-modal-content h3 {
  margin: 0 0 0.5rem; font-size: 1.1rem;
}
.api-tokens-modal-token {
  display: block; padding: 0.75rem;
  background: var(--bg-subtle); border: 1px solid var(--border);
  border-radius: 0.5rem; word-break: break-all;
  margin: 1rem 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
}
.api-tokens-modal-actions {
  display: flex; gap: 0.5rem; justify-content: flex-end; flex-wrap: wrap;
}

@media (max-width: 600px) {
  #s-api-access .api-tokens-toolbar {
    flex-direction: column; align-items: stretch;
  }
  #s-api-access .api-tokens-list li {
    flex-direction: column; align-items: flex-start; gap: 0.4rem;
  }
}

/* RAG inline citation badge — the LLM cites a non-owned catalog source
   in the middle of its reply with [[Bx]], replace_refs turns it into a
   pill-shaped link. Clicking it pops a contextual menu (see JS). */
.np-chat-ref-suggest {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0.05rem 0.45rem 0.05rem 0.55rem;
    margin: 0 0.1rem;
    background: linear-gradient(135deg,
        rgba(99, 102, 241, 0.12) 0%,
        rgba(59, 130, 246, 0.12) 100%);
    color: var(--accent);
    border: 1px solid rgba(99, 102, 241, 0.32);
    border-radius: 999px;
    font-size: 0.78em;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: transform 0.12s, box-shadow 0.12s, background 0.12s;
    vertical-align: baseline;
    line-height: 1.2;
    white-space: nowrap;
}
.np-chat-ref-suggest::before {
    content: '＋';
    font-size: 0.9em;
    color: var(--accent);
    opacity: 0.8;
    margin-right: 0.05rem;
    font-weight: 700;
}
.np-chat-ref-suggest:hover {
    background: linear-gradient(135deg,
        rgba(99, 102, 241, 0.2) 0%,
        rgba(59, 130, 246, 0.2) 100%);
    box-shadow: 0 1px 6px rgba(99, 102, 241, 0.25);
    transform: translateY(-1px);
    text-decoration: none;
}
[data-theme="dark"] .np-chat-ref-suggest {
    background: linear-gradient(135deg,
        rgba(99, 102, 241, 0.22) 0%,
        rgba(59, 130, 246, 0.22) 100%);
    border-color: rgba(129, 140, 248, 0.45);
    color: #c7d2fe;
}
[data-theme="dark"] .np-chat-ref-suggest::before { color: #a5b4fc; }
[data-theme="dark"] .np-chat-ref-suggest:hover {
    background: linear-gradient(135deg,
        rgba(99, 102, 241, 0.35) 0%,
        rgba(59, 130, 246, 0.35) 100%);
}

/* Contextual popup that appears below the badge on click. */
.np-chat-suggest-popup {
    position: absolute;
    z-index: 9999;
    min-width: 200px;
    max-width: 320px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18),
                0 2px 6px rgba(0, 0, 0, 0.08);
    padding: 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    animation: np-chat-suggest-pop 0.12s ease-out;
}
@keyframes np-chat-suggest-pop {
    from { opacity: 0; transform: translateY(-4px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0)    scale(1); }
}
.np-chat-suggest-popup-head {
    padding: 0.35rem 0.5rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.np-chat-suggest-popup-head strong {
    font-size: 0.85rem;
    color: var(--text);
}
.np-chat-suggest-popup-title {
    font-size: 0.72rem;
    color: var(--text-muted);
    line-height: 1.3;
    font-style: italic;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.np-chat-suggest-opt {
    text-align: left;
    background: transparent;
    border: none;
    color: var(--text);
    padding: 0.5rem 0.6rem;
    border-radius: 6px;
    font-size: 0.85rem;
    cursor: pointer;
    font-family: inherit;
    transition: background 0.1s;
}
.np-chat-suggest-opt:hover:not(:disabled) {
    background: var(--bg-subtle);
}
.np-chat-suggest-opt:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}
.np-chat-suggest-opt-add {
    color: var(--accent);
    font-weight: 600;
}
.np-chat-suggest-opt-done {
    color: var(--success, #10b981);
}

/* On phones the popup centres horizontally if it would clip; give it
   a touch-friendly height target. */
@media (max-width: 600px) {
    .np-chat-suggest-popup {
        min-width: 240px;
    }
    .np-chat-suggest-opt {
        padding: 0.7rem 0.7rem;
    }
}

/* RAG cross-catalog discovery: feeds you don't follow yet, surfaced
   beneath a chat answer when the catalog has strictly better matches.
   The `.np-chat-msg` wrapper is `display:flex` row by default, which
   would push this block next to the bubble and overlap it. Switching
   the assistant wrapper to column lets the bubble take its natural
   width and this card stack directly under it. */
.np-chat-msg-assistant {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
}
.np-chat-msg-assistant .chat-sources-suggested {
    max-width: 86%;        /* match the bubble's max-width */
    width: 100%;
    margin-top: 0;          /* gap is handled by the wrapper */
    border-top: none;       /* dashed top line moved to first card */
    padding-top: 0;
}
.chat-sources-suggested {
    margin-top: 0.75rem;
    padding-top: 0.6rem;
    border-top: 1px dashed var(--border);
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.chat-sources-suggested-title {
    font-size: 0.72rem;
    color: var(--text-muted);
    margin: 0 0 0.15rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

/* News-card visual: feed name + hostname header, clickable highlight
   block with title + 2-line snippet, action row with the + button. */
.chat-source-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.7rem 0.85rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.chat-source-card:hover {
    border-color: var(--accent);
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
}

.chat-source-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.chat-source-name-block {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    flex: 1;
}
.chat-source-name {
    font-size: 0.92rem;
    color: var(--text);
    line-height: 1.25;
    word-break: break-word;
}
.chat-source-host {
    font-size: 0.7rem;
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: 0.01em;
}
.chat-source-count {
    font-size: 0.7rem;
    color: var(--text-muted);
    background: var(--bg-subtle);
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
    align-self: flex-start;
}

/* Highlight = the clickable preview. Title is bold; snippet clamps to 2
   lines on desktop, 3 on mobile (more vertical room there). */
.chat-source-highlight {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.45rem 0.6rem;
    background: var(--bg-subtle);
    border-radius: 6px;
    text-decoration: none;
    color: var(--text);
    line-height: 1.35;
    border-left: 3px solid var(--accent);
    transition: background 0.15s;
}
.chat-source-highlight:hover {
    background: var(--bg-card);
    text-decoration: none;
}
.chat-source-highlight-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text);
}
.chat-source-snippet {
    font-size: 0.78rem;
    color: var(--text-muted);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chat-source-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 0.1rem;
}
.chat-source-add {
    align-self: stretch;
    text-align: center;
}
.chat-source-add.btn-success {
    background: var(--success, #10b981);
    border-color: transparent;
    color: white;
}

/* Mobile (Flutter WebView, viewports ≤ 600px): more vertical room for
   the snippet, full-width add button so the tap target is generous. */
@media (max-width: 600px) {
    .chat-source-card {
        padding: 0.6rem 0.7rem;
        gap: 0.45rem;
    }
    .chat-source-header {
        flex-direction: column;
        gap: 0.25rem;
    }
    .chat-source-count {
        align-self: flex-start;
    }
    .chat-source-snippet {
        -webkit-line-clamp: 3;
        line-clamp: 3;
    }
    .chat-source-actions {
        justify-content: stretch;
    }
    .chat-source-add {
        width: 100%;
    }
}

/* Desktop (≥ 768px): cards stay inside the bubble's 86% width but cap
   their snippet to 2 lines so the chat scroll stays compact. */
@media (min-width: 768px) {
    .chat-source-card {
        padding: 0.75rem 0.9rem;
    }
}

/* --- Admin: LLM Calls section --- */
.llm-row { cursor: pointer; }
.llm-row:hover { background: var(--bg-subtle); }
.llm-detail-row td { background: var(--bg-subtle); padding: 0.5rem 0.75rem; }
.llm-detail p { margin: 0.5rem 0 0.25rem; font-size: 0.8rem; }
.llm-detail pre {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem;
  max-height: 240px;
  overflow: auto;
  font-size: 0.75rem;
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0 0 0.5rem;
}
.llm-detail pre.llm-detail-error { color: var(--error); border-color: var(--error); }
.text-nowrap { white-space: nowrap; }

/* Citation popover (chat ⋯ menu). Anchored under each citation's menu
   button. Closes on outside-click. */
.np-cite-menu-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    margin-left: 2px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    border-radius: 4px;
    vertical-align: baseline;
}
.np-cite-menu-btn:hover {
    background: color-mix(in srgb, var(--text-muted) 14%, transparent);
    color: var(--text);
}
.np-cite-popover {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 4px;
    min-width: 220px;
    max-width: 360px;
    box-shadow: 0 10px 28px -12px rgba(0,0,0,0.18);
    z-index: 9999;
    font-size: 0.83rem;
}
.np-cite-pop-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.6rem;
    width: 100%;
    background: transparent;
    border: none;
    color: var(--text);
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    border-radius: 6px;
    font: inherit;
}
.np-cite-pop-row:hover { background: color-mix(in srgb, var(--text-muted) 10%, transparent); }
.np-cite-pop-ico { width: 18px; text-align: center; }
.np-cite-pop-rss {
    border-top: 1px solid var(--border);
    margin-top: 4px;
    padding: 0.4rem 0.6rem;
}
.np-cite-pop-rss-head {
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-bottom: 0.3rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.np-cite-pop-rss-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0;
}
.np-cite-pop-rss-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.82rem;
}
.np-cite-pop-add {
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 0.25rem 0.6rem;
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
}
.np-cite-pop-add:disabled { opacity: 0.6; cursor: default; }
.np-cite-pop-loading {
    font-size: 0.8rem;
    color: var(--text-muted);
    font-style: italic;
}
