/* assets/css/componentes.css
 * ============================================================
 *  GSHIELD — COMPONENTES
 * ============================================================
 *
 *  Nenhuma cor literal aqui. Tudo vem de tokens.css, e por isso todo
 *  componente funciona nos dois temas sem uma linha a mais.
 *
 *  Duas coisas valem por todo o arquivo:
 *
 *  ALVO DE TOQUE. Todo controle interativo tem no mínimo 44px de
 *  altura efetiva no mobile. Botão de copiar senha com 32px faz você
 *  errar e revelar o card errado — e revelação errada fica na trilha
 *  de auditoria como acesso indevido, que é o que você vai olhar
 *  quando um cliente reclamar.
 *
 *  HOVER NÃO É AFFORDANCE. Nada aparece só no :hover. No celular não
 *  existe hover, e um botão que só surge ao passar o mouse
 *  simplesmente não existe lá.
 * ============================================================ */

@layer componentes {

  /* ============================================================
     BOTÃO
     ============================================================ */

  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--esp-2);

    min-height: var(--alvo);
    padding: 0 var(--esp-4);

    font-size: var(--texto-md);
    font-weight: var(--peso-medio);
    color: var(--texto);

    background: var(--sup-2);
    border-radius: var(--raio-md);

    transition: background-color var(--dur-rapida) var(--ease-saida),
                transform var(--dur-rapida) var(--ease-saida);
  }

  @media (hover: hover) {
    .btn:hover { background: var(--sup-3); }
  }

  /* O feedback de toque é o :active, não o :hover. No celular é o
     único que dispara, e sem ele o toque parece não registrar. */
  .btn:active { transform: scale(0.97); }

  .btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    transform: none;
  }

  .btn--primario {
    color: var(--tinta-azul-fg);
    background: var(--tinta-azul-bg);
  }

  .btn--perigo {
    color: var(--perigo-fg);
    background: var(--perigo-bg);
  }

  .btn--fantasma { background: transparent; }

  .btn--largo { width: 100%; }

  /* Botão só de ícone. Quadrado, e o alvo é o mínimo em ambos os eixos. */
  .btn--icone {
    min-width: var(--alvo);
    padding: 0;
    font-size: 1.0625rem;
    color: var(--texto-2);
  }

  .btn--icone.btn--fantasma:active { background: var(--sup-2); }

  @media (min-width: 768px) {
    /* No desktop há ponteiro preciso: controle menor cabe melhor e a
       tela respira. O alvo grande continua no mobile. */
    .btn { min-height: var(--altura-controle); }
    .btn--icone { min-width: var(--altura-controle); }
  }

  /* ============================================================
     CAMPO
     ============================================================ */

  /* Espaço ENTRE campos maior que o espaço interno de cada um.
     Com os dois iguais, o rótulo de um campo parecia legenda do campo
     anterior — a lei de proximidade trabalhando contra você. */
  .campo { display: block; margin-bottom: var(--esp-5); }

  .campo__rotulo {
    display: block;
    margin-bottom: var(--esp-2);
    font-size: var(--texto-sm);
    font-weight: var(--peso-medio);
    color: var(--texto-2);
  }

  .campo__entrada,
  textarea.campo__entrada,
  select.campo__entrada {
    width: 100%;
    min-height: var(--alvo);
    padding: 0 var(--esp-3);

    /* 16px no mobile NÃO é escolha estética.
       Abaixo disso o Safari do iOS dá zoom automático ao focar o
       campo, e o usuário fica com o layout deslocado no meio de
       digitar a senha mestra. */
    font-size: 1rem;
    font-family: inherit;
    line-height: 1.4;

    color: var(--texto);
    background: var(--sup-1);
    border: 1px solid var(--borda-forte);
    border-radius: var(--raio-md);

    /* `appearance: none` no conjunto todo.
       Sem isto o iOS arredonda o input do jeito dele, ignora o
       border-radius e desenha uma sombra interna própria — dois
       campos lado a lado ficam com formatos diferentes. */
    appearance: none;
    -webkit-appearance: none;

    transition: border-color var(--dur-rapida) var(--ease-saida),
                box-shadow var(--dur-rapida) var(--ease-saida),
                background-color var(--dur-rapida) var(--ease-saida);
  }

  /* Borda mais forte que a dos cards, de propósito.
     Campo é área EDITÁVEL: ele precisa parecer clicável antes de você
     tocar. Com a mesma borda de um card, o formulário vira uma pilha
     de retângulos iguais e você não sabe onde escrever. */

  textarea.campo__entrada {
    min-height: 88px;
    padding: var(--esp-3);
    resize: vertical;
  }

  .campo__entrada::placeholder { color: var(--texto-3); opacity: 1; }

  @media (hover: hover) {
    .campo__entrada:hover:not(:disabled) { border-color: var(--texto-3); }
  }

  /* Foco: anel de 3px por box-shadow, não outline de 1px.
     O outline fino desaparecia em tela de notebook com brilho alto —
     e saber onde está o cursor é o que permite digitar sem olhar para
     o teclado. */
  /* A linha com rgba é a RESERVA.
     `color-mix` só existe a partir do Chrome 111 e do Safari 16.2 — em
     navegador mais velho ela é ignorada e a de cima vale. Sem a
     reserva, o anel de foco simplesmente não apareceria, e foco
     invisível é problema de acessibilidade, não de estética. */
  .campo__entrada:focus,
  .campo__entrada:focus-visible {
    outline: none;
    border-color: var(--foco);
    box-shadow: 0 0 0 3px rgba(90, 140, 210, 0.28);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--foco) 22%, transparent);
  }

  .campo__entrada:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    background: var(--sup-2);
  }

  /* ── SELECT ──
     A seta é obrigatória: sem ela o select fica idêntico a um campo de
     texto, e a pessoa clica esperando digitar. O cinza médio foi
     escolhido para funcionar nos quatro temas sem precisar de uma
     regra por tema. */
  select.campo__entrada {
    padding-right: calc(var(--esp-3) + 22px);
    cursor: pointer;

    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239a9a9a' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--esp-3) center;
  }

  /* ── NÚMERO ──
     Sem as setinhas: elas ocupam a lateral, mudam de aparência entre
     navegadores e, num campo de porta ou de meses, ninguém incrementa
     de um em um. */
  input[type="number"].campo__entrada {
    -moz-appearance: textfield;
  }

  input[type="number"].campo__entrada::-webkit-outer-spin-button,
  input[type="number"].campo__entrada::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }

  /* ── BUSCA ──
     O "x" nativo do Chrome não segue o tema e some no escuro. */
  input[type="search"].campo__entrada::-webkit-search-cancel-button {
    -webkit-appearance: none;
  }

  /* ── DATA ──
     O ícone do calendário é do sistema; `color-scheme` no :root já faz
     ele inverter no tema escuro. Aqui só o cursor. */
  input[type="date"].campo__entrada { cursor: pointer; }

  input[type="date"].campo__entrada::-webkit-calendar-picker-indicator {
    cursor: pointer;
    opacity: 0.6;
  }

  input[type="date"].campo__entrada::-webkit-calendar-picker-indicator:hover {
    opacity: 1;
  }

  /* ── CAIXA DE MARCAR ──
     `accent-color` em vez de recriar do zero: mantém o comportamento
     nativo (teclado, leitor de tela) e só troca a cor. */
  input[type="checkbox"],
  input[type="radio"] {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    accent-color: var(--tinta-azul-fg);
    cursor: pointer;
  }

  .campo__entrada--senha {
    font-family: var(--fonte-mono);
    letter-spacing: 0.5px;
  }

  .campo__entrada--erro,
  .campo__entrada--erro:focus {
    border-color: var(--perigo-fg);
    box-shadow: 0 0 0 3px rgba(200, 70, 70, 0.24);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--perigo-fg) 20%, transparent);
  }

  .campo__erro {
    display: block;
    margin-top: var(--esp-2);
    font-size: var(--texto-sm);
    color: var(--perigo-fg);
  }

  .campo__dica {
    display: block;
    margin-top: var(--esp-2);

    /* Um degrau abaixo do rótulo. A dica explica; o rótulo identifica.
       Do mesmo tamanho, as duas disputavam a mesma atenção. */
    font-size: var(--texto-xs);
    color: var(--texto-2);
    line-height: 1.5;
  }

  /* Campo com botão dentro (mostrar senha, copiar) */
  /* ─────────────────────────────────────────────
     CAMPO COM BOTÃO DENTRO
     ─────────────────────────────────────────────

     A versão anterior posicionava os botões em ABSOLUTO por cima do
     input, e reservava espaço para UM. O campo de senha tem dois
     (gerar e mostrar) — e o texto digitado passava por baixo deles.

     Agora o invólucro é que tem a borda; o input dentro é
     transparente e sem borda. Assim cabem quantos botões precisar,
     sem ninguém calcular padding. */

  .campo__grupo {
    display: flex;
    align-items: center;

    background: var(--sup-1);
    border: 1px solid var(--borda-forte);
    border-radius: var(--raio-md);

    transition: border-color var(--dur-rapida) var(--ease-saida),
                box-shadow var(--dur-rapida) var(--ease-saida);
  }

  @media (hover: hover) {
    .campo__grupo:hover { border-color: var(--texto-3); }
  }

  /* `:focus-within` no invólucro: o anel aparece quando o INPUT recebe
     foco, e não quando o conjunto é clicado. É o que faz a borda
     inteira reagir junto com o cursor. */
  .campo__grupo:focus-within {
    border-color: var(--foco);
    box-shadow: 0 0 0 3px rgba(90, 140, 210, 0.28);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--foco) 22%, transparent);
  }

  .campo__grupo .campo__entrada,
  .campo__grupo .campo__entrada:focus,
  .campo__grupo .campo__entrada:hover {
    flex: 1;
    min-width: 0;

    background: transparent;
    border: none;
    box-shadow: none;
    outline: none;
  }

  .campo__grupo .btn--icone {
    flex-shrink: 0;
    /* Um pouco menor que o alvo padrão: dois botões de 44px comeriam
       88px da largura do campo, e num celular estreito sobraria menos
       espaço para o texto que para os controles. */
    min-width: 38px;
    min-height: 38px;
    margin-right: 3px;
  }

  /* ============================================================
     MEDIDOR DE FORÇA
     ============================================================
     Quatro segmentos em vez de barra contínua: barra que enche dá a
     impressão de que existe um alvo a atingir, e a pessoa para no
     primeiro verde. Segmentos comunicam degrau. */

  .medidor { margin-top: var(--esp-3); }

  .medidor__barras {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--esp-1);
  }

  .medidor__barra {
    height: 4px;
    border-radius: var(--raio-cheio);
    background: var(--sup-2);
    transition: background-color var(--dur-media) var(--ease-saida);
  }

  .medidor[data-nivel="fraca"]    .medidor__barra:nth-child(-n+1),
  .medidor[data-nivel="razoavel"] .medidor__barra:nth-child(-n+2),
  .medidor[data-nivel="boa"]      .medidor__barra:nth-child(-n+3),
  .medidor[data-nivel="forte"]    .medidor__barra {
    background: var(--medidor-cor, var(--texto-2));
  }

  .medidor[data-nivel="fraca"]    { --medidor-cor: var(--perigo-fg); }
  .medidor[data-nivel="razoavel"] { --medidor-cor: var(--alerta-fg); }
  .medidor[data-nivel="boa"]      { --medidor-cor: var(--tinta-azul-fg); }
  .medidor[data-nivel="forte"]    { --medidor-cor: var(--ok-fg); }

  .medidor__texto {
    display: flex;
    justify-content: space-between;
    gap: var(--esp-3);
    margin-top: var(--esp-2);
    font-size: var(--texto-sm);
    color: var(--texto-2);
  }

  .medidor__nivel { font-weight: var(--peso-medio); color: var(--medidor-cor); }

  /* A dica fica à direita e trunca em vez de quebrar linha: texto de
     duas linhas ali empurraria os campos abaixo a cada tecla digitada,
     e o formulário pularia debaixo do dedo. */
  .medidor__dica {
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
  }

  /* Em tela estreita a dica sai: o nível já comunica o essencial e
     duas frases lado a lado em 320px ficam ilegíveis. */
  @media (max-width: 380px) {
    .medidor__dica { display: none; }
  }

  /* ============================================================
     CARD DE CREDENCIAL
     ============================================================ */

  .lista-cards {
    display: grid;
    gap: var(--esp-3);
    grid-template-columns: 1fr;
  }

  @media (min-width: 640px) {
    .lista-cards { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
  }

  .card {
    display: block;
    width: 100%;
    text-align: left;

    padding: var(--esp-4);
    background: var(--sup-1);
    border: var(--borda-card);
    border-radius: var(--raio-lg);

    /* container-type habilita container queries: o card se adapta à
       COLUNA em que está, não à janela. Sem isso, um card numa coluna
       estreita de desktop largo usaria o layout de desktop e
       quebraria. */
    container-type: inline-size;

    transition: background-color var(--dur-rapida) var(--ease-saida),
                transform var(--dur-rapida) var(--ease-saida);
  }

  @media (hover: hover) {
    .card:hover { background: var(--sup-3); }
  }

  .card:active { transform: scale(0.99); }

  .card--largo { grid-column: 1 / -1; }

  .card__topo { display: flex; align-items: flex-start; gap: var(--esp-3); }

  /* Quadrado de tinta com o ícone. É o que dá cor à interface sem
     pintar o card inteiro. */
  .card__icone {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    width: 40px;
    height: 40px;
    border-radius: 11px;

    font-size: 1.25rem;

    background: var(--tinta-cinza-bg);
    color: var(--tinta-cinza-fg);
  }

  .card__texto { min-width: 0; flex: 1; }

  .card__titulo {
    font-size: var(--texto-md);
    font-weight: var(--peso-medio);
    color: var(--texto);

    /* Título de card cifrado pode ser qualquer coisa. Sem isto, um
       título longo empurra o botão de copiar fora da tela. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .card__meta {
    margin-top: 1px;
    font-size: var(--texto-sm);
    color: var(--texto-2);

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .card__meta--alerta { color: var(--alerta-fg); }

  .card__rodape {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--esp-3);

    margin-top: var(--esp-4);
    padding-top: var(--esp-3);
    border-top: 0.5px solid var(--borda);
  }

  .card__acoes { display: flex; gap: var(--esp-1); }

  /* Etiquetas de contagem (3 campos, 1 foto) */
  .etiqueta {
    display: inline-flex;
    align-items: center;
    gap: var(--esp-1);

    padding: 5px var(--esp-3);

    font-size: var(--texto-xs);
    color: var(--texto-2);

    background: var(--sup-2);
    border-radius: var(--raio-sm);
    white-space: nowrap;
  }

  /* Em card estreito as etiquetas somem: o espaço é do título. */
  @container (max-width: 320px) {
    .card__etiquetas { display: none; }
  }

  /* Tintas por categoria, aplicadas ao ícone */
  .tinta-azul     { background: var(--tinta-azul-bg); color: var(--tinta-azul-fg); }
  .tinta-verde    { background: var(--tinta-verde-bg); color: var(--tinta-verde-fg); }
  .tinta-ambar    { background: var(--tinta-ambar-bg); color: var(--tinta-ambar-fg); }
  .tinta-vermelho { background: var(--tinta-vermelho-bg); color: var(--tinta-vermelho-fg); }
  .tinta-violeta  { background: var(--tinta-violeta-bg); color: var(--tinta-violeta-fg); }
  .tinta-rosa     { background: var(--tinta-rosa-bg); color: var(--tinta-rosa-fg); }
  .tinta-coral    { background: var(--tinta-coral-bg); color: var(--tinta-coral-fg); }
  .tinta-cinza    { background: var(--tinta-cinza-bg); color: var(--tinta-cinza-fg); }
  .tinta-turquesa { background: var(--tinta-turquesa-bg); color: var(--tinta-turquesa-fg); }
  .tinta-lima     { background: var(--tinta-lima-bg); color: var(--tinta-lima-fg); }
  .tinta-indigo   { background: var(--tinta-indigo-bg); color: var(--tinta-indigo-fg); }
  .tinta-magenta  { background: var(--tinta-magenta-bg); color: var(--tinta-magenta-fg); }
  .tinta-bronze   { background: var(--tinta-bronze-bg); color: var(--tinta-bronze-fg); }
  .tinta-ardosia  { background: var(--tinta-ardosia-bg); color: var(--tinta-ardosia-fg); }

  /* ============================================================
     CORTINA DO COFRE TRANCADO
     ============================================================
     Cobre o app inteiro, mas deixa a estrutura visível por trás.
     É a decisão visual que mais comunica: você vê que existem cards
     e não vê o que são — exatamente o que o servidor vê. */

  .cortina {
    position: absolute;
    inset: 0;
    z-index: var(--z-trancado);

    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--esp-4);

    background: var(--cortina);

    /* Progressive enhancement: onde backdrop-filter não existe, a cor
       semitransparente da cortina já esconde o suficiente. */
    backdrop-filter: blur(14px) saturate(0.8);
    -webkit-backdrop-filter: blur(14px) saturate(0.8);
  }

  .cortina__caixa {
    width: 100%;
    max-width: 380px;

    padding: var(--esp-5);

    background: var(--sup-flutuante);
    border: var(--borda-card);
    border-radius: var(--raio-xl);
    box-shadow: var(--sombra-modal);
  }

  .cortina__icone {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 48px;
    height: 48px;
    margin-bottom: var(--esp-4);

    font-size: 1.5rem;
    border-radius: 13px;

    background: var(--tinta-azul-bg);
    color: var(--tinta-azul-fg);
  }

  .cortina__titulo { margin-bottom: var(--esp-1); }

  .cortina__apoio {
    margin-bottom: var(--esp-5);
    font-size: var(--texto-sm);
    color: var(--texto-2);
    line-height: 1.5;
  }

  /* ============================================================
     PROGRESSO DA DERIVAÇÃO
     ============================================================
     O Argon2 leva de 0,3 a 2 segundos. Sem indicação, a pessoa aperta
     o botão de novo achando que não funcionou — e a segunda derivação
     concorre com a primeira. */

  .derivando {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
    padding: var(--esp-3) 0;
    font-size: var(--texto-sm);
    color: var(--texto-2);
  }

  .girando {
    width: 16px;
    height: 16px;
    flex-shrink: 0;

    border: 2px solid var(--borda-forte);
    border-top-color: var(--tinta-azul-fg);
    border-radius: 50%;

    animation: girar 640ms linear infinite;
  }

  @keyframes girar { to { transform: rotate(360deg); } }

  @media (prefers-reduced-motion: reduce) {
    .girando { animation-duration: 2s; }
  }

  /* ============================================================
     BOTTOM SHEET / MODAL
     ============================================================
     O MESMO componente. No mobile sobe de baixo; em 768px vira modal
     centralizado. Uma árvore de DOM só — duas viveriam e uma
     envelheceria. */

  .sheet-fundo {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);

    display: flex;
    align-items: flex-end;
    justify-content: center;

    background: rgba(0, 0, 0, 0.4);
    animation: aparecer var(--dur-media) var(--ease-saida);
  }

  .sheet {
    width: 100%;
    max-height: 92dvh;
    overflow-y: auto;

    background: var(--sup-flutuante);
    border-radius: var(--raio-xl) var(--raio-xl) 0 0;
    box-shadow: var(--sombra-sheet);

    padding: var(--esp-4)
             max(var(--esp-4), env(safe-area-inset-right))
             max(var(--esp-5), env(safe-area-inset-bottom))
             max(var(--esp-4), env(safe-area-inset-left));

    animation: subir var(--dur-lenta) var(--ease-saida);

    /* Impede que a rolagem interna arraste a página atrás. */
    overscroll-behavior: contain;
  }

  /* Alça: sinaliza que arrasta, e é o alvo do gesto de fechar. */
  .sheet__alca {
    width: 36px;
    height: 4px;
    margin: 0 auto var(--esp-4);
    border-radius: var(--raio-cheio);
    background: var(--borda-forte);
  }

  @media (min-width: 768px) {
    .sheet-fundo { align-items: center; }

    .sheet {
      max-width: 520px;
      max-height: 86dvh;
      border-radius: var(--raio-xl);
      padding: var(--esp-5);
      box-shadow: var(--sombra-modal);
      animation: aparecer var(--dur-media) var(--ease-saida);
    }

    .sheet__alca { display: none; }
  }

  @keyframes aparecer { from { opacity: 0; } }
  @keyframes subir { from { transform: translateY(100%); } }

  @media (prefers-reduced-motion: reduce) {
    .sheet-fundo, .sheet { animation: none; }
  }

  /* ============================================================
     AVISO EM LINHA
     ============================================================ */

  .aviso {
    display: flex;
    gap: var(--esp-3);
    padding: var(--esp-3) var(--esp-4);
    margin-bottom: var(--esp-4);

    font-size: var(--texto-sm);
    line-height: 1.45;

    border-radius: var(--raio-md);
  }

  .aviso__icone { flex-shrink: 0; font-size: 1.0625rem; margin-top: 1px; }

  .aviso--alerta { background: var(--alerta-bg); color: var(--alerta-fg); }
  .aviso--perigo { background: var(--perigo-bg); color: var(--perigo-fg); }
  .aviso--ok     { background: var(--ok-bg);     color: var(--ok-fg); }
  .aviso--info   { background: var(--sup-2);     color: var(--texto-2); }

  /* ============================================================
     CÓDIGO DO RECOVERY KIT
     ============================================================
     Oito grupos de cinco. Vai ser impresso e digitado por alguém em
     pânico, meses depois — então grande, mono e bem espaçado. */

  .recovery {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--esp-2);

    padding: var(--esp-4);
    margin: var(--esp-4) 0;

    background: var(--sup-2);
    border-radius: var(--raio-md);
  }

  @media (min-width: 480px) {
    .recovery { grid-template-columns: repeat(4, 1fr); }
  }

  .recovery__grupo {
    font-family: var(--fonte-mono);
    font-size: 1rem;
    letter-spacing: 1px;
    text-align: center;
    color: var(--texto);
    user-select: all;
  }

  /* ============================================================
     ESTADO VAZIO
     ============================================================ */

  .vazio {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;

    padding: var(--esp-7) var(--esp-4);
    color: var(--texto-2);
  }

  .vazio__icone {
    font-size: 2rem;
    color: var(--texto-3);
    margin-bottom: var(--esp-3);
  }

  .vazio__titulo {
    font-size: var(--texto-md);
    font-weight: var(--peso-medio);
    color: var(--texto);
    margin-bottom: var(--esp-1);
  }

  /* ============================================================
     BARRA INFERIOR (mobile)
     ============================================================ */

  .barra__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;

    flex: 1;
    min-height: 52px;
    padding: var(--esp-2) 0;

    font-size: var(--texto-xs);
    color: var(--texto-2);
  }

  .barra__item i { font-size: 1.375rem; }

  .barra__item[aria-current="page"] { color: var(--tinta-azul-fg); }
}

