Varejo e comércio eletrônico · Novo recurso

Sistema de design Sainsbury's.

Aplique as diretrizes públicas de design da Sainsbury’s a um fluxo completo de escolha de horário: referências reais de paleta e tamanhos, opções de rádio acessíveis, resumo atualizado e feedback local transparente.

Guia OpenDesign7 capítulos38 entradas de referênciaGuia de aplicação original
01

Prévia da interface de sistema de design Sainsbury's

Altere o dia e o horário, confira a taxa de exemplo e revise a seleção local.

Escolha um horário para retirar o pedidoAbrir exemplo completo
Interpretação original das orientações públicas da Sainsbury’s para HTML. · Referência de implementação
02

Referência de design de sistema de design Sainsbury's

Orientações públicas da Sainsbury’s sobre cores, tokens de tamanho, tipografia e componentes. As tabelas de pontos de quebra publicadas que apresentam divergências são identificadas, em vez de combinadas.

Papéis da paleta da Sainsbury’s

Fonte
Nome / RegraValor / ConfiguraçãoUso
Primary brand base#F06C00 Cor de destaque da marca e preenchimento de botão com texto escuro neste estudo.
Primary hover#E55000 Preenchimento ao passar o cursor; não usar como cor de texto pequeno sobre fundo branco.
Primary pressed#C15100 Estado pressionado.
Primary light#FEF5F0 Fundo de seleção e resumo.
Secondary base#7F0442 Cor decorativa usada com moderação.
Monochrome darker#262626 Conteúdo principal.
Monochrome dark#404040 Conteúdo complementar.
Monochrome light#D8D8D8 Limites.
Monochrome lighter#F2F2F2 Superfície da opção indisponível.
Success lighter#E6F4ED Superfície de feedback da revisão local.
Success darker#246127 Texto de feedback.
Info darker#135CA3 Contorno de foco da aplicação.

Tokens de tamanho publicados

Fonte
Nome / RegraValor / ConfiguraçãoUso
xs2pxValor de espaçamento da tabela pública de tokens de tamanho.
sm4pxValor de espaçamento da tabela pública de tokens de tamanho.
md8pxValor de espaçamento da tabela pública de tokens de tamanho.
lg16pxValor de espaçamento da tabela pública de tokens de tamanho.
xl24pxValor de espaçamento da tabela pública de tokens de tamanho.
2xl32pxValor de espaçamento da tabela pública de tokens de tamanho.
3xl40pxValor de espaçamento da tabela pública de tokens de tamanho.
4xl48pxValor de espaçamento da tabela pública de tokens de tamanho.
width-sm1pxToken de borda; mantenha distintos os nomes de largura e raio.
width-base2pxToken de borda; mantenha distintos os nomes de largura e raio.
radius-base2pxToken de borda; mantenha distintos os nomes de largura e raio.
radius-xl12pxToken de borda; mantenha distintos os nomes de largura e raio.
min-width-sm576pxPonto de quebra do token; diferente do ponto de quebra da página editorial.
min-width-md768pxPonto de quebra do token; diferente do ponto de quebra da página editorial.
min-width-lg992pxPonto de quebra do token; diferente do ponto de quebra da página editorial.
min-width-xl1200pxPonto de quebra do token; diferente do ponto de quebra da página editorial.

Escala tipográfica da Sainsbury’s

Fonte
Nome / RegraValor / ConfiguraçãoUso
Body 11rem / 1.5 / Arial RegularTexto principal.
Caption0.875rem / 1.571 / Arial RegularNotas complementares.
Label 11rem / 1.5 / Arial BoldRótulos de controles.
Display 11.25rem / 1.3Fonte de destaque da marca nas orientações oficiais; alternativa usada aqui.
Display 21.5rem / 1.333A alternativa responsiva é Display 3.
Display 31.875rem / 1.333A alternativa responsiva é Display 4.
Display 42.375rem / 1.316A alternativa responsiva é Display 5.
Display 53rem / 1.292A alternativa responsiva é Display 6.
Display 63.75rem / 1.267Maior tamanho de destaque documentado.
Responsive type thresholdlarger than 720pxIndependente do ponto de quebra de 768px dos tokens de tamanho.
03

