﻿:root {
    /* ---------------------------------------------------------------
       Design tokens da PLATAFORMA.

       Estes nomes (--color-*, --font-*, --radius-*) continuam existindo
       porque todo o resto deste arquivo já os consome. O que mudou: eles
       não guardam mais hex próprio — são um apelido para os tokens da
       identidade da Tick's, definidos em wwwroot/css/ticks-tokens.css.
       Para mudar a marca, edite lá, não aqui.

       O site do cliente NÃO passa por aqui: as cores dele vêm inline do
       C# (BlockColors.Resolve / LayoutBackground.ToCssBackground), e o
       que o preview herdava desta lista foi isolado nas variáveis
       --preview-* (ver ticks-tokens.css e a seção do preview abaixo).
       --------------------------------------------------------------- */

    /* Typography — uma família só para a plataforma inteira. */
    --font-heading: var(--tk-font);
    --font-body: var(--tk-font);

    /* Neutros — agora quentes, não mais cinza-azulado: a identidade da
       Tick's é creme + verde, e um cinza frio por cima disso suja o
       creme. Nada de branco puro nem preto puro em lugar nenhum.
       --color-bg-alt (fundo de seção) virou a areia da marca. */
    --color-bg: var(--tk-bg);
    --color-bg-alt: var(--tk-sand);
    --color-white: var(--tk-surface);
    --color-white-rgb: 255, 253, 248;
    --color-text: var(--tk-ink);
    --color-text-muted: var(--tk-muted);
    --color-border: var(--tk-line);
    /* Superfície escura (topo, rodapé, faixas de destaque) = verde da
       marca. Era um quase-preto neutro. */
    --color-ink: var(--tk-green);
    --color-ink-rgb: 23, 69, 42;
    --color-ink-deep: #0E2D1B;
    --color-ink-deep-rgb: 14, 45, 27;
    --color-glow: var(--color-accent);
    /* Objeto que precisa se destacar POR CIMA da superfície verde escura
       (ex.: a maquete de página na home) — um verde mais claro, nunca um
       cinza, para não abrir um buraco frio no meio da faixa verde. */
    --color-surface-raised: #24583A;
    --color-surface-raised-rgb: 36, 88, 58;

    /* Paleta da marca.

       Regra funcional, não decorativa:
         laranja = o que o usuário está fazendo AGORA (botão principal,
                   campo em foco, passo atual, bloco selecionado, tick
                   marcado);
         verde   = o que já está RESOLVIDO (passo concluído, validação
                   ok, item salvo, títulos).

       --color-primary-dark é o laranja escurecido que passa no contraste
       como TEXTO. O --color-primary puro nunca é cor de letra. */
    --color-primary: var(--tk-orange);
    --color-primary-rgb: 242, 107, 29;
    --color-primary-mid: #E8862F;
    --color-primary-dark: var(--tk-orange-text);
    --color-primary-light: #F79A5C;
    --color-primary-tint: var(--tk-sand);

    /* O acento da plataforma é o verde da marca: é ele que marca o que
       já está resolvido e colore títulos e ícones. */
    --color-accent: var(--tk-green);
    --color-accent-rgb: 23, 69, 42;
    --color-accent-light: #2E6B44;

    --color-highlight: var(--tk-green);
    --color-highlight-rgb: 23, 69, 42;

    /* Feedback. "Sucesso" é o próprio verde da marca — a identidade já
       usa verde como "resolvido", então um segundo verde só competiria
       com ele. O vermelho de erro foi aquecido para conviver com o
       creme sem parecer um alerta de sistema operacional. */
    --color-success: var(--tk-green);
    --color-success-rgb: 23, 69, 42;
    --color-danger: #A32B1E;
    --color-danger-rgb: 163, 43, 30;

    /* Decorative one-offs (not part of the themeable brand palette —
       e.g. the lightbulb icon's warm glow should stay warm regardless
       of theme) */
    --color-bulb-glow-rgb: 255, 214, 64;

    /* Superfícies que eram degradê.

       A identidade da Tick's não usa gradiente na interface. Os três
       nomes continuam porque muitas regras deste arquivo os aplicam em
       `background:` — mas agora carregam uma cor chapada. Assim nenhuma
       regra precisou ser reescrita uma a uma, e não sobra degradê em
       lugar nenhum da plataforma. */
    /* Superficie da marca = verde. O laranja e reservado para "o que o
       usuario esta fazendo agora" e aparece so onde isso for verdade,
       nunca como fundo de uma area grande. */
    --gradient-brand: var(--tk-green);
    --gradient-dark: var(--tk-green);
    --gradient-ink-accent: var(--tk-green);

    /* Sombras. Uma só, discreta, e reservada ao que flutua sobre o
       resto (menu suspenso, popover, modal). --shadow-strong deixou de
       ser "mais pesada" e virou a mesma sombra: a identidade não tem
       dois níveis de elevação. */
    --shadow-color-rgb: 23, 69, 42;
    --shadow-color-strong-rgb: 23, 69, 42;
    --shadow-color-nav-rgb: 23, 69, 42;
    --shadow-soft: var(--tk-shadow-float);
    --shadow-strong: var(--tk-shadow-float);

    /* Forma. Dois raios, nunca um só: superfícies (card, painel) a 12px,
       controles (campo, botão) a 6px — estes últimos aplicados na seção
       de botões e campos mais abaixo. */
    --radius-lg: var(--tk-radius-card);
    --radius-md: var(--tk-radius-card);
    --radius-field: var(--tk-radius-field);
    --ease: var(--tk-ease);
}

html, body {
    font-family: var(--font-body);
    color: var(--color-text);
    background: var(--color-bg);
    scroll-behavior: smooth;
}

/* ---------------------------------------------------------------------
   Tipografia da plataforma — Instrument Sans.

   Corpo 400/16px com entrelinha 1.6; título 700, entrelinha 1.1 e
   letter-spacing negativo (a Instrument Sans é larga em corpo grande, e
   fechar o espaçamento é o que faz o título "virar bloco" em vez de
   esparramar). Rótulo e botão em 500 — peso intermediário, sem caixa
   alta.
   --------------------------------------------------------------------- */
body {
    font-size: 16px;
    font-weight: 400;
    line-height: 1.6;
}

h1, h2, h3, h4, h5, h6, .display-font {
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.1;
}

label,
.form-group label,
.btn,
button {
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
}

/* Injected by site.js's initPageLoadingIndicator on every page (loaded
   globally, not just on the marketing site) — a thin bar that creeps
   toward (never quite reaching) 90% the instant an outbound link is
   clicked, so a real full-page navigation — e.g. #solicitar's "Continuar"
   into an [Authorize]-gated route while signed out, which redirects
   through /login and can take the better part of a second — reads as
   "loading" instead of "frozen". No JS-driven completion state: the whole
   point is that the browser replaces this page (bar included) once the
   next one is ready, so the animation never has to know when that happens. */
[data-page-loading-bar] {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0;
    background: var(--tk-orange);
    z-index: 9999;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
}

[data-page-loading-bar].is-active {
    opacity: 1;
    animation: page-loading-progress 4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes page-loading-progress {
    0% { width: 0%; }
    15% { width: 35%; }
    40% { width: 60%; }
    100% { width: 88%; }
}

@media (prefers-reduced-motion: reduce) {
    [data-page-loading-bar].is-active {
        animation: none;
        width: 60%;
    }
}

/* Paired with the inline head script in App.razor: keeps the page blank for
   the brief instant between "hash says #solicitar/#sobre-nos" and "the
   overlay script has actually opened it", instead of flashing the normal
   homepage first. */
html.pending-hash-overlay body {
    visibility: hidden;
}

h1, h2, h3, h4, h5, .display-font {
    font-family: var(--font-heading);
}

/* ---------- Shared building blocks (used across every page) ---------- */
.section-head {
    text-align: center;
    max-width: 640px;
    margin: 0 auto 3rem;
}

/* Rótulo pequeno acima de um título. Usava o laranja puro como cor de
   letra sobre o creme: 2,66:1, reprova no contraste. Passou para o
   laranja escurecido (--tk-orange-text, 4,54:1). Caixa alta removida. */
.eyebrow {
    display: inline-block;
    color: var(--tk-orange-text);
    font-weight: 500;
    /* 0.85rem = 13.6px era pequeno demais para um rotulo colorido. */
    font-size: 0.95rem;
    letter-spacing: normal;
    margin-bottom: 0.6rem;
}

/* Subtitulo de secao. Era so "cor secundaria", sem tamanho: herdava
   16px e, em texto centralizado e largo, lia como apagado. Um degrau
   acima do corpo e a cor de tinta suavizada dao a mesma hierarquia sem
   custar legibilidade — e o clamp evita que encolha no celular. */
.section-subtitle {
    color: var(--tk-muted);
    font-size: clamp(1rem, 1.1vw, 1.125rem);
    line-height: 1.6;
    margin: 0;
}

.hero-actions {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.page-shell {
    display: flex;
    flex-direction: column;
}

/* The [data-tilt] hover effect (initTilt in site.js) sets a fresh
   perspective()+rotateX/rotateY transform on every mousemove frame —
   without these hints, Chromium/WebKit re-rasterize the card's text at
   an angle each frame instead of compositing a single GPU layer, which
   reads as the text going blurry while the card tilts. */
[data-tilt] {
    will-change: transform;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

/* ---------- Shared "request flow" page shell (Solicitar*.razor) ---------- */
.request-shell {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - 4rem);
}

/* Decorative shapes filling the empty side gutters beside a centered
   form/panel on wide screens. Purely cosmetic (aria-hidden), and hidden
   below 1100px where the gutters disappear and shapes would overlap
   the content. */
.request-decor {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}

.decor-shape {
    position: absolute;
    top: var(--decor-top, 50%);
    left: var(--decor-left, auto);
    right: var(--decor-right, auto);
    width: var(--decor-size, 80px);
    height: var(--decor-size, 80px);
    background: rgba(var(--decor-color, var(--color-primary-rgb)), var(--decor-alpha, 0.1));
    will-change: transform;
}

.decor-circle {
    border-radius: 50%;
}

.decor-hexagon {
    clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
}

.decor-triangle {
    clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
}

.decor-pentagon {
    clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
}

@media (max-width: 1100px) {
    .request-decor {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .decor-shape {
        display: none;
    }
}

/* ---------- Shared form primitives (Solicitar*.razor) ---------- */
.request-form {
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: clamp(1.5rem, 4vw, 2.5rem);
    box-shadow: var(--shadow-soft);
}

.request-form .btn {
    width: 100%;
    margin-top: 0.5rem;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-bottom: 1.5rem;
}

.form-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
}

.form-row-pair {
    grid-template-columns: repeat(2, 1fr);
    margin-top: 0.6rem;
}

.form-group label {
    font-weight: 600;
    font-size: 0.92rem;
    color: var(--color-text);
}

.field-hint {
    color: var(--color-text-muted);
    font-size: 0.85rem;
    margin: 0;
    line-height: 1.5;
}

@media (max-width: 640px) {
    .form-row {
        grid-template-columns: 1fr;
    }
}

/* Blazor's built-in <InputText>/<InputSelect>/<InputTextArea>/
   <ValidationMessage> components — used by any form on the site, for
   the automatic valid/invalid CSS classes and aria-invalid they add —
   don't forward a page's CSS-isolation scope attribute onto the
   element they render (same gap as <NavLink> not forwarding it onto
   its <a>). Scoped rules targeting them silently never match, so this
   styling has to live here instead of in a per-page .razor.css file. */
.form-control,
.form-select {
    font-family: inherit;
    font-size: 0.95rem;
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--color-border);
    border-radius: var(--tk-radius-field);
    background: var(--color-white);
    color: var(--color-text);
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.form-control:focus,
.form-select:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.15);
}

