/* Interface deliberadamente sobria: a prioridade e' ler numeros depressa
   com o telemovel na mao e um dedo tapado. Contraste alto, alvos grandes. */

/* O Safari do iPhone INFLA o tipo de letra por conta propria quando um bloco
   e' mais largo do que o ecra ("text autosizing"). Media: numa tabela que
   transbordava, um cabecalho aparecia a quase o dobro do tamanho dos outros no
   telemovel e igual no computador. Fixar o ajuste em 100% torna o que se ve no
   telemovel igual ao que se ve a desenvolver. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

:root {
  --bg: #0b0f14;
  --panel: #131a22;
  --panel-2: #0f151c;
  --line: #223040;
  --grid: #2a3a4d;
  --text: #e6edf3;
  --muted: #8b9cb0;
  --accent: #4ade80;
  --peak: #f87171;
  --warn: #fbbf24;
  --bad: #ef4444;
  --red: #f87171;
  --green: #4ade80;
  --blue: #60a5fa;
  color-scheme: dark;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
  padding-bottom: 3rem;
}

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-variant-numeric: tabular-nums; }

/* Aviso permanente: colado ao topo, nunca desaparece. */
.disclaimer {
  position: sticky; top: 0; z-index: 10;
  background: #7c2d12; color: #ffedd5;
  border-bottom: 1px solid #9a3412;
  padding: .6rem 1rem;
  font-size: .85rem; text-align: center;
  padding-top: max(.6rem, env(safe-area-inset-top));
}
.disclaimer strong { color: #fff; }

main { max-width: 760px; margin: 0 auto; padding: 1rem; }

h1 { font-size: 1.3rem; margin: .8rem 0 1rem; }
h1 .sub { display: block; font-size: .8rem; font-weight: 400; color: var(--muted); }
h2 { font-size: .95rem; margin: 0 0 .5rem; color: var(--muted); font-weight: 600; }

/* ---- separadores de modo ---- */

.tabs { display: flex; gap: .4rem; margin-bottom: .85rem; }
.tab {
  flex: 1; min-height: 44px; padding: .6rem .5rem;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); font-size: .9rem; font-weight: 600;
}
.tab.active { background: var(--panel); color: var(--text); border-color: var(--accent); }

/* Contador grande: é o número que se lê de relance, a andar. */
.stepcount { text-align: center; }
.stepcount .label { font-size: .75rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.stepcount .value { font-size: clamp(3rem, 20vw, 5rem); line-height: 1.05; margin: .2rem 0; }
.stepcount .hint { font-size: .78rem; color: var(--muted); min-height: 1.1em; }

#stepChart { width: 100%; height: 130px; display: block; background: var(--panel-2); border-radius: 8px; margin-top: .5rem; }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 1rem;
  margin-bottom: .85rem;
}

/* ---- controlos ---- */

