Design system

Calm by default, precise underneath.

How this site is designed: a handful of tokens, three typefaces, one column, a small set of icons and motion that stays out of the way.

PrincípiosPrinciples

Texto primeiro, ornamento nunca. Cada decisão visual tem de ser explicável em uma frase, e cada valor vive em um único lugar.Text first, ornament never. Every visual decision has to be explainable in a sentence, and every value lives in exactly one place.

  • Clareza sobre abstração. Poucos componentes, nomes descritivos, nada de utilitários genéricos.Clarity over abstraction. Few components, descriptive names, no generic utilities.
  • Uma fonte para cada valor. Cores e espaçamentos em styles.css, horários e idiomas em boot.js, textos em i18n.js.One source for each value. Colours and spacing in styles.css, hours and languages in boot.js, copy in i18n.js.
  • Funciona sem enfeite. Sem JavaScript, o texto em inglês está no HTML. Sem animação, tudo aparece de uma vez.Works without the decoration. Without JavaScript the English text is in the HTML. Without animation everything simply appears.

CorColour

A paleta é de papel e tinta: quatro tokens, dois temas. Os temas trocam sozinhos pelo relógio do visitante, escuro das 18h às 6h.The palette is paper and ink: four tokens, two themes. The theme switches by the visitor’s own clock, dark from 18:00 to 06:00.

TokenClaroLightEscuroDarkUsoUse
--paper#f3f1ec#0d0d0cFundo da página.Page background.
--ink#141413#ebe9e3Texto, traços, ícones e o logo.Text, strokes, icons and the logo.
--muted#6c6a65#8f8c86Texto secundário.Secondary text.
--linergba(20, 20, 19, 0.12)rgba(235, 233, 227, 0.12)Filetes e bordas de 1px.1px rules and borders.

Não há cor de destaque. A hierarquia vem de peso, tamanho e do contraste entre tinta e texto secundário. A única exceção são o verde e o vermelho de estado (permitido e bloqueado) nas Notas de AWS.There is no accent colour. Hierarchy comes from weight, size and the contrast between ink and muted text. The only exception is the green and red of state (allowed and blocked) in the AWS notes.

TipografiaTypography

Geist · texto e títulostext and headings

Engenharia de software, feita com calma.Software engineering, built calmly.

Instrument Serif · ênfaseemphasis

precisão silenciosa.quiet precision.

Geist Mono · rótuloslabels

Hora local · 20:42 · noiteLocal time · 20:42 · night

O corpo usa 17px com entrelinha 1,65. Títulos têm espaçamento negativo (−0,02em a −0,035em). Qualquer <em> vira serifa itálica; é a única forma de ênfase do site.Body text is 17px on a 1.65 line height. Headings are tightened (−0.02em to −0.035em). Any <em> becomes italic serif; it is the site’s only form of emphasis.

LayoutLayout

Uma coluna de leitura centralizada de 40rem para texto corrido, dentro de um contêiner largo de 72rem para cabeçalho e rodapé. O respiro lateral é --gutter, que cresce com a tela. Seções são separadas por um filete de 1px, não por caixas.A single centred reading column of 40rem for prose, inside a 72rem wide container for header and footer. Side padding is --gutter, which grows with the screen. Sections are separated by a 1px rule, not by boxes.

  • --column · 40rem
  • --wide · 72rem
  • --gutter · clamp(20px, 4vw, 48px)

Páginas internas têm botões de voltar logo abaixo do cabeçalho: um para a tela anterior e um para o início.Inner pages have back buttons right under the header: one for the previous screen and one for Home.

Toda página de conteúdo tem uma legenda lateral: a lista de seções da página, fixa ao rolar, com a seção atual destacada. Em telas pequenas ela se recolhe atrás do botão “Seções”. Na lista de Notas, a legenda lista as próprias notas.Every content page has a side navigation: the list of the page’s sections, sticky while scrolling, with the current section highlighted. On small screens it collapses behind a “Sections” button. On the Notes index, it lists the notes themselves.

