:root {
  color-scheme: light dark;
  --accent: #4f7cff;
  --danger: #e0524d;
  --success: #3fb37f;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  background: #14161c;
  color: #f2f3f5;
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
  display: grid;
  place-items: center;
  user-select: none;
  -webkit-user-select: none;
}

button {
  touch-action: manipulation;
}

input {
  user-select: text;
  -webkit-user-select: text;
}

/*
 * The stage: one portrait 3:4 box, sized to the largest that fits the visible screen.
 * Everything inside is measured in --u, where 810 u is the stage width (an 8th-gen iPad in portrait).
 */
.game {
  width: min(100vw, 75vh);
  width: min(100vw, 75dvh);
  height: min(100vh, 133.333vw);
  height: min(100dvh, 133.333vw);
  container-type: size;
  text-align: center;
}

.stage {
  --u: calc(100cqw / 810);
  width: 100%;
  height: 100%;
  padding: calc(18 * var(--u)) calc(24 * var(--u)) calc(22 * var(--u));
  display: flex;
  flex-direction: column;
}

.screen {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.screen:not(#screen-game) {
  justify-content: center;
  padding-bottom: calc(80 * var(--u));
}

#screen-game {
  position: relative;
}

h1 {
  font-size: calc(46 * var(--u));
  line-height: 1.1;
  margin: 0 0 calc(6 * var(--u));
}

.connection-status {
  font-size: calc(26 * var(--u));
  font-weight: 600;
  color: #c8ccd4;
  margin: 0;
}

.session-line {
  font-size: calc(20 * var(--u));
  color: #c8ccd4;
  margin: calc(4 * var(--u)) 0 0;
  min-height: calc(26 * var(--u));
}

.reconnect-banner {
  position: absolute;
  top: calc(64 * var(--u));
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  padding: calc(6 * var(--u)) calc(14 * var(--u));
  border-radius: calc(10 * var(--u));
  background: color-mix(in srgb, var(--danger) 25%, #14161c);
  color: var(--danger);
  font-size: calc(20 * var(--u));
  font-weight: 600;
  margin: 0;
  white-space: nowrap;
}

.lead {
  font-size: calc(28 * var(--u));
  color: #c8ccd4;
  margin: 0;
}

.choices,
.entry-form {
  display: flex;
  flex-direction: column;
  gap: calc(14 * var(--u));
  width: calc(420 * var(--u));
  max-width: 100%;
  margin: calc(28 * var(--u)) auto 0;
}

.entry-form label {
  font-size: calc(20 * var(--u));
  color: #9aa0ab;
  text-align: left;
}

.entry-form input {
  font-size: max(16px, calc(30 * var(--u)));
  padding: calc(14 * var(--u)) calc(16 * var(--u));
  border-radius: calc(10 * var(--u));
  border: 1px solid #3a3f4a;
  background: #20232b;
  color: #f2f3f5;
  text-align: center;
  letter-spacing: 0.2em;
}

.big-btn {
  background: var(--accent);
  color: white;
  border: none;
  border-radius: calc(10 * var(--u));
  padding: calc(16 * var(--u)) calc(26 * var(--u));
  font-size: calc(26 * var(--u));
  font-weight: 600;
  cursor: pointer;
}

.big-btn:hover {
  filter: brightness(1.1);
}

.link-btn {
  background: none;
  border: none;
  color: #9aa0ab;
  text-decoration: underline;
  cursor: pointer;
  margin-top: calc(18 * var(--u));
  font-size: calc(20 * var(--u));
}

.note {
  color: #c8ccd4;
  font-size: calc(20 * var(--u));
  min-height: 1.2em;
}

.error {
  color: var(--danger);
  font-size: calc(20 * var(--u));
  font-weight: 600;
  min-height: 1.2em;
}

.end-btn {
  display: block;
  margin: calc(12 * var(--u)) auto 0;
  background: none;
  border: 1px solid var(--danger);
  color: var(--danger);
  border-radius: calc(8 * var(--u));
  padding: calc(6 * var(--u)) calc(16 * var(--u));
  font-size: calc(16 * var(--u));
  cursor: pointer;
}

.end-btn:hover {
  background: color-mix(in srgb, var(--danger) 20%, transparent);
}

/* Hangman on the left edge, info column filling the rest, in line with the keyboard's edges. */
.board {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: calc(20 * var(--u));
  align-items: center;
  margin: calc(4 * var(--u)) 0 calc(14 * var(--u));
}

.gallows {
  width: calc(424 * var(--u));
  height: calc(620 * var(--u));
  color: #f2f3f5;
}

.part {
  visibility: hidden;
}

.part.visible {
  visibility: visible;
}

/* ---- win celebration ---- */

#figure,
#part-3, #part-4, #part-7, #part-8,
#part-5, #part-6, #part-9, #part-10 {
  transform-box: view-box;
}

