/* ================= 国庆动态主题 ================= */
/* 由 js/festival.js 控制：html.festival 打开整套效果 */

.fest-layer {
  display: none;
  /* z-index 必须低于 .tabs-wrap(29)/.flash-bar：这两条是和顶栏一起露在红色区域里的
     内容条。节日层铺的是 --head-h 高（顶栏+频道栏 ≈ 100px）的一整块红底，
     早期 z-index 给到 1 是为了压在正文之上不影响点击（pointer-events:none），
     但跑马灯退回频道栏上方时是 position:static，被它整条盖掉（v4.0 实测：
     390px 视口下跑马灯几何全对、elementFromPoint 也命中，肉眼却看不到）。 */
  position: fixed; left: 0; right: 0; top: 0;
  height: var(--head-h, 96px);
  overflow: hidden; z-index: 0; pointer-events: none;
}
html.festival .fest-layer { display: block; }

/* --- 底：国旗红 + 金晕 --- */
.fest-sky {
  position: absolute; inset: 0;
  background:
    radial-gradient(120px 90px at 18% 120%, rgba(255, 222, 89, .55), transparent 70%),
    radial-gradient(180px 120px at 82% -20%, rgba(255, 236, 160, .40), transparent 70%),
    linear-gradient(100deg, #a80a12 0%, #d40f19 32%, #e8353c 55%, #c20f18 78%, #9a0710 100%);
}
/* 流光扫过 */
.fest-sky::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 240, 190, .38) 46%, rgba(255, 255, 255, .22) 52%, transparent 68%);
  transform: translateX(-120%);
  animation: festSweep 7s linear infinite;
}
@keyframes festSweep { 0% { transform: translateX(-120%); } 55%,100% { transform: translateX(120%); } }

