/* ---------------------------------------------------------------------------
   首页 / 落地页（public/login.html）。

   配色、字体栈、圆角在 tokens.css，全站共用；login.html 里 tokens.css 排在这一份
   前面。这里只写这一页自己的东西：夜的首屏、七段的版式、以及下面这块**钉死的
   颜色**。

   为什么要钉：tokens.css 在 `prefers-color-scheme: dark` 下会把 `--ink` 和
   `--paper` 整个翻过来。对界面那是对的，对这一页不对——**这一页的夜不是主题，
   是内容**。首屏必须永远是夜，第 6/7 段必须永远是纸，跟看的人把系统设成什么
   没有关系。同权重、排在 tokens.css 后面，所以这一份赢。
   字体栈不钉：那是品牌，改了应该跟着全站一起改。

   页面顺序：1 夜 · 2 あの人たち · 3 できること · 4 一分でわかる · 5 デスクトップ ·
   6 入口 · 7 页脚。1–5 默认全暗，第 2 段标题底下的「夜／灯」把 2–5 换成纸；
   6/7 永远是纸——**暗→亮在整页只发生一次**，`.turn` 那条渐变带有 before/after
   两个位置，开关决定用哪一条。 */

/* ------------------------------------------------- 这一页钉死的那几个颜色 */
:root {
  /* 夜那一半。tokens.css 在暗色主题下会把 --ink 翻成深墨，首屏的字就沉进画里，
     所以这里按明底的值重新钉一遍。 */
  --ink: #f2eee5;
  --ink-2: #bdb7aa;
  --ink-3: #8b8578;
  --shu: #e0674c;
  /* 纸那一半（第 6/7 段，以及点了灯之后的 2–5 段）。 */
  --paper: #f4efe6;
  --paper-2: #fffdf8;
  --ink-dark: #1b1a17;
  --ink-dark-2: #514d45;
  --ink-dark-3: #8d877a;
  --shu-dark: #b8442f;
  /* 这一页独有：比 tokens 的任何一档都深，夜的底。 */
  --night: #07070a;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--night);
  color: var(--ink);
  font: 16px/1.7 var(--gothic);
  -webkit-font-smoothing: antialiased;
}
/* 语言：三份文案都在 DOM 里，露哪一份由属性定。和 /guide 同一个做法——
   切语言不用重画任何东西，也不会在切换那一帧闪一下空白。

   **把「其余几种」逐条藏掉，不要写成「不是 A 就藏 A」**：原来这里是
   `[data-lang="ja"] .zh, [data-lang="zh"] .ja`，两种语言时等价，加第三种时
   一条都不命中——三份文案会同时显示，整页变一屏乱码（docs/英文版.md §5.1）。 */
[data-lang="ja"] .zh, [data-lang="ja"] .en,
[data-lang="zh"] .ja, [data-lang="zh"] .en,
[data-lang="en"] .ja, [data-lang="en"] .zh { display: none; }

/* =====================================================================
   第 1 段：夜

   sticky 而不是普通块：往下滚时她留在原位，第二段从下面推上来盖住她。
   「暗 → 亮」那一次转场要有个东西不动，才看得出是转场而不是翻页。
   高度用 svh：手机上 vh 把地址栏算进去，底下那行 CTA 会被顶出画面。
   ===================================================================== */
.hero {
  position: sticky;
  top: 0;
  height: 100svh;
  min-height: 560px;
  overflow: hidden;
  --exit: 0; /* 0→1，由 JS 按滚动写 */
}
.hero .layer { position: absolute; inset: 0; pointer-events: none; }

/* -- 最远：房间 + 窗外的城市 --------------------------------------- */
/* 一张平图当不了多层，但它自己有纵深（窗 → 地板 → 吧台）。做法是整张慢慢
   推近，再从同一张图里切一块糊掉的近景压在她前面（.l-fore）。一前一后两个
   速度，纵深就出来了。背景图由 JS 按当前角色写。 */
.l-room {
  background: var(--night) center 42% / cover no-repeat;
  transform: scale(calc(1.06 + var(--exit) * 0.04));
  filter: brightness(calc(0.72 - var(--exit) * 0.25)) contrast(1.06) saturate(0.95);
}

/* -- 两个光源，一冷一暖。抽成渐变层是为了能动：灯光有极慢的呼吸。 -- */
.l-bloom {
  background:
    radial-gradient(38% 30% at 52% 44%, rgba(120, 150, 210, 0.22), transparent 70%),
    radial-gradient(26% 26% at 9% 45%, rgba(255, 186, 106, 0.30), transparent 72%),
    radial-gradient(14% 12% at 92% 60%, rgba(255, 170, 90, 0.26), transparent 70%);
  mix-blend-mode: screen;
  animation: breathe 9s ease-in-out infinite;
}
@keyframes breathe { 0%, 100% { opacity: 0.82; } 50% { opacity: 1; } }

/* -- 浮尘。expedition33 首屏那些飘着的碎屑，最便宜的纵深来源：有东西在
      镜头和主体之间飘，大脑立刻认定这是个空间而不是一张画。 -- */
.l-dust { z-index: 2; }
.l-dust canvas { width: 100%; height: 100%; display: block; }

/* -- 她。偏右、压低、占屏高 88%。不垂直居中：重心低才像电影。 -- */
.l-figure {
  z-index: 3;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  padding-right: clamp(16px, 9vw, 170px);
}
.l-figure > * {
  height: 88%;
  max-height: 88svh;
  width: auto;
  /* 把她「坐进」这个房间。没有影子的立绘永远像贴纸。 */
  filter: brightness(0.94) contrast(1.04) saturate(0.97)
    drop-shadow(0 30px 46px rgba(0, 0, 0, 0.72));
  transition: opacity 260ms ease;
}
/* 换人时先淡出再换源，否则会闪一帧空白，而空白正中间就是脸。 */
.l-figure.is-swapping > * { opacity: 0; }
/* 盖在她身上的一层暖光（台灯那一侧）。CSS 做不了真的补光，用一层限制在
   人所在那条竖带里的渐变近似，很淡，漏到地板上的部分看不出来。 */
.l-figure::after {
  content: "";
  position: absolute;
  right: clamp(16px, 9vw, 170px);
  bottom: 0;
  width: min(46vh, 40vw);
  height: 88%;
  /* 用 radial 而不是 linear：linear 在元素左边缘那一端 alpha 是 0.2，
     到了盒子边上戛然而止，在暗底上就是一条看得见的**竖直硬边**——一块
     比周围亮的长方形浮在她身上，像没渲染完。radial 的高光在盒子内部，
     四周早就淡到 0 了，盒子边界不存在。 */
  background: radial-gradient(58% 46% at 24% 34%, rgba(255, 176, 96, 0.24), transparent 72%);
  mix-blend-mode: soft-light;
  pointer-events: none;
}

