/* washi paper and sumi ink, with the seal's vermilion as the one accent */
:root {
  --background: #f1ebe1;
  --foreground: #221e19;
  --card: #f8f4ec;
  --muted: #e5ddcf;
  --muted-foreground: #7c7265;
  --accent: rgb(60 44 26 / .07);
  --border: #dcd2c2;
  --input: #cbbfac;
  --primary: #221e19;
  --primary-foreground: #f8f4ec;
  --ring: #9a8c78;
  --destructive: #b8321f;
  --shu: #cc4630;
  --glow: #f9f5ee;
  --shadow-sm: 0 1px 2px rgb(70 50 30 / .08);
  --shadow-lg: 0 22px 44px -18px rgb(70 48 24 / .38), 0 2px 6px rgb(70 48 24 / .08);
  /* paper fibre: fine noise tinted with the ink colour */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .3 0 0 0 0 .22 0 0 0 0 .14 .16 0 0 0 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* the same fibre in pale ink, for dark grounds */
  --grain-pale: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .95 0 0 0 0 .9 0 0 0 0 .8 .07 0 0 0 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* artwork for the game-screen backgrounds (chosen under Board appearance) */
  --waves: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='28'%3E%3Cg fill='%23f1ebe1' stroke='rgba(70,92,124,.16)' stroke-width='1'%3E%3Ccircle cx='28' cy='-14.0' r='28.0'/%3E%3Ccircle cx='28' cy='-14.0' r='22.4'/%3E%3Ccircle cx='28' cy='-14.0' r='16.8'/%3E%3Ccircle cx='28' cy='-14.0' r='11.2'/%3E%3Ccircle cx='28' cy='-14.0' r='5.6'/%3E%3C/g%3E%3Cg fill='%23f1ebe1' stroke='rgba(70,92,124,.16)' stroke-width='1'%3E%3Ccircle cx='0' cy='0' r='28.0'/%3E%3Ccircle cx='0' cy='0' r='22.4'/%3E%3Ccircle cx='0' cy='0' r='16.8'/%3E%3Ccircle cx='0' cy='0' r='11.2'/%3E%3Ccircle cx='0' cy='0' r='5.6'/%3E%3C/g%3E%3Cg fill='%23f1ebe1' stroke='rgba(70,92,124,.16)' stroke-width='1'%3E%3Ccircle cx='56' cy='0' r='28.0'/%3E%3Ccircle cx='56' cy='0' r='22.4'/%3E%3Ccircle cx='56' cy='0' r='16.8'/%3E%3Ccircle cx='56' cy='0' r='11.2'/%3E%3Ccircle cx='56' cy='0' r='5.6'/%3E%3C/g%3E%3Cg fill='%23f1ebe1' stroke='rgba(70,92,124,.16)' stroke-width='1'%3E%3Ccircle cx='28' cy='14.0' r='28.0'/%3E%3Ccircle cx='28' cy='14.0' r='22.4'/%3E%3Ccircle cx='28' cy='14.0' r='16.8'/%3E%3Ccircle cx='28' cy='14.0' r='11.2'/%3E%3Ccircle cx='28' cy='14.0' r='5.6'/%3E%3C/g%3E%3Cg fill='%23f1ebe1' stroke='rgba(70,92,124,.16)' stroke-width='1'%3E%3Ccircle cx='0' cy='28' r='28.0'/%3E%3Ccircle cx='0' cy='28' r='22.4'/%3E%3Ccircle cx='0' cy='28' r='16.8'/%3E%3Ccircle cx='0' cy='28' r='11.2'/%3E%3Ccircle cx='0' cy='28' r='5.6'/%3E%3C/g%3E%3Cg fill='%23f1ebe1' stroke='rgba(70,92,124,.16)' stroke-width='1'%3E%3Ccircle cx='56' cy='28' r='28.0'/%3E%3Ccircle cx='56' cy='28' r='22.4'/%3E%3Ccircle cx='56' cy='28' r='16.8'/%3E%3Ccircle cx='56' cy='28' r='11.2'/%3E%3Ccircle cx='56' cy='28' r='5.6'/%3E%3C/g%3E%3Cg fill='%23f1ebe1' stroke='rgba(70,92,124,.16)' stroke-width='1'%3E%3Ccircle cx='28' cy='42.0' r='28.0'/%3E%3Ccircle cx='28' cy='42.0' r='22.4'/%3E%3Ccircle cx='28' cy='42.0' r='16.8'/%3E%3Ccircle cx='28' cy='42.0' r='11.2'/%3E%3Ccircle cx='28' cy='42.0' r='5.6'/%3E%3C/g%3E%3C/svg%3E");
  --hills: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='g0' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23b9c4c6' stop-opacity='0.55'/%3E%3Cstop offset='1' stop-color='%23b9c4c6' stop-opacity='0'/%3E%3C/linearGradient%3E%3ClinearGradient id='g1' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%239fafb3' stop-opacity='0.6'/%3E%3Cstop offset='1' stop-color='%239fafb3' stop-opacity='0'/%3E%3C/linearGradient%3E%3ClinearGradient id='g2' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%2386989d' stop-opacity='0.65'/%3E%3Cstop offset='1' stop-color='%2386989d' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath fill='url(%23g0)' d='M0 150 C170 110 300 70 470 112 C640 154 740 64 920 58 C1090 52 1210 128 1440 96 V320 H0Z'/%3E%3Cpath fill='url(%23g1)' d='M0 214 C150 186 320 160 520 198 C720 236 860 162 1040 168 C1220 174 1320 214 1440 200 V320 H0Z'/%3E%3Cpath fill='url(%23g2)' d='M0 262 C200 238 370 226 610 252 C830 276 1000 232 1200 236 C1320 239 1400 250 1440 248 V320 H0Z'/%3E%3C/svg%3E");
  --hills-sky: linear-gradient(#e6eae9, #f1ebe2 72%);
  --hills-orb: radial-gradient(circle closest-side, rgb(212 88 60 / .3) 0 30%, rgb(212 88 60 / .09) 34%, transparent);
  --dusk: radial-gradient(ellipse 60% 55% at 12% 16%, rgb(246 186 160 / .6), transparent 70%), radial-gradient(ellipse 55% 62% at 90% 28%, rgb(166 202 186 / .55), transparent 70%), radial-gradient(ellipse 70% 55% at 60% 98%, rgb(188 176 224 / .5), transparent 70%), #f2eae4;
  --indigo: radial-gradient(ellipse at 50% 45%, #2d3c62, #1c2643);
  /* how much page colour veils the home backdrop */
  --wash-center: 35%;
  --wash-mid: 22%;
  --wash-edge: 7%;
  --title: "Shippori Mincho B1", "Hiragino Mincho ProN", "Yu Mincho", Georgia, serif;
  --sans: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --background: #1a1814;
    --foreground: #ece4d6;
    --card: #23201b;
    --muted: #2f2b25;
    --muted-foreground: #9d927f;
    --accent: rgb(236 228 214 / .07);
    --border: #353029;
    --input: #4d463c;
    --primary: #ece4d6;
    --primary-foreground: #1a1814;
    --ring: #8a7f6d;
    --destructive: #f08a74;
    --shu: #d8553d;
    --glow: #24211c;
    --shadow-sm: 0 1px 2px rgb(0 0 0 / .4);
    --shadow-lg: 0 24px 48px -16px rgb(0 0 0 / .7), 0 2px 6px rgb(0 0 0 / .3);
    --grain: var(--grain-pale);
    --waves: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='28'%3E%3Cg fill='%231a1814' stroke='rgba(200,212,232,.075)' stroke-width='1'%3E%3Ccircle cx='28' cy='-14.0' r='28.0'/%3E%3Ccircle cx='28' cy='-14.0' r='22.4'/%3E%3Ccircle cx='28' cy='-14.0' r='16.8'/%3E%3Ccircle cx='28' cy='-14.0' r='11.2'/%3E%3Ccircle cx='28' cy='-14.0' r='5.6'/%3E%3C/g%3E%3Cg fill='%231a1814' stroke='rgba(200,212,232,.075)' stroke-width='1'%3E%3Ccircle cx='0' cy='0' r='28.0'/%3E%3Ccircle cx='0' cy='0' r='22.4'/%3E%3Ccircle cx='0' cy='0' r='16.8'/%3E%3Ccircle cx='0' cy='0' r='11.2'/%3E%3Ccircle cx='0' cy='0' r='5.6'/%3E%3C/g%3E%3Cg fill='%231a1814' stroke='rgba(200,212,232,.075)' stroke-width='1'%3E%3Ccircle cx='56' cy='0' r='28.0'/%3E%3Ccircle cx='56' cy='0' r='22.4'/%3E%3Ccircle cx='56' cy='0' r='16.8'/%3E%3Ccircle cx='56' cy='0' r='11.2'/%3E%3Ccircle cx='56' cy='0' r='5.6'/%3E%3C/g%3E%3Cg fill='%231a1814' stroke='rgba(200,212,232,.075)' stroke-width='1'%3E%3Ccircle cx='28' cy='14.0' r='28.0'/%3E%3Ccircle cx='28' cy='14.0' r='22.4'/%3E%3Ccircle cx='28' cy='14.0' r='16.8'/%3E%3Ccircle cx='28' cy='14.0' r='11.2'/%3E%3Ccircle cx='28' cy='14.0' r='5.6'/%3E%3C/g%3E%3Cg fill='%231a1814' stroke='rgba(200,212,232,.075)' stroke-width='1'%3E%3Ccircle cx='0' cy='28' r='28.0'/%3E%3Ccircle cx='0' cy='28' r='22.4'/%3E%3Ccircle cx='0' cy='28' r='16.8'/%3E%3Ccircle cx='0' cy='28' r='11.2'/%3E%3Ccircle cx='0' cy='28' r='5.6'/%3E%3C/g%3E%3Cg fill='%231a1814' stroke='rgba(200,212,232,.075)' stroke-width='1'%3E%3Ccircle cx='56' cy='28' r='28.0'/%3E%3Ccircle cx='56' cy='28' r='22.4'/%3E%3Ccircle cx='56' cy='28' r='16.8'/%3E%3Ccircle cx='56' cy='28' r='11.2'/%3E%3Ccircle cx='56' cy='28' r='5.6'/%3E%3C/g%3E%3Cg fill='%231a1814' stroke='rgba(200,212,232,.075)' stroke-width='1'%3E%3Ccircle cx='28' cy='42.0' r='28.0'/%3E%3Ccircle cx='28' cy='42.0' r='22.4'/%3E%3Ccircle cx='28' cy='42.0' r='16.8'/%3E%3Ccircle cx='28' cy='42.0' r='11.2'/%3E%3Ccircle cx='28' cy='42.0' r='5.6'/%3E%3C/g%3E%3C/svg%3E");
    --hills: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='g0' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%232c3540' stop-opacity='0.9'/%3E%3Cstop offset='1' stop-color='%232c3540' stop-opacity='0'/%3E%3C/linearGradient%3E%3ClinearGradient id='g1' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23242c36' stop-opacity='0.95'/%3E%3Cstop offset='1' stop-color='%23242c36' stop-opacity='0'/%3E%3C/linearGradient%3E%3ClinearGradient id='g2' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%231c232c' stop-opacity='1'/%3E%3Cstop offset='1' stop-color='%231c232c' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath fill='url(%23g0)' d='M0 150 C170 110 300 70 470 112 C640 154 740 64 920 58 C1090 52 1210 128 1440 96 V320 H0Z'/%3E%3Cpath fill='url(%23g1)' d='M0 214 C150 186 320 160 520 198 C720 236 860 162 1040 168 C1220 174 1320 214 1440 200 V320 H0Z'/%3E%3Cpath fill='url(%23g2)' d='M0 262 C200 238 370 226 610 252 C830 276 1000 232 1200 236 C1320 239 1400 250 1440 248 V320 H0Z'/%3E%3C/svg%3E");
    --hills-sky: linear-gradient(#11151c, #1a1c21 75%);
    --hills-orb: radial-gradient(circle closest-side, rgb(236 228 214 / .85) 0 22%, rgb(236 228 214 / .08) 26%, transparent);
    --dusk: radial-gradient(ellipse 60% 55% at 12% 16%, rgb(116 60 92 / .55), transparent 70%), radial-gradient(ellipse 55% 62% at 90% 28%, rgb(34 82 90 / .55), transparent 70%), radial-gradient(ellipse 70% 55% at 60% 98%, rgb(56 52 112 / .55), transparent 70%), #16141b;
    --indigo: radial-gradient(ellipse at 50% 45%, #233152, #141b30);
    --wash-center: 80%;
    --wash-mid: 66%;
    --wash-edge: 52%;
    color-scheme: dark;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--background);
  color: var(--foreground);
  font: 14px/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
[hidden] { display: none !important; }
button, input { font: inherit; color: inherit; }
h1, h2, p { margin: 0; }
:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); }

svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.muted { color: var(--muted-foreground); font-size: 13px; }
.small { font-size: 12px; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.spacer { flex: 1; }

/* ---------- button ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 36px;
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: transparent;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .15s, opacity .15s, border-color .15s, color .15s;
}
.btn:disabled { opacity: .4; pointer-events: none; }
.btn.primary { background: var(--primary); color: var(--primary-foreground); }
.btn.outline { border-color: var(--input); }
@media (hover: hover) {
  .btn.primary:hover { opacity: .88; }
  .btn.outline:hover, .btn.ghost:hover { background: var(--accent); }
}
/* icon buttons are round, like the stones */
.btn.icon { width: 36px; padding: 0; color: var(--muted-foreground); }
.btn.icon svg { width: 18px; height: 18px; stroke-width: 1.7; }
@media (hover: hover) { .btn.icon:hover { color: var(--foreground); } }
.btn.block { width: 100%; }

/* a word in the title face with the vermilion brush stroke beneath it */
.ink-btn {
  position: relative;
  border: 0;
  background: none;
  padding: .15em .2em .3em;
  font: 600 18px/1.1 var(--title);
  letter-spacing: .02em;
  color: var(--foreground);
  cursor: pointer;
}
.ink-btn::after, .play-btn::after, .seg span::after, .plate .name::after {
  content: "";
  position: absolute;
  left: .2em;
  right: .2em;
  bottom: .04em;
  height: .09em;
  min-height: 2px;
  border-radius: 999px 40% 999px 60%;
  background: var(--shu);
  transform: rotate(-1.5deg) scaleX(.25);
  transition: transform .4s cubic-bezier(.2, .8, .2, 1);
}
.ink-btn:hover::after, .ink-btn:focus-visible::after { transform: rotate(-1.5deg) scaleX(1); }
.ink-btn.quiet { color: var(--muted-foreground); }
.ink-btn.quiet::after { transform: rotate(-1.5deg) scaleX(0); }
.ink-btn:focus-visible, .play-btn:focus-visible { box-shadow: none; outline: 2px solid color-mix(in oklab, var(--ring) 60%, transparent); outline-offset: 4px; border-radius: 6px; }
.ink-btn:disabled { color: var(--muted-foreground); cursor: default; }
.ink-btn:disabled::after { transform: rotate(-1.5deg) scaleX(0); }
.ink-row { display: flex; gap: 18px; }

/* ---------- input ---------- */
.input {
  height: 36px;
  width: 100%;
  min-width: 0;
  padding: 0 12px;
  border-radius: 10px;
  border: 1px solid var(--input);
  background: var(--card);
  font-size: 14px;
  transition: border-color .15s, box-shadow .15s;
}
.input::placeholder { color: var(--muted-foreground); }
.input:focus-visible { border-color: var(--ring); }
.input.num { width: 80px; }
.input[readonly] { color: var(--muted-foreground); }
/* a ruled line to write on */
.input.line { height: 34px; padding: 0 2px; border: 0; border-bottom: 1px solid var(--input); border-radius: 0; background: none; }
.input.line:focus-visible { box-shadow: none; border-bottom-color: var(--foreground); }
.input.code { font: 600 17px/1 var(--title); letter-spacing: .02em; }

/* ---------- choices: the chosen word gets the brush stroke ---------- */
.seg { display: flex; flex-wrap: wrap; gap: 2px 16px; }
.seg label { position: relative; }
.seg input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.seg span {
  position: relative;
  display: block;
  padding: 3px 1px 7px;
  font-size: 14px;
  color: var(--muted-foreground);
  user-select: none;
  transition: color .15s;
}
.seg span::after { transform: rotate(-1.5deg) scaleX(0); left: 0; right: 0; }
.seg input:checked + span { color: var(--foreground); font-weight: 500; }
.seg input:checked + span::after { transform: rotate(-1.5deg) scaleX(1); }
@media (hover: hover) { .seg input:not(:disabled):hover + span { color: var(--foreground); } }
.seg input:focus-visible + span { outline: 2px solid color-mix(in oklab, var(--ring) 60%, transparent); outline-offset: 2px; border-radius: 4px; }
.seg input:disabled { cursor: default; }
.seg.sm { gap: 2px 14px; }
.seg.sm span { font-size: 13px; }

/* ---------- switch: a stone sliding along an ink groove ---------- */
.switch {
  appearance: none;
  flex: none;
  width: 34px;
  height: 20px;
  margin: 0;
  border-radius: 999px;
  background: var(--input);
  box-shadow: inset 0 1px 2px rgb(0 0 0 / .14);
  position: relative;
  cursor: pointer;
  transition: background-color .2s;
}
.switch::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff, #ddd6ca);
  box-shadow: 0 1px 2px rgb(0 0 0 / .3);
  transition: transform .2s cubic-bezier(.2, .8, .2, 1);
}
.switch:checked { background: var(--primary); }
.switch:checked::before { transform: translateX(14px); }
.switch:disabled { opacity: .5; cursor: default; }
.switch-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 6px 0; cursor: pointer; font-size: 14px; }

/* ---------- home ---------- */
.home {
  min-height: 100dvh;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: 24px 16px max(40px, env(safe-area-inset-bottom));
}
.hero {
  align-self: center;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(12px, 2.2vw, 30px);
}
.title {
  font: 800 clamp(76px, 17vw, 210px)/.88 var(--title);
  letter-spacing: -.03em;
}
.seal {
  writing-mode: vertical-rl;
  font: 800 clamp(17px, 3.3vw, 40px)/1 var(--title);
  letter-spacing: .28em;
  padding: .55em .32em .3em;
  margin-top: .15em;
  background: var(--shu);
  color: #fff4ef;
  border-radius: 4px;
  transform: rotate(-2deg);
  box-shadow: 0 6px 18px -6px color-mix(in oklab, var(--shu) 60%, transparent);
}
.home-foot { display: flex; flex-direction: column; align-items: center; gap: 12px; }

/* Play: one word in the title face that unfolds into its two choices */
.play { display: grid; place-items: center; }
.play > * { grid-area: 1 / 1; transition: opacity .35s ease, transform .45s cubic-bezier(.2, .8, .2, 1), visibility .45s; }
.play-btn {
  position: relative;
  border: 0;
  background: none;
  padding: .1em .25em .22em;
  font: 500 clamp(26px, 3.4vw, 34px)/1 var(--title);
  letter-spacing: .08em;
  color: var(--foreground);
  cursor: pointer;
}
.play-btn.sm { font-size: clamp(19px, 2.4vw, 24px); letter-spacing: .03em; }
.play-btn::after { min-height: 0; transform: rotate(-1.5deg) scaleX(.2); }
.play-btn.sm::after { transform: rotate(-1.5deg) scaleX(0); }
.play-btn:hover::after, .play-btn:focus-visible::after { transform: rotate(-1.5deg) scaleX(1); }
.play-btn:disabled { opacity: .5; cursor: default; }
.play-choices { display: flex; align-items: center; gap: clamp(8px, 2vw, 20px); opacity: 0; visibility: hidden; transform: translateY(14px); }
.play-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--shu); flex: none; }
/* each step lifts away as the next rises into its place */
.play:not([data-stage=""]) #playBtn, .play[data-stage="create"] #playChoices, .play[data-stage="join"] #playChoices { opacity: 0; visibility: hidden; transform: translateY(-14px) scale(.96); }
.play[data-stage="main"] #playChoices, .play[data-stage="create"] #createChoices, .play[data-stage="join"] #joinForm { opacity: 1; visibility: visible; transform: none; transition-property: opacity, transform; } /* visible at once, so it can take focus */
/* the code is written on a ruled line in the title face, between a back arrow and its mirror space */
.join-stage { gap: 6px; }
.join-stage .btn.icon { width: 36px; height: 36px; color: var(--foreground); }
.join-stage .btn.icon svg { width: 22px; height: 22px; stroke-width: 1.6; }
.join-balance { width: 36px; flex: none; }
.input.join-code {
  width: min(220px, 56vw);
  height: 42px;
  font: 500 clamp(19px, 2.4vw, 24px)/1 var(--title);
  letter-spacing: .03em;
  text-align: center;
  color: var(--foreground);
  border-bottom-color: color-mix(in oklab, var(--foreground) 45%, transparent);
}
.input.join-code::placeholder { color: color-mix(in oklab, var(--foreground) 45%, transparent); }
.input.join-code:focus-visible { border-bottom-color: var(--shu); }

