/*
 * ASCII-inspired, not ASCII-implemented: the board is a CSS Grid of individual cells
 * rather than one <pre>, so tiles can be styled and hit-tested independently.
 */

:root {
  --bg:        #0b0e0f;
  --panel:     #14191b;
  --line:      #222b2e;
  --ink:       #c8d6d8;
  --dim:       #5d6f73;
  --floor:     #101617;
  --wall:      #2b3639;
  --door:      #d8a657;
  --cabinet:   #d4a86a;
  --cabinet-bg: #4a3522;   /* wood, so a cabinet never reads as floor or wall */
  --bush:      #3f6b46;
  --self:      #7fd4c1;
  --enemy:     #e06c75;
  --item:      #e5c07b;
  --hp:        #7fd4c1;
  --hp-low:    #e06c75;
  --shot:      #f0f0e0;
  --button:    #8b1e3f;   /* Game Boy A/B magenta */
  --dpad:      #2a2d2f;   /* Game Boy cross, near black */
  --dpad-hi:   #3a3f42;
  --button-hi: #b02a55;

  --cell: min(6.2vw, 2rem);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  -webkit-text-size-adjust: 100%;
  overscroll-behavior: none;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
}

/* --- Overlays ---------------------------------------------------------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* safe: when the content is taller than a phone, scroll rather than clip the top */
  justify-content: safe center;
  gap: 1rem;
  padding: 1.5rem;
  overflow-y: auto;
  background: var(--bg);
  text-align: center;
}

.overlay[hidden] { display: none; }

/*
 * The title is block-letter art, so it scales with the viewport rather than wrapping:
 * 50 columns must fit a phone. The red offset shadow reads as a blood stain.
 */
.logo {
  margin: 0;
}

.logo pre {
  margin: 0;
  font-family: inherit;
  font-size: min(2.8vw, 11px);
  line-height: 1.05;
  color: var(--self);
  text-shadow: 0.15em 0.15em 0 rgba(224, 108, 117, 0.55), 0 0 0.8em rgba(127, 212, 193, 0.35);
}

.logo-rule {
  margin: -0.25rem 0 0;
  color: var(--enemy);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  opacity: 0.8;
}

.tagline {
  margin: 0 0 1rem;
  color: var(--dim);
  font-size: 0.8rem;
  line-height: 1.7;
  max-width: 34rem;
  word-break: keep-all;
}

.tagline em {
  font-style: normal;
  color: var(--enemy);
}

#lobby-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: min(100%, 18rem);
}

input, button {
  font: inherit;
  color: inherit;
}

#nickname {
  padding: 0.85rem 1rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 2px;
  text-align: center;
  letter-spacing: 0.2em;
}

#nickname:focus-visible {
  outline: 1px solid var(--self);
  outline-offset: 1px;
}

#start, #restart {
  padding: 0.85rem 1rem;
  background: transparent;
  border: 1px solid var(--self);
  border-radius: 2px;
  color: var(--self);
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  cursor: pointer;
}

#start:active, #restart:active { background: rgba(127, 212, 193, 0.12); }

/* --- Ranking -------------------------------------------------------------- */

.ranking[hidden] { display: none; }

.ranking {
  width: min(100%, 18rem);
  font-size: 0.75rem;
}

.ranking-title {
  margin: 0 0 0.5rem;
  color: var(--dim);
  letter-spacing: 0.1em;
}

.ranking ol {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line);
}

.ranking li {
  display: grid;
  grid-template-columns: 1.5rem 1fr auto;
  gap: 0.5rem;
  padding: 0.3rem 0.25rem;
  border-bottom: 1px solid var(--line);
  text-align: left;
}

.ranking .rank  { color: var(--dim); text-align: right; }
.ranking .name  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ranking .score { color: var(--item); font-variant-numeric: tabular-nums; }
.ranking li.mine { background: rgba(127, 212, 193, 0.08); }
.ranking li.mine .name,
.ranking li.mine .rank { color: var(--self); }
/* The break between the top ten and your own row further down. */
.ranking li.gap {
  display: block;
  padding: 0;
  border-bottom: none;
  color: var(--dim);
  text-align: center;
  line-height: 1.2;
}

.error {
  min-height: 1.2em;
  margin: 0;
  color: var(--enemy);
  font-size: 0.8rem;
}

.cause {
  margin: 0;
  max-width: 24rem;
  color: var(--ink);
  font-size: 0.95rem;
  line-height: 1.6;
  word-break: keep-all;
}

/* The caption and the numbers read as one record, so they sit tight together. */
.record {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.record[hidden] { display: none; }

.record-title {
  margin: 0;
  color: var(--dim);
  font-size: 0.8rem;
}

.record-title span { color: var(--self); }

.record .result { margin: 0; }

.result {
  display: grid;
  grid-template-columns: auto auto;
  gap: 0.35rem 1.5rem;
  margin: 0.5rem 0 1rem;
  font-size: 1.1rem;
}

.result dt { color: var(--dim); text-align: right; }
.result dd { margin: 0; text-align: left; }

/* --- Game frame -------------------------------------------------------- */

#game {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: min(100%, 26rem);
}

#game[hidden] { display: none; }

.hud-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.65rem;
  background: var(--panel);
  border: 1px solid var(--line);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
}

/* Name | clock | score. Equal outer columns keep the clock dead centre whatever the
   name and score lengths are. */
header.hud-bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
}

.hud-status .spacer { flex: 1; }
.hud-status .label { color: var(--dim); }

#hp-bar {
  display: block;
  width: 5.5rem;
  height: 0.55rem;
  background: var(--line);
  overflow: hidden;
}

