/*
 * Tokens visuais e componentes compartilhados.
 *
 * Este arquivo veste tanto as páginas estáticas quanto as renderizadas pelo
 * Worker (html.ts), nas três cascas que elas usam: `prose` (documentos legais,
 * /success, /dev/mailbox), `auth` (/login e as telas de link) e `app` (o painel,
 * /app e /app/e). Nenhum componente abaixo referencia cor literal — trocar
 * identidade é mexer só no bloco de token do `:root`.
 *
 * Paleta HoneyForms, com as restrições de contraste medidas:
 *
 *   ink    #101012    amber  #E8A317    cream  #FBEFD6
 *   gray   #6B6B70    paper  #FAFAF8
 *
 * Duas regras que o âmbar impõe e que não podem ser esquecidas:
 *
 *   1. Âmbar sobre papel dá 2,06:1. Ele é **preenchimento**, nunca cor de texto
 *      sobre o papel — por isso existe `--accent-ink` (5,6:1), usado em link e
 *      ênfase. Sobre a superfície invertida o âmbar dá 8,76:1 e aí sim vira
 *      texto; é a única exceção, e ela vale pelo fundo, não pelo tema.
 *   2. Texto sobre botão âmbar é `--accent-fg`, que é **tinta**, não branco:
 *      branco sobre âmbar dá 2,17:1 e tinta dá 8,76:1.
 *
 * O cream é holofote, não superfície. Se ele virasse `--bg-soft`, todo `.notice`
 * e todo `.card` do produto ficariam bege e a página sumiria num bloco só. Ele
 * tem token próprio e aparece em dois lugares: a faixa "How it works" da landing
 * e o cartão do honeypot.
 *
 * `--bg-invert` é a terceira superfície: tinta, para o cartão de código do hero
 * e a seção agêntica. Junto com o cream, é o que dá o ritmo papel → cream →
 * papel → tinta → papel que separa as seções da landing.
 *
 * **Não há modo escuro, e a ausência é deliberada.** A identidade é a do
 * desenho: papel sempre, com as duas superfícies acima fazendo o contraste. Um
 * `@media (prefers-color-scheme: dark)` aqui devolveria a página inteira em
 * tinta e desmontaria justamente esse ritmo — o cream não tem equivalente
 * escuro e a seção invertida deixaria de se distinguir do fundo. É por isso que
 * `:root` declara `color-scheme: light`: sem ele o navegador de quem usa o
 * sistema em escuro ainda pinta scrollbar, `<input>` e autofill por cima dos
 * nossos tokens.
 */

