:root {
  --bg: #14110f;
  --panel: #211c18;
  --panel-2: #2c2521;
  --line: #3d332c;
  --text: #f2e9df;
  --muted: #a9998a;
  --accent: #c8892f;
  --accent-2: #4a7c59;
  --white-checker: #efe6d6;
  --white-checker-edge: #b7a98f;
  --black-checker: #2b2b2f;
  --black-checker-edge: #6f6f78;
  --danger: #d1584f;
  --ok: #4a7c59;

  --die: 32px; /* set by JS from the board size */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
  overflow: hidden;              /* the game UI must never scroll */
  overscroll-behavior: none;
}

/* Pin the document to the viewport so a touch drag can never scroll or
   rubber-band the page (iOS Safari / Telegram WebView ignore overscroll-behavior
   on the root; a fixed body is the reliable cross-version lock). Scrollable
   panels (lobby list, stats, profile) are children with their own overflow. */
body {
  position: fixed;
  inset: 0;
  width: 100%;
}

/* --app-h is the real visible viewport height, kept in sync by JS from
   window.visualViewport (falls back to Telegram's viewportStableHeight, then
   100svh — the small viewport height, which never over-reports on mobile). */
#app {
  height: 100svh;
  height: var(--app-h, 100svh);
  max-width: 560px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  /* Keep ALL content clear of the notch / Dynamic Island / Telegram's header
     controls. The insets combine the OS safe area (env(...)) with Telegram's
     device + content safe area (--tg-safe-*, set by JS; 0 when unavailable).
     The BOTTOM inset is owned by the bottom nav (so its background still reaches
     the screen edge), hence no padding-bottom here. */
  padding-top: max(env(safe-area-inset-top), var(--tg-safe-top, 0px));
  padding-left: max(env(safe-area-inset-left), var(--tg-safe-left, 0px));
  padding-right: max(env(safe-area-inset-right), var(--tg-safe-right, 0px));
}

.hidden { display: none !important; }

.screen { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.screen.scroll { overflow-y: auto; justify-content: center; gap: 14px; padding: 16px 16px 40px; }
/* tabs whose content can exceed the viewport must scroll from the top, not be
   vertically centred (which would push the heading out of reach). */
#screen-profile { justify-content: flex-start; align-items: stretch; padding-top: 20px; }
#screen-rating > h1, #screen-profile > h1 { flex: 0 0 auto; }

h1 {
  font-size: 24px;
  text-align: center;
  letter-spacing: 2px;
  margin: 8px 0 10px;
}

/* ---------- buttons / inputs (lobby) ---------- */
.big-btn {
  width: 100%;
  min-height: 54px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel-2);
  color: var(--text);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 1px;
  cursor: pointer;
}
.big-btn:active { transform: translateY(1px); }
.big-btn.primary { background: var(--accent); border-color: var(--accent); color: #1c1300; }
.big-btn:disabled { opacity: .4; cursor: not-allowed; }

.text-btn {
  background: none; border: none;
  color: var(--muted); font-size: 12px;
  text-decoration: underline; cursor: pointer;
  padding: 6px 4px;
}

input[type="text"] {
  width: 100%; min-height: 50px; padding: 0 14px;
  border-radius: 12px; border: 1px solid var(--line);
  background: var(--panel); color: var(--text); font-size: 15px;
}

.field-label { font-size: 13px; color: var(--muted); margin-bottom: -6px; }
.divider { text-align: center; color: var(--muted); font-size: 13px; }
.hint { color: var(--muted); font-size: 14px; text-align: center; line-height: 1.5; }
.hint code, code { background: var(--panel); padding: 2px 6px; border-radius: 6px; font-size: 13px; }
.error-text { color: var(--danger); font-size: 14px; text-align: center; min-height: 18px; }

/* ---------- home screen: tabs + bottom nav, fills the viewport ---------- */
#screen-home {
  gap: 0;
  padding: 0;
}

