

/* Custom Scrollbar Styles */
::-webkit-scrollbar {
  width: 12px;
  height: 12px;
  -webkit-appearance: none;
}

::-webkit-scrollbar-track {
  background: #000000;
  border-radius: 10px;
  -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.1);
}

::-webkit-scrollbar-thumb {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 10px;
  border: 2px solid #000000;
  -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.2);
}

::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}

::-webkit-scrollbar-corner {
  background: #000000;
}

/* Firefox Scrollbar */
* {
  scrollbar-width: thin;
  scrollbar-color: #764ba2 #000000;
}

/* No swiping back or forward through history anywhere in the app (a sideways trackpad scroll that runs past the edge of
   the map, the action bar or the page would otherwise go back a page, out of the game) */
html,
body {
  overscroll-behavior-x: none;
}

body {
  font-family: 'Roboto', sans-serif;
  margin: 0;
  padding: 0;
}

input {
  padding: 12px 20px;
  font-size: 16px;
  border: 2px solid #764ba2;
  border-radius: 25px 0 0 25px;
  background-color: white;
  color: #333;
  width: 150px;
  outline: none;
  transition: border-color 0.3s;
  vertical-align: top;
}

button {
  font-family: 'Roboto', sans-serif;
  margin: 0 10px 0 0;
  padding: 12px 24px;
  white-space: nowrap;
  background-color: #764ba2;
  color: #ffffff;
  border: none;
  border-radius: 25px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 19px;
}

button.cancel {
  background-color: #dc3545;
}

input + button {
  border-radius: 0 25px 25px 0;
}

input::placeholder {
  color: #999;
}

button:hover {
  background-color: #9370db;
}

button:hover.cancel {
  background-color: #c82333;
}

button:disabled {
  background-color: #140f1d;
  cursor: not-allowed;
}

/* The header's height, which the page content (.Content) starts below: 10px above and below its 52px buttons */
:root {
  --header-height: 72px;
}

.Header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  box-sizing: border-box;
  height: var(--header-height);
  padding: 0 20px; /* its contents are centered in the height, so the space above and below them is the same */
  justify-content: space-between;
  align-items: center;
  color: white;
  display: flex;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

/* The title is a link home: it looks like the title, not a link */
.Header .titleLink {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

.Header .title {
  margin: 0;
  font-size: 32px;
  font-weight: bold;
  letter-spacing: 1px;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}

.Header .userSection {
  display: flex;
  align-items: center;
  gap: 6px;
}

.Header .loginSection {
  display: flex;
}

.Header .emailBadge {
  background: rgba(255, 255, 255, 0.2);
  padding: 15px 25px;
  border-radius: 12.5px;
  backdrop-filter: blur(10px);
  margin-right: 7.5px;
}

.Header button {
  margin: 0 0 0 10px; /* the space on the left instead of the right (see button), so the last one ends at the header's padding */
  background: rgba(255, 255, 255, 0.9);
  color: #764ba2;
  padding: 15px 25px;
  border-radius: 12.5px;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.Header button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

/* The Guide link (opens the guide in a new tab), drawn like the header's buttons */
.Header .guideLink {
  margin: 0 0 0 10px;
  background: rgba(255, 255, 255, 0.9);
  color: #764ba2;
  padding: 15px 25px;
  border-radius: 12.5px;
  font-family: 'Roboto', sans-serif;
  font-size: 19px;
  font-weight: 600;
  line-height: normal;
  white-space: nowrap;
  text-decoration: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  transition: all 0.3s ease;
}

.Header .guideLink:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

/* Logged out: the Guide link, then the email field */
.Header .loginSection .guideLink {
  margin: 0 17.5px 0 0;
}

.Header .input {
  padding: 15px 25px;
  border-radius: 12.5px;
  border: none;
  outline: none;
  min-width: 250px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  margin-right: 7.5px;
}

.Content {
  position: fixed;
  top: var(--header-height); /* right below the header, not over its bottom edge */
  left: 0;
  right: 0;
  bottom: 0;
  background-color: black;
}

.LoggedInMainPage {
  height: 100%;
  box-sizing: border-box;
  overflow-y: auto; /* the settings sit below the games list */
  padding: 40px;
  text-align: center;
}

/* The home page when logged out: the email field and Log In, then a note on how logging in works */
.LoginPage {
  padding: 80px 40px;
  text-align: center;
  color: white;
}

.LoginPage input {
  width: 320px;
  padding: 12px 20px;
  border: 2px solid #764ba2;
  border-radius: 25px 0 0 25px;
  font-size: 16px;
  vertical-align: top;
}

.LoginPage button {
  margin: 0;
  padding: 12px 24px;
  border-radius: 0 25px 25px 0;
  font-size: 19px;
}

.LoginPage .loginNote {
  margin-top: 16px;
  color: rgba(255, 255, 255, 0.75);
  font-size: 16px;
}

/* How the game is meant to be played, above the login */
.LoginPage .howToPlay {
  max-width: 620px;
  margin: 0 auto 40px;
  color: rgba(255, 255, 255, 0.85);
  font-size: 17px;
  line-height: 1.5;
}

/* A join link was opened: the game waiting for the login */
.LoginPage .invite {
  margin: 0 auto 24px;
  font-size: 18px;
  color: #ffc107;
}

/* After a login link is sent: check your email, or start over with another */
.LoginPage h2 {
  margin: 0 0 12px;
  font-size: 28px;
}

.LoginPage button.otherEmail {
  margin-top: 24px;
  border-radius: 25px;
  font-size: 16px;
}

.LoginPage .guideLink {
  display: inline-block;
  margin-top: 32px;
  color: #b9a3f5;
  font-size: 17px;
}

/* Shown instead of the login when the server is at capacity (ServerBusyEvent): the ask, why, PayPal's button, then
   Try Again or Back */
.DonatePage {
  max-width: 620px;
  margin: 0 auto;
  padding: 80px 16px;
  text-align: center;
  color: white;
}

.DonatePage h2 {
  margin: 0 0 20px;
  font-size: 32px;
  line-height: 1.3;
}

.DonatePage p {
  margin: 0 0 16px;
  font-size: 17px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.85);
}

.DonatePage .reason {
  color: #ffc107;
}

.DonatePage .after {
  margin-top: 32px;
}

/* The first wrong-level warning in a game (BattleMap): a popup over the page, closed with OK or a click outside it */
.LevelWarning {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.6);
}

.LevelWarning .box {
  max-width: 420px;
  margin: 16px;
  padding: 24px 28px;
  border-radius: 12px;
  background: #2a2140;
  color: white;
  text-align: center;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}

