# Sistema de design Duet

## Prévia da interface sistema de design Duet

Defina as datas de ida e volta, teste um intervalo inválido e calcule a quantidade de dias, incluindo as datas inicial e final.

## Sistema de design Duet Referência de design

Snapshot da documentação pública do Duet: principais componentes do sistema, tokens padrão do LocalTapiola e integração documentada com 10.7.0/CDN. Este não é o pacote separado @duetds/date-picker 1.x. Alguns tokens de raio continuam marcados como Em análise.

### Papéis padrão e da Turva

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| --color-primary | #0077b3 | Ação do LocalTapiola. |
| --color-primary-dark | #004b81 | Estado interativo mais escuro. |
| --color-primary-darker | #00619b | Papel de link. |
| --color-primary-light | #c6e1ee | Tonalidade da faixa. |
| --color-secondary | #082a4d | Texto do corpo. |
| --color-primary-turva | #e61740 | Ação da Turva, tema separado. |
| --color-danger | #d61c52 | Validação. |
| --radius-default | 4px | Campos e contêineres. |
| --radius-pill | 20rem | Botões. |
| --radius-medium | 8px; In Review | Não considere pronto para produção. |
### Tokens de espaçamento

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| --space-xxx-small | 2px | Estreito. |
| --space-xx-small | 4px | Estreito. |
| --space-x-small | 8px | Compacto. |
| --space-small | 12px | Pequeno. |
| --space-medium | 16px | Padrão. |
| --space-large | 20px | Entre componentes. |
| --space-x-large | 28px | Espaçamento maior. |
| --space-xx-large | 36px | Preenchimento horizontal do botão. |
| --space-xxx-large | 48px | Seção. |
| --size-layout-max-width | 1110px | Máximo de layout documentado. |
### Escala tipográfica

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| $font-size-medium | 16px / 1rem | Corpo e H5. |
| $font-size-large | 20px / 1.25rem | H4. |
| $font-size-x-large | 24px / 1.5rem | H3. |
| $font-size-xx-large | 36px / 2.25rem | H2. |
| $font-size-xxx-large | 48px / 3rem | H1. |
| $font-size-xxxx-large | 72px / 4.5rem | H0. |
### Contrato do Date Picker

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| value / min / max | YYYY-MM-DD strings | O armazenamento usa ISO, não o texto exibido. |
| duetChange | detail.value and detail.valueAsDate | Evento de data selecionada. |
| validity | badInput / valueMissing / rangeOverflow / rangeUnderflow / customError | Inspecione antes de aceitar. |
| setFocus() | Promise<void> | Foca o campo de entrada; não usa focus() no elemento hospedeiro. |
| show() / hide() | Promise<void> | Calendário e gerenciamento de foco. |
| language | Deprecated | Use html lang. |
| disallow-weekends | Boolean | Exclusão no nível do componente. |
### Propriedades do botão de ação

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| variation="primary" | Main action | Uma ação principal por tela. |
| submit | Boolean, default false | Ativação explícita do envio do formulário. |
| url | Anchor destination | Semântica de navegação. |
| expand | 100% container | Ação ampla. |
| theme | default / turva / inherited empty | Seleção da marca. |
| margin="none" | Remove automatic margin | O aplicativo controla o espaçamento. |
## Sistema de design Duet Guia completo

Um guia prático para escolher, aplicar e avaliar este sistema em uma interface real.

Orientações completas, um ponto de partida para a implementação e links para o código-fonte.

## Sistema de design Duet O sistema principal do Duet e o seletor de código aberto são separados

### Mantenha o contrato do pacote associado ao exemplo

> O Duet atende ao LocalTapiola e à Turva com componentes temáticos e fundamentos. O projeto @duetds/date-picker, publicado separadamente, é uma distribuição de código aberto mais restrita. O fato de compartilharem o nome da tag não torna intercambiáveis suas propriedades, configurações de localização ou variáveis CSS com o sistema de design principal atual.

O código de integração desta página tem como alvo o sistema principal. Sua prévia offline usa campos de data nativos e estilos originais baseados nos tokens do Duet vinculados. Ela demonstra regras de intervalo sem alegar executar o pop-up de calendário do Duet ou seu modelo de teclado.