/* -- 最近：糊掉的近景。
      选择器写成 `.hero .l-fore` 而不是 `.l-fore`：上面 `.hero .layer` 里的
      `inset: 0` 是两个类，单个类压不过它。压不过的后果不是「没生效」而是
      **过约束**——left/top 赢、right/bottom 被丢掉，这一层带着自己的宽高
      跑到左上角去，正好糊住她的脸。同权重、写在后面，才轮到它。 -- */
.hero .l-fore {
  z-index: 4;
  inset: auto 0 0 auto;
  width: 34%;
  height: 40%;
  background: right 92% / 230% auto no-repeat;
  filter: blur(15px) brightness(0.38) saturate(0.8);
  transform: scale(calc(1.06 + var(--exit) * 0.10));
  transform-origin: 100% 100%;
  /* 从右下角往外化开，不是一条直线边——近景该待在画框边上，不该横切主体。 */
  -webkit-mask-image: radial-gradient(115% 115% at 100% 100%, #000 34%, transparent 82%);
  mask-image: radial-gradient(115% 115% at 100% 100%, #000 34%, transparent 82%);
}

/* -- 调色：上下两条压暗带。
      抄 expedition33：文字压在图上还读得清，而且相邻两段的黑边互相咬住，
      整页读起来是一整片连续的黑，没有卡片边界。 -- */
.l-grade {
  z-index: 5;
  background:
    linear-gradient(
      rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0.30) 22%, rgba(0, 0, 0, 0.06) 46%,
      rgba(0, 0, 0, 0.42) 78%, rgba(0, 0, 0, 0.78)
    ),
    radial-gradient(120% 90% at 50% 50%, transparent 42%, rgba(0, 0, 0, 0.55));
}

/* ------------------------------------------------------------- 顶栏 */
/* 学 expedition33：导航透明，压在画上。导航不占版面，画面才能到顶。 */
.top {
  position: absolute;
  z-index: 8;
  opacity: calc(1 - var(--exit) * 1.8);
  inset: 0 0 auto 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: clamp(18px, 2.6vw, 30px) clamp(18px, 5vw, 58px) 0;
}
.brand { display: flex; align-items: center; gap: 11px; }
.brand-seal {
  width: 26px; height: 26px; flex: none;
  background: currentColor;
  -webkit-mask: url("/brand/anone-mark-mono.svg") no-repeat center / contain;
  mask: url("/brand/anone-mark-mono.svg") no-repeat center / contain;
}
.brand-word { display: flex; align-items: baseline; gap: 10px; }
.brand-mark {
  font-family: var(--mincho); font-size: 21px;
  letter-spacing: 0.14em; white-space: nowrap;
}
.brand-kana { font-size: 10px; letter-spacing: 0.34em; opacity: 0.6; white-space: nowrap; }

.top-right { display: flex; align-items: center; gap: clamp(8px, 1.6vw, 18px); }
/* 语言下拉。收起来的样子和喇叭键是同一枚小件——同高、同圆、同一层玻璃底，
   顶栏右边那一行才像一行，而不是「两个小图标外加一条长条」。 */
.lang { position: relative; flex: none; }
.lang-trigger {
  display: flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 9px 0 10px;
  border: 1px solid rgba(242, 238, 229, 0.22);
  border-radius: 999px;
  background: rgba(10, 10, 12, 0.35);
  color: var(--ink-3);
  cursor: pointer; backdrop-filter: blur(6px);
  transition: color 160ms, border-color 160ms, background 160ms;
}
.lang-trigger:hover { color: var(--ink); border-color: rgba(242, 238, 229, 0.45); }
.lang-globe { width: 15px; height: 15px; flex: none; opacity: 0.85; }
/* 当前语言这两个字母比图标亮一档：一枚键上只能有一个重点，重点是「现在是哪一门」。 */
.lang-now {
  font: 12px/1 var(--gothic); letter-spacing: 0.12em;
  color: var(--ink-2);
  transition: color 160ms;
}
.lang-trigger:hover .lang-now { color: var(--ink); }
.lang-caret { width: 11px; height: 11px; flex: none; opacity: 0.7; transition: transform 180ms; }
.lang[data-open="true"] .lang-caret { transform: rotate(180deg); }
.lang[data-open="true"] .lang-trigger {
  color: var(--ink);
  border-color: rgba(242, 238, 229, 0.45);
  background: rgba(10, 10, 12, 0.62);
}

/* 摊开的三条。比收起来那枚深、比它实——它盖在画上，底下是她的脸，
   半透明到能看见五官的菜单没人读得完。圆角收到 13px：胶囊是「一枚键」的形状，
   一张清单要有纸的形状。 */
.lang-menu {
  position: absolute; z-index: 20;
  top: calc(100% + 9px); right: 0;
  min-width: 156px; padding: 5px;
  border: 1px solid rgba(242, 238, 229, 0.16);
  border-radius: 13px;
  background: rgba(9, 9, 12, 0.88);
  backdrop-filter: blur(16px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
  animation: lang-drop 160ms ease both;
}
@keyframes lang-drop {
  from { opacity: 0; transform: translateY(-5px); }
  to { opacity: 1; transform: none; }
}
.lang-menu button {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  width: 100%; height: 36px; padding: 0 11px;
  border: 0; border-radius: 9px;
  background: transparent; color: var(--ink-2);
  font: 13px/1 var(--gothic); text-align: left; cursor: pointer;
  transition: background 140ms, color 140ms;
}
.lang-menu button:hover, .lang-menu button:focus-visible {
  background: rgba(242, 238, 229, 0.10); color: var(--ink); outline: none;
}
/* 代号那一列（JP/CN/EN）是给不认得字的人看的锚点，永远比名字暗一档——
   它是索引，不是内容。 */
.lang-code { font-size: 11px; letter-spacing: 0.14em; color: var(--ink-3); }
/* 选中的那一条不反白：反白（像原来那三枚胶囊）在这里会变成菜单里最亮的一块，
   人的眼睛先看见「已经选好的」，再去找别的。这里只给一条左边的墨线加一档字亮度。
   朱色不用——这一屏的红只归「入」那一枚（顶栏里红一旦有两处，就没有入口了）。 */
.lang-menu button[aria-selected="true"] { color: var(--ink); background: rgba(242, 238, 229, 0.07); }
.lang-menu button[aria-selected="true"] .lang-code { color: var(--ink-2); }
.lang-menu button[aria-selected="true"]::before {
  content: ""; position: absolute; left: 4px; top: 50%;
  width: 2px; height: 16px; margin-top: -8px; border-radius: 1px;
  background: rgba(242, 238, 229, 0.75);
}

/* 声音键。默认开——但浏览器多半不让一上来就出声，真正的开关在脚本里。 */
.sound {
  display: grid; place-items: center;
  width: 32px; height: 32px; flex: none;
  border: 1px solid rgba(242, 238, 229, 0.22);
  border-radius: 999px;
  background: rgba(10, 10, 12, 0.35);
  color: var(--ink-3);
  cursor: pointer; backdrop-filter: blur(6px);
  transition: color 160ms, border-color 160ms;
}
.sound:hover { color: var(--ink); border-color: rgba(242, 238, 229, 0.45); }
.sound svg { width: 16px; height: 16px; }
.sound[aria-pressed="true"] { color: var(--shu); border-color: rgba(224, 103, 76, 0.55); }
.sound .slash { opacity: 1; }
.sound[aria-pressed="true"] .slash { opacity: 0; }
.sound .wave { opacity: 0; }
.sound[aria-pressed="true"] .wave { opacity: 1; animation: wave 1.8s ease-in-out infinite; }
.sound[aria-pressed="true"] .wave--far { animation-delay: 0.22s; }
@keyframes wave { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

/* 自动播放被拦时才出现。不给这一句，他看到的是一个不响的页面加一个灰着的
   小喇叭，不会知道那是「点我」。 */
.sound-hint {
  padding: 6px 13px;
  border: 1px solid rgba(224, 103, 76, 0.55);
  border-radius: 999px;
  background: rgba(224, 103, 76, 0.14);
  color: var(--shu);
  font: 12px/1 var(--gothic); letter-spacing: 0.1em;
  cursor: pointer; white-space: nowrap; backdrop-filter: blur(6px);
  animation: hintPulse 2.2s ease-in-out infinite;
}
@keyframes hintPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(224, 103, 76, 0); }
  50%      { box-shadow: 0 0 0 5px rgba(224, 103, 76, 0.12); }
}

/* 登录入口：一枚题字徽标。
   原来是灰字加下划线（怕它抢 CTA 的戏）——但顶栏右边本来就全是灰色小件，
   那行字混在喇叭和 JP/CN 中间，老客回来找不到入口。现在给它这一页**唯一
   的一块红**：红只给一个东西用，它自然就是右边最先被看见的。
   它仍然不抢首屏 CTA：CTA 是 38px 内边距的实心大块，这一枚是淡底加一个字，
   量级差着一档；抢戏的是颜色浓度，不是位置。

   **为什么「入」不套框**：试过实心方印，字被夹在「胶囊 + 方块」两层边界里，
   而明朝体的撇捺本来是往外张的，四边留白不够就显得局促。拆掉里面那层，字
   直接站在胶囊里，撇捺才张得开——它是题字，不是图标。
   字号从 20px 收到 16px：20px 的「入」比旁边那行字高出一大截，整枚胶囊被它
   一个字顶到 34px，在一排灰字小件里显得墩。收下来之后按钮矮到 28px，和顶栏
   其余小件一个量级，红还是只有它一个人有，醒目靠的是颜色不是个头。
   字是「入」。左上角那枚墨印才是标志（见 .brand-seal），这一枚是门。 */
.signin {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 5px 16px 5px 14px;
  border: 1px solid rgba(224, 103, 76, 0.45);
  border-radius: 999px;
  background: rgba(224, 103, 76, 0.10);
  color: var(--ink);
  font: 13px/1 var(--gothic); letter-spacing: 0.1em;
  white-space: nowrap; cursor: pointer;
  backdrop-filter: blur(6px);
  /* 呼吸一圈很淡的红晕。顶栏压在夜景上，静止的小件容易被背后的城市灯光吃掉；
     一个周期 3.4s，慢到不会变成「广告在闪」。 */
  animation: signinBreath 3.4s ease-in-out infinite;
  transition: background 180ms, border-color 180ms, transform 180ms;
}
.signin-glyph {
  flex: none;
  font-family: var(--mincho); font-size: 16px; line-height: 1;
  color: var(--shu);
  /* 这一层光不是装饰：字是描线不是色块，压在窗外那片城市灯光上会被打散，
     给它一点自己的底。 */
  text-shadow: 0 0 16px rgba(224, 103, 76, 0.5);
  transition: text-shadow 180ms;
}
/* 一个字和一行字之间需要一道停顿，不然读成「入ログイン」。 */
.signin-rule { width: 1px; height: 13px; flex: none; background: rgba(224, 103, 76, 0.42); }
.signin:hover {
  background: rgba(224, 103, 76, 0.20);
  border-color: rgba(224, 103, 76, 0.8);
}
.signin:hover .signin-glyph { text-shadow: 0 0 20px rgba(224, 103, 76, 0.85); }
.signin:active { transform: translateY(1px); }
@keyframes signinBreath {
  0%, 100% { box-shadow: 0 0 0 0 rgba(224, 103, 76, 0); }
  50%      { box-shadow: 0 0 0 6px rgba(224, 103, 76, 0.10); }
}

/* ------------------------------------------------------------- 首屏文案 */
.copy {
  position: absolute;
  z-index: 8;
  left: clamp(18px, 5vw, 58px);
  bottom: clamp(46px, 9vh, 104px);
  max-width: min(680px, 54vw);
  /* 跟着 --exit 一起退场。不淡出的话，第二段从下面盖上来时会把还亮着的
     标题拦腰切一半，看起来像没渲染完。 */
  opacity: calc(1 - var(--exit) * 2.1);
  transform: translateY(calc(var(--exit) * -26px));
}
.eyebrow {
  display: flex; align-items: center; gap: 12px;
  margin: 0 0 clamp(14px, 2vh, 22px);
  font-size: 12px; letter-spacing: 0.30em; color: var(--ink-2);
}
.eyebrow::before {
  content: ""; width: clamp(26px, 4vw, 48px); height: 1px;
  background: var(--shu); flex: none;
}
.title {
  margin: 0;
  font-family: var(--mincho); font-weight: 500;
  /* 字号敢大是「震撼」里最不花钱的一项。 */
  font-size: clamp(34px, 5.4vw, 76px);
  line-height: 1.26; letter-spacing: 0.02em;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.75);
}
.title em { font-style: normal; color: var(--shu); }
.title .row { display: block; }
.lead {
  margin: clamp(16px, 2.4vh, 26px) 0 0;
  max-width: 34em; text-wrap: pretty;
  color: var(--ink-2);
  font-size: clamp(13px, 1.15vw, 16px);
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.8);
}
.cta-row {
  display: flex; align-items: center; gap: clamp(14px, 2vw, 26px);
  margin-top: clamp(22px, 3.4vh, 38px);
  flex-wrap: wrap;
}
.cta {
  display: inline-block;
  padding: 14px 38px;
  border: 0; border-radius: 2px;
  background: var(--shu); color: #fffdf8;
  font: 15px/1 var(--gothic); letter-spacing: 0.16em;
  text-decoration: none; cursor: pointer;
  box-shadow: 0 10px 34px rgba(224, 103, 76, 0.28);
  transition: transform 160ms, box-shadow 160ms, filter 160ms;
}
.cta:hover { transform: translateY(-2px); box-shadow: 0 14px 40px rgba(224, 103, 76, 0.38); filter: brightness(1.06); }
/* 首屏那条次要链接（「一分でわかる」）。
   用 --ink 而不是 --ink-3：它压在一张有明有暗的照片上，--ink-3（#8b8578）在
   窗外那片城市灯光上几乎看不见。次要靠字号和没有底色来表达，不靠把它调暗——
   一条看不见的链接不是「次要」，是「不存在」。
   text-shadow 和 .lead 那句同一条：照片亮的地方也得读得出。
   第 4、5 段那两条同名链接压在纯色底上，不需要这么亮，各自有覆盖（见下面）。 */