#figure {
  transform-origin: 130px 150px;
}

#party-hat {
  transform-box: view-box;
  transform-origin: 130px 53px;
}

@keyframes hat-flop {
  0%, 100% { transform: rotate(-8deg) skewX(9deg) scale(0.96, 1.06); }
  50% { transform: rotate(8deg) skewX(-9deg) scale(1.08, 0.92); }
}

#part-3, #part-4, #part-7, #part-8 {
  transform-origin: 130px 95px;
}

#part-5, #part-6, #part-9, #part-10 {
  transform-origin: 130px 150px;
}

#mouth-laugh {
  opacity: 0;
}

.eye-wink {
  opacity: 0;
}

.winking .eye-open {
  opacity: 0;
}

.winking .eye-wink {
  opacity: 1;
}

/* The mouth follows the words: open while a phrase is up, closed when it dissolves. */
.gallows.talking #mouth-laugh {
  opacity: 1;
}

.gallows.talking #mouth-smile {
  opacity: 0;
}

/* ---- loss: go limp and swing gently from the rope ---- */

#part-3, #part-4, #part-5, #part-6, #part-7, #part-8, #part-9, #part-10 {
  transition: transform 0.9s ease;
}

.gallows.lost #figure {
  transform-origin: 130px 50px;
}

.gallows.lost.swinging #figure {
  animation: swing 3.2s ease-in-out infinite;
}

#tongue-tip {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: top center;
  transform: scaleY(0.2);
  transition: opacity 0.4s ease, transform 0.6s cubic-bezier(0.3, 1.4, 0.5, 1);
}

.gallows.tongue #tongue-tip {
  opacity: 1;
  transform: scaleY(1);
}


.gallows.lost #part-3, .gallows.lost #part-7 { transform: rotate(-27deg); }
.gallows.lost #part-4, .gallows.lost #part-8 { transform: rotate(27deg); }
.gallows.lost #part-5, .gallows.lost #part-9 { transform: rotate(-20deg); }
.gallows.lost #part-6, .gallows.lost #part-10 { transform: rotate(20deg); }

@keyframes swing {
  0%, 100% { transform: rotate(-7deg); }
  50% { transform: rotate(7deg); }
}

/* Stage 1: cartoon toot cloud pops out, wobbles, then fades as the gas bubble takes over. */
.fart-toot {
  transform-box: view-box;
  transform-origin: 0 0;
  animation: fart-toot 1.3s ease-in-out forwards;
}

@keyframes fart-toot {
  0% { opacity: 0; transform: scale(0.15); }
  25% { opacity: 1; transform: scale(1.12); }
  40% { transform: scale(0.97); }
  65% { opacity: 1; transform: scale(1.04) rotate(2deg); }
  100% { opacity: 0; transform: scale(1.15); }
}

/* Stage 2: a purple gas bubble floats up, swells and wobbles, then bursts (particles are JS). */
.fart-gas {
  opacity: 0;
  transform-box: view-box;
  transform-origin: 0 0;
  animation: fart-gas 5.4s ease-in-out 0.85s forwards;
}

@keyframes fart-gas {
  0% { opacity: 0; transform: translate(0, 0) scale(0.8); }
  16% { opacity: 1; transform: translate(calc(var(--gx) * 0.1), calc(var(--gy) * 0.1)) scale(1, 0.94); }
  40% { transform: translate(calc(var(--gx) * 0.45), calc(var(--gy) * 0.45)) scale(1.18, 1.1); }
  60% { transform: translate(calc(var(--gx) * 0.75), calc(var(--gy) * 0.75)) scale(1.3, 1.4); }
  80% { transform: translate(var(--gx), var(--gy)) scale(1.5, 1.42); }
  95% { opacity: 1; transform: translate(var(--gx), var(--gy)) scale(1.62); }
  100% { opacity: 0; transform: translate(var(--gx), var(--gy)) scale(1.95); }
}

.smoke.dense {
  animation-name: smoke-dense;
  animation-duration: 5.2s;
}

@keyframes smoke-dense {
  0% { opacity: 0.95; transform: translate(0, 0) scale(0.5); }
  30% { opacity: 0.9; transform: translate(calc(var(--dx) * 0.3), calc(var(--dy) * 0.3)) scale(1.4); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(2.5); }
}