Consulte a especificação de apoio

## Sistema de design Duet O azul da marca e o vermelho de status têm funções distintas

### Use um tema em vez de trocar uma única cor de destaque

O tema padrão do LocalTapiola combina uma ação azul com texto do corpo em azul-escuro. A Turva tem sua própria ação vermelha e um papel de texto secundário. Trocar apenas a cor da ação deixaria de fora as demais relações do tema. A tabela atual também marca como obsoletas as tonalidades antigas da Turva; copiar todas as entradas históricas da paleta perpetuaria orientações ultrapassadas.

Nosso exemplo original de datas de viagem usa azul para a próxima ação e vermelho apenas quando é preciso corrigir um período escolhido. É uma demonstração de agendamento, não uma recomendação, cotação ou compra de seguro.

Consulte a especificação de apoio

## Sistema de design Duet O corpo de 16px serve de base para a hierarquia

### A escala não exige um título enorme em todas as situações

Nos níveis maiores, a tabela do Duet avança por 16, 20, 24, 36, 48 e 72px. Um painel de planejamento incorporado usa o nível de 24px para manter em destaque a ação e os rótulos das datas. O nível de 72px, próprio para marketing, não é o padrão de um formulário compacto.

Os pacotes de fontes do LocalTapiola e da Turva são recursos separados. A interpretação offline usa uma fonte alternativa do sistema; ela não inclui os arquivos das fontes das marcas. Um aplicativo autorizado deve carregar a família escolhida pelo caminho de fontes documentado e, em seguida, usar os tokens de peso correspondentes.

Consulte a especificação de apoio

## Sistema de design Duet Use os intervalos reais de 20px e 28px

### O Duet não usa uma escala genérica de oito pixels

Além das potências de dois mais conhecidas, a escala inclui 12, 20, 28 e 36px. Esses intervalos intermediários são importantes para reproduzir o ritmo dos formulários do sistema. Use o espaçamento de 20px entre os dois campos no layout amplo e, ao empilhá-los, mantenha cada rótulo junto ao respectivo campo. O ponto de quebra do exemplo é uma escolha do aplicativo.

Os cantos dos controles padrão usam raio de 4px, enquanto os botões usam raio em formato de pílula. Alguns valores mais recentes de raio para contêineres na referência de tokens estão explicitamente marcados como Em análise; este guia mantém esse status em vez de apresentar todos os tokens listados como aprovados.

Consulte a especificação de apoio

## Sistema de design Duet Armazene valores ISO e descreva o formato visível

### Não interprete textos localizados exibidos como dados

O valor e os limites do componente usam YYYY-MM-DD. O evento de data selecionada inclui uma string e um objeto Date. Use a string para comparação e armazenamento; a exibição localizada do campo é uma questão de apresentação. O idioma do documento é o ponto de entrada atual para a localização, enquanto a propriedade antiga de idioma está obsoleta.

O exemplo permite datas apenas durante junho de 2027. Esse intervalo fixo torna os testes determinísticos e é claramente uma restrição do exemplo. Em um formulário de produção, o intervalo permitido deve ser definido pela regra do produto, que também deve ser explicada junto ao campo.

Consulte a especificação de apoio

## Sistema de design Duet Uma data válida não significa necessariamente um intervalo válido

### Verifique a relação entre as datas quando cada campo for válido

O objeto de validade do componente descreve erros de campos individuais. Uma data de retorno anterior à partida ainda pode ser uma data válida no calendário; por isso, o aplicativo deve verificar o par separadamente. O exemplo nativo atribui um erro claro e usa setFocus(), o método documentado que direciona o foco para o campo de entrada interno.

A contagem é inclusiva: partida e retorno no mesmo dia correspondem a um dia de calendário. Converter datas ISO para meia-noite UTC evita que uma mudança de horário de verão transforme um intervalo de calendário em uma duração fracionária. Esse cálculo é uma lógica original do aplicativo, não uma regra de preços do Duet.

1. Rejeite datas de início ou término ausentes, malformadas ou fora dos limites.

2. Rejeite uma data de retorno anterior à partida.

