@aurea-uds/native 0.33.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/actions.js CHANGED
@@ -22,7 +22,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
22
  // do Lote 3. Aparência sem consumidor é a ADR-0034 ("ter a variante não é usar").
23
23
  import * as React from "react";
24
24
  import { AccessibilityInfo, Platform, Pressable, Share, View } from "react-native";
25
- import { canto, criarFolha, REACAO_AO_TOQUE, estadoAcessivel } from "./estilos.js";
25
+ import { canto, comOpacidade, criarFolha, misturaOpaca, preenchimento, REACAO_AO_TOQUE, estadoAcessivel } from "./estilos.js";
26
26
  import { Icon } from "./icon.js";
27
27
  import { Text } from "./text.js";
28
28
  import { AvisosContext, useAureaStrings, useAureaTheme, useAureaTokens, useSobreAMarca } from "./theme.js";
@@ -102,6 +102,16 @@ function pintar(t, tone) {
102
102
  * o da marca também seguem na tinta (neutro 1,61; marca é amarelo no amarelo, 1,00).
103
103
  */
104
104
  const TONS_COM_COR = new Set(["success", "danger", "warning", "info"]);
105
+ /**
106
+ * SEM LINHA (16/10/2026), a "C" da bancada, escolhida pelo Victor: no tema CLARO, a letra do botão de CONTORNO com tom de
107
+ * estado vai 20% para a cor do texto. O fundo é o tom a 16%, e o azul do claro, que já fica perto do limite contra a
108
+ * página branca, caía a 4,02:1 sobre ele (o mínimo é 4,5). Fora disso, a letra de sempre. O par da web está no fim do
109
+ * `aurea.css` (`[data-theme="light"] .btn-outline.btn-tone-*`).
110
+ */
111
+ function corDaLetra(t, tone, appearance, marca, sobre) {
112
+ const deEstado = tone === "info" || tone === "success" || tone === "warning" || tone === "danger";
113
+ return appearance === "outline" && !marca && deEstado && t.theme === "light" ? misturaOpaca(sobre, t.color.foreground, 0.8) : sobre;
114
+ }
105
115
  function pintarSobreAMarca(base, marca, tone, appearance) {
106
116
  if (marca == null)
107
117
  return base;
@@ -221,14 +231,20 @@ function CorpoDoBotao({ children, appearance = "solid", tone = "neutral", size =
221
231
  height: medida.altura,
222
232
  paddingHorizontal: medida.recheio,
223
233
  gap: medida.vao,
224
- backgroundColor: appearance === "solid" ? cor.solido : "transparent",
225
- borderColor: cor.contorno ?? (appearance === "outline" ? corDaBorda : "transparent"),
234
+ // Sem linha (16/10/2026): o de CONTORNO, sem a linha, ganha o fundo — o tom a 16%, o neutro a 10%. A letra do tom de
235
+ // estado, no claro, vai 20% para a cor do texto (`corDaLetra`): a "C" da bancada.
236
+ backgroundColor: appearance === "solid" ? cor.solido
237
+ // Dentro do cartão da marca, a mesma tinta escura do campo (a 14%): o branco a 10% clareava o amarelo e sumia.
238
+ : appearance === "outline" ? (marca ? comOpacidade(marca.tinta, 0.14)
239
+ : tone && tone !== "neutral" ? comOpacidade(cor.solido, 0.16) : preenchimento(t, 2))
240
+ : "transparent",
241
+ borderColor: "transparent",
226
242
  ...(fullWidth ? { flex: 1 } : null),
227
243
  // A regra do botão-link da referência: `height: auto; padding: 0`, e a do botão dela já
228
244
  // tem `border-width: 0`. A borda transparente de 1 empurraria o texto 1 para dentro.
229
245
  ...(semRecuo ? { height: undefined, paddingHorizontal: 0, borderWidth: 0 } : null),
230
- }), [medida.altura, medida.recheio, medida.vao, appearance, cor.solido, cor.contorno, corDaBorda, fullWidth, semRecuo]);
231
- const corDoTexto = appearance === "solid" ? cor.texto : cor.sobre;
246
+ }), [medida.altura, medida.recheio, medida.vao, appearance, cor.solido, cor.contorno, corDaBorda, fullWidth, semRecuo, marca, tone, t]);
247
+ const corDoTexto = appearance === "solid" ? cor.texto : corDaLetra(t, tone, appearance, marca, cor.sobre);
232
248
  return (_jsx(Pressable, { disabled: disabled, onPress: aoTocar, accessibilityRole: "button", accessibilityLabel: accessibilityLabel, ...estadoAcessivel({ disabled: !!disabled, pressed }), style: ({ pressed: tocando }) => [
233
249
  s.alvo, fullWidth && s.alvoLargura,
234
250
  tocando && s.pressionado, disabled && s.inerte,
@@ -286,15 +302,19 @@ function BotaoDeIcone({ name, label, appearance = "ghost", tone = "neutral", siz
286
302
  const caixa = React.useMemo(() => ({
287
303
  height: lado, width: lado, paddingHorizontal: 0,
288
304
  ...canto(t.size.radiusControl),
289
- backgroundColor: appearance === "solid" ? cor.solido : "transparent",
290
- borderColor: cor.contorno ?? (appearance === "outline" ? corDaBorda : "transparent"),
291
- }), [t, lado, appearance, cor.solido, cor.contorno, corDaBorda]);
305
+ // Sem linha (16/10/2026): o de contorno ganha o fundo, como o `Button` — a tinta do cartão da marca, o tom, ou o neutro.
306
+ backgroundColor: appearance === "solid" ? cor.solido
307
+ : appearance === "outline" ? (marca ? comOpacidade(marca.tinta, 0.14)
308
+ : tone && tone !== "neutral" ? comOpacidade(cor.solido, 0.16) : preenchimento(t, 2))
309
+ : "transparent",
310
+ borderColor: "transparent",
311
+ }), [t, lado, appearance, cor.solido, cor.contorno, corDaBorda, marca, tone]);
292
312
  return (_jsx(Pressable, { disabled: disabled, onPress: aoTocar, accessibilityRole: "button", accessibilityLabel: label, ...estadoAcessivel({ disabled: !!disabled, pressed }), style: ({ pressed: tocando }) => [
293
313
  // Largura FIXA, como o só-ícone da referência: ele nunca estica,
294
314
  // nem numa coluna sem alinhamento. O alvo é o maior entre o desenho e o `targetMin`.
295
315
  s.alvo, { width: Math.max(lado, t.size.targetMin), alignItems: "center" },
296
316
  tocando && s.pressionado, disabled && s.inerte,
297
- ], ...rest, children: _jsx(View, { style: [s.caixa, caixa], children: _jsx(Icon, { name: name, size: ICONE[size], icons: icons, weight: pesoDoIcone, color: corDoIcone && !marca ? corDoIcone : appearance === "solid" ? cor.texto : cor.sobre }) }) }));
317
+ ], ...rest, children: _jsx(View, { style: [s.caixa, caixa], children: _jsx(Icon, { name: name, size: ICONE[size], icons: icons, weight: pesoDoIcone, color: corDoIcone && !marca ? corDoIcone : appearance === "solid" ? cor.texto : corDaLetra(t, tone, appearance, marca, cor.sobre) }) }) }));
298
318
  }
