Prova gratis 14 giorni
Accedi

Design system

Contorno, e una cosa piena

Il logo è tre lettere monoline e un solo triangolo pieno. Il sistema fa la stessa cosa: le superfici sono disegnate da un tratto da 1px, e un solo elemento per schermata è riempito con l'accento — l'azione primaria, oppure il live, oppure la voce di navigazione attiva. Due riempimenti nella stessa vista vogliono dire che uno dei due è sbagliato.

Questa pagina è l'eccezione dichiarata: mostra i pezzi tutti insieme, e quindi mostra più di un riempimento alla volta.

Cambia il tema, l'accento o il carattere e la pagina intera si ridisegna, chrome compreso. La scelta resta in questo indirizzo: non tocca né i tuoi cookie né il tuo account.

Il marchio, e la regola che ne discende

Il logotipo è un PNG a viola fisso — un marchio non si ricolora per utente — e ha due varianti, una per fondo scuro e una per fondo pallido. La seconda vale anche per il tema mar7yyy, che ha la carta chiara: è una delle due sole regole che nominano un tema fuori da tokens.css.

Il triangolo del logotipo torna da solo come .marker: è l'unico segno «questo qui» del prodotto — voce di menu attiva, canale in diretta, segmento corrente. Non è mai decorativo.

Colore

src/styles/tokens.css è l'unico posto in cui esiste un colore. Fuori da lì nessun file scrive un valore: se manca una sfumatura si aggiunge lì e la si deriva da un'ancora con color-mix. I valori qui sotto sono letti dallo stile calcolato della pagina, non ricopiati.

Ancore di brand

--brand-midnight l'ancora: da qui nasce la rampa chiara e l'icona
--brand-night il fondo del tema scuro, più cupo e meno tinto
--brand-grape il tratto forte sul fondo scuro
--brand-violet il viola del marchio, e l'accento predefinito
--brand-mint il verde del marchio, riusato come success
--media-frame la cornice di un video, in tutti i temi

Le ancore dell'identità mar7yyy

L'unico posto in cui questi quattro valori esistono. Prefissati --m7- e non --brand-, che è di MART. La terracotta è circa 2:1 come testo sulla crema: è un riempimento e un bordo, e non è mai una parola.

--m7-cream la carta dell'identità mar7yyy
--m7-slate l'inchiostro in cui è disegnato il marchio
--m7-terracotta il riempimento caldo — mai una parola
--m7-clay l'argilla: il colore caldo quando va letto

Superfici e linee

Fondo e superficie sollevata stanno vicini di proposito: la card è disegnata dall'hairline, non da un cambio di riempimento. Nei temi scuro e chiaro sono tinte con l'accento scelto, così scegliere un colore cambia la pagina e non soltanto i bottoni; nel tema mar7yyy sono letterali, perché sono la carta di quell'identità.

--ground il fondo della pagina
--ground-inset campi, incassi, intestazioni di tabella
--raised card e pannelli
--raised-hover la stessa superficie sotto il puntatore
--line hairline: il device strutturale del sistema
--line-strong hairline enfatizzato — bordi di controlli
--scrim il velo sotto una modale

Inchiostro

testo primario — Aa Bb Cc 0123456789 --ink

testo secondario, prosa — Aa Bb Cc 0123456789 --ink-2

terziario: date, conteggi, disabilitato — Aa Bb Cc 0123456789 --ink-3

l'accento quando è testo o tratto — Aa Bb Cc 0123456789 --accent-ink

L'accento: riempimento o tratto, mai lo stesso valore

Ogni preset è composto da valori verificati e non da matematica a runtime, perché la divisione non è cosmetica: i preset chiari sono quasi invisibili come tratto su una pagina bianca — la menta su bianco è 1,7:1. Quindi --accent riempie e --accent-ink scrive.

Riempimento

background: var(--accent); color: var(--on-accent) un solo elemento per schermata

Linea o parola

color: var(--accent-ink); border-color: var(--accent-ink) quante volte serve
--accent il riempimento, e solo quello
--on-accent testo e icone sopra quel riempimento
--accent-ink l'accento come linea, glifo o parola
--accent-wash una superficie appena tinta (12%)
--accent-wash-strong la stessa, marcata (22%)
--accent-line un bordo tinto senza diventare accento

