/* index.html：填 Key 的首页。视觉方向 2「批注本」（借自吕敬人的书籍设计方法）。
   两个层级：外文在正文位置，中文在批注位置。朱色只用于批注、章号和印章；主要操作用墨色，没有别的强调色。
   1px 细线，直角，没有阴影和渐变。思源宋体接汉字，Newsreader 接拉丁字母和数字。
   颜色都是 :root 里的变量，深色模式只换这一组变量。 */
:root {
  color-scheme: light;
  --desk: #E9E4D8;
  --paper: #F6F2E8;
  --ink: #1F1B16;
  --soft: #6A6255;
  --rule: #CFC8B8;
  --red: #B4321E;
  --on-ink: #F6F2E8;
  /* 朱色的实心块（印章、章号、图上的标号）配纸色的字，深浅两种模式下是同一对颜色，和 app.css 一致 */
  --seal: #B4321E;
  --on-seal: #F6F2E8;
  --han: "Noto Serif SC", "Songti SC", "STSong", "Source Han Serif SC", "Noto Serif CJK SC", "SimSun", serif;
  --latin: "Newsreader", "Noto Serif SC", "Songti SC", "STSong", "Source Han Serif SC", "Noto Serif CJK SC", "SimSun", serif;
  --gutter: clamp(22px, 4.4vw, 60px);
  --gap: clamp(24px, 4vw, 56px);
}
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --desk: #12100D;
    --paper: #1B1814;
    --ink: #EFE9DC;
    --soft: #A69E8F;
    --rule: #3D382F;
    --red: #E8604A;
    --on-ink: #1B1814;
  }
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
html, body { overflow-x: clip; }
body { margin: 0; background: var(--desk); color: var(--ink); font-family: var(--latin); font-size: 17px; line-height: 1.9; }
h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
h1, h2, h3, b, dt { font-family: var(--han); font-weight: 900; }
p, li, dd, figcaption { text-wrap: pretty; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 4px; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.han { font-family: var(--han); }
.nowrap { white-space: nowrap; }

.sheet { max-width: 1300px; margin: clamp(0px, 2.2vw, 32px) auto; background: var(--paper); }

/* ---------- 首屏：一个对开页 ---------- */
.book { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.book::after { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--rule); }
.page { min-width: 0; padding: clamp(28px, 4.2vw, 56px) var(--gutter); }
.page--menu { grid-column: 1; grid-row: 1; }
.page--title { grid-column: 2; grid-row: 1; }

/* 左页：菜单原文在正文位置，朱色的中文在批注位置 */
.runhead { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 0 16px; padding-bottom: 10px; border-bottom: 1px solid var(--ink); font-size: 14px; line-height: 1.6; color: var(--soft); }
.runhead span { white-space: nowrap; }
.runhead span:first-child { font-size: 16px; }
.menu__cat { display: flex; align-items: baseline; gap: 14px; margin-top: 26px; font-size: 26px; line-height: 1.3; }
.menu__cat [lang] { font-style: italic; }
.menu__gloss { font-family: var(--han); font-size: 15px; color: var(--red); }
.line { display: flex; align-items: baseline; gap: 10px; margin-top: 18px; font-size: clamp(20px, 1.8vw, 25px); line-height: 1.3; }
.line__dots { flex: 1; min-width: 20px; border-bottom: 1px dotted var(--ink); }
.note { margin: 6px 0 0 18px; padding-left: 14px; border-left: 2px solid var(--red); color: var(--red); font-family: var(--han); font-size: 16px; line-height: 1.65; }
.note b { margin-right: 0.6em; font-size: 1.15em; }

/* 右页：竖排书名、竖排说明、Key 表单、分享码、印章 */
.page--title { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; grid-template-rows: 1fr auto auto; column-gap: clamp(14px, 2vw, 28px); row-gap: 24px; }
h1 { grid-column: 3; grid-row: 1 / 4; writing-mode: vertical-rl; font-size: clamp(60px, 7.5vw, 108px); line-height: 1; letter-spacing: 0.08em; }
.lead { grid-column: 2; grid-row: 1; writing-mode: vertical-rl; height: 10.9em; font-family: var(--han); font-size: clamp(17px, 1.55vw, 22px); line-height: 2; letter-spacing: 0.06em; }
.seal { grid-column: 3; grid-row: 3; align-self: end; justify-self: center; display: grid; place-items: center; width: 62px; height: 62px; background: var(--seal); color: var(--on-seal); font-family: var(--han); font-weight: 900; font-size: 36px; line-height: 1; }

/* ---------- Key 表单 ---------- */
.keybox { grid-column: 1 / 3; grid-row: 2; align-self: end; min-width: 0; padding: 18px 22px 20px; border: 1px solid var(--ink); font-size: 16px; line-height: 1.6; }
.field__label { display: block; }
.field__row { display: flex; align-items: center; gap: 10px; margin-top: 6px; border-bottom: 1px solid var(--ink); }
.field__row:has([aria-invalid="true"]) { border-bottom: 2px solid var(--red); margin-bottom: -1px; }
#api-key { flex: 1; min-width: 0; height: 52px; padding: 0 2px; border: 0; border-radius: 0; background: transparent; font-size: 20px; }
#api-key::placeholder { color: var(--soft); opacity: 1; }
.field__toggle { flex: none; min-width: 60px; height: 44px; padding: 0 12px; border: 0; border-radius: 0; background: transparent; font-size: 15px; }
.field__toggle[aria-pressed="true"] { background: var(--ink); color: var(--on-ink); }
/* 表单的提示是一条批注：朱色，左边一道朱线 */
.field__msg { margin-top: 10px; padding-left: 12px; border-left: 2px solid var(--red); color: var(--red); font-family: var(--han); font-size: 15px; line-height: 1.6; }
.field__msg:empty { display: none; }
.check { display: flex; align-items: center; gap: 10px; width: fit-content; min-height: 44px; margin-top: 6px; font-size: 15px; cursor: pointer; }
.check input { -webkit-appearance: none; appearance: none; flex: none; display: grid; place-content: center; width: 20px; height: 20px; margin: 0; border: 1px solid var(--ink); border-radius: 0; background: transparent; cursor: pointer; }
.check input::before { content: ""; width: 11px; height: 6px; border-left: 2px solid var(--on-ink); border-bottom: 2px solid var(--on-ink); transform: translateY(-1px) rotate(-45deg); visibility: hidden; }
.check input:checked { background: var(--ink); }
.check input:checked::before { visibility: visible; }
.actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
#key-save-anyway { flex: 1 1 auto; }
/* “正在检查…”比“检查 Key 并开始”短，按钮不跟着变窄 */
#key-submit { min-width: 9.5em; }
/* 检查失败时提示插在按钮上面，表单框在宽屏上贴着页脚，按钮会被顶上去。“不检查，保存并继续”放不进同一行时
   排到主按钮上面，主按钮留在原地：手没挪开再点一下，点到的还是“检查”。 */
@media (min-width: 601px) {
  #key-form .actions { flex-wrap: wrap-reverse; }
}
.btn { display: inline-flex; align-items: center; justify-content: center; min-height: 50px; padding: 0 14px; border: 1px solid var(--ink); border-radius: 0; background: transparent; color: var(--ink); font-weight: 600; font-size: 16px; line-height: 1.3; text-decoration: none; }
.btn--primary { padding: 0 18px; background: var(--ink); color: var(--on-ink); font-size: 17px; }
.btn:disabled { border-color: var(--soft); background: var(--soft); color: var(--on-ink); cursor: progress; }
/* 鼠标移上去：按钮外面多一道细线框，“显示”多一道下划线 */
@media (hover: hover) {
  .btn:hover:not(:disabled):not(:focus-visible) { outline: 1px solid var(--ink); outline-offset: 3px; }
  .field__toggle:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
}
@media (prefers-reduced-motion: no-preference) {
  .btn:active:not(:disabled) { transform: translateY(1px); }
}
.hint { margin-top: 12px; font-size: 14px; line-height: 1.7; color: var(--soft); }
/* 提示里一句话一个整体，标题里一个分句一个整体：放不下时整句换到下一行，不从中间断开 */
.hint span, h2 span { display: inline-block; }
.saved__key { display: flex; align-items: center; height: 52px; margin-top: 6px; border-bottom: 1px solid var(--ink); font-size: 20px; }
#key-saved .actions { margin-top: 16px; }

/* ---------- 分享码：给同桌收到分享码的人，不用 Key ----------
   排在 Key 表单下面，和表单框的左边对齐。没有框，“打开”是线框按钮，标签和 Key 表单的一样大，
   全页唯一的实心按钮还是“检查 Key 并开始”。输入框的字不小于 16px，手机上点进去时不会放大页面。 */
.codebox { grid-column: 1 / 3; grid-row: 3; align-self: end; min-width: 0; font-size: 16px; line-height: 1.6; }
.code__row { display: flex; align-items: center; gap: 12px; margin-top: 4px; }
#code-field { flex: 0 1 9em; min-width: 0; height: 44px; padding: 0 2px; border: 0; border-bottom: 1px solid var(--ink); border-radius: 0; background: transparent; font-size: 18px; letter-spacing: 0.12em; text-transform: uppercase; }
#code-field[aria-invalid="true"] { border-bottom: 2px solid var(--red); }
#code-field::placeholder { color: var(--soft); opacity: 1; }
#code-open { min-height: 44px; padding: 0 18px; }
.codebox .field__msg { margin-top: 8px; }
.codebox .hint { margin-top: 6px; }

/* ---------- 往下每一章：左边一窄栏放章号，右边是正文 ---------- */
.sec { display: grid; grid-template-columns: clamp(72px, 8.3vw, 120px) minmax(0, 1fr); column-gap: var(--gap); padding: clamp(48px, 7vw, 96px) var(--gutter); border-top: 1px solid var(--rule); }
.sec__side { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.sec__no { display: grid; place-items: center; width: 40px; height: 40px; background: var(--seal); color: var(--on-seal); font-family: var(--han); font-weight: 900; font-size: 22px; line-height: 1; }
.sec__run { writing-mode: vertical-rl; margin-left: 8px; font-family: var(--han); font-size: 14px; letter-spacing: 0.2em; color: var(--soft); }
.sec__body { min-width: 0; }
h2 { font-size: clamp(27px, 3.3vw, 44px); line-height: 1.35; text-wrap: balance; }
.sub { max-width: 32em; margin-top: 14px; }
.cap { margin-top: 10px; font-size: 14px; line-height: 1.7; color: var(--soft); }

/* 一 它做什么：截图和六条批注 */
.fig { display: grid; grid-template-columns: minmax(0, 360px) minmax(0, 1fr); gap: var(--gap); align-items: start; margin-top: clamp(28px, 4vw, 48px); }
.shot { position: relative; border: 1px solid var(--ink); background: var(--paper); }
.shot img { width: 100%; }
/* 标号是圆的：全页唯一的圆角。截图里识别页自己的印章和按钮都是方的，圈点才不会被看成界面的一部分。 */
.mk { position: absolute; left: var(--x); top: var(--y); display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--seal); color: var(--on-seal); font-family: var(--han); font-size: 14px; font-weight: 900; line-height: 1; transform: translate(-50%, -50%); }
/* 图一的标号。--x、--y 是标号中心相对截图左上角的百分比，截图是 img/app-result.webp（780×1404，5:9）。
   标号站在它说的那一部分旁边，不压在字上：一 分类栏里最后一个分类的下面；二 第一道菜示意图的左上角；
   三 中文名和原文名的右边；四 简介最后一个字的后面；五 标记（素、通常含）的右边；六 价格和加减份数之间。
   重新截图后只改这六行：node design-demos/tools/capture-app.js 会把这六行按新截图算好打印出来。 */
.mk--1 { --x: 9.7%; --y: 48.6%; }
.mk--2 { --x: 25.3%; --y: 30.7%; }
.mk--3 { --x: 84.8%; --y: 33.4%; }
.mk--4 { --x: 69.4%; --y: 46.5%; }
.mk--5 { --x: 87.7%; --y: 50.4%; }
.mk--6 { --x: 61.0%; --y: 55.1%; }
.notes { max-width: 24em; color: var(--red); font-family: var(--han); font-size: clamp(17px, 1.5vw, 20px); }
.notes li { display: grid; grid-template-columns: 1.6em minmax(0, 1fr); padding: 16px 0; border-top: 1px solid var(--rule); }
.notes li:last-child { border-bottom: 1px solid var(--rule); }

/* 二 每道菜：左边一张方的示意图（img/dish-carbonara.webp，640×640，最宽显示 280px，二倍屏上也清楚），右边是这道菜的批注 */
.entry { display: grid; grid-template-columns: minmax(0, 260px) minmax(0, 1fr); gap: var(--gap); align-items: center; margin-top: clamp(28px, 4vw, 48px); }
.plate img { width: 100%; aspect-ratio: 1; border: 1px solid var(--ink); }
.entry .line { margin-top: 0; font-size: clamp(22px, 2.4vw, 32px); }
.entry .note { margin-top: 10px; font-size: 17px; }
.fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gap); margin-top: clamp(28px, 4vw, 48px); }
.fields div { display: grid; grid-template-columns: 6.5em minmax(0, 1fr); align-items: baseline; gap: 12px; padding: 12px 0; border-top: 1px solid var(--rule); }
.fields dd { color: var(--soft); }

