/* Goi Dominos — domino-engine canonical CSS (forked from Kanji Dominos).
   Bunpou loads this sheet then layers an overrides file on top.
   Kanji currently maintains its own forked copy under kanji/css/ — see
   the README's "Known drift" section. */

:root {
  --bg: #0f0f12;
  --surface: #2a2a32;
  --surface-hover: #33333d;
  --text: #e8e6e3;
  --text-muted: #9a9590;
  --accent: #7c9cbf;
  --accent-hover: #9bb8db;
  --success: #7cb87c;
  --radius: 12px;
  --shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
  --transition-fast: 0.15s ease;
  --transition-flip: 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, "SF Pro Display", "SF Pro Text", system-ui, sans-serif;
  line-height: 1.5;
}

/* ----- Start page (level selection) ----- */
body.start-page {
  background: linear-gradient(170deg, #d4e6ef 0%, #a8c8d8 50%, #8aafbf 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  min-height: 100dvh;
  padding: calc(env(safe-area-inset-top, 0px) + 1.5rem) 1.5rem max(1.5rem, env(safe-area-inset-bottom, 0px));
  font-family: -apple-system, "SF Pro Display", "SF Pro Text", system-ui, sans-serif;
}

.start-page-bg {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.start-bg-svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0.25;
  filter: blur(0.5px);
}

.start-content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 400px;
}

.start-card {
  background: rgba(255, 255, 255, 0.25);
  backdrop-filter: blur(40px) saturate(180%);
  -webkit-backdrop-filter: blur(40px) saturate(180%);
  border-radius: 24px;
  border: 1px solid rgba(255, 255, 255, 0.45);
  padding: 2rem 1.5rem 1.75rem;
  box-shadow:
    0 8px 32px rgba(0, 40, 70, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.5);
  text-align: center;
}

.start-title {
  margin: 0 0 0.25rem;
  font-size: 2rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: #1a2d3d;
  line-height: 1.15;
}

.start-tagline {
  margin: 0 0 1.5rem;
  font-size: 0.9rem;
  font-weight: 400;
  line-height: 1.5;
  color: #4a6274;
}

.start-tagline-credit {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.82rem;
  font-style: normal;
  font-weight: 400;
  color: #7a8e9c;
}

.start-tagline-credit a {
  color: #4a7a95;
  text-decoration: none;
}

.start-tagline-credit a:hover {
  text-decoration: underline;
}

.level-select {
  padding-top: 0.5rem;
  border-top: 1px solid rgba(255, 255, 255, 0.3);
}

.level-select-heading {
  margin: 0 0 1rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #4a6274;
}

.level-buttons {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
  align-items: stretch;
}

.level-buttons-row {
  margin-bottom: 0.85rem;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.level-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 0;
  width: 100%;
  min-height: 90px;
  padding: 0.9rem 1rem;
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 16px;
  text-decoration: none;
  color: #1a2d3d;
  font-weight: 600;
  -webkit-tap-highlight-color: transparent;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 2px 0 rgba(100, 130, 155, 0.15),
    0 4px 8px rgba(30, 60, 80, 0.08),
    0 8px 24px rgba(30, 60, 80, 0.04);
  transition:
    transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.25s ease,
    background 0.2s ease;
}

