/* Palette and primitives shared by the three screens.
 *
 * The numbers beside each colour are its contrast ratio against the background it sits
 * on. The rule: 4.5 for body text, 3 for large text and for non-text things. This gets
 * read in the dark, on phone screens at auto brightness, by people holding a drink —
 * worth checking rather than trusting the eye. */
:root {
  --bg: #0d0b14;
  --surface: #171325; /* only the songbook sheet: it's the one thing that floats */
  --line: #463d68; /* 1.8 on the background — not text, it only outlines a button */
  /* O fio que separou as seções depois que os cartões saíram. Quase invisível de
     propósito: separa sem desenhar caixa. */
  --hairline: #1d1830;
  --text: #f4f1fb; /* 17.5 */
  --text-dim: #c4bcdd; /* 10.8 — secondary by size and weight, not by fading out */
  /* 3.3: rótulo mono, nota de rodapé, placeholder. Nunca frase que precise ser lida
     inteira — para isso existe o --text-dim. */
  --text-faint: #6b6484;
  --accent: #ff4d8d; /* 6.2 */
  --accent-2: #46e3c0; /* 12.1 */
  --accent-soft: #ff8fb5; /* "você" na fila, nota dos mais corajosos */
  --danger: #ff8a8a; /* encerrar, remover */
  /* White on that pink is 3.1: fails. Dark on the same pink is 6.2 and still lets the
     pink be pink, which is the point. */
  --on-accent: #0d0b14;
  --shadow: 0 8px 32px rgb(0 0 0 / 45%);

  /* Três famílias, três funções: display para nome próprio e número grande, sans para
     frase, mono para rótulo e algarismo. Cada uma com fallback do sistema — numa festa
     sem internet a Google Fonts não responde e as telas continuam de pé. */
  --display: "Bricolage Grotesque", system-ui, -apple-system, sans-serif;
  --sans: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  -webkit-text-size-adjust: 100%;
}

/* Rótulo mono: o que era <h2> em caixa alta nas três telas. Pequeno, espaçado e da cor
   do acento — anuncia a seção sem competir com o que vem depois. */
.mono-label,
h2 {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  /* Sem isto, um botão sem borda continua ganhando a moldura que o próprio sistema
     desenha — o macOS com "aumentar contraste" ligado põe contorno em todo controle, e
     aí "Ver o acervo" volta a parecer botão mesmo com border:0 aqui. */
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgb(13 11 20 / 60%);
  padding: 0.7em 1.1em;
}

button:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--text);
}

button:disabled {
  opacity: 0.45;
  cursor: default;
}

button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
}

button.primary:hover:not(:disabled) {
  filter: brightness(1.08);
  color: var(--on-accent);
}

/* Campos deixam de ser caixa com borda e viram bloco: uma faixa de transparência sobre o
   fundo. Menos contorno na tela, mesma área pro dedo. */
input {
  font: inherit;
  width: 100%;
  padding: 0.85em 1em;
  border-radius: 16px;
  border: 1px solid transparent;
  background: rgb(255 255 255 / 5%);
  color: var(--text);
}

/* Deliberately faint, still legible: 3.3 on the field background. A placeholder that
   disappears isn't discreet, it's a field that looks broken. */
input::placeholder {
  color: var(--text-faint);
  opacity: 1; /* Firefox applies 0.54 on its own */
}

input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Rótulo da seção e, na mesma linha, o número que resume o que vem embaixo: quantas
   músicas e quanto tempo. Alinhados pela base, que é o que faz o mono pequeno parecer
   parte do rótulo em vez de uma segunda linha solta. */
.section-head {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  flex-wrap: wrap;
}

.section-head .meta {
  margin: 0;
  color: var(--text-dim);
  font-size: 0.9rem;
}

/* --- fields --- */
.field {
  display: grid;
  gap: 0.5rem;
  margin-bottom: 1.1rem;
}