299
319
  export function ThemeToggle(props) {
300
320
  const { theme, toggleTheme } = useAureaTheme();
package/dist/arquivo.js CHANGED
@@ -33,7 +33,7 @@ import * as React from "react";
33
33
  import { Pressable, View } from "react-native";
34
34
  import * as DocumentPicker from "expo-document-picker";
35
35
  import { IconButton } from "./actions.js";
36
- import { canto, criarFolha, estadoAcessivel } from "./estilos.js";
36
+ import { canto, criarFolha, estadoAcessivel, preenchimento } from "./estilos.js";
37
37
  import { Icon } from "./icon.js";
38
38
  import { alturaDoTamanho, respiroDoTamanho, useCampo } from "./inputs.js";
39
39
  import { Text } from "./text.js";
@@ -43,10 +43,10 @@ const folha = criarFolha((t) => ({
43
43
  // O gatilho e a linha do arquivo têm a pele do campo: mesma borda, mesmo fundo, cápsula.
44
44
  caixa: {
45
45
  flexDirection: "row", alignItems: "center", gap: t.size.space2,
46
- width: "100%", minWidth: 0, borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
47
- ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
46
+ width: "100%", minWidth: 0, borderWidth: t.size.borderWidth, borderColor: "transparent",
47
+ ...canto(t.size.radiusControl), backgroundColor: preenchimento(t, 2),
48
48
  },
49
- invalido: { borderColor: t.color.danger400 ?? t.color.destructive },
49
+ invalido: { borderColor: "transparent", backgroundColor: t.color.dangerBg },
50
50
  desabilitado: { opacity: t.size.opacityDisabled },
51
51
  nomeETamanho: { flex: 1, minWidth: 0, flexDirection: "row", alignItems: "center", gap: t.size.space2 },
52
52
  nome: { flexShrink: 1 },
package/dist/busca.js CHANGED
@@ -69,7 +69,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
69
69
  import * as React from "react";
70
70
  import { Animated, Easing, FlatList, Modal, PanResponder, Pressable, TextInput, View, } from "react-native";
71
71
  import { IconButton } from "./actions.js";
72
- import { canto, cantosDeCima, criarFolha, estadoAcessivel } from "./estilos.js";
72
+ import { canto, cantosDeCima, criarFolha, estadoAcessivel, preenchimento } from "./estilos.js";
73
73
  import { Spinner } from "./feedback.js";
74
74
  import { Icon } from "./icon.js";
75
75
  import { KeyboardAvoiding, alturaDoTamanho, indicadorDaEscolhida, respiroDoGatilho, respiroDoTamanho, useCampo, } from "./inputs.js";
@@ -100,11 +100,11 @@ const folha = criarFolha((t) => ({
100
100
  // borda, o mesmo raio de controle.
101
101
  caixa: {
102
102
  width: "100%", minWidth: 0,
103
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
104
- ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
103
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
104
+ ...canto(t.size.radiusControl), backgroundColor: preenchimento(t, 2),
105
105
  flexDirection: "row", alignItems: "center",
106
106
  },
107
- invalido: { borderColor: t.color.danger400 ?? t.color.destructive },
107
+ invalido: { borderColor: "transparent", backgroundColor: t.color.dangerBg },
108
108
  desabilitado: { opacity: t.size.opacityDisabled },
109
109
  // As ações do gatilho — limpar e a seta. O `.combobox-actions` da web (`aurea.css:1673`) é
110
110
  // absoluto sobre o campo; aqui é um irmão na linha, porque não há campo por baixo.
@@ -150,7 +150,7 @@ const folha = criarFolha((t) => ({
150
150
  maxHeight: "90%",
151
151
  // HER-03 (ADR-0058): a folha que sobe de baixo tem 32, como a `BottomSheet`.
152
152
  ...cantosDeCima(t.size.radiusSheet),
153
- backgroundColor: t.color.popover, borderWidth: t.size.borderWidth, borderColor: t.color.border,
153
+ backgroundColor: t.color.popover, borderWidth: t.size.borderWidth, borderColor: "transparent",
154
154
  },
155
155
  // O puxador, copiado do `BottomSheet` (`overlays.tsx:111-112`) — mesma medida, mesmo token.
156
156
  puxadorArea: { alignItems: "center", paddingVertical: t.size.space2 },
@@ -162,8 +162,8 @@ const folha = criarFolha((t) => ({
162
162
  flexDirection: "row", alignItems: "center", gap: t.size.space1,
163
163
  margin: t.size.space3,
164
164
  paddingHorizontal: t.size.space3,
165
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
166
- ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
165
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
166
+ ...canto(t.size.radiusControl), backgroundColor: preenchimento(t, 2),
167
167
  },
168
168
  // ⚠ `paddingVertical: 0` e `textAlignVertical: "center"` — a MESMA correção que o `Input` do
169
169
  // Lote 4 levou depois do vidro (`inputs.tsx:280-296`): sem elas o Android injeta o padding do
package/dist/data.js CHANGED
@@ -77,7 +77,7 @@ const folha = criarFolha((t) => ({
77
77
  marginTop: t.size.space1, backgroundColor: t.color.primary,
78
78
  // O halo do CSS é `box-shadow: 0 0 0 space-05 surface-1`. No RN sombra não faz anel —
79
79
  // uma BORDA da cor da superfície faz o mesmo buraco, e cresce o ponto pelo mesmo tanto.
80
- borderWidth: t.size.space05, borderColor: t.color.surface1,
80
+ borderWidth: t.size.space05, borderColor: "transparent",
81
81
  },
82
82
  colunaDoEvento: { flex: 1, minWidth: 0, gap: t.size.space05 },
83
83
  // R-18: o ponto centrado na coluna da moldura, quando a lista tem molduras.
@@ -98,7 +98,7 @@ const folha = criarFolha((t) => ({
98
98
  tabela: { gap: t.size.space2 },
99
99
  linha: {
100
100
  padding: t.size.space3, gap: t.size.space2,
101
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
101
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
102
102
  ...canto(t.size.radiusLg), backgroundColor: t.color.card,
103
103
  },
104
104
  linhaTocavel: { minHeight: t.size.targetMin ?? 44 },
package/dist/display.js CHANGED
@@ -25,7 +25,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
25
25
  import * as React from "react";
26
26
  import { Image, View } from "react-native";
27
27
  import { IconButton, folgaDoToque } from "./actions.js";
28
- import { canto, acentoDoTom, criarFolha, fundoDoTom, preenchimentoDoTom } from "./estilos.js";
28
+ import { canto, acentoDoTom, comOpacidade, criarFolha, fundoDoTom, misturaOpaca, preenchimentoDoTom } from "./estilos.js";
29
29
  import { Card } from "./layout.js";
30
30
  import { gravidadeDoEstado } from "./strings.js";
31
31
  import { Icon } from "./icon.js";
@@ -48,7 +48,7 @@ const folha = criarFolha((t) => ({
48
48
  flexDirection: "row", alignItems: "center", justifyContent: "center", gap: t.size.space1,
49
49
  paddingVertical: t.size.space1, paddingHorizontal: t.size.space3,
50
50
  borderWidth: t.size.borderWidth, ...canto(t.size.radiusControl),
51
- backgroundColor: t.color.secondary, borderColor: t.color.border,
51
+ backgroundColor: t.color.secondary, borderColor: "transparent",
52
52
  },
53
53
  selo_xs: { minHeight: t.size.space4, paddingVertical: 0, paddingHorizontal: t.size.space1, borderWidth: 0 },
54
54
  selo_sm: { paddingVertical: t.size.space05, paddingHorizontal: t.size.space2 },
@@ -67,7 +67,7 @@ const folha = criarFolha((t) => ({
67
67
  // atrás. Antes sobrava o recheio vertical do tamanho — o "1" do `sm` media 14,9 × 22, esticado —
68
68
  // e o anel era uma sombra de 2.
69
69
  sobreposto: { position: "absolute", zIndex: 1, paddingVertical: 0, paddingHorizontal: t.size.space05,
70
- borderWidth: t.size.borderWidth, borderColor: t.color.background },
70
+ borderWidth: t.size.borderWidth, borderColor: "transparent" },
71
71
  // ── Status ─────────────────────────────────────────────────────────────────────────────────
72
72
  estado: { flexDirection: "row", alignItems: "center", gap: t.size.space2 },
73
73
  // O halo é `box-shadow 0 0 0 3px` da cor corrente a 14% (aurea.css:1055). Sem `color-mix` no
@@ -78,8 +78,8 @@ const folha = criarFolha((t) => ({
78
78
  // com as iniciais em 12 · 14 · 16 e peso médio. O lado sai no componente (`LADO_DO_AVATAR`).
79
79
  avatar: {
80
80
  alignItems: "center", justifyContent: "center", overflow: "hidden",
81
- ...canto(t.size.radiusFull), backgroundColor: t.color.surface3,
82
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
81
+ ...canto(t.size.radiusFull), backgroundColor: misturaOpaca(t.color.foreground, t.color.background, 0.2),
82
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
83
83
  },
84
84
  imagem: { width: "100%", height: "100%" },
85
85
  // ── KPI ────────────────────────────────────────────────────────────────────────────────────
@@ -124,12 +124,15 @@ export function Badge({ tone = "neutral", emphasis = "soft", size = "md", dot, c
124
124
  const pele = emphasis === "solid"
125
125
  ? { backgroundColor: cheio ? cheio[0] : acento, borderColor: "transparent" }
126
126
  : emphasis === "outline"
127
- ? { backgroundColor: "transparent", borderColor: acento }
127
+ ? { backgroundColor: comOpacidade(acento, 0.16), borderColor: "transparent" }
128
128
  : tone === "neutral"
129
129
  ? {}
130
- : { backgroundColor: fundo, borderColor: acento };
130
+ : { backgroundColor: fundo, borderColor: "transparent" };
131
+ // Sem linha (16/10/2026): a letra do selo de CONTORNO vai 20% para a cor do texto, nos dois temas — sobre o acento a 16%,
132
+ // a de sempre caía abaixo de 4,5:1 (o verde do claro, o `success` do escuro). O par da web é o `.badge-outline`.
133
+ const letra = tone === "neutral" ? t.color.secondaryForeground : acento;
131
134
  const corDoTexto = emphasis === "solid" ? (cheio ? cheio[1] : t.color.background)
132
- : tone === "neutral" ? t.color.secondaryForeground : acento;
135
+ : emphasis === "outline" ? misturaOpaca(letra, t.color.foreground, 0.8) : letra;
133
136
  const numero = count != null ? formatarContagem(count, max) : undefined;
134
137
  const miolo = anchor ? (numero ?? badgeContent) : (numero ?? children);
135
138
  // Ponto puro: `dot` sem nada para mostrar. Aí o selo não tem conteúdo e ganha medida própria.
@@ -237,9 +240,9 @@ export function Status({ variant, state, children, style, ...rest }) {
237
240
  return (_jsxs(View, { style: [s.estado, style], ...rest, children: [_jsx(View, { style: [
238
241
  s.pontoDeEstado,
239
242
  v === "offline"
240
- // Vazado: sem preenchimento, com o anel de 2 por dentro. `borderWidth` faz o que o
241
- // `inset 0 0 0 2px` do CSS faz.
242
- ? { backgroundColor: "transparent", borderWidth: 2, borderColor: cor }
243
+ // Sem linha (16/10/2026): era vazado (um anel de 2). Agora é a bolinha cheia, apagada,
244
+ // como a da web.
245
+ ? { backgroundColor: comOpacidade(cor, 0.4) }
243
246
  : { backgroundColor: cor },
244
247
  ] }), typeof rotulo === "string"
245
248
  ? _jsx(Text, { size: "sm", children: rotulo })
package/dist/escolha.js CHANGED
@@ -12,7 +12,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
12
12
  // do `BottomSheet` (`overlays.tsx`).
13
13
  import * as React from "react";
14
14
  import { Animated, PanResponder, Platform, Pressable, TextInput, View, } from "react-native";
15
- import { canto, criarFolha, estadoAcessivel } from "./estilos.js";
15
+ import { canto, criarFolha, estadoAcessivel, preenchimento } from "./estilos.js";
16
16
  import { Icon } from "./icon.js";
17
17
  import { Label, useCampo } from "./inputs.js";
18
18
  import { driverNativo, useReduceMotion } from "./movimento.js";
@@ -55,12 +55,12 @@ const folha = criarFolha((t) => ({
55
55
  casa: {
56
56
  width: t.size.space10 + t.size.space1, height: t.size.touchControlHMd,
57
57
  alignItems: "center", justifyContent: "center",
58
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
59
- ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
58
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
59
+ ...canto(t.size.radiusControl), backgroundColor: preenchimento(t, 2),
60
60
  },
61
61
  // A casa ativa: a borda da cor do foco, com a espessura do anel (o contorno de 2 da referência).
62
62
  casaAtiva: { borderColor: t.color.focusStrong, borderWidth: t.size.focusWidth },
63
- casaInvalida: { borderColor: t.color.danger400 ?? t.color.destructive },
63
+ casaInvalida: { borderColor: "transparent", backgroundColor: t.color.dangerBg },
64
64
  // O dígito da referência: 18 em seminegrito, na linha de 28 do `text-lg`.
65
65
  digito: { fontSize: t.size.textLg, lineHeight: t.size.textLg * t.size.textLgLeading,
66
66
  fontFamily: t.font.ui[600], color: t.color.foreground },
@@ -345,7 +345,7 @@ export function OTPField({ length, value, defaultValue, onValueChange, mask, dis
345
345
  ativa && s.casaAtiva,
346
346
  invalido && s.casaInvalida,
347
347
  // Sobre a marca vale a tinta, inclusive no lugar do vermelho — a regra do `Input`.
348
- pele && { borderColor: pele.borderColor, backgroundColor: pele.backgroundColor },
348
+ pele && { borderColor: "transparent", backgroundColor: pele.backgroundColor },
349
349
  ], children: digito != null
350
350
  ? (mask
351
351
  ? _jsx(View, { style: [s.ponto, pele && { backgroundColor: pele.color }] })
package/dist/estilos.d.ts CHANGED
@@ -33,6 +33,19 @@ export declare function criarFolha<T extends NamedStyles<T> | NamedStyles<Record
33
33
  * um ícone) não tinha como escrevê-lo sem número à mão. O `check 39` cobra o teste dele.
34
34
  */
35
35
  export declare const comOpacidade: (cor: string, pct: number) => string;
36
+ /**
37
+ * SEM LINHA (16/10/2026), a sugestão: o fundo TRANSLÚCIDO da cor do texto, que se separa de qualquer fundo atrás —
38
+ * como o trilho desligado do switch da referência (o texto a 20%). Uma cor fixa acaba igual a alguma superfície, e foi
39
+ * assim que as peças sumiram quando a linha saiu. Nível 1 = 6% (superfície de dentro), 2 = 10% (campo, botão de
40
+ * contorno), 3 = 20% (marca do checkbox e do rádio, trilho do switch).
41
+ */
42
+ export declare const preenchimento: (t: AureaTokens, nivel: 1 | 2 | 3) => string;
43
+ /**
44
+ * A mesma mistura, OPACA: a cor da frente a `pct` sobre a do fundo. Para o que tem algo passando POR TRÁS (o traço dos
45
+ * passos) ou cobre outra peça (as fotos sobrepostas) — translúcido, o que está atrás aparece. Hex de seis, como o
46
+ * `comOpacidade`; fora disso devolve a cor da frente.
47
+ */
48
+ export declare const misturaOpaca: (frente: string, fundo: string, pct: number) => string;
36
49
  /**
37
50
  * 🍎 O CANTO DO iOS — HER-01, 06/10/2026: todo canto arredondado do nativo passa por aqui.
38
51
  *
package/dist/estilos.js CHANGED
@@ -49,6 +49,27 @@ export function criarFolha(descrever) {
49
49
  export const comOpacidade = (cor, pct) => /^#[0-9a-fA-F]{6}$/.test(cor)
50
50
  ? cor + Math.round(Math.max(0, Math.min(1, pct)) * 255).toString(16).padStart(2, "0")
51
51
  : cor;
52
+ /**
53
+ * SEM LINHA (16/10/2026), a sugestão: o fundo TRANSLÚCIDO da cor do texto, que se separa de qualquer fundo atrás —
54
+ * como o trilho desligado do switch da referência (o texto a 20%). Uma cor fixa acaba igual a alguma superfície, e foi
55
+ * assim que as peças sumiram quando a linha saiu. Nível 1 = 6% (superfície de dentro), 2 = 10% (campo, botão de
56
+ * contorno), 3 = 20% (marca do checkbox e do rádio, trilho do switch).
57
+ */
58
+ export const preenchimento = (t, nivel) => comOpacidade(t.color.foreground, nivel === 1 ? 0.06 : nivel === 2 ? 0.1 : 0.2);
59
+ /**
60
+ * A mesma mistura, OPACA: a cor da frente a `pct` sobre a do fundo. Para o que tem algo passando POR TRÁS (o traço dos
61
+ * passos) ou cobre outra peça (as fotos sobrepostas) — translúcido, o que está atrás aparece. Hex de seis, como o
62
+ * `comOpacidade`; fora disso devolve a cor da frente.
63
+ */
64
+ export const misturaOpaca = (frente, fundo, pct) => {
65
+ const hex = /^#([0-9a-fA-F]{6})$/;
66
+ const a = hex.exec(frente), b = hex.exec(fundo);
67
+ if (!a || !b)
68
+ return frente;
69
+ const canal = (h, i) => parseInt(h.slice(i, i + 2), 16);
70
+ return "#" + [0, 2, 4].map((i) => Math.round(canal(a[1], i) * pct + canal(b[1], i) * (1 - pct))
71
+ .toString(16).padStart(2, "0")).join("");
72
+ };
52
73
  /**
53
74
  * 🍎 O CANTO DO iOS — HER-01, 06/10/2026: todo canto arredondado do nativo passa por aqui.
54
75
  *
@@ -79,9 +100,11 @@ export const peleDoCartao = (t) => ({
79
100
  padding: t.size.cardPad,
80
101
  backgroundColor: t.color.card,
81
102
  borderWidth: t.size.borderWidth,
82
- borderColor: t.color.border,
103
+ borderColor: "transparent",
83
104
  });
84
- export const peleDoCartaoEscolhido = (t) => ({ borderColor: t.color.primaryOutline, backgroundColor: t.color.surface2 });
105
+ // Sem linha (16/10/2026): o escolhido era a linha da marca sobre o fundo de cima; sem linha, o aviso é o FUNDO, na cor
106
+ // da marca a 12% — o mesmo da web (`.card-selected`).
107
+ export const peleDoCartaoEscolhido = (t) => ({ borderColor: "transparent", backgroundColor: comOpacidade(t.color.primary, 0.12) });
85
108
  /**
86
109
  * A cor FORTE de um tom: o texto do selo, o ícone da moldura.
87
110
  *
package/dist/feedback.js CHANGED
@@ -23,6 +23,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
23
23
  import * as React from "react";
24
24
  import { Animated, Easing, View } from "react-native";
25
25
  import { Button, CloseButton } from "./actions.js";
26
+ import Svg, { Circle } from "react-native-svg";
26
27
  import { canto, criarFolha, estadoAcessivel, letraDoToken } from "./estilos.js";
27
28
  import { Icon } from "./icon.js";
28
29
  import { IconeEmMoldura } from "./moldura.js";
@@ -39,7 +40,7 @@ const folha = criarFolha((t) => ({
39
40
  // HER-01: a ÚNICA peça com o canto `circular`, declarada. O anel GIRA, e um contorno que não
40
41
  // seja círculo perfeito balança ao girar. A referência também deixa o `Spinner` de
41
42
  // fora das 24 peças com canto contínuo.
42
- anel: { borderWidth: 2, borderRightColor: "transparent", ...canto(t.size.radiusFull, "circular") },
43
+ anel: { ...canto(t.size.radiusFull, "circular") },
43
44
  // ── Skeleton ───────────────────────────────────────────────────────────────────────────────
44
45
  // O raio 7 é cru no CSS (`aurea.css:1111`) e entra aqui **como está**: inventar um token para
45
46
  // ele faria o nativo e a web desenharem cantos diferentes para a mesma peça.
@@ -120,12 +121,17 @@ export function Spinner({ size = "md", label, decorative, style, testID }) {
120
121
  ? { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants" }
121
122
  : { accessible: true, accessibilityRole: "progressbar",
122
123
  accessibilityLabel: label ?? strings.loading };
124
+ // Sem linha (16/10/2026): o anel era BORDA (3/4 da volta). Agora é o mesmo arco desenhado, como a
125
+ // máscara da web — 2 de espessura em qualquer tamanho, por isso a conta em unidades do desenho.
126
+ const traco = (2 * 16) / lado;
127
+ const raio = 8 - traco / 2;
128
+ const volta = 2 * Math.PI * raio;
123
129
  return (_jsx(Animated.View, { testID: testID, ...acessibilidade, style: [
124
130
  s.anel,
125
- { width: lado, height: lado, borderColor: t.color.foreground, borderRightColor: "transparent" },
131
+ { width: lado, height: lado },
126
132
  { transform: [{ rotate: giro.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }) }] },
127
133
  style,
128
- ] }));
134
+ ], children: _jsx(Svg, { width: lado, height: lado, viewBox: "0 0 16 16", children: _jsx(Circle, { cx: 8, cy: 8, r: raio, fill: "none", stroke: t.color.foreground, strokeWidth: traco, strokeDasharray: `${volta * 0.75} ${volta * 0.25}` }) }) }));
129
135
  }
130
136
  export const GrupoDeEsqueleto = React.createContext(null);
131
137
  /**
package/dist/inputs.js CHANGED
@@ -44,7 +44,8 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
44
44
  // estão ao lado dela. O `SegmentedControl` fica na escala da web — não é desta frente.
45
45
  import * as React from "react";
46
46
  import { Animated, KeyboardAvoidingView as KeyboardAvoidingViewRN, Modal, Platform, Pressable, ScrollView, TextInput, View, } from "react-native";
47
- import { canto, cantosDeCima, criarFolha, estadoAcessivel, fioDoEscolhido, peleDoCartao, peleDoCartaoEscolhido } from "./estilos.js";
47
+ import Svg, { Path } from "react-native-svg";
48
+ import { canto, cantosDeCima, criarFolha, estadoAcessivel, fioDoEscolhido, peleDoCartao, peleDoCartaoEscolhido, preenchimento } from "./estilos.js";
48
49
  import { FilaRolante } from "./rolagem.js";
49
50
  import { IconButton } from "./actions.js";
50
51
  import { Icon } from "./icon.js";
@@ -70,8 +71,8 @@ const folha = criarFolha((t) => ({
70
71
  rotulo: { flexDirection: "row", justifyContent: "space-between", gap: 12 },
71
72
  caixa: {
72
73
  width: "100%", minWidth: 0,
73
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
74
- ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
74
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
75
+ ...canto(t.size.radiusControl), backgroundColor: preenchimento(t, 2),
75
76
  color: t.color.foreground,
76
77
  },
77
78
  // O `.textarea` é o único da família com raio LG em vez do de controle: uma caixa alta em
@@ -79,15 +80,15 @@ const folha = criarFolha((t) => ({
79
80
  // 0.32.0: a caixa alta da referência — 128 de altura (era 104) e 8 em cima e embaixo (era 12).
80
81
  areaDeTexto: { minHeight: t.size.space24 + t.size.space8, paddingVertical: t.size.space2,
81
82
  ...canto(t.size.radiusLg) },
82
- invalido: { borderColor: t.color.danger400 ?? t.color.destructive },
83
+ invalido: { borderColor: "transparent", backgroundColor: t.color.dangerBg },
83
84
  desabilitado: { opacity: t.size.opacityDisabled },
84
85
  // O GRUPO é a mesma caixa do campo virada em LINHA, e os números são os mesmos: mesma borda,
85
86
  // mesmo raio de controle, mesmo fundo. A altura e o respiro horizontal entram por tamanho, como
86
87
  // no `Input`, porque é o grupo que passa a desenhar a caixa quando existe um.
87
88
  grupo: {
88
89
  flexDirection: "row", alignItems: "center", width: "100%", minWidth: 0,
89
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
90
- ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
90
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
91
+ ...canto(t.size.radiusControl), backgroundColor: preenchimento(t, 2),
91
92
  gap: t.size.space1,
92
93
  },
93
94
  // Dentro do grupo o campo perde a caixa e vira só o texto — a borda passou a ser do grupo.
@@ -98,8 +99,8 @@ const folha = criarFolha((t) => ({
98
99
  encaixe: { flexDirection: "row", alignItems: "center", flexShrink: 0, gap: t.size.space1 },
99
100
  marcaBase: {
100
101
  alignItems: "center", justifyContent: "center",
101
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
102
- backgroundColor: t.color.fieldBg,
102
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
103
+ backgroundColor: preenchimento(t, 3),
103
104
  },
104
105
  // E5: a marca no MEIO da altura do texto, como a referência. Era `flex-start` com um
105
106
  // `marginTop: 1` fixo, e a bolinha ficava presa no topo do rótulo.
@@ -110,8 +111,8 @@ const folha = criarFolha((t) => ({
110
111
  itemCartao: { ...peleDoCartao(t), alignItems: "flex-start" },
111
112
  itemCartaoEscolhido: peleDoCartaoEscolhido(t),
112
113
  linhaNoTopo: { alignItems: "flex-start" },
113
- trilho: { ...canto(t.size.radiusFull), backgroundColor: t.color.muted,
114
- borderWidth: t.size.borderWidth, borderColor: t.color.border, justifyContent: "center" },
114
+ trilho: { ...canto(t.size.radiusFull), backgroundColor: preenchimento(t, 3),
115
+ borderWidth: t.size.borderWidth, borderColor: "transparent", justifyContent: "center" },
115
116
  // 0.32.0: a 2 da borda de FORA, como a bolinha da referência — o `left` conta de dentro da borda
116
117
  // do trilho, então é `space05 − borderWidth` (1), a mesma conta do `.switch-track:after` da web.
117
118
  polegar: { position: "absolute", left: t.size.space05 - t.size.borderWidth, ...canto(t.size.radiusFull) },
@@ -153,7 +154,7 @@ const folha = criarFolha((t) => ({
153
154
  maxHeight: "60%", paddingVertical: t.size.space2,
154
155
  // HER-03 (ADR-0058): a folha que sobe de baixo tem 32, como a `BottomSheet`.
155
156
  ...cantosDeCima(t.size.radiusSheet),
156
- backgroundColor: t.color.popover, borderWidth: t.size.borderWidth, borderColor: t.color.border,
157
+ backgroundColor: t.color.popover, borderWidth: t.size.borderWidth, borderColor: "transparent",
157
158
  },
158
159
  // 0.32.0: a opção da lista da referência — 12 em cima e embaixo, 8 dos lados, 8 entre o rótulo e
159
160
  // o indicador. Com a linha de 24 do rótulo dá 48, a altura de toque (era `controlHLg`, 40).
@@ -395,22 +396,16 @@ function ControleMarcado({ papel, label, description, checked, onChange, disable
395
396
  // web; era 5 cru.
396
397
  { width: lado, height: lado,
397
398
  ...canto(papel === "radio" ? t.size.radiusFull : t.size.radiusXs) },
398
- checked && { backgroundColor: t.color.controlSelected, borderColor: t.color.controlSelected },
399
+ checked && { backgroundColor: t.color.controlSelected, borderColor: "transparent" },
399
400
  ], children: checked && (papel === "radio"
400
401
  // O ponto do rádio é da cor de primeiro plano da seleção, sobre a marca já pintada.
401
402
  // 0.32.0: 10, o ponto da referência e o do `RadioGroup` (`space2 + space05`); era 8.
402
403
  ? _jsx(View, { style: { width: t.size.space2 + t.size.space05, height: t.size.space2 + t.size.space05,
403
404
  ...canto(t.size.radiusFull), backgroundColor: t.color.controlSelectedForeground } })
404
- // O visto da web é desenhado com DUAS BORDAS de um retângulo 8×4 girado −45°. Isso
405
- // atravessa inteiro: `transform: rotate` e `borderLeftWidth`/`borderBottomWidth`
406
- // existem no RN. Desenhá-lo assim, em vez de trazer um glifo, mantém a peça sem
407
- // depender do registro de ícones do app.
408
- : _jsx(View, { style: {
409
- width: 8, height: 4, marginTop: -2,
410
- borderLeftWidth: 2, borderBottomWidth: 2,
411
- borderColor: t.color.controlSelectedForeground,
412
- transform: [{ rotate: "-45deg" }],
413
- } })) }), temTexto && (_jsxs(View, { style: { flex: 1 }, children: [typeof label === "string" ? _jsx(Text, { size: "sm", children: label }) : label, description != null && (typeof description === "string"
405
+ // O visto. Era desenhado com DUAS BORDAS de um retângulo girado; sem linha (16/10/2026), ele é
406
+ // um glifo, o mesmo da web (a máscara do `.checkbox` no `aurea.css`), sobre o `react-native-svg`
407
+ // que o pacote já usa — sem depender do registro de ícones do app.
408
+ : _jsx(Svg, { width: "100%", height: "100%", viewBox: "0 0 16 16", children: _jsx(Path, { d: "M3.5 8.5l3 3 6-7", fill: "none", stroke: t.color.controlSelectedForeground, strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) })) }), temTexto && (_jsxs(View, { style: { flex: 1 }, children: [typeof label === "string" ? _jsx(Text, { size: "sm", children: label }) : label, description != null && (typeof description === "string"
414
409
  ? _jsx(Text, { size: "xs", tone: "muted", children: description }) : description)] }))] }));
415
410
  }
416
411
  /** A caixa que marca. `accessibilityRole="checkbox"` + `state.checked`. */
@@ -448,9 +443,9 @@ function ItemDoGrupoDeRadio({ value, label, description, disabled, invalid, indi
448
443
  const marcaDesenhada = (_jsx(View, { style: [
449
444
  s.marcaBase,
450
445
  { width: marca, height: marca, ...canto(t.size.radiusFull) },
451
- erro && { borderColor: perigo, backgroundColor: "transparent" },
446
+ erro && { borderColor: "transparent", backgroundColor: t.color.dangerBg },
452
447
  escolhido && { backgroundColor: erro ? perigo : t.color.controlSelected,
453
- borderColor: erro ? perigo : t.color.controlSelected },
448
+ borderColor: "transparent" },
454
449
  ], children: escolhido && _jsx(View, { style: { width: ponto, height: ponto, ...canto(t.size.radiusFull),
455
450
  backgroundColor: t.color.controlSelectedForeground } }) }, "marca"));
456
451
  // O ícone é decorativo: o rótulo já diz o que a opção é, e o `Icon` sem `label` sai da árvore
@@ -465,7 +460,7 @@ function ItemDoGrupoDeRadio({ value, label, description, disabled, invalid, indi
465
460
  // pagou no Android — caixa que ganha a pintura depois de montada perde o raio.
466
461
  cartao && s.itemCartao,
467
462
  cartao && escolhido && s.itemCartaoEscolhido,
468
- cartao && erro && { borderColor: perigo },
463
+ cartao && erro && { borderColor: "transparent", backgroundColor: t.color.dangerBg },
469
464
  inativo && s.desabilitado, style,
470
465
  ], ...rest, children: noInicio ? [marcaDesenhada, glifo, texto] : [glifo, texto, marcaDesenhada] }));
471
466
  }
@@ -551,7 +546,7 @@ export function Switch({ label, description, checked, onChange, disabled, size,
551
546
  ], children: [_jsx(View, { style: [
552
547
  s.trilho,
553
548
  { width: larguraDoTrilho, height: alturaDoTrilho },
554
- checked && { backgroundColor: t.color.controlSelected, borderColor: t.color.controlSelected },
549
+ checked && { backgroundColor: t.color.controlSelected, borderColor: "transparent" },
555
550
  ], children: _jsx(Animated.View, { style: [
556
551
  s.polegar,
557
552
  { width: larguraDoPolegar, height: alturaDoPolegar,
package/dist/layout.js CHANGED
@@ -17,7 +17,7 @@ import { Pressable, StyleSheet, View } from "react-native";
17
17
  // `@aurea-uds/react` ja' faz (o `Stack` da web e' `HTMLAttributes & RefAttributes`, sem
18
18
  // envelope). O `ViewProps`/`TextProps` do RN 0.87 ja' declaram `ref`, entao ele viaja no
19
19
  // `...rest` sem nada a mais.
20
- import { canto, criarFolha, peleDoCartao, peleDoCartaoEscolhido, REACAO_AO_TOQUE, estadoAcessivel } from "./estilos.js";
20
+ import { canto, comOpacidade, criarFolha, peleDoCartao, peleDoCartaoEscolhido, REACAO_AO_TOQUE, estadoAcessivel } from "./estilos.js";
21
21
  import { Text } from "./text.js";
22
22
  import { useAureaTheme, useAureaTokens, SobreAMarca, TemaDentro } from "./theme.js";
23
23
  const folha = criarFolha((t) => ({
@@ -43,14 +43,15 @@ const folha = criarFolha((t) => ({
43
43
  cardBase: peleDoCartao(t),
44
44
  card_base: {},
45
45
  card_raised: { boxShadow: [t.shadow.shadowLg] },
46
- card_interactive: { borderColor: t.color.borderStrong },
46
+ card_interactive: { borderColor: "transparent" },
47
47
  // `inset` recessa em vez de flutuar — é o painel DENTRO de um card, e a ficha da web diz isso.
48
48
  card_inset: { backgroundColor: t.color.surfaceInset, borderColor: "transparent" },
49
49
  // 0.32.0: `outline` é o cartão da cor de onde ele está, só com a linha em volta — o mesmo nome da
50
50
  // web. Sem fundo; a borda, o raio e o recheio continuam os do `cardBase`.
51
- card_outline: { backgroundColor: "transparent" },
51
+ // Sem linha (ADR-0072): a ÚNICA linha que fica — clara, o texto a 10% (a "B" da caixa da vitrine, o Victor, 16/10).
52
+ card_outline: { backgroundColor: "transparent", borderColor: comOpacidade(t.color.foreground, 0.1) },
52
53
  card_selected: peleDoCartaoEscolhido(t),
53
- card_danger: { borderColor: t.color.danger400 ?? t.color.destructive, backgroundColor: t.color.dangerBg },
54
+ card_danger: { borderColor: "transparent", backgroundColor: t.color.dangerBg },
54
55
  // O amarelo é o DE PREENCHER — `primary`, o mesmo do botão sólido. A borda some: uma superfície
55
56
  // cheia não precisa de contorno, e um contorno sobre o amarelo mede 2,43 no claro (invisível).
56
57
  card_brand: { backgroundColor: t.color.primary, borderColor: "transparent" },
@@ -58,7 +59,7 @@ const folha = criarFolha((t) => ({
58
59
  // `cardBase` já é o cartão do escuro. No claro, sem linha em volta (13,3:1 contra a tela); no
59
60
  // escuro, o amarelo, com a borda de sempre.
60
61
  card_contrast: { borderColor: "transparent" },
61
- contrasteNoEscuro: { borderColor: t.color.primary },
62
+ contrasteNoEscuro: { borderColor: "transparent" },
62
63
  // MT-02 (ADR-0063): o traço no topo. Uma borda mais grossa só em cima, com o canto 22, desenha
63
64
  // errado no Android (react-native#51926, fechada sem conserto em 24/03/2026: a borda sai do
64
65
  // contorno e deixa vão). Então o traço é uma faixa de `accentWidth` numa camada que se recorta no
package/dist/menu.js CHANGED
@@ -43,7 +43,7 @@ const folha = criarFolha((t) => ({
43
43
  painel: {
44
44
  position: "absolute",
45
45
  backgroundColor: t.color.popover,
46
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
46
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
47
47
  ...canto(t.size.radiusCard),
48
48
  boxShadow: [...t.shadowLayers.shadowLg],
49
49
  },
@@ -94,7 +94,7 @@ const folha = criarFolha((t) => ({
94
94
  fundoDoSubmenu: {
95
95
  position: "absolute", top: 0, right: 0, bottom: 0, left: 0,
96
96
  backgroundColor: t.color.popover,
97
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
97
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
98
98
  ...canto(t.size.radiusLg),
99
99
  boxShadow: [...t.shadowLayers.shadowMd],
100
100
  },
package/dist/midia.js CHANGED
@@ -60,7 +60,7 @@ const folha = criarFolha((t) => ({
60
60
  // superfície do cartão, a borda, a sombra média e o canto da folha de baixo; o de dentro acompanha.
61
61
  moldura: {
62
62
  padding: t.size.space2,
63
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
63
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
64
64
  ...canto(t.size.radiusSheet),
65
65
  backgroundColor: t.color.card,
66
66
  ...(t.shadow.shadowMd ? { boxShadow: [t.shadow.shadowMd] } : null),
@@ -3,7 +3,7 @@ import { Pressable, View } from "react-native";
3
3
  import { useSafeAreaInsets } from "react-native-safe-area-context";
4
4
  import { useAnotarBottomNav } from "./barranav.js";
5
5
  import { Avatar, Badge } from "./display.js";
6
- import { canto, comOpacidade, criarFolha, estadoAcessivel, fioDoEscolhido } from "./estilos.js";
6
+ import { canto, comOpacidade, criarFolha, estadoAcessivel, fioDoEscolhido, misturaOpaca } from "./estilos.js";
7
7
  import { Icon } from "./icon.js";
8
8
  import { Card } from "./layout.js";
9
9
  import { FilaRolante } from "./rolagem.js";
@@ -21,7 +21,7 @@ const folha = criarFolha((t) => ({
21
21
  topo_floating: {
22
22
  marginHorizontal: t.size.space4, marginTop: t.size.space4,
23
23
  paddingVertical: t.size.space2, paddingHorizontal: t.size.space4,
24
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
24
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
25
25
  ...canto(t.size.radiusCard), backgroundColor: t.color.card,
26
26
  },
27
27
  topo_flush: { paddingVertical: t.size.space2, paddingHorizontal: t.size.space5,
@@ -34,7 +34,7 @@ const folha = criarFolha((t) => ({
34
34
  topo_pill: {
35
35
  alignSelf: "center", marginTop: t.size.space4, justifyContent: "flex-start",
36
36
  gap: t.size.space2, padding: t.size.space2,
37
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
37
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
38
38
  ...canto(t.size.radiusControl), backgroundColor: t.color.card,
39
39
  },
40
40
  // ── BottomNav ──────────────────────────────────────────────────────────────────────────────
@@ -52,7 +52,7 @@ const folha = criarFolha((t) => ({
52
52
  barra: {
53
53
  position: "absolute", bottom: 0, zIndex: t.size.zSticky,
54
54
  flexDirection: "row", gap: t.size.space1, margin: t.size.space4, padding: t.size.space1,
55
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
55
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
56
56
  ...canto(t.size.radiusControl), backgroundColor: t.color.card,
57
57
  boxShadow: [t.shadow.shadowMd],
58
58
  },
@@ -226,7 +226,7 @@ const folha = criarFolha((t) => ({
226
226
  // indicador (secundária) border-bottom 2px na cor de destaque → `fioDoEscolhido`
227
227
  abasSecundarias: {
228
228
  flexDirection: "row", gap: t.size.space1,
229
- borderBottomWidth: t.size.borderWidth, borderColor: t.color.border,
229
+ borderBottomWidth: t.size.borderWidth, borderColor: "transparent",
230
230
  },
231
231
  abaSecundaria: {
232
232
  alignItems: "center", justifyContent: "center", minHeight: t.size.controlHMd,
@@ -240,8 +240,8 @@ const folha = criarFolha((t) => ({
240
240
  bolinha: {
241
241
  width: 32, height: 32, marginBottom: t.size.space2,
242
242
  alignItems: "center", justifyContent: "center", ...canto(t.size.radiusFull),
243
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
244
- backgroundColor: t.color.surface1,
243
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
244
+ backgroundColor: misturaOpaca(t.color.foreground, t.color.background, 0.2),
245
245
  },
246
246
  }));
247
247
  /**
@@ -393,7 +393,8 @@ export function BottomNav({ items, current, variant = "floating", indicator = "n
393
393
  backgroundColor: t.color.popover, boxShadow: [t.shadow.shadowMd],
394
394
  },
395
395
  ativo && indicator === "circle-outline" && {
396
- borderWidth: t.size.borderWidth, borderColor: t.color.primaryEmphasis,
396
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
397
+ backgroundColor: comOpacidade(t.color.primaryEmphasis, 0.10),
397
398
  },
398
399
  ativo && capsula && { backgroundColor: t.color.primary },
399
400
  ], children: [it.icon && _jsx(Icon, { name: it.icon, size: "lg", color: corDoIcone, weight: ativo ? "fill" : undefined }), it.badge != null && it.badge !== false && (_jsx(View, { style: [s.contador, capsula && s.contadorCapsula], children: typeof it.badge === "number"
@@ -531,8 +532,8 @@ export function Stepper({ items, label, doneIcon = "check", errorIcon = "x-circl
531
532
  : t.color.foreground;
532
533
  const miolo = (_jsxs(_Fragment, { children: [_jsx(View, { style: [
533
534
  s.bolinha,
534
- st === "error" && { borderColor: cor },
535
- st === "active" && { borderColor: t.color.primaryEmphasis },
535
+ st === "error" && { borderColor: "transparent", backgroundColor: t.color.dangerBg },
536
+ st === "active" && { borderColor: "transparent", backgroundColor: comOpacidade(t.color.primary, 0.14) },
536
537
  ], children: st === "done" && doneIcon
537
538
  ? _jsx(Icon, { name: doneIcon, size: "sm", color: cor })
538
539
  : st === "error" && errorIcon
package/dist/numero.js CHANGED
@@ -48,7 +48,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
48
48
  import * as React from "react";
49
49
  import { Platform, TextInput, View } from "react-native";
50
50
  import { IconButton } from "./actions.js";
51
- import { canto, criarFolha, estadoAcessivel } from "./estilos.js";
51
+ import { canto, criarFolha, estadoAcessivel, preenchimento } from "./estilos.js";
52
52
  import { useCampo } from "./inputs.js";
53
53
  import { useAureaStrings, useAureaTokens, usePeleSobreAMarca } from "./theme.js";
54
54
  // 0.32.0: o campo comum na altura de TOQUE, como o `Input` (40 · 48 · 56; era 32 · 36 · 40). O
@@ -80,14 +80,14 @@ const folha = criarFolha((t) => ({
80
80
  // não cabe em 64dp — nem aqui nem na web**, e é para isso que existe o `fullWidth`.
81
81
  campo: {
82
82
  width: t.size.space16, textAlign: "center",
83
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
84
- ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
83
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
84
+ ...canto(t.size.radiusControl), backgroundColor: preenchimento(t, 2),
85
85
  // A mesma correção de Android do `Input` do Lote 4 — ver `inputs.tsx:280-296`.
86
86
  paddingVertical: 0, textAlignVertical: "center",
87
87
  },
88
88
  campoLargo: { width: undefined, flex: 1, minWidth: t.size.space16 },
89
89
  campoDisplay: { width: t.size.space24 },
90
- invalido: { borderColor: t.color.danger400 ?? t.color.destructive },
90
+ invalido: { borderColor: "transparent", backgroundColor: t.color.dangerBg },
91
91
  desabilitado: { opacity: t.size.opacityDisabled },
92
92
  }));
93
93
  // ─────────────────────────────────────────────────────────────────────────────────────────────
package/dist/overlays.js CHANGED
@@ -79,7 +79,7 @@ const folha = criarFolha((t) => ({
79
79
  // título 18 em peso médio e descrição 16 (no componente).
80
80
  superficie: {
81
81
  width: "100%", maxWidth: 560, padding: t.size.space5,
82
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
82
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
83
83
  ...canto(t.size.radiusCard),
84
84
  backgroundColor: t.color.popover,
85
85
  ...(t.shadow.shadowLg ? { boxShadow: [t.shadow.shadowLg] } : null),
@@ -117,8 +117,8 @@ const folha = criarFolha((t) => ({
117
117
  backgroundColor: t.color.surface1,
118
118
  ...(t.shadow.shadowLg ? { boxShadow: [t.shadow.shadowLg] } : null),
119
119
  },
120
- gavetaDireita: { right: 0, borderLeftWidth: t.size.borderWidth, borderLeftColor: t.color.border },
121
- gavetaEsquerda: { left: 0, borderRightWidth: t.size.borderWidth, borderRightColor: t.color.border },
120
+ gavetaDireita: { right: 0, borderLeftWidth: t.size.borderWidth, borderLeftColor: "transparent" },
121
+ gavetaEsquerda: { left: 0, borderRightWidth: t.size.borderWidth, borderRightColor: "transparent" },
122
122
  folhaBaixo: {
123
123
  position: "absolute", left: 0, right: 0, bottom: 0,
124
124
  maxHeight: "90%",
@@ -131,7 +131,7 @@ const folha = criarFolha((t) => ({
131
131
  // do telefone. Decisão do Victor, olhando as duas na bancada. A lista do `Select` e a folha do
132
132
  // `Combobox` sobem do mesmo jeito e levam o mesmo token.
133
133
  ...cantosDeCima(t.size.radiusSheet),
134
- borderTopWidth: t.size.borderWidth, borderTopColor: t.color.border,
134
+ borderTopWidth: t.size.borderWidth, borderTopColor: "transparent",
135
135
  ...(t.shadow.shadowLg ? { boxShadow: [t.shadow.shadowLg] } : null),
136
136
  },
137
137
  folhaSemPuxador: { paddingTop: t.size.space5 },
package/dist/sistema.js CHANGED
@@ -35,7 +35,7 @@ import { Linking, Platform, Pressable, View } from "react-native";
35
35
  import RNDateTimePicker, { DateTimePickerAndroid } from "@react-native-community/datetimepicker";
36
36
  import * as ImagePicker from "expo-image-picker";
37
37
  import { IconButton } from "./actions.js";
38
- import { canto, criarFolha, estadoAcessivel } from "./estilos.js";
38
+ import { canto, criarFolha, estadoAcessivel, preenchimento } from "./estilos.js";
39
39
  import { Alert } from "./feedback.js";
40
40
  import { Icon } from "./icon.js";
41
41
  import { alturaDoTamanho, respiroDoTamanho, useCampo } from "./inputs.js";
@@ -45,10 +45,10 @@ import { useAureaStrings, useAureaTokens } from "./theme.js";
45
45
  const folha = criarFolha((t) => ({
46
46
  gatilho: {
47
47
  flexDirection: "row", alignItems: "center", justifyContent: "space-between",
48
- width: "100%", borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
49
- ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
48
+ width: "100%", borderWidth: t.size.borderWidth, borderColor: "transparent",
49
+ ...canto(t.size.radiusControl), backgroundColor: preenchimento(t, 2),
50
50
  },
51
- invalido: { borderColor: t.color.danger400 ?? t.color.destructive },
51
+ invalido: { borderColor: "transparent", backgroundColor: t.color.dangerBg },
52
52
  // No navegador o texto e o ícone vão numa caixa escondida do leitor de tela (E16): a mesma
53
53
  // fileira do gatilho, ocupando a largura dele.
54
54
  mioloWeb: { flex: 1, flexDirection: "row", alignItems: "center", justifyContent: "space-between" },
@@ -70,8 +70,8 @@ const folha = criarFolha((t) => ({
70
70
  adicionar: {
71
71
  alignItems: "center", justifyContent: "center", gap: t.size.space1,
72
72
  width: t.size.space16, height: t.size.space16, ...canto(t.size.radiusLg),
73
- borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
74
- borderStyle: "dashed", backgroundColor: t.color.fieldBg,
73
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
74
+ borderStyle: "dashed", backgroundColor: preenchimento(t, 2),
75
75
  },
76
76
  }));
77
77
  /**
package/dist/theme.d.ts CHANGED
@@ -161,6 +161,12 @@ export declare function TemaDentro({ tema, children }: {
161
161
  *
162
162
  * ⚠ **O texto digitado e o marcador de dica ficam da MESMA cor**, porque só existe uma tinta. É
163
163
  * perda real de hierarquia, declarada e não escondida: sobre o amarelo não há segunda cor.
164
+ *
165
+ * ⚠ **Sem linha (16/10/2026, o Victor: "quero tudo sem borda sem exceções").** O contorno da tinta
166
+ * saiu, e sem ele o campo sumia no amarelo (fundo transparente, nenhuma linha). Agora o campo é a
167
+ * TINTA a 14% sobre o amarelo — o amarelo um pouco mais escuro, como o campo fora do cartão é a
168
+ * superfície um pouco diferente da página. A 1.4.11 (3:1 para o limite do campo), que só o contorno
169
+ * alcançava, deixa de ser cumprida aqui, como em todo campo sem linha: decisão do Victor, ADR-0072.
164
170
  */
165
171
  export declare function usePeleSobreAMarca(): {
166
172
  borderColor: string;
package/dist/theme.js CHANGED
@@ -2,6 +2,7 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { useColorScheme } from "react-native";
4
4
  import { IconRegistryProvider } from "./icon.js";
5
+ import { comOpacidade } from "./estilos.js";
5
6
  import { defaultStrings } from "./strings.js";
6
7
  import { resolverTokens, } from "./tokens.js";
7
8
  // `comfortable` não é gosto: MEDIDO em 02/09/2026, os 8 tokens de densidade do `comfortable` são
@@ -182,10 +183,16 @@ export function TemaDentro({ tema, children }) {
182
183
  *
183
184
  * ⚠ **O texto digitado e o marcador de dica ficam da MESMA cor**, porque só existe uma tinta. É
184
185
  * perda real de hierarquia, declarada e não escondida: sobre o amarelo não há segunda cor.
186
+ *
187
+ * ⚠ **Sem linha (16/10/2026, o Victor: "quero tudo sem borda sem exceções").** O contorno da tinta
188
+ * saiu, e sem ele o campo sumia no amarelo (fundo transparente, nenhuma linha). Agora o campo é a
189
+ * TINTA a 14% sobre o amarelo — o amarelo um pouco mais escuro, como o campo fora do cartão é a
190
+ * superfície um pouco diferente da página. A 1.4.11 (3:1 para o limite do campo), que só o contorno
191
+ * alcançava, deixa de ser cumprida aqui, como em todo campo sem linha: decisão do Victor, ADR-0072.
185
192
  */
186
193
  export function usePeleSobreAMarca() {
187
194
  const marca = useSobreAMarca();
188
195
  return marca == null
189
196
  ? null
190
- : { borderColor: marca.tinta, backgroundColor: "transparent", color: marca.tinta };
197
+ : { borderColor: "transparent", backgroundColor: comOpacidade(marca.tinta, 0.14), color: marca.tinta };
191
198
  }
package/dist/toast.js CHANGED
@@ -74,7 +74,7 @@ const folha = criarFolha((t) => ({
74
74
  // 0.32.0: 16 de recheio, o do aviso do nativo da referência (era 14, o da web antiga).
75
75
  flexDirection: "row", alignItems: "center", gap: 11, padding: t.size.space4,
76
76
  maxWidth: 360, width: "100%", alignSelf: "flex-end",
77
- borderWidth: t.size.borderWidth, borderColor: t.color.border,
77
+ borderWidth: t.size.borderWidth, borderColor: "transparent",
78
78
  // HER-02 (06/10/2026): era `radiusLg` (16). O aviso é superfície flutuante, e superfície
79
79
  // flutuante é 22 na identidade da Aurea (`CLAUDE.md` §5). A referência usa 24.
80
80
  ...canto(t.size.radiusCard),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurea-uds/native",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "A Aurea UDS para React Native: o provider de tema e densidade, os componentes e os ícones do Phosphor sobre react-native-svg.",
5
5
  "keywords": [
6
6
  "aurea",
@@ -55,7 +55,7 @@
55
55
  "NOTICE"
56
56
  ],
57
57
  "dependencies": {
58
- "@aurea-uds/tokens": "^0.33.0"
58
+ "@aurea-uds/tokens": "^0.34.0"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@react-native-community/datetimepicker": ">=8",