/* ══════════════════════════════════════════════════════════════
   悦美国际医疗美容 · 多巴胺官网
   设计基底：Logo 米色 #E6D2C8 / 深棕 #704739
   点缀色：多巴胺高饱和撞色（橙 / 玫红 / 柠黄 / 湖青 / 电光紫 / 天蓝）
   ══════════════════════════════════════════════════════════════ */

/* ---------- 1. Tokens ---------- */

:root{
  /* 品牌基色（来自 logo） */
  --beige:      #E6D2C8;   /* R230 G210 B200 */
  --beige-50:   #FBF4F0;
  --beige-100:  #F6EBE5;
  --beige-200:  #EFDFD7;
  --beige-300:  #E0C8BC;
  --brown:      #704739;   /* 深棕 */
  --brown-700:  #5C3A2E;
  --brown-800:  #46291E;
  --brown-900:  #331D15;
  --brown-950:  #1E120D;
  --cream:      #FFFAF6;

  /* 多巴胺点缀色 */
  --pop-orange: #FF6A2B;
  --pop-pink:   #FF3D77;
  --pop-yellow: #FFCF33;
  --pop-teal:   #00BF9F;
  --pop-violet: #7B4DFF;
  --pop-blue:   #2E93FF;
  --pop-gold:   #C79A2E;

  /* 语义 */
  --ink:        var(--brown-900);
  --ink-soft:   #6B5148;
  --ink-mute:   #8E756B;
  --line:       #E7D8D0;
  --line-dark:  rgba(230,210,200,.18);
  --on-dark:    var(--beige);
  --on-dark-mute: rgba(230,210,200,.62);

  /* 排版 */

--font-sans: "PingFang SC","Microsoft YaHei UI","Microsoft YaHei","Hiragino Sans GB","Source Han Sans SC","Noto Sans CJK SC",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-disp: "Arial Black","Segoe UI Black","Microsoft YaHei","PingFang SC","Helvetica Neue",Impact,sans-serif;

  /* 形状 */
  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 26px;
  --r-xl: 34px;
  --r-pill: 999px;

  /* 阴影：硬阴影制造多巴胺的“贴纸感” */
  --sh-hard:   5px 5px 0 var(--brown-900);
  --sh-hard-sm:3px 3px 0 var(--brown-900);
  --sh-soft:   0 18px 44px -22px rgba(70,41,30,.42);
  --sh-lift:   0 26px 56px -26px rgba(70,41,30,.5);

  /* 拟态玻璃（glassmorphism）：半透明底 + 背景模糊 + 内高光边 + 柔和外投影
     底色用"斜向渐变"而不是纯色 —— 纯色玻璃在纯色底上会退化成白卡，
     斜向渐变自带一层光感，即使背后没东西也能看出是玻璃 */
  --glass-bg: linear-gradient(135deg,
                rgba(255,255,255,.66) 0%,
                rgba(255,255,255,.30) 48%,
                rgba(255,255,255,.46) 100%);
  --glass-bg-dark: linear-gradient(135deg,
                rgba(255,255,255,.155) 0%,
                rgba(255,255,255,.045) 48%,
                rgba(255,255,255,.085) 100%);
  --glass-bg-strong: linear-gradient(135deg,
                rgba(255,252,249,.9) 0%,
                rgba(255,247,241,.66) 55%,
                rgba(255,250,246,.8) 100%);
  --glass-border:       rgba(255,255,255,.85);
  --glass-border-dark:  rgba(255,255,255,.2);
  --glass-hi:           rgba(255,255,255,.95);  /* 顶部 1px 内高光 */
  --glass-lo:           rgba(255,255,255,.4);   /* 底部 1px 内反光，玻璃的"厚度" */
  --glass-hi-dark:      rgba(255,255,255,.16);
  --glass-shadow:       0 20px 44px -26px rgba(70,41,30,.5);
  --glass-shadow-hover: 0 32px 64px -28px rgba(70,41,30,.62);
  --glass-shadow-dark:  0 20px 44px -26px rgba(0,0,0,.6);
  --glass-blur:         blur(16px) saturate(160%);
  --glass-blur-dark:    blur(13px) saturate(135%);

  /* 容器 */
  --wrap: 1240px;
  --gutter: clamp(18px, 4vw, 40px);
  --sec-y: clamp(64px, 8vw, 128px);

  --ease: cubic-bezier(.22,1,.36,1);
  /* 【已删除】--spring:cubic-bezier(.34,1.56,.64,1) —— hallmark m2（Gate 12）：
     过冲曲线不得用在 UI 状态切换上。它原本服务于已删除的光标特效，
     删除后成了无人引用的死 token，留着会被后续误用。 */
}


/* ---------- 2. Reset ---------- */
*,*::before,*::after{ box-sizing:border-box; }
/* 连续滚动：不使用 scroll-snap，避免滚轮/触控板滚动时被强制吸附到分区。
  scroll-padding-top 是给固定页头留的位（页头高 65px）。 */
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-snap-type:none;
  scroll-padding-top:65px;
  overflow-x:clip;
}
body{
  margin:0;
  font-family:var(--font-sans);
  font-size:clamp(15px,1.05vw,16.5px);
  line-height:1.75;
  color:var(--ink);
  background:var(--cream);
  /* hallmark M4（Gate 34）：门禁要求 html 与 body **都**用 overflow-x:clip。
     hidden 会创建滚动容器，破坏 sticky/fixed 后代的定位；clip 不会。 */
  overflow-x:clip;
  /* ★ 字体渲染（Windows 中文锯齿的两处主因）
     · 去掉 -webkit-font-smoothing:antialiased —— 它是给 macOS 调细体用的，
       Windows 上无效，某些浏览器反而会关掉次像素抗锯齿、笔画更毛；
     · text-rendering 从 optimizeLegibility 改回 auto —— optimizeLegibility
       在部分引擎里会跳过字形微调（hinting），小字号中文边缘就碎。 */
}
img,svg{ display:block; max-width:100%; }
img{ height:auto; }
a{ color:inherit; text-decoration:none; }
button,input,select,textarea{ font:inherit; color:inherit; }
button{ background:none; border:0; cursor:pointer; }
h1,h2,h3,h4{ margin:0; line-height:1.16; font-weight:700; letter-spacing:-.015em; }
p{ margin:0; }
ul,ol{ margin:0; padding:0; list-style:none; }
figure{ margin:0; }
cite{ font-style:normal; }
:focus-visible{ outline:3px solid var(--pop-violet); outline-offset:3px; border-radius:6px; }

.skip-link{
  position:fixed; left:50%; top:-100px; transform:translateX(-50%);
  z-index:300; padding:12px 22px; border-radius:var(--r-pill);
  background:var(--brown-900); color:var(--beige); font-weight:700;
  transition:top .25s var(--ease);
}
.skip-link:focus{ top:14px; }

.wrap{ width:min(var(--wrap), calc(100% - var(--gutter)*2)); margin-inline:auto; }

/* 锚点定位避开固定页头 */
main section[id]{ scroll-margin-top:92px; }

/* 层级（关键，动之前先读这段）：
     区块底色（.section，position:relative / z-index:auto）  ← 不透明
     .wrap（z-index:3） / .marquee（z-index:3）              ← 正文与装饰条
   便签/贴纸那些 2/4/20/30 的层级都在 .wrap 内部，不受影响。 */
main .wrap,
.site-footer .wrap{ position:relative; z-index:3; }


/* ---------- 3. 滚动进度条 ---------- */
.scroll-progress{
  position:fixed; inset:0 0 auto 0; height:4px; z-index:220;
  background:transparent; pointer-events:none;
}
.scroll-progress span{
  display:block; height:100%; width:0%;
  background:linear-gradient(90deg,var(--pop-orange),var(--pop-pink) 38%,var(--pop-violet) 68%,var(--pop-teal));
  transition:width .1s linear;
}


/* ---------- 4. 品牌锁定版（Logo） ---------- */
/* 按新 Logo 实测比例还原：图标 25×42、中文高 16、拉丁高 8、图文间距 14
   --lh 为锁定版总高，其余尺寸全部按比例推导，改一个变量即可整体缩放 */
.brand{
  --lh: 40px;
  display:flex; align-items:center; gap:calc(var(--lh) * .34);
  color:var(--brown); flex:none;
  transition:color .3s var(--ease);
}
.brand-mark{
  display:block; flex:none;
  width:calc(var(--lh) * .637); height:var(--lh);
  background:currentColor;
  -webkit-mask:url(../img/logo-mark.png) no-repeat center/contain;
          mask:url(../img/logo-mark.png) no-repeat center/contain;
  transition:transform .4s var(--ease);
}
.brand:hover .brand-mark{ transform:rotate(-6deg) scale(1.06); }

.brand-text{ display:flex; flex-direction:column; line-height:1; }
.brand-text strong{
  font-size:calc(var(--lh) * .44);
  font-weight:700; letter-spacing:.005em; line-height:1.04; white-space:nowrap;
}
.brand-text em{
  margin-top:calc(var(--lh) * .075);
  font-size:calc(var(--lh) * .265); font-style:normal; font-weight:600;
  letter-spacing:.15em; text-transform:uppercase; white-space:nowrap;
  line-height:1; color:currentColor; opacity:.7;
}


