# sistema de design Kiwi Orbit

## Pré-visualização da interface do sistema de design Kiwi Orbit

Altere o número de viajantes e os extras; confira o detalhamento e remova uma revisão desatualizada editando uma opção.

## Referência de design do sistema de design Kiwi Orbit

Componentes nativos Orbit React 27.7.0 com defaultTheme e CSS Tailwind compilado; referência dos tokens 11.0.0.

### Cores de ação do produto

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| buttonPrimaryBackground | #008F7B | Referência dos estados da ação principal. Mantenha distintos os papéis de hover, active e focus. |
| buttonPrimaryBackgroundHover | #007565 | Referência dos estados da ação principal. Mantenha distintos os papéis de hover, active e focus. |
| buttonPrimaryBackgroundActive | #006153 | Referência dos estados da ação principal. Mantenha distintos os papéis de hover, active e focus. |
| buttonPrimaryForeground | #FFFFFF | Referência dos estados da ação principal. Mantenha distintos os papéis de hover, active e focus. |
| buttonPrimaryForegroundHover | #FFFFFF | Referência dos estados da ação principal. Mantenha distintos os papéis de hover, active e focus. |
| buttonPrimaryForegroundActive | #FFFFFF | Referência dos estados da ação principal. Mantenha distintos os papéis de hover, active e focus. |
| buttonPrimaryBorderColorFocus | rgba(0, 143, 123, 0.5) | Referência dos estados da ação principal. Mantenha distintos os papéis de hover, active e focus. |
### Espaçamento dos componentes

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| space50 | 2px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space100 | 4px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space150 | 6px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space200 | 8px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space300 | 12px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space400 | 16px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space500 | 20px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space600 | 24px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space800 | 32px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space1000 | 40px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
| space1200 | 48px | Medidas de espaçamento reais em pixels, conforme o pacote de tokens publicado. |
### Raios dos cantos

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| borderRadius50 | 2px | Diferentes papéis de raio atendem a controles e superfícies maiores da experiência de viagem. |
| borderRadius100 | 4px | Diferentes papéis de raio atendem a controles e superfícies maiores da experiência de viagem. |
| borderRadius150 | 6px | Diferentes papéis de raio atendem a controles e superfícies maiores da experiência de viagem. |
| borderRadius200 | 8px | Diferentes papéis de raio atendem a controles e superfícies maiores da experiência de viagem. |
| borderRadius300 | 12px | Diferentes papéis de raio atendem a controles e superfícies maiores da experiência de viagem. |
| borderRadius400 | 16px | Diferentes papéis de raio atendem a controles e superfícies maiores da experiência de viagem. |
| borderRadiusNone | 0 | Diferentes papéis de raio atendem a controles e superfícies maiores da experiência de viagem. |
| borderRadiusFull | 9999px | Diferentes papéis de raio atendem a controles e superfícies maiores da experiência de viagem. |
### Tipografia do corpo

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| fontSizeTextSmall | 13px | Papéis tipográficos publicados para o corpo; os títulos personalizados da página fazem parte da composição da aplicação. |
| fontSizeTextNormal | 15px | Papéis tipográficos publicados para o corpo; os títulos personalizados da página fazem parte da composição da aplicação. |
| fontSizeTextLarge | 16px | Papéis tipográficos publicados para o corpo; os títulos personalizados da página fazem parte da composição da aplicação. |
| fontSizeTextExtraLarge | 18px | Papéis tipográficos publicados para o corpo; os títulos personalizados da página fazem parte da composição da aplicação. |
### Superfícies do produto e neutras

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| paletteCloudLight | #F5F7F9 | Use superfícies discretas e texto legível ao redor da cor de ação do produto. |
| paletteCloudNormal | #E8EDF1 | Use superfícies discretas e texto legível ao redor da cor de ação do produto. |
| paletteInkDark | #252A31 | Use superfícies discretas e texto legível ao redor da cor de ação do produto. |
| paletteInkLight | #657890 | Use superfícies discretas e texto legível ao redor da cor de ação do produto. |
| paletteInkNormal | #4F5E71 | Use superfícies discretas e texto legível ao redor da cor de ação do produto. |
| paletteProductLight | #E1F4F3 | Use superfícies discretas e texto legível ao redor da cor de ação do produto. |
| paletteProductNormal | #008F7B | Use superfícies discretas e texto legível ao redor da cor de ação do produto. |
| paletteProductDark | #007061 | Use superfícies discretas e texto legível ao redor da cor de ação do produto. |
## Guia completo do sistema de design Kiwi Orbit

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.