/*
 * As duas famílias são servidas por nós, de `public/fonts/`.
 *
 * O Google Fonts entregaria os mesmos arquivos, mas cada visita à landing
 * mandaria o IP do visitante para fonts.gstatic.com — e a lista de
 * subprocessadores publicada em /privacy é fechada. Uma fonte não vale um nome
 * a mais nela.
 *
 * Os dois são arquivos **variáveis**: um woff2 por subset cobre toda a faixa de
 * peso, e é por isso que `font-weight` traz um intervalo em vez de um número.
 * Os `unicode-range` vêm verbatim do Google e são o que faz o `latin-ext` não
 * ser baixado numa página que só tem inglês. Licença em `fonts/OFL.txt`.
 */

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(/fonts/inter-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(/fonts/inter-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url(/fonts/jetbrains-mono-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url(/fonts/jetbrains-mono-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Sem isto o UA de um sistema em escuro pinta widget e scrollbar por cima. */
  color-scheme: light;

  --bg: #fafaf8;
  --bg-raised: #ffffff;
  --bg-soft: #f3f2ee;
  --bg-code: #f2f1eb;
  --bg-cream: #fbefd6;
  --fg: #101012;
  --fg-muted: #6b6b70;
  --border: #e3e1da;
  --border-cream: #ecd9ab;

  --accent: #e8a317;
  --accent-ink: #8a5a00;
  --accent-fg: #101012;

  --bg-invert: #101012;
  --fg-invert: #d7d7d2;
  --fg-invert-muted: #8a8a90;
  --border-invert: rgba(250, 250, 248, 0.16);

  --ok: #0f7b46;
  --warn: #9a4a0b;
  --error: #b3261e;

  --radius: 8px;
  --gap: 1rem;
  --measure: 34rem;
  --font: Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent-ink); }

.shell {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 3rem 1.25rem 5rem;
}

.wide { max-width: 52rem; }

h1 { font-size: 1.5rem; line-height: 1.25; margin: 0 0 0.5rem; letter-spacing: -0.02em; }
h2 { font-size: 1.05rem; margin: 2.5rem 0 0.5rem; letter-spacing: -0.01em; }
p  { margin: 0 0 1rem; }
.muted { color: var(--fg-muted); }
.small { font-size: 0.875rem; }

/* Rótulo acessível fora da tela, sem o hack de `left:-9999px` inline. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- marca ---- */

/*
 * A célula de favo com os três campos dentro. O SVG mora em `html.ts` (`MARK`),
 * inline, então continua sem custar requisição e continua escalando com a
 * fonte; daqui saem só as duas cores, para que a identidade siga trocável no
 * bloco de token.
 *
 * A caixa é 1.4em porque o `viewBox` traz folga em volta do hexágono: o favo
 * desenhado ocupa cerca de 1em dela, que é o tamanho que ele tinha quando era
 * `clip-path`.
 */
.mark {
  display: block;
  width: 1.4em;
  height: 1.4em;
  flex: none;
}

.mark-hex { fill: var(--accent); }
/* Em cima do âmbar vale a regra do botão: tinta, 8,76:1 — nunca papel. */
.mark-bar { fill: var(--accent-fg); }

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--fg);
  /*
   * O baseline de um `inline-flex` é o do primeiro item, que agora é o SVG —
   * sem isto a assinatura sobe alguns pixels quando aparece no meio de uma
   * frase, como em "Form delivered by" na página de sucesso. Em contexto flex
   * (o topo e o rodapé da landing) a declaração é ignorada.
   */
  vertical-align: middle;
}

/*
 * O nome é uma palavra só — `HoneyForms`, camel case — num único nó de texto.
 * Partido em `<b>Honey</b><span>Forms</span>` ele herdava o `gap` do flex acima
 * e saía escrito "Honey Forms", com dois pesos e duas cores.
 */

/* ---- formulários ---- */
.field {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

input[type="email"], input[type="text"], select, textarea {
  flex: 1 1 16rem;
  min-width: 0;
  padding: 0.65rem 0.75rem;
  font: inherit;
  color: var(--fg);
  /* Branco sobre o papel: é o que faz o campo ler como campo, e não como fundo. */
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

textarea {
  min-height: 7rem;
  line-height: 1.5;
  /* Vertical só: `resize` livre deixa arrastar para fora da medida de leitura. */
  resize: vertical;
}

/*
 * Formulário em coluna — o de `/report-abuse`.
 *
 * `.field` acima é a linha de um campo só da landing: flex, campo e botão lado
 * a lado. Cinco campos rotulados pedem coluna, e é aqui que os controles
 * ganham a largura toda — dentro do `.shell` de 34rem isso já é a medida certa,
 * sem `max-width` extra.
 */
.stack {
  display: grid;
  gap: 1.25rem;
  margin: 0 0 1.5rem;
}

.stack label {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--fg-muted);
}

.stack input, .stack select, .stack textarea { width: 100%; }

.stack p { margin: 0; }

/*
 * O anel de foco usa `--accent-ink`, não `--accent`: o âmbar puro dá 2,08:1
 * sobre o papel e a WCAG exige 3:1 para indicador de foco. Sobre a superfície
 * invertida quem sobrescreve para o âmbar cheio é a landing, que é onde ela
 * existe.
 */
input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
}

button {
  padding: 0.65rem 1.1rem;
  font: inherit;
  font-weight: 600;
  color: var(--accent-fg);
  background: var(--accent);
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
}

button.secondary {
  color: var(--fg);
  background: transparent;
  border-color: var(--border);
  font-weight: 500;
}

button[disabled] { opacity: 0.55; cursor: default; }

