Skip to content

Design System — Palette & Icons / Palette & Icônes

Update date : 2026-05-20 20:49

Color system, tokens, dark mode, CSS variables, icon registry, and spacing. Système de couleurs, tokens, dark mode, variables CSS, registre d'icônes et espacement.


Palette system / Système de palette

from pinky_streamlit import PALETTES, Palette, PaletteColors

Pre-built palettes / Palettes pré-construites

Six palettes available out of the box. / Six palettes disponibles nativement.

Palette Primary Secondary Tertiary
PALETTES.PYTHIA #60defb cyan #7056d7 violet #e07baa rose
PALETTES.ANTHROPIC #d97756 terracotta #4a8c8c teal #c9a07a sand
PALETTES.STREAMLIT #ff4b4b red #0068c9 blue #09ab3b green
PALETTES.APPLE #0066cc blue #ff9900 orange #9900cc purple
PALETTES.GITHUB #0969da blue #2da44e green #9a3ecb purple
PALETTES.PYTHON #3776ab blue #ffd43b yellow #1e415e dark blue
messages, main, df = setup_page(session, loaders=[...], palette=PALETTES.PYTHIA)

# Access individual colors / Accéder aux couleurs individuelles
color = PALETTES.PYTHIA.light.primary  # "#60defb"
dark  = PALETTES.PYTHIA.dark.primary   # auto-computed if dark=None

Color tokens / Tokens de couleur

Each palette defines 7 semantic tokens. / Chaque palette définit 7 tokens sémantiques.