## Layout de seleção de viagem do sistema de design Kiwi Orbit

### Apresente o trajeto antes dos extras

> O resumo do trajeto mostra os códigos dos dois aeroportos, os nomes das cidades e uma duração fictícia antes das opções de bagagem. Assim, o contexto da compra permanece visível enquanto a pessoa compara os extras. O conector tracejado é uma ilustração original de CSS, não um gráfico de rota de uma companhia aérea nem uma promessa sobre um serviço real.

### Separe as opções do total

Os viajantes e a bagagem ficam de um lado, enquanto o detalhamento do preço aparece ao lado. O mesmo estado determina os controles selecionados e os valores. Em celulares, o resumo vem depois das opções na ordem do documento, deixando claro quais entradas compõem o total.

## Sistema de design Kiwi Orbit: cores do produto e feedback

### Use a família de cores do produto para a ação principal

O pacote de tokens fornece uma cor verde para ações do produto, com tons distintos para os estados de foco e ativo. A referência lista os valores exatos para a função do botão, em vez de depender de um verde de marca presumido. Superfícies neutras em tom de nuvem enquadram os extras selecionáveis sem fazer com que todos os painéis disputem a atenção com a ação de revisão.

### Mantenha o feedback específico para o resultado

O alerta de sucesso nativo informa que a seleção foi revisada localmente e especifica a quantidade de viajantes e o total. Ele é removido sempre que uma opção é alterada. Assim, uma confirmação verde anterior não continua visível como se validasse um conjunto de extras recém-editado.

## Sistema de design Kiwi Orbit: tipografia e hierarquia de preços

### Use estilos de texto nativos para as explicações

O Orbit oferece estilos nativos de corpo de texto pequeno, com 13px, e normal, com 15px, além de opções maiores. O exemplo usa os componentes nativos Text e Heading, enquanto os códigos de rota e o total recebem destaque próprio. O navegador usa aqui uma pilha de fontes alternativas documentada; nenhuma fonte da marca Kiwi.com é carregada sem aviso.

### Mantenha as unidades junto aos valores

O preço de cada bagagem informa que é por viajante. O detalhamento multiplica cada extra selecionado pela quantidade de viajantes, e o total tem mais destaque visual do que seus componentes. A unidade não deve desaparecer em dispositivos móveis, pois um valor grande e chamativo sem indicar seu escopo pode ser facilmente interpretado de forma errada.

## Sistema de design Kiwi Orbit: escalas de raio e espaçamento

### Diferencie os controles das superfícies maiores

A escala de raio atual inclui os valores 2, 4, 6, 8, 12 e 16px, além de nenhum e máximo. Os painéis de rota e resumo definidos no exemplo usam cantos de 12px, enquanto os controles nativos mantêm as regras do próprio tema. Aplicar o maior raio a todos os elementos aninhados prejudicaria a hierarquia do formulário.

### Mantenha a linha da opção íntegra quando houver quebra de linha

Uma linha de bagagem agrupa a caixa de seleção nativa, o texto complementar sobre a franquia e o preço. A largura flexível é destinada ao conteúdo descritivo, enquanto o preço permanece legível. A página passa a uma única coluna antes que qualquer uma das regiões principais fique estreita demais para permitir a comparação.

## Sistema de design Kiwi Orbit: caixas de seleção e seletores controlados

### Use rótulos de componentes e campos de informação

Checkbox recebe seu rótulo visível e as informações complementares por meio de propriedades públicas. Select recebe um rótulo e opções explícitas para selecionar de um a quatro viajantes. Essas composições nativas preservam o comportamento de interação e rotulagem, sem recorrer a uma div clicável que se passe por controle de bagagem.

### Modele cada extra de forma independente

Bagagem de mão e bagagem despachada são valores booleanos separados. A aplicação não indica que selecionar uma opção desmarque automaticamente a outra. Esta é uma regra intencionalmente simples para o exemplo; uma companhia aérea real pode oferecer pacotes mutuamente exclusivos ou franquias específicas por passageiro, o que exigiria outro modelo.

## Sistema de design Kiwi Orbit: cálculo e revisão da seleção

### Calcule o total usando uma única fórmula

