ds-tis 1.0.0-beta.10

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.
Files changed (79) hide show
  1. package/LICENSE +49 -0
  2. package/README.md +125 -0
  3. package/css/base/forced-colors.css +62 -0
  4. package/css/base/icons.css +73 -0
  5. package/css/base/index.css +4 -0
  6. package/css/base/reset.css +80 -0
  7. package/css/base/typography.css +211 -0
  8. package/css/components/accordion.css +153 -0
  9. package/css/components/alert.css +161 -0
  10. package/css/components/avatar.css +76 -0
  11. package/css/components/badge.css +83 -0
  12. package/css/components/breadcrumb.css +58 -0
  13. package/css/components/button.css +364 -0
  14. package/css/components/card.css +159 -0
  15. package/css/components/checkbox.css +296 -0
  16. package/css/components/combobox.css +330 -0
  17. package/css/components/divider.css +20 -0
  18. package/css/components/form-field.css +137 -0
  19. package/css/components/index.css +28 -0
  20. package/css/components/input.css +356 -0
  21. package/css/components/link.css +67 -0
  22. package/css/components/menu.css +246 -0
  23. package/css/components/modal.css +236 -0
  24. package/css/components/pagination.css +132 -0
  25. package/css/components/radio.css +280 -0
  26. package/css/components/select.css +399 -0
  27. package/css/components/skeleton.css +52 -0
  28. package/css/components/spinner.css +59 -0
  29. package/css/components/tabs.css +79 -0
  30. package/css/components/textarea.css +218 -0
  31. package/css/components/toggle.css +202 -0
  32. package/css/components/tooltip.css +116 -0
  33. package/css/design-system.css +13 -0
  34. package/css/tokens/generated/component.css +720 -0
  35. package/css/tokens/generated/foundation.css +282 -0
  36. package/css/tokens/generated/index.css +5 -0
  37. package/css/tokens/generated/theme-dark.css +243 -0
  38. package/css/tokens/generated/theme-light.css +244 -0
  39. package/css/tokens/index.css +6 -0
  40. package/css/utilities/elevation.css +24 -0
  41. package/css/utilities/index.css +2 -0
  42. package/css/utilities/layout.css +132 -0
  43. package/docs/agent-consumer-usage.en.md +322 -0
  44. package/docs/agent-consumer-usage.md +294 -0
  45. package/docs/api/adrs.json +186 -0
  46. package/docs/api/components.json +2071 -0
  47. package/docs/api/consumer-context.json +66 -0
  48. package/docs/api/foundations.json +94 -0
  49. package/docs/api/tokens.json +6839 -0
  50. package/docs/llms-full.txt +23699 -0
  51. package/docs/llms.txt +109 -0
  52. package/docs/templates/contact.html +364 -0
  53. package/docs/templates/dashboard.html +318 -0
  54. package/docs/templates/index.html +232 -0
  55. package/docs/templates/login.html +286 -0
  56. package/docs/templates/settings.html +365 -0
  57. package/docs/templates/signup.html +350 -0
  58. package/js/accordion.js +192 -0
  59. package/js/combobox.js +263 -0
  60. package/js/menu.js +301 -0
  61. package/js/modal.js +256 -0
  62. package/js/package.json +3 -0
  63. package/js/tabs.js +200 -0
  64. package/js/theme/apply.js +75 -0
  65. package/js/theme/brand-contrast-audit.js +133 -0
  66. package/js/theme/color.js +149 -0
  67. package/js/theme/config-schema.js +40 -0
  68. package/js/theme/contrast.js +76 -0
  69. package/js/theme/export.js +118 -0
  70. package/js/theme/index.js +21 -0
  71. package/js/theme/overlay.js +29 -0
  72. package/js/theme/package.json +3 -0
  73. package/js/theme/palette.js +103 -0
  74. package/js/theme/radius.js +76 -0
  75. package/js/theme/semantic-mapper.js +138 -0
  76. package/js/theme/typography.js +33 -0
  77. package/js/theme/url-state.js +52 -0
  78. package/js/tooltip.js +227 -0
  79. package/package.json +139 -0