.LevelWarning h3 {
  margin: 0 0 12px;
  font-size: 24px;
}

.LevelWarning p {
  margin: 0 0 12px;
  font-size: 17px;
  line-height: 1.4;
}

.LevelWarning p.hint {
  color: rgba(255, 255, 255, 0.7);
  font-size: 15px;
}

.LevelWarning button {
  margin: 8px 0 0;
  min-width: 100px;
}

/* The game guide (/guide): contents links, then a section each: its text on the left and a picture on the right (the
   game's own card faces and token badges, or a small map), the picture under the text on a narrow screen */
.GuidePage {
  height: 100%;
  box-sizing: border-box;
  overflow-y: auto;
  padding: 40px 16px;
  color: rgba(255, 255, 255, 0.9);
}

.GuidePage .guide {
  max-width: 960px;
  margin: 0 auto;
  font-size: 17px;
  line-height: 1.5;
}

.GuidePage h2 {
  margin: 0 0 16px;
  font-size: 36px;
  color: white;
}

.GuidePage .contents {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
}

.GuidePage .contents a {
  padding: 6px 14px;
  border-radius: 16px;
  background: rgba(118, 75, 162, 0.35);
  color: white;
  text-decoration: none;
  font-size: 15px;
}

.GuidePage .contents a:hover {
  background: rgba(118, 75, 162, 0.7);
}

.GuidePage section {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 40px;
  padding: 24px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  margin-top: 16px;
}

.GuidePage section .text {
  flex: 1 1 320px;
}

.GuidePage section .example {
  flex: 0 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  pointer-events: none; /* a picture: its buttons don't do anything */
}

.GuidePage h3 {
  margin: 0 0 8px;
  font-size: 24px;
  color: #b9a3f5;
}

.GuidePage p {
  margin: 0 0 10px;
}

.GuidePage p.spirit {
  color: rgba(255, 255, 255, 0.7);
  font-style: italic;
}

.GuidePage strong {
  color: white;
}

.GuidePage .HandCard {
  height: 290px;
}

.GuidePage .cards {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
}

/* A small map: 44px squares, a character's portrait on its square */
.GuidePage .mapDiagram {
  margin: 0;
  text-align: center;
}

.GuidePage .mapDiagram .squares {
  display: grid;
  grid-auto-rows: 44px;
  gap: 2px;
  justify-content: center;
}

.GuidePage .mapDiagram .square {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  background: #3d4a36; /* ground */
  font-size: 13px;
  color: white;
}

.GuidePage .mapDiagram .square img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
}

