/* Crossword. */
.cw {
  --cw-accent: #ffd966;
  --cw-word: #d6e6fb;
  --cw-solved: #e2f2dc;
  --cw-solved-ink: #2f6a31;
  --cw-green: #3d7a3a;
  --cw-tag: #3b6fb3;
  --cw-ink: #1f2430;
  --cw-line: #4a4d57;
  /* Set here rather than inherited: a topic page centres everything its embedded game leaves unset. */
  position: relative; width: 100%; text-align: left;
}

/* The game sits on a pale sheet and its parts are white cards on it, so the page has layers:
   the header card, the clue bar and the board's card (one piece), the clue lists, and the
   toolbar. The colours are the game's own; nothing here moves. */
.game-root[data-game="crossword"] { background: var(--cw-sheet, #f3f6fb); }
/* Full screen and the page-filling panel put the cards on a deeper blue, the same family as the
   clue bar, so the white cards stand off it instead of melting into a white screen. */
.game-root[data-game="crossword"] { --cw-deep: radial-gradient(130% 100% at 50% 0%, #eaf2fd 0%, #d6e6fb 55%, #bfd5f2 100%); }
html.fills-window .game-root[data-game="crossword"]:not(.cw-fs), #game-root.cw-fs { background: var(--cw-deep); }
.cw { --cw-sheet: #f3f6fb; --cw-shadow: 0 1px 2px rgba(31, 36, 48, .06), 0 6px 18px rgba(40, 70, 120, .08); }

/* Everything round the board stays put from one puzzle to the next: the header, the clue bar,
   the clue lists and the buttons keep their places, and only the board grows or shrinks inside
   its card (.cw-stage). */
.cw-head { position: relative; margin: 0 0 12px; padding: 12px 18px 17px; border-radius: 16px; background: #fff; box-shadow: var(--cw-shadow); overflow: hidden; }
.cw-bar { display: flex; align-items: center; gap: 12px; margin: 0 0 10px; min-height: 44px; }
.cw-where { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; line-height: 1.2; }
/* One line each, cut short with an ellipsis: a long title must not make the row taller. */
.cw-name, .cw-step { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cw-name { font-weight: 900; font-size: 1.45rem; letter-spacing: -.005em; color: var(--c-text); }
.cw-step { margin-top: 2px; font-size: .82rem; font-weight: 600; color: var(--c-text-soft); }
.cw-step-count { display: none; }
.cw-count { flex: none; padding: 4px 11px; border-radius: 999px; background: var(--cw-solved); color: var(--cw-solved-ink); font-size: .82rem; font-weight: 800; white-space: nowrap; }
/* The puzzle's progress, along the header card's bottom edge. */
.cw-meter { position: absolute; left: 0; right: 0; bottom: 0; display: block; height: 5px; background: #e9eef5; }
.cw-meter-fill { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #7cc57a, var(--cw-green)); transition: width .6s cubic-bezier(.3, .8, .3, 1); }
.cw-pzs { display: flex; gap: 6px; flex: none; }
.cw-pz {
  display: grid; place-items: center; width: 36px; height: 36px; padding: 0;
  border: 0; border-radius: 50%; background: #eef3fa; color: var(--cw-tag); cursor: pointer;
}
.cw-pz:hover:not(:disabled) { background: #dfe9f7; }
.cw-pz:disabled { opacity: .35; cursor: default; }

/* The trail, as a stepper: a numbered dot for every warm-up, joined by a line that turns green
   as the puzzles are solved, then the open days. */
.cw-trail { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 22px; margin: 0; }
.cw-trail-group { display: flex; flex-wrap: wrap; align-items: center; gap: 0 10px; }
.cw-trail-h { margin-right: 4px; font-size: .7rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--c-text-soft); }
.cw-chip {
  position: relative; display: inline-grid; place-items: center; min-width: 30px; height: 30px; padding: 0 6px;
  border: 1.5px solid #cbd5e3; border-radius: 999px; background: #fff; color: #4a5568;
  font: inherit; font-size: .82rem; font-weight: 800; cursor: pointer;
}
.cw-chip + .cw-chip::before { content: ''; position: absolute; right: calc(100% + 1.5px); top: 50%; width: 10px; height: 2px; margin-top: -1px; background: #d5dce8; }
.cw-chip:hover { border-color: var(--cw-tag); }
.cw-chip.is-done { background: var(--cw-green); border-color: var(--cw-green); color: #fff; }
.cw-chip.is-done::before { background: var(--cw-green) !important; }
.cw-chip.is-now { background: var(--cw-tag); border-color: var(--cw-tag); color: #fff; box-shadow: 0 0 0 3px rgba(59, 111, 179, .22); }
.cw-chip-day { padding: 0 13px; }
.cw-ahead { margin: 6px 0 0; font-size: .88rem; font-weight: 600; color: var(--cw-tag); }

/* The clue lists sit beside the board's column only when the game is wide enough (crossword.js
   sets .cw-wide); otherwise the clue bar is the only clue shown. */
.cw-body { display: flex; flex-direction: column; }
.cw-main { display: flex; flex-direction: column; width: 100%; min-width: 0; }
.cw-lists { display: none; }
/* Each column is as tall as its own content, so a long list of clues cannot stretch the board's
   column (crossword.js measures the rows round the board to size its card). */
.cw-wide .cw-body { flex-direction: row; align-items: flex-start; gap: 16px; }
.cw-wide .cw-main { flex: 1 1 auto; width: auto; }
.cw-wide .cw-lists {
  display: block; flex: 0 0 292px; overflow-y: auto; overscroll-behavior: contain; padding: 16px 12px 26px;
  border-radius: 16px; background: #fff; box-shadow: var(--cw-shadow);
  /* The last clues fade out at the foot of the card, so a list that goes on reads as one. */
  -webkit-mask-image: linear-gradient(#000 calc(100% - 30px), transparent);
  mask-image: linear-gradient(#000 calc(100% - 30px), transparent);
}

/* The clue bar is the top of the board's card. Its height is fixed for two lines of clue and the
   row of squares below them (one for every letter of the answer), so a longer clue never moves
   the board. */
.cw-clue {
  display: flex; align-items: stretch; gap: 2px; height: 84px; overflow: hidden; margin: 0;
  border-radius: 16px 16px 0 0; background: #e3eefc; transition: background .3s ease;
}
.cw-clue.is-solved { background: var(--cw-solved); }
.cw-clue.is-coach { animation: cw-say-glow 1.6s ease-in-out infinite; }
.cw-clue-nav {
  flex: none; display: grid; place-items: center; width: 40px; padding: 0;
  border: 0; background: none; color: var(--cw-tag); cursor: pointer;
}
.cw-clue-nav:hover { background: rgba(59, 111, 179, .1); }
.cw-clue-nav .cw-icon { width: 1.3em; height: 1.3em; }
.cw-clue-t {
  display: flex; align-items: center; gap: 14px; flex: 1 1 auto; min-width: 0; padding: 8px 4px;
  border: 0; background: none; color: var(--c-text); cursor: pointer; text-align: left; font: inherit;
}
.cw-clue-badge {
  flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 60px; height: 58px; padding: 0 9px; box-sizing: border-box; border-radius: 14px; background: var(--cw-tag); color: #fff; line-height: 1;
  box-shadow: 0 3px 0 rgba(30, 60, 110, .25);
}
.cw-badge-n { font-size: 1.55rem; font-weight: 900; }
.cw-badge-d { display: flex; align-items: center; gap: 2px; margin-top: 4px; font-size: .58rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
.cw-badge-d .cw-icon { width: 1em; height: 1em; stroke-width: 2.6; }
.cw-clue.is-solved .cw-clue-badge { background: var(--cw-green); box-shadow: 0 3px 0 rgba(30, 80, 30, .25); }
.cw-clue-body { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.cw-clue-text {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  font-size: 1.22rem; font-weight: 700; line-height: 1.25;
}
.cw-pips { display: flex; gap: 4px; }
.cw-pip { width: 18px; height: 8px; border-radius: 3px; background: #fff; box-shadow: inset 0 0 0 1px #b6c7de; }
.cw-pip.on { background: #9dbbe6; box-shadow: none; }
.cw-pip.solved { background: var(--cw-green); box-shadow: none; }
/* Used by the intro's little grid. */
.cw-clue-tag {
  flex: none; padding: 3px 8px; border-radius: 7px; background: var(--cw-tag); color: #fff;
  font-size: .74rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
}

/* One line on a computer and two on a phone, fixed: a line longer than that is cut, so what is
   said never moves the board. */
.cw-say {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0 4px; height: 1.9em; overflow: hidden; margin: 6px 0 0; padding: 2px 6px;
  font-size: .88rem; line-height: 1.3; color: var(--c-text-soft); text-align: center;
}
.cw-say.is-coach { color: var(--c-text); font-weight: 650; }
@keyframes cw-say-glow {
  0%, 100% { box-shadow: 0 0 0 2px rgba(255, 190, 50, .35); }
  50% { box-shadow: 0 0 0 3px rgba(255, 190, 50, .95); }
}

/* The board: tiles whose size and gap crossword.js sets (--cell). Only squares that hold a
   letter exist; the rest of the grid is empty space. */
/* The board's box: the same for every puzzle (its height is set by crossword.js on the page and
   by the panel when the game fills it). The board sits at its top, under the clue bar, with the
   box's padding as room for the tiles' shadows (HEDGE in crossword.js). */
.cw-stage {
  position: relative; width: 100%; box-sizing: border-box; padding: 14px; display: grid; place-items: start center;
  border-radius: 0 0 16px 16px; box-shadow: var(--cw-shadow);
  /* Graph paper, a pale blue-grey with a dot at every corner, so the room the board leaves reads
     as paper and the white tiles stand off it. */
  background: #edf2fa radial-gradient(circle, #c3d0e3 1.1px, transparent 1.5px) 0 0 / 22px 22px;
}
.cw-fx { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 3; pointer-events: none; }
.cw-fx.cw-party { z-index: 40; border-radius: inherit; }
.cw-board {
  display: grid; --cell: 40px; perspective: 800px;
  touch-action: manipulation; user-select: none; -webkit-user-select: none;
}
.cw-cell {
  position: relative; display: grid; place-items: center; min-width: 0; min-height: 0;
  border-radius: 14%; color: var(--cw-ink); background: #fff;
  box-shadow: 0 0 0 1px var(--cw-line), 0 3px 0 rgba(74, 77, 87, .28);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color .15s ease, transform .15s ease;
}
/* The letter sits a little low so the clue's number, in the corner, never runs into it. */
.cw-ch { font-size: calc(var(--cell) * .54); font-weight: 800; line-height: 1; color: inherit; transform: translateY(7%); }
.cw-num {
  position: absolute; top: 2px; left: 4px; pointer-events: none;
  font-size: max(8px, calc(var(--cell) * .21)); font-weight: 700; line-height: 1; color: #6b7280;
}
/* The ring is ::before because ::after already carries the shown-letter dot. */
.cw-cell.is-mark::before {
  content: ''; position: absolute; inset: 15%; border-radius: 50%; border: 2px solid #c99a1c; pointer-events: none;
}
.cw-mark-n {
  position: absolute; right: 3px; bottom: 2px; pointer-events: none;
  font-size: max(8px, calc(var(--cell) * .2)); font-weight: 800; line-height: 1; color: #a87a00;
}
.cw-cell.is-solved { background: var(--cw-solved); color: var(--cw-solved-ink); }
.cw-cell.is-word { background: var(--cw-word); }
.cw-cell.is-word.is-solved { background: #cde6c4; }
.cw-cell.is-cur { z-index: 1; background: var(--cw-accent); transform: translateY(-2px); }
.cw-cell.is-bad { color: #d23c3c; }
.cw-cell.is-shown:not(.is-solved) { color: #2f6fb3; }
/* A shown letter keeps a small blue mark in its corner, so it can be told from a typed one. */
.cw-cell.is-shown::after {
  content: ''; position: absolute; right: 3px; top: 3px; width: calc(var(--cell) * .15); height: calc(var(--cell) * .15);
  border-radius: 50%; background: #7fa7d8; pointer-events: none;
}
.cw-cell.is-coach { animation: cw-halo 1.6s ease-in-out infinite; }
@keyframes cw-halo {
  0%, 100% { box-shadow: 0 0 0 1px var(--cw-line), 0 3px 0 rgba(74, 77, 87, .28), inset 0 0 0 2px rgba(255, 176, 30, .55); }
  50% { box-shadow: 0 0 0 1px var(--cw-line), 0 3px 0 rgba(74, 77, 87, .28), inset 0 0 0 4px rgba(255, 176, 30, .95); }
}

/* A word solved: its tiles turn over one after another (--k: the tile's place in the word) and
   come face up solved. FLIP_MS and FLIP_STEP in crossword.js match these. */
.cw-cell.cw-flip { animation: cw-flip .52s cubic-bezier(.4, .1, .3, 1) calc(var(--k, 0) * 90ms) both; }
@keyframes cw-flip {
  0% { transform: rotateX(0); color: var(--cw-ink); background-color: var(--cw-word); }
  49.9% { transform: rotateX(90deg); color: var(--cw-ink); background-color: var(--cw-word); }
  50% { transform: rotateX(90deg); color: var(--cw-solved-ink); background-color: var(--cw-solved); }
  100% { transform: rotateX(0); color: var(--cw-solved-ink); background-color: var(--cw-solved); }
}
/* A tile an earlier word already turned over only bounces. */
.cw-cell.cw-bounce { animation: cw-bounce .45s cubic-bezier(.3, .7, .4, 1) calc(var(--k, 0) * 90ms) both; }
@keyframes cw-bounce { 45% { transform: translateY(-12%); } }
.cw-cell.cw-shake { animation: cw-shake .42s ease both; }
@keyframes cw-shake {
  20% { transform: translateX(-3px); } 40% { transform: translateX(3px); }
  60% { transform: translateX(-2px); } 80% { transform: translateX(2px); }
}
.cw-cell.cw-reveal .cw-ch { animation: cw-pop .4s cubic-bezier(.2, 1.6, .4, 1) both; }
@keyframes cw-pop { from { transform: scale(.3); opacity: 0; } }
/* The puzzle solved: a wave runs across the grid from its top-left corner (--i: row + column). */
.cw-done .cw-cell { animation: cw-wave .75s ease calc(var(--i, 0) * 45ms) both; }
@keyframes cw-wave {
  35% { transform: translateY(-16%) scale(1.08); background-color: #fff1a8; }
  100% { transform: none; }
}
.cw-note-fly {
  position: absolute; z-index: 3; width: 18px; height: 22px; color: var(--cw-tag); pointer-events: none;
  animation: cw-note-fly 1.5s ease-out both;
}
@keyframes cw-note-fly {
  0% { opacity: 0; transform: translate(0, 0) scale(.6); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx, 0px), -52px) scale(1.1) rotate(var(--rot, 0deg)); }
}

/* The on-screen keyboard: only on a device whose main pointer is a finger. */
.cw-kbd { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 0; touch-action: manipulation; user-select: none; -webkit-user-select: none; }
.cw-kbd-row { display: flex; justify-content: center; gap: 5px; }
.cw-key {
  flex: 1 1 0; max-width: 44px; height: 46px; padding: 0;
  border: 0; border-radius: 8px; background: #eceff4; box-shadow: 0 2px 0 #c7ccd6;
  color: var(--c-text); font: inherit; font-size: 1.05rem; font-weight: 700; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.cw-key-back { flex: 1.5 1 0; max-width: 66px; display: grid; place-items: center; }
.cw-key-back .cw-icon { width: 1.4em; height: 1.4em; }
.cw-key.is-hit { animation: cw-key .18s ease; }
@keyframes cw-key { 40% { transform: translateY(2px); background: #dbe2ee; box-shadow: 0 0 0 #c7ccd6; } }

.cw-list + .cw-list { margin-top: 18px; }
.cw .cw-list-h {
  display: flex; align-items: center; gap: 6px; margin: 0 0 6px 8px; font-size: .76rem; font-weight: 900;
  letter-spacing: .09em; text-transform: uppercase; color: var(--cw-tag);
}
.cw-list-h .cw-icon { width: 1.2em; height: 1.2em; stroke-width: 2.6; }
.cw-list ol { list-style: none; margin: 0; padding: 0; }
.cw-item {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; margin: 1px 0; padding: 7px 8px; border: 0; border-radius: 10px;
  background: none; color: var(--c-text); cursor: pointer; text-align: left;
  font: inherit; font-size: .92rem; line-height: 1.35;
}
.cw-item:hover { background: #f1f5fb; }
.cw-item-n {
  flex: none; display: grid; place-items: center; min-width: 26px; height: 26px; margin-top: -1px; padding: 0 4px;
  border-radius: 8px; background: #e3eefc; color: var(--cw-tag); font-size: .8rem; font-weight: 900;
}
.cw-item-t { flex: 1 1 auto; min-width: 0; }
.cw-item-ok { display: none; flex: none; color: var(--cw-green); }
.cw-item-ok .cw-icon { width: 1.15em; height: 1.15em; stroke-width: 3; }
.cw-list li.is-now .cw-item { background: var(--cw-word); box-shadow: inset 3px 0 0 var(--cw-tag); }
.cw-list li.is-solved .cw-item { color: var(--c-text-soft); }
.cw-list li.is-solved .cw-item-n { background: var(--cw-solved); color: var(--cw-solved-ink); }
.cw-list li.is-solved .cw-item-ok { display: block; }

/* The toolbar: one rounded bar under the board, Hint, Music, Sounds, Full screen and Settings in it. */
.cw-controls {
  display: flex; align-self: center; gap: 2px; margin: 12px 0 0; padding: 5px;
  border-radius: 999px; background: #fff; box-shadow: var(--cw-shadow);
}
.cw-ctl {
  display: inline-flex; align-items: center; gap: 7px; padding: 8px 15px; border-radius: 999px;
  border: 0; background: none; color: var(--c-text); cursor: pointer;
  font: inherit; font-size: .88rem; font-weight: 700; white-space: nowrap;
}
.cw-ctl + .cw-ctl { box-shadow: -1px 0 0 #e6ebf2; }
.cw-ctl:hover { background: #eef3fa; }
.cw-ctl:disabled { opacity: .45; cursor: default; }
.cw-ctl:disabled:hover { background: none; }
.cw-toggle[aria-pressed="false"] { color: var(--c-text-soft); }
.cw-icon { width: 1.1em; height: 1.1em; flex: none; }
.cw-badge {
  display: inline-grid; place-items: center; min-width: 1.4em; height: 1.4em; padding: 0 .3em;
  border-radius: 999px; background: var(--cw-tag); color: #fff; font-size: .75em; font-weight: 800; line-height: 1;
}
.cw-ctl.is-out { color: var(--c-text-soft); }
.cw-ctl.is-out .cw-badge { background: #9aa3ad; }
.cw-say-btn {
  margin-left: 4px; padding: 3px 10px; border: 1px solid var(--c-border); border-radius: 999px;
  background: var(--c-surface); color: var(--c-text); cursor: pointer;
  font: inherit; font-size: .85rem; font-weight: 700;
}
.cw-say-btn:hover { background: var(--c-bg); }
.cw-switch {
  position: relative; flex: none; width: 26px; height: 15px; border-radius: 999px;
  background: #cdd3dc; transition: background .2s ease;
}
.cw-switch::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 11px; height: 11px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); transition: transform .2s ease;
}
.cw-toggle[aria-pressed="true"] .cw-switch { background: var(--cw-tag); }
.cw-toggle[aria-pressed="true"] .cw-switch::after { transform: translateX(11px); }

/* Settings: a card over the whole game, on the same dimmed backdrop as the result card. */
.cw-set {
  position: absolute; inset: 0; z-index: 35; display: flex; align-items: center; justify-content: center; padding: 12px;
  border-radius: inherit; background: rgba(243, 246, 251, .72); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  animation: cw-fade .25s ease both;
}
.cw-set-card {
  position: relative; width: min(440px, 100%); max-height: 100%; overflow-y: auto; box-sizing: border-box; padding: 20px 22px 16px;
  border-radius: 22px; background: #fff; box-shadow: 0 2px 4px rgba(28, 36, 50, .08), 0 22px 60px rgba(28, 36, 50, .28);
  animation: cw-win-in .35s cubic-bezier(.2, .9, .3, 1.15);
}
.cw-set-title { margin: 0; padding-right: 40px; font-size: 1.3rem; font-weight: 900; color: var(--cw-ink); }
.cw-set-sec { margin-top: 16px; }
.cw-set-sec h4 { margin: 0 0 4px; font-size: .74rem; font-weight: 900; letter-spacing: .08em; text-transform: uppercase; color: var(--cw-tag); }
.cw-set-sec p { margin: 0 0 8px; font-size: .88rem; line-height: 1.45; color: var(--c-text-soft); }
.cw-set-row { display: flex; gap: 8px; }
/* 16px at least: a smaller field makes iOS zoom the page when it takes focus. */
.cw-code {
  flex: 1 1 auto; min-width: 0; box-sizing: border-box; padding: 9px 12px; border: 1.5px solid #d5dfee; border-radius: 12px;
  background: #f3f6fb; color: var(--cw-ink); font: 700 1rem/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.cw-code:focus { outline: none; border-color: var(--cw-tag); background: #fff; }
.cw-code::placeholder { font-family: inherit; font-weight: 600; color: #9aa6b6; }
.cw-set-btn {
  flex: none; padding: 9px 16px; border: 1.5px solid #d5dfee; border-radius: 12px; background: #fff; color: var(--c-text);
  font: inherit; font-size: .88rem; font-weight: 800; cursor: pointer;
}
.cw-set-btn:hover { border-color: var(--cw-tag); background: #f5f9ff; }
.cw-set-btn:disabled { opacity: .5; cursor: default; }
.cw-set-note { min-height: 1.3em; margin: 12px 0 0; font-size: .88rem; font-weight: 700; color: var(--cw-green); }
.cw-set-note.is-bad { color: #c0392b; }

/* The first visit's intro: a little grid that plays itself, over the whole game. */
.cw-intro {
  position: absolute; inset: 0; z-index: 20; display: flex; align-items: center; justify-content: center; padding: 10px;
  border-radius: 12px; background: rgba(246, 243, 236, .8);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  animation: cw-fade .3s ease both;
}
.cw-intro.is-out { animation: cw-fade .3s ease reverse both; }
@keyframes cw-fade { from { opacity: 0; } }
.cw-intro-card {
  width: min(440px, 100%); max-height: 100%; overflow-y: auto; padding: 12px 18px 18px;
  border-radius: 16px; background: #fff; box-shadow: 0 14px 40px rgba(28, 36, 50, .22); text-align: center;
}
.cw-intro-top { display: flex; align-items: center; justify-content: space-between; margin: 0 0 6px; }
.cw-intro-kicker { font-size: .78rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--cw-tag); }
.cw-intro-skip {
  padding: 4px 10px; border: 0; border-radius: 8px; background: none; color: var(--c-text-soft); cursor: pointer;
  font: inherit; font-size: .85rem; font-weight: 700;
}
.cw-intro-skip:hover { background: var(--c-bg); color: var(--c-text); }
.cw-demo { position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.cw-demo-clue {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 44px; padding: 4px 10px;
  border-radius: 10px; background: #e3eefc; font-size: .9rem; line-height: 1.25; text-align: left;
  visibility: hidden; transition: background .3s ease;
}
.cw-demo-clue.on { visibility: visible; }
.cw-demo-clue.is-solved { background: var(--cw-solved); }
.cw-demo-clue.is-solved .cw-clue-tag { background: var(--cw-green); }
.cw-demo-row { position: relative; display: flex; align-items: center; justify-content: center; gap: 22px; }
.cw-demo-board { position: relative; gap: 3px; }
.cw-demo-board .cw-cell { cursor: default; }
/* Only until the tile's own flip or the grid's wave takes the animation over. */
.cw-demo-board:not(.cw-done) .cw-cell:not(.cw-flip) { animation: cw-arrive .45s ease-out calc(var(--i, 0) * 60ms) both; }
@keyframes cw-arrive { from { opacity: 0; transform: scale(.5); } }
.cw-demo-hint {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--c-border); background: var(--c-surface); color: var(--c-text);
  font-size: .85rem; font-weight: 600;
}
.cw-demo-hint.cw-demo-tap { animation: cw-key .3s ease; }
/* Where the hand taps, a ring opens. On ::before: a shown letter's mark uses ::after. */
.cw-cell.cw-demo-tap::before {
  content: ''; position: absolute; inset: -7px; z-index: 2; border-radius: 50%; pointer-events: none;
  border: 3px solid rgba(255, 176, 30, .9); animation: cw-ripple .5s ease-out both;
}
@keyframes cw-ripple { from { transform: scale(.4); opacity: 1; } to { transform: scale(1.25); opacity: 0; } }
.cw-demo-hand {
  position: absolute; left: 0; top: 0; z-index: 4; width: 34px; height: 34px; overflow: visible; pointer-events: none;
  opacity: 0; filter: drop-shadow(0 3px 3px rgba(0, 0, 0, .25));
  transition: transform .55s cubic-bezier(.4, .1, .3, 1), opacity .3s ease;
}
.cw-demo-hand.on { opacity: 1; }
.cw-demo-hand path { transform-box: fill-box; transform-origin: 30% 10%; }
.cw-demo-hand.is-tap path { animation: cw-hand-tap .35s ease; }
@keyframes cw-hand-tap { 45% { transform: scale(.82) translateY(6%); } }
.cw-intro-say { min-height: 3.9em; margin: 10px 0 0; font-size: .98rem; font-weight: 600; line-height: 1.3; color: var(--c-text); }
.cw-intro-dots { display: flex; justify-content: center; gap: 7px; margin: 8px 0 0; min-height: 42px; align-items: center; }
.cw-intro-dots[hidden] { display: none; }
.cw-intro-dot { width: 8px; height: 8px; border-radius: 50%; background: #d4dae3; transition: background .3s ease, transform .3s ease; }
.cw-intro-dot.on { background: var(--cw-tag); transform: scale(1.15); }
.cw-intro-go {
  display: inline-flex; align-items: center; gap: 6px; margin: 8px 0 0; padding: 10px 22px; border: 0; border-radius: 999px;
  background: var(--cw-tag); color: #fff; box-shadow: 0 4px 12px rgba(40, 90, 160, .3); cursor: pointer;
  font: inherit; font-size: .98rem; font-weight: 700; animation: cw-pop .45s cubic-bezier(.2, 1.6, .4, 1) both;
}
.cw-intro-go:hover { background: #33619d; }
.cw-intro-go[hidden] { display: none; }
.cw-kbd-key {
  display: inline-block; min-width: 1.6em; padding: 1px 6px; margin: 0 1px;
  border: 1px solid #c9ced8; border-bottom-width: 2px; border-radius: 5px; background: #fff;
  font: inherit; font-size: .85em; font-weight: 700; line-height: 1.4; text-align: center; color: var(--c-text);
}

/* A puzzle's result covers the whole game: the game behind it dims and waits, and the card, with
   a medal at its head, is the moment. Closing it gives back the finished board. */
.cw-win { position: absolute; inset: 0; z-index: 30; display: flex; align-items: center; justify-content: center; padding: 12px; border-radius: inherit; pointer-events: none; }
.cw-win:empty { display: none; }
.cw-win.is-open { background: rgba(243, 246, 251, .72); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); pointer-events: auto; animation: cw-fade .3s ease both; }
.cw-win-card {
  position: relative; pointer-events: auto; width: min(460px, 100%); max-height: 100%; overflow-y: auto;
  padding: 0 0 20px; border-radius: 22px; background: #fff;
  box-shadow: 0 2px 4px rgba(28, 36, 50, .08), 0 22px 60px rgba(28, 36, 50, .28);
  text-align: center;
  animation: cw-win-in .45s cubic-bezier(.2, .9, .3, 1.15);
}
@keyframes cw-win-in { from { opacity: 0; transform: translateY(18px) scale(.96); } }
.cw-win-card .result-card { display: flex; flex-direction: column; align-items: center; margin: 0; padding: 0; background: none; border: 0; box-shadow: none; }
.cw-win-card .result-card > * { max-width: calc(100% - 40px); }
.cw-win-card .result-card > .cw-medal-wrap { max-width: none; }
/* The head of the card: a soft green glow behind the medal. */
.cw-medal-wrap { width: 100%; padding: 24px 0 8px; background: radial-gradient(90% 100% at 50% 0%, #d7edcf 0%, #edf7e9 55%, #fff 100%); }
.cw-medal { display: block; width: 104px; height: 104px; margin: 0 auto; overflow: visible; filter: drop-shadow(0 6px 10px rgba(50, 90, 40, .28)); animation: cw-medal-in .7s cubic-bezier(.2, 1.5, .4, 1) both; }
@keyframes cw-medal-in { from { transform: scale(.3) rotate(-16deg); opacity: 0; } }
.cw-spark { transform-box: fill-box; transform-origin: center; animation: cw-spark 1s ease-out both; }
@keyframes cw-spark { 0% { transform: scale(0) rotate(-40deg); opacity: 0; } 55% { transform: scale(1.35) rotate(0); opacity: 1; } 100% { transform: scale(1); opacity: .95; } }
.cw-kicker { margin: 4px 0 0; font-size: .76rem; font-weight: 900; letter-spacing: .09em; text-transform: uppercase; color: var(--cw-green); }
.cw-win-name { margin: 4px 0 2px; font-size: 1.65rem; font-weight: 900; line-height: 1.15; letter-spacing: -.005em; color: var(--cw-ink); }
.cw-line { margin: 0; font-size: .97rem; font-style: italic; color: var(--c-text-soft); }
.cw-spell { margin: 14px 0 0; }
.cw-spell-h { margin: 0 0 8px; font-size: .68rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--c-text-soft); }
.cw-spell-word { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; }
.cw-spell-w { display: inline-flex; gap: 4px; }
.cw-spell-tile {
  display: grid; place-items: center; width: 30px; height: 36px; border-radius: 8px; background: #fff;
  font-size: 1.15rem; font-weight: 900; color: var(--cw-ink);
  box-shadow: 0 0 0 1.5px #c99a1c, 0 2px 0 rgba(74, 77, 87, .25);
  animation: cw-spell-in .4s cubic-bezier(.2, 1.5, .4, 1) calc(var(--k, 0) * 110ms + 350ms) both;
}
@keyframes cw-spell-in { from { transform: translateY(8px) scale(.6); opacity: 0; } }
.cw-stats { display: flex; gap: 8px; width: calc(100% - 40px); margin: 14px 0 0; }
.cw-stat { flex: 1 1 0; padding: 9px 6px; border-radius: 12px; background: #f3f6fb; }
.cw-stat-v { display: block; font-size: 1.3rem; font-weight: 900; line-height: 1.15; color: var(--cw-ink); }
.cw-stat-l { display: block; margin-top: 2px; font-size: .68rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--c-text-soft); }
.cw-feel { margin: 16px 0 0; font-size: .92rem; font-weight: 800; }
.cw-moods { display: flex; justify-content: center; gap: 10px; margin: 8px 0 0; }
.cw-mood {
  display: inline-flex; flex-direction: column; align-items: center; gap: 3px; min-width: 78px; padding: 7px 8px;
  border: 1.5px solid #d5dfee; border-radius: 14px; background: #fff; color: var(--c-text-soft);
  font: inherit; font-size: .8rem; font-weight: 700; cursor: pointer;
}
.cw-mood .cw-icon { width: 30px; height: 30px; }
.cw-mood:hover { color: var(--c-text); border-color: var(--cw-tag); }
.cw-mood.on { color: var(--cw-tag); border-color: var(--cw-tag); background: #eef4fc; }
.cw-note { display: block; min-height: 1.3em; margin: 6px 0 0; font-size: .85rem; color: var(--c-text-soft); }
/* Favorite, Share and the way on carry the same weight, so they are the same tile. */
.cw-acts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; width: calc(100% - 40px); margin: 6px 0 0; }
.cw-acts.two { grid-template-columns: repeat(2, 1fr); }
.cw-act {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; min-height: 78px; padding: 10px 6px;
  border: 1.5px solid #d5dfee; border-radius: 16px; background: #fff; color: var(--c-text); cursor: pointer;
  font: inherit; font-size: .85rem; font-weight: 800; line-height: 1.2; text-align: center;
}
.cw-act .cw-icon { width: 24px; height: 24px; color: var(--cw-tag); }
.cw-act-sub { margin-top: -4px; font-size: .72rem; font-weight: 700; color: var(--c-text-soft); white-space: nowrap; }
.cw-act:hover { border-color: var(--cw-tag); background: #f5f9ff; }
.cw-act.on { border-color: #efb3c3; background: #fff5f8; color: #d6456b; }
.cw-act.on .cw-icon { color: #d6456b; }
.cw-win-close {
  position: absolute; top: 10px; right: 10px; z-index: 2; padding: 7px; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .8); color: var(--c-text-soft); font: inherit; line-height: 1; cursor: pointer;
}
.cw-win-close .cw-icon { width: 1.1rem; height: 1.1rem; }
.cw-win-close:hover { background: #fff; color: var(--c-text); }
.cw-win-reopen {
  pointer-events: auto; padding: 8px 16px; border-radius: 999px;
  border: 1px solid var(--c-border); background: rgba(255, 255, 255, .94); color: var(--c-text);
  font: inherit; font-size: .85rem; font-weight: 700; cursor: pointer; box-shadow: 0 4px 14px rgba(28, 32, 50, .18);
}

@media (max-width: 640px) {
  .game-root[data-game="crossword"] { padding: 10px 8px 12px; }
  .cw-head { margin-bottom: 10px; padding: 10px 12px 15px; }
  /* One row that scrolls sideways: wrapped, the trail takes three rows from the board. It fades
     out at the right edge so a row cut short reads as one that goes on. */
  .cw-trail {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent);
    mask-image: linear-gradient(90deg, #000 88%, transparent);
  }
  .cw-trail::-webkit-scrollbar { display: none; }
  .cw-trail-group { flex-wrap: nowrap; flex: none; }
  /* The title gets the row: the words count moves up beside the puzzle's place in the run. */
  .cw-bar { min-height: 40px; margin-bottom: 8px; }
  .cw-name { font-size: 1.15rem; }
  .cw-count { display: none; }
  .cw-step-count { display: inline; }
  .cw-say { height: 2.9em; }
  .cw-clue { height: 78px; }
  .cw-clue-t { gap: 10px; padding: 6px 2px; }
  .cw-clue-badge { width: 48px; height: 48px; border-radius: 12px; }
  .cw-badge-n { font-size: 1.3rem; }
  .cw-clue-text { font-size: 1rem; }
  .cw-pip { width: 14px; height: 7px; }
  .cw-clue-nav { width: 32px; }
  .cw-stage { padding: 10px; }
}
/* The toolbar on one row at phone width: Music, Sounds and Settings are their icons alone (the
   toggles' icons show their state), and the buttons close up. Full screen keeps its words. */
@media (max-width: 520px) {
  .cw-controls { gap: 0; padding: 4px; }
  .cw-ctl { gap: 5px; padding: 8px 9px; font-size: .8rem; }
  .cw-switch, .cw-toggle .cw-ctl-label, .cw-ctl-set span { display: none; }
}

/* Inside the page-filling panel and in full screen the game is the panel's height and the
   board's box takes whatever the other rows leave; crossword.js fits the board to the box. */
html.fills-window .game-root:not(.cw-fs) .cw, .cw-fs .cw { display: flex; flex-direction: column; height: 100%; padding-top: 12px; padding-bottom: 10px; }
html.fills-window .game-root:not(.cw-fs) .cw > :not(.cw-body), .cw-fs .cw > :not(.cw-body) { flex: none; }
html.fills-window .game-root:not(.cw-fs) .cw-body, .cw-fs .cw-body { flex: 1 1 0; min-height: 0; }
html.fills-window .game-root:not(.cw-fs) .cw-wide .cw-body, .cw-fs .cw-wide .cw-body { align-items: stretch; }
html.fills-window .game-root:not(.cw-fs) .cw-main > :not(.cw-stage), .cw-fs .cw-main > :not(.cw-stage) { flex: none; }
html.fills-window .game-root:not(.cw-fs) .cw-stage, .cw-fs .cw-stage { flex: 1 1 0; min-height: 0; }

/* #game-root is itself the element that goes full screen; these same rules are the
   fixed-position fallback for a browser without the Fullscreen API. game-layout.css gives a
   [data-fill] panel an explicit width and height, which would beat the fallback's inset. */
#game-root.cw-fs {
  position: fixed; inset: 0; z-index: 200; margin: 0; padding: 12px 16px 14px;
  width: auto; height: auto; min-height: 0; overflow: hidden;
  border: 0; border-radius: 0; box-shadow: none;
}
.cw-fs .cw { max-width: 1400px; margin: 0 auto; }
body.cw-locked { overflow: hidden; }