Guia completo de sistema de design Sainsbury's

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

DESIGN-sainsburys.md

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

Baixar o guia

Sistema multimarcas sistema de design Sainsbury's sistema de design Sainsbury's

Escolha um tema de marca

O Fable oferece suporte a Sainsbury’s, Argos, Nectar, Tu e Habitat por meio de estruturas compartilhadas de componentes e valores específicos para cada marca. Este guia usa apenas a paleta da Sainsbury’s. Misturar o roxo da Nectar a uma interação da Sainsbury’s ou presumir que todas as marcas usam a mesma fonte apagaria um limite explícito do sistema. Mantenha o tema selecionado associado ao ponto de entrada da aplicação.

Com base neste guia de OpenDesign

Diferencie as orientações públicas dos pacotes privados

O guia público para parceiros descreve os componentes de React, o Fable Styles e o pacote de tokens de design, mas o acesso à base de código exige credenciais solicitadas por meio de um contato da Sainsbury’s. Este exemplo não precisa delas: é um HTML original e completo, baseado em orientações publicadas. Ele não finge executar o Fable nem inventa comandos de instalação para um registro inacessível.

Paleta e contraste de sistema de design Sainsbury's sistema de design Sainsbury's

Use o laranja com uma combinação adequada para o texto

A documentação informa que o laranja-base e o laranja-escuro não oferecem contraste suficiente para o texto corrido comum sobre fundo branco. O exemplo usa o laranja como preenchimento com texto preto no botão, em vez de texto pequeno em laranja sobre branco ou texto pequeno em branco sobre laranja. Uma exceção de marca na documentação não deve ser interpretada, sem aviso, como uma alegação de que todas as combinações são acessíveis.

Mantenha o significado semântico dos estados

O resultado da análise usa a superfície de sucesso verde e texto verde-escuro. Os horários indisponíveis usam uma superfície neutra e um rótulo textual, enquanto os horários selecionados têm um botão de opção marcado e um contorno laranja. A cor é apenas um indicador complementar; ela nunca substitui o texto sobre horário, disponibilidade ou seleção.

Sistema de design Sainsbury's sistema de design Sainsbury's Espaçamento, cantos e limites dos pontos de quebra

Siga a escala de tamanhos publicada

O exemplo usa 8px entre as opções, 16px dentro de cada horário e 24–32px entre os grupos principais. Os controles têm cantos de 2px, enquanto o resumo usa o raio documentado de 12px. Essas diferenças expressam a organização dos elementos, em vez de aplicar o mesmo estilo de cartão arredondado a tudo.

Registre a divergência na documentação

O guia de layout indica os limites de dispositivo de 600px e 900px, enquanto a tabela de tokens de tamanho indica 576px, 768px e 992px. O guia de tipografia também altera os tamanhos de exibição acima de 720px. Esses valores não são nomes intercambiáveis para uma única escala. Esta implementação escolhe o limite de 768px dos tokens de tamanho para as colunas e declara essa escolha explicitamente.

Sistema de design Sainsbury's sistema de design Sainsbury's Tipografia e conteúdo útil

Respeite os limites de uso da fonte da marca

Os estilos de exibição oficiais da Sainsbury’s usam Mary Ann Extra Bold, enquanto o texto corrido comum usa Arial. O exemplo público usa Arial em toda a interface, pois não inclui arquivos da fonte da marca. Ele preserva as proporções da escala e da altura de linha sem afirmar que a fonte alternativa é visualmente idêntica. Os níveis semânticos dos títulos são independentes dos tamanhos de exibição.

Deixe clara a decisão sobre a coleta

Sistema de design Sainsbury's sistema de design Sainsbury's Opções de seleção e estado local

Use opções dependentes dentro de um grupo