/* Applied automatically once EditContext has a validation message for
   the field — covers a submit with untouched required fields, not
   just ones the user typed into and left invalid. */
.form-control.invalid,
.form-select.invalid {
    border-color: var(--color-danger);
    background: rgba(var(--color-danger-rgb), 0.04);
}

.form-control.invalid:focus,
.form-select.invalid:focus {
    border-color: var(--color-danger);
    box-shadow: 0 0 0 3px rgba(var(--color-danger-rgb), 0.18);
}

/* Positive counterpart to .invalid above — once a touched field passes
   validation, confirm it with green instead of just going quiet/neutral. */
.form-control.valid.modified,
.form-select.valid.modified {
    border-color: var(--color-success);
    background: rgba(var(--color-success-rgb), 0.06);
}

.form-control.valid.modified:focus,
.form-select.valid.modified:focus {
    border-color: var(--color-success);
    box-shadow: 0 0 0 3px rgba(var(--color-success-rgb), 0.18);
}

textarea.form-control {
    resize: vertical;
    min-height: 8rem;
    line-height: 1.5;
}

.field-error {
    color: var(--color-danger);
    font-size: 0.82rem;
}

a, .btn-link {
    color: var(--color-primary);
}

/* ---------------------------------------------------------------------
   Botões e campos.

   Raio de 6px: botão e campo são controles, não superfícies. Card e
   painel continuam em 12px (--radius-md).
   --------------------------------------------------------------------- */
.btn,
.form-control,
.form-select,
input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="datetime-local"],
input[type="date"],
select,
textarea {
    border-radius: var(--tk-radius-field);
}

/* Botão primário: laranja chapado com texto na cor de tinta.

   O texto NÃO é creme nem branco: creme sobre este laranja dá 2,66:1 e
   branco 3,05:1 — os dois reprovam em AA. A tinta #2B2A26 dá 4,72:1,
   medido com o ContrastChecker do projeto. Sem degradê e sem sombra
   colorida: a identidade não usa nenhum dos dois. */
/* Os estados "pressionado" (:active) e "desabilitado" (:disabled) do
   Bootstrap NAO leem as propriedades acima: leem as variaveis
   --bs-btn-active-* e --bs-btn-disabled-*, que no .btn-primary padrao
   valem o azul #0a58ca / #0d6efd. Como so normal/hover/foco eram
   cobertos, o botao ficava azul ao ser clicado e, pior, continuava azul
   enquanto estivesse desabilitado — e o assistente desabilita os botoes
   durante cada transicao de etapa. Redefinir as variaveis (em vez de
   brigar por especificidade com `:not(.btn-check) + .btn:active`) cobre
   os dois estados de uma vez. */
.btn-primary {
    --bs-btn-active-color: var(--tk-ink);
    --bs-btn-active-bg: var(--color-primary-light);
    --bs-btn-active-border-color: var(--color-primary-light);
    --bs-btn-disabled-color: var(--tk-ink);
    --bs-btn-disabled-bg: var(--tk-orange);
    --bs-btn-disabled-border-color: var(--tk-orange);
    color: var(--tk-ink);
    background: var(--tk-orange);
    border: 2px solid var(--tk-orange);
    box-shadow: none;
    transition: background 0.2s var(--ease), border-color 0.2s var(--ease);
}

.btn-primary:hover,
.btn-primary:focus {
    color: var(--tk-ink);
    background: var(--color-primary-light);
    border-color: var(--color-primary-light);
    transform: none;
    box-shadow: none;
}

/* Botão secundário: fundo transparente, borda de 2px e texto em verde —
   o verde da marca, nunca o laranja, para não competir com a ação
   principal que está ao lado. */
.btn-outline-primary {
    --bs-btn-active-color: var(--tk-green);
    --bs-btn-active-bg: var(--tk-green-soft);
    --bs-btn-active-border-color: var(--tk-green);
    --bs-btn-disabled-color: var(--tk-green);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--tk-green);
    color: var(--tk-green);
    border: 2px solid var(--tk-green);
    background: transparent;
    transition: background 0.2s var(--ease), color 0.2s var(--ease);
}

.btn-outline-primary:hover,
.btn-outline-primary:focus {
    color: var(--tk-green);
    background: var(--tk-green-soft);
    border-color: var(--tk-green);
}

/* Anel de foco. Era o azul padrão do Bootstrap sobre branco puro — duas
   coisas que a identidade não usa. Foco é "o que o usuário está fazendo
   agora", então é laranja, sobre a superfície creme. */
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    outline: none;
    /* Laranja porque foco e "acontecendo agora". O fio verde por fora
       existe por contraste: laranja sobre creme da 2,66:1, abaixo dos
       3:1 exigidos para um indicador de interface — o verde (9,56:1) e
       quem torna o anel visivel em qualquer fundo claro. */
    box-shadow: 0 0 0 2px var(--tk-surface),
                0 0 0 4px var(--tk-orange),
                0 0 0 5px var(--tk-green);
}

.content {
    padding-top: 0;
}

h1:focus {
    outline: none;
}

/* Campo validado = resolvido = verde da marca. */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--tk-green);
}

.invalid {
    outline: 1px solid var(--color-danger);
}

.validation-message {
    color: var(--color-danger);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, var(--color-danger);
    padding: 1rem 1rem 1rem 3.7rem;
    color: var(--tk-surface);
    border-radius: var(--tk-radius-card);
}

    /* Estava em inglês e sem saída para quem lê. */
    .blazor-error-boundary::after {
        content: "Algo deu errado nesta parte da tela. Recarregue a página para continuar."
    }

.darker-border-checkbox.form-check-input {
    border-color: var(--tk-line);
}

/* Laranja escurecido sobre a AREIA da 3,73:1 — reprova. Nas seções de
   fundo areia o rótulo e o link usam o verde da marca (7,85:1). Mesma
   regra já valia para link; o rótulo .eyebrow tinha escapado, e é
   justamente ele que abre as seções "Como funciona" e "Nossa missão". */
.section.alt .eyebrow,
.about-mission .eyebrow,
.steps-section .eyebrow,
.section.alt a:not(.btn),
.about-mission a:not(.btn) {
    color: var(--tk-green);
}

.section.alt a:not(.btn),
.about-mission a:not(.btn) {
    text-decoration: underline;
}

/* A logo sobre superfície verde escura: o check verde desapareceria no
   fundo. Vira creme, mantendo a caixa em laranja. Variável de custom
   property, então atravessa o isolamento de CSS do componente
   (TicksLogo.razor.css) sem precisar de ::deep. */
.auth-brand-panel,
.simple-footer,
.cta-footer-inner {
    --ticks-logo-check: var(--tk-bg);
}

/* =====================================================================
   A CAIXA — elemento central da identidade da Tick's
   =====================================================================
   O checkbox da interface é o mesmo desenho da caixa-check da logo:
   cantos de 6px, borda de 2px, e o check verde saindo pelo canto
   superior direito quando marcado.

   Marcado = laranja, porque marcar é uma ação do usuário. O check por
   cima é verde, a cor do que já está resolvido.

   Como funciona: o <input> vira só a caixa (appearance: none), e o
   <svg class="tk-check"> logo ao lado dele desenha o traço. O SVG é
   puxado para cima da caixa por margem negativa — não por posição
   absoluta — para não precisar de um elemento embrulhando os dois.

   A matemática do alinhamento: no viewBox de 40, a caixa ocupa 23
   unidades (57,5%). Para ela cair exatamente sobre um input de 1.15em,
   o SVG precisa ter 1.15 / 0.575 = 2em. Daí a margem de -1.325em
   (largura do input + os 8,75% de folga à esquerda do viewBox) e o
   deslocamento de -0.15em, que faz os dois centros coincidirem.
   ===================================================================== */
input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    flex: none;
    width: 1.15em;
    height: 1.15em;
    border: 2px solid var(--tk-green);
    border-radius: var(--tk-radius-field);
    background: var(--tk-surface);
    vertical-align: middle;
    cursor: pointer;
    transition: background 0.2s var(--tk-ease), border-color 0.2s var(--tk-ease);
}

/* A borda continua VERDE quando marcado. Se ela virasse laranja junto
   com o preenchimento, a caixa inteira ficaria em 2,66:1 contra o creme —
   abaixo dos 3:1 que a WCAG pede para um elemento de interface. A borda
   verde (9,56:1) e o que garante o contorno visivel. */
input[type="checkbox"]:checked {
    background: var(--tk-orange);
    border-color: var(--tk-green);
}