I sei preset

Ognuno è uno scope data-accent annidato: sono loro stessi, non quello scelto in alto. È lo stesso meccanismo con cui il nome di un autore in chat porta il proprio colore dentro una pagina dipinta in un altro.

attivo violet
attivo mint
attivo sky
attivo amber
attivo rose
attivo lime

Ruoli di stato

Un valore per ruolo. C'erano sei rossi diversi. --live è uno stato di trasmissione e non una preferenza: non segue mai l'accento.

accent danger success warning live

l'errore quando è una frase — Aa Bb Cc 0123456789 --danger-ink

la conferma quando è una frase — Aa Bb Cc 0123456789 --success-ink

l'avviso quando è una frase — Aa Bb Cc 0123456789 --warning-ink

Stessa divisione dell'accento e per lo stesso motivo: --danger come testo è 3,05:1 su bianco, quindi un messaggio di errore usa --danger-ink. Il riempimento è per una forma piena, l'inchiostro per un glifo o una riga di testo.

Grafici

Deliberatamente non l'accento: l'accento è una preferenza personale, un grafico deve voler dire la stessa cosa su ogni account. I tre slot categoriali servono solo quando le serie sono il soggetto.

--chart-ink la serie unica — quasi tutti i grafici qui
--chart-1 categoriale 1
--chart-2 categoriale 2
--chart-3 categoriale 3
--chart-grid la griglia: un hairline, mai un segno

I due tag riservati

#mart è il viola del marchio qualunque accento abbia scelto chi legge: è il segno della piattaforma, non un elemento tematizzato. #ceoofmart è l'arcobaleno, e l'arcobaleno è i sei preset in ordine di tinta. Il colore sta sul testo, la luce che passa sta sulla pillola.

#mart #ceoofmart #gaming

Tipografia

Tre token e nient'altro: --font-display per i titoli, --font-ui per l'interfaccia, --font-mono per i numeri. Ogni regola font-family del prodotto passa da qui, ed è per questo che un set di caratteri è un solo attributo e zero CSS nuovo.

--font-display titoli e display
--font-ui il 90% del prodotto
--font-mono cifre a larghezza fissa

Un set di caratteri ridefinisce due token e nulla più: nessuna dimensione, nessun peso, nessuna interlinea. Quelli sono tarati sulla scala qui sotto, e un set che li spostasse sarebbe un secondo design system invece di una scelta di carattere. --font-mono resta fuori in quattro set su cinque: compone contatori e timecode, e una faccia proporzionale lì fa ballare la larghezza mentre il numero sale.

Scala

Aa — Contorno, e una cosa piena

--text-xs badge, timecode

Aa — Contorno, e una cosa piena

--text-sm meta, didascalie

Aa — Contorno, e una cosa piena

--text-base il default dell'interfaccia

Aa — Contorno, e una cosa piena

--text-md paragrafo di apertura

Aa — Contorno, e una cosa piena

--text-lg titolo di card

Aa — Contorno, e una cosa piena

--text-xl titolo di sezione

Aa — Contorno, e una cosa piena

--text-2xl titolo di pagina

Aa — Contorno, e una cosa piena

--text-3xl display, solo la landing

Da --text-xl in su la misura è un clamp(): cresce con la finestra invece di scattare a un breakpoint.

Interlinea e crenatura

--leading-tight titoli
--leading-snug titoli lunghi, card
--leading-normal prosa
--tracking-tight i titoli, da --text-lg in su
--tracking-wide solo l'eyebrow maiuscolo

Eyebrow e numeri

Eyebrow · l'unico maiuscolo del sistema

Testo di interfaccia, dove vive quasi tutto questo prodotto. Un link dentro la prosa resta sottolineato, perché il colore da solo non è un segnale accessibile.

1.204.887

.num mette la faccia monospaziata e le cifre tabulari: un contatore che sale da 999 a 1.000 non deve cambiare larghezza.

Spazio

Base 4px, nove gradini. Non ce n'è un decimo.

--space-1
--space-2
--space-3
--space-4
--space-5
--space-6
--space-7
--space-8
--space-9

Raggi

Generosi, come le lettere superellittiche del logotipo.

control bottoni, campi, chip quadrati
card card e riquadri
panel pannelli e modali
pill chip, badge, avatar