/* ---- código ---- */
pre, code { font-family: var(--mono); font-size: 0.8125rem; }

code { color: var(--accent-ink); }

pre {
  background: var(--bg-code);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  overflow-x: auto;
  line-height: 1.5;
  margin: 0 0 1rem;
}

pre code { color: inherit; }

/* ---- superfícies ---- */
.card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  margin: 0 0 0.75rem;
  background: var(--bg-soft);
}

/* Holofote. Usado só na demo e no bloco do honeypot. */
.cream {
  background: var(--bg-cream);
  border: 1px solid var(--border-cream);
  border-radius: var(--radius);
  padding: 1.25rem;
}

/* ---- avisos ---- */
.notice {
  padding: 0.75rem 0.9rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg-soft);
}
.notice--ok    { border-color: var(--ok);    color: var(--ok); }
.notice--warn  { border-color: var(--warn);  color: var(--warn); }
.notice--error { border-color: var(--error); color: var(--error); }

/* ---- tabelas ---- */
table { border-collapse: collapse; width: 100%; font-size: 0.9375rem; }
th, td { text-align: left; padding: 0.35rem 0.75rem 0.35rem 0; vertical-align: top; }
th { color: var(--fg-muted); font-weight: 500; white-space: nowrap; }

footer.site {
  border-top: 1px solid var(--border);
  margin-top: 4rem;
  padding-top: 1.25rem;
  color: var(--fg-muted);
  font-size: 0.875rem;
}
footer.site a { color: var(--fg-muted); }

/* ---- entrada ---- */

/*
 * A casca `auth`: /login e as três telas de link (enviado, gasto, excesso de
 * tentativas).
 *
 * Cartão centrado e nada mais. Não há navegação porque quem está aqui ainda não
 * tem para onde ir — o único caminho é o campo de e-mail — e a assinatura em
 * cima existe para que a tela não pareça de outro produto depois do clique que
 * veio da landing.
 */
.auth {
  max-width: 26rem;
  margin: 0 auto;
  padding: clamp(2.5rem, 9vh, 4.5rem) 1.25rem 4rem;
}

.auth .wordmark { margin-bottom: 1.25rem; }

.auth-card {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.6rem;
}

.auth-card h1 { font-size: 1.25rem; }
.auth-card > :last-child { margin-bottom: 0; }
.auth-card footer.site { margin-top: 1.75rem; }

/* ---- painel ---- */

/*
 * A casca `app`: /app e /app/e.
 *
 * Três superfícies, e é a diferença entre elas que dá a profundidade: a lateral
 * é o papel amassado (`--bg-soft`), a tela é o papel (`--bg`) e o que se lê fica
 * em cartão branco (`--bg-raised`). Nenhuma sombra — o contraste de superfície
 * já separa os planos, e sombra sobre papel é o começo do plástico.
 *
 * A lateral é `sticky` e não `fixed` para não precisar reservar coluna no
 * `body`: o grid faz isso, e num telefone ela vira barra de topo sem nenhuma
 * mudança de posicionamento.
 */
.app {
  display: grid;
  grid-template-columns: 15.5rem minmax(0, 1fr);
  min-height: 100vh;
}

.side {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  /*
   * `height: 100vh` com `align-self: start`, e não a altura da linha do grid: o
   * item esticado teria a altura do conteúdo da página, e uma lateral de três
   * mil pixels não gruda em lugar nenhum — ela sairia da tela junto com o resto.
   */
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
  padding: 1.25rem 0.9rem;
  background: var(--bg-soft);
  border-right: 1px solid var(--border);
}

.side .wordmark { font-size: 1.125rem; margin: 0.2rem 0.4rem 1.25rem; }

/*
 * Rótulo de grupo: na lateral e no corpo. O mesmo tratamento do `.eyebrow` da
 * landing — mono, miúdo, versalete — porque é a mesma função nas duas páginas:
 * nomear um grupo sem competir com o título dele.
 */