.GuidePage .mapDiagram .square.place { background: #2e8b3e; }
.GuidePage .mapDiagram .square.range { background: rgba(211, 47, 47, 0.75); }
.GuidePage .mapDiagram .square.wall { background: #555; }
.GuidePage .mapDiagram .square.fog { background: #151515; }

.GuidePage .mapDiagram .square.lastSeen img {
  opacity: 0.45;
}

.GuidePage .mapDiagram .square.lastSeen span {
  position: absolute;
  bottom: -2px;
  font-size: 9px;
  white-space: nowrap;
}

.GuidePage .mapDiagram figcaption {
  margin-top: 8px;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.7);
}

/* The movement die's six faces */
.GuidePage .dieFaces {
  display: flex;
  gap: 6px;
}

.GuidePage .dieFaces .face {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding: 0 6px;
  box-sizing: border-box;
  border-radius: 8px;
  background: white;
  color: #222;
  font-weight: bold;
  font-size: 16px;
}

.GuidePage .dieFaces .face.all {
  background: #b9a3f5;
}

.GuidePage .joinCode {
  display: flex;
  align-items: center;
  gap: 8px;
}

.GuidePage .joinCode span {
  font-family: monospace;
  font-size: 28px;
  letter-spacing: 3px;
  margin-right: 8px;
}

.GuidePage .joinCode button,
.GuidePage .alliances button {
  margin: 0;
  font-size: 15px;
  padding: 8px 16px;
}

.GuidePage .statuses div {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 0;
}

.GuidePage .statuses .bubble {
  width: 20px;
  height: 20px;
  border-radius: 50%;
}

.GuidePage .statuses .bubble.takingTurn { background: #1f5fbf; }
.GuidePage .statuses .bubble.ended { background: #28a745; }
.GuidePage .statuses .bubble.offline { background: #dc3545; }

.GuidePage .damage {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 20px;
}

.GuidePage .damage .attack,
.GuidePage .damage .defense {
  padding: 8px 14px;
  border-radius: 4px;
  font-size: 26px;
  font-weight: bold;
}

.GuidePage .damage .attack { background: #b3261e; }
.GuidePage .damage .defense { background: #1f5fbf; }

.GuidePage .tokenExample {
  display: flex;
  align-items: flex-start;
  margin: 5px;
}

.GuidePage .tokenExample img {
  width: 110px;
  height: 110px;
  border-radius: 4px;
  object-fit: cover;
}

.GuidePage .alliances {
  display: flex;
  align-items: center;
  gap: 8px;
}

.GuidePage .alliances .badge {
  padding: 10px 18px;
  border-radius: 12px;
  font-size: 13px;
  font-weight: bold;
}

.GuidePage .alliances .badge.ally { background: #28a745; }
.GuidePage .alliances .badge.enemy { background: #dc3545; }

.UpdateNickname, .JoinCode {
  display: inline-block;
}

/* Shown until the user sets a nickname: opening games waits for one */
.LoggedInMainPage .nicknameNeeded {
  margin: 12px 0;
  color: #ffc107;
  font-size: 16px;
}

.LoggedInMainPage input {
  padding: 12px 20px;
  font-size: 16px;
  vertical-align: top;
}

.LoggedInMainPage button {
  padding: 12px 24px;
  font-size: 19px;
}

.LoggedInMainPage input + button {
  border-radius: 0 25px 25px 0;
}

.LoggedInMainPage input::placeholder {
  color: #999;
}

.LoggedInMainPage .Settings {
  max-width: 560px;
  margin: 40px auto 0;
  text-align: left;
  color: white;
}

.LoggedInMainPage .Settings .settingsCard {
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.08);
}

.LoggedInMainPage .Settings .setting {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  font-size: 16px;
  cursor: pointer;
}

.LoggedInMainPage .Settings .setting + .setting {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* A checkbox drawn as an on/off switch, purple when on */
.LoggedInMainPage .Settings .switch {
  appearance: none;
  position: relative;
  width: 40px;
  height: 22px;
  margin: 0;
  padding: 0;
  border: none; /* the global input style has a border */
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.25);
  cursor: pointer;
}

.LoggedInMainPage .Settings .switch::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: white;
}

.LoggedInMainPage .Settings .switch:checked {
  background: #764ba2;
}

.LoggedInMainPage .Settings .switch:checked::after {
  left: 21px;
}

/* Donating (once the user has joined a game): a note, then PayPal's yellow Donate button, above the admin section */
.LoggedInMainPage .Donate {
  max-width: 560px;
  margin: 40px auto 0;
  color: white;
  font-size: 16px;
  line-height: 1.5;
}

/* PayPal's yellow Donate button (DonateButton: the main page's Donate section, the donate page) */
.DonateButton {
  display: inline-block;
  margin: 8px 0 0;
  padding: 12px 32px;
  border: none;
  border-radius: 25px;
  background-color: #ffc439;
  color: #003087;
  font-size: 18px;
  font-weight: bold;
  text-decoration: none;
  cursor: pointer;
}

.DonateButton:hover {
  background-color: #f2ba36;
}

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

.LoggedInMainPage .Admin {
  max-width: 1136px; /* two 560px columns and the gap */
  margin: 40px auto 0;
  text-align: left;
  color: white;
}

.LoggedInMainPage .Admin .adminColumns {
  display: flex;
  flex-wrap: wrap; /* one column when there isn't room for two */
  gap: 16px;
}

.LoggedInMainPage .Admin .adminColumn {
  flex: 1 1 360px;
  min-width: 0;
}

.LoggedInMainPage .Admin .thumbnail.portrait {
  width: 40px;
  background: rgba(255, 255, 255, 0.1);
}

.LoggedInMainPage .Admin h3 {
  margin: 0 0 8px;
  font-size: 16px;
  color: rgba(255, 255, 255, 0.7);
}

.LoggedInMainPage .Admin .settingsCard {
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.08);
}

.LoggedInMainPage .Admin .adminMap {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
}

.LoggedInMainPage .Admin .adminMap + .adminMap {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.LoggedInMainPage .Admin .adminMap.empty {
  color: rgba(255, 255, 255, 0.6);
}

/* The contact email in it */
.LoggedInMainPage .Admin .adminMap.empty a {
  color: #b39ddb;
}

.LoggedInMainPage .Admin .thumbnail {
  width: 64px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
}

.LoggedInMainPage .Admin .name {
  flex: 1;
  font-size: 16px;
}

.LoggedInMainPage .Admin .adminMap button {
  padding: 6px 16px;
  font-size: 14px;
}

/* Published / Unpublished tag, on the admin list, the map and roster editors, and an in-game map's admin controls (for
   admins who aren't the superadmin) */
.LoggedInMainPage .Admin .status,
.MapEditor .toolbar .status,
.RosterEditor .toolbar .status,
.MapArea .controls .mapAdmin .status {
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.15);
  color: white;
  font-size: 12px;
}

.LoggedInMainPage .Admin .status.published,
.MapEditor .toolbar .status.published,
.RosterEditor .toolbar .status.published,
.MapArea .controls .mapAdmin .status.published {
  background: #28a745;
}

/* Picking cards to discard (DiscardSelection), in place of the action bar: what to pick and Confirm, then the hand;
   a chosen card is outlined red */
.ActionBar .DiscardSelection {
  display: flex;
  flex-direction: column;
  gap: 6px;
  height: 100%;
  padding: 6px 10px 0;
  box-sizing: border-box;
  text-align: left;
}

.ActionBar .DiscardSelection .prompt {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: bold;
}

.ActionBar .DiscardSelection .picked {
  font-weight: normal;
  color: rgba(255, 255, 255, 0.6);
}

.ActionBar .DiscardSelection .Hand {
  flex: 1;
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  min-height: 0;
  overflow-x: auto;
}

.ActionBar .HandCard.discarding {
  outline: 3px solid #dc3545;
}

/* Choosing the characters for a card's effects (TargetSelection), in place of the action bar: the card, then each
   choice's possible characters above the chosen ones, then Confirm / Cancel */
.ActionBar .TargetSelection {
  display: flex;
  align-items: stretch;
  gap: 16px;
  height: 100%;
  padding: 0 10px;
  box-sizing: border-box;
  text-align: left;
}

.ActionBar .TargetSelection .choices {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 0;
  overflow-y: auto;
}

.ActionBar .TargetSelection .prompt {
  font-size: 16px;
  font-weight: bold;
}

.ActionBar .TargetSelection .picked {
  font-weight: normal;
  color: rgba(255, 255, 255, 0.6);
}

.ActionBar .TargetSelection .targets {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-height: 70px;
  margin-top: 6px;
  padding: 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
}

.ActionBar .TargetSelection .targets.chosen {
  background: rgba(40, 167, 69, 0.2);
}

.ActionBar .TargetSelection .none {
  color: rgba(255, 255, 255, 0.5);
  font-size: 13px;
}

.ActionBar .TargetSelection button.target {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 4px;
  border-radius: 6px;
  background: transparent;
}

.ActionBar .TargetSelection button.target:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.15);
}

.ActionBar .TargetSelection button.target .CharacterIcon {
  width: 46px;
  height: 46px;
}

.ActionBar .TargetSelection .targetName {
  font-size: 11px;
}

.ActionBar .TargetSelection .buttons {
  display: flex;
  gap: 8px;
}

.ActionBar .TargetSelection button.save {
  background-color: #28a745;
}

.ActionBar .TargetSelection button.save:disabled {
  background-color: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.4);
}

/* A character's tokens (TokenBadges): a 50px badge per token, its icon. They fill a column top to bottom (as many as fit
   in the column's height), then start a new column to the left of it (right to left: direction rtl) */
.TokenBadges {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(auto-fill, 50px);
  grid-auto-columns: 50px;
  gap: 6px;
  direction: rtl;
  margin: 5px 5px 5px 0;
}

/* In the action bar, a column is as tall as the portrait beside it (3 badges) */
.ActionBar .PlayPhase .CharacterControls .TokenBadges {
  height: 176px;
}

/* Always a 50px square: fixed on both sides, and never stretched or squeezed by a flex or grid around it */
.TokenBadges .token {
  width: 50px;
  height: 50px;
  min-width: 50px;
  min-height: 50px;
  max-width: 50px;
  max-height: 50px;
  aspect-ratio: 1;
  flex: none;
  padding: 6px;
  box-sizing: border-box;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.12);
  direction: ltr;
}

/* My character's token: a button that removes it */
.TokenBadges button.token {
  display: block;
  margin: 0;
  border: none;
  cursor: pointer;
}

.TokenBadges button.token:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.3);
}