/* ============================================================
   F2 — NAVEGAÇÃO E LISTAGEM
   ============================================================ */

@layer componentes {

  /* ─────────────────────────────────────────────
     ÁRVORE DE CATEGORIAS
     ─────────────────────────────────────────────
     Na lateral no desktop, dentro de um drawer no mobile. O MESMO
     componente — o drawer só muda onde a árvore mora. */

  .arvore { display: flex; flex-direction: column; gap: 2px; }

  .arvore__item {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    width: 100%;

    min-height: var(--alvo);
    padding: 0 var(--esp-2);

    font-size: var(--texto-sm);
    color: var(--texto-2);
    text-align: left;

    border-radius: var(--raio-sm);
    transition: background-color var(--dur-rapida) var(--ease-saida);
  }

  @media (hover: hover) {
    .arvore__item:hover { background: var(--sup-2); color: var(--texto); }
  }

  .arvore__item[aria-current="true"] {
    background: var(--sup-2);
    color: var(--texto);
    font-weight: var(--peso-medio);
  }

  /* Recuo por nível. Vem de data-nivel e não de margem calculada em
     JS: assim o CSS controla o espaçamento e o JS só informa o nível. */
  .arvore__item[data-nivel="1"] { padding-left: var(--esp-5); }
  .arvore__item[data-nivel="2"] { padding-left: var(--esp-6); }

  .arvore__ponto {
    width: 7px;
    height: 7px;
    flex-shrink: 0;
    border-radius: 50%;
    background: currentColor;
  }

  .arvore__nome {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .arvore__contagem {
    flex-shrink: 0;
    font-size: var(--texto-xs);
    color: var(--texto-3);
    font-variant-numeric: tabular-nums;
  }

  /* Seta de expandir. Botão separado do item para que tocar no nome
     navegue e tocar na seta apenas abra — no celular, um alvo que faz
     duas coisas dependendo de onde você toca erra sempre. */
  .arvore__seta {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    width: 24px;
    height: 24px;
    margin-left: calc(var(--esp-2) * -1);

    color: var(--texto-3);
    border-radius: var(--raio-sm);
    transition: transform var(--dur-rapida) var(--ease-saida);
  }

  .arvore__seta[aria-expanded="true"] { transform: rotate(90deg); }

  .arvore__grupo[hidden] { display: none; }

  /* ─────────────────────────────────────────────
     DRAWER (mobile)
     ───────────────────────────────────────────── */

  .drawer-fundo {
    position: fixed;
    inset: 0;
    z-index: var(--z-drawer);
    display: flex;
    background: rgba(0, 0, 0, 0.4);
    animation: aparecer var(--dur-media) var(--ease-saida);
  }

  .drawer {
    display: flex;
    flex-direction: column;

    width: min(84vw, 320px);
    height: 100dvh;
    overflow-y: auto;
    overscroll-behavior: contain;

    background: var(--sup-flutuante);
    box-shadow: var(--sombra-modal);

    padding: max(var(--esp-4), env(safe-area-inset-top))
             var(--esp-3)
             max(var(--esp-4), env(safe-area-inset-bottom))
             max(var(--esp-3), env(safe-area-inset-left));

    animation: entrar-esq var(--dur-lenta) var(--ease-saida);
  }

  @keyframes entrar-esq { from { transform: translateX(-100%); } }

  @media (prefers-reduced-motion: reduce) {
    .drawer-fundo, .drawer { animation: none; }
  }

  @media (min-width: 768px) {
    /* A árvore mora na lateral fixa; o drawer não existe. */
    .drawer-fundo { display: none; }
  }

  /* ─────────────────────────────────────────────
     BUSCA
     ───────────────────────────────────────────── */

  .busca { position: relative; margin-bottom: var(--esp-4); }

  /* A busca é o campo mais usado do app — e era o único que tinha
     ficado com o contorno de foco fino, de quando todos eram assim.
     Herda de `.campo__entrada`; aqui só o que é dela: o espaço para a
     lupa e para o botão de limpar. */
  .busca__entrada {
    padding-left: calc(var(--esp-4) + 20px);
    padding-right: var(--alvo);
  }

  .busca__lupa {
    position: absolute;
    left: var(--esp-3);
    top: 50%;
    transform: translateY(-50%);
    font-size: 1.125rem;
    color: var(--texto-3);
    pointer-events: none;
  }

  .busca__limpar {
    position: absolute;
    right: 0;
    top: 0;
    height: 100%;
  }

  /* Explicação da busca cega. Aparece só quando há termo, porque é
     informação que só interessa em contexto. */
  .busca__nota {
    margin-top: var(--esp-2);
    font-size: var(--texto-xs);
    color: var(--texto-3);
    line-height: 1.45;
  }

  /* ─────────────────────────────────────────────
     CABEÇALHO DA LISTA
     ───────────────────────────────────────────── */

  .lista__topo {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--esp-3);
    margin-bottom: var(--esp-4);
  }

  .lista__titulo { min-width: 0; }

  .lista__nome {
    font-size: var(--texto-lg);
    font-weight: var(--peso-medio);
    letter-spacing: -0.2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .lista__contagem { font-size: var(--texto-sm); color: var(--texto-2); }

  /* Filtro por tag: rola na horizontal no mobile em vez de quebrar em
     três linhas e empurrar os cards para baixo da tela. */
  .tags-fila {
    display: flex;
    gap: var(--esp-2);
    margin-bottom: var(--esp-4);
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
  }

  .tags-fila::-webkit-scrollbar { display: none; }

  .tag-pilula {
    display: inline-flex;
    align-items: center;
    gap: var(--esp-1);
    flex-shrink: 0;

    min-height: 34px;
    padding: 0 var(--esp-3);

    font-size: var(--texto-sm);
    color: var(--texto-2);

    background: var(--sup-2);
    border-radius: var(--raio-cheio);
    white-space: nowrap;
  }

  .tag-pilula[aria-pressed="true"] {
    background: var(--tinta-azul-bg);
    color: var(--tinta-azul-fg);
    font-weight: var(--peso-medio);
  }

  /* ─────────────────────────────────────────────
     CARREGANDO
     ─────────────────────────────────────────────
     Blocos neutros, sem animação de brilho. O brilho de skeleton dá a
     impressão de conteúdo chegando — aqui o conteúdo já chegou, está
     sendo DECIFRADO, e isso é rápido. Movimento a mais só polui. */

  .esqueleto {
    background: var(--sup-2);
    border-radius: var(--raio-sm);
    height: 12px;
  }

  .esqueleto--titulo { width: 55%; height: 15px; margin-bottom: 6px; }
  .esqueleto--meta { width: 78%; }
}

/* ============================================================
   F3 — DETALHE DO CARD
   ============================================================ */

@layer componentes {

  .detalhe__topo {
    display: flex;
    align-items: flex-start;
    gap: var(--esp-3);
    margin-bottom: var(--esp-5);
  }

  .detalhe__titulo {
    font-size: var(--texto-lg);
    font-weight: var(--peso-medio);
    letter-spacing: -0.2px;
    overflow-wrap: anywhere;
  }

  .detalhe__meta {
    margin-top: 2px;
    font-size: var(--texto-sm);
    color: var(--texto-2);
  }

  /* ─────────────────────────────────────────────
     CAMPO DO CARD
     ───────────────────────────────────────────── */

  .linha {
    padding: var(--esp-3) 0;
    border-bottom: 0.5px solid var(--borda);
  }

  .linha:last-of-type { border-bottom: none; }

  .linha__rotulo {
    font-size: var(--texto-xs);
    color: var(--texto-2);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    margin-bottom: var(--esp-1);
  }

  .linha__corpo {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    min-height: var(--alvo);
  }

  .linha__valor {
    flex: 1;
    min-width: 0;
    font-size: var(--texto-md);
    overflow-wrap: anywhere;
  }

  /* Valor sensível ainda não revelado. Os pontinhos não representam o
     comprimento real da senha — mostrar isso entregaria informação a
     quem olhasse a tela por cima do ombro. São sempre 10. */
  .linha__oculto {
    font-family: var(--fonte-mono);
    font-size: 1rem;
    letter-spacing: 3px;
    color: var(--texto-3);
    user-select: none;
  }

  .linha__acoes { display: flex; gap: var(--esp-1); flex-shrink: 0; }

  /* Contagem regressiva do TOTP */
  .totp {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
  }

  .totp__codigo {
    font-family: var(--fonte-mono);
    font-size: 1.375rem;
    letter-spacing: 3px;
    color: var(--texto);
    user-select: all;
  }

  .totp__anel {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 50%;
    background: conic-gradient(var(--tinta-azul-fg) var(--totp-volta, 0deg), var(--sup-2) 0);
  }

  /* Nos últimos 5 segundos vira laranja: você percebe que não vale a
     pena colar esse código no formulário agora. */
  .totp--acabando .totp__anel {
    background: conic-gradient(var(--alerta-fg) var(--totp-volta, 0deg), var(--sup-2) 0);
  }

  .totp--acabando .totp__codigo { color: var(--alerta-fg); }

  /* ─────────────────────────────────────────────
     NOTAS
     ───────────────────────────────────────────── */

  .nota {
    padding: var(--esp-3);
    margin-bottom: var(--esp-2);
    background: var(--sup-2);
    border-radius: var(--raio-md);
  }

  .nota__texto {
    font-size: var(--texto-sm);
    line-height: 1.55;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }

  .nota__rodape {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--esp-3);
    margin-top: var(--esp-2);
    font-size: var(--texto-xs);
    color: var(--texto-3);
  }

  /* `.nota__nova` herda de `.campo__entrada`.
   *
   * Ela tinha a própria definição de borda, foco e fundo — e quando o
   * campo padrão ganhou o anel de foco de 3px, a caixa de nota ficou
   * com o contorno fino antigo. Dois textareas na mesma tela com
   * aparências diferentes.
   *
   * Agora ela só ajusta o que é dela: a altura. */
  .nota__nova {
    min-height: 84px;
  }

  /* ─────────────────────────────────────────────
     SEÇÃO
     ───────────────────────────────────────────── */

  .secao { margin-top: var(--esp-5); }

  .secao__cabecalho {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--esp-3);
    margin-bottom: var(--esp-2);
  }

  .secao__nome {
    font-size: var(--texto-xs);
    font-weight: var(--peso-medio);
    color: var(--texto-2);
    text-transform: uppercase;
    letter-spacing: 0.4px;
  }

  /* ─────────────────────────────────────────────
     TORRADA
     ─────────────────────────────────────────────
     Confirmação de "copiado". Fica acima da barra inferior no mobile,
     senão o polegar cobre justamente a mensagem que confirma a ação. */

  .torrada {
    position: fixed;
    left: 50%;
    bottom: calc(72px + env(safe-area-inset-bottom));
    transform: translateX(-50%);
    z-index: var(--z-aviso);

    display: flex;
    align-items: center;
    gap: var(--esp-2);

    max-width: calc(100vw - var(--esp-6));
    padding: var(--esp-3) var(--esp-4);

    font-size: var(--texto-sm);
    color: var(--texto);

    background: var(--sup-flutuante);
    border: var(--borda-card);
    border-radius: var(--raio-cheio);
    box-shadow: var(--sombra-modal);

    animation: torrada-entra var(--dur-media) var(--ease-saida);
  }

  @keyframes torrada-entra {
    from { opacity: 0; transform: translate(-50%, 12px); }
  }

  @media (min-width: 768px) {
    .torrada { bottom: var(--esp-5); }
  }

  @media (prefers-reduced-motion: reduce) {
    .torrada { animation: none; }
  }
}