.field > label {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* The label is what gets small, not what you type. Below 16px iOS zooms on focus — and
   with the page zoomed the dropdown lands in the wrong place. */
.field input {
  font-size: 1rem;
}

/* Fica no leitor de tela e sai da tela: onde o placeholder já diz o que é o campo, o
   rótulo repetido só ocupava linha. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- search dropdown (guest phone and host screen) --- */
.combo {
  position: relative;
}

/* A lupa é SVG, não emoji: emoji muda de desenho e de cor a cada sistema, e este ícone
   precisa ser o mesmo cinza do placeholder que está ao lado dele. */
.search-icon {
  position: absolute;
  left: 1.1rem;
  top: 50%;
  translate: 0 -50%;
  pointer-events: none;
}

.combo input {
  padding-left: 3rem;
}

#results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 20;
  margin: 0.4rem 0 0;
  padding: 0.3rem;
  list-style: none;
  max-height: 52vh;
  overflow-y: auto;
  overscroll-behavior: contain; /* scrolling to the end doesn't drag the page */
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 18px;
  box-shadow: var(--shadow);
}

#results[hidden] {
  display: none;
}

.result {
  padding: 0.75rem 0.8rem;
  border-radius: 12px;
  line-height: 1.3;
  cursor: pointer;
  color: var(--text);
}

.result + .result {
  border-top: 1px solid var(--hairline);
}

/* Keyboard highlight and finger highlight in the same place. Dark text on the pink:
   with white, the selected row read as less legible than the others, which is the
   opposite of what "selected" should mean. */
.result.active,
.result:active {
  background: var(--accent);
  color: var(--on-accent);
  border-top-color: transparent;
}

.result.active .secondary,
.result:active .secondary {
  color: rgb(13 11 20 / 78%);
}

.result .primary {
  display: block;
  font-weight: 600;
}

.result .secondary {
  display: block;
  color: var(--text-dim);
  font-size: 0.88rem;
  margin-top: 0.15rem;
}

#results li.empty {
  padding: 0.85rem 0.8rem;
  color: var(--text-dim);
  font-size: 0.9rem;
  line-height: 1.35;
}

/* --- songbook sheet (guest phone and host screen) --- */
/* Os dois caminhos alternativos da busca são botões de contorno, do mesmo tamanho e um do
   lado do outro — o mesmo desenho do "Ligar o microfone" do pop-up da TV. Nenhum dos dois
   é a ação principal (essa é a busca logo acima), então nenhum leva fundo cheio; o que
   separa um do outro é a cor do texto. */
#view-songbook {
  font-size: 0.95rem;
  padding: 0.7em 1.1em;
  color: var(--accent-2);
}

#view-songbook:hover {
  color: var(--text);
}

#songbook-sheet {
  /* Full screen on a phone; a centred card on a monitor. Without max-height the list
     pushes the footer out and the close button goes with it. */
  width: min(100vw, 460px);
  max-width: 100%;
  height: min(100dvh, 720px);
  max-height: 100%;
  padding: 0;
  border: 0;
  border-radius: 26px;
  background: var(--surface);
  color: var(--text);
  overflow: hidden;
}

/* Só no [open]: um <dialog> fechado é display:none, e declarar flex fora disso deixaria o
   acervo visível o tempo todo. É esta regra que faz a lista virar a caixa que rola — sem
   ela o flex:1 lá embaixo não vale nada, a lista cresce com o acervo inteiro, quem corta
   é o overflow do cartão, e aí o cabeçalho gruda no lugar errado. */
#songbook-sheet[open] {
  display: flex;
  flex-direction: column;
}

#songbook-sheet::backdrop {
  background: rgb(8 6 15 / 82%);
}

.sheet-top {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 1.1rem 1.1rem 0.9rem;
  border-bottom: 1px solid var(--hairline);
  /* Não encolhe: é a barra que segura o botão de fechar. */
  flex-shrink: 0;
}

/* O número é contexto, não informação que alguém procura: fica atrás do título e da
   lista. Único lugar que apaga de propósito — em tudo mais o secundário se distingue
   por tamanho e peso. */
#songbook-count {
  flex: 1;
  font-size: 0.82rem;
  color: var(--text-faint);
}

/* Quadrado em vez de pílula: o X ocupa pouco, e sem largura mínima o botão encolheria
   demais pro dedo. */
#songbook-close {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border-radius: 12px;
  background: none;
  font-size: 1rem;
  line-height: 1;
  color: var(--text-dim);
}