.cta-sub {
  color: var(--ink); font: 12.5px/1.5 var(--gothic); letter-spacing: 0.08em;
  text-decoration: none; border: 0; border-bottom: 1px solid transparent;
  background: none; cursor: pointer; padding: 0 0 2px;
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.8);
}
.cta-sub:hover { border-color: rgba(242, 238, 229, 0.55); }

/* 首屏那行免责。AGENTS.md §6「明确告知用户正在与 AI 角色互动」——现首页把
   它放在表单下面，表单挪走之后这一句不能跟着走：它得在**第一眼就看得见的
   地方**，不能只躺在第六屏。完整那句在入口段和页脚各还有一份。 */
.disclosure-mini {
  margin: clamp(14px, 2vh, 20px) 0 0;
  font-size: 11.5px; letter-spacing: 0.04em;
  color: var(--ink-3);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.9);
}

/* 竖排题字。现首页已经有这一行，保留——它是这一页的「« »」，
   一个反复出现的记号。 */
.tate {
  position: absolute; z-index: 8;
  right: clamp(14px, 2.4vw, 30px);
  top: clamp(96px, 16vh, 170px);
  margin: 0;
  writing-mode: vertical-rl;
  font-family: var(--mincho);
  font-size: clamp(12px, 1.05vw, 15px);
  letter-spacing: 0.34em;
  color: var(--ink);
  opacity: calc((1 - var(--exit) * 2.4) * 0.5);
}