/* ============================================================
   F5 — MÍDIA
   ============================================================ */

@layer componentes {

  .galeria {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: var(--esp-2);
  }

  .anexo {
    position: relative;
    aspect-ratio: 1;
    overflow: hidden;

    background: var(--sup-2);
    border-radius: var(--raio-md);
  }

  .anexo__thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* Sem miniatura: ícone pelo tipo. Documento e vídeo não têm thumb
     no cofre — gerar exigiria o servidor abrir o arquivo. */
  .anexo__icone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--esp-1);

    width: 100%;
    height: 100%;

    font-size: 1.5rem;
    color: var(--texto-2);
  }

  .anexo__ext {
    font-size: var(--texto-xs);
    text-transform: uppercase;
    letter-spacing: 0.5px;
  }

  .anexo__tamanho {
    position: absolute;
    right: 4px;
    bottom: 4px;

    padding: 2px 6px;

    font-size: 10px;
    color: #fff;
    background: rgba(0, 0, 0, 0.6);
    border-radius: var(--raio-sm);
  }

  /* Progresso do upload em pedaços */
  .envio {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
    padding: var(--esp-3);
    margin-bottom: var(--esp-2);

    background: var(--sup-2);
    border-radius: var(--raio-md);
  }

  .envio__texto { flex: 1; min-width: 0; font-size: var(--texto-sm); }

  .envio__nome {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .envio__barra {
    height: 4px;
    margin-top: var(--esp-2);
    background: var(--sup-3);
    border-radius: var(--raio-cheio);
    overflow: hidden;
  }

  .envio__preenchida {
    height: 100%;
    width: 0;
    background: var(--tinta-azul-fg);
    border-radius: var(--raio-cheio);
    transition: width var(--dur-media) var(--ease-saida);
  }

  /* Área de soltar arquivo. No mobile vira só um botão — arrastar
     não existe lá, e uma área tracejada vazia só ocupa espaço. */
  .soltar {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--esp-2);

    padding: var(--esp-5) var(--esp-4);

    color: var(--texto-2);
    font-size: var(--texto-sm);
    text-align: center;

    border: 1px dashed var(--borda-forte);
    border-radius: var(--raio-md);
  }

  .soltar--ativo {
    border-color: var(--tinta-azul-fg);
    background: var(--tinta-azul-bg);
    color: var(--tinta-azul-fg);
  }

  /* ============================================================
     F6 — METADADOS
     ============================================================ */

  .laudo__resumo {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: var(--esp-2);
    margin-bottom: var(--esp-4);
  }

  .laudo__caixa {
    padding: var(--esp-3);
    background: var(--sup-2);
    border-radius: var(--raio-md);
  }

  .laudo__numero {
    font-size: 1.375rem;
    font-weight: var(--peso-medio);
    font-variant-numeric: tabular-nums;
  }

  .laudo__legenda { font-size: var(--texto-xs); color: var(--texto-2); }

  /* O thumbnail embutido lado a lado com a imagem enviada. É a
     comparação que revela o corte: se as duas diferem, o arquivo
     carrega a versão original de uma foto que você achava recortada. */
  .comparar {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--esp-2);
    margin: var(--esp-3) 0;
  }

  .comparar__item { text-align: center; }

  .comparar__img {
    width: 100%;
    border-radius: var(--raio-md);
    background: var(--sup-2);
  }

  .comparar__rotulo {
    margin-top: var(--esp-1);
    font-size: var(--texto-xs);
    color: var(--texto-2);
  }

  /* Grupos de tags do exiftool, colapsáveis */
  .grupo { margin-bottom: var(--esp-2); }

  .grupo__cabecalho {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    width: 100%;

    min-height: var(--alvo);
    padding: 0 var(--esp-3);

    font-size: var(--texto-sm);
    font-weight: var(--peso-medio);
    text-align: left;

    background: var(--sup-2);
    border-radius: var(--raio-md);
  }

  .grupo__contagem {
    margin-left: auto;
    font-size: var(--texto-xs);
    color: var(--texto-3);
    font-variant-numeric: tabular-nums;
  }

  .grupo__corpo { padding: var(--esp-2) var(--esp-3); }

  .grupo__corpo[hidden] { display: none; }

  .tag-linha {
    display: flex;
    gap: var(--esp-3);
    padding: var(--esp-2) 0;
    font-size: var(--texto-sm);
    border-bottom: 0.5px solid var(--borda);
  }

  .tag-linha:last-child { border-bottom: none; }

  .tag-linha__nome {
    flex: 0 0 40%;
    color: var(--texto-2);
    overflow-wrap: anywhere;
  }

  .tag-linha__valor {
    flex: 1;
    min-width: 0;
    font-family: var(--fonte-mono);
    font-size: var(--texto-xs);
    overflow-wrap: anywhere;
  }
}

