/* KOLflow shared design system */

/* === v1.0 Apple submission: hide all Sign-in UI globally ===
   The current signin.html is a demo-only placeholder (Google / X / Wallet
   buttons trigger toast notifications, no real OAuth). Apple rejected v1.0
   over guideline 4.8 (third-party login without Sign in with Apple) and
   2.1(a) (the demo Google login looked like a broken feature to reviewers).
   For v1.0 we ship pure read-only browsing. Re-enable these once we have
   real Sign in with Apple support. */
a[href*="signin"],
a[href*="signin.html"],
.profile-avatar,
.mobile-nav-link[href*="signin"] {
  display: none !important;
}

:root {
  --bg:#050609; --ink-950:#050609; --ink-900:#0a0c12; --ink-800:#10131c; --ink-700:#181c28;
  --line:rgba(255,255,255,.08); --line-strong:rgba(255,255,255,.14);
  --text:#e6e7ea; --text-dim:#94979e; --text-faint:#5a5f6a;
  --accent-300:#7df1de; --accent-400:#5eead4; --accent-500:#2dd4bf; --accent-600:#14b8a6;
  --shadow-card:0 20px 60px -30px rgba(0,0,0,.7);
  --radius-md:10px; --radius-lg:16px;
}
*,*::before,*::after{ box-sizing:border-box; }
html,body{ background:var(--bg); color:var(--text); margin:0; padding:0; -webkit-font-smoothing:antialiased; }
/* overflow-x:hidden MUST live on <html>, NOT <body>.
   Per CSS spec, setting one axis to non-visible forces the other to "auto",
   so body{ overflow-x:hidden } silently turns body into a scroll container.
   On iOS WKWebView (Capacitor) the actual document scroll happens on <html>,
   so the sticky header inside <body> picks body as its "nearest scrolling
   ancestor", but body never moves. Result: the KOLflow header scrolls away
   with the page instead of pinning to the top. Hoisting the horizontal-
   overflow guard to <html> preserves the no-sideways-scroll behavior while
   letting body stay non-scrolling, so position:sticky works as intended. */
html{ overflow-x:hidden; }
body{ font-family:'Geist','Noto Sans SC','Noto Sans JP','Noto Sans KR',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,'PingFang SC','Hiragino Sans',sans-serif;
      font-feature-settings:'ss01','ss03','cv11','calt','tnum';
      /* Auto-pick CJK Noto by html lang attr (browsers prefer earliest font with glyph; this also nudges weights) */ }
html[lang="zh-CN"] body, html[lang="zh"] body{ font-family:'Geist','Noto Sans SC',ui-sans-serif,system-ui,-apple-system,'PingFang SC','Microsoft YaHei',sans-serif; }
html[lang="ja"] body{ font-family:'Geist','Noto Sans JP',ui-sans-serif,system-ui,-apple-system,'Hiragino Sans','Yu Gothic',sans-serif; }
html[lang="ko"] body{ font-family:'Geist','Noto Sans KR',ui-sans-serif,system-ui,-apple-system,'Apple SD Gothic Neo','Malgun Gothic',sans-serif; }