O exemplo calcula a quantidade de viajantes multiplicada pela tarifa base mais os extras selecionados por pessoa. Ele não armazena um total editável de forma independente, que poderia divergir das opções exibidas. Todos os preços e franquias são explicitamente fictícios e não correspondem a ofertas atuais da Kiwi.com.

### Registre uma captura da revisão

A revisão armazena juntos a quantidade de viajantes, as opções de bagagem e o total. Alterar qualquer controle remove essa captura. Assim, o exemplo demonstra a consistência do estado sem apresentar um clique local como reserva, pagamento, verificação de disponibilidade em tempo real ou cotação final.

## Sistema de design Kiwi Orbit: feedback acessível para escolhas

### Verifique os rótulos e o recálculo em conjunto

Pessoas que usam teclado ou ponteiro podem selecionar a quantidade de viajantes e ativar ou desativar cada opção de bagagem usando os controles nativos. O resultado da revisão aparece em uma região de status. Não se inventa uma validação para bagagem opcional: deixar os dois extras desmarcados é um estado válido para esta tarifa fictícia.

1. Selecione dois viajantes e adicione bagagem de mão.

2. Adicione bagagem despachada e confira os três valores do detalhamento.

3. Faça a revisão local, altere uma opção e confirme que a mensagem de sucesso anterior desaparece.

### Evite consequências ocultas

A página explica o escopo fictício acima do formulário e ao lado do total. A ação é Revisar seleção local, não Comprar ou Reservar. Todas as alterações permanecem na página, e não são solicitados dados pessoais dos passageiros para uma demonstração que não precisa deles.

## Sistema de design Kiwi Orbit: provider e estilos compilados

### Use a versão estável correspondente

Este exemplo fixa a versão 27.7.0 de components e a versão 11.0.0 das referências de tokens. Ele importa OrbitProvider, o defaultTheme do pacote e o arquivo compilado lib/tailwind.css. Sem essa folha de estilos, os estilos dos componentes baseados em utilitários ficam incompletos, mesmo que a árvore de React seja renderizada.

- OrbitProvider e defaultTheme do pacote.

- Arquivo lib/tailwind.css compilado de components 27.7.0.

- Node.js 22 ou versão posterior para o ambiente de build do pacote.

### Deixe explícitos os requisitos de implantação

O pacote declara como requisito o Node.js 22 ou versão posterior. A entrada Vite fornecida pode ser reproduzida nesse ambiente com o pacote de componentes fixado. O CSS original cuida apenas da composição da viagem; os controles nativos mantêm os estilos publicados dos componentes e o comportamento do provider.

## Sistema de design Kiwi Orbit: exemplos de componentes

### main.jsx — exemplo funcional completo

Escolha as opções de bagagem e revise um total de exemplo. O código-fonte abaixo é a entrada completa de React, incluindo todo o estado e a validação.