/* ============================================================
   F7 — SEGURANÇA
   ============================================================ */

@layer componentes {

  /* Indicador de saúde do canal de alerta. É o número mais
     importante do painel: se os alertas não saem, a contingência
     detecta tudo e não avisa ninguém. */
  .saude {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
    padding: var(--esp-4);
    margin-bottom: var(--esp-4);
    border-radius: var(--raio-lg);
  }

  .saude--ok { background: var(--ok-bg); color: var(--ok-fg); }
  .saude--ruim { background: var(--perigo-bg); color: var(--perigo-fg); }

  .saude__icone { font-size: 1.5rem; flex-shrink: 0; }
  .saude__texto { flex: 1; min-width: 0; font-size: var(--texto-sm); line-height: 1.45; }

  /* Linha de dispositivo ou sessão */
  .item {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
    padding: var(--esp-3);
    margin-bottom: var(--esp-2);

    background: var(--sup-1);
    border: var(--borda-card);
    border-radius: var(--raio-md);
  }

  .item__icone {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    width: 36px;
    height: 36px;
    border-radius: 10px;

    background: var(--tinta-cinza-bg);
    color: var(--tinta-cinza-fg);
  }

  .item__corpo { flex: 1; min-width: 0; }

  .item__nome {
    font-size: var(--texto-md);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .item__meta {
    font-size: var(--texto-sm);
    color: var(--texto-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .item--revogado { opacity: 0.5; }

  /* Selo "este aparelho". Sem ele a lista vira uma sequência de
     navegadores parecidos e você revoga o próprio acesso. */
  .selo {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--esp-2);

    font-size: 10px;
    font-weight: var(--peso-medio);
    text-transform: uppercase;
    letter-spacing: 0.4px;

    background: var(--ok-bg);
    color: var(--ok-fg);
    border-radius: var(--raio-sm);
  }

  /* Trilha de eventos */
  .evento {
    display: flex;
    gap: var(--esp-3);
    padding: var(--esp-3) 0;
    border-bottom: 0.5px solid var(--borda);
  }

  .evento:last-child { border-bottom: none; }

  .evento__marca {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    margin-top: 6px;
    border-radius: 50%;
  }

  .evento__marca--info { background: var(--texto-3); }
  .evento__marca--atencao { background: var(--alerta-fg); }
  .evento__marca--alerta { background: var(--tinta-coral-fg); }
  .evento__marca--critico { background: var(--perigo-fg); }

  .evento__corpo { flex: 1; min-width: 0; }
  .evento__texto { font-size: var(--texto-sm); line-height: 1.45; }

  .evento__meta {
    margin-top: 2px;
    font-size: var(--texto-xs);
    color: var(--texto-3);
  }

  /* ============================================================
     F8 — PAINEL
     ============================================================ */

  .indicadores {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: var(--esp-3);
    margin-bottom: var(--esp-5);
  }

  .indicador {
    padding: var(--esp-4);
    background: var(--sup-1);
    border: var(--borda-card);
    border-radius: var(--raio-lg);
  }

  .indicador__topo {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    margin-bottom: var(--esp-2);
    font-size: var(--texto-sm);
    color: var(--texto-2);
  }

  .indicador__numero {
    font-size: 1.75rem;
    font-weight: var(--peso-medio);
    letter-spacing: -0.5px;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
  }

  .indicador__nota { margin-top: 2px; font-size: var(--texto-xs); color: var(--texto-3); }
  .indicador--alerta .indicador__numero { color: var(--alerta-fg); }
  .indicador--perigo .indicador__numero { color: var(--perigo-fg); }

  /* Atalhos de teclado */
  .atalhos { display: grid; gap: var(--esp-2); }

  .atalho {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--esp-3);
    font-size: var(--texto-sm);
  }

  kbd {
    display: inline-block;
    min-width: 22px;
    padding: 2px 6px;

    font-family: var(--fonte-mono);
    font-size: var(--texto-xs);
    text-align: center;

    background: var(--sup-2);
    border: 1px solid var(--borda);
    border-radius: var(--raio-sm);
  }
}

/* ============================================================
   PREVIEW DE ANEXO E CATEGORIAS
   ============================================================ */

@layer componentes {

  /* ─────────────────────────────────────────────
     VISOR DE IMAGEM
     ─────────────────────────────────────────────
     Fundo escuro fixo nos dois temas: a imagem é o conteúdo, e um
     fundo claro em volta de uma foto muda como você percebe as cores
     dela — ruim quando o que você está conferindo é um documento. */

  .visor {
    position: fixed;
    inset: 0;
    z-index: var(--z-aviso);

    display: flex;
    flex-direction: column;

    background: #0b0b0d;
    animation: aparecer var(--dur-media) var(--ease-saida);
  }

  .visor__topo {
    display: flex;
    align-items: center;
    gap: var(--esp-3);

    padding: max(var(--esp-3), env(safe-area-inset-top))
             var(--esp-4) var(--esp-3);

    color: #f2f3f5;
    background: rgba(0, 0, 0, 0.4);
  }

  .visor__nome {
    flex: 1;
    min-width: 0;
    font-size: var(--texto-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .visor__botao {
    display: flex;
    align-items: center;
    justify-content: center;

    min-width: var(--alvo);
    min-height: var(--alvo);

    font-size: 1.125rem;
    color: #f2f3f5;
    border-radius: var(--raio-md);
  }

  .visor__botao:active { background: rgba(255, 255, 255, 0.12); }

  .visor__palco {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--esp-3);
    overflow: auto;
  }

  .visor__img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--raio-sm);
  }

  .visor__pdf {
    width: 100%;
    height: 100%;
    border: none;
    border-radius: var(--raio-sm);
    background: #fff;
  }

  .visor__rodape {
    padding: var(--esp-3) var(--esp-4)
             max(var(--esp-3), env(safe-area-inset-bottom));

    font-size: var(--texto-xs);
    color: rgba(255, 255, 255, 0.6);
    text-align: center;
    background: rgba(0, 0, 0, 0.4);
  }

  /* ─────────────────────────────────────────────
     GERENCIAR CATEGORIAS E TAGS
     ───────────────────────────────────────────── */

  .gerenciar__linha {
    display: flex;
    align-items: center;
    gap: var(--esp-3);

    padding: var(--esp-2) var(--esp-3);
    margin-bottom: var(--esp-1);

    background: var(--sup-1);
    border: var(--borda-card);
    border-radius: var(--raio-md);
  }

  .gerenciar__linha[data-nivel="1"] { margin-left: var(--esp-5); }
  .gerenciar__linha[data-nivel="2"] { margin-left: var(--esp-6); }

  .gerenciar__nome {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Escolha de cor */
  .cores {
    display: flex;
    flex-wrap: wrap;
    gap: var(--esp-2);
  }

  .cor-opcao {
    width: 34px;
    height: 34px;
    border-radius: var(--raio-md);
    border: 2px solid transparent;
  }

  .cor-opcao[aria-pressed="true"] {
    border-color: var(--texto);
  }

  /* Escolha de ícone */
  .icones {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
    gap: var(--esp-2);
  }

  .icone-opcao {
    display: flex;
    align-items: center;
    justify-content: center;

    aspect-ratio: 1;
    font-size: 1.125rem;
    color: var(--texto-2);

    background: var(--sup-2);
    border: 2px solid transparent;
    border-radius: var(--raio-md);
  }

  .icone-opcao[aria-pressed="true"] {
    border-color: var(--tinta-azul-fg);
    color: var(--tinta-azul-fg);
    background: var(--tinta-azul-bg);
  }
}

/* ============================================================
   NAVEGAÇÃO DA LATERAL E SELETOR DE TEMA
   ============================================================ */

@layer componentes {

  /* A lateral do desktop passou a ter três partes: destinos, árvore de
     categorias e rodapé. Antes tinha só a árvore — e como a barra
     inferior é escondida em ≥768px, Metadados e Segurança ficavam
     inalcançáveis no computador. */

  .lateral__secao { margin-bottom: var(--esp-4); }

  .lateral__rotulo {
    padding: 0 var(--esp-2) var(--esp-2);
    font-size: var(--texto-xs);
    font-weight: var(--peso-medio);
    color: var(--texto-3);
    text-transform: uppercase;
    letter-spacing: 0.5px;
  }

  .lateral__rodape {
    margin-top: auto;
    padding-top: var(--esp-3);
    border-top: 1px solid var(--borda);
  }

  .nav-item {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
    width: 100%;

    min-height: 40px;
    padding: 0 var(--esp-3);

    font-size: var(--texto-sm);
    color: var(--texto-2);
    text-align: left;

    border-radius: var(--raio-md);
    transition: background-color var(--dur-rapida) var(--ease-saida),
                color var(--dur-rapida) var(--ease-saida);
  }

  .nav-item i { font-size: 1.125rem; flex-shrink: 0; }

  .nav-item__texto {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  @media (hover: hover) {
    .nav-item:hover { background: var(--sup-2); color: var(--texto); }
  }

  .nav-item:active { background: var(--sup-3); }

  .nav-item[aria-current="page"] {
    background: var(--tinta-azul-bg);
    color: var(--tinta-azul-fg);
    font-weight: var(--peso-medio);
  }

  /* Marca de contagem no item de navegação */
  .nav-item__conta {
    flex-shrink: 0;
    padding: 1px var(--esp-2);

    font-size: var(--texto-xs);
    font-variant-numeric: tabular-nums;

    background: var(--sup-2);
    color: var(--texto-2);
    border-radius: var(--raio-cheio);
  }

  /* Marca de pendência: ponto, não número. O que importa é "tem algo",
     e um número aqui competiria com o contador de cards ao lado. */
  .nav-item__ponto {
    flex-shrink: 0;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--perigo-fg);
  }

  /* Identidade no topo da lateral */
  .marca {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
    padding: var(--esp-2) var(--esp-2) var(--esp-4);
  }

  .marca__selo {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 34px;
    height: 34px;
    flex-shrink: 0;

    font-size: 1.125rem;
    border-radius: 10px;

    background: var(--tinta-azul-bg);
    color: var(--tinta-azul-fg);
  }

  .marca__nome {
    font-size: var(--texto-md);
    font-weight: var(--peso-medio);
    letter-spacing: -0.2px;
  }

  .marca__quem {
    font-size: var(--texto-xs);
    color: var(--texto-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ─────────────────────────────────────────────
     SELETOR DE TEMA
     ───────────────────────────────────────────── */

  .temas { display: grid; gap: var(--esp-2); }

  .tema-opcao {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
    width: 100%;

    padding: var(--esp-3);

    text-align: left;

    background: var(--sup-1);
    border: 2px solid var(--borda);
    border-radius: var(--raio-md);
  }

  .tema-opcao[aria-pressed="true"] {
    border-color: var(--tinta-azul-fg);
  }

  .tema-opcao__nome { font-size: var(--texto-md); font-weight: var(--peso-medio); }
  .tema-opcao__nota { font-size: var(--texto-xs); color: var(--texto-2); }

  /* Amostra da paleta. Mostra as cores REAIS do tema em vez de só o
     nome — escolher "Noite" sem ver como é vira tentativa e erro. */
  .amostra {
    display: flex;
    flex-shrink: 0;
    width: 56px;
    height: 38px;
    overflow: hidden;
    border-radius: var(--raio-sm);
    border: 1px solid var(--borda);
  }

  .amostra__faixa { flex: 1; }
}

@layer componentes {

  /* Amostra larga do esquema: cinco tintas lado a lado.
     Mostrar UMA cor não diria nada — o que muda no esquema é a família
     inteira, e é a relação entre elas que você precisa ver. */
  .amostra--larga { width: 74px; }
}

@layer componentes {

  /* Caminho da categoria dentro do card: "Cliente › Subpasta" */
  .caminho {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--esp-1);

    margin-top: 2px;
    font-size: var(--texto-sm);
    color: var(--tinta-azul-fg);
  }

  .caminho__sep { color: var(--texto-3); }

  .caminho__parte {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
  }
}

@layer componentes {

  /* A logo entra como <img> de SVG, não como ícone de fonte: ela tem
     duas cores e o Tabler é monocromático. */
  .marca__logo {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    border-radius: 9px;
  }
}

@layer componentes {

  /* A logo do cabeçalho some no desktop: a lateral já mostra a marca,
     e duas vezes na mesma tela só ocupa espaço. */
  @media (min-width: 768px) {
    .topo__logo { display: none; }
  }
}

@layer componentes {

  /* Faixa de atalhos: favoritos e recentes.
     Rola na horizontal em vez de quebrar em linhas — no topo da tela,
     altura é o recurso caro. */
  .atalhos-fila {
    display: flex;
    gap: var(--esp-2);
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
  }

  .atalhos-fila::-webkit-scrollbar { display: none; }

  .atalho-card {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    flex-shrink: 0;

    max-width: 200px;
    min-height: 44px;
    padding: 0 var(--esp-3) 0 var(--esp-2);

    font-size: var(--texto-sm);
    text-align: left;

    background: var(--sup-1);
    border: var(--borda-card);
    border-radius: var(--raio-cheio);
  }

  @media (hover: hover) {
    .atalho-card:hover { background: var(--sup-2); }
  }

  .atalho-card__icone {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    font-size: 0.875rem;
    border-radius: 8px;
  }

  .atalho-card__nome {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

@layer componentes {

  /* Rótulo de seção com ação à direita */
  .lateral__rotulo--acao {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--esp-2);
    padding-right: 0;
  }

  /* Botão de ícone menor, para caber numa linha de rótulo sem
     empurrar a altura. O alvo de toque continua 32px — abaixo disso
     o dedo erra. */
  .btn--mini {
    min-width: 32px;
    min-height: 32px;
    font-size: 0.9375rem;
  }
}

@layer componentes {

  /* ─────────────────────────────────────────────
     PASSO DE CHECKLIST
     ───────────────────────────────────────────── */

  .passo {
    display: flex;
    align-items: flex-start;
    gap: var(--esp-3);
    width: 100%;

    /* Alvo generoso: marcar item é a ação mais repetida desta tela, e
       uma caixinha de 16px no celular erra o tempo todo. A linha
       inteira é clicável. */
    min-height: var(--alvo);
    padding: var(--esp-3);
    margin-bottom: 2px;

    text-align: left;
    font-size: var(--texto-md);

    background: var(--sup-1);
    border: var(--borda-card);
    border-radius: var(--raio-md);

    transition: background-color var(--dur-rapida) var(--ease-saida);
  }

  .passo i { font-size: 1.25rem; flex-shrink: 0; margin-top: 1px; }

  @media (hover: hover) {
    .passo:hover { background: var(--sup-2); }
  }

  /* Feito fica esmaecido, NÃO riscado.
     Texto riscado é difícil de reler — e reler o que já foi feito é
     exatamente o que se faz ao retomar uma checklist no dia seguinte. */
  .passo--feito {
    background: var(--sup-2);
    color: var(--texto-2);
  }

  .passo--feito i { color: var(--ok-fg); }

  .passo__texto { flex: 1; min-width: 0; }

  .passo__dica {
    margin-top: 2px;
    font-size: var(--texto-xs);
    color: var(--texto-3);
  }
}

@layer componentes {

  /* ─────────────────────────────────────────────
     LIGAÇÃO ENTRE CARDS
     ───────────────────────────────────────────── */

  .ligacao {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    flex-wrap: wrap;

    padding: var(--esp-2) 0;
    border-bottom: 0.5px solid var(--borda);
  }

  .ligacao:last-child { border-bottom: none; }

  /* A seta indica a DIREÇÃO da leitura: saindo daqui ou chegando.
     Sem ela, "roda em" e "roda aqui" ficariam ambíguos numa lista
     misturada. */
  .ligacao__seta {
    display: flex;
    flex-shrink: 0;
    font-size: 1rem;
    color: var(--tinta-azul-fg);
  }

  .ligacao__seta--entrada { color: var(--tinta-verde-fg); }

  .ligacao__rotulo {
    flex-shrink: 0;
    font-size: var(--texto-xs);
    color: var(--texto-2);
    text-transform: lowercase;
  }

  .ligacao__alvo {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    flex: 1;
    min-width: 0;

    min-height: 34px;
    padding: 0 var(--esp-2);

    font-size: var(--texto-sm);
    text-align: left;

    border-radius: var(--raio-sm);
  }

  .ligacao__alvo > span:last-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  @media (hover: hover) {
    .ligacao__alvo:hover { background: var(--sup-2); }
  }

  /* ─────────────────────────────────────────────
     FICHA DE CLIENTE
     ───────────────────────────────────────────── */

  .ficha-atalho {
    display: flex;
    align-items: center;
    gap: var(--esp-3);
    width: 100%;

    padding: var(--esp-3);
    margin-bottom: var(--esp-4);

    text-align: left;

    background: var(--tinta-azul-bg);
    color: var(--tinta-azul-fg);
    border-radius: var(--raio-md);
  }

  .ficha-atalho__texto { flex: 1; min-width: 0; }

  .ficha-atalho__nome { font-size: var(--texto-md); font-weight: var(--peso-medio); }

  .ficha-atalho__nota { font-size: var(--texto-xs); opacity: 0.8; }
}

/* ============================================================
   CAMPO DINÂMICO DO EDITOR
   ============================================================
   O problema que isto resolve: rótulo, tipo e valor eram três
   controles soltos, separados só por uma linha fina. Com cinco campos
   na tela, você não enxergava onde um termina e o outro começa — e o
   "Valor" de um campo parecia pertencer ao campo de baixo.

   Agora cada campo é um painel com número, e o valor fica visivelmente
   dentro dele. */

@layer componentes {

  .campo-bloco {
    padding: var(--esp-3);
    margin-bottom: var(--esp-3);

    background: var(--sup-2);
    border: 1px solid var(--borda);
    border-radius: var(--raio-lg);

    transition: border-color var(--dur-rapida) var(--ease-saida);
  }

  /* O bloco inteiro reage ao foco: com cinco campos iguais na tela,
     saber em qual você está evita preencher o errado. */
  .campo-bloco:focus-within {
    border-color: var(--foco);
    background: var(--sup-1);
  }

  .campo-bloco__topo {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    margin-bottom: var(--esp-2);
  }

  .campo-bloco__num {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    width: 22px;
    height: 22px;

    font-size: var(--texto-xs);
    font-variant-numeric: tabular-nums;
    color: var(--texto-2);

    background: var(--sup-3);
    border-radius: var(--raio-cheio);
  }

  .campo-bloco__nome { flex: 1; min-width: 0; }

  /* O seletor de tipo é secundário: ele quase sempre fica no valor
     padrão. Menor e mais discreto que o campo do nome, que é o que
     você realmente digita. */
  .campo-bloco__tipo {
    flex: 0 0 132px;
    min-width: 0;
  }

  .campo-bloco__valor { margin-left: calc(22px + var(--esp-2)); }

  @media (max-width: 520px) {
    /* Em tela estreita, nome e tipo empilham: lado a lado sobram 90px
       para cada um, e "Chave de API" não cabe em nenhum dos dois. */
    .campo-bloco__topo { flex-wrap: wrap; }
    .campo-bloco__nome { flex: 1 1 100%; order: 1; }
    .campo-bloco__tipo { flex: 1 1 auto; order: 2; }
    .campo-bloco__valor { margin-left: 0; }
  }

  /* Rótulo de campo obrigatório */
  .campo__rotulo--obrigatorio::after {
    content: ' *';
    color: var(--perigo-fg);
  }

  /* ============================================================
     BOTÃO PRIMÁRIO — mais presença
     ============================================================
     "Criar card" estava com o mesmo peso visual de "Cancelar". Numa
     tela onde há uma ação certa, ela precisa ser óbvia. */

  .btn--primario {
    font-weight: var(--peso-medio);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
  }

  .btn--primario:active { box-shadow: none; }

  /* Botão largo em formulário respira mais que um botão de linha. */
  .btn--largo.btn--primario { min-height: 48px; font-size: var(--texto-md); }
}

/* ============================================================
   TAREFAS
   ============================================================ */

@layer componentes {

  /* ─────────────────────────────────────────────
     QUADRO
     ─────────────────────────────────────────────
     Colunas que rolam na horizontal no celular, lado a lado no
     desktop. Empilhar as colunas no mobile perderia o sentido do
     formato: a graça é ver as três fases ao mesmo tempo. */

  .quadro {
    display: flex;
    gap: var(--esp-3);
    overflow-x: auto;
    padding-bottom: var(--esp-3);
    scroll-snap-type: x mandatory;
  }

  .quadro::-webkit-scrollbar { height: 6px; }
  .quadro::-webkit-scrollbar-thumb {
    background: var(--borda-forte);
    border-radius: var(--raio-cheio);
  }

  .coluna {
    display: flex;
    flex-direction: column;
    flex: 0 0 min(84vw, 300px);
    scroll-snap-align: start;

    background: var(--sup-2);
    border-radius: var(--raio-lg);
    padding: var(--esp-3);
  }

  @media (min-width: 900px) {
    .coluna { flex: 1 1 0; min-width: 0; }
    .quadro { overflow-x: visible; }
  }

  .coluna__topo {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    margin-bottom: var(--esp-3);
  }

  .coluna__nome {
    flex: 1;
    font-size: var(--texto-sm);
    font-weight: var(--peso-medio);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--texto-2);
  }

  .coluna__conta {
    padding: 1px var(--esp-2);
    font-size: var(--texto-xs);
    font-variant-numeric: tabular-nums;
    background: var(--sup-3);
    color: var(--texto-2);
    border-radius: var(--raio-cheio);
  }

  .coluna__itens {
    display: flex;
    flex-direction: column;
    gap: var(--esp-2);
    min-height: 40px;
  }

  /* ─────────────────────────────────────────────
     CARTÃO DE TAREFA
     ───────────────────────────────────────────── */

  .tarefa {
    display: block;
    width: 100%;
    padding: var(--esp-3);
    text-align: left;

    background: var(--sup-1);
    border: var(--borda-card);
    border-left: 3px solid var(--borda);
    border-radius: var(--raio-md);

    transition: border-color var(--dur-rapida) var(--ease-saida),
                transform var(--dur-rapida) var(--ease-saida);
  }

  @media (hover: hover) {
    .tarefa:hover { border-color: var(--borda-forte); }
  }

  .tarefa:active { transform: scale(0.99); }

  /* A prioridade vira a barra da esquerda.
     Cor de fundo inteira competiria com a etiqueta e com o alerta de
     prazo — três sinais de cor no mesmo cartão viram ruído. */
  .tarefa--baixa   { border-left-color: var(--tinta-cinza-fg); }
  .tarefa--normal  { border-left-color: var(--tinta-azul-fg); }
  .tarefa--alta    { border-left-color: var(--tinta-ambar-fg); }
  .tarefa--urgente { border-left-color: var(--perigo-fg); }

  .tarefa--feita { opacity: 0.6; }

  .tarefa__titulo {
    font-size: var(--texto-md);
    line-height: 1.35;
    overflow-wrap: anywhere;
  }

  .tarefa__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--esp-2);
    margin-top: var(--esp-2);
    font-size: var(--texto-xs);
    color: var(--texto-2);
  }

  .tarefa__prazo {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 1px var(--esp-2);
    border-radius: var(--raio-cheio);
  }

  .tarefa__prazo--atrasada { background: var(--perigo-bg); color: var(--perigo-fg); }
  .tarefa__prazo--hoje     { background: var(--perigo-bg); color: var(--perigo-fg); }
  .tarefa__prazo--proxima  { background: var(--alerta-bg); color: var(--alerta-fg); }
  .tarefa__prazo--semana   { background: var(--sup-2); }

  .tarefa__etiquetas {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: var(--esp-2);
  }

  .etiqueta-mini {
    padding: 1px var(--esp-2);
    font-size: 10px;
    border-radius: var(--raio-cheio);
  }

  /* ─────────────────────────────────────────────
     SEÇÃO RECOLHÍVEL DA LATERAL
     ───────────────────────────────────────────── */

  .lateral__rotulo--dobra {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    width: 100%;

    min-height: 32px;
    padding: 0 var(--esp-2);

    font-size: var(--texto-xs);
    font-weight: var(--peso-medio);
    color: var(--texto-3);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-align: left;

    border-radius: var(--raio-sm);
  }

  @media (hover: hover) {
    .lateral__rotulo--dobra:hover { background: var(--sup-2); color: var(--texto-2); }
  }

  .lateral__rotulo--dobra i {
    font-size: 0.875rem;
    transition: transform var(--dur-rapida) var(--ease-saida);
  }

  .lateral__rotulo--dobra[aria-expanded="false"] i { transform: rotate(-90deg); }

  .lateral__rotulo--dobra .lateral__acao { margin-left: auto; }

  .lateral__dobra[hidden] { display: none; }
}

