/* =========================================================================
   COMPONENTES — as peças que qualquer tela pode usar.
   =========================================================================
   Barra de topo, cartão, botão, campo, tabela, modal, toast, etiqueta,
   paginação, chave liga/desliga. Se aparece em mais de uma tela, é daqui.

   O que NÃO entra: regra que só existe por causa de uma tela (a ficha do
   evento, o editor de template, o painel) — essa mora em telas.css.

   Carrega depois de base.css e antes de telas.css.
   ========================================================================= */

/* 
   -------------------------------------------------------------------------
   Componentes de Formulário (Inputs & Selects)
   ------------------------------------------------------------------------- 
*/
.campo-base,
.selecao-base {
    display: block;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
    padding: 0.5rem 0.75rem;
    font-size: var(--texto-base);
    line-height: 1.5;
    min-height: var(--altura-controle);
    color: var(--cor-texto-principal);
    background-color: var(--cor-input-fundo);
    background-clip: padding-box;
    border: 1px solid var(--cor-borda);
    border-radius: var(--raio);
    /* 6px */
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

/* <select> tem altura intrínseca maior que <input> — trava na mesma para alinhar */
select.campo-base,
select.selecao-base { height: var(--altura-controle); }

textarea.campo-base { min-height: 4.25rem; }

/* Inputs de data/hora: neutraliza a largura intrínseca do seletor nativo (iOS/Safari) */
input[type="date"].campo-base,
input[type="time"].campo-base,
input[type="datetime-local"].campo-base,
input[type="month"].campo-base {
    -webkit-appearance: none;
    appearance: none;
    max-width: 100%;
}

input[type="date"].campo-base::-webkit-date-and-time-value {
    text-align: left;
    margin: 0;
}

input[type="date"].campo-base::-webkit-calendar-picker-indicator {
    margin-left: auto;
    flex-shrink: 0;
}

.campo-base:focus,
.selecao-base:focus {
    color: var(--cor-texto-principal);
    background-color: var(--cor-input-fundo);
    border-color: var(--cor-primaria);
    outline: 0;
    box-shadow: 0 0 0 0.25rem rgba(59, 130, 246, 0.25);
    /* Primary color with opacity */
}

.campo-base::placeholder {
    color: var(--cor-texto-fraco);
    /* Gray 400 */
    opacity: 1;
}

.campo-base:disabled,
.selecao-base:disabled {
    background-color: var(--cor-superficie-2);
    /* Gray 100 */
    opacity: 1;
    cursor: not-allowed;
}

/*
   -------------------------------------------------------------------------
   Checkbox — visual minimalista, alvo grande (bom no mobile)
   -------------------------------------------------------------------------
*/
input[type="checkbox"] {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
    flex: none;
    width: 1.5rem;
    height: 1.5rem;
    border: 1.5px solid var(--cor-borda);
    border-radius: var(--raio);
    background-color: var(--cor-superficie);
    cursor: pointer;
    display: inline-grid;
    place-content: center;
    transition: background-color 0.15s ease, border-color 0.15s ease;
    vertical-align: middle;
}

input[type="checkbox"]::after {
    content: "";
    width: 0.7rem;
    height: 0.7rem;
    transform: scale(0);
    transition: transform 0.12s ease-in-out;
    background-color: var(--cor-superficie);
    /* checkmark desenhado por clip-path */
    clip-path: polygon(14% 44%, 0 65%, 43% 100%, 100% 16%, 82% 0%, 40% 62%);
}

input[type="checkbox"]:checked {
    background-color: var(--cor-primaria);
    border-color: var(--cor-primaria);
}

input[type="checkbox"]:checked::after { transform: scale(1); }

input[type="checkbox"]:focus-visible {
    outline: 0;
    box-shadow: 0 0 0 0.2rem rgba(55, 64, 99, 0.25);
}

input[type="checkbox"]:disabled {
    background-color: var(--cor-superficie-2);
    border-color: var(--cor-borda);
    cursor: not-allowed;
    opacity: 0.6;
}

/* label que embrulha um checkbox vira alvo de toque confortável */
label:has(> input[type="checkbox"]) {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    cursor: pointer;
    min-height: 2.75rem;
    user-select: none;
}

/*
   -------------------------------------------------------------------------
   Botões Base
   -------------------------------------------------------------------------
*/
.botao-primario {
    display: inline-block;
    /*
     * Compacto e em CAIXA ALTA.
     *
     * Era 18px em caixa baixa com 51px de altura: um botão do tamanho de um
     * campo de formulário, e numa barra de ações isso vira parede. Caixa alta
     * num corpo menor ocupa menos e continua lendo como botão — o rótulo de
     * botão é sempre curto, e é aí que versal funciona.
     */
    padding: 0.3rem 0.9rem;
    font-size: var(--texto-xxs);
    font-weight: var(--peso-forte);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    line-height: 1.5;
    color: var(--cor-superficie);
    text-align: center;
    text-decoration: none;
    vertical-align: middle;
    cursor: pointer;
    user-select: none;
    background-color: var(--cor-primaria);
    border: 1px solid transparent;
    border-radius: var(--raio);
    transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.botao-primario:hover {
    background-color: var(--cor-primaria-hover);
}

/* 
   -------------------------------------------------------------------------
   Componentes de Interface (UI)
   ------------------------------------------------------------------------- 
*/

/* Toast (Notificações) */
.toast-container {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Fluxo normal, não flex.
 *
 * Em flex, cada pedaço do recado vira um item: o <strong> de um lado, cada
 * trecho de texto de outro, o <code> esticado no meio. A tela de atendimento
 * local mostrou isso no ar — o aviso saiu embaralhado em colunas. O toast
 * flutuante só recebe texto puro (visual.js usa textContent), então nada
 * perde com o bloco; quem precisa de linha com botão é o .toast-central,
 * que declara o próprio display. */
.toast {
    display: block;
    padding: 1rem;
    border-radius: var(--raio);
    background-color: var(--cor-superficie);
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
    min-width: 300px;
    animation: slideIn 0.3s ease-out forwards;
    border-left: 4px solid var(--cor-info);
    font-size: var(--texto-base);
    /* Updated to 16px */
}

.toast-sucesso {
    border-left-color: var(--cor-sucesso);
}

.toast-erro {
    border-left-color: var(--cor-erro);
}

.toast-aviso {
    border-left-color: var(--cor-aviso);
}

/* Comando dentro do recado: precisa ser copiável e quebrar em telas estreitas
   em vez de empurrar a largura do aviso. */
.toast code {
    padding: 0.1rem 0.3rem;
    border-radius: var(--raio);
    background-color: var(--cor-superficie-3);
    word-break: break-word;
}

/* Modal (Janelas) */
.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    /* Semi-transparent black */
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 40;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
}

.modal-overlay.ativo {
    opacity: 1;
    visibility: visible;
}

.modal-janela {
    background-color: var(--cor-superficie);
    border-radius: var(--raio);
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
    max-width: 32rem;
    /* lg */
    width: 100%;
    margin: 1rem;
    transform: scale(0.95);
    transition: transform 0.2s ease-in-out;
    /* cabeçalho e rodapé fixos; o corpo rola quando a lista fica grande */
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 2rem);
}

.modal-cabecalho, .modal-rodape { flex: 0 0 auto; }

.modal-overlay.ativo .modal-janela {
    transform: scale(1);
}

.modal-cabecalho {
    padding: 1rem 1.5rem;
    border-bottom: 1px solid var(--cor-borda);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.modal-titulo {
    font-size: var(--texto-md);
    font-weight: 600;
    color: var(--cor-texto-principal);
}

.modal-corpo {
    padding: 1.5rem;
    color: var(--cor-texto-principal);
    overflow-y: auto;
    flex: 1 1 auto;
    -webkit-overflow-scrolling: touch;
}

.modal-rodape {
    padding: 1rem 1.5rem;
    border-top: 1px solid var(--cor-borda);
    background-color: var(--cor-fundo);
    border-bottom-left-radius: 0.5rem;
    border-bottom-right-radius: 0.5rem;
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* 
   -------------------------------------------------------------------------
   Tabelas e Paginação
   ------------------------------------------------------------------------- 
*/

/* Tabela */
.tabela-container {
    width: 100%;
    overflow-x: auto;
    border-radius: var(--raio);
    border: 1px solid var(--cor-borda);
    background-color: var(--cor-superficie);
}

.tabela {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--texto-base);
    /* Updated to 16px */
    text-align: left;
}

.tabela thead {
    background-color: var(--cor-superficie-2);
    /* Gray 100 */
    border-bottom: 1px solid var(--cor-borda);
}

.tabela thead th {
    padding: 0.75rem 1.5rem;
    font-weight: 600;
    color: var(--cor-texto-principal);
    text-transform: uppercase;
    font-size: var(--texto-xs);
    letter-spacing: 0.05em;
}

.tabela tbody tr {
    border-bottom: 1px solid var(--cor-borda);
    transition: background-color 0.15s;
}

.tabela tbody tr:last-child {
    border-bottom: none;
}

.tabela tbody tr:hover {
    background-color: var(--cor-superficie-2);
    /* Gray 50 */
}

.tabela tbody td {
    padding: 1rem 1.5rem;
    color: var(--cor-texto-principal);   /* era --cor-texto-main, que não existe: a regra não valia nada */
    white-space: normal;          /* nunca forçar a tabela a estourar a largura */
    overflow-wrap: anywhere;
}

.tabela td.nao-quebrar, .tabela th.nao-quebrar { white-space: nowrap; }

/* Paginação */
.paginacao {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 0;
}

.paginacao-lista {
    display: inline-flex;
    gap: 0.25rem;
}

.paginacao-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 0.5rem;
    border-radius: var(--raio);
    font-size: var(--texto-sm);
    font-weight: 500;
    color: var(--cor-texto-principal);
    background-color: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    cursor: pointer;
    text-decoration: none;
    transition: all 0.15s;
}

.paginacao-item:hover {
    background-color: var(--cor-superficie-2);
    border-color: var(--cor-borda-forte);
}

.paginacao-item.ativo {
    background-color: var(--cor-primaria);
    color: var(--cor-superficie);
    border-color: var(--cor-primaria);
}

.paginacao-item.desabilitado {
    opacity: 0.5;
    cursor: not-allowed;
    background-color: var(--cor-superficie-2);
}

/* 
   -------------------------------------------------------------------------
   Componentes Extras & Utilitários
   ------------------------------------------------------------------------- 
 */

/* Rótulos de Campo (Labels) */
label {
    display: block;
    font-size: var(--texto-base);
    /* Updated to 16px */
    font-weight: 500;
    margin-bottom: 0.25rem;
    color: var(--cor-texto-principal);
}

/* Badges / Etiquetas (Status) - Less rounded as requested */
.etiqueta {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.5rem;
    border-radius: var(--raio);
    /* Reduced from full roundness */
    font-size: var(--texto-xs);
    font-weight: 600;
    line-height: 1;
}

/* Material Icons Helper */
.material-icons {
    font-size: var(--texto-md);
    /* 20px default for actions */
    vertical-align: middle;
}

.tabela-acao {
    color: var(--cor-primaria);
    /* Mesma família dos outros botões: caixa alta e o mesmo corpo. */
    font-size: var(--texto-xxs);
    font-weight: var(--peso-forte);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    transition: all 0.2s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0 0.25rem;
    text-decoration: none;

    /* New styles for subtle border */
    border: 1px solid var(--cor-borda-media);
    /* Reduced to 1px as requested */
    border-radius: var(--raio);
    /* Increased to 6px */
    padding: 6px;
    /* Increased to 6px */
    background-color: var(--cor-superficie);
}

/* Override icon size for table actions specifically */
.tabela-acao svg {
    width: 18px;
    height: 18px;
}

.tabela-acao:hover {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    background-color: var(--cor-superficie-2);
    /* Very faint blue-white */
    border-color: var(--cor-borda-forte);
    /* Slightly darker navy tint on hover */
}

/*
   =========================================================================
   PalcoPronto — componentes específicos do app
   =========================================================================
*/

/* ---- Barra de topo ---- */
/*
 * Gruda no topo e se estende POR TRÁS do relógio do iPhone.
 *
 * Salvo na tela de início, o app roda em tela cheia, e ao rolar o iOS
 * desenhava na faixa do relógio um esmaecimento branco que descia sobre a
 * barra. Com a barra ocupando essa faixa, o esmaecimento passa a ser roxo
 * sobre roxo e some. O padding de cima é o que impede o logo de ficar
 * embaixo das horas; fora do iPhone, env() devolve 0 e nada muda.
 */
.barra-topo {
    background-color: var(--cor-primaria);
    color: var(--cor-superficie);
    /* o espaço do relógio vale em qualquer aparelho com recorte, deitado ou
       em pé; fora deles env() devolve 0 e nada muda */
    padding-top: env(safe-area-inset-top, 0px);
}

/* Grudar é SÓ no celular: o defeito é do iPhone em tela cheia, e no PC a
   barra rolar junto é o comportamento que o app sempre teve. Mudar os dois
   seria resolver um problema e inventar outra discussão. */
/* ---- Os fios separadores, a partir de 1100px ----
 *
 * SEPARADORES DE VERDADE: um fio vertical, não um espaço maior. Com quatro
 * números seguidos só por espaço, a linha vira uma lista que ninguém agrupa
 * de olho — "22° 35% 0,3 13" é tudo igual. O fio diz onde um dado termina e
 * o outro começa.
 *
 * Em CSS (border-left) e não em caractere: uma barra vertical escrita no HTML
 * seria lida em voz alta pelo leitor de tela, uma vez por dado. E o caractere
 * de desenho de caixa não está na fonte embutida do PDF — a trava de símbolos
 * da bateria cobra isso, e cobrava até dentro deste comentário.
 *
 * 1100px, e o número foi MEDIDO no navegador, não escolhido: com o texto
 * mais longo do catálogo ("Trovoada com granizo forte") e uma cidade grande
 * ("São José do Rio Preto/SP"), o cabeçalho ainda cabe numa linha até
 * 1080px. Abaixo disso ele quebra — e um border-left num bloco que quebrou
 * deixa de ser separador: vira um trilho vertical correndo ao lado de duas
 * linhas, que parece defeito. Visto a 769px, antes de existir este corte.
 */
@media (min-width: 1100px) {
    .bloco-clima .clima-linha,
    .bloco-clima .clima-numeros,
    .bloco-clima .clima-numeros > .clima-dado + .clima-dado:not(.clima-chuva-mm) {
        border-left: var(--borda-fina) solid var(--cor-borda);
        padding-left: var(--e3);
    }
}

@media (max-width: 768px) {
    .barra-topo {
        position: sticky;
        top: 0;
        z-index: var(--z-barra);
    }
}

.barra-topo-conteudo {
    max-width: 1400px;
    margin: 0 auto;
    /* deitado, a borda arredondada do aparelho come o canto: max() mantém o
       respiro de sempre e só aumenta quando o sistema pede */
    padding: 0.75rem max(1.25rem, env(safe-area-inset-right, 0px))
             0.75rem max(1.25rem, env(safe-area-inset-left, 0px));
    display: flex;
    align-items: center;
    gap: 1.5rem;
}

.barra-marca {
    color: var(--cor-superficie);
    font-weight: 700;
    font-size: var(--texto-md);
    text-decoration: none;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
}

.barra-marca-icone {
    color: var(--cor-secundaria);
}

.barra-logo-img {
    height: 38px;
    width: auto;
    max-width: 120px;
    display: block;
    object-fit: contain;
}

.barra-marca-nome {
    margin-left: 0.55rem;
    font-weight: 800;
    font-size: var(--texto-base);
    letter-spacing: 0.06em;
    color: var(--cor-superficie);
    white-space: nowrap;
}

/* Botão hamburguer — só no mobile */
.barra-menu-btn {
    display: none;
    margin-left: auto;
    background: transparent;
    border: 0;
    color: var(--cor-superficie);
    cursor: pointer;
    padding: 0.25rem;
    align-items: center;
}

.barra-navegacao {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
}

.barra-links {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.barra-links a {
    color: rgba(255, 255, 255, 0.85);
    text-decoration: none;
    font-size: var(--texto-base);
    font-weight: 500;
}

.barra-links a:hover {
    color: var(--cor-superficie);
    opacity: 1;
}

.barra-usuario {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.barra-usuario .texto-pequeno,
.barra-usuario a {
    color: rgba(255, 255, 255, 0.85);
}

.barra-conta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.35;
    text-align: right;
}

.barra-conta .barra-empresa {
    color: var(--cor-superficie);
    font-weight: 700;
    font-size: var(--texto-sm);
    text-decoration: none;
}

.barra-conta .barra-empresa:hover { text-decoration: underline; }

.barra-conta .barra-usuario-nome {
    color: rgba(255, 255, 255, 0.7);
    font-size: var(--texto-xs);
}

.barra-sair {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--raio);
    color: rgba(255, 255, 255, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.25);
    flex: none;
}

.barra-sair svg { width: 17px; height: 17px; }

.barra-sair:hover { background: rgba(255, 255, 255, 0.12); color: var(--cor-superficie); }

/* ---- Cartão ---- */
.cartao {
    background-color: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: var(--raio);
    padding: 1.25rem;
}

.cartao + .cartao {
    margin-top: 1rem;
}

/* ---- Selos de status de seção ---- */
.selo {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.55rem;
    border-radius: var(--raio);
    font-size: var(--texto-xxs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.selo::before {
    content: "";
    width: 0.5rem;
    height: 0.5rem;
    border-radius: var(--raio);
    background: currentColor;
}

.selo-alinhamento { background: var(--cor-aviso-fundo); color: var(--cor-aviso-texto); }

/* ---- Grade de campos técnicos ---- */
/*
 * Grade padrão de formulário. Toda coluna tem a mesma largura (1fr), então
 * campo nenhum fica maior que o vizinho por acidente de layout.
 *
 * Os campos de uma mesma linha alinham pela BASE: sem isto, um rótulo que
 * quebra em duas linhas empurra o próprio campo ~18px para baixo e a linha
 * inteira fica torta. Cada célula vira coluna flex com o conteúdo no fim.
 *
 * Mira em "> div" de propósito: há <label> de checkbox como filho direto da
 * grade (cadastros/hoteis.php), e esses precisam continuar horizontais.
 */
.grade-campos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.9rem;
    align-items: stretch;
}

/*
 * A célula se encaixa em TRÊS faixas da grade: rótulo, campo, ajuda.
 *
 * O olho lê uma linha de formulário pela borda de baixo dos campos — é ela
 * que diz "isto é uma fileira". Com cada célula de altura própria (rótulo
 * curto, rótulo que quebra, com ajuda, sem ajuda), essa borda serrilhava.
 *
 * As duas tentativas anteriores erravam, cada uma de um jeito: alinhar pela
 * BASE resolvia o rótulo que quebra mas deixava o texto de ajuda encostar
 * embaixo, empurrando o campo para cima; alinhar pelo TOPO só nas células com
 * ajuda deixou, numa linha mista, 52px entre a base do campo com ajuda e a
 * dos vizinhos.
 *
 * Com subgrid os rótulos da linha dividem uma faixa, os campos outra e as
 * ajudas a terceira. Medido: quatro campos com UMA base, e com um rótulo
 * forçado a três linhas, ainda uma.
 */
.grade-campos > div {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 3;
    min-width: 0;
}

/* A regra do :has(.ajuda-campo) saiu: ela existia para remendar o
   alinhamento, e o subgrid acima resolve o caso dela e o do rótulo que quebra
   de uma vez. Remendo que vira regra é o que faz um CSS virar arqueologia. */

/*
 * Célula que carrega um botão no lugar de um campo.
 *
 * grid-row: 2 porque a célula não tem rótulo: sem isso o botão se acomoda na
 * PRIMEIRA faixa do subgrid, que é a dos rótulos, e flutua acima da linha dos
 * campos. Era o que acontecia no endereço do fornecedor.
 */
.grade-campos > div.celula-acao > button,
.grade-campos > div.celula-acao > .botao-primario,
.grade-campos > div.celula-acao > .botao-secundario {
    grid-row: 2;
    /* E encostado embaixo: o botão quadrado é mais baixo que um campo, e a
       linha de formulário se lê pela borda DE BAIXO — alinhado pelo topo ele
       ficava 16px acima da base dos vizinhos. */
    align-self: end;
}

/* O botão ocupa a célula inteira, para ter a largura e a altura de um campo.
   Isto vale para botão de TEXTO, que é o único que entra aqui: botão de
   ícone fica DENTRO da célula do campo, ao lado dele (.campo-com-acoes +
   .campo-acao-mini), como a ficha sempre fez. Numa célula da grade ele
   gastava uma coluna inteira com um desenho de 20px. */
.grade-campos > div.celula-acao > button,
.grade-campos > div.celula-acao > .botao-primario,
.grade-campos > div.celula-acao > .botao-secundario {
    width: 100%;
    min-height: 2.85rem;
}

/*
 * ---- O bloco de endereço: seis campos numa linha só ----
 *
 * A grade comum reparte o espaço em colunas iguais, e endereço não é assim:
 * UF tem duas letras e rua tem o nome inteiro de uma avenida. Em colunas
 * iguais sobrava espaço vazio na UF e faltava na rua, e os seis campos
 * quebravam em duas fileiras.
 *
 * As proporções (1fr = a coluna igual de antes): CEP 0,7 — Rua 1,5 —
 * Número 0,5 — Bairro 1 — Cidade 0,8 — UF 0,4.
 *
 * minmax(0, …) e não um mínimo em rem: com mínimo fixo a linha não encolhe,
 * ela ESTOURA para fora do cartão em telas intermediárias. Com zero, os seis
 * campos cabem em qualquer largura acima do ponto de quebra do celular, que
 * é onde eles voltam a empilhar.
 *
 * O CEP e a rua levam um botão de ícone dentro da própria célula (copiar),
 * e por isso são as duas colunas com mais folga proporcional.
 */
.bloco-endereco {
    grid-template-columns:
        /* Piso só aqui: o CEP tem tamanho conhecido (00000-000) e divide a
           célula com o botão de copiar. Em 0,7fr puro sobravam 71px para o
           campo e o valor aparecia cortado — "07175" sem o final. O piso é a
           largura em que ele cabe inteiro; acima disso a proporção volta a
           mandar. Os outros campos não precisam: nenhum tem comprimento fixo
           e todos cabem no espaço que a proporção lhes dá. */
        minmax(9.5rem, 0.7fr)   /* CEP, com o botão de copiar o endereço */
        minmax(0, 1.5fr)    /* Rua, com o botão de copiar o valor */
        minmax(0, 0.5fr)    /* Número */
        minmax(0, 1fr)      /* Bairro */
        minmax(0, 0.8fr)    /* Cidade */
        minmax(0, 0.4fr);   /* UF */
}

/*
 * ---- Os dados do evento: seis campos numa linha só ----
 *
 * Mesma ideia do bloco de endereço. Em colunas iguais a Situação caía
 * sozinha para uma segunda fileira, com espaço sobrando na data e faltando
 * no título e no local, que levam nome de festa e nome de casa de show.
 *
 * Proporções, tomando a coluna igual como 1fr. Somam 6, que é o que seis
 * colunas iguais somavam: a linha ocupa a mesma largura de antes.
 */
.bloco-dados-evento {
    grid-template-columns:
        minmax(0, 1.3fr)      /* Título — nome de festa, é o mais comprido */
        /* Piso na data: o seletor do navegador tem tamanho próprio
           (dd/mm/aaaa mais o ícone do calendário) e abaixo disto ele corta.
           É a mesma exceção do CEP, e pelo mesmo motivo: conteúdo de
           tamanho fixo não encolhe junto com a coluna. */
        minmax(9rem, 0.75fr)  /* Data */
        minmax(0, 0.9fr)      /* Cidade/UF */
        minmax(0, 1fr)        /* Turnê */
        minmax(0, 1.3fr)      /* Local — nome da casa, às vezes com a cidade */
        minmax(0, 0.75fr);    /* Situação */
}

/* Cidade num campo só (locais, hotéis, empresa): cinco colunas, não seis.
   Com as seis declaradas e cinco células, a última coluna ficava vazia e a
   linha terminava num buraco do tamanho da UF. */
.bloco-endereco-cidade-unica {
    grid-template-columns:
        minmax(9.5rem, 0.7fr)   /* CEP, com o botão de copiar */
        minmax(0, 1.5fr)        /* Rua */
        minmax(0, 0.5fr)        /* Número */
        minmax(0, 1fr)          /* Bairro */
        minmax(0, 1.2fr);       /* Cidade/UF, que leva a sigla junto */
}

.selo-contra-rider-secao {
    background: var(--cor-aviso-fundo);
    color: var(--cor-aviso-texto);
    white-space: nowrap;
}

/* ---- Chave liga/desliga ---- */
.chave-linha {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    cursor: pointer;
    margin: 0;
    font-weight: 500;
}

.chave-linha .chave {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.chave-visual {
    flex: none;
    position: relative;
    width: 3rem;
    height: 1.6rem;
    border-radius: var(--raio);
    background: var(--cor-borda-media);
    transition: background 0.18s;
}

.chave-visual::after {
    content: '';
    position: absolute;
    top: 0.2rem;
    left: 0.2rem;
    width: 1.2rem;
    height: 1.2rem;
    border-radius: var(--raio);
    background: var(--cor-superficie);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
    transition: transform 0.18s;
}

.chave:checked + .chave-visual { background: var(--cor-primaria); }

.chave:checked + .chave-visual::after { transform: translateX(1.4rem); }

.chave:focus-visible + .chave-visual {
    outline: 2px solid var(--cor-primaria);
    outline-offset: 2px;
}

/* Indicador de salvamento no campo */
.campo-base.salvando { border-color: var(--cor-aviso); }

.campo-base.salvo { border-color: var(--cor-sucesso); }

.campo-base.erro-salvar { border-color: var(--cor-erro); }

/* ---- Botão secundário / texto ---- */
.botao-secundario {
    display: inline-block;
    padding: 0.3rem 0.9rem;
    /* Sem isto herdava os 13,3px padrão do <button> e saía visivelmente
       menor que o primário ao lado — os dois são o mesmo tipo de controle,
       e por isso repetem medida por medida o que está no primário. */
    font-size: var(--texto-xxs);
    line-height: 1.5;
    font-weight: var(--peso-forte);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--cor-primaria);
    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: var(--raio);
    cursor: pointer;
    text-decoration: none;
}

.botao-secundario:hover {
    background: var(--cor-superficie-2);
}

.botao-perigo {
    background: var(--cor-erro);
    color: var(--cor-superficie);
    border: 0;
}

/* Botão só-ícone (ex.: abrir busca) */
.botao-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* A medida sai da regra dos quadrados, mais abaixo (--altura-botao).
       Havia 40px fixos aqui: perdiam por ordem no arquivo e não faziam nada,
       mas ganhariam no dia em que alguém reordenasse as regras. */
    flex: 0 0 auto;
    color: var(--cor-primaria);
    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: var(--raio);
    cursor: pointer;
}

.botao-icone:hover { background: var(--cor-superficie-2); }

/* Botão só-ícone dentro de modais/linhas (salvar, apagar, adicionar item) */
.botao-icone-acao {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    flex: 0 0 auto;
    padding: 0;
    /* Roxo em repouso, e não só no hover: no celular não existe hover, e um
       ícone de ação cinza parecia desligado. Cinza é inativo. */
    color: var(--cor-primaria);
    background: transparent;
    border: 1.5px solid var(--cor-borda);
    border-radius: var(--raio);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.botao-icone-acao svg { width: 1.15rem; height: 1.15rem; }

.botao-icone-acao:hover { background: var(--cor-superficie-2); color: var(--cor-primaria); border-color: var(--cor-primaria); }

/* Vermelho em repouso, como todo botão que destrói. Ficava roxo até alguém
   passar o mouse — e no celular ninguém passa: o botão de apagar tinha a cor
   de "faça" a vida inteira. */
.botao-icone-acao.perigo { color: var(--cor-erro); }
.botao-icone-acao.perigo:hover { background: var(--cor-erro-fundo); color: var(--cor-erro); border-color: var(--cor-erro); }

.botao-icone-acao:active { transform: translateY(1px); }

/* Botão flutuante "voltar ao topo" */
#voltar-topo {
    position: fixed;
    right: 1rem;
    /* acima da barrinha de gestos do iPhone, que agora o app alcança */
    bottom: max(1rem, env(safe-area-inset-bottom, 0px));
    z-index: 45;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 3px solid var(--cor-primaria-hover);
    border-radius: var(--raio);
    background: var(--cor-primaria);
    color: var(--cor-superficie);
    cursor: pointer;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
    opacity: 0;
    visibility: hidden;
    transform: translateY(0.5rem);
    transition: opacity 0.2s, visibility 0.2s, transform 0.2s;
}

#voltar-topo.visivel {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

#voltar-topo:hover { background: var(--cor-primaria-hover); }

/* Erro de validação (ex.: nome de pessoa inválido) */
.campo-base.erro-validacao {
    border-color: var(--cor-erro);
    background: var(--cor-erro-fundo);
}

/* Linhas/cartões clicáveis */
.linha-clicavel { cursor: pointer; }

.tag-setor {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.5rem;
    border-radius: var(--raio);
    background: var(--cor-info-fundo);
    color: var(--cor-primaria);
    font-size: var(--texto-xxs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.tag-setor[hidden] { display: none; }

tr[data-travado] .campo-rotulo { background: var(--cor-superficie-2); cursor: not-allowed; }

body.arrastando-item { user-select: none; cursor: grabbing; }

body.arrastando-item * { cursor: grabbing !important; }

.campo-base.campo-fora-modelo {
    background: var(--cor-aviso-fundo);
    border-color: var(--cor-aviso);
}

.botao-acao-icone {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.45rem 0.7rem;
    border: 1px solid var(--cor-borda);
    border-radius: var(--raio);
    background: var(--cor-superficie);
    color: var(--cor-primaria);
    text-decoration: none;
    font-size: var(--texto-sm);
    font-weight: 500;
    white-space: nowrap;
}

.botao-acao-icone:hover { background: var(--cor-superficie-2); }

.botao-acao-icone svg {
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
}

.botao-acao-perigo { color: var(--cor-erro); }

.botao-acao-perigo:hover { background: var(--cor-erro-fundo); border-color: var(--cor-erro); }

.campo-grupo {
    margin-bottom: 1rem;
}

/* O canto de 3px não mora mais aqui: é regra universal em base.css, que vale
   para todo elemento em vez de para uma lista de seletores lembrados. */

/* =========================================================================
   REGRA GLOBAL: botão de lixeira / excluir — implementação única.
   Minimalista, moderno, borda vermelha. Vale para TODOS os botões-ícone de
   remover do sistema. (ver implementação/regras.md §10)
   ========================================================================= */
.botao-lixeira,
.campos-editor .rm-campo,
.secao-editor .rm-secao,
.secao-editor-cabecalho .rm-secao,
.tabela-acao.botao-acao-perigo,
.tabela-acao.excluir-lista {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Mesmo token de altura dos demais BOTÕES (não o do campo). Fixado em
       2rem, brigava com o min-height da regra global e o botão saía 46px de
       altura por 32 de largura — um retângulo no meio de botões quadrados.
       E preso em --altura-controle, ficava 51px ao lado de vizinhos de 35 —
       foi assim que o catálogo de opções saiu com três ícones em duas
       linhas. */
    width: var(--altura-botao);
    height: var(--altura-botao);
    min-width: var(--altura-botao);
    padding: 0;
    margin: 0;
    border: 1px solid var(--cor-erro);
    border-radius: var(--raio);
    background: var(--cor-superficie);
    color: var(--cor-erro);
    cursor: pointer;
    box-shadow: none;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.botao-lixeira svg,
.campos-editor .rm-campo svg,
.secao-editor .rm-secao svg,
.secao-editor-cabecalho .rm-secao svg,
.tabela-acao.botao-acao-perigo svg,
.tabela-acao.excluir-lista svg {
    width: 1rem;
    height: 1rem;
}

.botao-lixeira:hover,
.campos-editor .rm-campo:hover,
.secao-editor .rm-secao:hover,
.secao-editor-cabecalho .rm-secao:hover,
.tabela-acao.botao-acao-perigo:hover,
.tabela-acao.excluir-lista:hover {
    background: var(--cor-erro);
    color: var(--cor-superficie);
    border-color: var(--cor-erro);
    box-shadow: none;
}

.busca-sug-nome { display: block; font-weight: 600; color: var(--cor-texto-principal); }

.busca-sug-sub {
    display: block;
    margin-top: 0.1rem;
    font-size: var(--texto-xs);
    color: var(--cor-texto-suave);
}

/* ==========================================================================
   REGRA GLOBAL: todo controle clicável tem a altura de um campo.
   ==========================================================================
   Antes cada botão tinha a sua medida — lixeira 2rem, ícone 40px, ação de
   tabela por padding — e todos saíam menores que o campo ao lado, o que
   deixava a linha desalinhada e o alvo de toque pequeno demais no celular.
   Agora todos herdam --altura-controle. Não redefinir altura por componente:
   se algum precisar de outra medida, muda-se o token.

   Vale para PC e celular: no celular a altura é a mesma, e é justamente lá
   que 45,6px importa — o mínimo recomendado de toque no iPhone é 44px. */
/* Botão tem altura própria (--altura-botao); campo continua em
   --altura-controle. No celular as duas voltam a ser iguais, lá embaixo. */
.botao-primario,
.botao-secundario,
.botao-icone,
.tabela-acao,
.campo-acao-mini,
.botao-lixeira {
    min-height: var(--altura-botao);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Os quadrados também travam a largura, para não virarem retângulos. */
.botao-icone,
.campo-acao-mini,
.botao-lixeira {
    /* Mesmo token de altura dos outros botões: um quadrado de 51px ao lado
       de um de 35px é a mesma barra com dois tamanhos, que é a queixa que
       originou isto. No celular o token volta a valer --altura-controle e
       o alvo de toque continua de pé. */
    width: var(--altura-botao);
    height: var(--altura-botao);
    min-width: var(--altura-botao);
    padding: 0;
    flex: none;
}

/* O ícone cresce junto, senão fica um desenho pequeno perdido num botão grande. */
.campo-acao-mini svg,
.botao-lixeira svg,
.botao-icone svg { width: 1.25rem; height: 1.25rem; }

/* Ação de tabela é botão de texto: mantém a largura pelo conteúdo. */
.tabela-acao { padding: 0.35rem 0.7rem; }

/* ==========================================================================
   REGRA GLOBAL: número em coluna usa figura tabular.
   ==========================================================================
   Sem isto o "1" é mais estreito que o "8" e valores empilhados desalinham —
   em qualquer fonte. Vale para campo, célula de tabela, selo e valor de ficha:
   é onde telefone, CNPJ, CEP, medida, cachê, data e horário se comparam de
   uma linha para a outra. Texto corrido segue com figura proporcional, que
   é o certo para leitura. */
.campo-base,
.selecao-base,
.tabela td,
.tabela th,
.lt-valor,
.area-status,
.etiqueta,
.selo-secao,
.campo-qtd,
.row-num,
.texto-pequeno {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
}







/* =========================================================================
   AUXILIARES DE ESTRUTURA
   =========================================================================
   Cada uma destas classes substitui um style="..." que estava repetido pelas
   telas — eram 108 atributos, e o mesmo `color:var(--cor-texto-suave)`
   aparecia em dez arquivos. Trocar a cor do texto de apoio exigia caçar os
   dez; agora é uma linha.

   Não são "utilitárias novas": é o vocabulário que o HTML já usava, com nome.
   ========================================================================= */

.texto-suave { color: var(--cor-texto-suave); }
.texto-secundario { color: var(--cor-secundaria); }
.texto-erro { color: var(--cor-erro-texto); }
.sem-margem { margin: 0; }
.sem-margem-lados { margin-left: 0; margin-right: 0; }
.largura-total { width: 100%; }
.empurra-direita { margin-left: auto; }
.forma-inline { display: inline; }
.forma-inline-bloco { display: inline-block; }
.centro-vertical { align-self: center; }
.sem-acao { cursor: default; }
.entrelinha-larga { line-height: 1.8; }
.fundo-suave { background: var(--cor-superficie-2); }
.icone-pequeno { width: 1.05rem; height: 1.05rem; }
.celula-folgada { padding: var(--e2); }
.rotulo-bloco { display: block; margin-bottom: var(--e1); }
/* Modal de uma pergunta só (um campo, uma confirmação): estreito de propósito,
   para a linha de texto não ficar larga demais para ler. */
.modal-estreito { max-width: 22rem; }

/* Texto que veio de um <textarea>: preserva as quebras que a pessoa digitou. */
.texto-preservado { white-space: pre-wrap; margin-top: var(--e2); }

/* Linha de ajuda debaixo de um campo. */
.ajuda-campo { margin-top: var(--e1); color: var(--cor-texto-suave); }
.ajuda-recuada { margin: var(--e1) 0 0 3.6rem; color: var(--cor-texto-suave); }
.legenda { margin: 0 0 var(--e2); color: var(--cor-texto-suave); }

/* Larguras de campo: três, e não uma por tela. */
.campo-curto { max-width: 7rem; }
.campo-medio { max-width: 20rem; }
.campo-largo { max-width: 32rem; }

/* Texto corrido tem largura de leitura — linha muito longa cansa. */
.limite-leitura { max-width: 52rem; margin: var(--e3) auto; }

/* Lista com marcador: o reset tira de todas, e aqui a gente devolve. */
.lista-marcada { margin: 0; padding-left: 1.1rem; list-style: disc; }
.lista-marcada li { margin-bottom: var(--e1); }

/* Cartão com uma tarja na lateral — o jeito do sistema de dizer "olhe aqui". */
.cartao-marcado { border-left: 4px solid var(--cor-primaria); }
.cartao-marcado-erro { border-left-color: var(--cor-erro); }
.cartao-marcado-aviso { border-left-color: var(--cor-aviso); }

/* Mensagens de ticket: quem falou aparece pela lateral, não pela cor do texto. */
.mensagem-suporte { border-left: 4px solid var(--cor-primaria); }
.mensagem-interna { background: var(--cor-aviso-fundo); border-left: 4px solid var(--cor-aviso); }

/* Situação da conta na tabela do fornecedor. */
.estado-conta { font-weight: var(--peso-forte); }
.estado-trial { color: var(--cor-texto-suave); }
.estado-trial_vencido,
.estado-inadimplente,
.estado-cancelada { color: var(--cor-erro-texto); }

/* Aviso que ocupa a tela sozinho (link expirado, sem permissão). */
.aviso-solto { max-width: 32rem; margin: var(--e7) auto; text-align: center; }
.link-aviso { color: var(--cor-aviso-texto); text-decoration: underline; }
.marca-pendente { background: var(--cor-aviso); }

/* Prévia da logo: sempre sobre a cor base, que é onde ela vai aparecer. */
.logo-previa {
    height: 44px;
    width: auto;
    max-width: 160px;
    object-fit: contain;
    background: var(--cor-primaria);
    padding: 4px 8px;
}

/* Amostra da cor em uso. Não recebe a cor por atributo: ela JÁ é a
   --cor-primaria da página. */
.amostra-cor {
    display: inline-block;
    width: 2.2rem;
    height: 2.2rem;
    background: var(--cor-primaria);
    border: var(--borda-fina) solid var(--cor-borda);
}

/* =========================================================================
   FAIXAS DO SISTEMA — avisos de largura total, no topo de tudo
   ========================================================================= */
.faixa-sistema {
    display: flex;
    gap: var(--e3);
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    padding: var(--e2) var(--e3);
    color: var(--cor-superficie);
    font-size: var(--texto-sm);
    letter-spacing: 0.03em;
}
/* Cópia de trabalho: o app é idêntico ao de produção, e confundir os dois é o
   engano que só se percebe depois de apagar algo.
   Texto corrido, não linha flex: como item de flex, o <strong> do nome do
   banco virava um bloco só dele e a frase quebrava no meio no celular. */
.faixa-sistema-copia {
    background: var(--cor-faixa-copia);
    display: block;
    text-align: center;
}
/* Modo suporte: fica grudada no topo porque vale enquanto durar o acesso. */
.faixa-sistema-suporte {
    background: var(--cor-faixa-suporte);
    position: sticky;
    top: 0;
    z-index: var(--z-barra);
}

/*
 * Duas coisas grudadas em top:0 se empilham no mesmo lugar.
 *
 * A barra de topo passou a grudar por causa do iPhone, e em modo suporte ela
 * cobriria o aviso vermelho — que é justamente o que não pode sumir de vista.
 * Então, quando a faixa de suporte existe, ela fica e a barra volta a rolar:
 * quem está dentro da conta de outra pessoa precisa mais do aviso do que da
 * barra. O esmaecimento do iPhone não é problema aqui — modo suporte é tela
 * de operador, e operador trabalha no computador.
 */
body:has(.faixa-sistema-suporte) .barra-topo {
    position: static;
}
.faixa-sistema strong { font-weight: var(--peso-forte); }

/* Toast que aparece no corpo da página (e não no canto): aviso de e-mail não
   confirmado, formulário recarregado por CSRF. */
.toast-central {
    margin: var(--e3) auto;
    max-width: 60rem;
    display: flex;
    gap: var(--e3);
    align-items: center;
    flex-wrap: wrap;
    justify-content: center;
}

.rodape-legal {
    text-align: center;
    padding: var(--e5) var(--e4) var(--e6);
    font-size: var(--texto-xs);
    color: var(--cor-texto-suave);
}

@media (max-width: 768px) {
input[type="checkbox"] { width: 1.65rem; height: 1.65rem; }

input[type="checkbox"]::after { width: 0.8rem; height: 0.8rem; }

/* No cartão do celular a identificação do link é o título, não mais uma
       linha rótulo/valor: como flex, o nome disputava largura com o escopo e
       quebrava no meio ("Ilumina / dor"). */
table.tabela-cartoes tbody td.cel-link {
        display: block;
        text-align: left;
        padding-bottom: 0.55rem;
        margin-bottom: 0.35rem;
        border-bottom: 2px solid var(--cor-borda);
    }

table.tabela-cartoes tbody td.cel-link::before { display: none; }

td.cel-link strong { font-size: var(--texto-base); }

/* Nome, contato e data/IP são três linhas, não três colunas: como flex
       disputavam a largura e quebravam no meio da palavra. */
table.tabela-cartoes tbody td.cel-visitante { display: block; text-align: left; }

table.tabela-cartoes tbody td.cel-visitante::before {
        display: block;
        margin-bottom: 0.15rem;
    }

/* ---- Navbar recolhível ---- */
.barra-topo-conteudo {
        flex-wrap: wrap;
        gap: 0;
        padding: 0.6rem 1rem;
    }

.barra-menu-btn { display: flex; }

.barra-navegacao {
        display: none;
        flex-basis: 100%;
        flex-direction: column;
        align-items: stretch;
        justify-content: flex-start;
        gap: 0;
        margin-top: 0.5rem;
    }

.barra-navegacao.aberto { display: flex; }

.barra-links {
        flex-direction: column;
        gap: 0;
    }

.barra-links a {
        padding: 0.85rem 0.25rem;
        border-top: 1px solid rgba(255, 255, 255, 0.15);
        font-size: var(--texto-base);
    }

.barra-usuario {
        gap: 0.6rem;
        padding: 0.85rem 0.25rem 0.25rem;
        border-top: 1px solid rgba(255, 255, 255, 0.15);
        justify-content: space-between;
    }

.barra-conta { align-items: flex-start; text-align: left; }

.cartao { padding: 1rem; border-radius: var(--raio); }

/* ---- Formulários: 1 coluna, alvos de toque maiores ---- */
    /* minmax(0,1fr) deixa a coluna encolher abaixo da largura do seletor de data */
.grade-campos { grid-template-columns: minmax(0, 1fr); gap: 0.8rem; }

.campo-base, .selecao-base {
        /* Acima do mínimo de 16px, abaixo do qual o iOS dá zoom sozinho ao
           focar o campo. É medida do aparelho, não degrau da escala. */
        font-size: var(--toque-fonte-minima);
        /*
         * O espaçamento VERTICAL tem de caber dentro de --altura-controle.
         *
         * Com 0.65rem a conta dava 30px de linha + 24,7 de padding + 2 de
         * borda = 56,7px, acima do token (54,15). O input passava a mandar na
         * própria altura, enquanto o <select> — que usa line-height normal e
         * tem altura fixa — ficava nos 54,15. Resultado: campo de texto 2,5px
         * mais alto que o select ao lado, visível onde os dois se encostam,
         * como no Qtd + lista. Só no celular, porque no PC a soma cabe.
         */
        padding: 0.5rem 0.75rem;
    }

input[type="date"].campo-base,
    input[type="time"].campo-base {
        width: 100%;
        max-width: 100%;
    }

/*
 * No celular, botão volta a ter a altura de campo.
 *
 * 44px é o mínimo de toque do iPhone, e 90% do uso está aqui. O aperto que
 * deixa a barra de ações elegante no PC vira erro de dedo na estrada.
 */
:root { --altura-botao: var(--altura-controle); }

.botao-primario, .botao-secundario {
        /* De volta ao corpo do texto: caixa alta pequena demais num alvo de
           toque grande fica perdida no meio do botão. */
        font-size: var(--texto-base);
        padding: 0.5rem 1rem;
        /* flex, não block: ocupa a linha toda igual, mas mantém o rótulo
           centralizado na vertical junto com a altura mínima do controle. */
        display: flex;
        width: 100%;
        align-items: center;
        justify-content: center;
        text-align: center;
        /*
         * Sem aumentar o espaçamento vertical: quem manda na altura é o
         * min-height do token. Com 0.65rem a conta dava 28,5 de linha + 24,7
         * de padding + 2 de borda = 55,2px, e o botão passava a mandar na
         * própria altura — 1px acima do campo de 54,15 logo abaixo dele.
         * Com 0.5rem a soma fica em 49,5, abaixo do token, e o min-height
         * decide. O alvo de toque não encolhe: continua nos 54,15.
         */
        padding: 0.5rem 1rem;
    }

/* botões dentro de barras de ação continuam lado a lado, mas quebram */
.flex.gap-2, .flex.gap-3 { flex-wrap: wrap; }

.flex.gap-2 > .botao-primario, .flex.gap-2 > .botao-secundario,
    .flex.gap-3 > .botao-primario, .flex.gap-3 > .botao-secundario { width: auto; flex: 1 1 auto; }

/* ---- Tabelas em modo "cartão" ---- */
table.tabela-cartoes thead { display: none; }

table.tabela-cartoes tbody tr {
        display: block;
        border: 1px solid var(--cor-borda);
        border-radius: var(--raio);
        margin-bottom: 0.75rem;
        padding: 0.5rem 0.75rem;
        background: var(--cor-superficie);
    }

table.tabela-cartoes tbody td {
        display: flex;
        justify-content: space-between;
        gap: 1rem;
        padding: 0.4rem 0;
        white-space: normal;
        border: 0;
        border-bottom: 1px solid var(--cor-superficie-2);
        text-align: right;
    }

table.tabela-cartoes tbody td:last-child { border-bottom: 0; }

table.tabela-cartoes tbody td::before {
        content: attr(data-rotulo);
        font-weight: 600;
        color: var(--cor-texto-suave);
        text-transform: uppercase;
        font-size: var(--texto-xxs);
        letter-spacing: 0.03em;
        text-align: left;
        flex-shrink: 0;
        align-self: center;
    }

table.tabela-cartoes tbody td:empty { display: none; }

/* coluna de ações: sem rótulo, botões alinhados e com bom alvo de toque */
table.tabela-cartoes tbody td[data-rotulo=""] {
        justify-content: flex-end;
        gap: 0.5rem;
        padding-top: 0.6rem;
        flex-wrap: wrap;
    }

table.tabela-cartoes tbody td[data-rotulo=""]::before { display: none; }

/* 40px fixos deixavam a ação de tabela ABAIXO do mínimo de toque do iPhone
   (44px), justamente no celular. O token já vale 54px aqui — e uma medida
   fixa no meio do caminho só serve para brigar com ele. */
table.tabela-cartoes tbody td[data-rotulo=""] .tabela-acao,
    table.tabela-cartoes tbody td[data-rotulo=""] form { min-height: var(--altura-botao); display: inline-flex; align-items: center; }

table.tabela-cartoes tbody td .campo-base { width: 100%; }

.linha-resumo-texto {
        flex: 1;
        min-width: 0;
        font-weight: 600;
        font-size: var(--texto-base);
        color: var(--cor-primaria);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

.linha-resumo-texto.vazio {
        color: var(--cor-texto-suave);
        font-weight: 500;
        font-style: italic;
    }

.linha-resumo-seta {
        flex: none;
        color: var(--cor-texto-suave);
        font-size: var(--texto-xs);
        transition: transform 0.15s ease;
    }

/* Tabelas comuns que continuam com rolagem lateral */
.tabela-container { -webkit-overflow-scrolling: touch; }

/* Em modo cartão o container não desenha moldura (só o cartão) */
.tabela-container:has(.tabela-cartoes) {
        border: 0;
        border-radius: 0;
        background: transparent;
        overflow: visible;
    }

table.tabela-cartoes tbody tr:last-child { margin-bottom: 0; }

/* Campos não encolhem quando vazios (time/date no iOS ficavam baixinhos) */
input.campo-base, select.campo-base { min-height: 2.85rem; }

textarea.campo-base { min-height: 4.25rem; }

/* ---- Toasts ocupam a largura ---- */
.toast-container { left: 0.75rem; right: 0.75rem; top: 0.75rem; }

.toast { min-width: 0; width: 100%; }

.botao-acao-icone {
        /* 44px é o mínimo de toque, mas os vizinhos usam o token e ficavam
           10px mais altos — três ícones numa fileira, dois tamanhos. O token
           no celular já vale 54px, acima do mínimo. */
        width: var(--altura-botao);
        height: var(--altura-botao);
        justify-content: center;
        padding: 0;
    }

.botao-acao-icone .botao-rotulo { display: none; }

.botao-acao-icone svg { width: 21px; height: 21px; }

/* ---- Modal de opções: botões abaixo do campo ---- */
.modal-janela { max-width: none; }

.modal-corpo .flex.gap-2 { flex-wrap: wrap; }

.modal-janela { max-height: calc(100vh - 1rem); }

.busca-sug-sub { font-size: var(--texto-sm); }
}

@media (max-width: 480px) {
.barra-marca-nome { font-size: var(--texto-sm); letter-spacing: 0.04em; margin-left: 0.4rem; }

.barra-logo-img { height: 30px; }
}

@media print {
#voltar-topo { display: none; }

.barra-topo, .secao-cabecalho .secao-seta, .botao-primario,
    .botao-secundario, .faixa-publica { display: none !important; }
}


/* O campo de nome que procura no cadastro: a caixa de sugestões se pendura
   nele, então ele precisa ser a referência de posição. */
.campo-com-busca { position: relative; }

/* =========================================================================
   BUSCA COM SUGESTÕES
   =========================================================================
   O campo que procura no cadastro e mostra o que achou logo abaixo. Nasceu no
   campo "Local do evento" e hoje serve também aos modais de hotel e de
   fornecedor — por isso subiu de telas.css para cá.

   A caixa é `position: absolute`: o container precisa de `position: relative`
   (é o caso de .campo-local e do .campo-grupo dos modais).
   ========================================================================= */
/* O campo de cidade, que a busca embrulha para poder ancorar a caixa de
   sugestões logo abaixo dele. */
.campo-busca-cidade { position: relative; }

.campo-busca-cidade > input { width: 100%; }

.busca-sugestoes {
    position: absolute;
    top: calc(100% + 0.25rem);
    left: 0;
    right: 0;
    z-index: 60;
    max-height: 15rem;
    overflow-y: auto;
    background: var(--cor-superficie);
    border: 1px solid var(--cor-borda);
    border-radius: var(--raio);
    box-shadow: 0 8px 24px rgba(17, 24, 39, 0.14);
}

.busca-sug {
    display: block;
    width: 100%;
    padding: 0.5rem 0.7rem;
    border: 0;
    border-bottom: 1px solid var(--cor-superficie-2);
    background: none;
    text-align: left;
    cursor: pointer;
    font: inherit;
}

.busca-sug:last-child { border-bottom: 0; }

.busca-sug:hover, .busca-sug.marcada { background: var(--cor-superficie-3); }

/* ---- Rodapé de salvar da seção ----
   A ficha deixou de salvar campo a campo: o que muda fica pendente e vai
   junto no botão. O rodapé só existe quando há o que salvar, e por isso é
   uma barra discreta e não um bloco fixo ocupando tela no celular. */
.secao-rodape {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.75rem 1rem;
    border-top: 1px solid var(--cor-borda-media);
    background: var(--cor-superficie-2);
}
.secao-rodape .secao-pendentes { color: var(--cor-texto-suave); }

/* Campo com alteração ainda não enviada. A borda à esquerda, e não um fundo:
   fundo colorido em vinte campos ao mesmo tempo deixa a seção ilegível. */
.campo-pendente {
    border-left: 3px solid var(--cor-aviso);
}

/* =========================================================================
   Botão inativo — cinza, e o mesmo cinza em toda parte

   O sistema tem três cores de ação e cada uma diz uma coisa:
     roxo     = faça (editar, abrir, salvar, publicar)
     vermelho = destrói (excluir, remover, revogar)
     cinza    = não dá para clicar

   Até aqui a terceira não existia: botão desabilitado ficava idêntico ao
   habilitado, e quem clicava não entendia por que nada acontecia. Pior, dois
   ícones de AÇÃO nasciam cinza e só ficavam roxos no hover — no celular, que
   é 90% do uso, eles pareciam desligados a vida inteira.

   O hover também é neutralizado: botão desligado que reage ao passar o mouse
   promete o que não cumpre.
   ========================================================================= */
.botao-primario:disabled,
.botao-secundario:disabled,
.botao-perigo:disabled,
.botao-icone:disabled,
.botao-icone-acao:disabled,
.botao-acao-icone:disabled,
.botao-lixeira:disabled,
.campo-acao-mini:disabled,
.tabela-acao:disabled,
.botao-mini:disabled,
.botao-link:disabled,
.botao-primario[aria-disabled="true"],
.botao-secundario[aria-disabled="true"],
.tabela-acao[aria-disabled="true"],
.tabela-acao.sem-acao {
    background: var(--cor-desativado-fundo);
    color: var(--cor-desativado-texto);
    border-color: var(--cor-borda);
    cursor: not-allowed;
    box-shadow: none;
}

.botao-primario:disabled:hover,
.botao-secundario:disabled:hover,
.botao-perigo:disabled:hover,
.botao-icone:disabled:hover,
.botao-icone-acao:disabled:hover,
.botao-acao-icone:disabled:hover,
.botao-lixeira:disabled:hover,
.campo-acao-mini:disabled:hover,
.tabela-acao:disabled:hover,
.botao-mini:disabled:hover,
.botao-link:disabled:hover,
.botao-primario[aria-disabled="true"]:hover,
.botao-secundario[aria-disabled="true"]:hover,
.tabela-acao[aria-disabled="true"]:hover,
.tabela-acao.sem-acao:hover {
    background: var(--cor-desativado-fundo);
    color: var(--cor-desativado-texto);
    border-color: var(--cor-borda);
}

/* ---- Bloco de campos com título (fieldset) ----
   Para formulário longo: agrupa o que se confere junto e dá ao olho um ponto
   de parada. Sem isto, trinta e quatro caixas iguais viram uma parede.
   O <legend> é o título de verdade, e não um <h3> solto: leitor de tela
   anuncia o grupo ao entrar em cada campo. */
.bloco-campos {
    border: 1px solid var(--cor-borda-suave);
    border-radius: var(--raio);
    padding: 0.9rem 1rem 1rem;
    margin: 0 0 1rem;
    min-width: 0;   /* fieldset ignora o grid pai sem isto e estoura a largura */
}
.bloco-campos > legend {
    padding: 0 0.4rem;
    margin-left: -0.4rem;
    font-weight: var(--peso-forte);
    color: var(--cor-texto-suave);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: var(--texto-sm);
}
.bloco-campos > legend .etiqueta { text-transform: none; letter-spacing: 0; }

/* ---- Largura mínima do botão de TEXTO ----
   Botões de rótulo curto ("Ver", "Sim", "Editar") ficavam cada um de um
   tamanho, e uma barra com quatro deles parecia desalinhada mesmo estando
   alinhada. Uma largura de piso resolve sem esticar o que é longo.

   Só para quem tem TEXTO: botão que é só ícone é quadrado por definição —
   largura e altura vêm do mesmo token — e 100px o transformaria num
   retângulo com um desenho perdido no meio. Daí o :not(:has(svg)), que o
   sistema já usa noutros lugares. */
.botao-primario:not(:has(svg)),
.botao-secundario:not(:has(svg)),
.tabela-acao:not(:has(svg)) {
    min-width: 100px;
}

/* ---- A lista de campos no modal "atualizar o cadastro?" ----
   A pergunta nomeia a empresa no título e lista aqui o que vai subir. Antes
   ela era feita campo a campo, sem dizer de qual campo falava — três modais
   empilhados para o mesmo fornecedor. */
.lista-campos-cadastro {
    margin: var(--e2) 0 var(--e3);
    padding-left: var(--e4);
    font-size: var(--texto-sm);
}
.lista-campos-cadastro li { margin-bottom: var(--e1); }

/* ---- Clima do dia do evento ----
   A peça aparece em três lugares (ficha do painel, link público e PDF) e por
   isso mora aqui, não em telas.css. O PDF tem o desenho dele em pdf.css, com
   as MESMAS classes: o HTML sai de render_clima_cartao() uma vez só.

   Três estados de alerta, e as cores são as de feedback do sistema — perigo
   é o vermelho de erro, aviso é o âmbar, informação é o azul-petróleo. Alerta
   de vento não inventa paleta própria. */
.bloco-clima { margin-bottom: 1rem; }

.clima-titulo {
    font-size: var(--texto-sm);
    font-weight: var(--peso-forte);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--cor-texto-suave);
    margin: 0 0 var(--e3);
}

/* Ícone, descrição e números numa linha; no celular os números descem.
   O auto do meio é o que empurra os números para a direita sem largura
   fixa — faixa de temperatura e rajada mudam de tamanho a cada cidade. */
.clima-linha {
    display: flex;
    align-items: center;
    gap: var(--e3);
    flex-wrap: wrap;
}

.clima-icone {
    flex: 0 0 auto;
    color: var(--cor-primaria);
}
.clima-icone svg { width: 2.2rem; height: 2.2rem; display: block; }

.clima-tempo {
    display: flex;
    flex-direction: column;
    margin-right: auto;
}
.clima-texto { font-size: var(--texto-md); line-height: var(--entrelinha-curta); }
.clima-lugar { font-size: var(--texto-sm); color: var(--cor-texto-suave); }

.clima-numeros {
    display: flex;
    align-items: baseline;
    gap: var(--e3);
    flex-wrap: wrap;
}
.clima-dado {
    font-size: var(--texto-sm);
    color: var(--cor-texto-suave);
    /* tabular: a faixa "8° / 31°" não dança de largura entre eventos */
    font-variant-numeric: tabular-nums;
}
.clima-temp {
    font-size: var(--texto-md);
    font-weight: var(--peso-forte);
    color: var(--cor-texto-principal);
}

.clima-alertas {
    list-style: none;
    margin: var(--e3) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--e2);
}
/* A barra à esquerda é a mesma linguagem do .cartao-marcado: cor na borda,
   não no fundo inteiro — três alertas empilhados de fundo cheio viram
   semáforo e deixam de ser lidos. */
.clima-alerta {
    padding: var(--e2) var(--e3);
    border-left: var(--borda-grossa) solid var(--cor-borda-media);
    background: var(--cor-superficie-2);
    font-size: var(--texto-sm);
}
.clima-alerta-perigo { border-left-color: var(--cor-erro); background: var(--cor-erro-fundo); }
.clima-alerta-aviso  { border-left-color: var(--cor-aviso-texto); background: var(--cor-aviso-fundo); }
.clima-alerta-info   { border-left-color: var(--cor-info); background: var(--cor-info-fundo); }

.clima-alerta-detalhe { color: var(--cor-texto-suave); }
/* De quem é o alerta, em letra miúda: "INMET" é aviso oficial e pesa
   diferente de um limiar nosso lido da previsão. */
.clima-alerta-fonte {
    font-size: var(--texto-xxs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--cor-texto-fraco);
    white-space: nowrap;
}

.clima-ausente,
.clima-fonte { font-size: var(--texto-xs); color: var(--cor-texto-suave); margin: 0; }
.clima-fonte { margin-top: var(--e3); }

/* ---- O esqueleto, enquanto a previsão não chega ----
   A página desenha isto na hora e o main.js troca pelo cartão. Nenhuma outra
   seção do evento espera por ele.

   A animação é de OPACIDADE, não de gradiente correndo: gradiente pediria
   cores literais (que esta camada não aceita) e, num cartão pequeno, pulsar
   comunica "estou trabalhando" igual, por bem menos. */
.bloco-clima-carregando .clima-esqueleto-barra,
.bloco-clima-carregando .clima-esqueleto-icone {
    display: block;
    background: var(--cor-superficie-3);
    border-radius: var(--raio);
    animation: clima-pulsa 1.4s ease-in-out infinite;
}
.bloco-clima-carregando .clima-esqueleto-icone { width: 2.2rem; height: 2.2rem; }
.clima-esqueleto-texto { width: 9rem; height: var(--texto-md); }
.clima-esqueleto-lugar { width: 12rem; height: var(--texto-sm); margin-top: var(--e1); }
.clima-esqueleto-dado  { width: 5rem;  height: var(--texto-md); }
/* O recado em texto existe para quem usa leitor de tela: barra cinza não se
   ouve, e um cabeçalho seguido de silêncio não diz que algo está vindo. */
.clima-esqueleto-recado { margin-top: var(--e3); }

@keyframes clima-pulsa {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.4; }
}
/* Quem pediu menos movimento no sistema não quer um cartão pulsando: a barra
   fica parada e o recado em texto continua dizendo o que está acontecendo. */
@media (prefers-reduced-motion: reduce) {
    .bloco-clima-carregando .clima-esqueleto-barra,
    .bloco-clima-carregando .clima-esqueleto-icone { animation: none; }
}

/* ---- O cartão na tela larga: uma linha só ----
 *
 * No PC o cartão gastava três linhas (título, conteúdo, hora da consulta)
 * para o que cabe em uma — e num dia sem alerta isso é um bloco alto com
 * pouca informação, bem no topo da ficha, empurrando as seções para baixo.
 *
 * Aqui a seção inteira vira UMA linha: o título à esquerda como rótulo, o
 * tempo e os números no meio, a hora da consulta na ponta direita. Os
 * alertas, quando existem, continuam em linhas próprias — eles são o que se
 * lê com atenção, e espremê-los seria economizar no lugar errado.
 *
 * min-width, e não max: o desenho de celular já está pronto e aprovado, e
 * escrever isto como padrão obrigaria a desfazer tudo lá embaixo.
 */
@media (min-width: 769px) {
    .bloco-clima {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        column-gap: var(--e4);
        /* o padding do .cartao é generoso para um bloco de leitura; aqui é
           uma faixa de uma linha, e a folga vertical de 1,25rem sobrava */
        padding-top: var(--e3);
        padding-bottom: var(--e3);
    }
    .bloco-clima .clima-titulo { margin: 0; }
    .bloco-clima .clima-linha { flex: 1 1 auto; }

    /* Descrição e lugar lado a lado, não empilhados. */
    .bloco-clima .clima-tempo {
        flex-direction: row;
        align-items: baseline;
        column-gap: var(--e2);
        flex-wrap: wrap;
    }

    /*
     * Os separadores entram mais adiante, num ponto de corte próprio — ver
     * logo abaixo deste bloco.
     */
    /* O fio separa GRUPOS, e o ícone é a mesma coisa que a descrição ao lado:
       um traço entre os dois partiria "garoa fraca" no meio. Por isso ele fica
       antes do ícone (separando do título) e antes dos números. */
    /* O volume em mm NÃO ganha fio: ele é a segunda metade do mesmo dado de
       chuva, e separá-lo do "35%" desfaria o par. */
    .bloco-clima .clima-numeros { column-gap: var(--e3); }

    /* A hora da consulta vai para a ponta, onde não disputa leitura. */
    .bloco-clima .clima-fonte { margin: 0 0 0 auto; }
    /* Alerta ocupa a largura toda: é o que se lê com atenção. */
    .bloco-clima .clima-alertas { flex: 1 1 100%; margin-top: var(--e2); }
    /* Ausência de previsão também cabe na linha do título. */
    .bloco-clima .clima-ausente { margin: 0; }
}

@media (max-width: 768px) {
    /*
     * O desenho de celular, pedido pelo dono.
     *
     * Em grade, não em flex: o ícone precisa ir para o CANTO SUPERIOR
     * DIREITO sem sair da ordem do HTML (onde ele vem primeiro, para o leitor
     * de tela anunciar "trovoada" antes dos números). Grade com áreas
     * nomeadas faz isso sem position: absolute, que exigiria reservar altura
     * à mão e quebraria quando a descrição tivesse duas linhas.
     */
    .clima-linha {
        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-areas:
            "tempo  icone"
            "numeros numeros";
        column-gap: var(--e3);
        row-gap: var(--e2);
        align-items: start;
    }
    .clima-tempo   { grid-area: tempo; margin-right: 0; }
    .clima-icone   { grid-area: icone; }
    .clima-numeros { grid-area: numeros; }

    /* A faixa de temperatura fica numa linha só, e a chance de chuva cai
       LOGO ABAIXO dela — é a ordem que o dono pediu, e a que se lê de relance
       com o telefone na mão. O vento acompanha a chuva na mesma linha: são os
       dois números de condição, e separá-los esticaria o cartão sem ganho. */
    .clima-temp { flex: 1 1 100%; }

    /* O VOLUME em mm sai de cena: "80% de chuva · 25 mm" são dois números
       sobre a mesma chuva, e na linha estreita o segundo empurra o vento para
       fora. Quem precisa do volume está no PC ou com a ficha impressa. */
    .clima-chuva-mm { display: none; }

    /* O pé do cartão encolhe: no celular a hora da consulta é nota de rodapé,
       não informação de primeira leitura. */
    .clima-fonte { font-size: var(--texto-xxs); }
}