Os controles de dia alteram as opções de horário disponíveis, e cada horário é um botão de opção nativo dentro de um grupo identificado. Ao mudar o dia, o primeiro horário disponível desse dia é selecionado e o resumo é atualizado. Uma opção indisponível continua visível, mas não pode ser selecionada. Botões de opção nativos oferecem um comportamento de teclado conhecido, sem precisar recriá-lo com elementos div clicáveis.

Evite alegações desatualizadas sobre reservas

Ao revisar, a interface mostra uma confirmação local e informa que nenhum horário foi reservado. A alteração do dia ou do horário oculta esse resultado. Um fluxo de produção precisaria verificar novamente a disponibilidade e receber uma resposta do servidor antes de confirmar uma reserva. O exemplo isola o contrato de interação para que a ausência de integração com o back-end não seja confundida com uma reserva concluída.

Sistema de design Sainsbury's sistema de design Sainsbury's Áreas de interação, foco e comportamento responsivo

Ofereça espaço suficiente às opções

As orientações públicas para botões recomendam uma área de toque de 48px. Os botões de dia e a ação de revisão atendem a essa altura, e toda a área de cada horário identificado é clicável. Um contorno azul de foco permanece visível sobre as superfícies laranja e claras. O ícone decorativo da cesta fica oculto para tecnologias assistivas.

Permita que conteúdos longos quebrem a linha

Em telas estreitas, o resumo aparece depois da lista de opções, e o ícone decorativo desaparece. Os rótulos dos horários e os preços permanecem no fluxo normal do documento, com altura flexível. O nome de um local traduzido ou mais longo não deve ser cortado em um cartão de altura fixa; este protótipo em inglês reserva espaço para a etapa posterior de localização.

Sistema de design Sainsbury's sistema de design Sainsbury's Implementação e revisão do agente

Execute o exemplo independente

Salve o exemplo completo de HTML e disponibilize-o localmente. Os três dias e os três horários por dia são dados de exemplo definidos no código, e todas as alterações ficam na memória. O código-fonte contém o elemento CSS, a criação dos botões de opção, a atualização do resumo e a limpeza de mensagens desatualizadas. Não há uma camada de aplicação ausente por trás da prévia.

  1. Salve o arquivo completo como index.html.
  2. Escolha terça-feira e confirme que não é possível selecionar o horário da manhã indisponível.
  3. Altere o horário e confira o resumo.
  4. Revise, depois altere o dia e confirme que o resultado anterior é removido.

Só migre para o Fable com acesso verificado

Para uma integração interna autorizada, obtenha acesso real ao pacote e consulte as APIs atuais de tema e componentes. Preserve o comportamento do exemplo ao substituir a marcação original por componentes compatíveis. Verifique se a escala de tokens instalada corresponde às referências públicas antes de considerar uma captura de tela como prova da implementação.

  • Use um único tema de marca de forma consistente.
  • Verifique o acesso ao pacote e as APIs atuais.
  • Verifique o contraste do texto separadamente da fidelidade às cores da marca.

Sistema de design Sainsbury's sistema de design Sainsbury's Exemplos de componentes do sistema de design

Fluxo completo de seleção de horário para coleta

Implementação independente de HTML/CSS/JavaScript com seleção de dia, horários em botões de opção, disponibilidade desativada e resumo atualizado em tempo real.