/* ============================================================
   ARRASTAR TAREFA
   ============================================================ */

@layer componentes {

  /* Durante o arrasto, o corpo inteiro para de selecionar texto.
     Sem isto, arrastar no desktop pinta metade da tela de azul. */
  body.arrastando {
    user-select: none;
    -webkit-user-select: none;
    cursor: grabbing;
  }

  /* Eu tinha escrito `body.arrastando * { cursor: grabbing !important }`
     aqui e removi.
     
     O projeto não usa `!important` em lugar nenhum, e essa invariante
     vale mais que o cursor certo sobre um botão durante o arrasto —
     que dura menos de um segundo e não muda o que acontece. Quebrar a
     regra por um detalhe cosmético abre a porta para a próxima
     exceção, que já não será cosmética. */

  .tarefa { cursor: grab; touch-action: manipulation; }

  /* O original fica no lugar, esmaecido — é a referência de "de onde
     saiu". Removê-lo faria a coluna pular de altura no meio do
     arrasto. */
  .tarefa--arrastando {
    opacity: 0.35;
    pointer-events: none;
  }

  /* O clone segue o dedo. `position: fixed` porque as coordenadas do
     ponteiro são da viewport. */
  .tarefa--clone {
    position: fixed;
    z-index: var(--z-aviso);
    pointer-events: none;

    box-shadow: var(--sombra-modal);
    transform: rotate(1.5deg);
    opacity: 0.95;
  }

  /* Coluna sob o dedo */
  .coluna--alvo {
    background: var(--tinta-azul-bg);
    outline: 2px dashed var(--tinta-azul-fg);
    outline-offset: -2px;
  }

  .coluna__vazia {
    padding: var(--esp-4) var(--esp-2);
    font-size: var(--texto-xs);
    color: var(--texto-3);
    text-align: center;
    border: 1px dashed var(--borda);
    border-radius: var(--raio-md);
  }

  /* No quadro dentro da área principal as colunas ganham altura mínima
     de tela, senão soltar numa coluna vazia exige mira de 40px. */
  #tarefas-area .coluna { min-height: 180px; }

  #tarefas-area .coluna__itens { flex: 1; }
}

