/* ==========================================================================
   镇史馆·借物单 —— 设计系统
   风格：新拟物（双向软阴影）+ 高斯玻璃（backdrop-filter）
   配色：莫兰迪灰米打底，天青作主色，陶红只留给「镇」这枚印
   铁律：全站不使用任何渐变函数（linear-gradient / radial-gradient 一律不出现），
        层次全部由「实色 + 软阴影 + SVG 纸纹 + 模糊」堆出来
   ========================================================================== */

:root{
  color-scheme: light;   /* 明确只支持浅色，别让系统深色模式把纸色反相 */
  /* ---------- 莫兰迪底色：偏灰的米，不刺眼 ---------- */
  --paper:      #e8e4dd;
  --paper-deep: #ded9d0;
  --surface:    #efebe4;
  --white:      #fbf9f5;

  /* ---------- 墨色：三级就够，别再多 ---------- */
  --ink:   #2c302e;
  --ink-2: #5b625f;
  --ink-3: #868d89;

  /* ---------- 天青：主色，取自汝窑「雨过天青」 ---------- */
  --cyan:      #7fa8ae;
  --cyan-deep: #577f86;
  --cyan-soft: #d9e5e6;

  /* ---------- 莫兰迪点缀，用于状态区分 ---------- */
  --sage: #97a38f;
  --rose: #c0a5a0;
  --lilac:#a69fac;

  /* ---------- 陶红：全场唯一的暖色，只给镇印 ---------- */
  --seal: #a3472b;

  /* ---------- 新拟物阴影：一亮一暗，同一光源 ---------- */
  --out: 7px 7px 16px rgba(150,142,130,.42), -7px -7px 16px rgba(255,255,255,.86);
  --out-sm: 4px 4px 9px rgba(150,142,130,.34), -4px -4px 9px rgba(255,255,255,.76);
  --in: inset 4px 4px 9px rgba(150,142,130,.38), inset -4px -4px 9px rgba(255,255,255,.82);
  --in-sm: inset 2px 2px 5px rgba(150,142,130,.30), inset -2px -2px 5px rgba(255,255,255,.70);

  /* ---------- 间距：只用这几档，避免随手写数字 ---------- */
  --s1: 6px;  --s2: 10px; --s3: 14px;
  --s4: 20px; --s5: 28px; --s6: 40px; --s7: 56px;

  --r-sm: 10px; --r-md: 16px; --r-lg: 22px; --r-xl: 30px;

  --mono: "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --font: "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", system-ui, sans-serif;
}

*, *::before, *::after{ box-sizing: border-box; }

html, body{ height: 100%; }

body{
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background-color: var(--paper);
  /* 纸纹 + 网格：两层 SVG 平铺，没有任何渐变 */
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M28 0H0V28' fill='none' stroke='%232c302e' stroke-opacity='0.05' stroke-width='1'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

/* ==========================================================================
   顶栏：左边是「镇」印，右边是步骤轨
   ========================================================================== */

.topbar{
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s3) var(--s5);
  background: rgba(232,228,221,.72);
  -webkit-backdrop-filter: blur(18px) saturate(120%);
  backdrop-filter: blur(18px) saturate(120%);
  border-bottom: 1px solid rgba(255,255,255,.55);
}

.brand{ display: flex; align-items: center; gap: var(--s3); flex: none; }

.brand__seal{
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  font-size: 19px; font-weight: 700; color: var(--seal);
  border: 2px solid var(--seal); border-radius: 9px;
  background: rgba(251,249,245,.7);
  box-shadow: var(--out-sm);
}

.brand__name{ font-size: 16px; font-weight: 700; letter-spacing: .5px; line-height: 1.3; }
.brand__sub{ font-size: 11.5px; color: var(--ink-3); letter-spacing: 1.6px; }

/* ---------- 步骤轨 ---------- */
.rail{ display: flex; align-items: center; gap: clamp(4px, 1.4vw, 18px); margin-left: auto; }

.rail__item{
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--ink-3); letter-spacing: .5px;
  text-decoration: none; white-space: nowrap;
  padding: 4px 6px; border-radius: 20px;
  transition: color .25s ease;
}

.rail__dot{
  width: 24px; height: 24px; flex: none;
  display: grid; place-items: center;
  font-size: 11.5px; font-weight: 700;
  color: var(--ink-3);
  border-radius: 50%;
  background: var(--paper);
  box-shadow: var(--out-sm);
  transition: color .25s ease, box-shadow .25s ease, transform .25s cubic-bezier(.34,1.56,.64,1);
}

.rail__item.is-done{ color: var(--cyan-deep); }
.rail__item.is-done .rail__dot{ color: var(--cyan-deep); box-shadow: var(--in-sm); }

