/* ==========================================================================
   forms-fx.css — 15 套皮肤的动效令牌、特效层与布局族（specs/036）
   --------------------------------------------------------------------------
   三条硬规则，写在这里而不是散在 JS 里：
   1) 点按只做局部反馈：波纹 + 频率条 + 弹簧按压，全部只动 transform / opacity；
   2) 整屏不许重新淡入：入场动画只在「首次进入某一路由」时播一次（[data-enter]）；
   3) 每套皮肤有自己的手感：力度、波形、频率根数、错峰、仪式形状，都在 html[data-skin=…] 覆写。
   色值不在这个文件里发明（11 套沿用 skin-<k>.css 的 token，这里只做别名接线）。
   ========================================================================== */

/* ---------- 1. 默认手感（名单外的皮肤一律走这套） ---------- */
html {
  --sq-press: .97;
  --sq-press-dy: 0px;
  --sq-spring: cubic-bezier(.2, .9, .22, 1.07);
  --sq-settle: cubic-bezier(.22, 1, .36, 1);
  --sq-ripple-ms: 480;
  --sq-ripple-shape: 50%;
  --sq-ripple: color-mix(in srgb, var(--accent, #496d60) 26%, transparent);
  --sq-bars: 9;
  --sq-bar-ms: 420;
  --sq-bar-stagger: 26;
  --sq-bar-shape: 50%;
  --sq-bar-color: var(--accent, #496d60);
}

/* ---------- 2. 色板接线：.fe-app 只认 --paper/--ink/--accent/--line ---------- */
/* 11 套旧皮肤：值来自它们自己的 skin-<k>.css，这里只改名，不复制色值 */
html[data-skin="paper"], html[data-skin="booth"], html[data-skin="riso"],
html[data-skin="guochao"], html[data-skin="pixel"], html[data-skin="posthuman"],
html[data-skin="dream"], html[data-skin="petri"], html[data-skin="naive"],
html[data-skin="bauhaus"], html[data-skin="construct"] {
  --sq-paper: var(--paper);
  --sq-ink: var(--ink);
  --sq-accent: var(--vermillion);
  --sq-accent-2: var(--pine);
  --sq-line: var(--line);
  --sq-paper-2: var(--paper-2, var(--paper));
  --sq-paper-3: var(--paper-3, var(--paper));
}
/* 4 套形态：它们没有 token 文件，色板就写在这里（唯一一处） */
html[data-skin="desk"] {
  --sq-paper: #f7f8f4; --sq-paper-2: #ffffff; --sq-paper-3: #eef1ea;
  --sq-ink: #263c38; --sq-accent: #496d60; --sq-accent-2: #496d60; --sq-line: #cfdad3;
}
html[data-skin="map"] {
  --sq-paper: #f0f5f2; --sq-paper-2: #ffffff; --sq-paper-3: #e4ebdf;
  --sq-ink: #263c38; --sq-accent: #47725d; --sq-accent-2: #47725d; --sq-line: #cfdad3;
}
html[data-skin="radio"] {
  --sq-paper: #f6f1f4; --sq-paper-2: #ffffff; --sq-paper-3: #e9dfe6;
  --sq-ink: #4d394c; --sq-accent: #77576a; --sq-accent-2: #77576a; --sq-line: #dfd0db;
}
html[data-skin="theatre"] {
  --sq-paper: #f8f4f0; --sq-paper-2: #ffffff; --sq-paper-3: #efe4df;
  --sq-ink: #583c43; --sq-accent: #8e5667; --sq-accent-2: #8e5667; --sq-line: #dfcdd1;
}
/* 把接线交给 forms 层（同特异性、后加载 → 覆盖 forms-app.css 里写死的那组） */
/* 层叠：app.css 的 body::before / body::after 是 position:fixed + z-index:0 的整屏装饰，
   旧界面靠 .app{position:relative;z-index:1} 站在它们上面。forms 的 .fe-app 少了这一层，
   于是 construct / guochao / bauhaus 等皮肤的一整张背景图直接压在内容上 ——
   用户看到的就是「切完皮肤什么都没有」。别删这两行。 */
body.forms-only { background-color: var(--sq-paper, var(--paper, #e9efed)); }

/* 旧版整屏纸纹（app.css 的 body::before/::after）是给老页面用的。
   四套皮肤自己就有一层纸底，再叠一层灰点会让所有颜色发脏 —— forms 里关掉。 */
body.forms-only::before,
body.forms-only::after { display: none; }
.forms-only .fe-app {
  --paper: var(--sq-paper); --ink: var(--sq-ink);
  --accent: var(--sq-accent); --line: var(--sq-line);
  position: relative; z-index: 1;
  /* 透明而不是再糊一层纸：让 body::after 里那套皮肤自己的底纹透上来 */
  background: transparent; color: var(--ink);
}

/* ---------- 3. 15 套皮肤的手感参数 ---------- */
html[data-skin="desk"] {
  --sq-press: .97; --sq-ripple-ms: 620; --sq-bars: 5; --sq-bar-ms: 640; --sq-bar-stagger: 90;
  --sq-spring: cubic-bezier(.2, .8, .3, 1.02);
}
html[data-skin="map"] {
  --sq-press: .972; --sq-ripple-ms: 520; --sq-bars: 12; --sq-bar-ms: 520; --sq-bar-stagger: 34;
}
html[data-skin="radio"] {
  --sq-press: .965; --sq-ripple-ms: 700; --sq-bars: 15; --sq-bar-ms: 380; --sq-bar-stagger: 22;
  --sq-spring: cubic-bezier(.18, .9, .24, 1.08);
}
html[data-skin="theatre"] {
  --sq-press: .968; --sq-ripple-ms: 420; --sq-bars: 7; --sq-bar-ms: 300; --sq-bar-stagger: 14;
  --sq-bar-shape: 2px; --sq-spring: cubic-bezier(.22, .9, .28, 1.12);
}
html[data-skin="paper"] {
  --sq-press: .976; --sq-ripple-ms: 760; --sq-bars: 3; --sq-bar-ms: 780; --sq-bar-stagger: 150;
  --sq-spring: cubic-bezier(.24, .82, .34, 1.01);
}
html[data-skin="booth"] {
  --sq-press: .98; --sq-ripple-ms: 360; --sq-ripple-shape: 0; --sq-bars: 8;
  --sq-bar-ms: 260; --sq-bar-stagger: 40; --sq-bar-shape: 0;
  --sq-spring: steps(2, end); --sq-settle: steps(2, end);
}
html[data-skin="riso"] {
  --sq-press: .974; --sq-ripple-ms: 520; --sq-ripple-shape: 0; --sq-bars: 10;
  --sq-bar-ms: 420; --sq-bar-stagger: 46; --sq-bar-shape: 0; --sq-spring: steps(6, end);
}
html[data-skin="guochao"] {
  --sq-press: .966; --sq-ripple-ms: 560; --sq-ripple-shape: 8px; --sq-bars: 5;
  --sq-bar-ms: 300; --sq-bar-stagger: 60; --sq-bar-shape: 4px;
  --sq-spring: cubic-bezier(.2, .94, .26, 1.16);
}
html[data-skin="pixel"] {
  --sq-press: 1; --sq-press-dy: 4px; --sq-ripple-ms: 320; --sq-ripple-shape: 0; --sq-bars: 7;
  --sq-bar-ms: 280; --sq-bar-stagger: 40; --sq-bar-shape: 0;
  --sq-spring: steps(4, end); --sq-settle: steps(4, end);
}
html[data-skin="posthuman"] {
  --sq-press: .982; --sq-ripple-ms: 300; --sq-ripple-shape: 0; --sq-bars: 16;
  --sq-bar-ms: 200; --sq-bar-stagger: 12; --sq-bar-shape: 0; --sq-spring: cubic-bezier(.4, 0, .2, 1);
}
html[data-skin="dream"] {
  --sq-press: .98; --sq-ripple-ms: 900; --sq-bars: 15; --sq-bar-ms: 900; --sq-bar-stagger: 40;
  --sq-spring: cubic-bezier(.3, .7, .3, 1);
}
html[data-skin="petri"] {
  --sq-press: .972; --sq-ripple-ms: 820; --sq-bars: 11; --sq-bar-ms: 700; --sq-bar-stagger: 70;
  --sq-spring: cubic-bezier(.18, .74, .24, 1.04);
}
html[data-skin="naive"] {
  --sq-press: .94; --sq-ripple-ms: 520;
  --sq-ripple-shape: 46% 54% 52% 48% / 52% 44% 56% 48%;
  --sq-bars: 9; --sq-bar-ms: 340; --sq-bar-stagger: 28; --sq-bar-shape: 6px;
  --sq-spring: cubic-bezier(.3, 1.5, .5, 1); --sq-settle: cubic-bezier(.3, 1.2, .4, 1);
}
html[data-skin="bauhaus"] {
  --sq-press: .978; --sq-ripple-ms: 420; --sq-bars: 6; --sq-bar-ms: 360; --sq-bar-stagger: 60;
  --sq-bar-shape: 0;
}
html[data-skin="construct"] {
  --sq-press: .985; --sq-ripple-ms: 260; --sq-ripple-shape: 0; --sq-bars: 4;
  --sq-bar-ms: 220; --sq-bar-stagger: 0; --sq-bar-shape: 0;
  --sq-spring: steps(2, end); --sq-settle: steps(2, end);
}

/* ---------- 4. 特效层 ---------- */
.sq-fx {
  position: fixed;
  inset: 0;
  z-index: 9998;
  overflow: hidden;
  pointer-events: none;
}
.sq-ripple {
  position: fixed;
  transform: translate(-50%, -50%) scale(0);
  border-radius: var(--sq-ripple-shape);
  background: var(--sq-ripple);
  animation: sq-ripple calc(var(--sq-ripple-ms) * 1ms) var(--sq-spring) forwards;
}
@keyframes sq-ripple { to { transform: translate(-50%, -50%) scale(1); opacity: 0; } }
.sq-bars {
  position: fixed;
  display: flex;
  gap: 3px;
  align-items: flex-end;
  height: 10px;
}
.sq-bars i {
  flex: 1;
  height: 100%;
  border-radius: var(--sq-bar-shape);
  background: var(--sq-bar-color);
  opacity: .75;
  transform: scaleY(.22);
  transform-origin: bottom;
  animation: sq-bar calc(var(--sq-bar-ms) * 1ms) var(--sq-spring) both;
}
@keyframes sq-bar { 0% { transform: scaleY(.22); } 42% { transform: scaleY(1); } 100% { transform: scaleY(.22); } }

/* 抽取仪式的六种原语，皮肤在注册表里各挑一种 */
.sq-ritual { position: fixed; pointer-events: none; overflow: hidden; border-radius: inherit; }
.sq-ritual--ink {
  background: radial-gradient(circle at 50% 60%, var(--sq-accent) 0 16%, transparent 46%);
  opacity: 0; filter: blur(9px); animation: sq-ink 900ms var(--sq-settle) forwards;
}
@keyframes sq-ink { 0% { opacity: 0; transform: scale(.35); } 30% { opacity: .34; } 100% { opacity: 0; transform: scale(1.5); } }
.sq-ritual--iris {
  background: var(--sq-paper);
  clip-path: circle(4% at 50% 50%);
  animation: sq-iris 760ms var(--sq-spring) forwards;
}
@keyframes sq-iris { from { clip-path: circle(4% at 50% 50%); } to { clip-path: circle(150% at 50% 50%); opacity: 0; } }
.sq-ritual--flip {
  background: repeating-linear-gradient(180deg, rgb(0 0 0 / 9%) 0 2px, transparent 2px 26px);
  transform-origin: top; animation: sq-flip 620ms var(--sq-spring) 2;
}
@keyframes sq-flip { 0% { transform: perspective(420px) rotateX(0); } 50% { transform: perspective(420px) rotateX(-84deg); } 100% { transform: perspective(420px) rotateX(0); } }
.sq-ritual--mis {
  background: linear-gradient(90deg, var(--sq-accent) 0 50%, var(--sq-accent-2) 50% 100%);
  mix-blend-mode: multiply; opacity: .34; animation: sq-mis 700ms steps(6) forwards;
}
@keyframes sq-mis { 0% { transform: translate3d(-9px, 5px, 0); } 100% { transform: none; opacity: 0; } }
.sq-ritual--scan {
  background: linear-gradient(180deg, transparent 0 42%, var(--sq-accent) 46% 54%, transparent 58% 100%);
  animation: sq-scan 780ms var(--sq-settle) forwards;
}
@keyframes sq-scan { from { transform: translateY(-100%); opacity: .9; } to { transform: translateY(100%); opacity: 0; } }
.sq-ritual--bloom {
  background: radial-gradient(circle at 50% 50%, #fff 0 12%, var(--sq-accent) 28%, transparent 62%);
  animation: sq-bloom 900ms var(--sq-settle) forwards;
}
@keyframes sq-bloom { from { opacity: .95; transform: scale(.2); } to { opacity: 0; transform: scale(1.7); } }

/* ---------- 5. 按压反馈：只动 transform ---------- */
.forms-only .fe-btn {
  transition: transform calc(var(--sq-bar-ms) * 1ms) var(--sq-spring),
    box-shadow 220ms var(--sq-settle), background-color 200ms linear, color 200ms linear;
}
.fe-btn.sq-pressed { transform: translate3d(0, var(--sq-press-dy), 0) scale(var(--sq-press)); }
.fe-btn.sq-pressed.fe-primary { box-shadow: 0 0 0 3px var(--sq-ripple); }

/* ---------- 6. 不闪：入场只在首次进入该路由时播一次 ---------- */
/* forms-app.css 的 `.fe-main > * { animation: fe-enter }` 已被改成需要 [data-enter] 才生效 */
.fe-app[data-enter] .fe-main > * { animation: fe-enter 320ms var(--sq-settle) both; }
.fe-app[data-enter] .fe-main > :nth-child(2) { animation-delay: 40ms; }

/* ---------- 7. 布局族：导航方位（注册表 nav 字段） ---------- */
/* bottom 是 forms-app.css 的原样，不用重写 */
.forms-only .fe-app[data-nav="right-rail"] { grid-template-columns: minmax(0, 1fr) 58px; }
.forms-only .fe-app[data-nav="left-rail"] { grid-template-columns: 58px minmax(0, 1fr); }
.forms-only .fe-app[data-nav="right-rail"],
.forms-only .fe-app[data-nav="left-rail"] { grid-template-rows: 66px minmax(0, 1fr); }
/* 右轨在第二列、左轨在第一列 —— 名字得和实际位置对得上 */
.fe-app[data-nav="right-rail"] .fe-header,
.fe-app[data-nav="right-rail"] .fe-main { grid-column: 1; }
.fe-app[data-nav="right-rail"] .fe-nav { grid-column: 2; grid-row: 1 / -1; }
.fe-app[data-nav="left-rail"] .fe-header { grid-column: 2; }
.fe-app[data-nav="left-rail"] .fe-main { grid-column: 2; grid-row: 2; }
.fe-app[data-nav="left-rail"] .fe-nav { grid-column: 1; grid-row: 1 / -1; }
.fe-app[data-nav="right-rail"] .fe-nav,
.fe-app[data-nav="left-rail"] .fe-nav {
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  gap: 6px;
  border-top: 0;
  padding: 10px 4px;
}
.fe-app[data-nav="left-rail"] .fe-nav { border-right: 1px solid var(--line); }
.fe-app[data-nav="right-rail"] .fe-nav { border-left: 1px solid var(--line); }
.fe-app[data-nav="right-rail"] .fe-nav .fe-btn,
.fe-app[data-nav="left-rail"] .fe-nav .fe-btn { min-width: 0; width: 100%; min-height: 44px; padding: 6px 2px; gap: 2px; flex-direction: column; font-size: 10px; }
.fe-app[data-nav="right-rail"] .fe-nav .fe-current,
.fe-app[data-nav="left-rail"] .fe-nav .fe-current { box-shadow: none; background: var(--sq-paper-3); border-radius: 8px; }

.fe-app[data-nav="top-strip"] { grid-template-rows: 66px auto minmax(0, 1fr); }
.fe-app[data-nav="top-strip"] .fe-nav { grid-row: 2; border-top: 0; border-bottom: 1px solid var(--line); }
.fe-app[data-nav="top-strip"] .fe-main { grid-row: 3; }

.fe-app[data-nav="bottom-dots"] .fe-nav { gap: 26px; }
.fe-app[data-nav="bottom-dots"] .fe-nav small { display: none; }
.fe-app[data-nav="bottom-dots"] .fe-nav .fe-btn {
  min-width: 44px; width: 44px; height: 44px; border-radius: 50%;
  background: var(--sq-paper-2); border: 1px solid var(--line); font-size: 9px; padding: 0;
}
.fe-app[data-nav="bottom-dots"] .fe-nav .fe-current { box-shadow: none; background: var(--accent); color: var(--sq-paper); }

.fe-app[data-nav="ring"] { grid-template-rows: 66px minmax(0, 1fr); }
.fe-app[data-nav="ring"] .fe-main { grid-row: 2; }
.fe-app[data-nav="ring"] .fe-nav {
  position: absolute; right: 12px; bottom: 12px; left: 12px; z-index: 3;
  border-top: 0; background: none;
}
.fe-app[data-nav="ring"] .fe-nav .fe-btn {
  min-width: 44px; width: 44px; height: 44px; border-radius: 50%; padding: 0;
  flex-direction: column; gap: 0; font-size: 9px; background: var(--sq-paper-2);
  border: 1px solid var(--line); box-shadow: 0 4px 14px rgb(0 0 0 / 8%);
}
.fe-app[data-nav="ring"] .fe-nav small { display: none; }
.fe-app[data-nav="ring"] .fe-nav .fe-current { box-shadow: none; background: var(--accent); color: var(--sq-paper); }

/* ---------- 8. 主图几何（注册表 hero 字段，plate 渲染器用） ---------- */
.fe-plate { display: grid; gap: 16px; min-height: 0; align-content: start; padding: 22px 0; }
.fe-plate-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 10px; }
.fe-plate-hero { position: relative; min-height: 0; height: min(38vh, 300px); overflow: hidden; background: var(--sq-paper-3); border: 1px solid var(--line); }
.fe-plate-hero .fe-photo { position: absolute; inset: 0; }
.fe-plate-label { position: absolute; z-index: 2; left: 14px; bottom: 14px; padding: 5px 9px; font-size: 10px; background: var(--accent); color: var(--sq-paper); }
.fe-plate-copy { display: grid; gap: 12px; min-height: 0; }
.fe-plate-acts { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

.fe-app[data-hero="letter"] .fe-plate-hero { border-radius: 0; border-width: 0 0 1px; background: var(--sq-paper-2); }
.fe-app[data-hero="board"] .fe-plate-hero { border: 2px solid var(--ink); box-shadow: 6px 6px 0 var(--ink); background: var(--ink); }
.fe-app[data-hero="board"] .fe-plate-label { background: var(--sq-accent); }
.fe-app[data-hero="print"] .fe-plate-hero { box-shadow: -7px 7px 0 var(--sq-accent), 7px -7px 0 var(--sq-accent-2); }
.fe-app[data-hero="seal"] .fe-plate-hero { border: 2px solid var(--ink); }
.fe-app[data-hero="seal"] .fe-plate-hero::after {
  content: ""; position: absolute; z-index: 2; top: 12px; right: 12px; width: 38px; height: 38px;
  border: 2px solid var(--sq-accent); border-radius: 5px; background: rgb(164 41 31 / 78%);
}
.fe-app[data-hero="arcade"] .fe-plate-hero { border: 3px solid var(--ink); border-radius: 0; image-rendering: pixelated; }
.fe-app[data-hero="arcade"] .fe-plate-hero .fe-photo { filter: saturate(1.25) contrast(1.1); }
.fe-app[data-hero="chip"] .fe-plate-hero {
  border: 1px solid var(--ink); border-radius: 0;
  clip-path: polygon(0 0, calc(100% - 22px) 0, 100% 22px, 100% 100%, 22px 100%, 0 calc(100% - 22px));
}
.fe-app[data-hero="cloud"] .fe-plate-hero { border: 0; border-radius: 40px; box-shadow: 0 24px 46px -22px var(--sq-accent-2); }
.fe-app[data-hero="dish"] .fe-plate-hero { border: 6px double var(--ink); border-radius: 50%; height: min(44vh, 320px); }
.fe-app[data-hero="sticker"] .fe-plate-hero { border: 3px dashed var(--ink); border-radius: 22px 26px 20px 28px; transform: rotate(-1.4deg); }
.fe-app[data-hero="grid"] .fe-plate-hero { border: 1px solid var(--ink); display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
.fe-app[data-hero="grid"] .fe-plate-hero::after {
  content: ""; position: absolute; left: 8%; top: 12%; width: 44%; aspect-ratio: 1;
  border-radius: 50%; background: var(--sq-accent);
}
.fe-app[data-hero="cut"] .fe-plate-hero { border: 2px solid var(--ink); }
.fe-app[data-hero="cut"] .fe-plate-hero .fe-photo,
.fe-app[data-hero="cut"] .fe-plate-hero::after { clip-path: polygon(0 0, 100% 18%, 100% 100%, 0 82%); }
.fe-app[data-hero="cut"] .fe-plate-hero::after {
  content: ""; position: absolute; inset: 0; background: linear-gradient(115deg, transparent 0 46%, var(--sq-accent) 46% 58%, transparent 58%);
}
.fe-app[data-hero="sheet"] .fe-plate-hero { border-width: 0 0 1px; border-radius: 0; }
.fe-app[data-hero="finder"] .fe-plate-hero { border-radius: 2px; box-shadow: inset 0 0 0 1px var(--sq-paper); }
.fe-app[data-hero="dial"] .fe-plate-hero { border-radius: 50%; aspect-ratio: 1; height: auto; }

/* 像素皮肤按下是「下沉」而不是缩放 */
.fe-app[data-skin="pixel"] .fe-btn.sq-pressed,
html[data-skin="pixel"] .fe-app .fe-btn.sq-pressed { transform: translate3d(0, 4px, 0); }

/* ---------- 8.5 可滚动页：内容比屏幕长时必须能滚，不能裁 ---------- */
.fe-styles-page, .fe-list-page, .fe-detail, .fe-plate { overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
.fe-styles-page::-webkit-scrollbar, .fe-list-page::-webkit-scrollbar,
.fe-detail::-webkit-scrollbar, .fe-plate::-webkit-scrollbar { display: none; }
/* 列表页是「读字」的地方：铺一层半透纸，皮肤的整屏底图不能穿到字后面 */
.fe-styles-page, .fe-list-page, .fe-detail {
  background: color-mix(in srgb, var(--sq-paper) 88%, transparent);
}

/* ---------- 8.6 皮肤选择页：15 套用「列表 + 缩略图」，别再拿 2 列卡片互压 ---------- */
.fe-styles-page { gap: 14px; padding-top: 20px; padding-bottom: 26px; }
.fe-skin-now {
  display: flex; align-items: center; gap: 14px; padding: 12px 14px;
  border: 1px solid var(--line); background: color-mix(in srgb, var(--sq-paper-2) 78%, transparent);
}
.fe-skin-now-swatch { width: 46px; height: 46px; flex: none; display: grid; place-items: center; gap: 2px; border: 1px solid var(--line); background: var(--sq-paper-3); }
.fe-skin-now-swatch i { display: block; width: 22px; height: 3px; background: var(--accent); }
.fe-skin-now-swatch i:nth-child(2) { opacity: .55; width: 16px; }
.fe-skin-now-copy { display: grid; gap: 3px; min-width: 0; }
.fe-skin-now-copy strong { font-weight: 500; font-size: 15px; }
.fe-skin-now-copy small { font-size: 10px; opacity: .8; }
.fe-style-section { display: grid; gap: 2px; }
.fe-style-section > h2 { font-size: 11px; font-weight: 500; letter-spacing: .12em; opacity: .68; padding: 12px 2px 6px; }
.fe-skin-row {
  width: 100%; display: flex; align-items: center; gap: 14px; padding: 10px 2px;
  border-bottom: 1px solid var(--line); text-align: left; border-radius: 0;
}
.fe-skin-row.is-current { background: color-mix(in srgb, var(--sq-accent) 9%, transparent); }
.fe-skin-thumb {
  width: 58px; height: 72px; flex: none; position: relative; overflow: hidden;
  background: var(--sq-paper-3); border: 1px solid var(--line);
}
.fe-skin-thumb::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 5px;
  background: var(--skin-accent, var(--accent));
}
.fe-skin-thumb img { width: 100%; height: 100%; object-fit: cover; opacity: .92; }
.fe-skin-copy { display: grid; gap: 4px; min-width: 0; flex: 1; }
.fe-skin-copy strong { font-weight: 500; font-size: 15px; }
.fe-skin-copy small { font-size: 10px; line-height: 1.5; opacity: .76; }
.fe-skin-state { flex: none; font-size: 11px; color: var(--accent); }
.fe-skin-row.is-current .fe-skin-state { font-weight: 600; }

/* ---------- 8.7 初次见面：三步有进度、有方向，不再是一列挤在中间 ---------- */
.forms-only .fe-onboard {
  width: min(600px, 100%); height: 100%; margin: auto; padding: 20px 4px;
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 18px;
  justify-content: initial;
}
.fe-onboard-top { display: flex; align-items: center; gap: 14px; }
.fe-onboard-brand { font-family: "Songti SC", "STSong", "SimSun", serif; font-size: 15px; letter-spacing: .06em; flex: none; }
.fe-onboard-progress { display: flex; gap: 5px; flex: 1; }
.fe-onboard-progress i { height: 2px; flex: 1; background: var(--line); transform-origin: left; transition: background-color 240ms linear; }
.fe-onboard-progress i.is-on { background: var(--accent); }
.fe-onboard-step { min-height: 0; display: flex; flex-direction: column; justify-content: center; gap: 22px; animation: fe-step-in 380ms var(--sq-settle) both; }
.fe-onboard-step .fe-onboard-intro { gap: 16px; }
.fe-onboard-step .fe-onboard-intro > .fe-photo { height: 26dvh; max-height: 230px; }
.fe-onboard-step h1 { font-size: clamp(28px, 7.6vw, 40px); line-height: 1.32; }
.fe-onboard-foot { display: flex; align-items: center; gap: 10px; }
.fe-onboard-foot .fe-primary { flex: 1; min-width: 0; }
.fe-onboard-back { flex: none; width: 46px; min-width: 46px; padding: 0; }
.fe-scene-choices button { display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
.fe-scene-check { color: var(--accent); font-weight: 700; }
.fe-locate { display: grid; gap: 7px; padding: 12px 0; border-top: 1px solid var(--line); }
.fe-locate h3 { font-size: 12px; font-weight: 500; }
.fe-locate p { font-size: 11px; line-height: 1.65; }
.fe-locate .fe-btn { justify-self: start; border: 1px solid var(--line); font-size: 12px; }
@keyframes fe-step-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (max-width: 700px) {
  .forms-only .fe-onboard { padding: 14px 0; gap: 12px; }
  .fe-onboard-step { gap: 16px; }
  .fe-onboard-step h1 { font-size: clamp(26px, 7.4vw, 34px); }
  .fe-onboard-step .fe-onboard-intro > .fe-photo { height: 22dvh; }
  .fe-onboard-top .fe-meta { font-size: 9px; }
}
@media (max-height: 720px) {
  .fe-onboard-step { justify-content: flex-start; overflow-y: auto; }
  .fe-onboard-step h1 { font-size: 26px; }
  .fe-onboard-step .fe-onboard-intro > .fe-photo { height: 16dvh; }
  .fe-draw-stage { height: min(330px, 56vh); }
}

/* ---------- 8.8 抽卡：一副牌摊开 → 翻面 → 底下的页面跟着换 ---------- */
.fe-draw { position: fixed; inset: 0; z-index: 9997; display: grid; place-items: center; }
/* 抽卡这一秒里不许点到底下的导航：否则牌还在翻，页面已经被换走了。 */
.fe-draw { pointer-events: auto; }
.fe-draw::before {
  content: ""; position: absolute; inset: 0;
  background: color-mix(in srgb, var(--sq-paper) 82%, transparent);
  backdrop-filter: blur(2px); opacity: 0; transition: opacity 220ms linear;
}
.fe-draw.is-on::before { opacity: 1; }
.fe-draw-stage {
  position: relative; width: min(300px, 74vw); height: min(400px, 58vh);
  perspective: 900px; opacity: 0; transform: scale(.92);
  transition: opacity 220ms linear, transform 420ms var(--sq-spring);
}
.fe-draw.is-on .fe-draw-stage { opacity: 1; transform: none; }
.fe-draw.is-out { opacity: 0; transition: opacity 260ms linear; }
.fe-draw-card {
  position: absolute; inset: 0; padding: 24px 22px 22px; display: flex; flex-direction: column; justify-content: flex-end; gap: 10px;
  background: var(--sq-paper-2); border: 1px solid var(--line); border-radius: 6px;
  box-shadow: 0 22px 50px -24px rgb(0 0 0 / 42%); backface-visibility: hidden;
}
.fe-draw-card.b1 { transform-origin: 50% 90%; background: color-mix(in srgb, var(--sq-paper-3) 70%, var(--sq-paper-2)); }
.fe-draw-card.b2 { transform-origin: 50% 90%; background: var(--sq-paper-3); }
.fe-draw.is-on .b1 { animation: fe-card-fan-l 560ms var(--sq-spring) both; }
.fe-draw.is-on .b2 { animation: fe-card-fan-r 560ms var(--sq-spring) both; }
.fe-draw-card.back { align-items: center; justify-content: center; color: var(--sq-paper); background: var(--accent); border-color: var(--accent); }
.fe-draw-card.back span { font-family: "Songti SC", "STSong", "SimSun", serif; font-size: 22px; letter-spacing: .24em; writing-mode: vertical-rl; }
.fe-draw-card.back small { font-size: 9px; letter-spacing: .22em; opacity: .8; }
.fe-draw.is-on .fe-draw-card.back { animation: fe-card-back-out 220ms 560ms linear forwards; }
.fe-draw-card.front {
  transform: rotateY(180deg); padding: 0; gap: 0; justify-content: normal;
  display: grid; grid-template-rows: minmax(0, 58%) auto;
}
.fe-draw.is-on .fe-draw-card.front { animation: fe-card-flip 560ms 560ms var(--sq-settle) forwards; }
.fe-draw-photo { width: 100%; height: 100%; object-fit: cover; }
.fe-draw-body { display: grid; gap: 7px; padding: 16px 20px 18px; background: var(--sq-paper-2); align-content: start; }
.fe-draw-kicker { font-size: 10px; letter-spacing: .16em; color: var(--accent); }
.fe-draw-card.front strong { font-family: "Songti SC", "STSong", "SimSun", serif; font-size: 25px; font-weight: 500; line-height: 1.4; }
.fe-draw-meta { font-size: 11px; opacity: .74; }
.fe-draw-serial { position: absolute; top: 12px; right: 12px; padding: 3px 6px; font-size: 9px; letter-spacing: .14em; opacity: .72; background: color-mix(in srgb, var(--sq-paper-2) 88%, transparent); }
@keyframes fe-card-fan-l { 0% { transform: none; } 60% { transform: translate(-12px, -8px) rotate(-5deg); } 100% { transform: translate(-7px, -4px) rotate(-3deg); } }
@keyframes fe-card-fan-r { 0% { transform: none; } 60% { transform: translate(12px, -8px) rotate(5deg); } 100% { transform: translate(7px, -4px) rotate(3deg); } }
@keyframes fe-card-flip { from { transform: rotateY(180deg); } to { transform: rotateY(0); } }
@keyframes fe-card-back-out { from { opacity: 1; } to { opacity: 0; } }

/* ---------- 8.9 换皮肤 / 换页：View Transition（圆从手指位置长开） ---------- */
html[data-vt]::view-transition-old(root),
html[data-vt]::view-transition-new(root) { animation-duration: 420ms; animation-timing-function: var(--sq-settle, cubic-bezier(.22, 1, .36, 1)); }
html[data-vt="route"]::view-transition-old(root) { animation-name: sq-vt-out; }
html[data-vt="route"]::view-transition-new(root) { animation-name: sq-vt-in; }
html[data-vt="skin"]::view-transition-old(root) { animation-name: sq-vt-out; animation-duration: 300ms; }
html[data-vt="skin"]::view-transition-new(root) {
  animation-name: sq-vt-circle;
  animation-duration: 560ms;
  animation-timing-function: linear;
}
/* View Transition 已经在轮换整页，内层入场必须关掉，否则一快一慢叠成两下。 */
html[data-vt] .fe-app[data-enter] .fe-main > * { animation: none; }
@keyframes sq-vt-out { to { opacity: 0; } }
@keyframes sq-vt-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes sq-vt-circle { from { clip-path: circle(0 at var(--sq-vt-x, 50%) var(--sq-vt-y, 50%)); } to { clip-path: circle(140% at var(--sq-vt-x, 50%) var(--sq-vt-y, 50%)); } }

/* ---------- 9. 降级：动效全停，但按压必须有看得见的静态反馈 ---------- */
@media (prefers-reduced-motion: reduce) {
  .sq-ripple, .sq-bars i, .sq-ritual, .fe-app[data-enter] .fe-main > *,
  .fe-onboard-step, .fe-draw-card, .fe-draw-stage { animation: none !important; }
  .fe-btn, .fe-btn.sq-pressed { transition: none; transform: none; }
  .fe-btn.sq-pressed { outline: 3px solid var(--sq-accent); outline-offset: 2px; }
  .fe-draw { display: none; }
}
