/* ==========================================================================
   Formulários

   Estrutura obrigatória do campo:

     <div class="field">
         <label class="field__label" for="id">Rótulo</label>
         <input class="input" id="id" aria-describedby="id-hint">
         <p class="field__hint" id="id-hint">Apoio.</p>
         <p class="field__error" id="id-error">Erro.</p>
     </div>

   Em erro, o controle precisa de aria-invalid="true" E aria-describedby
   apontando para o .field__error. Um sem o outro pinta a borda mas não
   avisa quem usa leitor de tela. O componente Plates components/field cuida
   dos dois; markup manual precisa fazer à mão.
   ========================================================================== */

/* ==========================================================================
   Grade de campos
   ========================================================================== */

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }

.form-grid--single { grid-template-columns: minmax(0, 1fr); }

.form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }

.field--wide { grid-column: 1 / -1; }

.field--end { justify-content: flex-end; }

.field__label { font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--color-title); }

.field__hint { font-size: var(--fs-xs); color: var(--color-text-secondary); }

.field__hint--block { display: block; }

.field__error { font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--color-danger-text); }

/* Marcador de obrigatório: o asterisco é decorativo, o required do controle
   é o que vale para tecnologia assistiva. */
.field__required { color: var(--color-danger-text); }

/* ==========================================================================
   Controles de texto

   A borda padrão usa o token Gray 200. Foco, erro e demais estados continuam
   semânticos e mais destacados.
   ========================================================================== */

.input,
.select,
.textarea {
    height: var(--control-h);
    width: 100%;
    border: var(--border-width) solid var(--color-border-control);
    border-radius: var(--radius-control);
    padding: 0 var(--space-3);
    font-family: inherit;
    font-size: var(--fs-sm);
    color: var(--color-title);
    background: var(--color-body);
    outline: none;
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.input:hover,
.select:hover,
.textarea:hover { border-color: var(--color-text-secondary); }

.input:focus,
.select:focus,
.textarea:focus {
    border-color: var(--color-border-interactive);
    box-shadow: var(--focus-ring);
}

.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"] { border-color: var(--color-danger-solid); }

.input[aria-invalid="true"]:focus,
.select[aria-invalid="true"]:focus,
.textarea[aria-invalid="true"]:focus {
    border-color: var(--color-danger-text);
    box-shadow: 0 0 0 3px var(--color-danger-surface);
}

.input[disabled],
.select[disabled],
.textarea[disabled] {
    background: var(--color-body-secondary);
    color: var(--color-text-secondary);
    cursor: not-allowed;
}

.input::placeholder,
.textarea::placeholder { color: var(--color-text-tertiary); }

.textarea {
    height: auto;
    min-height: 96px;
    padding: var(--space-3);
    resize: vertical;
    line-height: var(--lh-base);
}

/* ==========================================================================
   Select

   <select> nativo com chevron em data: URI — a CSP permite data: em
   background-image. Não trocar por <img> nem por ícone Lucide.
   O traço do chevron é --color-gray-500 codificado; ao mudar o token,
   atualize também o %23757575 abaixo.
   ========================================================================== */

.select {
    appearance: none;
    cursor: pointer;
    padding-right: var(--space-8);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23757575' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--space-3) center;
}

/* Larguras de select na toolbar. Nunca style="width:…" na view. */
.select--inline  { width: auto; min-width: 168px; }
.select--auto    { width: auto; min-width: 170px; }
.select--auto-lg { width: auto; min-width: 190px; }
/* Filtro de listagem: largura do CONTEÚDO, sem piso.

   Os três acima têm piso porque nasceram para formulário, onde a coluna de
   campos precisa alinhar. Numa barra de filtros o piso é o problema: quatro
   controles a 168px somam 672px de largura mínima só para dizer "Etapa",
   "Responsável", "Origem" e "Prioridade" — encurtar o rótulo não muda nada,
   porque quem manda é o `min-width`.

   Sem piso, o controle mede o próprio rótulo e cresce só quando um filtro
   entra em vigor, que é exatamente quando ele merece ocupar mais espaço. O
   teto de 190px com truncamento evita que um valor longo empurre a barra. */
.select--compact { width: auto; min-width: 0; max-width: 190px; }

/* ==========================================================================
   Arquivo
   ========================================================================== */

.input[type="file"] {
    height: auto;
    min-height: 56px;
    padding: var(--space-2);
    border-style: dashed;
    color: var(--color-text-secondary);
    cursor: pointer;
}

.input[type="file"]::file-selector-button {
    height: var(--control-h);
    margin-right: var(--space-3);
    padding: 0 var(--space-4);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-control);
    color: var(--color-text);
    background: var(--color-body-secondary);
    font: inherit;
    font-weight: var(--fw-medium);
    cursor: pointer;
}