3. Mova o foco para o campo que precisa de correção.

4. Prepare o intervalo inclusivo somente depois que ambas as verificações forem aprovadas.

Consulte a especificação de apoio

## Sistema de design Duet A ação principal não implica envio

### O Duet usa uma propriedade explícita de envio

O botão do sistema principal ativa o envio do formulário com submit; o valor padrão é false. A composição fornecida usa uma ação de clique que prepara um resultado local, portanto não precisa dessa propriedade. Um destino deve ser definido em url, que gera semântica de âncora.

A prévia limpa a mensagem preparada sempre que um dos campos é alterado. Caso contrário, a mensagem poderia parecer confirmar valores que a pessoa já substituiu. Nenhum indicador de carregamento é exibido porque não há uma operação assíncrona.

- Use uma única ação principal para preparar o resultado.

- Informe que o resultado é local.

- Não reutilize uma mensagem de sucesso para sugerir a criação de uma apólice.

Consulte a especificação de apoio

## Sistema de design Duet Fixe os recursos do sistema principal como um conjunto compatível

### O exemplo é um registro documentado, não uma promessa de que seja a versão mais recente

A página de uso consultada fornece os componentes 10.7.0 com CSS 5.1.4; os registros do índice de pesquisa já mencionam versões posteriores. O exemplo mantém deliberadamente juntos o par consultado diretamente. Para adoção em produção, selecione uma versão e verifique se CSS, as fontes e o comportamento dos componentes são compatíveis.

Os campos de data são elementos personalizados. Aguarde a definição deles antes de chamar métodos, adicione ouvintes a duetChange e leia os dados documentados, sem presumir que se trate de um evento change nativo. Não misture o módulo CDN do sistema principal com o seletor independente na mesma página: ambos definem a mesma tag.

Consulte a especificação de apoio

## Sistema de design Duet Exemplos de componentes do sistema de design

### Exemplo interativo completo e independente

Salve o documento completo como index.html e abra-o em um navegador. Interpretação offline de HTML com campos de data nativos e valores verificados do tema padrão do Duet; não é o ambiente de execução do calendário do Duet.