.TokenBadges button.token:disabled {
  cursor: default;
  opacity: 1;
}

/* A Generic token's icon, one of /icons/<n>.png (TokenIcon; each file has its icon centered): centered wherever it's
   shown, a token badge or the editor's buttons */
.TokenIcon {
  display: block;
  margin: auto;
}

/* The roster editor's Generic token look: the icon button (on its color), the color input, and the grid of icons */
.RosterEditor .TokenLookPicker {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 8px;
}

.RosterEditor .TokenLookPicker button.tokenIconButton {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin: 0;
  padding: 0;
  border-radius: 8px;
}

.RosterEditor .TokenLookPicker input[type="color"] {
  width: 36px;
  height: 36px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}

.RosterEditor .TokenLookPicker .iconGrid {
  position: absolute;
  top: 42px;
  left: 0;
  z-index: 20;
  display: grid;
  grid-template-columns: repeat(10, 34px);
  gap: 4px;
  padding: 8px;
  border-radius: 8px;
  background: #222;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.6);
}

.RosterEditor .TokenLookPicker .iconGrid button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin: 0;
  padding: 0;
  border-radius: 6px;
}

.RosterEditor .TokenLookPicker .iconGrid button.chosen {
  outline: 2px solid #ffc107;
}

/* Moving a card's characters (MoveSelection), in place of the action bar: the card, then the characters left to move
   (the one being moved outlined), each with Skip; it shares the target picker's look */
.ActionBar .MoveSelection,
.ActionBar .AdjacentMoveSelection {
  display: flex;
  align-items: stretch;
  gap: 16px;
  padding: 0 10px;
  box-sizing: border-box;
  text-align: left;
}

.ActionBar .MoveSelection .choices,
.ActionBar .AdjacentMoveSelection .choices {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 0;
}

.ActionBar .MoveSelection .prompt,
.ActionBar .AdjacentMoveSelection .prompt {
  font-size: 16px;
  font-weight: bold;
}

.ActionBar .MoveSelection .picked,
.ActionBar .AdjacentMoveSelection .picked,
.ActionBar .MoveSelection .hint,
.ActionBar .AdjacentMoveSelection .hint {
  font-weight: normal;
  color: rgba(255, 255, 255, 0.6);
}

.ActionBar .MoveSelection .hint,
.ActionBar .AdjacentMoveSelection .hint {
  font-size: 13px;
}

.ActionBar .MoveSelection .targets,
.ActionBar .AdjacentMoveSelection .targets {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
  padding: 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
}

.ActionBar .MoveSelection .mover {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border-radius: 6px;
}

.ActionBar .MoveSelection .mover.moving {
  outline: 2px solid #28a745;
  background: rgba(40, 167, 69, 0.2);
}

.ActionBar .MoveSelection button.target,
.ActionBar .AdjacentMoveSelection button.target {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 4px;
  border-radius: 6px;
  background: transparent;
}

.ActionBar .MoveSelection button.target:hover,
.ActionBar .AdjacentMoveSelection button.target:hover {
  background: rgba(255, 255, 255, 0.15);
}

.ActionBar .MoveSelection button.target .CharacterIcon,
.ActionBar .AdjacentMoveSelection button.target .CharacterIcon {
  width: 46px;
  height: 46px;
}

.ActionBar .MoveSelection .targetName,
.ActionBar .AdjacentMoveSelection .targetName {
  font-size: 11px;
}

.ActionBar .MoveSelection button.skip {
  margin: 0;
  padding: 2px 10px;
  font-size: 12px;
  background-color: rgba(255, 255, 255, 0.15);
}

/* The roster editor page: a toolbar, then each character with its deck, one row per card (fields, then a preview) */
/* The Move Adjacent picker (like the Move picker): the character being moved outlined, a character out of sight
   dashed (picking it shows where it is), and Back */
.ActionBar .AdjacentMoveSelection button.target.moving {
  outline: 2px solid #ffc107;
}

.ActionBar .AdjacentMoveSelection button.target.unseen {
  border: 2px dashed rgba(255, 255, 255, 0.5);
}

.ActionBar .AdjacentMoveSelection .buttons {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.RosterEditor {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;
  color: white;
}

/* Stays at the top while the page scrolls, lined up with the characters below (the full width, like them) */
.RosterEditor .toolbar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 12px;
  height: 60px;
  margin: 0;
  padding: 0 16px;
  box-sizing: border-box;
  background: black;
}

.RosterEditor .toolbar .name {
  font-size: 18px;
  font-weight: bold;
}

.RosterEditor .toolbar .deckSize {
  color: rgba(255, 255, 255, 0.6);
  font-size: 14px;
}

/* Every button on the page has the same compact shape, square-ish like the fields */
.RosterEditor button {
  height: 32px;
  margin: 0;
  padding: 0 16px;
  border-radius: 4px;
  font-size: 13px;
}

/* The full width of the screen; never narrower than its content, so the longest effect criteria sentence (a Character
   Effect with Select, How Many, In and Of) stays on one line beside the card preview, even with larger fonts (the page
   scrolls sideways instead) */
.RosterEditor .characters {
  min-width: min-content;
  margin: 0;
  padding: 0 16px 40px;
  box-sizing: border-box;
}

.RosterEditor .character {
  margin-top: 24px;
  padding-bottom: 16px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.08);
}

.RosterEditor .characterHeader {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
}

.RosterEditor .characterHeader img {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 4px;
}

.RosterEditor .characterHeader > div {
  flex: 1;
}

.RosterEditor .characterName {
  font-size: 18px;
  font-weight: bold;
}

.RosterEditor .characterStats,
.RosterEditor .noCards {
  color: rgba(255, 255, 255, 0.6);
  font-size: 13px;
}

.RosterEditor .noCards {
  padding: 12px 16px;
}

/* Each card on a darker panel of its own, with a thick border and space between them, so neighbouring cards don't run
   together */
.RosterEditor .CardEditor {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin: 0 16px;
  padding: 16px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.35);
}

.RosterEditor .CardEditor + .CardEditor {
  margin-top: 20px;
}

.RosterEditor .CardEditor .fields {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
}

.RosterEditor .CardEditor label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
}

/* Takes the rest of its line (the name, beside the copies) */
.RosterEditor .CardEditor label.grow {
  flex: 1 1 auto;
}

/* Health and range, in the character's header */
.RosterEditor .CharacterStatsEditor {
  display: flex;
  align-items: flex-end;
  gap: 8px;
}