/* 滚动提示：一条会掉下去的竖线，比箭头安静。 */
.scroll-cue {
  position: absolute; z-index: 8;
  opacity: calc(1 - var(--exit) * 4);
  left: 50%; bottom: 22px; transform: translateX(-50%);
  width: 1px; height: 46px;
  background: linear-gradient(rgba(242, 238, 229, 0), rgba(242, 238, 229, 0.55));
  overflow: hidden;
}
.scroll-cue::after {
  content: ""; position: absolute; inset: 0;
  background: var(--shu);
  animation: cue 2.6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes cue {
  0% { transform: translateY(-100%); }
  60%, 100% { transform: translateY(100%); }
}

/* =====================================================================
   开场序列

   和 expedition33 最不一样的一处：它一进去就全亮了。这一页给自己 2 秒——
   黑 → 城市的灯先亮 → 房间浮出来 → 她淡入 → 标题一行行落 → 最后印盖下来。
   这种页面上的「震撼」其实是**时间**，不是尺寸。
   ===================================================================== */
.intro .l-room   { animation: inRoom 2600ms cubic-bezier(0.22, 0.61, 0.36, 1) both; }
.intro .l-bloom  { animation: inFade 1600ms ease-out 260ms both, breathe 9s ease-in-out 1900ms infinite; }
.intro .l-dust   { animation: inFade 2000ms ease-out 900ms both; }
.intro .l-figure { animation: inFigure 1700ms cubic-bezier(0.22, 0.61, 0.36, 1) 620ms both; }
.intro .l-fore   { animation: inFade 1500ms ease-out 500ms both; }
.intro .brand    { animation: inSeal 900ms cubic-bezier(0.2, 1.4, 0.4, 1) 1850ms both; }
.intro .top-right{ animation: inFade 700ms ease-out 2050ms both; }
.intro .eyebrow  { animation: inUp 700ms ease-out 1180ms both; }
.intro .title .row:nth-child(1) { animation: inUp 800ms ease-out 1340ms both; }
.intro .title .row:nth-child(2) { animation: inUp 800ms ease-out 1470ms both; }
.intro .lead     { animation: inUp 700ms ease-out 1680ms both; }
.intro .cta-row  { animation: inUp 700ms ease-out 1820ms both; }
.intro .disclosure-mini { animation: inFade 900ms ease-out 2150ms both; }
.intro .tate     { animation: inFade 1200ms ease-out 2100ms both; }
.intro .scroll-cue { animation: inFade 900ms ease-out 2400ms both; }

@keyframes inRoom {
  from { opacity: 0; transform: scale(1.20); filter: brightness(0) contrast(1.06); }
  45%  { opacity: 1; }
  to   { opacity: 1; transform: scale(1.06); filter: brightness(0.72) contrast(1.06) saturate(0.95); }
}
@keyframes inFigure {
  from { opacity: 0; transform: translateY(26px) scale(1.05); }
  to   { opacity: 1; transform: none; }
}
@keyframes inFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes inUp   { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; } }
/* 印是「盖」下来的：从大到小 + 一点点转正。 */
@keyframes inSeal {
  from { opacity: 0; transform: scale(1.5) rotate(-6deg); }
  to   { opacity: 1; transform: none; }
}

/* =====================================================================
   第 2–5 段的皮肤

   四段共用一组变量，「夜 ／ 灯」只换这组变量的值——不是给每一段写两套规则。
   排版一个字不动：「亮」不该是另一套布局。
   ===================================================================== */
.sheet {
  position: relative;
  z-index: 10;
  --bg: var(--night);
  --fg: var(--ink);
  --fg2: var(--ink-2);
  --fg3: var(--ink-3);
  --accent: var(--shu);
  --card: #0b0b0e;
  --line: rgba(242, 238, 229, 0.08);
  /* 卡片上那束光 / 压字的那层幕 */
  --pool: rgba(255, 196, 138, 0.34);
  --scrim: linear-gradient(transparent 46%, rgba(7, 7, 10, 0.55) 68%, rgba(7, 7, 10, 0.96) 88%);
  --shadow: rgba(0, 0, 0, 0.7);
}
[data-cast="light"] .sheet {
  --bg: var(--paper);
  --fg: var(--ink-dark);
  --fg2: var(--ink-dark-2);
  --fg3: var(--ink-dark-3);
  --accent: var(--shu-dark);
  --card: var(--paper-2);
  --line: rgba(27, 26, 23, 0.10);
  --pool: rgba(224, 168, 108, 0.16);
  --scrim: linear-gradient(transparent 46%, rgba(255, 253, 248, 0.72) 68%, var(--paper-2) 88%);
  --shadow: rgba(27, 26, 23, 0.18);
}

