/* ==========================================================================
   5126游戏厅 · Design tokens
   World: a matte handheld console. Warm charcoal shell, arcade-LED amber,
   one saturated ink per cartridge. Dark-first because the real scene is a
   phone in a dim room. Colours are picked from the object, not from category
   habit: no violet-on-blue gradient gaming page lives here.
   ========================================================================== */

:root {
  /* --- shell ------------------------------------------------------------ */
  --shell-0: #0F0D0B;      /* page ground: matte charcoal plastic */
  --shell-1: #171412;      /* raised panel */
  --shell-2: #201C18;      /* control faces */
  --shell-3: #2A2521;      /* pressed / inset wells */
  --screen-0: #0B0A09;     /* the screen itself, darker than the shell */
  --screen-1: #12100E;
  /* Plain rgba first, then the more precise mix where it is supported. A
     declaration the engine cannot parse is dropped, so the fallback survives —
     this is why the hairlines do not vanish on Safari 15. */
  --line: rgba(247, 244, 240, .09);
  --line-strong: rgba(247, 244, 240, .18);
  --line: color-mix(in oklab, #F7F4F0 9%, transparent);
  --line-strong: color-mix(in oklab, #F7F4F0 18%, transparent);

  /* --- ink -------------------------------------------------------------- */
  --ink: #F7F4F0;
  --ink-2: #BEB6AB;
  --ink-3: #948B81;
/* 11px 标签的最低色。原来 #8A8177 在 --shell-2（控制面）上只有 4.42:1，
   差一点点不到 WCAG AA 的 4.5；提亮到 #90877C 后 shell-2 上 4.79:1、
   shell-1 上 5.19:1，同时仍然比 --ink-3 暗一档，层级不塌。 */
--ink-4: #90877C;

  /* --- signal inks ------------------------------------------------------ */
  --amber: #FF8A3D;        /* the lit LED, primary action */
  --amber-hi: #FFA25F;     /* 主按钮渐变的上端（主题换色时一起换） */
  --amber-deep: #C25E1E;
  --amber-ink: #1A0F05;

  /* --- surfaces that used to be hard-coded ---------------------------------
     这几个是"面板/横幅/提示条/机壳"的底色。以前写死在 app.css 里，只有深色一套；
     抽成 token 之后主题才能整体换（浅色主题最需要）。 */
  --bezel-0: #17140F;      /* 首页那块"屏幕框"的上端 */
  --bezel-1: #100E0C;
  --banner-0: #221E19;     /* 结算横幅 */
  --banner-1: #191612;
  --toast-bg: rgba(28, 24, 20, .96);
  --boot-bg: #0F0D0B;      /* 启动画面（首帧，必须和内联样式里的默认一致） */
  --boot-ink: #F7F4F0;

  /* 压在游戏画面上的字（机壳跑马灯、比分牌、倒计时）。
     它们的底永远偏暗——画布本身是深色，或者垫了一层半透明黑——所以这几支
     颜色**故意不跟主题走**：浅色主题下也要是浅字，否则直接看不见。 */
  --on-screen: #F7F4F0;
  --on-screen-2: rgba(247, 244, 240, .78);
  --on-screen-3: rgba(247, 244, 240, .58);
  --chip-bg: rgba(15, 13, 11, .86);

  /* Interactive colour. `--accent-live` is set by the hall to the selected
     cartridge's ink when 设置 → 外观 · 自动 is on; otherwise amber. */
  --accent: var(--accent-live, var(--amber));
  --jade: #3FD08A;
  --jade-ink: #05170E;
  --red: #F0524A;          /* alerts, 红方, danger */
  --red-ink: #1B0605;
  --azure: #6DA5FF;
  --violet: #B18BFF;
  --teal: #4FC8BE;
  --terracotta: #E0705A;
  --vermilion: #E2574C;

  /* --- cartridge inks (one saturated colour per game) ------------------- */
  --tint-snake: #3FD08A;
  --tint-2048: #FF8A3D;
  --tint-tetris: #6DA5FF;
  --tint-sudoku: #B18BFF;
  --tint-sokoban: #E0705A;
  --tint-gomoku: #4FC8BE;
  --tint-xiangqi: #E2574C;

  /* --- material --------------------------------------------------------- */
  --r-sm: 8px;
  --r-md: 12px;            /* card floor: 12–16px, pills only for small controls */
  --r-lg: 16px;
  --r-xl: 22px;
  --bevel: inset 0 1px 0 rgba(255, 255, 255, .07);
  --bevel: inset 0 1px 0 color-mix(in oklab, #FFFFFF 7%, transparent);
  --drop: 0 10px 24px -14px rgba(0, 0, 0, .9);
  --press-drop: 0 2px 6px -4px rgba(0, 0, 0, .9);
  --well: inset 0 2px 6px rgba(0, 0, 0, .55);

  /* --- type ------------------------------------------------------------- */
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
  /* Reserved for real data: connection codes and score tables. Not a costume. */
  --font-data: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --step--1: 0.8125rem;   /* 13px meta */
  --step-0: 0.9375rem;    /* 15px dense UI */
  --step-1: 1.0625rem;    /* 17px body — the iOS body size */
  --step-2: 1.3125rem;
  --step-3: 1.75rem;
  --step-4: 2.25rem;
  --track-wide: .14em;
  --track-wider: .26em;

  /* --- rhythm ----------------------------------------------------------- */
  --gap-1: 4px;
  --gap-2: 8px;
  --gap-3: 12px;
  --gap-4: 16px;
  --gap-5: 22px;
  --gap-6: 30px;

  /* --- motion ----------------------------------------------------------- */
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-in-out: cubic-bezier(.5, 0, .2, 1);
  --dur-press: 90ms;
  --dur-ui: 200ms;
  --dur-screen: 320ms;

  --tap-min: 44px;        /* iOS HIG floor; every control clears it */
  /* 游戏里的操作键比"最低标准"再大一档：手指按得准、连点不容易误触。
     HIG 的 44 是下限，不是舒适值；拇指操作的键做到 52–56 才不别扭。 */
  --tap-key: 52px;
}

/* ==========================================================================
   Base
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  height: 100%;
  background: var(--shell-0);
  -webkit-text-size-adjust: 100%;
}

body {
  height: 100%;
  background: var(--shell-0);
  color: var(--ink);
  font: var(--step-1) / 1.5 var(--font-ui);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overscroll-behavior: none;
  overflow: hidden;
  /* The dial and the buttons stop looking like text. */
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  /* A fast tap must not become a double-tap zoom; pinch zoom stays available. */
  touch-action: manipulation;
}

/* Deliberate text selection: real, themed, never the browser default blue. */
::selection { background: color-mix(in oklab, var(--amber) 42%, transparent); color: #fff; }

/* Focus rings are designed, not deleted. */
:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

button, input, select, textarea {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
}

button { cursor: pointer; }

ul, ol { list-style: none; }

img, canvas, svg { display: block; max-width: 100%; }

/* Screen-only chrome: thin warm scrollbar, defined caret. */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: 3px;
}
::-webkit-scrollbar-track { background: transparent; }
input, textarea { caret-color: var(--amber); }

.numeric { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   Controls — physical keys, not web buttons.
   Every press sinks 2px and collapses its shadow, inside 90ms.
   ========================================================================== */
.key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-2);
  min-height: var(--tap-min);
  min-width: var(--tap-min);
  padding: 0 var(--gap-4);
  border-radius: var(--r-md);
  background: linear-gradient(180deg, var(--shell-2), var(--shell-1));
  box-shadow: var(--bevel), var(--drop);
  color: var(--ink);
  font-weight: 600;
  font-size: var(--step-0);
  letter-spacing: .01em;
  transition: transform var(--dur-press) var(--ease-out),
              box-shadow var(--dur-press) var(--ease-out),
              background-color var(--dur-ui) linear;
  touch-action: manipulation;
  user-select: none;
}
.key:active:not([disabled]) {
  transform: translateY(2px);
  box-shadow: var(--bevel), var(--press-drop);
}
.key[disabled] { opacity: .42; cursor: not-allowed; }
.key[data-variant="primary"] {
  background: linear-gradient(180deg, var(--amber-hi), var(--amber) 62%, var(--amber-deep));
  color: var(--amber-ink);
  font-weight: 800;
  letter-spacing: .02em;
}
.key[data-variant="ghost"] {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--line-strong);
  color: var(--ink-2);
}
.key[data-variant="quiet"] {
  background: var(--shell-1);
  box-shadow: none;
  color: var(--ink-2);
}
.key[data-variant="danger"] {
  background: linear-gradient(180deg, #F4695F, var(--red) 62%, #B3312B);
  color: #fff;
}
.key[data-size="lg"] {
  min-height: 56px;
  font-size: var(--step-2);
  border-radius: var(--r-lg);
}
.key[data-size="sm"] { min-height: var(--tap-min); padding: 0 var(--gap-3); font-size: var(--step--1); }
.key[data-square] { width: var(--tap-min); padding: 0; }
.key[data-tone="on"] { color: var(--amber); }
/* Icons must not be squeezed by a crowded row of keys. */
.key svg { flex: 0 0 auto; }

/* An LED that means something: offline-ready, link up, low battery. */
.led {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ink-4);
  box-shadow: 0 0 0 1px color-mix(in oklab, #000 55%, transparent) inset;
  flex: 0 0 auto;
}
.led[data-state="ready"] { background: var(--jade); box-shadow: 0 0 7px color-mix(in oklab, var(--jade) 70%, transparent); }
.led[data-state="live"] { background: var(--amber); box-shadow: 0 0 8px color-mix(in oklab, var(--amber) 80%, transparent); animation: ledPulse 1.9s var(--ease-in-out) infinite; }
.led[data-state="warn"] { background: var(--red); box-shadow: 0 0 7px color-mix(in oklab, var(--red) 70%, transparent); }
@keyframes ledPulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

.stamp {
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: .12em;
  color: var(--ink-3);
  text-transform: uppercase;
}

.meta-line {
  font-size: var(--step--1);
  color: var(--ink-3);
  letter-spacing: .01em;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