.rail__item.is-now{ color: var(--ink); font-weight: 700; }
.rail__item.is-now .rail__dot{
  color: var(--white); background: var(--cyan-deep);
  box-shadow: 0 3px 10px rgba(87,127,134,.42);
  transform: scale(1.12);
}

/* ==========================================================================
   舞台与卡片
   ========================================================================== */

.shell{
  max-width: 880px;
  margin: 0 auto;
  padding: var(--s5) var(--s5) 132px;
}

/* 玻璃卡片：背后有网格和色块可模糊，才看得出是玻璃 */
.card{
  position: relative;
  border-radius: var(--r-xl);
  padding: var(--s6);
  background: rgba(251,249,245,.62);
  -webkit-backdrop-filter: blur(26px) saturate(118%);
  backdrop-filter: blur(26px) saturate(118%);
  border: 1px solid rgba(255,255,255,.66);
  box-shadow: var(--out), 0 18px 46px rgba(120,113,102,.14);
}

/* 新拟物：同色系的哑光块，用来托内容 */
.slab{
  border-radius: var(--r-lg);
  background: var(--paper);
  box-shadow: var(--in);
  padding: var(--s4);
}

.slab--out{ box-shadow: var(--out); background: var(--surface); }

/* ==========================================================================
   文字层级
   ========================================================================== */

.eyebrow{
  font-size: 11.5px; letter-spacing: 3px; color: var(--ink-3);
  font-weight: 700; margin: 0 0 var(--s2);
}

h1{ font-size: clamp(23px, 3.2vw, 30px); line-height: 1.35; margin: 0 0 var(--s2); font-weight: 700; letter-spacing: .5px; }
h2{ font-size: 17px; line-height: 1.5; margin: 0 0 var(--s2); font-weight: 700; }
h3{ font-size: 14.5px; margin: 0 0 var(--s1); font-weight: 700; }

p{ margin: 0 0 var(--s3); line-height: 1.72; font-size: 15px; color: var(--ink-2); }
p.lead{ font-size: 16px; color: var(--ink-2); }
p:last-child{ margin-bottom: 0; }

.muted{ color: var(--ink-3); }
.tiny{ font-size: 12.5px; line-height: 1.65; color: var(--ink-3); }
strong{ color: var(--ink); font-weight: 700; }

/* 数字用等宽，跳动时不抖 */
.num{ font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   表单
   ========================================================================== */

.field{ margin: 0 0 var(--s4); }
.field:last-child{ margin-bottom: 0; }

.field__label{
  display: flex; align-items: baseline; gap: var(--s2);
  font-size: 13.5px; font-weight: 700; color: var(--ink);
  margin-bottom: var(--s2); letter-spacing: .4px;
}

.input, .textarea{
  display: block; width: 100%;
  font: inherit; font-size: 16px; color: var(--ink);
  padding: 15px 18px;
  border: 1px solid rgba(255,255,255,.7);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--in);
  outline: none;
  transition: box-shadow .22s ease, border-color .22s ease;
}

.textarea{ line-height: 1.75; resize: none; min-height: 84px; }

.input::placeholder, .textarea::placeholder{ color: var(--ink-3); opacity: 1; }

.input:focus, .textarea:focus{
  border-color: var(--cyan);
  box-shadow: var(--in), 0 0 0 3px rgba(127,168,174,.26);
}

.input.is-bad, .textarea.is-bad{
  border-color: var(--rose);
  box-shadow: var(--in), 0 0 0 3px rgba(192,165,160,.34);
}

/* 就近报错，不让它跑到页面顶上 */
.field__err{
  display: none; align-items: center; gap: 6px;
  font-size: 13px; color: #9c4436; font-weight: 700;
  margin-top: var(--s2);
}
.field__err.is-on{ display: flex; }
.field__err::before{ content: "!"; display: grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; background: #9c4436; color: #fff; font-size: 11px; flex: none; }

/* ==========================================================================
   按钮
   ========================================================================== */

.btn{
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: inherit; font-size: 16px; font-weight: 700; letter-spacing: .8px;
  color: var(--ink);
  padding: 15px 30px;
  border: 1px solid rgba(255,255,255,.7);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--out);
  cursor: pointer;
  transition: transform .18s cubic-bezier(.34,1.4,.64,1), box-shadow .18s ease, background .18s ease;
  -webkit-user-select: none; user-select: none;
}

.btn:hover{ transform: translateY(-1px); }
.btn:active{ transform: translateY(1px); box-shadow: var(--in-sm); }
.btn:disabled{ opacity: .5; cursor: not-allowed; transform: none; box-shadow: var(--out-sm); }

