/* The phone.
 *
 * Different job from the TV entirely: this is held at arm's length, operated by thumbs,
 * and — once a game starts — used without looking at it. So the controls are enormous,
 * sit inside the safe area, and never move between frames. The screen explains; the
 * phone acts. */

.pad {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overscroll-behavior: none;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom)
    env(safe-area-inset-left);
  background:
    repeating-linear-gradient(0deg, transparent 0 3px, rgba(255, 255, 255, 0.012) 3px 4px),
    var(--void);
}

/* This is a phone UI wherever it is opened. On a desktop it stays a phone-width
   column rather than stretching a d-pad across 1900px. */
:root {
  --pad-max: 460px;
}

.pad-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--s3) var(--s4);
  border-bottom: 2px solid var(--line);
  flex: none;
  width: 100%;
  max-width: var(--pad-max);
  margin-inline: auto;
}

.pad-brand {
  font-family: var(--label);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  color: var(--dimmer);
}

.link-dot {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--label);
  font-size: 0.55rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}

.link-dot i {
  width: 8px;
  height: 8px;
  background: var(--dim);
}

.link-dot[data-state='open'] {
  color: var(--live);
}
.link-dot[data-state='open'] i {
  background: var(--live);
}
.link-dot[data-state='connecting'] i,
.link-dot[data-state='reconnecting'] i {
  background: var(--warn);
  animation: blink 0.9s steps(1, end) infinite;
}
.link-dot[data-state='connecting'],
.link-dot[data-state='reconnecting'] {
  color: var(--warn);
}
.link-dot[data-state='closed'] i,
.link-dot[data-state='refused'] i {
  background: var(--dead);
}
.link-dot[data-state='closed'],
.link-dot[data-state='refused'] {
  color: var(--dead);
}

#pad-stage {
  flex: 1;
  min-height: 0;
  display: grid;
}

.step {
  grid-area: 1 / 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  padding: var(--s6) var(--s4) var(--s4);
  overflow-y: auto;
  width: 100%;
  max-width: var(--pad-max);
  margin-inline: auto;
}

.step-title {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.9rem;
  line-height: 1.1;
}

.step-note {
  margin: 0;
  font-size: 0.8rem;
  color: var(--dim);
  line-height: 1.5;
}

.step-note[data-tone='bad'] {
  color: var(--dead);
}

/* ------------------------------------------------------------------- scanner */

/* The whole join step is meant to land inside one phone screen with no scrolling:
   title, viewfinder and code field all visible at once. Tighter gaps here buy the
   viewfinder its size back. */
.step-scan {
  gap: var(--s3);
  padding-top: var(--s4);
  justify-content: flex-start;
}

.step-scan .step-title {
  font-size: 1.55rem;
}

/* Square, because the thing being framed is square. A tall viewfinder invites people
   to fill the height with a QR that then sits too small to decode. */
/* Square, because the thing being framed is square. Sized by whichever runs out
   first — the column's width or the screen's height — so it never pushes the code
   field off the bottom on a short phone, and never becomes a 1000px box on a desktop.
   */
.scan-frame {
  position: relative;
  flex: none;
  width: min(100%, 42vh);
  aspect-ratio: 1;
  align-self: center;
  border: var(--border-bright);
  background: #000;
  overflow: hidden;
}

#scan-cam {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Four corner brackets rather than a full box: it frames the target without
   hiding any of the picture the person is trying to aim. */
.reticle {
  position: absolute;
  inset: 14%;
  pointer-events: none;
}

.reticle i {
  position: absolute;
  width: 28px;
  height: 28px;
  border: 3px solid var(--live);
}

.reticle i:nth-child(1) {
  top: 0;
  left: 0;
  border-right: 0;
  border-bottom: 0;
}
.reticle i:nth-child(2) {
  top: 0;
  right: 0;
  border-left: 0;
  border-bottom: 0;
}
.reticle i:nth-child(3) {
  bottom: 0;
  left: 0;
  border-right: 0;
  border-top: 0;
}
.reticle i:nth-child(4) {
  bottom: 0;
  right: 0;
  border-left: 0;
  border-top: 0;
}