/* ---------- 5. 按钮 / 标签 ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:13px 26px; border-radius:var(--r-pill);
  font-weight:700; font-size:15px; line-height:1; white-space:nowrap;
  border:2px solid transparent; cursor:pointer;
  transition:transform .22s var(--ease), box-shadow .22s var(--ease), background .22s var(--ease), color .22s var(--ease), border-color .22s var(--ease);
}
.btn svg{ width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:2.4; stroke-linecap:round; stroke-linejoin:round; flex:none; }
.btn:hover{ transform:translateY(-3px); }
.btn:active{ transform:translateY(-1px); }

.btn--solid{ background:var(--brown); color:var(--beige); box-shadow:var(--sh-hard-sm); }
.btn--solid:hover{ background:var(--brown-800); box-shadow:5px 5px 0 var(--brown-900); }

.btn--pop{ background:linear-gradient(100deg,var(--pop-orange),var(--pop-pink)); color:#fff; box-shadow:3px 3px 0 var(--brown-900); }
.btn--pop:hover{ box-shadow:5px 5px 0 var(--brown-900); }

.btn--ghost{ background:transparent; color:var(--brown); border-color:var(--brown); }
.btn--ghost:hover{ background:var(--beige-100); }

.btn--lg{ padding:16px 32px; font-size:16px; }
.btn--block{ width:100%; }

/* 高亮色块 */
.hl{ position:relative; display:inline-block; padding:0 .16em; z-index:0; }
.hl::before{
  content:""; position:absolute; left:-.02em; right:-.02em; top:.16em; bottom:.04em;
  border-radius:.22em; transform:rotate(-1.4deg); z-index:-1;
  background:var(--pop-yellow);
}
.hl--yellow::before{ background:var(--pop-yellow); }
.hl--teal::before{ background:#8FF0E0; }
.hl--pink::before{ background:#FFB3CC; }
.hl--violet::before{ background:#CFBDFF; }
.hl--orange::before{ background:#FFC3A1; }


/* ---------- 6. 页头导航 ---------- */
.site-header{
  position:fixed; inset:4px 0 auto 0; z-index:200;
  padding:10px 0;
  transition:background .3s var(--ease), box-shadow .3s var(--ease), padding .3s var(--ease);
}
.site-header.is-stuck{
  background:rgba(255,250,246,.9);
  backdrop-filter:saturate(1.4) blur(14px);
  -webkit-backdrop-filter:saturate(1.4) blur(14px);
  box-shadow:0 12px 34px -22px rgba(70,41,30,.55);
  padding:6px 0;
}
.site-header.is-menu-open,
.site-header.is-menu-open.is-stuck,
.site-header.is-menu-open.is-dark{
  background:#fff; background-color:#fff !important;
  box-shadow:0 1px 0 rgba(70,41,30,.08);
  -webkit-backdrop-filter:none; backdrop-filter:none;
  transition:none;
}
/* ★ 页头随底下区块变色（客户："导航栏在这个颜色的界面很突兀，自然融入变色"）
   深色区块（资质与正品 / 客人怎么说 / 预约到店 / 页脚）滚到页头下面时，
   main.js 第 7b 节给 .site-header 加 .is-dark，整条页头换成深色玻璃。
   logo 是 mask + currentColor，所以只要改 .brand 的 color，logo 自己跟着变色 ✓
   ⚠️ 这些规则限定在桌面端：移动端 .nav 是整屏抽屉（背景 var(--cream)），
      不加限定的话这里的 .nav 背景会把它压成透明。 */
@media (min-width:1025px){
  .site-header.is-dark{
    background:rgba(30,18,13,.8);
    box-shadow:0 14px 36px -24px rgba(0,0,0,.9);
  }
  .site-header.is-dark .brand{ color:var(--beige); }
.site-header.is-dark .burger{ background:transparent; border-color:var(--beige); }
.site-header.is-dark .burger span{ background:var(--beige); }
  .site-header.is-dark .nav{
    background:rgba(255,255,255,.07);
    border-color:rgba(230,210,200,.14);
    box-shadow:0 12px 28px -18px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.12);
  }
  .site-header.is-dark .nav > a{ color:var(--on-dark-mute); }
  .site-header.is-dark .nav > a:hover{ color:#fff; background:rgba(255,255,255,.12); }
  /* 选中的那颗保持"整颗填区块色" —— 深色底上反而更亮 */
  .site-header.is-dark .nav > a.is-active{ color:#fff; background:var(--c); }
  .site-header.is-dark .nav > a::before{ opacity:.8; }
  /* 电话药丸：深色下换成描边款，不再是一颗亮白块 */
  .site-header.is-dark .nav-phone{
    background:rgba(255,255,255,.08);
    border-color:rgba(230,210,200,.32);
    color:var(--beige);
    box-shadow:3px 3px 0 rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.12);
  }
}
/* 移动端：页头底色与 logo 也跟着深色走（抽屉菜单本身保持浅色） */
.site-header.is-dark{ background:rgba(30,18,13,.8); box-shadow:0 14px 36px -24px rgba(0,0,0,.9); }
.site-header.is-dark .brand{ color:var(--beige); }
.site-header.is-dark .burger{ background:transparent; border-color:var(--beige); }
.site-header.is-dark .burger span{ background:var(--beige); }
/* 页头通栏三栏栅格：Logo 贴最左 · 菜单栏居中 · 电话贴最右
   左右用 minmax(0,1fr) 而非 1fr：1fr 会带上内容的基准宽度，
   会让"菜单居中"被 Logo 与电话的宽度差带偏；minmax(0,1fr) 两栏严格等宽，
   菜单因此精确居中于视口 */
.header-inner{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  align-items:center;
  gap:clamp(12px, 2vw, 30px);
  width:100%;
  padding-inline:clamp(16px, 2.2vw, 34px);
}
.brand{ justify-self:start; }
.nav{ justify-self:center; }
.header-end{ justify-self:end; display:flex; align-items:center; gap:12px; }

/* ★ 导航改版（客户："这里太普通了，而且间距是不是有点近了"）
   旧版：六个一样的灰字 + 悬停时一条橙粉渐变下划线 —— 和全站的多巴胺语言脱节。
   新版：① 整条导航是一枚**玻璃胶囊**（沿用站内的玻璃卡片语言），
         ② 每个链接是一颗药丸，左端一枚**该区块颜色的圆点**，
         ③ 悬停：圆点由空心变实心、底色透出一点白；
         ④ 滚到该区块时由 JS 加 .is-active，**整颗填成该区块的颜色**。
   间距：旧版 gap 只有 6~20px、链接内边距 4px，所以挤在一起；
         新版靠"药丸自身的内边距 17px"提供呼吸，相邻文字之间实际有 34px+ ✓ */

/* 胶囊容器 */
.nav{
  display:flex; align-items:center;
  gap:clamp(2px,.35vw,5px);
  padding:6px; border-radius:var(--r-pill);
  background:rgba(255,255,255,.5);
  border:1.5px solid rgba(112,71,57,.10);
  -webkit-backdrop-filter:blur(10px) saturate(1.3);
  backdrop-filter:blur(10px) saturate(1.3);
  box-shadow:0 12px 28px -20px rgba(70,41,30,.55), inset 0 1px 0 rgba(255,255,255,.8);
}
/* 药丸本身 */
.nav > a{
  position:relative;
  --c:var(--pop-orange);          /* 兜底色；实际由 HTML 内联按区块覆盖 */
  display:inline-flex; align-items:center; gap:8px;
  font-size:14.5px; font-weight:600; color:var(--brown-800);
  padding:9px 17px; border-radius:var(--r-pill);
  white-space:nowrap;
  transition:color .22s var(--ease), background .22s var(--ease),
             box-shadow .22s var(--ease), transform .22s var(--ease);
}
/* 左端圆点：默认空心描边（淡），悬停/选中变实心 */
.nav > a::before{
  content:""; flex:none;
  width:7px; height:7px; border-radius:50%;
  background:transparent; box-shadow:inset 0 0 0 2px var(--c);
  opacity:.5; transform:scale(.8);
  transition:background .22s var(--ease), opacity .22s var(--ease),
             transform .22s var(--ease), box-shadow .22s var(--ease);
}
.nav > a:hover{
  color:var(--brown-950);
  background:rgba(255,255,255,.85);
  transform:translateY(-1px);
}
.nav > a:hover::before{ background:var(--c); box-shadow:none; opacity:1; transform:scale(1); }
/* 当前所在区块：整颗填成该区块的颜色 */
.nav > a.is-active{
  color:#fff; background:var(--c);
  box-shadow:0 8px 18px -10px var(--c), inset 0 1px 0 rgba(255,255,255,.4);
}
.nav > a.is-active::before{ background:#fff; box-shadow:none; opacity:1; transform:scale(1); }

/* 联系电话：独立于菜单栏，固定在页头最右侧
   原来是一颗"白底 + 棕字 + 一个绿点"的素净药丸，太单调。现在给它三件事：
     · 暖色渐变纸面 + 内高光 + 黄色硬阴影（沿用全站的硬阴影骨架，顺便把多巴胺色引到页头）
     · 左侧一枚橙→粉渐变圆底话筒徽标：呼吸光圈 + 周期性"响铃"抖动
     · 悬停：整颗换成橙→粉渐变、字变白、徽标反白，硬阴影加厚并抬起
   两处动效都会被第 24 节 prefers-reduced-motion 统一降级 */
.nav-phone{
  position:relative;
  display:inline-flex; align-items:center; gap:9px;
  padding:8px 18px 8px 9px; border-radius:var(--r-pill);
  background:linear-gradient(135deg,#FFFCF6,#FFF0E0);
  border:2.5px solid var(--brown-900);
  font-weight:700; font-size:14.5px; letter-spacing:.02em; color:var(--brown-900);
  white-space:nowrap;
  box-shadow:3px 3px 0 var(--pop-yellow), inset 0 1px 0 rgba(255,255,255,.9);
  transition:transform .22s var(--ease), box-shadow .22s var(--ease), background .22s var(--ease), color .22s var(--ease);
}
.nav-phone-ico{
  flex:none;
  width:25px; height:25px; border-radius:50%;
  display:grid; place-items:center;
  background:linear-gradient(120deg,var(--pop-orange),var(--pop-pink));
  color:#fff;
  animation:navPhonePulse 2.6s ease-out infinite;
}
.nav-phone-ico svg{
  width:14px; height:14px;
  fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round;
  animation:navPhoneRing 4.4s ease-in-out infinite;
}
@keyframes navPhonePulse{
  0%{   box-shadow:0 0 0 0 rgba(255,61,119,.55); }
  70%{  box-shadow:0 0 0 9px rgba(255,61,119,0); }
  100%{ box-shadow:0 0 0 0 rgba(255,61,119,0); }
}
/* 响铃：绝大多数时间是静的，每 4.4 秒抖一下，避免一直动分散注意 */
@keyframes navPhoneRing{
  0%, 60%, 100%{ transform:rotate(0deg); }
  64%{ transform:rotate(-13deg); }
  69%{ transform:rotate(11deg); }
  74%{ transform:rotate(-8deg); }
  79%{ transform:rotate(6deg); }
  84%{ transform:rotate(-3deg); }
  89%{ transform:rotate(0deg); }
}
.nav-phone:hover{
  transform:translate(-2px,-2px);
  background:linear-gradient(100deg,var(--pop-orange),var(--pop-pink));
  color:#fff;
  box-shadow:5px 5px 0 var(--brown-900), inset 0 1px 0 rgba(255,255,255,.35);
}
.nav-phone:hover .nav-phone-ico{ background:#fff; color:var(--pop-pink); animation:none; }
.burger{ display:none; width:46px; height:46px; border-radius:14px; border:2px solid var(--brown); background:#fff; }
.burger span{ display:block; width:20px; height:2.4px; margin:4px auto; border-radius:2px; background:var(--brown); transition:transform .3s var(--ease), opacity .2s; }
.burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(6.4px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ opacity:0; }
.burger[aria-expanded="true"] span:nth-child(3){ transform:translateY(-6.4px) rotate(-45deg); }


/* ---------- 7. Hero ---------- */
/* ★ hero 改成 flex 列，跑马灯（.marquee）用 margin-top:auto 贴到最底部。
   下内边距归零 —— 跑马灯要贴齐 hero 底边，否则会在它下面留一条缝。
   原来那条 48~80px 的呼吸空间改由 .hero-facts 的下外边距提供。
   （.hero-blobs 是绝对定位，不参与 flex 流，不受影响） */
.hero{
  position:relative;
  padding:clamp(120px,15vw,190px) 0 0;
  overflow:hidden;
  display:flex; flex-direction:column;
}
.hero .marquee{ margin-top:auto; }
.hero-blobs{ position:absolute; inset:0; pointer-events:none; }
.blob{ position:absolute; border-radius:50%; filter:blur(58px); opacity:.5; }
.blob--1{ width:clamp(230px,30vw,440px); aspect-ratio:1; background:#FFC3A1; top:-6%; left:-6%; }
.blob--2{ width:clamp(200px,26vw,380px); aspect-ratio:1; background:#B9A6FF; top:22%; right:-8%; }
.blob--3{ width:clamp(180px,22vw,320px); aspect-ratio:1; background:#8FF0E0; bottom:-10%; left:26%; opacity:.42; }
.blob--4{ width:clamp(150px,18vw,260px); aspect-ratio:1; background:#FFB3CC; top:52%; left:-4%; opacity:.4; }


/* 页面级固定底图：像右下角预约按钮一样常驻屏幕，不随页面滚走
   层级安排（关键）：
     区块底色（常规流） < 本层 z-index:0 < 正文容器 .wrap z-index:1
   底图放在 body 最末，因此压在包括页脚在内的所有区块底色之上，但仍在所有正文之下

/* ---------- 页面级品牌字「YUE MEI」：一页填一个字母 ----------
   客户要的是**原来那种"随滚动填充"的进度感**，但填充要**一格一格跳**：
     第 1 屏填满 Y → 第 2 屏 YU → 第 3 屏 YUE → … → 第 6 屏整块填满。
   两层结构：
     .ghost-base  棕色描边，整块字始终都在（"还没填到"的骨架）
     .ghost-fill  彩色渐变填充，宽度 = 已填字母数对应的百分比（JS 写 --ghost-p）
   百分比不是按字数平均分的 —— 字母宽度不等（M 比 I 宽），
   所以 JS 用同字号的隐藏元素实测每个前缀的真实宽度。
   transition 只作用在 width 上：每推进一页，填充"扫"进下一个字母。 */
.page-ghost{
  position:fixed; z-index:0;
  /* ★ 还原改版前的落点：原来是 top:76% + translateY(-50%)（垂直居中在 76% 处）。
     我改成 bottom:3% 之后，配合 line-height:.8（行盒比字形矮），
     字形底部会坠出视口下沿 —— 客户反馈"U 字底部不见了"。
     改回原版定位即可保证整字可见；改这里之前先想清楚"行盒 ≠ 字形"。 */
  right:2%; top:76%;
  transform:translateY(-50%);
  font-family:var(--font-disp);
  /* 字号回到改版前那一档：之前我为了配合"堆叠/字母填充"调大到了 120~340px，
     客户反馈"之前的背景的 YUE MEI 没有这么大的"。 */
  font-size:clamp(90px,17vw,260px);
  line-height:.82; letter-spacing:-.04em;
  pointer-events:none; user-select:none; white-space:nowrap;
  --ghost-tone:rgba(112,71,57,.13);
  --ghost-fill-op:.20;
  --ghost-fill-op-dark:.17;

  /* ★ 分区裁切（客户："YUEMEI 进入深色区域部分就变色"）。
     大字是一整块 fixed 元素，跨越浅色区与深色区；
     要把"压在深色区里的那一部分"单独变白，就得按区间裁切。
     JS 每次滚动写入深色区在这块字里的高度区间（--ghost-dark-top / --ghost-dark-h）。 */
  --ghost-dark-top:0px;  --ghost-dark-h:0px;
  --clip-dark:inset(var(--ghost-dark-top) 0 max(0px, calc(100% - var(--ghost-dark-top) - var(--ghost-dark-h))) 0);
  --clip-pop: inset(var(--ghost-dark-top) 0 0 0);
  --clip-pop-b: inset(0 0 max(0px, calc(100% - var(--ghost-dark-top) - var(--ghost-dark-h))) 0);
}
/* ---------- 背景品牌字「YUE MEI」的四层与分区上色 ----------
   四层各自只栅格化一次，**全部常显**；浅/深的区分完全交给 clip-path 分区裁切：
   浅色层挖掉"深色段"（polygon = 上段 + 下段），深色层只留"深色段"。
   于是"压在深色区里的那一部分才变白"成立
   （客户："YUEMEI 进入深色区域部分就变色"），
   而且切换只改 clip-path —— 不换背景图、不重栅格化
   （客户反馈的浅↔深切换卡顿就是这么修的）。

   ⚠️⚠️ 顺序是硬要求：.ghost-base--dark 的元素 class 里**同时含 .ghost-base**，
   .ghost-fill--dark 同理含 .ghost-fill。所以"深色覆盖层"必须写在
   "通用层"**之后** —— 否则两条同权重，后者胜出，两层会拿到同一个 clip。
   这个坑在本项目已经踩过两次（描边一次、填充一次），改这块务必保持顺序。 */
.ghost-base{
  display:block; color:transparent;
  -webkit-text-stroke:2px var(--ghost-tone);
  clip-path:polygon(0 0, 100% 0, 100% var(--ghost-dark-top), 0 var(--ghost-dark-top), 0 100%, 100% 100%, 100% calc(var(--ghost-dark-top) + var(--ghost-dark-h)), 0 calc(var(--ghost-dark-top) + var(--ghost-dark-h)));
}
.ghost-fill{
  position:absolute; left:0; top:0; bottom:0;
  width:var(--ghost-p, 0%); overflow:hidden;
  transition:width .55s var(--ease);
}
.ghost-fill > span{
  position:absolute; left:0; top:0;
  display:block; white-space:nowrap;
  /* ★ hallmark C1（Gate 2）：原来用 background-clip:text + 橙→粉→紫→青四色渐变。
     门禁原文 "No genre allows gradient text." —— 全站最典型的一条 AI 味。

     ⚠️⚠️ 这里**必须用 color 直接上色，绝不能再用 background-clip:text**。
     第一版我改成了 `background-color:var(--brown)` 却把同块的
     `background-clip:text` 与 `-webkit-text-fill-color:transparent` 一起删了 ——
     于是"只染文字"的裁切没了，填充层变成**一整块实心矩形**，
     深色区那层更是直接画出一个白方块（客户截图里那块白色方块就是它）。
     用 color 上色既不需要裁切、也不可能出错。 */
  background:none; color:var(--brown);
  opacity:var(--ghost-fill-op);
  transition:opacity .45s var(--ease);
  clip-path:polygon(0 0, 100% 0, 100% var(--ghost-dark-top), 0 var(--ghost-dark-top), 0 100%, 100% 100%, 100% calc(var(--ghost-dark-top) + var(--ghost-dark-h)), 0 calc(var(--ghost-dark-top) + var(--ghost-dark-h)));
}
/* ---- 以下两条是深色覆盖层：必须放在通用层之后 ---- */
.ghost-base--dark{
  position:absolute; left:0; top:0;
  -webkit-text-stroke-color:rgba(255,255,255,.16);
  clip-path:var(--clip-dark);
}
.ghost-fill--dark > span{
  background:none; color:#fff;
  opacity:var(--ghost-fill-op-dark, .17);
  clip-path:var(--clip-dark);
}
/* 首屏：描边层照常显示（"YUE MEI" 的字一直在），只是**彩色填充为 0 格**。
   JS 在首屏把 --ghost-p 写成 0%，.ghost-fill 宽度为 0 自然就没有填充。 */
/* 【已删除】原深色态在这里换 background-image，会触发整块重栅格化 → 卡顿。改为叠加层 + opacity。 */

.hero-grid{ position:relative; display:grid; grid-template-columns:1.27fr .73fr; gap:clamp(28px,4.4vw,64px); align-items:center; }

/* ★ 标题字号原是 clamp(37px,5.9vw,74px)。换文案后第一行变成 11 个字放不下，
   新标题第一行「青春不减分，魅力悦美颜」有 11 个字，实测 74px 时宽 790px，
   于是把 .hero-grid 的列比从 1.02fr/.98fr 调成 1.27fr/.73fr（右侧便签墙整体缩小），
   标题列从 600px 拓到 747px，字号得以回到 64px。改列比或改文案后必须重新量。
   （想换成更小的字号或改行数，见 README 三节「Hero 标题」） */
.hero h1{
  margin:0;
  /* ⚠️ 字号跟标题内容绑死：左栏宽 747px。
     最长一行「让变美是一件轻松愉悦的事」12 字，
     64px 时实测 768px —— 放不进，会折行；58px 时 696px，留 51px 余量。
     改标题文案时务必回来复量。 */
  font-size:clamp(26px,4.2vw,58px);
  line-height:1.12; letter-spacing:-.03em; font-weight:700;
}
/* max-width 从 33em 放宽到 36em：标题列已拓到 747px，正文没必要还停在 594px。
   窄了会多出一行（加粗短语带 nowrap，放不下就整块推到下一行）；
   但也不宜超过 ~38em —— 中文单行超过 36 字读起来会累。 */
.hero-lead{ margin:24px 0 0; max-width:36em; font-size:clamp(15.5px,1.25vw,18px); color:var(--ink-soft); }
/* 加粗的短语一律不换行。
   中文没有词边界，浏览器会在任意两字之间断行 —— 实测出现过
   「扫码验 / 真」这种把一个词劈成两半的断法，很难看。
   ⚠️ 加了 nowrap 就要求这些 <b> 必须足够短（现在最长 9 个字）：
      一旦写长了，它会顶破 .hero-lead 的 max-width 而不是换行。 */
.hero-lead b{ color:var(--brown); font-weight:700; white-space:nowrap; }

.hero-actions{ display:flex; flex-wrap:wrap; gap:14px; margin:30px 0 0; }

/* Hero 视觉位：便签墙 ------------------------------------------------------
   照片还没到位，先做成"贴在墙上的便签条"：每张一张纸条 + 一条和纸胶带，
   整组故意歪斜、互相压叠。倾斜度刻意给大（-13° ~ +12°），才有随手贴上去的手感；
   照片到位后把 .note-ph 换成 <img>，便签骨架不用动。
   --tape 由行内样式写在 .note 上（伪元素 ::before 取不到子元素的变量）。 */
.hero-visual{
  position:relative;
  padding:18px 0 clamp(56px,7vw,86px);   /* 给下方溢出的小便签留出空间，别压到数字条 */
}
.notes{ position:relative; }

.note{
  position:relative; margin:0;
  --rot:0deg;                            /* 每张便签的倾斜角（见下方各 --rot 赋值） */
  display:flex; flex-direction:column; gap:9px;
  padding:17px 17px 15px;
  border-radius:3px;
  background:linear-gradient(158deg,#FFFDF5 0%,#FFF6E5 58%,#FFEFD6 100%);
  border:1px solid rgba(112,71,57,.20);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    0 18px 32px -16px rgba(70,41,30,.5),
    3px 4px 0 rgba(112,71,57,.07);
  /* 倾斜写成变量而不是写死 transform：悬停时要叠 scale/translate，
     写死的话每张便签都得再抄一遍自己的角度 */
  transform:rotate(var(--rot));
  transition:transform .3s var(--ease), box-shadow .3s var(--ease);
}
/* 和纸胶带：半透明压在便签上沿，两端做撕边 */
.note::before{
  content:""; position:absolute; left:50%; top:-13px;
  width:84px; height:26px; transform:translateX(-50%) rotate(-1.8deg);
  background:var(--tape, var(--pop-yellow));
  opacity:.5;
  border-left:2px dashed rgba(255,255,255,.8);
  border-right:2px dashed rgba(255,255,255,.8);
  box-shadow:0 4px 9px -4px rgba(70,41,30,.45);
  pointer-events:none;
}
/* 照片占位：虚线框 + 45° 斜纹底，全站统一（Hero 便签内是 .note-ph，其余区块是 .ph） */
.ph,.note-ph{
  display:grid; place-items:center;
  border:2px dashed rgba(112,71,57,.30); border-radius:3px;
  background:repeating-linear-gradient(45deg, rgba(112,71,57,.05) 0 9px, transparent 9px 18px);
  color:var(--ink-mute);
  font-weight:700; letter-spacing:.06em;
}
.note-ph{ flex:1; min-height:76px; font-size:clamp(13px,1.05vw,15px); }

/* ★ 照片位的真图样式（原来这里放的是 .ph / .note-ph 虚线占位）。
   ⚠️ 三处都必须 object-fit:cover —— 便签是 4/3 与 1/1、画廊是 4/3 与 16/9、
      资质照片是 16/8，比例各不相同，不加 cover 图会被拉变形。 */
.note img{
  display:block; width:100%; flex:1; min-height:76px;
  object-fit:cover; border-radius:3px;
}
.gal-item img{
  display:block; width:100%; height:100%;
  aspect-ratio:20/9; object-fit:cover;
}
.gal-item--wide img{ aspect-ratio:32/7; }
.verify-photo img{
  /* ⚠️ 比例决定这一屏高度：照片在 1fr 列里宽约 500px，
     21/9 → 214px，比左侧步骤块（167px）还高，成了高度主导。
     改成 8/3 → 187px，整块矮 27px，资质区余量从 49px 回到 74px。 */
  display:block; width:100%; aspect-ratio:8/3; object-fit:cover;
}

/* ★ 医师墙 + 执业说明并排（客户："医师这里页面调整"）
   原来照片独占通栏：1240px ÷ 3 = 413px 高，把团队区顶成两屏、照片还在屏底被切断。
   改成左列（1.25fr ≈ 660px）→ 3:1 只有 220px 高，右侧放执业说明，整区回到一屏。 */
.team-foot{
  display:grid; grid-template-columns:1.25fr 1fr;
  gap:clamp(20px,2.6vw,40px); align-items:center;
  margin-top:clamp(24px,2.9vw,42px);
}
.team-wall{
  position:relative; margin:0;
  border-radius:var(--r-lg); overflow:hidden;
  border:3px solid var(--beige-300); box-shadow:var(--sh-soft);
}
.team-foot .team-note{ margin-top:0; }
/* ⚠️ 用 3/1 而不是 21/9：21/9 在 1240px 宽下高达 532px，
   会把团队区从 538px 顶到 1117px（多出一屏）。3/1 是 413px，
   裁出来正好是医师墙中间那一排照片，观感也更好。
   object-position 取 38% 是为了让那一排人像保持在画面中部。 */
.team-wall img{ display:block; width:100%; aspect-ratio:2.62/1; object-fit:cover; object-position:center 38%; }
.team-wall figcaption{
  position:absolute; left:16px; bottom:16px;
  padding:7px 14px; border-radius:var(--r-pill);
  background:rgba(30,18,13,.82); color:var(--beige);
  font-size:12px; font-weight:700; backdrop-filter:blur(6px);
}
/* 深色区块（资质与正品）里，棕色的虚线与斜纹会糊在底色上，换成白色低透明度 */
.section--trust .ph{
  border-color:rgba(255,246,238,.30);
  background:repeating-linear-gradient(45deg, rgba(255,246,238,.07) 0 9px, transparent 9px 18px);
  color:rgba(255,246,238,.75);
}

/* 主便签在文档流里定尺寸；四张小便签绝对定位绕着它散开。
   层级刻意做成"上面两张塞在主便签后面、下面两张压在它前面"，
   主便签的信息不会被四张一起盖住，堆叠关系也更像真的叠纸 */
.note--main{ aspect-ratio:4/3; --rot:-2deg; z-index:3; }
.note--a,.note--b,.note--c,.note--d{ position:absolute; aspect-ratio:1/1; }
.note--c{ width:38%; left:-12%; top:-3%;   --rot:-13deg; z-index:2; }
.note--d{ width:35%; right:-13%; top:3%;   --rot:12deg;  z-index:2; }
.note--a{ width:46%; left:-11%; bottom:-14%; --rot:-9deg; z-index:4; }
.note--b{ width:44%; right:-10%; bottom:-12%; --rot:8deg;  z-index:4; }

/* 悬停：这张便签升到最上层、轻轻抬起，并浮出这一格的照片说明。
   z-index 一步跳到 20，保证压过其余四张（原层级 2/3/4） */
.note:hover{
  z-index:20;
  transform:rotate(var(--rot)) translateY(-10px) scale(1.04);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    0 30px 48px -18px rgba(70,41,30,.55),
    4px 6px 0 rgba(112,71,57,.09);
}
/* 说明气泡：悬停时从卡片上方浮出，小尾巴朝下指向卡片。
   半透明 + 磨砂，故意压住存在感，不跟便签主体抢眼 */
.note-tip{
  position:absolute; left:50%; bottom:calc(100% + 13px); z-index:3;
  padding:7px 14px; border-radius:11px;
  background:rgba(255,253,245,.82);
  -webkit-backdrop-filter:blur(7px) saturate(160%);
          backdrop-filter:blur(7px) saturate(160%);
  border:1.5px solid rgba(112,71,57,.20);
  box-shadow:0 12px 26px -16px rgba(70,41,30,.55);
  font-size:12.5px; font-weight:700; letter-spacing:.06em;
  color:var(--brown); white-space:nowrap;
  opacity:0; pointer-events:none;
  transform:translateX(-50%) translateY(7px);
  transition:opacity .24s var(--ease), transform .24s var(--ease);
}
/* 尾巴：旋转 45° 的方块，只留右+下描边，就成了朝下的尖角 */
.note-tip::after{
  content:""; position:absolute; left:50%; top:100%;
  width:11px; height:11px; margin:-6px 0 0 -5.5px;
  transform:rotate(45deg);
  background:rgba(255,253,245,.82);
  -webkit-backdrop-filter:blur(7px) saturate(160%);
          backdrop-filter:blur(7px) saturate(160%);
  border-right:1.5px solid rgba(112,71,57,.20);
  border-bottom:1.5px solid rgba(112,71,57,.20);
}
.note:hover .note-tip{ opacity:1; transform:translateX(-50%) translateY(0); }

.sticker{
  position:absolute; z-index:30;
  --rot:0deg; --dx:0px; --dy:0px; --dodge:1;   /* 基础倾角 + 躲让位移 + 躲让幅度系数（见下） */
  display:inline-flex; flex-direction:column; align-items:center;
  padding:9px 15px; border-radius:16px; border:2.4px solid var(--brown);
  font-size:13px; font-weight:700; line-height:1.25; text-align:center;
  box-shadow:var(--sh-hard-sm); white-space:nowrap;
  transform:translate(calc(var(--dx) * var(--dodge)), calc(var(--dy) * var(--dodge))) rotate(var(--rot));
  transition:transform .34s var(--ease), opacity .34s var(--ease);
}
.sticker em{ font-style:normal; font-size:10.5px; font-weight:600; opacity:.72; }
/* 五张贴纸搭在便签上：各自压在某一两张便签的边角/接缝上，
   倾斜度比便签更大（−11° ~ +15°），像随手拍上去的标签。
   z-index 高于便签悬停时的 20，保证便签抬起时贴纸不会被吞掉。

   ★ 下面这几行现在只是**兜底**（JS 没跑起来时才生效）。
   正常加载时位置由 main.js 第 12 节每次刷新随机生成，用行内 left/top + --rot 覆盖，
   并且会把 right / bottom 置为 auto（否则 left 与 right 同时存在会把元素拉宽）。
   随机化的约束（扇区打乱、外扩上限、避开气泡带与已放好的贴纸）都写在那边。
   注意锚点变了：贴纸现在在 .notes 里，百分比相对**便签组**而不是 .hero-visual。 */
.sticker--1{ left:15%;  top:-1%;    --rot:-11deg; background:var(--pop-yellow); color:var(--brown-900); }
.sticker--2{ right:7%;  top:13%;    --rot:9deg;   background:var(--pop-teal);   color:#06342B; }
.sticker--3{ left:38%;  bottom:4%;  --rot:-8deg;  background:var(--pop-pink);   color:#fff; box-shadow:3px 3px 0 var(--brown-900); }
.sticker--4{ left:-3%;  top:16%;    --rot:15deg;  background:var(--pop-violet); color:#fff; box-shadow:3px 3px 0 var(--brown-900); }
.sticker--5{ right:-1%; bottom:11%; --rot:-6deg;  background:var(--pop-blue);   color:#fff; box-shadow:3px 3px 0 var(--brown-900); }

/* 光标指到某张便签时，压在这张便签上的贴纸躲开：滑出去 + 淡到 30%。
   位移幅度给足——目标是"卡片周围与卡片上方气泡那一带彻底干净"，不是挪开一点点。
   方向是挑过的，每一条都避开了它可能碰到的东西：
     · s1 只往上：它正卡在左右两个气泡的横带之间，往左会压到 c 的气泡、往右会压到主便签的气泡，
       只有垂直方向是干净的
     · s2 往上、s3/s5 往下：都是往画外走，远离卡片
     · s4 往左下：它整张都压在 c 上，只能靠"往左挪 + 变淡"让开；左侧到标题文案只剩约 47px 余量，
       所以给 -34px 是上限，再多就会碰到文案
   `--dodge` 是幅度系数：单列断点下上下都被挤着，见第 23 节把它减半 */
/* 变淡：让开的贴纸统一淡到 30% */
.hero-visual:has(.note--main:hover) .sticker--3,
.hero-visual:has(.note--main:hover) .sticker--4,
.hero-visual:has(.note--main:hover) .sticker--5,
.hero-visual:has(.note--c:hover) .sticker--1,
.hero-visual:has(.note--c:hover) .sticker--4,
.hero-visual:has(.note--d:hover) .sticker--2,
.hero-visual:has(.note--a:hover) .sticker--3,
.hero-visual:has(.note--a:hover) .sticker--4,
.hero-visual:has(.note--b:hover) .sticker--5{ opacity:.3; }

/* 位移逐条写开（方向是按实测挑的，不是对称给一个"往外"）：
   · 主便签悬停：只让压在它身上的 s3/s4/s5 躲。s1/s2 虽然也搭在它上沿，
     但它们横向正卡在"左卡气泡 / 主卡气泡"两条带之间，往上躲反而会撞气泡，所以留原地不动
   · c 悬停：s1 上移、s4 往左下（s4 整张压在 c 上，只能靠左移 + 变淡让开；
     左侧到标题文案只剩约 47px，-24px 是上限）
   · a 悬停：s4 只往左，不带向下——向下会蹭到 a 卡片上方的气泡
   · 其余：s2 上移、s3/s5 往画外走 */
.hero-visual:has(.note--main:hover) .sticker--3{ --dx:-8px;  --dy:34px; }
.hero-visual:has(.note--main:hover) .sticker--4{ --dx:-24px; --dy:10px; }
.hero-visual:has(.note--main:hover) .sticker--5{ --dx:28px;  --dy:28px; }

.hero-visual:has(.note--c:hover) .sticker--1{ --dx:0px;   --dy:-38px; }
.hero-visual:has(.note--c:hover) .sticker--4{ --dx:-24px; --dy:16px; }

.hero-visual:has(.note--d:hover) .sticker--2{ --dx:6px;   --dy:-38px; }

.hero-visual:has(.note--a:hover) .sticker--3{ --dx:-8px;  --dy:34px; }
.hero-visual:has(.note--a:hover) .sticker--4{ --dx:-26px; --dy:0px; }

.hero-visual:has(.note--b:hover) .sticker--5{ --dx:28px;  --dy:28px; }

/* Hero 数字条 */
.hero-facts{
  display:grid; grid-template-columns:repeat(6,1fr); gap:clamp(10px,1.4vw,20px);
  margin-top:clamp(40px,5.4vw,74px); margin-bottom:clamp(40px,5.4vw,74px); padding:22px clamp(16px,2.4vw,30px);
  border-radius:var(--r-lg);
  background:#fff; border:2px solid var(--beige-300);
  box-shadow:6px 6px 0 var(--beige-200);
}
.hero-facts li{ display:flex; flex-direction:column; gap:2px; text-align:center; }
.hero-facts b{ font-family:var(--font-disp); font-size:clamp(21px,2.5vw,33px); line-height:1; color:var(--brown); letter-spacing:-.02em; }
.hero-facts b small{ font-size:.52em; font-weight:700; }
.hero-facts span{ font-size:12.5px; color:var(--ink-mute); font-weight:600; }


/* ---------- 8. 跑马灯 ---------- */
.marquee{
  position:relative; z-index:3; overflow:hidden;
  padding:15px 0;
  background:linear-gradient(92deg,var(--pop-orange),var(--pop-pink) 34%,var(--pop-violet) 68%,var(--pop-teal));
  border-block:3px solid var(--brown-900);
}
.marquee-track{ display:flex; width:max-content; animation:marquee 34s linear infinite; }
.marquee-group{ display:flex; align-items:center; gap:clamp(16px,2.2vw,36px); padding-right:clamp(16px,2.2vw,36px); }
.marquee-group span{ font-size:clamp(15px,1.7vw,21px); font-weight:700; color:#fff; letter-spacing:.04em; white-space:nowrap; }
.marquee-group i{ font-style:normal; color:var(--pop-yellow); font-size:13px; }
@keyframes marquee{ to{ transform:translateX(-50%); } }
.marquee:hover .marquee-track{ animation-play-state:paused; }


/* ---------- 9. 通用区块 ---------- */
/* ★ min-height 让每个区块至少占满"停靠窗口 + 上下内边距"。
   停靠点是按内容顶部对齐的，窗口会向下延伸约 (视口 - 页头 - 8)，
   若区块本身比这个窗口矮，窗口底部就会露出**下一个区块的内容**
   （客户要求"界面上不要出现其他板块的信息"）。
   + var(--sec-y) 是补上被跳过的上内边距。 */
/* ★ 锚点跳转要给固定页头留位。
   不加 scroll-margin-top 的话，点导航后区块顶部会**钻到 77px 的页头底下**，
   看起来"跳歪了、内容整体偏低"（客户反馈："点击导航栏跳转界面有问题"）。
   这里只是**无 JS 时的兜底**；有 JS 时由 main.js 第 13 节接管，
   精确落到"内容对齐"的那个停靠点上，和滚轮翻页完全一致。 */
.section, .hero{ scroll-margin-top:85px; }   /* 页头 77 + 8 呼吸 */

.section{
  position:relative; padding:var(--sec-y) 0;
  min-height:calc(100vh + var(--sec-y));
}
/* hero 单独给满屏：它的停靠点是 0，窗口就是整个视口 */
.hero{ min-height:100vh; }
/* 区块底色：浅色区加极淡的多巴胺环境色（两层大半径 radial-gradient）
   它有三个作用：① 让玻璃卡片有东西可折射，玻璃感才成立
                ② 让整页有色彩呼吸，不只是纯色底
                ③ 强度很低（10%~16% alpha、半径 700px+），不抢正文

   ★ 色温统一原则（改这块之前先读）：
     原方案每区都用"主色 + 一个冷色"（橙配紫、粉配蓝、青绿配黄），
     单看每一区都成立，但整页连起来读就是冷暖来回横跳 ——
     尤其相邻两区的交界处，一个偏冷的收尾接一个偏暖的开头，就是一道断层。
     现在把所有冷色挪到暖侧，色相环只走 340°→45° 这一段（玫红→粉→珊瑚→橙→金）：
       蓝  46,147,255  →  玫粉 255,140,178
       青绿 0,191,159  →  金橙 255,188,104
       紫  123,77,255  →  暖紫 206,120,206
     位置、半径、alpha 全部不动 —— 只换色相，
     层次感照样有（靠明暗和位置），但不再有"冷暖撞车"。 */
.section--projects{
  background:
    radial-gradient(820px 460px at 10% 4%,  rgba(255,106,43,.13), transparent 72%),
    radial-gradient(700px 400px at 92% 52%, rgba(206,120,206,.11), transparent 72%),
    radial-gradient(640px 380px at 38% 96%, rgba(255,188,104,.10), transparent 72%),
    var(--cream);
}
.section--motto{
  background:
    radial-gradient(760px 420px at 84% 12%, rgba(255,61,119,.11), transparent 72%),
    radial-gradient(700px 400px at 12% 88%, rgba(255,140,178,.10), transparent 72%),
    var(--beige-100);
}
.section--trust{
  background:
    radial-gradient(900px 500px at 82% 6%, rgba(255,188,104,.10), transparent 70%),
    var(--brown-950);
  color:var(--on-dark);
}
.section--devices{
  background:
    radial-gradient(760px 420px at 88% 8%,  rgba(255,188,104,.13), transparent 72%),
    radial-gradient(700px 400px at 14% 78%, rgba(255,207,51,.17), transparent 72%),
    var(--cream);
}
.section--environment{
  background:
    radial-gradient(780px 440px at 16% 10%, rgba(255,207,51,.17), transparent 72%),
    radial-gradient(700px 400px at 90% 82%, rgba(255,188,104,.11), transparent 72%),
    var(--beige-100);
}
.section--team{
  background:
    radial-gradient(760px 420px at 90% 14%, rgba(206,120,206,.13), transparent 72%),
    radial-gradient(680px 380px at 16% 86%, rgba(255,106,43,.12), transparent 72%),
    var(--cream);
}
.section--voice{
  background:
    radial-gradient(820px 460px at 14% 90%, rgba(255,61,119,.11), transparent 70%),
    var(--brown-800);
  color:var(--on-dark);
}
.section--faq{
  background:
    radial-gradient(720px 400px at 8% 20%,  rgba(255,61,119,.10), transparent 72%),
    radial-gradient(700px 400px at 92% 78%, rgba(255,140,178,.12), transparent 72%),
    var(--cream);
}
.section--book{
  background:
    radial-gradient(900px 520px at 90% 88%, rgba(206,120,206,.15), transparent 70%),
    var(--brown-950);
  color:var(--on-dark);
}

.sec-head{
  display:grid; grid-template-columns:1.06fr .94fr; gap:clamp(22px,4vw,64px);
  align-items:end; margin-bottom:clamp(12px,1.4vw,18px);
}
/* ⚠️ 字号与标题长度是绑死的：左栏 623px，44px 时一行只放得下 14.2 个中文字。
   客户要求标题"长一点、阳光开朗、有多巴胺气息"（15~17 字），
   继续用 44px 会全部折成两行、每节多出约 50px，把压进一屏的余量吃光。
   降到 36px → 一行 17.3 字，长标题单行放得下，且整块比原来还矮一点。
   改标题长度时**必须回来看这个字号**。 */
.sec-head h2{ font-size:clamp(22px,2.6vw,36px); letter-spacing:-.022em; margin-top:8px; }
.sec-note{ font-size:15.5px; color:var(--ink-soft); max-width:44ch; }

/* ★ 招牌项目的引导段（客户："标题以下整体下移，在标题与卡片之间补一段文案"）
   语气跟 hero 导语一致：短句、关键句加粗、不吹项目。
   加这一段会占掉这一屏的余量（原本 115px），所以下面同时把 .sig 招牌卡收紧，
   保证「一屏放下 7 条项目」不被破坏 —— 这是这一屏的硬约束，别只改一边。 */
.proj-lead{
  margin:clamp(14px,1.8vw,22px) 0 0;
  /* ⚠️ 别用 ch 限制中文行宽：ch 是数字 0 的宽度，中文字约半个字宽，
       46ch 在中文下只有约 345px，会把这段挤成 3 行、吃掉 30px 余量。
       36em ≈ 540px，正好两行。 */
  max-width:36em;
  font-size:clamp(15px,.98vw,16.5px);
  line-height:1.62;
  color:var(--ink-soft);
}
.proj-lead b{ color:var(--brown); font-weight:700; }
.sec-head--light .sec-note{ color:var(--on-dark-mute); }
.sec-head--light h2{ color:#fff; }

/* 脚注式说明（招牌项目那段合规文案）：从右栏挪到标题正下方，做成极小号。
   几点是刻意的：
     · 字号 clamp 到 10.5~11.5px，比 .filter em（11.5px）还小一档 —— 它是脚注，不是正文；
     · 颜色沿用 --ink-soft 而不是 --ink-mute：小字号下再用浅灰会掉到可读线以下；
     · max-width 收到 54ch，让它在标题栏那一列里折成两行，而不是拉成一条通栏长线；
     · 星号用 ::before 生成，不写进 HTML 文本 —— 它是版式标记，不该被读屏软件念出来。 */
.sec-note--fn{
  margin-top:clamp(9px,1vw,13px);
  max-width:70ch;
  /* 悬挂缩进：折行的第二行对齐到星号之后的文字，而不是对齐星号本身 */
  padding-left:1.35em;
  text-indent:-1.35em;
  font-size:clamp(10.5px,.78vw,11.5px);
  line-height:1.66;
  letter-spacing:.012em;
}
.sec-note--fn::before{ content:"*"; margin-right:.3em; font-weight:700; }

/* ★ 区块最底部的合规脚注（客户："写一行在底部，基本隐藏掉，字体小一点"）
   做法是**低对比 + 小字号**，而不是 display:none ——
   合规说明必须留在 DOM 里让读屏和搜索引擎读到，只是视觉上退到最后。
   一段式排版（不换行、不缩进），桌面端正好一行。 */
.sec-note--foot{
  margin-top:clamp(8px,1vw,14px);
  font-size:10.5px; line-height:1.7;
  color:var(--ink-mute);
  opacity:.5;              /* 基本隐藏：对比度压到刚好看得见 */
  padding-left:1.2em; text-indent:-1.2em;   /* 窄屏折行时第二行对齐到文字 */
  max-width:none;
}

.sec-tag{
  display:inline-flex; align-items:center; gap:8px;
  font-size:12.5px; font-weight:700; letter-spacing:.16em; text-transform:uppercase;
  padding:6px 14px; border-radius:var(--r-pill);
  background:var(--beige-200); color:var(--brown);
}
.sec-tag--pink{ background:#FFE3EC; color:#C1195A; }
.sec-tag--teal{ background:#DFF8F3; color:#00846E; }
.sec-tag--orange{ background:#FFE9DF; color:#C04412; }
.sec-tag--violet{ background:#EDE6FF; color:#5730C4; }
.sec-tag--yellow{ background:#FFF4D1; color:#8A6A0A; }
.sec-tag--lime{ background:#DFF8F3; color:#00846E; }

.disclaimer{
  margin-top:clamp(30px,3.6vw,48px); padding:18px 24px;
  border-radius:var(--r-md);
  color:var(--ink-mute); font-size:13px; line-height:1.85;
}
.disclaimer--light{ color:var(--on-dark-mute); }


/* ---------- 10. 项目筛选与卡片 ---------- */
.filters{ display:flex; flex-wrap:wrap; gap:10px; margin-bottom:28px; }
.filter{
  display:inline-flex; align-items:center; gap:7px;
  padding:10px 19px; border-radius:var(--r-pill);
  border:2px solid var(--beige-300); background:#fff;
  font-size:14px; font-weight:700; color:var(--brown-700);
  transition:transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.filter em{ font-style:normal; font-size:11.5px; padding:1px 7px; border-radius:var(--r-pill); background:var(--beige-100); color:var(--ink-mute); }
.filter:hover{ transform:translateY(-2px); border-color:var(--brown); }
.filter.is-active{ background:var(--brown); border-color:var(--brown); color:var(--beige); box-shadow:3px 3px 0 var(--beige-300); }
.filter.is-active em{ background:rgba(230,210,200,.25); color:var(--beige); }

.cards{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(16px,2vw,26px); }

.card{
  position:relative; display:flex; flex-direction:column;
  padding:clamp(15px,1.6vw,20px);
  border-radius:var(--r-lg); background:#fff;
  border:2px solid var(--beige-200);
  transition:transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
  overflow:hidden;
}
.card::before{
  content:""; position:absolute; inset:0 0 auto 0; height:6px;
  background:var(--accent); transform:scaleX(.16); transform-origin:left;
  transition:transform .4s var(--ease);
}
/* hover 上浮。transform 能直接生效，无需 !important ——
   入场动画的初始态用的是 `.js .reveal:not(.is-in)`，
   加了 is-in 之后就不再干预 transform，交给这里的 :hover。 */
.card:hover{ transform:translateY(-8px); border-color:var(--accent); box-shadow:var(--sh-lift); }
.card:hover::before{ transform:scaleX(1); }
.card.is-hidden{ display:none; }

.card-top{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
.card-idx{
  font-family:var(--font-disp); font-size:23px; line-height:1; letter-spacing:-.03em;
  color:transparent; -webkit-text-stroke:1.6px var(--accent); text-stroke:1.6px var(--accent);
}
.card-badge{
  padding:5px 12px; border-radius:var(--r-pill);
  font-size:11.5px; font-weight:700; letter-spacing:.04em;
  background:var(--accent-soft); color:var(--accent);
}
.card h3{ font-size:clamp(18px,1.55vw,22px); letter-spacing:-.02em; }
.card-sub{ margin-top:4px; font-size:12px; font-weight:700; color:var(--accent); letter-spacing:.02em; }
.card-desc{ margin-top:10px; font-size:13.5px; color:var(--ink-soft); flex:1 1 auto; }
.card-meta{ margin-top:12px; display:grid; gap:7px; padding-top:12px; border-top:1.5px dashed var(--beige-200); }
.card-meta li{ display:flex; align-items:baseline; gap:10px; font-size:13.5px; color:var(--brown-800); font-weight:600; }
.card-meta li span{
  flex:none; min-width:36px; font-size:11px; font-weight:700;
  color:var(--ink-mute); letter-spacing:.06em;
}
.card-foot{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:12px; }
.card-doc{ font-size:12px; color:var(--ink-mute); font-weight:600; }
.card-price{
  padding:5px 13px; border-radius:var(--r-pill);
  font-size:12px; font-weight:700; color:#fff; background:var(--accent);
}


/* ---------- 10b. 招牌项目：大色块主角 ----------
   设计参考（客户给的"高级的多巴胺"方法）三条：
     ① 一屏一个主角 —— 每个招牌独占一条通栏色块，不与别的项目并列争视线
     ② 一个大色块撑住画面 —— 色块本身就是主视觉；用颜色建立情绪，而不是堆元素
     ③ 其他敢删 —— 只留「项目名 + 一句说明 + 三个关键参数 + 一个 CTA」，
        原卡片里的描边编号、虚线分隔、报价药丸等全部去掉

   配色：卧蚕=橙、美唇=粉，均取自站内 --pop-* 色板。
   文字用深棕 --brown-950：在饱和橙/粉上对比度约 7–9:1，
   既满足可读性，也正好是参考图里"饱和底 + 深色字"的观感。
   渐变刻意只在**同色相内做明度变化**，避免跨色相导致深色字对比度不可预期。

   右侧 .sig-art 不依赖任何图片：超大号半透明水印字（眼 / 唇）+ 星芒徽章，
   星芒由 clip-path 生成（见 .sig-badge），比图片更轻、可任意缩放，
   也呼应参考图上那个爆炸标。 */
.sig-list{
  position:relative; display:grid;
  /* 缝从 18–28px 收到 10–16px：原来那条缝会把页面底下的 .page-ghost
     （彩虹大字的残影）露出来，夹在橙和粉之间就是一条杂乱的带子。
     收窄之后两块读起来是一组，而不是两张互不相干的卡。 */
  gap:clamp(10px,1.2vw,16px);
}

/* 「玻璃背后要有东西可以被模糊」—— 这是拟态玻璃最容易翻车的一点：
   backdrop-filter 若背后是纯色，模糊只是空转，看起来就只是"调淡的色块"。
   页面底色是纯 cream，所以这里自己铺一层彩团当素材。三个约束：

   ① 色标写成 `rgba(...) 0 44%, transparent 66%` —— 硬边圆，不是柔边渐变。
      只有轮廓足够锐利，被 .sig 的 backdrop-filter(24px) 磨开之后
      才有「清晰 → 模糊」的对比可看；全用柔边的话，模糊前后一个样。
   ② 圆的位置避开花纹区：纵向只用 17% / 37%（第一块内）与 65% / 85%（第二块内），
      横向 20%~80%。两块之间那条 20px 的 gap 因此不会露出硬边色带。
   ③ z-index:-1 落在 .wrap 的负层：压在区块底色之上、所有正文之下，
      既盖不住 .sec-head 的文字，也不遮任何内容，只做玻璃的"底料"。 */
.sig-list::before{
  content:""; position:absolute; inset:-7% -3%; z-index:-1; pointer-events:none;
  background:
    radial-gradient(28% 15% at 78% 17%, rgba(255,186,84,.60) 0 44%, transparent 66%),
    radial-gradient(32% 17% at 20% 37%, rgba(255,124,56,.54) 0 44%, transparent 66%),
    radial-gradient(28% 15% at 80% 65%, rgba(255,238,228,.62) 0 44%, transparent 66%),
    radial-gradient(32% 17% at 22% 85%, rgba(255,108,132,.52) 0 44%, transparent 66%);
  /* 只补 4px 的轻微柔化，避免硬边圆读起来像色块贴纸；
     主要那 24px 的高斯模糊必须留给 backdrop-filter 去做。 */
  filter:blur(4px);
}

.sig{
  /* z-index:1 有两件事要做：
     ① 压住页面级的 .page-ghost（巨大的"YUE MEI"底图字，fixed/z-index:0）。
        它虽是 fixed，却被 .wrap（z-index:3）盖着，所以就在玻璃**背后** ——
        玻璃化之后这不是麻烦而是福利：ghost 的巨型字会被 backdrop-filter
        虚化成一团柔和白影，是"这里真有一块玻璃"最直观的证据。
     ② 压住上面那层光斑（z-index:-1） */
  position:relative; z-index:1; overflow:hidden;
  display:grid; grid-template-columns:1.14fr .86fr;
  gap:clamp(14px,2.2vw,32px); align-items:center;
  /* ★ 尺寸比初版收了一圈：初版 min-height 40vh / padding 最大 58px /
     项目名最大 104px 会让每块几乎独占一屏，过于占版面。
     现在压到「一眼看清主角，但两块能连起来读」的量级。 */
  min-height:clamp(150px,16vh,190px);
  padding:clamp(9px,1vw,13px);
  border-radius:var(--r-xl);
  color:var(--brown-950);

  /* ---- 拟态玻璃（glassmorphism）四件套 ----
     ① 半透明彩色底（见下方 .sig--eye/.sig--lip）：alpha 收到 .62–.76，
        让背后光斑与页面透上来，颜色因此比原来更亮、更透气
     ② backdrop-filter: blur + saturate —— 高斯模糊的来源，
        顺带提饱和，把背后的光斑"炒"成更浓的色雾
     ③ 1.5px 白色描边 + 上下 inset 高光 —— 玻璃的厚度与受光边缘
     ④ 柔阴影 —— 玻璃是透明物体，旧的硬阴影（贴纸那套）会立刻拆穿它，
        所以这里换成大范围低透明度的环境投影 */
  border:1.5px solid rgba(255,255,255,.68);
  box-shadow:
    /* 1px 的极淡深色外描边：浅底上白描边会糊进背景，
       光靠白边交代不清"这有一块玻璃"。补一圈几乎看不见的暗边，边界立刻站住。 */
    0 0 0 1px rgba(30,18,13,.055),
    0 26px 54px -24px rgba(30,18,13,.44),
    0 2px 10px -4px rgba(30,18,13,.16),
    /* 玻璃"厚度"：整圈 1px 内亮边 + 顶部再压一道 2px 高光（受光面）。
       这两条比外描边更决定观感 —— 玻璃是靠边缘的折光被认出来的。 */
    inset 0 0 0 1px rgba(255,255,255,.36),
    inset 0 2px 2px -1px rgba(255,255,255,.68),
    inset 0 -26px 46px -30px rgba(255,255,255,.52);
  -webkit-backdrop-filter:blur(24px) saturate(168%);
  backdrop-filter:blur(24px) saturate(168%);
  transition:transform .34s var(--ease), box-shadow .34s var(--ease);
}
/* hover：向左上"抬起" 3px，阴影同步放大（不再是硬阴影加深 —— 玻璃抬起时
   是投影变虚变大，不是位移出第二层实心影子）。
   入场动画的初始态用 `.js .reveal:not(.is-in)` 限定，
   加 is-in 后不再干预 transform，所以这里能直接生效、无需 !important。 */
.sig:hover{
  transform:translate(-3px,-3px);
  box-shadow:
    0 34px 64px -22px rgba(30,18,13,.5),
    0 3px 12px -4px rgba(30,18,13,.18),
    inset 0 0 0 1px rgba(255,255,255,.46),
    inset 0 2px 2px -1px rgba(255,255,255,.78),
    inset 0 -26px 46px -28px rgba(255,255,255,.62);
}

/* 玻璃内侧的两团柔光 —— 让色块内部不是一块死色，而是有厚度的磨砂体。
   位置刻意压到角落（20% 12% / 86% 84%）而不是铺在中央：
   玻璃的高光只会出现在受光的那一侧，铺平就成了"整体发白"。
   这里只负责体积感，"模糊"的主叙述仍归 backdrop-filter。 */
.sig::before{
  content:""; position:absolute; inset:-24%; z-index:0; pointer-events:none;
  background:
    radial-gradient(30% 34% at 20% 12%, rgba(255,255,255,.54), transparent 60%),
    radial-gradient(24% 28% at 70% 30%, rgba(255,255,255,.20), transparent 62%),
    radial-gradient(28% 32% at 86% 84%, rgba(255,255,255,.32), transparent 62%);
  filter:blur(26px);
}
/* 玻璃表面的斜向反光带 —— glassmorphism 里最提味的一笔。
   没有它，半透明色块只会读成"调淡了的色块"而不是玻璃。
   范围收在 28% 以内：初版给到 46%，在 1240px 宽的块上等于左半张脸都发白。 */
.sig::after{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:linear-gradient(112deg,
    rgba(255,255,255,.42) 0%,
    rgba(255,255,255,.10) 14%,
    rgba(255,255,255,0) 28%);
  opacity:.88;
  transition:opacity .34s var(--ease);
}
.sig:hover::after{ opacity:1; }

/* 半透明彩色玻璃：色相完全不变，只把 alpha 收到 .60–.73。
   底下是浅色页面，所以透上来之后整体比原来更亮 ——
   深棕字的对比度反而更好，不用为此改文字颜色。
   颜色用「空格分隔的 RGB 变量」写，好处是下面 @supports 的兜底
   可以拿同一组变量拼回不透明色，不用再抄一遍十六进制。 */
.sig--eye{
  --sig-c1:255 138 61; --sig-c2:255 106 43; --sig-c3:239 80 8; --sig-tint:255 211 120;
  /* 下缘掺一点对方的粉：橙(25°) 和粉(340°) 差 45°，两块叠在一起时中间那条缝
     就是一道硬断层。让相邻的两侧各向对方靠一点，交界处的色差被拉平 —— */
  --sig-seam:linear-gradient(180deg, rgba(255,116,150,0) 56%, rgba(255,116,150,.36) 100%);
}
.sig--lip{
  --sig-c1:255 110 140; --sig-c2:255 78 112; --sig-c3:238 45 82; --sig-tint:255 158 186;
  /* —— 粉的上缘反向掺橙，两块互相靠拢，缝里就不再是"跳跃"。 */
  --sig-seam:linear-gradient(180deg, rgba(255,146,96,.32) 0%, rgba(255,146,96,0) 44%);
}
.sig--eye,
.sig--lip{
  background:
    /* 细密噪点 = 磨砂玻璃的"手感"。用内联 SVG feTurbulence 生成，
       省一次网络请求，且矢量噪点放大也不会露出像素网格。
       关键在于 blend-mode 用 soft-light：它只做微观起伏、不改颜色，
       所以远看是干净色块，近看才有一层细沙 —— 换成 normal 会立刻显脏。 */
    var(--sig-seam),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E"),
    radial-gradient(120% 100% at 92% 8%, rgba(255,255,255,.30), transparent 58%),
    radial-gradient(90% 120% at 4% 96%, rgba(var(--sig-tint) / .30), transparent 62%),
    linear-gradient(118deg,
      rgba(var(--sig-c1) / .73) 0%,
      rgba(var(--sig-c2) / .68) 56%,
      rgba(var(--sig-c3) / .60) 100%);
  background-size:auto, 160px 160px, auto, auto, auto;
  background-blend-mode:normal, soft-light, normal, normal, normal;
}

/* 不支持 backdrop-filter 的浏览器：半透明底会让深棕字的对比度掉下来，
   直接退回不透明渐变，宁可少一层质感也别让人看不清字。 */
@supports not ((-webkit-backdrop-filter:blur(4px)) or (backdrop-filter:blur(4px))){
  .sig{
    background:
      radial-gradient(120% 100% at 92% 8%, rgba(255,255,255,.34), transparent 58%),
      radial-gradient(90% 120% at 4% 96%, rgba(var(--sig-tint) / .32), transparent 62%),
      linear-gradient(118deg, rgb(var(--sig-c1)) 0%, rgb(var(--sig-c2)) 56%, rgb(var(--sig-c3)) 100%);
  }
  .sig-list::before{ display:none; }
}

.sig-body{ position:relative; z-index:2; }

/* 分类小字。原本前面挂一个「招牌 01」黑底药丸，已去掉 ——
   项目名本身就是绝对主角，再挂序号反而把它降级成清单条目。
   改用一个小圆点起头，保留"这是一条分类说明"的引导感。 */
.sig-kicker{
  display:inline-flex; align-items:center; gap:8px;
  font-size:11.5px; font-weight:700; letter-spacing:.12em;
  color:rgba(30,18,13,.76);
}
.sig-kicker::before{
  content:""; flex:none;
  width:7px; height:7px; border-radius:50%;
  background:var(--brown-950);
}

/* 主角字号：初版给到 46–104px 过大，收到 32–64px —— 仍是全节最大，
   但不再把色块顶得那么高。 */
.sig-name{
  margin:10px 0 0;
  font-family:var(--font-disp);
  font-size:clamp(23px,2.6vw,35px);
  font-weight:900;
  line-height:.98; letter-spacing:-.04em;
  color:var(--brown-950);
}
.sig-en{
  margin-top:6px;
  font-size:clamp(10.5px,.92vw,12px); font-weight:700;
  letter-spacing:.24em; text-transform:uppercase;
  color:rgba(30,18,13,.64);
}
.sig-desc{
  margin-top:7px; max-width:42ch;
  font-size:clamp(12.5px,.93vw,13.5px); line-height:1.5;
  color:rgba(30,18,13,.86);
}

/* 三个关键参数压成一行 —— 不再用原来的卡片表格 */
.sig-meta{
  display:flex; flex-wrap:wrap; gap:7px 9px;
  margin:9px 0 0; padding:0; list-style:none;
}
/* 参数小药丸：同一套玻璃语言，只是尺寸小、模糊弱
   —— 大块用 blur(24px)，这里 blur(8px) 就够，
   再大反而会把块内仅有的层次糊平，也白白多耗一层合成。 */
.sig-meta li{
  display:inline-flex; align-items:baseline; gap:6px;
  padding:4px 10px; border-radius:var(--r-pill);
  background:rgba(255,255,255,.38);
  border:1.5px solid rgba(255,255,255,.62);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.8);
  -webkit-backdrop-filter:blur(8px);
  backdrop-filter:blur(8px);
  font-size:12px; font-weight:700;
}
.sig-meta span{ font-size:10.5px; font-weight:700; letter-spacing:.1em; color:rgba(30,18,13,.6); }

.sig-actions{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:11px; }
.sig-cta{
  display:inline-flex; align-items:center; gap:8px;
  padding:7px 14px; border-radius:var(--r-pill);
  background:var(--brown-950); color:#FFF3E9;
  font-size:14px; font-weight:700;
  /* 实心深棕按钮放在玻璃上，是刻意的对比 —— 全玻璃会失去着落点。
     阴影也换成柔投影 + 顶部内高光：硬白阴影在玻璃上会显得像另一张贴纸。 */
  box-shadow:
    0 14px 26px -14px rgba(30,18,13,.6),
    inset 0 1px 0 rgba(255,255,255,.24);
  transition:transform .24s var(--ease), box-shadow .24s var(--ease);
}
.sig-cta svg{
  width:16px; height:16px; fill:none; stroke:currentColor;
  stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round;
}
.sig-cta:hover{
  transform:translate(-2px,-2px);
  box-shadow:
    0 20px 32px -14px rgba(30,18,13,.66),
    inset 0 1px 0 rgba(255,255,255,.32);
}
.sig-doc{ font-size:11.5px; font-weight:700; color:rgba(30,18,13,.68); }

/* ---- 右侧装饰：大号水印字 + 星芒徽章（纯 CSS，零图片） ----
   z-index:2 是必须的：.sig::after（反光带，z-index:0）是 .sig 的最后一个
   生成子元素，会画在 auto 层级的 .sig-art 之上，把水印字和星芒一起罩上一层白。
   提到 2 之后与 .sig-body 平级，反光带只作用在玻璃底上。 */
.sig-art{ position:relative; z-index:2; align-self:stretch; min-height:88px; }
/* ⚠ 当前**无引用**：两块招牌的装饰都换成了实物素材（见下方 .sig-photo）。
   保留这条是为了万一要回退到"半透明水印大字"方案 —— 改回去只需在 HTML 里
   把 <img class="sig-photo"> 换回 <span class="sig-glyph">眼/唇</span>。
   确定不再用的话，整条删掉即可。 */
.sig-glyph{
  position:absolute; right:-.04em; bottom:-.18em;
  font-family:var(--font-disp); font-weight:900;
  font-size:clamp(94px,9.6vw,164px); line-height:.78;
  letter-spacing:-.06em;
  color:rgba(255,255,255,.34);
  /* 2px 的轻微虚化 + 略提透明度：让这个字读起来像"被压在玻璃后面"，
     而不是浮在玻璃表面上的一行白字。真穿透得靠 backdrop-filter，
     但水印字在 .sig 内部，拿不到那层模糊，所以这里手工补一小口。 */
  filter:blur(2px);
  user-select:none;
}

/* 两块招牌的实物素材（均为透明 PNG）：
   · 眼  assets/img/eye-signature.png  390×280  → tools/make_eye_asset.py
   · 唇  assets/img/lip-signature.png  444×254  → tools/make_lip_asset.py
   三个决定：
   ① 用 drop-shadow 而不是 box-shadow —— 素材都是异形轮廓，
      方框投影会在四周露出一圈看得见的矩形边。
   ② 投影不能省：唇是红色、玻璃底是粉色，明度接近；眼是冷紫灰、底是暖橙，
      冷暖相撞但双方都偏中性。不托一下会糊在一起，读不出"这是贴上去的一件东西"。
   ③ right/bottom 都取 0：右下角是装饰区里唯一不会被右上角
      「院长推荐」标签压到的地方。垂直居中会正好撞上它。 */
.sig-photo{
  position:absolute; right:0; bottom:0; height:auto;
  filter:drop-shadow(0 10px 16px rgba(30,18,13,.26));
  pointer-events:none; user-select:none;
}
/* 两块素材比例不同（唇 1.75:1 宽扁；眼 1.51:1），套同一个 width
   会让眼睛高出近一半、吃掉装饰区。按各自比例定宽，让两块的**有效面积**
   大致相当，视觉重量才对得上。
   唇试过 288px，在一张 1240px 宽的玻璃上只占 23%，读起来像"角落里的小图标"
   而不是这块牌子的主角，所以放到 330px。 */
.sig--eye .sig-photo{
  /* 素材换了（用户给的"右眼_无底素材"）。新素材是紧裁到眼睛轮廓的，
     眼睛本体占画面约 97% 宽；旧素材四周留了橙雾、眼睛只占 77%。
     所以显示宽度从 392px 收到 318px —— 眼睛的**有效尺寸**才和上一版相同，
     不会比唇大出一圈。 */
  width:clamp(140px,14.5vw,210px);
  /* 倾角对齐：素材是画成"右端略向下"的（眼裂中轴 +2.2°），
     而唇是"右端明显向下"（唇缝 +7.8°）—— 两个量差 5.6°，并排看就是两种手势。
     这里补上差值，让眼和唇的角度读起来一致。
     量法：眼取"上下眼线之间的开口"逐列的中点做 Theil-Sen 斜率
     （不受睫毛与上眼睑高光带影响）；唇取"唇缝"（逐列最暗的饱和红像素）。
     想微调就改这个数 —— 正值 = 顺时针 = 右端向下，和唇同向。
     5.6° 是"与唇同幅"的解，但那个量看着偏平；用户要求左端再抬高一些，
     所以在同幅之上又加了 3°，现在是 8.6°（比唇略斜）。 */
  transform:rotate(8.6deg);
  /* 这是**真正抠出来的透明 PNG**：alpha 由"眼睛本体（flood fill 定出）
     + 保留 0.35 的原始粉晕"给出，颜色一律原色。
     所以这里**不要再加任何滤镜**：
       · 不加 opacity —— 粉晕本身就带渐变，再压一层会把它洗掉、脱离色块；
       · 不加 drop-shadow —— 它的边缘是渐隐的，投影会沿着渐隐带糊出一圈脏边，
         而唇那种硬轮廓才需要投影把它"托"起来。
     注意它和唇的差别：唇是白底水彩去背，这里是白底数码平涂去背 ——
     后者不能用合成模型（A=1-min/255）反解前景色，那会把粉晕反解成饱和红，
     给眼睛镶一圈红边。详见 tools/make_eye_asset.py 的文件头。 */
  filter:none;
}
.sig--lip .sig-photo{ width:clamp(134px,14vw,204px); }
/* 「院长推荐」标记：去掉底框，改用品牌 logo 本身当图形。
   这个位置前后改了三轮，原因值得记下来：
     ① 黄色星芒爆炸标 —— 星芒属于"促销"语汇（打折/限时/爆款），
        而"院长推荐"是**背书**，需要的是稳，所以换成
     ② 深棕实心胶囊 + 小 logo —— 稳了，但它本质上还是一个"标签"，
        形状和色块里的 CTA 按钮撞了，读起来像第二个按钮；
     ③ 现在这版：去掉底框，把 logo 放大当背景图形，文字叠在它上面。
        没有了"标签"的外轮廓，它才变成色块上的一个印记而不是控件。
   logo-mark.png 本身是浅米色，在橙/粉玻璃上几乎看不见，
   所以压深到接近品牌深棕（brightness .3）才读得出那个 M 形。 */
.sig-badge{
  position:absolute; right:0; top:0;
  display:grid; place-items:center;
  width:clamp(78px,7vw,98px); height:clamp(78px,7vw,98px);
  /* 正角度 = 顺时针 = 左端向上，也就是要的"左边斜向上"。
     静止姿态取摆动区间的中点 9deg，动起来两侧各 3deg。 */
  transform:rotate(9deg);
  animation:sig-badge-sway 5.4s ease-in-out infinite;
}
.sig-badge-logo{
  position:absolute; inset:0; margin:auto; z-index:0;
  /* 只给 height、宽度 auto：logo 原始比例 209×328 是竖长的，
     写死 width+height 会把它压扁。 */
  height:92%; width:auto;
  /* 文案要压在它上面，所以 logo 退成"底纹"：透明度压到 .28。
     试过 .46，字与 M 的竖画在同一色阶上，笔画直接糊在一起。 */
  opacity:.28;
  filter:brightness(.34) saturate(1.2);
  pointer-events:none;
}
/* 同一个深棕 logo 压在粉底上会发紫 —— 不是它变了，是"同时对比"：
   低饱和的棕挨着高饱和的粉，眼睛会自动往互补方向补色。
   粉块这侧把 logo 往红偏 14°，抵消掉这层错觉，两块上的 logo 才读作同一个色。 */
.sig--lip .sig-badge-logo{ filter:brightness(.34) saturate(1.35) hue-rotate(-14deg); }
.sig-badge b{
  position:relative; z-index:1;
  /* 往下压一点：logo 顶部那枚花蕾把它自己的几何中心抬高了，
     grid 居中会让字落在 M 的上半截。12% ≈ 一字高，正好落到两竖中间。 */
  transform:translateY(12%);
  font-size:clamp(11px,.92vw,12.5px); font-weight:900;
  letter-spacing:.06em; line-height:1.1; white-space:nowrap;
  color:var(--brown-950);
  /* 字压在 logo 线条上，靠一圈浅色光晕把笔画托出来。
     用 text-shadow 而不是 -webkit-text-stroke：后者会加粗字形、
     让 12px 的字在小尺寸下反而糊掉。 */
  text-shadow:
    0 0 3px rgba(255,255,255,.82),
    0 1px 1px rgba(255,255,255,.55);
}
/* 轻微的左右摆动。3deg 是上限 —— 再大就从"呼吸"变成"摇晃"了；
   右上角这个位置本来就该安静，摆动只是让它别像贴死的图。 */
@keyframes sig-badge-sway{
  0%, 100%{ transform:rotate(6deg); }
  50%     { transform:rotate(12deg); }
}
@media (prefers-reduced-motion:reduce){
  .sig-badge{ animation:none; }
}

/* ---------- 10c. 其余项目：入口在标题右侧，内容默认收起 ----------
   入口是一张小卡（.op-entry），塞进 .sec-head 原本空着的右栏 ——
   用户圈了标题右上的空白区，要求把"其余项目"藏进去。
   展开后的内容仍在两张招牌卡下方（.other-panel，原位置），
   由 button 的 aria-expanded 驱动开关（main.js 6b 节）。
   原来"横贯整行的 <details> 折叠条"退役：summary 没法脱离
   details 放进标题栏，所以换成 JS 开关，键盘可达性由 button 自带。 */
/* 标题两栏各管各的：右栏顶对齐，入口小卡和 tag 大致同一水平线 */
.section--projects .sec-head{ grid-template-columns:1fr; align-items:start; }
.sec-aside{ display:flex; justify-content:flex-start; margin-top:clamp(16px,2vw,26px); }
.op-entry{
  display:flex; align-items:center; gap:16px;
  width:100%; max-width:100%;
  padding:clamp(16px,1.8vw,22px) clamp(18px,2vw,26px);
  text-align:left; cursor:pointer;
  /* 与下面 .other-panel 同一套米白容器，视觉上是一家人 */
  background:rgba(255,249,243,.68);
  border:2px solid rgba(240,222,200,.9);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-hard-sm);
  transition:transform .24s var(--ease), box-shadow .24s var(--ease), background .24s var(--ease);
}
.op-entry:hover{
  transform:translate(-3px,-3px);
  background:rgba(255,255,255,.92);
  box-shadow:var(--sh-hard);
}
.op-entry:focus-visible{ outline:3px solid var(--pop-blue); outline-offset:3px; }
.op-lead{ display:grid; gap:3px; flex:1 1 auto; min-width:0; }
.op-lead b{ font-size:clamp(16px,1.4vw,19px); letter-spacing:-.015em; color:var(--brown); }
.op-lead em{ font-style:normal; font-size:12px; font-weight:600; color:var(--ink-mute); }
.op-side{ display:flex; align-items:center; gap:12px; flex:none; margin-left:auto; }
.op-count{
  font-family:var(--font-disp); font-size:26px; line-height:1;
  color:transparent;
  -webkit-text-stroke:1.6px var(--beige-300); text-stroke:1.6px var(--beige-300);
}
.op-hint{ font-size:12px; font-weight:700; letter-spacing:.08em; color:var(--brown); }
.op-hint-close{ display:none; }
.op-entry[aria-expanded="true"] .op-hint-open{ display:none; }
.op-entry[aria-expanded="true"] .op-hint-close{ display:inline; }
.op-arrow{
  width:11px; height:11px; flex:none;
  border-right:2.6px solid var(--brown);
  border-bottom:2.6px solid var(--brown);
  transition:transform .32s var(--ease);
}
/* 默认朝下（展开方向）；打开后转 180° 朝上 */
.op-arrow{ transform:rotate(45deg); }
.op-entry[aria-expanded="true"] .op-arrow{ transform:rotate(-135deg); }

.other-panel{
  margin-top:clamp(12px,1.4vw,18px);
  border-radius:var(--r-lg);
  /* 原来用纯白 .62，压在粉色块下面就是一道硬反差（彩色→白）。
     换成带暖调的米白，同时把描边也调暖，和上面两块接上气。 */
  background:rgba(255,249,243,.68);
  border:2px solid rgba(240,222,200,.9);
  overflow:hidden;
}
.other-panel[hidden]{ display:none; }

.op-body{ padding:clamp(20px,2.2vw,28px) clamp(20px,2.4vw,30px) clamp(22px,2.6vw,32px); }

/* ---------- 10c. 项目区左右分栏（2026/09）----------
   用户画框指定：左列放两块主打项目，右列放其余项目列表。
   原来两块招牌上下堆叠、其余项目是下方一个 3 列大卡面板，上下加起来近三屏；
   分栏后标题区不动，下面切成左 1.55fr / 右 1fr 两列，一屏能看到
   两块招牌 + 全部 7 个其余项目。

   ⚠️ 右列必须把 `.cards` 从 repeat(3,1fr) 改成单列：
      右列只有约 476px，三列的话每张卡只剩约 150px，文字会挤成竖排。 */
.proj-split{
  display:grid;
  grid-template-columns:1.5fr 1fr;
  gap:clamp(16px,2vw,26px);
  /* ★ align-items:start（不是 stretch）+ 只给右列 align-self:stretch。
     两列都用 stretch 会**循环膨胀**：右列被拉高 → 内部 grid-auto-rows:1fr
     把 7 行撑大 → 右列的自然高也跟着变大 → 行高上限被抬高（实测 758 → 795）。
     改成 start 后，行高由上方的 max-content 定死（= 左列的自然高），
     再由右列自己的 align-self:stretch 精确对齐，不会再涨。 */
  align-items:stretch;
  margin-top:clamp(10px,1.2vw,16px);
}
/* ★ grid-template-rows 用 auto 而不是 1fr：
   1fr 会把这一行**强制成容器高度**，一旦右列内容需要更多高度，
   多出来的部分就被 .other-panel 的 overflow:hidden 剪掉 ——
   实测客户机器上第 7 条「燕窝水光」整条消失。
   改 auto 后内容高就撑高，配合上面 align-items:stretch 两列仍然等高：
   谁高谁决定行高，另一列被拉伸补齐。 */
.proj-others{ display:grid; grid-template-rows:auto; gap:0; }
.proj-others .sec-aside{ margin-top:0; }
.proj-others .other-panel{ margin-top:0; display:grid; }
.proj-others .op-body{ padding:10px; display:grid; grid-template-rows:auto; }

/* 右列：单列紧凑列表。
   每行 = 项目名 + 分类徽章（绝对定位到右上角）+ 副标 + 一行描述 + 一行要点。
   描述用 line-clamp:1 截断 —— 7 条描述长短不一，不截断的话行高参差、总高压不住。 */
/* ★ 每行重新排布：把"小字挤三行"改成"大字三行"。
   原先把字号压到 h3 15px / 副标 11px / 要点 10px 才塞得下 7 行，
   但中文在 10~11px 下笔画会糊在一起，100% 缩放时根本读不清。
   现在用 flex + order 把 DOM 顺序重排成：
       ① 项目名(17px) + 分类徽章（绝对定位在右上）
       ② 副标 与 要点 并排一行（12/11.5px）
       ③ 描述一行（12px，超出省略）
   DOM 里描述在要点之前，靠 order 把它挪到最后。

   ⚠️ align-content:start 不能省：flex 容器的默认 align-content 是 stretch，

      会把描述那一行拉到剩余高度（实测盒子被撑到 85px），

      每条卡因此从 79px 虚高到 105px，7 条就多出 180px。 */
/* ★ 行高用 auto，**不能用 grid-auto-rows:1fr**：
   在高度不确定的网格里，`1fr` 会把每一行都撑到"最高那行"的高度
   （实测 103px），7 行从 605 虚高到 795。
   改成 auto 保持自然高度，再用 align-content:space-between 把多出来的
   空间分到行间距上，右列因此能撑满到与左列等高而不变形。 */
.proj-others .cards{ grid-template-columns:1fr; gap:6px; grid-auto-rows:auto; align-content:stretch; }
.proj-others .card{
  /* ★ flex-direction:row 必须写 —— 基础 .card 是 column，不重置的话主轴仍是垂直的，
     下面子项的 flex:0 0 100% 会变成'高度 100%'，把 h3 和描述各撑到 85px、
     每条卡虚高到 105px（踩过，查了很久）。 */
  display:flex; flex-direction:row; flex-wrap:wrap;
  align-items:baseline; align-content:center; gap:2px 9px;
  position:relative; padding:8px 13px; border-width:1.5px;
}
.proj-others .card-top{ position:absolute; right:11px; top:10px; margin:0; }
.proj-others .card-idx{ display:none; }
.proj-others .card-badge{ padding:3px 9px; font-size:11px; }
.proj-others .card h3{ order:1; flex:0 0 100%; font-size:18px; padding-right:7em; }
/* 副标 / 要点都不允许折行 —— 一折行那一行就比别人高 20px，
   7 行里出现一两个"高个子"会让整列高度不可预测（实测「紧致收紧热拉提」就是 105px、
   其他都是 82px），也是第 7 条被挤出可见区的直接原因。
   放不下就省略，保证每行等高。 */
/* ★ 副标「不压缩」、要点「可压缩」——两者必须永远共处一行。
   只给要点内部设 nowrap 是没用的：折行发生在**卡片这一层**
   （卡片是 flex-wrap:wrap），副标+要点一超宽，整个要点就被推到下一行，
   那一行就比别人高 23px。实测「紧致收紧热拉提」副标 164px + 要点 289px
   + 间距 10px = 463px，超出可用的 460px 3 个像素就折行了。
   现在给副标 flex:0 0 auto（不许压），要点 flex:1 1 auto + min-width:0
   （可以让位并在极窄时裁剪），两者就锁死在同一行。 */
.proj-others .card-sub{ order:2; flex:0 0 auto; margin:0; font-size:12.5px; white-space:nowrap; }
.proj-others .card-meta{
  /* ★ flex-basis 必须是 0（flex:1 1 0），不能是 auto。
     flex-wrap 的**折行是按"基准尺寸"算的**，收缩只在折行之后才生效 ——
     用 auto 时副标 164px + 要点 277px + 间距 9px = 450px > 可用 436px，
     要点在来得及收缩之前就被推到下一行，那一行就高 23px。
     基准设 0 之后折行看到的是 164+0+9 = 173px，稳稳放得下，
     再由 flex-grow 把剩余宽度分给要点。 */
  order:3; flex:1 1 0; min-width:0; margin:0; padding:0; gap:3px 6px;
  display:flex; flex-wrap:nowrap; overflow:hidden; border:none;
}
/* ★ 每一项都必须 nowrap —— 折行发生在 li **内部**，而不是卡片层。
   客户机器上「授权 飞顿原厂」自己折了行，那一行比别人高 20px，
   7 行合计超出可用高度，第 7 条「燕窝水光」就被挤到屏幕外
   （客户反馈"还是少了一个项目"就是这个原因）。
   nowrap 后每行高度绝对一致；宽度不够时由 .card-meta 的 overflow:hidden 裁尾。 */
.proj-others .card-meta li{ font-size:10.5px; white-space:nowrap; }
.proj-others .card-meta li span{ min-width:auto; font-size:10.5px; }
/* ★ 列表里**不显示项目描述**（客户反馈"不用写这么详细的介绍，文字太密集"）。
   原来一行描述 = 每行多 20px，7 行加 140px，整列又挤又长。
   现在每行只留：项目名 + 分类徽章 + 副标 + 要点（部位/材料/恢复）。
   想恢复的话把下面这行改成 display:block 即可（整列会高出约 140px）。 */
.proj-others .card-desc{ display:none; }
/* 底部那行（主诊 / 面诊报价）在列表里省掉 —— 主诊姓名两块招牌卡上已有 */
.proj-others .card-foot{ display:none; }

/* 窄屏退回单列（左列在上、右列在下） */
@media (max-width:1400px){ .cred-list{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:1100px){
  .proj-split{ grid-template-columns:1fr; }
}

/* ---------- 11. 五好一公道 ---------- */
/* ★ 这一屏要"填满"（客户："调整页面，覆盖整个页面内容"）。
   原来 grid 只有 440px，内容盒 828px → 空了 388px（47%）。
   做法分三步，缺一不可：
     a) .section--motto 改成 grid + 1fr 行，让 .wrap 撑满内容盒；
     b) .motto-grid 两列都 stretch，左栏用 flex 把 CTA 压到底；
     c) .motto-list 的 3 行拉伸（grid-auto-rows:1fr），卡片内部内容垂直居中。
   注意：这里**不用 align-content:space-between** —— 内容盒有 828px，
   靠拉开行距填满会让行间空隙达到 165px，非常难看。让卡片本身长高才对。 */
/* ⚠️【已失效】下面的 .section--motto / .motto-* 规则对应的区块**已被客户删除**，6 条承诺已挪到预约区的 .creed。这些规则保留仅为留痕，不再生效。 */
/* ★ 这一屏改成"上半标题 / 下半六条"（客户要求把 6 张卡整体下移）。
   上半 .motto-head 自身是两列：左标题、右描述+CTA（底部对齐，形成基线感）；
   下半 .motto-list 通栏 3 列 × 2 行，6 张卡平分整行宽度。
   外层 .motto-grid 用 align-content:space-between 把上下两块推到内容盒两端。 */
.section--motto{ display:grid; grid-template-rows:1fr; }
/* ★ 两行用 auto 1fr：上半按内容高、下半吃掉剩余高度。
   ⚠️ 千万别用 align-content:space-between —— 富余的 294px 会全部塞进
      上下两块之间的间距里，标题和卡片之间空出一大块，非常难看。
      让 .motto-list 的卡片长高（grid-auto-rows:1fr）才是正确做法。 */
.motto-grid{
  display:grid; grid-template-columns:1fr; grid-template-rows:auto 1fr;
  gap:clamp(26px,3.6vw,56px);
}
.motto-head{
  display:grid; grid-template-columns:1.06fr .94fr;
  gap:clamp(24px,4vw,64px); align-items:end;
}
.motto-head-side{ display:flex; flex-direction:column; align-items:flex-start; }
/* ⚠️ 这里**不要**用 margin-top:auto 把 CTA 压到最底：
   左栏内容只有 322px，压到底会让"描述"和"按钮"之间拉开约 459px 的空档。
   保持紧跟描述（顶部对齐），和右侧第一行卡片同一起跑线；
   左下角的留白正好由 .page-ghost 的 "YUE MEI" 水印填掉，不显得空。 */
.motto-head .btn{ align-self:flex-start; }
.motto-list{ align-content:stretch; grid-auto-rows:1fr; }
.motto-list li{ display:flex; flex-direction:column; justify-content:center; }
.motto-list em{ display:block; margin-top:9px; font-style:normal; font-size:12.5px; color:var(--ink-mute); }
/* ★ 这一块是「口号」区，标题**故意比其它区块大**（74px vs 44px）——
   客户明确说过"不是对齐大小，是对齐**风格**"（长句子 + 高亮词）。
   所以这里保留原来的大字号规格，不要往 .sec-head h2 上靠。
   要改风格请改 index.html 里的文案结构（标签 + 长句标题 + hl 高亮），别动这里。 */
.motto-title{ font-size:clamp(38px,6vw,74px); letter-spacing:-.035em; margin:14px 0 0; color:var(--brown); }
.motto-head p{ margin-top:16px; color:var(--ink-soft); max-width:30ch; }
.motto-head .btn{ margin-top:26px; }
.motto-list{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(12px,1.5vw,18px); }
.motto-list li{
    position:relative; padding:22px 22px 22px 26px;
  border-radius:var(--r-md); background:#fff;
  border:2px solid var(--beige-200); border-left:7px solid var(--accent);
  transition:transform .28s var(--ease), box-shadow .28s var(--ease);
}
.motto-list li:hover{ transform:translate(-3px,-3px); box-shadow:var(--sh-hard-sm); }
.motto-list b{ display:block; font-size:19px; color:var(--brown); letter-spacing:-.01em; }
.motto-list span{ display:block; margin-top:7px; font-size:13.5px; color:var(--ink-soft); line-height:1.7; }


/* ---------- 12. 资质 ---------- */
/* ★ 资质区要塞进一屏（客户："将内容放在一个页面展示范围里"）。
   原来是 2 列 × 5 行，9 张卡就占 878px。改 3 列 × 3 行 + 收紧内距后约 370px。
   ⚠️ 卡内是三行文本（编号 / 标题 / 说明 / 授权方），字号和内距必须一起收，
      只改列数的话每行变窄、文本折行更多，反而更高。 */
.cred-list{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(8px,1vw,12px); }
.cred{
  display:flex; gap:10px; padding:clamp(10px,1.1vw,13px);
  border-radius:var(--r-md);
  background:rgba(230,210,200,.06);
  border:1.5px solid var(--line-dark);
  transition:background .28s var(--ease), transform .28s var(--ease), border-color .28s var(--ease);
}
.cred:hover{ background:rgba(230,210,200,.12); border-color:rgba(230,210,200,.4); transform:translateY(-4px); }
.cred-no{
  flex:none; width:32px; height:32px; border-radius:10px;
  display:grid; place-items:center;
  font-family:var(--font-disp); font-size:13px; letter-spacing:-.02em;
  background:var(--beige); color:var(--brown-900);
  transform:rotate(-4deg);
}
.cred h3{ font-size:14.5px; color:#fff; letter-spacing:-.01em; line-height:1.28; }
.cred p{ margin-top:5px; font-size:11.5px; color:var(--on-dark-mute); line-height:1.45; }
.cred-org{
  display:inline-block; margin-top:6px; padding:3px 8px; border-radius:var(--r-pill);
  font-size:10.5px; font-weight:700; letter-spacing:.03em;
  background:rgba(255,188,104,.16); color:#7FE6D2;
}

/* ★ 核验步骤与资质照片改成**并排**（原来上下叠：步骤 4 列 156px + 照片 467px = 735px）。
   并排后：左边步骤 2×2、右边照片 2:1，整块约 230px。 */
/* ⚠️ gap 是"行+列"一起设的：标题与下面步骤之间因此吃到了 36px 的**行间距**，
   再叠加标题自己的 margin-bottom 18px = 54px，
   而标题上方只有 16px —— 实测上下差 51px（客户："往下一点，上下间距一致"）。
   网格里外边距**不会折叠**，所以要把行、列间距拆开单独给。 */
.verify{
  display:grid; grid-template-columns:1.4fr 1fr;
  column-gap:clamp(20px,2.4vw,36px);
  row-gap:clamp(10px,1.2vw,16px);
  align-items:center;
  margin-top:clamp(24px,2.8vw,36px);
}
/* ⚠️ 标题必须横跨两列（grid-column:1/-1）：
   不然它会占掉第一格，把「步骤」推到第二格、「照片」挤到第二行，
   照片就落到 1.4fr 那一列（实测 696px 宽），整块反而 618px 高。 */
/* ★ 核验小标题：放大 + 居中（客户："比较奇怪，放大居中放置好吗"）。
   理由：它下面是一个对称块（左 2×2 步骤 + 右照片），
   贴左的小字标题和这个对称块不搭；居中后正好把
   「9 格证件卡」和「四步核验」两段内容在视觉上分开。
   下面那道渐变短线沿用全站多巴胺渐变，起"分段"作用。 */
.verify-title{
  grid-column:1 / -1; text-align:center;
  font-size:clamp(19px,2.1vw,25px); color:#fff;
  margin:0 0 clamp(4px,.6vw,8px); letter-spacing:-.01em;
}
.verify-title::after{
  content:""; display:block; width:62px; height:3px; margin:7px auto 0;
  border-radius:3px;
  background:linear-gradient(90deg,var(--pop-orange),var(--pop-pink),var(--pop-violet));
}
.verify-steps{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(8px,1vw,12px); }
.verify-steps li{
  padding:9px 11px; border-radius:var(--r-md);
  background:rgba(255,255,255,.05); border:1.5px solid var(--line-dark);
  transition:transform .28s var(--ease), background .28s var(--ease);
}
.verify-steps li:hover{ transform:translateY(-5px); background:rgba(255,255,255,.09); }
.verify-steps b{ display:block; font-family:var(--font-disp); font-size:17px; line-height:1; color:var(--accent); }
.verify-steps h4{ margin-top:6px; font-size:13px; color:#fff; }
.verify-steps p{ margin-top:3px; font-size:11px; color:var(--on-dark-mute); line-height:1.48; }

.verify-photo{
  position:relative; margin:0;
  border-radius:var(--r-lg); overflow:hidden;
  border:3px solid var(--beige-300);
}
.verify-photo .ph{ width:100%; aspect-ratio:16/8; }
.verify-photo figcaption{
  position:absolute; left:16px; bottom:16px;
  padding:7px 14px; border-radius:var(--r-pill);
  background:rgba(30,18,13,.82); color:var(--beige);
  font-size:12px; font-weight:700;
  backdrop-filter:blur(6px);
}


/* ---------- 13. 设备 ---------- */
/* ★ 设备实拍 + 核验说明（卡片下方的一行）
   方形设备照片固定在左侧（clamp 140~175px），右侧是说明文字。
   整行高度 = max(照片, 文字) ≈ 175px，正好填掉原来底部的 258px 空白，
   又不会把这一屏顶成两屏（实测总内容 613 → 约 800px，窗口 871）。 */
.dev-foot{
  display:grid; grid-template-columns:auto 1fr;
  gap:clamp(18px,2.2vw,34px); align-items:center;
  margin-top:clamp(14px,1.7vw,22px);
}
.dev-shot{
  margin:0; flex:none; width:clamp(132px,13vw,164px);
  border-radius:var(--r-lg); overflow:hidden;
  border:3px solid var(--beige-300); box-shadow:var(--sh-soft);
}
.dev-shot img{ display:block; width:100%; aspect-ratio:1/1; object-fit:cover; }
.dev-note h3{ font-size:clamp(16.5px,1.75vw,20px); color:var(--brown); letter-spacing:-.01em; }
.dev-note p{ margin-top:9px; font-size:13.5px; color:var(--ink-soft); line-height:1.75; max-width:66ch; }
.dev-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(14px,1.7vw,22px); }
.dev{
  position:relative; display:flex; flex-direction:column; gap:9px;
  padding:clamp(20px,2.1vw,26px);
  border-radius:var(--r-md); background:#fff;
  border:2px solid var(--beige-200);
  transition:transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.dev:hover{ transform:translateY(-7px); border-color:var(--accent); box-shadow:6px 6px 0 var(--beige-200); }
.dev-tag{
  align-self:flex-start; padding:4px 12px; border-radius:var(--r-pill);
  font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  background:var(--accent); color:#fff;
}
.dev h3{ font-size:18px; letter-spacing:-.015em; color:var(--brown); }
.dev p{ font-size:13.5px; color:var(--ink-soft); flex:1 1 auto; }
.dev-auth{
  margin-top:6px; padding-top:13px; border-top:1.5px dashed var(--beige-200);
  font-size:12px; font-weight:700; color:var(--accent);
}


/* ---------- 14. 环境 ---------- */
/* ★ 图库从 3 列 × 3 行压到 4 列 × 2 行（客户："这里太大了"）。
   原来：宽图 16/9 → 813×457，普通图 4/3 → 393×295，整块 1108px
        （占环境区 1667px 的 64%）。
   现在：4 列，宽图改 3/1（= 604÷201），普通图改 3/2。
        关键是让宽图的高度**正好等于普通格的高度**，整行才不会有一格被拉高。
   实测 1108 → 414px。 */
/* ★★ 图库改成「堆叠」（客户："图片以堆叠的形式呈现吧"）★★
   从 4 列网格改成**一摞水平铺开的照片**：每张轻微旋转 + 上下微错落，
   悬停时抬起、转正、放大 —— 和首屏"便签墙"同一套语言，
   既比网格矮，也比网格更不像模板。
   铺开位置用 calc 算：第 i 张的 left = i × (容器宽 − 单张宽) ÷ 6。
   高度只由单张高度 + 旋转外扩决定，所以整块很矮。 */
.gal{
  /* 卡片加宽 → 同样的整行宽度下重叠更多，才像"一摞"（原来是 236px，只叠 82px） */
  --w:clamp(200px,17.5vw,300px);
  position:relative; display:block;
  height:clamp(202px,18.4vw,248px);
  /* 悬停气泡要从卡片上方浮出（约 45px），上边距必须留够，否则会压到上面的说明段 */
  margin-top:clamp(44px,5vw,62px);
}
/* ⚠️ 必须用 .gal .gal-item 提权：下面还留着一条旧的 `.gal-item{position:relative}`，
   同权重时**后写的赢**，会把这里的 absolute 顶掉 ——
   结果就是照片不叠，而是顺着文档流斜着一路往下淌（每张正好低一张卡高）。
   这个 bug 实际发生过。 */
.gal .gal-item{
  position:absolute; top:50%;
  width:var(--w); aspect-ratio:3/2; margin:0;
  left:calc(var(--i) * (100% - var(--w)) / 6);
  z-index:calc(var(--i) + 1);
  transform-origin:50% 50%;
  transform:translateX(var(--shift, 0px)) translateY(calc(-50% + var(--y, 0px))) rotate(calc((var(--i) - 3) * 2.1deg));
  border-radius:var(--r-md);
  /* ⚠️ 必须是 visible！悬停气泡定位在卡片**上方之外**（bottom:calc(100% + 13px)），
     卡片一旦 overflow:hidden 就会把整块气泡裁掉 —— 气泡 opacity 变成 1 也照样看不见。
     （客户反馈"现在的看不到标签"，就是这个原因。）
     照片的圆角改由 <img> 自身承担，视觉完全一样。 */
  overflow:visible;
  border:5px solid #fff;
  box-shadow:0 18px 34px -18px rgba(51,29,21,.5);
  transition:transform .28s var(--ease), box-shadow .28s var(--ease);
}
/* 悬停：抬起 + 转正 + 略微放大，并把层级顶到最上 */
.gal .gal-item:hover{
  transform:translateY(calc(-50% - 18px)) rotate(0deg) scale(1.07);
  z-index:20;
  box-shadow:0 30px 50px -20px rgba(51,29,21,.58);
}
/* 照片填满整张卡（覆盖原来的固定比例） */
.gal .gal-item img{ width:100%; height:100%; aspect-ratio:auto; object-fit:cover; border-radius:calc(var(--r-md) - 5px); }
/* 【已失效】被上面的 .gal .gal-item 覆盖；窄屏回退时靠它兜底 */
.gal-item{ position:relative; border-radius:var(--r-lg); overflow:hidden; border:3px solid #fff; box-shadow:var(--sh-soft); }
.gal-item--wide{ grid-column:span 2; grid-row:span 1; }
.gal-item .ph{ width:100%; height:100%; aspect-ratio:20/9; }
.gal-item--wide .ph{ aspect-ratio:32/7; }
/* ★ 图库悬停 = 首屏便签那套（客户："是像首页一样的图片一样，光标选中有特效"）。
   首屏是：抬起 + 放大 + **上方浮出毛玻璃说明气泡**（.note-tip）。
   这里把图注从"卡片内的深色胶囊"改成同样的**悬浮气泡**，
   两边共用一套视觉，悬停时被压住的那张也能看清说明。 */
.gal-item figcaption{
  position:absolute; left:50%; bottom:calc(100% + 13px); z-index:3;
  padding:7px 14px; border-radius:11px;
  background:rgba(255,253,245,.86);
  -webkit-backdrop-filter:blur(7px) saturate(160%);
          backdrop-filter:blur(7px) saturate(160%);
  border:1.5px solid rgba(112,71,57,.20);
  box-shadow:0 12px 26px -16px rgba(70,41,30,.55);
  font-size:12.5px; font-weight:700; letter-spacing:.06em;
  color:var(--brown); white-space:nowrap;
  opacity:0; pointer-events:none;
  transform:translateX(-50%) translateY(7px);
  transition:opacity .24s var(--ease), transform .24s var(--ease);
}
.gal .gal-item figcaption::after{
  content:""; position:absolute; left:50%; top:100%;
  width:11px; height:11px; margin:-6px 0 0 -5.5px;
  transform:rotate(45deg);
  background:rgba(255,253,245,.86);
  -webkit-backdrop-filter:blur(7px) saturate(160%);
          backdrop-filter:blur(7px) saturate(160%);
  border-right:1.5px solid rgba(112,71,57,.20);
  border-bottom:1.5px solid rgba(112,71,57,.20);
}
.gal .gal-item:hover figcaption{ opacity:1; transform:translateX(-50%) translateY(0); }
/* ★★ 悬停时其余照片「躲开」★★（客户："采取和首页一样的方法，让未选中的照片躲开选中的照片"）
   首页的做法是 .hero-visual:has(.note--main:hover) .sticker--3{ --dx:-8px; --dy:34px }：
   选中一个，其余的元素让位。
   这里通用化：被选中那张**左边的往左躲、右边的往右躲**，位移量按大致距离给；
   并且其余照片淡到 .55（首页用的是更狠的 .3，这里保守一些，别影响浏览）。
   全程只改 transform / opacity（ui-ux-pro-max §7 transform-performance）。 */
.gal:has(.gal-item:nth-child(1):hover) .gal-item:nth-child(n+2){ --shift:30px; }
.gal:has(.gal-item:nth-child(2):hover) .gal-item:nth-child(1){ --shift:-26px; }
.gal:has(.gal-item:nth-child(2):hover) .gal-item:nth-child(n+3){ --shift:26px; }
.gal:has(.gal-item:nth-child(3):hover) .gal-item:nth-child(-n+2){ --shift:-24px; }
.gal:has(.gal-item:nth-child(3):hover) .gal-item:nth-child(n+4){ --shift:24px; }
.gal:has(.gal-item:nth-child(4):hover) .gal-item:nth-child(-n+3){ --shift:-22px; }
.gal:has(.gal-item:nth-child(4):hover) .gal-item:nth-child(n+5){ --shift:22px; }
.gal:has(.gal-item:nth-child(5):hover) .gal-item:nth-child(-n+4){ --shift:-24px; }
.gal:has(.gal-item:nth-child(5):hover) .gal-item:nth-child(n+6){ --shift:24px; }
.gal:has(.gal-item:nth-child(6):hover) .gal-item:nth-child(-n+5){ --shift:-26px; }
.gal:has(.gal-item:nth-child(6):hover) .gal-item:nth-child(7){ --shift:26px; }
.gal:has(.gal-item:nth-child(7):hover) .gal-item:nth-child(-n+6){ --shift:-30px; }
/* 未选中的淡下去（一条通则即可，不必逐个写） */
.gal .gal-item{ transition:transform .28s var(--ease), box-shadow .28s var(--ease), opacity .28s var(--ease); }
.gal:has(.gal-item:hover) .gal-item:not(:hover){ opacity:.55; }

.perks{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(12px,1.5vw,18px); margin-top:clamp(34px,4vw,54px); }
.perk{
  display:grid; grid-template-columns:auto 1fr; grid-template-rows:auto auto;
  column-gap:15px; align-items:center;
  padding:11px 14px; border-radius:var(--r-md);
  background:#fff; border:2px solid var(--beige-200);
  transition:transform .28s var(--ease), box-shadow .28s var(--ease);
}
.perk:hover{ transform:translateY(-4px); box-shadow:5px 5px 0 var(--beige-200); }
/* ★ 图标：从"字符当图标"改成内联 SVG（ui-ux-pro-max 技能包 Pre-Delivery Checklist
   明令 "No emojis as icons (use SVG: Heroicons/Lucide)"，并给出
   "Phosphor (primary) + Heroicons (fallback)" 的图标库建议）。
   官网是零依赖站点（无 CDN、无 npm），所以不引库，手写同族单色描边路径，
   与页面里已有的箭头 / 电话 / 日历图标保持同一视觉族。
   装饰性图标已带 aria-hidden="true"（技能包 icon-context-accessibility 规则）。 */
.perk-ico svg,
.team-avatar svg{
  display:block; width:21px; height:21px;
  fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round;
}
/* ⚠️ 必须补这一条：下面还有一条既有的 `.perk span{ color:var(--ink-mute) }`，
   而 .perk-ico 本身就是个 <span> —— 权重 (0,1,1) 会压过 .perk-ico 的 (0,1,0)，
   于是图标的 currentColor 变成棕灰 rgb(142,117,107)，描在彩色方块上几乎看不见。
   用两个类 (0,2,0) 提权，把图标本身的白色拿回来。 */
.perk .perk-ico{ color:#fff; }
.perk-ico{
  grid-row:span 2; width:40px; height:40px; border-radius:13px;
  display:grid; place-items:center; font-size:17px; font-weight:700;
  background:var(--accent); color:#fff; transform:rotate(-5deg);
}
.perk b{ font-size:14px; color:var(--brown); }
.perk span{ font-size:12px; color:var(--ink-mute); }

.flow{ margin-top:clamp(38px,4.4vw,64px); }
.flow h3{ font-size:clamp(20px,2.2vw,27px); color:var(--brown); margin-bottom:24px; }
.flow-list{ display:grid; grid-template-columns:repeat(6,1fr); gap:12px; }
.flow-list li{
  position:relative; padding:10px 12px; border-radius:var(--r-md); line-height:1.3;
  background:#fff; border:2px solid var(--beige-200); text-align:center;
}
.flow-list li:not(:last-child)::after{
  content:""; position:absolute; right:-9px; top:50%; width:14px; height:2px;
  background:var(--beige-300); transform:translateY(-50%);
}
.flow-list b{ display:block; font-size:14.5px; color:var(--brown); }
.flow-list span{ display:block; margin-top:6px; font-size:12px; color:var(--ink-mute); line-height:1.6; }


/* ---------- 15. 团队 ---------- */
.team-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(14px,1.7vw,22px); }
.team{
  padding:clamp(28px,2.9vw,38px); border-radius:var(--r-lg);
  background:#fff; border:2px solid var(--beige-200); text-align:center;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.team:hover{ transform:translateY(-7px); border-color:var(--accent); box-shadow:6px 6px 0 var(--beige-200); }
.team-avatar{
  display:grid; place-items:center; width:84px; height:84px; margin:0 auto 22px;
  border-radius:24px; font-size:26px; font-weight:700;
  background:var(--accent); color:#fff; transform:rotate(-6deg);
  box-shadow:4px 4px 0 var(--beige-200);
}
.team h3{ font-size:19.5px; color:var(--brown); }
.team p{ margin-top:13px; font-size:14.5px; line-height:1.8; color:var(--ink-soft); }
.team-role{
  display:inline-block; margin-top:20px; padding:7px 16px; border-radius:var(--r-pill);
  font-size:11.5px; font-weight:700; background:var(--beige-100); color:var(--brown);
}
.team-note{
  margin-top:0; padding:22px 26px;
  border-radius:var(--r-md);
  font-size:13.5px; color:var(--ink-soft);
}


/* ---------- 16. 口碑 ---------- */
/* 【已失效】口碑区整节已删（内容并入 FAQ 区的 .proof-strip） */
.voice-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(14px,1.8vw,22px); }
.voice{
  position:relative; margin:0; padding:30px 26px 24px;
  border-radius:var(--r-lg); background:rgba(255,255,255,.06);
  border:1.5px solid var(--line-dark);
  transition:transform .3s var(--ease), background .3s var(--ease);
}
.voice::before{
  content:"“"; position:absolute; left:18px; top:2px;
  font-family:Georgia,serif; font-size:66px; line-height:1; color:var(--accent); opacity:.85;
}
.voice:hover{ transform:translateY(-6px); background:rgba(255,255,255,.1); }
.voice p{ position:relative; font-size:16.5px; color:#fff; font-weight:600; line-height:1.75; }
.voice cite{ display:block; margin-top:18px; font-size:12.5px; color:var(--on-dark-mute); }

.badges{ display:flex; flex-wrap:wrap; gap:11px; margin-top:clamp(30px,3.6vw,48px); }
.badge{
  padding:10px 20px; border-radius:var(--r-pill);
  background:var(--beige); color:var(--brown-900);
  font-size:13.5px; font-weight:700;
  box-shadow:3px 3px 0 rgba(0,0,0,.28);
}


/* ---------- 17. FAQ ---------- */
.faq-wrap{ display:grid; grid-template-columns:.82fr 1.18fr; gap:clamp(28px,4vw,64px); align-items:start; }
/* ---------- 「平台与反馈」带 ----------
   原「客人怎么说」整节已取消（客户："这一页不要了，内容你看看放在哪里合适"）。
   三张卡片本身就是"服务反馈方向摘要（非逐字引用）"，不值得占三列，
   压缩成一行放进 FAQ 区的末尾；平台标签与合规脚注原样保留。
   作为 .faq-wrap 的最后一个 grid item，用 grid-column:1/-1 横跨两列。
   ⚠️ 标签样式原来写的是"深色底上的浅字"，这里是浅色区，必须整套换成浅底胶囊。 */
/* 摘要与标签排成两列一行，把这块压到 ~90px 以内 ——
   FAQ 那一屏余量有限，脚注另放页脚（见上）。 */
.proof-strip{
  grid-column:1 / -1;
  margin-top:clamp(18px,2.2vw,26px);
  /* 两列等宽：标签列要放得下 4 个标签**一行**排开（折成两行会多出 ~45px，
     正好把 FAQ 那一屏的余量吃掉）。 */
  display:grid; grid-template-columns:1fr 1fr;
  gap:clamp(16px,2vw,30px); align-items:center;
}
/* ⚠️ 必须同时压掉 margin-top：原来的 .badges 带着深色区那条
   `margin-top:clamp(30px,3.6vw,48px)`，只改 justify-content 会漏掉 48px，
   足以把 FAQ 那一屏从"余量充足"顶到"余量 9px"。 */
.proof-strip .badges{ justify-content:flex-end; margin-top:0; }
.proof-strip .badge{ padding:5px 12px; font-size:12.5px; border-width:1.5px; }
.proof-line{ font-size:14px; color:var(--ink-soft); line-height:1.78; max-width:80ch; }
.proof-line b{ color:var(--brown); font-weight:700; }
.proof-line em{ font-style:normal; font-size:12.5px; color:var(--ink-mute); }
.proof-strip .badges{ display:flex; flex-wrap:wrap; gap:10px; margin-top:0; }
.proof-strip .badge{
  display:inline-flex; align-items:center;
  padding:8px 16px; border-radius:var(--r-pill);
  background:#fff; border:2px solid var(--beige-200);
  font-size:13px; font-weight:700; color:var(--brown);
}
.faq-head h2{ font-size:clamp(29px,4.1vw,50px); letter-spacing:-.028em; margin:12px 0 0; }
.faq-head .sec-note{ margin-top:16px; }
.faq-head a{ color:var(--brown); font-weight:700; border-bottom:2.5px solid var(--pop-yellow); }
.faq-list{ display:grid; gap:12px; }
.qa{
  border-radius:var(--r-md); background:#fff;
  border:2px solid var(--beige-200); overflow:hidden;
  transition:border-color .28s var(--ease), box-shadow .28s var(--ease);
}
.qa[open]{ border-color:var(--brown); box-shadow:5px 5px 0 var(--beige-200); }
.qa summary{
  display:flex; align-items:flex-start; gap:14px;
  padding:19px 22px; cursor:pointer; list-style:none;
  font-size:16px; font-weight:700; color:var(--brown);
}
.qa summary::-webkit-details-marker{ display:none; }
.qa summary span{
  flex:none; padding:3px 10px; border-radius:var(--r-pill);
  background:var(--pop-yellow); color:var(--brown-900);
  font-family:var(--font-disp); font-size:12px; letter-spacing:0;
}
.qa summary::after{
  content:"+"; margin-left:auto; flex:none;
  font-size:22px; font-weight:700; line-height:1; color:var(--ink-mute);
  transition:transform .28s var(--ease);
}
.qa[open] summary::after{ transform:rotate(45deg); color:var(--brown); }
.qa-body{ padding:0 22px 22px 22px; }
.qa-body p{ font-size:14px; color:var(--ink-soft); line-height:1.85; border-top:1.5px dashed var(--beige-200); padding-top:16px; }


/* ---------- 18. 预约 ---------- */
/* ★ 六条承诺条（原「五好一公道」区块已删除，6 条挪到预约区底部）
   暗底（.section--book 是深色区）上的一条通栏 6 列细条，左侧一道多巴胺色边。
   ⚠️ 窄屏要折列，见下方 @media (max-width:1024px) 的 .creed。 */
.creed{
  display:grid; grid-template-columns:repeat(6,1fr);
  gap:clamp(8px,1vw,14px);
  margin-top:clamp(16px,2vw,22px);
  padding-top:clamp(13px,1.6vw,18px);
  border-top:1.5px solid var(--line-dark);
}
.creed li{
  display:flex; flex-direction:column; gap:5px;
  padding-top:2px; border-top:4px solid var(--accent);
}
.creed b{ font-size:13.5px; color:var(--beige); letter-spacing:-.01em; }
.creed span{ font-size:11px; color:var(--on-dark-mute); line-height:1.58; }
.book-grid{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(30px,4.4vw,68px); align-items:start; }
.book-copy h2{ font-size:clamp(30px,4.3vw,54px); letter-spacing:-.03em; margin:12px 0 0; color:#fff; }
.book-lead{ margin-top:20px; color:var(--on-dark-mute); max-width:34ch; }

.book-phone{
  display:inline-flex; align-items:center; gap:16px;
  margin-top:30px; padding:16px 26px 16px 18px;
  border-radius:var(--r-lg); color:var(--brown-900);
  transition:transform .26s var(--ease), box-shadow .26s var(--ease);
}
.book-phone-ico{
  display:grid; place-items:center; width:50px; height:50px; border-radius:16px;
  background:var(--pop-orange); flex:none;
}
.book-phone-ico svg{ width:24px; height:24px; fill:#fff; }
.book-phone em{ display:block; font-style:normal; font-size:12px; font-weight:700; opacity:.68; letter-spacing:.06em; }
.book-phone b{ display:block; font-family:var(--font-disp); font-size:clamp(21px,2.4vw,29px); letter-spacing:-.01em; line-height:1.2; }

.book-info{ margin-top:34px; display:grid; gap:16px; }
.book-info li{ display:grid; grid-template-columns:88px 1fr; gap:14px; padding-top:16px; border-top:1.5px solid var(--line-dark); }
.book-info b{ font-size:13px; color:var(--beige); letter-spacing:.04em; }
.book-info span{ font-size:13.5px; color:var(--on-dark-mute); line-height:1.8; }

.book-form{
  padding:clamp(24px,3vw,38px); border-radius:var(--r-xl);
  background:var(--cream); color:var(--ink);
  border:3px solid var(--brown-900); box-shadow:10px 10px 0 var(--pop-yellow);
}
.book-form h3{ font-size:clamp(20px,2.2vw,26px); color:var(--brown); }
.form-hint{ margin-top:8px; font-size:12.5px; color:var(--ink-mute); }
.form-trap{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; }
.field{ margin-top:18px; }
.field label{ display:block; font-size:13px; font-weight:700; color:var(--brown); margin-bottom:7px; }
.field label i{ color:var(--pop-pink); font-style:normal; }
.field input,.field select{
  width:100%; padding:13px 16px; border-radius:var(--r-sm);
  border:2px solid var(--beige-300); background:#fff;
  font-size:15px; transition:border-color .22s var(--ease), box-shadow .22s var(--ease);
}
.field select{ appearance:none; background-image:linear-gradient(45deg,transparent 50%,var(--brown) 50%),linear-gradient(135deg,var(--brown) 50%,transparent 50%); background-position:calc(100% - 20px) 21px,calc(100% - 14px) 21px; background-size:6px 6px,6px 6px; background-repeat:no-repeat; padding-right:44px; }
.field input:focus,.field select:focus{ outline:none; border-color:var(--brown); box-shadow:0 0 0 4px rgba(112,71,57,.12); }
.field input::placeholder{ color:#B9A79F; }
.field.has-err input{ border-color:var(--pop-pink); box-shadow:0 0 0 4px rgba(255,61,119,.12); }
.err{ display:block; margin-top:6px; font-size:12px; font-weight:700; color:var(--pop-pink); min-height:0; }

.agree{ display:flex; align-items:flex-start; gap:11px; margin-top:22px; font-size:12.5px; color:var(--ink-soft); line-height:1.7; cursor:pointer; }
.agree input{ width:19px; height:19px; flex:none; margin-top:2px; accent-color:var(--brown); }
.book-form .btn{ margin-top:20px; }
.form-done{
  margin-top:16px; padding:13px 18px; border-radius:var(--r-sm);
  background:#DFF8F3; color:#00674F; font-size:13.5px; font-weight:700;
}
.form-done.is-error{ background:#FFF0EC; color:#9B3327; }


/* ---------- 19. 页脚 ---------- */
.site-footer{ background:var(--brown-950); color:var(--on-dark); padding:clamp(48px,5.6vw,80px) 0 34px; border-top:6px solid var(--beige); }
.footer-grid{ display:grid; grid-template-columns:1.15fr .9fr .95fr; gap:clamp(24px,3.4vw,54px); align-items:start; }
.footer-brand{ display:flex; align-items:center; gap:16px; }
.brand-mark--footer{ width:34px; height:54px; color:var(--beige); }
.footer-brand strong{ display:block; font-size:21px; color:#fff; letter-spacing:.05em; }
.footer-brand em{ display:block; margin-top:6px; font-style:normal; font-size:12px; color:var(--on-dark-mute); line-height:1.7; }

.footer-nav{ display:grid; grid-template-columns:1fr 1fr; gap:11px 20px; }
.footer-nav a{ font-size:14px; color:var(--on-dark-mute); font-weight:600; transition:color .22s var(--ease); }
.footer-nav a:hover{ color:var(--pop-yellow); }

.footer-note{ margin-top:clamp(28px,3.2vw,44px); padding-top:0; font-size:12px; color:rgba(230,210,200,.55); line-height:1.9; max-width:100ch; }
.footer-contact p{ display:flex; gap:11px; font-size:13px; color:var(--on-dark-mute); line-height:1.8; margin-bottom:11px; }
.footer-contact b{ flex:none; color:var(--beige); font-size:12.5px; letter-spacing:.06em; }
.footer-contact a{ color:var(--pop-yellow); font-weight:700; }

.footer-legal{ margin-top:clamp(34px,4vw,54px); padding-top:26px; border-top:1.5px solid var(--line-dark); }
.footer-legal p{ font-size:12px; color:rgba(230,210,200,.5); line-height:1.9; max-width:100ch; }

.footer-copy{ margin-top:14px; }


/* ---------- 20. 悬浮操作按钮（预约固定右下角 · 最上层 · 不受滚动影响） ---------- */
.fab{
  position:fixed; z-index:400;
  bottom:clamp(18px, 2.2vw, 30px);
  display:inline-flex; align-items:center; gap:9px;
  padding:16px 26px; border-radius:var(--r-pill);
  font-size:15.5px; font-weight:700; line-height:1; letter-spacing:.02em;
  border:2.5px solid var(--brown-900);
  transition:transform .24s var(--ease), box-shadow .24s var(--ease), background .24s var(--ease);
}
.fab svg{ width:19px; height:19px; flex:none; fill:none; stroke:currentColor; stroke-width:2.1; stroke-linecap:round; stroke-linejoin:round; }
.fab:hover{ transform:translate(-3px,-3px); }

/* 【已删除】.fab--book 与它的呼吸光圈 ::after —— 客户要求删掉「预约面诊」浮动按钮。 */

@keyframes fabPing{
  0%{ opacity:.7; transform:scale(1); }
  70%{ opacity:0; transform:scale(1.32); }
  100%{ opacity:0; transform:scale(1.32); }
}

/* 手机端左下角补一个打电话，与右下角预约左右呼应 */
.fab--call{
  left:clamp(18px, 2.2vw, 30px);
  display:none;
  background:#fff; color:var(--brown);
  box-shadow:5px 5px 0 var(--beige-300), 0 20px 44px -22px rgba(70,41,30,.6);
}
.fab--call:hover{ box-shadow:9px 9px 0 var(--beige-300), 0 24px 50px -22px rgba(70,41,30,.6); }


/* ---------- 21. 拟态玻璃卡片 ---------- */
/* 全站卡片统一换成玻璃拟态：半透明底 + backdrop-filter 磨砂 + 1px 内高光边 + 柔和外投影。
   底图 .page-ghost 在卡片后方经过时会被真实磨砂虚化，玻璃质感因此成立，而不是"看着像"。
   这一节放在各组件之后，用同优先级+源码顺序覆盖各组件原有的底色与边框。 */
.card,
.dev,
.team,
.perk,
.qa,
.hero-facts,
.motto-list li,
.flow-list li,
.team-note,
.disclaimer,
.book-form,
.book-phone{
  background:var(--glass-bg);
  -webkit-backdrop-filter:var(--glass-blur);
          backdrop-filter:var(--glass-blur);
  border:1.5px solid var(--glass-border);
  box-shadow:var(--glass-shadow), inset 0 1px 0 var(--glass-hi), inset 0 -1px 0 var(--glass-lo);
}
/* 「五好一公道」卡片的左侧强调条要保住 */
.motto-list li{ border-left:7px solid var(--accent); }
/* 医师团队下方说明条：保留左侧橙色强调条 */
.team-note{ border-top:6px solid var(--pop-orange); }
/* 合规声明：玻璃面 + 虚线边，保留"这是注释"的语义 */
.disclaimer{ border:1.6px dashed rgba(112,71,57,.24); }

/* 深色区块里的玻璃：浅白玻璃会在棕底上发灰发脏，改用低透明度白 + 内高光 */
.cred,
.voice,
.verify-steps li,
.disclaimer--light{
  background:var(--glass-bg-dark);
  -webkit-backdrop-filter:var(--glass-blur-dark);
          backdrop-filter:var(--glass-blur-dark);
  border:1.5px solid var(--glass-border-dark);
  box-shadow:var(--glass-shadow-dark), inset 0 1px 0 var(--glass-hi-dark);
}
.disclaimer--light{ border:1.6px dashed rgba(230,210,200,.2); }

/* 深色底上的**浅色**玻璃：预约表单与电话面板。透明度提高，保证深色文字可读 */
.book-form,
.book-phone{
  background:var(--glass-bg-strong);
  border:1.5px solid rgba(255,255,255,.9);
  box-shadow:0 34px 70px -30px rgba(0,0,0,.75), inset 0 1px 0 rgba(255,255,255,.98), inset 0 -1px 0 rgba(255,255,255,.5);
}
.book-phone:hover{ transform:translate(-3px,-3px); box-shadow:0 44px 84px -32px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.98), inset 0 -1px 0 rgba(255,255,255,.5); }

/* 悬停：玻璃面板改为"抬起来 + 阴影变深"，不再用原来的硬阴影（硬阴影会破坏玻璃感） */
.motto-list li:hover{ transform:translate(-3px,-3px); box-shadow:var(--glass-shadow-hover), inset 0 1px 0 var(--glass-hi), inset 0 -1px 0 var(--glass-lo); }
.perk:hover{ transform:translateY(-4px); box-shadow:var(--glass-shadow-hover), inset 0 1px 0 var(--glass-hi), inset 0 -1px 0 var(--glass-lo); }
.dev:hover{ box-shadow:var(--glass-shadow-hover), inset 0 1px 0 var(--glass-hi), inset 0 -1px 0 var(--glass-lo); }
.team:hover{ box-shadow:var(--glass-shadow-hover), inset 0 1px 0 var(--glass-hi), inset 0 -1px 0 var(--glass-lo); }
.qa[open]{ box-shadow:var(--glass-shadow-hover), inset 0 1px 0 var(--glass-hi), inset 0 -1px 0 var(--glass-lo); }
.cred:hover{ background:linear-gradient(135deg, rgba(255,255,255,.22) 0%, rgba(255,255,255,.08) 50%, rgba(255,255,255,.14) 100%); border-color:rgba(255,255,255,.34); }
.voice:hover{ background:linear-gradient(135deg, rgba(255,255,255,.2) 0%, rgba(255,255,255,.07) 50%, rgba(255,255,255,.12) 100%); }
.verify-steps li:hover{ background:linear-gradient(135deg, rgba(255,255,255,.2) 0%, rgba(255,255,255,.07) 50%, rgba(255,255,255,.12) 100%); }

/* 玻璃面板里的分隔线：从实色虚线改成低对比，避免在磨砂底上显脏 */
.card-meta{ border-top-color:rgba(112,71,57,.16); }
.card-meta li span{ color:rgba(112,71,57,.55); }
.qa-body p{ border-top-color:rgba(112,71,57,.16); }
.dev-auth{ border-top-color:rgba(112,71,57,.16); }

/* ---------- 22. 入场动效 ---------- */
/* 入场动画的初始态：**只在"尚未入场"时生效**（用 :not(.is-in) 限定）。
   这样一旦加上 is-in，transform 就完全交还给元素自身 ——
   例如 .card:hover 的上浮、.note 的固定旋转角都能正常保留。

   ⚠️ 千万别改回 `.reveal.is-in{ transform:none !important }` 那种写法：
     !important 会压过任何非 important 声明（与优先级无关），
     于是页面上**所有**带 reveal 类的 hover 位移会集体失效 ——
     卡片、五好一公道、团队、设备、口碑、认证等区块的上浮全部不动，
     而且带固定 transform 的 reveal 元素（旋转的便签）还会被强行拉平。
     本项目实际踩过这个坑，改回即回归。 */
.js .reveal:not(.is-in){ opacity:0; transform:translateY(24px); }
.reveal{ transition:opacity .72s var(--ease), transform .72s var(--ease); }
.reveal.is-in{ opacity:1; }
.reveal[data-delay="1"]{ transition-delay:.07s; }
.reveal[data-delay="2"]{ transition-delay:.14s; }
.reveal[data-delay="3"]{ transition-delay:.21s; }
.reveal[data-delay="4"]{ transition-delay:.28s; }
.reveal[data-delay="5"]{ transition-delay:.35s; }


/* ---------- 23. 响应式 ---------- */
/* 1500px 以下：正文栏两侧已无余量、右栏又贴着视口右缘，
   右侧两张便签若继续按大百分比外扩，旋转后的外角会被 body 的 overflow-x 裁掉。
   （1500px 以上两侧留白够，保持大外扩的"溢出画面"手感）
   同一条断点里把贴纸的躲让幅度也收到 0.8：窄屏上便签、气泡、贴纸挤得更近 */
@media (max-width:1500px){
  .note--d{ right:-3%; }
  .note--b{ right:-3%; }
  .sticker{ --dodge:.8; }
}

@media (max-width:1180px){
  .dev-grid{ grid-template-columns:repeat(3,1fr); }
  .hero-facts{ grid-template-columns:repeat(3,1fr); gap:20px; }
  .flow-list{ grid-template-columns:repeat(3,1fr); }
  .flow-list li:nth-child(3)::after{ display:none; }
}

@media (max-width:1024px){
  .hero-grid{ grid-template-columns:1fr; gap:44px; }
  .hero-visual{ max-width:640px; }
  .hero h1{ font-size:clamp(27px,6.2vw,44px); }
  .page-ghost{ font-size:clamp(70px,20vw,150px); opacity:.8; }
  .sec-head,.motto-grid,.faq-wrap,.book-grid{ grid-template-columns:1fr; gap:26px; }
  /* 口号区上半的两列（标题 / 描述）在窄屏也要折成单列 */
  .creed{ grid-template-columns:repeat(2,1fr); gap:14px; }   /* 六条承诺条窄屏折两列 */
  /* 招牌色块降到单列：文字在上、装饰区在下。
     装饰区要给回固定高度，否则 stretch 会把水印字压扁。 */
  .sig{ grid-template-columns:1fr; gap:8px; min-height:0; }
  /* 单列后装饰区变矮（84–112px），而素材按 width 撑出 110–140px；
     它们是绝对定位、撑不开容器，会被色块的 overflow:hidden 裁掉一截。
     这里让素材切回正常流并居中，.sig-art 自己跟着长高 ——
     比在每个断点里对着数字调 min-height 稳得多。
     padding-top 是给右上角「院长推荐」标签让位：胶囊横着排在
     色块右侧，素材居中后会撞上它，垫 48px 正好错开。 */
  .sig-art{ min-height:clamp(84px,13vw,112px); display:grid; place-items:center; padding-top:48px; }
  .sig-photo{ position:relative; right:auto; bottom:auto; }
  .sig--eye .sig-photo{ width:clamp(176px,46vw,238px); }
  .sig--lip .sig-photo{ width:clamp(200px,50vw,264px); }
  .sig-name{ font-size:clamp(30px,8vw,52px); }
  .sec-note,.motto-head p,.book-lead{ max-width:60ch; }
  .cards{ grid-template-columns:repeat(2,1fr); }
  /* 窄屏退回网格：堆叠在窄屏会重叠过头 */
  .gal{ display:grid; grid-template-columns:repeat(2,1fr); gap:10px; height:auto; margin-top:24px; }
  /* ⚠️ 触摸设备没有 hover —— 悬浮气泡式的图注会永远看不见，
     所以窄屏把图注还原成"卡片内的深色胶囊"，常驻可见。 */
  .gal-item figcaption{
    left:12px; bottom:12px; opacity:1; transform:none;
    border-radius:var(--r-pill); padding:6px 12px; font-size:12px;
    background:rgba(30,18,13,.8); color:var(--beige);
    -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
    border:0; box-shadow:none;
  }
  .gal-item figcaption::after{ display:none; }
  /* ⚠️ 选择器必须带 .gal 前缀：主规则是 `.gal .gal-item`（0,2,0），
     只写 `.gal-item`（0,1,0）即使放在后面也压不过它 —— **权重赢过源码顺序**。
     不修的话窄屏卡片仍是绝对定位，而 .gal 的 height:auto 会塌成 0。 */
  .gal .gal-item{ position:static; width:auto; aspect-ratio:auto; transform:none; z-index:auto; border-width:3px; }
  .gal .gal-item img{ aspect-ratio:4/3; height:auto; }
  .gal-item--wide{ grid-column:span 2; }
  .verify-steps{ grid-template-columns:repeat(2,1fr); }
  .footer-grid{ grid-template-columns:1fr 1fr; }
  .footer-contact{ grid-column:span 2; }
  .brand{ --lh:36px; }
  .fab--call{ display:inline-flex; }
  body{ padding-bottom:96px; }
}

@media (max-width:1024px){
  /* 手机/平板：菜单收进页头下方的白色下拉面板。 */
  .header-inner{ display:flex; align-items:center; justify-content:space-between; }
  .nav{
    position:fixed; inset:calc(70px + env(safe-area-inset-top)) 0 auto; z-index:190;
    left:0; right:0; width:100%; max-width:none;
    flex-direction:column; align-items:stretch; gap:0;
    padding:0 22px 24px;
    background:#fff;
    border:0; border-radius:0 0 14px 14px;
    box-shadow:0 14px 24px -20px rgba(70,41,30,.35);
    transform:none;
    /* 收起后连同键盘焦点与读屏一起移出，避免 Tab 进到看不见的菜单 */
    visibility:hidden;
    transition:visibility 0s linear .22s;
    max-height:calc(100vh - 70px - env(safe-area-inset-top));
    max-height:calc(100dvh - 70px - env(safe-area-inset-top));
    overflow-y:auto;
    overscroll-behavior:contain;
  }
  .nav.is-open{
    visibility:visible;
    transition:visibility 0s;
  }
  /* 移动端菜单按参考样式展示为白底分隔列表，链接右侧加轻量箭头。 */
  .nav{ -webkit-backdrop-filter:none; backdrop-filter:none; }
  .nav > a{
    display:flex; justify-content:space-between; align-items:center;
    min-height:52px; padding:14px 2px; border-radius:0;
    border-bottom:1px solid #e8e3df; font-size:16px;
  }
  .nav > a::after{
    content:""; width:7px; height:7px; flex:none;
    border-top:1.5px solid #8c8986; border-right:1.5px solid #8c8986;
    transform:rotate(45deg); margin-right:3px;
  }
  .nav > a::before{ display:none; }
  .nav > a.is-active,
  .nav > a[aria-current="page"]{ color:#df263f; background:none; box-shadow:none; }
  .nav > a:hover{ background:none; transform:none; }
  .burger{ display:block; position:relative; z-index:200; }

  .cred-list{ grid-template-columns:1fr; }
  .motto-list{ grid-template-columns:1fr; }
  .dev-grid{ grid-template-columns:repeat(2,1fr); }
  .perks{ grid-template-columns:repeat(2,1fr); }
  .team-grid{ grid-template-columns:repeat(2,1fr); }
  .voice-grid{ grid-template-columns:1fr; }
  /* 单列布局：视觉区变成整幅宽，便签按百分比会等比放大，
     这里统一收小尺寸与外扩量，否则小便签会盖到下面的数字条、并从屏幕左缘冒出一角 */
  .hero-visual{ padding-bottom:clamp(40px,6vw,58px); }
  .note--c{ width:32%; left:2%;   top:-4%; }
  .note--d{ width:30%; right:1%;  top:2%;  }
  .note--a{ width:40%; left:0%;   bottom:-8%; }
  .note--b{ width:38%; right:1%;  bottom:-7%; }
  .sticker--2{ top:44%; }
  /* 单列布局：视觉区上方紧挨 CTA 按钮、下方紧挨数字条、左右也贴到视口边，
     贴纸再往外躲就会压到按钮/越出屏幕，所以这一档直接关掉躲让（触屏本来也没有悬停） */
  .sticker{ --dodge:0; }
  /* 窄屏同时把标签本身收小。main.js 第 12 节是按"槽距 − 最宽标签"算抖动量预算的：
     这一档槽距只有 240px，标签不收小的话抖动量要压到 0.17 以下，散落感就没了；
     收小到约 100x58 之后，预算回到 0.2 以上，位置才有随机余地。 */
  .sticker{ font-size:11.5px; padding:7px 11px; border-width:2px; border-radius:13px; }
  .sticker em{ font-size:9.5px; }
  /* 单列时视觉区上面就是 CTA 按钮，气泡浮上去会压到按钮；触屏本来也没有悬停 */
  .note-tip{ display:none; }
}

@media (max-width:620px){
  :root{ --sec-y:56px; }
  .brand{ --lh:31px; }
  .cards{ grid-template-columns:1fr; }
  /* 招牌色块（手机）：首屏要能一眼看到主角，所以字号与留白继续收，
     徽章缩到 74px 挪到角落，避免压住水印字 */
  .sig{ padding:17px 16px; border-radius:var(--r-lg); }
  .sig-name{ font-size:clamp(27px,8.8vw,38px); }
  .sig-art{ min-height:clamp(68px,18vw,90px); }
  /* 标记本身没有底框，缩小靠改尺寸；logo 是 height:100% 跟着走，不用单独设。 */
  .sig-badge{ width:68px; height:68px; }
  .sig-badge b{ font-size:10.5px; letter-spacing:.04em; }
  .sig-meta li{ font-size:12px; padding:5px 10px; }
  .sig-actions{ margin-top:15px; gap:11px; }
  .sig-cta{ padding:11px 18px; font-size:13.5px; }
  .op-count{ font-size:22px; }
  .dev-grid{ grid-template-columns:1fr; }
  .perks{ grid-template-columns:1fr; }
  .team-grid{ grid-template-columns:1fr; }
  .verify-steps{ grid-template-columns:1fr; }
  .gal{ grid-template-columns:1fr; }
  .gal-item--wide{ grid-column:span 1; }
  .gal-item .ph,.gal-item--wide .ph{ aspect-ratio:4/3; }
  .flow-list{ grid-template-columns:repeat(2,1fr); }
  .flow-list li::after{ display:none; }
  .hero-facts{ grid-template-columns:repeat(2,1fr); gap:16px; padding:18px; }
  .footer-grid{ grid-template-columns:1fr; }
  .footer-contact{ grid-column:span 1; }
  .footer-nav{ grid-template-columns:1fr 1fr; }
  .book-form{ box-shadow:0 26px 54px -26px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.95); }
  /* 手机屏：上面两张小便签收起来，只留主便签 + 左右两张；贴纸跟着往内收 */
  .note--c,.note--d{ display:none; }
  .note--a{ left:0%; bottom:-6%; }
  .note--b{ right:0%; bottom:-5%; }
  .hero-visual{ padding:14px 0 clamp(34px,9vw,48px); }
  .sticker--1{ left:12%; top:2%; }
  .sticker--2{ right:0%; top:38%; }
  .sticker--3{ left:26%; bottom:6%; }
  .sticker--4{ left:0%; top:20%; }
  .sticker--5{ right:0%; bottom:16%; }
  .hero-actions .btn{ flex:1 1 100%; }
  .card-foot{ flex-direction:column; align-items:flex-start; gap:10px; }
}

/* 极窄屏：页头电话让位给空间（左下角已有常驻「打电话」悬浮按钮兜底） */
@media (max-width:460px){
  .header-end .nav-phone{ display:none; }
}

/* ---------- 24. 动效降级 ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; scroll-behavior:auto !important; }
  /* 必须跟基础规则一样带 :not(.is-in) ——
     否则优先级 (0,2,0) 低于 `.js .reveal:not(.is-in)` 的 (0,3,0)，
     降级时压不住初始的 opacity:0，内容会整片看不见。
     同优先级 + 源序在后 → 这条生效。 */
  .js .reveal:not(.is-in){ opacity:1; transform:none; }
  .marquee-track{ animation:none; }
}

/* ---------- 25. 鼠标光晕（多巴胺配色 · 三层同心圆形散光） ----------
   三层柔光叠在一起：橙（核心，最小最亮）/ 粉（中层）/ 紫（外层，最大最淡）。
   颜色直接取站点已有的多巴胺变量，保证和便签/贴纸是同一套色。

   ★ 三个 <i> 只负责**跟随** —— transform 由 main.js 第 11 节每帧写入；
     渐变底色、色相漂移、亮度呼吸全在这里（CSS 动画）。两者分属
     "写 transform 的 JS" 与 "写 filter/opacity 的 CSS 动画"，互不覆盖。

   opacity 用 class 切换做淡入淡出。
   z-index:2 —— **置于内容最底层**（区块底色 < 本层 < 正文 .wrap 的 3），
   所以只染背景、完全碰不到文字与卡片。 */
.cursor-glow{
  position:fixed; left:0; top:0; z-index:2;
  pointer-events:none; opacity:0;
  /* multiply 而不是普通叠加：深色文字乘上浅色几乎不变 → **文字对比度不受影响**，
     只有浅色底会被染色。用普通 alpha 叠加时深色笔画会被冲淡，
     光标扫过标题/正文就会"抢文字"（客户反馈过）。 */
  mix-blend-mode:multiply;
  transition:opacity .45s var(--ease);
}
.cursor-glow.is-on{ opacity:1; }
/* 光标在**深色区块**（资质/口碑/预约/页脚）里时切到 screen。
   multiply 在深色底上只会加深，看起来像一块暗斑/脏点，而不是光晕。
   深色区块的文字本身就是浅米色，screen 提亮背景不会伤它的对比度。 */
.cursor-glow.is-dark{ mix-blend-mode:screen; }

.cursor-glow i{
  position:absolute; left:0; top:0; display:block;
  border-radius:50%;
  will-change:transform;
}
/* 叠放顺序：大的在下、小的在上 —— 否则最大的紫色层会把橙色核心盖住，
   中心就变成一片紫，看不出"核心橙"。
   （三条 z-index 与 nth-child 的尺寸顺序相反，别搞反） */
.cursor-glow i:nth-child(1){ z-index:3; }
.cursor-glow i:nth-child(2){ z-index:2; }
.cursor-glow i:nth-child(3){ z-index:1; }

/* ---- 核心：最小最亮，跟得最紧（main.js TAU[0] = 0.055） ---- */
.cursor-glow i:nth-child(1){
  width:125px; height:125px;
  background:radial-gradient(circle,
    rgba(255,106,43,.17) 0%,
    rgba(255,106,43,.075) 40%,
    rgba(255,106,43,0) 72%);
}
/* ---- 中层：过渡带（TAU[1] = 0.115） ---- */
.cursor-glow i:nth-child(2){
  width:195px; height:195px;
  background:radial-gradient(circle,
    rgba(255,61,119,.105) 0%,
    rgba(255,61,119,.045) 44%,
    rgba(255,61,119,0) 73%);
}
/* ---- 外层：最大最淡，拖尾最长（TAU[2] = 0.210） ----
   ★ 这里用的是**色板原始紫** --pop-violet #7B4DFF（123,77,255），
     不是第 9 节区块背景统一后的"暖紫" 206,120,206。

     两者取舍（客户 2026/09 明确要求回到这一版，所以先用原始紫）：
       · 用 123,77,255（现在）：三层是"橙→粉→紫"的邻近色阶，紫更清透、
         光晕更"多巴胺"；但比全站区块背景的暖紫略冷一档。
       · 用 206,120,206（第 9 节的暖紫）：与区块背景完全同一色温，
         整页更统一；但光晕外层会偏灰发浊，三层的色阶跳跃变小。
     想换回去只改下面三个 rgba 的数字即可。 */
.cursor-glow i:nth-child(3){
  width:280px; height:280px;
  background:radial-gradient(circle,
    rgba(123,77,255,.07) 0%,
    rgba(123,77,255,.03) 46%,
    rgba(123,77,255,0) 75%);
}

/* 动态：三层各自做**缓慢色相漂移 + 亮度呼吸**。
   周期互不相同（6.5s / 9.1s / 12.4s）并用负 animation-delay 错开相位，
   所以是"活的"而不是三层同步闪烁。

   ⚠️ **只动 filter 和 opacity，绝不能动 transform** ——
   光晕位置是 main.js 每帧写 translate3d() 的（光标跟随），
   CSS 动画若也动 transform 会互相覆盖、光晕直接不跟手。
   色相摆幅 ±30°：橙色(20°)在 350°~50° 之间游走，即红粉 ↔ 橙黄，
   始终落在多巴胺色域内，不会飘到绿蓝去。 */
@keyframes glowDrift{
  0%   { filter:hue-rotate(-30deg); opacity:.86; }
  50%  { filter:hue-rotate( 30deg); opacity:1;   }
  100% { filter:hue-rotate(-30deg); opacity:.86; }
}
.cursor-glow i:nth-child(1){ animation:glowDrift 6.5s  ease-in-out infinite; }
.cursor-glow i:nth-child(2){ animation:glowDrift 9.1s  ease-in-out infinite; animation-delay:-2.3s; }
.cursor-glow i:nth-child(3){ animation:glowDrift 12.4s ease-in-out infinite; animation-delay:-5.7s; }

/* 文字选中高亮：原来是浏览器默认蓝，换成品牌黄 + 深棕字。
   这是"选择"最直接的一处，零成本、零动画。 */
::selection{ background:var(--pop-yellow); color:var(--brown-900); }
::-moz-selection{ background:var(--pop-yellow); color:var(--brown-900); }
/* ---------- 25b. 滚动期间的合成降级（解卡顿） ----------
   由 main.js 第 13 节在滚动时给 <html> 挂 .is-scrolling。
   本页有两处很重的合成，长距离平滑滚动时每帧都要重算：
     · .sig 的 backdrop-filter:blur(24px)  两块各约 728×330 ≈ 每帧模糊 48 万像素
     · .cursor-glow 的 mix-blend-mode:multiply  fixed 全屏混合
   滚动时把模糊半径降到一半、暂时去掉全屏混合；停止 220ms 后恢复。
   模糊半径减半在运动过程中几乎看不出来，但每帧像素量降到约 1/4。

   ⚠️ 如果滚动仍然卡，下一步是：
      · 把这里的 blur 再降到 0（玻璃会变成纯半透明色块）
      · 或把 .cursor-glow 的 mix-blend-mode 永久改回 normal
        （它现在在 z-index:2，本来就在正文之下、碰不到文字，
          当年加 multiply 是为了保护文字，现在其实已经冗余） */
html.is-scrolling .sig{
  -webkit-backdrop-filter:blur(10px) saturate(140%);
  backdrop-filter:blur(10px) saturate(140%);
}
html.is-scrolling .sig::before,
html.is-scrolling .sig-list::before{ filter:none; }
html.is-scrolling .cursor-glow{ mix-blend-mode:normal; }
/* ---------- 25d. 「关于我们」页（按 GEO 结构编写） ----------
   这是一张**阅读型页面**，和首页的"一屏一板块"完全不同：
   不以撑满视口为目标，而是以"每段都能被独立引用"为目标。
   结构对应 GEO 的几条要求：
     · 开头是含主体全称的定义句（answer-first，不含"我们"这类指代）
     · 事实用 <dl> 成对列出，日期用 <time datetime>，地址用 <address>
     · 问答用自包含的问答对，且与页面里 FAQPage 结构化数据逐字一致
   样式上沿用全站的纸面 / 描边 / 硬阴影语言，不加新装饰。 */
.page-about main{ padding:clamp(96px,11vw,132px) 0 clamp(44px,5.5vw,76px); }
.page-about .crumb,
.page-about .about-head,
.page-about .about-sec{ width:min(var(--wrap), calc(100% - var(--gutter)*2)); margin-inline:auto; }
.crumb{ display:flex; align-items:center; gap:9px; margin-bottom:22px; font-size:13px; color:var(--ink-mute); }
.crumb a{ color:var(--ink-soft); font-weight:600; }
.crumb a:hover{ color:var(--brown); }
.about-head{ padding-bottom:clamp(20px,2.4vw,32px); border-bottom:2.5px solid var(--beige-300); }
.page-about h1{ font-size:clamp(32px,4.4vw,56px); color:var(--brown); letter-spacing:-.03em; }
.about-lede{ margin-top:18px; font-size:clamp(15px,1.2vw,17px); line-height:1.95; color:var(--ink-soft); max-width:76ch; }
.about-sec{ margin-top:clamp(32px,3.8vw,52px); }
.page-about h2{ font-size:clamp(21px,2.3vw,30px); color:var(--brown); letter-spacing:-.02em; }
.page-about h3{ margin-top:26px; font-size:clamp(17px,1.6vw,21px); color:var(--brown); }
.page-about p{ margin-top:14px; font-size:15px; line-height:1.95; color:var(--ink-soft); max-width:76ch; }
.page-about p b{ color:var(--brown); font-weight:700; }
.facts{
  margin-top:18px; display:grid; grid-template-columns:repeat(2,1fr); gap:2px;
  border:1.5px solid var(--beige-200); border-radius:var(--r-md); overflow:hidden; background:var(--beige-200);
}
.facts>div{ display:grid; grid-template-columns:124px 1fr; gap:14px; padding:13px 16px; background:#fff; }
.facts dt{ font-size:12.5px; font-weight:700; color:var(--brown); letter-spacing:.02em; }
.facts dd{ margin:0; font-size:13.5px; line-height:1.7; color:var(--ink-soft); }
.facts address{ font-style:normal; }
.biz{ margin-top:14px; display:grid; gap:9px; }
.biz li{ position:relative; padding-left:20px; font-size:14.5px; line-height:1.85; color:var(--ink-soft); }
.biz li::before{ content:""; position:absolute; left:2px; top:.72em; width:7px; height:7px; border-radius:50%; background:var(--pop-orange); }
.biz li b{ color:var(--brown); }
.qa-plain{ margin-top:18px; }
.qa-plain dt{ padding-top:18px; border-top:1.5px dashed var(--beige-200); font-size:15.5px; font-weight:700; color:var(--brown); }
.qa-plain dt:first-of-type{ padding-top:0; border-top:0; }
.qa-plain dd{ margin:9px 0 0; font-size:14.5px; line-height:1.9; color:var(--ink-soft); max-width:78ch; }
.visit{ margin-top:18px; display:grid; gap:11px; font-style:normal; }
.visit p{ margin:0; display:flex; gap:12px; font-size:14px; color:var(--ink-soft); }
.visit b{ flex:none; color:var(--brown); font-size:13px; letter-spacing:.04em; }
.visit a{ color:var(--brown); font-weight:700; }
@media (max-width:900px){
  .facts{ grid-template-columns:1fr; }
  .facts>div{ grid-template-columns:104px 1fr; gap:10px; }
}
/* ---------- 25e. 一键返回顶部 ----------
   ★ 以下 6 条规则 = 客户提供的 Uiverse 按钮 CSS（作者 vinodjangid07），
     **逐字原样写入，未做任何修改**（含 rgb(20,20,20)、淡紫光圈、Back to Top 文案）。 */
.to-top{
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: rgb(20, 20, 20);
  border: none;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0px 0px 0px 4px rgba(180, 160, 255, 0.253);
  cursor: pointer;
  transition-duration: 0.3s;
  overflow: hidden;
  position: relative;
}

.svgIcon {
  width: 12px;
  transition-duration: 0.3s;
}

/* ★ 把箭头钉在**收起态的水平正中**。
   按钮 50px、箭头 12px → right = (50 − 12) / 2 = 19px，收起时它正好居中。
   为什么不用父级的 display:flex 居中：按钮右对齐，展开时**左边缘向左移动 45px**，
   flex 居中会让箭头跟着中心一起左移 45px，同时上移 —— 合起来就是"斜着飞"。
   锚 right（这条边永远不动）之后，水平位移恒为 0，只剩垂直上飞。 */
.to-top .svgIcon{
  position: absolute;
  right: 19px;
  top: 50%;
  transform: translateY(-50%);
}

.svgIcon path {
  fill: white;
}

.to-top:hover {
  width: 140px;
  border-radius: 50px;
  transition-duration: 0.3s;
  background-color: rgb(181, 160, 255);
  align-items: center;
}

.to-top:hover .svgIcon {
  /* width: 20px; */
  transition-duration: 0.3s;
  /* 只改 Y。X 由 right:19px 锁死，不参与动画，所以是笔直上飞。 */
  transform: translateY(-200%);
}

.to-top::before {
  position: absolute;
  bottom: -20px;
  content: "Back to Top";
  color: white;
  /* ★ 原版靠 font-size:0px → 13px 显形：文字每帧重排、从 0 宽撑满，所以是"蹦"出来的。
     改成固定字号 + 静止态透明 + 轻微下移，用 opacity/transform 淡入。 */
  font-size: 13px;
  opacity: 0;
  transform: translateY(7px);
  pointer-events: none;
  transition: opacity .3s var(--ease), transform .3s var(--ease);
}

.to-top:hover::before {
  opacity: 1;
  bottom: unset;
  transform: translateY(0);
  /* 比按钮展开稍晚一点点出现，让"先撑开、再浮出文字"的次序读得出来 */
  transition: opacity .3s var(--ease) .06s, transform .3s var(--ease) .06s;
}

/* ---------- 25f. 接入所需（★ 不属于设计，仅为让上面那个按钮出现在本站页面上） ----------
   ① 定位：原版是 position:relative（Uiverse 演示里它就在文档流中）。
      本站要它固定在右下角，所以覆盖成 fixed。
   ② 出现/隐藏：滚过 80% 一屏才淡入（首屏在顶部时按钮没有意义）。
   ③ reduced-motion：尊重系统偏好。 */
.to-top{
  position: fixed; z-index: 390;
  right: clamp(18px, 2.2vw, 30px);
  bottom: clamp(18px, 2.2vw, 30px);
  opacity: 0; visibility: hidden;
  /* ★★ 这里必须把 width / border-radius / background-color 一起列上。
     原版只写了 transition-duration:.3s，靠默认的 transition-property:all 生效；
     而本节的 transition-property 与它同权重、位置在后 ——
     一旦只写 opacity, visibility，就会**覆盖掉原版**，
     导致展开时 width 根本不参与过渡，按钮"啪"地跳到 140px。 */
  transition-property: opacity, visibility, width, border-radius, background-color;
  transition-duration: .3s;
}
.to-top.is-on{ opacity: 1; visibility: visible; }
@media (prefers-reduced-motion: reduce){
  .to-top{ transition-duration: .01ms; }
  .to-top:hover .svgIcon{ transform: none; }
}
/* ---------- 26. 打印 ---------- */
@media print{
  .site-header,.fab,.marquee,.scroll-progress,.hero-blobs,.page-ghost ,.cursor-glow,.to-top{ display:none !important; }
  body{ background:#fff; padding:0; }
  .section{ padding:24px 0; page-break-inside:avoid; }
}

/* ---------- 27. 大屏（2K 及以上）尺度补偿 ----------
   问题：正文栏 --wrap 固定 1240px，字号又几乎都 clamp(...) 到了上限，所以在 2560×1440
   （100% 缩放）下会"内容只占视口 48%、字长得和 1080p 一样" —— 看着又小又空。
   实测：1920 下正文栏占视口 65%，2560 下只剩 48%；h1 在两者都是 64px（已被 clamp 卡住）。
   这里只放大"骨架尺度"：正文栏宽度、区块纵向节奏、几个标题/正文级字号。
  ⚠️ 试过更省事的方案：给 html 加 zoom:1.333 一次性整体放大——**实测不可行**：
    · zoom 下 100vh 仍按未缩放的视口算，.hero{min-height:100vh} 会变成 133% 屏高；
    · 会改变视口相关尺寸的计算，与显式布局尺度不一致。
  所以走"显式调大令牌"这条路，宁可少放大几个冷门小字号，也不动 zoom。
   ⚠️ 断点必须 >1920：1920×1080 是客户那边"看着正常"的基准，不能被这条规则改到。 */
@media (min-width: 2100px){
  :root{
    /* ★ 全部改用 vw：数值 = 1080p 下的原值 ÷ 1920 × 100。
       这样 2K/4K 就是把 1080p 那一版**整体等比放大**，比例与 1K 完全一致，
       而不是"只把几处字号调大一点"。 */
    --wrap: 64.6vw;        /* 1240 / 1920 */
    --sec-y: 6.67vw;       /* 128  / 1920 */
  }
  .hero{ padding-top:9.9vw; }            /* 190 / 1920 */
  body{ font-size:0.86vw; }              /* 16.5 / 1920 */
  .hero h1{ font-size:3.02vw; }          /* 58   */
  .hero-lead{ font-size:0.94vw; }        /* 18   */
  .hero-facts b{ font-size:1.72vw; }     /* 33   */
  .hero-facts span{ font-size:0.65vw; }  /* 12.5 */
  .note-ph{ font-size:0.78vw; }          /* 15   */
  .sticker{ font-size:0.68vw; }          /* 13   */
  .sticker em{ font-size:0.55vw; }       /* 10.5 */
  .sec-head h2{ font-size:2.29vw; }      /* 44   */
  .sec-note{ font-size:0.81vw; }         /* 15.5 */
  .card h3{ font-size:1.15vw; }          /* 22   */
  .marquee-group span{ font-size:1.09vw; } /* 21 */
  .nav > a{ font-size:0.76vw; }          /* 14.5 */
  .nav-phone{ font-size:0.76vw; }
  .btn--lg{ font-size:0.83vw; padding:0.83vw 1.67vw; }  /* 16 / 16 32 */
  /* 卡片类正文（13~15px 的硬编码小字）同步等比放大 */
  .card-desc,.dev p,.team p,.perk span,.cred p,.qa-body p,.verify-steps p,
  .motto-list span,.voice p,.flow-list p{ font-size:0.78vw; }
}
