/* Host line, guess input, strike indicator.
   On mobile this whole block sticks to the bottom of the viewport so the
   input sits directly above the keyboard rather than scrolling away under it. */

.hud {
  margin-top: var(--gap-lg);
}

/* The two-up board's tighter rhythm (see board.css). It lives here, after the
   base rule, because the same override in board.css — which loads first —
   never won. */
@media (min-width: 900px) {
  .hud { margin-top: var(--gap); }
}

.hostline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--gap-sm);
  min-height: 26px;
  padding: 4px 2px;
  color: var(--green);
  font-size: clamp(13px, 3.2vw, 15px);
  letter-spacing: 0.02em;
}

.hostline__prompt {
  color: var(--green-dim);
  flex: none;
}

.hostline__text {
  flex: 0 1 auto;
  min-width: 0;
}

.hostline__cursor {
  flex: none;
  width: 8px;
  height: 15px;
  background: var(--green);
  animation: cursor-blink 1.05s steps(1, end) infinite;
}

@keyframes cursor-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.hostline--gold .hostline__text {
  color: var(--gold-bright);
  text-shadow: var(--glow-gold);
}

.hostline--alert .hostline__text {
  color: var(--red);
}

.guess-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-sm);
  margin-top: var(--gap-sm);
}

/* `display: flex` would otherwise win over the [hidden] default. */
.guess-form[hidden] { display: none; }

.guess-input {
  flex: 1 1 12ch;
  min-width: 0;
  /* 16px minimum: anything smaller makes iOS Safari zoom on focus. */
  font-size: 16px;
  font-family: var(--font-mono);
  padding: 12px var(--gap);
  color: var(--ink);
  background: #05091a;
  border: var(--border-chunky) solid var(--stage-line);
  border-radius: var(--radius);
  caret-color: var(--green);
}

.guess-input::placeholder {
  color: var(--ink-faint);
}

.guess-input:focus {
  border-color: var(--green);
  outline: none;
  box-shadow: var(--glow-green);
}

.guess-input[readonly] {
  opacity: 0.6;
}

.guess-form.is-shaking .guess-input {
  animation: input-shake var(--t-shake) ease-in-out;
  border-color: var(--red);
}

@keyframes input-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(3px); }
}

.guess-submit {
  flex: none;
  font-family: var(--font-display);
  font-size: 15px;
  letter-spacing: 0.08em;
  padding: 0 var(--gap-lg);
  color: var(--stage-deep);
  background: linear-gradient(180deg, var(--gold-bright) 0%, var(--gold) 100%);
  border: var(--border-chunky) solid var(--gold-deep);
  border-radius: var(--radius);
  cursor: pointer;
  transition: filter 140ms ease, transform 90ms ease;
}

.guess-submit:hover { filter: brightness(1.1); }
.guess-submit:active { transform: translateY(1px); }
.guess-submit:disabled { filter: grayscale(0.7) brightness(0.7); cursor: default; }

/* While a guess is in flight. `is-waiting` only appears once the round trip has
   run long enough to be worth explaining — usually a live judge call. */
.guess-form.is-thinking .guess-input {
  border-color: var(--green-dim);
}

.guess-form.is-waiting .guess-input {
  animation: input-breathe 1.1s ease-in-out infinite;
}

@keyframes input-breathe {
  0%, 100% { box-shadow: 0 0 0 rgba(74, 255, 160, 0); }
  50% { box-shadow: 0 0 16px rgba(74, 255, 160, 0.35); }
}

/* --- Strikes ----------------------------------------------------------- */

.strikes {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap);
  margin-top: var(--gap);
}

.strike {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 24px;
  line-height: 1;
  color: #1b2452;
  border: 2px solid #1b2452;
  border-radius: var(--radius);
  transition: color 160ms ease, border-color 160ms ease;
}

.strike.is-lit {
  color: var(--red);
  border-color: var(--red);
  text-shadow: 0 0 14px rgba(255, 46, 62, 0.8);
}

.strike.is-popping {
  animation: strike-pop 380ms var(--ease-overshoot);
}

@keyframes strike-pop {
  0% { transform: scale(0.4); opacity: 0.2; }
  60% { transform: scale(1.35); }
  100% { transform: scale(1); opacity: 1; }
}

/* Narrow screens give the input the whole width and put the button under it.
   The input is the player's primary interaction and it was losing to the
   button: at 195 CSS pixels — a 390px phone at 200% zoom — a side-by-side
   input measured 42px, which is not a text field, it is a slot. Wrapping is
   the trade: one more row of height, an input that always works.

   Below the base rules on purpose — same specificity, so order decides, and
   putting this first is exactly how the first attempt silently did nothing. */
@media (max-width: 520px) {
  .guess-input { flex: 1 1 100%; }
  .guess-submit { flex: 1 1 100%; padding: 12px var(--gap-lg); }
}

@media (max-width: 720px) {
  .hud {
    position: sticky;
    bottom: 0;
    z-index: 20;
    margin-top: var(--gap);
    padding: var(--gap) var(--gap) calc(var(--gap-sm) + env(safe-area-inset-bottom));
    margin-left: calc(-1 * var(--gap));
    margin-right: calc(-1 * var(--gap));
    /* Opaque within a few pixels: the board must not read through the HUD. */
    background: linear-gradient(180deg, rgba(6, 10, 24, 0) 0, var(--stage-deep) 10px);
    border-top: 1px solid var(--stage-edge);
  }

  .strikes { margin-top: 6px; gap: var(--gap-sm); }
  .strike { width: 26px; height: 26px; font-size: 17px; }
  .guess-input { padding: 10px var(--gap); }
}

@media (prefers-reduced-motion: reduce) {
  .hostline__cursor { animation: none; }
  .guess-form.is-shaking .guess-input { animation: none; }
  .guess-form.is-waiting .guess-input { animation: none; border-color: var(--green); }
  .strike.is-popping { animation: none; }
}