.RosterEditor .CharacterStatsEditor label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
}

/* Undo the global input style (rounded left end, purple border, fixed width) */
.RosterEditor .CharacterStatsEditor input,
.RosterEditor .CardEditor input {
  width: 80px;
  padding: 6px 8px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.4);
  color: white;
  font-family: inherit;
  font-size: 14px;
  box-sizing: border-box;
}

.RosterEditor .CardEditor select {
  padding: 6px 8px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.4);
  color: white;
  font-size: 14px;
}

/* Effects: a header, then each effect on a panel of its own (its criteria line, then its sub-effect lines, then the
   buttons that add sub-effects), then the buttons that add effects */
.RosterEditor .CardEditor .effectsHeader {
  flex: 1 1 100%;
  margin-top: 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  font-size: 14px;
  font-weight: bold;
  color: white;
}

.RosterEditor .CardEditor .effect {
  flex: 1 1 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
}

.RosterEditor .CardEditor .effect .criteria,
.RosterEditor .CardEditor .effect .subEffect,
.RosterEditor .CardEditor .effect .addSubEffect,
.RosterEditor .CardEditor .addEffect {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px 12px;
}

.RosterEditor .CardEditor .addEffect {
  flex: 1 1 100%;
}

/* An Add Token's removal: its own list of effects, indented under the token's line with a rule on the left */
.RosterEditor .CardEditor .tokenRemoval {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-left: 40px;
  padding-left: 16px;
  border-left: 2px solid rgba(255, 255, 255, 0.2);
}

.RosterEditor .CardEditor .tokenRemoval .effectsHeader {
  font-size: 13px;
  font-weight: normal;
  color: rgba(255, 255, 255, 0.8);
}

.RosterEditor .CardEditor .tokenRemoval .effect {
  background: rgba(0, 0, 0, 0.25);
}

/* The criteria and each sub-effect read as one sentence: the words inline around their fields, never wrapping (the page
   is wide enough for the longest criteria, Select + How Many + In + Of) */
.RosterEditor .CardEditor .effect .criteria,
.RosterEditor .CardEditor .effect .subEffect {
  flex-wrap: nowrap;
  align-items: center;
  white-space: nowrap;
}

/* A bespoke effect's panel: what it does (its card text; the rule is written in code), indented like a sub-effect */
.RosterEditor .CardEditor .effect.bespoke .bespokeDescription {
  margin: 6px 0 0 40px;
  font-size: 14px;
  font-style: italic;
  color: rgba(255, 255, 255, 0.8);
}

.RosterEditor .CardEditor .effect .criteria label,
.RosterEditor .CardEditor .effect .subEffect label {
  flex-direction: row;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}

.RosterEditor .CardEditor .effect .criteria input,
.RosterEditor .CardEditor .effect .subEffect input {
  width: 56px;
}

/* Move up / down, then remove: pushed to the end of the criteria line */
.RosterEditor .CardEditor .effect .criteria .moveButtons {
  margin-left: auto;
}

.RosterEditor .CardEditor .effect .moveButtons {
  display: flex;
  gap: 4px;
}

.RosterEditor .CardEditor .effect .moveButtons button {
  width: 28px;
  padding: 0;
}

.RosterEditor .CardEditor .effect .moveButtons button:disabled {
  opacity: 0.3;
  cursor: default;
}

.RosterEditor .CardEditor .effect .effectType {
  align-self: center;
  font-size: 13px;
  font-weight: bold;
  color: white;
}

/* Sub-effects sit under their criteria, indented */
.RosterEditor .CardEditor .effect .subEffect,
.RosterEditor .CardEditor .effect .addSubEffect {
  margin-left: 40px;
}

.RosterEditor .CardEditor .effect button.removeEffect {
  width: 32px;
  padding: 0;
  background-color: #dc3545;
}

.RosterEditor .CardEditor label.grow input {
  width: 100%;
}

/* The generated description, read only: a label, then the text as it will be on the card */
.RosterEditor .CardEditor .descriptionPreview {
  flex: 1 1 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.RosterEditor .CardEditor .descriptionLabel {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
}

.RosterEditor .CardEditor .descriptionText {
  padding: 8px 10px;
  border: 1px dashed rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.04);
  font-size: 14px;
  line-height: 1.4;
  color: white;
}

.RosterEditor .CardEditor .buttons {
  flex: 1 1 100%;
  display: flex;
  gap: 8px;
}

/* Save: green when there are changes to save, faded when there aren't */
.RosterEditor button.save {
  background-color: #28a745;
  color: white;
  font-weight: bold;
}

.RosterEditor button.save:hover:not(:disabled) {
  background-color: #218838;
}

.RosterEditor button.save:disabled {
  background-color: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.4);
}

/* The card preview keeps the hand's card size */
.RosterEditor .CardEditor .HandCard {
  flex: 0 0 auto;
  height: 300px;
  margin: 0;
}

/* The map editor page: a toolbar, then the map (the game's map styles, taking the rest of the page) */
.MapEditor {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.MapEditor .toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 60px;
  padding: 0 16px;
  box-sizing: border-box;
  color: white;
}

.MapEditor .toolbar .name {
  font-size: 18px;
  font-weight: bold;
}

.MapEditor .toolbar button,
.RosterEditor .toolbar button {
  margin: 0;
  padding: 8px 20px;
  font-size: 14px;
}

.MapEditor .MapArea {
  top: 60px;
  right: 0;
  bottom: 0;
}

.ChooseGame .gameSelect {
  display: inline-block;
  margin: 20px;
  padding: 10px;
  border-radius: 8px;
  background-color: aliceblue;
  cursor: pointer;
}

/* Can't be opened until the user sets a nickname */
.ChooseGame .gameSelect.locked {
  opacity: 0.6;
  cursor: not-allowed;
}

.ChooseGame .gameSelect div {
  color: black;
  padding: 5px;
  border-radius: 8px;
  background-color: aliceblue;
}

.ChooseGame .gameSelect .gameName {
  font-size: 20px;
  font-weight: bold;
  text-align: center;
}

.ChooseGame .gameSelect img {
  height: 200px;
}

/* The map on the left above the action bar, the event log down the right. The action bar's row is exactly as tall as
   what it shows (up to half the screen, then it scrolls), and the map takes the rest, so the bar resizes whenever its
   content changes */
.Game {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 450px; /* = .EventLog width */
  grid-template-rows: minmax(0, 1fr) auto;
  grid-template-areas:
    "map log"
    "bar log";
  width: 100%;
  height: 100%;
}