html
<!doctype html>
<html lang="en">
  <meta charset="utf-8" /><meta
    name="viewport"
    content="width=device-width,initial-scale=1"
  /><title>Collection slot study</title
  ><style>
    * {
      box-sizing: border-box;
    }
    body {
      margin: 0;
      background: #fff;
      color: #262626;
      font:
        16px/1.5 Arial,
        sans-serif;
      padding: 32px;
    }
    header {
      border-top: 8px solid #f06c00;
      padding-top: 24px;
      display: flex;
      justify-content: space-between;
      gap: 24px;
    }
    h1 {
      font-size: 38px;
      line-height: 1.316;
      margin: 8px 0 16px;
    }
    h2 {
      font-size: 24px;
      line-height: 1.333;
      margin: 0 0 16px;
    }
    .eyebrow,
    small {
      font-size: 14px;
      color: #404040;
    }
    p {
      margin: 8px 0 24px;
    }
    .basket {
      font-size: 48px;
      line-height: 1;
      background: #fef5f0;
      border-radius: 50%;
      width: 96px;
      height: 96px;
      display: grid;
      place-items: center;
      color: #7f0442;
    }
    main {
      display: grid;
      grid-template-columns: 2fr 1fr;
      gap: 32px;
      margin-top: 24px;
    }
    fieldset {
      border: 0;
      padding: 0;
      margin: 0 0 24px;
    }
    legend {
      font-weight: bold;
      margin-bottom: 16px;
    }
    .dates {
      display: flex;
      gap: 8px;
      flex-wrap: wrap;
    }
    button,
    select {
      font: inherit;
      min-height: 48px;
      padding: 12px 16px;
      border: 1px solid #737373;
      border-radius: 2px;
      background: white;
      color: #262626;
      cursor: pointer;
    }
    .dates button[aria-pressed="true"] {
      border: 2px solid #f06c00;
      background: #fef5f0;
      padding: 11px 15px;
    }
    .slots {
      display: grid;
      gap: 8px;
    }
    .slot {
      display: flex;
      gap: 12px;
      align-items: center;
      padding: 16px;
      border: 1px solid #d8d8d8;
      border-radius: 2px;
      cursor: pointer;
    }
    .slot:has(input:checked) {
      border: 2px solid #f06c00;
      padding: 15px;
      background: #fef5f0;
    }
    .slot:has(input:disabled) {
      background: #f2f2f2;
      cursor: default;
    }
    .slot input {
      accent-color: #c15100;
      width: 20px;
      height: 20px;
    }
    .slot strong {
      margin-left: auto;
    }
    .unavailable {
      color: #404040;
    }
    .primary {
      background: #f06c00;
      border: 2px solid #f06c00;
      font-weight: bold;
      color: #000;
    }
    .primary:hover {
      background: #e55000;
      border-color: #e55000;
    }
    .primary:active {
      background: #c15100;
      border-color: #c15100;
    }
    .summary {
      background: #fef5f0;
      border-radius: 12px;
      padding: 24px;
      align-self: start;
    }
    .summary dl {
      margin: 0;
    }
    .summary dt {
      font-size: 14px;
      margin-top: 16px;
    }
    .summary dd {
      margin: 4px 0;
      font-weight: bold;
    }
    #result {
      padding: 16px;
      background: #e6f4ed;
      color: #246127;
      margin-top: 24px;
    }
    button:focus-visible,
    input:focus-visible {
      outline: 3px solid #135ca3;
      outline-offset: 3px;
    }
    footer {
      border-top: 1px solid #d8d8d8;
      margin-top: 32px;
      padding-top: 16px;
      font-size: 14px;
      color: #404040;
    }
    [hidden] {
      display: none !important;
    }
    @media (max-width: 767px) {
      body {
        padding: 16px;
      }
      main {
        grid-template-columns: 1fr;
        gap: 24px;
      }
      h1 {
        font-size: 30px;
      }
      .basket {
        display: none;
      }
      .dates button {
        flex: 1;
      }
      .summary {
        padding: 16px;
      }
    }
  </style>
  <body>
    <header>
      <div>
        <span class="eyebrow">GROCERIES / ORIGINAL COLLECTION STUDY</span>
        <h1>Choose a collection slot</h1>
        <p>
          Select a sample day and time. No order or real availability is
          connected.
        </p>
      </div>
      <div class="basket" aria-hidden="true">▥</div>
    </header>
    <main>
      <section>
        <fieldset>
          <legend>Collection day</legend>
          <div class="dates" id="dates"></div>
        </fieldset>
        <fieldset>
          <legend id="slotLabel">Available times</legend>
          <div id="slots" class="slots"></div>
        </fieldset>
      </section>
      <aside class="summary">
        <h2>Collection details</h2>
        <dl>
          <dt>Sample location</dt>
          <dd>Riverside collection point</dd>
          <dt>Day and time</dt>
          <dd id="selection"></dd>
          <dt>Sample fee</dt>
          <dd id="fee"></dd>
        </dl>
        <p><small>All fees and slots are illustrative.</small></p>
        <button class="primary" id="review">Review collection</button>
        <div id="result" role="status" hidden></div>
      </aside>
    </main>
    <footer>
      Independent HTML interpretation of Sainsbury’s public guidance. Arial
      fallback; no private Fable runtime or brand font assets.
    </footer>
    <script>
      const days = [
        {
          label: "Monday",
          slots: [
            ["09:00–10:00", 1, true],
            ["12:00–13:00", 0, true],
            ["17:00–18:00", 2, false],
          ],
        },
        {
          label: "Tuesday",
          slots: [
            ["09:00–10:00", 0, false],
            ["12:00–13:00", 1, true],
            ["17:00–18:00", 1, true],
          ],
        },
        {
          label: "Wednesday",
          slots: [
            ["09:00–10:00", 0, true],
            ["12:00–13:00", 0, true],
            ["17:00–18:00", 2, true],
          ],
        },
      ];
      let day = 0,
        slot = 0;
      const $ = (id) => document.getElementById(id);
      function update() {
        const choice = days[day].slots[slot];
        $("selection").textContent = days[day].label + ", " + choice[0];
        $("fee").textContent =
          choice[1] === 0 ? "No collection fee" : "£" + choice[1].toFixed(2);
        $("result").hidden = true;
      }
      function render() {
        $("dates").replaceChildren(
          ...days.map((d, i) => {
            let b = document.createElement("button");
            b.textContent = d.label;
            b.setAttribute("aria-pressed", i === day);
            b.onclick = () => {
              day = i;
              slot = d.slots.findIndex((s) => s[2]);
              render();
            };
            return b;
          }),
        );
        $("slotLabel").textContent = days[day].label + " collection times";
        $("slots").replaceChildren(
          ...days[day].slots.map((s, i) => {
            let l = document.createElement("label");
            l.className = "slot";
            let input = document.createElement("input");
            input.type = "radio";
            input.name = "time";
            input.checked = i === slot;
            input.disabled = !s[2];
            input.onchange = () => {
              slot = i;
              update();
            };
            let text = document.createElement("span");
            text.textContent = s[0];
            let fee = document.createElement("strong");
            fee.textContent = s[2]
              ? s[1] === 0
                ? "No fee"
                : "£" + s[1].toFixed(2)
              : "Unavailable";
            l.append(input, text, fee);
            return l;
          }),
        );
        update();
      }
      $("review").onclick = () => {
        $("result").hidden = false;
        $("result").textContent =
          "Local selection ready: " +
          $("selection").textContent +
          ". No slot has been reserved.";
      };
      render();
    </script>
  </body>
</html>

Referência de código

  • Não é necessário ter um pacote privado nem credenciais.
04

Sistema de design Sainsbury's Configuração do agente

Ponto de partida para implementação

O acesso ao pacote Fable é independente deste estudo público e autossuficiente.

sh
# Save the complete HTML example as index.html
python3 -m http.server 8080
# Open http://localhost:8080

Um prompt para seu projeto

Prompt para agente de IA
Crie, com base neste exemplo completo de HTML, um seletor de horários para coleta inspirado nas orientações da Sainsbury’s. Mantenha uma única paleta de marca, texto preto na ação laranja, botões de opção nativos identificados, uma área de interação de 48px e a escolha explícita do layout de 768px. Limpe as mensagens de revisão sempre que a seleção mudar. Use disponibilidade fictícia e não alegue que há um ambiente de execução do Fable ou uma reserva confirmada.
05

Sistema de design Sainsbury's Fontes e escopo

Estudo de aplicação de OpenDesign baseado nas orientações públicas da Sainsbury’s. Esta é uma implementação original de HTML, não o ambiente de execução privado do Fable. Ela usa Arial, em vez de redistribuir os arquivos de Mary Ann, e apresenta horários e taxas de coleta fictícios.