/* Timeline: drop (0-0.8s), fast dance + laugh (1-5.2s), then a slow happy loop until the next game. */
.gallows.won #figure {
  animation:
    win-drop 0.8s ease-in forwards,
    win-dance 0.6s ease-in-out 1s 7 forwards,
    win-happy 2.4s ease-in-out 5.2s infinite;
}

.gallows.won #part-3, .gallows.won #part-7 {
  animation: wave-left 0.6s ease-in-out 1s 7, wave-left 3s ease-in-out 5.2s infinite;
}
.gallows.won #part-4, .gallows.won #part-8 {
  animation: wave-right 0.6s ease-in-out 1s 7, wave-right 3s ease-in-out 6.7s infinite;
}
.gallows.won #party-hat { animation: hat-flop 1.1s ease-in-out infinite; }
.gallows.won #part-5, .gallows.won #part-9 { animation: kick-a 2.4s ease-in-out 5.2s infinite; }
.gallows.won #part-6, .gallows.won #part-10 { animation: kick-b 2.4s ease-in-out 5.2s infinite; }

@keyframes win-drop {
  0% { transform: translate(0, 0); }
  55% { transform: translate(-3px, 48px) rotate(-10deg); }
  75% { transform: translate(6px, 40px) rotate(4deg); }
  100% { transform: translate(12px, 44px) rotate(0); }
}

@keyframes win-dance {
  0%, 100% { transform: translate(12px, 44px) rotate(0); }
  25% { transform: translate(6px, 34px) rotate(-12deg); }
  50% { transform: translate(12px, 44px) rotate(0); }
  75% { transform: translate(18px, 34px) rotate(12deg); }
}

@keyframes win-happy {
  0%, 100% { transform: translate(12px, 44px) rotate(0); }
  25% { transform: translate(9px, 38px) rotate(-6deg); }
  50% { transform: translate(12px, 44px) rotate(0); }
  75% { transform: translate(15px, 38px) rotate(6deg); }
}

@keyframes wave-left {
  0%, 100% { transform: rotate(0); }
  50% { transform: rotate(70deg); }
}

@keyframes wave-right {
  0%, 100% { transform: rotate(0); }
  50% { transform: rotate(-70deg); }
}

@keyframes kick-a {
  0%, 50%, 100% { transform: rotate(0); }
  25% { transform: rotate(-16deg); }
}

@keyframes kick-b {
  0%, 50%, 100% { transform: rotate(0); }
  75% { transform: rotate(16deg); }
}

.confetti {
  opacity: 0;
  transform-box: fill-box;
  animation: confetti-throw 1.7s ease-in forwards;
}

@keyframes confetti-throw {
  0% { opacity: 1; transform: translate(0, 0) rotate(0); }
  35% { opacity: 1; transform: translate(calc(var(--dx) * 0.5), -38px) rotate(calc(var(--rot) * 0.4)); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--rot)); }
}

.firework {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: firework 2.6s ease-out infinite;
}

.phrase {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  paint-order: stroke;
  animation: phrase 6.2s ease-in-out forwards;
}

.phrase-fly {
  transform-box: fill-box;
  animation: phrase-fly 0.9s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}

@keyframes phrase-fly {
  0% { transform: translate(var(--from-dx), var(--from-dy)); }
  100% { transform: translate(0, 0); }
}

/* Grow out of the mouth while flying in, hold for ~3.5s, then blur away slowly in place. */
@keyframes phrase {
  0% { opacity: 0.7; transform: scale(0.12); filter: blur(0); }
  14% { opacity: 1; transform: scale(1.12); }
  18%, 61% { opacity: 1; transform: scale(1); filter: blur(0); }
  75% { opacity: 0.75; transform: scale(1.12); filter: blur(1px); }
  100% { opacity: 0; transform: scale(1.3); filter: blur(5px); }
}

.spark {
  opacity: 0;
  transform-box: fill-box;
  animation: spark 4s cubic-bezier(0.25, 0.6, 0.6, 1) forwards;
}

@keyframes spark {
  0% { opacity: 1; transform: translate(0, 0) scale(1); }
  45% { opacity: 1; transform: translate(var(--mx), var(--my)) scale(0.8); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.3); }
}

.smoke {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: smoke 5s ease-out forwards;
}

.streamer-bit {
  opacity: 0;
  transform-box: fill-box;
  animation: streamer var(--dur) cubic-bezier(0.3, 0.1, 0.75, 0.55) forwards;
}

.streamer-smoke {
  animation-name: streamer-smoke;
}

