Design de produto empresarial · Novo recurso

Sistema de design Porsche.

Explore Porsche Design System v4 com espaçamento fluido, esquemas de cores CSS, tipografia Porsche Next e um configurador com duas opções. A referência inclui expressões reais de tokens e uma entrada completa do Vite que usa os eventos atuais do controle segmentado.

Guia OpenDesign8 capítulos45 entradas de referênciaGuia de aplicação original
01

Prévia da interface sistema de design Porsche

Escolha um acabamento e um estilo de roda, mantenha um resumo da sessão e alterne entre os modos claro e escuro da interface.

Estudo original de acabamentos e rodasAbrir exemplo completo
Interpretação original offline de HTML/CSS dos papéis dos tokens do v4 e do comportamento de escolha segmentada. Sem runtime nativo do PDS, fontes remotas, imagens oficiais de modelos ou dados reais de veículos. · Referência de implementação
02

Referência de design sistema de design Porsche

Documentação do Porsche Design System v4, com páginas de tokens que exibem a versão v4.8.0. Esta é uma referência com escopo de versão, não uma afirmação de que seja a versão mais recente. As amostras de acabamentos originais são dados do aplicativo, não códigos oficiais de pintura Porsche.

Espaçamento estático

Fonte
Nome / RegraValor / ConfiguraçãoUso
spacingStatic2Xs1pxToken de espaçamento fixo.
spacingStaticXs4pxToken de espaçamento fixo.
spacingStaticSm8pxToken de espaçamento fixo.
spacingStaticMd16pxToken de espaçamento fixo.
spacingStaticLg32pxToken de espaçamento fixo.
spacingStaticXl48pxToken de espaçamento fixo.
spacingStatic2Xl80pxToken de espaçamento fixo.

Espaçamento fluido

Fonte
Nome / RegraValor / ConfiguraçãoUso
spacingFluidXsclamp(4px, 0.25vw + 3px, 8px)Pequeno intervalo adaptável.
spacingFluidSmclamp(8px, 0.5vw + 6px, 16px)Espaçamento adaptável compacto.
spacingFluidMdclamp(16px, 1.25vw + 12px, 36px)Preenchimento de exemplo da página.
spacingFluidLgclamp(32px, 2.75vw + 23px, 76px)Espaçamento entre seções.
spacingFluidXlclamp(48px, 3vw + 38px, 96px)Espaçamento amplo.
spacingFluid2Xlclamp(80px, 7.5vw + 56px, 200px)Espaçamento amplo para a composição.

Papéis das cores