.scan-frame[data-found='true'] .reticle i {
  border-color: var(--chalk);
  background: rgba(102, 224, 163, 0.22);
}

/* No camera means the viewfinder is a black rectangle taking the whole screen for
   nothing. Drop it and give the room to the thing that still works. */
.step-scan[data-nocam='true'] .scan-frame {
  display: none;
}

.step-scan[data-nocam='true'] .manual {
  border-top: 0;
  padding-top: 0;
}

.step-scan[data-nocam='true'] .manual > .name-label {
  display: none;
}

.nocam-note {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--warn);
  border-left: 2px solid var(--warn);
  padding-left: var(--s3);
}

.step-scan:not([data-nocam='true']) .nocam-note {
  display: none;
}

/* ----------------------------------------------------------------- code entry */

/* Always present, never behind a disclosure. Someone whose camera is slow, refused,
   or aimed at a glare on the TV needs the keyboard in front of them, not one tap away.
   */
.manual {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  border-top: 2px solid var(--line);
  padding-top: var(--s3);
}

#code-form {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding-top: var(--s2);
}

.code-input {
  font-family: var(--display);
  font-weight: 700;
  font-size: 2.5rem;
  text-align: center;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
  color: var(--chalk);
  background: var(--panel);
  border: var(--border-bright);
  border-radius: 0;
  padding: var(--s3) var(--s2);
  width: 100%;
}

.code-input::placeholder {
  color: var(--dimmer);
}

/* ------------------------------------------------------------------- profile */

.face-row {
  display: flex;
  gap: var(--s4);
  align-items: stretch;
}

.face-frame {
  position: relative;
  width: 40%;
  max-width: 140px;
  flex: none;
  border: var(--border-bright);
  background: var(--panel);
  padding: var(--s2);
}

.face-size {
  position: absolute;
  right: 0;
  bottom: 0;
  font-family: var(--label);
  font-size: 0.5rem;
  letter-spacing: 0.08em;
  color: var(--void);
  background: var(--dim);
  padding: 2px 4px;
}

.face-actions {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  justify-content: center;
  flex: 1;
}

.face-actions .btn {
  font-size: 0.95rem;
  padding: var(--s3);
}

.face-note {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--dim);
  border-left: 2px solid var(--line-bright);
  padding-left: var(--s3);
}

.name-label {
  font-family: var(--label);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}

.name-input {
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--chalk);
  background: var(--panel);
  border: var(--border-bright);
  border-radius: 0;
  padding: var(--s3) var(--s4);
  width: 100%;
}

.name-input::placeholder {
  color: var(--dimmer);
}

.btn-join {
  margin-top: auto;
  font-size: 1.4rem;
  padding: var(--s4);
}

/* -------------------------------------------------------------------- camera */

.cam-frame {
  flex: 1;
  min-height: 0;
  border: var(--border-bright);
  background: var(--panel);
  overflow: hidden;
  display: flex;
}

#cam {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
}

.cam-actions {
  display: flex;
  gap: var(--s3);
}

.cam-actions .btn {
  flex: 1;
}

/* ------------------------------------------------------------------- gamepad */

.pad-live {
  padding: var(--s2);
  gap: var(--s2);
  overflow: hidden;
}

.pad-head {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex: none;
  padding-bottom: var(--s3);
  border-bottom: 2px solid var(--line);
}

.me-face {
  width: 40px;
  height: 40px;
  border: 2px solid var(--line-bright);
  flex: none;
}

.me-name {
  margin: 0;
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.1;
}

.me-state {
  margin: 0;
  font-size: 0.7rem;
  color: var(--dim);
}

.exit-btn {
  font-family: var(--label);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dead);
  background: transparent;
  border: 2px solid var(--dead);
  border-radius: 0;
  padding: var(--s2) var(--s3);
  cursor: pointer;
  flex: none;
}

