/* Word Derby — one hand-written stylesheet.

   Everything is sized in rem so browser zoom scales the whole interface. The
   play screen keeps one complete square that grows with a tall window up to a
   bounded cap. Phones can enlarge the board and pan for precise placement. */

/* Fredoka, self-hosted from the Google Fonts repository.
   SIL Open Font License 1.1: fonts/Fredoka-OFL.txt. */
@font-face {
  font-family: "Fredoka";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/assets/fonts/fredoka-variable-fae8641b.ttf") format("truetype");
}

:root {
  --site-max: 70rem;
  --button-bevel: inset 0 2px 0 #ffffff99, inset 0 -2px 0 #00000018, 0 3px 0 #0000002b, 0 5px 8px #200e301c;
  --cream: #fff8e5;
  --cream-deep: #f5e6bd;
  --paper: #fffdf7;
  --ink: #200e30;
  --ink-soft: #615466;
  --plum: #372044;
  --plum-deep: #200e30;
  --teal: #2c7a22;
  --teal-soft: #e8f2df;
  --coral: #b8452f;
  --coral-deep: #9c3823;
  --coral-soft: #fbdfd6;
  --lavender: #67527e;
  --lavender-soft: #eee6f3;
  --gold: #8c5d0e;
  --gold-soft: #fff0bd;
  --gold-bright: #ffcb14;
  --green-deep: #206019;
  --tile-face: #fff9e8;
  --tile-edge: #d9bd79;
  --line: #e3d4ad;
  --font-friendly: "Fredoka", ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, sans-serif;

  --radius-lg: 18px;
  --radius: 12px;
  --radius-sm: 8px;

  --shadow-sm: 0 1px 2px rgba(59, 42, 69, 0.12);
  --shadow-md: 0 4px 12px rgba(59, 42, 69, 0.14);
  --shadow-tile: 0 2px 0 var(--tile-edge), 0 3px 6px rgba(59, 42, 69, 0.14);

  --tile: 3.3rem;
}

html {
  font-size: 17px;
}


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

body {
  margin: 0;
  background-color: var(--cream);
  background-image: linear-gradient(180deg, var(--paper) 0%, var(--cream) 100%);
  background-repeat: no-repeat;
  color: var(--ink);
  font-family: var(--font-friendly);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-weight: 600;
  margin: 0;
  line-height: 1.25;
}

b, strong { font-weight: 500; }

.avatar-icon { display: block; width: 70%; height: 70%; object-fit: contain; }

p {
  margin: 0;
}

ul,
ol,
dl,
dd {
  margin: 0;
}

code {
  background: var(--cream-deep);
  border-radius: 6px;
  padding: 0.1em 0.35em;
}

:focus-visible {
  outline: 3px solid var(--teal);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--plum-deep);
  color: #fff;
  padding: 0.6rem 1rem;
  z-index: 100;
}

.skip-link:focus {
  left: 0.5rem;
  top: 0.5rem;
}

/* primitives: shared heading, buttons, fields, icons, and helpers. */

.section-heading {
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  margin-bottom: 0.6rem;
}

/* ----------------------------------------------------------------- buttons */

.button {
  appearance: none;
  box-shadow: var(--button-bevel);
  font: inherit;
  font-weight: 500;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.6rem 1.05rem;
  min-height: 2.85rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  cursor: pointer;
  text-decoration: none;
  transition: transform 120ms ease, box-shadow 120ms ease, background-color 120ms ease;
}

.button:hover:not(:disabled) {
  box-shadow: var(--button-bevel), var(--shadow-md);
  transform: translateY(-1px);
}

.button:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: var(--shadow-sm);
}

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

.button--primary {
  background: var(--teal);
  border-color: var(--green-deep);
  color: #fff;
}

.button--secondary {
  background: var(--paper);
  border-color: var(--line);
  color: var(--ink);
}

.button--danger {
  background: var(--coral);
  border-color: var(--coral-deep);
  color: #fff;
}

.button--quiet {
  box-shadow: none;
  background: transparent;
  border-color: transparent;
  color: var(--plum);
  min-height: 2.3rem;
  padding: 0.35rem 0.6rem;
}

.button--quiet:hover:not(:disabled) {
  background: var(--cream-deep);
  box-shadow: none;
}

.button--wide {
  width: 100%;
}

.button--letter {
  background: var(--paper);
  border-color: var(--line);
  min-height: 2.9rem;
  min-width: 2.9rem;
  padding: 0.4rem;
  font-size: 1.1rem;
}