.Game .MapArea {
  position: relative;
  grid-area: map;
  inset: auto;
}

.CharacterIcon {
  position: relative;
  display:inline-block;
  vertical-align: top;
  border-radius: 4px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  text-align: left;
  writing-mode: vertical-rl;
  text-orientation: upright;
  white-space: wrap;
}

.CharacterIcon img {
  position : absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* Out of the game */
.CharacterIcon.defeated {
  filter: grayscale(1);
  opacity: 0.5;
}

.CharacterIcon .health {
  display: inline-block;
  width: 10%;
  height: 6%;
  margin: 1%;
  border-radius: 40%;
  background-color: red;
}

.MapArea {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.MapArea .BattleMap {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: scroll;
  /* A trackpad scroll that reaches the map's edge stops there: it isn't passed on to the page, where a sideways
     swipe is the browser's back / forward */
  overscroll-behavior: none;
}
.MapArea .BattleMap img {
  position: absolute;
  top: 0;
  left: 0;
}

.MapArea .BattleMap * {
  transition: all 500ms linear;
}

.MapArea .BattleMap.loading * {
  transition: none;
}

.MapArea button {
  margin: 20px auto;
  padding: 15px 30px;
  font-size: 18px;
  border-radius: 30px;
}

.MapArea .grid {
  position: absolute;
}

.MapArea .grid .CharacterIcon  {
  position: absolute;
  top: 0;
  left: 0;
  right:0;
  bottom:0;
}

.MapArea .grid .CharacterIcon img {
  width: 100%;
  height: 100%;
}

/* Fog of war: out of my characters' sight, shown where it was last seen */
.MapArea .grid.lastSeen .CharacterIcon {
  opacity: 0.4;
}

.MapArea .grid.lastSeen .lastSeenLabel {
  position: absolute;
  left: 50%;
  bottom: -2px;
  transform: translateX(-50%);
  padding: 0 4px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  font-size: 10px;
  line-height: 14px;
  white-space: nowrap;
  pointer-events: none;
}

.MapArea .grid.canMove {
  background-color: green;
  cursor: pointer;
  opacity: .2;
}

.MapArea .grid.canTarget {
  background-color: red;
  opacity: .25;
  pointer-events: none;
}

/* An opponent's character in range: clickable to attack it */
.MapArea .grid.canTarget.opponent {
  box-sizing: border-box;
  background-color: rgba(255, 0, 0, 0.35);
  border: 3px solid red;
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}

.MapArea .grid.canTarget.opponent:hover {
  background-color: rgba(255, 0, 0, 0.5);
}

.MapArea .grid.fogOfWar {
  background-color: black;
}

.MapArea .unpublishedGrid {
  position: absolute;
  border: 1px solid black;
  transition: all 0ms none;
}

.MapArea .wallToggle {
  position: absolute;
  padding: 0px;
  margin: 0px;
  border: none;
  border-radius: 0px;
  background-color: rgba(255, 255, 255, 0);
}

.MapArea .wallToggle:hover {
  background-color: rgba(255, 255, 255, 0.7);
}

.MapArea .selectMap {
  display: inline-block;
  margin: 20px;
  padding: 10px;
  border-radius: 8px;
  background-color: aliceblue;
  color: black;
  cursor: pointer;
}

.MapArea .selectMap img {
  height: 350px;
}

.MapArea .controls {
  position: absolute;
  bottom: 10px;
  right: 25px;
  z-index: 1000;
}

.MapArea .controls div {
  display: inline-block;
}

.MapArea .controls button {
  margin: 3px;
  min-width: 55px;
}

.MapArea .controls .mapAdmin {
  display: inline-flex;
  flex-direction: column;
  vertical-align: bottom;
}

.MapArea .controls .mapAdmin .status {
  margin: 3px;
  text-align: center;
}

.EventLog {
  position: relative;
  z-index: 1; /* its shadow over the map and the action bar */
  grid-area: log;
  width: 450px;
  background: black;
  overflow-y: auto;
  box-shadow: -2px 0 10px rgba(0, 0, 0, 0.3);
  color: white;
  font-size: 14px;
}

.EventLog .Event {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  padding: 2px;
  margin: 10px;
  margin-bottom: 0px;
  backdrop-filter: blur(5px);
  border-left: 3px solid #667eea;
  transition: all 0.2s ease;
}

.EventLog .Event .CharacterIcon {
  height: 50px;
  width: 50px;
  vertical-align: top;
}

.EventLog .Event:hover {
  background: rgba(255, 255, 255, 0.15);
  transform: translateX(-3px);
}

.EventLog .EventTime {
  color: rgba(255, 255, 255, 0.6);
  font-size: 11px;
  margin-bottom: 6px;
}

.EventLog .text {
  display: inline-block;
  vertical-align: top;
  padding: 10px;

}

.EventLog .nickname {
  color: #9370db;
  font-weight: bold;
  margin-right: 4px;
}

.EventLog .Event div {
  display: inline-block;
}

/* Attacker, red attack badge, ✕, blue defense badge (empty when not defended), defender */
.EventLog .Event .ResolvedAttack {
  padding: 6px 10px;
}

.EventLog .ResolvedAttack .attackRow {
  display: flex;
  align-items: center;
  gap: 8px;
}

.EventLog .ResolvedAttack.cancelled {
  opacity: 0.4;
}

.EventLog .ResolvedAttack .badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 4px;
  font-size: 20px;
  font-weight: bold;
}

.EventLog .ResolvedAttack .badge.attack {
  background: #b3261e;
}

.EventLog .ResolvedAttack .badge.defense {
  background: #1f5fbf;
}

.EventLog .ResolvedAttack .badge.empty {
  background: rgba(255, 255, 255, 0.05);
}

.EventLog .ResolvedAttack .versus {
  font-size: 18px;
  color: rgba(255, 255, 255, 0.7);
}

/* Each player's roll: their nickname, then the roll in a badge */
.EventLog .StartedNewTurn .playerRolls {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 6px;
}

.EventLog .StartedNewTurn .playerRoll {
  display: flex;
  align-items: center;
  gap: 8px;
}

.EventLog .StartedNewTurn .playerRoll .movementRoll {
  position: static;
  padding: 2px 8px;
  background: rgba(255, 255, 255, 0.15);
}

.EventLog .StartedNewTurn .roll {
  position: relative;
  margin-right: 4px;
}

.EventLog .StartedNewTurn .movementRoll {
  position: absolute;
  right: 0;
  bottom: 0;
  padding: 0 4px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.7);
  font-weight: bold;
}