.exit-btn:active {
  background: var(--dead);
  color: var(--void);
}

.rtt {
  margin-left: auto;
  margin-right: var(--s2);
  font-family: var(--label);
  font-size: 0.55rem;
  letter-spacing: 0.08em;
  color: var(--dimmer);
}

/* Sound toggle.
 *
 * Deliberately the same three-bar readout as the equaliser on the TV's music widget,
 * because it means the same thing on both screens. It lives in .pad-head and not in
 * the top bar for one concrete reason: the top bar is display:none in landscape, and
 * landscape is exactly when someone is mid-round and wants their handset quiet. */
.sound-btn {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  min-height: 40px;
  padding: var(--s2);
  margin-right: var(--s2);
  background: transparent;
  border: 2px solid var(--line-bright);
  border-radius: 0;
  cursor: pointer;
}

.sound-btn:active {
  background: var(--line);
}

.snd-bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 14px;
}

.snd-bars i {
  width: 3px;
  background: var(--live);
}

.snd-bars i:nth-child(1) { height: 45%; }
.snd-bars i:nth-child(2) { height: 100%; }
.snd-bars i:nth-child(3) { height: 70%; }

/* Off reads as flat and dead, not merely dimmer — at a glance, on a phone, in a dark
   room, a slightly grey version of the same shape is not a different state. */
.sound-btn[data-off='true'] {
  border-color: var(--dead);
}

.sound-btn[data-off='true'] .snd-bars i {
  background: var(--dead);
  height: 25%;
}

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

/* ---- shared layout furniture ------------------------------------------- */

.lay {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

/* Anything a thumb lands on during play. Never moves, never animates position. */
.key {
  border: 2px solid var(--line-bright);
  background: var(--panel-2);
  color: var(--chalk);
  font-family: var(--display);
  font-weight: 700;
  border-radius: 0;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 40ms steps(1);
}

.key[data-down='true'] {
  background: var(--chalk);
  color: var(--void);
  border-color: var(--chalk);
}

/* dpad
   Both clusters are held to a square-ish aspect and centred. Letting the grid rows
   stretch to a tall container turns every key into a thin vertical slab, which is
   both ugly and harder to hit accurately with a thumb. */
.lay-dpad {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: var(--s2);
  /* Anchored to the bottom, where thumbs already are. Centring the clusters puts
     them where a hand has to reach up for them, mid-game, without looking. */
  align-items: end;
  padding-bottom: var(--s2);
}

.dpad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: var(--s2);
  aspect-ratio: 1;
}

.dpad .key {
  font-size: 2.4rem;
}

.dpad .key[data-dir='up'] {
  grid-area: 1 / 2;
}
.dpad .key[data-dir='left'] {
  grid-area: 2 / 1;
}
.dpad .key[data-dir='right'] {
  grid-area: 2 / 3;
}
.dpad .key[data-dir='down'] {
  grid-area: 3 / 2;
}

.dpad-mid {
  grid-area: 2 / 2;
  border: 2px dashed var(--line);
}

.actions {
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: var(--s3);
  /* Sized to land near the d-pad's height, so the two clusters read as one control
     surface rather than one tall column beside one short one. */
  aspect-ratio: 0.78;
}

.actions .key {
  font-size: 2rem;
}

/* tap */
.lay-tap {
  display: flex;
}

.tap-target {
  flex: 1;
  font-size: 2.2rem;
  letter-spacing: 0.04em;
}