.band {
  background: var(--bg);
  color: var(--fg);
  padding: clamp(64px, 11vh, 120px) clamp(18px, 5vw, 58px);
}
/* 第一段夜的下沿和这一段的上沿咬住，不许出现分界线。 */
.band--first { box-shadow: 0 -60px 80px -20px var(--bg); }
.inner { max-width: 1320px; margin: 0 auto; }

.section-head { text-align: center; margin-bottom: clamp(34px, 5.5vh, 60px); }
.section-head .mark {
  font-family: var(--mincho);
  font-size: clamp(22px, 3vw, 38px);
  letter-spacing: 0.22em;
  margin: 0;
}
/* 那对 — — 是这一页重复的装饰母题，每段标题都戴。 */
.section-head .mark::before,
.section-head .mark::after {
  content: "—"; color: var(--accent); margin: 0 0.5em;
  font-size: 0.6em; vertical-align: 0.25em;
}
.section-head .sub {
  margin: 12px 0 0; color: var(--fg3);
  font-size: 12.5px; letter-spacing: 0.24em;
}

/* 宣传片合集（/films）的入口，压在 MEET THEM 底下。
   和第 4 段那条「看全部（十三集）」是同一个角色，所以样式也照抄那一条：
   压在纯色底上，不需要首屏那条的高光。明暗两种模式下都要读得出——
   这一段「灯」模式的底是纸，--fg2/--fg 在两套里各自翻过。 */
.cast-films { margin: 14px 0 0; }
.cast-films-play { font-style: normal; font-size: 8.5px; margin-right: 7px; vertical-align: 1px; color: var(--accent); }
.cast-films .cta-sub { color: var(--fg2); text-shadow: none; }
.cast-films .cta-sub:hover { color: var(--fg); border-color: var(--fg); }

/* 明暗开关。放在第二段标题底下而不是顶栏：它改的是从这里往下那几段，
   不是整站，也不该改首屏——夜是首屏的内容。 */
.lamp {
  display: inline-flex; margin-top: 20px; padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: color-mix(in srgb, var(--fg) 4%, transparent);
}
.lamp button {
  min-width: 58px; padding: 6px 14px;
  border: 0; border-radius: 999px;
  background: transparent; color: var(--fg3);
  font: 12px/1 var(--mincho); letter-spacing: 0.2em; cursor: pointer;
  transition: background 200ms, color 200ms;
}
.lamp button[aria-pressed="true"] { background: var(--fg); color: var(--bg); }

/* --------------------------------------------------- 第 2 段：あの人たち */
.cast-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(12px, 1.8vw, 26px);
}
.cast-card {
  position: relative;
  aspect-ratio: 3 / 4.2;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
  display: block; cursor: pointer;
  text-align: left; padding: 0;
  color: inherit; font: inherit;
}
/* 每人一束光，位置错开——四张并排才不像四个一样的格子。 */
.cast-card::before {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  background:
    radial-gradient(62% 50% at var(--lx, 50%) 30%, var(--pool), transparent 74%),
    linear-gradient(color-mix(in srgb, var(--fg) 5%, transparent), transparent 40%);
}
/* 用 /home/*.webp 那张抠好的立绘，不是 *.face.webp 的圆头像——头像是给
   现首页那排小圆点用的方形脸部裁剪，放进这么高的卡片里只剩半个头顶。 */
.cast-card img {
  position: absolute;
  left: 0; right: 0; bottom: -2%;
  width: 100%; height: 92%;
  object-fit: contain; object-position: bottom center;
  filter: brightness(1.02) contrast(1.04) saturate(0.95) drop-shadow(0 16px 26px var(--shadow));
  transform-origin: 50% 100%;
  transition: transform 600ms cubic-bezier(0.22, 0.61, 0.36, 1), filter 400ms;
}
[data-cast="light"] .cast-card img { filter: drop-shadow(0 14px 22px var(--shadow)); }
.cast-card:hover img { transform: scale(1.05); }
.cast-card::after { content: ""; position: absolute; inset: 0; z-index: 2; background: var(--scrim); }
/* 有宣传片的那张卡片，右上角这枚角标。位置和 .guide-play 那个圆钮不一样：
   那一段的封面是空的 16:9，正中间放得下；这里画面正中间是脸，钮压上去
   就是压在脸上。角标只挂在有片子的卡片上——没片子的不挂，见 buildCast()。
   深底白字两种明暗下都读得出来（灯模式的底是立绘不是纸）。 */
.cast-play {
  position: absolute; z-index: 3; right: 10px; top: 10px;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  border: 1px solid rgba(255, 255, 255, 0.42);
  border-radius: 999px;
  background: rgba(10, 10, 12, 0.48);
  color: rgba(255, 255, 255, 0.92);
  font-size: 10.5px; line-height: 1; letter-spacing: 0.08em;
  transition: background 220ms, border-color 220ms, transform 220ms;
}
.cast-play i { font-style: normal; font-size: 9px; }
.cast-card:hover .cast-play { background: var(--accent); border-color: transparent; transform: scale(1.04); }
.cast-card[aria-pressed="true"] { border-color: color-mix(in srgb, var(--accent) 60%, transparent); }
/* 卡片上只有名字和罗马字两行（2026-09-14 撤掉了 .cast-meta / .cast-line）。
   两行字比原来的四行矮了一大截，所以底边留白给厚一点——字贴着卡片下沿排，
   少了的那两行就只是缺了一块，而不是「下面还空着一片」。 */
.cast-body {
  position: absolute; z-index: 3; left: 0; right: 0; bottom: 0;
  padding: clamp(14px, 1.6vw, 24px);
  padding-bottom: clamp(18px, 2vw, 30px);
}
.cast-name { font-family: var(--mincho); font-size: clamp(18px, 1.8vw, 27px); margin: 0; letter-spacing: 0.1em; }
.cast-kana {
  font-size: 10px; letter-spacing: 0.28em; color: var(--fg3); margin: 8px 0 0;
  /* 罗马字压在浅色衣服上会吃字，给它一层很淡的背影。 */
  text-shadow: 0 1px 6px var(--bg);
  /* 「SHINOHARA SOU」在两列的手机上一行放不下，断行也要断得整齐。 */
  line-height: 1.5;
  /* 名字已经是拉丁字母的那张（中文版的 Elise）这一行是空的，见 kanaFor()。
     空行仍然占位，不然那张卡的名字会比旁边三张低半行。 */
  min-height: 15px;
}
.cast-note { margin: clamp(22px, 3vh, 34px) 0 0; text-align: center; color: var(--fg3); font-size: 12px; letter-spacing: 0.08em; }
/* 「不只这几位」比上面那句操作提示要紧一点：明朝体、亮一档。两句之间只留
   10px，读起来是同一段的第二行，不是又一条注释。 */
.cast-more {
  margin: 10px 0 0; text-align: center;
  color: var(--fg2);
  font: 13px/1.6 var(--mincho); letter-spacing: 0.12em;
}