.tk-check {
    width: 2em;
    height: 2em;
    margin-left: -1.325em;
    margin-right: 0.35em;
    position: relative;
    top: -0.15em;
    vertical-align: middle;
    overflow: visible;
    pointer-events: none;
    flex: none;
}

.tk-check path {
    fill: none;
    stroke: var(--tk-green);
    stroke-width: 5.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    /* O traço mede ~42,5 unidades; 44 cobre com folga. Escondido por
       padrão (deslocamento igual ao comprimento) e "desenhado" ao
       marcar. */
    stroke-dasharray: 44;
    stroke-dashoffset: 44;
}

input[type="checkbox"]:checked + .tk-check path {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 250ms var(--tk-ease);
}

/* Quem pediu menos movimento no sistema vê o check aparecer pronto, sem
   o traço sendo desenhado. */
@media (prefers-reduced-motion: reduce) {
    input[type="checkbox"]:checked + .tk-check path {
        transition: none;
    }

    input[type="checkbox"] {
        transition: none;
    }
}

.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;
}

/* ---------- Scroll-reveal engine (used across pages) ---------- */
[data-reveal] {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
    will-change: opacity, transform;
}

[data-reveal].is-visible {
    opacity: 1;
    transform: translateY(0);
}

[data-reveal-delay="1"] { transition-delay: 0.08s; }
[data-reveal-delay="2"] { transition-delay: 0.16s; }
[data-reveal-delay="3"] { transition-delay: 0.24s; }
[data-reveal-delay="4"] { transition-delay: 0.32s; }
[data-reveal-delay="5"] { transition-delay: 0.4s; }

/* Opacity-only variant of the reveal engine, for elements (like the
   semicircle icons) whose `transform` is already busy positioning them
   and can't also carry the reveal's slide-in offset. */
[data-reveal-fade] {
    opacity: 0;
    transition: opacity 0.6s var(--ease);
    will-change: opacity;
}

[data-reveal-fade].is-visible {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    [data-reveal] {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }

    [data-reveal-fade] {
        opacity: 1 !important;
        transition: none !important;
    }
}

/* ---------- Site builder (etapa "Criando" do /solicitar/site) ----------
   Shared across every Components/SiteBuilder/*.razor component — kept here
   instead of per-component .razor.css because they're all one cohesive UI
   and several classes (.item-grid, .add-item-btn) are reused identically
   across module editors. */
.module-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 2rem;
}

/* The same chips inside a form (ChipChoice): a row of options under a label,
   not a whole screen's main choice — closer together, no big gap below. */
.module-picker.is-compact {
    gap: 0.5rem;
    margin-bottom: 0;
}

.module-picker.is-compact .module-chip {
    padding: 0.45rem 0.9rem;
    font-size: 0.86rem;
}

.module-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 1rem;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-white);
    color: var(--color-text-muted);
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.25s var(--ease), border-color 0.25s var(--ease), color 0.25s var(--ease);
}

.module-chip-dot {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background: var(--color-border);
    transition: background 0.25s var(--ease);
}

.module-chip.is-enabled {
    background: rgba(var(--color-primary-rgb), 0.08);
    border-color: rgba(var(--color-primary-rgb), 0.35);
    color: var(--color-primary-dark);
}

.module-chip.is-enabled .module-chip-dot {
    background: var(--tk-orange);
}

/* Staggered "pop" entrance for "Quais páginas você vai querer?" — each chip
   (ModulePicker's catalog ones, SolicitarSite.razor's own custom-layout
   ones, and the "+ Adicionar página" button) sets its own animation-delay
   inline via PageChipStagger.ChipDelayStyle, using one continuous index
   across all three so the whole row reads as a single staggered sequence
   rather than two separate ones. opacity: 0 as the base state (not just in
   the 0% keyframe) matters here — without it, an element would flash fully
   visible for whatever the animation-delay is before the animation itself
   ever starts. */
.page-chip-pop {
    opacity: 0;
    animation: page-chip-pop 0.45s var(--ease) both;
}

@keyframes page-chip-pop {
    0% { opacity: 0; transform: scale(0.4); }
    60% { opacity: 1; transform: scale(1.08); }
    100% { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .page-chip-pop {
        opacity: 1;
        animation: none;
        transform: none;
    }
}

.module-section {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    margin-bottom: 1.25rem;
    background: var(--color-white);
}

/* "Preencha o conteúdo do seu site" (SolicitarSite.razor) shows exactly one
   of these at a time now (its own page-by-page walk, like "Qual o conteúdo
   da sua página") — tighter chrome around the single visible editor fits
   more of its actual fields on screen without scrolling. */
.module-section.is-compact > summary {
    padding: 0.6rem 0.9rem;
}

.module-section.is-compact .module-section-body {
    padding: 0.7rem 0.9rem 0.85rem;
}

.module-section.is-compact .module-settings-popover {
    padding: 0.65rem 0.9rem;
}

.module-section > summary {
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.1rem 1.4rem;
    cursor: pointer;
    font-family: var(--font-heading);
    font-weight: 700;
}

.module-section > summary::-webkit-details-marker {
    display: none;
}

.module-section-chevron {
    color: var(--color-text-muted);
    transition: transform 0.25s var(--ease);
    flex-shrink: 0;
}

.module-section[open] .module-section-chevron {
    transform: rotate(180deg);
}

.module-section-title-row {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.module-settings-gear {
    border: 1px solid var(--color-border);
    background: var(--color-white);
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.35rem 0.6rem;
    border-radius: var(--radius-md);
    opacity: 0.85;
    box-shadow: var(--shadow-soft);
    transition: opacity 0.2s var(--ease), background 0.2s var(--ease), border-color 0.2s var(--ease);
}

.module-settings-gear:hover {
    opacity: 1;
    background: rgba(var(--color-primary-rgb), 0.08);
    border-color: var(--color-primary);
}

.module-settings-gear.is-active {
    background: var(--tk-orange);
    border-color: transparent;
    color: var(--color-white);
    opacity: 1;
}

.module-settings-popover {
    padding: 1.1rem 1.4rem;
    border-top: 1px solid var(--color-border);
    background: var(--color-bg-alt);
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.module-section-body {
    padding: 0 1.4rem 1.5rem;
    border-top: 1px solid var(--color-border);
    padding-top: 1.4rem;
}

/* ---------- Builder layout: editor list + one compiled, tabbed preview ----------
   Every enabled module's editor stacks in the left column; a single global
   preview panel on the right compiles ALL of them behind a top nav ("guias")
   instead of each module carrying its own separate preview. */
.builder-layout {
    display: grid;
    grid-template-columns: 1.2fr 0.8fr;
    gap: 1.75rem;
    align-items: start;
}

.builder-editor-col {
    min-width: 0;
}

.builder-preview-col {
    position: sticky;
    /* Clears the sticky site nav (~3rem once scrolled) with some breathing room. */
    top: 4.5rem;
    /* Without this, a CSS grid track won't shrink below its content's
       intrinsic width — and .site-preview-body's fixed 1200px width in
       "computador" mode (seção 5.2) makes that intrinsic width 1200px, so
       the 0.8fr track was growing to fit it instead of honoring its share
       and letting .site-preview-viewport's own overflow-x:auto handle the
       overflow. That's what broke the two-column layout the moment
       "computador" mode rendered anything. */
    min-width: 0;
}

.site-preview-panel {
    border-radius: var(--radius-md);
    /* No background fill here on purpose — a predefined color behind the
       layout would compete with (and make it hard to judge) the real site
       background configured below. The shadow alone is what sets this
       panel apart as a "device frame" around the actual site preview. */
    box-shadow: var(--shadow-soft);
    overflow: hidden;
}

.site-preview-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg-alt);
}

.site-preview-fullscreen-btn {
    border: none;
    background: var(--color-white);
    border-radius: var(--radius-md);
    padding: 0.4rem 0.75rem;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-text-muted);
    cursor: pointer;
    box-shadow: var(--shadow-soft);
    transition: transform 0.15s var(--ease), color 0.15s var(--ease);
}

.site-preview-fullscreen-btn:hover {
    transform: scale(1.03);
    color: var(--color-text);
}

.site-preview-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    padding: 0.6rem;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-white);
}

.site-preview-nav-link {
    border: none;
    background: transparent;
    padding: 0.45rem 0.85rem;
    border-radius: var(--radius-md);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: background 0.2s var(--ease), color 0.2s var(--ease);
}

.site-preview-nav-link.is-active {
    background: var(--preview-accent);
    color: var(--color-white);
}

.site-preview-device-toggle {
    display: inline-flex;
    gap: 0.15rem;
    padding: 0.2rem;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.device-toggle-btn {
    border: none;
    background: transparent;
    padding: 0.35rem 0.55rem;
    border-radius: calc(var(--radius-md) - 0.2rem);
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.55;
    transition: background 0.2s var(--ease), opacity 0.2s var(--ease);
}

.device-toggle-btn.is-active {
    background: var(--color-white);
    box-shadow: var(--shadow-soft);
    opacity: 1;
}

/* Raiz do site do CLIENTE dentro do preview.

   Tudo aqui usa --preview-* (congeladas em ticks-tokens.css), nunca os
   tokens da Tick's: a identidade da Tick's é a moldura do produto, não o
   site que o cliente está montando. --preview-accent é sobrescrita
   inline pelo C# com a cor que o cliente escolheu da própria logo
   (SolicitarSite.razor / SitePreviewPanel.razor); o valor abaixo é só o
   que vale enquanto ele ainda não escolheu nenhuma.

   `color` passou a ser declarado explicitamente: antes o texto do
   cliente herdava a cor do <body> da plataforma, então retematizar a
   plataforma mexeria no site dele sem querer. */
.site-preview-body {
    --preview-accent: var(--preview-accent-fallback);
    padding: 1.25rem;
    font-family: var(--preview-font-body);
    color: var(--preview-text);
    max-height: min(70vh, 640px);
    overflow-y: auto;
}

/* "Computador" only forces a real desktop content width (1200px) in tela
   cheia (.is-fullscreen further below) — forcing it here too, in the
   embedded sidebar preview, used to make ordinary content (the map embed,
   item-grids) bleed past the panel's own edge into a horizontal scrollbar,
   which read as broken rather than as "see the real width" — especially
   since the sidebar is almost always much narrower than 1200px to begin
   with, so nearly everything triggered it. The embedded view now just
   reflows to whatever width the column actually is (like every other
   block type already does); tela cheia is where the real, no-compromise
   desktop width — and the multi-column item-grids it enables — actually
   lives, where there's genuine room for it. */
.site-preview-viewport.is-desktop.is-fullscreen {
    overflow-x: auto;
}

.site-preview-viewport.is-mobile {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 1.5rem 1rem;
    background: var(--color-bg-alt);
}

.site-preview-viewport.is-mobile .site-preview-body {
    width: 375px;
    max-width: 100%;
    max-height: min(70vh, 700px);
    border-radius: 1.75rem;
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-soft);
}