/* --- 旋转光芒 --- */
.fest-rays {
  position: absolute; top: -140px; left: 50%; width: 420px; height: 420px;
  margin-left: -210px; opacity: .30;
  background: repeating-conic-gradient(from 0deg, rgba(255, 226, 120, .95) 0deg 3deg, transparent 3deg 12deg);
  -webkit-mask-image: radial-gradient(circle, #000 12%, transparent 68%);
  mask-image: radial-gradient(circle, #000 12%, transparent 68%);
  animation: festSpin 46s linear infinite;
}
@keyframes festSpin { to { transform: rotate(360deg); } }

.fest-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* --- 底部波浪，与页面主体自然衔接 --- */
.fest-wave {
  position: absolute; left: -50%; bottom: -1px; width: 200%; height: 16px; display: block;
  fill: var(--bg); animation: festWave 9s ease-in-out infinite alternate;
}
@keyframes festWave { from { transform: translateX(0); } to { transform: translateX(-25%); } }

/* --- 国庆飘带（PC 端 Hero 区域右上；移动端不显示，改由信息流顶部横幅承担） --- */
.fest-ribbon {
  display: none; position: fixed; z-index: 31;
  /* v4.0：内容容器已统一为 1272px + 16px 内边距（内容区 1240px），
     这里跟着改成 calc(50% - 620px) + 16px，与顶栏 / 频道栏右边缘同一条竖线。
     同时下移到 top:100px，避开顶栏右侧的「下载APP / 发布」按钮。 */
  right: max(16px, calc(50% - 604px));
  top: 100px;
  align-items: center; gap: 6px; cursor: pointer;
  padding: 4px 12px; border-radius: 999px;
  background: linear-gradient(100deg, rgba(255, 222, 89, .95), rgba(255, 244, 205, .92));
  color: #a5060d; font-size: 12.5px; font-weight: 700; letter-spacing: .3px; white-space: nowrap;
  box-shadow: 0 3px 10px rgba(80, 0, 0, .28);
  animation: festFloat 3.4s ease-in-out infinite;
}
.fest-ribbon i { font-style: normal; font-size: 10px; opacity: .75; }
@keyframes festFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
/* 只在「PC 首页 + Hero 尚未滚出」时出现：那时频道栏还在 Hero 下方（y≈315），
   右侧是一整片空闲的红金画布；一旦滚动，频道栏吸顶到 y=60，
   我们新加的账号入口（登录按钮 / 用户名）正好在飘带位置，必须让位。
   非首页没有 Hero，频道栏同样吸顶在 y=60，因此也不显示。 */
@media (min-width: 1000px) {
  html.festival body.has-hero:not(.hero-out) .fest-ribbon { display: flex; }
}

/* 信息流顶部的国庆标语（移动端主入口） */
.bb-fest-txt {
  margin-left: 2px; color: #ffe07a; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ================= 顶栏反色 =================
   只作用于顶栏 —— 它的背后一定有红色底（PC 首页是 Hero 红金渐变，其余情况是国内庆红带 fest-layer）。
   频道栏 tabs-wrap 绝不可参与：它永远位于红色区域下方、压在浅色信息流之上，
   一旦透明 + 白字，实测对比度只有 1.09，等于隐形（2024 国庆期间踩过这个坑）。 */
html.festival .topbar {
  background: transparent !important;
  border-bottom-color: transparent !important;
  box-shadow: none !important;
}
/* 769~999px：顶栏里塞着搜索框，跑马灯又紧接着顶栏，节日红只剩顶栏那 52px，
   飘带固定压在顶部会把搜索框整个糊住（v4.0 实测 768px：搜索框描边压住快讯文字）。
   这一档直接不显示飘带，红底仍由 fest-layer 提供。 */
@media (max-width: 999px) and (min-width: 769px) {
  html.festival .fest-ribbon { display: none !important; }
}
html.festival .brand-text {
  background: none !important; -webkit-text-fill-color: #fff !important; color: #fff !important;
  text-shadow: 0 1px 3px rgba(90, 0, 0, .45);
}
html.festival .brand-logo { box-shadow: 0 0 0 2px rgba(255, 226, 130, .9), 0 3px 10px rgba(60, 0, 0, .35); }
html.festival .searchbar {
  background: rgba(255, 255, 255, .20);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .34);
}
html.festival .searchbar .s-ico { opacity: .85; }
html.festival .searchbar .s-text { color: rgba(255, 255, 255, .92); }
html.festival .searchbar .s-btn { background: linear-gradient(135deg, #ffe07a, #ffcf3f); color: #a5060d; }
html.festival .btn-write { background: linear-gradient(135deg, #ffe07a, #ffcf3f); color: #a5060d; }
html.festival .btn-app { background: rgba(255, 255, 255, .16); color: #fff; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .42); }

/* ---- 与 Hero 页头的协作规则 ----
   首页 Hero 已经顶到页面最上方并自带红金渐变，此时不再重复铺国庆层的顶部红带；
   滚出 Hero 后（body.hero-out）顶栏必须回到常规实体底，否则白字会压在浅色内容上看不见。 */
/* Hero 只在 ≥1000px 真正显示；手机端 Hero 是 display:none，
   此处若不限断点，会把红带一并隐藏 —— 白字品牌名直接压在浅灰页面上消失。 */
@media (min-width: 1000px) {
  html.festival body.has-hero .fest-layer { display: none; }
}
/* v6.0 第 3 项：节日主题下同样固定白底（原来跟 var(--card) 走，夜间模式是一条深条）。
   顶栏内部元素按亮色取色，所以把变量一并改亮，与 main.css 的全局 hero-out 段保持一致。 */
html.festival body.hero-out .topbar {
  background: #fff !important;
  border-bottom-color: rgba(20, 22, 30, .09) !important;
  box-shadow: 0 1px 6px rgba(20, 22, 30, .06);
  --text3: #55585f;
  --text2: #6b7078;
  --line: rgba(20, 22, 30, .14);
  --chip: #f0f1f3;
}
/* v6.0 第 3 项：节日主题 + 滚出 Hero 时顶栏也是白底，
   品牌字必须回到实心红，不能再走「渐变 + 透明字」那一套。
   原写法用 !important 强推 background-clip:text + 透明字色，本文件在 main.css 之后加载，
   于是把 main.css 里的白底还原规则整个压掉，品牌名变成一块红方块 / 直接消失。
   这里同样是 !important，但改成实心红 —— 与 main.css 的 hero-out 规则目标一致，谁赢都对。 */
html.festival body.hero-out .brand-text {
  background: none !important;
  -webkit-background-clip: border-box; background-clip: border-box;
  -webkit-text-fill-color: var(--primary) !important; color: var(--primary) !important;
  text-shadow: none !important;
}
html.festival body.hero-out .topbar .theme-btn { color: var(--text3) !important; }
html.festival body.hero-out .topbar .btn-app {
  color: var(--text3) !important; background: none !important;
  box-shadow: inset 0 0 0 1px var(--line) !important;
}
/* 频道栏不反色：保持浅色实体底 + 常规深色字（见上方说明）。
   节日点缀只做在「选中频道的下划线」上——用深金而非浅金，保证在白底上看得见。 */
/* v7.0：手机端首屏快讯条一直被 .fest-layer 盖住（flash-bar 是 static 无 z-index，
   positioned 的 fest-layer 即使 z-index:0 也会盖在它上面），
   文字变成「暗红叠红」几乎不可读。给一个低于 tabs-wrap(29)、高于 fest-layer(0) 的层级。 */
html.festival .flash-bar:not(.hero-flash) { position: relative; z-index: 28; }

html.festival .tab.active::after { background: linear-gradient(90deg, #f0b419, #ffd95e); }
html.festival .tabs-more { color: var(--text3); border-left-color: var(--line); }
html.festival .side-nav button.active { background: #fff2f2; }

/* 首页「要闻」条切换为国庆配色 */
html.festival .brief-bar {
  background: linear-gradient(100deg, #9c0610, #d40f19 45%, #e8353c);
  border-bottom-color: transparent;
}
html.festival .brief-bar span { color: rgba(255, 255, 255, .96); }
html.festival .brief-bar .bb-tag {
  background: linear-gradient(135deg, #ffe07a, #ffcf3f); color: #a5060d;
}
html.festival .side-card h5, html.festival .side-ch h5 { color: var(--text); }

/* ================= 全屏飘落 ================= */
.fest-fall {
  display: none; position: fixed; inset: 0; z-index: 5;
  pointer-events: none; overflow: hidden;
}
html.festival .fest-fall { display: block; }
.ff {
  position: absolute; top: -32px; will-change: transform, opacity;
  animation: ffDown linear forwards;
}
.ff svg { display: block; width: 100%; height: 100%; }
@keyframes ffDown {
  0%   { transform: translate3d(0, -32px, 0) rotate(0deg); opacity: 0; }
  10%  { opacity: 1; }
  100% { transform: translate3d(var(--dx, 30px), 105vh, 0) rotate(var(--rot, 360deg)); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .fest-sky::after, .fest-rays, .fest-wave, .fest-ribbon { animation: none !important; }
}