.input[type="file"]:hover::file-selector-button {
    border-color: var(--color-primary-600);
    color: var(--color-primary-700);
}

/* ==========================================================================
   Caixa de seleção
   ========================================================================== */

.check {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--fs-sm);
    color: var(--color-text);
    cursor: pointer;
}

.check--top { align-items: flex-start; }

.check input[type="checkbox"] {
    appearance: none;
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    display: grid;
    place-items: center;
    border: var(--border-width) solid var(--color-border-control);
    border-radius: var(--radius-control);
    background: var(--color-body);
    cursor: pointer;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.check input[type="checkbox"]::before {
    content: "";
    width: 8px;
    height: 4px;
    border: solid var(--color-white);
    border-width: 0 0 2px 2px;
    opacity: 0;
    transform: translateY(-1px) rotate(-45deg) scale(.7);
    transition: opacity var(--transition-fast), transform var(--transition-fast);
}

.check input[type="checkbox"]:checked {
    border-color: var(--color-primary-600);
    background: var(--color-primary-600);
}

.check input[type="checkbox"]:checked::before { opacity: 1; transform: translateY(-1px) rotate(-45deg) scale(1); }

.check input[type="checkbox"]:focus-visible { outline: 0; box-shadow: var(--focus-ring); border-color: var(--color-primary-600); }

/* ==========================================================================
   Interruptor — para ligar/desligar de efeito imediato
   ========================================================================== */

.switch {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    color: var(--color-text);
    cursor: pointer;
}

.switch--top { align-items: flex-start; }

.switch input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.switch__control {
    position: relative;
    flex: 0 0 auto;
    width: 36px;
    height: 20px;
    border: var(--border-width) solid var(--color-border-control);
    border-radius: var(--radius-pill);
    background: var(--color-gray-400);
    transition: border-color var(--transition-base), background-color var(--transition-base);
}

.switch__control::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: var(--radius-full);
    background: var(--color-white);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
    transition: transform var(--transition-base);
}

.switch input:checked + .switch__control {
    border-color: var(--color-primary-600);
    background: var(--color-primary-600);
}

.switch input:checked + .switch__control::after { transform: translateX(16px); }

.switch input:focus-visible + .switch__control { box-shadow: var(--focus-ring); }

.switch strong,
.switch small { display: block; }