#hp-fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--hp);
  transition: width 120ms linear;
}

#hp-fill.low { background: var(--hp-low); }

#item { color: var(--item); }

.state {
  min-height: 1.1em;
  margin: 0;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  color: var(--dim);
  text-align: center;
}

.state.hidden-bush { color: var(--bush); }
.state.hidden-cabinet { color: var(--cabinet); }

#hud-name {
  color: var(--self);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#score { justify-self: end; white-space: nowrap; }
/* letter-spacing trails the last digit; pull it back so the digits themselves centre */
#clock { color: var(--dim); font-variant-numeric: tabular-nums; margin-right: -0.1em; }

/* --- Board ------------------------------------------------------------- */

#board {
  display: grid;
  grid-template-columns: repeat(15, var(--cell));
  grid-template-rows: repeat(15, var(--cell));
  justify-content: center;
  background: var(--floor);
  border: 1px solid var(--line);
}

.cell {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: calc(var(--cell) * 0.72);
  line-height: 1;
  user-select: none;
}

.t-wall    { background: var(--wall); }
.t-floor   { background: var(--floor); }
.t-door    { color: var(--door); }
.t-cabinet { color: var(--cabinet); background: var(--cabinet-bg); }
.t-bush    { color: var(--bush); background: rgba(63, 107, 70, 0.14); }

.cell.has-item  { color: var(--item); }
.cell.has-enemy { color: var(--enemy); }
.cell.has-self  { color: var(--self); }
/* Your own cabinet, on your screen only; others see a cabinet like any other. */
.cell.self-cabinet { color: var(--self); outline: 1px solid var(--self); outline-offset: -2px; }

/* A shot is a 100ms flourish over the tiles it crossed, not a moving entity. */
.cell.shot  { color: var(--shot); }
.cell.swing { color: var(--shot); font-weight: bold; }

/* Loot gauge: fills while B is held; the server decides when the item lands. */
#loot {
  height: 4px;
  background: var(--line);
  overflow: hidden;
}
#loot-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--item);
}

/*
 * Red is being hurt: the victim's own board. The attacker's HIT is a neutral blink —
 * it says only that something was struck, so it is the whole board, never a tile.
 */
#board.hurt { outline: 2px solid var(--enemy); }
#board.hit  { outline: 2px solid var(--shot); }
.state.looting { color: var(--item); }
#hp-fill.hurt { background: var(--hp-low); }

/* --- Controls ---------------------------------------------------------- */

/*
 * The whole strip is the touch surface: its left half steers, its right half is A/B
 * (see wireInput). The drawn buttons are only a picture of where things are, so they
 * take no pointer events of their own and show presses through .pressed.
 */
#controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 0.25rem;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  cursor: pointer;
}

/* On a phone the strip takes all the height the board leaves, so a thumb can land
   anywhere below the board. */
@media (max-width: 479px) {
  #game { align-self: stretch; }
  #controls { flex: 1 0 auto; min-height: 9rem; }
}

/*
 * Game Boy cross: one dark plus-shaped piece with no gaps between the arms, a dimpled
 * centre, and small dim arrows. The centre is a pseudo-element occupying the middle
 * grid cell, so the four arms read as a single part.
 */
#dpad {
  display: grid;
  grid-template-columns: repeat(3, 2.8rem);
  grid-template-rows: repeat(3, 2.8rem);
  gap: 0;
  filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.5));
}

#dpad::before {
  content: '';
  grid-area: 2 / 2;
  background: radial-gradient(circle, #1b1d1e 0 30%, var(--dpad) 32%);
}

.pad, .action {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--ink);
  pointer-events: none;
}

.pad.pressed { background: var(--dpad-hi); color: var(--ink); }

.pad {
  background: var(--dpad);
  border: none;
  color: #5b6164;
  font-size: 0.8rem;
  user-select: none;
  -webkit-user-select: none;
}

.pad.up    { grid-area: 1 / 2; border-radius: 0.3rem 0.3rem 0 0; }
.pad.left  { grid-area: 2 / 1; border-radius: 0.3rem 0 0 0.3rem; }
.pad.down  { grid-area: 3 / 2; border-radius: 0 0 0.3rem 0.3rem; }
.pad.right { grid-area: 2 / 3; border-radius: 0 0.3rem 0.3rem 0; }

/*
 * Game Boy look, but mirrored by choice: A low on the left, B high on the right, on a
 * tilted pill, so the left key J and the left button are both A. The
 * letters are counter-rotated so they stay upright.
 */
#actions {
  display: flex;
  align-items: flex-end;
  gap: 0.9rem;
  padding: 0.6rem 0.8rem;
  border-radius: 3rem;
  background: rgba(255, 255, 255, 0.04);
  transform: rotate(-25deg);
  /* the tilt pokes a few pixels past the box; keep it off a phone's edge */
  margin-right: 0.4rem;
}

#btn-b { margin-bottom: 1.1rem; }

.action {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1rem;
  width: 3.4rem;
  height: 3.4rem;
  border-radius: 50%;
  background: var(--button);
  border: none;
  color: #f4e6ea;
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.45);
  user-select: none;
  -webkit-user-select: none;
}

.action > * { transform: rotate(25deg); }
.action b { font-size: 1.05rem; }
.action small { font-size: 0.6rem; color: #f4e6ea; opacity: 0.85; }
.action.pressed:not(:disabled) {
  background: var(--button-hi);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.45);
  transform: translateY(2px);
}
.action:disabled { opacity: 0.4; cursor: default; }

@media (min-width: 480px) {
  :root { --cell: 1.6rem; }
}