/* Nickname on the left; roster, then the alliance button, pushed to the right */
.PlayerStatus {
  display: flex;
  align-items: center;
  margin:5px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 8px;
}

.PlayerStatus .status-bubble {
  display: inline-block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  margin-right: 4px;
  border: 2px solid rgba(0,0,0,0.15);
  background: #dc3545; /* default red */
  transition: background 0.2s;
  vertical-align: middle;
}
.PlayerStatus .status-bubble.active {
  background: #28a745;
}
.PlayerStatus .status-bubble.inactive {
  background: #dc3545;
}
.PlayerStatus .status-bubble.takingTurn {
  background: #1f5fbf;
}

.PlayerStatus .nickname {
  display:inline-block;
  margin-right: auto; /* pushes the roster and the alliance button right, even with no roster yet */
  padding: 17px 10px;
}

/* Same size for every label, one word per line: the word spacing is wider than the button, so each space wraps */
.PlayerStatus .alliance {
  flex: 0 0 auto;
  margin: 0 5px 0 0;
  width: 80px;
  height: 40px;
  padding: 0 4px;
  border-radius: 12px;
  white-space: normal;
  word-spacing: 80px;
  font-size: 12px;
  line-height: 1.2;
}

/* Locked alliances: same footprint as the button */
.PlayerStatus .allianceBadge {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 40px;
  margin: 0 5px 0 0;
  border-radius: 12px;
  color: white;
  font-size: 12px;
  font-weight: bold;
}

.PlayerStatus .allianceBadge.ally {
  background: #28a745;
}

.PlayerStatus .allianceBadge.enemy {
  background: #dc3545;
}

.PlayerStatus .alliance.invited {
  background: #28a745;
  color: white;
}

.PlayerStatus .alliance.allied {
  background: #1f5fbf;
  color: white;
}

.ActionBar {
  grid-area: bar;
  max-height: 50vh;
  padding: 10px;
  box-sizing: border-box;
  background-color: #000000;
  overflow: auto;
  color: white;
  text-align: center;
}

.ActionBar label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: 600;
  cursor: pointer;
}

.ActionBar input[type="checkbox"] {
  cursor: pointer;
  width: 18px;
  height: 18px;
}

.ActionBar input[type="number"] {
  width: 60px;
  padding: 6px 8px;
  border: 1px solid #666;
  border-radius: 4px;
  background-color: #333;
  color: white;
  font-size: 18px;
}

.ActionBar input[type="text"] {
  padding: 8px 12px;
  border: 1px solid #666;
  border-radius: 4px;
  background-color: #333;
  color: white;
}

.ActionBar button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
}

/* Everyone's placed: the one thing to do */
.ActionBar button.startGame {
  margin: 0;
  padding: 24px 80px;
  border-radius: 8px;
  font-size: 36px;
  font-weight: bold;
}

.ActionBar input + button {
  margin-right: 0px;
}

.ActionBar .PlaceCharacters {
  text-align: center;
  padding: 15px;
}

.ActionBar .PlaceCharacters span {
  display:inline-block;
  padding: 50px;
  font-size: 50px;
  font-weight: 400;
}

.ActionBar .PlaceCharacters .CharacterIcon {
  width: 150px;
  height: 150px;
}


.RosterList {
  color: white;
  height: 120px;
  width: 100%;
  overflow-y:scroll;
  white-space:nowrap;
}

.Roster {
  display: inline-block;
  text-align: left;
  padding:10px;
  margin:5px;
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  vertical-align: top;
}

.Roster .name {
  display: inline-block;
  text-align: left;
  font-weight: 600;
}

.Roster .characters {
  display: block;
  clear: both;
  margin-top:10px;
}

.Roster.mini {
  margin: 0px;
  padding: 5px;
}

.Roster .characters .CharacterIcon {
  width: 50px;
  height: 50px;
}

.Roster.mini .characters{
  margin: 0px;  
}

.Roster.mini .characters .CharacterIcon {
  width: 46px;
  height: 46px;
}

.Roster button {
  float: right;
  color: white;
  border: none;
  border-radius: 4px;
  height: 20px;
  width: 20px;
  cursor: pointer;
  font-size: 12px;
  font-weight: bold;
  text-align: center;
  padding:0px;
}

.Roster span {
  margin-right:10px;
  padding-top:3px;
}

.RosterList .Roster .remove {
  background-color: #dc3545;
}

.RosterList .Roster .remove:hover {
  background-color: #c82333;
}

.RosterList .Roster .add {
  background-color: #28a745;
}

.RosterList .Roster .add:hover {
  background-color: #218838;
}

.GameSetup {
  padding: 10px;
}

.GameSetup .settings {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 5px;
}

.GameSetup .settings button {
  padding: 10px 20px;
  font-weight: 600;
  font-size: 16px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  transition: all 0.2s ease;
}

.GameSetup .settings button:hover {
  transform: translateY(-1px);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
}

.GameSetup .settings button:active {
  transform: translateY(0);
}

.GameSetup .gameCode {
  display: flex;
  align-items: center;
  gap: 8px;
}

.GameSetup .gameCode input {
  width: 75px;
}