/* Fullscreen has real room, so "computador" no longer needs the horizontal
   scroll above — it just fits (or scales down gracefully on a narrow
   window) — and "celular" gets more headroom to show a taller slice of the
   page before it has to scroll internally. */
.site-preview-viewport.is-fullscreen {
    flex: 1;
    min-height: 0;
}

.site-preview-viewport.is-desktop.is-fullscreen .site-preview-body {
    width: min(1200px, 100%);
    max-width: 1200px;
    margin: 0 auto;
    /* The inline embedded panel's 70vh/640px cap makes sense for a sidebar
       preview, but tela cheia has an entire screen to work with — now that
       it stacks every section into one page (seção 5.3) instead of showing
       one tab at a time, keeping that same small cap would defeat the point
       of "tela cheia" by cramming the whole page back into a tiny scrollbox. */
    max-height: min(85vh, 900px);
}

.site-preview-viewport.is-mobile.is-fullscreen {
    padding: 2.5rem 1rem;
}

.site-preview-viewport.is-mobile.is-fullscreen .site-preview-body {
    max-height: min(85vh, 812px);
}

.site-preview-fullscreen-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 16, 20, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    z-index: 1000;
}

.site-preview-fullscreen-panel {
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-strong);
    width: 100%;
    height: 100%;
    max-width: 1400px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.site-preview-fullscreen-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg-alt);
}

.site-preview-fullscreen-close {
    border: none;
    background: var(--color-white);
    border-radius: var(--radius-md);
    padding: 0.45rem 0.85rem;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-text-muted);
    cursor: pointer;
    box-shadow: var(--shadow-soft);
}

/* Mockup of the real site's own header — brand left, links right — painted
   with the business's actual primary color (set inline via style, since it
   comes from SiteDraft, not a fixed value) instead of the builder's own UI
   chrome, so "computador"/"celular" in tela cheia reads as a preview of the
   real site rather than a generic modal. See SitePreviewPanel.razor's
   FullscreenNavbar/NavTextColor for how the text color always stays legible
   against whatever that primary color turns out to be. */
.site-preview-fullscreen-navbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1.5rem;
    transition: background-color 0.2s var(--ease);
}

/* Tamanho (NavSettings.Size, seção 2.2) — just the navbar's own padding, so
   "Compacto" reads as a tighter bar and "Amplo" as a roomier one without
   touching anything else in the layout. */
.site-preview-fullscreen-navbar.nav-size-compacto {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

.site-preview-fullscreen-navbar.nav-size-amplo {
    padding-top: 1.35rem;
    padding-bottom: 1.35rem;
}

.site-preview-fullscreen-brand {
    display: flex;
    align-items: center;
    min-width: 0;
}

.site-preview-fullscreen-logo {
    max-height: 2.25rem;
    max-width: 9rem;
    object-fit: contain;
}

.site-preview-fullscreen-logo-placeholder {
    font-size: 0.8rem;
    font-weight: 600;
    font-style: italic;
    opacity: 0.65;
}

.site-preview-fullscreen-navbar-links {
    display: flex;
    align-items: center;
    gap: 1.75rem;
}

.site-preview-fullscreen-navlink {
    border: none;
    background: transparent;
    color: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    padding: 0.3rem 0;
    opacity: 0.8;
    border-bottom: 2px solid transparent;
    transition: opacity 0.2s var(--ease), border-color 0.2s var(--ease);
}

.site-preview-fullscreen-navlink:hover {
    opacity: 1;
}

.site-preview-fullscreen-navlink.is-active {
    opacity: 1;
    border-bottom-color: currentColor;
}

/* "Celular" collapses to a hamburger instead of shrinking the same
   horizontal link row — mirrors the real site's own mobile nav collapse
   (NavMenu.razor/home.css) rather than being a purely cosmetic size change. */
.site-preview-fullscreen-navbar-toggle {
    border: none;
    background: color-mix(in srgb, currentColor 15%, transparent);
    color: inherit;
    border-radius: var(--radius-md);
    width: 2.25rem;
    height: 2.25rem;
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
}

.site-preview-fullscreen-navbar-dropdown {
    display: flex;
    flex-direction: column;
    padding: 0.25rem 1.5rem 1rem;
    gap: 0.15rem;
}

.site-preview-fullscreen-navbar-dropdown .site-preview-fullscreen-navlink {
    text-align: left;
    padding: 0.6rem 0;
    border-bottom: 1px solid color-mix(in srgb, currentColor 20%, transparent);
}

.site-preview-fullscreen-navbar-dropdown .site-preview-fullscreen-navlink:last-child {
    border-bottom: none;
}

/* A NavGroup (Menu superior do site → "Grupos de menu") bundles several
   layouts under one dropdown item instead of each getting its own flat
   link — SitePreviewPanel.NavEntries decides what's grouped, these just
   draw whichever shape it hands back. */
.site-preview-navlink-group {
    position: relative;
}

.site-preview-navlink-group-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: 0.5rem;
    display: flex;
    flex-direction: column;
    min-width: 10rem;
    padding: 0.4rem 0.9rem;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-strong);
    z-index: 10;
    animation: previewNavDropdownIn 0.18s var(--ease);
}

.site-preview-navlink-group-dropdown .site-preview-fullscreen-navlink {
    text-align: left;
    padding: 0.5rem 0;
    border-bottom: 1px solid color-mix(in srgb, currentColor 20%, transparent);
}

.site-preview-navlink-group-dropdown .site-preview-fullscreen-navlink:last-child {
    border-bottom: none;
}

/* Mobile hamburger dropdown: no open/close state of its own (the hamburger
   itself is already that toggle) — a group just shows as a small label with
   its members indented right under it. */
.site-preview-navlink-group-label {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.6;
    padding: 0.6rem 0 0.1rem;
}

.site-preview-fullscreen-navbar-dropdown .site-preview-navlink-group-member {
    padding-left: 0.9rem;
}

/* ---------- Tela cheia: entrance/transition polish ---------- */

@keyframes previewFullscreenFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes previewFullscreenPanelIn {
    from { opacity: 0; transform: scale(0.97); }
    to { opacity: 1; transform: scale(1); }
}

.site-preview-fullscreen-backdrop {
    animation: previewFullscreenFadeIn 0.2s var(--ease);
}

.site-preview-fullscreen-panel {
    animation: previewFullscreenPanelIn 0.25s var(--ease);
}

@keyframes previewNavDropdownIn {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
}

.site-preview-fullscreen-navbar-dropdown {
    transform-origin: top;
    animation: previewNavDropdownIn 0.22s var(--ease);
}

.site-preview-fullscreen-navbar-toggle {
    transition: background 0.2s var(--ease), transform 0.15s var(--ease);
}

.site-preview-fullscreen-navbar-toggle:active {
    transform: scale(0.92);
}

@keyframes previewOverlaySectionIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

.site-preview-overlay-section {
    animation: previewOverlaySectionIn 0.3s var(--ease);
}

.site-preview-overlay-close {
    border: none;
    background: var(--color-bg-alt);
    border-radius: var(--radius-md);
    padding: 0.5rem 0.9rem;
    margin-bottom: 1.25rem;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: background 0.2s var(--ease), transform 0.15s var(--ease);
}

.site-preview-overlay-close:hover {
    background: var(--color-border);
}

.site-preview-overlay-close:active {
    transform: scale(0.97);
}

/* Every stacked section fades/slides in on its own — independent of
   whatever RevealAnimation (seção 6) that specific layout has configured —
   so tela cheia always feels alive the moment it opens, not just the
   sections someone happened to pick an animation for. The stagger
   (animation-delay, set inline per section index) is what turns a page's
   worth of sections appearing at once into something that reads as a
   sequence instead of a flash. */
@keyframes previewStackedSectionIn {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: translateY(0); }
}

.site-preview-stacked-section {
    animation: previewStackedSectionIn 0.45s var(--ease) both;
}

.site-preview-stacked-section + .site-preview-stacked-section {
    margin-top: 2.5rem;
    padding-top: 2.5rem;
    border-top: 1px solid var(--color-border);
}

/* Switching "computador"/"celular" morphs the frame instead of snapping —
   both the surrounding padding (viewport) and the frame itself (width,
   corners, border, shadow) animate together. */
.site-preview-viewport {
    transition: padding 0.3s var(--ease);
}

.site-preview-body {
    transition: width 0.3s var(--ease), max-width 0.3s var(--ease),
        border-radius 0.3s var(--ease), box-shadow 0.3s var(--ease),
        border-color 0.3s var(--ease);
}

.avaliacao-author-input,
.botao-link-input {
    margin-top: 0.5rem;
}


/* Carrossel block (BlockType.Carrossel). Bootstrap's own CSS (bootstrap.min.css,
   linked globally in App.razor) already draws the control-arrow icons,
   indicator dot sizing, dark-variant colors and caption box for free — only
   the actual slide transition needs supplementing here, since this app
   doesn't vendor Bootstrap's JS bundle (see Docs/SiteBuilder.md and
   siteBuilder.bindCarousel, wwwroot/js/sitebuilder.js, for why and how). */
.carousel-inner {
    position: relative;
    overflow: hidden;
}

/* aspect-ratio, not a fixed height — a fixed height doesn't scale down with
   a narrower container (the embedded sidebar preview is nowhere near as
   wide as tela cheia's real desktop width), so the same "22rem" that looks
   right at 1200px wide turned into a tall, narrow strip at ~200-300px wide.
   16:9 scales correctly at any container width. */