button {
  font: inherit;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--text);
  padding: .7rem 1.1rem;
  cursor: pointer;
  min-height: 48px;              /* alvo tactil confortavel */
}
button:disabled { opacity: .45; cursor: not-allowed; }
button.primary {
  width: 100%;
  background: var(--accent); color: #06240f;
  border-color: transparent; font-weight: 700; font-size: 1.05rem;
}
button.primary.stop { background: var(--bad); color: #fff; }

.controls .meta {
  display: flex; flex-wrap: wrap; gap: .5rem 1.2rem;
  margin: .8rem 0 .4rem; font-size: .85rem; color: var(--text);
}
.k { color: var(--muted); }

.status { margin: .5rem 0 0; font-size: .88rem; color: var(--muted); }
.status.error { color: var(--bad); }

.coverage { margin-top: .5rem; font-size: .82rem; min-height: 1.2em; }
.coverage.ok { color: var(--accent); }
.coverage.bad { color: var(--warn); }

body.warming .controls { outline: 1px dashed var(--warn); outline-offset: 3px; }
body.invalid-session .readouts { outline: 1px solid var(--bad); outline-offset: 3px; }

/* ---- leituras ---- */

.readouts {
  /* 128px de minimo (e nao 150) para que num ecra de 375 px caibam DUAS
     colunas: com uma so, e' preciso fazer scroll para ver o bpm e o indice de
     qualidade ao mesmo tempo — precisamente o que se quer ler de relance com
     o dedo em cima da camara. */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: .9rem .8rem;
}
.readout .label { font-size: .75rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.readout .value { font-size: clamp(1.6rem, 8vw, 2.1rem); line-height: 1.1; margin: .1rem 0; }
.readout .hint { font-size: .72rem; color: var(--muted); }

.bar { height: 6px; background: var(--panel-2); border-radius: 3px; overflow: hidden; margin-top: .4rem; }
.bar span { display: block; height: 100%; width: 0; background: var(--accent); transition: width .2s linear; }
.bar span[data-level="mid"] { background: var(--warn); }
.bar span[data-level="bad"] { background: var(--bad); }

.divergence { font-size: .82rem; margin: -.4rem 0 .85rem; padding-left: .2rem; min-height: 1.2em; }
.divergence.ok { color: var(--muted); }
.divergence.bad { color: var(--warn); font-weight: 600; }

/* ---- grafico ---- */

.chart-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.channel { font-size: .8rem; color: var(--muted); }
.channel select {
  font: inherit; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px; padding: .35rem .5rem; margin-left: .3rem;
}
#chart { width: 100%; height: 150px; display: block; background: var(--panel-2); border-radius: 8px; margin-top: .5rem; }

.perfusion { margin-top: .6rem; font-size: .78rem; color: var(--muted); display: flex; flex-wrap: wrap; gap: .8rem; }
.perfusion .ch.r b { color: var(--red); }
.perfusion .ch.g b { color: var(--green); }
.perfusion .ch.b b { color: var(--blue); }
.perfusion b { font-family: ui-monospace, Menlo, monospace; }
/* Canal fora da gama utilizavel: a percentagem existe mas nao e' de confianca. */
.perfusion .ch.unusable { opacity: .45; text-decoration: line-through; }
.perfusion { display: block; }
.perfusion .ch { display: inline-block; margin-right: .8rem; }

.best { margin-top: .35rem; font-size: .78rem; min-height: 1.1em; }
.best.ok { color: var(--accent); }
.best.hint { color: var(--warn); font-weight: 600; }

.calib { display: flex; flex-wrap: wrap; gap: .6rem; align-items: flex-end; margin-top: .6rem; }
.calib label { font-size: .78rem; color: var(--muted); display: flex; flex-direction: column; gap: .25rem; flex: 1 1 140px; }
.calib input {
  font: inherit; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px; padding: .55rem .6rem; min-height: 44px; width: 100%;
}
.calib button { flex: 0 0 auto; }

.sessionlen { display: block; margin-top: .7rem; font-size: .8rem; color: var(--muted); }
.sessionlen select {
  font: inherit; background: var(--panel-2); color: var(--text); width: 100%;
  border: 1px solid var(--line); border-radius: 6px; padding: .55rem .6rem; min-height: 44px; margin-top: .25rem;
}

/* ---- guia de respiração ---- */
/*
   Um disco que respira, em vez de uma barra. A barra obrigava a perceber em
   que sentido ia; um círculo que cresce e encolhe lê-se sem pensar, e é a
   forma que as pessoas já associam a respirar.

   Cores pedidas pelo Carlos: AZUL a inspirar, VERMELHO a expirar. Nota que a
   convenção dos diagramas de circulação é a inversa — vermelho para sangue
   oxigenado, azul para o venoso — mas em guias de respiração o azul-frio a
   entrar e o quente a sair é leitura comum, e é dele a escolha.
*/

:root {
  --inspirar: #3b9dff;
  --inspirar-claro: #8fcaff;
  --expirar: #f8615c;
  --expirar-claro: #ffa9a2;
}

.pacer { margin-top: .6rem; }

.pacer-stage {
  position: relative;
  height: 190px;
  display: grid;
  place-items: center;
}

/* Anel fixo: marca o tamanho máximo, para se ver quanto falta para o topo. */
.pacer-ring {
  position: absolute;
  width: 172px; height: 172px; border-radius: 50%;
  border: 1px dashed var(--line);
}

.pacer-disc {
  width: 170px; height: 170px; border-radius: 50%;
  transform: scale(0.3);
  background: radial-gradient(circle at 50% 38%, var(--inspirar-claro), var(--inspirar) 70%);
  box-shadow: 0 0 40px -8px var(--inspirar);
  /* A ESCALA não leva transição: é escrita a cada frame e uma transição por
     cima atrasaria o disco face ao ritmo pedido. A COR leva, para a viragem
     entre fases não ser um salto brusco. */
  transition: background .45s linear, box-shadow .45s linear;
}
.pacer-disc.expirar {
  background: radial-gradient(circle at 50% 38%, var(--expirar-claro), var(--expirar) 70%);
  box-shadow: 0 0 40px -8px var(--expirar);
}

/* A etiqueta fica POR CIMA do disco, que encolhe até 51 px — mais estreito do
   que a própria palavra. Texto escuro ficaria escuro-sobre-escuro no mínimo do
   ciclo, por isso é claro, com sombra a garantir contraste tanto sobre o disco
   aceso como sobre o painel. */
.pacer-label {
  position: relative;
  font-size: 1.05rem; font-weight: 700; letter-spacing: .04em;
  color: #fff; text-transform: lowercase;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .55), 0 0 12px rgba(0, 0, 0, .45);
  pointer-events: none;
}

.pacer-row { display: flex; justify-content: space-between; align-items: baseline; margin-top: .2rem; }
.pacer-hint { font-size: .78rem; color: var(--muted); }
.pacer-cycles { font-size: .78rem; color: var(--muted); font-family: ui-monospace, Menlo, monospace; }

.pacer.off .pacer-stage { opacity: .25; }
.pacer.off .pacer-label { color: var(--muted); }

/* ---- avisos ---- */

.warnings { list-style: none; margin: 0 0 .85rem; padding: 0; }
.warnings li {
  background: #3f2d0b; border: 1px solid #78500f; color: #fde68a;
  padding: .55rem .75rem; border-radius: 8px; font-size: .83rem; margin-bottom: .4rem;
}

/* ---- exportacao ---- */

.btn-row { display: flex; gap: .6rem; flex-wrap: wrap; }
.btn-row button { flex: 1 1 auto; min-width: 150px; }
.hint { font-size: .78rem; color: var(--muted); }
code { background: var(--panel-2); padding: .1em .35em; border-radius: 4px; font-size: .92em; }

/* ---- tabela de capacidades ---- */

.caps { overflow-x: auto; }
.caps table { border-collapse: collapse; width: 100%; font-size: .78rem; }
.caps th, .caps td { text-align: left; padding: .35rem .5rem; border-bottom: 1px solid var(--line); white-space: nowrap; }
.caps th { color: var(--muted); font-weight: 600; }
.caps tr.ok td:last-child { color: var(--accent); }
.caps tr.fail td:last-child { color: var(--bad); white-space: normal; }
.caps tr.na td:last-child { color: var(--muted); }
.caps tr.info td { color: var(--muted); }

/* Tabela dos metodos de respiracao: a coluna do estado tem frases inteiras.
   Com o `white-space: nowrap` herdado de .caps a linha nunca quebrava, a tabela
   ficava mais larga do que o ecra e o Safari do iPhone respondia a isso a
   INFLAR o tipo de letra (text autosizing): no telemovel via-se "estado" e os
   motivos num corpo maior do que o resto da tabela, e cortados a meio.
   Coluna fixa + quebra de linha resolve as duas coisas de uma vez. */
#respMethods { overflow-x: visible; }
#respMethods table { table-layout: fixed; }
#respMethods table { font-size: .72rem; }
#respMethods th, #respMethods td { padding: .35rem .3rem; }
#respMethods th:nth-child(1), #respMethods td:nth-child(1) { width: 24%; white-space: normal; }
#respMethods th:nth-child(2), #respMethods td:nth-child(2) { width: 17%; }
#respMethods th:nth-child(3), #respMethods td:nth-child(3) { width: 15%; }
#respMethods th:nth-child(4), #respMethods td:nth-child(4) { white-space: normal; }

/* O video e' a fonte de pixeis para a canvas 64x64 E a pre-visualizacao.
   NAO o esconder com display:none / opacity:0 / posicao fora do ecra: nesses
   casos o browser deixa de compor o elemento e requestVideoFrameCallback nunca
   dispara — a captura fica parada sem dar erro nenhum.

   Fica ao lado da instrucao e do estado do dedo: sao a mesma informacao, e ler
   "coloque o dedo" num sitio e ver se ele la esta noutro obrigava a saltar. */
.cov-row {
  display: flex; align-items: flex-start; gap: .75rem;
  margin-top: .7rem; padding-top: .7rem; border-top: 1px solid var(--line);
}
#video {
  width: 76px; height: 76px; flex: 0 0 76px;
  object-fit: cover; border-radius: 10px;
  background: #000; border: 1px solid var(--line);
}
.cov-text { flex: 1 1 auto; min-width: 0; }
.cov-text .status { margin: 0; }
.cov-row .coverage { margin-top: .35rem; }

/* ---------------------------------------------------------------------------
   Verificacao de contacto (antes de gastar a sessao).

   O objectivo do desenho e' um so': deixar ajustar a pressao do dedo sem olhar
   para numeros. A barra move-se enquanto se ajusta e a marca fixa mostra onde
   e' preciso chegar. O numero fica la' para quem o quiser, mas nao e' preciso
   le-lo para acertar.
   --------------------------------------------------------------------------- */
.contact:empty { display: none; }
.contact {
  margin-top: .6rem; padding: .55rem .7rem;
  border: 1px solid var(--line); border-left-width: 3px;
  border-radius: 8px; background: var(--panel-2);
}
.contact.estabilizar, .contact.aguardar { border-left-color: var(--muted); }
.contact.mao   { border-left-color: var(--bad); }
.contact.mau   { border-left-color: var(--bad); }
.contact.fraco { border-left-color: var(--warn); }
.contact.bom   { border-left-color: var(--accent); }

.contact-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .5rem; font-size: .84rem;
}
.contact-head b { font-variant-numeric: tabular-nums; font-size: 1rem; }
.contact.mau   .contact-head b { color: var(--bad); }
.contact.fraco .contact-head b { color: var(--warn); }
.contact.bom   .contact-head b { color: var(--accent); }