/* --------------------------------------------------- 第 3 段：できること */
.can-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(14px, 1.8vw, 24px);
}
/* 五件事排成 6 列：前两件各占 3 列（大），后三件各占 2 列。
   不是均分——「文字」和「通话」是这个产品的正事，另外三件是它的样子。 */
.can-item:nth-child(1), .can-item:nth-child(2) { grid-column: span 3; }
.can-item:nth-child(n + 3) { grid-column: span 2; }
.can-item { min-width: 0; }
.can-frame {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
}
.can-item:nth-child(n + 3) .can-frame { aspect-ratio: 4 / 3; }
/* 占位框。真素材到了就把 .can-slot 换成 <img>/<video>，别的都不用动。
   做成虚线空框而不是随便垫一张图：垫图会让人以为版面已经定了。 */
.can-slot {
  position: absolute; inset: 10px;
  display: grid; place-content: center; gap: 6px;
  border: 1px dashed color-mix(in srgb, var(--fg) 22%, transparent);
  color: var(--fg3); text-align: center;
  font-size: 11.5px; letter-spacing: 0.12em;
  padding: 10px;
}
.can-slot b { display: block; font-weight: 500; color: var(--fg2); font-size: 12.5px; letter-spacing: 0.16em; }
/* 真素材。竖构图的照片放进横框里，靠 object-position 把脸留在画面里，
   别居中裁——居中裁一张站姿照留下的正好是腰。 */
.can-frame img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 700ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.can-frame img[data-fit="portrait"] { object-position: 50% 18%; }
/* 视觉小说那张是 16:10，塞进 4:3 的格子里裁掉的正好是左上角的 Scene 标题。
   改成整张放进去：上下留出来的那两条底色和它自己的深蓝几乎同色，看不出来，
   而裁掉标题会让人认不出这是一段故事。 */
.can-frame img[data-fit="wide"] { object-fit: contain; }
.can-item:hover .can-frame img { transform: scale(1.03); }
.can-body { padding: clamp(14px, 1.6vw, 20px) 2px 0; }
.can-name { margin: 0; font-family: var(--mincho); font-size: clamp(15px, 1.45vw, 21px); letter-spacing: 0.08em; }
.can-desc { margin: 8px 0 0; color: var(--fg2); font-size: clamp(12px, 1vw, 14px); line-height: 1.8; text-wrap: pretty; }

/* --------------------------------------- 第 4 段：一分でわかる（教程片） */
.guide-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(12px, 1.6vw, 22px);
}
.guide-card {
  display: block; width: 100%; padding: 0; text-align: left;
  background: none; border: 0; color: inherit; font: inherit; cursor: pointer;
}
.guide-thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
}
/* 用 <img loading="lazy"> 而不是 CSS 的 background-image：背景图没有懒加载，
   一进页面这五张 200–330KB 的封面就全下了，而这一段是第四屏。 */
.guide-thumb img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.guide-thumb::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(transparent 40%, rgba(7, 7, 10, 0.62));
}
.guide-play {
  position: absolute; z-index: 2; left: 50%; top: 50%;
  width: 42px; height: 42px; margin: -21px 0 0 -21px;
  display: grid; place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  background: rgba(10, 10, 12, 0.42);
  color: #fff; font-size: 13px;
  transition: transform 220ms, background 220ms;
}
.guide-card:hover .guide-play { transform: scale(1.1); background: var(--accent); border-color: transparent; }
.guide-len {
  position: absolute; z-index: 2; right: 8px; bottom: 7px;
  color: rgba(255, 255, 255, 0.82); font-size: 11px; letter-spacing: 0.06em;
}
.guide-name { margin: 12px 0 0; font-family: var(--mincho); font-size: clamp(13px, 1.15vw, 16px); letter-spacing: 0.06em; }
.guide-why { margin: 6px 0 0; color: var(--fg3); font-size: 11.5px; line-height: 1.7; text-wrap: pretty; }
.guide-more { margin: clamp(26px, 3.4vh, 40px) 0 0; text-align: center; }
.guide-more .cta-sub { color: var(--fg3); text-shadow: none; }
.guide-more .cta-sub:hover { color: var(--fg); border-color: var(--fg); }