Elevazione

Solo ciò che galleggia sopra la pagina ha un'ombra. Tutto il resto è disegnato da --line. Se stai per scrivere un box-shadow su una card, la card non ne ha bisogno.

--shadow-popover popover e menu
--shadow-modal modali e fogli

Movimento

Tre durate e una sola curva. Passa il puntatore sui bottoni più sotto per vedere --dur-micro: è quasi tutto il movimento che c'è.

--dur-micro hover, focus, un colore che cambia
--dur-base apertura di un pannello, un accordion
--dur-overlay modali e fogli
--ease l'unica curva del sistema

Livelli

Una pila sola, sette pioli. Un z-index scritto a mano da qualche parte è un bug che aspetta.

--z-raised un elemento sollevato nel flusso
--z-sticky intestazioni appiccicate
--z-pip il player agganciato in un angolo
--z-nav barra in alto e tab bar
--z-overlay popover, menu, toast di sistema
--z-modal modali
--z-toast i toast, sopra tutto

Layout

--nav-h la barra in alto
--tab-bar-h la tab bar del telefono
--page-max la larghezza massima di una pagina
--prose-max la misura di un testo lungo
--chat-w la colonna della chat live
--focus-ring lo spessore dell'anello di focus
--bottom-inset quanto fondo schermo è coperto dal chrome

I breakpoint sono 640 / 900 / 1200. Non sono token: una custom property non si può usare in una media query, quindi vivono in un commento di tokens.css e in nessun altro posto. Se ne serve un quarto, la cosa da cambiare è il disegno.

Componenti

Il vocabolario condiviso sta in src/styles/primitives.css. Ogni bottone, card, campo, badge, modale e stato vuoto del prodotto è uno di questi: non esiste il ri-stile a livello di pagina. Se ti trovi a scrivere un border-radius e un border in un foglio di pagina, la cosa che vuoi è già lì dentro.

Bottoni

.btn--primary è l'unico riempimento pieno: su una pagina live quel ruolo passa al badge del live, e allora il bottone primario non c'è.

Chip e controllo segmentato

Badge

Neutro Accent Verificato In revisione Segnalato Live

Avatar

Campi

Massimo 120 caratteri.
Serve un indirizzo email valido.

Messaggi

Card, stato vuoto, scheletro

Live 12:04

Come si costruisce una community da zero

nome_creator 1.204 visualizzazioni

Ancora nessun video

Carica il primo e comparirà qui, insieme alle sue statistiche.

Riga

03:41

Un risultato di ricerca

2 giorni · 88 visualizzazioni

Icone

Uno sprite inline, colore ereditato da currentColor: seguono il tema e l'accento senza una riga di JavaScript. Prima erano 139 PNG in due set scambiati da un MutationObserver.

Le regole della casa

  1. Nessun colore fuori da tokens.css. Se manca una sfumatura, si aggiunge lì e la si deriva da un'ancora con color-mix. Un foglio di pagina fa layout, mai colore.
  2. Un solo riempimento d'accento per schermata. È l'azione primaria, oppure il live, oppure la voce attiva. Due vogliono dire che uno dei due è sbagliato.
  3. --accent riempie, --accent-ink scrive. Vale anche per --danger, --success e --warning: il riempimento è per una forma, l'inchiostro per una parola.
  4. La superficie è disegnata dall'hairline, non da un riempimento pesante e non da un'ombra. L'ombra è solo di ciò che galleggia.
  5. Il componente esiste già. Prima di scrivere un bordo e un raggio in una pagina, cercalo in primitives.css.
  6. Il colore da solo non è un segnale. Un link nella prosa è sottolineato, un errore ha un'icona oltre al rosso, uno stato attivo ha aria-pressed oltre al tratto.
  7. Il contrasto è un test, non un'opinione. tests/test_accent_contrast.mjs misura ogni coppia su tutti e tre i fondi: un preset che smette di essere leggibile è una build rossa.
  8. Il tema mar7yyy è un'identità intera, non un settimo accento: porta la propria carta, il proprio riempimento e i propri caratteri, e per questo è l'unico che sovrascrive accento e set. Mezza identità non è un'identità.
  9. Le cifre sono .num. Contatori, timecode, durate e saldi in cifre tabulari, così non ballano mentre salgono.