.GameSetup .movementMultiplier {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.GameSetup .movementMultiplier input {
  width: 90px;
}

.GameSetup .movementMultiplier .recommended {
  font-weight: normal;
  color: rgba(255, 255, 255, 0.7);
}

.GameSetup .gameName {
  display: flex;
  align-items: center;
  gap: 8px;
}

.GameSetup .gameName input {
  width: 200px;
}

.CharacterSelect {
  text-align: center;
  padding: 5px;
  font-size: 16px;
  font-weight: 400;
}

.CharacterSelect .rollCharacter {
  display: inline-block;
}

.CharacterSelect button{
  display:inline-block;
  vertical-align: top;
  margin: 10px;
  padding: 21px 30px;
  border-radius:10px;
  font-size: 28px;
}

.CharacterSelect button div{
  font-size: 16px;
}

.CharacterSelect .acceptRoster {
  font-size: 28px;
  padding: 30px 30px;
  background-color: #28a745;
  color: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  transition: all 0.2s ease;
}

.CharacterSelect .acceptRoster:hover {
  background-color: #218838;
  transform: translateY(-1px);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
}

/* One row: the characters (portrait, tokens, Center In Map, Move), the turn controls, then the hand, from the left, so the buttons stay put as cards come and
   go. max-content lets the ActionBar scroll sideways when it doesn't fit */
.ActionBar .PlayPhase {
  display: flex;
  align-items: flex-start;
  width: max-content;
  height: 100%;
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  text-align: center;
}

.ActionBar .PlayPhase .TurnControls {
  display: inline-block;
  vertical-align: top;
  margin: 5px;
}

.ActionBar .PlayPhase .TurnControls button {
  display: block;
  width: 180px;
  margin: 5px 0;
}

/* Attack in progress: attacker, attack card, defender, then the response (defense cards or waiting + cancel) */
.ActionBar .AttackPanel {
  display: flex;
  align-items: stretch;
  gap: 10px;
  width: max-content;
  height: 100%;
  margin: 0 auto;
  padding: 0 5px;
  box-sizing: border-box;
  font-size: 18px;
  font-weight: 600;
}

.ActionBar .AttackPanel .side,
.ActionBar .AttackPanel .response,
.ActionBar .AttackPanel .versus {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 10px;
}

.ActionBar .AttackPanel .side .CharacterIcon {
  width: 140px;
  height: 140px;
}

/* The portrait with its token badges beside it, a column as tall as the portrait (2 badges) */
.ActionBar .AttackPanel .side .portrait {
  display: flex;
  align-items: flex-start;
}

.ActionBar .AttackPanel .side .TokenBadges {
  height: 140px;
  margin: 0 0 0 6px;
}

.ActionBar .AttackPanel .versus {
  color: #ff6b6b;
  text-transform: uppercase;
}

.ActionBar .AttackPanel .response button {
  width: 160px;
}

.ActionBar .AttackPanel .HandCard {
  margin: 5px 0;
}

.ActionBar .HandCard.attacking,
.RosterEditor .HandCard.attacking,
.GuidePage .HandCard.attacking {
  outline: 2px solid red;
}

/* Cards in draw order, left to right, never wrapping */
.ActionBar .PlayPhase .Hand {
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  margin: 0 5px;
}

/* Every card the same size (290px tall in the action bar, whose height follows its content): name on top, large portrait on the left with attack (red)
   over defense (blue) on the right, then the description and the discard button */
.ActionBar .HandCard,
.RosterEditor .HandCard,
.GuidePage .HandCard {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 110px 64px; /* portrait column = 52 + 6 + 52, the height of the two stat rows, so it's square */
  grid-template-rows: 22px 52px 52px 1fr 28px;
  grid-template-areas:
    "name        name"
    "portrait    attack"
    "portrait    defense"
    "description description"
    "actions     actions";
  gap: 6px;
  width: 196px; /* 110 + 6 + 64 + 16 padding */
  box-sizing: border-box;
  margin: 5px;
  padding: 8px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.1);
  font-size: 16px;
  text-align: left;
}

/* Its own height: the action bar fits around its cards, not the other way round */
.ActionBar .HandCard {
  height: 290px;
}

.ActionBar .HandCard .name,
.RosterEditor .HandCard .name,
.GuidePage .HandCard .name {
  grid-area: name;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ActionBar .HandCard .portrait,
.RosterEditor .HandCard .portrait,
.GuidePage .HandCard .portrait {
  grid-area: portrait;
  width: 110px; /* always square, at most 110px tall (the two stat rows: 52 + 6 + 52) */
  height: 110px;
  max-height: 110px;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 4px;
}

.ActionBar .HandCard .attack,
.ActionBar .HandCard .defense,
.RosterEditor .HandCard .attack,
.GuidePage .HandCard .attack,
.RosterEditor .HandCard .defense,
.GuidePage .HandCard .defense {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  font-size: 30px;
  font-weight: bold;
  line-height: 1;
}

.ActionBar .HandCard .attack,
.RosterEditor .HandCard .attack,
.GuidePage .HandCard .attack {
  grid-area: attack;
  background: #b3261e;
}

.ActionBar .HandCard .defense,
.RosterEditor .HandCard .defense,
.GuidePage .HandCard .defense {
  grid-area: defense;
  background: #1f5fbf;
}

/* No attack or defense badges: the portrait is centered across the card (still 110px square) */
.ActionBar .HandCard.noStats .portrait,
.RosterEditor .HandCard.noStats .portrait,
.GuidePage .HandCard.noStats .portrait {
  grid-column: 1 / -1;
  justify-self: center;
}

.ActionBar .HandCard .description,
.RosterEditor .HandCard .description,
.GuidePage .HandCard .description {
  grid-area: description;
  overflow-y: auto; /* long descriptions scroll instead of resizing the card */
  padding: 4px 6px;
  box-sizing: border-box;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.05);
  font-size: 12px;
  font-weight: normal;
  line-height: 1.3;
}

.ActionBar .HandCard.playing,
.RosterEditor .HandCard.playing,
.GuidePage .HandCard.playing {
  outline: 2px solid red;
}

.ActionBar .HandCard .actions,
.RosterEditor .HandCard .actions,
.GuidePage .HandCard .actions {
  grid-area: actions;
  display: flex;
  gap: 6px;
}

.ActionBar .HandCard .actions button,
.RosterEditor .HandCard .actions button,
.GuidePage .HandCard .actions button {
  flex: 1;
  margin: 0;
  padding: 4px 8px;
  font-size: 12px;
}

.ActionBar .PlayPhase .TurnControls .actionsLeft {
  font-size: 16px;
}

/* "Rolled:" and the die, centered across the column (as wide as its buttons) */
.ActionBar .PlayPhase .TurnControls .movementRoll {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 180px;
  gap: 8px;
  margin: 6px 0;
  font-size: 16px;
}

/* A face of the movement die: a white die with the number, and "All" under it for an All face */
.MovementDie {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  box-sizing: border-box;
  border: 2px solid #ccc;
  border-radius: 8px;
  background: white;
  color: #222;
  line-height: 1;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}

.MovementDie .amount {
  font-size: 20px;
  font-weight: bold;
}

.MovementDie .allLabel {
  margin-top: 2px;
  font-size: 11px;
  font-weight: bold;
  text-transform: uppercase;
}

.ActionBar .PlayPhase .TurnControls .discardPile {
  font-size: 14px;
  font-weight: normal;
}

.ActionBar .PlayPhase .CharacterControls {
  display: inline-block;
  height: 100%;
}

/* The portrait with its token badges in a column beside it */
.ActionBar .PlayPhase .CharacterControls .portrait {
  display: flex;
  align-items: flex-start;
}

.ActionBar .PlayPhase .CharacterControls .CharacterIcon {
  display: block;
  height:176px;
  width: 176px;
  margin: 5px;
}

/* Center In Map and Move (not the token badges, which are buttons too) */
.ActionBar .PlayPhase .CharacterControls > button {
  display: block;
  width:180px;
  margin: 5px;
}