/* 播放器。不跳 /guide：跳走等于把人从这一页赶出去。 */
.player[hidden] { display: none; }
.player {
  position: fixed; z-index: 60; inset: 0;
  display: grid; place-items: center;
  background: rgba(4, 4, 6, 0.88);
  backdrop-filter: blur(6px);
  padding: clamp(16px, 4vw, 48px);
}
.player-box { width: min(1000px, 100%); }
.player video { width: 100%; display: block; background: #000; }
.player-bar { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-top: 12px; }
.player-title { font-family: var(--mincho); font-size: 16px; letter-spacing: 0.08em; color: var(--ink); margin: 0; }
.player-close {
  border: 1px solid rgba(242, 238, 229, 0.3); border-radius: 999px;
  background: none; color: var(--ink-2); cursor: pointer;
  padding: 6px 16px; font: 12px/1 var(--gothic); letter-spacing: 0.14em;
}
.player-close:hover { color: var(--ink); border-color: var(--ink); }

/* --------------------------------------------- 第 5 段：デスクトップ */
.desk {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
}
.desk-copy .mark { font-family: var(--mincho); font-size: clamp(24px, 3.2vw, 42px); margin: 0; line-height: 1.35; letter-spacing: 0.04em; }
.desk-copy .mark em { font-style: normal; color: var(--accent); }
.desk-copy p { color: var(--fg2); font-size: clamp(13px, 1.1vw, 15.5px); line-height: 1.9; max-width: 34em; text-wrap: pretty; }
.desk-actions { display: flex; align-items: center; gap: clamp(12px, 2vw, 24px); flex-wrap: wrap; margin-top: clamp(20px, 3vh, 32px); }
.dl {
  display: inline-flex; align-items: baseline; gap: 10px;
  padding: 14px 30px; border: 0; border-radius: 2px;
  background: var(--accent); color: #fffdf8;
  font: 14.5px/1 var(--gothic); letter-spacing: 0.12em;
  text-decoration: none; cursor: pointer;
  box-shadow: 0 10px 30px color-mix(in srgb, var(--accent) 26%, transparent);
  transition: transform 160ms, filter 160ms;
}
.dl:hover { transform: translateY(-2px); filter: brightness(1.06); }
.dl small { font-size: 11px; letter-spacing: 0.06em; opacity: 0.8; }
.desk-actions .cta-sub { color: var(--fg3); text-shadow: none; }
.desk-actions .cta-sub:hover { color: var(--fg); border-color: var(--fg); }
.desk-frame { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: #07070a; border: 1px solid var(--line); }
/* 片子本身就是 16:10，cover 只是防着以后换一支比例不一样的。
   底色钉死成夜色而不是 var(--card)：点了灯之后卡片底是纸白，而这支片子
   首尾各有半秒黑，纸白底上那半秒会变成一次刺眼的闪。 */
.desk-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.desk-video[hidden] { display: none; }

/* ------------------------------------------------------- 第 6 段：入口 */
/* 这一段永远是纸。暗→亮在整页里只发生一次，落点就在这里（点了灯的话
   提前到第一段之后，见 .turn 的两个位置）。 */
.gate {
  background: var(--paper);
  color: var(--ink-dark);
  padding: clamp(64px, 11vh, 120px) clamp(18px, 5vw, 58px) clamp(40px, 6vh, 64px);
}
.gate-inner { max-width: 560px; margin: 0 auto; text-align: center; }
.gate .mark { font-family: var(--mincho); font-size: clamp(24px, 3.2vw, 40px); margin: 0; letter-spacing: 0.12em; }
.gate .sub { margin: 14px 0 0; color: var(--ink-dark-3); font-size: 13px; line-height: 1.9; }
.gate-form { margin-top: clamp(26px, 4vh, 40px); }
.gate-label {
  display: block; text-align: left;
  font-size: 11.5px; letter-spacing: 0.2em; color: var(--ink-dark-3);
  margin-bottom: 8px;
}
.gate-row { display: flex; gap: 10px; }
.gate-input {
  flex: 1; min-width: 0;
  padding: 14px 16px;
  border: 1px solid rgba(27, 26, 23, 0.2);
  border-radius: 2px;
  background: var(--paper-2); color: var(--ink-dark);
  font: 16px/1.3 var(--gothic); letter-spacing: 0.08em;
}
.gate-input:focus { outline: 2px solid color-mix(in srgb, var(--shu-dark) 50%, transparent); outline-offset: 1px; }
.gate-submit {
  flex: none; padding: 14px 30px;
  border: 0; border-radius: 2px;
  background: var(--shu-dark); color: var(--paper-2);
  font: 14.5px/1 var(--gothic); letter-spacing: 0.14em; cursor: pointer;
}
.gate-submit:disabled { opacity: 0.6; cursor: default; }
.gate-hint { margin: 10px 0 0; text-align: left; color: var(--ink-dark-3); font-size: 12px; line-height: 1.8; }
.gate-message { margin: 12px 0 0; text-align: left; font-size: 13px; color: var(--shu-dark); }
.gate-message[hidden] { display: none; }
/* 输进去之前该知道的三件事。左对齐、比 hint 再淡一档：它是说明不是警告，
   不该和上面那行格式提示抢同一个亮度。 */
.gate-notes {
  margin: 16px 0 0; padding: 0 0 0 1.1em;
  text-align: left; list-style: disc;
  color: var(--ink-dark-3); font-size: 12px; line-height: 1.9;
}
.gate-notes li + li { margin-top: 4px; }
.gate-notes b { font-weight: 600; color: var(--ink-dark-2); }
/* 没有 ID 的人从这里申请（docs/ID申请.md）。
   那一行字是**按钮不是链接**：它展开的是同一页上的一块东西，不跳走。

   **朱色。** 第一版是墨色小字，理由是「大多数人要按的是上面那个朱色方块」——
   但那条理由说反了：手里有号的人根本不用找这一行，找的人是**没号的那个**，
   而他在这一页上除了这一行没有别的路。一行和三条说明同色的小字，等于让他
   自己从说明里认出哪一句是能按的。
   和上面那个方块仍然分得开：方块是**填满的朱**，这里只是**朱色的字**加一道
   下划线，分量差着一档。它也不会和报错撞车——那一句是没有下划线的整句话，
   而且出现在表单里面。 */
.apply { margin-top: 20px; text-align: left; }
.apply-open {
  padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--shu-dark); font: 12.5px/1.8 var(--gothic);
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--shu-dark) 45%, transparent);
}
.apply-open:hover { text-decoration-color: currentColor; }
.apply-form {
  margin-top: 14px; padding: 16px 16px 18px;
  border: 1px solid rgba(27, 26, 23, 0.16); border-radius: 2px;
  background: var(--paper-2);
}
.apply-form[hidden] { display: none; }
.apply-sub { margin: 0 0 14px; color: var(--ink-dark-3); font-size: 12px; line-height: 1.9; }
.apply-input { width: 100%; box-sizing: border-box; font-size: 16px; }
/* 16px 不是排版选择：iOS Safari 对小于 16px 的输入框会自动放大整页，
   放大之后这一段就跑出屏幕了。 */
.apply-pick { margin: 14px 0 0; padding: 0; border: 0; }
.apply-pick legend {
  padding: 0; margin-bottom: 7px;
  font-size: 11.5px; letter-spacing: 0.16em; color: var(--ink-dark-3);
}
.apply-pick legend i { font-style: normal; letter-spacing: 0.04em; }
.apply-pick label {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 16px 6px 0;
  color: var(--ink-dark-2); font-size: 13px; cursor: pointer;
}
.apply-pick input { accent-color: var(--shu-dark); margin: 0; }
.apply-submit { margin-top: 16px; width: 100%; }
.apply-message { text-align: left; }
/* 收下了的那一句是墨不是朱：朱色在这一页里一直是「出错了」。 */
.apply-message[data-ok="1"] { color: var(--ink-dark-2); }

/* 已经登录着的人从 /about 进来时，表单的位置上换成这一块。 */
.gate-signed { margin-top: clamp(26px, 4vh, 40px); }
.gate-signed[hidden] { display: none; }
.gate-signed-line { margin: 0 0 16px; color: var(--ink-dark-2); font-size: 13px; line-height: 1.9; }
.gate-signed-line b { font-family: var(--gothic); letter-spacing: 0.08em; }
/* 和 .gate-submit 同一枚朱色方块，只是它是个 <a>。 */
.gate-back { display: inline-block; text-decoration: none; }

/* 完整那句免责，和现首页逐字一致。 */
.disclosure {
  margin: clamp(26px, 4vh, 38px) 0 0;
  padding-left: 12px;
  border-left: 2px solid var(--shu-dark);
  text-align: left;
  color: var(--ink-dark-2); font-size: 12.5px; line-height: 1.8;
}
/* 只有试做台有：这一页跑在静态服务器上，POST 不会通。 */
.gate-testnote {
  margin: 18px 0 0; padding: 10px 12px;
  border: 1px dashed rgba(27, 26, 23, 0.22);
  color: var(--ink-dark-3); font-size: 11.5px; line-height: 1.7; text-align: left;
}

/* ---------------------------------------------------------- 第 7 段：页脚 */
.foot {
  background: var(--paper);
  color: var(--ink-dark-2);
  padding: clamp(30px, 5vh, 52px) clamp(18px, 5vw, 58px) clamp(40px, 7vh, 72px);
  border-top: 1px solid rgba(27, 26, 23, 0.1);
}
.foot-inner {
  max-width: 1320px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}