```
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Duet travel period interpretation</title><style>*{box-sizing:border-box}body{margin:0;background:#f0f7fa;color:#082a4d;font:16px/1.5 system-ui,sans-serif}main{max-width:1000px;margin:auto;padding:36px 28px}.eyebrow{font-size:12px;letter-spacing:2px;text-transform:uppercase;margin-bottom:12px}h1{font-size:36px;line-height:1.2;font-weight:600;margin:0 0 20px}p{margin:0 0 20px}.hero{display:grid;grid-template-columns:1fr 300px;gap:28px;align-items:center;margin-bottom:28px}.art{height:170px;position:relative;overflow:hidden;border-radius:50%;background:#c6e1ee}.sun{position:absolute;top:25px;right:60px;width:36px;height:36px;border-radius:50%;background:white}.hill{position:absolute;background:#0077b3;width:210px;height:170px;bottom:-95px;left:-10px;transform:rotate(25deg);border-radius:24px}.hill.two{left:135px;background:#00619b;bottom:-110px;transform:rotate(-25deg)}.road{position:absolute;width:150px;height:200px;border:12px solid white;border-radius:50%;top:65px;left:95px;transform:rotate(25deg)}.card{background:white;border-radius:4px;padding:28px;box-shadow:0 2px 8px #082a4d0d;display:grid;grid-template-columns:1fr 230px;gap:28px}h2{font-size:24px;line-height:1.3;margin:0 0 20px}.fields{display:grid;grid-template-columns:1fr 1fr;gap:20px}label{display:block;font-weight:600;margin-bottom:8px}input{width:100%;max-width:100%;min-width:0;border:1px solid #909599;border-radius:4px;font:inherit;color:inherit;padding:12px;background:white}input[aria-invalid=true]{border-color:#d61c52}button{background:#0077b3;color:white;border:0;border-radius:20rem;padding:12px 36px;font:600 16px/1.5 system-ui;cursor:pointer}button:hover{background:#004b81}button:focus-visible,input:focus-visible{outline:3px solid #082a4d;outline-offset:3px}.error{font-size:14px;color:#d61c52;min-height:24px;margin:8px 0 20px}.calendar{background:#f0f7fa;border-radius:4px;padding:20px}.calendar strong{display:block;margin-bottom:12px}.grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;font-size:12px;text-align:center}.grid span{padding:3px 0}.grid .in-range{background:#c6e1ee}.grid .endpoint{background:#0077b3;color:white;border-radius:50%}.caption{font-size:12px;margin:12px 0 0}.result{margin-top:20px;background:#e4f1f7;padding:20px;border-radius:4px}.result:empty{display:none}.boundary{font-size:12px;margin-top:28px}.hint{font-size:14px}@media(max-width:650px){main{padding:24px 16px}.hero{grid-template-columns:1fr}.art{display:none}h1{font-size:28px}.card{grid-template-columns:1fr;padding:20px}.fields{grid-template-columns:1fr;gap:16px}.calendar{max-width:300px;width:100%}button{width:100%;padding:12px 20px}}
</style><main><div class="hero"><div><div class="eyebrow">Travel period planner</div><h1>Make time for a change of scenery.</h1><p>Choose a departure and return date to explore an inclusive calendar-day count.</p></div><div class="art" aria-hidden="true"><div class="sun"></div><div class="hill"></div><div class="hill two"></div><div class="road"></div></div></div><div class="card"><section><h2>When will you travel?</h2><p class="hint" id="hint">Use dates from 1–30 June 2027. This fixed month is for demonstration.</p><form novalidate><div class="fields"><div><label for="start">Departure</label><input id="start" type="date" min="2027-06-01" max="2027-06-30" value="2027-06-10" required aria-describedby="hint error"></div><div><label for="end">Return</label><input id="end" type="date" min="2027-06-01" max="2027-06-30" value="2027-06-17" required aria-describedby="hint error"></div></div><div class="error" id="error" role="alert"></div><button type="submit">Prepare date range</button></form></section><aside class="calendar"><strong>June 2027</strong><div class="grid" id="calendar" aria-hidden="true"></div><p class="caption" id="range-caption">10–17 June selected</p></aside></div><div class="result" id="result" role="status"></div><p class="boundary">Independent HTML interpretation of Duet tokens with native date fields. The calendar image is a non-interactive range overview. No insurance quote, booking or policy is created.</p></main><script>const start=document.querySelector('#start'),end=document.querySelector('#end'),result=document.querySelector('#result'),error=document.querySelector('#error');function valid(){return start.validity.valid&&end.validity.valid&&start.value&&end.value&&end.value>=start.value}function draw(){let days=['M','T','W','T','F','S','S'].map(d=>'<span>'+d+'</span>').join('')+'<span></span>';for(let i=1;i<=30;i++){let iso='2027-06-'+String(i).padStart(2,'0'),range=valid()&&iso>=start.value&&iso<=end.value,edge=range&&(iso===start.value||iso===end.value);days+='<span class="'+(edge?'endpoint':range?'in-range':'')+'">'+i+'</span>'}document.querySelector('#calendar').innerHTML=days;document.querySelector('#range-caption').textContent=valid()?start.value+' to '+end.value:'Choose a valid range to highlight it.'}function changed(){result.textContent='';error.textContent='';start.removeAttribute('aria-invalid');end.removeAttribute('aria-invalid');draw()}[start,end].forEach(el=>el.oninput=changed);document.querySelector('form').onsubmit=e=>{e.preventDefault();let bad;if(!start.value||!start.validity.valid){error.textContent='Choose a departure date in June 2027.';bad=start}else if(!end.value||!end.validity.valid){error.textContent='Choose a return date in June 2027.';bad=end}else if(end.value<start.value){error.textContent='Return must be on or after departure.';bad=end}if(bad){bad.setAttribute('aria-invalid','true');bad.focus();result.textContent='';return}const days=(Date.parse(end.value+'T00:00:00Z')-Date.parse(start.value+'T00:00:00Z'))/86400000+1;result.textContent=days+' calendar '+(days===1?'day':'days')+', including departure and return. Local draft: '+start.value+' to '+end.value+'. No policy created.'};draw();</script></html>
```