.side-label, .sec-label {
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.side-label { margin: 1.25rem 0.4rem 0.4rem; }
.sec-label { margin: 0 0 0.6rem; }

.side-nav { display: grid; gap: 0.1rem; }

.side-item {
  display: block;
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius);
  font-size: 0.9375rem;
  color: var(--fg);
  text-decoration: none;
  /* Nome de endpoint é escolhido pelo cliente e não cabe em 15rem sempre. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.side-item:hover { background: var(--bg-raised); }

/*
 * `box-shadow` interno, e não `border-left`: a borda desalinharia o texto dos
 * outros itens em 2px, e a marca âmbar precisa acompanhar o canto arredondado.
 */
.side-item.is-active {
  background: var(--bg-raised);
  font-weight: 600;
  box-shadow: inset 2px 0 0 var(--accent);
}

.side-foot {
  margin-top: auto;
  padding: 0.9rem 0.6rem 0;
  border-top: 1px solid var(--border);
  font-size: 0.8125rem;
  color: var(--fg-muted);
  /* A borda do topo só faz sentido colada no fim; sem isto ela sobe num
     painel curto e vira um traço solto no meio da lateral. */
  min-height: 0;
}

.side-foot .who {
  display: block;
  margin-bottom: 0.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

.side-foot button { padding: 0.35rem 0.7rem; font-size: 0.8125rem; }

.app-main {
  max-width: 68rem;
  width: 100%;
  margin: 0 auto;
  padding: 2.25rem 1.75rem 4rem;
}

/*
 * Abaixo de 60rem a lateral vira barra de topo: mesma marcação, mesmo conteúdo,
 * lista de endpoints rolando na horizontal. É o que evita um menu sanfonado —
 * que precisaria de JavaScript para uma navegação de três itens.
 */
@media (max-width: 60rem) {
  /*
   * `grid-template-rows` explícito: com uma coluna só, a lateral e o conteúdo
   * viram duas linhas, e o `min-height: 100vh` do grid reparte a sobra entre as
   * duas — o que esticava a barra de topo e abria um vão de meia tela antes do
   * conteúdo, tanto maior quanto mais curta a aba aberta.
   */
  .app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
  }
  .side {
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    height: auto;
    overflow: visible;
    position: static;
    padding: 0.75rem 1rem;
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }
  .side .wordmark { margin: 0; }
  .side-label { display: none; }
  .side-nav { display: flex; flex: 1 1 100%; gap: 0.35rem; overflow-x: auto; min-width: 0; }
  /*
   * `min-width: 0` nos dois: item de flex não encolhe abaixo do próprio
   * conteúdo por padrão, e sem isto a linha do topo (assinatura + e-mail +
   * sair) empurrava a página inteira para ~500px num telefone de 390 — a barra
   * não estourava sozinha, ela alargava o documento e cortava todo o resto.
   */
  .side-foot {
    margin: 0 0 0 auto;
    padding: 0;
    border-top: 0;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
  }
  .side-foot .who {
    margin: 0;
    min-width: 0;
    max-width: 11rem;
    white-space: nowrap;
  }
  .app-main { padding: 1.5rem 1.25rem 3rem; }
}

/* ---- cabeçalho de página ---- */

.crumb { font-size: 0.875rem; margin: 0 0 0.75rem; }
.crumb a { color: var(--fg-muted); text-decoration: none; }
.crumb a:hover { color: var(--fg); }

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin: 0 0 1.75rem;
}

.page-head h1 { margin: 0; font-size: 1.6rem; }
.page-head .subtitle { margin: 0.3rem 0 0; color: var(--fg-muted); font-size: 0.9375rem; }
.page-head .meta {
  margin: 0.5rem 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.75rem;
  font-size: 0.8125rem;
  color: var(--fg-muted);
}
.page-head .actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.page-head .meta code { color: var(--fg-muted); }

/*
 * Ação em forma de link: o export do histórico e a paginação. Precisa ser `<a>`
 * — os dois são navegação de topo, e é o `SameSite=Lax` do cookie que faz o
 * download funcionar sem JavaScript.
 */
.btn {
  display: inline-block;
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--fg);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
}

.btn:hover { border-color: var(--fg-muted); }