.switch strong { font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.switch small { margin-top: 2px; font-size: var(--fs-xs); color: var(--color-text-secondary); }

/* ==========================================================================
   Senha
   ========================================================================== */

.password-field { position: relative; }

.password-field__input { padding-right: 44px; }

.password-field__toggle {
    position: absolute;
    top: 0;
    right: 0;
    width: var(--control-h);
    height: var(--control-h);
    display: grid;
    place-items: center;
    border: 0;
    border-radius: var(--radius-control);
    color: var(--color-text-secondary);
    background: transparent;
    cursor: pointer;
}

.password-field__toggle:hover { color: var(--color-primary-700); }

.password-field__toggle:focus-visible {
    color: var(--color-primary-700);
    outline: var(--focus-outline);
    outline-offset: calc(var(--focus-offset) * -1);
}

/* ==========================================================================
   Busca

   Duas mecânicas, UMA aparência — sempre a mesma caixa, altura e borda:

     .search            submete um <form> GET. Alcança a base inteira, inclusive
                        o que está em outra página da paginação. Ícone à direita,
                        porque é um botão de verdade.
     .search--live      filtra as linhas já renderizadas enquanto se digita
                        (data-table-filter). Só faz sentido em lista sem
                        paginação. Mantém o ícone à direita como as demais
                        buscas, embora não precise submeter o formulário.

   As duas gravam o termo na URL: o app.js espelha o filtro instantâneo em ?q=
   com replaceState e o restaura ao carregar. Sem isso, quem copiava o endereço
   de uma lista filtrada mandava a lista inteira para o colega.
   ========================================================================== */

.search { position: relative; display: flex; align-items: center; width: min(var(--container-search), 100%); }

.project-list-search .toolbar__group,
.project-list-search .search,
.client-list-search .toolbar__group,
.client-list-search .search { width: 100%; }

.orders-toolbar .toolbar__group:first-child { flex: 1 1 760px; }
.orders-toolbar .search { width: auto; flex: 1 1 360px; }

.service-list-toolbar .toolbar__group:first-child {
    min-width: 0;
    flex: 1 1 760px;
    flex-wrap: nowrap;
}

.service-list-toolbar .search {
    width: auto;
    min-width: 240px;
    flex: 1 1 360px;
}

.support-list-toolbar .toolbar__group:first-child { flex: 1 1 760px; }
.support-list-toolbar .search { flex: 1 1 360px; }

.follow-up-list-toolbar .toolbar__group:first-child { flex: 1 1 760px; }
.follow-up-list-toolbar .search { flex: 1 1 360px; }

/* Busca que divide a toolbar com filtros. Os 560px de --container-search
   são a medida da busca sozinha; ao lado de dois selects ela estourava a
   linha e empurrava os filtros para uma segunda fileira, deixando a barra
   com duas alturas e o contador solto no canto. */
.search--inline { width: min(var(--container-search-inline), 100%); }

.search__icon {
    position: absolute;
    top: 50%;
    right: var(--space-3);
    display: flex;
    color: var(--color-text-secondary);
    pointer-events: none;
    transform: translateY(-50%);
}

.search--live .search__input { padding: 0 44px 0 var(--space-3); }

.search__input {
    height: var(--control-h);
    width: 100%;
    border: var(--border-width) solid var(--color-border-control);
    border-radius: var(--radius-control);
    padding: 0 44px 0 var(--space-3);
    font-family: inherit;
    font-size: var(--fs-sm);
    color: var(--color-title);
    background: var(--color-body);
    outline: none;
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.search__input::placeholder { color: var(--color-text-tertiary); }

.search__input:hover { border-color: var(--color-text-secondary); }

.search__input:focus { border-color: var(--color-border-interactive); box-shadow: var(--focus-ring); }

.search__button {
    position: absolute;
    top: 0;
    right: 0;
    width: var(--control-h);
    height: var(--control-h);
    display: grid;
    place-items: center;
    border: 0;
    border-radius: var(--radius-control);
    color: var(--color-text-secondary);
    background: transparent;
    cursor: pointer;
}

.search__button:hover { color: var(--color-primary-700); }

.search__button:focus-visible {
    color: var(--color-primary-700);
    outline: var(--focus-outline);
    outline-offset: calc(var(--focus-offset) * -1);
}

/* ==========================================================================
   Rodapé de formulário
   ========================================================================== */

/* Mesma convenção do rodapé de drawer (.modal footer em dialogs.css): ações à
   esquerda e a primária primeiro. O formulário se lê de cima para baixo e da
   esquerda para a direita, e confirmar é o destino do fluxo — a página e o
   drawer não podem inverter a ordem um do outro.

   O "Cancelar" ao lado é `.btn` puro, a variante fantasma: sem fundo e sem
   traço. Não use `.btn--outline` aqui — a moldura o empata com a primária. */
.form-actions {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: var(--space-2);
    padding: var(--space-4) var(--space-6);
    border-top: var(--border-width) solid var(--color-border);
    background: var(--color-body-secondary);
    flex-wrap: wrap;
}

.form-actions .btn--primary,
.form-actions .btn--danger { order: -1; }

.user-list-search,
.notification-list-search { width: 100%; }
.user-list-search .toolbar,
.user-list-search .toolbar__group,
.user-list-search .search,
.notification-list-search .toolbar,
.notification-list-search .toolbar__group,
.notification-list-search .search { width: 100%; max-width: none; }

.user-company-access {
    padding: var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-box);
    background: var(--color-body-secondary);
}

/* ==========================================================================
   Área de troca de avatar (perfil)
   ========================================================================== */

.avatar-drop {
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) dashed var(--color-border-control);
    border-radius: var(--radius-box);
    cursor: pointer;
    margin-bottom: var(--space-4);
    transition: border-color var(--transition-fast), background var(--transition-fast);
}