Token Role
primary Main brand accent, primary actions, links / Accent de marque principal, actions primaires, liens
secondary Second accent / Deuxième accent
tertiary Third accent / Troisième accent
success Success states (default #09ab3b) / États de succès
warning Warning states (default #ffa421) / États d'avertissement
error Error states (default #ff4b4b) / États d'erreur
grey Neutral text, secondary icons (default #535353) / Texte neutre, icônes secondaires

Color shades / Nuances de couleur

CSS computes 4 shades from each base token via color-mix(in oklch, ...). / Le CSS calcule 4 nuances depuis chaque token de base via color-mix(in oklch, ...).

Shade Light mode Dark mode Usage
darkest base + black 50% base + white 30% Maximum contrast titles / Titres à contraste max
darker base + black 25% base + white 15% Body text, main titles / Texte courant, titres principaux
default base color boosted luminosity Accents, icons, buttons / Accents, icônes, boutons
lighter base + white 90% base + black 80% Backgrounds: pills, badges, secondary buttons / Fonds : pills, badges, boutons secondaires

Custom palette / Palette personnalisée

from pinky_streamlit import Palette, PaletteColors

# Auto-compute dark variant from light / Auto-calculer la variante dark depuis light
MY_PALETTE = Palette(
    light=PaletteColors(primary="#6200ea", secondary="#00bcd4", tertiary="#76ff03"),
)

# Full dark control / Contrôle total du dark
MY_PALETTE = Palette(
    light=PaletteColors(primary="#6200ea", secondary="#00bcd4", tertiary="#76ff03"),
    dark=PaletteColors( primary="#b388ff", secondary="#80deea", tertiary="#ccff90"),
)

# Extend pre-built palettes via subclassing / Étendre via héritage
from pinky_streamlit import PALETTES

class AppPalettes(PALETTES):
    MY_BRAND = Palette(
        light=PaletteColors(primary="#6200ea", secondary="#00bcd4", tertiary="#76ff03"),
    )

CSS variables / Variables CSS

setup_page() injects palette colors as CSS custom properties after loading style.css. / setup_page() injecte les couleurs de la palette comme propriétés CSS personnalisées après le chargement de style.css.

Color variables / Variables couleur

--primary-default    --primary-darker    --primary-darkest    --primary-lighter
--secondary-default  --secondary-darker  --secondary-darkest  --secondary-lighter
--tertiary-default   --tertiary-darker   --tertiary-darkest   --tertiary-lighter
--success-default    --warning-default   --error-default      --grey-default

Dark mode is handled automatically by the @media (prefers-color-scheme: dark) block. / Le dark mode est géré automatiquement par le bloc @media (prefers-color-scheme: dark).

Layout variables / Variables de mise en page

Variable Light Dark Usage
--app-bg #ffffff #0e1117 App background / Fond de l'app
--app-text #3E4264 #e0e0e0 Default text / Texte par défaut
--sidebar-background #f7f7f7 #1a1a1a Sidebar background / Fond sidebar
--grey-lightest-1 #f7f7f7 #2a2a2a Secondary background / Fond secondaire

Never hardcode background: white or background: #ffffff. Use var(--app-bg) to follow the active theme. / Ne jamais coder en dur background: white ou background: #ffffff. Utiliser var(--app-bg) pour suivre le thème actif.

Spacing tokens / Tokens d'espacement

Token Value Usage
--space-xs 0.25rem Minimal gaps / Espaces minimaux
--space-sm 0.5rem Small spacing / Petits espacements
--space-md 1rem Standard spacing / Espacement standard
--space-lg 1.5rem Sections, cards / Sections, cartes
--space-xl 2.5rem Major separations / Séparations majeures
--space-2xl 4rem Empty states, hero sections
--radius-sm 8px Buttons, small elements / Boutons, petits éléments
--radius-md 12px Cards, containers / Cartes, containers
--radius-lg 20px KPI cards, metrics
--radius-pill 999px Pills, badges
--radius-circle 50% Round buttons, icons / Boutons ronds, icônes

Key naming conventions / Conventions de nommage des keys

The CSS design system targets Streamlit elements by their key attribute. / Le système de design CSS cible les éléments Streamlit par leur attribut key.

# Buttons / Boutons
key="btn-{type}-{accent}-{name}"
# Types: primary | secondary | tertiary | square

# Containers
key="container-{accent}-{shade}-{name}"

# Tables
key="table-{accent}-{name}"
# Examples / Exemples
st.button("Save", key="btn-primary-primary-save", icon=str(ICONS.SAVE))
st.button("Cancel", key="btn-secondary-grey-cancel", icon=str(ICONS.CLOSE))
st.button("", key="btn-tertiary-error-delete", icon=str(ICONS.DELETE))

with st.container(border=True, key="container-success-lighter-summary"):
    st.write("Summary card")

with st.container(key="table-primary-devices"):
    st.dataframe(df)

Dark mode

Dark mode is handled entirely in CSS via @media (prefers-color-scheme: dark). No Python code needed. / Le dark mode est entièrement géré en CSS via @media (prefers-color-scheme: dark). Aucun code Python nécessaire.

st.context.theme is None in SiS — dark mode detection is not available from Python. / st.context.theme est None en SiS — la détection du dark mode n'est pas disponible côté Python.

Images with light/dark variants / Images avec variantes light/dark

Provide two image files and toggle via CSS. / Fournir deux fichiers image et basculer via CSS.

with st.sidebar:
    with st.container(key="img-title-light"):
        st.image(app_logo_light, width=165)
    with st.container(key="img-title-dark"):
        st.image(app_logo_dark, width=165)
.st-key-img-title-dark { display: none; }

@media (prefers-color-scheme: dark) {
    .st-key-img-title-light { display: none; }
    .st-key-img-title-dark  { display: block; }
}

st.image() does not support key= in SiS — hence the st.container(key=...) wrapper. / st.image() ne supporte pas key= en SiS — d'où l'enveloppe st.container(key=...).

Plotly charts in dark mode / Charts Plotly en dark mode

Since the theme cannot be detected from Python, use mid-grey values visible in both modes. / Comme le thème ne peut pas être détecté depuis Python, utiliser des gris moyens visibles dans les deux modes.

Usage Color
Donut remaining portion #dbdbdb
Donut center text #888888
Y-axis gridlines #888888
Data editor highlight #d0d0d0

Icons — ICONS registry / Registre d'icônes

from pinky_streamlit import ICONS, Icon

Each icon has two variants: a Material Symbol for Streamlit UI elements, and an emoji for dataframe columns. / Chaque icône a deux variantes : un Material Symbol pour les éléments UI Streamlit, et un emoji pour les colonnes dataframe.

ICONS.SUCCESS.material   # ":material/check_circle:"  — for buttons, badges, headers
ICONS.SUCCESS.emoji      # "✅"                        — for dataframe columns
str(ICONS.SUCCESS)       # ":material/check_circle:"  — shortcut for .material

Material icons (:material/xxx:) are not rendered in st.dataframe / st.data_editor. Use .emoji for table columns. / Les Material icons ne sont pas rendues dans st.dataframe / st.data_editor. Utiliser .emoji pour les colonnes de tableau.

Available icons / Icônes disponibles

Category / Catégorie Icons / Icônes
Navigation & layout HOME DASHBOARD WIDGETS SETTINGS ADMIN FILTER SORT SEARCH EXPAND COLLAPSE BACK FORWARD ARROW_RIGHT LINK PIN TAG COPY
Status & feedback SUCCESS WARNING ERROR INFO HELP LEGEND UNDEFINED CELEBRATION BLOCKED DO_NOT_DISTURB CHECK CANCEL FLAG STAR SKULL NOTIFICATION SATISFIED NEUTRAL DISSATISFIED
Actions ADD ADD_ROW EDIT EDIT_COLUMN DELETE SAVE CLOSE REFRESH SYNC PLAY PAUSE STOP EXECUTE MANUAL TRIGGERED SP_PARAMS LOCK UNLOCK VISIBLE HIDDEN
Files & data DOWNLOAD UPLOAD CLOUD_UPLOAD FILE FOLDER TABLE TABLE_EDIT TABLE_READONLY OUTPUT
Content ARTICLE IMAGE CHAT CARDS MAIL
Users & org USER USERS BUILDING COMPANY
Analytics & time ANALYTICS CHART CHARTS TIMELINE TRENDING_UP TRENDING_DOWN CALENDAR CLOCK HISTORY UPDATE
Finance MONEY RECEIPT

App-specific icons / Icônes spécifiques à l'app

Subclass ICONS to add app-specific icons without modifying the kit. / Hériter de ICONS pour ajouter des icônes spécifiques sans modifier le kit.

from pinky_streamlit import ICONS, Icon

class MyIcons(ICONS):
    SMARTPHONE = Icon(":material/smartphone:", "📱")
    LAPTOP     = Icon(":material/laptop:",     "💻")

# Use throughout the app / Utiliser dans toute l'app
icon = MyIcons.SMARTPHONE.material  # ":material/smartphone:"

MATERIAL_ICONS (backward compat / compat ascendante)

MATERIAL_ICONS is a flat dict[str, str] mapping string keys to material icon strings. Deprecated — migrate to ICONS.<NAME>.material. / MATERIAL_ICONS est un dict[str, str] plat. Déprécié — migrer vers ICONS.<NAME>.material.

# Old / Ancien
MATERIAL_ICONS["save"]   # ":material/save:"

# New / Nouveau
str(ICONS.SAVE)          # ":material/save:"

Palette generator tool / Outil de génération de palette

Available in pinky-studiopinky-and-co.github.io/pinky-studio/pages/palette-title-generator/ Open in a browser outside Snowflake. / Ouvrir dans un navigateur en dehors de Snowflake.

Features / Fonctionnalités : 1. Signature color → pick a base color / Choisir une couleur de base 2. Harmonies → complementary, triadic, analogous, split-comp — generates primary, secondary, tertiary via OKLCH 3. Reassignment → drag & drop to reassign color roles / Glisser-déposer pour réattribuer les rôles 4. Semantic → edit success, warning, error, grey independently / Editer indépendamment 5. App title → text + emoji + font choice (Syne, Bebas Neue, Space Grotesk…) 6. Export → 6 PNG (light/dark × Apple/Twemoji/Noto) + CSS and Python code ready to use / 6 PNG + code CSS et Python prêt à l'emploi

Dark mode is auto-computed via OKLCH inversion. / Le dark mode est calculé automatiquement via inversion OKLCH.