/* backdrop: the endless game, washed with the page colour so the title reads */
.backdrop { position: fixed; inset: 0; z-index: -1; overflow: hidden; background: var(--background); }
.backdrop canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 75% 70% at 50% 48%,
    color-mix(in oklab, var(--background) var(--wash-center), transparent) 0%,
    color-mix(in oklab, var(--background) var(--wash-mid), transparent) 55%,
    color-mix(in oklab, var(--background) var(--wash-edge), transparent) 100%);
}
.home-error { display: flex; flex-direction: column; align-items: center; gap: 6px; color: var(--destructive); font: 500 16px/1.4 var(--title); text-align: center; }
.home-error:empty { display: none; }


/* ---------- game layout ---------- */
.game {
  height: 100dvh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto auto;
  overflow: clip;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* ---------- backgrounds: the table the board sits on, also drawn small as swatches ---------- */
/* washi: lamplight on paper, a little brighter where the board sits */
[data-bg="washi"] { background: var(--grain), radial-gradient(ellipse 70% 75% at 50% 46%, var(--glow), var(--background)); }
/* seigaiha waves in hairline ink */
[data-bg="waves"] { background: radial-gradient(ellipse 70% 75% at 50% 46%, color-mix(in oklab, var(--glow) 75%, transparent), transparent 80%), var(--grain), var(--waves) 0 0 / 4em 2em; }
/* aizome linen: a fine weave over deep indigo */
[data-bg="indigo"] {
  background:
    radial-gradient(ellipse 75% 80% at 50% 45%, rgb(255 255 255 / .06), transparent 70%),
    var(--grain-pale),
    repeating-linear-gradient(0deg, rgb(255 255 255 / .03) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgb(0 0 0 / .08) 0 1px, transparent 1px 3px),
    var(--indigo);
}
/* ink-wash hills fading into mist, under a low sun (a moon in dark mode) */
[data-bg="hills"] { background: var(--grain), var(--hills-orb) 93% 9% / 12em 12em no-repeat, var(--hills) center bottom / 100% 32% no-repeat, var(--hills-sky); }
/* a soft blurred colour field */
[data-bg="dusk"] { background: var(--grain), var(--dusk); }

/* indigo is dark in either mode, so text and tools beside the board turn pale */
.game[data-bg="indigo"] > .panel, .game[data-bg="indigo"] > .stage, .game[data-bg="indigo"] .rail > :not(.pop) {
  --foreground: #e9e6ef;
  --muted-foreground: #9ea8c4;
  --accent: rgb(255 255 255 / .08);
  --border: rgb(255 255 255 / .13);
  --input: rgb(255 255 255 / .24);
  --card: #24304e;
  --primary: #e9e6ef;
  --primary-foreground: #1c2643;
  --ring: #8292bb;
  color: var(--foreground);
}

/* background swatches: the same artwork at a tiny scale */
.swatches { display: flex; gap: 10px; }
.swatches label { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; }
.swatches input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.swatch { width: 46px; height: 32px; border-radius: 8px; font-size: 2.6px; box-shadow: inset 0 0 0 1px rgb(0 0 0 / .1); transition: box-shadow .15s; }
.swatches small { font-size: 12px; color: var(--muted-foreground); }
.swatches input:checked + .swatch { box-shadow: inset 0 0 0 1px rgb(0 0 0 / .1), 0 0 0 2px var(--card), 0 0 0 4px var(--shu); }
.swatches input:checked ~ small { color: var(--foreground); font-weight: 500; }
.swatches input:focus-visible + .swatch { box-shadow: inset 0 0 0 1px rgb(0 0 0 / .1), 0 0 0 2px var(--card), 0 0 0 4px color-mix(in oklab, var(--ring) 70%, transparent); }
.panel { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.panel.left { padding: 6px 14px 2px 8px; }
.panel.right { padding: 4px 12px 0; gap: 2px; }
.bar { display: flex; align-items: center; gap: 4px; }
.brand { display: flex; align-items: center; gap: 9px; font: 800 20px/1 var(--title); letter-spacing: -.01em; }
.brand-seal {
  font: 800 11px/1 var(--title);
  letter-spacing: .1em;
  padding: 3px 2px 3px 4px;
  border-radius: 2px;
  background: var(--shu);
  color: #fff4ef;
  transform: rotate(-3deg) translateY(-1px);
}

/* players: name in the title face; the one to move is underlined in vermilion */
.players { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; padding-left: 6px; }
.plate {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
  border-radius: 8px;
  transition: opacity .3s;
}
.game.live .plate:not(.active) { opacity: .55; }
.plate .stone { width: 22px; height: 22px; border-radius: 50%; box-shadow: 0 1px 2px rgb(0 0 0 / .25), inset 0 0 0 1px rgb(0 0 0 / .1); }
.plate .who { min-width: 0; }
.plate .name { position: relative; display: block; width: fit-content; max-width: 100%; padding-bottom: 3px; font: 600 17px/1.2 var(--title); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.plate .name::after { left: 0; right: 0; bottom: 0; transform: rotate(-1deg) scaleX(0); transform-origin: left; }
.plate.active .name::after { transform: rotate(-1deg) scaleX(1); }
.plate .sub { display: block; color: var(--muted-foreground); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.plate .sub:empty { display: none; }
.plate .meta { display: flex; flex-direction: column; align-items: flex-end; }
.plate .clock { font-variant-numeric: tabular-nums; font-weight: 500; font-size: 15px; }
.plate .clock.low { color: var(--destructive); }
.plate .score { color: var(--muted-foreground); font-size: 12px; }
.plate.offline .name { opacity: .5; }
.plate.editable { cursor: pointer; }
@media (hover: hover) { .plate.editable:hover .name::after { transform: rotate(-1deg) scaleX(1); opacity: .45; } .plate.editable.active:hover .name::after { opacity: 1; } }
.status { font: 500 15px/1.4 var(--title); text-align: center; min-height: 21px; }
.game.over .status { visibility: hidden; }

.stage { position: relative; min-height: 0; overflow: hidden; }
#board { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; cursor: crosshair; }

/* slips: notes laid on the table beside the board */
.slip { display: flex; flex-direction: column; gap: 8px; }
.line-row { display: flex; align-items: center; gap: 4px; }
.line-label { color: var(--muted-foreground); font-size: 13px; margin-right: 6px; }

.result { flex-direction: row; align-items: center; gap: 12px; padding: 6px 4px 10px; }
.result-text { flex: 1; min-width: 0; }
.result-text h2 { font-size: 20px; }
.result-text p { margin-top: 2px; }
#resultHint { display: none; }

/* tool rail: round icon buttons, a thin row under the board on mobile */
.rail {
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 2px 8px max(4px, env(safe-area-inset-bottom));
}
.rail > .btn.icon { width: 40px; height: 40px; }
.rail > .btn.icon svg { width: 20px; height: 20px; }
.rail > .btn.icon.on { background: var(--accent); color: var(--foreground); }
/* disabled tools still show their tooltip */
.rail > .btn:disabled { pointer-events: auto; cursor: default; }
.rail-gap { flex: none; width: 4px; height: 4px; border-radius: 50%; background: var(--input); }
.game.over #resignBtn { display: none; }
#soundBtn .vol-off, #soundBtn.muted .vol-on { display: none; }
#soundBtn.muted .vol-off { display: block; }

[data-tip] { position: relative; }
@media (hover: hover) {
  [data-tip]::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    padding: 4px 9px;
    border-radius: 6px;
    background: var(--primary);
    color: var(--primary-foreground);
    font: 500 12px/1.4 var(--sans);
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transition: opacity .12s;
    z-index: 20;
  }
  /* keep the end tooltips of the mobile row on screen */
  #undoBtn::after { left: 0; transform: none; }
  #settingsBtn::after { left: auto; right: 0; transform: none; }
  [data-tip]:hover::after { opacity: 1; transition-delay: .3s; }
  [data-tip].on::after { display: none; }
}

/* rail popovers (top layer; positioned from app.js) */
.pop {
  position: fixed;
  inset: auto;
  margin: 0;
  width: max-content;
  max-width: calc(100vw - 24px);
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--grain), var(--card);
  color: var(--foreground);
  box-shadow: var(--shadow-lg);
}
.pop-head h2, .dialog-head h2 { font: 600 19px/1.25 var(--title); }
.pop-head { margin-bottom: 6px; }
#soundPop, #palettePop { width: 300px; }
#soundPop:popover-open { display: flex; flex-direction: column; gap: 6px; }
.emote-pop { padding: 4px; border-radius: 999px; }
.emote-pop:popover-open { display: flex; gap: 2px; }
.emote-pop button { font-size: 22px; width: 42px; height: 42px; border: 0; background: none; border-radius: 50%; cursor: pointer; transition: transform .15s; }
.emote-pop button:hover { background: var(--accent); transform: scale(1.12); }

/* volume slider: an ink line with a black stone to slide */
.slider-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 4px 12px; padding: 4px 0; font-size: 14px; }
.slider-row output { grid-area: 1 / 2; color: var(--muted-foreground); font-size: 13px; font-variant-numeric: tabular-nums; }
.slider-row .slider { grid-column: 1 / -1; }
.slider {
  --v: 50%;
  appearance: none;
  width: 100%;
  height: 22px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}
.slider::-webkit-slider-runnable-track { height: 3px; border-radius: 999px; background: linear-gradient(to right, var(--primary) var(--v), var(--input) var(--v)); }
.slider::-moz-range-track { height: 3px; border-radius: 999px; background: var(--input); }
.slider::-moz-range-progress { height: 3px; border-radius: 999px; background: var(--primary); }
.slider::-webkit-slider-thumb {
  appearance: none;
  width: 18px;
  height: 18px;
  margin-top: -7.5px;
  border-radius: 50%;
  border: 0;
  background: radial-gradient(circle at 35% 30%, #6a6d76, #16171b 70%);
  box-shadow: 0 2px 3px rgb(0 0 0 / .3);
}
.slider::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; border: 0; background: radial-gradient(circle at 35% 30%, #6a6d76, #16171b 70%); box-shadow: 0 2px 3px rgb(0 0 0 / .3); }
.slider:focus-visible { box-shadow: none; }
.slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 55%, transparent); }
.slider:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 55%, transparent); }