.avatar-drop:hover { border-color: var(--color-primary-600); background: var(--color-body-secondary); }

.avatar-drop__title { display: block; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--color-title); }

.avatar-drop__meta { display: block; font-size: var(--fs-xs); color: var(--color-text-secondary); margin-top: 2px; }

.profile-security-list {
    display: grid;
    gap: var(--space-2);
    margin: 0;
    padding-left: var(--space-5);
    color: var(--color-text);
    font-size: var(--fs-sm);
}

/* ==========================================================================
   Select personalizado (data-pick)

   Duas portas de entrada, um componente só:

     data-pick           markup escrito na view. Serve quando a opção não é
                         texto puro — etiqueta colorida de etapa, avatar de
                         responsável — porque <option> só aceita texto.
     data-select-search  atributo em um <select class="select"> comum. O app.js
                         monta o mesmo .pick a partir das <option> e mantém o
                         <select> no formulário, invisível, guardando o valor.

   A segunda é o padrão do portal: dá busca dentro da lista e não custa markup
   novo na view. Como o <select> continua lá, `required`, submissão, `change`
   (usado pelos filtros) e a tela sem JS seguem funcionando.
   ========================================================================== */

.pick { position: relative; min-width: 0; }

.pick__btn {
    width: 100%;
    min-height: var(--control-h-compact);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    border: var(--border-width) solid transparent;
    border-radius: var(--radius-control);
    background: transparent;
    font-family: inherit;
    font-size: var(--fs-sm);
    color: var(--color-title);
    text-align: left;
    transition: background var(--transition-fast), border-color var(--transition-fast);
}

.pick__btn:hover { background: var(--color-body-tertiary); border-color: var(--color-border-strong); }

.pick__btn[aria-expanded="true"] { background: var(--color-body-tertiary); border-color: var(--color-border-strong); }

.pick__btn:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-offset); }

.pick__value { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; }

.pick__value .truncate { min-width: 0; }

.pick__chevron { flex: 0 0 auto; color: var(--color-text-tertiary); }

.pick__list {
    position: absolute;
    z-index: var(--z-dropdown);
    top: calc(100% + var(--space-1));
    left: 0;
    min-width: 100%;
    max-height: 264px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--space-1);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-box);
    background: var(--color-body);
    box-shadow: var(--shadow-menu);
}

/* Perto da borda direita do modal a lista abriria para fora da tela. */
.pick__list--right { left: auto; right: 0; }

.pick__opt {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2);
    border: 0;
    border-radius: var(--radius-control);
    background: transparent;
    font-family: inherit;
    font-size: var(--fs-sm);
    color: var(--color-text);
    text-align: left;
    cursor: pointer;
    transition: background var(--transition-fast);
}

.pick__opt:hover { background: var(--color-body-tertiary); }

.pick__opt:focus-visible { outline: var(--focus-outline); outline-offset: calc(var(--focus-offset) * -1); }

.pick__opt[aria-selected="true"] { background: var(--color-primary-surface); color: var(--color-primary-700); }

/* O contorno de seleção não pode ser só a cor de fundo. */
.pick__check { margin-left: auto; flex: 0 0 auto; color: var(--color-primary-700); visibility: hidden; }

.pick__opt[aria-selected="true"] .pick__check { visibility: visible; }

.pick__status-dot { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 50%; background: var(--color-neutral-solid); }
.pick__status-dot--success { background: var(--color-success-solid); }
.pick__status-dot--info { background: var(--color-info-solid); }
.pick__status-dot--warning { background: var(--color-warning-solid); }
.pick__status-dot--danger { background: var(--color-danger-solid); }
.pick__status-dot--purple { background: var(--color-purple-solid); }