/* Dois formulários de um botão só, lado a lado — os do read token. */
.formrow { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }

/* Lista de saídas curtas: "mudei de domínio", "travou no errado". Era uma
   tabela de duas colunas, que não cabe na largura de um cartão. */
.tips {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: grid;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--fg-muted);
}

.tips b { color: var(--fg); font-weight: 600; }

.mono { font-family: var(--mono); font-size: 0.8125rem; }

/* ---- números do mês ---- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.75rem;
  margin: 0 0 2rem;
}

.stat {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
}

.stat h3 {
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 0.6rem;
}

.stat p { margin: 0; font-size: 0.875rem; line-height: 1.45; color: var(--fg-muted); }

/*
 * O número grande sai daqui, e não de uma classe no próprio `<strong>`: a frase
 * do uso é aferida literalmente pela suíte ("<strong>1</strong> of 500
 * submissions"), então a tag não pode ganhar atributo. Estilo pelo pai resolve
 * sem tocar no que o teste lê.
 */
.stat p strong {
  display: block;
  font-size: 1.9rem;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--fg);
}

.meter {
  height: 0.4rem;
  margin-top: 0.75rem;
  border-radius: 999px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  overflow: hidden;
}

/* Âmbar é preenchimento, nunca texto: aqui ele está no seu lugar. */
.meter i { display: block; height: 100%; background: var(--accent); }
.meter--warn i { background: var(--warn); }
.meter--error i { background: var(--error); }

/* ---- etiqueta de estado ---- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.15rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-raised);
  font-size: 0.75rem;
  font-weight: 500;
  white-space: nowrap;
  color: var(--fg-muted);
}

.chip::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.chip--ok { color: var(--ok); }
.chip--warn { color: var(--warn); }

/* ---- cartões ---- */

.panel {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin: 0 0 1rem;
}

/* A nav de seções fica grudada no topo e cobriria o cabeçalho do alvo. */
.panel[id] { scroll-margin-top: 4.5rem; }

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.8rem 1.1rem;
  border-bottom: 1px solid var(--border);
}

.panel-head h2 { margin: 0; font-size: 0.9375rem; font-weight: 600; }
.panel-body { padding: 1.1rem; }
/* Sem isto a lista de saídas encosta no botão de salvar, e as duas coisas leem
   como um bloco só. */
.panel-body form { margin: 0 0 1.25rem; }
.panel-body > :last-child { margin-bottom: 0; }
.panel-body .notice:first-child { margin-top: 0; }

/* Estado vazio: moldura tracejada, para ler como espaço reservado e não como
   erro. Todas as três telas vazias do painel usam esta. */
.empty {
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  padding: 1.75rem 1.25rem;
  text-align: center;
  color: var(--fg-muted);
  margin: 0;
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr));
  gap: 1rem;
  align-items: start;
  margin: 0 0 1rem;
}

.grid-2 .panel { margin: 0; }

/* ---- abas ---- */

/*
 * São links, e cada um carrega uma página inteira. Sem estado no cliente: os
 * quatro POSTs da página do endpoint re-renderizam tudo, e quem escolhe a aba da
 * resposta é o servidor — é o que devolve a pessoa ao formulário que ela acabou
 * de usar, em vez de jogá-la de volta na primeira aba.
 */
.secnav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin: 0 0 1.25rem;
  padding: 0 0 0.55rem;
  border-bottom: 1px solid var(--border);
}

.secnav a {
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  font-size: 0.875rem;
  color: var(--fg-muted);
  text-decoration: none;
}

.secnav a:hover { color: var(--fg); background: var(--bg-soft); }

/* A aba corrente vem em cartão, como o conteúdo que ela abre logo abaixo. */
.secnav a.is-active {
  color: var(--fg);
  font-weight: 600;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  padding: 0.28rem 0.78rem;
}

/* ---- nome editável ---- */

/*
 * O campo *é* o título. Sem moldura em repouso, com moldura ao passar o mouse ou
 * ao receber foco: uma caixa de formulário permanente no meio do cabeçalho leria
 * como "preencha isto", quando o que se quer dizer é "isto pode ser corrigido".
 */