.button--play {
  background: var(--coral);
  border-color: var(--coral-deep);
  color: #fff;
  font-size: 1.2rem;
  padding: 0.9rem 1.6rem;
  min-height: 3.6rem;
  width: 100%;
  max-width: 28rem;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.icon {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: 0 0 auto;
}

.field {
  display: grid;
  gap: 0.35rem;
}

.field__label {
  font-weight: 500;
  color: var(--ink-soft);
}

.input {
  font: inherit;
  padding: 0.65rem 0.8rem;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--paper);
  min-height: 2.85rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ui icons: the few reused decorative glyphs, sized in rem and inert to the
   pointer so a glyph never steals a tap from the control it sits in. */

.ui-icon {
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
  display: block;
  color: inherit;
  pointer-events: none;
}
i.ui-icon { font-size: 1.15rem; line-height: 1; text-align: center; }

/* header: the site header shell and brand, the lobby/board/onboarding header
   variants, the signed-in nav row, the account panel, and notifications. */

.site-header {
  position: relative;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.site-header__inner,
.site-main,
.site-footer {
  width: min(100%, var(--site-max));
}

.site-header__inner {
  max-width: var(--site-max);
  margin: 0 auto;
  padding: 0.85rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  color: var(--plum-deep);
}

.brand__art {
  position: relative;
  display: block;
  width: 220px;
  aspect-ratio: 943 / 881;
  overflow: hidden;
  flex: none;
}

/* Frame the actual artwork, excluding the PNG's transparent outer margins. */
.brand__logo {
  position: absolute;
  width: 153.5525%;
  height: auto;
  max-width: none;
  left: -26.8293%;
  top: -9.8751%;
  display: block;
}


.site-main {
  max-width: var(--site-max);
  margin: 0 auto;
  padding: 1.5rem 1.5rem 3rem;
}

.site-footer {
  max-width: var(--site-max);
  margin: 0 auto;
  padding: 0 1.5rem 2.5rem;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

:is(.home-page, .game-page) .site-header { background: transparent; }

.onboarding .site-header {
  background: transparent;
  border-bottom-color: #eadcc4;
}

.onboarding .site-header__inner {
  max-width: 58rem;
}

.onboarding--entry .site-header { border: 0; }
.onboarding--entry .site-header__inner {
  justify-content: center;
  padding: 2.4rem 1rem 1.6rem;
}
.onboarding--entry .brand { gap: 1.25rem; }
.onboarding--entry .brand__art { width: 340px; }

@media (max-width: 600px) {
  .onboarding .site-header__inner { padding-inline: 1rem; }
  .onboarding--entry .site-header__inner { padding-block: 1.5rem 0.75rem; }
  .onboarding--entry .brand { gap: 0.65rem; }
  .onboarding--entry .brand__art { width: 260px; }
}

/* The signed-in header is the same chrome in the lobby and on the board. */

/* Shared page width; the lobby keeps its own responsive gutters. */
:is(.home-page, .game-page) .site-header__inner { max-width: var(--site-max); gap: 1rem; padding: 0.9rem var(--lobby-gutter, 1.5rem); }
:is(.home-page, .game-page) .brand { color: #200e30; }
:is(.home-page, .game-page) .button--quiet { min-height: 44px; }

/* Notification menu overlays header instead of changing header height. */
.notification-menu { position: relative; flex: 0 0 auto; font-size: .95rem; }
.notification-menu .notification-menu__toggle { border: 0; background: transparent; font: inherit; display: flex; align-items: center; min-height: 2.4rem; padding: .35rem .5rem; cursor: pointer; list-style: none; color: var(--plum-deep); font-weight: 500; white-space: nowrap; border-radius: var(--radius-sm); }
.notification-menu .notification-menu__toggle::after { content: "▾"; margin-left: .35rem; font-size: .8em; }
.notification-menu[open] .notification-menu__toggle { background: var(--cream-deep); }
.notification-menu:not([open]) .notification-menu__content, .notification-menu__content[hidden] { display: none; visibility: hidden; pointer-events: none; }
.notification-menu__content { position: absolute; z-index: 40; top: calc(100% + .35rem); right: 0; width: min(22rem, calc(100vw - 1rem)); padding: .65rem .75rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); box-shadow: var(--shadow-md); }
.notification-list { margin: 0; padding: 0; list-style: none; }
.notification-menu .notification-list { max-height: min(18rem, 50vh); overflow: auto; }
.notification-list li { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .65rem 0; border-bottom: 1px solid var(--line); }
.notification-list li:last-child { border-bottom: 0; }
.notification-list li.is-read { color: var(--ink-soft); }
.notification-list p { min-width: 0; overflow-wrap: anywhere; }
.notification-list__open { flex: 0 0 auto; min-height: 44px; padding: .2rem .45rem; font-size: .9rem; white-space: nowrap; }
.notification-menu__links { display: flex; gap: .75rem; padding-top: .55rem; border-top: 1px solid var(--line); font-size: .9rem; }
.notification-menu__links a { display: inline-flex; align-items: center; gap: .4rem; min-height: 44px; color: var(--plum); font-weight: 500; }
.notification-update:not([hidden]) { position: fixed; z-index: 80; top: auto; bottom: calc(max(1rem, env(safe-area-inset-bottom)) + var(--flash-banner-height, 0px)); left: auto; right: max(1rem, env(safe-area-inset-right)); width: min(28rem, calc(100% - 2rem)); margin: 0; padding: 1.1rem 1.25rem; display: flex; gap: .75rem; align-items: center; background: var(--teal); border: 1px solid var(--green-deep); border-radius: var(--radius); box-shadow: var(--shadow-md); color: #fffdf7; font-size: 1rem; font-weight: 500; }
.notification-update > span { min-width: 0; flex: 1 1 auto; overflow-wrap: anywhere; }
.notification-update[hidden], .notification-update__message { display: none; }
.notification-update form { margin: 0; }
.notification-update__open { min-height: 44px; padding: .4rem .6rem; background: #fff7e9; border-color: #d9c7a5; color: #14584f; white-space: nowrap; }
.notification-update__dismiss { flex: 0 0 44px; min-height: 44px; padding: 0; border: 0; border-radius: var(--radius-sm); background: transparent; color: inherit; font: inherit; font-size: 1.5rem; cursor: pointer; }
.notification-update__dismiss:hover { background: #ffffff24; }
.notification-update__dismiss:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.game-page .notification-update:not([hidden]) {
  position: absolute;
  top: auto;
  right: auto;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  box-shadow: none;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  pointer-events: none;
}
@media (max-width: 600px) {
  body:not(.game-page) .notification-update:not([hidden]) {
    position: fixed; flex: none; margin: 0; padding: 6px 10px;
    display: grid; grid-template-columns: minmax(0, 1fr) 44px; gap: 8px;
    background: #edf7f3; border-color: #b7d9ce; color: #17574a;
    border-radius: 10px; box-shadow: none; font-size: 1rem; line-height: 1.35;
  }
  body:not(.game-page) .notification-update__copy, .notification-update__action-label { display: none; }
  .notification-update__message { display: inline; }
  .notification-update form { min-width: 0; }
  .notification-update .notification-update__open {
    width: 100%; padding: 0; border: 0; border-radius: 4px; background: none;
    color: inherit; box-shadow: none; font-size: 1rem; font-weight: 500; line-height: 1.35;
    text-align: left; white-space: normal; justify-content: start; overflow-wrap: anywhere;
  }
  .notification-update .notification-update__open:hover:not(:disabled) { box-shadow: none; transform: none; text-decoration: underline; }
  .notification-update__dismiss { width: 44px; }
  .notification-update__dismiss:focus-visible { outline-color: #17574a; }
}
.notification-page { max-width: 38rem; margin: 2rem auto; font-size: 1.15rem; }
.notification-page h1 { font-size: 2rem; }
.notification-page h2 { font-size: 1.4rem; }
.notification-settings-actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.notification-settings-actions .button { min-height: 56px; font-size: 1.15rem; }
.notification-note { font-size: 1rem; }
.notification-menu .notification-menu__toggle:focus-visible { outline: 3px solid #267e74; outline-offset: 3px; border-radius: .3rem; }

.notification-settings-actions [hidden] { display: none; }

.notification-page p { margin: .85rem 0; }

.notification-menu__summary { display: inline-flex; align-items: center; gap: .35rem; }

.notification-page__action { display: inline-flex; align-items: center; gap: .4rem; }

/* ------------------------------------------------------ shared header nav
   The signed-in header is three clear groups on one row at every width:
   the brand on the left, and a right-aligned cluster of the standalone My Games
   link, Notifications disclosure and compact Account disclosure. Settings and
   Sign out always live inside that account panel, so there is one DOM node and
   no mode to switch between: the panel is a dropdown at every width, opened by
   the existing 44px icon trigger. Nothing is rendered twice, so the
   notifications controller keeps its single set of targets. The panel sits
   out of flow so opening it cannot shift the row, and the header keeps its
   own z-index to stay above the positioned board squares it drops over. */
.header-menu.site-header {
  z-index: 50;
}

.header-menu .site-header__inner {
  position: relative;
  max-width: var(--site-max);
  padding: 0.9rem var(--lobby-gutter, 1.5rem);
  flex-wrap: nowrap;
  align-items: center;
}

/* The horizontal navbar artwork fits inside the row; frame its alpha bounds. */
.header-menu .brand__art { position: relative; width: 100%; aspect-ratio: 2013 / 542; }
.header-menu .brand__logo { width: 103.9245%; left: -2.0864%; top: -14.2066%; }

.header-menu .brand {
  position: relative;
  width: 260px;
  height: auto;
  flex: 0 1 auto;
  min-width: 44px;
  min-height: 44px;
}


.site-header__games {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  min-height: 56px;
  flex: none;
  margin-left: auto;
  min-width: 56px;
  justify-content: center;
  color: var(--plum-deep);
  font-size: 1.05rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.site-header__games:hover { text-decoration: underline; }
.site-header__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  background: var(--plum-deep);
  color: #fffdf7;
  font-size: 1rem;
  line-height: 1.2;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.site-header__games:focus-visible { outline: 3px solid var(--teal); outline-offset: 2px; border-radius: 4px; }

/* Keep horizontal bounds relative to the header. The automatic vertical
   position follows the trigger instead of the bottom of the padded header. */
.header-menu .notification-menu {
  position: static;
}

.header-menu .notification-menu__content {
  top: auto;
  margin-top: .35rem;
  right: .75rem;
  left: auto;
  width: min(22rem, calc(100% - 1.5rem));
}

.header-menu .notification-menu .notification-menu__toggle {
  position: relative;
  min-height: 56px;
  min-width: 56px;
  justify-content: center;
  font-size: 1.05rem;
}
.header-menu .notification-menu .notification-menu__toggle::before {
  content: "";
  position: absolute;
  left: -.5rem;
  height: 28px;
  width: 1px;
  background: var(--line);
}
.header-menu .notification-menu .notification-menu__toggle::after { display: none; }

.header-menu__account { position: relative; display: flex; align-items: center; flex: none; }

.header-menu__toggle {
  position: relative;
  display: inline-flex;
  flex: none;
  gap: .65rem;
  margin-left: .75rem;
  font: inherit;
  font-size: 1.05rem;
  font-weight: 500;
  align-items: center;
  justify-content: center;
  min-width: 56px;
  min-height: 56px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--plum-deep);
  cursor: pointer;
}

.header-menu__toggle::before {
  content: "";
  position: absolute;
  left: -1rem;
  height: 28px;
  width: 1px;
  background: var(--line);
}
.header-menu__avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid #bad4ad;
  background: var(--teal-soft);
  color: var(--green-deep);
  font-size: 1.35rem;
  font-weight: 500;
}
.header-menu__label { max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.header-menu__chevron { font-size: .75rem; }

.header-menu__toggle:focus-visible {
  outline: 3px solid var(--teal);
  outline-offset: 2px;
}

/* Account panel: one compact, right-aligned cream card, the same at every
   width. It is off flow, so opening it cannot move the row beneath it, and it
   never spans a desktop viewport. */
.header-menu .site-header__who {
  display: none;
  position: absolute;
  z-index: 60;
  top: calc(100% + .35rem);
  right: 0;
  left: auto;
  width: min(20rem, calc(100vw - 1.5rem));
  max-height: calc(100dvh - 5rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: .35rem;
  margin: 0;
  padding: .7rem;
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  color: var(--ink-soft);
  font-size: 1rem;
}

.header-menu.is-open .header-menu__toggle { outline: none; }
.header-menu .notification-menu[open] .notification-menu__toggle { outline: none; }

.header-menu.is-open .site-header__who {
  display: flex;
}

.header-menu .site-header__who > form {
  margin: 0;
}

.header-menu .site-header__who .button {
  justify-content: flex-start;
  width: 100%;
  min-height: 56px;
}

.header-menu__zoom { display: flex; align-items: center; justify-content: space-between; gap: .5rem; min-height: 44px; padding: .35rem .6rem; color: var(--plum); font-weight: 500; }
.header-menu__zoom select { min-height: 2rem; font: inherit; color: inherit; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm); }

/* Narrow screens keep the horse logo, the 44px icon-only bell and the 44px
   account trigger so the standalone My Games link still fits beside them. The
   "Notifications" word stays in the DOM for screen readers, so the summary
   keeps its accessible name. The compact row also fits browser zoom. */
@media (max-width: 950px) {
  .site-header__games-label { display: none; }
  .header-menu__label { display: none; }
  .header-menu__toggle { margin-left: 6px; gap: 4px; }
  .header-menu__toggle::before { left: -7px; }
  .header-menu__avatar { width: 36px; height: 36px; font-size: 1.1rem; }
  .header-menu .site-header__inner { padding: 8px var(--lobby-gutter, 12px); gap: 6px; }
  .header-menu .brand { gap: 6px; }
  .header-menu .brand { width: 180px; }
  .site-header__games { font-size: 1rem; gap: .3rem; }
  .header-menu .notification-menu .notification-menu__toggle { padding-inline: 6px; }
  .header-menu .notification-menu .notification-menu__toggle::before { left: -3px; }
  .header-menu .notification-menu .ui-icon,
  .header-menu__toggle .ui-icon { width: 22px; height: 22px; font-size: 22px; }
  .notification-menu__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* Very narrow phones need the last few pixels: a slightly smaller brand mark
   buys room for the My Games link, the bell and the account trigger without
   touching the row's target sizes. Lobby and board share the same chrome. */
@media (max-width: 380px) {
  .header-menu .site-header__inner { gap: .25rem; padding-inline: var(--lobby-gutter, 8px); }
  .site-header__games { font-size: .9rem; }
  .header-menu .notification-menu .notification-menu__toggle { padding-inline: 2px; }
  .header-menu .brand { gap: .35rem; }
}

/* game: board-first play screen for older eyes. The board is the only
   responsive piece and stays one complete square: it takes the smaller of the
   available width and a bounded maximum that grows with the window's height,
   about 42px squares on a short window and larger on a tall one. The gaps
   between the major groups are deliberate whitespace, and nothing scrolls
   sideways, so the board overview stays whole. */

/* Reserve the scrollbar without adding an empty strip on the left edge. */
html:has(.game-page) { overflow-y: scroll; }
.game-page {
  --tile-face: #fffdf6;
  --tile-edge: #d9c096;
  --tile-merged-face: #f7d96f;
  --tile-merged-edge: #c8a83f;
  --tile-latest-face: #f3b45b;
  --board-gap: 2px;
  /* 15 squares of about 42px plus their 2px gaps at the short-desktop floor.
     A tall window grows the square with the available height, but only up to a
     bounded ceiling, so the scores, rack, and actions stay beside the board and
     nothing is stretched to fill a window it does not need. */
  --board-max: clamp(660px, calc(100dvh - 26rem), 740px);
  --frame-pad: 3px;
  --frame-edge: 1px;
  --frame-extra: calc(2 * (var(--frame-pad) + var(--frame-edge)));
  --cluster-width: calc(var(--board-max) + var(--frame-extra) + 2.5rem);
  font-family: var(--font-friendly);
}

.game-page .site-main { max-width: var(--cluster-width); padding: 0.85rem 1.25rem 1.5rem; }
.game-page .flash:not(:has(p)) { display: none; }

/* Open page composition: no enclosing panel. The board frame, the rack tray,
   and the controls keep their own shapes; deliberate gaps do the separating:
   header 14 / scores 14 / board 18 / rack 18 / actions 24 / history. */
.game {
  position: relative;
  -webkit-user-select: none;
  user-select: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  width: min(100%, calc(var(--board-max) + var(--frame-extra)));
  margin: 0 auto;
}
.game input, .game textarea, .game [contenteditable="true"] {
  -webkit-user-select: text;
  user-select: text;
}
.game > turbo-cable-stream-source { display: none; }
.game-page .flash .flash__message {
  padding: .55rem .75rem;
  border-radius: 10px;
  box-shadow: none;
  font-size: 1rem;
}
.game-page .flash__icon { flex-basis: 1.5rem; height: 1.5rem; font-size: 1rem; }
.game-scoreboard {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.85rem;
  width: 100%;
}
/* Phone-only route back to the lobby once the site header is hidden. */
.game-back { display: none; }
.players { display: contents; }
.player {
  grid-row: 1;
  justify-self: center;
  text-align: center;
  display: flex;
  align-items: center;
  width: 190px;
  max-width: 100%;
  height: calc(2.598rem + 2px);
  padding: 0 0.5rem;
}
.player--you { grid-column: 1; justify-self: start; }
.player--opponent { grid-column: 3; justify-self: end; }
.player__identity { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: 0.9rem; }
.player--opponent .player__identity { flex-direction: row-reverse; }
.player__name { font-size: 1.25rem; line-height: 1.1; color: #46414f; white-space: nowrap; }
.player__score { display: flex; align-items: baseline; gap: 0.25rem; margin: 0; line-height: 1; white-space: nowrap; }
.player__number { font-size: 2.1rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.player--you .player__number { color: #2b607f; }
.player--opponent .player__number { color: #a2543f; }
.game-status { grid-column: 2; grid-row: 1; justify-self: center; display: flex; flex-direction: column; align-items: center; gap: .6rem; min-width: 0; }
.game .game-scoreboard { min-height: 0; margin-bottom: .6rem; padding-top: .35rem; }
.game .board-tools { align-items: start; }
.tile-bag-count { margin: 0; text-align: center; white-space: nowrap; font-size: .8rem; line-height: 1.3; color: var(--ink-soft); }
.tile-bag-count strong { color: var(--plum-deep); font-variant-numeric: tabular-nums; }
.status-banner {
  position: relative;
  justify-self: center;
  grid-column: 2;
  grid-row: 1;
  display: inline-grid;
  justify-items: center;
  gap: 0.05rem;
  text-align: center;
  padding: 0.4rem 1.15rem;
  border-radius: 999px;
  border: 1px solid #e7ddc8;
  background: linear-gradient(#fffefb, #f5efe2);
  box-shadow: inset 0 1px 0 #fff, 0 1px 0 #e6dac3;
  color: var(--ink-soft);
}
.status-banner--turn {
  background: linear-gradient(#eaf8f1, #d9efe4);
  border-color: #b3dcc7;
  box-shadow: inset 0 1px 0 #fff, 0 1px 0 #b3dcc7;
  color: #17574a;
}
.status-banner--over { background: transparent; border: 0; box-shadow: none; border-radius: 0; padding: 0; }
.player--winner { background: #dcefe3; border: 1px solid #92c6aa; border-radius: 12px; height: auto; min-height: 52px; padding: .4rem .6rem; }
.player--winner .player__number { color: #17574a; }
.status-banner__headline { font-size: 1.25rem; font-weight: 500; line-height: 1.15; }
.status-banner__direction { position: absolute; right: calc(100% + 0.5rem); top: 50%; transform: translateY(-50%); font-size: 1.4rem; font-weight: 500; line-height: 1; }
.status-banner__direction--opponent { right: auto; left: calc(100% + 0.5rem); }
.status-banner__detail { font-size: 0.95rem; font-weight: 500; margin: 0; color: #4b4761; }

/* Board down to the rack band. */
.board-region { width: 100%; min-width: 0; margin-bottom: 1.05rem; }
.board-tools { display: grid; align-items: center; height: 3rem; margin-bottom: 6px; }
.board-tools:not(:has(> :not([hidden]))) { display: none; }
.board-tools > p { grid-area: 1 / 1; justify-self: center; max-width: 100%; min-width: 0; margin: 0; padding: .35rem .9rem; border-radius: 999px; font-size: 1.1rem; line-height: 1.4rem; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.board-tools > [hidden] { display: none; }
.board-latest-play { background: #e2eff8; box-shadow: inset 0 0 0 1px #afcadf; color: #285874; font-weight: 500; }
.board-word-error { background: #f7d7cf; box-shadow: inset 0 0 0 1px #d18e80; color: #7c2925; font-weight: 500; }
.board-zoom {
  display: none;
  font: inherit; font-size: 0.8rem; font-weight: 500; color: var(--teal);
  background: var(--paper); border: 1px solid var(--teal); border-radius: 8px;
  min-height: 44px; padding: 6px 10px; cursor: pointer;
}
.board-zoom:focus-visible { outline: 3px solid var(--teal); outline-offset: 2px; }
.board-viewport { width: 100%; aspect-ratio: 1; overflow: hidden; }
.board-viewport.is-zoomed { overflow: auto; overscroll-behavior: contain; }
.board-viewport.is-zoomed .board { width: 200%; }
.board-scroll {
  position: relative;
  overflow: visible;
  width: 100%;
  padding: var(--frame-pad);
  border: var(--frame-edge) solid #ceb98e;
  border-radius: 10px;
  background: linear-gradient(#eedfbe, #dfcba1);
  box-shadow: inset 0 1px 0 #fffdf4, inset 0 -2px 0 #d6c5a1, 0 2px 0 #d3c29c,
    0 8px 18px rgba(101, 83, 52, 0.16), 0 22px 40px rgba(101, 83, 52, 0.07);
}
.board {
  display: grid;
  grid-template-columns: repeat(15, 1fr);
  grid-template-rows: repeat(15, 1fr);
  gap: var(--board-gap);
  width: 100%;
  aspect-ratio: 1 / 1;
  margin: 0 auto;
  background: #e2d3b4;
  border-radius: calc(10px - var(--frame-pad) - var(--frame-edge));
  container-type: inline-size;
}
.board__row { display: contents; }
.move-score {
  position: absolute; z-index: 8; pointer-events: auto; white-space: nowrap;
  padding: 2px 6px; border: 1px solid #b3dcc7; border-radius: 6px;
  background: #e2f2ea; color: #17574a; font-size: 18px; line-height: 20px;
  font-weight: 500; box-shadow: 0 2px 5px #14523f24;
}
.move-score[hidden] { display: none; }
.game.is-dragging .move-score,
.game:has(.tile.is-selected) .move-score { pointer-events: none; }

.square {
  appearance: none;
  font: inherit;
  padding: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 7px;
  background: #fbf4e3;
  box-shadow: inset 1px 1px 0 #fffdf7, inset -1px -1px 0 #8e785322, inset 0 1px 2px #8e78531c;
  color: #46546a;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  cursor: pointer;
  transition: box-shadow 120ms ease, background-color 120ms ease;
}
.square:focus-visible { box-shadow: inset 0 0 0 3px #1f7a66; z-index: 3; }
@media (hover: hover) and (pointer: fine) {
  .square:hover:not(:disabled) { box-shadow: inset 0 0 0 3px #1f7a66; z-index: 3; }
}
.square:disabled { cursor: default; }
.square--double_letter { background: #d2e4f0; color: #305a75; box-shadow: inset 1px 1px 0 #ffffffb3, inset -1px -1px 0 #4d759020, inset 0 2px 3px #4d759012; }
.square--triple_letter { background: #b6d9ca; color: #23574c; box-shadow: inset 1px 1px 0 #ffffffb3, inset -1px -1px 0 #2f6d5d24, inset 0 2px 3px #2f6d5d12; }
.square--double_word { background: #f1d3c7; color: #8a4b3e; box-shadow: inset 1px 1px 0 #ffffffb3, inset -1px -1px 0 #a2604a20, inset 0 2px 3px #a2604a12; }
.square--triple_word { background: #e8a08c; color: #6b2a1d; box-shadow: inset 1px 1px 0 #ffffff9e, inset -1px -1px 0 #8d3f2c26, inset 0 2px 3px #8d3f2c14; }
.square--center { background: #f6e3ac; color: #7d5410; }
.square__premium, .square__star { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
/* cqw keeps the labels and the star in proportion at every board size; the
   clamps hold them near 17px on a full-size board and keep them legible when
   the board shrinks. */
.square__premium { font-size: clamp(14px, 2.6cqw, 18px); font-weight: 500; letter-spacing: 0.01em; text-shadow: 0 1px 0 #ffffff8c; }
.square__star { font-size: clamp(14px, 3.4cqw, 24px); text-shadow: 0 1px 0 #ffffff8c; }
.square.has-draft .square__premium, .square.has-draft .square__star { visibility: hidden; }
/* The square the tile would land on, and the square that already holds a
   tentative tile. Both are louder than a hover so an older player can see
   where the tile is about to go. */
.square.is-drop-target { box-shadow: inset 0 0 0 4px #15695a, 0 0 0 2px #ffffffcc; background: #cfeade; }
/* The destination square fills with a cell-sized ghost carrying the held
   letter, so the player sees both WHAT is going down and exactly WHERE. It is
   a real element (not a pseudo) so its letter and size can be asserted, and it
   renders above a tentative tile when the drop is a replacement. */
.square .tile--drop-ghost {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  background: linear-gradient(166deg, #f4f0ff, #ded3f6);
  border: 2px solid #6b53a8;
  border-bottom-color: #503b8c;
  box-shadow: inset 0 1px 0 #fff, 0 3px 0 #6d5aa8, 0 6px 10px #3d2f5c33;
  opacity: 0.92;
  pointer-events: none;
}
.square.is-drop-target .square__premium, .square.is-drop-target .square__star { visibility: hidden; }
/* A committed square under the finger is a clear "no", never a silent hop. */
.square.is-drop-invalid { box-shadow: inset 0 0 0 4px #b65246, 0 0 0 2px #ffffffcc; background: #f2d7d0; }
/* A committed tile fills its square (merged tiles fill it edge to edge), which
   hides the inset shadow above. Paint the invalid "no" as an overlay so it
   stays visible on top of the letter and tile, without redirecting the drop. */
.square.is-drop-invalid::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: inherit;
  border: 4px solid #b65246;
  box-shadow: 0 0 0 2px #ffffffcc;
  background: #b6524626;
  pointer-events: none;
}
.square.has-draft { background: #e3d9f4; }

.tile {
  width: var(--tile);
  height: var(--tile);
  flex-shrink: 0;
  font: inherit;
  border-radius: 10px;
  background: linear-gradient(166deg, #fffdf7, #fff2d8);
  border: 1px solid var(--tile-edge);
  border-top-color: #fffef9;
  border-bottom: 2px solid #cdae74;
  box-shadow: inset 1px 1px 0 #ffffffd9, inset -1px -1px 0 #bc965b29, 0 2px 0 #c3a771, 0 5px 8px #5c492229;
  color: var(--plum-deep);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  font-weight: 500;
}
.tile__letter { font-size: 1.9rem; font-weight: 600; line-height: 1; }
.tile__points { position: absolute; right: 5px; bottom: 2px; font-size: 0.85rem; font-weight: 500; line-height: 1; color: #3f4053; }
/* Board tiles are sized by their square; rack tiles keep a fixed size. */
.board .tile { width: 88%; height: 88%; }
.board .tile__letter { font-size: 4.1cqw; transform: translate(-2px, -2px); }
.board .tile__points { right: 5%; bottom: 3%; font-size: clamp(12px, 2.15cqw, 15px); }
/* touch-action: none belongs on the draggable tile itself and must be present
   from the start of a touch: the browser decides gesture ownership before any
   JS drag threshold runs, so it cannot be applied later. This suppresses
   native scrolling only for a gesture that begins on a tile; page scrolling
   and board panning stay available everywhere else. The .is-dragging class
   does not own scrolling. */
.tile--rack { appearance: none; cursor: grab; touch-action: none; }
.tile--rack:hover:not(:disabled) { transform: translateY(-4px); box-shadow: inset 1px 1px 0 #ffffffd9, inset -1px -1px 0 #bc965b29, 0 4px 0 #c3a771, 0 9px 14px #5c492233; }
.tile--rack:disabled { cursor: default; }
/* Choosing a tile has to be unmistakable: a thick ring, a tinted face, and a
   clear lift, not a one-pixel colour change. */
.tile--rack.is-selected {
  outline: 4px solid #10695a;
  outline-offset: 3px;
  transform: translateY(-6px);
  background: linear-gradient(166deg, #dff3e6, #c6e8d3);
  border-color: #1c7d69;
  box-shadow: inset 0 1px 0 #fff, 0 6px 0 #1a705f, 0 12px 18px #1b5f4d3d;
}
.tile--rack.is-lifted, .tile--rack.is-drag-source { visibility: hidden; }
.tile--played {
  z-index: 1;
  background: linear-gradient(166deg, #ffed9c, #f2d363);
  border-color: #c8aa43;
  border-top-color: #fff7ce;
  border-bottom-color: #b39432;
  box-shadow: inset 1px 1px 0 #fff9dccc, inset -1px -1px 0 #b3943233, 0 2px 0 #b39432, 0 5px 8px #69502529;
}
.tile--latest-play {
  background: var(--tile-latest-face);
  outline: none;
  filter: none;
}
.tile--latest-play.is-word-settling {
  animation: word-settle 480ms cubic-bezier(.22, 1, .36, 1) var(--word-delay, 0ms) both;
}
@keyframes word-settle {
  0% { transform: translateY(-18%) scale(.88); filter: brightness(1.22); }
  62% { transform: translateY(0) scale(1.045); filter: brightness(1.12); }
  100% { transform: none; filter: none; }
}
/* A committed tile that touches another committed tile joins it into one gold
   surface. The tile keeps its letter and points but swaps its raised face for a
   flat one, drops the bevel and outline on the sides it shares, and grows by
   half the board gap so the faces meet with no seam. Neighbour classes are
   rendered by the server, one per shared side and never on a diagonal. */
#game-board .tile--played.tile--merged {
  position: absolute;
  inset: calc(var(--board-gap) * -0.5);
  width: auto;
  height: auto;
  border: 0;
  border-radius: 0;
  background: var(--tile-merged-face);
  box-shadow: none;
  outline: none;
}
#game-board .tile--merged:not(.tile--join-up) { border-top: 1px solid var(--tile-merged-edge); }
#game-board .tile--merged:not(.tile--join-down) { border-bottom: 1px solid var(--tile-merged-edge); }
#game-board .tile--merged:not(.tile--join-left) { border-left: 1px solid var(--tile-merged-edge); }
#game-board .tile--merged:not(.tile--join-right) { border-right: 1px solid var(--tile-merged-edge); }
#game-board .tile--merged:not(.tile--join-up):not(.tile--join-left) { border-top-left-radius: 10px; }
#game-board .tile--merged:not(.tile--join-up):not(.tile--join-right) { border-top-right-radius: 10px; }
#game-board .tile--merged:not(.tile--join-down):not(.tile--join-left) { border-bottom-left-radius: 10px; }
#game-board .tile--merged:not(.tile--join-down):not(.tile--join-right) { border-bottom-right-radius: 10px; }
/* The latest word uses a warm orange face while keeping the joined geometry. */
#game-board .tile--latest-play.tile--merged {
  background: var(--tile-latest-face);
  filter: none;
}
/* Played blanks keep their zero-point label without breaking the word outline. */
#game-board .tile--played.tile--merged.tile--blank { border-style: solid; }
#game-board .tile--played.tile--merged.tile--blank::after { content: none; }
/* A tentative tile is tinted, outlined, and raised, so it never reads as a
   committed board tile. */
.tile--draft {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  cursor: grab;
  touch-action: none;
  background: linear-gradient(166deg, #f2edff, #ded3f6);
  border: 2px solid #6b53a8;
  border-bottom-color: #503b8c;
  box-shadow: inset 0 1px 0 #fff, 0 3px 0 #6d5aa8, 0 7px 11px #3d2f5c33;
}
.tile--draft.is-selected { outline: 4px solid #10695a; outline-offset: 2px; transform: translate(-50%, -50%) translateY(-3px); box-shadow: inset 0 1px 0 #fff, 0 5px 0 #6d5aa8, 0 10px 16px #3d2f5c45; }
.tile--draft.is-invalid {
  background: linear-gradient(166deg, #fff0eb, #f3c7bf);
  border-color: #b65246; border-bottom-color: #953e35;
  box-shadow: inset 0 1px 0 #fff, 0 3px 0 #ad574b, 0 7px 11px #66322933;
}
.square:has(.tile--draft.is-invalid) { background: #f2d7d0; }
.tile--blank { border-style: dashed; }
.tile--blank::after { content: ""; position: absolute; left: 3px; top: 3px; width: 4px; height: 4px; border-radius: 50%; background: #8a719c; }
.tile--small { width: 2.6rem; height: 2.6rem; }
.tile--small .tile__letter { font-size: 1.55rem; }
/* The lifted preview floats above a touch finger purely for visibility, or at
   the mouse pointer on desktop. Targeting and release use the finger, never
   this point. Desktop mouse keeps the familiar lighter ghost; a touch finger
   gets a nearly solid tile so the held letter reads over the board. The
   destination ghost, not this preview, communicates precision. */
.tile--ghost { position: fixed; width: 3.4rem; height: 3.4rem; transform: translate(-50%, -50%) rotate(-2deg) scale(1.06); pointer-events: none; z-index: 60; opacity: 0.5; box-shadow: inset 0 1px 0 #fff, 0 4px 0 #b89d6b, 0 16px 26px #35283b52; }
.tile--ghost.tile--ghost--touch { opacity: 0.95; }
.tile--ghost .tile__letter { font-size: 2.3rem; }
/* The original slot stays visible but faded, so the tile reads as being moved. */
.tile--draft.is-drag-source { opacity: 0.5; }
.tile__letter--blank { color: #8c7751; }

/* minmax(0, 1fr) plus min-width: 0 on the spanning items keeps the play area,
   the rack band, and the action row exactly as wide as the board frame. */
.play-area { width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; justify-items: center; }
/* The rack sits in its own band under the board; the 18px gap above it keeps
   the tray from reading as part of the board frame. The band is named for
   assistive technology with a visually hidden heading, not an on-screen one. */
.rack-action-row { grid-column: 1 / -1; grid-row: 2; display: flex; justify-content: center; align-items: stretch; gap: 1rem; width: 100%; min-width: 0; }
.rack-region { display: flex; justify-content: center; flex: 1 1 0; min-width: 0; }
.rack {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.5rem;
  justify-content: center;
  align-items: center;
  width: 100%;
  padding: 6px 0.9rem 8px;
  border-radius: 16px;
  border: 1px solid #cdb488;
  border-top-color: #e4cda2;
  background: linear-gradient(#e9cd9c, #f2ddb9);
  box-shadow: inset 0 1px 0 #fff3da, inset 0 4px 8px #8a623026, inset 0 -4px 0 #d3b07a, 0 2px 0 #bf9c6b, 0 5px 10px #493c2422;
  container-type: inline-size;
}
/* Tiles fill the tray, so the rack hugs its seven letters at any size. */
.rack .tile { width: 100%; height: auto; aspect-ratio: 1 / 1; }
.rack .tile__letter { font-size: clamp(28px, 7.5cqw, 34px); }
.rack .tile__points { right: 7%; bottom: 5%; font-size: clamp(14px, 3.3cqw, 16px); }
.rack.is-drop-target { outline: 3px solid var(--teal); outline-offset: 2px; }
.rack .is-insert-before::before, .rack .is-insert-after::before {
  content: ""; position: absolute; top: 3px; bottom: 3px; width: 4px;
  border-radius: 2px; background: #10695a; box-shadow: 0 0 0 1px #fffdf6;
  pointer-events: none;
}
.rack .is-insert-before::before { left: -7px; }
.rack .is-insert-after::before { right: -7px; }

.rack__empty { grid-column: 1 / -1; text-align: center; }
/* Utility actions stay in a compact row below the rack and GO. */
.action-bar { grid-column: 1 / -1; grid-row: 4; margin-top: 1.05rem; display: flex; width: 100%; max-width: 100%; min-width: 0; justify-content: center; align-items: center; gap: 1.3rem; flex-wrap: wrap; }
.controls { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); align-items: stretch; gap: 0.5rem; width: 100%; min-width: 0; }
.game:not(.is-your-turn) .controls { display: none; }
/* Soft filled capsules with a lower edge, so the row reads as game pieces
   rather than a toolbar of outlined product buttons. Icons accompany labels. */
.controls .button, .game-options > .button, .game-chat--floating .game-chat__panel:not([open]) .game-chat__summary {
  width: 100%;
  font-size: 1.2rem;
  font-weight: 500;
  line-height: 1.25;
  min-height: 62px;
  min-width: 5.3rem;
  padding: 0.55rem 0.7rem;
  gap: 0.45rem;
  border-radius: 14px;
  border: 1px solid #e7dcc6;
  border-bottom: 2px solid #dbcdb1;
  background: linear-gradient(#fffdf7, #f7efdd);
  color: var(--ink);
  box-shadow: inset 0 1px 0 #fff, 0 3px 0 #ddccaa, 0 5px 9px #6b583514;
}
.button__icon { display: block; flex: 0 0 auto; width: 22px; height: 22px; pointer-events: none; }
.controls .button:hover:not(:disabled) {
  background: linear-gradient(#fffefb, #fbf4e6);
  box-shadow: inset 0 1px 0 #fff, 0 4px 0 #e3d6bb, 0 8px 14px #6b583518;
  transform: translateY(-1px);
}
.controls .button:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 2px 3px #b8a58338, 0 1px 0 #e5d6b9;
}
.game-page .button:disabled { opacity: 1; cursor: default; }
.controls .button:disabled {
  color: #6f6a58;
  border-color: #e7dfd0;
  border-bottom-color: #e3dbca;
  background: linear-gradient(#f5f2e9, #eeeadf);
  box-shadow: inset 0 1px 0 #fff9e8, 0 2px 0 #e6e0d2;
  transform: none;
}
/* Primary play action. */
.preview { position: relative; display: flex; align-items: stretch; flex: 0 0 auto; }
.game-page .button--play {
  flex: 0 0 auto;
  margin-left: 0;
  width: auto;
  max-width: none;
  min-width: 8rem;
  min-height: 56px;
  gap: 0.45rem;
  padding: 0.7rem 1.05rem;
  border-radius: 18px;
  border: 1px solid var(--green-deep);
  background: linear-gradient(var(--teal), var(--green-deep));
  color: #fff;
  font-size: 1.75rem;
  font-weight: 500;
  line-height: 1.25;
  box-shadow: inset 0 0 0 1px #ffffff26, 0 3px 7px #075a4626;
  white-space: nowrap;
}
.game-page .button--play:hover:not(:disabled) {
  background: linear-gradient(#328449, var(--teal));
  transform: none;
  box-shadow: inset 0 0 0 1px #ffffff30, 0 4px 9px #075a4633;
}
.game-page .button--play:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 1px 3px #0c3d3329, 0 1px 3px #075a4626;
}
.game-page .button--play:disabled {
  background: #e3e7e2;
  color: #929a93;
  border-color: #c9d0c9;
  border-bottom-color: #c9d0c9;
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}

.game-secondary { grid-column: 1 / -1; grid-row: 5; margin-top: 0.25rem; display: flex; gap: 0.5rem; align-items: center; width: 100%; color: var(--ink-soft); }
.game-play-dock .game-options:not([hidden]) { display: contents; }
.game-options > .button { grid-row: 3; min-width: 0; }
.game-options__back { grid-column: 1; }
.game-options__chat { grid-column: 2; }
.game-sound-toggle { grid-column: 3; }
.game-resign { grid-column: 4; }
.game-nudge__button { min-height: 44px; font-size: .85rem; padding: 6px 10px; }
.game-nudge__button > span { width: 4em; flex-shrink: 0; text-align: center; }
.game-options > .button .ui-icon { width: 22px; height: 22px; font-size: 22px; }
.game-options > .game-options__back { background: var(--gold-bright); border-color: #c59a12; color: var(--plum-deep); }
.game-options > .game-sound-toggle { background: linear-gradient(#f0f8ed, #deeedb); border-color: #bcd3b5; color: #345d2d; }
.game-options > .game-resign { background: linear-gradient(#fbefea, #f5e3de); border-color: #dab4a9; color: #843e30; }

/* Rematch call to action: an empty, hidden target while the game is live, filled
   in place by the finishing response for both players. */
.game-rematch { width: 100%; display: flex; justify-content: center; margin: 0; }
.game-rematch[hidden], .game-rematch:empty { display: none; }
.game-rematch__button { min-height: 52px; padding-inline: 2rem; font-size: 1.2rem; }

/* Private chat opens from its action-row button; pending and finished notices stay in flow. */
.game-chat { width: 100%; min-width: 0; margin-top: 0.5rem; }
.game-chat__panel { border: 1px solid var(--plum-deep); border-radius: 12px; background: #fffdf8; overflow: hidden; }
.game-chat__summary { display: flex; align-items: center; gap: 0.5rem; justify-content: center; min-width: 9rem; min-height: 56px; padding: 0 1.1rem; font-weight: 500; color: #fffdf7; background: var(--plum-deep); cursor: pointer; list-style: none; }
.game-chat__summary::-webkit-details-marker { display: none; }
.game-chat__summary-title { display: inline-flex; align-items: center; gap: 0.5rem; }
.game-chat__unread { display: inline-flex; align-items: center; justify-content: center; min-width: 1.5rem; padding: 0.1rem 0.45rem; border-radius: 999px; background: #fffdf7; color: var(--plum-deep); font-size: 1rem; line-height: 1.2; font-weight: 500; font-variant-numeric: tabular-nums; }
.game-chat__unread[hidden] { display: none; }
.game-chat__panel:not([open]) .game-chat__summary { min-width: 11rem; min-height: 64px; font-size: 1.4rem; }
.game-chat__close-icon { display: none; }
.game-chat__panel[open] .game-chat__summary { justify-content: space-between; }
.game-chat__panel[open] .game-chat__close-icon { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; font-size: 1.3rem; }
.game-chat__summary .ui-icon { width: 1.4rem; height: 1.4rem; font-size: 1.4rem; }
@media (max-width: 600px) {
  .game-chat__panel:not([open]) .game-chat__summary { min-width: 6rem; min-height: 48px; padding-inline: .75rem; font-size: 1.06rem; }
  .game-chat__panel:not([open]) .game-chat__summary .ui-icon { width: 1.1rem; height: 1.1rem; font-size: 1.1rem; }
}
/* The panel clips its overflow, so a positive outline-offset would leave the
   summary focus ring half-hidden. An inset ring stays fully inside the bounds. */
.game-chat__summary:focus-visible { outline: 3px solid #267e74; outline-offset: -3px; }
.game-chat__body { display: grid; gap: 0.6rem; padding: 0.9rem; min-width: 0; }
.game-chat__note { margin: 0; color: var(--ink-soft); font-size: 1rem; overflow-wrap: anywhere; }
.game-chat__messages { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; max-height: 16rem; overflow-y: auto; overflow-wrap: anywhere; }
.game-chat__message { display: grid; gap: 0.1rem; min-width: 0; max-width: 100%; padding: 0.35rem 0.55rem; border-radius: 10px; background: #f4f0e6; }
.game-chat__author { font-weight: 500; color: var(--plum-deep); font-size: 1rem; }
.game-chat__text { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; }
.game-chat__form { display: grid; gap: 0.5rem; min-width: 0; }
.game-chat__input { width: 100%; min-width: 0; max-width: 100%; min-height: 3rem; padding: 0.5rem 0.65rem; border: 1px solid var(--line); border-radius: 10px; font: inherit; resize: none; overflow-y: auto; box-sizing: border-box; }
.game-chat__input:focus-visible { outline: 3px solid #267e74; outline-offset: 2px; }
.game-chat__error { margin: 0; color: #7d2f1e; font-weight: 500; }
.game-chat__send { justify-self: end; min-height: 44px; font-size: inherit; }

/* Chat shares the secondary action row. The open panel floats so
   opening it never shifts the board or replaces a draft. */
.game:has(.game-chat--floating) { padding-bottom: 0; }
.game-chat--floating {
  position: relative;
  font-size: 1.2rem;
  grid-column: 2; grid-row: 3; align-self: stretch;
  width: 100%; min-width: 0; margin: 0; z-index: 60;
  display: flex; flex-direction: column;
}
.game-chat--floating .game-chat__panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: fit-content;
  max-width: 100%;
  max-height: min(var(--chat-room, calc(100dvh - 16px)), calc(100dvh - 16px));
}
.game-chat--floating .game-chat__panel[open] {
  position: absolute; left: 0; bottom: 0;
  width: min(22rem, calc(100vw - 32px)); max-width: none;
  transform-origin: bottom right;
  animation: chat-open 160ms ease-out;
}
.game-chat--floating .game-chat__panel[open].game-chat__panel--below {
  top: 0; bottom: auto; transform-origin: top right;
  animation-name: chat-open-below;
}
@keyframes chat-open {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes chat-open-below {
  from { opacity: 0; transform: translateY(-16px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .game-chat--floating .game-chat__panel[open] { animation: none; }
}
.game-chat--floating .game-chat__summary { flex: 0 0 auto; }
.game-chat--floating .game-chat__body {
  min-height: 0;
  max-height: min(calc(var(--chat-room, 100dvh) - 58px), calc(100dvh - 74px));
  /* A short viewport scrolls the whole body so the note and the reply controls
     can both be reached; the messages list keeps its own scroll on tall ones. */
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  align-content: start;
}
/* Cap the thread against the visible viewport so the input and Send stay on
   screen at 320px wide, short landscape, or high zoom. The 28rem reserve leaves
   room for the note, the form, and the panel's header/gutter chrome before the
   body itself has to scroll; 16rem remains the ceiling on a tall window. */
.game-chat--floating .game-chat__messages {
  max-height: min(16rem, max(2.5rem, calc(100dvh - 28rem)));
  min-height: 2.5rem;
}


/* While typing, reserve the composer and let only message history scroll. */
.game-chat--floating .game-chat__panel[open].game-chat__panel--composing {
  position: fixed;
  animation: none;
}
.game-chat--floating .game-chat__panel--composing .game-chat__body {
  height: min(24rem, calc(var(--chat-room) - 58px));
  grid-template-rows: minmax(0, 1fr) auto; padding: .6rem; overflow: hidden;
}
.game-chat__panel--composing .game-chat__note { display: none; }
.game-chat--floating .game-chat__panel--composing .game-chat__messages { min-height: 0; max-height: none; }

/* Chat stays outside the Turbo-replaced play area to preserve its draft. */
.game-play-dock { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; width: 100%; }
.game-play-dock .action-bar,
.game .game-play-dock .controls { display: contents; }
.game-play-dock .controls .button { grid-row: 2; }
.game-play-dock .play-area:not([hidden]) { display: contents; }
.game-play-dock .rack-action-row { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 1fr); grid-column: 1 / -1; grid-row: 1; gap: 8px; }
.game-play-dock .rack-region { grid-column: 1; grid-row: 1; }
.game-play-dock .preview { grid-column: 2; grid-row: 1; min-width: 0; width: 100%; }
.game-play-dock .button--play { width: 100%; min-width: 0; min-height: 64px; }
.game-play-dock .action-bar { grid-column: 1 / -1; grid-row: 2; margin-top: 0; }
.game-chat--floating .game-chat__panel:not([open]) { width: 100%; border: 0; background: transparent; overflow: visible; }
.game-chat--floating .game-chat__panel:not([open]) .game-chat__summary {
  position: relative; min-width: 0; width: 100%; min-height: 62px; padding: .55rem .7rem; font-size: 1.2rem;
  background: var(--gold-soft); border-color: var(--line); color: var(--plum-deep);
}

.game-chat--floating .game-chat__panel:not([open]) .game-chat__summary .ui-icon { width: 22px; height: 22px; font-size: 22px; }

@media (max-width: 950px) {
  .game-scoreboard { grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 0.5rem; }
  .controls { justify-content: center; }
  .action-bar { justify-content: center; }
  .game-page .button--play { margin-left: 0; }
  .rack { gap: 0.45rem; padding-inline: 0.75rem; }
}
@media (max-width: 600px), (max-width: 950px) and (max-height: 500px) {
  .game-page .site-main { padding: 8px 12px 16px; }
  .game-scoreboard { gap: 8px; margin-bottom: 8px; }
  /* Phones stack each player's name over their score inside its own column,
     with the turn pill alone in the centre column and a clear gap between. */
  .player { width: 100%; min-width: 0; height: auto; padding-inline: 0; }
  .player__identity {
    min-width: 0; gap: 2px;
    flex-direction: column; align-items: stretch; justify-content: center;
  }
  .player--you .player__identity { text-align: left; }
  .player--opponent .player__identity { flex-direction: column; text-align: right; }
  .player__name {
    width: 100%; max-width: 100%; min-width: 0;
    overflow: hidden; text-overflow: ellipsis;
    font-size: clamp(0.8rem, 3.6vw, 1rem);
  }
  .player__score { flex-shrink: 0; }
  .player--you .player__score { justify-content: flex-start; }
  .player--opponent .player__score { justify-content: flex-end; }
  .player__number { font-size: 1.6rem; }
  .status-banner { max-width: 34vw; min-width: 0; padding: 6px 8px; }
  .status-banner__headline { max-width: 100%; font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .status-banner__direction { display: none; }
  .board-region { margin-bottom: 6px; }
  .board-zoom { display: inline-flex; position: absolute; top: 6px; right: 6px; z-index: 4; }
  .board-tools > p { font-size: 1rem; }
  .board .tile__points { display: none; }
  .board .tile__letter { font-size: 4.5cqw; transform: none; }
  .board .square__premium { font-size: clamp(8px, 2.6cqw, 14px); }
  .move-score { font-size: 12px; line-height: 14px; padding: 1px 3px; }
  .rack-action-row { flex-wrap: wrap; gap: 8px; }
  .rack-region { flex-basis: 100%; }
  .rack { gap: 5px; padding-inline: 6px; }
  .rack .tile__letter { font-size: clamp(22px, 7.5cqw, 30px); transform: translateY(-2px); }
  .rack .tile__points { font-size: clamp(10px, 3cqw, 14px); }
  .preview { width: 100%; }
  .game-page .button--play { min-width: 0; width: 100%; min-height: 56px; padding: 4px 12px; font-size: 1.5rem; }
  .action-bar { margin-top: 8px; }
  .controls { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
  .controls .button, .game-options > .button { flex-direction: column; gap: 3px; padding: 6px 2px; min-width: 0; font-size: 0.9rem; }
  /* Chat sits below the controls/options on phones, matching the desktop order
     it gets from the DOM; without this the flex default (0) floats it up. */
  .game-chat { order: 5; }
  .game-chat__messages { max-height: 12rem; }
  .preview__message:has(.preview__error:not(:empty)) {
    position: static; width: 100%; height: auto; clip: auto; white-space: normal;
    overflow: visible; order: 3; margin: 8px 0 0; padding: 10px 12px;
    border: 1px solid var(--line); border-radius: 10px; background: var(--paper);
  }
}

@media (max-width: 950px) and (max-height: 500px) and (orientation: landscape) {
  .game { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px 16px; width: 100%; align-items: start; }
  .game-scoreboard, .game > .flash { grid-column: 1 / -1; }
  .game-scoreboard { margin: 0; }
  .board-region { grid-column: 1; grid-row: 2 / span 3; margin: 0; }
  .board-scroll { width: min(100%, calc(100dvh - 156px)); margin: auto; }
  .game-play-dock, .preview__message, .game-options { grid-column: 2; }
}

/* Compact mobile game header and rack controls. */
@media (max-width: 600px) {
  html:has(.game-page) { scrollbar-gutter: auto; scrollbar-width: none; }
  .game-page .site-header { display: none; }
  .game-page .site-main {
    padding: max(0px, env(safe-area-inset-top, 0px)) max(6px, env(safe-area-inset-right, 0px))
      calc(12px + env(safe-area-inset-bottom, 0px)) max(6px, env(safe-area-inset-left, 0px));
  }

  .game-scoreboard {
    grid-template-columns: 44px minmax(0, 1fr) auto minmax(0, 1fr) 44px;
    column-gap: 4px;
    align-items: center;
    min-height: 60px;
    margin-bottom: 8px;
  }
  .player--you { grid-column: 2; }
  .game-status { grid-column: 3; }
  .status-banner { grid-column: 3; max-width: 30vw; padding: 4px 6px; }
  .status-banner--over { padding: 0; }
  .status-banner .game-rematch__button { min-height: 44px; padding: .45rem .6rem; font-size: .9rem; }
  .player--winner { padding: .3rem .4rem; }
  .player--opponent { grid-column: 4; }
  .game-back { grid-column: 1; }
  .player__number { font-size: 1.5rem; }

  .game-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    min-width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    border: 0;
    border-radius: 10px;
    background: none;
    color: var(--plum-deep);
    text-decoration: none;
    cursor: pointer;
  }
  .game-back .ui-icon { width: 1.4rem; height: 1.4rem; }
  .game-back:focus-visible { outline: 3px solid var(--teal); outline-offset: 2px; }

  .game-play-dock .button--play { min-height: 56px; }
  .game-chat--floating .game-chat__panel:not([open]) .game-chat__summary { min-height: 62px; padding: 6px 2px; font-size: .9rem; }
  .game-chat--floating .game-chat__panel:not([open]) .game-chat__summary-title { flex-direction: column; gap: 3px; }
  .game-chat--floating .game-chat__panel[open] {
    width: calc(100vw - 12px - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px));
  }
  .game-chat--floating .game-chat__summary-title { gap: 5px; }
  .game-chat--floating .game-chat__panel:not([open]) .game-chat__unread { position: absolute; top: 2px; right: 2px; background: var(--plum-deep); color: white; min-width: 1.1rem; padding: 0 3px; font-size: .8rem; }

}

/* ----------------------------------------------------------------- dialogs */

dialog.dialog {
  border: none;
  border-radius: var(--radius-lg);
  padding: 0;
  max-width: min(38rem, calc(100vw - 2rem));
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 18px 40px rgba(59, 42, 69, 0.3);
}

dialog.dialog::backdrop {
  background: rgba(59, 42, 69, 0.45);
}

.dialog__inner {
  padding: 1.5rem;
  display: grid;
  gap: 1rem;
}

.dialog__title {
  font-size: 1.4rem;
  color: var(--plum-deep);
}

.dialog__text {
  color: var(--ink-soft);
}

.dialog__actions {
  display: flex;
  gap: 0.75rem;
  justify-content: flex-end;
  flex-wrap: wrap;
}

@media (min-width: 900px) {
  #confirm-dialog[data-kind="play"] { width: 40rem; max-width: calc(100vw - 4rem); }
  #confirm-dialog[data-kind="play"] .dialog__inner { padding: 2.25rem; gap: 1.5rem; }
  #confirm-dialog[data-kind="play"] .dialog__title { font-size: 2rem; }
  #confirm-dialog[data-kind="play"] .dialog__text { font-size: 1.25rem; }
  #confirm-dialog[data-kind="play"] .button { min-height: 56px; font-size: 1.2rem; }
}

.letter-grid .button--letter { min-height: 56px; }

.letter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(56px, 1fr));
  gap: 0.45rem;
}

.swap-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  padding: 0.5rem 0;
}

.swap-choice {
  position: relative;
  cursor: pointer;
}
.swap-choice .tile { width: 3.5rem; height: 3.5rem; }
.swap-choice .tile__letter { font-size: 2rem; }
.swap-choice input:checked + .tile {
  background: #d8eee4;
  border-color: #15695a;
  outline: 3px solid #15695a;
  outline-offset: 2px;
}
.swap-choice input:focus-visible + .tile {
  outline: 3px solid #2b607f;
  outline-offset: 5px;
}

/* ------------------------------------------------------------------- flash */

.flash-stack, .game > .flash {
  position: fixed;
  top: auto;
  left: auto;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom));
  z-index: 90;
  width: min(28rem, calc(100% - 2rem));
  max-height: 50dvh;
  overflow-y: auto;
  display: grid;
  gap: 0.4rem;
  pointer-events: none;
}

.game > .flash { bottom: calc(max(1rem, env(safe-area-inset-bottom)) + var(--flash-banner-height, 0px)); }

.flash {
  position: relative;
  z-index: 90;
  display: grid;
  gap: 0.4rem;
}

.flash:not(:has(.flash__message)) {
  display: none;
}

.flash .flash__message {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1.1rem 1.25rem;
  background: var(--teal);
  color: #fff;
  border: 2px solid var(--green-deep);
  border-radius: 16px;
  box-shadow: 0 8px 28px #200e3038;
  font-size: 1.2rem;
  font-weight: 500;
  line-height: 1.45;
  pointer-events: auto;
}
.flash .flash__alert { background: #873928; border-color: #692619; }
.flash__message p { align-self: center; overflow-wrap: anywhere; min-width: 0; }
.flash__icon {
  flex: 0 0 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border: 2px solid currentColor;
  border-radius: 50%;
  font-size: 1.25rem;
  line-height: 1;
}
.flash__dismiss {
  flex: 0 0 44px;
  margin-left: auto;
  min-height: 44px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 1.5rem;
  cursor: pointer;
}
.flash__dismiss:hover { background: #ffffff24; }
.flash__dismiss:focus-visible { outline: 3px solid white; outline-offset: 2px; }

@media (max-width: 600px) {
  .flash .flash__message {
    padding: 10px 12px; gap: 8px; font-size: 1rem; line-height: 1.35;
    border-width: 1px; border-radius: 12px; box-shadow: var(--shadow-sm);
  }
  .flash__icon { display: none; }
}

.is-pending {
  cursor: progress;
}

.is-pending .rack,
.is-pending .controls,
.is-pending .board-scroll {
  opacity: 0.72;
}

/* sign-in and onboarding: the shared card plus the onboarding, entry, and
   invitation variants and the miniature welcome board. */

.signin {
  max-width: 30rem;
  min-width: 0;
  overflow-wrap: anywhere;
  margin: 2rem auto;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 2rem;
  box-shadow: var(--shadow-md);
  display: grid;
  gap: 1rem;
}

.signin__title {
  font-size: 1.8rem;
  color: var(--plum-deep);
}

.signin__text {
  color: var(--ink-soft);
}

.signin__list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

/* Sign-in form. */

.signin__form {
  display: grid;
  gap: 1rem;
}

.signin__text--quiet {
  font-size: 0.95rem;
}

/* --------------------------------------------------------------- onboarding */

.onboarding {
  min-height: 100vh;
}

.onboarding:not(.home-page) {
  background:
    radial-gradient(circle at 12% 15%, #fffdf7 0 7rem, transparent 19rem),
    linear-gradient(155deg, #f8eedb 0%, #fbf5e9 50%, #e8f0e9 100%);
}

.onboarding .site-main {
  max-width: 32rem;
  padding-top: clamp(2.5rem, 10vh, 6rem);
}

.onboarding .signin {
  max-width: 31rem;
  margin: 0 auto;
  padding: 0;
  gap: 1.15rem;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.onboarding .signin__title {
  font-size: clamp(1.875rem, 4vw, 2.25rem);
  overflow-wrap: anywhere;
}

.onboarding .signin__text {
  color: #57475e;
  font-size: 1.15rem;
  overflow-wrap: anywhere;
}

.onboarding .signin__text--quiet {
  color: #6d5b4b;
  font-size: 1rem;
  display: grid;
  gap: 0.1rem;
}

/* Shared welcome text and form grouping. */
.onboarding__intro,
.onboarding__signin {
  display: grid;
  gap: 1.15rem;
  justify-items: center;
  min-width: 0;
}

.onboarding__intro {
  gap: 0.75rem;
  max-width: 29rem;
  margin-inline: auto;
  text-align: center;
}

.onboarding .field {
  gap: 0.45rem;
  min-width: 0;
}

.onboarding .field__label {
  color: #493852;
  font-size: 1.1rem;
}

.onboarding .input {
  width: 100%;
  min-height: 3.45rem;
  padding: 0.75rem 0.9rem;
  border-color: #bfa878;
  background: #fffdf8;
  box-shadow: inset 0 1px 2px rgba(91, 66, 45, 0.08);
  font-size: 1.15rem;
}

.onboarding .signin__form {
  min-width: 0;
}

.onboarding__button {
  min-height: 3.45rem;
  background: linear-gradient(var(--teal), var(--green-deep));
  border-color: var(--green-deep);
  border-bottom-width: 3px;
  box-shadow: inset 0 1px 0 #ffffff4d, 0 3px 0 var(--green-deep), 0 5px 9px rgba(31, 90, 84, 0.2);
  font-size: 1.18rem;
}

.onboarding__button:hover:not(:disabled) {
  background: linear-gradient(#328449, var(--teal));
}

.onboarding__button:active:not(:disabled) {
  transform: translateY(2px);
  box-shadow: inset 0 1px 3px rgba(16, 61, 57, 0.4), 0 1px 0 var(--green-deep);
}

/* A miniature board fragment: the real board's ivory squares, premium
   colours, centre star, and raised tiles at a small decorative size. Scoped
   under .onboarding so the play board itself never changes. It is a picture,
   not a control: the markup marks it aria-hidden and the copy above it says
   what the game is. */
.onboarding__preview {
  display: grid;
  grid-template-columns: repeat(5, 2.05rem);
  gap: 2px;
  width: fit-content;
  max-width: 100%;
  margin: 0.15rem auto;
  padding: 5px;
  border: 1px solid #ceb98e;
  border-radius: 10px;
  background: linear-gradient(#eedfbe, #dfcba1);
  box-shadow: inset 0 1px 0 #fffdf4, inset 0 -2px 0 #d6c5a1, 0 2px 0 #d3c29c,
    0 8px 16px rgba(101, 83, 52, 0.16);
}

.onboarding__preview-square {
  display: grid;
  aspect-ratio: 1 / 1;
  place-items: center;
  border-radius: 5px;
  background: #fbf4e3;
  box-shadow: inset 1px 1px 0 #fffdf7, inset -1px -1px 0 #8e785322, inset 0 1px 2px #8e78531c;
  color: #46546a;
}

.onboarding__preview-square--double-letter { background: #d2e4f0; color: #305a75; }
.onboarding__preview-square--triple-letter { background: #b6d9ca; color: #23574c; }
.onboarding__preview-square--double-word { background: #f1d3c7; color: #8a4b3e; }
.onboarding__preview-square--triple-word { background: #e8a08c; color: #6b2a1d; }
.onboarding__preview-square--center { background: #f6e3ac; color: #7d5410; }

.onboarding__preview-tile {
  display: grid;
  width: 88%;
  height: 88%;
  place-items: center;
  border: 1px solid #d9c096;
  border-top-color: #fffef9;
  border-bottom: 2px solid #cdae74;
  border-radius: 6px;
  background: linear-gradient(166deg, #fffdf7, #fff2d8);
  box-shadow: inset 1px 1px 0 #ffffffd9, inset -1px -1px 0 #bc965b29, 0 2px 0 #c3a771,
    0 4px 6px #5c492229;
  color: var(--plum-deep);
}

.onboarding__preview-letter {
  font-size: 1.05rem;
  font-weight: 500;
  line-height: 1;
  transform: translate(-1px, -1px);
}

.onboarding__preview-premium {
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-shadow: 0 1px 0 #ffffff8c;
}

.onboarding__preview-star { font-size: 0.9rem; text-shadow: 0 1px 0 #ffffff8c; }

@media (min-width: 64rem) {
  .onboarding .site-main { max-width: 62rem; }

  /* The 194px board fragment grows to about 348px on the invitation and
     magic-link screens, with the squares, letters, and premium labels scaled
     to match it. */
  .onboarding__preview {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    width: min(100%, 20.5rem);
    gap: 3px;
    padding: 7px;
    margin: 0.35rem auto;
  }

  .onboarding__preview-square { border-radius: 8px; }
  .onboarding__preview-tile { border-radius: 9px; }
  .onboarding__preview-letter { font-size: 1.8rem; }
  .onboarding__preview-premium { font-size: 1rem; }
  .onboarding__preview-star { font-size: 1.5rem; }
}

@media (max-width: 600px) {
  .onboarding .site-main { padding: 1.5rem 1rem 2.5rem; }
  .onboarding .signin { margin: 0; }
  .onboarding__preview { margin-top: 0; }
}

/* Entry sign-in: one centered welcome, with the real game's tiles. */

.onboarding--entry {
  background: radial-gradient(ellipse at 50% 25%, var(--paper) 0%, var(--cream) 65%, var(--cream-deep) 100%);
}

.onboarding--entry .site-main { max-width: var(--site-max); padding: 1rem 1.5rem 3rem; }
.onboarding--entry .signin { max-width: none; gap: 2.3rem; }
.onboarding--entry .onboarding__intro { max-width: 40rem; gap: 0.9rem; }
.onboarding--entry .signin__title { font-size: clamp(1.9rem, 3.3vw, 2.8rem); }
.onboarding--entry .signin__text { font-size: clamp(1.15rem, 2vw, 1.55rem); }
.onboarding--entry .onboarding__signin { width: min(100%, 40rem); margin-inline: auto; gap: 1.5rem; }
.onboarding--entry .signin__form { width: 100%; gap: 1.2rem; }
.onboarding--entry .field__label { font-size: clamp(1.1rem, 2vw, 1.5rem); }
.onboarding--entry .input,
.onboarding--entry .onboarding__button { min-height: 4.4rem; font-size: clamp(1.15rem, 2.2vw, 1.7rem); border-radius: 16px; }
.onboarding--entry .input { padding-inline: 1.25rem; border: 2px solid #d1b483; }
.onboarding--entry .input::placeholder { color: #756e68; opacity: 1; }
.onboarding--entry .signin__text--quiet { display: block; font-size: clamp(1rem, 1.7vw, 1.25rem); text-align: center; color: #615466; }

.onboarding--entry:has(.signin-confirmation) .brand__art { width: 180px; }

.signin-confirmation {
  width: min(100%, 40rem);
  margin: clamp(1rem, 4vh, 3rem) auto 0;
  padding: clamp(1.5rem, 4vw, 3rem);
  display: grid;
  justify-items: center;
  gap: 1.2rem;
  text-align: center;
  background: #e4f2e9;
  border: 2px solid #9bcabb;
  border-radius: 22px;
  box-shadow: 0 6px 18px #235e4912;
}
.signin-confirmation__check {
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: var(--teal);
  color: white;
  font-size: 2.4rem;
  font-weight: 500;
}
.signin-confirmation__help { color: #425b51; font-size: 1.1rem; line-height: 1.6; }
.signin-confirmation__back { min-height: 56px; font-size: 1.15rem; background: #fffdf7; }

.welcome-board {
  --frame-pad: 8px;
  --frame-edge: 1px;
  --board-gap: 3px;
  --plum-deep: #33304a;
  --tile-edge: #d9c096;
  width: min(100%, 40rem);
  margin-inline: auto;
  pointer-events: none;
  user-select: none;
}
.welcome-board__grid { grid-template-columns: repeat(9, 1fr); grid-template-rows: repeat(2, 1fr); aspect-ratio: 9 / 2; }
.welcome-board .tile__letter { font-size: 4.85cqw; }

@media (max-width: 600px) {
  .onboarding--entry .site-main { padding: 1rem 1rem 2rem; }
  .onboarding--entry .signin { gap: 1.6rem; }
  .onboarding--entry .input, .onboarding--entry .onboarding__button { min-height: 3.6rem; }
  .welcome-board { --frame-pad: 5px; --board-gap: 2px; }
  .welcome-board__grid { grid-template-columns: repeat(7, 1fr); aspect-ratio: 7 / 2; }
  .welcome-board .square:nth-child(9n + 1),
  .welcome-board .square:nth-child(9n + 9) { display: none; }
  .welcome-board .tile__letter { font-size: 7cqw; }
  .welcome-board .square__premium { font-size: 12px; }
}

/* lobby: the shared .home base plus the signed-in home-page composition,
   cards, invites, artwork, and their responsive rules. */

.home {
  display: grid;
  gap: 2rem;
  max-width: 46rem;
}

.game-list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 1rem;
}

.game-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
  display: grid;
  gap: 0.9rem;
  box-shadow: var(--shadow-sm);
}

.game-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.game-card__title {
  font-size: 1.15rem;
}

.score-line {
  display: flex;
  gap: 1.5rem;
}

.score-line__item dt {
  color: var(--ink-soft);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.score-line__item dd {
  font-size: 1.6rem;
  font-weight: 500;
  color: var(--plum-deep);
}

/* Lobby composition: the page column fills the viewport so the tagline can
   rest at the bottom edge of a short lobby, and the games and invitation panels
   share one bounded frame. */
.home-page .site-header__inner { max-width: var(--site-max); width: 100%; margin-inline: auto; }
.home-page .site-main { max-width: var(--site-max); padding: 3.5rem var(--lobby-gutter, 1.5rem) 3rem; width: 100%; flex: 1 1 auto; display: flex; flex-direction: column; }
.home-page .home { --lobby-control: 64px; max-width: none; min-width: 0; gap: 1.5rem; font-size: 1.2rem; color: var(--ink-soft); overflow-wrap: break-word; flex: 1 1 auto; display: flex; flex-direction: column; }
.home-page .home__frame { display: grid; gap: 1.75rem; min-width: 0; width: 100%; max-width: var(--lobby-max, 79rem); margin-inline: auto; }
/* Sticky lobby footer: the page column fills the viewport, so the tagline
   rests near the bottom edge when the lobby is short and is simply pushed
   below the content when the lobby is long. --lobby-gutter is the shared
   header/main horizontal gutter: 40/28/18 CSS px at the 17px root, kept in rem
   so it still scales with the reader's font size and browser zoom. */
body.home-page { isolation: isolate; display: flex; flex-direction: column; min-height: 100dvh; --lobby-gutter: 2.35rem; --lobby-max: 80rem; }
/* Compensate for the app’s 80% CSS zoom so short lobbies still fill the screen. */
html[data-app-zoom="0.8"] body.home-page { min-height: 125dvh; }
/* The tagline and the closing art share one bounded footer. The negative
   inline and bottom margins let that band reach the page edges and the
   viewport bottom without ever using 100vw, so no scrollbar overflow. */
.home-page .home__footer { margin-top: auto; margin-inline: calc(-1 * var(--lobby-gutter, 1.5rem)); margin-bottom: -3rem; }

.home-page .section-heading { margin: 0; text-transform: none; letter-spacing: 0; color: var(--plum-deep); }
.home-page .home__title { font-size: clamp(1.8rem, 3vw, 2.45rem); line-height: 1.15; }
.home__welcome { display: flex; justify-content: space-between; align-items: center; gap: 2rem; }
.home__welcome #player-search-help { font-size: 1.1rem; margin-top: .5rem; }
.home__search-help--mobile { display: none; }
.home__welcome .home__train-accent { display: block; flex: none; width: 5.75rem; height: auto; transform: translateX(-1rem) scale(1.6) rotate(-8deg); opacity: .9; pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  html:has(.home-page) { scroll-behavior: smooth; }
}
.home-page .lobby-card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 1.75rem; min-width: 0; }
.home__active { display: grid; gap: 1rem; }
.home__invite { display: grid; gap: 1.5rem; }
.home__share-invite { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center; row-gap: .5rem; min-width: 0; }
.invite-link { display: contents; }
.invite-link__field { grid-column: 1; position: relative; min-width: 0; }
.invite-link__icon { position: absolute; inset: 0 auto 0 0; display: grid; place-items: center; width: 4.2rem; color: var(--teal); font-size: 1.65rem; pointer-events: none; }
.invite-link__url { min-width: 0; width: 100%; color: var(--ink-soft); user-select: all; }
.invite-link__url:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.invite-link__copy { grid-column: 3; width: 100%; height: var(--lobby-control); min-height: var(--lobby-control); padding-inline: 1.25rem; font-size: 1.35rem; box-shadow: var(--button-bevel); }
.invite-link__copy:hover { background: var(--green-deep); }
.invite-link__status { grid-column: 1 / -1; margin: 0; font-size: .9rem; color: var(--ink-soft); }
.invite-link__status:empty { display: none; }
.home__suggested .player-result { flex-wrap: wrap; border: 1px solid var(--line); border-radius: 16px; background: #fffdf899; }
.home__suggested .player-result__copy { flex: 1; min-width: 0; }
.home-page .home__suggested .button { min-height: var(--lobby-control); width: 100%; font-size: 1.35rem; }
.home__suggested-actions { display: grid; gap: .6rem; width: 100%; min-width: 0; }
.home-page .home__suggested-actions > form { margin: 0; width: 100%; }
.suggested-label--mobile, .invite-link__mobile-label { display: none; }
@media (min-width: 601px) {
  .home-page .home__suggested .player-result { display: grid; grid-template-columns: max-content minmax(0, 1fr) max-content; }
  .home__suggested-avatar { grid-column: 1; }
  .home__suggested .player-result__copy { grid-column: 2; }
  .home__suggested-actions { grid-column: 3; }
}
.home__choices { display: grid; grid-template-columns: minmax(0, 1fr) auto 16rem; align-items: center; gap: 2.25rem 1rem; }
.home__search { position: relative; min-width: 0; }
.home__search-results { position: absolute; top: calc(100% + .5rem); left: 0; right: 0; z-index: 20; max-height: min(24rem, 50vh); overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--line); border-radius: 16px; background: var(--paper); box-shadow: 0 8px 22px #35202224; }
.home__search-results[hidden],
.home__search-results:not(:has(.start-game__outcome:not([hidden]) > *, .start-game__status:not(.visually-hidden):not(:empty), #new-game-error:not(:empty))) { display: none; }
.home__search-results .player-results, .home__search-results .player-result { border: 0; border-radius: 0; }
.home__search-results .start-game__outcome > .start-game__state,
.home__search-results .start-game__status:not(.visually-hidden),
.home__search-results #new-game-error:not(:empty) { padding: 1rem; margin: 0; }
.home-page .start-game { width: 100%; min-width: 0; }
.home-page .field__row { position: relative; }
.home-page .input { min-height: var(--lobby-control); height: var(--lobby-control); font-size: 1.35rem; padding-left: 4.5rem; border-color: #d7cdbf; background: #fffefd; box-shadow: 0 3px 7px #35202208; }
.home-page .input:focus { border-color: var(--teal); outline: 3px solid var(--teal); outline-offset: 2px; box-shadow: 0 0 0 6px var(--teal-soft); }
.home-page .invite-link__url { background: #f7f6f4; border-color: transparent; box-shadow: none; }
.home-page .start-game__search { position: absolute; inset: 0 auto 0 0; width: 4.2rem; border: 0; background: transparent; color: var(--teal); cursor: pointer; border-radius: var(--radius); }
.home-page .start-game__search svg { width: 1.85rem; height: 1.85rem; }
.home__or { display: grid; justify-items: center; gap: .4rem; font-size: 1rem; }
.home__or::before, .home__or::after { content: ""; width: 1px; height: 1.4rem; background: #e3d2b3; }
.home__ponybot { display: flex; align-items: center; justify-content: center; gap: .75rem; min-width: 0; padding-inline: .5rem; }
.home__ponybot-mascot { display: block; width: 5rem; height: 5rem; flex: none; object-fit: contain; }
.home__ponybot form { min-width: 0; }
.home__ponybot-action { appearance: none; display: flex; align-items: center; justify-content: center; min-height: 56px; padding: .25rem 0; border: 0; background: transparent; box-shadow: none; color: var(--plum-deep); font: inherit; font-size: 1.35rem; font-weight: 500; text-align: center; cursor: pointer; }
.computer-icon { width: 3.4rem; height: 3.4rem; flex-shrink: 0; object-fit: contain; }
.home__ponybot-label { white-space: nowrap; }
.home__ponybot-copy { display: grid; min-width: 0; gap: .1rem; }
.home__ponybot-note { display: none; }
.home__tagline { display: flex; align-items: center; justify-content: center; gap: .7rem; margin: 0; color: var(--ink-soft); font-size: 1.05rem; font-weight: 500; }
.home__tagline-rule { flex: none; width: 2.5rem; height: 1px; background: #dcc9a2; }
.home__tagline .ui-icon { flex: none; width: 1.15rem; height: 1.15rem; color: #c39a4a; fill: currentColor; stroke: none; }
/* Anchor the racetrack scenery at the bottom, cropping the banner's empty sky. */
body { isolation: isolate; }
.site-backdrop {
  position: fixed; left: 0; bottom: 0; z-index: -1;
  width: 100%; height: auto; aspect-ratio: 5 / 1;
  object-fit: cover; object-position: 50% 100%;
  opacity: .18; pointer-events: none;
}
@media (min-width: 1101px) {
  /* Keep the existing art visible at the viewport edge, behind the lobby. */
  .home-page .home__footer { padding-bottom: max(6rem, 8vw); }
}
.home-page .start-game__status:empty, .home-page .start-game__outcome:empty, .home-page .start-game__outcome[hidden] { display: none; }
.home-page .start-game__outcome { margin: 0; }
.home-page .start-game__state { margin: 0; color: var(--ink-soft); }
.home-page .player-results { list-style: none; padding: 0; margin: 0; border: 1px solid var(--line); border-radius: 16px; overflow: hidden; background: #fffdf899; }
.home-page .player-result { display: flex; align-items: center; gap: 1.2rem; min-width: 0; padding: .85rem 1.25rem; }
.home-page .player-results .player-result + .player-result { border-top: 1px solid var(--line); }
.home-page .player-result--invite, .home-page .player-result--none { border: 1px solid var(--line); border-radius: 16px; background: #fffdf899; }
.home-page .player-result__avatar, .game-card__avatar { display: grid; place-items: center; width: 3.5rem; height: 3.5rem; flex-shrink: 0; border: 1px solid #200e302e; border-radius: 50%; background: var(--teal-soft); color: var(--green-deep); font-weight: 500; font-size: 1.3rem; }
.home-page .player-result__avatar--1 { background: #d2e4f0; color: #305a75; }
.home-page .player-result--invite .player-result__avatar { background: #f1d3c7; color: #8a4b3e; }
.home-page .player-result--none .player-result__avatar { background: #eee9e4; color: var(--ink-soft); }
.home-page .player-result__avatar svg { width: 1.7rem; height: 1.7rem; }
.home-page .player-result__name { min-width: 0; overflow-wrap: anywhere; font-weight: 500; color: var(--plum-deep); }
.home-page .player-result__copy { min-width: 0; }
.home-page .player-result form { margin-left: auto; flex-shrink: 0; }
.home-page .onboarding__button { min-height: 58px; font-size: 1.15rem; }
.home-page .player-result .onboarding__button { min-width: 12rem; }
.home-page .player-result--invite { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem 1rem; }
.home-page .player-result--invite > .player-result__name { grid-column: 1 / -1; overflow-wrap: anywhere; }
.home-page .player-result--invite > .player-result__copy { grid-column: 1; grid-row: 2; }
.home-page .player-result--invite > form { grid-column: 2; grid-row: 2; align-self: center; }
.home-page .player-result--invite .onboarding__button { min-width: 0; }

.home-page .home__games { display: grid; gap: 1.25rem; min-width: 0; }
.home-page .home__games-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.home-page .home__games-title { font-size: clamp(1.75rem, 4.2vw, 3.5rem); margin: 0; }
.home-page .home__new-game { display: inline-flex; align-items: center; gap: .6rem; min-height: 76px; padding: .65rem 1.75rem; font-size: 1.6rem; font-weight: 500; white-space: nowrap; }
.home-page .home__empty { margin: 0; padding: 1.2rem 0; }
.home-page .home__empty-art { width: 100%; max-width: 17rem; height: 6rem; object-fit: cover; object-position: 50% 60%; }
.home-page .game-list { margin: 0; }
.game-list__heading { list-style: none; margin: .65rem 0 0; }
.game-list__heading h2 { display: flex; align-items: center; gap: .65rem; margin: 0; font-size: 1.1rem; font-weight: 500; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.game-list__count { display: inline-grid; place-items: center; min-width: 1.8rem; height: 1.8rem; border-radius: 50%; background: #85818b; color: #fff; font-size: 1rem; }
.game-list__count--turn { background: var(--green-deep); }
.home__more-heading, .home__find-friend { display: none; }


/* Active rows keep identity and an optional nudge on the left, scores and
   the board link on the right. Nudge remains a separate accessible control. */
.home-page .game-card { position: relative; min-width: 0; padding: .85rem 1.25rem; background: var(--paper); border: 1px solid #ecdcc0; border-radius: 16px; box-shadow: 0 2px 4px #35202210; }
.home-page .game-card--active { grid-template-columns: minmax(0, 1fr) minmax(10rem, 12rem) 56px; grid-template-areas: "identity scores actions"; align-items: center; gap: .75rem 1.25rem; min-height: 144px; }
.home-page .game-card--turn { background: var(--paper); border-color: #ecdcc0; }
.home-page .game-card--waiting { background: var(--paper); border-color: #ecdcc0; }
.home-page .game-card--over { border-color: #e1dbe7; }
.home-page .game-card.game-card--invitation { background: var(--paper); border-color: var(--line); grid-template-columns: minmax(0, 1fr) 10rem 10rem; grid-template-areas: "identity scores status"; }
.game-card__accept { grid-area: status; margin: 0; width: 100%; }
.game-card__status--accept { background: var(--teal); border-color: var(--green-deep); color: #fff; }
.game-card__invitation-error { grid-column: 1 / -1; margin: 0; color: #8c3e2f; }
.game-card__invitation-error:empty { display: none; }

.game-card__identity { grid-area: identity; display: flex; align-items: center; gap: .85rem; min-width: 0; }
.game-card__who { min-width: 0; }
.game-card__name { display: flex; align-items: center; gap: 0; }
.game-card__name .game-nudge { position: relative; z-index: 2; flex: none; }
.home-page .game-card__name .game-nudge__button { width: 56px; }
.home-page .game-card__name .game-nudge .game-nudge__button { justify-content: flex-start; padding-left: .9rem; }
.home-page .game-card__title { font-size: 1.6rem; margin: 0; color: var(--plum-deep); overflow-wrap: anywhere; }
.game-card__meta { display: block; margin-top: .15rem; font-size: 1.15rem; font-weight: 500; color: var(--ink-soft); white-space: nowrap; }
.game-card__avatar { position: relative; width: 5rem; height: 5rem; background: var(--gold-soft); color: var(--plum-deep); font-size: 2rem; }
.game-card--turn .game-card__avatar:not(:has(.game-card__unread-chat))::after,
.game-card__unread-chat { position: absolute; right: 14.65%; bottom: 14.65%; translate: 50% 50%; }
.game-card--turn .game-card__avatar:not(:has(.game-card__unread-chat))::after {
  content: "";
  width: .8rem;
  height: .8rem;
  border: 2px solid var(--paper);
  border-radius: 50%;
  background: var(--green-deep);
}
@media (prefers-reduced-motion: no-preference) {
  .game-card--turn .game-card__avatar:not(:has(.game-card__unread-chat))::after { animation: turn-dot-pulse 2s ease-in-out infinite; }
}
.game-card__unread-chat { display: grid; place-items: center; min-width: 1.25rem; height: 1.25rem; padding-inline: .2rem; border: 2px solid var(--paper); border-radius: 999px; background: var(--plum-deep); color: #fff; font-size: .75rem; line-height: 1; font-weight: 500; }
.game-card:nth-child(4n + 2) .game-card__avatar { background: var(--lavender-soft); }
.game-card:nth-child(4n + 3) .game-card__avatar { background: #d2e4f0; }
.game-card:nth-child(4n + 4) .game-card__avatar { background: var(--teal-soft); }
.home-page .game-card__avatar .computer-icon { width: 3.5rem; height: 3.5rem; }

/* Paired lobby scores keep the board's .score-line untouched: a new grid puts
   your score first, a divider, then the opponent's. */
.game-card__scores { grid-area: scores; justify-self: center; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: center; gap: 1.4rem; width: 100%; max-width: 12rem; margin: 0; }
.game-card__score { min-width: 0; text-align: center; }
.game-card__score dt { max-width: 7rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: .15rem; font-size: 1rem; line-height: 1.3; font-weight: 500; color: var(--ink-soft); }
.game-card__score + .game-card__score { position: relative; }
.game-card__score + .game-card__score::before { content: "|"; position: absolute; left: -.7rem; top: calc(50% + .72rem); transform: translate(-50%, -50%); font-size: 1.5rem; font-weight: 500; color: #c9b9a4; }

.game-card__score dd { margin: 0; font-size: 2.8rem; line-height: 1.1; font-weight: 600; color: var(--plum-deep); font-variant-numeric: tabular-nums; }

.game-card__status { position: relative; z-index: 1; grid-area: status; justify-self: center; min-width: 0; display: inline-flex; align-items: center; justify-content: center; width: 100%; max-width: 16rem; min-height: 58px; padding: .7rem 1.1rem; border: 1px solid; border-radius: 14px; box-shadow: var(--button-bevel); font-size: 1.3rem; font-weight: 500; text-align: center; overflow-wrap: anywhere; }
.game-card__status--turn { background: var(--green-deep); border-color: var(--green-deep); color: #fff; gap: .55rem; }
.game-card__status--turn::before { content: ""; width: .6rem; height: .6rem; border-radius: 50%; background: currentColor; flex: none; }
@media (prefers-reduced-motion: no-preference) {
  .game-card__status--turn::before { animation: turn-dot-pulse 2s ease-in-out infinite; }
}
@keyframes turn-dot-pulse {
  50% { opacity: .65; transform: scale(.8); }
}
.game-card__status--waiting { background: var(--gold-bright); border-color: #c59a12; color: var(--plum-deep); }

.game-card__actions { grid-area: actions; display: grid; grid-template-columns: 56px; align-items: center; gap: 1.25rem; min-width: 0; }
.game-card__actions .game-nudge { position: relative; z-index: 1; justify-self: stretch; }
.game-card__actions .game-card__open { grid-column: 1; }
.game-card__actions .game-nudge, .game-card__actions form { display: grid; min-width: 0; }
.home-page .game-card .game-nudge__button { width: 56px; min-height: 56px; padding: 0; font-size: 1.3rem; background: transparent; border: 0; color: var(--green-deep); box-shadow: none; }
.home-page .game-card .game-nudge__button > span { display: none; }

.game-card__open { display: inline-flex; align-items: center; justify-content: center; width: 56px; height: 56px; flex: none; border-radius: .4rem; background: transparent; border: 0; color: var(--plum-deep); font-size: 1.9rem; line-height: 1; font-weight: 500; text-decoration: none; }
.game-card__open::after { content: ""; position: absolute; inset: 0; border-radius: 16px; }
.game-card:has(.game-card__open:focus-visible) { outline: 3px solid var(--teal); outline-offset: 3px; }
.lobby-chevron { display: inline-block; flex: none; width: 1em; font-size: 1.1rem; line-height: 1; text-align: center; }

/* Existing games lead the lobby; green marks a turn ready to play. */
.home-page .game-card--active { border-width: 2px; box-shadow: 0 4px 12px #200e3014; }
.home-page .game-card--active .game-card__title { font-size: 1.8rem; }
.home-page .game-card--active .game-card__score dd { font-size: 3rem; }
.home-page .button--secondary,
.home-page .finished-games__more { background: var(--gold-bright); border-color: #c59a12; color: var(--plum-deep); box-shadow: var(--button-bevel); }
.home-page .home__suggested-reroll { background: #e9e8ec; border-color: #c7c3cb; color: var(--plum-deep); }
.home-page .home__new-game,
.home-page .game-card--waiting .game-card__status { background: var(--plum); border-color: var(--plum-deep); color: var(--paper); }
.home-page:has(.game-card--active) .home__train-accent { display: none; }
.home-page:has(.game-card--active) .home__title { font-size: 1.6rem; }

/* Finished rows: identity with an explicit result, paired scores, the finished
   date, then the same chevron that opens the post-game page (where Rematch
   already lives). */
.home-page .game-card--finished { grid-template-columns: minmax(0, 1fr) 12rem minmax(10rem, .8fr) 44px; grid-template-areas: "identity scores finished-at open"; align-items: center; gap: .6rem 1.1rem; min-height: 90px; padding: .6rem 1.1rem; background: transparent; border: 0; border-radius: 0; box-shadow: none; }
.home-page .game-card--finished .game-card__avatar { width: 3.5rem; height: 3.5rem; font-size: 1.4rem; }
.home-page .game-card--finished .game-card__avatar .computer-icon { width: 1.8rem; height: 1.8rem; }
.home-page .game-card--finished .game-card__title { font-size: 1.35rem; }
.home-page .game-card--finished .game-card__score dd { font-size: 1.85rem; }
.game-card--finished .game-card__scores { align-items: end; max-width: 18rem; }
.game-card--finished .game-card__score dt { max-width: none; overflow: visible; white-space: normal; overflow-wrap: anywhere; }
.game-card__result { display: block; margin-top: .15rem; font-size: 1.1rem; color: var(--ink-soft); }
.game-card__result--won { color: #17574a; }
.game-card__result--lost { color: #843e30; }
.game-card__finished-at { grid-area: finished-at; justify-self: end; font-size: 1.1rem; font-weight: 500; color: var(--ink-soft); white-space: nowrap; }
.game-card--finished > .game-card__open { grid-area: open; }

.finished-games { display: block; }
:is(.finished-games__summary, .pending-invitations__summary) { display: flex; align-items: center; gap: .65rem; min-height: 44px; cursor: pointer; font-size: 1.65rem; font-weight: 600; line-height: 1.2; color: var(--plum-deep); list-style: none; }
:is(.finished-games__summary, .pending-invitations__summary) > .ui-icon { width: 1em; height: 1em; font-size: 1em; flex-shrink: 0; }
:is(.finished-games__summary, .pending-invitations__summary) > span:not(.site-header__count) { min-width: 0; }
:is(.finished-games__summary, .pending-invitations__summary)::-webkit-details-marker { display: none; }
:is(.finished-games__summary, .pending-invitations__summary) > .lobby-chevron { margin-left: auto; }
details[open] > :is(.finished-games__summary, .pending-invitations__summary) > .lobby-chevron { transform: rotate(90deg); }
:is(.finished-games__summary, .pending-invitations__summary):focus-visible { outline: 3px solid #267e74; outline-offset: 3px; border-radius: .3rem; }

/* Compact cream disclosure cards for Finished Games and Pending Invitations,
   with a pale gold count beside the title and the chevron at the right. */
.home-page details.finished-games, .home-page #lobby-invites { padding: .8rem 1.1rem; }
.home-page :is(.finished-games__summary, .pending-invitations__summary) { min-height: 56px; }
.home-page :is(.finished-games__count, .pending-invitations__count) { background: var(--gold-soft); color: var(--plum-deep); font-size: 1.05rem; }

.home-page .finished-games .game-list { margin: .6rem 0 0; gap: 0; }
.home-page .game-card--finished:has(~ .game-card--finished:not([hidden])) { border-bottom: 1px solid #e8dfd3; }
.home-page .game-list--finished > [hidden] { display: none; }
.finished-games__more { display: flex; align-items: center; justify-content: center; gap: .7rem; width: fit-content; min-width: 15rem; max-width: 100%; min-height: 44px; margin: .8rem auto 0; padding: .4rem 1rem; font: inherit; font-weight: 500; color: var(--plum-deep); background: #fffdf7; border: 1px solid #ecdcbe; border-radius: .65rem; box-shadow: var(--button-bevel); cursor: pointer; }
.finished-games__more[hidden] { display: none; }
.finished-games__more:hover { background: #fff; }
.home-page .pending-invites__item { border-style: solid; min-width: 0; }
.home-page .pending-invites__item strong { min-width: 0; max-width: 100%; }
.home-page .home__invite-error { color: #7d2f1e; font-weight: 500; margin-top: 1rem; }
.home-page .home__invite-error:empty, .home-page #lobby-invites[hidden] { display: none; }
@media (max-width: 1100px) {
  body.home-page { --lobby-gutter: 1.65rem; }
  .home-page .site-main { padding: 1.5rem var(--lobby-gutter, 1.25rem) 2rem; }
  .home-page .home__footer { margin-inline: calc(-1 * var(--lobby-gutter, 1.25rem)); margin-bottom: -2rem; }
  .home-page .lobby-card { padding: 1.35rem; }
  .home__welcome { display: block; }
  .home__welcome .home__train-accent { display: none; }
  .invite-link__icon { width: 2.8rem; }
  .home-page .input { font-size: 1.1rem; padding-left: 3rem; }
  .home-page .start-game__search { width: 2.8rem; }
  .home__ponybot { width: 100%; }
  .home-page .player-result { gap: .75rem; padding: 1rem; flex-wrap: wrap; }
  .home-page .player-result__name, .home-page .player-result__copy { flex: 1; }
  .home-page .player-result form { width: 100%; }
  .home-page .player-result .onboarding__button { width: 100%; min-width: 0; }
  .home-page .player-result--invite { grid-template-columns: minmax(0, 1fr); }
  .home-page .player-result--invite > form { grid-column: 1; grid-row: 3; }
  .home-page .game-card__actions { gap: 1rem; }
  /* Keep medium windows horizontal; only phones need stacked actions. */
  .home-page .game-card--active {
    grid-template-columns: minmax(0, 1fr) 11rem 56px;
    grid-template-areas: "identity scores actions";
    gap: .75rem;
    min-height: 108px;
    padding: .85rem 1rem;
  }
  .home-page .game-card--active .game-card__title { font-size: 1.35rem; }
  .home-page .game-card--active .game-card__score dd { font-size: 2rem; }
  .home-page .game-card__score dt { max-width: none; overflow: visible; white-space: normal; overflow-wrap: anywhere; }
  .home-page .game-card__scores { max-width: 11rem; }
  .home-page .game-card__meta { font-size: 1rem; white-space: normal; }
  .home-page .game-card__actions { grid-template-columns: 56px; gap: 0; }

  .home-page .home__games-title { font-size: 2.25rem; }
  .home-page .home__new-game { min-height: 56px; font-size: 1.2rem; padding: .5rem 1rem; }
  .home-page .game-card--finished {
    grid-template-columns: minmax(0, 1fr) 44px;
    grid-template-areas:
      "identity open"
      "scores scores"
      "finished-at finished-at";
    gap: .5rem .9rem;
    min-height: 0;
    padding: .65rem .9rem;
  }
  .home-page .game-card__avatar { width: 72px; height: 72px; font-size: 2rem; }
  .home-page .game-card__avatar .computer-icon { width: 60px; height: 60px; }
  .home-page .game-card__title { font-size: 1.1rem; }
  .home-page .game-card__score dd { font-size: 1.6rem; }
  .home-page .game-card__status { justify-self: start; font-size: 1.05rem; }
  .home-page .game-card__finished-at { grid-area: finished-at; }
}

@media (max-width: 760px) {
  .home__choices { grid-template-columns: 1fr; gap: .7rem; }
  .home__share-invite { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: .7rem; }
  .invite-link__copy { grid-column: 2; }
  .home__or { display: flex; justify-content: center; align-items: center; }
  .home__or::before, .home__or::after { height: 1px; width: 2rem; }
}

@media (max-width: 600px) {
  body.home-page { --lobby-gutter: 1.06rem; }
  .home-page .home__footer { margin-inline: 0; margin-bottom: 0; }
  .home-page .lobby-card { padding: .85rem; }
  .home__invite { gap: 1rem; }
  .home-page .home__games-title { font-size: 1.65rem; }
  .home-page .home__title { font-size: 1.8rem; }
  .home__welcome #player-search-help { margin-top: .8rem; font-size: 1.05rem; }
  .home__search-help--desktop { display: none; }
  .home__search-help--mobile { display: inline; }
  .home-page .home__empty-art { height: 5rem; }

  /* Search: a full-width 56px field with a 48px icon target. */
  .home-page .input { height: 56px; min-height: 56px; font-size: 1.06rem; padding-left: 3.4rem; }
  .home-page .start-game__search { width: 48px; }
  .home-page .start-game__search svg { width: 1.5rem; height: 1.5rem; }

  /* Keep the practice button compact on phones. */
  .home__or { display: none; }
  .home__choices { gap: .82rem; }
  .home__ponybot { margin-top: 0; }
  .home__ponybot-copy { line-height: 1.15; }
  .home__ponybot-label { font-size: 1.1rem; }
  .home__ponybot-note { display: block; font-size: 1rem; font-weight: 500; line-height: 1.2; color: var(--ink-soft); }

  /* Phones stack identity and centered scores above the game actions. */
  .home-page .game-card--active { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-areas: "identity identity" "scores scores" "status actions"; gap: .55rem .7rem; padding: .7rem .8rem; border-radius: 14px; }
  .home-page .game-card--finished {
    grid-template-columns: minmax(0, 1fr) 44px;
    grid-template-areas:
      "identity open"
      "scores scores"
      "finished-at finished-at";
    gap: .4rem .7rem;
    padding: .65rem .8rem;
    border-radius: 14px;
  }
  .home-page .game-card--finished > .game-card__open { align-self: center; }
  .home-page .home__games-header { gap: .5rem; }
  .home-page .home__new-game { min-height: 44px; font-size: 1rem; padding: .45rem .7rem; }
  .home-page .game-card__identity { gap: .65rem; }
  .home-page .game-card__avatar { width: 40px; height: 40px; font-size: 1.15rem; }
  .home-page .game-card__avatar .computer-icon { width: 28px; height: 28px; }
  .home-page .game-card__title { font-size: 1.1rem; overflow-wrap: anywhere; }
  .home-page .game-card__meta { font-size: .95rem; }
  .home-page .game-card__score dd { font-size: 1.7rem; }
  .home-page .game-card__score + .game-card__score::before { font-size: 1.3rem; }
  .home-page .game-card__status { justify-self: center; width: auto; max-width: 100%; min-height: 44px; padding: .35rem .7rem; }
  .home-page .game-card--active .game-card__scores { justify-self: center; }
  .home-page .game-card__actions { gap: .7rem; }
  .home-page .game-card .game-nudge__button { min-height: 44px; padding: 6px 8px; font-size: 1rem; }
  .home-page .game-card__finished-at { justify-self: end; font-size: .85rem; }
  .home-page .game-card--finished .game-card__title { font-size: 1.1rem; }
  .home-page .game-card--finished .game-card__score dd { font-size: 1.45rem; }
  .home-page .game-card--finished .game-card__avatar { width: 40px; height: 40px; }
  .home-page .game-card--finished .game-card__scores { justify-self: start; }
  .finished-games .game-list { margin-top: .5rem; }
  :is(.finished-games__summary, .pending-invitations__summary) { font-size: 1.25rem; gap: .5rem; }
}

@media (max-width: 380px) {

  /* Keep the heading and shortcut on one line on the smallest phones. */
  .home-page .home__games-title { font-size: 1.4rem; }
  .home-page .home__new-game { font-size: .94rem; padding-inline: .5rem; gap: .25rem; }
  /* Keep the avatar on the smallest phones, just a touch smaller. */
  .home-page .game-card__avatar { width: 36px; height: 36px; font-size: 1.05rem; }
  .home-page .game-card__avatar .computer-icon { width: 24px; height: 24px; }
  .home-page .game-card__title { font-size: 1.05rem; }
}

@media (max-width: 600px) {
  .home-page .game-card--active .game-card__status { width: 100%; max-width: none; }
  .home-page .game-card--active .game-card__actions { display: block; }
  .home-page .game-card--active .game-card__open { position: absolute; grid-area: auto; z-index: 0; inset: 0; width: auto; height: auto; display: block; }
  .home-page .game-card--active .game-card__open .lobby-chevron { display: none; }
  .home-page .game-card--active .game-nudge { position: relative; z-index: 2; }
  .home-page .game-card--active .game-nudge,
  .home-page .game-card--active .game-nudge__button { width: 100%; }
  .home-page .game-card--active:not(:has(.game-nudge)) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "identity" "scores" "status";
  }
  .home-page .game-card--active:not(:has(.game-nudge)) .game-card__actions { display: contents; }
}

/* Pending invitations and their resend controls. */

.home-page #lobby-invites { display: block; }
.home-page #lobby-invites > .pending-invites { margin-top: .75rem; }
.pending-invites {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.pending-invites__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.5rem 1.1rem;
  background: #fffdf6;
  border: 1px solid #ecdcbe;
  border-radius: 16px;
  padding: 0.85rem 1.1rem;
}

.pending-invites__icon { display: grid; place-items: center; width: 2.75rem; height: 2.75rem; flex: none; border-radius: 50%; background: #f0e9fb; color: var(--plum); }
.pending-invites__icon .ui-icon { width: 1.5rem; height: 1.5rem; }
.pending-invites__message { min-width: 0; margin: 0; overflow-wrap: anywhere; }
.pending-invites__mobile, .pending-invites__label-short { display: none; }
.pending-invites__actions { display: flex; align-items: center; justify-self: end; gap: .5rem; }
.pending-invites__actions form { flex-shrink: 0; }

@media (max-width: 600px) {
  .home-page #lobby-invites > .pending-invites { margin-top: .6rem; }
  /* Recipient, waiting state, then the resend/cancel actions on their own row. */
  .pending-invites { gap: .5rem; }
  .pending-invites__item {
    /* Keep long recipient names within the card. */
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: .55rem;
    row-gap: .15rem;
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: .55rem 0;
  }
  .pending-invites__icon { grid-area: 1 / 1 / 2 / 2; width: auto; height: auto; border-radius: 0; background: transparent; color: var(--plum); }
  .pending-invites__icon .ui-icon { width: 1.15rem; height: 1.15rem; }
  .pending-invites__desktop { display: none; }
  .pending-invites__message, .pending-invites__mobile { display: contents; }
  .pending-invites__recipient { grid-area: 1 / 2 / 2 / 3; display: block; min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; color: var(--plum-deep); }
  .pending-invites__state { grid-area: 2 / 2 / 3 / 3; display: block; min-width: 0; font-size: 1.05rem; color: var(--ink-soft); }
  .pending-invites__item--received > .button { grid-column: 2; justify-self: start; }
  .pending-invites__item--received > p { min-width: 0; overflow-wrap: anywhere; }
  .pending-invites__actions { grid-area: 3 / 2 / 4 / 3; justify-self: end; }
  .pending-invites__label-full { display: none; }
  .pending-invites__label-short { display: inline; }
  /* The envelope already identifies the invitation on mobile. */
  .pending-invites__actions .button { min-height: 48px; min-width: 48px; padding: .4rem .8rem; font-size: 1.06rem; gap: .35rem; }
  .pending-invites__actions .button .ui-icon { display: none; }
}

/* local sign-in and outbox (development only). */

.empty-state {
  background: var(--paper);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: 1.1rem;
  color: var(--ink-soft);
}

.outbox {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

.outbox__item {
  display: grid;
  gap: 0.35rem;
  justify-items: start;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.8rem;
}

.outbox__subject {
  font-weight: 500;
}

.outbox__meta {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

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

@media (min-width: 601px) {
  .home__ponybot .home__ponybot-chevron { display: none; }
}