/* Arc up and out, then fall to the ground; the smoke copies run the same path a beat behind. */
@keyframes streamer {
  0% { opacity: 1; transform: translate(0, 0); }
  28% { opacity: 1; transform: translate(calc(var(--dx) * 0.45), var(--peak)); }
  92% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)); }
}

@keyframes streamer-smoke {
  0% { opacity: 0.5; transform: translate(0, 0); }
  28% { opacity: 0.45; transform: translate(calc(var(--dx) * 0.45), var(--peak)); }
  92% { opacity: 0.3; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)); }
}

@keyframes smoke {
  0% { opacity: 0.5; transform: translate(0, 0) scale(0.4); }
  50% { opacity: 0.35; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(3.5); }
}

@keyframes firework {
  0% { opacity: 1; transform: scale(0.1); }
  40% { opacity: 1; transform: scale(1); }
  55%, 100% { opacity: 0; transform: scale(1.15); }
}

@media (prefers-reduced-motion: reduce) {
  .gallows.lost #figure,
  .fart-toot,
  .fart-gas,
  .gallows.won *,
  .confetti,
  .firework,
  .spark,
  .smoke,
  .streamer-bit,
  .phrase-fly,
  .phrase {
    animation: none !important;
  }
  .phrase { opacity: 1; }
  .gallows.won #figure { transform: translate(12px, 44px); }
}

.info {
  min-width: 0;
  font-size: calc(20 * var(--u));
}

.info p {
  margin: calc(6 * var(--u)) 0;
}

.wrong-line {
  font-size: calc(28 * var(--u));
  font-weight: 700;
}

.status-banner strong {
  display: block;
  font-size: 1.25em;
  letter-spacing: 0.12em;
  margin-top: calc(2 * var(--u));
}

.word-display {
  font-size: calc(40 * var(--u)); /* overridden per word by fitWord() to span the column */
  letter-spacing: 0.22em;
  font-weight: 700;
  margin: calc(10 * var(--u)) 0;
  white-space: nowrap;
  line-height: 1.1;
}

.guessed-list {
  color: #9aa0ab;
  min-height: 1.2em;
  line-height: 1.15;
}

.status-banner {
  font-size: calc(19 * var(--u));
  font-weight: 700;
  padding: calc(8 * var(--u)) calc(12 * var(--u));
  border-radius: calc(10 * var(--u));
  margin: calc(12 * var(--u)) 0;
}

.status-banner.won {
  background: color-mix(in srgb, var(--success) 25%, transparent);
  color: var(--success);
}

.status-banner.lost {
  background: color-mix(in srgb, var(--danger) 25%, transparent);
  color: var(--danger);
}

.action-btn {
  color: white;
  border: none;
  border-radius: calc(10 * var(--u));
  padding: calc(12 * var(--u)) calc(18 * var(--u));
  font-size: calc(20 * var(--u));
  font-weight: 600;
  cursor: pointer;
  max-width: 100%;
}

.action-btn.yours {
  background: var(--success);
}

.action-btn.theirs {
  background: var(--danger);
}

.action-btn.newgame {
  background: var(--accent);
}

.action-btn.paused {
  background: #b8862b;
  color: #1a1a1a;
}

.action-btn.idle,
.action-btn.newgame:disabled {
  background: #3a3f4a;
  color: #8a909c;
}

.action-btn:disabled {
  cursor: default;
}

.action-btn:hover:not(:disabled) {
  filter: brightness(1.1);
}

.keyboard {
  display: grid;
  grid-template-columns: repeat(9, minmax(0, 1fr));
  gap: calc(10 * var(--u));
  width: 100%;
}

.key {
  height: calc(64 * var(--u));
  padding: 0;
  border-radius: calc(10 * var(--u));
  border: 1px solid #3a3f4a;
  background: #20232b;
  color: #f2f3f5;
  font-size: calc(32 * var(--u));
  font-weight: 700;
  cursor: pointer;
  text-transform: uppercase;
}

.key:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.key:disabled {
  opacity: 0.35;
  cursor: default;
}

.key.correct {
  border-color: var(--success);
  color: var(--success);
  opacity: 1;
}

.key.wrong {
  border-color: var(--danger);
  color: var(--danger);
  opacity: 1;
}


/* Shown instead of the game when a touch device is held in landscape (see updateRotate in app.js). */
#rotate-screen {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: #14161c;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  padding: 24px;
  text-align: center;
}

html.needs-rotate #rotate-screen {
  display: flex;
}

html.needs-rotate .game {
  display: none;
}

#rotate-screen svg {
  width: min(360px, 60vw);
  height: auto;
  color: #9aa0ab;
}