.rename { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.rename h1 { margin: 0; flex: 1 1 16rem; min-width: 0; }

.rename input {
  width: 100%;
  font: inherit;
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--fg);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 0.1rem 0.4rem;
  margin-left: -0.4rem;
}

.rename input:hover { border-color: var(--border); }
.rename input:focus { background: var(--bg-raised); border-color: var(--border); }

/*
 * O botão só aparece quando há o que salvar — passar o mouse pelo bloco ou estar
 * com o campo em foco. Um "Rename" permanente ao lado do título pesaria mais que
 * o próprio título, e teclado e toque continuam alcançando pelo `:focus-within`.
 */
.rename button {
  padding: 0.4rem 0.9rem;
  font-size: 0.875rem;
  opacity: 0;
  transition: opacity 0.12s;
}
.rename:hover button, .rename:focus-within button { opacity: 1; }
@media (hover: none) {
  .rename button { opacity: 1; }
}

/* ---- a URL de envio ---- */

/*
 * Sobre a superfície invertida, como o cartão de código do hero: é o objeto que
 * a pessoa veio buscar quando não veio ver submissão, e sobre papel ele lia
 * como mais uma linha de tabela.
 */
.urlbar {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius);
  background: var(--bg-invert);
  margin: 0 0 1.25rem;
}

.urlbar .verb {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  color: var(--fg-invert-muted);
  flex: none;
}

.urlbar code {
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  white-space: nowrap;
  color: var(--fg-invert);
}

/* ---- copiar ---- */

/*
 * O botão é injetado por JavaScript (`COPY_SCRIPT` em html.ts). Sem script ele
 * não existe, e o valor continua legível e selecionável onde está.
 */
.copy {
  flex: none;
  padding: 0.25rem 0.7rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 500;
  border-radius: 999px;
  color: var(--fg);
  background: var(--bg-raised);
  border: 1px solid var(--border);
}

.urlbar .copy {
  margin-left: auto;
  color: var(--fg-invert);
  background: transparent;
  border-color: var(--border-invert);
}

/* Sobre a tinta, o anel de foco tem de ser o âmbar cheio: `--accent-ink` ali
   dá menos do que os 3:1 que a WCAG pede para indicador de foco. */
.urlbar .copy:focus-visible { outline-color: var(--accent); }

/* Bloco de código com botão no canto — o snippet do Turnstile. */
.snip { position: relative; }
.snip .copy { position: absolute; top: 0.55rem; right: 0.55rem; }
.snip pre { padding-right: 5.5rem; }

/*
 * O snippet quebra linha em vez de rolar: são linhas longas de HTML, e rolagem
 * horizontal esconde justamente o fim delas — que é onde estão os atributos que
 * a pessoa precisa conferir.
 */
pre.snippet { white-space: pre-wrap; word-break: break-word; }

/* ---- lista de endpoints ---- */

.ep {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  margin: 0 0 0.75rem;
}

.ep-top {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
}

.ep-name { font-size: 1rem; font-weight: 600; color: var(--fg); text-decoration: none; }
.ep-name:hover { color: var(--accent-ink); }
.ep-open { margin-left: auto; font-size: 0.875rem; text-decoration: none; white-space: nowrap; }
.ep .urlbar { margin: 0; }

/* ---- submissões ---- */

.subs { display: grid; gap: 0.6rem; }

.sub {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  padding: 0.8rem 0.9rem;
}

.sub-time {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0 0 0.6rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--fg-muted);
}

.sub-fields {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.35rem 0.9rem;
  font-size: 0.9375rem;
}

.sub-key {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--fg-muted);
  padding-top: 0.25rem;
  word-break: break-word;
}

/* `pre-wrap` porque mensagem de formulário vem com quebra de linha, e sem isto
   um parágrafo inteiro colapsa numa linha só. */
.sub-val { margin: 0; white-space: pre-wrap; word-break: break-word; }

@media (max-width: 34rem) {
  .sub-fields { grid-template-columns: minmax(0, 1fr); gap: 0.1rem; }
  .sub-key { padding-top: 0.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