/* 三 点菜清单 */
.pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, min(380px, 46%)); gap: var(--gap); align-items: start; }

/* 四 Key 和费用 */
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gap); margin-top: clamp(28px, 4vw, 48px); }
.facts li { padding: 18px 0 22px; border-top: 1px solid var(--ink); }
h3 { font-size: clamp(19px, 1.9vw, 24px); line-height: 1.5; }
h3 b { margin-right: 0.5em; color: var(--red); }
.facts p { margin-top: 6px; color: var(--soft); }

/* 五 附记：三条批注 */
.after { max-width: 36em; margin-top: clamp(24px, 3.4vw, 40px); }
.after li { padding-left: 14px; border-left: 2px solid var(--red); color: var(--red); font-family: var(--han); }
.after li + li { margin-top: 16px; }

/* 版权页 */
.colophon { padding: 32px var(--gutter) 48px; border-top: 1px solid var(--ink); font-size: 14px; line-height: 1.8; color: var(--soft); }

/* 404.html：找不到页面时 Cloudflare Pages 给的页面，排成一章，标题横排，字号和章标题一样 */
.lost .sec { border-top: 0; }
.lost h1 { writing-mode: horizontal-tb; font-size: clamp(27px, 3.3vw, 44px); line-height: 1.35; letter-spacing: 0; text-wrap: balance; }
.lost .actions { margin-top: 28px; }