.foot .brand { color: var(--ink-dark); }
.foot-links { display: flex; gap: clamp(14px, 2.4vw, 30px); flex-wrap: wrap; align-items: baseline; }
.foot-links a, .foot-links button {
  color: var(--ink-dark-2); font: 13px/1.4 var(--gothic);
  text-decoration: none; background: none; border: 0; border-bottom: 1px solid transparent;
  cursor: pointer; padding: 0 0 2px;
}
.foot-links a:hover, .foot-links button:hover { color: var(--ink-dark); border-color: var(--ink-dark); }
.foot-note { width: 100%; margin: clamp(20px, 3vh, 30px) 0 0; color: var(--ink-dark-3); font-size: 11.5px; line-height: 1.8; }

/* ------------------------------------------------------------ 转场带 */
/* 暗→亮那条渐变带有两个可能的位置，同一时刻只出现一条：
   夜（默认）→ 在第 5 段之后；点灯 → 提前到第 1 段之后。 */
.turn {
  height: clamp(140px, 22vh, 260px);
  background: linear-gradient(var(--night), #2a2823 24%, #ada598 58%, var(--paper) 88%);
}
.turn--before { display: none; }
[data-cast="light"] .turn--before { display: block; }
[data-cast="light"] .turn--after { display: none; }


/* ------------------------------------------------------------- 平板 */
@media (max-width: 1000px) {
  .can-grid { grid-template-columns: repeat(2, 1fr); }
  .can-item:nth-child(1), .can-item:nth-child(2),
  .can-item:nth-child(n + 3) { grid-column: span 1; }
  .can-item .can-frame, .can-item:nth-child(n + 3) .can-frame { aspect-ratio: 16 / 10; }
  .guide-grid { grid-template-columns: repeat(3, 1fr); }
  .desk { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------- 手机 */
@media (max-width: 760px) {
  /* 手机上顶对齐会把她的头顶顶到顶栏后面（375 宽上「印 + 喇叭 + 入 + JP/CN」
     那一行正好横在她脸上）。往下压一截：头顶落在顶栏下面，脸就整个露出来。
     用 svh 不用 vh——理由和 .hero 的高度同一条，地址栏会吃掉那一截。 */
  .l-figure {
    justify-content: center; padding-right: 0;
    align-items: flex-start;
    --fig-top: clamp(44px, 8svh, 92px);
    padding-top: var(--fig-top);
  }
  .l-figure > * {
    /* 高度按 svh 而不是百分比：上面那条 padding-top 会从百分比的基数里扣掉，
       她会跟着往下走一截的同时缩小一圈。这里要的只是「往下挪」，不是「变小」。 */
    height: 66svh; max-height: 66svh;
    /* 手机上她是顶对齐的，片子的下边缘正好落在画面中间，会留一条笔直的
       横切口。把底部化进黑里——桌面版不需要，那边这条边在画框外面。 */
    -webkit-mask-image: linear-gradient(#000 72%, transparent 98%);
    mask-image: linear-gradient(#000 72%, transparent 98%);
  }
  /* 那一层补光跟着她一起下移，否则光留在原地、人走了。 */
  .l-figure::after { right: auto; left: 50%; transform: translateX(-50%); width: 70vw; height: 66svh; top: var(--fig-top); bottom: auto; }
  .hero .l-fore { width: 74%; height: 34%; }
  /* 文案整块沉到画面底边：手机是单手拿着看的，「はじめる」离拇指越近越好，
     悬在半空中间那一版下面空着一大片黑，白白浪费掉最容易点的那一块。
     env() 那一项是给刘海机底部那条横杠留的位置（<meta viewport-fit=cover>
     已经开了），没有安全区的机器上它是 0。 */
  .copy {
    max-width: none;
    right: clamp(18px, 5vw, 58px);
    bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  }
  .title { font-size: clamp(27px, 8.2vw, 42px); }
  /* 她往下挪之后，这行小字落在她那件亮衣服上（矮屏尤其明显，640 高的机器上
     整行都压在胸口那片高光里）。给一层和 .lead 同一条的底光——顶上那句
     「一条看不见的链接不是次要，是不存在」对这行同样成立。 */
  .eyebrow { text-shadow: 0 1px 14px rgba(0, 0, 0, 0.92); }
  .tate, .scroll-cue { display: none; }
  .cast-grid { grid-template-columns: repeat(2, 1fr); }
  /* 两列之后卡片很窄，名字仍然压在人身上。幕布提前一点，字才读得出来——
     不过现在只剩两行字（2026-09-14），比原来那四行往回收了一截。 */
  .sheet { --scrim: linear-gradient(transparent 38%, rgba(7, 7, 10, 0.66) 60%, rgba(7, 7, 10, 0.96) 82%); }
  [data-cast="light"] .sheet { --scrim: linear-gradient(transparent 38%, rgba(255, 253, 248, 0.82) 60%, var(--paper-2) 82%); }
  .can-grid { grid-template-columns: 1fr; }
  .guide-grid { grid-template-columns: repeat(2, 1fr); }
  .gate-row { flex-direction: column; }
  /* 顶栏在 375 宽上挤不下「印 + あのね + ANONE + 喇叭 + ログイン + JP/CN」。
     先撤罗马字——它是给品牌认读用的，手机上那一行不缺它。 */
  .brand-kana { display: none; }
  .brand-mark { font-size: 19px; }
  .top { padding-left: 16px; padding-right: 16px; }
  .sound-hint { padding: 6px 10px; font-size: 0; }
  .sound-hint::before { content: "♪"; font-size: 13px; }
  /* 印留下，字撤掉——一枚红印比一行小字更认得出来，也更省地方（375 宽上顶栏
     本来就挤）。外圈那道胶囊也一起撤：只剩一枚印的时候，圆圈套方印是两层边框
     打架，印自己就是形状。 */
  /* 字留下，「ログイン」和竖线撤掉——375 宽的顶栏本来就挤。胶囊那圈留着：
     只剩一个字的时候，那圈是它「能点」的唯一交代，也把点得着的那块面积撑到
     34px 见方。 */
  .signin { padding: 6px 13px; gap: 0; }
  .signin-word, .signin-rule { display: none; }
  .signin-glyph { font-size: 19px; }
  /* 小箭头撤掉，地球仪和「JP」留着——箭头说的是「这里能点开」，那句话在手机上
     由「点一下就开了」自己说，不用先写在键上。摊开的三条一点没动：选项是内容，
     内容在哪块屏上都不该缩水。 */
  .lang-caret { display: none; }
  .lang-trigger { padding: 0 10px; gap: 5px; }
}

/* 关掉动效的人：全部直接到位，只保留淡入。 */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .intro * { animation-duration: 1ms !important; animation-delay: 0ms !important; }
  .l-bloom, .scroll-cue::after, .sound-hint, .signin { animation: none !important; }
  .lang-menu { animation: none !important; }
  .lang-caret { transition: none; }
}