/* Régua e lista lado a lado, ocupando o que sobra da caixa. */
.sheet-body {
  display: flex;
  flex: 1;
  min-height: 0;
}

/* A régua fica fora da caixa que rola: é ela que tem que ficar parada. Uma coluna
   estreita de letras, do jeito da agenda do telefone. */
#songbook-index {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  justify-content: space-evenly;
  padding: 0.4rem 0.25rem;
  border-right: 1px solid var(--hairline);
}

#songbook-index button {
  /* Sem cara de botão: são 27 deles empilhados, e 27 caixinhas viram uma parede. */
  border: 0;
  background: none;
  border-radius: 6px;
  padding: 0 0.35rem;
  min-width: 1.6rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--accent-2);
}

/* Letra sem ninguém continua ocupando o lugar dela. Sumir mudaria a posição de todas as
   outras a cada acervo, e é a posição fixa que deixa acertar a letra sem mirar. */
#songbook-index button:disabled {
  color: var(--text-faint);
  opacity: 0.5;
}

#songbook-index button:not(:disabled):hover,
#songbook-index button:not(:disabled):active {
  background: var(--accent);
  color: var(--on-accent);
}

#songbook-list {
  list-style: none;
  margin: 0;
  /* A lista rola dentro da folha: a barra de cima, com o botão de fechar, continua ao
     alcance mesmo com centenas de músicas embaixo. Ocupa a largura que sobra ao lado da
     régua; `min-width: 0` é o que permite encolher em vez de empurrar a régua pra fora. */
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 0.7rem 1.2rem;
}

/* Marca onde cada artista começa. Já foi fixo no topo enquanto a lista rolava; o Safari
   ancora `position: sticky` fora desta caixa e deixava passar meia linha de música por
   cima do nome, então por ora ele rola junto com o resto. */
#songbook-list .artist {
  padding: 0.85rem 0.4rem 0.35rem;
  font-weight: 600;
  color: var(--accent-2);
  font-size: 0.92rem;
}

#songbook-list .song {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  border-radius: 12px;
  padding: 0.65rem 0.7rem;
  font-size: 1rem;
  line-height: 1.3;
}

#songbook-list .song:hover,
#songbook-list .song:active {
  background: var(--accent);
  color: var(--on-accent);
}

#songbook-list .empty {
  padding: 1rem 0.7rem;
  color: var(--text-dim);
  line-height: 1.35;
}

/* --- link fallback, shared by the two phone screens --- */
/* O <details> perde a caixa: vira a mesma linha de texto clicável que "Ver o acervo",
   e o formulário só aparece quando alguém pede. */
#by-link {
  font-size: 0.95rem;
}

/* O <summary> não é um <button>, então veste o botão à mão — e sem o triângulo, que o
   sistema desenha por conta. */
#by-link summary {
  cursor: pointer;
  list-style: none;
  appearance: none;
  -webkit-appearance: none;
  display: inline-block;
  padding: 0.7em 1.1em;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgb(13 11 20 / 60%);
  color: var(--text-dim);
}

#by-link summary::-webkit-details-marker {
  display: none;
}

#by-link summary:hover {
  border-color: var(--accent);
  color: var(--text);
}

#by-link form {
  display: grid;
  gap: 0.7rem;
  margin-top: 0.9rem;
}

/* As duas saídas alternativas na mesma linha; o formulário do link, quando abre, ocupa a
   largura toda em vez de espremer o vizinho. */
.more-ways {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.7rem;
  margin-top: 0.7rem;
}

#by-link[open] {
  flex: 1 0 100%;
}

/* Connection dot: green while the WebSocket is up. O ponto ganhou legenda — de longe,
   um ponto vermelho sozinho não diz se o problema é a festa ou o wi-fi. */
.connection {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
  flex: none;
}

.connection::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #d64545;
  transition: background 0.3s;
}

.connection::after {
  content: "sem conexão";
}

.connection.up {
  color: var(--accent-2);
}

.connection.up::before {
  background: var(--accent-2);
  box-shadow: 0 0 10px rgb(70 227 192 / 60%);
}

.connection.up::after {
  content: "na festa";
}