.carousel-item img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
}

/* Slide (default): every item sits side by side in a flex row; advancing
   shifts every slide left by the same amount, driven by --gd-carousel-index
   (set by bindCarousel).

   The shift goes on each .carousel-item, NOT on .carousel-inner: the inner is
   the element that clips (overflow: hidden), and a transform moves an
   element's clip box along with its content. Translating the inner by -100%
   carried the window off the slide it was meant to reveal, so slide 1 was
   laid out in the right place and clipped away — only the first photo ever
   showed. Each slide is 100% of the inner's width, so a slide's own -100% *
   index lands the active one exactly on the (stationary) window. */
.carousel:not(.carousel-fade) .carousel-inner {
    display: flex;
}

.carousel:not(.carousel-fade) .carousel-item {
    flex: 0 0 100%;
    display: block !important;
    /* Bootstrap's own .carousel-item is float: left with margin-right: -100%
       (its float-based slider trick). In THIS flex row that negative margin
       collapses every slide's outer width to 0, so all of them pile up at
       x = 0: the first slide showed the LAST photo and every slide after it
       slid into blank space. */
    margin-right: 0;
    transform: translateX(calc(-100% * var(--gd-carousel-index, 0)));
    transition: transform 0.6s var(--ease);
}

/* Fade: items stack on top of each other, so the container needs its own
   size source (absolutely positioned children don't contribute to it) —
   same 16:9 as the images themselves, so it also scales with width instead
   of being a fixed height. Advancing just crossfades opacity. */
.carousel-fade .carousel-inner {
    aspect-ratio: 16 / 9;
}

.carousel-fade .carousel-item {
    display: block !important;
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 0.6s var(--ease);
}

.carousel-fade .carousel-item.active {
    opacity: 1;
}

.carousel-caption p {
    margin-bottom: 0;
}

.carousel-options-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.4rem 1rem;
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--color-border);
}

.carousel-options-grid .carousel-options-title {
    grid-column: 1 / -1;
}

.carousel-options-grid .field-group-inline {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.carousel-options-grid input[type="number"] {
    width: 4.5rem;
    display: inline-block;
}

@media (max-width: 860px) {
    .builder-layout {
        grid-template-columns: 1fr;
    }

    .builder-preview-col {
        position: static;
    }

    .site-preview-body {
        max-height: none;
    }
}

.item-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.item-card {
    position: relative;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    background: var(--color-bg-alt);
}

.item-card-remove {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    border: none;
    background: rgba(var(--color-danger-rgb), 0.1);
    color: var(--color-danger);
    font-size: 0.9rem;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.add-item-btn {
    align-self: flex-start;
    border: 1px dashed rgba(var(--color-primary-rgb), 0.4);
    background: transparent;
    color: var(--color-primary-dark);
    font-weight: 600;
    padding: 0.6rem 1.1rem;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}

.add-item-btn:hover {
    background: rgba(var(--color-primary-rgb), 0.06);
    border-color: rgba(var(--color-primary-rgb), 0.6);
}

.logo-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    align-items: flex-start;
    margin-bottom: 2rem;
}

.logo-preview {
    width: 6rem;
    height: 6rem;
    border-radius: var(--radius-md);
    border: 1px dashed var(--color-border);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
}

.logo-preview img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Reading and resizing an image (LogoColorPicker/GaleriaModuleEditor —
   sitebuilder.js's readAndResizeImage(s)) takes a visible moment on a big
   photo — this is the "something is happening" signal for that stretch,
   shown in place of the preview/grid slot the finished image will occupy. */
.upload-spinner {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    color: var(--color-text-muted);
    font-size: 0.75rem;
    text-align: center;
}

.spinner {
    width: 1.4rem;
    height: 1.4rem;
    border: 2px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}

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

.item-card-loading {
    align-items: center;
    justify-content: center;
    min-height: 8rem;
}

label.btn.is-disabled {
    opacity: 0.6;
    cursor: not-allowed;
    pointer-events: none;
}

.palette-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-top: 0.75rem;
}

.palette-swatch {
    position: relative;
    width: 3.75rem;
    height: 3.75rem;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    box-shadow: var(--shadow-soft);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.62rem;
    font-weight: 700;
    font-family: var(--font-body);
    line-height: 1.1;
    padding: 0;
}

.palette-swatch.is-selected {
    border-color: var(--color-text);
    box-shadow: 0 0 0 3px rgba(var(--color-white-rgb), 0.9), 0 0 0 5px var(--color-text);
}

.palette-swatch.is-primary {
    box-shadow: 0 0 0 3px rgba(var(--color-white-rgb), 0.9), 0 0 0 5px var(--color-primary);
}

.palette-swatch.is-secondary {
    box-shadow: 0 0 0 3px rgba(var(--color-white-rgb), 0.9), 0 0 0 5px var(--color-accent);
}

.palette-swatch-badge {
    position: absolute;
    top: -0.3rem;
    right: -0.3rem;
    width: 1.3rem;
    height: 1.3rem;
    border-radius: 50%;
    background: var(--color-text);
    color: var(--color-white);
    font-size: 0.65rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--shadow-soft);
}

.add-palette-color-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 1rem;
}

/* "+ Adicionar cor": o seletor nativo fica invisivel por cima do botao
   inteiro, entao clicar no botao e clicar no seletor — abre na hora, sem
   um segundo controle ao lado. */
.add-palette-color-btn {
    position: relative;
    overflow: hidden;
    cursor: pointer;
}

.add-palette-color-btn input[type="color"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    opacity: 0;
    cursor: pointer;
}

/* O foco de teclado fica no input (invisivel); o botao mostra o mesmo
   estado de foco/hover dos outros .btn-outline-primary. */
.add-palette-color-btn:focus-within {
    background: var(--tk-green-soft);
    box-shadow: 0 0 0 2px var(--tk-surface),
                0 0 0 4px var(--tk-orange),
                0 0 0 5px var(--tk-green);
}

@media (max-width: 640px) {
    .logo-picker {
        flex-direction: column;
        align-items: center;
        text-align: center;
    }
}

/* ---------- Flexible layout editor (Sobre / Contato block system) ---------- */
.layout-preset-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
    margin-bottom: 1.5rem;
}

.layout-preset-bar {
    padding: 1rem 1.15rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg-alt);
}

.layout-preset-bar label {
    font-weight: 600;
    display: block;
    margin-bottom: 0.4rem;
}

/* Menu superior do site: a sibling of .layout-preset-grid instead of a grid
   item inside it — its visibility/grouping UI (seção 3.4) needs the whole
   row's width to lay out its columns reasonably, which it never had while
   squeezed into the same 240px-ish grid track as Estilo de layout/Animação
   padrão. */
.layout-preset-bar-full {
    margin-bottom: 1.5rem;
}

.layout-preset-bar .field-hint {
    margin-top: 0.5rem;
    margin-bottom: 0;
}

.layout-preset-bar-label-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.4rem;
}

.layout-preset-bar-label-row label {
    margin-bottom: 0;
}

.layout-block-card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0.6rem;
    margin-bottom: 0.5rem;
    background: var(--color-bg-alt);
}

/* Scoped to this card, not the global .form-control/.form-select (used all
   over the app) — "Preencha o conteúdo" packs one full block editor at a
   time into a compact card now, so its own inputs go a size down too. */
.layout-block-card .form-control,
.layout-block-card .form-select {
    padding: 0.5rem 0.7rem;
    font-size: 0.88rem;
}

/* "Continuar" in "Preencha o conteúdo" (SolicitarSite.razor) validates every
   block/catalog item before letting the user advance — whichever one is
   still empty gets scrolled into view (siteBuilder.scrollToId) and marked
   this way until it's filled in or a later check finds a different one.
   The pulse fires twice to draw the eye there; the tinted border it settles
   into afterward is what keeps it legible as "this one's the problem". */
.layout-block-card.is-missing,
.item-card.is-missing {
    border-color: var(--color-danger);
    background: rgba(var(--color-danger-rgb), 0.05);
    animation: missing-field-pulse 1s var(--ease) 2;
}

@keyframes missing-field-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(var(--color-danger-rgb), 0); }
    50% { box-shadow: 0 0 0 6px rgba(var(--color-danger-rgb), 0.15); }
}

@media (prefers-reduced-motion: reduce) {
    .layout-block-card.is-missing,
    .item-card.is-missing {
        animation: none;
    }
}

.layout-block-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.4rem;
    flex-wrap: wrap;
}

.layout-block-title-group {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    min-width: 0;
}

/* The rich-text toolbar (Negrito/Itálico/Sublinhado/Fonte) sits inline in
   the header now, right after the block's name, instead of on its own row
   above the text — frees up a whole row of vertical space per Título/Texto/
   Depoimento block. Its own margin-bottom (still needed when it sat above
   the text) would misalign it here, in a horizontal row. */
.layout-block-title-group .richtext-toolbar {
    margin-bottom: 0;
}

.layout-block-drag-handle {
    cursor: grab;
    color: var(--color-text-muted);
    font-size: 1.1rem;
    padding: 0.2rem 0.3rem;
    user-select: none;
    line-height: 1;
}

.layout-block-drag-handle:active {
    cursor: grabbing;
}

.layout-block-title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.95rem;
}

.layout-block-actions {
    display: flex;
    gap: 0.4rem;
}

.layout-block-actions button {
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-white);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    line-height: 1;
}

.layout-block-actions button:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

/* Stays in the flex row (not the absolute corner placement the base
   .item-card-remove has), but as `relative` — NOT `static`. The invisible
   touch-target ::after on .item-card-remove ("Area de toque", further down)
   is position: absolute; on a static button it has no positioned ancestor
   close by, so it anchors to a far-away one and stretches over that whole
   area, swallowing every click on the inputs underneath and removing a
   block instead. top/right are reset because the base rule's offsets would
   otherwise shift a relatively-positioned button. */
.layout-block-actions button.item-card-remove {
    position: relative;
    top: auto;
    right: auto;
}

.block-inline-checkbox {
    display: block;
    margin-top: 0.6rem;
    font-size: 0.88rem;
    color: var(--color-text-muted);
}