Fonte
Nome / RegraValor / ConfiguraçãoUso
colorCanvaslight-dark(#fff,hsl(225 66.7% 1.2%))Fundo da página.
colorSurfacelight-dark(hsl(240 10% 95%),hsl(240 2% 10%))Superfície secundária.
colorPrimarylight-dark(hsl(225 66.7% 1.2%),hsl(225 100% 99%))Texto principal.
colorFocuslight-dark(#1A44EA,#1A44EA)Foco do teclado.
colorContrastLow / colorContrastLowerDecorative onlyPapéis de texto que não atendem aos requisitos de acessibilidade.

Expressões tipográficas

Fonte
Nome / RegraValor / ConfiguraçãoUso
fontPorscheNext'Porsche Next','Arial Narrow',Arial,'Heiti SC',SimHei,sans-serifFamília oficial e fallbacks.
typescale2Xs.75remMenor tamanho tipográfico listado.
typescaleXs.875remMetadados pequenos.
typescaleSm1remTamanho-base do corpo do texto.
typescaleMdclamp(1.13rem, 0.21vw + 1.08rem, 1.33rem)Tipografia fluida.
typescale2Xlclamp(1.6rem, 1.56vw + 1.29rem, 3.16rem)Título grande fluido.
leadingNormalcalc(6px + 2.125ex)Altura de linha sensível à fonte.
fontWeightNormal / Semibold / Bold400 / 600 / 700Pesos disponíveis.

Formas

Fonte
Nome / RegraValor / ConfiguraçãoUso
radiusXs / Sm / Md2px / 4px / 6pxFormas pequenas.
radiusLg8pxControles interativos compactos.
radiusXl12pxControles interativos padrão.
radius2Xl16pxNotificações.
radius3Xl24pxBlocos e contêineres semelhantes a diálogos.
radius4Xl32pxMaior raio fixo.
radiusFullcalc(infinity * 1px)Indicadores isolados em formato de pílula.

Pontos de quebra

Fonte
Nome / RegraValor / ConfiguraçãoUso
breakpointXs480Token numérico usado com px.
breakpointSm760Token numérico usado com px.
breakpointMd1000Token numérico usado com px.
breakpointLg1300Token numérico usado com px.
breakpointXl1760Token numérico usado com px.
breakpoint2Xl1920Token numérico usado com px.

Contrato de escolha segmentada

Fonte
Nome / RegraValor / ConfiguraçãoUso
valuestring | numberValor do item selecionado.
change eventdetail: { value: string | number }Atualize o estado do aplicativo.
columnsauto or 1–25; responsive values supportedControle a grade de itens.
noWrapfalse by defaultTrue cria uma linha única com rolagem.
statenone / error / successEstilo de validação.
disabledExcludes value from form submissionDiferente de um item comum não selecionado.
03

Guia completo de sistema de design Porsche

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

DESIGN-porsche.md

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

Baixar o guia

Sistema de design Porsche Use a base do v4 como um conjunto completo

As variáveis globais agora são obrigatórias

A versão 4 cria estilos de componentes com base em variáveis globais CSS. Portanto, importar a folha de estilos global é um requisito arquitetural, não apenas uma redefinição decorativa. A mesma importação inclui a normalização e as definições de font-face do Porsche Next.

Com base neste guia de OpenDesign

Esta referência reúne os contratos dos componentes e dos tokens do v4. Exemplos antigos que usam contêineres text-field ou propriedades de tema por componente não devem ser reutilizados sem consultar o guia de migração. A própria documentação é versionada; por isso, a página especifica seu escopo em vez de afirmar que o API é imutável.

Consulte a especificação de apoio

Sistema de design Porsche O esquema de cores seleciona pares completos de papéis

Separe os papéis da interface das amostras de acabamento

Os tokens de tela, superfície e primeiro plano principal contêm pares light-dark(). A propriedade CSS color-scheme seleciona a opção. Defina light, dark ou light dark conforme o aplicativo fixe um modo ou siga a preferência do usuário.

As cores de acabamento deste exemplo são amostras originais independentes. Ao mudar a interface para o modo escuro, as superfícies ao redor e o texto mudam, mas o acabamento selecionado permanece igual. Os papéis de cor com menor contraste são decorativos; usá-los no rótulo de uma opção essencial ultrapassaria o limite de uso previsto para o token.

Consulte a especificação de apoio

Sistema de design Porsche Ritmo fluido e espaçamentos fixos entre controles coexistem

Use expressões clamp quando o espaço precisar aumentar

A Porsche oferece escalas estáticas e fluidas. A entrada nativa usa a expressão fluida média no preenchimento da página, enquanto os espaçamentos de 16px e 32px mantêm relações estáveis na área de opções. Um limite fluido evita que o espaço em branco continue aumentando indefinidamente em telas largas.

O exemplo passa de uma disposição ampla, com visual e controles lado a lado, para seções empilhadas abaixo de 760px, um dos valores de breakpoint documentados. A decisão de empilhar é uma escolha de composição do aplicativo; o valor do breakpoint é a referência do sistema.

Consulte a especificação de apoio

Sistema de design Porsche A tipografia depende da fonte fornecida

A expressão de altura de linha não é uma proporção genérica

Porsche Next tem uma pilha de fallbacks documentada e uma escala tipográfica com tamanhos pequenos fixos e tamanhos maiores fluidos. leadingNormal usa unidades ex, que respondem à altura-x da fonte, mais um acréscimo fixo em pixels. Substituí-la por uma proporção arbitrária de 1.5 altera o ritmo previsto.

A interpretação offline usa um fallback local e uma altura de linha confortável para leitura, sem fingir que a fonte licenciada foi incluída. Na implementação nativa, a folha de estilos global define a fonte real. Na linguagem visual do v4, os títulos usam peso regular; um tamanho maior não exige um peso mais forte para estabelecer hierarquia.

Consulte a especificação de apoio

Sistema de design Porsche Controles e contêineres usam raios diferentes

Doze e vinte e quatro pixels definem a hierarquia principal

O raio padrão para elementos interativos é de 12px; a família de cartões e diálogos usa 24px. Controles compactos usam 8px, enquanto notificações usam 16px. Aplicar o maior arredondamento a todos os elementos apagaria essas relações.

A prévia original apresenta o estudo do veículo em uma superfície ampla com raio de 24px e usa controles com raio de 12px. A silhueta do veículo é uma ilustração original de CSS, não uma renderização de um modelo Porsche nem uma fotografia de produto. A mesma composição pode ser usada para um seletor de materiais sem sugerir que haja uma configuração real disponível.

Consulte a especificação de apoio

Sistema de design Porsche Um controle segmentado é uma escolha, não uma barra de abas

Use valores estáveis e uma única fonte de estado

Cada p-segmented-control-item fornece um valor. Um evento change retorna esse valor em event.detail, que o exemplo armazena antes de redesenhar o resumo. O grupo exibe um rótulo visível para diferenciar as opções de acabamento das opções de rodas.

O API do v4 permite definir a quantidade de colunas de forma responsiva e usar, opcionalmente, um contêiner rolável que não quebra a linha. Opções curtas podem ficar visíveis ao mesmo tempo; rótulos longos e localizados devem quebrar linha ou usar uma área de rolagem planejada, em vez de serem cortados. Controles desativados são excluídos dos dados do formulário, algo importante ao ampliar este exemplo para um formulário real.

  1. Inicialize os valores de acabamento e rodas uma única vez no estado do aplicativo.
  2. Leia detail.value do evento change do grupo.
  3. Atualize o estudo visual e a seleção textual ao mesmo tempo.
  4. Limpe qualquer resumo salvo anteriormente após uma edição.

Consulte a especificação de apoio

Sistema de design Porsche Uma seleção local não é uma transação concluída

Defina explicitamente os tipos dos botões

p-button usa submit por padrão. O exemplo define type="button" porque salvar uma combinação e mudar o esquema de cores são interações locais. A navegação deve usar o componente Link, não um botão com um destino inventado.

A ação principal informa exatamente o que aconteceu: uma combinação foi mantida durante a sessão atual da página. Ela não promete persistência após recarregar a página, armazenamento na conta nem realização de um pedido. Esse comportamento limitado é intencional e suficiente para um exemplo de interface.

  • A ação principal mantém a combinação local atual.
  • A ação secundária muda o esquema de cores da interface.
  • Os rótulos visíveis permanecem presentes nas duas ações.
  • Nenhum indicador de carregamento é exibido quando não há uma operação pendente.

Consulte a especificação de apoio

Sistema de design Porsche Carregue os componentes e proteja a primeira renderização

Loader, folha de estilos e compilador trabalham juntos

A configuração do Vite injeta o partial oficial do loader no corpo do documento. A entrada principal importa a folha de estilos global e renderiza elementos personalizados reais. As regras escopadas :not(:defined) impedem que as tags de componentes selecionadas pisquem antes do registro.

A configuração documentada do Vite exclui a transformação LightDark do Lightning CSS porque esse polyfill é identificado como defeituoso. Manter essa exclusão é importante: compilar incorretamente a função de token pode quebrar o tema, mesmo quando a marcação do componente está correta. Os preloads recomendados podem ser adicionados depois por meio dos partials documentados de fontes, ícones e componentes.

Consulte a especificação de apoio

Exemplos de componentes do sistema de design sistema de design Porsche

Exemplo interativo completo e independente

Salve o documento completo como index.html e abra-o em um navegador. Interpretação original e offline das funções dos tokens e do comportamento das opções segmentadas de HTML/CSS v4. Não inclui runtime nativo do PDS, fontes remotas, imagens oficiais de modelos nem dados reais de veículos.

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Original finish study</title><style>:root{color-scheme:light;--canvas:#fff;--surface:hsl(240 10% 95%);--ink:hsl(225 66.7% 1.2%);--line:#c8c8cd;--paint:#b9b6ae}*{box-sizing:border-box}body{margin:0;background:var(--canvas);color:var(--ink);font:16px/1.5 'Arial Narrow',Arial,sans-serif}body.dark{color-scheme:dark;--canvas:hsl(225 66.7% 1.2%);--surface:hsl(240 2% 10%);--ink:#fcfcff;--line:#515156}button{font:inherit;cursor:pointer}button:focus-visible,input:focus-visible+span{outline:3px solid #1a44ea;outline-offset:4px}header{display:flex;justify-content:space-between;gap:16px;align-items:center;padding:24px 32px;border-bottom:1px solid var(--line)}header b{letter-spacing:3px;font-weight:400}header button{border:1px solid var(--line);color:var(--ink);background:var(--canvas);border-radius:12px;padding:8px 16px}main{max-width:1200px;padding:clamp(16px,1.25vw + 12px,36px);margin:auto}h1{font-size:clamp(1.6rem,1.56vw + 1.29rem,3.16rem);font-weight:400;line-height:1.2;margin:16px 0}.intro{color:var(--ink);opacity:.8;max-width:650px}.layout{display:grid;grid-template-columns:1.4fr 1fr;gap:32px;margin-top:32px}.stage{background:var(--surface);border-radius:24px;display:flex;flex-direction:column;justify-content:center;min-height:360px;overflow:hidden;padding:32px;position:relative}.scene{height:210px;position:relative;width:100%;max-width:520px;margin:auto}.car{height:80px;width:94%;position:absolute;bottom:28px;left:3%;background:var(--paint);border-radius:60% 35% 18% 22% / 75% 65% 25% 35%;box-shadow:inset 0 5px 10px #ffffff70,inset 0 -10px 12px #0003}.roof{position:absolute;bottom:80px;left:25%;width:46%;height:70px;background:var(--paint);border-radius:65% 55% 0 0;transform:skewX(-9deg)}.window{position:absolute;inset:9px 13px 4px;background:linear-gradient(135deg,#202d37,#67737b);border-radius:70% 52% 0 0;border-right:7px solid var(--paint)}.window:after{content:'';position:absolute;left:46%;top:0;height:100%;width:6px;background:var(--paint)}.wheel{position:absolute;bottom:12px;width:69px;height:69px;background:repeating-conic-gradient(#d2d5d8 0deg 13deg,#42464b 13deg 60deg);border:11px solid #191a1d;border-radius:50%;box-shadow:0 0 0 4px #08090a}.wheel.a{left:16%}.wheel.b{right:12%}.aero .wheel{background:radial-gradient(circle,#505860 0 18%,#c6c9cc 20% 65%,#464a4d 68%)}.headlight{position:absolute;right:0;top:18px;width:34px;height:12px;background:#fff9d8;border:2px solid #ffffff80;border-radius:80%;transform:rotate(15deg)}.shadow{height:10px;background:#0002;position:absolute;bottom:7px;width:90%;left:5%;border-radius:50%;filter:blur(5px)}.stage small{font-size:12px;opacity:.7}.panel{padding:8px 0}fieldset{border:0;padding:0;margin:0 0 32px;min-width:0}legend{font-size:18px;margin-bottom:16px}.segments{display:flex;background:var(--surface);padding:4px;border-radius:16px;gap:4px}.segments label{flex:1;min-width:0;position:relative;text-align:center;cursor:pointer}.segments input{position:absolute;opacity:0;width:1px;height:1px}.segments span{display:block;padding:12px 8px;border:1px solid transparent;border-radius:12px}.segments input:checked+span{background:var(--canvas);border-color:var(--ink);box-shadow:0 1px 4px #0002}.swatch{display:inline-block;width:12px;height:12px;border-radius:50%;margin-right:6px;border:1px solid #777}.summary{border-top:1px solid var(--line);padding-top:24px;margin:0 0 24px}.summary small{display:block;opacity:.65;margin-bottom:4px}.summary strong{font-weight:400;font-size:20px}.primary{border:0;border-radius:12px;min-height:52px;background:var(--ink);color:var(--canvas);padding:12px 24px;width:100%}.saved{border-left:3px solid var(--ink);padding-left:16px;margin-top:24px}.saved:empty{display:none}footer{font-size:12px;opacity:.7;padding-top:32px}@media(max-width:759px){header{padding:16px}header b{font-size:13px;letter-spacing:1px}.layout{grid-template-columns:1fr;gap:24px}.stage{min-height:270px;padding:16px}.scene{height:210px}.wheel{width:53px;height:53px;border-width:8px;bottom:21px}.car{bottom:38px}.roof{bottom:91px;height:60px}.segments span{padding:12px 5px;font-size:14px}fieldset{margin-bottom:24px}}
</style><header><b>DESIGN STUDY / 01</b><button id="theme" type="button">Dark interface</button></header><main><h1>A different point of view.</h1><p class="intro">Explore two small choices in an original vehicle study. See how a restrained interface keeps the object at the center.</p><div class="layout"><div class="stage"><div class="scene" id="scene" role="img" aria-label="Original vehicle illustration in Chalk with Classic wheels"><div class="shadow"></div><div class="roof"><div class="window"></div></div><div class="car"><div class="headlight"></div></div><div class="wheel a"></div><div class="wheel b"></div></div><small>Original illustration · Not a Porsche model render</small></div><section class="panel" aria-label="Study options"><fieldset><legend>Finish</legend><div class="segments"><label><input type="radio" name="paint" value="chalk" checked><span><i class="swatch" style="background:#b9b6ae"></i>Chalk</span></label><label><input type="radio" name="paint" value="blue"><span><i class="swatch" style="background:#456171"></i>Coastal blue</span></label><label><input type="radio" name="paint" value="red"><span><i class="swatch" style="background:#9f2937"></i>Garnet</span></label></div></fieldset><fieldset><legend>Wheel study</legend><div class="segments"><label><input type="radio" name="wheel" value="Classic" checked><span>Classic</span></label><label><input type="radio" name="wheel" value="Aero"><span>Aero</span></label></div></fieldset><p class="summary" aria-live="polite"><small>YOUR COMBINATION</small><strong id="summary">Chalk · Classic</strong></p><button class="primary" id="save" type="button">Keep this combination</button><p class="saved" id="saved" role="status"></p></section></div><footer>Independent PDS v4 interpretation. Original finish names and illustration; no pricing, vehicle specification, live configuration or order. Choices last only for this page session.</footer></main><script>const colors={chalk:'#b9b6ae',blue:'#456171',red:'#9f2937'},names={chalk:'Chalk',blue:'Coastal blue',red:'Garnet'};function values(){return[document.querySelector('[name=paint]:checked').value,document.querySelector('[name=wheel]:checked').value]}function update(){const[p,w]=values();document.documentElement.style.setProperty('--paint',colors[p]);document.querySelector('#scene').classList.toggle('aero',w==='Aero');document.querySelector('#scene').setAttribute('aria-label',`Original vehicle illustration in ${names[p]} with ${w} wheels`);document.querySelector('#summary').textContent=`${names[p]} · ${w}`;document.querySelector('#saved').textContent=''}document.querySelectorAll('input').forEach(x=>x.addEventListener('change',update));document.querySelector('#save').onclick=()=>{const[p,w]=values();document.querySelector('#saved').textContent=`Kept for this page session: ${names[p]}, ${w}. No order submitted.`};document.querySelector('#theme').onclick=e=>{const dark=document.body.classList.toggle('dark');e.currentTarget.textContent=dark?'Light interface':'Dark interface'};</script></html>

Referência de código

  • As escolhas de acabamento e rodas atualizam uma ilustração original do configurador. Elas não são especificações de produtos Porsche; os eventos nativos do controle segmentado aparecem no exemplo v4 separado.

Duas opções controladas com um resumo válido apenas durante a sessão

Os elementos nativos p-segmented-control emitem eventos change com detail.value; p-button usa click e um type explícito.

typescript
import './style.css';
const paints={chalk:'#b9b6ae',blue:'#456171',red:'#9f2937'};
const names={chalk:'Chalk',blue:'Coastal blue',red:'Garnet'};
type Paint=keyof typeof paints;
let paint:Paint='chalk',wheel='Classic';
document.querySelector<HTMLDivElement>('#app')!.innerHTML=`
<main><h1>Explore an original color study</h1>
<p>This specimen is not a real vehicle configurator or order.</p>
<div class="options">
<p-segmented-control id="paint" label="Finish" value="chalk">
 <p-segmented-control-item value="chalk">Chalk</p-segmented-control-item>
 <p-segmented-control-item value="blue">Coastal blue</p-segmented-control-item>
 <p-segmented-control-item value="red">Garnet</p-segmented-control-item>
</p-segmented-control>
<p-segmented-control id="wheel" label="Wheel study" value="Classic">
 <p-segmented-control-item value="Classic">Classic</p-segmented-control-item>
 <p-segmented-control-item value="Aero">Aero</p-segmented-control-item>
</p-segmented-control>
</div><div class="preview"><div id="swatch" style="height:120px;border-radius:12px"></div>
<p id="summary" aria-live="polite"></p></div>
<div class="actions"><p-button id="save" type="button">Keep this combination</p-button>
<p-button id="scheme" type="button" variant="secondary">Switch color scheme</p-button></div>
<p id="saved" role="status"></p></main>`;
function render(){document.querySelector<HTMLElement>('#swatch')!.style.background=paints[paint];document.querySelector('#summary')!.textContent=`${names[paint]} · ${wheel} wheel study`;document.querySelector('#saved')!.textContent='';}
document.querySelector('#paint')!.addEventListener('change',e=>{const v=(e as CustomEvent<{value:string}>).detail.value;if(v in paints){paint=v as Paint;render();}});
document.querySelector('#wheel')!.addEventListener('change',e=>{wheel=String((e as CustomEvent<{value:string}>).detail.value);render();});
document.querySelector('#save')!.addEventListener('click',()=>{document.querySelector('#saved')!.textContent=`Kept for this page session: ${names[paint]}, ${wheel}. No order submitted.`;});
document.querySelector('#scheme')!.addEventListener('click',()=>{const root=document.documentElement;root.style.colorScheme=root.style.colorScheme==='dark'?'light':'dark';});
render();

Referência de código

  • A alteração de qualquer uma das opções limpa a combinação salva anteriormente.
  • A propriedade color-scheme controla o tema do sistema; as amostras de acabamento continuam sendo dados originais do aplicativo.
  • O exemplo não coleta informações de contato, não reserva um veículo nem envia um pedido.
04

Configuração do agente sistema de design Porsche

Ponto de partida para implementação

Configuração de Web Components nativos da versão 4 com a folha de estilos global documentada e o partial do loader. A prévia offline não usa fontes remotas nem runtime de pacote; a compilação do pacote nativo não foi verificada aqui.

texto
# In a new Vite vanilla-ts project:
npm create vite@latest pds-specimen -- --template vanilla-ts
cd pds-specimen
npm install
npm install @porsche-design-system/components-js@4
npm install --save-dev lightningcss

// vite.config.ts
import {defineConfig} from 'vite';
import {Features} from 'lightningcss';
import {getLoaderScript} from '@porsche-design-system/components-js/partials';
export default defineConfig({
 plugins:[{name:'pds-loader',transformIndexHtml(html){
  return html.replace('</body>',getLoaderScript()+'</body>');
 }}],
 css:{transformer:'lightningcss',lightningcss:{exclude:Features.LightDark}}
});

/* src/style.css */
@import '@porsche-design-system/components-js';
html { color-scheme: light; }
:is(p-button,p-segmented-control,p-segmented-control-item):not(:defined){visibility:hidden}
main{max-width:60rem;margin:auto;padding:clamp(16px,1.25vw + 12px,36px)}
.options{display:grid;gap:32px}
.preview{padding:32px;border-radius:24px;margin-block:32px;border:1px solid currentColor}
.actions{display:flex;gap:16px;flex-wrap:wrap}

# Replace src/main.ts with the example below, then:
npm run dev

Um prompt para seu projeto

Prompt para agente de IA
Crie uma composição do PDS v4 com estilos globais obrigatórios, o partial do loader, color-scheme, espaçamento fluido real e raios de 12px para controles e 24px para contêineres. Use change detail.value do controle segmentado para duas opções de exemplo originais e type=button explícito para ações locais. Não misture APIs de wrappers legados nem apresente o exemplo como uma configuração real de veículo.
05

Fontes e escopo de sistema de design Porsche

Referência independente de OpenDesign, restrita ao PDS v4. As ilustrações e os nomes de acabamento originais não são especificações de veículos Porsche, códigos de pintura nem opções disponíveis. Nenhuma transação é realizada.