:root {
  --ink: #241b14;
  --ink-soft: #6a5844;
  --parchment: #f3ead8;
  --paper: #fbf6ea;
  --line: #d8cbb0;
  --frame: #3a2e24;
  --light-fill: #cb9d63;
  --light-edge: #875f2b;
  --dark-fill: #6e2a24;
  --dark-edge: #3a120f;
  --accent: #8a5a2b;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background:
    radial-gradient(1200px 700px at 50% -10%, #fffdf6 0%, transparent 60%),
    #ece1cb;
  color: var(--ink);
  font: 15px/1.5 "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  min-height: 100vh;
}

kbd {
  font: 11px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  background: rgba(0,0,0,.07);
  border: 1px solid rgba(0,0,0,.16);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 2px 4px;
  vertical-align: 1px;
}

/* ------------------------------------------------------------------- bar */

.bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px 22px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(#fbf6ea, #f2e8d4);
}
.bar h1 {
  margin: 0;
  font-size: 26px;
  letter-spacing: .01em;
  font-weight: 600;
}
.bar .sub {
  display: block;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.ctl {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.ctl.check { text-transform: none; letter-spacing: 0; font-size: 13px; }
select, button {
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 6px 10px;
  cursor: pointer;
}
select { text-transform: none; letter-spacing: 0; }
button:hover:not(:disabled) { background: #fff; border-color: var(--accent); }
button:disabled { opacity: .42; cursor: default; }
button.primary { background: var(--frame); color: #f6eddb; border-color: var(--frame); }
button.primary:hover { background: #4d3d2f; }
button.primary kbd { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.3); color: inherit; }

/* ----------------------------------------------------------------- board */

main {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 20px;
  padding: 22px;
}

.board-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

#board {
  width: 476px;
  max-width: min(92vw, 476px);
  height: auto;
  border-radius: 10px;
  box-shadow: 0 14px 34px rgba(50,35,18,.28), 0 2px 0 #fff8;
  cursor: crosshair;
  touch-action: none;
}

.status {
  font-size: 17px;
  letter-spacing: .02em;
  padding: 7px 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--paper);
}
.status.turn-light { border-color: var(--light-edge); box-shadow: inset 0 0 0 2px rgba(203,157,99,.28); }
.status.turn-dark  { border-color: var(--dark-edge); background: var(--dark-fill); color: #f6e7d6; }
.status.turn-over  { border-color: var(--accent); background: #fff3d9; font-weight: 600; }
.status.thinking { animation: pulse 1.1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .58; } }
@media (prefers-reduced-motion: reduce) { .status.thinking { animation: none; } }

.hint { margin: 0; font-size: 12.5px; color: var(--ink-soft); }

/* Rotate and Undo repeated beneath the board; only wanted where there is no
   keyboard or right mouse button. */
.touch-controls { display: none; gap: 8px; }
button.touch.primary { background: var(--frame); color: #f6eddb; border-color: var(--frame); }
button.touch.primary:disabled { background: var(--paper); color: var(--ink); border-color: var(--line); }
button.touch {
  font-size: 14px;
  padding: 9px 16px;
  min-height: 42px;
  border-color: var(--line);
  box-shadow: 0 1px 0 rgba(60, 45, 25, .12);
}

.cath-slot { display: none; }
.cath-slot.shown {
  display: block;
  padding: 8px 12px;
  border: 1px dashed var(--accent);
  border-radius: 10px;
  background: #fff8e8;
}

/* ----------------------------------------------------------------- trays */

.tray {
  width: 178px;
  flex: 0 0 178px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px;
  box-shadow: 0 3px 12px rgba(60,45,25,.08);
}
.tray.active { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(138,90,43,.16), 0 3px 12px rgba(60,45,25,.12); }

.tray-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.tray-head .who { font-weight: 600; letter-spacing: .06em; text-transform: uppercase; font-size: 12px; }
.tray-head .score { margin-left: auto; font-size: 11.5px; color: var(--ink-soft); }
.swatch { width: 14px; height: 14px; border-radius: 3px; display: inline-block; }
.swatch.light { background: var(--light-fill); border: 1.5px solid var(--light-edge); }
.swatch.dark  { background: var(--dark-fill);  border: 1.5px solid var(--dark-edge); }

.tray-list { display: flex; flex-direction: column; gap: 3px; }

button.piece {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 4px 7px;
  border: 1px solid transparent;
  background: transparent;
  border-radius: 8px;
  text-align: left;
  min-height: 40px;
}
button.piece canvas { flex: 0 0 auto; }
button.piece .plabel { font-size: 13px; }
button.piece:hover:not(:disabled) { background: #fff; border-color: var(--line); }
button.piece.selected {
  background: #fff5df;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(138,90,43,.3);
}
button.piece.stuck { opacity: .45; }
button.piece.stuck .plabel { text-decoration: line-through; }
button.piece:disabled { opacity: .6; }
.tray .empty { font-size: 13px; color: var(--ink-soft); font-style: italic; margin: 6px 2px; }

/* ----------------------------------------------------------------- lower */

.lower {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  padding: 0 22px 32px;
  align-items: flex-start;
  justify-content: center;
}
.panel {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 16px;
  flex: 1 1 340px;
  max-width: 560px;
}
.panel h2 {
  margin: 0 0 6px;
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: inline;
}
.log {
  margin: 0;
  padding: 0 0 0 4px;
  list-style: none;
  max-height: 170px;
  overflow-y: auto;
  font-size: 13.5px;
}
.log li { padding: 2px 0; border-bottom: 1px dotted var(--line); }
.log li:last-child { font-weight: 600; }

.rules summary { cursor: pointer; }
.rules ol { margin: 10px 0 0; padding-left: 20px; font-size: 13.5px; }
.rules li { margin-bottom: 7px; }
.rules .src { font-size: 12px; color: var(--ink-soft); font-style: italic; }

@media (max-width: 900px) {
  /* On a phone the trays go under the board, and a tall vertical list of
     fourteen buildings means scrolling away from the board to pick one - worse
     for whoever is listed second.  So each tray becomes a single row that
     scrolls sideways, and the side you are actually playing is ordered
     directly beneath the board.  --m-order is set per tray by the UI; it is
     ignored on wider screens, where the trays are columns either side. */
  main { flex-wrap: wrap; gap: 10px; padding: 10px; }
  .board-wrap { order: 1; flex: 1 1 100%; gap: 7px; }
  /* min-width:0 matters: without it a flex item refuses to shrink below its
     content, so the row of buildings widens the tray past the viewport and the
     whole page scrolls sideways instead of just the strip. */
  .tray { order: var(--m-order, 3); flex: 1 1 100%; width: auto; min-width: 0; padding: 6px 9px; }

  .tray-list {
    display: flex;
    flex-direction: row;
    gap: 6px;
    min-width: 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    padding-bottom: 4px;
    -webkit-overflow-scrolling: touch;
  }
  .tray-list::-webkit-scrollbar { height: 5px; }
  .tray-list::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }

  button.piece {
    flex: 0 0 auto;
    flex-direction: column;
    justify-content: center;
    width: 66px;
    min-height: 0;
    gap: 3px;
    padding: 6px 3px;
    text-align: center;
    scroll-snap-align: start;
  }
  button.piece .plabel { font-size: 11px; line-height: 1.15; }
  /* Sideways gestures scroll the strip; anything vertical is a drag towards
     the board and is delivered to the page instead of panning. */
  .tray-list button.piece { touch-action: pan-x; }
  body.zh button.piece { width: 74px; min-height: 0; }
  body.zh button.piece .plabel { font-size: 11px; }
  .py { font-size: .78em; }

  /* The toolbar is seven controls wide; let it breathe less on a phone. */
  .bar { padding: 10px 12px; gap: 8px 12px; }
  .bar h1 { font-size: 21px; }
  .controls { gap: 6px; margin-left: 0; }
  .ctl { font-size: 11px; }
  select, button, a.navlink { font-size: 12px; padding: 5px 8px; }
  .status { font-size: 15px; padding: 6px 13px; }
  /* Toolbar chrome drops its pinyin on a phone.  Seven stacked readings cost
     about fifty vertical pixels, which pushes your own tray past the fold, and
     setting them inline only made the labels wider and wrapped the bar onto
     more rows still.  Readings stay everywhere they carry the game: the status
     line, the move log, the trays and the whole rules page. */
  .ctl .py { display: none; }

  /* Keep the board short enough that it and one tray share a screenful. */
  #board { max-width: min(92vw, 476px, 58vh); }
  /* The buttons make the gesture obvious, so the written hint - which named a
     right-click and a scroll wheel that a phone does not have - gives up its
     row to them instead of adding one. */
  .touch-controls { display: flex; }
  .hint { display: none; }
  .lower { padding: 0 12px 20px; }
}

/* Very small screens: keep board plus one tray row on a single screenful. */
@media (max-width: 430px) {
  .tray-head { padding-bottom: 5px; margin-bottom: 5px; }
  .tray-head .score { font-size: 10.5px; }
  button.piece { width: 60px; }
  body.zh button.piece { width: 68px; }
  .log { max-height: 120px; }
}

/* ------------------------------------------------------------ rules page */

a.navlink {
  font-size: 13px;
  color: var(--ink);
  text-decoration: none;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 6px 10px;
}
a.navlink:hover { background: #fff; border-color: var(--accent); }
a.navlink.primary { background: var(--frame); color: #f6eddb; border-color: var(--frame); }
a.navlink.primary:hover { background: #4d3d2f; }

.sheet {
  max-width: 860px;
  margin: 0 auto;
  padding: 26px 24px 60px;
}
.sheet section {
  margin-top: 34px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}
.sheet h2 {
  margin: 0 0 12px;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: .01em;
}
.sheet h3 { margin: 26px 0 8px; font-size: 15px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }
.sheet p { margin: 0 0 12px; max-width: 68ch; }
.lede { font-size: 17px; line-height: 1.62; }
.aside { font-size: 13px; color: var(--ink-soft); font-style: italic; }

ul.plain { margin: 0 0 12px; padding-left: 20px; max-width: 68ch; }
ul.plain li { margin-bottom: 7px; }
ol.tips { margin: 0; padding-left: 22px; max-width: 68ch; }
ol.tips li { margin-bottom: 6px; }

.cards { display: flex; flex-wrap: wrap; gap: 14px; }
.card {
  flex: 1 1 300px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 16px;
}
.card h3 { margin: 0 0 8px; }
.card p:last-child { margin-bottom: 0; }

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 10px;
  margin: 14px 0 4px;
}
.mirrors { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); max-width: 640px; }

figure.pcard {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 74px;
  padding: 8px 10px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
}
figure.pcard canvas { flex: 0 0 auto; }
figure.pcard figcaption { display: flex; flex-direction: column; line-height: 1.28; }
.pname { font-size: 14px; }
.psub { font-size: 11.5px; color: var(--ink-soft); }

.diagrams {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(272px, 1fr));
  gap: 18px;
  margin: 18px 0;
}
figure.diagram {
  margin: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px;
}
figure.diagram h3 { margin: 0 0 10px; font-size: 12px; letter-spacing: .1em; }
figure.diagram canvas {
  display: block;
  margin: 0 auto 10px;
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  box-shadow: 0 5px 14px rgba(50,35,18,.2);
}
figure.diagram figcaption { font-size: 13px; line-height: 1.5; color: var(--ink); }
.outcome {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  padding: 5px 9px;
  border-radius: 7px;
}
.outcome.yes { background: #e9f2e2; border: 1px solid #b6cfa4; color: #33501f; }
.outcome.no  { background: #f4e7e4; border: 1px solid #d8b8b0; color: #6d3b30; }

.backlink { margin-top: 34px; }

/* --------------------------------------------------- chinese and pinyin */

/* The pinyin reading sits under whatever it belongs to, so a label, a status
   line and a whole paragraph all stack the same way. */
.py {
  display: block;
  font-size: .74em;
  line-height: 1.35;
  letter-spacing: .01em;
  opacity: .62;
  /* Headings uppercase and letter-space their contents; pinyin must not
     inherit any of that, or the tone marks become unreadable. */
  text-transform: none;
  font-style: normal;
  font-variant: normal;
  font-weight: 400;
  /* The serif face has no caron vowels (ǎ ě ǐ ǒ ǔ), so third-tone syllables
     fall back glyph by glyph and the mark drifts off the letter.  This stack
     covers the whole of pinyin. */
  font-family: "Segoe UI", "Noto Sans", "Helvetica Neue", Arial, sans-serif;
}

/* Mandarin wants a font stack that actually has the glyphs, and a touch more
   line height than the serif face gives Latin text. */
body.zh {
  font-family: "Noto Sans SC", "Source Han Sans SC", "PingFang SC",
               "Microsoft YaHei", "Hiragino Sans GB", sans-serif;
  line-height: 1.65;
}
body.zh .bar h1 { letter-spacing: .02em; }
body.zh .sub { letter-spacing: .06em; }
body.zh .status { font-size: 16px; }
body.zh .py { font-family: "Segoe UI", "Noto Sans", "Helvetica Neue", Arial, sans-serif; }

/* Rows grow taller once a reading is stacked under the label, and the tray
   needs a little more width so the side name does not wrap mid-word. */
body.zh button.piece { min-height: 44px; }
body.zh .tray { width: 200px; flex: 0 0 200px; }
.tray-head .who, .tray-head .score { white-space: nowrap; }
body.zh .tray-head { align-items: flex-start; }
body.zh .tray-head .score { font-size: 11px; }
button.piece .plabel .xn { opacity: .7; margin-left: 2px; }

/* The pinyin switch only means anything while Mandarin is selected. */
.ctl.off { opacity: .4; pointer-events: none; }

/* Chinese text carries a hover tooltip with its literal reading and meaning;
   the faint underline is the only hint that there is something to hover. */
.gloss { text-decoration: underline dotted rgba(90, 70, 45, .32); text-underline-offset: 3px; }
body.zh .status .gloss { text-decoration-color: rgba(255, 255, 255, .25); }
.gloss .py { text-decoration: none; }