.block-style-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px dashed var(--color-border);
}

/* Scoped to FlexibleLayoutEditor's own per-block panel (not the "Escolha o
   estilo" -> "Personalizado" one, which reuses the same base classes but
   has room to spare) — "Preencha o conteúdo" shows one page's full editor
   at a time now, so its Tamanho/Animação <select>s go smaller too, same as
   .module-section.is-compact around it. */
.block-style-controls.is-compact select.form-select {
    padding: 0.35rem 0.6rem;
    font-size: 0.82rem;
    width: auto;
}

.block-style-group {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

/* Rótulo dos controles de estilo de bloco (construtor). Sem caixa alta. */
.block-style-label {
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--color-text-muted);
    letter-spacing: normal;
}

.block-style-options {
    display: flex;
    gap: 0.4rem;
}

.block-style-options button {
    padding: 0.4rem 0.75rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    background: var(--color-white);
    font-size: 0.82rem;
    cursor: pointer;
}

.block-style-options button.is-active {
    background: var(--tk-orange);
    border-color: transparent;
    color: var(--color-white);
}

.block-color-options {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.block-color-option {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.65rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    background: var(--color-white);
    font-size: 0.8rem;
    cursor: pointer;
}

.block-color-option.is-active {
    border-color: var(--color-primary);
    background: rgba(var(--color-primary-rgb), 0.08);
    font-weight: 600;
}

/* A borda destas amostras e um NEUTRO de proposito, nao o --tk-line
   verde: elas exibem a cor que o CLIENTE escolheu, e um contorno
   esverdeado tingiria todas as cores dele com a marca da Tick's. Era
   preto puro, que a identidade nao usa; virou a tinta da marca a 18%,
   que e neutra e quente. */
.block-color-swatch {
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 50%;
    border: 1px solid rgba(43, 42, 38, 0.18);
    flex-shrink: 0;
}

.block-color-variants {
    display: flex;
    gap: 0.3rem;
    margin-left: 0.25rem;
}

.block-color-variant {
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    border: 1px solid rgba(43, 42, 38, 0.18);
    cursor: pointer;
    padding: 0;
}

.block-color-variant.is-active {
    box-shadow: 0 0 0 2px var(--color-white), 0 0 0 4px var(--color-primary);
}

.richtext-toolbar {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-bottom: 0.4rem;
    flex-wrap: wrap;
}

.richtext-toolbar button {
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    background: var(--color-white);
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1;
}

.richtext-toolbar button:hover {
    background: rgba(var(--color-primary-rgb), 0.08);
}

.richtext-toolbar select {
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    background: var(--color-white);
    font-size: 0.8rem;
    padding: 0.3rem 0.4rem;
}

.richtext-editable {
    min-height: 2.6rem;
    cursor: text;
}

.layout-bg-picker {
    padding: 0.9rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-white);
}

.nav-settings-editor {
    margin-top: 0.75rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-white);
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.nav-settings-preview {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.6rem 0.9rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    font-size: 0.8rem;
    font-weight: 600;
    transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}

.nav-settings-preview-brand {
    opacity: 0.7;
    font-style: italic;
}

.nav-group-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.nav-group-row .form-control {
    flex: 1;
}

/* One layout per block: its name, then its visibility chips, then (when
   there are groups) its group — stacked, because three chips no longer fit
   on a single line next to the name the way a <select> did. */
.nav-layout-row {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.55rem;
    padding: 0.8rem 0;
    border-bottom: 1px solid var(--color-border);
}

.nav-layout-row .form-select {
    width: auto;
    min-width: 10rem;
}

.nav-layout-row:last-child {
    border-bottom: none;
}

