/* ============================================================
   w1_polish.css · 乐豆说 H5 壳页 W1 视觉打磨（纯 CSS，不改 JS/HTML 结构）
   v2 · 梅 · 2026-09-01 · 对应施工图 V1.6
   v2：W1-4 夏帧到挂接（v1 原地招手精灵条 4 帧/1.6s/来回无缝循环，
        steps 帧切换无插值，根治整图 rotate 拖影；帧图 ledou_wave_sprite.png
        与本 css 同目录发布到 /hotfix/）；15:10 截图实测修正 steps(4) 终点
        位移为 -N 帧宽（-192px），修复 (N-1) 帧宽的跨帧串影
   v1：W1-1 Pad 氛围满铺 + W1-5 两处收光 + W1-4 空槽位
   覆盖壳页：/hotfix/town_map.html / school_hall.html / park_hall.html / pet_home.html
   本期工单：
     W1-1  Pad(≥768px) 居中主容器两侧空区补氛围满铺（手机 ≤767 零影响）
     W1-5  座舱灯/焦点光微调（乐园摩天轮中心金光柔化、小镇单焦点光圈收敛）
     W1-4  乐豆招手帧挂接（town_map 向导，夏出帧；帧位变量集中在文件末尾，
            到帧后只改 :root 三个变量 + 一段 @keyframes，规则骨架不动）
   不在本单：W1-2 乐园底栏实底色（雨独立交付，本文件不碰，避免双份覆盖）
   断点纪律：所有 Pad 氛围规则均在 @media (min-width:768px) 内，
            320/375/390 手机视口一条规则都不生效（W1-1 验收点：375 不受影响）。
   呈现纪律：只加氛围/收光，无任何红叉/警告色；低幼卡通、暖纸/糖果色系统一；
            热区 ≥44px 不遮不抢，新增层全部 pointer-events:none。
   挂载：各壳页 </head> 前、壳页内联 <style> 之后加一行
            <link rel="stylesheet" href="/hotfix/w1_polish.css?v=20260901">
         （CDN/部署引用必须带版本号破缓存；本地 file:// 自测用同目录相对路径 w1_polish.css）
   ============================================================ */

/* ============================================================
   W1-1 · Pad/宽屏（≥768px）：居中主容器两侧空区氛围满铺
   做法：只给 body 加固定背景（多层径向纹理 + 纵向渐变 + 云斑），
        主容器（.town-map/.phone/main.stage/#stage）居中且自带底色/卡片底，
        两侧自然露出 body 氛围；全部规则封在 min-width:768 内，手机零命中。
   兜底：不支持 :has() 的老 WebView 也有暖纸渐变（第一条通用规则），
        不会出现生硬浅蓝/浅灰空条；支持 :has() 则按壳出专属氛围。
   ============================================================ */