.skip-link{ position:absolute; left:-1000px; top:0; background:var(--accent-400); color:#050609; padding:8px 12px; z-index:999; font-weight:600; border-radius:0 0 6px 0; text-decoration:none; }
.skip-link:focus{ left:0; outline:none; }

.mesh{ position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden; }
.blob{ position:absolute; border-radius:9999px; filter:blur(90px); opacity:.55; will-change:transform; }
.b1{ width:620px; height:620px; left:-120px; top:-160px; background:radial-gradient(circle at 30% 30%, #2dd4bf 0%, transparent 60%); animation:drift1 22s ease-in-out infinite alternate; }
.b2{ width:720px; height:720px; right:-160px; top:80px; background:radial-gradient(circle at 60% 50%, #8b5cf6 0%, transparent 60%); animation:drift2 28s ease-in-out infinite alternate; }
.b3{ width:540px; height:540px; left:30%; bottom:-200px; background:radial-gradient(circle at 50% 50%, #6366f1 0%, transparent 60%); animation:drift3 26s ease-in-out infinite alternate; opacity:.35; }
@keyframes drift1{ from{transform:translate3d(0,0,0) scale(1);} to{transform:translate3d(120px,80px,0) scale(1.15);} }
@keyframes drift2{ from{transform:translate3d(0,0,0) scale(1);} to{transform:translate3d(-90px,140px,0) scale(1.1);} }
@keyframes drift3{ from{transform:translate3d(0,0,0) scale(1);} to{transform:translate3d(60px,-80px,0) scale(1.2);} }
.noise{ position:fixed; inset:0; z-index:1; pointer-events:none; opacity:.5; mix-blend-mode:overlay;
        background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1   0 0 0 0 1   0 0 0 0 1   0 0 0 0.16 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }
.grid-bg{ position:fixed; inset:0; z-index:0; pointer-events:none;
          background-image:linear-gradient(rgba(255,255,255,.025) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.025) 1px, transparent 1px);
          background-size:56px 56px; mask-image:radial-gradient(circle at 50% 30%, #000 30%, transparent 75%); -webkit-mask-image:radial-gradient(circle at 50% 30%, #000 30%, transparent 75%); }
.content{ position:relative; z-index:5; }

/* === Floating Back button — always visible on non-home pages === */
.floating-back{
  position:fixed;
  top:80px;          /* sits just below the sticky nav */
  left:16px;
  z-index:25;        /* above content, below sticky nav (z-30) */
  display:inline-flex;
  align-items:center;
  gap:7px;
  padding:9px 15px 9px 12px;
  border-radius:999px;
  background:linear-gradient(135deg, rgba(8,11,18,.85), rgba(15,23,42,.85));
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  border:1px solid rgba(94,234,212,.3);
  color:var(--accent-300);
  font-family:'Geist Mono', monospace;
  font-size:11.5px;
  font-weight:500;
  text-transform:uppercase;
  letter-spacing:.18em;
  text-decoration:none;
  cursor:pointer;
  transition:all .22s cubic-bezier(.2,.7,.2,1);
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset, 0 12px 28px -10px rgba(0,0,0,.6), 0 0 0 1px rgba(94,234,212,.05);
  user-select:none;
  -webkit-user-select:none;
}
.floating-back:hover{
  background:linear-gradient(135deg, rgba(94,234,212,.15), rgba(45,212,191,.1));
  border-color:rgba(94,234,212,.55);
  color:#fff;
  transform:translateX(-3px);
  box-shadow:0 1px 0 rgba(255,255,255,.08) inset, 0 16px 32px -8px rgba(94,234,212,.25), 0 0 0 1px rgba(94,234,212,.2);
}
.floating-back:active{ transform:translateX(-1px); }
.floating-back svg{
  width:13px; height:13px;
  transition:transform .22s cubic-bezier(.2,.7,.2,1);
}
.floating-back:hover svg{ transform:translateX(-2px); }
@media (max-width: 640px){
  /* Compact icon-only pill on mobile — was chunky with text + padding */
  .floating-back{
    top:68px;
    left:10px;
    width:36px;
    height:36px;
    padding:0;
    gap:0;
    border-radius:50%;
    justify-content:center;
    box-shadow:0 4px 14px -4px rgba(0,0,0,.6), 0 0 0 1px rgba(94,234,212,.12);
  }
  .floating-back span{ display:none; }   /* hide "BACK" label on mobile, keep arrow only */
  .floating-back svg{ width:14px; height:14px; }
}

/* === Shared hero section spacing — same across all pages (matches homepage) === */
.hero-section{ padding-top:5rem; padding-bottom:5rem; }
@media (min-width:768px){ .hero-section{ padding-top:7rem; padding-bottom:6rem; } }

/* === AI Digest widget — daily-read card with expand/collapse === */
.ai-digest-card{
  position:relative;
  background:linear-gradient(135deg, rgba(94,234,212,.08) 0%, rgba(139,92,246,.06) 50%, rgba(8,11,18,.78) 100%);
  border:1px solid rgba(94,234,212,.22);
  border-radius:var(--radius-lg);
  padding:22px 26px 18px;
  backdrop-filter:blur(16px);
  -webkit-backdrop-filter:blur(16px);
  overflow:hidden;
  box-shadow:
    0 1px 0 rgba(255,255,255,.05) inset,
    0 0 0 1px rgba(94,234,212,.08),
    0 24px 56px -32px rgba(94,234,212,.45);
  transition:border-color .3s, box-shadow .3s;
}
.ai-digest-card:hover{
  border-color:rgba(94,234,212,.4);
  box-shadow:
    0 1px 0 rgba(255,255,255,.07) inset,
    0 0 0 1px rgba(94,234,212,.15),
    0 28px 70px -28px rgba(94,234,212,.6);
}
/* Animated top scan line */
.ai-digest-card .ai-scan{
  position:absolute; top:0; left:0; right:0; height:1px; pointer-events:none;
  background:linear-gradient(90deg, transparent 0%, rgba(94,234,212,.85) 50%, transparent 100%);
  width:32%;
  animation:aiDigestScan 5s cubic-bezier(.65,.05,.36,1) infinite;
  box-shadow:0 0 14px rgba(94,234,212,.6);
}
@keyframes aiDigestScan{
  0%   { transform:translateX(-30%); opacity:0; }
  15%  { opacity:1; }
  85%  { opacity:1; }
  100% { transform:translateX(360%); opacity:0; }
}
@media (prefers-reduced-motion: reduce){
  .ai-digest-card .ai-scan{ animation:none; opacity:.4; transform:translateX(140%); }
  .ai-spark, .ai-live-dot{ animation:none !important; }
}

/* Header row — badge + LIVE chip */
.ai-digest-head{
  display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap;
  margin-bottom:16px;
}
.ai-digest-badge{
  display:inline-flex; align-items:center; gap:9px;
  padding:6px 13px;
  border-radius:999px;
  background:linear-gradient(135deg, rgba(94,234,212,.14), rgba(139,92,246,.1));
  border:1px solid rgba(94,234,212,.35);
  color:var(--accent-300);
  font-family:'Geist Mono', monospace;
  font-size:11px;
  text-transform:uppercase;
  letter-spacing:.2em;
  font-weight:500;
}
.ai-spark{
  font-size:14px;
  background:linear-gradient(135deg, #5eead4, #8b5cf6 60%, #f472b6);
  -webkit-background-clip:text;
  background-clip:text;
  -webkit-text-fill-color:transparent;
  animation:aiSparkPulse 2.6s ease-in-out infinite;
}
@keyframes aiSparkPulse{
  0%,100% { opacity:1; transform:scale(1) rotate(0deg); }
  50%     { opacity:.6; transform:scale(.85) rotate(180deg); }
}
.ai-live-chip{
  display:inline-flex; align-items:center; gap:7px;
  font-family:'Geist Mono', monospace;
  font-size:10px;
  font-weight:600;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:#86efac;
  padding:4px 9px;
  border-radius:999px;
  background:rgba(74,222,128,.08);
  border:1px solid rgba(74,222,128,.22);
}
.ai-live-dot{
  width:6px; height:6px; border-radius:50%;
  background:#4ade80;
  box-shadow:0 0 8px rgba(74,222,128,.85);
  animation:aiLivePulse 1.6s ease-out infinite;
}
@keyframes aiLivePulse{
  0%,100% { opacity:1; transform:scale(1); }
  50%     { opacity:.45; transform:scale(.7); }
}

/* Headline — the AI's one-sentence read */
.ai-digest-headline{
  font-size:18px;
  line-height:1.45;
  color:var(--text);
  font-weight:500;
  letter-spacing:-.012em;
  margin-bottom:14px;
}

/* Compact narrative tags row */
.ai-digest-tags{
  display:flex; gap:8px; flex-wrap:wrap;
}
.ai-tag{
  display:inline-flex; align-items:center; gap:6px;
  padding:4px 10px 4px 8px;
  border-radius:999px;
  background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.08);
  font-size:11.5px;
  color:var(--text-dim);
  transition:all .18s;
}
.ai-tag:hover{
  background:rgba(94,234,212,.08);
  border-color:rgba(94,234,212,.3);
  color:var(--text);
}
.ai-tag-text{ font-weight:500; }
.ai-tag-count{
  font-family:'Geist Mono', monospace;
  font-size:10px;
  color:rgba(148,163,184,.7);
  font-feature-settings:'tnum' 1;
  padding-left:2px;
  border-left:1px solid rgba(255,255,255,.08);
  margin-left:2px;
}
.ai-trend-up   { color:#86efac; font-size:8px; }
.ai-trend-down { color:#fca5a5; font-size:8px; }
.ai-trend-stable{ color:rgba(148,163,184,.5); font-size:14px; line-height:0; }

/* Expandable section — full read + narrative breakdown */
.ai-digest-expand-wrap{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .45s cubic-bezier(.4,0,.2,1), opacity .3s ease, margin-top .35s ease;
  opacity:0;
  margin-top:0;
  overflow:hidden;
}
.ai-digest-card.is-expanded .ai-digest-expand-wrap{
  grid-template-rows:1fr;
  opacity:1;
  margin-top:18px;
}
.ai-digest-expand-wrap > *{
  min-height:0;
}
.ai-digest-divider{
  height:1px;
  background:linear-gradient(90deg, transparent, rgba(94,234,212,.18) 30%, rgba(94,234,212,.18) 70%, transparent);
  margin-bottom:18px;
}
.ai-digest-section{
  margin-bottom:20px;
}
.ai-digest-section:last-child{ margin-bottom:0; }
.ai-digest-section-label{
  font-family:'Geist Mono', monospace;
  font-size:9.5px;
  text-transform:uppercase;
  letter-spacing:.24em;
  color:var(--accent-300);
  margin-bottom:10px;
  display:flex; align-items:center; gap:8px;
}
.ai-digest-section-label::before{
  content:'';
  width:14px; height:1px;
  background:rgba(94,234,212,.5);
  display:inline-block;
}
.ai-digest-summary{
  font-size:14.5px;
  line-height:1.7;
  color:var(--text-dim);
  margin:0;
}

/* Narrative detailed list */
.ai-narrative-list{
  display:flex; flex-direction:column;
  border:1px solid rgba(255,255,255,.06);
  border-radius:10px;
  overflow:hidden;
  background:rgba(255,255,255,.015);
}
.ai-nrow{
  display:grid;
  grid-template-columns:24px 1fr auto;
  align-items:center;
  gap:12px;
  padding:11px 14px;
  border-bottom:1px solid rgba(255,255,255,.04);
  transition:background .18s;
}
.ai-nrow:last-child{ border-bottom:0; }
.ai-nrow:hover{ background:rgba(94,234,212,.04); }
.ai-nrow-trend{ display:flex; justify-content:center; }
.ai-nrow-tag{
  font-size:13px;
  color:var(--text);
  font-weight:500;
}
.ai-nrow-count{
  display:inline-flex; align-items:baseline; gap:6px;
  font-family:'Geist Mono', monospace;
}
.ai-nrow-num{
  font-size:18px;
  font-weight:500;
  color:#fff;
  background:linear-gradient(180deg,#fff 0%,#5eead4 130%);
  -webkit-background-clip:text;
  background-clip:text;
  -webkit-text-fill-color:transparent;
  font-feature-settings:'tnum' 1;
  letter-spacing:-.02em;
}
.ai-nrow-suffix{
  font-size:9.5px;
  text-transform:uppercase;
  letter-spacing:.18em;
  color:rgba(148,163,184,.6);
}

/* Footer meta inside expanded view */
.ai-digest-foot{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  font-family:'Geist Mono', monospace;
  font-size:10.5px;
  color:rgba(148,163,184,.7);
  text-transform:uppercase;
  letter-spacing:.16em;
}
.ai-digest-meta-stat{
  display:inline-flex; align-items:baseline; gap:4px;
}
.ai-digest-meta-num{
  font-weight:600;
  color:var(--text);
  font-feature-settings:'tnum' 1;
  font-size:13px;
  letter-spacing:0;
}
.ai-digest-meta-suffix{ color:rgba(148,163,184,.65); }
.ai-digest-meta-sep{ color:rgba(148,163,184,.3); }

/* Toggle button */
.ai-digest-toggle{
  display:inline-flex; align-items:center; gap:8px;
  margin-top:16px;
  padding:8px 14px;
  border-radius:8px;
  background:rgba(94,234,212,.06);
  border:1px solid rgba(94,234,212,.2);
  color:var(--accent-300);
  font-family:'Geist Mono', monospace;
  font-size:11px;
  text-transform:uppercase;
  letter-spacing:.18em;
  font-weight:500;
  cursor:pointer;
  transition:all .2s;
}
.ai-digest-toggle:hover{
  background:rgba(94,234,212,.12);
  border-color:rgba(94,234,212,.4);
  color:#fff;
}
.ai-toggle-icon{ transition:transform .3s ease; }
.ai-digest-card.is-expanded .ai-toggle-icon{ transform:rotate(180deg); }

/* Bottom-right timestamp */
.ai-digest-stamp{
  position:absolute;
  right:18px; bottom:14px;
  font-family:'Geist Mono', monospace;
  font-size:9.5px;
  color:rgba(148,163,184,.5);
  text-transform:uppercase;
  letter-spacing:.16em;
}
.ai-digest-card.is-expanded .ai-digest-stamp{ display:none; }

.ai-digest-fallback{
  font-family:'Geist Mono', monospace;
  font-size:12px;
  color:var(--text-faint);
  padding:18px 4px;
  text-align:center;
  border:1px dashed rgba(255,255,255,.1);
  border-radius:var(--radius-lg);
}

@media (max-width: 640px){
  .ai-digest-card{ padding:18px 18px 14px; }
  .ai-digest-headline{ font-size:15.5px; }
  .ai-digest-summary{ font-size:13.5px; }
  .ai-digest-stamp{ right:12px; bottom:10px; font-size:9px; }
  .ai-nrow{ padding:10px 11px; gap:10px; }
}

.glass{ position:relative; background:rgba(255,255,255,.035); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); border:1px solid var(--line); border-top-color:rgba(255,255,255,0.09); border-radius:var(--radius-lg); transition:transform .35s cubic-bezier(.2,.7,.2,1), border-color .35s, background .35s; }
.glass::before{ content:''; position:absolute; inset:0; border-radius:inherit; padding:1px; background:linear-gradient(135deg, rgba(255,255,255,.18), rgba(255,255,255,0) 30%, rgba(255,255,255,0) 70%, rgba(94,234,212,.18)); -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite:xor; mask-composite:exclude; pointer-events:none; opacity:.9; }
.glass:hover{ transform:translateY(-2px); border-color:rgba(94,234,212,.3); background:rgba(255,255,255,.05); }
.card-glow{ position:absolute; inset:-1px; border-radius:inherit; background:conic-gradient(from var(--a,0deg), transparent 0 70%, rgba(94,234,212,.55) 78%, rgba(167,139,250,.55) 86%, transparent 92% 100%); opacity:0; transition:opacity .4s; pointer-events:none; filter:blur(8px); z-index:-1; }
.glass:hover .card-glow{ opacity:1; animation:spin 4s linear infinite; }
@keyframes spin{ to{ --a:360deg; } }
@property --a { syntax:'<angle>'; inherits:false; initial-value:0deg; }

.pill{ transition:all .18s cubic-bezier(.2,.7,.2,1); cursor:pointer; }
.pill.active{ background:linear-gradient(180deg, rgba(45,212,191,.18), rgba(45,212,191,.08)); color:var(--accent-300); border-color:rgba(45,212,191,.45); box-shadow:0 0 0 1px rgba(45,212,191,.1) inset, 0 8px 24px -12px rgba(45,212,191,.5); }
.pill:hover:not(.active):not([disabled]){ background:rgba(255,255,255,.06); border-color:var(--line-strong); }

.btn-primary{
  position: relative;
  background: linear-gradient(135deg, #5eead4 0%, #2dd4bf 50%, #0ea5e9 100%);
  color: #050609;
  font-weight: 600;
  letter-spacing: -0.005em;
  border: none;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  box-shadow:
    0 1px 0 rgba(255,255,255,.4) inset,
    0 -1px 0 rgba(0,0,0,.15) inset,
    0 8px 24px -6px rgba(45,212,191,.55),
    0 0 0 1px rgba(94,234,212,.3);
  transition: transform .2s ease, box-shadow .25s ease, filter .2s ease;
}
.btn-primary::before{
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, transparent 0%, rgba(255,255,255,.18) 50%, transparent 100%);
  transform: translateX(-100%);
  transition: transform .6s ease;
  pointer-events: none;
}
.btn-primary:hover{
  transform: translateY(-2px);
  filter: brightness(1.06);
  box-shadow:
    0 1px 0 rgba(255,255,255,.5) inset,
    0 -1px 0 rgba(0,0,0,.15) inset,
    0 14px 36px -6px rgba(45,212,191,.7),
    0 0 0 1px rgba(94,234,212,.5),
    0 0 28px rgba(94,234,212,.3);
}
.btn-primary:hover::before{ transform: translateX(100%); }
.btn-primary:active{ transform: translateY(0); filter: brightness(.97); }

/* Larger hero variant — for above-the-fold primary actions */
.btn-primary.btn-lg{
  padding: 14px 28px !important;
  font-size: 14.5px !important;
  border-radius: 10px !important;
}

/* Extra-large hero CTA — bigger than the headline so users can't miss it */
.btn-primary.btn-xl{
  padding: 22px 44px !important;
  font-size: 18px !important;
  font-weight: 700 !important;
  border-radius: 14px !important;
  letter-spacing: -0.01em;
  box-shadow:
    0 1px 0 rgba(255,255,255,.45) inset,
    0 -1px 0 rgba(0,0,0,.18) inset,
    0 14px 40px -8px rgba(45,212,191,.65),
    0 0 0 1px rgba(94,234,212,.4),
    0 0 32px rgba(94,234,212,.18);
}
.btn-primary.btn-xl:hover{
  transform: translateY(-3px);
  filter: brightness(1.08);
  box-shadow:
    0 1px 0 rgba(255,255,255,.55) inset,
    0 -1px 0 rgba(0,0,0,.18) inset,
    0 22px 56px -8px rgba(45,212,191,.8),
    0 0 0 1px rgba(94,234,212,.6),
    0 0 48px rgba(94,234,212,.4);
}
.btn-primary.btn-xl svg{ width: 20px; height: 20px; }
@media (max-width: 640px) {
  .btn-primary.btn-xl{ padding: 18px 32px !important; font-size: 16px !important; }
}

.btn-secondary{
  background: rgba(255,255,255,.04);
  color: var(--text);
  border: 1px solid rgba(255,255,255,.12);
  transition: all .2s ease;
  cursor: pointer;
  text-decoration: none;
}
.btn-secondary:hover{
  background: rgba(255,255,255,.08);
  border-color: rgba(94,234,212,.3);
  color: #fff;
}

.pulse-dot{ position:relative; }
.pulse-dot::after{ content:''; position:absolute; inset:0; border-radius:9999px; background:inherit; opacity:.7; animation:pulse 1.8s ease-out infinite; }
@keyframes pulse{ 0%{ transform:scale(1); opacity:.7 } 100%{ transform:scale(2.6); opacity:0 } }

::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.07); border-radius:999px; border:2px solid transparent; background-clip:padding-box; }
::selection{ background:rgba(94,234,212,.35); color:#fff; }

/* Top-level desktop nav links — positioned in <header>.
 * Pre-design: 13px regular dimmed grey. Read as cheap.
 * After: 14px medium weight, near-white tone, slightly tight tracking.
 * Hover/current state animates a gradient underline + a soft accent glow,
 * which is the high-end touch you see on premium SaaS landing pages. */
.nav-link{
  position:relative;
  font-size:14px;
  font-weight:500;
  letter-spacing:-.005em;
  color:#cbd2dc;                 /* mid-light slate, brighter than text-dim */
  text-decoration:none;
  transition:color .2s ease, text-shadow .2s ease;
  padding:2px 0;
}
.nav-link:hover{
  color:#ffffff;
  text-shadow:0 0 18px rgba(94,234,212,.25);
}
.nav-link::after{
  content:'';
  position:absolute;
  left:0; right:0; bottom:-6px;
  height:1.5px;
  background:linear-gradient(90deg, transparent, var(--accent-400) 50%, transparent);
  transform:scaleX(0);
  transform-origin:center;
  transition:transform .35s cubic-bezier(.2,.7,.2,1);
}
.nav-link:hover::after, .nav-link.current::after{ transform:scaleX(1); }
.nav-link.current{
  color:#ffffff;
  font-weight:600;
  text-shadow:0 0 24px rgba(94,234,212,.3);
}
.hr-fine{ background:linear-gradient(90deg, transparent, rgba(255,255,255,.1), transparent); height:1px; border:0; }

.hero-grad{ background:linear-gradient(180deg, #fff 0%, #c8cdd8 100%); -webkit-background-clip:text; background-clip:text; color:transparent; }
.hero-italic{ font-family:'Instrument Serif',serif; font-style:italic; font-weight:400; background:linear-gradient(120deg, #5eead4 0%, #a78bfa 60%, #f0abfc 100%); -webkit-background-clip:text; background-clip:text; color:transparent; padding:0 .04em; }

/* CJK-aware hero text wrapping. CJK doesn't have word boundaries, so the
 * browser may break mid-compound. word-break:keep-all keeps Latin words intact
 * AND keeps CJK 2-character compounds (e.g. "声音", "目录") from splitting
 * at the visual line edge. overflow-wrap:anywhere is the safety net for the
 * rare case where a single word is wider than the container. */
html[lang="zh-CN"] .hero-grad,
html[lang="ja"] .hero-grad,
html[lang="ko"] .hero-grad{
  word-break:keep-all;
  overflow-wrap:anywhere;
  line-break:strict;
}

:focus-visible{ outline:2px solid var(--accent-400); outline-offset:2px; border-radius:4px; }
@media (prefers-reduced-motion: reduce){ *,*::before,*::after{ animation-duration:.001ms !important; transition:none !important; } }

.toast-host{ position:fixed; bottom:24px; left:50%; transform:translateX(-50%); z-index:300; display:flex; flex-direction:column; gap:8px; align-items:center; pointer-events:none; }
.toast{ background:rgba(15,17,24,.98); border:1px solid var(--line-strong); padding:10px 16px; border-radius:999px; font-size:13px; color:var(--text); box-shadow:var(--shadow-card); display:flex; align-items:center; gap:10px; transform:translateY(20px); opacity:0; transition:all .3s cubic-bezier(.2,.7,.2,1); pointer-events:auto; }
.toast.in{ transform:translateY(0); opacity:1; }
.toast .dot{ width:8px; height:8px; background:var(--accent-400); border-radius:50%; box-shadow:0 0 8px rgba(94,234,212,.7); }

.back-to-top{ position:fixed; bottom:24px; right:24px; width:44px; height:44px; border-radius:50%; border:0; cursor:pointer;
  background:linear-gradient(180deg, var(--accent-400), var(--accent-600)); color:#051713;
  box-shadow:0 1px 0 rgba(255,255,255,.25) inset, 0 12px 28px -8px rgba(45,212,191,.55), 0 0 0 1px rgba(45,212,191,.3);
  display:grid; place-items:center; opacity:0; transform:translateY(16px) scale(.92); pointer-events:none;
  transition:opacity .35s cubic-bezier(.2,.7,.2,1), transform .35s cubic-bezier(.2,.7,.2,1), box-shadow .25s; z-index:60; }
.back-to-top.show{ opacity:1; transform:translateY(0) scale(1); pointer-events:auto; }
.back-to-top:hover{ transform:translateY(-3px) scale(1.04); box-shadow:0 1px 0 rgba(255,255,255,.3) inset, 0 18px 36px -8px rgba(45,212,191,.7), 0 0 0 1px rgba(45,212,191,.5); }
.back-to-top svg{ width:18px; height:18px; }
@media (max-width: 640px){ .back-to-top{ bottom:18px; right:18px; width:42px; height:42px; } }
body.scroll-locked{ overflow:hidden; }

@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .35s; animation-timing-function: cubic-bezier(.2,.7,.2,1); }

header { --hdr-py: 14px; --hdr-logo: 1; transition: background .25s, border-color .25s; }
header > .container { padding-top: var(--hdr-py) !important; padding-bottom: var(--hdr-py) !important; transition: padding .3s cubic-bezier(.2,.7,.2,1); }
header > .container > a:first-of-type > div:first-child { transition: transform .3s cubic-bezier(.2,.7,.2,1); transform: scale(var(--hdr-logo)); transform-origin: left center; }
header.is-shrunk { --hdr-py: 8px; --hdr-logo: .88; background: rgba(5,6,9,.88); border-bottom-color: rgba(255,255,255,.08); }

/* === iOS safe-area / Dynamic Island bleed fix ===
   Without this, the WKWebView extends to the very top of the screen,
   and page content scrolls visibly through the iOS status bar / Dynamic
   Island area, looking like the logo wobbles while scrolling. By pushing
   the body content down by env(safe-area-inset-top) AND moving the sticky
   header down by the same amount, scrolled content stays below the
   status bar. The html/body background matches the header so any
   exposed safe-area band looks like an extension of the header. */
html, body { background: #0a0a0a; }
body { padding-top: env(safe-area-inset-top, 0px); }
header { background: #0a0a0a !important; }
header.sticky.top-0,
header[class*="sticky"][class*="top-0"] {
  top: env(safe-area-inset-top, 0px) !important;
}

/* === Mobile: kill scroll-triggered header shrink animation ===
   On iOS Capacitor WKWebView the .is-shrunk toggle fires repeatedly
   during fast scroll, making the logo visibly scale 1.0 <-> 0.88 with
   a 300ms transition. Users perceive it as the logo "wobbling" or
   "following the screen". Lock header size on mobile widths. */
@media (max-width: 767px) {
  header, header.is-shrunk { --hdr-py: 14px !important; --hdr-logo: 1 !important; }
  header > .container { transition: none !important; }
  header > .container > a:first-of-type > div:first-child {
    transition: none !important;
    transform: none !important;
  }
}

/* === Mobile: header MUST be position:fixed, not sticky ===
   On real iPhones running the App Store Capacitor build, position:sticky
   on the header silently fails — the header scrolls away with content
   instead of pinning to the top. Hoisting overflow-x to <html> alone did
   NOT fix it, so the root cause is deeper (WKWebView has a chronic sticky
   bug when combined with body padding-top, a wrapping .content layer, or
   backdrop-filter — unclear which). position:fixed bypasses all of it:
   it pins to the viewport directly, independent of scroll-container
   detection, transform stacking contexts, or padding offsets.

   Pairing rules:
   - Header itself takes top:0 + safe-area padding so the logo sits below
     the notch / Dynamic Island.
   - Body padding-top = safe-area + header height (~60px) so the first
     line of content isn't hidden under the fixed header. */
@media (max-width: 767px) {
  header.sticky.top-0,
  header[class*="sticky"][class*="top-0"] {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    padding-top: env(safe-area-inset-top, 0px) !important;
  }
  /* Override the earlier `body { padding-top: env(safe-area-inset-top) }`
     to also include header height so content clears the fixed header. */
  body {
    padding-top: calc(env(safe-area-inset-top, 0px) + 60px) !important;
  }
}

@media (hover: none) and (pointer: coarse) {
  .glass { transition: transform .2s cubic-bezier(.2,.7,.2,1), border-color .35s, background .35s !important; }
  .glass:active { transform: scale(.985) !important; transition-duration: .08s !important; }
  .pill:active { transform: scale(.96); }
  .btn-primary:active, .btn-secondary:active { transform: scale(.97); }
}

/* Use longhand padding so Tailwind utility classes can override top/bottom.
   Shorthand "padding: 0 24px" was resetting top/bottom to 0 and beating
   utility classes like .pt-20 site-wide. */
.container { max-width: 1240px; margin: 0 auto; padding-left: 24px; padding-right: 24px; }
.section-eyebrow { font-size: 11px; text-transform: uppercase; letter-spacing: .22em; color: var(--accent-300); font-family: 'Geist Mono', monospace; }
.section-title { font-size: clamp(28px, 4vw, 44px); font-weight: 600; letter-spacing: -.035em; line-height: 1.05; margin: 12px 0 14px; }

/* Roster — status pills */
.kpill { display:inline-flex; align-items:center; gap:6px; padding:3px 9px; border-radius:999px; font-size:10.5px; font-family:'Geist Mono', monospace; letter-spacing:.04em; border:1px solid var(--line); background:rgba(255,255,255,.04); color:var(--text-dim); }
.pill-available { color:#5eead4; border-color:rgba(94,234,212,.32); background:rgba(94,234,212,.08); }
.pill-verified  { color:#a7f3d0; border-color:rgba(74,222,128,.4);  background:rgba(74,222,128,.1);  }
.pill-priority  { color:#fde68a; border-color:rgba(251,191,36,.4);  background:rgba(251,191,36,.1);  }
.pill-inactive  { color:#cbd5e1; border-color:rgba(148,163,184,.32); background:rgba(148,163,184,.08); }
.kpill .dot { width:6px; height:6px; border-radius:50%; background:currentColor; box-shadow:0 0 8px currentColor; }

/* Roster — KOL card */
.kol-card { padding:18px; cursor:pointer; transition:transform .35s cubic-bezier(.2,.7,.2,1), border-color .35s, background .35s; text-decoration:none; color:inherit; display:block; }
.kol-card .avatar { width:52px; height:52px; border-radius:50%; overflow:hidden; position:relative; flex-shrink:0; display:grid; place-items:center; font-weight:700; font-size:17px; color:#050609; }
.kol-card .avatar img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }

/* Standalone .avatar — used on profile pages (kol.html) where the element
   has both classes "kol-card avatar" but is NOT nested in another .kol-card,
   so the descendant rules above don't apply. Repeats the geometry/centering
   so initials center and the <img> covers the whole circle. Inline style
   sets width/height/font-size on profile, so we don't repeat those here. */
.avatar { border-radius:50%; overflow:hidden; position:relative; flex-shrink:0; display:grid; place-items:center; font-weight:700; color:#050609; }
.avatar img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.kol-card.avatar { padding:0; }  /* override .kol-card padding when both classes are on the same element */
.kol-card .platform-icons { display:flex; gap:6px; flex-wrap:wrap; }
.kol-card .platform-icons .pl { display:inline-flex; align-items:center; gap:4px; font-size:10.5px; font-family:'Geist Mono', monospace; color:var(--text-dim); padding:2px 7px; border-radius:6px; background:rgba(255,255,255,.04); border:1px solid var(--line); }
/* Global niche-pill — works on /home cards, /kol profile, /search results.
   Was previously scoped to .kol-card so it didn't apply on kol.html profile
   page (where niches sit outside any .kol-card). Now global so every page
   gets the same teal pill styling. */
.niche-pill { display:inline-flex; align-items:center; font-size:11px; padding:4px 10px; border-radius:999px; background:rgba(94,234,212,.08); color:var(--accent-300); border:1px solid rgba(94,234,212,.22); font-family:'Geist Mono', monospace; letter-spacing:.04em; line-height:1; white-space:nowrap; }
/* Compact variant inside small card contexts (home roster + search results) */
.kol-card .niche-pill,
.kol-result-row .niche-pill { font-size:10px; padding:2px 8px; }
/* Hover state — slightly brighter teal */
.niche-pill:hover { background:rgba(94,234,212,.14); border-color:rgba(94,234,212,.38); color:#fff; }
/* On the KOL profile page, niches sit in a flex-wrap container with gap */
#kolNiches { display:flex; flex-wrap:wrap; gap:6px; margin-top:4px; }

/* Clickable URL / @mention / #hashtag inside KOL bios (rendered by H.linkifyBio).
   Uses brand teal so it's visually distinct from regular bio prose. */
.bio-link { color: var(--accent-300); text-decoration: none; border-bottom: 1px dotted rgba(94,234,212,.35); transition: color .15s, border-color .15s; }
.bio-link:hover { color: #fff; border-bottom-color: rgba(255,255,255,.6); }

/* Filter bar */
.filter-pill { padding:6px 12px; border-radius:999px; font-size:12px; border:1px solid var(--line); background:rgba(255,255,255,.03); color:var(--text-dim); cursor:pointer; transition:all .18s; font-family:inherit; }
.filter-pill:hover { background:rgba(255,255,255,.06); color:var(--text); }
.filter-pill.on { background:linear-gradient(180deg, rgba(45,212,191,.18), rgba(45,212,191,.08)); color:var(--accent-300); border-color:rgba(45,212,191,.45); }

/* Tier pill (richer — label + count + budget) */
.tier-pill { width:100%; padding:9px 12px; border-radius:8px; border:1px solid var(--line); background:rgba(255,255,255,.025); color:var(--text-dim); cursor:pointer; transition:all .18s; font-family:inherit; text-align:left; font-size:12px; }
.tier-pill:hover { background:rgba(255,255,255,.05); color:var(--text); border-color:var(--line-strong); }
.tier-pill.on { background:linear-gradient(180deg, rgba(45,212,191,.16), rgba(45,212,191,.04)); color:var(--accent-300); border-color:rgba(45,212,191,.45); box-shadow:0 0 0 1px rgba(45,212,191,.15) inset; }
.filter-section { padding:14px 0; border-bottom:1px solid var(--line); }
.filter-section:last-child { border-bottom:0; }
.filter-section h4 { font-size:10.5px; text-transform:uppercase; letter-spacing:.18em; color:var(--text-faint); font-family:'Geist Mono', monospace; margin:0 0 10px; font-weight:500; }

/* Trending news rail */
.news-rail { display:flex; gap:10px; overflow-x:auto; scroll-snap-type:x mandatory; padding-bottom:6px; -webkit-overflow-scrolling:touch; }
.news-rail::-webkit-scrollbar { height:6px; }
.news-card { flex:0 0 280px; scroll-snap-align:start; padding:14px; text-decoration:none; color:inherit; display:flex; flex-direction:column; gap:8px; min-height:120px; }
.news-card .src { font-size:10.5px; color:var(--text-faint); font-family:'Geist Mono', monospace; letter-spacing:.04em; }
.news-card .ttl { font-size:13px; line-height:1.45; color:var(--text); font-weight:500; display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
.news-card .when { font-size:10.5px; color:var(--accent-300); margin-top:auto; font-family:'Geist Mono', monospace; }

/* ============================================================
 * Mobile navigation — hamburger button + slide-down menu
 * Used on every page; shown only below 768px (Tailwind's md).
 * ============================================================ */
.mobile-nav-toggle {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--line);
  width: 38px; height: 38px;
  border-radius: 8px;
  color: var(--text);
  display: grid; place-items: center;
  cursor: pointer;
  transition: background .18s, border-color .18s, transform .15s;
  -webkit-tap-highlight-color: transparent;
}
.mobile-nav-toggle:hover,
.mobile-nav-toggle:focus-visible { background: rgba(255,255,255,.08); border-color: var(--line-strong); }
.mobile-nav-toggle:active { transform: scale(.94); }

/* Hamburger lines morph into × when nav open */
.mobile-nav-toggle .ln1,
.mobile-nav-toggle .ln2,
.mobile-nav-toggle .ln3 { transition: transform .25s cubic-bezier(.2,.7,.2,1), opacity .2s; transform-origin: center; }
body.mobile-nav-open .mobile-nav-toggle .ln1 { transform: translateY(6px) rotate(45deg); }
body.mobile-nav-open .mobile-nav-toggle .ln2 { opacity: 0; }
body.mobile-nav-open .mobile-nav-toggle .ln3 { transform: translateY(-6px) rotate(-45deg); }

.mobile-nav {
  max-height: 0;
  overflow: hidden;
  border-top: 1px solid transparent;
  background: rgba(5,6,9,.96);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  transition: max-height .32s cubic-bezier(.2,.7,.2,1), border-color .25s;
}
body.mobile-nav-open .mobile-nav {
  /* Use viewport height minus header so the drawer never extends past screen */
  max-height: calc(100vh - 64px);
  overflow-y: auto;             /* user can scroll inside the drawer if content overflows */
  -webkit-overflow-scrolling: touch;
  border-top-color: var(--line);
}

/* ========= Mobile drawer becomes BOTTOM SHEET when triggered from bottom-nav More =========
   Slides up from above the bottom nav (instead of down from top header).
   Bottom nav stays visible. Backdrop dims rest of page. */
@media (max-width: 767px){
  .mobile-nav{
    position: fixed;
    left: 0; right: 0;
    bottom: 76px;                    /* sit above the 76px-tall bottom nav */
    max-height: 0;
    overflow: hidden;
    background: rgba(5,6,9,.98);
    backdrop-filter: blur(22px) saturate(1.4);
    -webkit-backdrop-filter: blur(22px) saturate(1.4);
    border: 1px solid var(--line);
    border-bottom: 0;
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -16px 40px -12px rgba(0,0,0,.7);
    z-index: 55;                     /* under .app-bottom-nav (z=60) */
    transition: max-height .3s cubic-bezier(.2,.7,.2,1);
  }
  body.mobile-nav-open .mobile-nav{
    max-height: 70vh;
    overflow-y: auto;
  }
  /* Backdrop dimmer behind the sheet */
  body.mobile-nav-open::before{
    content: '';
    position: fixed;
    inset: 0 0 76px 0;               /* don't cover the bottom nav */
    background: rgba(0,0,0,.45);
    z-index: 54;
    animation: mobileNavBackdropIn .25s ease-out;
  }
  @keyframes mobileNavBackdropIn{
    from{ opacity: 0; }
    to{ opacity: 1; }
  }
  /* Drag handle visual at the top of the sheet */
  body.mobile-nav-open .mobile-nav::before{
    content: '';
    position: sticky;
    top: 0;
    display: block;
    width: 40px; height: 4px;
    margin: 10px auto 8px;
    border-radius: 2px;
    background: rgba(255,255,255,.18);
  }
  /* Highlight More tab when sheet is open */
  body.mobile-nav-open .app-bottom-nav .abn-item[data-abn-id="more"]{
    color: var(--accent-300);
  }
  body.mobile-nav-open .app-bottom-nav .abn-item[data-abn-id="more"]::before{
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 28px; height: 2px;
    background: var(--accent-400);
    border-radius: 0 0 2px 2px;
    box-shadow: 0 0 8px rgba(94,234,212,.5);
  }
}
.mobile-nav-link {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 24px;
  color: var(--text);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  transition: background .15s, color .15s, padding .15s;
  min-height: 44px;
  -webkit-tap-highlight-color: transparent;
}
.mobile-nav-link:active { background: rgba(94,234,212,.06); padding-left: 28px; }
.mobile-nav-link.current { color: var(--accent-300); background: rgba(94,234,212,.04); }
.mobile-nav-link.cta { color: var(--accent-300); font-weight: 600; border-bottom: 0; padding-top: 18px; padding-bottom: 18px; }

/* Desktop language switcher (in header, hidden below md) */
.lang-switcher { position: relative; }
.lang-switcher-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 9px;
  background: rgba(255,255,255,.04);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--text);
  font-size: 12px;
  font-family: 'Geist Mono', monospace;
  letter-spacing: .04em;
  cursor: pointer;
  transition: background .18s, border-color .18s;
  -webkit-tap-highlight-color: transparent;
}
.lang-switcher-btn:hover,
.lang-switcher-btn:focus-visible { background: rgba(255,255,255,.08); border-color: var(--line-strong); }
.lang-switcher-btn .lang-current { font-weight: 600; min-width: 18px; text-align: center; }
.lang-switcher-btn svg:last-child { transition: transform .2s; opacity: .6; }
.lang-switcher.open .lang-switcher-btn svg:last-child { transform: rotate(180deg); }

.lang-switcher-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 160px;
  background: rgba(10,12,18,.97);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  padding: 4px;
  box-shadow: 0 18px 48px -12px rgba(0,0,0,.6);
  display: none;
  flex-direction: column;
  z-index: 40;
}
.lang-switcher.open .lang-switcher-menu { display: flex; }
.lang-switcher-menu button {
  display: flex; align-items: center; justify-content: flex-start;
  gap: 10px;
  background: transparent;
  border: 0;
  padding: 8px 12px;
  border-radius: 7px;
  color: var(--text-dim);
  font-size: 13px;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .12s, color .12s;
  -webkit-tap-highlight-color: transparent;
}
.lang-switcher-menu button:hover,
.lang-switcher-menu button:focus-visible { background: rgba(255,255,255,.05); color: var(--text); }
.lang-switcher-menu button.active {
  color: var(--accent-300);
  background: rgba(94,234,212,.08);
}
.lang-switcher-menu button.active::after {
  content: '✓';
  font-size: 12px;
  margin-left: auto;
  padding-left: 8px;
}

/* Flag emoji inside menu items */
.lang-switcher-btn .lang-current-flag,
.lang-switcher-menu .flag {
  font-size: 16px;
  line-height: 1;
  display: inline-block;
  /* Some platforms render flag emoji in B&W; force the color font when available */
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}
.lang-switcher-menu button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
}

/* Mobile language dropdown (inside the slide-down nav drawer) — collapsed by default,
   tap to expand. Uses the same .lang-switcher / .lang-switcher-menu structure as desktop
   so the toggle JS works identically; the .mobile-lang-dropdown modifier makes it full-width. */
.mobile-lang-dropdown-wrap {
  padding: 14px 20px 22px;
  border-top: 1px solid var(--line);
  background: rgba(255,255,255,.015);
}
.lang-switcher.mobile-lang-dropdown { width: 100%; position: relative; }
.lang-switcher.mobile-lang-dropdown .lang-switcher-btn.mobile-lang-trigger {
  width: 100%;
  justify-content: flex-start;
  padding: 12px 14px;
  font-size: 15px;
  font-family: inherit;
  letter-spacing: 0;
  border-radius: 12px;
  background: rgba(255,255,255,.06);
  gap: 8px;            /* tight spacing flag → name */
}
.lang-switcher.mobile-lang-dropdown .lang-current-flag { font-size: 20px; margin: 0; line-height: 1; }
.lang-switcher.mobile-lang-dropdown .lang-current-name { flex: 0 1 auto; margin-right: auto; text-align: left; font-weight: 500; color: var(--text); }
.lang-switcher.mobile-lang-dropdown .lang-switcher-menu button { gap: 10px; }
.lang-switcher.mobile-lang-dropdown .lang-switcher-menu button > .flag { margin-right: 0; }
/* On mobile, the language dropdown sits inside the slide-down nav drawer,
 * which itself uses overflow:auto. Absolute-positioned dropdowns get clipped
 * by that overflow, so we render this one inline (position:static) — the
 * drawer's natural scroll handles any overflow but in practice 5 languages
 * fit without scroll. The drawer scroll lets the user reach all 5 even at
 * tiny viewport heights. */
.lang-switcher.mobile-lang-dropdown .lang-switcher-menu {
  position: static;
  width: 100%;
  min-width: 0;
  margin-top: 8px;
  border-radius: 12px;
  /* Match the trigger button's surface treatment for visual cohesion */
  background: rgba(10,12,18,.85);
  border: 1px solid var(--line);
  padding: 6px;
  box-shadow: none;
}
.lang-switcher.mobile-lang-dropdown .lang-switcher-menu button {
  padding: 14px 16px;
  font-size: 14px;
}
.lang-switcher.mobile-lang-dropdown .lang-switcher-menu .flag { font-size: 20px; }

/* legacy/no-op rule for any older list markup that may still be cached */
.mobile-lang-list-wrap {
  padding: 16px 16px 22px;
  border-top: 1px solid var(--line);
  background: rgba(255,255,255,.015);
}
.mobile-nav-lang-label {
  display: block;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .18em;
  color: var(--text-faint); font-family: 'Geist Mono', monospace;
  margin-bottom: 10px;
  padding: 0 8px;
}
.mobile-lang-list { display: flex; flex-direction: column; gap: 4px; }
.mobile-lang-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--text);
  font-size: 15px;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .12s, border-color .12s;
  -webkit-tap-highlight-color: transparent;
}
.mobile-lang-item .flag { font-size: 22px; line-height: 1; flex-shrink: 0;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif; }
.mobile-lang-item .name { flex: 1; font-weight: 500; }
.mobile-lang-item .check { color: var(--accent-300); font-weight: 700; opacity: 0; transition: opacity .15s; }
.mobile-lang-item:active,
.mobile-lang-item:focus-visible { background: rgba(255,255,255,.05); }
.mobile-lang-item.active {
  background: rgba(94,234,212,.06);
  border-color: rgba(94,234,212,.25);
}
.mobile-lang-item.active .check { opacity: 1; }
.mobile-lang-item.active .name { color: var(--accent-300); }

/* Lock body scroll while menu open (avoid scrolling background) */
body.mobile-nav-open { overflow: hidden; }

/* Hide entire mobile-nav apparatus on desktop */
@media (min-width: 768px) {
  .mobile-nav-toggle, .mobile-nav { display: none !important; }
}

/* ============================================================
 * Roster filter panel — collapsible on tablet/mobile
 * Always-on at lg (≥1024px); toggle button below that.
 * ============================================================ */
.filter-toggle-btn {
  display: none;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: rgba(255,255,255,.035);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  margin-bottom: 14px;
  transition: background .18s, border-color .18s;
  -webkit-tap-highlight-color: transparent;
}
.filter-toggle-btn:hover,
.filter-toggle-btn:focus-visible { background: rgba(255,255,255,.06); border-color: var(--line-strong); }
.filter-toggle-btn .lbl { display: flex; align-items: center; gap: 8px; }
.filter-toggle-btn .arrow { transition: transform .25s cubic-bezier(.2,.7,.2,1); display: inline-block; }
#filterPanel.open .filter-toggle-btn .arrow { transform: rotate(180deg); }
.filter-toggle-btn .badge {
  font-size: 10.5px; font-family: 'Geist Mono', monospace;
  padding: 2px 8px; border-radius: 999px;
  background: rgba(94,234,212,.12); color: var(--accent-300);
  letter-spacing: .04em;
}

@media (max-width: 1023px) {
  .filter-toggle-btn { display: flex; }
  #filterPanel .filter-content { display: none; }
  #filterPanel.open .filter-content { display: block; }
}

/* ============================================================
 * Mobile-only touch, spacing & PERFORMANCE tweaks
 * ---------------------------------------------------------------
 * GPU killers we disable below 768px:
 *   - .noise mix-blend-mode (full-screen blend computation)
 *   - .blob filter:blur(90px) + drift animations
 *   - .glass backdrop-filter (50+ instances repaint on scroll)
 * Desktop UX is untouched.
 * ============================================================ */
@media (max-width: 767px) {
  /* Longhand again — see note on the desktop .container rule above. */
  .container { padding-left: 16px; padding-right: 16px; }

  /* Bigger taps on common pills */
  .filter-pill { padding: 9px 14px; font-size: 12.5px; }
  .tier-pill { padding: 12px 14px; font-size: 12.5px; }
  .niche-pill, .kol-card .niche-pill { padding: 4px 10px; }

  /* Slightly tighter card padding on tiny screens */
  .kol-card { padding: 14px; }

  /* Profile hero shouldn't blow past viewport edges */
  .stat-tile { padding: 12px 14px; }
  .stat-tile .value { font-size: 20px; }

  /* News rail: looser spacing and smaller cards */
  .news-card { flex: 0 0 240px; padding: 12px; }

  /* ---- GPU offloading ---- */

  /* Kill full-screen blend mode — replace with low-opacity overlay */
  .noise { mix-blend-mode: normal; opacity: 0.18; }

  /* Stop blob drift animations + halve their blur (still ambient, no GPU thrash) */
  .blob { animation: none !important; filter: blur(60px); opacity: 0.4; }
  .b1 { width: 380px; height: 380px; }
  .b2 { width: 420px; height: 420px; }
  .b3 { width: 320px; height: 320px; }

  /* Glass cards: replace backdrop-filter with semi-transparent solid bg.
     Massive scroll perf win — backdrop-filter forces repaint on every scroll. */
  .glass { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(15, 17, 24, .92); }

  /* Hover effect on cards is moot on touch devices — drop the transform too */
  .glass:hover { transform: none; }

  /* Conic gradient card-glow is hidden behind .glass anyway; disable to save GPU */
  .glass:hover .card-glow { display: none; }
}

/* === App-style Mobile Bottom Nav (DApp-inside feel) ===
   Mobile only. Persistent across all pages. Fixed to bottom.
   Mimics native app or DApp inner-page navigation. */
.app-bottom-nav{
  position: fixed !important;
  left: 0 !important; right: 0 !important; bottom: 0 !important;
  z-index: 9999 !important;            /* defensively above everything */
  display: none;
  background: rgba(8, 10, 16, .94);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  border-top: 1px solid rgba(255,255,255,.08);
  padding: 6px 0 max(8px, env(safe-area-inset-bottom)) 0;   /* zero horizontal padding — let items use full width */
  width: 100vw;                         /* explicit full-viewport width */
  max-width: 100vw;
  box-sizing: border-box;
}
@media (max-width: 767px){
  .app-bottom-nav{
    display: flex !important;           /* simpler than grid; flex 1:1:1:1:1 always works */
    align-items: stretch;
    justify-content: stretch;
    gap: 0;
  }
  body.has-bottom-nav{ padding-bottom: 76px; }
  /* Floating-back stays visible on every non-home page — vendor request.
     The bottom-nav Home button goes to home; the floating-back goes to the
     previous page (history.back()). Different purposes, both useful. */
  body.has-bottom-nav .floating-back{ display: inline-flex; }
}
.app-bottom-nav .abn-item{
  flex: 1 1 20%;            /* exactly 20% each, equal */
  width: 20%;
  min-width: 0;
  max-width: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 8px 2px 6px;
  text-decoration: none;
  color: var(--text-faint);
  font-size: 10px;
  font-weight: 500;
  transition: color .15s;
  position: relative;
  min-height: 56px;
  box-sizing: border-box;
}
.app-bottom-nav .abn-item:hover,
.app-bottom-nav .abn-item:active{ color: var(--text-dim); }
.app-bottom-nav .abn-item.active{ color: var(--accent-300); }
.app-bottom-nav .abn-item.active::before{
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 28px; height: 2px;
  background: var(--accent-400);
  border-radius: 0 0 2px 2px;
  box-shadow: 0 0 8px rgba(94,234,212,.5);
}
.app-bottom-nav .abn-icon{
  width: 22px; height: 22px;
  display: grid; place-items: center;
}
.app-bottom-nav .abn-icon svg{ width: 100%; height: 100%; }
.app-bottom-nav .abn-label{
  letter-spacing: .01em;
  line-height: 1;
}

/* Center "Activity" item gets prominence — DeFi-style FAB */
.app-bottom-nav .abn-item.abn-center{
  position: relative;
  margin-top: -14px;
}
.app-bottom-nav .abn-item.abn-center .abn-icon{
  width: 48px; height: 48px;
  background: linear-gradient(135deg, var(--accent-400), #8b5cf6);
  border-radius: 50%;
  color: #050609;
  box-shadow: 0 8px 24px -6px rgba(94,234,212,.55), 0 4px 12px -2px rgba(139,92,246,.4);
  border: 3px solid rgba(8,10,16,.92);
  margin-bottom: 2px;
}
.app-bottom-nav .abn-item.abn-center .abn-icon svg{ width: 22px; height: 22px; }
.app-bottom-nav .abn-item.abn-center.active::before{ display: none; }
.app-bottom-nav .abn-item.abn-center .abn-label{
  font-weight: 600;
  color: var(--text);
}

/* === App-inside slim mobile header (activity / ai / kol pages) ===
   Mobile only. Hides tagline and CTA buttons; bottom nav handles those.
   Keeps logo and hamburger for context + drawer access. */
@media (max-width: 767px){
  body.app-inner header .text-\[9\.5px\]{
    /* Hide "The Web3 voice atlas" tagline on inner pages — bottom nav makes context clear */
    display: none;
  }
  body.app-inner header a[href^="signin.html"],
  body.app-inner header a[href^="insight.html"].btn-primary{
    /* Hide top-right Sign in / AI Insight buttons — bottom nav has Insight, More has Sign in */
    display: none;
  }
  body.app-inner header .container{
    padding-top: .5rem; padding-bottom: .5rem;
  }
  /* Tighten the logo to leave room for page title */
  body.app-inner header [class*="h-8 w-8"]{
    height: 28px; width: 28px;
  }
  body.app-inner header span[data-i18n="common.tagline"]{
    display: none;
  }
}

/* === Mobile top header cleanup ===
   Bottom nav now handles Home/KOLs/Activity/Insight/More.
   Top header on mobile should only show: logo + lang switcher.
   Hamburger + AI Insight CTA + Sign in are redundant on mobile. */
@media (max-width: 767px){
  header .mobile-nav-toggle,
  header a[href^="insight.html"].btn-primary,
  header a[href^="signin.html"]{
    display: none !important;
  }
  /* lang-switcher (was hidden md:block; now lang-top class) — make visible on mobile too */
  header .lang-switcher.lang-top{
    display: inline-block;
  }
  /* Compact lang switcher on mobile */
  header .lang-switcher.lang-top .lang-switcher-btn{
    padding: 6px 10px;
    font-size: 12px;
    gap: 6px;
  }
  header .lang-switcher.lang-top .lang-current{
    font-size: 12px;
  }
}

/* === Premium brand logo polish === */
.brand-logo{
  position: relative;
  box-shadow: 0 0 0 1px rgba(94,234,212,.2), 0 0 16px -4px rgba(94,234,212,.4), 0 0 24px -8px rgba(139,92,246,.5);
  letter-spacing: -0.02em;
  font-weight: 900;
  font-size: 15px !important;
}
.brand-logo::before{
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(135deg, rgba(255,255,255,.18) 0%, transparent 50%);
  pointer-events: none;
}

/* === Premium tech accent — glow line under header on scroll === */
header.is-shrunk{
  border-bottom-color: rgba(94,234,212,.18) !important;
  box-shadow: 0 0 24px -10px rgba(94,234,212,.3);
}

/* === Trending section — premium scan accent line === */
#trending::before{
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 60%;
  max-width: 600px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(94,234,212,.5), transparent);
  box-shadow: 0 0 12px rgba(94,234,212,.3);
}
#trending{ position: relative; }

/* === Trending tabs row — slightly elevate the tabs === */
.trend-tab.active{
  position: relative;
}
.trend-tab.active::after{
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  background: linear-gradient(135deg, rgba(94,234,212,.15), transparent);
  z-index: -1;
  filter: blur(4px);
  pointer-events: none;
}

/* ============================================================
 * Profile avatar — circular K placeholder in top-right header.
 * Future: localStorage('kolflow_user').name first letter swaps the K.
 * ============================================================ */
.profile-avatar{
  display:inline-grid; place-items:center;
  width:32px; height:32px;
  border-radius:50%;
  background: linear-gradient(135deg, var(--accent-400) 0%, #8b5cf6 55%, #f0abfc 100%);
  color:#050609;
  font-weight:800;
  font-size:14px;
  letter-spacing:-0.02em;
  text-decoration:none !important;
  flex-shrink:0;
  transition: transform .2s ease, box-shadow .2s ease;
  box-shadow: 0 0 0 1px rgba(94,234,212,.3), 0 0 12px rgba(94,234,212,.25);
}
.profile-avatar:hover{
  transform: scale(1.06);
  box-shadow: 0 0 0 1.5px rgba(94,234,212,.55), 0 0 18px rgba(94,234,212,.45);
}
.profile-avatar:active{ transform: scale(.98); }
.profile-initial{
  font-family: 'Geist', -apple-system, BlinkMacSystemFont, sans-serif;
  line-height:1;
}

/* === v1.0 Apple submission: defensive end-of-file hide for Sign-in UI ===
   Repeats the top-of-file rule with higher-specificity selectors at the end
   so we win the cascade against any later in-file rule, regardless of CSS
   load order or browser/CDN quirks. Hides every legitimate way the demo
   sign-in UI could surface: the avatar link, "Sign in" text link, and the
   "Profile →" mobile nav entry. Re-enable once Sign in with Apple ships. */
header a.profile-avatar,
header a[href*="signin"],
header a[href$="signin"],
body a.profile-avatar,
body a[href*="signin"],
body .mobile-nav-link[href*="signin"],
.mobile-nav .mobile-nav-link[href*="signin"] {
  display: none !important;
  visibility: hidden !important;
  pointer-events: none !important;
  width: 0 !important;
  height: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  overflow: hidden !important;
}

/* === Mobile: shrink Home hero, drop redundant tagline eyebrow ===
   Hero ate ~1/3 of the viewport with three stacked text blocks ("Find your
   Web3 KOL." + body copy + "The free, public atlas of Web3 voices" tagline)
   plus tall section padding. First KOL card got pushed below the fold. */
@media (max-width: 767px) {
  section.hero-tight {
    padding-top: 1.25rem !important;
    padding-bottom: 0.25rem !important;
  }
  section.hero-tight h1 {
    font-size: 30px !important;
    line-height: 1.05 !important;
  }
  section.hero-tight > p.mt-4 {
    margin-top: 0.5rem !important;
    font-size: 13.5px !important;
  }
  /* The eyebrow tagline duplicates KOLflow's header subtitle; kill on mobile */
  .home-hero-tagline {
    display: none !important;
  }
}

/* === "see more..." inline links: make them obviously tappable ===
   Truncated post bodies on Trending render "...see more..." in plain text
   color — users have no idea it's interactive. Promote to brand teal,
   underline on hover, and add a chevron so the affordance is unmissable. */
.see-more,
.see-more-inline,
a.see-more,
.see-more-link {
  color: var(--accent-300) !important;
  font-weight: 500 !important;
  text-decoration: none !important;
  cursor: pointer !important;
  white-space: nowrap;
  margin-left: 4px;
}
.see-more::after,
.see-more-inline::after,
a.see-more::after,
.see-more-link::after {
  content: ' ›';
  display: inline-block;
  margin-left: 1px;
  font-weight: 600;
  transform: translateY(-0.5px);
}
.see-more:hover,
.see-more-inline:hover,
a.see-more:hover,
.see-more-link:hover {
  color: #fff !important;
  text-decoration: underline !important;
  text-underline-offset: 2px;
}

/* === Mobile More drawer: app version footer ===
   Injected by nav.js so users see the build version after force-quit
   reinstall (helps confirm whether a fix actually reached them). */
.mobile-nav-version {
  padding: 14px 24px 18px;
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--text-faint);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  border-top: 1px solid var(--line);
  margin-top: 4px;
}

/* === Bottom-nav tap-pressed feedback ===
   Paired with nav.js touchstart handler. The browser's own "tap → click →
   navigate" pipeline adds ~150–200ms of perceived dead time before the
   destination page shows. During that window, the tab needs to LOOK pressed
   so the user's brain registers the action. teal color + slight icon scale
   does the job; transitions are tight (60–80ms) so the press feels physical
   instead of animated. */
.app-bottom-nav .abn-item {
  -webkit-tap-highlight-color: transparent;
  transition: color 0.08s ease, background-color 0.08s ease;
}
.app-bottom-nav .abn-item .abn-icon {
  transition: transform 0.12s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.app-bottom-nav .abn-item.tap-pressed {
  color: var(--accent-300);
  background-color: rgba(94, 234, 212, 0.06);
}
.app-bottom-nav .abn-item.tap-pressed .abn-icon {
  transform: scale(0.92);
}
/* Center FAB has its own gradient bg — don't fight it on press; just
   shrink the icon a hair so the tap registers without color clash. */
.app-bottom-nav .abn-item.abn-center.tap-pressed {
  background-color: transparent;
}
.app-bottom-nav .abn-item.abn-center.tap-pressed .abn-icon {
  transform: scale(0.94);
  filter: brightness(1.1);
}

/* === Scroll containment: stop overscroll chain ===
   On iOS WKWebView, scrolling a horizontal news strip or KOL list to its
   end chains the overscroll into the parent document, which bounces the
   whole app shell — looks "loose" and unfocused. `overscroll-behavior:
   contain` stops the chain at each scroll container's boundary. Applied
   to html/body for the main vertical scroll, and to known inner scrollers
   (.news-rail horizontal strip, .trend-scroll on Trending top strip,
   .mobile-nav drawer scroll). */
html,
body {
  overscroll-behavior: contain;
}
.news-rail,
.trend-scroll,
.mobile-nav,
.lang-switcher-menu,
[data-scroll-container] {
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* === Pull-to-refresh spinner ===
   Injected by nav.js when the user pulls down at the top of the page.
   Sits centered horizontally below the fixed header. The spinner ring
   uses pure CSS so no extra asset request is needed. */
.kolflow-ptr {
  position: fixed;
  left: 50%;
  top: calc(env(safe-area-inset-top, 0px) + 64px);
  transform: translate3d(-50%, 0, 0);
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(10, 12, 18, 0.92);
  border: 1px solid rgba(94, 234, 212, 0.25);
  box-shadow: 0 8px 24px -10px rgba(0, 0, 0, 0.6),
              0 0 0 1px rgba(94, 234, 212, 0.06);
  opacity: 0;
  z-index: 95;
  pointer-events: none;
  transition: transform 0.18s cubic-bezier(0.2, 0.7, 0.2, 1),
              opacity 0.18s ease,
              border-color 0.18s ease;
}
.kolflow-ptr.is-visible {
  opacity: 1;
}
.kolflow-ptr.is-ready {
  border-color: rgba(94, 234, 212, 0.65);
  box-shadow: 0 8px 24px -10px rgba(94, 234, 212, 0.55),
              0 0 0 1px rgba(94, 234, 212, 0.35);
}
.kolflow-ptr-spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid rgba(94, 234, 212, 0.25);
  border-top-color: var(--accent-300);
  transition: transform 0.18s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.kolflow-ptr.is-ready .kolflow-ptr-spinner {
  transform: rotate(180deg);
}
.kolflow-ptr.is-loading .kolflow-ptr-spinner {
  animation: kolflowPtrSpin 0.7s linear infinite;
  transform: none !important;
}
@keyframes kolflowPtrSpin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .kolflow-ptr,
  .kolflow-ptr-spinner {
    transition: opacity 0.18s ease;
    animation: none !important;
  }
}