.home-head {
  flex: 0 0 auto;
  padding: 10px 16px 8px; /* the safe-area top inset is handled on #app */
}
.home-title {
  font-size: 20px;
  letter-spacing: 1px;
  margin: 0;
  text-align: left;
}

.home-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0 12px;
}
.tab-panel {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* --- create a game --- */
.create-box {
  flex: 0 0 auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.create-label { font-size: 13px; color: var(--muted); }
.stake-row {
  display: flex;
  gap: 6px;
}
.stake-chip {
  flex: 1;
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--text);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}
.stake-chip.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #1c1300;
}
.stake-chip:active { transform: translateY(1px); }

/* --- pick your colour --- */
.color-row {
  display: flex;
  gap: 6px;
}
.color-chip {
  flex: 1;
  min-height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--text);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}
.color-chip.on { background: var(--accent); border-color: var(--accent); color: #1c1300; }
.color-chip:active { transform: translateY(1px); }
.chip-disc {
  width: 18px; height: 18px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.chip-disc.white { background: radial-gradient(circle at 35% 30%, #fff, var(--white-checker)); border: 1px solid var(--white-checker-edge); }
.chip-disc.black { background: radial-gradient(circle at 35% 30%, #55555f, var(--black-checker)); border: 1px solid var(--black-checker-edge); }

.create-box .big-btn { min-height: 48px; font-size: 16px; }
.create-box .error-text { min-height: 0; }
.create-box .error-text:empty { display: none; }

/* --- resume in-progress game --- */
.resume-card {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--accent);
  border-radius: 14px;
  background: rgba(200, 137, 47, .14);
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.resume-text { display: flex; flex-direction: column; gap: 2px; font-size: 14px; }
.resume-text span { color: var(--muted); font-size: 12px; }
.resume-go { color: var(--accent); font-weight: 700; font-size: 13px; white-space: nowrap; }

/* --- list of open games --- */
.open-head {
  flex: 0 0 auto;
  font-size: 13px;
  color: var(--muted);
  padding: 2px 2px 0;
}
.open-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-bottom: 8px;
}
.open-empty {
  color: var(--muted);
  font-size: 13px;
  text-align: center;
  padding: 20px 8px;
}
.open-empty.hidden { display: none; }
.open-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "name players" "info players";
  gap: 2px 10px;
  align-items: center;
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.open-row:active { background: var(--panel-2); }
.open-name { grid-area: name; font-weight: 700; font-size: 15px; }
.open-info { grid-area: info; color: var(--muted); font-size: 13px; }
.open-players {
  grid-area: players;
  font-size: 13px;
  color: var(--accent-2);
  white-space: nowrap;
}

/* ---------- avatar (shared: profile + game HUD; always a circle) ----------
   The stored/served avatar is a square 256×256 WebP; the round shape is UI only.
   --avatar-size is set per use-site; the <img> and the placeholder are the same
   size so an image loading in never shifts the layout. */
.avatar {
  --avatar-size: 40px;
  position: relative;
  width: var(--avatar-size);
  height: var(--avatar-size);
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  background: var(--panel-2);
  border: 1px solid var(--line);
}
.avatar > img,
.avatar > .avatar-ph {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;            /* fill the circle, never stretch */
  display: block;
}
.avatar > img[hidden] { display: none; }
/* when a real image is showing, the silhouette underneath must not cover it */
.avatar > img:not([hidden]) ~ .avatar-ph { display: none; }
/* two-tone silhouette placeholder — inline SVG, so it stays crisp at any size */
.avatar-ph {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' fill='%232c2521'/%3E%3Ccircle cx='32' cy='24' r='11' fill='%238a7866'/%3E%3Cpath d='M13 58c1-12 9-19 19-19s18 7 19 19z' fill='%238a7866'/%3E%3C/svg%3E")
    center / cover no-repeat;
}

/* --- profile tab --- */
.profile-box {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding-top: 20px;
}
.avatar--profile {
  --avatar-size: clamp(96px, 26vw, 132px);
  border-width: 2px;
}
.avatar-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
}
.ghost-btn {
  min-height: 38px;
  padding: 0 14px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.ghost-btn:active { transform: translateY(1px); }
.ghost-btn:disabled { opacity: .5; cursor: not-allowed; }
.ghost-btn.danger { color: var(--danger); border-color: var(--danger); }
.avatar-msg {
  min-height: 16px;
  margin: 0;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
}
.avatar-msg.error { color: var(--danger); }

.profile-fields {
  width: 100%;
  max-width: 340px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 4px;
}
.profile-row {
  display: flex; gap: 10px; align-items: center;
  justify-content: space-between;
  font-size: 15px;
  padding: 8px 4px;
  border-top: 1px solid var(--line);
}
.profile-row:first-child { border-top: none; }
.profile-row > span:first-child { color: var(--muted); font-size: 13px; flex: 0 0 auto; }
.profile-note {
  color: var(--muted);
  font-size: 13px;
  text-align: center;
  max-width: 280px;
}
.profile-note.error { color: var(--danger); }

/* inline username edit: a value + pencil, swapping to input + ✓/✕ */
.nick-view { display: inline-flex; align-items: center; gap: 6px; }
.nick-view.hidden { display: none; }
.nick-edit { display: flex; align-items: center; gap: 6px; }
.nick-edit.hidden { display: none; }
.icon-btn {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.icon-btn:active { transform: translateY(1px); }
.icon-btn.ok { color: var(--ok); border-color: var(--ok); }
.icon-btn.ok:disabled { opacity: .5; }
.nick-input {
  flex: 1 1 auto;
  width: 8em;
  min-height: 34px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  font-size: 15px;
}

/* --- bottom navigation (app-level: one bar under every screen but error) --- */
.bottom-nav {
  flex: 0 0 auto;
  display: flex;
  border-top: 1px solid var(--line);
  background: var(--panel);
  padding-bottom: max(env(safe-area-inset-bottom), var(--tg-safe-bottom, 0px));
  z-index: 30;
}
.nav-btn {
  flex: 1;
  min-height: 50px;
  border: none;
  background: none;
  color: var(--muted);
  font-size: 11px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  cursor: pointer;
}
.nav-btn .nav-ico { font-size: 18px; filter: grayscale(1) opacity(.7); }
.nav-btn.on { color: var(--accent); }
.nav-btn.on .nav-ico { filter: none; }

/* --- rating tab (global leaderboard — a game screen, not a data table) --- */
#screen-rating { padding: 16px 12px 0; gap: 10px; overflow: hidden; }

/* "Ваше место" summary — always visible, compact, subtly accented */
.rating-me {
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 10px 14px;
  background: var(--panel);
  border: 1px solid var(--accent);
  border-radius: 12px;
}
.rating-me-cap { color: var(--muted); font-size: 12px; }
.rating-me-rank { font-weight: 800; color: var(--accent); }
.rating-me-val { margin-left: auto; font-weight: 800; font-size: 17px; }

/* the scroll container: list grows on scroll, page body never scrolls */
.rating-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding-bottom: 12px;
}
.rating-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.rating-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: 14px;
}
.rating-row.me {
  border-color: var(--accent);
  background: rgba(200, 137, 47, 0.14); /* --accent tint */
}
.rating-rank {
  flex: 0 0 auto;
  min-width: 3.2em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
}
.rating-av { --avatar-size: 32px; }
.rating-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}
.rating-val {
  flex: 0 0 auto;
  font-weight: 800;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
}
.rating-sentinel { height: 1px; }
.rating-status { padding: 12px 4px; text-align: center; color: var(--muted); font-size: 13px; }

.stat-grid { display: flex; gap: 10px; width: 100%; max-width: 340px; }
.stat-cell {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
}
.stat-cell b { font-size: 24px; font-weight: 800; }
.stat-cell span { font-size: 12px; color: var(--muted); }
.stat-cell.win b { color: var(--ok); }
.stat-cell.loss b { color: var(--danger); }
.stat-break {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 340px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 6px 12px;
}
.stat-break-head {
  font-size: 12px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 1px;
  padding: 10px 0 4px;
}
.stat-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 6px 0;
  font-size: 14px;
  border-top: 1px solid var(--line);
}
.stat-break-head + .stat-line { border-top: none; }
.stat-line span i { color: var(--muted); font-style: normal; font-size: 12px; margin-left: 4px; }
.stat-line b { font-weight: 700; }

/* ---------- game screen (fills the viewport, no scroll) ---------- */
/* All safe-area insets are handled on #app; this just needs a small visual gutter. */
#screen-game {
  gap: 6px;
  padding: 6px;
}

.topbar {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; font-size: 11px; color: var(--muted);
}
.topbar-id { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar code { font-size: 10px; background: transparent; padding: 0; }

.players { flex: 0 0 auto; display: flex; gap: 8px; }
.player-card {
  flex: 1;
  display: flex; align-items: center; gap: 7px;
  padding: 6px 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: 13px;
  position: relative;
  transition: border-color .15s, box-shadow .15s;
}
.player-card.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }

/* HUD avatar — a large circle that reads as its own element sitting ABOVE the
   info card (portrait) or beside it (landscape), never squeezed inside it. The
   coloured ring stands in for the old .pdisc; the --bg halo separates it from
   the card it overlaps. */
.avatar--hud {
  --avatar-size: 50px;
  position: absolute;
  top: -40px; /* mostly ABOVE the card — only a sliver overlaps it */
  z-index: 3;
  border-width: 2px;
  box-shadow: 0 0 0 3px var(--bg);
}
.player-card.white .avatar--hud { border-color: var(--white-checker-edge); }
.player-card.black .avatar--hud { border-color: var(--black-checker-edge); }
/* Portrait: player 1 (me) avatar hugs the top-LEFT, player 2 the top-RIGHT. */
#player-me .avatar--hud { left: 4px; }
#player-opp .avatar--hud { right: 4px; }

/* connection badge, docked to the bottom-outer corner of the avatar */
.avatar--hud .dot {
  position: absolute;
  right: 0; bottom: 0;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--danger);
  border: 2px solid var(--panel);
}
.avatar--hud .dot.on { background: var(--ok); }
.player-card .pdisc { display: none; } /* colour now shown by the avatar ring + .pcolor text */