/* A barra tem uma marca fixa no limiar: sem ela, um valor a subir nao diz se
   ja' chega. Com ela, ve-se de relance quanto falta. */
.contact-bar {
  position: relative; height: 8px; margin: .4rem 0 .3rem;
  border-radius: 4px; background: var(--grid); overflow: hidden;
}
.contact-bar i {
  display: block; height: 100%; border-radius: 4px;
  background: var(--muted); transition: width .25s ease;
}
.contact.mau   .contact-bar i { background: var(--bad); }
.contact.fraco .contact-bar i { background: var(--warn); }
.contact.bom   .contact-bar i { background: var(--accent); }
.contact-bar u {
  position: absolute; top: 0; bottom: 0; width: 2px;
  background: var(--text); opacity: .55;
}
.contact-foot { font-size: .7rem; color: var(--muted); }

button.ghost {
  display: block; width: 100%; margin-top: .5rem;
  padding: .55rem .8rem; font-size: .82rem;
  background: transparent; color: var(--muted);
  border: 1px solid var(--line); border-radius: 8px;
}
button.ghost:hover { color: var(--text); border-color: var(--muted); }
button.ghost.urge { color: var(--warn); border-color: var(--warn); }

/* Tendencia entre avaliacoes: a direccao do ajuste. Sem ela, saber que o pulso
   esta fraco nao diz para que lado mexer — e os dois lados sao possiveis. */
