h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}
/* ---------------------------------------------------------------------------
   Enquadramento da aplicação

   Sem rolagem na página: só a área das tabelas rola, e só quando precisa
   (overflow:auto). A aplicação fica centralizada horizontalmente na janela.
   --------------------------------------------------------------------------- */
html, body {
    height: 100%;
    margin: 0;
    overflow: hidden;
    overscroll-behavior: none;
    touch-action: pan-x pan-y;
    background: var(--fundo);
    color: var(--textos);
    font-family: "Segoe UI", system-ui, sans-serif;
}

.aplicacao {
    height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* ---------------------------------------------------------------------------
   Portão de tela cheia

   A API de tela cheia exige gesto do usuário — nenhuma página entra sozinha ao
   carregar. Enquanto não estiver em tela cheia, a aplicação some e fica só o
   convite para voltar. Vive em CSS + JS puro, sem Blazor: continua valendo mesmo
   se o circuito cair.
   --------------------------------------------------------------------------- */
/* A aparência é compartilhada por dois portões: o de tela cheia, que é CSS+JS puro, e o
   de licença, que é decisão do servidor e por isso é um componente Blazor. O que os
   distingue é só quando aparecem. */
.portao {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: #1b1b1b;
    color: #f0f0f0;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: calc(18px * var(--fh));
    text-align: center;
    font-size: calc(14px * var(--fw));
}

.portao img { height: calc(192px * var(--fh)); opacity: .92; }   /* 3x */
.portao p { margin: 0; max-width: calc(460px * var(--fw)); line-height: 1.5; color: #c9c9c9; }

#portao-tela-cheia { display: none; }

.portao button {
    font-family: "Segoe UI", system-ui, sans-serif;
    font-size: calc(14px * var(--fw));
    font-weight: 600;
    padding: calc(10px * var(--fh)) calc(22px * var(--fw));
    border: 1px solid #4b8fd0;
    border-radius: 4px;
    background: #0099FF;
    color: #fff;
    cursor: pointer;
}

.portao button:hover { background: #33adff; }

html.sem-tela-cheia .aplicacao { visibility: hidden; }
html.sem-tela-cheia #portao-tela-cheia { display: flex; }

/* ---------------------------------------------------------------------------
   Portão de licença: o dispositivo não está cadastrado, está suspenso, ou não
   tem projeto nenhum concedido. Não é erro nem tela de bloqueio — é a primeira
   coisa que um interessado vê, então tem o convite nas três línguas.
   --------------------------------------------------------------------------- */
/* Acima do portão de tela cheia, e visível mesmo com .aplicacao escondida: um visitante
   fora de tela cheia tem de ver o convite, e não o pedido de tela cheia de um aplicativo
   que ele ainda nem pode abrir. */
.portao-licenca { display: flex; z-index: 101; visibility: visible; }
.portao-licenca[hidden] { display: none; }

/* Cadastro de dispositivo */
.portao-cadastro input {
    font-family: "Segoe UI", system-ui, sans-serif;
    font-size: calc(18px * var(--fw));
    letter-spacing: .12em;
    text-align: center;
    text-transform: uppercase;
    padding: calc(8px * var(--fh)) calc(12px * var(--fw));
    width: calc(240px * var(--fw));
    border: 1px solid #4b8fd0;
    border-radius: 4px;
    background: #111;
    color: #f0f0f0;
}

.portao-cadastro button:disabled { opacity: .6; cursor: default; }
.portao-cadastro .mensagem { min-height: 3em; }
.portao-cadastro .mensagem.erro { color: #ff8a8a; }
.portao-cadastro .mensagem.sucesso { color: #7fd97f; }

/* Link discreto do convite, para o cliente que abriu num navegador sem a marca local.
   visibility: visible pelo mesmo motivo do .portao-licenca: fora de tela cheia a
   .aplicacao inteira fica com visibility: hidden, e sem isto o link herdava a regra —
   existia na página, mas invisível e sem receber clique, e quem estava sem a marca
   local não tinha como entrar. */
.licenca-ja-cliente {
    visibility: visible;
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(18px * var(--fh));
    z-index: 102;
    text-align: center;
    color: #8a8a8a;
    font-size: calc(12px * var(--fw));
    text-decoration: none;
}

.licenca-ja-cliente:hover { color: #c9c9c9; text-decoration: underline; }

/* Motivo da última tentativa de entrada, logo acima do link */
.licenca-motivo {
    visibility: visible;
    position: fixed;
    left: 10%;
    right: 10%;
    bottom: calc(44px * var(--fh));
    z-index: 102;
    margin: 0;
    text-align: center;
    color: #ff8a8a;
    font-size: calc(13px * var(--fw));
}

.portao-licenca .convite {
    display: flex;
    flex-direction: column;
    gap: calc(6px * var(--fh));
}

.portao-licenca .convite p:last-of-type { margin-top: calc(10px * var(--fh)); }

.portao-licenca a {
    color: #0099FF;
    text-decoration: none;
    font-weight: 600;
    font-size: calc(15px * var(--fw));
}

.portao-licenca a:hover { text-decoration: underline; }

/* ---------------------------------------------------------------------------
   Fatores do Dimensiona_objetos(): --fw = largura/1280, --fh = altura/720.
   Publicados por capacitool.js a cada redimensionamento. Os valores abaixo são
   só o padrão até o script rodar.
   --------------------------------------------------------------------------- */
:root {
    --fw: 1;
    --fh: 1;
}

/* ---------------------------------------------------------------------------
   Tamanho das grades, num lugar só.

   A grade é a única parte da aplicação em tamanho fixo — o resto acompanha
   --fw/--fh. 1,35 leva a célula dos 89x32 do SGrid para cerca de 120x43: foi
   pedido que ela ficasse maior sem passar a acompanhar a janela.

   --gz é o fator efetivo, imune ao zoom: "fixo em pixel CSS" não é fixo na tela,
   porque afastar a página encolhe o pixel CSS. Medido na máquina do usuário, com
   a janela em 1920 físicos e zoom em 37,5%, a célula de 89px CSS virava 33px na
   tela enquanto o cromo continuava certo — --fw sai da innerWidth, que o zoom
   infla, e cresce na mesma medida em que o pixel encolhe. Multiplicando por --pz
   (1/devicePixelRatio, publicado por capacitool.js), a célula ocupa sempre os
   mesmos pixels físicos; com zoom em 100% o fator é 1 e nada muda.

   Está na raiz, e não dentro de Grade.razor.css, porque a tabela de inversões do
   Rebalanceamento tem marcação própria e precisa das mesmas medidas: as duas
   aparecem lado a lado e a célula tem de ser do mesmo tamanho nas duas. Mudar
   aqui move as duas juntas — fonte, célula e respiro andam pelo mesmo fator,
   então a proporção não se perde.

   14 colunas a 120px dão 1680px, que ainda cabem sem rolagem horizontal numa
   janela de 1920. Acima de 1,35 a tabela de 33x14 passa a rolar mesmo lá.
   --------------------------------------------------------------------------- */
:root {
    --escala-grade: 1.35;
    --gz: calc(var(--escala-grade) * var(--pz, 1));

    /*
       Largura mínima da célula, a mesma nas duas grades.

       Era 10ch, que comporta "9999,9999" sem cortar — 9 dígitos tabulares mais o
       separador. Só que ch é a largura do "0" na fonte do ELEMENTO, e a tabela de
       inversões é negrito (gridinversion.Font_weight = FontWeights.Bold): o mesmo
       10ch dava 85,4px lá contra 80,1px na grade, e as duas células saíam com
       larguras diferentes lado a lado.

       Em em o valor não depende do peso. 5,39em é exatamente o que 10ch media na
       grade a 14,85px (8,005px por dígito): ela não muda de tamanho nenhum, e a de
       inversões passa a casar com ela.

       O 16px do respiro é o único trecho que precisa do fator: o em já acompanha a
       fonte, que é medida em --gz.
    */
    --celula-largura: calc(5.39em + 16px * var(--gz));
}

/* ---------------------------------------------------------------------------
   Tema claro e escuro

   No UWP a troca de tema faz duas coisas. A primeira é
   `frameworkElement.RequestedTheme = ElementTheme.Dark/Light`, que manda o WinUI
   repintar tudo o que usa os pincéis do sistema — fundo da página, textos, botões.
   A segunda é Cria_cores_fixas(), que declara à mão as cores que o app não deixa
   para o sistema decidir.

   Não há RequestedTheme aqui, então as duas viram a mesma coisa: os RGBs que o
   original declara, publicados como variáveis e usados em toda a folha de estilo.
   Os cinco primeiros são exatamente os de Cria_cores_fixas():

       --fundo          MainPage.xaml.cs:649    #FFFFFF / #000000
       --textos         MainPage.xaml.cs:650    #000000 / #FFFFFF
       --botao          MainPage.xaml.cs:651    #F5F5F5 / #323232
       --borda          cores_fixas[10]         #7F7F7F / #333333
       --fundo-grade    cores_fixas[14]         #F3F3F3 / #202020

   Os cinco últimos não têm equivalente no UWP porque lá quem os fornecia era o
   pincel do sistema: separador fino, texto secundário, realce de passagem do ponteiro,
   cor de ação e cor de erro. Ficam derivados dos primeiros, para os dois temas
   continuarem coerentes.

   A classe entra no <html> por capacitoolAplicarTema, chamada antes de o Blazor
   subir — assim a primeira pintura já é a do tema guardado, sem piscar em claro.
   --------------------------------------------------------------------------- */
:root {
    /* pedido: nada de branco puro no fundo do tema claro — #F3F3F3 no lugar de #FFFFFF */
    --fundo: #F3F3F3;
    --textos: #000000;
    --botao: #F5F5F5;
    --borda: #7F7F7F;
    --fundo-grade: #F3F3F3;

    --linha: #C8C8C8;
    --textos-fracos: #555555;
    --realce: #E9F2FB;
    --acao: #2B6CB0;
    --erro: #B00020;

    /* o que o navegador desenha sozinho: barra de rolagem, cursor, preenchimento */
    color-scheme: light;
}

html.tema-escuro {
    /* pedido: nada de preto puro no fundo do tema escuro — #202020 no lugar de #000000 */
    --fundo: #202020;
    --textos: #FFFFFF;
    --botao: #323232;
    --borda: #333333;
    --fundo-grade: #202020;

    --linha: #3C3C3C;
    --textos-fracos: #A8A8A8;
    --realce: #10314E;
    --acao: #4FA8FF;
    --erro: #FF6B6B;

    color-scheme: dark;
}

/* ---------------------------------------------------------------------------
   Botões e caixas

   O UWP não estiliza nenhum dos dois: eles saem do tema do sistema, e é o
   RequestedTheme que os acompanha. Aqui o navegador faria o mesmo com o esquema
   dele, que não é o da aplicação — daí a regra única, que vale para os botões e
   caixas de todos os componentes. Quem precisa de cor própria (o bt_placa_med
   azul, os ícones de tema e idioma) usa classe, que ganha destas por especificidade.
   --------------------------------------------------------------------------- */
button, input, select, textarea {
    color: var(--textos);
    font-family: inherit;
}

button {
    background: var(--botao);
    border: 1px solid var(--linha);
}

button:hover:not(:disabled) { background: var(--realce); }

input, textarea {
    background: var(--fundo);
    border: 1px solid var(--linha);
}

/* accent-color pinta o "marcado" da caixa de seleção nativa, no azul da fase A */
input[type="checkbox"] { accent-color: #0099FF; }