.btn--primary{
  color: var(--white);
  background: var(--cyan-deep);
  border-color: rgba(255,255,255,.28);
  box-shadow: 0 6px 16px rgba(87,127,134,.34), inset 0 1px 0 rgba(255,255,255,.22);
}
.btn--primary:hover{ box-shadow: 0 9px 22px rgba(87,127,134,.4), inset 0 1px 0 rgba(255,255,255,.22); }

.btn--ghost{ background: transparent; box-shadow: none; border-color: rgba(44,48,46,.16); color: var(--ink-2); font-weight: 600; }
.btn--ghost:hover{ background: rgba(251,249,245,.7); box-shadow: var(--out-sm); }

.btn--danger{ color: #9c4436; }
.btn--sm{ font-size: 13.5px; padding: 9px 18px; letter-spacing: .4px; }
.btn--block{ width: 100%; }

.btn__kbd{ font-family: var(--mono); font-size: 11px; opacity: .5; font-weight: 400; }

/* ==========================================================================
   选项卡片（卡通风格二选一）
   ========================================================================== */

.opts{ display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }

.opt{
  text-align: left; cursor: pointer;
  padding: var(--s4);
  border-radius: var(--r-lg);
  border: 1px solid rgba(255,255,255,.6);
  background: var(--surface);
  box-shadow: var(--out-sm);
  transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
.opt:hover{ transform: translateY(-2px); }
.opt.is-sel{
  border-color: var(--cyan);
  box-shadow: var(--in-sm), 0 0 0 2px var(--cyan);
}

.opt__ico{ display: block; margin-bottom: var(--s2); color: var(--cyan-deep); }
.opt__title{ display: block; font-size: 15px; font-weight: 700; margin-bottom: 2px; }
.opt__desc{ display: block; font-size: 12.5px; color: var(--ink-3); }

/* 卡片里的小字副标题：单独一行，别和标题挤在一起 */
.sub{ display: block; font-size: 12.5px; line-height: 1.6; color: var(--ink-3); margin-top: 3px; }

/* ==========================================================================
   录音
   ========================================================================== */

.clock{
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: clamp(38px, 7vw, 54px); font-weight: 300;
  letter-spacing: 4px; color: var(--cyan-deep);
  text-align: center; margin: 0;
}

.recwrap{ display: grid; justify-items: center; gap: var(--s3); padding: var(--s5) 0; }

.recbtn{
  width: 150px; height: 150px; border-radius: 50%;
  display: grid; place-items: center; gap: 4px;
  border: 1px solid rgba(255,255,255,.7);
  background: var(--surface);
  box-shadow: var(--out), 0 14px 30px rgba(87,127,134,.18);
  color: var(--cyan-deep);
  font: inherit; font-size: 15px; font-weight: 700;
  cursor: pointer;
  transition: transform .2s cubic-bezier(.34,1.5,.64,1), box-shadow .25s ease, background .25s ease, color .25s ease;
}
/* 围绕录音钮：轨道不动，一颗小球沿轨迹跑；左升右落，顶上慢、底下快 */
.recstage{
  position: relative; display: grid; place-items: center;
  width: 220px; height: 220px; margin: 0 auto;
}
.recing{
  position: absolute; inset: 0; width: 100%; height: 100%;
  transform: rotate(-90deg); overflow: visible; pointer-events: none;
}
.recing__base{ fill: none; stroke: rgba(120,113,102,.16); stroke-width: 1.5; }
.recing__arc{
  fill: none; stroke: var(--cyan); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 628.32; stroke-dashoffset: 628.32;
  transition: stroke-dashoffset .18s linear, stroke .45s ease;
}

/* 球：整块绕中心转，球钉在正上方，于是走出一圈 */
.recball{
  position: absolute; inset: 0; pointer-events: none;
  opacity: .55;
  animation: orbit 4.2s infinite;
}
.recball i{
  position: absolute; left: 50%; top: 10px;   /* 让球心落在半径 100 的轨道上 */
  width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px; border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 3px 8px rgba(87,127,134,.32);
}

/* 一圈两段：前半圈加速落到底，后半圈减速回到顶 */
@keyframes orbit{
  0%   { transform: rotate(0deg);   animation-timing-function: cubic-bezier(.72,0,1,.32); }
  50%  { transform: rotate(180deg); animation-timing-function: cubic-bezier(0,.68,.28,1); }
  100% { transform: rotate(360deg); }
}

.recstage.is-rec .recball{ opacity: 1; animation-duration: 2.4s; }
.recstage.is-rec .recball i{ background: var(--cyan-deep); }
.recstage.is-done .recball{ animation: none; transform: rotate(0deg); opacity: 1; }
.recstage.is-done .recball i{ background: var(--sage); }
.recstage.is-done .recing__arc{ stroke: var(--sage); }

.recbtn:hover{ transform: scale(1.02); }
.recbtn:active{ transform: scale(.97); box-shadow: var(--in); }

.recbtn.is-on{
  color: #fff; background: var(--cyan-deep);
  box-shadow: 0 0 0 10px rgba(127,168,174,.16), 0 10px 26px rgba(87,127,134,.4);
  animation: breathe 1.9s ease-in-out infinite;
}

@keyframes breathe{
  0%,100%{ box-shadow: 0 0 0 10px rgba(127,168,174,.16), 0 10px 26px rgba(87,127,134,.4); }
  50%    { box-shadow: 0 0 0 20px rgba(127,168,174,.06), 0 10px 26px rgba(87,127,134,.4); }
}

/* 电平：五格，够看清有没有声音，不追求频谱 */
.meter{ display: flex; align-items: flex-end; gap: 6px; height: 30px; margin-bottom: var(--s3); }
.meter i{
  width: 9px; height: 10px; border-radius: 5px;
  background: var(--paper-deep);
  box-shadow: var(--in-sm);
  transition: height .12s ease, background .12s ease;
}
.meter i.is-lit{ background: var(--cyan); box-shadow: none; }

/* ==========================================================================
   进度
   ========================================================================== */

.bar{
  height: 14px; border-radius: 999px;
  background: var(--paper-deep);
  box-shadow: inset 0 1px 3px rgba(120,113,102,.26), inset 0 -1px 0 rgba(251,249,245,.7);
  overflow: hidden;
}
.bar__fill{
  height: 100%; width: 0%;
  border-radius: 999px;
  background: var(--cyan);
  box-shadow: 0 0 14px rgba(127,168,174,.7);
  transition: width .5s cubic-bezier(.4,0,.2,1);
}

/* 播放器：外面套一层凹槽，让原生控件不至于白得刺眼 */
.player-slot{ padding: var(--s2); }
.player-slot audio{ display: block; width: 100%; }
.player-slot video{
  display: block; width: 100%; height: auto;
  border-radius: var(--r-md); background: var(--paper-deep);
}

/* ==========================================================================
   换页：一张纸从下往上盖住，新页面再从上方抽走——像翻过一页借物单
   ========================================================================== */
.sheet{
  position: fixed; inset: -1px; z-index: 96;
  background-color: var(--paper);
  /* 和 body 同一套纸纹，盖上来时不会突然变一块死板的纯色 */
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M28 0H0V28' fill='none' stroke='%232c302e' stroke-opacity='0.05' stroke-width='1'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
  pointer-events: none;
  display: grid; place-items: center;
  will-change: transform;
}
/* 进场：HTML 里写死的空纸，加载即向上抽走 */
/* 进场：HTML 里写死的空纸，加载即抽走。
   走哪一种是“语义”不是随机：前进往上翻、后退往下退、去旁支横扫、回门口缩放。 */
.sheet--in{
  transform: translateY(-100%);
  box-shadow: 0 24px 46px rgba(43,36,32,.16);
  animation: sheetUp .5s cubic-bezier(.66,0,.34,1) forwards;
}
html[data-move="up"]   .sheet--in{ animation-name: sheetUp; }
html[data-move="down"] .sheet--in{ animation-name: sheetDown; }
html[data-move="side"] .sheet--in{ animation-name: sheetSide; }
html[data-move="diag"] .sheet--in{ animation-name: sheetDiag; transform-origin: 50% 100%; }
html[data-move="zoom"] .sheet--in{ animation-name: sheetZoom; }

@keyframes sheetUp{
  from{ transform: translateY(0);      box-shadow: 0 24px 46px rgba(43,36,32,.16); }
  to  { transform: translateY(-100%);  box-shadow: 0 8px 18px rgba(43,36,32,0); }
}
@keyframes sheetDown{
  from{ transform: translateY(0);      box-shadow: 0 -24px 46px rgba(43,36,32,.16); }
  to  { transform: translateY(100%);   box-shadow: 0 -8px 18px rgba(43,36,32,0); }
}
@keyframes sheetSide{
  from{ transform: translateX(0);      box-shadow: -26px 0 48px rgba(43,36,32,.15); }
  to  { transform: translateX(-100%);  box-shadow: -8px 0 18px rgba(43,36,32,0); }
}
@keyframes sheetDiag{
  from{ transform: rotate(0deg) translate(0,0);      box-shadow: -20px -20px 48px rgba(43,36,32,.16); }
  to  { transform: rotate(-4deg) translate(-14%,-100%); box-shadow: 0 8px 18px rgba(43,36,32,0); }
}
@keyframes sheetZoom{
  from{ transform: scale(1);    opacity: 1; }
  to  { transform: scale(1.07); opacity: 0; }
}

/* 退场：从哪边进来，盖上来时的投影也跟着换方向 */
.sheet--out{
  transform: translateY(100%);
  box-shadow: 0 -24px 46px rgba(43,36,32,.18);
  transition: transform .42s cubic-bezier(.66,0,.34,1), opacity .42s ease;
}
.sheet--out--down{ transform: translateY(-100%); box-shadow: 0 24px 46px rgba(43,36,32,.18); }
.sheet--out--side{ transform: translateX(100%);  box-shadow: -24px 0 46px rgba(43,36,32,.18); }
.sheet--out--zoom{
  transform: scale(.93); opacity: 0;
  /* 不透明度先到位，别让后一页从纸里透出来；缩放慢慢稳 */
  transition: transform .42s cubic-bezier(.66,0,.34,1), opacity .16s ease;
}
.sheet--out.is-on{ transform: none; opacity: 1; pointer-events: auto; }
.sheet--out--zoom.is-on{ transform: scale(1); }
.sheet--out--diag{
  transform: translate(30%, 100%) rotate(7deg);
  transform-origin: 50% 100%;
  box-shadow: -20px -20px 48px rgba(43,36,32,.18);
}
.sheet--out--diag.is-on{ transform: rotate(0deg); }

.sheet__seal{
  position: relative;
  width: 58px; height: 58px; border-radius: 10px;
  display: grid; place-items: center;
  border: 2px solid var(--seal); color: var(--seal);
  font-size: 30px; font-weight: 700;
  opacity: 0; transform: scale(.84) rotate(-6deg);
  transition: opacity .22s .1s ease, transform .3s .1s cubic-bezier(.34,1.4,.64,1);
}
.sheet--out.is-on .sheet__seal{ opacity: .92; transform: scale(1) rotate(-6deg); }
.sheet__seal::after{
  content: ""; position: absolute; inset: -7px; border-radius: 15px;
  border: 1.5px solid var(--seal);
  opacity: 0; transform: scale(1);
}
.sheet--out.is-on .sheet__seal::after{
  animation: sealBurst .78s cubic-bezier(.2,.7,.3,1) .05s forwards;
}
@keyframes sealBurst{
  0%  { opacity: .45; transform: scale(1); }
  100%{ opacity: 0;   transform: scale(2.5); }
}

/* ---- 换页时让「页面本身」也跟着动，而不只是纸盖上来 --------------------
   只有纸在动的话，五个方向看起来都差不多；页面同向偏移才有「被推走」的手感。 */
.shell, .nav{
  transition: transform .42s cubic-bezier(.66,0,.34,1),
              opacity .42s ease,
              filter .42s ease;
}
html.is-leaving-up   .shell, html.is-leaving-up   .nav{ transform: translateY(-11%); opacity: .45; }
html.is-leaving-down .shell, html.is-leaving-down .nav{ transform: translateY(11%);  opacity: .45; }
html.is-leaving-side .shell, html.is-leaving-side .nav{ transform: translateX(-20%); opacity: .40; }
html.is-leaving-diag .shell, html.is-leaving-diag .nav{ transform: translate(-8%,9%) rotate(2.4deg); opacity: .40; }
html.is-leaving-zoom .shell, html.is-leaving-zoom .nav{ transform: scale(1.09); opacity: .18; filter: blur(7px); }

/* 落地页从反方向滑进来，纸揭开时正好接上 */
html[data-move="up"]   .shell{ animation: shellInUp   .52s cubic-bezier(.2,.9,.28,1) both; }
html[data-move="down"] .shell{ animation: shellInDown .52s cubic-bezier(.2,.9,.28,1) both; }
html[data-move="side"] .shell{ animation: shellInSide .52s cubic-bezier(.2,.9,.28,1) both; }
html[data-move="diag"] .shell{ animation: shellInDiag .54s cubic-bezier(.2,.9,.28,1) both; }
html[data-move="zoom"] .shell{ animation: shellInZoom .56s cubic-bezier(.2,.9,.28,1) both; }

@keyframes shellInUp  { from{ transform: translateY(9%); }  to{ transform: none; } }
@keyframes shellInDown{ from{ transform: translateY(-9%); } to{ transform: none; } }
@keyframes shellInSide{ from{ transform: translateX(14%); } to{ transform: none; } }
@keyframes shellInDiag{ from{ transform: translate(6%,-7%) rotate(-2deg); } to{ transform: none; } }
@keyframes shellInZoom{ from{ transform: scale(.94); filter: blur(5px); opacity: .6; } to{ transform: none; filter: none; opacity: 1; } }

@media (prefers-reduced-motion: reduce){
  .shell, .nav{ transition: none; animation: none; }
  html.is-leaving-up .shell, html.is-leaving-up .nav,
  html.is-leaving-down .shell, html.is-leaving-down .nav,
  html.is-leaving-side .shell, html.is-leaving-side .nav,
  html.is-leaving-diag .shell, html.is-leaving-diag .nav,
  html.is-leaving-zoom .shell, html.is-leaving-zoom .nav{ transform: none; opacity: 1; filter: none; }
}

@media (prefers-reduced-motion: reduce){
  .sheet--in{ display: none; }
  .sheet--out{ transition: none; }
}

/* ==========================================================================
   底部导航
   ========================================================================== */

.nav{
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s5) calc(var(--s3) + env(safe-area-inset-bottom));
  background: rgba(232,228,221,.74);
  -webkit-backdrop-filter: blur(20px) saturate(120%);
  backdrop-filter: blur(20px) saturate(120%);
  border-top: 1px solid rgba(255,255,255,.6);
}
.nav__inner{ display: flex; align-items: center; gap: var(--s3); width: 100%; max-width: 880px; margin: 0 auto; }
.nav .btn{ flex: none; }
.nav .btn--grow{ flex: 1; }

/* ==========================================================================
   提示条
   ========================================================================== */

.toast{
  position: fixed; left: 50%; bottom: 108px; z-index: 80;
  transform: translate(-50%, 14px);
  opacity: 0; pointer-events: none;
  padding: 13px 24px; border-radius: 999px;
  font-size: 14px; font-weight: 700; color: var(--ink);
  background: rgba(251,249,245,.94);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid rgba(255,255,255,.7);
  box-shadow: 0 10px 30px rgba(120,113,102,.24);
  transition: opacity .28s ease, transform .28s cubic-bezier(.34,1.4,.64,1);
  white-space: nowrap; max-width: 90vw; overflow: hidden; text-overflow: ellipsis;
}
.toast.is-on{ opacity: 1; transform: translate(-50%, 0); }

/* ==========================================================================
   登录门
   ========================================================================== */

.gate{
  position: fixed; left: 0; right: 0; z-index: 70;
  /* 跟着「看得见的那块」走：手机弹出键盘时 fixed 不会自己缩，靠 JS 写的这两个变量兜住 */
  top: var(--vvt, 0px);
  height: var(--vvh, 100dvh);
  /* 用 flex + margin:auto 而不是 grid 居中：卡片比屏幕高时不会被裁掉顶边 */
  display: flex; flex-direction: column;
  overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: var(--s5);
  background: rgba(232,228,221,.55);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.gate.is-off{ display: none; }

/* 门开着的时候，后面的页面不许滚——手机上那条多余的滚动条就是它 */
body.gate-open{ overflow: hidden; overscroll-behavior: none; }

/* 键盘把屏幕挤小的时候：内容一样，只是把留白和印章收一收，
   保证「印章 + 镇史馆 + 输入框」永远整块看得见。 */
html.kb .gate{ padding: 10px; }
html.kb .gate__card{ padding: 18px 16px 16px; }
html.kb .gate__seal{
  width: 40px; height: 40px; margin: 0 auto 10px;
  font-size: 19px; border-width: 2px; border-radius: 9px;
  transition: width .38s cubic-bezier(.4,0,.2,1), height .38s cubic-bezier(.4,0,.2,1),
              font-size .38s ease, margin .38s ease;
}
html.kb .gate__input{ padding: 13px; font-size: 18px; }

/* 换挡时给一点「吸附」的反馈：卡片轻微回弹 + 印章抖出一圈印痕 */
html.kb .gate__card.kb-snap{ animation: gateSnap .46s cubic-bezier(.2,.9,.3,1.02) both; }
@keyframes gateSnap{
  from{ transform: scale(.965); }
  60% { transform: scale(1.008); }
  to  { transform: none; }
}
.gate__seal{ position: relative; }
.gate__seal::after{
  content: ""; position: absolute; inset: -6px; border-radius: 12px;
  border: 1.5px solid var(--seal); opacity: 0; pointer-events: none;
}
html.kb .gate__seal.snap::after{
  animation: sealBurst .72s cubic-bezier(.2,.7,.3,1) forwards;
}

.gate__card{
  width: min(430px, 100%);
  margin: auto;              /* 有空间就居中，没空间就贴顶，绝不裁切 */
  padding: var(--s6) var(--s5) var(--s5);
  text-align: center;
}

.gate__seal{
  width: 62px; height: 62px; margin: 0 auto var(--s4);
  display: grid; place-items: center;
  font-size: 29px; font-weight: 700; color: var(--seal);
  border: 2.5px solid var(--seal); border-radius: 13px;
  background: rgba(251,249,245,.62);
  box-shadow: var(--out-sm);
}

.gate__input{
  width: 100%; font: inherit; font-size: 20px; font-weight: 600;
  text-align: center; letter-spacing: 3px;
  padding: 17px;
  border: 1px solid rgba(255,255,255,.7);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--in);
  outline: none;
  transition: box-shadow .2s ease, border-color .2s ease;
}
.gate__input:focus{ border-color: var(--cyan); box-shadow: var(--in), 0 0 0 3px rgba(127,168,174,.26); }
.gate__input::placeholder{ letter-spacing: 2px; color: var(--ink-3); }

.gate__hints{ min-height: 52px; margin-top: var(--s2); display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.gate__hints:empty{ min-height: 0; }   /* 没候选就别留一个空洞 */

/* ---------- 登入确认 ---------- */
.ask{
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  padding: var(--s5);
  background: rgba(43,36,32,.26);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  animation: askFade .22s ease both;
}
.ask[hidden]{ display: none; }
.ask__card{
  width: min(360px, 100%);
  margin: auto;
  padding: var(--s6) var(--s5) var(--s5);
  text-align: center;
  border-radius: var(--r-lg);
  background: var(--white);
  box-shadow: 0 26px 60px rgba(43,36,32,.24), inset 0 1px 0 #fff;
  animation: askPop .3s cubic-bezier(.2,.9,.3,1.04) both;
}
.ask__k{ margin: 0; font-size: 13.5px; letter-spacing: 1px; color: var(--ink-3); }
.ask__name{
  margin: var(--s3) 0 var(--s5);
  font-size: 30px; font-weight: 700; letter-spacing: 4px; color: var(--ink);
  word-break: break-all;
}
.ask__row{ display: flex; gap: var(--s2); }
.ask__row .btn{ flex: 1; }
@keyframes askFade{ from{ opacity: 0; } to{ opacity: 1; } }
@keyframes askPop{
  from{ opacity: 0; transform: translateY(14px) scale(.96); }
  to  { opacity: 1; transform: none; }
}

.hint-chip{
  font: inherit; font-size: 14.5px; font-weight: 600;
  padding: 9px 18px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,.7);
  background: var(--surface); color: var(--ink-2);
  box-shadow: var(--out-sm); cursor: pointer;
  transition: transform .16s ease, box-shadow .16s ease;
}
.hint-chip:hover{ transform: translateY(-1px); }
.hint-chip:active{ box-shadow: var(--in-sm); }

/* ==========================================================================
   换页入场动画：每页 data-motion 不同，所以翻页手感不一样
   ========================================================================== */

[data-motion] .card{ animation-duration: .62s; animation-timing-function: cubic-bezier(.22,.9,.28,1); animation-fill-mode: both; }

[data-motion="rise"]  .card{ animation-name: m-rise; }
[data-motion="slide"] .card{ animation-name: m-slide; }
[data-motion="zoom"]  .card{ animation-name: m-zoom; }
[data-motion="blur"]  .card{ animation-name: m-blur; }
[data-motion="flip"]  .card{ animation-name: m-flip; }
[data-motion="drift"] .card{ animation-name: m-drift; }
[data-motion="settle"] .card{ animation-name: m-settle; }

@keyframes m-rise{  from{ opacity: 0; transform: translateY(26px); } to{ opacity: 1; transform: none; } }
@keyframes m-slide{ from{ opacity: 0; transform: translateX(34px); } to{ opacity: 1; transform: none; } }
@keyframes m-zoom{  from{ opacity: 0; transform: scale(.94); }       to{ opacity: 1; transform: none; } }
@keyframes m-blur{  from{ opacity: 0; filter: blur(12px); }          to{ opacity: 1; filter: blur(0); } }
@keyframes m-flip{  from{ opacity: 0; transform: perspective(900px) rotateX(9deg) translateY(20px); } to{ opacity: 1; transform: none; } }
@keyframes m-drift{ from{ opacity: 0; transform: translateY(-22px) scale(1.02); } to{ opacity: 1; transform: none; } }
@keyframes m-settle{from{ opacity: 0; transform: translateY(14px) scale(.99); filter: blur(6px); } to{ opacity: 1; transform: none; filter: blur(0); } }

/* 支持跨页 View Transition 的浏览器，再用一次交叉淡入把硬切盖住 */
@view-transition{ navigation: auto; }
::view-transition-old(root){ animation: vt-out .34s ease both; }
::view-transition-new(root){ animation: vt-in .46s cubic-bezier(.22,.9,.28,1) both; }
@keyframes vt-out{ to{ opacity: 0; } }
@keyframes vt-in{ from{ opacity: 0; } }

/* ==========================================================================
   动效：逐字入场 / 按钮涟漪 / 录音环自绘
   ========================================================================== */

.chline{ display: inline; }
.ch{
  display: inline-block;
  animation: chIn .56s cubic-bezier(.22,.9,.28,1) both;
  animation-delay: calc(var(--i, 0) * 24ms + 40ms);
  will-change: transform, opacity, filter;
}
@keyframes chIn{
  from{ opacity: 0; transform: translateY(.36em) rotate(1.4deg); filter: blur(7px); }
  to  { opacity: 1; transform: none; filter: blur(0); }
}

.btn, .recbtn{ position: relative; overflow: hidden; }
.ripple{
  position: absolute; border-radius: 50%; pointer-events: none;
  background: rgba(87,127,134,.19);
  transform: scale(.15); opacity: .95;
  animation: rippleOut .46s cubic-bezier(.2,.8,.3,1) forwards;
}
.ripple--light{ background: rgba(255,255,255,.30); }
@keyframes rippleOut{ to{ transform: scale(1); opacity: 0; } }

.recing__base{
  transition: stroke-dashoffset .95s cubic-bezier(.4,.1,.3,1) .18s;
}

@media (prefers-reduced-motion: reduce){
  .ch{ animation: none; }
  .ripple{ display: none; }
  .recing__base{ transition: none; }
}

/* ==========================================================================
   滚动条：小窗口下卡片内部滚动，条子要看得见但不碍眼
   ========================================================================== */

.card::-webkit-scrollbar, .scroll::-webkit-scrollbar{ width: 8px; height: 8px; }
.card::-webkit-scrollbar-track, .scroll::-webkit-scrollbar-track{ background: transparent; }
.card::-webkit-scrollbar-thumb, .scroll::-webkit-scrollbar-thumb{
  background: rgba(44,48,46,.16); border-radius: 99px;
  border: 2px solid transparent; background-clip: content-box;
}
.card::-webkit-scrollbar-thumb:hover, .scroll::-webkit-scrollbar-thumb:hover{ background: rgba(44,48,46,.3); background-clip: content-box; }

/* ==========================================================================
   布局工具
   ========================================================================== */

.stack > * + *{ margin-top: var(--s5); }
.stack-sm > * + *{ margin-top: var(--s3); }
.row{ display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.row--end{ justify-content: flex-end; }
.grow{ flex: 1; min-width: 0; }
.center{ text-align: center; }
.hr{ height: 1px; background: rgba(44,48,46,.1); border: 0; margin: var(--s5) 0; }

/* ==========================================================================
   开发模式标记
   ========================================================================== */

.devflag{
  margin-left: var(--s2);
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px; letter-spacing: .5px; color: var(--ink-3);
  background: var(--paper-deep);
  box-shadow: var(--in-sm);
  white-space: nowrap;
  align-self: center;
}

/* ==========================================================================
   响应式：窄屏把标签收起来，留数字
   ========================================================================== */

@media (max-width: 720px){
  /* 窄屏：品牌一行、步骤轨单独一行，否则五个点会顶到边框外 */
  .topbar{ padding: var(--s2) var(--s3); gap: var(--s2); flex-wrap: wrap; }
  .rail{ width: 100%; margin-left: 0; justify-content: space-between; gap: 0; }
  .brand__sub{ display: none; }
  .rail__item{ font-size: 0; gap: 0; padding: 2px; }
  .rail__dot{ width: 26px; height: 26px; font-size: 11px; }
  .shell{ padding: var(--s3) var(--s3) 124px; }
  .card{ padding: var(--s4); border-radius: var(--r-lg); }
  .nav{ padding: var(--s2) var(--s3) calc(var(--s2) + env(safe-area-inset-bottom)); }
  .nav .btn{ font-size: 15px; padding: 13px 20px; }
  .opts{ grid-template-columns: 1fr; }
  .recbtn{ width: 128px; height: 128px; }
}

/* 步骤页：内容比一屏短时把卡片在剩余空间里居中，别让下方空一大块。
   margin:auto 在放不下的时候会退化成 0，所以长页面照样从顶上开始。 */
body[data-step]{ min-height: 100dvh; display: flex; flex-direction: column; }
body[data-step] .shell{ flex: 1; display: flex; flex-direction: column; }
body[data-step] .shell > .card{ margin-block: auto; }

/* 窗口很矮时（笔记本半屏、投屏切一半），卡片自己滚，别把整页推跑。
   只限步骤页的卡片：登录门那张卡不能被限高，否则键盘一弹输入框就被裁掉。 */
@media (max-height: 720px){
  .shell .card{ max-height: calc(100dvh - 196px); overflow-y: auto; overscroll-behavior: contain; }
}

/* 动效敏感的人：全站静音，不是减弱 */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
