/* WordRails — 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, and phones always show the whole board without enlarging or
   panning it. */

/* Nunito, self-hosted. Copyright 2014 The Nunito Project Authors
   (https://github.com/googlefonts/nunito). Licensed under the SIL Open Font
   License 1.1; the full text ships beside the font files in
   app/assets/stylesheets/fonts/Nunito-OFL.txt. Files are the Latin subsets
   Google Fonts serves for the "Nunito" family, variable weight 200-1000. */
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin-a6de09cc.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin-ext-6e74a3a2.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --cream: #fbf3e6;
  --cream-deep: #f2e5d1;
  --paper: #fffcf6;
  --ink: #3b2a45;
  --ink-soft: #6d5b76;
  --plum: #6a3d73;
  --plum-deep: #4d2a56;
  --teal: #2e7d74;
  --teal-soft: #d9ebe7;
  --coral: #b8452f;
  --coral-deep: #9c3823;
  --coral-soft: #fbdfd6;
  --lavender: #7f6fb5;
  --lavender-soft: #e9e3f8;
  --gold: #b8821c;
  --gold-soft: #fbeecb;
  --tile-face: #fffaf0;
  --tile-edge: #e0c9a2;
  --line: #e6d8c6;
  --font-friendly: "Nunito", 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: #f5efe1;
  background-image: linear-gradient(180deg, #fcf9f2 0%, #f9f4ea 55%, #f5efe1 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 {
  margin: 0;
  line-height: 1.25;
}

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;
  font: inherit;
  font-weight: 700;
  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(--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(--plum);
  border-color: var(--plum-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 {
  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: 700;
  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 {
  max-width: 68rem;
  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__icon {
  width: 2.6rem;
  height: 2.1rem;
  flex: none;
  display: block;
}

.brand__name {
  font-size: 1.4rem;
  font-weight: 800;
  letter-spacing: 0;
}

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

.site-footer {
  max-width: 68rem;
  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; --plum-deep: #4d2a56; --ink-soft: #6d5b76; --paper: #fffcf6; --line: #e6d8c6; }

.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__name { font-size: clamp(2rem, 4vw, 3.15rem); }
.onboarding--entry .brand__icon { width: 5.5rem; height: 4.7rem; }

@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__icon { width: 3.5rem; height: 3rem; }
}

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

:is(.home-page, .game-page) .site-header__inner { max-width: 82rem; gap: 1rem; padding: 0.9rem 1.5rem; }
:is(.home-page, .game-page) .brand { color: #4d2a56; }
:is(.home-page, .game-page) .brand__icon { width: 44px; height: 44px; }
:is(.home-page, .game-page) .brand__name { font-size: 1.5rem; }
: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 summary { display: flex; align-items: center; min-height: 2.4rem; padding: .35rem .5rem; cursor: pointer; list-style: none; color: var(--plum-deep); font-weight: 750; white-space: nowrap; border-radius: var(--radius-sm); }
.notification-menu summary::-webkit-details-marker { display: none; }
.notification-menu summary::after { content: "▾"; margin-left: .35rem; font-size: .8em; }
.notification-menu[open] summary { background: var(--cream-deep); }
.notification-menu:not([open]) .notification-menu__content { display: 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: 700; }
.notification-update:not([hidden]) { position: fixed; z-index: 80; top: calc(var(--banner-top, max(5rem, env(safe-area-inset-top))) + var(--flash-banner-height, 0px)); left: 1rem; right: 1rem; width: auto; margin: 0; padding: 1.1rem 1.25rem; display: flex; gap: .75rem; align-items: center; background: #176f63; border: 1px solid #11584f; border-radius: var(--radius); box-shadow: var(--shadow-md); color: #fffdf7; font-size: 1rem; font-weight: 700; }
.notification-update > span { min-width: 0; flex: 1 1 auto; overflow-wrap: anywhere; }
.notification-update[hidden] { 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;
}
.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 summary: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: 82rem;
  padding: 0.9rem 1.5rem;
  flex-wrap: nowrap;
  align-items: center;
}

.header-menu .brand__icon { width: 44px; height: 44px; }

.header-menu .brand {
  flex: 0 0 auto;
  min-width: 0;
}

.header-menu .brand__name {
  font-size: 1.5rem;
  white-space: nowrap;
}

.site-header__games {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  min-height: 44px;
  flex: none;
  margin-left: auto;
  min-width: 44px;
  justify-content: center;
  color: var(--plum-deep);
  font-size: 1.05rem;
  font-weight: 750;
  text-decoration: none;
  white-space: nowrap;
}
.site-header__games:hover { text-decoration: underline; }
.site-header__count { position: relative; top: -.45em; font-size: .7em; line-height: 1; font-weight: 800; }
.site-header__games:focus-visible { outline: 3px solid var(--teal); outline-offset: 2px; border-radius: 4px; }

/* The Notifications disclosure is a sibling of the account panel, not one of
   its rows, so the bell stays on the row and rides with the account trigger on
   the right. Making it static hands its popover's absolute coordinates to the
   header row, which keeps the popover right-aligned and viewport-bounded at
   every width without a container query. */
.header-menu .notification-menu {
  position: static;
}

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

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

.header-menu__toggle {
  position: relative;
  display: inline-flex;
  flex: none;
  gap: .65rem;
  margin-left: .75rem;
  font: inherit;
  font-size: 1.05rem;
  font-weight: 750;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  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 #b6ded2;
  background: #daf3e9;
  color: #17574a;
  font-size: 1.35rem;
  font-weight: 800;
}
.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% + .4rem);
  right: .75rem;
  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 .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: 44px;
}

/* Narrow screens keep the train-only brand, 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 .brand__name { display: none; }
  .header-menu .site-header__inner { padding: 8px 12px; gap: 6px; }
  .header-menu .brand { gap: 6px; }
  .header-menu .brand__icon { width: 40px; height: 40px; }
  .site-header__games { font-size: 1rem; gap: .3rem; }
  .header-menu .notification-menu summary { padding-inline: 6px; }
  .header-menu .notification-menu summary::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: 8px; }
  .site-header__games { font-size: .9rem; }
  .header-menu .notification-menu summary { padding-inline: 2px; }
  .header-menu .brand { gap: .35rem; }
  :is(.home-page, .game-page) .brand__icon { width: 32px; height: 32px; }
}

/* 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. */

/* Status text can make a short page scroll. Balanced gutters keep the board
   and rack centered in the same place before and after that happens. */
html:has(.game-page) { scrollbar-gutter: stable both-edges; }
.game-page {
  --cream: #f9f5ec;
  --paper: #fffdf8;
  --ink: #2f2b41;
  --ink-soft: #5f5b71;
  --plum-deep: #33304a;
  --teal: #1f7a66;
  --teal-soft: #e2f2ea;
  --line: #e8dfcd;
  --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 > .flash { width: 100%; }
.game-page .flash-stack {
  position: static;
  transform: none;
  margin: .75rem auto;
  max-height: none;
}
.game-page .flash .flash__message {
  margin-top: 1rem;
  padding: .55rem .75rem;
  border-radius: 10px;
  box-shadow: none;
  font-size: 1rem;
}
.game-page .flash__icon { flex-basis: 1.5rem; height: 1.5rem; margin-top: .1rem; 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%;
}
.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; font-weight: 650; 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: 850; font-variant-numeric: tabular-nums; }
.player--you .player__number { color: #2b607f; }
.player--opponent .player__number { color: #a2543f; }
.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: linear-gradient(#f4f0fb, #eae3f7); border-color: #cdc0e6; color: #5c4a7e; }
.status-banner__headline { font-size: 1.25rem; font-weight: 800; 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: 800; line-height: 1; }
.status-banner__direction--opponent { right: auto; left: calc(100% + 0.5rem); }
.status-banner__detail { font-size: 0.95rem; font-weight: 650; margin: 0; color: #4b4761; }

/* Board down to the rack band. */
/* The board region reserves space only while the crowded-board score
   fallback is docked under the frame; the value is the badge height plus
   its gap, so the dock never covers the rack, controls, or help text. */
.board-region {
  width: 100%; min-width: 0; margin-bottom: 1.05rem;
  --score-dock-space: 0px;
  padding-bottom: var(--score-dock-space);
}
.board-touch-help { display: none; }
.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: 800; 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:hover:not(:disabled), .square:focus-visible { 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: 800; 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; }
.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: 700;
}
.tile__letter { font-size: 1.9rem; font-weight: 700; line-height: 1; }
.tile__points { position: absolute; right: 5px; bottom: 2px; font-size: 0.85rem; font-weight: 750; 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); }
.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 tile matches the rack piece it most often comes from, and rides
   clear above the pointer - a 3.3rem tile against a 42px square - so the square
   it would land on keeps its whole outline visible underneath. The drop still
   uses the pointer position, never this offset. */
.tile--ghost { position: fixed; width: 3.4rem; height: 3.4rem; transform: translate(-50%, -105%) rotate(-2deg) scale(1.06); pointer-events: none; z-index: 60; box-shadow: inset 0 1px 0 #fff, 0 4px 0 #b89d6b, 0 16px 26px #35283b52; }
.tile--ghost .tile__letter { font-size: 2.3rem; }
.tile--ghost--touch { transform: translate(-50%, -50%) rotate(-2deg) scale(1.06); }
.tile--draft.is-drag-source, .tile--ghost { 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 {
  width: 100%;
  font-size: 1.2rem;
  font-weight: 800;
  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 #fffaf0, 0 2px 0 #e6e0d2;
  transform: none;
}
/* GO sits beside the tray. */
.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 #08644e;
  background: linear-gradient(#08795e, #056149);
  color: #fff;
  font-size: 1.75rem;
  font-weight: 800;
  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(#078667, #056d52);
  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); }
/* An empty announcement keeps its place in the accessibility tree and takes up
   no room: the region is never display:none, so the first message is still
   announced to a screen reader. */
.game-secondary:has(.announce:empty) { margin-top: 0; }
.announce { flex: 1 1 auto; min-width: 0; font-size: 1rem; }
.announce:empty { min-height: 0; margin: 0; }
.game-resign { font: inherit; font-size: 0.95rem; font-weight: 650; color: #5f5b71; background: none; border: none; text-decoration: underline; text-underline-offset: 3px; padding: 0.25rem 0.4rem; min-height: 44px; cursor: pointer; }
.game-resign:disabled { visibility: hidden; }
.game-options { width: fit-content; max-width: 100%; margin-top: 1.4rem; }

/* 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-top: 0.5rem; }
.game-rematch[hidden], .game-rematch:empty { display: none; }
.game-rematch__button { min-height: 52px; padding-inline: 2rem; font-size: 1.2rem; }

/* Collapsible private chat below the controls. Collapsed by default so the
   play screen keeps its height, and constrained so a long message can never
   widen the page or shrink the board. */
.game-chat { width: 100%; min-width: 0; margin-top: 0.5rem; }
.game-chat__panel { border: 1px solid #e7ddc8; border-radius: 12px; background: #fffdf8; overflow: hidden; }
.game-chat__summary { display: flex; align-items: center; gap: 0.5rem; min-height: 44px; padding: 0 0.9rem; font-weight: 750; color: var(--plum-deep); cursor: pointer; list-style: none; }
.game-chat__summary::-webkit-details-marker { display: none; }
.game-chat__summary::before { content: "\25BE"; font-size: 0.8em; }
.game-chat__panel[open] .game-chat__summary::before { content: "\25B4"; }
.game-chat__summary:focus-visible { outline: 3px solid #267e74; outline-offset: 2px; }
.game-chat__body { display: grid; gap: 0.6rem; padding: 0 0.9rem 0.9rem; min-width: 0; }
.game-chat__note { margin: 0; color: var(--ink-soft); font-size: 0.85rem; 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: 750; color: var(--plum-deep); font-size: 0.8rem; }
.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: vertical; 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: 600; }
.game-chat__send { justify-self: end; min-height: 44px; }

@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: 10px; }
  .board-touch-help { display: block; margin: 0 0 6px; color: var(--ink-soft); font-size: 0.8rem; }
  .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: 48px; 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 { flex-direction: column; gap: 3px; padding: 6px 2px; min-width: 0; font-size: 0.9rem; }
  .game-options { order: 4; margin-top: 8px; }
  /* 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; }
  .play-area, .preview__message, .game-options { grid-column: 2; }
  .game-options { justify-self: center; margin: 0; }
}

/* ----------------------------------------------------------------- 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;
}

.letter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(2.9rem, 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 {
  position: fixed;
  top: var(--banner-top, max(5rem, env(safe-area-inset-top)));
  left: 1rem;
  right: 1rem;
  z-index: 40;
  width: auto;
  max-height: 50vh;
  overflow-y: auto;
  display: grid;
  gap: 0.4rem;
  pointer-events: none;
}

.flash {
  display: grid;
  gap: 0.4rem;
}

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

.flash .flash__message {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1.1rem 1.25rem;
  background: #1d6259;
  color: #fff;
  border: 2px solid #124c44;
  border-radius: 16px;
  box-shadow: 0 8px 28px #3b2a4538;
  font-size: 1.2rem;
  font-weight: 700;
  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;
  margin-top: 0.3rem;
  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; }

.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;
  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(#287b72, #1e7068);
  border-color: #175b55;
  border-bottom-width: 3px;
  box-shadow: inset 0 1px 0 #ffffff4d, 0 3px 0 #175b55, 0 5px 9px rgba(31, 90, 84, 0.2);
  font-size: 1.18rem;
}

.onboarding__button:hover:not(:disabled) {
  background: linear-gradient(#27776f, #216f68);
}

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

/* 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: 700;
  line-height: 1;
  transform: translate(-1px, -1px);
}

.onboarding__preview-premium {
  font-size: 0.6rem;
  font-weight: 800;
  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%, #fffdf8 0%, #fbf3e5 65%, #f4e5ce 100%);
}

.onboarding--entry .site-main { max-width: 72rem; 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); font-weight: 800; }
.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: #6d5b76; }

.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: #1e7068;
  color: white;
  font-size: 2.4rem;
  font-weight: 800;
}
.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: 800;
  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-main { max-width: none; padding: 3.5rem 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: 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. */
body.home-page { display: flex; flex-direction: column; min-height: 100dvh; }
/* 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: -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__welcome .home__train-accent { display: block; flex: none; width: 4.5rem; height: auto; opacity: .9; pointer-events: none; }
.home__invite { display: grid; gap: 1.5rem; background: #fdf7ec; border: 1px solid #f0e2cb; border-radius: var(--radius-lg); padding: 1.75rem; }
.home__choices { display: grid; grid-template-columns: minmax(0, 2fr) auto minmax(0, 1fr); align-items: center; gap: 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 .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__computer { display: flex; align-items: center; min-width: 0; }
.home__computer form { width: 100%; }
.home-page .home__computer .button { display: inline-flex; align-items: center; justify-content: center; gap: .7rem; width: 100%; min-height: var(--lobby-control); height: var(--lobby-control); padding: .4rem 1.35rem; font-size: 1.2rem; background: #e0eff8; color: var(--plum-deep); border-color: #a7cde5; box-shadow: inset 0 1px 0 #ffffffb3, 0 2px 4px #305a7512; }
.computer-icon { width: 3.4rem; height: 3.4rem; flex-shrink: 0; color: var(--plum-deep); }
.home-page .home__computer .computer-icon { width: 2.5rem; height: 2.5rem; }
.home__robot-label { font-weight: 750; white-space: nowrap; }
.home__tagline { display: flex; align-items: center; justify-content: center; gap: .7rem; margin: 0; color: var(--ink-soft); font-size: 1.05rem; font-weight: 650; }
.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; }
/* Keep the mountain silhouettes intact. The source's top half is transparent;
   this band trims that empty space without cropping or fading the hills. */
.home__landscape {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 6 / 1;
  margin: 0;
  object-fit: cover;
  object-position: 50% 100%;
  opacity: .18;
  pointer-events: none;
}
.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-radius: 50%; background: #d0e8de; color: #23574c; font-weight: 800; 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 { font-weight: 750; 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 .home__games { border-top: 1px solid var(--line); padding-top: 1.3rem; display: grid; gap: 1rem; min-width: 0; }
.home-page .home__games:first-child { border-top: 0; padding-top: 0; }
.home-page .home__games-title { font-size: clamp(1.8rem, 3vw, 2.45rem); }
.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; }
.home-page .game-card { min-width: 0; grid-template-columns: minmax(0, 1.35fr) minmax(12rem, .85fr) minmax(15rem, 1fr); align-items: center; gap: 1.5rem; padding: 1rem 1.5rem; background: #fffdfa99; border-radius: 16px; box-shadow: 0 2px 4px #35202206; }
.home-page .game-card--turn { background: #f0f8f2; border-color: #bdded0; }
.home-page .game-card--over { border-color: #e1dbe7; }
.home-page .game-card__top { justify-content: flex-start; flex-wrap: nowrap; gap: 1.25rem; min-width: 0; }
.home-page .game-card__title { font-size: 1.3rem; color: var(--plum-deep); overflow-wrap: break-word; }
.game-card__avatar { width: 4.4rem; height: 4.4rem; background: #f7d1c9; color: #8d332e; font-size: 1.5rem; }
.game-card:nth-child(even) .game-card__avatar { background: #e5d9ee; color: var(--plum-deep); }
.home-page .game-card__avatar--computer { background: #d0e8de; }
.home-page .score-line { display: grid; grid-template-columns: 1fr 1fr; gap: 0; text-align: center; }
.home-page .score-line__item + .score-line__item { border-left: 1px solid var(--line); }
.home-page .score-line__item dt { font-size: 1.05rem; text-transform: none; letter-spacing: 0; color: var(--plum-deep); }
.home-page .score-line__item dd { font-size: 2.25rem; line-height: 1.2; margin-top: .2rem; white-space: nowrap; }
.home-page .game-card--turn .score-line__item:first-child dd { color: #185637; }
.game-card__action { display: grid; gap: .25rem; text-align: center; }
.home-page .game-card__action .button { width: 100%; min-width: 0; min-height: 58px; font-size: 1.15rem; }
.home-page .game-card__waiting { display: flex; align-items: center; gap: 1rem; background: #fff0db; border-color: #f0d9b7; color: #675746; box-shadow: none; }
.home-page .game-card--over .button { background: #efedf3; border-color: #dfdbe7; color: var(--plum-deep); box-shadow: none; }
.finished-games { display: grid; gap: .75rem; }
.finished-games__summary { display: flex; align-items: center; gap: .4rem; min-height: 44px; cursor: pointer; font-weight: 750; color: var(--plum-deep); list-style: none; }
.finished-games__summary::-webkit-details-marker { display: none; }
.finished-games__summary::after { content: "\25BE"; font-size: .8em; }
.finished-games[open] .finished-games__summary::after { content: "\25B4"; }
.finished-games__summary:focus-visible { outline: 3px solid #267e74; outline-offset: 3px; border-radius: .3rem; }
.finished-games .game-list { margin: 0; }
.home-page .game-card--finished { grid-template-columns: minmax(0, 1.35fr) minmax(12rem, .85fr) auto; }
.home-page .game-card--finished .game-card__action { align-self: center; }
.home-page .game-card--over .game-card__rematch { background: linear-gradient(#08795e, #056149); border-color: #08644e; color: #fff; box-shadow: none; min-height: 48px; }
.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: 600; margin-top: 1rem; }
.home-page .home__invite-error:empty, .home-page #lobby-invites[hidden] { display: none; }
@media (max-width: 1100px) {
  .home-page .site-main { padding: 1.5rem 1.25rem 2rem; }
  .home-page .home__footer { margin-inline: -1.25rem; margin-bottom: -2rem; }
  .home__invite { padding: 1.35rem; }
  .home__welcome { display: block; }
  .home__welcome .home__train-accent { display: none; }
  .home__choices { grid-template-columns: 1fr; gap: .7rem; }
  .home__or { display: flex; justify-content: center; align-items: center; }
  .home__or::before, .home__or::after { height: 1px; width: 2rem; }
  .home-page .input { font-size: 1.1rem; padding-left: 3rem; }
  .home-page .start-game__search { width: 2.8rem; }
  .home__computer, .home__computer form { width: 100%; }
  .home-page .home__computer .button { 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 .game-card { grid-template-columns: minmax(0, 1.35fr) minmax(6rem, .85fr) minmax(8rem, 1fr); gap: .75rem; padding: .75rem; }
  .home-page .game-card--finished { grid-template-columns: minmax(0, 1fr) 7rem auto; }
  .home-page .game-card__top { gap: .5rem; }
  .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 { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 1.05rem; }
  .home-page .score-line { width: 100%; min-width: 0; }
  .home-page .score-line__item { min-width: 0; }
  .home-page .score-line__item dt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .8rem; }
  .home-page .score-line__item dd { font-size: 1.5rem; }
  .home-page .game-card__action { min-width: 0; }
  .home-page .game-card__action .button { display: block; align-content: center; min-height: 44px; padding: .5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 1rem; }
}

@media (max-width: 600px) {
  .home-page .home__footer { margin-inline: 0; margin-bottom: 0; }
  .home__invite { padding: 1.1rem; }
  .home__landscape { display: none; }
  .home-page .home__empty-art { height: 5rem; }
  .home-page .game-card { grid-template-columns: minmax(0, 1.35fr) minmax(5rem, .85fr) minmax(6rem, 1fr); gap: 6px; padding: 8px; border-radius: 12px; }
  .home-page .game-card__avatar { width: 28px; height: 28px; font-size: .9rem; }
  .home-page .game-card__avatar .computer-icon { width: 22px; height: 22px; }
  .home-page .game-card__top { gap: 5px; }
  .home-page .game-card__title { font-size: .85rem; }
  .home-page .score-line__item dt { font-size: .65rem; }
  .home-page .score-line__item dd { font-size: 1.1rem; }
  .home-page .game-card__action .button { font-size: .85rem; padding-inline: 5px; }
}

@media (max-width: 380px) {
  .home-page .game-card__avatar { display: none; }
}

/* Pending invitations and their resend controls. */

.home-page #lobby-invites { display: grid; gap: .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__item form { justify-self: end; flex-shrink: 0; }

@media (max-width: 600px) {
  .pending-invites__item { grid-template-columns: auto minmax(0, 1fr); }
  .pending-invites__item form { grid-column: 1 / -1; justify-self: stretch; width: 100%; }
  .pending-invites__item form .button { width: 100%; }
}

/* 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: 700;
}

.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;
  }
}