.floaters { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.floaters span { position: absolute; font-size: 40px; animation: float 2.2s ease-out forwards; }
@keyframes float {
  0% { opacity: 0; transform: translateY(20px) scale(.6); }
  15% { opacity: 1; transform: translateY(0) scale(1.1); }
  100% { opacity: 0; transform: translateY(-140px) scale(1); }
}

/* move history: a quiet strip of round buttons around the move count */
.history { display: flex; align-items: center; justify-content: center; gap: 0; }
.history .btn.icon { width: 36px; height: 36px; }
.hist-label { min-width: 112px; text-align: center; font: 500 15px/1 var(--title); color: var(--muted-foreground); }
.history.reviewing .hist-label { color: var(--foreground); }
.review-chip {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 16px;
  background: var(--grain), var(--card);
  color: var(--foreground);
  font: 500 14px/1.3 var(--title);
  white-space: nowrap;
  box-shadow: var(--shadow-lg);
  cursor: pointer;
}

/* mobile: the takeback prompt floats above the bar */
.ask {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: calc(92px + env(safe-area-inset-bottom));
  z-index: 10;
  max-width: 400px;
  margin: 0 auto;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--grain), var(--card);
  box-shadow: var(--shadow-lg);
}
.ask p { font: 500 16px/1.4 var(--title); }
/* mobile: the two players face each other across the top */
@media (max-width: 999px), (max-height: 559px) {
  #plate1 { grid-template-columns: auto minmax(0, 1fr) auto; text-align: right; }
  #plate1 .stone { order: 3; }
  #plate1 .meta { order: -1; align-items: flex-start; }
  #plate1 .name { margin-left: auto; }
  #plate1 .name::after { transform-origin: right; }
}