```
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import {
  OrbitProvider,
  Button,
  Checkbox,
  Select,
  Alert,
  Heading,
  Text,
} from "@kiwicom/orbit-components";
import defaultTheme from "@kiwicom/orbit-components/lib/defaultTheme";
import "@kiwicom/orbit-components/lib/tailwind.css";
import "./orbit.css";
function App() {
  const [travellers, setTravellers] = useState("1"),
    [cabin, setCabin] = useState(false),
    [checked, setChecked] = useState(false),
    [saved, setSaved] = useState(null);
  const count = Number(travellers),
    extras = (cabin ? 18 : 0) + (checked ? 32 : 0),
    total = count * (96 + extras);
  function update(fn) {
    fn();
    setSaved(null);
  }
  return (
    <OrbitProvider theme={defaultTheme}>
      <main className="trip">
        <header>
          <Text size="small">ORIGINAL TRAVEL SPECIMEN</Text>
          <Heading as="h1" type="title1">Choose what travels with you</Heading>
          <Text>
            Fictional one-way fare. Prices illustrate the interface, not a
            bookable flight.
          </Text>
        </header>
        <div className="trip-grid">
          <section>
            <div className="route">
              <div>
                <strong>PRG</strong>
                <span>Prague</span>
              </div>
              <div className="route-line">
                <span>1h 45m · direct</span>
                <i></i>
              </div>
              <div>
                <strong>AMS</strong>
                <span>Amsterdam</span>
              </div>
            </div>
            <div className="options">
              <Heading as="h2" type="title3">Travellers and baggage</Heading>
              <Select
                label="Travellers"
                ariaLabel="Travellers"
                value={travellers}
                options={[1, 2, 3, 4].map((n) => ({
                  value: String(n),
                  label: n + " adult" + (n === 1 ? "" : "s"),
                }))}
                onChange={(e) => update(() => setTravellers(e.target.value))}
              />
              <div className="bag-option">
                <div>
                  <Heading as="h3" type="title4">Personal item</Heading>
                  <Text size="small">
                    Fits under the seat · included in this example fare
                  </Text>
                </div>
                <strong>Included</strong>
              </div>
              <div className="bag-option">
                <Checkbox
                  label="Add cabin baggage"
                  info="One 10 kg bag per traveller · fictional allowance"
                  checked={cabin}
                  onChange={(e) => update(() => setCabin(e.target.checked))}
                />
                <strong>
                  €18<span>/ traveller</span>
                </strong>
              </div>
              <div className="bag-option">
                <Checkbox
                  label="Add checked baggage"
                  info="One 20 kg bag per traveller · fictional allowance"
                  checked={checked}
                  onChange={(e) => update(() => setChecked(e.target.checked))}
                />
                <strong>
                  €32<span>/ traveller</span>
                </strong>
              </div>
            </div>
          </section>
          <aside>
            <Heading as="h2" type="title3">Your example selection</Heading>
            <dl>
              <dt>Base fare × {count}</dt>
              <dd>€{96 * count}</dd>
              {cabin && (
                <>
                  <dt>Cabin baggage × {count}</dt>
                  <dd>€{18 * count}</dd>
                </>
              )}
              {checked && (
                <>
                  <dt>Checked baggage × {count}</dt>
                  <dd>€{32 * count}</dd>
                </>
              )}
            </dl>
            <div className="trip-total">
              <span>Total</span>
              <strong>€{total}</strong>
            </div>
            <Text size="small">
              All amounts are illustrative. No payment or reservation will be
              created.
            </Text>
            <Button
              fullWidth
              onClick={() => setSaved({ count, cabin, checked, total })}
            >
              Review local selection
            </Button>
            {saved && (
              <div role="status" className="trip-confirm">
                <Alert type="success" title="Selection reviewed locally">
                  {saved.count} traveller{saved.count === 1 ? "" : "s"} · €
                  {saved.total}. No booking created.
                </Alert>
              </div>
            )}
          </aside>
        </div>
        <footer>
          Native Orbit 27.7.0 components and compiled package styles. Original
          layout and fictional pricing logic by OpenDesign.
        </footer>
      </main>
    </OrbitProvider>
  );
}
createRoot(document.getElementById("root")).render(<App />);
```

Referência de código

- Crie um projeto Vite React, mantenha <div id="root"></div> e carregue este arquivo como src/main.jsx.

### orbit.css — composição responsiva original

Layout da aplicação organizado em torno dos componentes nativos.

```
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  background: #f5f7f9;
  color: #252a31;
  font:
    16px/1.5 Arial,
    sans-serif;
}
.trip {
  padding: 32px;
}
.trip header {
  max-width: 760px;
  margin-bottom: 28px;
}
.trip header h1 {
  margin: 8px 0 12px;
}
.trip-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(280px, 1fr);
  gap: 24px;
}
.route,
.options,
.trip aside {
  background: #fff;
  border-radius: 12px;
  border: 1px solid #e8edf1;
  padding: 24px;
}
.route {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 20px;
}
.route strong {
  font-size: 32px;
  display: block;
}
.route span {
  font-size: 14px;
  display: block;
  color: #4f5e71;
}
.route-line {
  flex: 1;
  text-align: center;
}
.route-line i {
  display: block;
  border-top: 2px dashed #bac7d5;
  margin-top: 12px;
}
.options > h3 {
  margin-bottom: 20px;
}
.options > div:first-of-type {
  margin-bottom: 12px;
}
.bag-option {
  display: flex;
  gap: 20px;
  align-items: center;
  justify-content: space-between;
  padding: 24px 0;
  border-top: 1px solid #e8edf1;
}
.bag-option:last-child {
  padding-bottom: 0;
}
.bag-option > strong {
  white-space: nowrap;
  font-size: 18px;
}
.bag-option > strong span {
  display: block;
  font-size: 12px;
  font-weight: 400;
  color: #657890;
}
.trip aside {
  align-self: start;
}
.trip dl {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  margin: 24px 0;
}
.trip dd {
  margin: 0;
  text-align: right;
  font-weight: 600;
}
.trip-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid #bac7d5;
  padding: 20px 0;
}
.trip-total strong {
  font-size: 32px;
}
.trip aside > button {
  margin-top: 24px;
}
.trip-confirm {
  margin-top: 20px;
}
.trip footer {
  font-size: 12px;
  color: #657890;
  margin-top: 24px;
}
@media (max-width: 900px) {
  .trip-grid {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 550px) {
  .trip {
    padding: 16px;
  }
  .route,
  .options,
  .trip aside {
    padding: 20px;
  }
  .route {
    gap: 12px;
  }
  .route strong {
    font-size: 28px;
  }
  .route-line span {
    font-size: 12px;
  }
  .bag-option {
    align-items: flex-start;
    gap: 12px;
  }
}
```