<div class="page-layout">
  <aside class="side-nav" id="side-nav">…</aside>
  <article class="reading-column">…</article>
</div>

Assim que o visitante rola para além da área do hero, aparece um botão redondo no canto inferior direito que volta ao topo da página. Ele e o botão “Seções” são criados pelo main.js, então o HTML não precisa repetir nada.As soon as the visitor scrolls past the hero area, a round button appears in the bottom-right corner that returns to the top of the page. It and the “Sections” button are created by main.js, so the HTML does not repeat them.

ÍconesIcons

Sem emoji e sem biblioteca de ícones. O conjunto é desenhado na mesma grade 32×32 do logo: só traço, sem preenchimento, pontas arredondadas, cor herdada do texto (currentColor). Cada ícone nomeia um conceito (um bucket é um balde, um load balancer é uma balança) e nada além disso.No emoji and no icon library. The set is drawn on the same 32×32 grid as the logo: stroke only, no fill, round caps, colour inherited from the text (currentColor). Each icon names one concept (a bucket is a pail, a load balancer is a scale) and nothing more.

<svg class="icon" aria-hidden="true"><use href="#i-globe"/></svg>

MovimentoMotion

Movimento é só um fade-up suave ao carregar e ao rolar (16px, 0,9s, curva ease-out expo) e uma transição cruzada na troca de idioma. É feito com Motion. Se o visitante prefere menos movimento, ou a biblioteca não carrega, a página aparece inteira sem animação.Motion is just a soft fade-up on load and on scroll (16px, 0.9s, ease-out expo) and a cross-fade when the language changes. It is built with Motion. If the visitor prefers reduced motion, or the library fails to load, the page shows everything without animation.

Tema e hora localTheme and local time

O tema é definido em <head> por boot.js, antes da primeira pintura, para não haver flash. Depois, main.js confere o relógio a cada 15 segundos e faz uma transição de 1,2s quando cruza 6h ou 18h. O rodapé mostra a hora local e o período do dia.The theme is set in <head> by boot.js, before first paint, so there is no flash. Then main.js checks the clock every 15 seconds and cross-fades over 1.2s when it crosses 06:00 or 18:00. The footer shows the local time and day period.

Além do claro/escuro por horário, o botão no cabeçalho troca o tema de design (padrão ou Estúdio). Veja a nota “Tema do site”.Besides the light/dark by time of day, the header button switches the design theme (default or Studio). See the “Site theme” note.

Os scripts são clássicos, não módulos, então o site também funciona aberto direto do disco (file://).Scripts are classic, not modules, so the site also works when opened straight from disk (file://).

IdiomaLanguage

Inglês e português do Brasil. A primeira visita segue o idioma do navegador; depois vale a escolha salva. Os textos ficam em i18n.js, ligados ao HTML por data-i18n. Em páginas longas, como as Notas de AWS, os dois idiomas ficam no HTML e o CSS esconde o inativo.English and Brazilian Portuguese. The first visit follows the browser language; after that the saved choice wins. Copy lives in i18n.js, wired to the HTML with data-i18n. On long pages, like the AWS notes, both languages sit in the HTML and CSS hides the inactive one.

Convenções de códigoCode conventions

  • Nada dependente do tempo é fixo no código: ano, hora e período vêm do relógio do visitante.Nothing time-dependent is hardcoded: year, time and day period come from the visitor’s clock.
  • Nenhum erro é engolido em silêncio: todo catch se recupera de forma definida e registra o motivo.No error is swallowed silently: every catch recovers in a defined way and logs why.
  • Nomes descritivos, como .site-header, .reading-column, data-animate-reveal.Descriptive names, such as .site-header, .reading-column, data-animate-reveal.
  • Sem etapa de build e sem node_modules: HTML, CSS e JavaScript simples.No build step and no node_modules: plain HTML, CSS and JavaScript.