/* text */
.lay-text {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.prompt {
  margin: 0;
  font-family: var(--display);
  font-size: 1.3rem;
  line-height: 1.25;
  border-left: 3px solid var(--live);
  padding-left: var(--s3);
}

.answer {
  font-family: var(--body);
  font-size: 1.05rem;
  color: var(--chalk);
  background: var(--panel);
  border: var(--border-bright);
  border-radius: 0;
  padding: var(--s3);
  resize: none;
  flex: 1;
  min-height: 90px;
  width: 100%;
}

.choices {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.choice {
  display: grid;
  grid-template-columns: 36px 1fr;
  align-items: center;
  gap: var(--s3);
  text-align: left;
  padding: var(--s3);
  font-family: var(--body);
  font-size: 1rem;
  min-height: 56px;
}

.choice img {
  width: 32px;
  height: 32px;
  border: 2px solid var(--void);
}

.choice[data-chosen='true'] {
  border-color: var(--live);
  background: var(--panel-2);
  color: var(--live);
}

.choice[disabled] {
  opacity: 0.4;
}

/* menu (lobby) */
.lay-menu {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  overflow-y: auto;
}

.menu-hint {
  margin: 0;
  font-size: 0.78rem;
  color: var(--dim);
  line-height: 1.5;
}

.menu-game {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  text-align: left;
  padding: var(--s3);
  border: 2px solid var(--line-bright);
  background: var(--panel);
  color: var(--chalk);
  border-radius: 0;
  width: 100%;
}

.menu-game[data-picked='true'] {
  border-color: var(--live);
  background: var(--panel-2);
}

.menu-game b {
  font-family: var(--display);
  font-size: 1.2rem;
}

.menu-game span {
  font-size: 0.72rem;
  color: var(--dim);
}

.menu-go {
  flex: none;
  font-size: 1.3rem;
  padding: var(--s4);
}

/* --------------------------------------------------------------------- toast */

.toast {
  position: fixed;
  left: var(--s4);
  right: var(--s4);
  bottom: calc(var(--s4) + env(safe-area-inset-bottom));
  margin: 0;
  padding: var(--s3) var(--s4);
  background: var(--chalk);
  color: var(--void);
  font-size: 0.85rem;
  box-shadow: var(--drop);
  z-index: 20;
  /* A message must never sit between a thumb and a button. */
  pointer-events: none;
}

.toast[data-tone='bad'] {
  background: var(--dead);
  color: var(--void);
}

@media (orientation: landscape) and (max-height: 480px) {
  .pad-top {
    display: none;
  }
  .pad-live {
    padding: var(--s2);
  }
  .pad-head {
    padding-bottom: var(--s2);
  }
  .me-face {
    width: 28px;
    height: 28px;
  }
  .sound-btn {
    min-width: 32px;
    min-height: 32px;
    padding: var(--s1);
  }
}


/* confirm */
.lay-confirm {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  justify-content: flex-end;
  padding-bottom: var(--s2);
}

.confirm-title {
  margin: 0 0 auto;
  font-family: var(--display);
  font-size: 1.6rem;
  line-height: 1.15;
  text-align: center;
  padding-top: var(--s6);
}

.confirm-yes,
.confirm-no {
  font-size: 1.35rem;
  padding: var(--s4);
}

.confirm-yes {
  background: var(--dead);
  border-color: var(--dead);
  color: var(--void);
}

.confirm-yes:hover:not(:disabled) {
  background: var(--dead);
  border-color: var(--dead);
}


/* touch — a pointer surface for placing, aiming and dragging */
.lay-touch {
  display: flex;
}

.touch-surface {
  position: relative;
  flex: 1;
  border: 2px dashed var(--line-bright);
  background:
    repeating-linear-gradient(0deg, transparent 0 15px, rgba(255, 255, 255, 0.03) 15px 16px),
    repeating-linear-gradient(90deg, transparent 0 15px, rgba(255, 255, 255, 0.03) 15px 16px),
    var(--panel);
  touch-action: none;
  overflow: hidden;
}

/* Feedback stays on the phone; the screen is where the real thing happens. */
.touch-dot {
  position: absolute;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border: 3px solid var(--live);
  pointer-events: none;
}

.touch-label {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: var(--s2);
  text-align: center;
  font-family: var(--label);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  pointer-events: none;
}