@layer componentes {

  /* ─────────────────────────────────────────────
     ABAS DE SITUAÇÃO — só no celular
     ───────────────────────────────────────────── */

  /* ─────────────────────────────────────────────
     ABAS DE SITUAÇÃO
     ─────────────────────────────────────────────

     Cada situação tem cor própria, e a contagem vira um selo sobre o
     ícone.

     Antes eram quatro círculos cinzas iguais com um número ao lado —
     você tinha que LER para saber onde estava. Com cor, "tem coisa em
     fazendo" e "tem coisa parada" se distinguem no relance, que é o
     que se pede de um quadro. */

  .abas {
    display: flex;
    gap: var(--esp-2);
    margin: var(--esp-3) 0;
  }

  .aba {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    flex: 1;
    min-width: 0;

    padding: var(--esp-2) var(--esp-1);

    font-size: var(--texto-xs);
    color: var(--texto-2);

    background: var(--sup-1);
    border: 1px solid var(--borda);
    border-radius: var(--raio-md);

    transition: border-color var(--dur-rapida) var(--ease-saida),
                background-color var(--dur-rapida) var(--ease-saida);
  }

  /* O ícone dentro de um disco da cor da situação. */
  .aba__disco {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;

    width: 34px;
    height: 34px;
    font-size: 1.0625rem;

    border-radius: 50%;
  }

  /* O selo com a contagem, sobre o canto do disco.
     Some quando é zero: um "0" em destaque chama atenção para a
     ausência de trabalho, que é o oposto do útil. */
  .aba__selo {
    position: absolute;
    top: -4px;
    right: -6px;

    min-width: 18px;
    height: 18px;
    padding: 0 4px;

    display: flex;
    align-items: center;
    justify-content: center;

    font-size: 10px;
    font-weight: var(--peso-medio);
    font-variant-numeric: tabular-nums;
    line-height: 1;

    color: #fff;
    border-radius: var(--raio-cheio);

    /* A borda da cor do fundo separa o selo do disco sem precisar de
       sombra — que ficaria borrada em 18px. */
    box-shadow: 0 0 0 2px var(--sup-1);
  }

  .aba__nome {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
  }

  .aba[aria-pressed="true"] {
    border-color: currentColor;
    font-weight: var(--peso-medio);
  }

  /* Cor por situação.
     A fazer é neutro de propósito: ele é o estado padrão, e pintá-lo
     faria os quatro competirem entre si. */
  .aba--a_fazer  .aba__disco { background: var(--tinta-ardosia-bg); color: var(--tinta-ardosia-fg); }
  .aba--fazendo  .aba__disco { background: var(--tinta-azul-bg);    color: var(--tinta-azul-fg); }
  .aba--parado   .aba__disco { background: var(--tinta-ambar-bg);   color: var(--tinta-ambar-fg); }
  .aba--feito    .aba__disco { background: var(--tinta-verde-bg);   color: var(--tinta-verde-fg); }

  .aba--a_fazer  .aba__selo { background: var(--tinta-ardosia-fg); }
  .aba--fazendo  .aba__selo { background: var(--tinta-azul-fg); }
  .aba--parado   .aba__selo { background: var(--tinta-ambar-fg); }
  .aba--feito    .aba__selo { background: var(--tinta-verde-fg); }

  .aba--a_fazer[aria-pressed="true"] { color: var(--tinta-ardosia-fg); background: var(--tinta-ardosia-bg); }
  .aba--fazendo[aria-pressed="true"] { color: var(--tinta-azul-fg);    background: var(--tinta-azul-bg); }
  .aba--parado[aria-pressed="true"]  { color: var(--tinta-ambar-fg);   background: var(--tinta-ambar-bg); }
  .aba--feito[aria-pressed="true"]   { color: var(--tinta-verde-fg);   background: var(--tinta-verde-bg); }

  @media (max-width: 400px) {
    .aba__nome { display: none; }
  }

  /* ─────────────────────────────────────────────
     CABEÇALHO DA COLUNA — mesma linguagem
     ───────────────────────────────────────────── */

  .coluna--a_fazer .coluna__icone { background: var(--tinta-ardosia-bg); color: var(--tinta-ardosia-fg); }
  .coluna--fazendo .coluna__icone { background: var(--tinta-azul-bg);    color: var(--tinta-azul-fg); }
  .coluna--parado  .coluna__icone { background: var(--tinta-ambar-bg);   color: var(--tinta-ambar-fg); }
  .coluna--feito   .coluna__icone { background: var(--tinta-verde-bg);   color: var(--tinta-verde-fg); }

  .coluna__icone {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    width: 26px;
    height: 26px;
    font-size: 0.875rem;

    border-radius: 50%;
  }

  .coluna--a_fazer .coluna__conta { background: var(--tinta-ardosia-bg); color: var(--tinta-ardosia-fg); }
  .coluna--fazendo .coluna__conta { background: var(--tinta-azul-bg);    color: var(--tinta-azul-fg); }
  .coluna--parado  .coluna__conta { background: var(--tinta-ambar-bg);   color: var(--tinta-ambar-fg); }
  .coluna--feito   .coluna__conta { background: var(--tinta-verde-bg);   color: var(--tinta-verde-fg); }

  /* ── Uma coluna por vez no celular ── */
  @media (max-width: 899px) {
    .abas { display: flex; }

    .quadro {
      display: block;
      overflow-x: visible;
    }

    .coluna { display: none; }

    .coluna--ativa {
      display: flex;
      width: 100%;
    }

    /* O cabeçalho da coluna some: a aba já diz qual é. */
    .coluna--ativa .coluna__topo { display: none; }
  }

  @media (min-width: 900px) {
    /* No desktop as quatro colunas ficam lado a lado e as abas somem. */
    .abas { display: none; }
    .coluna { display: flex; }
  }
}