/* Variante de formulário: mesma geometria do .select nativo. */
.pick--field .pick__btn {
    min-height: var(--control-h);
    padding-inline: var(--space-3);
    border-color: var(--color-border-control);
    background: var(--color-body);
}

.pick--field .pick__btn:hover { border-color: var(--color-text-secondary); background: var(--color-body); }

.pick--field .pick__btn[aria-expanded="true"] {
    border-color: var(--color-border-interactive);
    background: var(--color-body);
    box-shadow: var(--focus-ring);
}

.pick--field .pick__btn[aria-invalid="true"] { border-color: var(--color-danger-solid); }

.pick--field .pick__btn[disabled] {
    background: var(--color-body-secondary);
    color: var(--color-text-secondary);
    pointer-events: none;
}

/* Enquanto nada foi escolhido, o rótulo é um espaço reservado — mesmo cinza
   do ::placeholder do .input, e não a cor de um valor real. */
.pick__placeholder { color: var(--color-text-tertiary); }

/* Larguras da toolbar, espelhando .select--inline/--auto/--auto-lg: o app.js
   traduz a classe do <select> ao montar o pick. */
.pick--inline  { width: auto; min-width: 168px; }
.pick--auto    { width: auto; min-width: 170px; }
.pick--auto-lg { width: auto; min-width: 190px; }
.pick--compact { width: auto; min-width: 0; max-width: 190px; }

/* Sem espaço abaixo — dentro de drawer, sobretudo — a lista abre para cima. */
.pick__list--up { top: auto; bottom: calc(100% + var(--space-1)); }

/* ---- Busca dentro da lista ----
   Quem rola é .pick__options, não .pick__list: assim o campo de busca fica
   sempre à vista, sem depender de position: sticky. */

.pick__search {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-1);
    padding-inline: var(--space-2);
    border: var(--border-width) solid var(--color-border-control);
    border-radius: var(--radius-control);
    background: var(--color-body);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.pick__search:focus-within { border-color: var(--color-border-interactive); box-shadow: var(--focus-ring); }

.pick__search-icon { flex: 0 0 auto; color: var(--color-text-secondary); display: flex; }

.pick__search-input {
    flex: 1 1 auto;
    min-width: 0;
    height: var(--control-h-compact);
    border: 0;
    padding: 0;
    font-family: inherit;
    font-size: var(--fs-sm);
    color: var(--color-title);
    background: transparent;
    outline: none;
}

.pick__search-input::placeholder { color: var(--color-text-tertiary); }

.pick__options {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 216px;
    overflow-y: auto;
}

.pick__empty { padding: var(--space-3) var(--space-2); font-size: var(--fs-xs); color: var(--color-text-secondary); text-align: center; }

/* O <select> não sai do formulário: ele guarda o valor, valida `required` e
   submete. Fica invisível, mas não em display:none — o balão de validação do
   navegador precisa de um alvo posicionado, senão o Chrome recusa a submissão
   com "invalid form control is not focusable" e o usuário não vê nada. */
.pick__native {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1px;
    padding: 0;
    border: 0;
    opacity: 0;
    pointer-events: none;
}

/* ==========================================================================
   Responsivo
   ========================================================================== */

@media (max-width: 900px) {
    .form-grid,
    .form-grid--3 { grid-template-columns: minmax(0, 1fr); }

    .search { width: 100%; }

    .select--inline,
    .select--auto,
    .select--auto-lg,
    .pick--inline,
    .pick--auto,
    .pick--auto-lg { width: 100%; min-width: 0; }

    .orders-toolbar .toolbar__group:first-child {
        width: 100%;
        flex: 0 1 auto;
        flex-direction: column;
        align-items: stretch;
    }

    .orders-toolbar .search {
        width: 100%;
        flex: 0 1 auto;
    }

    .service-list-toolbar .toolbar__group:first-child {
        width: 100%;
        flex: 0 1 auto;
        flex-wrap: wrap;
    }

    .service-list-toolbar .search {
        width: 100%;
        min-width: 0;
        flex: 1 1 100%;
    }
}
