/* 句型贪吃蛇 · 样式。和连连看同一套浅色主题：白卡、墨蓝字、一抹亮绿，平的，没有阴影。颜色都在下面这组变量里。
   成分颜色永远不是唯一的信号：块左端还印字母（S V O C A），色弱的学生也分得清。
   成分浅底（块）：S 蓝、V 红、O 黄、C 紫、A 白底虚线框（虚线 = 能挪）；吃下去那几节用同一成分的深色。
   C 用 #cdb6ff 不用连连看的 #dccbff：绿色盲模拟下 #dccbff 和主语蓝几乎分不开。
   唯一源在 网站-门户网站/rocket/。 */
.sn-root { width:100%; font-family:inherit;
  --sn-ink:#042330; --sn-sub:#56666d; --sn-line:#dfe6e3; --sn-soft:#f1f6f4; --sn-board:#f7faf9; --sn-grid:#e9efed;
  --sn-green:#2ce080; --sn-green-deep:#087a45; --sn-next:#0365f2; --sn-warn:#c2361f;
  --sn-s:#b8dcff; --sn-v:#ffc2c7; --sn-o:#ffeb99; --sn-c:#cdb6ff; --sn-a:#ffffff;
  --sn-s-line:#1f5fa8; --sn-v-line:#b3261e; --sn-o-line:#8a5a00; --sn-c-line:#5b3fb0; --sn-a-line:#56666d;
  --sn-s-deep:#1f5fbf; --sn-v-deep:#c45100; --sn-o-deep:#00796b; --sn-c-deep:#8e2f86; --sn-a-deep:#7a6a3a;
  --sn-rival:#56666d; --sn-rival-2:#c5cfd0; --sn-rival-head:#2b3438;
  /* 从句题的三种：主句（淡蓝）、引导词（杏色，整句的「关节」）、从句（淡青）。只在从句包里出现，和基本句型那五种不同时上场 */
  --sn-m:#dbe8f6; --sn-k:#ffd2a8; --sn-x:#cdeee8;
  --sn-m-line:#2f5d8a; --sn-k-line:#a6460c; --sn-x-line:#0f6e75;
  --sn-m-deep:#2f5d8a; --sn-k-deep:#b0480f; --sn-x-deep:#0f6e75; }
.sn-root * { box-sizing:border-box; }
.sn-root [hidden] { display:none !important; }
.sn-root .sn-game { position:relative; max-width:736px; margin:auto; overflow:hidden; border-radius:20px; background:#fff; color:var(--sn-ink); color-scheme:light; padding-bottom:16px; text-align:left; }
.sn-root .sn-game::after { content:""; position:absolute; inset:0; border:1px solid var(--sn-line); border-radius:inherit; pointer-events:none; }
.sn-root button { font:inherit; cursor:pointer; color:inherit; }
.sn-root button:focus-visible, .sn-root .sn-board:focus-visible { outline:2px solid var(--sn-next); outline-offset:2px; }
.sn-root .sn-header { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:8px 10px; padding:12px 16px 4px; font-weight:700; }
.sn-root .sn-tools { position:relative; display:flex; flex-wrap:wrap; gap:8px; }   /* 设置 / 全屏玩 / 暂停：手机上放不下一行就折 */
/* 设置：声音、朗读、连续玩收在一个弹出的小框里（平的、描边，没有阴影）。框对着这一排的右边缘，不对着设置钮：
   手机上标题和这一排分两行，设置钮在最左边，对着它往左开就开出卡片外被裁掉（2026-10-07 评审） */
.sn-root .sn-set { position:static; }
.sn-root .sn-setpanel { position:absolute; right:0; top:calc(100% + 6px); z-index:6; display:flex; flex-direction:column; align-items:stretch; gap:8px; min-width:150px; padding:10px;
  border:1.5px solid var(--sn-ink); border-radius:18px; background:#fff; }
.sn-root .sn-tools button { min-height:40px; padding:6px 14px; border:1.5px solid var(--sn-ink); border-radius:99px; background:#fff; font-weight:600; font-size:.92em; }

/* 选类、选关：两个下拉排一行（2026-10-07 站主：按键收成下拉，更简洁、突出游戏），放不下就折到第二行（不横着滚，不藏东西）。
   下拉是原生 select：手机上点开是系统的选择器，好点；右边的小三角用两道渐变画（不用图标字符） */
.sn-root .sn-pick { display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding:10px 16px 6px; }
.sn-root .sn-packs, .sn-root .sn-levels { display:flex; min-width:0; max-width:100%; }
.sn-root .sn-pick select { -webkit-appearance:none; appearance:none; max-width:100%; min-height:40px; padding:6px 34px 6px 14px; border:1.5px solid var(--sn-ink); border-radius:99px;
  color:var(--sn-ink); font:inherit; font-size:16px; font-weight:600; cursor:pointer; background-color:#fff;   /* 16px：小于 16 的表单控件 iPhone 一点就把整页放大 */
  background-image:linear-gradient(45deg, transparent 50%, var(--sn-ink) 50%), linear-gradient(135deg, var(--sn-ink) 50%, transparent 50%);
  background-position:calc(100% - 20px) 52%, calc(100% - 14px) 52%; background-size:6px 6px, 6px 6px; background-repeat:no-repeat; }
.sn-root .sn-pick select:focus-visible { outline:2px solid var(--sn-next); outline-offset:2px; }
/* 难句再练：跟在两个下拉后面，白底虚线框；正在练时变深 */
.sn-root .sn-hardlv { min-height:40px; padding:4px 14px; border:1.5px dashed var(--sn-sub); border-radius:99px; background:#fff; color:var(--sn-ink); font-size:.92em; }
.sn-root .sn-hardlv.on { border-style:solid; border-color:var(--sn-ink); background:var(--sn-ink); color:#fff; font-weight:600; }

.sn-root .sn-status { display:flex; justify-content:space-between; flex-wrap:wrap; gap:10px; padding:6px 18px 0; font-variant-numeric:tabular-nums; color:var(--sn-sub); font-size:.92em; }
.sn-root .sn-where { color:var(--sn-ink); font-weight:600; }
/* 这一句的级别（A1~C1）：跟在「第几句」后面的一枚小签，页面传了 options.cefr 才出 */
.sn-root .sn-whereg { display:inline-flex; align-items:center; gap:6px; }
.sn-root .sn-cefr { display:inline-block; padding:0 6px; border:1px solid currentColor; border-radius:6px; color:var(--sn-ink); font-size:.82em; font-weight:700; line-height:1.5; letter-spacing:.02em; }
.sn-root .sn-cefr[hidden] { display:none; }

/* 题目：整句中文一直挂着（定死意思），句型名，格子条 */
.sn-root .sn-task { padding:8px 18px 0; }
.sn-root .sn-zh { margin:0; font-size:1.08em; font-weight:600; line-height:1.5; }
.sn-root .sn-pattern { margin:2px 0 0; color:var(--sn-sub); font-size:.92em; }
.sn-root .sn-slots { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.sn-root .sn-slot { min-width:44px; min-height:32px; padding:4px 10px; border:1.5px solid var(--sn-line); border-radius:10px; background:var(--sn-soft); color:var(--sn-sub); font-size:.92em; font-weight:600; display:inline-flex; align-items:center; justify-content:center; }
.sn-root .sn-slot.next { border-color:var(--sn-next); }
.sn-root .sn-slot.filled { border-color:var(--sn-ink); background:#fff; color:var(--sn-ink); }
.sn-root .sn-slot.filled.r-S { background:var(--sn-s); } .sn-root .sn-slot.filled.r-V { background:var(--sn-v); }
.sn-root .sn-slot.filled.r-O, .sn-root .sn-slot.filled.r-Oi, .sn-root .sn-slot.filled.r-Od { background:var(--sn-o); }
.sn-root .sn-slot.filled.r-Cs, .sn-root .sn-slot.filled.r-Co { background:var(--sn-c); }
.sn-root .sn-slot.filled.r-M { background:var(--sn-m); } .sn-root .sn-slot.filled.r-K { background:var(--sn-k); } .sn-root .sn-slot.filled.r-X { background:var(--sn-x); }
/* 连续玩：刚做完的那句留在格子条下面一行（一直占着这一行，换句时棋盘不上下跳） */
.sn-root .sn-last { margin:8px 0 0; min-height:1.55em; color:var(--sn-sub); font-size:.92em; line-height:1.55; overflow-wrap:anywhere; }
.sn-root .sn-hint { min-height:calc(3.1em + 10px); margin:0; padding:8px 18px 4px; line-height:1.55; overflow-wrap:anywhere; }

/* 棋盘：格子边长和字号由 snake-game.js 写进 --sn-cell / --sn-font；块和蛇都是绝对定位的 div */
.sn-root .sn-boardwrap { position:relative; padding:6px 12px 0; }
.sn-root .sn-board { position:relative; margin:0 auto; background-color:var(--sn-board); border:2px solid var(--sn-ink); border-radius:6px; box-sizing:content-box; outline:none;
  background-image:linear-gradient(var(--sn-grid) 1px, transparent 1px), linear-gradient(90deg, var(--sn-grid) 1px, transparent 1px);
  background-size:var(--sn-cell, 32px) var(--sn-cell, 32px); touch-action:pan-y; }
/* 玩着的时候（包括每句开头等出发）手指在棋盘上滑是转向，不让页面跟着滚；暂停、结束时放开 */
.sn-root .sn-board.sn-live { touch-action:none; }
.sn-root .sn-chunk { position:absolute; display:flex; align-items:center; gap:5px; padding:0 6px; border:1.5px solid var(--sn-ink); border-radius:8px; background:#fff;
  font-size:var(--sn-font, 15px); font-weight:600; line-height:1; white-space:nowrap; }
/* 量字用的隐身块（snake-game.js 的 measureChunk）：不占位、看不见，宽度由字撑开 */
.sn-root .sn-chunk.sn-measure { visibility:hidden; left:0; top:0; pointer-events:none; }
.sn-root .sn-chunk.plain { border-color:var(--sn-ink); }
.sn-root .sn-chunk.r-S { background:var(--sn-s); border-color:var(--sn-s-line); }
.sn-root .sn-chunk.r-V { background:var(--sn-v); border-color:var(--sn-v-line); }
.sn-root .sn-chunk.r-O, .sn-root .sn-chunk.r-Oi, .sn-root .sn-chunk.r-Od { background:var(--sn-o); border-color:var(--sn-o-line); }
.sn-root .sn-chunk.r-Cs, .sn-root .sn-chunk.r-Co { background:var(--sn-c); border-color:var(--sn-c-line); }
.sn-root .sn-chunk.r-A { background:var(--sn-a); border:1.5px dashed var(--sn-a-line); }
.sn-root .sn-chunk.r-M { background:var(--sn-m); border-color:var(--sn-m-line); }
.sn-root .sn-chunk.r-K { background:var(--sn-k); border-color:var(--sn-k-line); }
.sn-root .sn-chunk.r-X { background:var(--sn-x); border-color:var(--sn-x-line); }
/* 成分小标签：实心色块、白字，颜色跟这一成分走（和吃下去那几节蛇身同一套深色）。
   2026-10-06 站主：标签要和词有区分度——原来是同色细字贴在词前面，「V smiled」读起来像一个词 */
.sn-root .sn-tag { flex:none; display:inline-flex; align-items:center; justify-content:center; min-width:1.4em; height:1.4em; padding:0 .3em; border-radius:.4em;
  font-size:.72em; font-weight:800; line-height:1; color:#fff; background:var(--sn-ink); }
.sn-root .r-S .sn-tag { background:var(--sn-s-deep); } .sn-root .r-V .sn-tag { background:var(--sn-v-deep); }
.sn-root .r-O .sn-tag, .sn-root .r-Oi .sn-tag, .sn-root .r-Od .sn-tag { background:var(--sn-o-deep); }
.sn-root .r-Cs .sn-tag, .sn-root .r-Co .sn-tag { background:var(--sn-c-deep); }
.sn-root .r-A .sn-tag { background:var(--sn-a-deep); }
.sn-root .r-M .sn-tag { background:var(--sn-m-deep); } .sn-root .r-K .sn-tag { background:var(--sn-k-deep); } .sn-root .r-X .sn-tag { background:var(--sn-x-deep); }
/* 词一律完整显示：不截断、不加省略号（块的宽度在 snake-game.js 里按真字量好了） */
.sn-root .sn-text { white-space:nowrap; }
.sn-root .sn-chunk.hinted, .sn-root .sn-tapchunk.hinted { outline:3px solid var(--sn-next); outline-offset:1px; }
.sn-root .sn-chunk.wrong, .sn-root .sn-tapchunk.wrong { border:2px solid var(--sn-warn); animation:sn-shake .3s ease; }
@keyframes sn-shake { 0%, 100% { transform:translateX(0); } 25% { transform:translateX(-3px); } 75% { transform:translateX(3px); } }

/* 蛇：亮绿身子、墨蓝描边，头是墨蓝；这一句吃下去的那几节按成分着深色 */
.sn-root .sn-seg { position:absolute; width:var(--sn-cell, 32px); height:var(--sn-cell, 32px); padding:2px; display:block; }
.sn-root .sn-seg::before { content:""; display:block; width:100%; height:100%; border-radius:30%; background:var(--sn-green); border:2px solid var(--sn-ink); }
.sn-root .sn-seg.sn-head::before { background:var(--sn-ink); border-radius:40%; }
.sn-root .sn-seg.d-S::before { background:var(--sn-s-deep); } .sn-root .sn-seg.d-V::before { background:var(--sn-v-deep); }
.sn-root .sn-seg.d-O::before, .sn-root .sn-seg.d-Oi::before, .sn-root .sn-seg.d-Od::before { background:var(--sn-o-deep); }
.sn-root .sn-seg.d-Cs::before, .sn-root .sn-seg.d-Co::before { background:var(--sn-c-deep); }
.sn-root .sn-seg.d-A::before { background:var(--sn-a-deep); }
.sn-root .sn-seg.d-M::before { background:var(--sn-m-deep); } .sn-root .sn-seg.d-K::before { background:var(--sn-k-deep); } .sn-root .sn-seg.d-X::before { background:var(--sn-x-deep); }
/* 干扰蛇：灰色斜条纹、深灰的头加一圈红边。和自己那条（亮绿）、吃下去那几节的成分深色都分得开；条纹是形状上的区别，色弱也认得出 */
.sn-root .sn-seg.sn-rival::before { background:repeating-linear-gradient(45deg, var(--sn-rival) 0 3px, var(--sn-rival-2) 3px 6px); border-color:var(--sn-rival-head); }
.sn-root .sn-seg.sn-rival.sn-rival-head::before { background:var(--sn-rival-head); border-color:var(--sn-warn); border-radius:40%; }

/* 360° 转向（2026-10-21，方案 8.23；根节点带 sn-free）：块一层、蛇一层，蛇身是一串圆点，每帧只改 transform（不加过渡，位置全由脚本算——画在哪就按哪判撞）。
   先铺一层墨蓝的圆（描边），再铺一层小一圈的绿圆（填充），头最后放，看着是一条带边的管子；头上两只白眼睛朝着走的方向。没有阴影 */
.sn-root.sn-free .sn-board { -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; -webkit-tap-highlight-color:transparent; isolation:isolate; }   /* 只管 360°：格子模式（闯关页）一字不变 */
.sn-root .sn-blocks, .sn-root .sn-snake { position:absolute; left:0; top:0; width:100%; height:100%; pointer-events:none; }
.sn-root .sn-snake { contain:layout paint; }
.sn-root .sn-snake i { position:absolute; left:0; top:0; display:block; border-radius:50%; pointer-events:none; transition:none; }
.sn-root .sn-outl .sn-dot { width:calc(var(--sn-cell, 32px) * .6); height:calc(var(--sn-cell, 32px) * .6); margin:calc(var(--sn-cell, 32px) * -.3) 0 0 calc(var(--sn-cell, 32px) * -.3); background:var(--sn-ink); }
.sn-root .sn-fill .sn-dot { width:calc(var(--sn-cell, 32px) * .6 - 4px); height:calc(var(--sn-cell, 32px) * .6 - 4px); margin:calc(var(--sn-cell, 32px) * -.3 + 2px) 0 0 calc(var(--sn-cell, 32px) * -.3 + 2px); background:var(--sn-green); }
.sn-root .sn-fill .sn-dot.d-S { background:var(--sn-s-deep); } .sn-root .sn-fill .sn-dot.d-V { background:var(--sn-v-deep); }
.sn-root .sn-fill .sn-dot.d-O, .sn-root .sn-fill .sn-dot.d-Oi, .sn-root .sn-fill .sn-dot.d-Od { background:var(--sn-o-deep); }
.sn-root .sn-fill .sn-dot.d-Cs, .sn-root .sn-fill .sn-dot.d-Co { background:var(--sn-c-deep); }
.sn-root .sn-fill .sn-dot.d-A { background:var(--sn-a-deep); }
.sn-root .sn-fill .sn-dot.d-M { background:var(--sn-m-deep); } .sn-root .sn-fill .sn-dot.d-K { background:var(--sn-k-deep); } .sn-root .sn-fill .sn-dot.d-X { background:var(--sn-x-deep); }
.sn-root .sn-snake .sn-fhead { width:calc(var(--sn-cell, 32px) * .7); height:calc(var(--sn-cell, 32px) * .7); margin:calc(var(--sn-cell, 32px) * -.35) 0 0 calc(var(--sn-cell, 32px) * -.35); background:var(--sn-ink); }
.sn-root .sn-fhead::before, .sn-root .sn-fhead::after { content:""; position:absolute; left:52%; width:24%; height:24%; border-radius:50%; background:#fff; }
.sn-root .sn-fhead::before { top:14%; } .sn-root .sn-fhead::after { top:62%; }
.sn-root .sn-snake .sn-rdot { width:calc(var(--sn-cell, 32px) * .8); height:calc(var(--sn-cell, 32px) * .8); margin:calc(var(--sn-cell, 32px) * -.4) 0 0 calc(var(--sn-cell, 32px) * -.4); box-sizing:border-box;
  background:repeating-linear-gradient(45deg, var(--sn-rival) 0 3px, var(--sn-rival-2) 3px 6px); border:2px solid var(--sn-rival-head); }
.sn-root .sn-snake .sn-rdot.sn-rival-head { background:var(--sn-rival-head); border-color:var(--sn-warn); }

/* 一句做完、暂停：盖在棋盘上的面板 */
/* 内容比棋盘高（手机上卡过的句子：整句 + 规矩 + 也可以说）：面板里自己滚，不往上溢出盖住提示、「下一句」不压到方向键（2026-10-06 评审） */
.sn-root .sn-done, .sn-root .sn-paused { position:absolute; inset:6px 12px 0; display:flex; flex-direction:column; align-items:center; justify-content:center; justify-content:safe center; overflow-y:auto; gap:6px; padding:16px;
  background:rgba(255,255,255,.95); border-radius:8px; text-align:center; }
.sn-root .sn-done-en { margin:0; font-size:1.25em; font-weight:700; }
.sn-root .sn-done-roles { margin:0; color:var(--sn-sub); font-size:.92em; }
.sn-root .sn-done-zh { margin:0; }
.sn-root .sn-done-alt, .sn-root .sn-done-note { margin:0; color:var(--sn-ink); font-size:.92em; max-width:34em; }
.sn-root .sn-go, .sn-root .sn-resume, .sn-root .sn-quit, .sn-root .sn-again, .sn-root .sn-here, .sn-root .sn-redo { min-height:44px; padding:8px 22px; border:1.5px solid var(--sn-ink); border-radius:99px; background:var(--sn-ink); color:#fff; font-weight:600; }
.sn-root .sn-quit, .sn-root .sn-here { background:#fff; color:var(--sn-ink); }

/* 点块排句：不开蛇，按顺序点块（读屏、投屏、布置作业用） */
.sn-root .sn-tapbox { display:flex; flex-wrap:wrap; gap:10px; padding:12px 18px; justify-content:center; }
.sn-root .sn-tapchunk { min-height:44px; padding:8px 14px; border:1.5px solid var(--sn-ink); border-radius:10px; background:#fff; font-weight:600;
  display:inline-flex; align-items:center; gap:6px; }
.sn-root .sn-tapchunk.r-S { background:var(--sn-s); } .sn-root .sn-tapchunk.r-V { background:var(--sn-v); }
.sn-root .sn-tapchunk.r-O, .sn-root .sn-tapchunk.r-Oi, .sn-root .sn-tapchunk.r-Od { background:var(--sn-o); }
.sn-root .sn-tapchunk.r-Cs, .sn-root .sn-tapchunk.r-Co { background:var(--sn-c); }
.sn-root .sn-tapchunk.r-A { border-style:dashed; }
.sn-root .sn-tapchunk.r-M { background:var(--sn-m); } .sn-root .sn-tapchunk.r-K { background:var(--sn-k); } .sn-root .sn-tapchunk.r-X { background:var(--sn-x); }
/* 点块排句没有棋盘：做完一句、暂停的面板不再盖在棋盘上，排在块的上面 */
.sn-root .sn-boardwrap.sn-tapwrap .sn-done, .sn-root .sn-boardwrap.sn-tapwrap .sn-paused { position:static; }

/* 方向键：倒 T，只在触屏上露出来 */
.sn-root .sn-pad { display:none; flex-direction:column; align-items:center; gap:6px; padding:12px 0 0; }
@media (pointer: coarse) { .sn-root .sn-pad { display:flex; } }
.sn-root .sn-pad-row { display:flex; gap:6px; }
.sn-root .sn-dir { width:52px; height:52px; border:1.5px solid var(--sn-ink); border-radius:14px; background:#fff; display:flex; align-items:center; justify-content:center; touch-action:manipulation; }
.sn-root .sn-arrow { width:0; height:0; border:9px solid transparent; }
.sn-root .sn-arrow-up { border-bottom:12px solid var(--sn-ink); border-top:0; }
.sn-root .sn-arrow-down { border-top:12px solid var(--sn-ink); border-bottom:0; }
.sn-root .sn-arrow-left { border-right:12px solid var(--sn-ink); border-left:0; }
.sn-root .sn-arrow-right { border-left:12px solid var(--sn-ink); border-right:0; }

.sn-root .sn-finish { padding:16px 18px 4px; }
.sn-root .sn-finish-title { margin:0 0 6px; font-size:1.2em; }
.sn-root .sn-summary { margin:0 0 10px; }
.sn-root .sn-review-title { margin:8px 0 4px; font-weight:600; }
.sn-root .sn-review { margin:0 0 12px; padding-left:1.2em; line-height:1.6; }
.sn-root .sn-finish-actions { display:flex; flex-wrap:wrap; gap:10px; }

/* 全屏玩（2026-10-07）：盖满屏幕的一层（游戏整块挪到 body 下面）。上面一条「退出全屏 / 暂停」，再往下题目、提示，棋盘占剩下的，方向键贴底。
   格子大小由 snake-game.js 按棋盘那一块剩下的宽、高算；方向键竖着排放不下一个像样的棋盘就排成一行（sn-padrow）。横屏：棋盘在左，别的在右。
   暂停 = 菜单：声音、朗读、连续玩、选类、选关挪进暂停面板（.sn-pmenu），面板盖住下面，顶上那一条还在（能退出全屏、能继续）。 */
html.sn-fs-on, html.sn-fs-on body { overflow:hidden; }
.sn-root.sn-fs { position:fixed; inset:0; z-index:1000; display:flex; background:#fff; overscroll-behavior:none; }
.sn-root.sn-fs .sn-game { flex:1 1 auto; max-width:none; margin:0; border-radius:0; display:flex; flex-direction:column; min-height:0; overflow-x:hidden; overflow-y:auto;
  padding-bottom:calc(8px + env(safe-area-inset-bottom, 0px)); }
.sn-root.sn-fs .sn-game::after { display:none; }
.sn-root.sn-fs .sn-game > * { flex:none; }
.sn-root.sn-fs .sn-title, .sn-root.sn-fs .sn-set { display:none; }   /* 全屏时设置里那三样挪进暂停面板了 */
.sn-root.sn-fs .sn-header { position:relative; z-index:3; background:#fff; padding:calc(8px + env(safe-area-inset-top, 0px)) 12px 2px; }
.sn-root.sn-fs .sn-tools { width:100%; flex-wrap:nowrap; justify-content:space-between; }
.sn-root.sn-fs .sn-tools button { min-height:38px; padding:4px 14px; }
.sn-root.sn-fs .sn-fsexit { order:-1; }
.sn-root.sn-fs .sn-status { padding:4px 14px 0; }
.sn-root.sn-fs .sn-task { padding:4px 14px 0; }
.sn-root.sn-fs .sn-zh { font-size:1em; }
.sn-root.sn-fs .sn-slots { flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; margin-top:6px; }
.sn-root.sn-fs .sn-slots::-webkit-scrollbar { display:none; }
.sn-root.sn-fs .sn-slot { flex:none; min-height:28px; }
.sn-root.sn-fs .sn-last { margin-top:4px; max-height:4.7em; overflow-y:auto; }
.sn-root.sn-fs .sn-last.sn-intro { display:none; }
.sn-root.sn-fs .sn-last.sn-full { max-height:none; }
.sn-root.sn-fs .sn-hint { min-height:calc(3.1em + 6px); max-height:calc(3.1em + 6px); overflow-y:auto; padding:3px 14px; }
.sn-root.sn-fs .sn-boardwrap { flex:1 1 0; min-height:0; display:flex; align-items:center; justify-content:center; padding:4px 8px; }
.sn-root.sn-fs .sn-board { margin:0; flex:none; touch-action:none; }   /* 全屏时页面本来就不滚：手指在棋盘上竖着划也是转向（不然还没开蛇时竖着划被当成翻页） */
.sn-root.sn-fs .sn-pad { display:flex; padding:6px 0 0; }
.sn-root.sn-fs.sn-padrow .sn-pad { flex-direction:row; justify-content:center; gap:8px; }
.sn-root.sn-fs.sn-padrow .sn-pad-row { display:contents; }
.sn-root.sn-fs.sn-padrow .sn-dir { width:min(21vw, 84px); height:48px; }
.sn-root.sn-fs.sn-padrow .sn-dir-left { order:1; } .sn-root.sn-fs.sn-padrow .sn-dir-up { order:2; }
.sn-root.sn-fs.sn-padrow .sn-dir-down { order:3; } .sn-root.sn-fs.sn-padrow .sn-dir-right { order:4; }
.sn-root.sn-fs .sn-boardwrap .sn-paused { position:fixed; inset:0; z-index:2; justify-content:flex-start; padding:76px 16px calc(24px + env(safe-area-inset-bottom, 0px)); background:#fff; overflow-y:auto; }
.sn-root.sn-fs .sn-finish { padding-bottom:16px; }
.sn-root .sn-pmenu { display:flex; flex-wrap:wrap; justify-content:center; gap:8px; width:100%; max-width:560px; margin-top:12px; padding-top:14px; border-top:1px solid var(--sn-line); }
.sn-root .sn-pmenu > button { min-height:40px; padding:6px 14px; border:1.5px solid var(--sn-ink); border-radius:99px; background:#fff; font-weight:600; font-size:.92em; }
.sn-root .sn-pmenu .sn-pick { flex-basis:100%; min-width:0; max-width:100%; justify-content:center; padding:4px 0; }
/* 矮屏（小手机、Safari 上下两条栏都在）：上面一截再紧一点，多给棋盘几格高 */
@media (max-height:640px) {
  .sn-root.sn-fs .sn-header { padding-top:calc(4px + env(safe-area-inset-top, 0px)); }
  .sn-root.sn-fs .sn-tools button { min-height:34px; padding:3px 12px; }
  .sn-root.sn-fs .sn-status { padding-top:2px; font-size:.85em; }
  .sn-root.sn-fs .sn-zh { font-size:.95em; line-height:1.35; }
  .sn-root.sn-fs .sn-pattern { margin:0; font-size:.82em; }
  .sn-root.sn-fs .sn-slots { margin-top:4px; }
  .sn-root.sn-fs .sn-slot { min-width:36px; min-height:26px; padding:2px 8px; }
  .sn-root.sn-fs .sn-hint { min-height:calc(2.9em + 4px); max-height:calc(2.9em + 4px); font-size:.95em; }
  .sn-root.sn-fs.sn-padrow .sn-dir { height:44px; }
}
/* 横屏：右边一栏是 顶上一条 / 状态 / 题目（占剩下的，放不下自己滚）/ 提示 / 方向键——方向键、提示都是定高，不会被挤到下面去 */
@media (orientation: landscape) and (max-height:560px) {
  .sn-root.sn-fs .sn-game { display:grid; grid-template-columns:minmax(0, 1fr) minmax(250px, 42%); grid-template-rows:auto auto minmax(0, 1fr) auto auto; column-gap:4px; overflow:hidden; }
  .sn-root.sn-fs .sn-game > * { grid-column:2; }
  .sn-root.sn-fs .sn-boardwrap { grid-column:1; grid-row:1 / -1; }
  .sn-root.sn-fs .sn-task { min-height:0; overflow-y:auto; }
  .sn-root.sn-fs .sn-finish { grid-column:1 / -1; grid-row:1 / -1; overflow-y:auto; }
  .sn-root.sn-fs .sn-pad { padding-bottom:6px; }
}
/* 横屏又矮（小手机横过来）：方向键排成一行 ← ↑ ↓ → */
@media (orientation: landscape) and (max-height:420px) {
  .sn-root.sn-fs .sn-pad { flex-direction:row; justify-content:center; gap:8px; }
  .sn-root.sn-fs .sn-pad-row { display:contents; }
  .sn-root.sn-fs .sn-dir { width:min(11vw, 64px); height:44px; }
  .sn-root.sn-fs .sn-dir-left { order:1; } .sn-root.sn-fs .sn-dir-up { order:2; } .sn-root.sn-fs .sn-dir-down { order:3; } .sn-root.sn-fs .sn-dir-right { order:4; }
}

@media (prefers-reduced-motion: reduce) { .sn-root .sn-chunk.wrong, .sn-root .sn-tapchunk.wrong { animation:none; } }
@media (max-width:520px) { .sn-root .sn-zh { font-size:1em; } .sn-root .sn-hint { min-height:calc(4.6em + 10px); } .sn-root .sn-last { min-height:3.1em; } }

/* 棋盘上方一行小字（2026-10-08）：往右走按 ← 这类「按了没反应」的时候说一句为什么，说完自己收。不挡点击、不占提示行 */
.sn-root .sn-tip { position:absolute; top:14px; left:50%; transform:translateX(-50%); z-index:1; max-width:calc(100% - 48px); margin:0; padding:6px 14px;
  border-radius:99px; background:var(--sn-ink); color:#fff; font-size:.92em; font-weight:600; line-height:1.4; text-align:center; pointer-events:none; }
.sn-root .sn-tip[hidden] { display:none; }

/* 触感（iPhone，2026-10-09）：方向键、「震动」开关里铺一层透明的 label，手指点的是它，浏览器把这一下转给里面看不见的系统开关、带一下系统触感（snake-game.js 的 makeHaptics）。
   开关本身不能在手指底下（会吃掉滑动），也不能 appearance:none（iOS 27 起不震）；藏用 visibility */
.sn-root .sn-dir, .sn-root .sn-haptic { position:relative; }
.sn-root .sn-hap { position:absolute; inset:0; border-radius:inherit; touch-action:manipulation; cursor:pointer; }   /* 不去掉点按时那一下灰色闪：方向键自己没有按下的样子，iPhone 上就靠它看出按上了 */
.sn-root .sn-hap input { position:absolute; left:0; top:0; width:1px; height:1px; margin:0; visibility:hidden; }

/* 方向转盘（2026-10-10）：触屏上默认用它，「设置」里能换回四个键。一个圆圈，四个方向键摆在圆圈的上下左右（点一下照样是那个方向，读屏、iPhone 触感也靠它们），
   中间一个圆点跟着手指转（snake-game.js 写 transform）；拨到哪边，那边的键涂深。整块 touch-action:none：按住拨的时候页面不跟着滚。
   放在文件最后：盖过上面全屏、横屏把方向键排成一行的那几条（转盘不排成一行，放不下就换小一号 sn-ringsm） */
.sn-root .sn-knob { display:none; }
.sn-root.sn-ringmode .sn-pad { --ring:152px; --ring-key:46px; --ring-knob:54px; position:relative; display:block; flex:none; box-sizing:border-box;
  width:var(--ring); height:var(--ring); margin:14px auto 0; padding:0; border:1.5px solid var(--sn-ink); border-radius:50%; background:var(--sn-soft);
  touch-action:manipulation; -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; }
/* 转盘「活」了才抓手指（全屏，或者卡片里已经开过蛇、snake-game.js 的 ringLive）：之前手指在上面划过照样翻页，和棋盘没上手之前一个规矩 */
.sn-root.sn-fs.sn-ringmode .sn-pad, .sn-root.sn-ringmode .sn-pad.sn-live { touch-action:none; }
.sn-root.sn-ringmode .sn-pad-row { display:contents; }
.sn-root.sn-ringmode .sn-pad .sn-dir { position:absolute; width:var(--ring-key); height:var(--ring-key); margin:0; border:0; border-radius:50%; background:transparent; }
.sn-root.sn-ringmode .sn-pad .sn-dir-up { top:3px; left:calc(50% - var(--ring-key) / 2); }
.sn-root.sn-ringmode .sn-pad .sn-dir-down { bottom:3px; left:calc(50% - var(--ring-key) / 2); }
.sn-root.sn-ringmode .sn-pad .sn-dir-left { left:3px; top:calc(50% - var(--ring-key) / 2); }
.sn-root.sn-ringmode .sn-pad .sn-dir-right { right:3px; top:calc(50% - var(--ring-key) / 2); }
.sn-root.sn-ringmode .sn-knob { display:block; position:absolute; left:calc(50% - var(--ring-knob) / 2); top:calc(50% - var(--ring-knob) / 2); width:var(--ring-knob); height:var(--ring-knob);
  border:1.5px solid var(--sn-ink); border-radius:50%; background:#fff; pointer-events:none; transition:transform .14s ease-out; }
.sn-root.sn-ringmode .sn-pad[data-on] .sn-knob { background:var(--sn-ink); transition:none; }
.sn-root.sn-ringmode .sn-pad[data-on="up"] .sn-dir-up, .sn-root.sn-ringmode .sn-pad[data-on="down"] .sn-dir-down,
.sn-root.sn-ringmode .sn-pad[data-on="left"] .sn-dir-left, .sn-root.sn-ringmode .sn-pad[data-on="right"] .sn-dir-right { background:var(--sn-ink); }
.sn-root.sn-ringmode .sn-pad[data-on="up"] .sn-arrow-up { border-bottom-color:#fff; }
.sn-root.sn-ringmode .sn-pad[data-on="down"] .sn-arrow-down { border-top-color:#fff; }
.sn-root.sn-ringmode .sn-pad[data-on="left"] .sn-arrow-left { border-right-color:#fff; }
.sn-root.sn-ringmode .sn-pad[data-on="right"] .sn-arrow-right { border-left-color:#fff; }
.sn-root.sn-fs.sn-ringmode .sn-pad { --ring:140px; margin-top:6px; }
.sn-root.sn-fs.sn-ringmode.sn-ringsm .sn-pad { --ring:100px; --ring-key:34px; --ring-knob:38px; }
/* 矮屏（360×520 这种）小一号还不够：最小的圈。手指按住以后拖出圈外也照样算（snake-game.js 抓住了这根手指），圈小不碍事 */
.sn-root.sn-fs.sn-ringmode.sn-ringxs .sn-pad { --ring:68px; --ring-key:24px; --ring-knob:26px; margin-top:4px; }
.sn-root.sn-fs.sn-ringmode.sn-ringxs .sn-arrow { border-width:6px; }
.sn-root.sn-fs.sn-ringmode.sn-ringxs .sn-arrow-up { border-bottom-width:8px; } .sn-root.sn-fs.sn-ringmode.sn-ringxs .sn-arrow-down { border-top-width:8px; }
.sn-root.sn-fs.sn-ringmode.sn-ringxs .sn-arrow-left { border-right-width:8px; } .sn-root.sn-fs.sn-ringmode.sn-ringxs .sn-arrow-right { border-left-width:8px; }
@media (orientation: landscape) and (max-height:560px) { .sn-root.sn-fs.sn-ringmode .sn-pad { --ring:min(128px, 30vh); --ring-key:38px; --ring-knob:44px; margin-bottom:6px; } }
@media (prefers-reduced-motion: reduce) { .sn-root.sn-ringmode .sn-knob { transition:none; } }
/* 360° 的转盘（2026-10-22 站主：「转盘目前还是上下左右，想个办法让它看出来可以用圆圈转，哪一个方向都可以」）：四个三角箭头换成一圈刻度（上下左右四根长一点），
   圈边一个绿色小圆点指着蛇头现在朝的方向（snake-game.js 写 rotate），中间圆点上一个绕圈的箭头。四个键还在原处（透明），点一下照样是那个方向。
   每台手机第一次进全屏，小圆点沿着圈转一圈示范（sn-dialdemo）。上下左右模式（没有 sn-free）一字不变 */
.sn-root .sn-dial, .sn-root .sn-dial-ptr, .sn-root .sn-knob svg { display:none; }
.sn-root.sn-free.sn-ringmode .sn-dial { display:block; position:absolute; left:0; top:0; width:100%; height:100%; pointer-events:none; }
.sn-root.sn-free.sn-ringmode .sn-dial line { stroke:var(--sn-sub); stroke-width:1.6; stroke-linecap:round; }
.sn-root.sn-free.sn-ringmode .sn-dial line.big { stroke:var(--sn-ink); stroke-width:2.8; }
.sn-root.sn-free.sn-ringmode .sn-arrow { display:none; }
.sn-root.sn-free.sn-ringmode .sn-pad[data-on] .sn-dir { background:transparent; }
.sn-root.sn-free.sn-ringmode .sn-dial-ptr { display:block; position:absolute; left:50%; top:50%; width:0; height:0; pointer-events:none; }
.sn-root.sn-free.sn-ringmode .sn-dial-ptr::after { content:""; position:absolute; left:calc(var(--ring) / 2 - 12px); top:0; width:12px; height:12px; margin:-6px 0 0 -6px; box-sizing:border-box;
  border-radius:50%; background:var(--sn-green); border:2px solid var(--sn-ink); }
.sn-root.sn-free.sn-ringmode .sn-knob svg { display:block; width:58%; height:58%; margin:21%; color:var(--sn-ink); }
.sn-root.sn-free.sn-ringmode .sn-pad[data-on] .sn-knob svg { color:#fff; }
.sn-root.sn-free.sn-ringmode .sn-pad.sn-dialdemo .sn-dial-ptr { animation:sn-dial-sweep 1.6s ease-in-out 1; }
@keyframes sn-dial-sweep { from { transform:rotate(0deg); } to { transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .sn-root.sn-free.sn-ringmode .sn-pad.sn-dialdemo .sn-dial-ptr { animation:none; } }
