/*==============================================================================
  COMPONENTES (x-ui.* e x-form.*)

  Fundação reutilizável do AgendaZ. Tudo aqui sai dos tokens `--w-*`, entao
  claro e escuro funcionam sem nenhuma regra duplicada por tema — e sem um
  componente "escuro" ao lado de um "claro".
==============================================================================*/

/*------------------------------------------------------------------------------
  Botao
------------------------------------------------------------------------------*/

.ui-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .6rem 1.1rem;
    border-radius: var(--w-radius-md, 10px);
    border: 1px solid transparent;
    font-size: var(--w-text-sm, .875rem);
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--w-duration-fast, .12s) var(--w-ease-out, ease),
                border-color var(--w-duration-fast, .12s) var(--w-ease-out, ease);
}

/* Alvo de toque de 44px no celular: abaixo disso o dedo erra. */
@media (max-width: 40rem) {
    .ui-btn {
        min-height: 44px;
    }
}

.ui-btn:focus-visible {
    outline: 2px solid var(--w-accent);
    outline-offset: 2px;
}

.ui-btn--primario {
    background: var(--w-accent);
    border-color: var(--w-accent);
    color: var(--w-accent-contrast, #fff);
}

.ui-btn--primario:hover {
    background: var(--w-accent-hover, var(--w-accent));
    color: var(--w-accent-contrast, #fff);
}

.ui-btn--secundario {
    background: var(--w-surface);
    border-color: var(--w-border);
    color: var(--w-text-primary);
}

.ui-btn--secundario:hover {
    border-color: var(--w-accent);
    color: var(--w-accent);
}

/* Terciário: ação disponível, mas que não disputa atenção. */
.ui-btn--terciario {
    background: transparent;
    color: var(--w-text-link, var(--w-accent));
    padding-left: .5rem;
    padding-right: .5rem;
}

.ui-btn--perigo {
    background: var(--w-danger-bg, #fdeaea);
    color: var(--w-danger-fg, #a12626);
}

.ui-btn--perigo:hover {
    background: var(--w-danger, #dc2626);
    color: #fff;
}

.ui-btn--icone {
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--w-border);
    background: var(--w-surface);
    color: var(--w-text-secondary);
}

.ui-btn--pequeno {
    padding: .4rem .8rem;
    font-size: var(--w-text-xs, .8125rem);
}

.ui-btn--grande {
    padding: .8rem 1.5rem;
    font-size: var(--w-text-md, 1rem);
}

.ui-btn:disabled,
.ui-btn.is-carregando {
    opacity: .6;
    cursor: not-allowed;
}

.ui-btn__spinner {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-right-color: transparent;
    animation: ui-girar .7s linear infinite;
}

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

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

/*------------------------------------------------------------------------------
  Cartao
------------------------------------------------------------------------------*/

.ui-card {
    background: var(--w-surface);
    border-radius: var(--w-radius-lg, 14px);
    overflow: hidden;
}

.ui-card__topo {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: flex-start;
    justify-content: space-between;
    padding: 1.15rem 1.25rem .85rem;
}

.ui-card__titulo {
    margin: 0;
    font-size: var(--w-text-md, 1rem);
    font-weight: 700;
    color: var(--w-text-primary);
}

.ui-card__descricao {
    margin: .2rem 0 0;
    font-size: var(--w-text-sm, .875rem);
    color: var(--w-text-secondary);
}

.ui-card__corpo {
    padding: 0 1.25rem 1.25rem;
}

.ui-card--compacto .ui-card__topo { padding: .9rem 1rem .6rem; }
.ui-card--compacto .ui-card__corpo { padding: 0 1rem 1rem; }

.ui-card__rodape {
    padding: .85rem 1.25rem;
    border-top: 1px solid var(--w-border-subtle, var(--w-border));
    background: var(--w-surface-sunken);
}

/*------------------------------------------------------------------------------
  Selo
------------------------------------------------------------------------------*/

.ui-badge {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .65rem;
    border-radius: var(--w-radius-full, 999px);
    font-size: var(--w-text-2xs, .75rem);
    font-weight: 700;
    white-space: nowrap;
}

.ui-badge--neutro  { background: var(--w-surface-sunken); color: var(--w-text-secondary); }
.ui-badge--sucesso { background: var(--w-success-bg, #e7f7ee); color: var(--w-success-fg, #14724a); }
.ui-badge--perigo  { background: var(--w-danger-bg, #fdeaea); color: var(--w-danger-fg, #a12626); }
.ui-badge--alerta  { background: var(--w-warning-bg, #fff8e6); color: var(--w-warning-fg, #7a5b12); }
.ui-badge--info    { background: var(--w-info-bg, #e8f1fe); color: var(--w-info-fg, #1d4ed8); }

/*------------------------------------------------------------------------------
  Estado vazio
------------------------------------------------------------------------------*/

.ui-vazio {
    padding: 3rem 1.5rem;
    text-align: center;
}

.ui-vazio__icone {
    display: inline-grid;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--w-surface-sunken);
    color: var(--w-text-tertiary);
    font-size: 1.35rem;
}

.ui-vazio__titulo {
    margin: .9rem 0 0;
    font-size: var(--w-text-md, 1rem);
    font-weight: 700;
    color: var(--w-text-primary);
}

.ui-vazio__descricao {
    margin: .3rem auto 0;
    max-width: 46ch;
    font-size: var(--w-text-sm, .875rem);
    color: var(--w-text-secondary);
}

.ui-vazio__acao {
    margin-top: 1.15rem;
}

/*------------------------------------------------------------------------------
  Campos
------------------------------------------------------------------------------*/

.ui-campo {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    min-width: 0;
}

.ui-campo label {
    font-size: var(--w-text-xs, .8125rem);
    font-weight: 600;
    color: var(--w-text-secondary);
}

.ui-campo__obrig {
    color: var(--w-danger, #dc2626);
}

.ui-campo__controle {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: 0 .75rem;
    border-radius: var(--w-radius-md, 10px);
    border: 1px solid var(--w-border);
    background: var(--w-surface);
}

.ui-campo__controle:focus-within {
    border-color: var(--w-border-focus, var(--w-accent));
    box-shadow: var(--w-shadow-focus, 0 0 0 3px rgba(74, 108, 247, .18));
}

.ui-campo__controle input,
.ui-campo__controle select,
.ui-campo__controle textarea {
    width: 100%;
    padding: .55rem 0;
    border: 0;
    outline: none;
    background: transparent;
    color: var(--w-text-primary);
    font-size: var(--w-text-sm, .875rem);
    font-family: inherit;
}

.ui-campo__controle textarea {
    padding: .55rem 0;
    resize: vertical;
}

.ui-campo__prefixo {
    font-size: var(--w-text-sm, .875rem);
    color: var(--w-text-tertiary);
}

.ui-campo__ajuda {
    font-size: var(--w-text-2xs, .75rem);
    color: var(--w-text-tertiary);
}

/* Erro: borda, texto e ícone — nunca só a cor da borda. */
.ui-campo__erro {
    font-size: var(--w-text-2xs, .75rem);
    color: var(--w-danger-fg, #a12626);
    font-weight: 600;
}

.ui-campo.is-invalido .ui-campo__controle {
    border-color: var(--w-danger, #dc2626);
}

/*------------------------------------------------------------------------------
  Chave (switch)
------------------------------------------------------------------------------*/

.ui-switch {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    margin: 0;
    cursor: pointer;
    position: relative;
}

.ui-switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.ui-switch__trilho {
    flex: none;
    width: 44px;
    height: 24px;
    margin-top: 2px;
    border-radius: 999px;
    background: var(--w-border-strong, #cfd4e2);
    transition: background var(--w-duration-fast, .15s) ease;
}

.ui-switch__bola {
    display: block;
    width: 18px;
    height: 18px;
    margin: 3px;
    border-radius: 50%;
    background: var(--w-surface);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
    transition: transform var(--w-duration-fast, .15s) ease;
}

.ui-switch input:checked + .ui-switch__trilho {
    background: var(--w-accent);
}

.ui-switch input:checked + .ui-switch__trilho .ui-switch__bola {
    transform: translateX(20px);
}

.ui-switch input:focus-visible + .ui-switch__trilho {
    outline: 2px solid var(--w-accent);
    outline-offset: 2px;
}

.ui-switch__texto strong {
    display: block;
    font-size: var(--w-text-sm, .875rem);
    color: var(--w-text-primary);
}

.ui-switch__texto small {
    display: block;
    margin-top: .15rem;
    font-size: var(--w-text-xs, .8125rem);
    color: var(--w-text-secondary);
}

/*------------------------------------------------------------------------------
  Grade de formulario
------------------------------------------------------------------------------*/

.ui-form-grade {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
}

@media (max-width: 40rem) {
    .ui-form-grade {
        grid-template-columns: 1fr;
    }
}

/*==============================================================================
  ESTADOS

  Cinco estados, uma aparencia cada, em todo o sistema. Antes cada tela
  escolhia: um alert do Bootstrap aqui, um texto vermelho ali, um spinner
  improvisado acola.

  Todos combinam cor COM icone e texto — cor sozinha nao chega a quem nao a
  distingue, nem sobrevive a uma impressao em preto e branco.
==============================================================================*/

.ui-estado {
    display: flex;
    gap: .7rem;
    align-items: flex-start;
    padding: .85rem 1rem;
    border-radius: var(--w-radius-md, 12px);
    font-size: var(--w-text-sm, .875rem);
    line-height: 1.55;
}

.ui-estado__icone {
    flex: none;
    margin-top: .1rem;
}

.ui-estado--sucesso { background: var(--w-success-bg, #e7f7ee); color: var(--w-success-fg, #14724a); }
.ui-estado--erro    { background: var(--w-danger-bg, #fdeaea);  color: var(--w-danger-fg, #a12626); }
.ui-estado--alerta  { background: var(--w-warning-bg, #fff8e6); color: var(--w-warning-fg, #7a5b12); }
.ui-estado--info    { background: var(--w-info-bg, #e8f1fe);    color: var(--w-info-fg, #1d4ed8); }

/*------------------------------------------------------------------------------
  Carregando
------------------------------------------------------------------------------*/

.ui-carregando {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    padding: 2rem 1rem;
    color: var(--w-text-secondary);
    font-size: var(--w-text-sm, .875rem);
}

.ui-carregando::before {
    content: "";
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-right-color: transparent;
    animation: ui-girar .7s linear infinite;
}

/* Esqueleto para listas que carregam depois: mantem a altura da area e evita o
   salto de layout quando o conteudo chega. */
.ui-esqueleto {
    height: 1em;
    border-radius: 6px;
    background: linear-gradient(90deg,
        var(--w-surface-sunken) 25%,
        var(--w-surface-hover) 50%,
        var(--w-surface-sunken) 75%);
    background-size: 200% 100%;
    animation: ui-esqueleto 1.4s ease-in-out infinite;
}

@keyframes ui-esqueleto {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .ui-esqueleto { animation-duration: 4s; }
}

/*------------------------------------------------------------------------------
  Desabilitado

  Regra unica para qualquer controle: opacidade, cursor e nenhum evento de
  ponteiro — para o clique nao "quase funcionar".
------------------------------------------------------------------------------*/

.ui-desabilitado,
[aria-disabled="true"] {
    opacity: .55;
    cursor: not-allowed;
    pointer-events: none;
}

/*==============================================================================
  MODAIS — comportamento comum

  O Bootstrap ja cuida do foco e do backdrop. O que falta e o corpo rolar sem
  levar o rodape junto: num formulario longo em 375px, botao que rola para fora
  e botao que a pessoa nao encontra.
==============================================================================*/

.modal-dialog-scrollable .modal-body {
    overflow-y: auto;
}

.w-main .modal-content,
body .modal-content {
    border: 0;
    border-radius: var(--w-radius-lg, 14px);
    background: var(--w-surface);
    color: var(--w-text-primary);
}

body .modal-header,
body .modal-footer {
    border-color: var(--w-border);
}

body .modal-footer {
    /* Rodape sempre alcancavel: fica fora da area rolavel. */
    position: sticky;
    bottom: 0;
    background: var(--w-surface);
    gap: .5rem;
}

@media (max-width: 40rem) {
    /* Celular: a modal ocupa a tela inteira, como um app. Uma caixa centralizada
       com margem sobrando desperdica altura justamente onde ela e escassa. */
    .modal-dialog {
        margin: 0;
        max-width: 100%;
        min-height: 100%;
    }

    .modal-content {
        min-height: 100vh;
        border-radius: 0;
    }

    body .modal-footer {
        flex-direction: column-reverse;
    }

    body .modal-footer > .btn,
    body .modal-footer > .ui-btn {
        width: 100%;
        margin: 0;
        min-height: 44px;
    }
}

/* ── Modo manutenção no menu do usuário ─────────────────────────────────────
   O ponto colorido diz o estado atual num relance: apagado é sistema aberto,
   aceso é manutenção ligada. Sem ele o item vira uma frase que exige leitura
   para saber o que vai acontecer ao clicar. */
.w-manutencao__acao {
    display: flex;
    align-items: center;
    gap: 8px;
}

.w-manutencao__ponto {
    width: 8px;
    height: 8px;
    flex: none;
    border-radius: 50%;
    background: var(--w-text-secondary, #94a3b8);
    opacity: .5;
}

.w-manutencao__ponto.is-ligado {
    background: var(--w-danger, #dc2626);
    opacity: 1;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--w-danger, #dc2626) 22%, transparent);
}

/* ── Aviso em modal ─────────────────────────────────────────────────────────
   Confirmação que exige um olhar, ao contrário do toast que some sozinho. */
.az-aviso {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: grid;
    place-items: center;
    padding: var(--w-space-4, 16px);
}

.az-aviso[hidden] { display: none; }

body.az-aviso-aberto { overflow: hidden; }

.az-aviso__fundo {
    position: absolute;
    inset: 0;
    background: rgb(0 0 0 / .45);
    backdrop-filter: blur(2px);
}

.az-aviso__caixa {
    position: relative;
    width: min(26rem, 100%);
    padding: var(--w-space-6, 24px);
    border-radius: var(--w-radius-lg, 16px);
    background: var(--w-surface);
    border: 1px solid var(--w-border);
    box-shadow: var(--w-shadow-lg, 0 18px 48px rgb(0 0 0 / .28));
    text-align: center;
    animation: az-aviso-entra .18s var(--w-ease-out, ease-out);
}

@keyframes az-aviso-entra {
    from { opacity: 0; transform: translateY(10px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

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

.az-aviso__icone {
    width: 56px;
    height: 56px;
    margin: 0 auto var(--w-space-4, 16px);
    display: grid;
    place-items: center;
    border-radius: 50%;
    font-size: 24px;
    background: color-mix(in srgb, var(--w-success, #059669) 14%, transparent);
    color: var(--w-success, #059669);
}

.az-aviso[data-tipo="erro"] .az-aviso__icone {
    background: color-mix(in srgb, var(--w-danger) 14%, transparent);
    color: var(--w-danger);
}

.az-aviso[data-tipo="aviso"] .az-aviso__icone {
    background: color-mix(in srgb, var(--w-warning, #d97706) 16%, transparent);
    color: var(--w-warning, #d97706);
}

.az-aviso[data-tipo="info"] .az-aviso__icone {
    background: color-mix(in srgb, var(--w-accent) 14%, transparent);
    color: var(--w-accent);
}

.az-aviso__titulo {
    margin: 0 0 var(--w-space-2, 8px);
    font-size: var(--w-text-xl, 1.25rem);
    font-weight: var(--w-weight-bold, 700);
    color: var(--w-text-primary);
}

.az-aviso__texto {
    margin: 0;
    color: var(--w-text-secondary);
    line-height: 1.55;
}

.az-aviso__texto[hidden] { display: none; }

.az-aviso__lista {
    margin: var(--w-space-4, 16px) 0 0;
    padding: var(--w-space-3, 12px);
    list-style: none;
    text-align: left;
    border-radius: var(--w-radius-md, 10px);
    background: var(--w-surface-sunken);
    font-size: var(--w-text-sm, .875rem);
    color: var(--w-text-secondary);
    max-height: 9rem;
    overflow-y: auto;
}

.az-aviso__lista[hidden] { display: none; }

.az-aviso__lista li { padding: 2px 0; }

.az-aviso__acoes {
    display: flex;
    gap: var(--w-space-2, 8px);
    justify-content: center;
    margin-top: var(--w-space-5, 20px);
}

.az-aviso__x {
    position: absolute;
    top: 10px;
    right: 12px;
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--w-text-tertiary);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
}

.az-aviso__x:hover { background: var(--w-surface-hover); color: var(--w-text-primary); }

/* ── Aviso do período de teste ──────────────────────────────────────────────
   Fica no topo do conteúdo, acima de tudo. Chama atenção sem travar a tela:
   um bloqueio a três dias do fim seria punir quem ainda está decidindo. */
.w-teste {
    display: flex;
    align-items: center;
    gap: var(--w-space-3, 12px);
    margin-bottom: var(--w-space-4, 16px);
    padding: var(--w-space-3, 12px) var(--w-space-4, 16px);
    border: 1px solid color-mix(in srgb, var(--w-warning, #d97706) 38%, transparent);
    border-radius: var(--w-radius-lg, 14px);
    background: color-mix(in srgb, var(--w-warning, #d97706) 10%, var(--w-surface));
}

/* No último dia a cor muda: é a diferença entre lembrete e prazo vencendo. */
.w-teste--ultimo {
    border-color: color-mix(in srgb, var(--w-danger) 42%, transparent);
    background: color-mix(in srgb, var(--w-danger) 10%, var(--w-surface));
}

.w-teste__icone {
    width: 36px;
    height: 36px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: color-mix(in srgb, var(--w-warning, #d97706) 20%, transparent);
    color: var(--w-warning, #d97706);
}

.w-teste--ultimo .w-teste__icone {
    background: color-mix(in srgb, var(--w-danger) 18%, transparent);
    color: var(--w-danger);
}

.w-teste__texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }

.w-teste__texto strong {
    font-size: var(--w-text-sm, .875rem);
    font-weight: var(--w-weight-semibold, 600);
    color: var(--w-text-primary);
}

.w-teste__texto span { font-size: var(--w-text-xs, .75rem); color: var(--w-text-secondary); }

.w-teste__acao {
    flex: none;
    padding: 9px 16px;
    border-radius: var(--w-radius-md, 10px);
    background: var(--w-accent);
    color: var(--w-accent-contrast, #fff);
    font-size: var(--w-text-sm, .875rem);
    font-weight: var(--w-weight-semibold, 600);
    text-decoration: none;
    white-space: nowrap;
}

.w-teste__acao:hover { filter: brightness(1.07); color: var(--w-accent-contrast, #fff); }

.w-teste__fechar {
    flex: none;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--w-text-tertiary);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

.w-teste__fechar:hover { background: var(--w-surface-hover); color: var(--w-text-primary); }

/* No celular empilha: o botão precisa da linha inteira para ser um alvo de
   toque confortável. */
@media (max-width: 40rem) {
    .w-teste { flex-wrap: wrap; }
    .w-teste__texto { flex: 1 1 60%; }
    .w-teste__acao { flex: 1 1 100%; text-align: center; order: 3; }
}
