/* ── Rustploy — glacier-ui stylesheet.─────────────────────────────────────
Terminal-flavoured dark theme, monospaced throughout, matching design/.
Aqui ficam apenas os seletores COMPARTILHADOS por mais de um template (mais
alguns utilitários ainda sem uso). Seletores usados por um único template
moram no style desse próprio template — o glacier-ui escopa cada style
à subárvore do componente que o declara, então colocá-los junto do markup
mantém o estilo perto de quem o usa. */
/* ── Convenção de nomes: BEM ───────────────────────────────────────────────
Toda classe segue Bloco / Elemento / Modificador, em minúsculas com hífen
dentro de cada palavra:
.bloco componente autônomo .card, .kv-list, .btn
.bloco__elemento parte que só existe nele .card__head, .nav-item__icon
.bloco--modificador variação ou estado .btn--danger, .nav-item--active
• O modificador NUNCA vem sozinho: o markup leva as duas classes
(`class = "btn btn--danger"`) e a regra do modificador só troca o que muda.
• Elemento não aninha elemento (`.a__b__c` não existe): o bloco é dono de
todas as suas partes, por mais fundo que estejam na árvore.
• `u-*` são utilitários de uma propriedade só, sem bloco (`u-fill`, `u-muted`).
• Um modificador declarado DEPOIS do base ganha dele (mesma especificidade).
Seletores compostos e combinadores (glacier-ui 0.122+): como no CSS,
.a > .b filho DIRETO de .a .a .b .b em QUALQUER profundidade
row.a tag + classe .a.b as duas classes no mesmo nó
.a > text:hover :estado só vale no ÚLTIMO seletor
A regra composta fica logo acima do tier simples (`.a > .b` vence `.b`) e
abaixo do `#id` simples e do inline. Fora da gramática — e ERRO de parse, não
regra ignorada: `+`, `~`, `[attr]`, `::pseudo`, `:not(…)` e `:estado` num
ancestral.
Onde isto simplifica o app: um MODIFICADOR NA RAIZ do bloco recolore os
filhos, em vez de cada filho carregar o seu par de classes de estado.
nav_item.component.gv .nav-item--active > .nav-item__icon (era *_on / *_off ×3)
state_cell.component.gv .state-cell--ok > text (a cor de ponto + rótulo)
Onde NÃO ajuda, e fica seletor simples de propósito: bloco cujo único estado é
uma propriedade do próprio nó (`.btn--primary`, `.service__actions--full`) — um
combinador só trocaria `.x` por `.y > .x` sem tirar nenhuma classe do markup. */
/* ── Design tokens (glacier-ui 0.8.0+) ─────────────────────────────────────
Fonte única da paleta. Referenciados via var(--x) aqui e nos style dos
templates (var() é cross-sheet: esta :root global resolve em qualquer sheet
com escopo). Trocar um tom aqui reflete no app inteiro. */
:root {
--bg: #0A0E14; /* fundo do app */
--surface: #0D1117; /* painéis / sidebar / inputs */
--raised: #161B22; /* cards / cabeçalho de tabela / linha arrastada */
--border: #21262D; /* bordas + botões ghost/sutis */
--border-hover: #2D333B; /* o mesmo, com o ponteiro em cima */
--text: #E6EDF3; /* texto/títulos mais claros */
--text-2: #C9D1D9; /* valores/corpo */
--muted: #8B949E; /* secundário */
--faint: #6E7681; /* rótulos apagados */
--accent: #58A6FF; /* azul de destaque */
--blue: #1F6FEB; /* botões/abas azuis */
--blue-hover: #4A8CF5; /* o mesmo azul, com o ponteiro em cima */
--spin: #2F81F7; /* ação (connect) / spinner */
--green: #238636; /* botão primário */
--ok: #3FB950; /* estado ok / sucesso */
--danger: #DA3633; /* botão de perigo */
/* Paradas do gradiente leve dos botões preenchidos (topo → base, ~8%). */
--green-a: #2A9142; --green-b: #1E7A30;
--blue-a: #2A7BF0; --blue-b: #1A60CC;
--danger-a: #E5413E; --danger-b: #C42E2B;
--error: #F85149; /* texto de erro */
--warn: #D29922; /* estado de alerta */
}
/* ── Utilitários (u-*) ────────────────────────────────────────────────── */
.u-mono { }
.u-fill { width: fill; }
.u-fill-all { width: fill; height: fill; }
.u-center-fill { width: fill; height: fill; align_x: center; align_y: center; }
.u-align-y-end { alignY: end; }
.u-muted { size: 12; color: var(--muted); }
.u-label-cap { size: 11; bold: true; color: var(--faint); }
.u-error { color: var(--error); }
.u-ok { color: var(--ok); }
.u-warn { color: var(--warn); }
/* ── Base ─────────────────────────────────────────────────────────────── */
/* Sem `background`: o tema já pinta `--bg` (#0A0E14 em theme.json) na janela
inteira, e repintar a mesma cor aqui era uma camada redobrada em cada pixel.
Medido no motor: caixas pintadas custam ~45 ms por quadro numa GPU integrada
antiga, e as de janela inteira são as mais caras (ver PRIMITIVAS.md, "O que
custa num quadro"). Se um dia o fundo da tela precisar diferir do tema, mude
o tema — não pinte por cima. */
.screen { width: fill; height: fill; }
/* ── Janela sem moldura: alças de resize + barra de título ────────────────
Antes repetidas em app.gv e em cada janela auxiliar; um motor por janela
carrega este sheet global, então basta declarar aqui. */
.resize__top { width: fill; height: 6; }
.resize__bottom { width: fill; height: 6; }
.resize__mid { width: fill; height: fill; }
.resize__body { width: fill; height: fill; }
.resize__corner { width: 6; height: fill; }
.resize__edge-h { width: fill; height: fill; cursor: resize-v; }
.resize__edge-v { width: 6; height: fill; cursor: resize-h; }
/* Cursores diagonais dos cantos (modificador sobre .resize__corner) */
.resize__corner--nw { cursor: resize-nw; }
.resize__corner--ne { cursor: resize-ne; }
.resize__corner--sw { cursor: resize-sw; }
.resize__corner--se { cursor: resize-se; }
.titlebar { width: fill; height: 32; background: var(--surface); align_y: center; }
.titlebar__drag { width: fill; height: fill; align_y: center; padding: 0 0 0 16; spacing: 9; }
.titlebar__dot { size: 10; color: var(--blue); }
.titlebar__title { size: 12; bold: true; color: var(--muted); }
.titlebar__btn { width: 48; padding: 5 0; color: var(--border); text_align: center; }
.titlebar__btn--close { color: var(--danger); }
.titlebar__icon-box { width: fill; height: 20.8; align_x: center; align_y: center; } /* = altura de linha do "—" (16 × 1.3) */
.titlebar__icon { width: 12; height: 12; color: var(--text); }
/* ── Sidebar / top bar ────────────────────────────────────────────────── */
/* O item de navegação (`.nav-item`) mora no style de nav_item.component.gv. O antigo
`.nav_item` (botão-texto puro, sem ícone) ficou sem uso quando o componente
passou a montar ícone+rótulo; mantido comentado, não removido (é
reutilizável). */
/* .nav-item--text { width: fill; color: var(--surface); padding: 11 14; } */
/* ── Tabs ─────────────────────────────────────────────────────────────── */
.tabs { width: fill; spacing: 4; }
.tabs__tab { color: var(--surface); padding: 9 16; border_radius: 5 }
.tabs__tab--active { color: var(--blue); }
/* ── Buttons ──────────────────────────────────────────────────────────── */
/* `.btn` é o bloco; a cor vem de um modificador (--primary/--danger/--ghost/
--blue) e o tamanho de outro (--sm/--xs/--wide). Os de tamanho vêm DEPOIS
dos de cor porque o `--ghost` fixa o padding. */
.btn { color: var(--border); padding: 11 20; border_radius: 5 }
/* `gradient` pinta o fundo do botão (glacier-ui 0.141+); `color` fica de base. */
.btn--primary { color: var(--green); gradient: var(--green-a) var(--green-b); }
.btn--danger { color: var(--danger); gradient: var(--danger-a) var(--danger-b); }
.btn--ghost { color: var(--border); padding: 11 18; }
.btn--blue { color: var(--blue); gradient: var(--blue-a) var(--blue-b); }
.btn--wide { padding: 11 22; }
.btn--sm { padding: 7 13; border_radius: 4; size: 12 }
.btn--xs { padding: 5 12; border_radius: 4 }
/* `.btn-secondary` nunca teve regra (botão sem estilo); fica como marcador. */
/* Ação em andamento (busy.luau liga `disabled = @busy_<ação>`): o botão apaga na hora. */
/* Hover/pressionado com `transition` (glacier-ui 0.145, medido numa janela real): a cor sobe em
rampa em vez de saltar. A transição vale só para botões de cor SÓLIDA (ghost, secundário,
barra de título, abas); um gradiente de paradas diferentes troca de uma vez — por isso os
botões preenchidos clareiam para a parada de cima (`--*-a`) sem rampa. */
.btn { transition: all 150ms ease-out; }
.btn--primary:hover { background: var(--green-a); }
.btn--danger:hover { background: var(--danger-a); }
.btn--blue:hover { background: var(--blue-a); }
.btn--ghost:hover { background: var(--border-hover); }
.titlebar__btn { transition: all 150ms ease-out; }
.titlebar__btn:hover { background: var(--border-hover); }
.titlebar__btn--close:hover { background: var(--danger); text_color: var(--text); }
.tabs__tab { transition: all 150ms ease-out; }
.tabs__tab:hover { background: var(--raised); }
/* A aba ativa é azul: o hover dela clareia o azul (e não cai no cinza da aba inativa). */
.tabs__tab--active:hover { background: var(--blue-hover); }
.btn:disabled { text_color: var(--faint); }
.btn--primary:disabled { color: var(--border); }
.btn--danger:disabled { color: var(--border); }
.btn--blue:disabled { color: var(--border); }
.btn--ghost:disabled { color: var(--surface); }
/* ── Panels & cards ───────────────────────────────────────────────────── */
/* Idem: `--bg` é a cor do tema, e o `.content` fica dentro do `.screen`, que
já está sobre ela. Era a terceira camada da mesma cor nos mesmos pixels. */
.content { width: fill; height: fill; padding: 28 32; spacing: 22; }
/* `.panel` sem raio: o painel que ocupa a área de conteúdo inteira
(`--fill`) não arredonda — custa matemática por pixel nela toda para um
detalhe de 7px que quase não se nota. Os cantos ficam nas caixas pequenas
(cards, botões, abas), onde se veem e são baratos: `--round`. */
.panel { background: var(--surface); border_width: 1; border_color: var(--border); padding: 4; }
.panel--round { border_radius: 7; }
.panel--fill { width: fill; height: fill; }
.card { width: fill; background: var(--raised); border_radius: 6; border_width: 1; border_color: var(--border); padding: 18; spacing: 10; }
.panel-pad { width: fill; background: var(--surface); border_radius: 6; border_width: 1; border_color: var(--border); padding: 18; spacing: 8; }
/* ── Typography / cabeçalho de página ─────────────────────────────────── */
.page-head { width: fill; align_y: start; }
.page-head__titles { width: fill; spacing: 6; }
.page-head__title { size: 30; bold: true; color: var(--text); }
.page-head__subtitle { size: 13; color: var(--muted); }
.page-head__stats { spacing: 14; }
/* ── Table ────────────────────────────────────────────────────────────── */
/* `tableview(header_class = "table__head table__head-cell", row_class =
"table__row table__cell table__row--divided")`: a faixa do cabeçalho é o
`.table__head` (fundo, raio, padding) com o texto do `.table__head-cell`; a
linha é o `.table__row` (padding) com o texto do `.table__cell` nas células
sem corpo, e o border-color do `--divided` é o fio entre uma linha e a
próxima (o antigo `hr`). */
.table__head { width: fill; padding: 14 18; background: var(--raised); border_radius: 5; spacing: 0; }
.table__head-cell { size: 11; bold: true; color: var(--faint); }
.table__row { width: fill; padding: 13 18; spacing: 0; align_y: center; }
.table__row--divided { border_color: var(--border); }
.table__cell { size: 13; color: var(--text-2); }
.table__cell--key { bold: true; color: var(--accent); }
.table__col-svc { width: 240; }
.table__col-proj { width: 180; }
.table__col-state { width: 170; }
.table__col-dur { width: 150; }
.table__col-start { width: fill; }
.table__col-act { width: 120; }
/* Coluna IMAGEM da sub-aba Containers (Docker): mais larga que a de projeto
porque uma referência de imagem (registry/repo:tag ou sha256:<digest>) é
tipicamente mais longa que "projeto/serviço" — e, sem espaços, não quebra
linha (ver format.docker_containers, que trunca com Util.ellipsis para nunca
estourar). */
.table__col-img { width: 340; }
.stepper { width: fill; padding: 0 18 12 18; spacing: 14; align_y: center; }
.stepper__step { size: 12; }
.stepper__step--done { color: var(--ok); }
.stepper__step--current { color: var(--accent); bold: true; }
.stepper__step--failed { color: var(--error); bold: true; }
.stepper__step--pending { color: var(--muted); }
.detail { width: 760; height: 480; padding: 14 18; spacing: 12; }
.detail__head { width: fill; align_y: center; }
.detail__title { width: fill; size: 14; bold: true; color: var(--text); }
/* ── Seção de conteúdo (Deploy Engine) ────────────────────────────────────
O `.panel--fill` acima é um painel que ocupa a tela inteira: certo quando a
tela TEM uma lista só. O Deploy Engine tem três listas de naturezas
diferentes — a fila (curta), o que está rodando (no máximo um) e o
histórico (longo) — e empilhar três `.panel--fill` dava a cada um um terço
da altura: três caixas enormes e vazias quando não há deploy nenhum. Aqui
a altura vem do conteúdo (`shrink`) e só o histórico recebe `--fill`. */
.section { width: fill; height: shrink; background: var(--surface); border_radius: 7; border_width: 1; border_color: var(--border); }
.section--fill { height: fill; }
/* Cabeçalho da seção: título à esquerda, ação à direita. O `width: fill` no
TÍTULO é o que empurra o botão — o iced não tem `justify-content`, e sem
isso o botão encosta no rótulo (era o caso do "⏸ Pausar fila", que saía
colado no "NA FILA (0)" em vez de ir para a borda direita). */
.section__head { width: fill; align_y: center; padding: 13 16; }
.section__title { width: fill; size: 11; bold: true; color: var(--faint); }
/* Corpo: padding nas laterais e embaixo — o cabeçalho de tabela encosta no
topo do corpo, como nas outras telas. */
.section__body { width: fill; padding: 0 6 6 6; }
.section__scroll { width: fill; height: fill; padding: 0 6 6 6; }
/* Vazio: centralizado e com respiro, em vez de uma frase solta no canto
superior esquerdo de um painel de 300px de altura. */
.empty-state { width: fill; text_align: center; padding: 26 0; size: 12; color: var(--faint); }
/* Só para a seção que recebe `--fill` (o histórico): sem isto o aviso de vazio
fica encostado no topo de um card de várias centenas de pixels. É uma ROW
de propósito — `align-y` centraliza no eixo cruzado, e numa column esse
eixo é o horizontal, então lá a regra não teria efeito nenhum. */
.empty-state__wrap { width: fill; height: fill; align_y: center; }
/* Aviso de fila pausada: faixa com a cor de alerta, não um texto cinza que
se confunde com o estado vazio logo abaixo. */
.banner { width: fill; padding: 9 16; size: 12; background: var(--raised); border_radius: 5; }
.banner--warn { color: var(--warn); }
.form-panel {
width: fill;
height: shrink;
max_width: 720;
background: var(--surface);
border_radius: 7; border_width: 1;
border_color: var(--border);
padding: 24;
spacing: 10;
}
/* O mesmo painel com os campos mais juntos (o formulário de renomear). */
.form-panel--tight { spacing: 6; }
/* Uma linha da lista + a linha extra de baixo (ex.: o valor revelado de um secret). */
.kv-list__block { width: fill; height: shrink; }
/* Pilha de painéis dentro de um scrollable (que só aceita um filho). */
.form-stack { width: fill; height: shrink; spacing: 14; }
/* Formulário sem painel: ocupa a largura do pai; o espaço entre os campos vem
do modificador. Antes era `width`/`spacing` inline em cada `form(...)`. */
.form { width: fill; }
.form--gap-6 { spacing: 6; }
.form--gap-8 { spacing: 8; }
.form--gap-10 { spacing: 10; }
.form--gap-14 { spacing: 14; }
.form--gap-16 { spacing: 16; }
/* Ponto colorido do state-cell/rp-badge — compartilhado; o rótulo e a paleta
(`state-cell--<kind>`) moram no style do state_cell.component.gv. */
.status-dot { size: 11; }
/* ── Projects / service grid ──────────────────────────────────────────── */
.grid { width: fill; spacing: 16; }
.running__head { width: fill; align_y: center; spacing: 12; }
.running__projects { width: fill; spacing: 40; }
.grid__row { width: fill; spacing: 16; }
.card__head { width: fill; align_y: center; }
.card__badges { spacing: 8; align_y: center; }
.card__name { width: fill; size: 16; bold: true; color: var(--text); }
.badge { spacing: 7; align_y: center; }
.badge__label { size: 12; bold: true; }
/* Ações do card (projeto e serviço): um botão cheio, no tamanho da coluna. */
.card__action { width: fill; color: var(--border); padding: 9 10; text_align: center; border_radius: 5 }
.card__action--auto { width: shrink; padding: 9 14; }
.card__action--open { padding: 9 14; }
.card__action--icon { padding: 9 0; }
.card__action--danger { color: var(--danger); }
/* ── Service detail (compartilhado) ───────────────────────────────────── */
.kv-list { width: fill; background: var(--surface); border_radius: 6; border_width: 1; border_color: var(--border); padding: 8 18; spacing: 0; }
.kv-list__row { width: fill; padding: 12 0; align_y: center; spacing: 6; }
/* Linha agarrada durante o drag-and-drop (flag {var}.__dragging do
glacier-ui): fundo elevado + borda de destaque enquanto o resto reflui. */
.kv-list__row--dragging { padding: 12 10; background: var(--raised); border_radius: 4; border_width: 1; border_color: var(--accent); }
.kv-list__key { width: fill; size: 13; color: var(--muted); }
.kv-list__val { size: 16; bold: true; color: var(--text); }
.kv-list__val--compact { size: 13; color: var(--text-2); }
.form-select { width: fill; padding: 12 14; background: var(--raised); border_radius: 4; border_width: 1; border_color: #30363D; color: var(--text-2); }
.env { width: fill; height: fill; spacing: 10; }
/* Aba inteira dentro de um scrollable (altura pelo conteúdo, não fill). */
/* padding à direita: a barra de rolagem do scrollable fica por cima do conteúdo e cortava o último botão da linha. */
.env--flow { width: fill; spacing: 10; padding: 0 16 0 0; }
.tabs__scroll { width: fill; }
.tabs__main { width: shrink; spacing: 4; }
.env__head { width: fill; align_y: center; }
/* Barra de ferramentas de uma aba (texto + checkboxes + botão): sem espaço entre os itens, o rótulo de
um checkbox encosta no box do seguinte. */
.env__toolbar { width: fill; align_y: center; spacing: 16; }
.env__add { width: fill; spacing: 8; align_y: center; }
.env__input { width: fill; padding: 9 12; }
/* Edição no lugar de chave/valor: o campo some a borda e herda a cara do texto que substitui; só o
foco desenha um filete. O wrapper (form) tem a largura da célula que ele ocupa. */
.env__edit { width: fill; }
.env__edit--key { width: 230; }
.env__inline { width: fill; padding: 3 6; background: transparent; border_width: 0; font_size: 13; }
.env__inline:focus { background: var(--raised); border_width: 1; border_color: var(--accent); }
.env__drag-handle { color: var(--faint); padding: 0 6 0 0; cursor: grab; }
.env__drag-handle--dragging { cursor: grabbing; }
.env__del { color: var(--danger); padding: 4 10; background: var(--border); border_radius: 4; }
.env__del:disabled { color: var(--surface); text_color: var(--faint); }
/* Respiro entre o botão ✕ e a chave da variável (evita que o vermelho encoste
no texto). Usado nas linhas de env de serviço e de projeto. */
.env__sep { width: 10; }
.reorder__index { size: 13; bold: true; color: var(--accent); width: 32; }
.env__key { size: 13; bold: true; color: var(--accent); width: 400; }
/* Editor .env (textarea + toggle), compartilhado por service.component.gv e shell.component.gv. */
.env__editor { width: fill; height: 200; padding: 10 12; font: mono; }
/* Webhook (aba Deployments): a URL ocupa a linha inteira — é longa demais para
dividir espaço com os botões, que ficam na linha de baixo. */
.webhook { width: fill; spacing: 10; }
.webhook__url { width: fill; size: 13; bold: true; color: var(--text-2); font: mono; }
.webhook__actions { spacing: 8; align_y: center; }
.healthcheck__grid { width: fill; spacing: 14; }
.healthcheck__field { width: fill; spacing: 6; }
/* ── Forms ────────────────────────────────────────────────────────────── */
.field { width: fill; spacing: 6; }
.field__row { width: fill; }
.field__label { size: 11; bold: true; color: var(--muted); }
.field__input { width: fill; padding: 13 14; }
/* Campo de um spinbox (`field_class="field__spin"`). O `.field__input` (padding
13 14 → ~44px de altura) desencontrava o campo dos degraus ▴▾, que somam
~30px (2 × ~1,3 × glyph_size 11 — ver o builtin SpinBox do glacier-ui). Um
padding menor casa a altura dos dois. Sem `width`: cada spinbox passa a
largura do campo pela prop `width=`. */
.field__spin { padding: 6 12; }
/* Janelas auxiliares (novo projeto/job/serviço/token, exportar): a casca de
tela e o corpo rolável são os mesmos; o resto mora no style de cada janela. */
.dialog__screen { width: fill; height: fill; }
.dialog__body { width: fill; height: fill; }
.dialog__input { width: fill; }
.dialog__actions { width: fill; spacing: 10; align_y: center; }
/* Linha "ocupado": spinner + texto de status enquanto um RPC está no ar. O
spinner só aparece com a flag `*_busy` ligada; o texto acompanha o `*_msg`. */
.busy-row { spacing: 9; align_y: center; }
.busy-row__spin { width: 15; height: 15; color: var(--spin); }
/* Destaque de campo reprovado na validação declarada do form(...) (glacier-ui
0.102+): NÃO é uma classe que o script liga — é o pseudo-estado `:invalid`,
que o motor acende sozinho enquanto o `{erro_<campo>}` do campo estiver
preenchido. Uma regra por classe (o GSS não agrupa por vírgula). */
.field__input:invalid { border_width: 1; border_color: var(--error); }
.field__spin:invalid { border_width: 1; border_color: var(--error); }
.dialog__input:invalid { border_width: 1; border_color: var(--error); }
.env__input:invalid { border_width: 1; border_color: var(--error); }
/* ── Responsivo (glacier-ui 0.9.0+) ────────────────────────────────────────
O motor só ajusta PROPRIEDADES (não reestrutura Row↔Column nem esconde), então
"mobile" aqui = modo compacto: menos padding, colunas/fontes menores conforme a
largura da janela encolhe. A sidebar/topbar têm os deles no style do shell. */
/* StatCards ao lado do título (page-head): o Row não quebra linha nem clipa,
então com muitos cards eles invadem o título bem antes dos 560 que escondem
.page-head__stats abaixo. Cada view marca a sua página com o modificador do
ponto em que ela deixa de caber, medido pela densidade: xl = 5 cards com valor
largo (Deploy Engine, ~1240px de janela com sidebar cheia), lg = 2 cards largos
(Deployments: STATUS + UPTIME "1d 11h 49m", ~950px), md = 4 cards compactos
(Docker/Monitoring/Schedules, ~700px com sidebar colapsada). Ingress (2
cards curtos) cabe até os 560 gerais e fica só com .page-head__stats. */
@media (max-width: 1280) {
.page-head__stats--hide-xl { hidden: true; }
}
/* Ações da tela de serviço (Deploy/Reload/Rebuild/Stop). Dois arranjos que se
alternam por largura (modificadores de `.service__actions`):
• >1240px → `--full`: rótulos por extenso, À DIREITA do título
(mesma linha — há espaço de sobra).
• ≤1240px → `--compact`: ícones + tooltip, EMPILHADOS abaixo do
título/status (dentro da coluna page-head__titles, ver service.component.gv).
O empilhamento (em vez de encolher na mesma linha) é o que garante que os
botões nunca dividam linha com o nome quando aperta — antes eles transbordavam
por cima de "Landing page"/"Running". Base: full visível, compacta oculta; o
@media inverte as duas. O limiar é medido na largura da JANELA, mas o header
vive dentro do shell com a sidebar comendo espaço horizontal — 1240px dá a
folga para os rótulos por extenso só aparecerem quando realmente cabem. */
.service__actions--full { hidden: false; }
.service__actions--compact { hidden: true; }
@media (max-width: 1240) {
.service__actions--full { hidden: true; }
.service__actions--compact { hidden: false; }
}
.page-head__clear--full { hidden: false; }
.page-head__clear--compact { hidden: true; }
@media (max-width: 860) {
.page-head__clear--full { hidden: true; }
.page-head__clear--compact { hidden: false; }
}
@media (max-width: 1000) {
.page-head__stats--hide-lg { hidden: true; }
}
@media (max-width: 760) {
.page-head__stats--hide-md { hidden: true; }
/* Título + botão de ação dividem a linha e o motor não empilha Row: sem o
subtítulo (que quebrava palavra por palavra) e com o título menor, cabem. */
.page-head__subtitle { hidden: true; }
.page-head__title { size: 20; }
}
@media (max-width: 900) {
.content { padding: 16 18; spacing: 16; }
.page-head__title { size: 24; }
.page-head__stats { spacing: 10; }
.table__head { padding: 10 12; }
.table__row { padding: 10 12; }
.table__col-svc { width: 150; }
.table__col-proj { width: 120; }
.table__col-state { width: 130; }
.table__col-dur { width: 90; }
.table__col-img { width: 220; }
.form-panel { padding: 16; }
.grid { spacing: 10; }
.grid__row { spacing: 10; }
.kv-list { padding: 6 12; }
}
@media (max-width: 560) {
.content { padding: 10 10; spacing: 12; }
.page-head__title { size: 20; }
.table__col-svc { width: 110; }
.table__col-proj { width: 82; }
.table__col-state { width: 110; }
.table__col-dur { width: 64; }
.table__col-img { width: 140; }
.form-panel { padding: 12; }
/* Em telas estreitas não há largura pra os cards de stat ao lado do título
(empilhavam sobre o texto) nem pra a coluna INÍCIO — some com ambos
(glacier-ui 0.10.0: `hidden`). */
.page-head__stats { hidden: true; }
.table__col-start { hidden: true; }
}