@layer componentes {

  /* Pílulas de situação no detalhe da tarefa: a mesma cor das abas,
     para "verde = feito" valer em toda a tela. */
  .pilula--a_fazer[aria-pressed="true"] { background: var(--tinta-ardosia-bg); color: var(--tinta-ardosia-fg); }
  .pilula--fazendo[aria-pressed="true"] { background: var(--tinta-azul-bg);    color: var(--tinta-azul-fg); }
  .pilula--parado[aria-pressed="true"]  { background: var(--tinta-ambar-bg);   color: var(--tinta-ambar-fg); }
  .pilula--feito[aria-pressed="true"]   { background: var(--tinta-verde-bg);   color: var(--tinta-verde-fg); }

  /* Barra colorida do cartão segue a SITUAÇÃO quando ela não é o
     padrão, e a prioridade quando é. Assim o cartão em "parado" se
     destaca mesmo com prioridade baixa. */
  .tarefa--feito { border-left-color: var(--tinta-verde-fg); }
  .tarefa--parado { border-left-color: var(--tinta-ambar-fg); }
}

@layer componentes {

  /* ─────────────────────────────────────────────
     PASSO EXPANSÍVEL
     ───────────────────────────────────────────── */

  .passo-bloco {
    margin-bottom: var(--esp-2);
    background: var(--sup-1);
    border: var(--borda-card);
    border-radius: var(--raio-md);
    overflow: hidden;
  }

  .passo-bloco--feito { background: var(--sup-2); }

  .passo-bloco__topo { display: flex; align-items: stretch; }

  /* Marcar e expandir são alvos SEPARADOS.
     Um alvo só que faz as duas coisas dependendo de onde você toca
     erra sempre — e aqui errar significa marcar um passo que você não
     fez. */
  .passo__marca {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    width: var(--alvo);
    font-size: 1.25rem;
    color: var(--texto-2);

    border-right: 1px solid var(--borda);
  }

  .passo__marca[aria-pressed="true"] { color: var(--ok-fg); }

  .passo__abrir {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    flex: 1;
    min-width: 0;

    min-height: var(--alvo);
    padding: var(--esp-2) var(--esp-3);

    text-align: left;
    font-size: var(--texto-md);
  }

  .passo__abrir i { color: var(--texto-3); transition: transform var(--dur-rapida) var(--ease-saida); }

  .passo__abrir[aria-expanded="true"] i { transform: rotate(180deg); }

  .passo-bloco--feito .passo__abrir { color: var(--texto-2); }

  .passo__corpo {
    padding: var(--esp-3);
    border-top: 1px solid var(--borda);
    background: var(--sup-2);
  }

  .passo__corpo[hidden] { display: none; }

  .passo__descricao {
    font-size: var(--texto-sm);
    line-height: 1.55;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin-bottom: var(--esp-3);
  }
}