.level-card:hover {
  background: rgba(255, 255, 255, 0.92);
  transform: translateY(-3px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 3px 0 rgba(100, 130, 155, 0.12),
    0 8px 16px rgba(30, 60, 80, 0.10),
    0 16px 32px rgba(30, 60, 80, 0.06);
}

.level-card:active {
  transform: translateY(1px) scale(0.98);
  transition-duration: 0.08s;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 1px 0 rgba(100, 130, 155, 0.15),
    0 2px 4px rgba(30, 60, 80, 0.06);
}

.level-badge {
  display: inline-block;
  margin-bottom: 0.3rem;
  padding: 0.2rem 0.7rem;
  background: #3a7ca5;
  color: #fff;
  border-radius: 20px;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* Stacked 2-line variant: category caption above tier label, both inside
   the same colored block. Used for Bunpou tier buttons (and planned for
   Kanji / Goi when they migrate to tier-based labels). */
.level-badge-stacked {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 0.3rem;
  padding: 0.3rem 0.95rem 0.4rem;
  background: #3a7ca5;
  color: #fff;
  border-radius: 14px;
  line-height: 1.15;
}

.level-badge-stacked .badge-cat {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.85;
}

.level-badge-stacked .badge-tier {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  margin-top: 0.1rem;
}

.level-n4 .level-badge,
.level-n4 .level-badge-stacked {
  background: #2e6e8a;
}

.level-n3 .level-badge,
.level-n3 .level-badge-stacked {
  background: #3a7a95;
}

.level-n2 .level-badge,
.level-n2 .level-badge-stacked {
  background: #40677d;
}

.level-n1 .level-badge,
.level-n1 .level-badge-stacked {
  background: #4a6070;
}

.level-beyond .level-badge,
.level-beyond .level-badge-stacked {
  background: #5a6a78;
}

.level-disabled {
  opacity: 0.5;
  cursor: default;
  pointer-events: none;
  filter: grayscale(0.15);
}

.level-disabled:hover {
  transform: none;
}

.level-desc {
  font-size: 0.75rem;
  font-weight: 400;
  color: #4a6274;
  margin-top: 0.1rem;
}

.level-count {
  font-size: 0.75rem;
  font-weight: 400;
  color: #7a8e9c;
  margin-top: 0.08rem;
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1.5rem;
}

/* Game page (2nd page): light blue canvas so dark dominos stand out */
body.game-page {
  background: linear-gradient(180deg, #e8f0f6 0%, #f0f5f9 40%, #e8f0f6 100%);
  color: #1a2d3d;
  font-family: -apple-system, "SF Pro Display", "SF Pro Text", system-ui, sans-serif;
  margin: 0;
}

body.game-page #app {
  min-height: 100vh;
  min-height: 100dvh;
  /* Dynamic Island / notch: safe area + modest breathing room */
  padding-top: calc(env(safe-area-inset-top, 0px) + 0.45rem);
  padding-bottom: max(1.2rem, env(safe-area-inset-bottom, 0px));
  /*
   * Same horizontal inset on BOTH sides (max of L/R + 1.5rem) — iOS can report
   * asymmetric safe-area values; matching sides keeps the column visually centered.
   */
  --game-pad: max(1.5rem, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  padding-left: var(--game-pad);
  padding-right: var(--game-pad);
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
  overflow-x: clip;
}

/*
 * Single wrapper: one flex-centered column (more reliable on iPhone than 3-col grid).
 * Header + main share width with the domino grid.
 */
body.game-page .game-column {
  width: 100%;
  max-width: 420px;
  min-width: 0;
  flex-shrink: 0;
}

body.game-page .header,
body.game-page main {
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  box-sizing: border-box;
  min-width: 0;
}

body.game-page main {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-width: 0;
}

.progress-panel {
  width: 100%;
  /* margin-bottom bumped from 0.4rem to 1.25rem so the gauge breathes
     above the domino grid (was visually touching the tiles). */
  margin: 0 0 1.25rem;
}

.progress-meta {
  display: flex;
  justify-content: flex-start;
  align-items: baseline;
  margin-bottom: 0.35rem;
  padding: 0 0.05rem;
}

.progress-label {
  font-size: 0.82rem;
  font-weight: 700;
  color: #37566a;
}

.progress-track {
  position: relative;
  width: 100%;
  height: 12px;
  border-radius: 999px;
  /* Blue → yellow → red gradient (was green → yellow → red). Per user
     preference, blue replaces green on the "doing well" side; this also
     echoes the Japanese 青 (ao), traditionally encompassing green/blue. */
  background: linear-gradient(90deg, #3a8ec5 0%, #f0d852 50%, #d95050 100%);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}

.progress-indicator {
  position: absolute;
  top: 3px;
  left: 0%;
  width: 3px;
  height: 20px;
  border-radius: 2px;
  background: #2f3238;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  transform: translateX(-50%);
  transition: left 0.28s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

.progress-indicator::before {
  content: '';
  position: absolute;
  top: -6px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 8px solid #2f3238;
}

.progress-indicator::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -5px;
  transform: translateX(-50%);
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: #f2f3f6;
  border: 2px solid #2f3238;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5);
}

body.game-page .grid-container.grid-c3r8,
body.game-page .grid-container.grid-c3r5 {
  max-width: 100%;
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}

/*
 * Grid had padding: 56px on all sides (for enlarged flip). That inset the domino
 * cells horizontally vs. the header text (full width of the column), so the
 * grid looked misaligned. Use vertical padding only on the game page; flip
 * still has room via overflow + safe areas.
 */
body.game-page .grid-container {
  padding-left: 0;
  padding-right: 0;
  padding-top: 8px;
  padding-bottom: 8px;
  box-sizing: border-box;
}

@media (max-width: 480px) {
  body.game-page .grid-container {
    padding-top: 6px;
    padding-bottom: 6px;
  }

  .header {
    margin-bottom: 1.35rem;
  }

  .header h1 {
    font-size: 1.62rem;
    margin-bottom: 0.2rem;
  }

  .subtitle {
    margin-bottom: 0.9rem;
    font-size: 0.87rem;
  }

  .controls {
    gap: 0.62rem;
    margin-bottom: 0.6rem;
  }

  .btn {
    min-height: 42px;
    padding: 0.58rem 1.05rem;
  }

  .status {
    font-size: 0.82rem;
  }

  .progress-panel {
    margin-bottom: 0.85rem;
  }

  .progress-label {
    font-size: 0.79rem;
  }

  .progress-track {
    height: 11px;
  }

  .progress-indicator {
    height: 18px;
  }
}

body.game-page .header h1 {
  color: #1a2d3d;
  font-weight: 600;
}

body.game-page .subtitle {
  color: #4a6274;
  font-weight: 400;
}

body.game-page .status {
  color: #7a8e9c;
  font-weight: 400;
}

body.game-page .btn-secondary {
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: #1a2d3d;
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 12px;
  font-weight: 600;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 2px 0 rgba(100, 130, 155, 0.12),
    0 3px 6px rgba(30, 60, 80, 0.06);
}

body.game-page .btn-secondary:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.92);
  transform: translateY(-1px);
}

body.game-page .btn-secondary:active:not(:disabled) {
  transform: translateY(1px);
  transition-duration: 0.08s;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 1px 0 rgba(100, 130, 155, 0.12),
    0 1px 3px rgba(30, 60, 80, 0.04);
}

/* Header */
.header {
  text-align: center;
  margin-bottom: 2rem;
  width: 100%;
  max-width: 720px;
}

.header h1 {
  margin: 0 0 0.25rem;
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.subtitle {
  margin: 0 0 1.25rem;
  color: var(--text-muted);
  font-size: 0.9rem;
}

.controls {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  margin-bottom: 0.75rem;
}

.btn {
  padding: 0.6rem 1.25rem;
  border: none;
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--transition-fast), transform var(--transition-fast);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--accent);
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  background: var(--accent-hover);
  transform: translateY(-1px);
}

.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.btn-secondary:hover:not(:disabled) {
  background: var(--surface-hover);
}

.status {
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* Grid + examples layout */
.grid-container {
  display: grid;
  row-gap: 0.35rem;
  column-gap: 0.25rem;
  width: 100%;
  margin: 0 auto 1rem;
  padding: 4px 0;
  overflow: visible;
  /* No `contain: layout style` — WebKit treats it as a containing block
     for `position: fixed` descendants, which would re-anchor the flipped
     popup back to the grid. Paint optimization isn't worth that. */

  /* Constant cell width across grid variants (3×8 baseline). Pre-2026-05-01
   * each shrunk variant had its own max-width, so the cells visibly grew
   * when the grid shrank from 3×3 (118px cells) to 2×2 (158px cells), and
   * also got smaller in 3×3 vs 3×8. Now every variant uses the same
   * --cell-w computed from the 3-col baseline; the container fits its
   * content (centered via `margin: 0 auto`) so 2×2 / 3×3 are simply
   * narrower, not differently-sized. Cell width still adapts to viewport
   * (smaller on iPhone narrow, capped at 420px / 3 on wider screens). */
  --grid-max: min(100%, 420px);
  --grid-gap: 0.25rem;
  --cell-w: calc((var(--grid-max) - 2 * var(--grid-gap)) / 3);
}

/* Baseline 3-col grids — fill container, 1fr distributes evenly. */
.grid-container.grid-c3r8,
.grid-container.grid-c3r5 {
  grid-template-columns: repeat(3, 1fr);
  max-width: 420px;
}

/* Shrunk variants — fixed cell width, container stays at 100% (so the
 * `100%` in --cell-w's calc resolves to a definite value), cells are
 * centered within the wider container via `justify-content: center`.
 *
 * Why not `width: fit-content`: it makes container width depend on cell
 * width, but cell width via --cell-w uses `100%` which depends on
 * container width → circular. Browser resolves the circular percentage
 * to auto (0), the grid collapses to a tiny dot ("dead insect bug"). */
.grid-container.grid-3 {
  grid-template-columns: repeat(3, var(--cell-w));
  justify-content: center;
}

.grid-container.grid-2 {
  grid-template-columns: repeat(2, var(--cell-w));
  justify-content: center;
}

/* 4-col variant kept for legacy paths (not produced by current shrink
 * thresholds in goi). Uses 1fr at its own max-width, like c3r8. */
.grid-container.grid-4 {
  grid-template-columns: repeat(4, 1fr);
  max-width: 480px;
}

/* Domino block — card with two faces */
.domino {
  position: relative;
  /* Wide horizontal dominos for vocabulary */
  width: 100%;
  aspect-ratio: 2.2 / 1;
  justify-self: stretch;
  min-height: 0;
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  /* Performance: promote to own layer for flip/shuffle */
  will-change: transform;
  transform: translateZ(0);
  backface-visibility: hidden;
  transition: transform var(--transition-flip), box-shadow var(--transition-fast);
  isolation: isolate;
}

/*
 * Goi and Bunpou tiles use a centered-modal popup on flip (position: fixed),
 * not the 3D rotateY flip that the base .domino's compositor hints
 * (will-change: transform + transform: translateZ(0) + backface-visibility:
 * hidden) were optimized for. On iOS Safari, those base hints promote the
 * tile to a hardware layer; when our .flipped rule then changes position to
 * fixed and transform to translate(-50%, -50%), iOS's compositor decides the
 * layer is "facing away" and stops painting it AND the grid behind, until a
 * touch event forces a repaint (user-reported symptom: "flipped popup
 * disappears, dark screen, touch reveals grid again").
 *
 * Disable the hints in the BASE state for these tiles so the tile stays in
 * the normal paint flow from the start. No compositor promotion → no
 * face-culling glitch when .flipped is applied.
 *
 * .domino-kanji is included too — only affects the challenge box (where
 * mixed types live in the same grid). When a goi/bunpou tile flips while
 * kanji siblings still have the compositor hints, iOS sometimes glitches
 * the whole grid during paint. Standalone kanji game loads its own
 * stylesheet, not this one, so its rotateY flip animation is unaffected.
 */
.domino.domino-goi,
.domino.domino-bunpou,
.domino.domino-kanji {
  /* !important on the iOS compositor hints because iOS WebKit's compositor
   * sometimes still promotes the layer if the cascade is even slightly
   * ambiguous — and the bug returned in goi after we added unrelated
   * grid-layout changes. !important is NOT used on transform: it would
   * also override the .flipped rule's translate(-50%, -50%) and break
   * centering. The .flipped rule's transform wins via higher specificity
   * (.domino.domino-goi.flipped beats .domino.domino-goi). */
  will-change: auto !important;
  transform: none;
  backface-visibility: visible !important;
  -webkit-backface-visibility: visible !important;
  /* Drop the transform transition too — it would otherwise animate the
   * 0→translate(-50%,-50%) change, recreating the slide-in. Box-shadow can
   * still transition for hover/state effects. */
  transition: box-shadow var(--transition-fast);
}

/*
 * Defang the 3D rendering context for goi/bunpou/kanji-in-challenge tiles.
 * The base `.domino-inner { transform-style: preserve-3d }` plus
 * `.domino-face { backface-visibility: hidden }` form a 3D flip card —
 * appropriate for a rotateY animation, but these tile flavors use a
 * centered-modal popup (or scale-only popup for kanji-in-challenge),
 * never the rotateY flip. Keeping preserve-3d and hidden-backface lets
 * iOS WebKit's compositor decide a face is "back-facing" and cull it,
 * which is the recurring "popup paints empty / grid disappears" bug.
 *
 * Force flat layout + visible backfaces for these tiles so iOS has
 * nothing to cull. The closed-state visual still works because
 * .domino-face-front has higher z-index than .domino-face-back.
 */
.domino.domino-goi .domino-inner,
.domino.domino-bunpou .domino-inner,
.domino.domino-kanji .domino-inner {
  transform-style: flat !important;
  -webkit-transform-style: flat !important;
}

.domino.domino-goi .domino-face,
.domino.domino-bunpou .domino-face,
.domino.domino-kanji .domino-face {
  backface-visibility: visible !important;
  -webkit-backface-visibility: visible !important;
}

/* The base .domino-face-back has transform: rotateY(180deg) (line ~907)
 * — meant to put it on the "back" of a 3D card. With our transform-style:
 * flat above, that rotateY now mirror-flips the element in 2D, producing
 * a visible mirror-flipped back face behind the front face on iOS Safari
 * (technically covered by z-index but iOS sometimes paints anyway). Just
 * remove the rotation entirely for these tile types — the back face stays
 * "facing forward" alongside the front, hidden visually by the front
 * face's higher z-index when closed, and shown directly by .flipped. */
.domino.domino-goi .domino-face-back,
.domino.domino-bunpou .domino-face-back,
.domino.domino-kanji .domino-face-back {
  transform: none !important;
  -webkit-transform: none !important;
}

/*
 * Flipped highlight: do NOT use border on .domino — descendants paint on top of the
 * parent's border in CSS, so the dark back face covered the blue ring on iPhone/WebKit.
 * A ::after ring is painted after the faces and stays visible.
 */
.domino.flipped {
  transform: translateZ(0) scale(2.2) translateY(-4px);
  z-index: 30;
  box-shadow:
    0 16px 40px rgba(0, 30, 60, 0.25),
    0 4px 12px rgba(0, 30, 60, 0.15);
}

/* Left column: shift right when flipped so popup stays on screen */
.grid-container > .domino.flipped:nth-child(3n+1) {
  transform: translateZ(0) translateX(30%) scale(2) translateY(-4px);
}

/* Right column: shift left when flipped so popup stays on screen */
.grid-container > .domino.flipped:nth-child(3n+3) {
  transform: translateZ(0) translateX(-30%) scale(2) translateY(-4px);
}

.domino.flipped::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 40;
  border-radius: inherit;
  box-sizing: border-box;
  border: 2px solid rgba(255, 255, 255, 0.6);
  pointer-events: none;
}

.domino:hover {
  background: var(--surface-hover);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}

/* Right-click peek: after flip-back, glow advances (edge → wide → full) */
.domino--glow-edge .domino-face-front {
  box-shadow: inset 0 0 0 4px rgba(200, 45, 45, 0.55);
}

.domino--glow-edge {
  box-shadow: var(--shadow),
    0 0 0 2px rgba(220, 60, 60, 0.9),
    0 0 14px rgba(255, 70, 70, 0.5),
    0 0 24px rgba(255, 50, 50, 0.25);
}

.domino--glow-wide .domino-face-front {
  box-shadow: inset 0 0 0 12px rgba(200, 45, 45, 0.55);
}

.domino--glow-full .domino-face-front {
  background: rgba(200, 45, 45, 0.55);
  box-shadow: inset 0 0 0 0 transparent;
}

/* Placeholder for removed slot in 2×2 */
.domino-placeholder {
  background: transparent;
  border: none;
  box-shadow: none;
  cursor: default;
  min-height: 0;
}

.domino-placeholder:hover {
  background: transparent;
  transform: none;
  box-shadow: none;
}

.domino.removed {
  visibility: hidden;
  pointer-events: none;
  position: absolute;
  opacity: 0;
  transform: scale(0);
  transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
}

/* Shuffle: brief pulse when grid reorders.
   Exclude .flipped — the popup uses transform: translate(-50%, -50%) for
   centering, and the shufflePulse keyframes set transform: scale(...) which
   would override the centering, causing the popup to jump to the lower-right
   (translate dropped) and back. */
.grid-container.shuffling .domino:not(.flipped) {
  animation: shufflePulse 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes shufflePulse {
  0% { transform: scale(1); }
  50% { transform: scale(0.96); }
  100% { transform: scale(1); }
}

/* Inner wrapper for 3D flip */
.domino-inner {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  transform-style: preserve-3d;
  transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.domino.flipped .domino-inner {
  transform: rotateY(180deg);
}

.domino-face {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.domino-face-front {
  background: var(--surface);
  z-index: 1;
}

/* Front: word display — sized for multi-character vocabulary */
.domino-face-front .domino-kanji {
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
  white-space: nowrap;
}

/* Furigana on the front face — small kana above kanji, in the same blue
   the back face uses for ruby annotations. The ruby <rt> sits above
   without affecting horizontal width, so the existing fitFrontText
   shrinking logic still works. */
.domino-face-front .domino-kanji ruby {
  ruby-position: over;
}

.domino-face-front .domino-kanji rt {
  font-size: 0.64em;
  color: #6ba0c5;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.05em;
  /* Japanese proportional metrics — Hiragino Sans / Noto Sans JP support
     the "palt" feature, which shrinks per-character sidebearings so
     multi-kana readings (e.g. あたた over 暖) pack closer without
     squishing the glyphs. Falls through harmlessly on fonts without it. */
  font-feature-settings: "palt" 1;
}

/* Front-face furigana toggle (default ON; user can opt out via settings page).
   The class is set on <html> by js/settings.js based on localStorage. The
   flipped/back face ruby is unaffected — only the closed-domino front face
   hides its furigana when the user chooses kanji-only display. */
html.front-furigana-off .domino-face-front .domino-kanji rt {
  display: none;
}

.domino-face-back {
  background: linear-gradient(180deg, #1e2a35 0%, #253340 100%);
  transform: rotateY(180deg);
  z-index: 0;
  text-align: center;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  padding: 0.6rem;
}

/* Game Over overlay */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 20, 40, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  animation: fadeIn 0.3s ease;
}

.overlay.hidden {
  display: none;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.game-over-card {
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: blur(30px) saturate(180%);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  padding: 2.25rem 2rem;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  box-shadow: 0 12px 40px rgba(0, 30, 60, 0.15);
  text-align: center;
  max-width: 320px;
  color: #1a2d3d;
}

.game-over-card h2 {
  margin: 0 0 0.5rem;
  font-size: 1.4rem;
  font-weight: 600;
  color: #1a2d3d;
}

.game-over-card p {
  margin: 0 0 1.25rem;
  color: #4a6274;
  font-weight: 400;
}

/* Victory overlay: light blue */
.overlay.victory {
  background: rgba(170, 210, 255, 0.5);
}

.overlay.victory .game-over-default {
  display: none;
}

.overlay.victory .game-over-victory {
  display: block;
}

.game-over-victory {
  display: none;
  background: rgba(220, 240, 255, 0.95);
  border: 1px solid rgba(150, 200, 240, 0.5);
}

.overlay.victory .game-over-victory {
  color: #1a3a5c;
}

.game-over-prompt {
  margin: 0 0 1.25rem;
  font-size: 1.25rem;
  font-weight: 600;
  color: inherit;
}

.game-over-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}

.game-over-actions .btn {
  min-width: 5.5rem;
}

.overlay.victory .game-over-victory p {
  color: #2a4a6c;
}

/* Reduce motion preference */
@media (prefers-reduced-motion: reduce) {
  .domino,
  .domino-inner,
  .domino.shuffling,
  .progress-indicator {
    transition-duration: 0.15s;
  }
}

/* ==========================================================================
 * Flipped Goi back-face styles — EXTRACTED to css/goi-back-face.css
 *
 * The back-face typography, layout, counter tables, and mobile responsive
 * rules now live in css/goi-back-face.css (loaded by both goi/game.html and
 * kanji/game.html). The kanji 例 Examples popup → "tap a compound's
 * Japanese writing" jump renders the same Goi flipped card on the kanji
 * page; sharing the CSS keeps the two contexts identical.
 *
 * Mahjong Hall accent overrides for the back face (vermilion POS pill,
 * brass example border, brass note left-rule) and back-face furigana ruby
 * typography also moved to css/goi-back-face.css for the same reason.
 *
 * What stays in this file: front-face tile chrome, glow states, closed-
 * tile back-face background (for the rotateY transition), and the
 * Mahjong Hall game-page header / button overrides further below.
 * ========================================================================== */


/* ============================================================
 * MAHJONG HALL OVERRIDES (Step 6 — Goi game-page redesign)
 *
 * Re-skins the game-page chrome and the domino front face for the dark
 * mahjong-hall design language. Loaded LAST so it wins the cascade against
 * the older light-pastel rules above. Tokens (colors, fonts) come from
 * css/design.css which is linked first by goi/game.html.
 *
 * Old light-theme rules above are now mostly unreachable visually but
 * left in place for safety; they can be cleaned up in a follow-up pass
 * once this design has lived for a while.
 * ============================================================ */

body.game-page {
  background: var(--canvas);
  color: var(--text);
  font-family: var(--font-en);
  margin: 0;
}
/* Re-apply the felt texture (design.css's body::before would normally do this
   but body.game-page has its own background that wins, so we re-add the
   texture here scoped to the game page). */
body.game-page::before {
  content: '';
  position: fixed; inset: 0;
  background-image:
    radial-gradient(ellipse at 20% 0%, rgba(212, 74, 58, 0.06) 0%, transparent 50%),
    radial-gradient(ellipse at 80% 100%, rgba(201, 164, 100, 0.05) 0%, transparent 50%),
    repeating-linear-gradient(45deg, rgba(255,255,255,0.008) 0px, transparent 1px, transparent 4px);
  pointer-events: none;
  z-index: 0;
}
body.game-page #app { position: relative; z-index: 1; }

/* === Header (Back link + title + subtitle + controls + status) === */
body.game-page .header {
  text-align: center;
  margin-bottom: 1.2rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--rule);
  position: relative;
}
body.game-page .header .back-link {
  display: inline-block;
  margin-bottom: 10px;
}
body.game-page .header h1 {
  font-family: var(--font-jp);
  font-weight: 700;
  font-size: 1.6rem;
  letter-spacing: 0.04em;
  color: var(--text);
  margin: 0 0 0.2rem;
}
body.game-page .subtitle {
  font-family: var(--font-en);
  font-style: italic;
  font-size: 0.85rem;
  color: var(--text-soft);
  font-weight: 400;
  margin: 0 0 1rem;
}
body.game-page .status {
  font-family: var(--font-ui);
  font-size: 0.78rem;
  color: var(--text-faint);
  letter-spacing: 0.04em;
  margin-top: 0.6rem;
}

/* === Buttons (Reset / Shuffle / Finish + game-over Yes/No) === */
body.game-page .controls { gap: 0.5rem; margin-bottom: 0.6rem; }
body.game-page .btn {
  padding: 0.5rem 1.1rem;
  border-radius: 100px;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
body.game-page .btn-secondary {
  background: rgba(232, 220, 196, 0.06);
  border: 1px solid var(--rule);
  color: var(--text);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
}
body.game-page .btn-secondary:hover:not(:disabled) {
  background: rgba(232, 220, 196, 0.12);
  border-color: rgba(232, 220, 196, 0.25);
  transform: translateY(-1px);
}
body.game-page .btn-secondary:active:not(:disabled) {
  transform: translateY(0);
  background: rgba(232, 220, 196, 0.08);
}
body.game-page .btn-primary {
  background: var(--vermilion);
  color: var(--bone);
  border: 1px solid var(--vermilion);
}
body.game-page .btn-primary:hover:not(:disabled) {
  background: #e85544;
  border-color: #e85544;
}

/* === Progress bar — keep colored heatmap track but theme indicator + label === */
body.game-page .progress-label {
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-soft);
}
body.game-page .progress-track {
  /* Muted blue → brass-yellow → red gradient — was green-based, switched
     per user preference (blue echoes the Japanese 青/ao). Darker tones
     than the base .progress-track gradient so it doesn't look neon
     against the Mahjong Hall dark canvas. */
  background: linear-gradient(90deg, #2a6d9a 0%, #c9a464 50%, #b94538 100%);
  box-shadow: inset 0 0 0 1px rgba(232, 220, 196, 0.15);
}
body.game-page .progress-indicator {
  background: var(--bone);
}
body.game-page .progress-indicator::before {
  border-bottom-color: var(--bone);
}
body.game-page .progress-indicator::after {
  background: var(--canvas);
  border-color: var(--bone);
}

/* === Domino front face — bone-color tile with engraved kanji === */
.domino.domino-goi {
  background: transparent;            /* tile face provides the bone surface */
  border-radius: 10px;
  box-shadow:
    0 3px 0 var(--tile-edge),
    0 6px 16px rgba(0, 0, 0, 0.5);
}
.domino.domino-goi .domino-face-front {
  background: linear-gradient(155deg, var(--bone-bright) 0%, var(--bone) 50%, var(--bone-shadow) 100%);
  border-radius: 10px;
  box-shadow:
    inset -1.5px -1.5px 3px rgba(74, 69, 51, 0.3),
    inset 1.5px 1.5px 3px rgba(255, 255, 255, 0.45);
}
.domino.domino-goi .domino-face-front .domino-kanji {
  color: var(--tile-engrave);
  font-family: var(--font-jp);
  font-weight: 700;
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.45),
    0 -1px 0 rgba(74, 69, 51, 0.35),
    1px 1px 0 rgba(74, 69, 51, 0.25);
}
.domino.domino-goi .domino-face-front .domino-kanji rt {
  color: var(--vermilion);
  text-shadow: none;
  font-weight: 600;
  /* Larger furigana on the bone face — looks more inscribed than the original 0.64em */
  font-size: 0.42em;
  letter-spacing: 0.02em;
}

/* === Domino back face — keep mostly as-is (already dark), just harmonize === */
.domino.domino-goi .domino-face-back {
  background: linear-gradient(180deg, #2a2e44 0%, #1f2335 100%);
  border-radius: 10px;
  box-shadow: inset 0 1px 0 rgba(232, 220, 196, 0.05);
}
/* Mahjong Hall accent overrides for the back face moved to
 * css/goi-back-face.css (vermilion POS pill, brass example border, brass
 * note left-rule). See block comment near top of this file. */

/* === Game-over overlay === */
.overlay {
  background: rgba(20, 23, 33, 0.75);
}
.game-over-card {
  background: linear-gradient(155deg, #2a2e44 0%, #1f2335 100%);
  border: 1px solid var(--rule);
  color: var(--text);
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.6);
}
.game-over-card h2,
.game-over-card p,
.game-over-prompt {
  color: var(--text);
  font-family: var(--font-en);
}


/* ============================================================
 * GLOW STATE OVERRIDES (peek-counter visual feedback)
 *
 * Replaces the legacy red-ring glow system (which was designed for
 * white-card front faces) with a progressive bone-tile color shift
 * that reads clearly on the Mahjong Hall design:
 *
 *   Glow 0 (default)  — bone cream
 *   Glow 1 (1 peek)   — bone shifts to warm amber + subtle outer ring
 *   Glow 2 (2 peeks)  — orange tint + soft outer glow
 *   Glow 3 (3 peeks)  — vermilion tile (matches challenge box accent)
 *                       + strong outer glow + bone-color kanji for contrast
 *
 * The original .domino--glow-* rules above keep their selectors but get
 * superseded by these app-scoped versions for goi (and bunpou via its
 * own override block). The peek-counter logic in main.js is unchanged —
 * only the CSS skin differs.
 * ============================================================ */

/* === Glow 1: amber warmth ("you peeked once") === */
.domino.domino-goi.domino--glow-edge .domino-face-front {
  background: linear-gradient(155deg, #f5dcae 0%, #ecc88e 50%, #b89968 100%);
  box-shadow:
    inset -1.5px -1.5px 3px rgba(74, 69, 51, 0.3),
    inset 1.5px 1.5px 3px rgba(255, 255, 255, 0.45);
}
.domino.domino-goi.domino--glow-edge {
  box-shadow:
    0 3px 0 var(--tile-edge),
    0 6px 16px rgba(0, 0, 0, 0.5),
    0 0 0 1.5px rgba(228, 175, 100, 0.5);
}

/* === Glow 2: orange warning ("you peeked twice — careful") === */
.domino.domino-goi.domino--glow-wide .domino-face-front {
  background: linear-gradient(155deg, #f2bf86 0%, #e6a06a 50%, #b87850 100%);
  box-shadow:
    inset -1.5px -1.5px 3px rgba(74, 69, 51, 0.35),
    inset 1.5px 1.5px 3px rgba(255, 255, 255, 0.4);
}
.domino.domino-goi.domino--glow-wide {
  box-shadow:
    0 3px 0 #6a4a30,
    0 6px 16px rgba(0, 0, 0, 0.5),
    0 0 0 2px rgba(228, 140, 80, 0.7),
    0 0 14px rgba(228, 140, 80, 0.35);
}

/* === Glow 3: vermilion / Challenge-Box trigger ("now in the queue") === */
.domino.domino-goi.domino--glow-full .domino-face-front {
  background: linear-gradient(155deg, #ee8a78 0%, #d44a3a 50%, #a83025 100%);
  box-shadow:
    inset -1.5px -1.5px 3px rgba(60, 18, 14, 0.45),
    inset 1.5px 1.5px 3px rgba(255, 220, 210, 0.35);
}
/* At glow 3 the bg goes vermilion-dark, so flip kanji to bone-cream
   for legibility. Engraved-shadow inverts to dark + light pair. */
.domino.domino-goi.domino--glow-full .domino-face-front .domino-kanji {
  color: var(--bone);
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.4),
    0 -1px 0 rgba(255, 255, 255, 0.2),
    1px 1px 0 rgba(0, 0, 0, 0.3);
}
.domino.domino-goi.domino--glow-full .domino-face-front .domino-kanji rt {
  color: rgba(248, 232, 211, 0.9);
  text-shadow: none;
}
.domino.domino-goi.domino--glow-full {
  box-shadow:
    0 3px 0 #5a2820,
    0 6px 16px rgba(0, 0, 0, 0.5),
    0 0 0 2px rgba(212, 74, 58, 0.95),
    0 0 22px rgba(212, 74, 58, 0.55),
    0 0 10px rgba(212, 74, 58, 0.4);
}


/* ============================================================
 * .domino-kanji parity overrides
 *
 * Mirrors the .domino-goi front-face + glow rules so kanji-sourced
 * tiles in the Challenge Box (and anywhere else that loads this sheet)
 * get the same bone-tile treatment + amber/orange/vermilion glow
 * progression. Kanji's own dedicated game page (kanji/game.html) does
 * NOT load this sheet, so it's unaffected — its design comes later in
 * the dedicated Kanji overhaul.
 * ============================================================ */

.domino.domino-kanji {
  background: transparent;
  border-radius: 10px;
  box-shadow:
    0 3px 0 var(--tile-edge),
    0 6px 16px rgba(0, 0, 0, 0.5);
}
.domino.domino-kanji .domino-face-front {
  background: linear-gradient(155deg, var(--bone-bright) 0%, var(--bone) 50%, var(--bone-shadow) 100%);
  border-radius: 10px;
  box-shadow:
    inset -1.5px -1.5px 3px rgba(74, 69, 51, 0.3),
    inset 1.5px 1.5px 3px rgba(255, 255, 255, 0.45);
}
.domino.domino-kanji .domino-face-front .domino-kanji {
  color: var(--tile-engrave);
  font-family: var(--font-jp);
  font-weight: 700;
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.45),
    0 -1px 0 rgba(74, 69, 51, 0.35),
    1px 1px 0 rgba(74, 69, 51, 0.25);
}

/* Glow progression — copied from .domino-goi block above */
.domino.domino-kanji.domino--glow-edge .domino-face-front {
  background: linear-gradient(155deg, #f5dcae 0%, #ecc88e 50%, #b89968 100%);
  box-shadow:
    inset -1.5px -1.5px 3px rgba(74, 69, 51, 0.3),
    inset 1.5px 1.5px 3px rgba(255, 255, 255, 0.45);
}
.domino.domino-kanji.domino--glow-edge {
  box-shadow:
    0 3px 0 var(--tile-edge),
    0 6px 16px rgba(0, 0, 0, 0.5),
    0 0 0 1.5px rgba(228, 175, 100, 0.5);
}
.domino.domino-kanji.domino--glow-wide .domino-face-front {
  background: linear-gradient(155deg, #f2bf86 0%, #e6a06a 50%, #b87850 100%);
  box-shadow:
    inset -1.5px -1.5px 3px rgba(74, 69, 51, 0.35),
    inset 1.5px 1.5px 3px rgba(255, 255, 255, 0.4);
}
.domino.domino-kanji.domino--glow-wide {
  box-shadow:
    0 3px 0 #6a4a30,
    0 6px 16px rgba(0, 0, 0, 0.5),
    0 0 0 2px rgba(228, 140, 80, 0.7),
    0 0 14px rgba(228, 140, 80, 0.35);
}
.domino.domino-kanji.domino--glow-full .domino-face-front {
  background: linear-gradient(155deg, #ee8a78 0%, #d44a3a 50%, #a83025 100%);
  box-shadow:
    inset -1.5px -1.5px 3px rgba(60, 18, 14, 0.45),
    inset 1.5px 1.5px 3px rgba(255, 220, 210, 0.35);
}
.domino.domino-kanji.domino--glow-full .domino-face-front .domino-kanji {
  color: var(--bone);
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.4),
    0 -1px 0 rgba(255, 255, 255, 0.2),
    1px 1px 0 rgba(0, 0, 0, 0.3);
}
.domino.domino-kanji.domino--glow-full {
  box-shadow:
    0 3px 0 #5a2820,
    0 6px 16px rgba(0, 0, 0, 0.5),
    0 0 0 2px rgba(212, 74, 58, 0.95),
    0 0 22px rgba(212, 74, 58, 0.55),
    0 0 10px rgba(212, 74, 58, 0.4);
}

/* ============================================================
   OVERLAY ARCHITECTURE — in-grid .domino.flipped is a no-op.

   The visual modal lives in #flipped-overlay (body-level sibling
   of #app — see css/design.css for the overlay's styling). The
   .domino in the grid stays in its cell; the .flipped class on it
   is now just a JS state marker, no visual transform.

   This override neutralizes the earlier in-place modal CSS:
     .domino.flipped { transform: scale(2.2)... }                (line ~742)
     .domino.domino-goi.flipped { position: fixed; ... }         (line ~1045)
     .domino.domino-bunpou.flipped { ... }                       (in bunpou/css)
   We don't delete those rules to keep the diff minimal — this
   override at the end of the file wins by !important + later
   source order, the bulletproof way to deactivate them.

   Scoped to body.game-page so kanji/css/style.css's standalone game
   (loaded by kanji/index.html and kanji/game.html) is unaffected —
   kanji standalone keeps its scale(2.2) flipped behavior pending
   the kanji overhaul.
   ============================================================ */
body.game-page .grid-container .domino.flipped,
body.game-page .grid-container > .domino.flipped:nth-child(3n+1),
body.game-page .grid-container > .domino.flipped:nth-child(3n+3),
body.game-page .grid-container .domino.domino-goi.flipped,
body.game-page .grid-container .domino.domino-bunpou.flipped,
body.game-page .grid-container .domino.domino-kanji.flipped {
  position: relative !important;
  inset: auto !important;
  top: auto !important;
  left: auto !important;
  right: auto !important;
  bottom: auto !important;
  transform: none !important;
  width: 100% !important;
  height: auto !important;
  aspect-ratio: 2.2 / 1 !important;
  z-index: auto !important;
}

/* Front face stays visible on the in-grid tile when flipped — the back-face
   content lives in the overlay, not on the tile. Override the existing
   `.domino.domino-goi.flipped .domino-face-front { display: none }` rule. */
body.game-page .grid-container .domino.flipped .domino-face-front {
  display: flex !important;
}

/* Back face is hidden entirely on the in-grid tile when flipped. The
   existing `.domino.domino-goi.flipped .domino-face-back` rule (line ~1138)
   sets position: relative + height: 100% + 1.4rem padding for the OLD
   in-place modal — when that rule applies to a tile in the grid (no
   in-place modal anymore), the back face becomes a flow child of
   .domino-inner, its content (.goi-word at 2.6rem etc.) stretches the
   .domino taller than its aspect-ratio target, and the whole grid row
   pushes outward (user-reported: "grid gets bigger and moves right").

   `display: none` removes the back face from layout entirely. JS still
   finds it via `block.node.querySelector('.domino-face-back')` (display
   doesn't remove from DOM), and `.innerHTML` is preserved — so the
   overlay clone source still works. */
body.game-page .grid-container .domino.flipped .domino-face-back {
  display: none !important;
}


/* ============================================================
   FURIGANA MASTER (goi/bunpou tiles + challenge inheritance)

   User feedback (2026-05-01): default furigana was hard to read
   even with reading glasses. The goi front-face was at 0.42em
   (~9.7px on a 1.45rem kanji) with positive letter-spacing —
   the goi-specific override at line ~1531 had accidentally
   widened the original ~0.64em + palt + negative-spacing rule.

   This block bumps every furigana <rt> across the app to a
   readable size and applies the right narrowing tools so the
   bigger glyphs still fit over a single kanji:
     - Sans-serif Japanese stack (Hiragino on macOS/iOS, Yu
       Gothic on Windows). Sans is more compact width-wise than
       serif and more legible at small sizes.
     - `font-feature-settings: "palt" 1` — Japanese proportional
       metrics. Shrinks per-character sidebearings so multi-kana
       readings (あたた over 暖) pack closer without distorting.
     - Negative letter-spacing for additional tightening.

   Vermilion accent on the closed-tile front face is preserved
   (the existing goi rule still sets color: var(--vermilion);
   we don't touch color here, just typography + size).

   Kanji standalone game (kanji/css/style.css) is unaffected —
   that fork doesn't load this sheet. Apply the same pattern
   when the kanji overhaul lands.

   Selectors are listed at the same specificity as the existing
   rules they're tuning, so source-order (this block at EOF) wins
   without needing !important.
   ============================================================ */
/* Note: Back-face Goi ruby typography (.goi-word rt, .goi-example-jp rt)
   moved to css/goi-back-face.css. The rules below cover front-face Goi
   ruby + Bunpou back-face ruby, both of which still live with this sheet. */
.domino.domino-goi .domino-face-front .domino-kanji rt,
.domino.domino-bunpou.flipped .bunpou-example-jp rt {
  font-family: 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', 'Noto Sans JP', sans-serif;
  font-weight: 500;
  letter-spacing: -0.05em;
  font-feature-settings: "palt" 1;
  line-height: 1;
}

/* Closed-tile front face — biggest readability win, was 0.42em (~9.7px). */
.domino.domino-goi .domino-face-front .domino-kanji rt {
  font-size: 0.58em;
}

/* Back-face Bunpou example-sentence ruby — was 0.45em, the example
   sentence ran tiny on iPhone. */
.domino.domino-bunpou.flipped .bunpou-example-jp rt {
  font-size: 0.6em;
}