.contact-head b em { font-style: normal; margin-left: .3rem; font-size: .85em; }
.contact-head b em.sobe { color: var(--accent); }
.contact-head b em.desce { color: var(--bad); }
.contact-head b em.igual { color: var(--muted); }
.contact-trend { font-size: .76rem; margin-bottom: .25rem; }
.contact-trend.sobe { color: var(--accent); }
.contact-trend.desce { color: var(--bad); }
.contact-trend.igual { color: var(--muted); }

/* Nivel do verde ao vivo: o retorno imediato, ao lado do veredicto lento. */
.contact-live { font-size: .76rem; color: var(--muted); margin-bottom: .2rem; }
.contact-live b { font-variant-numeric: tabular-nums; color: var(--text); }
.contact-live b.bom { color: var(--accent); }
.contact-live b.fraco { color: var(--warn); }
.contact-live b.mau { color: var(--bad); }

/* Respiração recuperada por consenso: nem confirmada nem descartada. */
.hint.consenso { color: var(--warn); }
.caps tr.consenso td { color: var(--warn); }
.caps tr.consenso td:last-child { white-space: normal; }

/* Tabela das métricas de HRV: a coluna da direita tem frases inteiras e, com o
   nowrap herdado de .caps, transbordava e ficava cortada — o mesmo defeito que
   a tabela da respiração teve. Coluna fixa e quebra de linha. */
#hrvMetrics { overflow-x: visible; }
#hrvMetrics table { table-layout: fixed; font-size: .74rem; }
#hrvMetrics th, #hrvMetrics td { padding: .35rem .3rem; }
#hrvMetrics th:nth-child(1), #hrvMetrics td:nth-child(1) { width: 22%; white-space: normal; }
#hrvMetrics th:nth-child(2), #hrvMetrics td:nth-child(2) { width: 22%; }
#hrvMetrics th:nth-child(3), #hrvMetrics td:nth-child(3) { white-space: normal; }