/* 通用兜底：宽屏两侧暖纸渐变（任何壳都不空） */
@media (min-width: 768px) {
  html, body { background-attachment: fixed; }
  body {
    background-color: #EAD9C2;
    background-image: linear-gradient(180deg, #F2E4CE 0%, #E7D4BA 55%, #E0C9A8 100%);
    background-repeat: no-repeat;
    background-size: 100% 100%;
  }
}

/* --- 小镇地图 town_map.html（body 直含 .town-map）：天空蓝两侧，云斑 + 淡金星点 --- */
@media (min-width: 768px) {
  body:has(> .town-map) {
    background-color: #BFE3F2;
    background-image:
      /* 云斑（固定在视口两侧边带，主容器居中后落在容器外） */
      radial-gradient(circle at 6vw 14vh,  rgba(255,255,255,.85) 0 34px, rgba(255,255,255,0) 35px),
      radial-gradient(circle at 9vw 22vh,  rgba(255,255,255,.8) 0 26px, rgba(255,255,255,0) 27px),
      radial-gradient(circle at 4vw 22vh,  rgba(255,255,255,.8) 0 22px, rgba(255,255,255,0) 23px),
      radial-gradient(circle at 94vw 30vh, rgba(255,255,255,.85) 0 36px, rgba(255,255,255,0) 37px),
      radial-gradient(circle at 90vw 37vh, rgba(255,255,255,.8) 0 26px, rgba(255,255,255,0) 27px),
      radial-gradient(circle at 97vw 38vh, rgba(255,255,255,.8) 0 22px, rgba(255,255,255,0) 23px),
      radial-gradient(circle at 7vw 68vh,  rgba(255,255,255,.7) 0 30px, rgba(255,255,255,0) 31px),
      radial-gradient(circle at 93vw 74vh, rgba(255,255,255,.7) 0 30px, rgba(255,255,255,0) 31px),
      /* 淡金星点（低透明、不可点、不抢热区） */
      radial-gradient(circle, rgba(255,214,90,.30) 0 2px, rgba(255,214,90,0) 3px),
      radial-gradient(circle, rgba(255,255,255,.55) 0 1.5px, rgba(255,255,255,0) 2.5px),
      /* 天空纵向渐变，与地图画布 #BFE3F2 同源 */
      linear-gradient(180deg, #D7F0FC 0%, #BFE3F2 60%, #AED7EC 100%);
    background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat,
                     repeat, repeat, no-repeat;
    background-size: auto, auto, auto, auto, auto, auto, auto, auto,
                     160px 160px, 160px 160px, 100% 100%;
    background-position: 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0,
                        0 0, 80px 80px, 0 0;
    background-attachment: fixed, fixed, fixed, fixed, fixed, fixed, fixed, fixed,
                           fixed, fixed, fixed;
  }
}

/* --- 学堂 school_hall.html（body 直含 .phone）：暖纸两侧，橙点 + 明黄书点纹理 --- */
@media (min-width: 768px) {
  body:has(> .phone) {
    background-color: #EDE3D2;
    background-image:
      radial-gradient(circle at 6vw 20vh,  rgba(255,255,255,.65) 0 40px, rgba(255,255,255,0) 41px),
      radial-gradient(circle at 94vw 32vh, rgba(255,255,255,.6) 0 42px, rgba(255,255,255,0) 43px),
      /* 橙圆点（主色 #C96F3D 低透明） */
      radial-gradient(circle, rgba(201,111,61,.14) 0 5px, rgba(201,111,61,0) 6px),
      /* 明黄书点（#F6B93B 低透明） */
      radial-gradient(circle, rgba(246,185,59,.16) 0 4px, rgba(246,185,59,0) 5px),
      /* 学堂绿点缀 */
      radial-gradient(circle, rgba(126,159,122,.12) 0 3px, rgba(126,159,122,0) 4px),
      linear-gradient(180deg, #F1E6D3 0%, #E7DAC4 60%, #DFCFB6 100%);
    background-repeat: no-repeat, no-repeat, repeat, repeat, repeat, no-repeat;
    background-size: auto, auto, 140px 140px, 140px 140px, 140px 140px, 100% 100%;
    background-position: 0 0, 0 0, 0 0, 70px 70px, 35px 105px, 0 0;
    background-attachment: fixed, fixed, fixed, fixed, fixed, fixed;
  }
}

/* --- 乐园 park_hall.html（body 直含 main.stage）：奶橙两侧，糖果色点纹理 + 云斑 --- */
@media (min-width: 768px) {
  body:has(> main.stage) {
    background-color: #EAD9C2;
    background-image:
      radial-gradient(circle at 6vw 16vh,  rgba(255,255,255,.7) 0 38px, rgba(255,255,255,0) 39px),
      radial-gradient(circle at 9vw 24vh,  rgba(255,255,255,.65) 0 28px, rgba(255,255,255,0) 29px),
      radial-gradient(circle at 94vw 40vh, rgba(255,255,255,.7) 0 40px, rgba(255,255,255,0) 41px),
      radial-gradient(circle at 90vw 48vh, rgba(255,255,255,.65) 0 28px, rgba(255,255,255,0) 29px),
      /* 糖果八色点（对应摩天轮座舱色，全部 ≤.12 透明，氛围不抢焦） */
      radial-gradient(circle, rgba(255,107,107,.12) 0 5px, rgba(255,107,107,0) 6px),
      radial-gradient(circle, rgba(255,159,67,.12) 0 5px, rgba(255,159,67,0) 6px),
      radial-gradient(circle, rgba(255,212,71,.14) 0 5px, rgba(255,212,71,0) 6px),
      radial-gradient(circle, rgba(119,217,130,.12) 0 5px, rgba(119,217,130,0) 6px),
      radial-gradient(circle, rgba(93,183,255,.12) 0 5px, rgba(93,183,255,0) 6px),
      radial-gradient(circle, rgba(180,140,232,.12) 0 5px, rgba(180,140,232,0) 6px),
      linear-gradient(180deg, #F5E5CE 0%, #ECD8BE 55%, #E3CBAC 100%);
    background-repeat: no-repeat, no-repeat, no-repeat, no-repeat,
                     repeat, repeat, repeat, repeat, repeat, repeat, no-repeat;
    background-size: auto, auto, auto, auto,
                     180px 180px, 180px 180px, 180px 180px, 180px 180px, 180px 180px, 180px 180px, 100% 100%;
    background-position: 0 0, 0 0, 0 0, 0 0,
                        0 0, 60px 60px, 120px 30px, 30px 120px, 90px 120px, 150px 90px, 0 0;
    background-attachment: fixed, fixed, fixed, fixed,
                           fixed, fixed, fixed, fixed, fixed, fixed, fixed;
  }
}

/* --- 我的小屋 pet_home.html（body 直含 #stage）：暖黄两侧，心点/绿芽点纹理 --- */
@media (min-width: 768px) {
  body:has(> #stage) {
    background-color: #F3E4C0;
    background-image:
      radial-gradient(circle at 6vw 24vh,  rgba(255,255,255,.6) 0 42px, rgba(255,255,255,0) 43px),
      radial-gradient(circle at 94vw 36vh, rgba(255,255,255,.55) 0 40px, rgba(255,255,255,0) 41px),
      /* 粉心点 */
      radial-gradient(circle, rgba(240,168,184,.16) 0 4px, rgba(240,168,184,0) 5px),
      /* 绿芽点 */
      radial-gradient(circle, rgba(126,159,122,.14) 0 4px, rgba(126,159,122,0) 5px),
      /* 星光金点 */
      radial-gradient(circle, rgba(255,201,60,.14) 0 4px, rgba(255,201,60,0) 5px),
      linear-gradient(180deg, #F8EACB 0%, #F2E1BC 60%, #EBD5AC 100%);
    background-repeat: no-repeat, no-repeat, repeat, repeat, repeat, no-repeat;
    background-size: auto, auto, 150px 150px, 150px 150px, 150px 150px, 100% 100%;
    background-position: 0 0, 0 0, 0 0, 75px 75px, 38px 112px, 0 0;
    background-attachment: fixed, fixed, fixed, fixed, fixed, fixed;
  }
}

/* ============================================================
   W1-5 · 座舱灯 / 焦点光微调（只收光、不位移、不遮热区）
   ============================================================ */

/* 乐园·摩天轮中心金光（.ferris-wheel::after 的 hubGlow 脉冲）：
   原态峰值 0 0 24px 9px rgba(255,220,110,.95) + 0 0 52px 16px .55，
   亮峰略喧宾（标题“大声说英语乐园就会亮起来”同区）。收 30~40% 光强、
   脉冲放慢到 3s，呼吸更柔；金光在 .gate(overflow:hidden) 内，
   不遮任何可点卡片（feature/zone 卡在 gate 外），pointer-events 无关。 */
body:has(> main.stage) .ferris-wheel::after {
  animation-name: hubGlowW1;
  animation-duration: 3s;
}
@keyframes hubGlowW1 {
  0%, 100% { box-shadow: 0 0 12px 4px rgba(255,210,80,.55), 0 0 26px 8px rgba(255,210,80,.28); }
  50%      { box-shadow: 0 0 16px 6px rgba(255,218,110,.70), 0 0 34px 11px rgba(255,210,80,.38); }
}

/* 小镇·单焦点呼吸光圈（.home-halo，径向金光、pointer-events:none 非热区）：
   原态 .4→.8 opacity 且 scale 1.08，峰值偏亮、靠近“我的小屋”名牌；
   收到 .32→.58、scale 1.05、周期 2.8s，存在感保留但不抢名牌/热区视线。
   注：town_map 位图(JPEG)里摩天轮/街灯等“灯”是画死的像素，CSS 无法调；
       树屋按 r12 避让注释“不亮灯不探头”，保持不亮。 */
.home-halo {
  animation-name: haloBreathW1;
  animation-duration: 2.8s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}
@keyframes haloBreathW1 {
  0%, 100% { opacity: .32; transform: scale(.92); }
  50%      { opacity: .58; transform: scale(1.05); }
}

/* 低动效偏好：微调后的光效同样关停（尊重系统设置） */
@media (prefers-reduced-motion: reduce) {
  body:has(> main.stage) .ferris-wheel::after,
  .home-halo { animation: none !important; }
}

/* ============================================================
   W1-4 · 乐豆招手帧挂接（town_map.html 向导，夏出帧·梅挂接）
   现状：.ledou-guide 是夏官方挥手立绘 PNG（48px、站小屋前院 37%/56.5%），
        原动画 ledouWave = 整图 rotate(-4°→5°)+上下位移，整图摇摆产生拖影。
   做法（纯 CSS、零 JS、不动 HTML）：
     1) 夏到帧为横向精灵条（1 行 N 帧 PNG）→ 用 .town-canvas::after 叠帧层，
        background-position 步进播放（steps），帧间无插值，根治拖影；
        旧 <img> 隐藏（visibility:hidden 保留 48px 占位，零布局位移）。
     2) 帧层绝对定位于向导同位（left/top 与 .ledou-guide 一致），
        z-index:7 压在底图(z1)/光圈(z3)/热区(z5)之上、名牌/标题(z7-9)之下，
        pointer-events:none 不抢任何热区。
     3) 到帧后只需改 :root 三个变量（帧数/帧宽/精灵图 URL）+
        @keyframes ledouFrameW1 的终点 background-position，骨架不动。
   若夏到的是独立帧序列（多张 PNG）：帧切换说明随图，
        梅按说明改为 ES5 轻量切换（另附 w1_wave_loader.js，node --check 过），
        CSS 帧层定位规则复用本段。
   验收点（施工图 W1-4）：无拖影、±3° 摆动自然。
   ============================================================ */

/* 帧参数（v2 已按夏精灵条 v1 填实：4 帧、单帧 3:4、一轮 1.6s 来回无缝循环）。
   帧图 ledou_wave_sprite.png 与本 css 同目录部署到 /hotfix/；
   用相对路径（不带前导 /），file:// 本地自测与线上 /hotfix/ 同源都能命中，
   带版本号破缓存。 */
:root {
  --w1-wave-n: 4;            /* 精灵条帧数：左高→正中最高→右高→正中（f2=f4 回摆） */
  --w1-wave-frame-w: 48px;   /* 单帧显示宽（与向导 48px 一致；精灵图源单帧 240×320） */
  --w1-wave-sprite: url("ledou_wave_sprite.png?v=20260901");
  --w1-wave-dur: 1.6s;       /* 完整一轮时长：4 帧 × 400ms */
}

/* 帧层：仅小镇地图壳出现；精灵图未就位时 background-image:none，规则空转无副作用 */
.town-canvas::after {
  content: "";
  position: absolute;
  left: 37%;                 /* 与 .ledou-guide 同位（v5e 小屋前院 S 形路径左畔） */
  top: 56.5%;
  width: var(--w1-wave-frame-w);
  aspect-ratio: 3 / 4;       /* 夏立绘 239×320 比例；老 WebView 不支持时由 height 兜底 */
  height: auto;
  z-index: 7;
  pointer-events: none;
  background-image: var(--w1-wave-sprite);
  background-repeat: no-repeat;
  background-size: calc(var(--w1-wave-frame-w) * var(--w1-wave-n)) 100%;
  background-position: 0 0;
  transform-origin: bottom center;
  filter: drop-shadow(0 4px 5px rgba(44,44,52,.22));  /* 与原向导同款落影 */
}

/* 精灵图就位后（--w1-wave-sprite 非 none）：启帧动画 + 藏旧整图。
   用 @supports 兜底：不支持 aspect-ratio 的老内核直接给高度 = 宽×4/3。 */
@supports not (aspect-ratio: 1) {
  .town-canvas::after { height: calc(var(--w1-wave-frame-w) * 4 / 3); }
}

/* 帧步进动画：steps(4, end) 每 400ms 硬切一帧、帧间零插值。
   关键（15:10 实测修正）：steps(4,end) 可见的四档对应进度 0/25/50/75%，
   终点值（100%）仅在循环瞬间出现。故终点位移必须 = N 个帧宽（-4×48 = -192px），
   四档才落在 0/-48/-96/-144 = f1/f2/f3/f4 干净单帧；
   若误写 (N-1) 帧宽（-144），四档变 0/-36/-72/-108，窗口同时露出相邻两帧=串影。
   -192px 瞬间精灵条整体滚出窗口、无缝回 0 接 f1。
   摆动由帧画本身表达，CSS 不 rotate 整图，杜绝拖影；
   末帧 f4=f2（正中）接首帧 f1（左高），来回无缝。 */
@keyframes ledouFrameW1 {
  from { background-position: 0 0; }
  to   { background-position: calc(0px - var(--w1-wave-frame-w) * var(--w1-wave-n)) 0; }
}

/* 精灵图就位开关（v2 已启用）：帧层播放 + 旧整图向导隐藏保占位；
   .ledou-guide 自身 pointer-events:none 且非热区（热区在各 <a>），
   visibility:hidden 不影响任何点击，48px 占位保留零布局位移。 */
.town-canvas::after {
  animation: ledouFrameW1 var(--w1-wave-dur) steps(4) infinite;
}
.ledou-guide { visibility: hidden; }
@media (prefers-reduced-motion: reduce) {
  .town-canvas::after { animation: none; }   /* 停在首帧（左高招手）静帧引导 */
}

/* 低动效偏好：W1-1 氛围纹理无需关停（静态背景）；W1-4 帧动画随上方规则关停。 */