/* ---------- 表单不贴页脚的时候：跟在说明下面，分享码跟在表单下面 ----------
   贴着页脚时，最下面一栏是分享码，表单框在它上面。两种情况不贴页脚：
   1. 对开页比屏幕高时（矮的笔记本和横放的平板），贴着页脚的分享码和表单会被屏幕下沿切掉。左页每条批注都是两行，
      页脚在 1240px 以上最低到 871px（菜名的字号和页边距跟着屏幕宽度变大，到 1440px 为止），所以要到 881px 高才贴页脚。
   2. 1240px 以下右页窄。检查 Key 没成功时，表单框里多出提示和“不检查，保存并继续”，要往上长；表单框和分享码都贴着页脚时，
      上面留给它的地方不够，对开页会被撑高，“检查 Key 并开始”跟着往下挪。所以这个宽度下表单总是跟在说明下面。
   数字是用网页字体量的，改了左页的菜单或这两个表单要重新量。 */
@media (min-width: 861px) and (max-width: 1239px), (min-width: 1240px) and (max-height: 880px) {
  .page--title { grid-template-rows: auto auto 1fr; }
  .keybox, .codebox { align-self: start; }
}

/* ---------- 窄屏：一栏。先是书名、说明和表单，再是带批注的菜单 ---------- */
@media (max-width: 860px) {
  .sheet { margin-block: 0; }
  .book { grid-template-columns: minmax(0, 1fr); }
  .book::after { display: none; }
  .page--menu, .page--title { grid-column: 1; grid-row: auto; }
  .page--menu { border-top: 1px solid var(--rule); }
  /* 书名页：表单在左下，说明和书名在右，印章在书名下面，分享码在表单下面 */
  .page--title { grid-template-rows: auto auto auto; }
  h1 { grid-row: 1; }
  .lead { grid-row: 1 / 3; height: 17em; }
  .seal { grid-row: 2; width: 52px; height: 52px; font-size: 30px; }
  .keybox { grid-column: 1; grid-row: 1 / 3; justify-self: start; width: 100%; max-width: 460px; }
  .codebox { grid-column: 1; grid-row: 3; align-self: start; justify-self: start; width: 100%; max-width: 460px; }
  .sec { grid-template-columns: minmax(0, 1fr); }
  .sec__side { flex-direction: row; align-items: center; margin-bottom: 18px; }
  .sec__no { width: 34px; height: 34px; font-size: 19px; }
  .sec__run { writing-mode: horizontal-tb; margin-left: 0; }
}

/* ---------- 手机：书名、说明、印章一行，表单占满下一行，分享码再下一行 ---------- */
@media (max-width: 600px) {
  .page--title { row-gap: 28px; }
  .lead { grid-row: 1; }
  .seal { grid-column: 1; grid-row: 1; justify-self: start; }
  .keybox { grid-column: 1 / 4; grid-row: 2; max-width: none; }
  .codebox { grid-column: 1 / 4; grid-row: 3; max-width: none; }
  .actions .btn { flex: 1 1 auto; }
  .fig, .entry, .pair, .fields, .facts { grid-template-columns: minmax(0, 1fr); }
  .fig figure { width: min(100%, 320px); }
  .plate { width: min(100%, 280px); }
  .pair figure { width: min(100%, 360px); }
  .mk { width: 20px; height: 20px; font-size: 12px; }
}
/* Below 360px "Spaghetti alla Carbonara" does not fit on one line at 22px, and its leader would start far
   from the name. At 19px it fits at 320px, with a leader of about 30px. */
@media (max-width: 359px) {
  .entry .line { font-size: 19px; }
}