/* desktop: everything but the board gathers in the left margin; tools hug the right */
@media (min-width: 1000px) and (min-height: 560px) {
  .game {
    --side: clamp(250px, 22vw, 320px);
    grid-template-columns: var(--side) minmax(0, 1fr) var(--side);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "left stage rail" "right stage rail";
  }
  .panel.left { grid-area: left; padding: 26px 12px 0 30px; gap: 22px; }
  .panel.right { grid-area: right; padding: 22px 12px 26px 30px; gap: 22px; overflow-y: auto; }
  .stage { grid-area: stage; }
  .rail { grid-area: rail; justify-self: end; align-self: center; flex-direction: column; gap: 6px; padding: 16px 22px 16px 0; }
  .rail-gap { margin: 8px 0; }
  [data-tip]::after, #undoBtn::after, #settingsBtn::after { bottom: auto; left: auto; top: 50%; right: calc(100% + 8px); transform: translateY(-50%); }
  .bar { margin-left: -10px; }
  .players { grid-template-columns: 1fr; gap: 14px; padding-left: 0; }
  .status { text-align: left; }
  .ask { position: static; margin: 0; max-width: none; padding: 14px 0; border: 0; border-block: 1px solid var(--border); border-radius: 0; background: none; box-shadow: none; }
  .game.over .status { display: none; }
  .result { flex-direction: column; align-items: flex-start; gap: 10px; padding: 0; }
  .result .ink-btn { margin-left: -.2em; }
  .result-text h2 { font-size: 26px; }
  #resultHint { display: block; }
  .history { justify-content: flex-start; margin-left: -8px; }
  .hist-label { min-width: 104px; }
}