.nav-layout-row-label {
    font-weight: 600;
    font-size: 0.88rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.layout-bg-type-options {
    display: flex;
    gap: 0.4rem;
    margin-bottom: 0.75rem;
}

.layout-bg-type-options button {
    padding: 0.4rem 0.75rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    background: var(--color-white);
    font-size: 0.82rem;
    cursor: pointer;
}

.layout-bg-type-options button.is-active {
    background: var(--tk-orange);
    border-color: transparent;
    color: var(--color-white);
}

.layout-bg-fields {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin-bottom: 0.75rem;
}

.layout-bg-field {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

.layout-bg-angle-field {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.3rem;
}

.layout-bg-angle-field input[type="range"] {
    width: 10rem;
}

.layout-bg-preview {
    height: 3.5rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
}

/* Typed as a percentage so the two custom properties the interactive
   background's glow position rides on (site.js sets them on mousemove) can
   actually be transitioned — animating a raw, untyped custom property is a
   no-op in CSS. Without this, the glow snaps straight to the cursor on every
   pixel of movement, which is exactly what read as "raw" (see the buttons
   below picking it up via the shared .layout-bg-preview/.layout-preview-surface
   transition instead). */
@property --mx {
    syntax: '<percentage>';
    inherits: true;
    initial-value: 50%;
}

@property --my {
    syntax: '<percentage>';
    inherits: true;
    initial-value: 50%;
}

.layout-bg-preview,
.layout-preview-surface {
    transition: background-color 0.3s var(--ease), --mx 0.5s var(--ease), --my 0.5s var(--ease);
}

.layout-bg-quick-picks {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.layout-bg-quick-pick {
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    border: 1px solid rgba(43, 42, 38, 0.18);
    cursor: pointer;
    padding: 0;
}

.block-contrast-warning {
    margin-top: 0.75rem;
    padding: 0.6rem 0.85rem;
    border-radius: var(--radius-md);
    background: rgba(var(--color-danger-rgb), 0.1);
    color: var(--color-danger);
    font-size: 0.82rem;
    font-weight: 600;
}

.add-block-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
    margin-top: 1.5rem;
}

.add-block-row .form-select {
    max-width: 260px;
}


/* ---------- Animation demo replays ----------
   These play once whenever the element they're on is (re)created — the
   Blazor components pair each of these classes with an @key tied to the
   chosen RevealAnimation, so picking a different animation forces Blazor to
   recreate the node and the browser to replay the @keyframes from scratch.
   On the real published site these would instead be scroll-triggered (like
   the marketing site's own [data-reveal] in site.js); here, since the
   preview box is too small to scroll within, playing once on selection is
   what actually lets the user see what they picked. */
@keyframes reveal-demo-fade-up {
    from { opacity: 0; transform: translateY(24px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes reveal-demo-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes reveal-demo-slide-left {
    from { opacity: 0; transform: translateX(40px); }
    to { opacity: 1; transform: translateX(0); }
}

@keyframes reveal-demo-slide-right {
    from { opacity: 0; transform: translateX(-40px); }
    to { opacity: 1; transform: translateX(0); }
}

@keyframes reveal-demo-zoom-in {
    from { opacity: 0; transform: scale(0.85); }
    to { opacity: 1; transform: scale(1); }
}

.reveal-demo-fade-up { animation: reveal-demo-fade-up 0.6s var(--ease); }
.reveal-demo-fade-in { animation: reveal-demo-fade-in 0.6s var(--ease); }
.reveal-demo-slide-left { animation: reveal-demo-slide-left 0.6s var(--ease); }
.reveal-demo-slide-right { animation: reveal-demo-slide-right 0.6s var(--ease); }
.reveal-demo-zoom-in { animation: reveal-demo-zoom-in 0.6s var(--ease); }

@media (prefers-reduced-motion: reduce) {
    .reveal-demo-fade-up,
    .reveal-demo-fade-in,
    .reveal-demo-slide-left,
    .reveal-demo-slide-right,
    .reveal-demo-zoom-in {
        animation: none;
    }
}

/* =====================================================================
   A CAIXA APLICADA A TODA ESCOLHA DA INTERFACE
   =====================================================================
   A identidade se apoia na caixa de seleção, entao tudo que e "escolher
   uma coisa" na plataforma carrega a mesma caixa: o modulo que voce liga,
   a aba que voce esta vendo, o estilo de bloco selecionado, o tipo de
   fundo, computador/celular, a opcao da home.

   Funciona so por CSS, sem tocar em marcacao nenhuma: cada um desses
   controles ja tinha uma classe de estado (.is-active ou .is-enabled), e
   a caixa entra por ::before/::after.

   O check e o mesmo tracado da logo, aplicado como mascara — por isso ele
   ultrapassa o canto superior direito da caixa, igual a marca.
   ===================================================================== */

:root {
    --tk-check-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Cpath d='M9 22l6 6.5L37 3' fill='none' stroke='%23000' stroke-width='5.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.module-chip,
.auth-tab,
.device-toggle-btn,
.layout-bg-type-options button,
.block-style-options button,
.preset-option {
    position: relative;
}

/* A caixa. Fica a esquerda do rotulo em tudo que e escolha. */
.auth-tab::before,
.device-toggle-btn::before,
.layout-bg-type-options button::before,
.block-style-options button::before,
.preset-option::before {
    content: "";
    position: absolute;
    left: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    width: 1.15rem;
    height: 1.15rem;
    border: 2px solid var(--tk-green);
    border-radius: var(--tk-radius-field);
    background: var(--tk-surface);
    transition: background 0.2s var(--tk-ease);
    pointer-events: none;
}

/* Marcado = laranja, com o check verde por cima. A borda continua verde:
   laranja sobre creme da 2,66:1 e nao daria contorno visivel sozinho. */
.auth-tab.is-active::before,
.device-toggle-btn.is-active::before,
.layout-bg-type-options button.is-active::before,
.block-style-options button.is-active::before,
.preset-option.is-active::before {
    background: var(--tk-orange);
}

.auth-tab.is-active::after,
.device-toggle-btn.is-active::after,
.layout-bg-type-options button.is-active::after,
.block-style-options button.is-active::after,
.preset-option.is-active::after {
    content: "";
    position: absolute;
    left: 0.55rem;
    top: 50%;
    width: 1.5rem;
    height: 1.5rem;
    transform: translateY(-62%);
    background: var(--tk-green);
    -webkit-mask: var(--tk-check-mask) no-repeat center / contain;
    mask: var(--tk-check-mask) no-repeat center / contain;
    pointer-events: none;
}

/* Abre espaco para a caixa sem espremer o rotulo. */
.auth-tab,
.device-toggle-btn,
.layout-bg-type-options button,
.block-style-options button,
.preset-option {
    padding-left: 2.5rem;
}

/* O chip de modulo ja tinha um ponto redondo como indicador de ligado.
   Esse ponto VIRA a caixa — nao entra uma segunda marca ao lado dele.

   Medida em rem, nao em em: o chip usa fonte de 0.88rem, entao 1.05em
   dava ~12px — pequeno demais, e com borda de 2px a caixa lia como um
   anel redondo em vez de uma caixa. Em rem ela tem o mesmo tamanho em
   qualquer chip, independente do tamanho da letra ao redor. */
.module-chip-dot {
    position: relative;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: var(--tk-radius-field);
    border: 2px solid var(--tk-green);
    background: var(--tk-surface);
    flex: none;
    transition: background 0.2s var(--tk-ease);
}

.module-chip.is-enabled .module-chip-dot,
.module-chip.is-active .module-chip-dot {
    background: var(--tk-orange);
}

.module-chip.is-enabled .module-chip-dot::after,
.module-chip.is-active .module-chip-dot::after {
    content: "";
    position: absolute;
    left: -0.12rem;
    top: -0.26rem;
    width: 1.5rem;
    height: 1.5rem;
    background: var(--tk-green);
    -webkit-mask: var(--tk-check-mask) no-repeat center / contain;
    mask: var(--tk-check-mask) no-repeat center / contain;
}

/* O chip precisa de mais respiro entre a caixa e o rotulo: a ponta do
   check passa do canto da caixa e encostava na primeira letra. */
.module-chip {
    gap: 0.7rem;
}

/* Cor de bloco: o botao ja mostra a propria cor resolvida, entao uma
   caixa por cima competiria com ela. Aqui vai so o check, sobre a cor. */
.block-color-option.is-active::after,
.block-color-variant.is-active::after {
    content: "";
    position: absolute;
    right: 0.25em;
    top: 0.18em;
    width: 1.1em;
    height: 1.1em;
    background: var(--tk-green);
    -webkit-mask: var(--tk-check-mask) no-repeat center / contain;
    mask: var(--tk-check-mask) no-repeat center / contain;
    pointer-events: none;
}

.block-color-option,
.block-color-variant {
    position: relative;
}

@media (prefers-reduced-motion: reduce) {
    .auth-tab::before,
    .device-toggle-btn::before,
    .layout-bg-type-options button::before,
    .block-style-options button::before,
    .preset-option::before,
    .module-chip-dot {
        transition: none;
    }
}

/* =====================================================================
   Ajustes vindos da revisao do assistente, com ele ja rodando
   ===================================================================== */

/* 3) O seletor de cor era o quadradinho nativo do navegador, do tamanho
   de um icone, ao lado de um botao de 1.1rem de altura — nao lia como
   controle da mesma familia. Agora tem a altura dos botoes vizinhos, o
   mesmo raio e a mesma borda, e mostra a propria cor como conteudo.
   (A cartela de cores nao usa mais esse seletor: virou um botao unico,
   ver .add-palette-color-btn.) */
.layout-bg-field input[type="color"],
.block-color-custom input[type="color"] {
    -webkit-appearance: none;
    appearance: none;
    width: 4.5rem;
    height: 2.9rem;
    padding: 0.2rem;
    border: 2px solid var(--tk-green);
    border-radius: var(--tk-radius-field);
    background: var(--tk-surface);
    cursor: pointer;
}

.layout-bg-field input[type="color"]::-webkit-color-swatch,
.block-color-custom input[type="color"]::-webkit-color-swatch {
    border: none;
    border-radius: 3px;
}

/* 5) A tela "Qual o conteudo da sua pagina" e uma escolha de blocos, e
   passa a falar a mesma lingua do resto: a lista da esquerda e o que ja
   esta na pagina (caixa marcada), a paleta da direita e o que esta
   disponivel para entrar (caixa vazia).

   ATENCAO: sao marcadores visuais, nao checkboxes de verdade — e
   proposital. O mesmo tipo de bloco pode entrar mais de uma vez na
   pagina (a captura do Lucca mostra "Titulo" e "Texto descritivo"
   duas vezes cada), e uma caixa marcada so sabe dizer sim ou nao. Virar
   checkbox de verdade exigiria mudar esse comportamento, que e logica e
   decisao do Gabriel. */
.add-item-btn {
    position: relative;
    padding-left: 2.5rem;
    border: 1px dashed var(--tk-line);
    color: var(--tk-green);
}

.add-item-btn::before {
    content: "";
    position: absolute;
    left: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    width: 1.15rem;
    height: 1.15rem;
    border: 2px solid var(--tk-green);
    border-radius: var(--tk-radius-field);
    background: var(--tk-surface);
}

.add-item-btn:hover {
    background: var(--tk-green-soft);
    border-color: var(--tk-green);
}

/* Miniaturas dos blocos (BlockTypeThumbnail) — o esboco de como cada bloco
   aparece no site, mostrado nos cartoes de "Qual o conteudo da sua pagina".
   Cores vem dos tokens da plataforma; formas sao SVG inline. */
.block-thumb { display: block; width: 100%; height: 100%; }
.block-thumb .bt-ink { fill: var(--tk-ink); }
.block-thumb .bt-text { fill: var(--tk-ink); opacity: 0.5; }
.block-thumb .bt-mute { fill: var(--tk-ink); opacity: 0.2; }
.block-thumb .bt-soft { fill: var(--tk-sand); }
.block-thumb .bt-soft2 { fill: var(--tk-sand); opacity: 0.55; }
.block-thumb .bt-green { fill: var(--tk-green); }
.block-thumb .bt-orange { fill: var(--tk-orange); }
.block-thumb .bt-paper { fill: var(--tk-surface); }
.block-thumb .bt-hills { fill: var(--tk-green); opacity: 0.4; }
.block-thumb .bt-card { fill: var(--tk-surface); stroke: var(--tk-line); stroke-width: 1; }
.block-thumb .bt-street { fill: none; stroke: var(--tk-surface); stroke-width: 3; stroke-linecap: round; }
.block-thumb .bt-ring { fill: var(--tk-surface); stroke: var(--tk-green); stroke-width: 2; }
.block-thumb .bt-ring-thin { fill: var(--tk-surface); stroke: var(--tk-line); stroke-width: 1; }
.block-thumb .bt-line,
.block-thumb .bt-line-fine,
.block-thumb .bt-line-light {
    fill: none;
    stroke: var(--tk-green);
    stroke-linecap: round;
    stroke-linejoin: round;
}
.block-thumb .bt-line { stroke-width: 1.8; }
.block-thumb .bt-line-fine { stroke-width: 1.3; }
.block-thumb .bt-line-light { stroke: var(--tk-surface); stroke-width: 1.8; }

/* O que ja esta na pagina: caixa marcada. */
.layout-block-card > .layout-block-header > .layout-block-title-group {
    position: relative;
    padding-left: 1.95rem;
}

.layout-block-card > .layout-block-header > .layout-block-title-group::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 1.15rem;
    height: 1.15rem;
    border: 2px solid var(--tk-green);
    border-radius: var(--tk-radius-field);
    background: var(--tk-orange);
}

.layout-block-card > .layout-block-header > .layout-block-title-group::after {
    content: "";
    position: absolute;
    left: -0.12rem;
    top: 50%;
    width: 1.5rem;
    height: 1.5rem;
    transform: translateY(-62%);
    background: var(--tk-green);
    -webkit-mask: var(--tk-check-mask) no-repeat center / contain;
    mask: var(--tk-check-mask) no-repeat center / contain;
}

/* ---------------------------------------------------------------------
   O check sendo marcado

   Nos controles de escolha (abas, chips, estilo de bloco, tipo de fundo)
   o check e uma MASCARA, e mascara nao anima traco — por isso ele
   aparecia pronto, de uma vez. O que da para animar e o recorte: o check
   e revelado da esquerda para a direita, que e a mesma ordem em que o
   traco da marca e desenhado (comeca embaixo a esquerda e sobe para a
   direita). Lido rapido, e o mesmo gesto.

   Os checkboxes de verdade (input[type=checkbox] + svg irmao) continuam
   com stroke-dashoffset, que e o traco real — ali existe um <path> para
   animar.

   A caixa tambem da uma leve inflada ao ser marcada, para o clique ter
   resposta fisica e nao so troca de cor.
   --------------------------------------------------------------------- */
@keyframes tk-check-marcar {
    from { clip-path: inset(0 100% 0 0); }
    to   { clip-path: inset(0 0 0 0); }
}

@keyframes tk-caixa-marcar {
    0%   { transform: translateY(-50%) scale(1); }
    45%  { transform: translateY(-50%) scale(1.18); }
    100% { transform: translateY(-50%) scale(1); }
}

@keyframes tk-caixa-marcar-chip {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.18); }
    100% { transform: scale(1); }
}

.auth-tab.is-active::after,
.device-toggle-btn.is-active::after,
.layout-bg-type-options button.is-active::after,
.block-style-options button.is-active::after,
.preset-option.is-active::after,
.block-color-option.is-active::after,
.block-color-variant.is-active::after {
    animation: tk-check-marcar 260ms var(--tk-ease);
}

.auth-tab.is-active::before,
.device-toggle-btn.is-active::before,
.layout-bg-type-options button.is-active::before,
.block-style-options button.is-active::before,
.preset-option.is-active::before {
    animation: tk-caixa-marcar 260ms var(--tk-ease);
}

.module-chip.is-enabled .module-chip-dot::after,
.module-chip.is-active .module-chip-dot::after {
    animation: tk-check-marcar 260ms var(--tk-ease);
}

.module-chip.is-enabled .module-chip-dot,
.module-chip.is-active .module-chip-dot {
    animation: tk-caixa-marcar-chip 260ms var(--tk-ease);
}

@media (prefers-reduced-motion: reduce) {
    .auth-tab.is-active::after,
    .auth-tab.is-active::before,
    .device-toggle-btn.is-active::after,
    .device-toggle-btn.is-active::before,
    .layout-bg-type-options button.is-active::after,
    .layout-bg-type-options button.is-active::before,
    .block-style-options button.is-active::after,
    .block-style-options button.is-active::before,
    .preset-option.is-active::after,
    .preset-option.is-active::before,
    .block-color-option.is-active::after,
    .block-color-variant.is-active::after,
    .module-chip.is-enabled .module-chip-dot,
    .module-chip.is-enabled .module-chip-dot::after,
    .module-chip.is-active .module-chip-dot,
    .module-chip.is-active .module-chip-dot::after {
        animation: none;
    }
}

/* ---------------------------------------------------------------------
   Area de toque

   O "X" de remover tem 25,6px de lado. No dedo isso erra — a
   recomendacao e ~44px. Em vez de aumentar o circulo (que ficaria
   pesado ao lado do conteudo), a area clicavel e esticada por um
   pseudo-elemento invisivel. O desenho continua pequeno, o alvo fica
   grande.
   --------------------------------------------------------------------- */
.item-card-remove {
    position: absolute;
}

.item-card-remove::after {
    content: "";
    position: absolute;
    inset: -0.6rem;
}

.module-settings-gear {
    position: relative;
}

.module-settings-gear::after {
    content: "";
    position: absolute;
    inset: -0.5rem;
}


/* ---------------------------------------------------------------------
   Editor dos blocos compostos: Menu de itens, Informacoes de contato e
   Horario de funcionamento ("Preencha o conteudo").

   Cada um e um conjunto de varios campos, entao o aperto aqui importa: a
   linha de um item cabe em duas linhas de campo (nome + preco / descricao)
   com uma miniatura de 3,5rem, no lugar do cartao alto de antes (imagem de
   6rem + botao + tres campos empilhados, um item por "tijolo").
   --------------------------------------------------------------------- */
.menu-price-format {
    display: grid;
    gap: 0.35rem;
    margin-bottom: 0.85rem;
}

.menu-price-format .field-hint {
    margin: 0;
}

/* Sete formatos numa linha so de chips pequenos (cabem em duas), nao em tres. */
.menu-price-format .module-picker.is-compact {
    gap: 0.35rem;
}

.menu-price-format .module-picker.is-compact .module-chip {
    padding: 0.3rem 0.7rem;
    font-size: 0.8rem;
}

.menu-cat {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
    padding: 0.65rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg-alt);
}

.menu-cat-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.layout-block-card .menu-cat-name {
    flex: 1;
    min-width: 0;
    font-weight: 600;
}

.menu-items {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.menu-item-row {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-white);
}

.menu-item-thumb {
    flex: none;
    width: 3.5rem;
    height: 3.5rem;
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border: 1px dashed var(--color-border);
    border-radius: 0.6rem;
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
    font-size: 0.7rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
}

.menu-item-thumb:hover {
    border-color: rgba(var(--color-primary-rgb), 0.5);
    background: rgba(var(--color-primary-rgb), 0.05);
}

.menu-item-thumb.is-disabled {
    opacity: 0.6;
    pointer-events: none;
}

.menu-item-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.menu-item-main {
    flex: 1;
    min-width: 0;
    display: grid;
    gap: 0.35rem;
}

.menu-item-line {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.layout-block-card .menu-item-name {
    flex: 1 1 9rem;
    min-width: 0;
}

.layout-block-card .menu-item-price {
    flex: 0 0 8.5rem;
    width: 8.5rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.layout-block-card .menu-item-desc {
    font-size: 0.82rem;
}

/* O "x" de remover das linhas compactas: o mesmo circulo do .item-card-remove,
   mas no fluxo da linha em vez de absoluto no canto de um cartao. */
.menu-remove {
    position: relative;
    flex: none;
    width: 1.6rem;
    height: 1.6rem;
    border: none;
    border-radius: 50%;
    background: rgba(var(--color-danger-rgb), 0.1);
    color: var(--color-danger);
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Area de toque esticada, como a do .item-card-remove. */
.menu-remove::after {
    content: "";
    position: absolute;
    inset: -0.5rem;
}

/* Mantem o espaco a esquerda do marcador quadrado do .add-item-btn (::before)
   e nao estica na largura quando o pai e uma grade. */
.add-item-btn.is-compact {
    padding: 0.4rem 0.8rem 0.4rem 2.3rem;
    font-size: 0.85rem;
    justify-self: start;
    align-self: flex-start;
}

/* Informacoes de contato */
.contact-editor {
    display: grid;
    gap: 0.6rem;
}

.contact-editor > .field-hint {
    margin: 0;
}

.contact-field {
    display: grid;
    gap: 0.25rem;
}

.contact-field-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

.contact-links {
    display: grid;
    gap: 0.4rem;
}

.contact-link-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.layout-block-card .contact-link-label {
    flex: 0 1 11rem;
    min-width: 0;
}

.layout-block-card .contact-link-url {
    flex: 1;
    min-width: 0;
}

/* Horario de funcionamento */
.horario-editor {
    display: grid;
    gap: 0.55rem;
}

.horario-row {
    display: grid;
    gap: 0.5rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-white);
}

.horario-row.has-problem {
    border-color: var(--color-danger);
    background: rgba(var(--color-danger-rgb), 0.04);
}

.horario-row-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.horario-row-number {
    min-width: 4.8rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.horario-times {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.layout-block-card .horario-time {
    width: 5.2rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.horario-times-sep {
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* Os sete dias numa linha: chips menores que os do resto do app, sem a bolinha. */
.day-picker.module-picker.is-compact {
    gap: 0.35rem;
}

.day-picker .module-chip {
    padding: 0.3rem 0.65rem;
    font-size: 0.8rem;
}

.day-picker .module-chip-dot {
    display: none;
}

.horario-add-line {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.horario-add-line .field-hint {
    margin: 0;
}

.add-item-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* "Proxima pagina" com algo faltando: o campo exato que falta fica vermelho
   (nao so o cartao do bloco, que num cardapio grande nao diz qual item e). O
   mesmo pulso do .is-missing, e o mesmo vermelho. */
.layout-block-card .form-control.is-field-missing,
.add-item-btn.is-field-missing,
.menu-item-thumb.is-field-missing,
.module-picker.is-field-missing {
    border-color: var(--color-danger);
    background: rgba(var(--color-danger-rgb), 0.05);
    animation: missing-field-pulse 1s var(--ease) 2;
}

.module-picker.is-field-missing {
    padding: 0.4rem;
    border: 1px solid var(--color-danger);
    border-radius: var(--radius-md);
}

@media (prefers-reduced-motion: reduce) {
    .layout-block-card .form-control.is-field-missing,
    .add-item-btn.is-field-missing,
    .menu-item-thumb.is-field-missing,
    .module-picker.is-field-missing {
        animation: none;
    }
}

/* ---------------------------------------------------------------------
   Listas que se reordenam arrastando ("Sortable lists", sitebuilder.js):
   "Qual o conteudo da sua pagina" e "Preencha o conteudo do seu site".

   Pegar o ponto de arraste ergue o item (acompanha o ponteiro, com sombra);
   um espaco tracejado marca onde ele vai cair e os outros itens deslizam para
   abrir lugar — e ao soltar, o item se encaixa nesse espaco. O gesto todo roda
   no navegador; o servidor so recebe a ordem final.
   --------------------------------------------------------------------- */
[data-sortable] {
    position: relative;
}

/* touch-action: sem isso o dedo rola a pagina em vez de arrastar o item. */
.layout-block-drag-handle,
.layout-card-item-drag {
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
}

.is-sort-dragging {
    border-radius: var(--radius-md);
    box-shadow: 0 18px 38px rgba(23, 69, 42, 0.24), 0 0 0 2px rgba(var(--color-primary-rgb), 0.55);
    cursor: grabbing;
}

/* O espaco onde o item vai se encaixar. Fica por ultimo na lista (position:
   absolute, entao nao ocupa lugar) e sai antes de o servidor ser avisado. */
.sortable-slot {
    position: absolute;
    z-index: 0;
    box-sizing: border-box;
    border: 2px dashed rgba(var(--color-primary-rgb), 0.7);
    border-radius: var(--radius-md);
    background: rgba(var(--color-primary-rgb), 0.07);
    pointer-events: none;
    transition: top 0.22s var(--ease), height 0.22s var(--ease);
    animation: sortable-slot-in 0.18s var(--ease) backwards;
}

.sortable-slot.is-landed {
    animation: sortable-slot-land 0.27s var(--ease) forwards;
}

.sortable-slot.is-leaving {
    opacity: 0;
    transition: opacity 0.2s var(--ease);
}

@keyframes sortable-slot-in {
    from { opacity: 0; transform: scale(0.98); }
}

/* O encaixe: o espaco "aceita" o item (um pulso) e some. */
@keyframes sortable-slot-land {
    0% { opacity: 1; box-shadow: 0 0 0 0 rgba(var(--color-primary-rgb), 0.45); }
    55% { opacity: 1; box-shadow: 0 0 0 8px rgba(var(--color-primary-rgb), 0); }
    100% { opacity: 0; }
}

/* Em qualquer ponto da tela durante o arraste: mao fechada, sem selecionar texto. */
html.is-sorting,
html.is-sorting * {
    cursor: grabbing !important;
    user-select: none !important;
    -webkit-user-select: none !important;
}

/* Um modulo recem-adicionado ("Adicionar modulo") chega com um destaque. So
   `backwards`: anima DE um estado inicial ate o visual normal do cartao, sem
   ficar preso num estado final. */
.layout-block-card.is-just-added {
    animation: block-card-arrive 0.55s var(--ease) backwards,
               block-card-flash 1.6s ease-out backwards;
}

@keyframes block-card-arrive {
    from { opacity: 0; transform: translateY(1.25rem) scale(0.98); }
}

@keyframes block-card-flash {
    from {
        background-color: color-mix(in srgb, var(--tk-orange) 24%, var(--color-bg-alt));
        box-shadow: 0 0 0 3px var(--tk-orange);
    }
}

@media (prefers-reduced-motion: reduce) {
    .sortable-slot,
    .sortable-slot.is-landed {
        animation: none;
        transition: none;
    }

    .layout-block-card.is-just-added {
        animation: none;
        box-shadow: 0 0 0 2px var(--tk-orange);
    }
}