/* ============================================================
   GRADE DE QUADROS
   ============================================================
   A fileira horizontal era ruim com dez quadros: você arrastava
   procurando, e o botão de criar sumia no fim dela. Uma grade cresce
   em ALTURA, que é a direção onde sobra espaço numa tela de celular.
   ============================================================ */

@layer componentes {

  .quadros-grade {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--esp-2);
  }

  @media (min-width: 520px) {
    .quadros-grade { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
  }

  .quadro-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--esp-3);

    min-height: 68px;
    padding: var(--esp-3);

    text-align: left;

    background: var(--sup-1);
    border: var(--borda-card);
    border-radius: var(--raio-lg);

    transition: border-color var(--dur-rapida) var(--ease-saida),
                transform var(--dur-rapida) var(--ease-saida);
  }

  @media (hover: hover) {
    .quadro-card:hover { border-color: var(--borda-forte); }
  }

  .quadro-card:active { transform: scale(0.99); }

  .quadro-card__icone {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    width: 40px;
    height: 40px;
    font-size: 1.25rem;

    border-radius: 12px;
  }

  .quadro-card__texto { flex: 1; min-width: 0; }

  .quadro-card__nome {
    font-size: var(--texto-md);
    font-weight: var(--peso-medio);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .quadro-card__meta { font-size: var(--texto-xs); color: var(--texto-2); }

  /* Selo com as abertas, no canto. Some quando é zero — quadro em dia
     não precisa de número gritando. */
  .quadro-card__selo {
    position: absolute;
    top: var(--esp-2);
    right: var(--esp-2);

    min-width: 22px;
    padding: 2px 6px;

    font-size: var(--texto-xs);
    font-weight: var(--peso-medio);
    font-variant-numeric: tabular-nums;
    text-align: center;

    border-radius: var(--raio-cheio);
  }

  /* Criar quadro: tracejado, para não competir com os que existem. */
  .quadro-card--novo {
    background: transparent;
    border: 1px dashed var(--borda-forte);
    color: var(--texto-2);
  }

  .quadro-card--novo .quadro-card__icone {
    background: var(--sup-2);
    color: var(--texto-2);
  }
}

@layer componentes {

  /* Área que aceita arquivo arrastado */
  .area-solta {
    border: 1px dashed transparent;
    border-radius: var(--raio-md);
    padding: var(--esp-2);
    transition: border-color var(--dur-rapida) var(--ease-saida),
                background-color var(--dur-rapida) var(--ease-saida);
  }

  .area-solta.solta-aqui {
    border-color: var(--tinta-azul-fg);
    background: var(--tinta-azul-bg);
  }

  /* `pointer-events: none` nos filhos durante o arrasto.
     Sem isto, passar sobre um botão dentro da área dispara
     `dragleave` no pai e a moldura pisca. */
  .area-solta.solta-aqui * { pointer-events: none; }
}