Referência de código

- Salve junto de main.jsx. Estas regras de composição personalizadas são distintas da referência de tokens da biblioteca.

## Sistema de design Kiwi Orbit: configuração do agente

### Ponto de partida para implementação

O exemplo nativo com versões fixadas foi empacotado e verificado localmente no navegador. O exemplo usa apenas o estado local da aplicação.

```
npm create vite@latest orbit-trip -- --template react
cd orbit-trip
npm install
npm install react@18.3.1 react-dom@18.3.1 @kiwicom/orbit-components@27.7.0
# Use Node.js >=22. Replace src/main.jsx and add src/orbit.css.
npm run dev
```

### Um prompt para seu projeto

```
Crie um seletor de extras de viagem com componentes nativos do Orbit e estilos compilados. Mantenha consistentes o contexto da rota, os preços por viajante, os extras escolhidos e o total. Identifique claramente os preços fictícios e a revisão local, remova revisões desatualizadas após alterações e não sugira que há recursos de reserva ou pagamento.
```

## Sistema de design Kiwi Orbit: fontes e escopo

Guia de aplicação de OpenDesign. A rota, a duração, os preços e as franquias de bagagem são fictícios. Os controles nativos do Orbit funcionam localmente; nenhuma busca de voos, reserva ou pagamento é realizada.

- Primeiros passos com Orbit Versões atuais dos componentes e tokens e recursos de implementação.

- Código-fonte dos componentes Orbit Propriedades nativas, estilos e requisitos do pacote.

- Exportação de tokens fixados Valores exatos de produto, tipografia, espaçamento e raio.

## Sistema de design Kiwi Orbit: recursos relacionados

### Maersk sistema de design

Conheça a linguagem de interface operacional da Maersk por meio das funções reais do tema claro, das escalas de títulos e textos, dos raios aninhados e do tratamento de identificadores. Uma consulta de remessa de exemplo demonstra a correspondência exata de referências e um histórico de eventos acessível, sem alegar acesso a dados logísticos em tempo real.

### Microsoft Fluent 2

Crie um espaço de trabalho com Fluent UI React v9, tokens semânticos reais, as escalas tipográfica e de espaçamento para a web, abas controladas e um diálogo de acesso validado. Compare os valores do tema, examine a anatomia dos componentes e teste uma interação local antes de usar o exemplo completo de React.

### Monday Vibe

Monte um painel de entregas funcional com tokens do Vibe 4 e controles de React. Entenda a diferença entre cores semânticas de ação e rótulos do painel, os níveis de espaçamento nomeados, as formas abreviadas de fonte e a configuração explícita de CSS necessária para uma nova aplicação.


- [Referência de implementação](https://orbit.kiwi/getting-started/)
- [Fonte](https://cdn.jsdelivr.net/npm/@kiwicom/orbit-design-tokens@11.0.0/dist/index.js)
- [Referência de código](https://orbit.kiwi/getting-started/)
- [Primeiros passos com Orbit Versões atuais dos componentes e tokens e recursos de implementação.](https://orbit.kiwi/getting-started/)
- [Código-fonte dos componentes Orbit Propriedades nativas, estilos e requisitos do pacote.](https://github.com/kiwicom/orbit)
- [Exportação de tokens fixados Valores exatos de produto, tipografia, espaçamento e raio.](https://cdn.jsdelivr.net/npm/@kiwicom/orbit-design-tokens@11.0.0/dist/index.js)