package/docs/llms.txt ADDED
@@ -0,0 +1,109 @@
1
+ # Design System Core
2
+
3
+ > Design system white-label em CSS puro com tokens DTCG em JSON, componentes documentados, modos light/dark e paleta brand única customizável. Versão atual: 1.0.0-beta.10.
4
+
5
+ Repositório: definir no ambiente de destino.
6
+ Site: documentação local
7
+ Arquivo completo para LLMs: docs/llms-full.txt
8
+ No pacote instalado: `ds-tis/metadata`, `ds-tis/metadata/components`, `ds-tis/metadata/tokens`, `ds-tis/agent-guide`, `ds-tis/agent-guide/en`, `ds-tis/llms` e `ds-tis/llms-full`.
9
+
10
+ ## Visão geral
11
+
12
+ - [Home](index.html): visão rápida, quick start e dark mode.
13
+ - [README](README.md): instalação e navegação.
14
+ - [Token Architecture](docs/token-architecture.html): arquitetura 3-layer (Foundation/Core → Semantic/System → Component).
15
+ - [Theming](docs/theming.html): como customizar brand e alternar modo.
16
+ - [Accessibility](docs/accessibility.html): WCAG 2.2 AA aplicada.
17
+ - [Design Principles](docs/design-principles.html): princípios do sistema.
18
+ - [Agent Consumer Usage](docs/agent-consumer-usage.html): como agents implementam telas em projetos consumidores usando o DS TIS.
19
+
20
+ ## Foundations
21
+
22
+ - [Colors](docs/foundations-colors.html)
23
+ - [Theme Colors](docs/foundations-theme-colors.html)
24
+ - [Typography](docs/foundations-typography.html)
25
+ - [Spacing](docs/foundations-spacing.html)
26
+ - [Radius](docs/foundations-radius.html)
27
+ - [Elevation](docs/foundations-elevation.html)
28
+ - [Borders](docs/foundations-borders.html)
29
+ - [Motion](docs/foundations-motion.html)
30
+ - [Opacity](docs/foundations-opacity.html)
31
+ - [Z-index](docs/foundations-zindex.html)
32
+
33
+ ## Components
34
+
35
+ - [Accordion](docs/accordion.html)
36
+ - [Button](docs/button.html)
37
+ - [Input Text](docs/input.html)
38
+ - [Textarea](docs/textarea.html)
39
+ - [Select](docs/select.html)
40
+ - [Combobox](docs/combobox.html)
41
+ - [Checkbox](docs/checkbox.html)
42
+ - [Radio](docs/radio.html)
43
+ - [Toggle](docs/toggle.html)
44
+ - [Badge](docs/badge.html)
45
+ - [Alert](docs/alert.html)
46
+ - [Card](docs/card.html)
47
+ - [Modal](docs/modal.html)
48
+ - [Tooltip](docs/tooltip.html)
49
+ - [Menu](docs/menu.html)
50
+ - [Tabs](docs/tabs.html)
51
+ - [Breadcrumb](docs/breadcrumb.html)
52
+ - [Pagination](docs/pagination.html)
53
+ - [Avatar](docs/avatar.html)
54
+ - [Divider](docs/divider.html)
55
+ - [Form Field](docs/form-field.html)
56
+ - [Spinner](docs/spinner.html)
57
+ - [Skeleton](docs/skeleton.html)
58
+
59
+ ## Decisões arquiteturais (ADRs)
60
+
61
+ - [ADR-001 — Migração da arquitetura de tokens para Foundation→Semantic→Component com DTCG + Style Dictionary](docs/decisions/adr-001-migracao-tokens.html) — Aceita — superseded em parte por ADR-014 (themes Default/Ocean/Forest removidos em 0.8.0; Brand virou paleta única customizável)
62
+ - [ADR-002 — Stack agnóstica — HTML + CSS + vanilla JS como base](docs/decisions/adr-002-stack-agnostica.html) — Aceita
63
+ - [ADR-003 — Figma como origem canônica de tokens, Git como consolidação](docs/decisions/adr-003-fontes-verdade.html) — Aceita — Revisada em 0.5.8
64
+ - [ADR-004 — WCAG 2.2 AA como padrão de acessibilidade](docs/decisions/adr-004-wcag.html) — Aceita — Implementada em 0.5.0
65
+ - [ADR-005 — Brand como camada foundation, estados explícitos no semantic, e limpeza tipográfica](docs/decisions/adr-005-brand-foundation-e-estados-explicitos.html) — Aceita — Implementada em 0.5.0 (fechamento formal em 0.5.2). Superseded por ADR-014: collection Brand (modes Default/Ocean/Forest) deletada em 0.8.0, Brand virou paleta única customizável dentro da Foundation.
66
+ - [ADR-006 — Tokens semânticos de controle para dimensões e tipografia compartilhadas entre controles interativos](docs/decisions/adr-006-semantic-control-tokens.html) — Parcialmente substituída — `size.control.*` e `space.control.padding-{x,y}.*` substituídos por escala `size.{xs..5xl}` + `space.{xs..2xl}` + `space.control.padding.10` em **ADR-015** (2026-04-26). O contrato público de anatomia dos componentes foi movido para tokens Component em **ADR-019** (2026-05-10). `typography.control.*` permanece vigente.
67
+ - [ADR-007 — Estabelecer sistema de cores toned com overlays coloridos e tokens semânticos toned](docs/decisions/adr-007-toned-color-system.html) — Aceita — Implementada em 0.5.0 (fechamento formal em 0.5.4, sincronização Figma completa em 0.5.6)
68
+ - [ADR-008 — Recalibração das paletas foundation `green` e `amber`](docs/decisions/adr-008-recalibracao-paletas-feedback.html) — Aceita — Implementada em 0.5.0
69
+ - [ADR-009 — Separação de `border.default` (decorativa) e `border.control` (funcional)](docs/decisions/adr-009-border-control-vs-decorative.html) — Aceita — Implementada em 0.5.0
70
+ - [ADR-010 — Remoção de `foundation.color.white` e `foundation.color.black` puros](docs/decisions/adr-010-abolir-white-black-puros.html) — Aceita — Implementada em 0.5.0
71
+ - [ADR-011 — Reestruturação do naming de tokens semânticos de cor](docs/decisions/adr-011-renaming-tokens-semanticos-de-cor.html) — Aceita — Implementada em 0.5.0
72
+ - [ADR-012 — Tokens de line-height e letter-spacing divergem por design entre Figma e JSON](docs/decisions/adr-012-typography-tokens-divergence.html) — Aceita
73
+ - [ADR-013 — Camadas de consumo de tokens — Foundation nunca direto em consumidor final](docs/decisions/adr-013-camadas-de-consumo-de-tokens.html) — Aceita — implementada em 0.7.0 e parcialmente substituída por ADR-019 em 2026-05-11
74
+ - [ADR-014 — Reestruturação Semantic em `action` × `style` × `prop` × `state` — eliminação de brand/accent e themes](docs/decisions/adr-014-action-tokens-role-style.html) — Aceita — implementada em 0.7.0 e estabilizada em 1.0.0-beta.1
75
+ - [ADR-015 — — Unificação da escala size, eliminação de tokens component-specific e renomeação spacing→dimension](docs/decisions/adr-015-unificacao-de-size-e-dimension.html) — Aceito
76
+ - [ADR-016 — — Tokens sem equivalência no Figma (CSS-only)](docs/decisions/adr-016-tokens-sem-equivalencia-no-figma.html) — Aceito
77
+ - [ADR-017 — — Componentes CSS-only (sem equivalência no Figma)](docs/decisions/adr-017-componentes-css-only.html) — Aceito
78
+ - [ADR-018 — — Renomear `content.{default,secondary,tertiary}` para `content.{strong,default,subtle}`](docs/decisions/adr-018-content-naming-strong-default-subtle.html) — Aceito
79
+ - [ADR-019 — — Reintrodução de Component tokens como contrato anatômico](docs/decisions/adr-019-component-tokens-contrato-anatomico.html) — Aceita
80
+ - [ADR-020 — Biblioteca consumível e contrato de readiness dos componentes](docs/decisions/adr-020-biblioteca-consumivel-componentes-app-ready.html) — Aceita
81
+
82
+ ## Processo
83
+
84
+ - [Contributing](docs/process-contributing.html): setup, fluxo de PR, convenções.
85
+ - [Versionamento](docs/process-versioning.html): releases 1.0.0-beta.N com cadência semanal durante beta.
86
+ - [Releases](docs/process-releasing.html): passo a passo.
87
+ - [Changelog](docs/changelog.html): histórico de versões.
88
+ - [Backlog](docs/backlog.html): itens fora do escopo imediato.
89
+
90
+ ## Marca
91
+
92
+ - [Brand Principles](docs/brand-principles.html): missão, princípios, tom de voz, identidade.
93
+
94
+ ## APIs JSON (consumo programático)
95
+
96
+ - [consumer-context.json](docs/api/consumer-context.json): manifesto pequeno com entrypoints, fontes e contrato responsivo intrinsic-first.
97
+ - [components.json](docs/api/components.json): catálogo de componentes com variantes, tokens, readiness, runtime e perfil responsivo.
98
+ - [tokens.json](docs/api/tokens.json): camadas Foundation, Semantic (light/dark) e Component.
99
+ - [adrs.json](docs/api/adrs.json): índice estruturado das decisões.
100
+ - [foundations.json](docs/api/foundations.json): catálogo das foundations.
101
+ - [tokens-sync.json](docs/api/tokens-sync.json): estado de coerência Figma ↔ JSON ↔ CSS.
102
+
103
+ ## Figma
104
+
105
+ - Arquivo: `IE68amP9Hya5ieFw1rX8S8` (TIS, acesso via convite).
106
+
107
+ ---
108
+
109
+ Gerado por `scripts/build-llms.mjs`. Versão atual: 1.0.0-beta.10.
@@ -0,0 +1,364 @@
1
+ <!DOCTYPE html>
2
+ <html lang="pt">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Contato — Design System</title>
7
+ <link rel="stylesheet" href="../../css/design-system.css">
8
+ <link rel="stylesheet" href="../layout.css">
9
+ <script>
10
+ (function(){var l=localStorage.getItem('ds-lang');if(l)document.documentElement.setAttribute('lang',l)})();
11
+ </script>
12
+ </head>
13
+ <body>
14
+
15
+ <header class="ds-site-header">
16
+ <div style="display:flex;align-items:center;gap:var(--ds-dimension-16)">
17
+ <button class="ds-menu-toggle" id="menu-toggle" aria-label="Toggle navigation" aria-expanded="false">
18
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
19
+ </button>
20
+ <a href="../../index.html" class="ds-site-header__brand" aria-label="TIS Design System">
21
+ <img class="ds-site-header__logo" src="../assets/logo-tis-mark.svg" alt="TIS" width="36" height="36">
22
+ <span class="ds-site-header__title ds-site-header__title--brand">TIS</span>
23
+ <span class="ds-site-header__brand-separator" aria-hidden="true"></span>
24
+ <span class="ds-site-header__title ds-site-header__title--product">Design System</span>
25
+ </a>
26
+ </div>
27
+ <div class="ds-site-header__actions">
28
+ <select class="ds-theme-switcher__select" id="lang-switcher" aria-label="Language">
29
+ <option value="pt">PT</option>
30
+ <option value="en">EN</option>
31
+ </select>
32
+ <button class="ds-button ds-button--ghost ds-button--sm" id="mode-toggle" aria-pressed="false" aria-label="Toggle dark mode"><svg class="ds-button__icon ds-site-header__mode-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path></svg><span class="ds-button__label">Dark</span></button>
33
+ </div>
34
+ </header>
35
+ <div class="ds-sidebar-overlay" id="sidebar-overlay"></div>
36
+
37
+ <nav class="ds-sidebar" id="sidebar" aria-label="Main navigation"></nav>
38
+
39
+ <main class="ds-main">
40
+
41
+ <!-- 1. HEADER -->
42
+ <div class="ds-section">
43
+ <h1 class="ds-section__title"><span data-lang="pt">Contato</span><span data-lang="en">Contact</span></h1>
44
+ <p class="ds-section__subtitle">
45
+ <span data-lang="pt">Formulário completo de contato com seleção de assunto via Select, textarea para mensagem, Radio group para prioridade, confirmação de envio via Alert e validação de campos obrigatórios.</span>
46
+ <span data-lang="en">Complete contact form with subject selection via Select, message textarea, Radio group for priority, submission confirmation via Alert, and required field validation.</span>
47
+ </p>
48
+ <div style="display:flex;flex-wrap:wrap;gap:var(--ds-dimension-8);margin-top:var(--ds-dimension-16)">
49
+ <span class="ds-badge ds-badge--neutral ds-badge--subtle">Input</span>
50
+ <span class="ds-badge ds-badge--neutral ds-badge--subtle">Textarea</span>
51
+ <span class="ds-badge ds-badge--neutral ds-badge--subtle">Select</span>
52
+ <span class="ds-badge ds-badge--neutral ds-badge--subtle">Radio</span>
53
+ <span class="ds-badge ds-badge--neutral ds-badge--subtle">Checkbox</span>
54
+ <span class="ds-badge ds-badge--neutral ds-badge--subtle">Alert</span>
55
+ <span class="ds-badge ds-badge--neutral ds-badge--subtle">Button</span>
56
+ </div>
57
+ </div>
58
+
59
+ <!-- 2. PREVIEW -->
60
+ <div class="ds-subsection">
61
+ <h2 class="ds-subsection__title">Preview</h2>
62
+ <div class="ds-preview">
63
+ <div class="ds-preview__tabs">
64
+ <button class="ds-preview__tab ds-preview__tab--active" data-tab="preview">Preview</button>
65
+ <button class="ds-preview__tab" data-tab="code">Code</button>
66
+ <button type="button" class="ds-button ds-button--ghost ds-button--sm ds-preview__action" onclick="openPreviewInNewTab()" aria-label="Abrir preview em nova aba"><svg class="ds-button__icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg><span class="ds-button__label">Abrir em nova aba</span></button>
67
+ </div>
68
+ <div class="ds-preview__canvas" style="padding:0;display:block">
69
+ <div style="background:var(--ds-background-subtle);padding:var(--ds-dimension-40);min-height:700px;display:flex;align-items:flex-start;justify-content:center">
70
+ <div style="width:100%;max-width:560px">
71
+
72
+ <!-- Success alert (post-submit state) -->
73
+ <div class="ds-alert ds-alert--success ds-alert--subtle" style="margin-bottom:var(--ds-dimension-24)" role="alert">
74
+ <div class="ds-alert__content">
75
+ <p class="ds-alert__title"><span data-lang="pt">Mensagem enviada!</span><span data-lang="en">Message sent!</span></p>
76
+ <span class="ds-alert__description">
77
+ <span data-lang="pt">Retornaremos em até 2 dias úteis para o e-mail informado.</span>
78
+ <span data-lang="en">We'll respond within 2 business days to the email provided.</span>
79
+ </span>
80
+ </div>
81
+ </div>
82
+
83
+ <div class="ds-card ds-card--outlined" style="padding:var(--ds-dimension-32)">
84
+
85
+ <h2 style="font-size:var(--ds-body-font-size-xl);font-weight:var(--ds-body-font-weight-bold);color:var(--ds-content-strong);margin:0 0 var(--ds-dimension-4)">
86
+ <span data-lang="pt">Fale conosco</span><span data-lang="en">Get in touch</span>
87
+ </h2>
88
+ <p style="font-size:var(--ds-body-font-size-md);color:var(--ds-content-default);margin:0 0 var(--ds-dimension-24)">
89
+ <span data-lang="pt">Preencha o formulário e nossa equipe entrará em contato.</span>
90
+ <span data-lang="en">Fill in the form and our team will get back to you.</span>
91
+ </p>
92
+
93
+ <form novalidate>
94
+
95
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--ds-dimension-16);margin-bottom:var(--ds-dimension-16)">
96
+ <div class="ds-field">
97
+ <div class="ds-field__label-row">
98
+ <label class="ds-field__label" for="ct-name"><span data-lang="pt">Nome</span><span data-lang="en">Name</span></label>
99
+ <span class="ds-field__required" aria-hidden="true">*</span>
100
+ </div>
101
+ <div class="ds-input ds-input--lg">
102
+ <input class="ds-input__field" type="text" id="ct-name" autocomplete="given-name" required>
103
+ </div>
104
+ </div>
105
+ <div class="ds-field">
106
+ <div class="ds-field__label-row">
107
+ <label class="ds-field__label" for="ct-email">E-mail</label>
108
+ <span class="ds-field__required" aria-hidden="true">*</span>
109
+ </div>
110
+ <div class="ds-input ds-input--lg">
111
+ <input class="ds-input__field" type="email" id="ct-email" placeholder="seu@email.com" autocomplete="email" required>
112
+ </div>
113
+ </div>
114
+ </div>
115
+
116
+ <div class="ds-field" style="margin-bottom:var(--ds-dimension-16)">
117
+ <div class="ds-field__label-row">
118
+ <label class="ds-field__label" for="ct-subject"><span data-lang="pt">Assunto</span><span data-lang="en">Subject</span></label>
119
+ <span class="ds-field__required" aria-hidden="true">*</span>
120
+ </div>
121
+ <div class="ds-select ds-select--lg">
122
+ <select class="ds-select__field" id="ct-subject" required>
123
+ <option value="">Selecione um assunto...</option>
124
+ <option>Dúvida técnica</option>
125
+ <option>Proposta comercial</option>
126
+ <option>Parceria</option>
127
+ <option>Outro</option>
128
+ </select>
129
+ <span class="ds-select__arrow" aria-hidden="true"></span>
130
+ </div>
131
+ </div>
132
+
133
+ <div class="ds-field" style="margin-bottom:var(--ds-dimension-16)">
134
+ <div class="ds-field__label-row">
135
+ <label class="ds-field__label" for="ct-message"><span data-lang="pt">Mensagem</span><span data-lang="en">Message</span></label>
136
+ <span class="ds-field__required" aria-hidden="true">*</span>
137
+ </div>
138
+ <div class="ds-textarea">
139
+ <textarea class="ds-textarea__field" id="ct-message" rows="5" placeholder="Descreva sua solicitação com detalhes..." required></textarea>
140
+ </div>
141
+ <span class="ds-field__helper"><span data-lang="pt">Quanto mais detalhes, mais rápido poderemos ajudar.</span><span data-lang="en">The more details you provide, the faster we can help.</span></span>
142
+ </div>
143
+
144
+ <!-- Priority radio group -->
145
+ <fieldset style="border:none;padding:0;margin:0 0 var(--ds-dimension-24)">
146
+ <legend style="font-size:var(--ds-body-font-size-sm);font-weight:var(--ds-body-font-weight-medium);color:var(--ds-content-strong);margin-bottom:var(--ds-dimension-12)">
147
+ <span data-lang="pt">Prioridade</span><span data-lang="en">Priority</span>
148
+ </legend>
149
+ <div style="display:flex;gap:var(--ds-dimension-24)">
150
+ <label class="ds-radio-label">
151
+ <input class="ds-radio" type="radio" name="priority" value="low">
152
+ <span class="ds-radio__content">
153
+ <span class="ds-radio__label"><span data-lang="pt">Baixa</span><span data-lang="en">Low</span></span>
154
+ </span>
155
+ </label>
156
+ <label class="ds-radio-label">
157
+ <input class="ds-radio" type="radio" name="priority" value="medium" checked>
158
+ <span class="ds-radio__content">
159
+ <span class="ds-radio__label"><span data-lang="pt">Média</span><span data-lang="en">Medium</span></span>
160
+ </span>
161
+ </label>
162
+ <label class="ds-radio-label">
163
+ <input class="ds-radio" type="radio" name="priority" value="high">
164
+ <span class="ds-radio__content">
165
+ <span class="ds-radio__label"><span data-lang="pt">Alta</span><span data-lang="en">High</span></span>
166
+ </span>
167
+ </label>
168
+ </div>
169
+ </fieldset>
170
+
171
+ <!-- Terms checkbox -->
172
+ <label class="ds-checkbox-label" style="margin-bottom:var(--ds-dimension-32)">
173
+ <input class="ds-checkbox" type="checkbox" id="ct-privacy" required>
174
+ <span class="ds-checkbox__content">
175
+ <span class="ds-checkbox__label">
176
+ <span data-lang="pt">Concordo com a <a class="ds-link" href="#">Política de privacidade</a> e autorizo o contato por e-mail.</span>
177
+ <span data-lang="en">I agree to the <a class="ds-link" href="#">Privacy policy</a> and authorize contact by email.</span>
178
+ </span>
179
+ </span>
180
+ </label>
181
+
182
+ <button class="ds-button ds-button--brand ds-button--lg ds-button--full" type="submit">
183
+ <span class="ds-button__label"><span data-lang="pt">Enviar mensagem</span><span data-lang="en">Send message</span></span>
184
+ </button>
185
+
186
+ </form>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </div>
191
+ <div class="ds-preview__code" style="display:none">
192
+ <button class="ds-preview__copy">Copy</button>
193
+ <pre tabindex="0"><code>&lt;!DOCTYPE html&gt;
194
+ &lt;html lang="pt-BR"&gt;
195
+ &lt;head&gt;
196
+ &lt;meta charset="UTF-8"&gt;
197
+ &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
198
+ &lt;title&gt;Contato&lt;/title&gt;
199
+ &lt;link rel="stylesheet" href="css/design-system.css"&gt;
200
+ &lt;style&gt;
201
+ *, *::before, *::after { box-sizing: border-box; }
202
+ body { background: var(--ds-background-subtle); min-height: 100vh; margin: 0; display: flex; align-items: flex-start; justify-content: center; padding: var(--ds-dimension-40); }
203
+ .contact-card { background: var(--ds-surface-default); border-radius: var(--ds-radius-lg); padding: var(--ds-dimension-32); width: 100%; max-width: 560px; border: 1px solid var(--ds-border-default); }
204
+ .contact-name-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ds-dimension-16); margin-bottom: var(--ds-dimension-16); }
205
+ @media (max-width: 540px) { .contact-name-row { grid-template-columns: 1fr; } body { padding: var(--ds-dimension-16); } }
206
+ &lt;/style&gt;
207
+ &lt;/head&gt;
208
+ &lt;body&gt;
209
+
210
+ &lt;div style="width:100%;max-width:560px"&gt;
211
+
212
+ &lt;!-- Show this alert after successful submission --&gt;
213
+ &lt;div class="ds-alert ds-alert--success ds-alert--subtle" style="margin-bottom:var(--ds-dimension-24);display:none" role="alert" id="success-alert"&gt;
214
+ &lt;div class="ds-alert__content"&gt;
215
+ &lt;p class="ds-alert__title"&gt;Mensagem enviada!&lt;/p&gt;
216
+ &lt;span class="ds-alert__description"&gt;Retornaremos em até 2 dias úteis.&lt;/span&gt;
217
+ &lt;/div&gt;
218
+ &lt;/div&gt;
219
+
220
+ &lt;div class="contact-card"&gt;
221
+ &lt;h1 style="font-size:var(--ds-body-font-size-xl);font-weight:var(--ds-body-font-weight-bold);color:var(--ds-content-strong);margin:0 0 var(--ds-dimension-4)"&gt;Fale conosco&lt;/h1&gt;
222
+ &lt;p style="font-size:var(--ds-body-font-size-md);color:var(--ds-content-default);margin:0 0 var(--ds-dimension-24)"&gt;Preencha o formulário e nossa equipe entrará em contato.&lt;/p&gt;
223
+
224
+ &lt;form id="contact-form" novalidate&gt;
225
+
226
+ &lt;div class="contact-name-row"&gt;
227
+ &lt;div class="ds-field"&gt;
228
+ &lt;div class="ds-field__label-row"&gt;
229
+ &lt;label class="ds-field__label" for="name"&gt;Nome&lt;/label&gt;
230
+ &lt;span class="ds-field__required" aria-hidden="true"&gt;*&lt;/span&gt;
231
+ &lt;/div&gt;
232
+ &lt;div class="ds-input ds-input--lg"&gt;
233
+ &lt;input class="ds-input__field" type="text" id="name" autocomplete="given-name" required&gt;
234
+ &lt;/div&gt;
235
+ &lt;/div&gt;
236
+ &lt;div class="ds-field"&gt;
237
+ &lt;div class="ds-field__label-row"&gt;
238
+ &lt;label class="ds-field__label" for="email"&gt;E-mail&lt;/label&gt;
239
+ &lt;span class="ds-field__required" aria-hidden="true"&gt;*&lt;/span&gt;
240
+ &lt;/div&gt;
241
+ &lt;div class="ds-input ds-input--lg"&gt;
242
+ &lt;input class="ds-input__field" type="email" id="email" placeholder="seu@email.com" autocomplete="email" required&gt;
243
+ &lt;/div&gt;
244
+ &lt;/div&gt;
245
+ &lt;/div&gt;
246
+
247
+ &lt;div class="ds-field" style="margin-bottom:var(--ds-dimension-16)"&gt;
248
+ &lt;div class="ds-field__label-row"&gt;
249
+ &lt;label class="ds-field__label" for="subject"&gt;Assunto&lt;/label&gt;
250
+ &lt;span class="ds-field__required" aria-hidden="true"&gt;*&lt;/span&gt;
251
+ &lt;/div&gt;
252
+ &lt;div class="ds-select ds-select--lg"&gt;
253
+ &lt;select class="ds-select__field" id="subject" required&gt;
254
+ &lt;option value=""&gt;Selecione um assunto...&lt;/option&gt;
255
+ &lt;option&gt;Dúvida técnica&lt;/option&gt;
256
+ &lt;option&gt;Proposta comercial&lt;/option&gt;
257
+ &lt;option&gt;Parceria&lt;/option&gt;
258
+ &lt;option&gt;Outro&lt;/option&gt;
259
+ &lt;/select&gt;
260
+ &lt;span class="ds-select__arrow" aria-hidden="true"&gt;&lt;/span&gt;
261
+ &lt;/div&gt;
262
+ &lt;/div&gt;
263
+
264
+ &lt;div class="ds-field" style="margin-bottom:var(--ds-dimension-16)"&gt;
265
+ &lt;div class="ds-field__label-row"&gt;
266
+ &lt;label class="ds-field__label" for="message"&gt;Mensagem&lt;/label&gt;
267
+ &lt;span class="ds-field__required" aria-hidden="true"&gt;*&lt;/span&gt;
268
+ &lt;/div&gt;
269
+ &lt;div class="ds-textarea"&gt;
270
+ &lt;textarea class="ds-textarea__field" id="message" rows="5" required&gt;&lt;/textarea&gt;
271
+ &lt;/div&gt;
272
+ &lt;span class="ds-field__helper"&gt;Quanto mais detalhes, mais rápido poderemos ajudar.&lt;/span&gt;
273
+ &lt;/div&gt;
274
+
275
+ &lt;fieldset style="border:none;padding:0;margin:0 0 var(--ds-dimension-24)"&gt;
276
+ &lt;legend style="font-size:var(--ds-body-font-size-sm);font-weight:var(--ds-body-font-weight-medium);color:var(--ds-content-strong);margin-bottom:var(--ds-dimension-12)"&gt;Prioridade&lt;/legend&gt;
277
+ &lt;div style="display:flex;gap:var(--ds-dimension-24)"&gt;
278
+ &lt;label class="ds-radio-label"&gt;
279
+ &lt;input class="ds-radio" type="radio" name="priority" value="low"&gt;
280
+ &lt;span class="ds-radio__content"&gt;&lt;span class="ds-radio__label"&gt;Baixa&lt;/span&gt;&lt;/span&gt;
281
+ &lt;/label&gt;
282
+ &lt;label class="ds-radio-label"&gt;
283
+ &lt;input class="ds-radio" type="radio" name="priority" value="medium" checked&gt;
284
+ &lt;span class="ds-radio__content"&gt;&lt;span class="ds-radio__label"&gt;Média&lt;/span&gt;&lt;/span&gt;
285
+ &lt;/label&gt;
286
+ &lt;label class="ds-radio-label"&gt;
287
+ &lt;input class="ds-radio" type="radio" name="priority" value="high"&gt;
288
+ &lt;span class="ds-radio__content"&gt;&lt;span class="ds-radio__label"&gt;Alta&lt;/span&gt;&lt;/span&gt;
289
+ &lt;/label&gt;
290
+ &lt;/div&gt;
291
+ &lt;/fieldset&gt;
292
+
293
+ &lt;label class="ds-checkbox-label" style="margin-bottom:var(--ds-dimension-32)"&gt;
294
+ &lt;input class="ds-checkbox" type="checkbox" id="privacy" required&gt;
295
+ &lt;span class="ds-checkbox__content"&gt;
296
+ &lt;span class="ds-checkbox__label"&gt;
297
+ Concordo com a &lt;a class="ds-link" href="/privacy"&gt;Política de privacidade&lt;/a&gt;
298
+ &lt;/span&gt;
299
+ &lt;/span&gt;
300
+ &lt;/label&gt;
301
+
302
+ &lt;button class="ds-button ds-button--brand ds-button--lg ds-button--full" type="submit"&gt;
303
+ &lt;span class="ds-button__label"&gt;Enviar mensagem&lt;/span&gt;
304
+ &lt;/button&gt;
305
+
306
+ &lt;/form&gt;
307
+ &lt;/div&gt;
308
+ &lt;/div&gt;
309
+
310
+ &lt;script&gt;
311
+ document.getElementById('contact-form').addEventListener('submit', function (e) {
312
+ e.preventDefault();
313
+ // Replace with your form submission logic
314
+ document.getElementById('success-alert').style.display = '';
315
+ this.reset();
316
+ window.scrollTo({ top: 0, behavior: 'smooth' });
317
+ });
318
+ &lt;/script&gt;
319
+
320
+ &lt;/body&gt;
321
+ &lt;/html&gt;</code></pre>
322
+ </div>
323
+ </div>
324
+ </div>
325
+
326
+ <!-- 3. USAGE -->
327
+ <div class="ds-subsection">
328
+ <h2 class="ds-subsection__title"><span data-lang="pt">Notas de uso</span><span data-lang="en">Usage notes</span></h2>
329
+ <table class="ds-token-table">
330
+ <thead><tr><th><span data-lang="pt">Padrão</span><span data-lang="en">Pattern</span></th><th><span data-lang="pt">Decisão</span><span data-lang="en">Decision</span></th></tr></thead>
331
+ <tbody>
332
+ <tr><td><code>&lt;fieldset&gt;</code> + <code>&lt;legend&gt;</code> <span data-lang="pt">no Radio group</span><span data-lang="en">for Radio group</span></td><td><span data-lang="pt">Semântica nativa de agrupamento — screen readers anunciam a pergunta antes de cada opção, sem JavaScript adicional.</span><span data-lang="en">Native grouping semantics — screen readers announce the question before each option, without additional JavaScript.</span></td></tr>
333
+ <tr><td><span data-lang="pt">Alert de sucesso oculto inicialmente</span><span data-lang="en">Success alert hidden initially</span></td><td><span data-lang="pt">O alert de confirmação é renderizado no DOM mas oculto (<code>display:none</code>). Exiba-o via JS após o envio e use <code>role="alert"</code> para anúncio automático em leitores de tela.</span><span data-lang="en">The confirmation alert is rendered in the DOM but hidden (<code>display:none</code>). Show it via JS after submission and use <code>role="alert"</code> for automatic screen reader announcement.</span></td></tr>
334
+ <tr><td><span data-lang="pt">Textarea com ds-field__helper</span><span data-lang="en">Textarea with ds-field__helper</span></td><td><span data-lang="pt">O texto auxiliar abaixo da textarea define a expectativa de qualidade antes do erro — reduz reenvios por mensagens incompletas.</span><span data-lang="en">Helper text below the textarea sets quality expectations before the error — reduces resubmissions due to incomplete messages.</span></td></tr>
335
+ </tbody>
336
+ </table>
337
+ </div>
338
+
339
+ <!-- 4. RELATED -->
340
+ <div class="ds-subsection">
341
+ <h2 class="ds-subsection__title"><span data-lang="pt">Templates relacionados</span><span data-lang="en">Related templates</span></h2>
342
+ <div class="ds-related">
343
+ <a href="login.html" class="ds-related__link">Login</a>
344
+ <a href="signup.html" class="ds-related__link"><span data-lang="pt">Cadastro</span><span data-lang="en">Sign Up</span></a>
345
+ <a href="index.html" class="ds-related__link"><span data-lang="pt">Ver todos os templates</span><span data-lang="en">All templates</span></a>
346
+ </div>
347
+ </div>
348
+
349
+ </main>
350
+
351
+ <script src="../../js/main.js"></script>
352
+ <script>
353
+ function openPreviewInNewTab() {
354
+ var code = document.querySelector('.ds-preview__code pre code').textContent;
355
+ var cssUrl = new URL('../../css/design-system.css', window.location.href).href;
356
+ var html = code.replace(/"css\/design-system\.css"/, '"' + cssUrl + '"');
357
+ var blob = new Blob([html], { type: 'text/html' });
358
+ var url = URL.createObjectURL(blob);
359
+ window.open(url, '_blank');
360
+ setTimeout(function() { URL.revokeObjectURL(url); }, 30000);
361
+ }
362
+ </script>
363
+ </body>
364
+ </html>