#rotate-screen p {
  margin: 0;
  font-size: clamp(22px, 3.4vw, 34px);
  line-height: 1.3;
  color: #f2f3f5;
}

#rotate-screen p strong {
  display: block;
  font-size: 1.15em;
}

/* ---- chat: lives in the info column under the buttons ---- */

.board {
  align-items: stretch;
}

.gallows {
  align-self: center;
}

.info {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-height: 0;
}

.info > .action-btn,
.info > .end-btn {
  align-self: center;
}

.chat {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: calc(8 * var(--u));
  margin-top: calc(14 * var(--u));
  padding: calc(10 * var(--u));
  border: calc(2 * var(--u)) solid #3a3f4a;
  border-radius: calc(14 * var(--u));
  background: #1a1d24;
  text-align: left;
}

.chat.ping {
  animation: chat-ping 1.6s ease-out;
}

@keyframes chat-ping {
  0% { border-color: var(--accent); box-shadow: 0 0 0 calc(2 * var(--u)) var(--accent), 0 0 calc(24 * var(--u)) var(--accent); }
  100% { border-color: #3a3f4a; box-shadow: 0 0 0 0 transparent, 0 0 0 0 transparent; }
}

.chat-log {
  flex: 1;
  min-height: calc(40 * var(--u));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  font-size: calc(19 * var(--u));
  line-height: 1.3;
  user-select: text;
  -webkit-user-select: text;
  overflow-wrap: anywhere;
}

.chat-log .msg {
  margin: 0 0 calc(5 * var(--u));
}

.chat-log .msg b {
  color: #7aa2ff;
}

.chat-log .msg.from-2 b {
  color: #f78fff;
}

.quick-replies {
  display: flex;
  flex-wrap: wrap;
  gap: calc(6 * var(--u));
}

.quick-replies button {
  border: 1px solid #3a3f4a;
  background: #262a33;
  color: #f2f3f5;
  border-radius: calc(20 * var(--u));
  padding: calc(6 * var(--u)) calc(12 * var(--u));
  font-size: calc(18 * var(--u));
  cursor: pointer;
}

.quick-replies button:active {
  background: var(--accent);
}

.chat-form {
  display: flex;
  gap: calc(6 * var(--u));
}

.chat-form input {
  flex: 1;
  min-width: 0;
  font-size: max(16px, calc(20 * var(--u)));
  padding: calc(8 * var(--u)) calc(10 * var(--u));
  border-radius: calc(10 * var(--u));
  border: 1px solid #3a3f4a;
  background: #20232b;
  color: #f2f3f5;
}

.chat-send {
  border: none;
  border-radius: calc(10 * var(--u));
  background: var(--accent);
  color: white;
  font-size: calc(19 * var(--u));
  font-weight: 600;
  padding: 0 calc(14 * var(--u));
  cursor: pointer;
}

/*
 * Typing mode: when the iPad's on-screen keyboard is up (detected in app.js), the stage shrinks
 * to the space above it, the letter keys and title fold away, and the drawing scales to fit.
 */
.game.typing {
  position: fixed;
  top: var(--vv-top, 0px);
  left: 50%;
  transform: translateX(-50%);
  height: var(--vv-h, 100dvh);
}

.game.typing h1,
.game.typing .keyboard,
.game.typing .quick-replies,
.game.typing .end-btn {
  display: none;
}

.game.typing .gallows {
  height: var(--g-h, calc(400 * var(--u)));
  width: calc(var(--g-h, calc(400 * var(--u))) * 0.6839);
}

@media (prefers-reduced-motion: reduce) {
  .chat.ping {
    animation: none;
  }
}

/* One-time "Add to Home Screen" tip, shown on the sign-in screens in iPad Safari only. */
.install-hint {
  position: absolute;
  left: calc(24 * var(--u));
  right: calc(24 * var(--u));
  bottom: calc(24 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(14 * var(--u));
  padding: calc(14 * var(--u)) calc(18 * var(--u));
  border: 1px solid #3a3f4a;
  border-radius: calc(14 * var(--u));
  background: #1f232b;
  color: #c8ccd4;
  font-size: calc(20 * var(--u));
  line-height: 1.3;
  text-align: left;
}

.install-hint b {
  color: #f2f3f5;
}

.install-hint button {
  flex: none;
  border: none;
  border-radius: calc(10 * var(--u));
  background: var(--accent);
  color: #fff;
  font-size: calc(20 * var(--u));
  font-weight: 600;
  padding: calc(10 * var(--u)) calc(18 * var(--u));
  cursor: pointer;
}
