portal_publico/static/css/components.css

1140 lines
25 KiB
CSS

.icon-btn {
display: flex;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
border-radius: var(--radius-sm);
color: var(--text-secondary);
transition: background var(--transition-fast), color var(--transition-fast), transform 100ms ease;
}
.icon-btn:hover {
background: var(--bg-surface-raised);
color: var(--text-primary);
}
.icon-btn:active {
transform: scale(0.92);
}
/* Botão "?" reutilizável ao lado do nome de uma aplicação (ver
static/js/ajuda-aplicacao.js) — tooltip "Mais informações" ao passar o
mouse, CSS puro (sem JS de posicionamento) porque a posição relativa ao
próprio botão nunca varia, ao contrário de .sidebar-tooltip acima. */
.info-tooltip {
position: relative;
display: inline-flex;
}
.info-tooltip__trigger {
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
border-radius: var(--radius-pill);
border: 1px solid var(--border-subtle);
background: transparent;
color: var(--text-secondary);
font-size: 0.7rem;
font-weight: 700;
line-height: 1;
transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}
.info-tooltip__trigger:hover,
.info-tooltip__trigger:focus-visible {
background: var(--bg-surface-raised);
color: var(--accent);
border-color: var(--accent);
}
.info-tooltip__text {
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
background: var(--bg-surface-raised);
color: var(--text-primary);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
padding: var(--space-1) var(--space-2);
font-size: 0.75rem;
box-shadow: var(--shadow-sm);
opacity: 0;
pointer-events: none;
transition: opacity var(--transition-fast);
z-index: 20;
}
.info-tooltip__trigger:hover + .info-tooltip__text,
.info-tooltip__trigger:focus-visible + .info-tooltip__text {
opacity: 1;
}
.btn-ghost {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-pill);
border: 1px solid var(--accent);
color: var(--accent);
font-size: 0.85rem;
font-weight: 600;
transition: background var(--transition-fast), color var(--transition-fast), transform 100ms ease;
}
.btn-ghost:active,
.btn-solid:active,
.btn-outline:active,
.btn-danger-outline:active {
transform: scale(0.97);
}
.btn-solid {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-sm);
background: var(--accent);
color: var(--accent-contrast);
font-size: 0.85rem;
font-weight: 600;
transition: background var(--transition-fast), transform 100ms ease;
}
.btn-solid:hover {
background: var(--accent-hover);
}
.btn-outline {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-sm);
border: 1px solid var(--border-subtle);
color: var(--text-secondary);
font-size: 0.85rem;
font-weight: 600;
transition: border-color var(--transition-fast), color var(--transition-fast), transform 100ms ease;
}
.btn-outline:hover {
border-color: var(--accent);
color: var(--text-primary);
}
.btn-danger-outline {
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-sm);
border: 1px solid var(--danger);
color: var(--danger);
font-size: 0.85rem;
font-weight: 600;
margin-right: auto;
transition: background var(--transition-fast), color var(--transition-fast), transform 100ms ease;
}
.btn-danger-outline:hover {
background: var(--danger);
color: #fff;
}
/* Modal genérico (reutilizado por compromissos, widgets, etc.) */
.modal-overlay {
position: fixed;
inset: 0;
background: var(--overlay-scrim);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
padding: var(--space-5);
animation: pidFadeIn 120ms ease;
}
/* Empilha um modal por cima de outro já aberto — usado só pelo modal de
confirmação genérico (static/js/confirm-modal.js), que precisa aparecer
por cima de qualquer modal em edição sem fechá-lo. */
.modal-overlay--top {
z-index: 150;
}
.modal-card {
width: 100%;
max-width: 420px;
/* .modal-overlay já centraliza com padding:var(--space-5) nos 4 lados —
sem isso, um modal com conteúdo dinâmico (ex. lista de componentes de
indicador, dashboard-contabil.js) cresce pra fora da tela e força o
usuário a dar zoom out pra alcançar os botões no rodapé. */
max-height: calc(100vh - var(--space-5) * 2);
overflow-y: auto;
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
padding: var(--space-6) var(--space-5);
display: flex;
flex-direction: column;
gap: var(--space-4);
animation: pidScaleIn 160ms ease;
}
.modal-card__title {
font-size: 1.05rem;
font-weight: 700;
}
.modal-card__subtitle {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.5;
}
/* Modal que precisa de mais espaço horizontal que o padrão de 420px — hoje
usado só por #manage-account-modal quando o campo de liderados (duas
tabelas lado a lado, ver .dual-select abaixo) está visível; aplicado/
removido em JS conforme `me.lideranca`, pra não deixar o modal largo à
toa quando só tem o botão "Alterar senha". */
.modal-card--wide {
max-width: 760px;
}
/* Modal que embute uma ferramenta externa num <iframe> (ex.: "Calendário De
Paula" no sidebar, todo shell) — ocupa quase a tela inteira e o iframe
preenche todo o espaço vertical restante (flex:1 dentro do .modal-card,
que já é flex-column), senão o conteúdo da ferramenta externa (mais alto
que um modal padrão) fica cortado no meio de um campo em vez de rolar de
forma previsível. Mesmo padrão do modal "Novo Chamado" de ramais.css
(`.ram-chamado-*`), só que genérico aqui porque é usado em todo shell,
não só em ramais.html. */
.iframe-modal-card {
width: min(1400px, 97vw);
max-width: none;
height: min(92vh, 1000px);
max-height: 92vh;
}
.iframe-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
}
.iframe-modal-iframe {
flex: 1;
width: 100%;
min-height: 0;
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
background: #fff;
}
/* Campos de formulário genéricos para dentro de um .modal-card */
.modal-field {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.modal-field-row {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: var(--space-4);
}
.modal-field label {
font-size: 0.8rem;
font-weight: 600;
color: var(--text-secondary);
}
.modal-field p {
font-size: 0.9rem;
color: var(--text-primary);
}
.modal-field input:not([type="checkbox"]):not([type="radio"]):not([type="file"]) {
width: 100%;
padding: var(--space-3);
border-radius: var(--radius-sm);
border: 1px solid var(--border-subtle);
background: var(--bg-canvas);
color: var(--text-primary);
font-size: 0.9rem;
outline: none;
}
.modal-field input:focus {
border-color: var(--accent);
}
.modal-field select {
width: 100%;
padding: var(--space-3);
padding-right: var(--space-7);
border-radius: var(--radius-sm);
border: 1px solid var(--border-subtle);
background-color: var(--bg-canvas);
color: var(--text-primary);
font-size: 0.9rem;
outline: none;
appearance: none;
-webkit-appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238a8598' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right var(--space-3) center;
}
.modal-field select:focus {
border-color: var(--accent);
}
.modal-field textarea {
width: 100%;
padding: var(--space-3);
border-radius: var(--radius-sm);
border: 1px solid var(--border-subtle);
background: var(--bg-canvas);
color: var(--text-primary);
font-size: 0.9rem;
outline: none;
font-family: inherit;
resize: vertical;
}
.modal-field textarea:focus {
border-color: var(--accent);
}
/* Campo de senha com botão de mostrar/ocultar (usado em .pa-field e .modal-field) */
.password-field {
position: relative;
}
.pa-field .password-field input[type="password"],
.pa-field .password-field input[type="text"],
.modal-field .password-field input[type="password"],
.modal-field .password-field input[type="text"] {
padding-right: var(--space-7);
}
.password-field__toggle {
position: absolute;
right: var(--space-2);
top: 50%;
transform: translateY(-50%);
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
border-radius: var(--radius-sm);
}
.password-field__toggle:hover {
color: var(--text-primary);
background: var(--bg-surface-raised);
}
.modal-checkbox {
display: flex;
align-items: center;
gap: var(--space-2);
font-size: 0.85rem;
color: var(--text-primary);
}
.modal-checkbox input {
width: 16px;
height: 16px;
accent-color: var(--accent);
}
.modal-error {
min-height: 1em;
font-size: 0.78rem;
color: var(--danger);
}
.modal-actions {
display: flex;
gap: var(--space-3);
justify-content: flex-end;
}
.modal-actions--spread {
justify-content: space-between;
}
/* Agrupa botões dentro de um dos lados de `.modal-actions--spread` — usado
quando um lado (ex.: "Excluir") precisa ficar isolado de vários botões do
outro lado (ex.: "Fechar"/"Salvar alterações"), não só um botão por lado. */
.modal-actions__group {
display: flex;
gap: var(--space-3);
}
/* Modal de "Mais informações" (ver static/js/ajuda-aplicacao.js) — único,
criado sob demanda e reaproveitado por todas as aplicações da página. */
.ajuda-modal__card {
max-width: 620px;
}
.ajuda-modal__titulo {
font-size: 1.05rem;
font-weight: 700;
}
.ajuda-modal__texto {
white-space: pre-wrap;
color: var(--text-primary);
font-size: 0.9rem;
line-height: 1.6;
max-height: 55vh;
overflow-y: auto;
}
.ajuda-modal__texto img {
max-width: 100%;
border-radius: var(--radius-sm);
margin: var(--space-2) 0;
}
/* Editor rico (contenteditable + imagens embutidas via colar/arrastar) —
mesmo mecanismo de .ag-richtext (acessos-gerais.js), reimplementado aqui
porque este modal pode aparecer em qualquer página, não só
acessos-gerais.html (que é onde .ag-richtext mora, escopado). */
.ajuda-modal__editor {
min-height: 220px;
max-height: 55vh;
overflow-y: auto;
padding: var(--space-3);
border-radius: var(--radius-sm);
border: 1px solid var(--border-subtle);
background: var(--bg-canvas);
color: var(--text-primary);
font-size: 0.9rem;
outline: none;
}
.ajuda-modal__editor:focus {
border-color: var(--accent);
}
.ajuda-modal__editor:empty::before {
content: attr(data-placeholder);
color: var(--text-muted);
}
.ajuda-modal__editor img {
max-width: 100%;
border-radius: var(--radius-sm);
margin: var(--space-2) 0;
}
.ajuda-modal__editor-hint {
font-size: 0.76rem;
color: var(--text-muted);
}
.checklist-box {
display: flex;
flex-direction: column;
gap: var(--space-2);
background: var(--bg-canvas);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
padding: var(--space-3);
max-height: 180px;
overflow-y: auto;
}
.checklist-item {
display: flex;
align-items: flex-start;
gap: var(--space-2);
font-size: 0.88rem;
padding: var(--space-1) 0;
}
.checklist-item input {
width: 16px;
height: 16px;
margin-top: 2px;
accent-color: var(--accent);
flex-shrink: 0;
}
.checklist-item__info {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
flex: 1;
}
.checklist-item__departamento {
font-size: 0.78rem;
color: var(--text-muted);
white-space: normal;
overflow-wrap: break-word;
}
.checklist-empty {
font-size: 0.85rem;
color: var(--text-muted);
padding: var(--space-2) 0;
}
.checklist-search {
width: 100%;
padding: var(--space-2) var(--space-3);
border-radius: var(--radius-sm);
border: 1px solid var(--border-subtle);
background: var(--bg-canvas);
color: var(--text-primary);
font-size: 0.85rem;
outline: none;
margin-bottom: var(--space-2);
}
.checklist-search:focus {
border-color: var(--accent);
}
.checklist-select-all {
margin-bottom: var(--space-2);
}
/* Widget genérico de vinculação em duas tabelas (não vinculados à esquerda,
vinculados à direita — ver static/js/dual-select.js), com checkbox de
seleção múltipla, busca por coluna, ordenação por nome e um botão de ação
em lote por painel ("Vincular"/"Desvincular"). Mora aqui, não em
perfis-acesso.css, porque roda tanto em usuarios.html quanto dentro do
modal "Gerenciar Usuário" (presente em todo shell) — mesma razão de
.checklist-box viver aqui. Auto-contido (não reaproveita .pa-table),
porque a maioria dos shells que usam esse modal não carrega
perfis-acesso.css. */
.dual-select {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-4);
align-items: start;
}
@media (max-width: 720px) {
.dual-select {
grid-template-columns: 1fr;
}
}
.dual-select__panel-header {
display: flex;
align-items: center;
justify-content: flex-end;
margin-bottom: var(--space-2);
}
.dual-select__panel-header .btn-solid:disabled,
.dual-select__panel-header .btn-danger-outline:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.dual-select__table-wrap {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
overflow: hidden;
max-height: 280px;
overflow-y: auto;
}
.dual-select__table {
width: 100%;
border-collapse: collapse;
}
.dual-select__table thead {
position: sticky;
top: 0;
z-index: 1;
}
.dual-select__table th {
text-align: left;
font-size: 0.72rem;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--text-muted);
padding: var(--space-2) var(--space-3);
background: var(--bg-surface-raised);
border-bottom: 1px solid var(--border-subtle);
}
.dual-select__table td {
padding: var(--space-2) var(--space-3);
border-bottom: 1px solid var(--border-subtle);
font-size: 0.85rem;
color: var(--text-primary);
}
.dual-select__table tr:last-child td {
border-bottom: none;
}
.dual-select__table tr:hover td {
background: var(--card-bg-hover);
}
.dual-select__table th input[type="checkbox"],
.dual-select__table td input[type="checkbox"] {
width: 15px;
height: 15px;
accent-color: var(--accent);
vertical-align: middle;
}
.dual-select__sort {
cursor: pointer;
user-select: none;
white-space: nowrap;
}
.dual-select__sort-icon {
color: var(--text-muted);
font-size: 0.72rem;
}
.dual-select__sort.is-sort-asc .dual-select__sort-icon,
.dual-select__sort.is-sort-desc .dual-select__sort-icon {
color: var(--accent);
}
.dual-select__filters th {
background: var(--bg-surface);
padding: var(--space-2) var(--space-3);
}
.dual-select__filters input {
width: 100%;
padding: var(--space-1) var(--space-2);
border-radius: var(--radius-sm);
border: 1px solid var(--border-subtle);
background: var(--bg-canvas);
color: var(--text-primary);
font-size: 0.78rem;
font-weight: 400;
text-transform: none;
letter-spacing: normal;
outline: none;
}
.dual-select__filters input:focus {
border-color: var(--accent);
}
.dual-select__empty-row td {
text-align: center;
color: var(--text-muted);
padding: var(--space-5);
}
.dual-select__footer {
padding: var(--space-2) var(--space-1) 0;
font-size: 0.76rem;
color: var(--text-muted);
}
.btn-ghost:hover {
background: var(--accent);
color: var(--accent-contrast);
}
/* Menu de conta (usuário logado) */
.account-menu {
position: relative;
}
.persona-chip {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-3);
border-radius: var(--radius-pill);
background: var(--bg-surface-raised);
border: 1px solid var(--border-subtle);
font-size: 0.8rem;
font-weight: 600;
color: var(--text-primary);
}
.persona-chip:hover {
border-color: var(--accent);
}
.persona-chip__icon {
display: flex;
color: var(--gold);
}
.account-dropdown {
position: absolute;
top: calc(100% + var(--space-2));
right: 0;
width: 260px;
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
z-index: 30;
overflow: hidden;
animation: pidFadeSlideUp 140ms ease;
}
.account-dropdown__header {
padding: var(--space-3) var(--space-4);
border-bottom: 1px solid var(--border-subtle);
}
.account-dropdown__name {
font-size: 0.88rem;
font-weight: 700;
color: var(--text-primary);
}
.account-dropdown__profile {
font-size: 0.76rem;
color: var(--text-muted);
margin-top: 2px;
}
.account-dropdown__item {
display: block;
width: 100%;
text-align: left;
padding: var(--space-3) var(--space-4);
font-size: 0.85rem;
font-weight: 600;
color: var(--text-primary);
}
.account-dropdown__item:hover {
background: var(--bg-surface-raised);
color: var(--accent);
}
.account-dropdown__section {
padding: var(--space-3) var(--space-4);
border-top: 1px solid var(--border-subtle);
}
.account-dropdown__logout {
border-top: 1px solid var(--border-subtle);
color: var(--danger);
}
.account-dropdown__logout:hover {
color: var(--danger);
}
.account-dropdown__section-title {
font-size: 0.68rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--text-muted);
margin-bottom: var(--space-2);
}
.theme-swatches {
display: flex;
gap: var(--space-2);
}
.theme-swatch {
width: 26px;
height: 26px;
border-radius: 50%;
border: 2px solid transparent;
display: flex;
align-items: center;
justify-content: center;
transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.theme-swatch:hover {
transform: scale(1.1);
}
.theme-swatch.is-active {
border-color: var(--text-primary);
}
.theme-swatch svg {
color: #ffffff;
}
/* Botão "Temas sazonais" (menu da conta) — liga/desliga temas sazonais
(Halloween etc.) por preferência do usuário (motivos: gosto pessoal ou,
no caso do Halloween, aracnofobia). Estado "Ativo" (padrão) usa a cor de
destaque, igual a um toggle ligado; "Inativo" fica neutro/apagado, igual
a um toggle desligado — mesmo padrão visual de outros toggles booleanos
do Portal (ex.: `.theme-swatch.is-active`, mas aqui como texto+ponto em
vez de amostra de cor, já que não há uma cor própria pra representar). */
.seasonal-theme-toggle {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: 6px 12px;
border-radius: var(--radius-pill);
border: 1px solid var(--border-subtle);
background: var(--bg-surface-raised);
color: var(--text-secondary);
font-size: 0.8rem;
font-weight: 600;
cursor: pointer;
transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}
.seasonal-theme-toggle:hover {
border-color: var(--accent);
}
.seasonal-theme-toggle__dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: currentColor;
opacity: 0.5;
transition: opacity var(--transition-fast);
}
.seasonal-theme-toggle[aria-pressed="true"] {
background: var(--accent);
border-color: var(--accent);
color: #ffffff;
}
.seasonal-theme-toggle[aria-pressed="true"] .seasonal-theme-toggle__dot {
opacity: 1;
}
/* Notificações */
.notifications {
position: relative;
}
.notif-badge {
position: absolute;
top: 4px;
right: 4px;
min-width: 16px;
height: 16px;
padding: 0 3px;
border-radius: var(--radius-pill);
background: var(--danger);
color: #fff;
font-size: 0.62rem;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
}
.notif-dropdown {
position: absolute;
top: calc(100% + var(--space-2));
right: 0;
width: 340px;
background: var(--bg-canvas);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
z-index: 30;
overflow: hidden;
animation: pidFadeSlideUp 140ms ease;
}
.notif-dropdown__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-3) var(--space-4);
background: var(--bg-surface);
border-bottom: 1px solid var(--border-subtle);
font-size: 0.85rem;
font-weight: 700;
}
.notif-dropdown__header button {
font-size: 0.75rem;
font-weight: 600;
color: var(--accent);
}
.notif-dropdown__header-actions {
display: flex;
align-items: center;
gap: var(--space-3);
}
.notif-list {
max-height: 360px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: var(--space-2);
padding: var(--space-2);
}
.notif-item {
position: relative;
display: flex;
align-items: flex-start;
gap: var(--space-3);
padding: var(--space-3);
padding-right: var(--space-6);
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
}
.notif-item__icon {
flex-shrink: 0;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.notif-item--tool .notif-item__icon {
background: rgba(var(--gold-rgb), 0.16);
color: var(--gold);
}
.notif-item--event .notif-item__icon {
background: rgba(var(--accent-rgb), 0.14);
color: var(--accent);
}
.notif-item__body {
flex: 1;
min-width: 0;
}
.notif-item__title {
font-size: 0.8rem;
font-weight: 700;
color: var(--text-primary);
line-height: 1.35;
text-transform: uppercase;
}
.notif-item__breadcrumb {
font-size: 0.7rem;
color: var(--text-muted);
margin-top: var(--space-1);
}
.notif-item__dismiss {
position: absolute;
top: var(--space-2);
right: var(--space-2);
width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-sm);
color: var(--text-muted);
}
.notif-item__dismiss:hover {
background: var(--bg-surface-raised);
color: var(--danger);
}
.notif-item__restore {
position: absolute;
top: var(--space-2);
right: var(--space-2);
width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-sm);
color: var(--text-muted);
}
.notif-item__restore:hover {
background: var(--bg-surface-raised);
color: var(--accent);
}
.notif-empty {
text-align: center;
color: var(--text-muted);
font-size: 0.85rem;
padding: var(--space-6) var(--space-4);
}
/* Busca de aplicações */
.app-search {
position: relative;
max-width: 560px;
margin: 0 auto var(--space-6);
}
.app-search input {
width: 100%;
padding: var(--space-4) var(--space-5);
padding-right: var(--space-7);
border-radius: var(--radius-pill);
border: 1px solid var(--border-subtle);
background: var(--bg-surface);
color: var(--text-primary);
font-size: 0.95rem;
box-shadow: var(--shadow-sm);
outline: none;
transition: border-color var(--transition-fast);
}
.app-search input:focus {
border-color: var(--accent);
}
.app-search svg {
position: absolute;
right: var(--space-5);
top: 50%;
transform: translateY(-50%);
color: var(--text-muted);
}
/* Grade de cards de atalho */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: var(--space-4);
}
.app-card {
position: relative;
background: var(--card-bg);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
padding: var(--space-6) var(--space-4);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-2);
text-align: center;
cursor: pointer;
transition: background var(--transition-fast), transform var(--transition-fast), box-shadow var(--transition-fast);
}
.app-card:hover {
background: var(--card-bg-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.app-card--dragging {
opacity: 0.4;
}
.app-card--drop-before,
.app-card--drop-after {
box-shadow: inset 3px 0 0 0 var(--accent);
}
.app-card--drop-after {
box-shadow: inset -3px 0 0 0 var(--accent);
}
.app-card__icon {
width: 36px;
height: 36px;
color: var(--accent);
}
.app-card__label {
font-weight: 700;
font-size: 0.9rem;
letter-spacing: 0.02em;
color: var(--text-primary);
}
.app-card__remove {
position: absolute;
top: var(--space-2);
right: var(--space-2);
width: 28px;
height: 28px;
border-radius: var(--radius-sm);
color: var(--text-muted);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity var(--transition-fast), color var(--transition-fast), background var(--transition-fast);
}
.app-card:hover .app-card__remove {
opacity: 1;
}
.app-card__remove:hover {
color: var(--danger);
background: var(--bg-surface-raised);
}
.card-grid__empty {
grid-column: 1 / -1;
text-align: center;
color: var(--text-muted);
font-size: 0.9rem;
padding: var(--space-6);
}
/* Estado sem perfil de acesso vinculado */
.no-access {
max-width: 420px;
margin: var(--space-7) auto 0;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-3);
color: var(--text-secondary);
}
.no-access svg {
color: var(--text-muted);
}
.no-access h2 {
font-size: 1.05rem;
font-weight: 700;
color: var(--text-primary);
}
.no-access p {
font-size: 0.9rem;
line-height: 1.5;
}