Referência de código

- Este documento usa controles de data nativos do navegador. O exemplo separado do Duet usa o seletor do sistema principal; ele não deve ser confundido com o pacote independente de seletor de datas de código aberto.

### Valide um par de seletores de data do sistema principal

Dois campos identificados, datas de junho dentro dos limites, extremos em ordem, foco no seletor inválido e contagem inclusiva de dias.

```
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Date range draft</title>
<link rel="stylesheet" href="https://cdn.duetds.com/api/css/5.1.4/lib/duet.min.css">
<script type="module" src="https://cdn.duetds.com/api/components/10.7.0/lib/duet/duet.esm.js"></script>
<style>main{max-width:680px;margin:auto;padding:28px}.range{display:grid;grid-template-columns:1fr 1fr;gap:20px}@media(max-width:576px){.range{grid-template-columns:1fr}}</style>
<main><h1>Choose a travel period</h1><p>Demonstration only. No insurance is quoted or purchased.</p><div class="range">
<duet-date-picker id="start" label="Departure" required expand value="2027-06-10" min="2027-06-01" max="2027-06-30"></duet-date-picker>
<duet-date-picker id="end" label="Return" required expand value="2027-06-17" min="2027-06-01" max="2027-06-30"></duet-date-picker></div>
<duet-button id="prepare" variation="primary">Prepare date range</duet-button>
<p id="result" role="status"></p></main><script type="module">
await customElements.whenDefined('duet-date-picker');
const start=document.querySelector('#start'),end=document.querySelector('#end'),result=document.querySelector('#result');
function error(picker){const v=picker.validity;if(!picker.value)return 'Choose a date.';if(v&&!v.valid)return 'Choose a valid date in June 2027.';return '';}
function validate(){start.error=error(start);end.error=error(end);if(!start.error&&!end.error&&end.value<start.value)end.error='Return must be on or after departure.';return !start.error&&!end.error;}
[start,end].forEach(p=>p.addEventListener('duetChange',()=>{result.textContent='';validate()}));
document.querySelector('#prepare').addEventListener('click',async()=>{if(!validate()){await(start.error?start:end).setFocus();return;}const a=Date.parse(start.value+'T00:00:00Z'),b=Date.parse(end.value+'T00:00:00Z');result.textContent=`Local range: ${start.value} to ${end.value}, ${(b-a)/86400000+1} calendar days inclusive. No policy created.`;});
</script></html>
```

Referência de código

- Este exemplo usa @duetds/components por meio da CDN do sistema principal, não @duetds/date-picker 1.x.

- Intervalos com a mesma data abrangem um dia do calendário, inclusive.

- A aritmética UTC evita diferenças de fuso horário causadas pelo horário de verão na contagem.

## Sistema de design Duet Configuração do agente

### Ponto de partida para implementação

Composição completa pela CDN do sistema principal, usando as versões presentes explicitamente na página de integração consultada. Registros de pesquisa públicos também mostram versões mais recentes; fixe uma versão compatível em vez de presumir que esta seja a mais recente. As fontes não são redistribuídas aqui.

```
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Date range draft</title>
<link rel="stylesheet" href="https://cdn.duetds.com/api/css/5.1.4/lib/duet.min.css">
<script type="module" src="https://cdn.duetds.com/api/components/10.7.0/lib/duet/duet.esm.js"></script>
<style>main{max-width:680px;margin:auto;padding:28px}.range{display:grid;grid-template-columns:1fr 1fr;gap:20px}@media(max-width:576px){.range{grid-template-columns:1fr}}</style>
<main><h1>Choose a travel period</h1><p>Demonstration only. No insurance is quoted or purchased.</p><div class="range">
<duet-date-picker id="start" label="Departure" required expand value="2027-06-10" min="2027-06-01" max="2027-06-30"></duet-date-picker>
<duet-date-picker id="end" label="Return" required expand value="2027-06-17" min="2027-06-01" max="2027-06-30"></duet-date-picker></div>
<duet-button id="prepare" variation="primary">Prepare date range</duet-button>
<p id="result" role="status"></p></main><script type="module">
await customElements.whenDefined('duet-date-picker');
const start=document.querySelector('#start'),end=document.querySelector('#end'),result=document.querySelector('#result');
function error(picker){const v=picker.validity;if(!picker.value)return 'Choose a date.';if(v&&!v.valid)return 'Choose a valid date in June 2027.';return '';}
function validate(){start.error=error(start);end.error=error(end);if(!start.error&&!end.error&&end.value<start.value)end.error='Return must be on or after departure.';return !start.error&&!end.error;}
[start,end].forEach(p=>p.addEventListener('duetChange',()=>{result.textContent='';validate()}));
document.querySelector('#prepare').addEventListener('click',async()=>{if(!validate()){await(start.error?start:end).setFocus();return;}const a=Date.parse(start.value+'T00:00:00Z'),b=Date.parse(end.value+'T00:00:00Z');result.textContent=`Local range: ${start.value} to ${end.value}, ${(b-a)/86400000+1} calendar days inclusive. No policy created.`;});
</script></html>
```