.players { margin-top: 34px; } /* room for the avatars overhanging above */
.player-card { min-height: 44px; overflow: visible; }
/* keep the info clear of the avatar that overhangs each card's outer edge */
#player-me { padding-left: 56px; }
#player-opp { padding-right: 56px; }

.player-card .ptext { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.player-card .pwho {
  font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.player-card .pcolor { color: var(--muted); font-size: 11px; }
.player-card .pmeta { margin-left: auto; color: var(--muted); font-size: 12px; flex: 0 0 auto; }

/* ---------- board area (flex:1, the board scales to fit) ---------- */
.board-wrap {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
  display: grid;
  place-items: center;
}

.board {
  /* width/height are set by JS (fitBoard); this is a sane fallback */
  position: relative;
  width: 100%;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 1.12 / 1;
  background: var(--panel);
  border: 2px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  user-select: none;
  touch-action: none;
}

.board-grid {
  position: absolute;
  /* the right strip is reserved for the bear-off area */
  inset: 0 var(--bear-w, 8.5%) 0 0;
  display: grid;
  grid-template-columns: 1fr 3.4% 1fr;
  grid-template-rows: 1fr 1fr;
  grid-template-areas:
    "tl bar tr"
    "bl bar br";
  gap: 2px;
  padding: 2.4%;
}

.bar { grid-area: bar; background: var(--panel-2); border-radius: 4px; }

/* ---------- bear-off area: real borne-off checkers, never a count ---------- */
.bear-off {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: var(--bear-w, 8.5%);
  z-index: 4;
  display: flex;
  flex-direction: column;
  padding: 2.4% 0;
  gap: 4px;
  background: linear-gradient(180deg, rgba(0,0,0,.22), rgba(0,0,0,.28));
  border-left: 2px solid var(--line);
}
.bear-off-half {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
  border-radius: 6px;
  position: relative;
}
.bear-off-half.far  { justify-content: flex-start; }
.bear-off-half.near { justify-content: flex-end; cursor: pointer; }
/* subtle tint so each half reads as belonging to a colour */
.bear-off-half.white::before,
.bear-off-half.black::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: 6px;
  z-index: 0;
}
.bear-off-half.white::before { background: rgba(239, 230, 214, .05); }
.bear-off-half.black::before { background: rgba(43, 43, 47, .18); }
.bear-off-half.near.can-bear {
  box-shadow: 0 0 0 2px var(--ok) inset, 0 0 10px 1px rgba(74, 124, 89, .45);
}
.bear-off-half.near.drop-hover {
  box-shadow: 0 0 0 2px var(--ok) inset;
  background: rgba(74, 124, 89, .35);
}
.bear-off .checker.off {
  position: relative;
  z-index: 1;
  width: calc(var(--die) * 0.56);
  height: calc(var(--die) * 0.56);
  flex: 0 0 auto;
}
.bear-off .checker.off.stacked { margin-top: calc(var(--die) * -0.4); }

.quad { display: flex; flex-direction: row; min-width: 0; }
.quad.top-left { grid-area: tl; }
.quad.bottom-left { grid-area: bl; }
.quad.top-right { grid-area: tr; }
.quad.bottom-right { grid-area: br; }

.point {
  flex: 1 1 0;
  min-width: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  padding: 3px 0;
}
.point.bottom { flex-direction: column-reverse; }

.point::before {
  content: "";
  position: absolute;
  left: 8%; right: 8%; top: 0; bottom: 0;
  z-index: 0;
  background: var(--tri, #2e2620);
}
.point.top::before { clip-path: polygon(0 0, 100% 0, 50% 94%); }
.point.bottom::before { clip-path: polygon(50% 6%, 0 100%, 100% 100%); }
.point:nth-child(odd) { --tri: #352c25; }
.point:nth-child(even) { --tri: #241e1a; }

.point.home-white::before { background: #4a3a1e; }
.point.home-black::before { background: #24402e; }

.point.active::after,
.point.target::after,
.point.drop-hover::after {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: 6px;
  z-index: 3;
  pointer-events: none;
  transition: background .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.point.active::after { border: 2px solid var(--accent); }
.point.target::after { border: 2px dashed var(--ok); background: rgba(74, 124, 89, .16); }
.point.drop-hover::after { border: 2px solid var(--ok); background: rgba(74, 124, 89, .46); }

/* while dragging: the valid destinations for the picked checker stand out */
body.dragging .point.target::after {
  border: 2.5px solid var(--ok);
  background: rgba(74, 124, 89, .3);
  box-shadow: 0 0 10px 1px rgba(74, 124, 89, .4);
  animation: tgt-pulse 1.5s ease-in-out infinite;
}
@keyframes tgt-pulse {
  0%, 100% { background: rgba(74, 124, 89, .24); }
  50%      { background: rgba(74, 124, 89, .4); }
}

/* checkers you may pick up this turn — a gentle amber ring, slow breathing */
.point.movable:not(.active) .checker:last-child {
  animation: chk-breathe 2.2s ease-in-out infinite;
}
@keyframes chk-breathe {
  0%, 100% {
    box-shadow: 0 1px 2px rgba(0, 0, 0, .55), 0 0 0 2px rgba(200, 137, 47, .7), 0 0 8px 1px rgba(200, 137, 47, .3);
  }
  50% {
    box-shadow: 0 1px 2px rgba(0, 0, 0, .55), 0 0 0 2px rgba(200, 137, 47, 1), 0 0 13px 3px rgba(200, 137, 47, .55);
  }
}
/* during a drag, dim the other pickable checkers so the drag + targets lead */
body.dragging .point.movable:not(.active) .checker:last-child {
  animation: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .55), 0 0 0 1.5px rgba(200, 137, 47, .38);
}
@media (prefers-reduced-motion: reduce) {
  .point.movable:not(.active) .checker:last-child {
    animation: none;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .55), 0 0 0 2px rgba(200, 137, 47, .85);
  }
  body.dragging .point.target::after { animation: none; }
}

/* ---------- checkers ---------- */
.checker {
  width: calc(var(--die) * 0.78);
  height: calc(var(--die) * 0.78);
  border-radius: 50%;
  flex: 0 0 auto;
  position: relative;
  z-index: 1;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: calc(var(--die) * 0.32);
  font-weight: 800;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .55);
}
.checker.white { background: radial-gradient(circle at 35% 30%, #fff, var(--white-checker)); border: 1px solid var(--white-checker-edge); color: #6a5b40; }
.checker.black { background: radial-gradient(circle at 35% 30%, #55555f, var(--black-checker)); border: 1px solid var(--black-checker-edge); color: #edeef5; }
/* --overlap (in --die units, negative) is set per point by BoardUI.fitStacks so
   a full 15-checker stack still fits inside the point. */
.checker.stacked { margin-top: calc(var(--die) * var(--overlap, -0.5)); }
.point.bottom .checker.stacked {
  margin-top: 0;
  margin-bottom: calc(var(--die) * var(--overlap, -0.5));
}

.checker.ghost {
  position: fixed;
  z-index: 200;
  width: calc(var(--die) * 1.1);
  height: calc(var(--die) * 1.1);
  font-size: calc(var(--die) * 0.42);
  transform: translate(-50%, -50%);
  box-shadow: 0 4px 12px rgba(0, 0, 0, .6);
  opacity: .95;
}
body.dragging { cursor: grabbing; }
body.dragging * { user-select: none; }

/* a checker hopping between points (App drives the keyframes via the
   Web Animations API — lift, arc, settle) */
.checker.flyer {
  position: fixed;
  z-index: 190;
  margin: 0;
  pointer-events: none;
  box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
  will-change: transform;
}

/* ---------- dice, lying on the board surface ---------- */
.dice-layer {
  position: absolute;
  inset: 0;
  pointer-events: none; /* taps pass through to the board underneath */
  z-index: 5;
}
/* No slot, no frame — the dice simply come to rest around the centre of the
   player's RIGHT half of the board. The 180° board rotation for black is
   mirrored here so each player sees their dice on their own right. */
.dice-tray {
  position: absolute;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  gap: calc(var(--die) * 0.26);
  max-width: calc(var(--die) * 2.55); /* a double (4 dice) wraps to a 2×2 cluster */
  transform: translate(-50%, -50%);
}
.dice-tray.near { left: 71%; top: 50%; }
.dice-tray.far  { left: 29%; top: 50%; }
#app.view-black .dice-tray.near { left: 29%; }
#app.view-black .dice-tray.far  { left: 71%; }
.dice-tray.empty { display: none; }
.dice-count {
  flex: 0 0 100%;
  text-align: center;
  margin-top: calc(var(--die) * 0.12);
  font-size: calc(var(--die) * 0.34);
  font-weight: 800;
  color: var(--text);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .7);
}

.die {
  width: var(--die);
  height: var(--die);
  border-radius: 22%;
  background: linear-gradient(150deg, #fdf8ee, #ded1b8);
  box-shadow:
    0 3px 7px rgba(0, 0, 0, .55),
    inset 0 1px 2px rgba(255, 255, 255, .8),
    inset 0 -3px 4px rgba(0, 0, 0, .18);
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  padding: 15%;
  gap: 4%;
  will-change: transform;
  transform: rotate(var(--tilt, 0deg)); /* small per-die tilt: "tossed", not placed */
}
.die.used { opacity: .26; filter: grayscale(.55); }
.die .pip { display: block; }
.die .pip.on {
  background: radial-gradient(circle at 35% 35%, #4a3f38, #241d19);
  border-radius: 50%;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .55);
}

/* Player-coloured dice. Square with a hard rim, so they never read as a
   checker (round) of the same colour. */
.die.white {
  background: linear-gradient(150deg, #ffffff, #e7e2d4);
  box-shadow:
    0 3px 7px rgba(0, 0, 0, .55),
    inset 0 1px 2px rgba(255, 255, 255, .95),
    inset 0 -3px 5px rgba(120, 110, 88, .30),
    inset 0 0 0 1px rgba(110, 100, 78, .40);
}
.die.white .pip.on {
  background: radial-gradient(circle at 35% 35%, #3b3430, #131010);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .5);
}
.die.black {
  background: linear-gradient(150deg, #24242c, #0d0d11);
  box-shadow:
    0 3px 8px rgba(0, 0, 0, .7),
    inset 0 1px 2px rgba(255, 255, 255, .16),
    inset 0 -3px 5px rgba(0, 0, 0, .55),
    inset 0 0 0 1px rgba(255, 255, 255, .16);
}
.die.black .pip.on {
  background: radial-gradient(circle at 35% 35%, #fcf8ef, #d5cfc0);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .35);
}

/* roll animation — the values themselves always come from the server */
.die.rolling { animation: die-roll .5s cubic-bezier(.35, .1, .5, 1) infinite; }
@keyframes die-roll {
  0%   { transform: translateY(0) rotate(0) scale(1); }
  20%  { transform: translateY(-42%) rotate(130deg) scale(1.12); }
  45%  { transform: translateY(10%) rotate(215deg) scale(.9); }
  70%  { transform: translateY(-20%) rotate(315deg) scale(1.06); }
  100% { transform: translateY(0) rotate(360deg) scale(1); }
}
/* the toss landing: drop in, bounce, settle at the die's resting tilt */
.die.settling { animation: die-land .38s cubic-bezier(.2, 1.35, .4, 1); }
@keyframes die-land {
  0%   { transform: translateY(-70%) scale(1.3) rotate(calc(var(--tilt, 0deg) - 16deg)); opacity: .7; }
  55%  { transform: translateY(6%) scale(.92) rotate(calc(var(--tilt, 0deg) + 5deg)); opacity: 1; }
  78%  { transform: translateY(-3%) scale(1.03) rotate(var(--tilt, 0deg)); }
  100% { transform: translateY(0) scale(1) rotate(var(--tilt, 0deg)); }
}
@media (prefers-reduced-motion: reduce) {
  .die.rolling, .die.settling { animation: none; }
}

/* ---------- end-of-match overlay (centred over the board) ---------- */
.board-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6%;
  background: rgba(12, 10, 8, .58);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.board-overlay-card {
  max-width: 88%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 18px 22px;
  border-radius: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .55);
  text-align: center;
}
.board-overlay-title {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: .5px;
  color: var(--text);
}
.board-overlay.won .board-overlay-title { color: var(--accent); }
.board-overlay-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}
.overlay-btn {
  min-height: 42px;
  padding: 0 18px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--text);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.overlay-btn.primary { background: var(--accent); border-color: var(--accent); color: #1c1300; }
.overlay-btn:active { transform: translateY(1px); }
.overlay-btn:disabled { opacity: .5; cursor: default; }

/* ---------- status line ---------- */
.status-line {
  flex: 0 0 auto;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  min-height: 20px;
  padding: 4px 6px;
  color: var(--text);
}
.status-line.win { color: var(--accent); font-size: 16px; }
.status-line.warn { color: var(--danger); }

/* ---------- toast ---------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(64px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  background: var(--danger);
  color: #fff;
  padding: 9px 16px;
  border-radius: 10px;
  font-size: 13px;
  z-index: 300;
  max-width: 90vw;
  text-align: center;
}

/* ================================================================
   LANDSCAPE — a dedicated layout, not a scaled-down portrait one.
   `.landscape` is toggled on <html> by JS (main.ts) from the real
   viewport ratio, so it is reliable during Telegram fullscreen
   transitions where an (orientation:) media query can lag.

       [ info rail ] [ BIG BOARD ]
   ================================================================ */
:root.landscape #app {
  /* the 560px portrait cap would leave huge empty side bands here */
  max-width: none;
}
/* non-game screens still read best as a centred narrow column */
:root.landscape #screen-home,
:root.landscape #screen-rating,
:root.landscape #screen-profile,
:root.landscape #screen-error {
  width: 100%;
  max-width: 560px;
  margin-inline: auto;
}
/* keep the nav slim when height is scarce */
:root.landscape .nav-btn { min-height: 40px; font-size: 10px; flex-direction: row; gap: 5px; }
:root.landscape .nav-btn .nav-ico { font-size: 15px; }

:root.landscape #screen-game {
  display: grid;
  /* rail is a small slice of the ACTUAL screen-game width (already inside the
     safe-area padding on #app), so the board gets the rest */
  grid-template-columns: clamp(102px, 19%, 172px) minmax(0, 1fr);
  grid-template-rows: auto auto minmax(0, 1fr);
  grid-template-areas:
    "top     board"
    "players board"
    "status  board";
  gap: 6px 10px;
}
:root.landscape .topbar {
  grid-area: top;
  flex-wrap: wrap;
  font-size: 10px;
  gap: 4px 8px;
}
:root.landscape .players {
  grid-area: players;
  flex-direction: column;
  gap: 10px;
  margin-top: 0;
  margin-left: 18px; /* room for the avatars that overhang each card's left edge */
}
/* Landscape rail: every card is [avatar][info]; the avatar overhangs the card's
   LEFT border (bigger than before) but never widens the rail into the board —
   the rail column keeps its fixed grid width and the overhang spills into the
   small gutter, not the board. */
:root.landscape .player-card {
  padding: 6px 8px 6px 30px;
  font-size: 12px;
}
:root.landscape #player-opp { flex-direction: row; }
:root.landscape #player-opp .pmeta { margin-left: auto; margin-right: 0; }
:root.landscape #player-me .avatar--hud,
:root.landscape #player-opp .avatar--hud {
  --avatar-size: 40px;
  top: 50%;
  left: -16px;
  right: auto;
  transform: translateY(-50%);
}
:root.landscape .player-card .pmeta { font-size: 11px; }
:root.landscape .board-wrap {
  grid-area: board;
  /* spanning all three rows: min-height:0 lets it NOT inflate the auto rows,
     so the info rail keeps its natural (small) size and the board takes the
     rest of the height. */
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}
:root.landscape .status-line {
  grid-area: status;
  align-self: start;
  text-align: left;
  min-height: 0;
  padding: 2px 2px;
  font-size: 12px;
  line-height: 1.3;
}

/* very short landscape (phone on its side): trim the rail further */
@media (orientation: landscape) and (max-height: 430px) {
  :root.landscape #screen-game { gap: 4px 8px; }
  :root.landscape .player-card { padding: 4px 7px 4px 28px; }
  :root.landscape #player-me .avatar--hud,
  :root.landscape #player-opp .avatar--hud { --avatar-size: 34px; left: -13px; }
  :root.landscape .topbar .text-btn { padding: 3px 2px; }
}
