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.
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.
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.
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.
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
Aa — Contorno, e una cosa piena
Aa — Contorno, e una cosa piena
Aa — Contorno, e una cosa piena
Aa — Contorno, e una cosa piena
Aa — Contorno, e una cosa piena
Aa — Contorno, e una cosa piena
Aa — Contorno, e una cosa piena
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
Avatar
Campi
Messaggi
Card, stato vuoto, scheletro
Ancora nessun video
Carica il primo e comparirà qui, insieme alle sue statistiche.
Riga
Un risultato di ricerca
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
- Nessun colore fuori da
tokens.css. Se manca una sfumatura, si aggiunge lì e la si deriva da un'ancora concolor-mix. Un foglio di pagina fa layout, mai colore. - 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.
-
--accentriempie,--accent-inkscrive. Vale anche per--danger,--successe--warning: il riempimento è per una forma, l'inchiostro per una parola. - La superficie è disegnata dall'hairline, non da un riempimento pesante e non da un'ombra. L'ombra è solo di ciò che galleggia.
- Il componente esiste già. Prima di scrivere un bordo e
un raggio in una pagina, cercalo in
primitives.css. - 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-pressedoltre al tratto. - Il contrasto è un test, non un'opinione.
tests/test_accent_contrast.mjsmisura ogni coppia su tutti e tre i fondi: un preset che smette di essere leggibile è una build rossa. - 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à.
- Le cifre sono
.num. Contatori, timecode, durate e saldi in cifre tabulari, così non ballano mentre salgono.