### Um prompt para seu projeto

```
Crie um intervalo de datas do sistema principal do Duet com dois seletores de data identificados, valores ISO e verificações de validade. Valide a ordem dos extremos separadamente, chame setFocus em caso de erro e use uma ação explícita e primária para preparar o intervalo local. Não inclua o pacote de seletor independente na mesma página.
```

## Sistema de design Duet Fontes e escopo

Referência independente de OpenDesign. Planejador original; não cria apólice, reserva nem cotação. O Duet do sistema principal e seu seletor de datas independente e de código aberto têm contratos diferentes.

- Tokens de design Cores do tema, espaçamento e status dos tokens.

- Tipografia Escala e fontes da marca separadas.

- Seletor de datas Valores ISO, validação e métodos.

- Button Confirmação de participação e variação.

- Uso dos componentes CDN e pacotes do sistema principal.

- Seletor independente Distribuição independente de código aberto; não é o alvo de código aqui.

## Sistema de design Duet Recursos relacionados

### Elastic UI

Crie um explorador de registros do Elastic UI com escalas Borealis verificadas, controles nativos de tabela e busca, filtragem por gravidade, eventos salvos localmente e código-fonte completo de React.

### Emplifi Soul

Conheça o contrato de tabela de dados do Soul junto com seu espaçamento de seis pixels, funções de cores em camadas e tipografia compacta Inter. Compare a seleção em lote, a notação de dados ausentes e as linhas de resumo; depois, examine os pontos de entrada verificados do pacote privado React.

### Esri Calcite

Uma referência prática do Calcite para ferramentas espaciais com foco: superfícies semânticas e ações azuis, painéis compactos de inspeção, APIs reais de entrada e um exemplo completo de revisão local de site.


- [Referência de implementação](https://www.duetds.com/components/date-picker/)
- [Fonte](https://www.duetds.com/tokens/)
- [Fonte](https://www.duetds.com/typography/)
- [Fonte](https://www.duetds.com/components/date-picker/)
- [Fonte](https://www.duetds.com/components/button/)
- [Consulte a especificação de apoio](https://www.duetds.com/using-components/)
- [Consulte a especificação de apoio](https://www.duetds.com/tokens/)
- [Consulte a especificação de apoio](https://www.duetds.com/typography/)
- [Consulte a especificação de apoio](https://www.duetds.com/components/date-picker/)
- [Consulte a especificação de apoio](https://www.duetds.com/components/button/)
- [Referência de código](https://www.duetds.com/components/date-picker/)
- [Tokens de design Cores do tema, espaçamento e status dos tokens.](https://www.duetds.com/tokens/)
- [Tipografia Escala e fontes da marca separadas.](https://www.duetds.com/typography/)
- [Seletor de datas Valores ISO, validação e métodos.](https://www.duetds.com/components/date-picker/)
- [Button Confirmação de participação e variação.](https://www.duetds.com/components/button/)
- [Uso dos componentes CDN e pacotes do sistema principal.](https://www.duetds.com/using-components/)
- [Seletor independente Distribuição independente de código aberto; não é o alvo de código aqui.](https://github.com/duetds/date-picker)