/* ---------- settings form ---------- */
.gform { display: flex; flex-direction: column; gap: 10px; }
.gform fieldset { border: 0; padding: 0; margin: 0; min-width: 0; display: flex; flex-direction: column; gap: 22px; }
.gform fieldset:disabled { opacity: .55; }
.field { display: flex; flex-direction: column; gap: 6px; }
.label { font: 600 15px/1.3 var(--title); }
.field .switch-row { padding: 4px 0 0; }
.sub { display: flex; flex-direction: column; gap: 6px; }
.sub:has(> .input) { flex-direction: row; align-items: center; gap: 8px; }
.form-error { color: var(--destructive); font-size: 13px; }
.form-error:empty { display: none; }

/* ---------- dialog ---------- */
.dialog {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--grain), var(--card);
  color: var(--foreground);
  padding: 20px;
  width: min(440px, calc(100% - 24px));
  max-height: min(88dvh, 760px);
  box-shadow: var(--shadow-lg);
}
.dialog::backdrop { background: rgb(34 24 14 / .35); }
.dialog-head { display: flex; align-items: center; justify-content: space-between; margin: -6px -8px 8px 0; }
.invite { width: min(420px, calc(100% - 32px)); padding: 22px 24px 20px; }
.invite[open] { display: flex; flex-direction: column; gap: 8px; animation: invite-in .28s cubic-bezier(.2, .8, .2, 1); }
.invite .dialog-head { margin-bottom: 0; }
.invite .dialog-head h2 { font-size: 22px; }
.invite #inviteNote { margin-bottom: 6px; }
@keyframes invite-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }
.sheet {
  inset: 0 0 0 auto;
  margin: 0;
  width: min(380px, 100%);
  height: 100dvh;
  max-width: none;
  max-height: none;
  border: 0;
  border-left: 1px solid var(--border);
  border-radius: 0;
  padding: max(24px, env(safe-area-inset-top)) 26px max(24px, env(safe-area-inset-bottom));
  overflow-y: auto;
}
.sheet[open] { animation: sheet-in .26s cubic-bezier(.2, .8, .2, 1); }
@keyframes sheet-in { from { transform: translateX(100%); } }
.sheet .dialog-head { margin-bottom: 4px; }
.sheet .dialog-head h2 { font-size: 22px; }
#lockNote { margin-bottom: 10px; }
#lockNote:empty { display: none; }
.prefs { display: flex; flex-direction: column; gap: 12px; }
.prefs .switch-row { padding: 2px 0; }

/* ---------- toast ---------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(88px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  background: var(--grain), var(--card);
  color: var(--foreground);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  padding: 9px 18px;
  border-radius: 999px;
  font: 500 15px/1.4 var(--title);
  z-index: 30;
  max-width: calc(100% - 32px);
  text-align: center;
}
@media (min-width: 1000px) {
  .toast { left: auto; right: 24px; bottom: 24px; transform: none; }
}

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