ЁЯО╜ рдзрдбрд╛ 08 тАФ Design systems рдЖрдгрд┐ tokens: рд╢рд╛рд│реЗрдЪрд╛ рдЧрдгрд╡реЗрд╢
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 08 ┬╖ рдорд╛рдЧреАрд▓: lesson-07-frameworks ┬╖ рдкреБрдвреАрд▓: lesson-09-performance
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ07, рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд рдЕрдиреЗрдХ рд▓реЛрдХ рдмрджрд▓ рдХрд░рдд рдЕрд╕рддрд╛рдирд╛рд╣реА рдлрд▓рдХ рдПрдХрд╕рд╛рд░рдЦрд╛ рдХрд╕рд╛ рд░рд╛рд╣рддреЛ: design tokens (рдирд╛рд╡ рджрд┐рд▓реЗрд▓реЗ рдирд┐рд░реНрдгрдп), рдЕрдВрддрд░ рдЖрдгрд┐ рдЕрдХреНрд╖рд░рд╛рдВрд╕рд╛рдареА scales, рдЖрдгрд┐ token swap рдореНрд╣рдгреВрди dark mode.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдкрд╛рдЪ рд▓реЛрдХрд╛рдВрдирд╛ рдПрдХ рдлрд▓рдХ рджреНрдпрд╛ рдЖрдгрд┐ рдХреЛрдгрддреЗрд╣реА рдирд┐рдпрдо рджреЗрдК рдирдХрд╛, рддрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдкрд╛рдЪ рдирд┐рд│реЗ рд░рдВрдЧ, рд░рд╛рдЦрд╛рдбреАрдЪреНрдпрд╛ рдЪрд╛рд░ рдЫрдЯрд╛, 7px, 13px рдЖрдгрд┐ 18px рдЪреЗ рдЕрдВрддрд░, рдЖрдгрд┐ рдмрдЯрдгрд╛рдВрдЪреНрдпрд╛ рддреАрди рд╢реИрд▓реА рдорд┐рд│рддрд╛рдд. рдХрд╛рд╣реАрдЪ рдЪреВрдХ рдирд╛рд╣реА; рдлрдХреНрдд рдлрд▓рдХ рдкрд╛рдЪ рдлрд▓рдХрд╛рдВрд╕рд╛рд░рдЦрд╛ рджрд┐рд╕рддреЛ.
рдЧрдгрд╡реЗрд╢ рд╣реЗ рджреБрд░реБрд╕реНрдд рдХрд░рддреЛ ЁЯО╜. "рд╕рдЧрд│реЗ рдПрдХрдЪ рдХрдкрдбреЗ рдШрд╛рд▓рддрд╛рдд" рдЕрд╕реЗ рдирд╛рд╣реА, рддрд░ "рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрдгрдп рдПрдХрджрд╛рдЪ рдШреЗрддрд▓рд╛ рдЬрд╛рддреЛ рдЖрдгрд┐ рддреНрдпрд╛рд▓рд╛ рдирд╛рд╡ рджрд┐рд▓реЗ рдЬрд╛рддреЗ":
:root {
--bg: #f8fafc; --ink: #0f172a; --accent: #db2777;
--space-1: 6px; --space-2: 12px; --space-3: 20px;
--radius: 12px;
}
рдЖрддрд╛ stylesheet рдордзреНрдпреЗ рдХреБрдареЗрд╣реА #db2777 рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рдирд╛рд╣реА тАФ рддрд┐рдереЗ var(--accent)
рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рдЖрд╣реЗ. Token рдПрдХрджрд╛ рдмрджрд▓рд╛ рдЖрдгрд┐ рд╕рдВрдкреВрд░реНрдг рдлрд▓рдХ рдмрджрд▓рддреЛ. рдпрд╛ рдирд╛рд╡ рджрд┐рд▓реЗрд▓реНрдпрд╛
рдирд┐рд░реНрдгрдпрд╛рдВрдирд╛ design tokens рдореНрд╣рдгрддрд╛рдд, рдЖрдгрд┐ рддреА рд╕рдЧрд│реНрдпрд╛рдд рдЫреЛрдЯреА рдЙрдкрдпреЛрдЧреА design
system рдЖрд╣реЗ.
рд╕рдЧрд│реНрдпрд╛рдд рдЫрд╛рди рднрд╛рдЧ рдореНрд╣рдгрдЬреЗ dark mode ЁЯМЩ: рдкреНрд░рддреНрдпреЗрдХ component рд░рдВрдЧ рди рдорд╛рдЧрддрд╛
var(--bg) рдЖрдгрд┐ var(--ink) рдорд╛рдЧрддреЛ, рдореНрд╣рдгреВрди theme рдмрджрд▓рдгреЗ рдореНрд╣рдгрдЬреЗ рд╕рд╣рд╛ tokens
рдкреБрдиреНрд╣рд╛ рдард░рд╡рдгреЗ. рджреБрд╕рд░реА stylesheet рдирд╛рд╣реА. Elements рдмрджрд▓рдгрд╛рд░реА JavaScript рдирд╛рд╣реА. рд╕рд╣рд╛
рдУрд│реА.
рдЖрдгрд┐ рдлрд▓рдХ рд╡рд╛рдЪрдХрд╛рдЪрд╛ рджреЛрдирджрд╛ рдЖрджрд░ рдХрд░рддреЛ: рддреЛ system setting
(prefers-color-scheme) рдкрд╛рд│рддреЛ рдЖрдгрд┐ toggle рдиреЗ (<html> рд╡рд░рдЪрд╛ data-theme)
рддреА рдмрджрд▓реВ рджреЗрддреЛ, рдЬреА рдирд┐рд╡рдб localStorage рдордзреНрдпреЗ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд▓реА рдЬрд╛рддреЗ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart TB
tok[":root tokens тАФ --bg --ink --accent --space-2 --radius --font"]
comp["components only use var(--token) тАФ never a raw colour"]
sys["@media (prefers-color-scheme: dark) тЖТ redefine 6 tokens"]
user[':root[data-theme="dark"] тЖТ the toggle wins, saved in localStorage']
tok --> comp
tok --> sys --> comp
tok --> user --> comp
note["change --accent once тЖТ the whole board changes"]
тЭУ рдХрд╛рдп
- Token = рдирд╛рд╡ рджрд┐рд▓реЗрд▓рд╛ design рдирд┐рд░реНрдгрдп: рд░рдВрдЧ, рдЕрдВрддрд░рд╛рдЪреА рдкрд╛рдпрд░реА, radius, font,
shadow, motion рдЪрд╛ рдХрд╛рд▓рд╛рд╡рдзреА. CSS custom properties (
--name) рд╣реА рдореВрд│ рдкрджреНрдзрдд рдЖрд╣реЗ; design tools рдЖрдгрд┐ multi-platform systems рддреАрдЪ рдирд╛рд╡реЗ Figma, iOS рдЖрдгрд┐ Android рдХрдбреЗ export рдХрд░рддрд╛рдд. - рдЖрдХрдбреЗ рдирд╛рд╣реА, scales: рдЕрдВрддрд░ 6/12/20, рдЕрдХреНрд╖рд░реЗ 0.85/1/1.15/1.5rem. Scale рдордзреВрди рдирд┐рд╡рдбрд▓реНрдпрд╛рдиреЗ рд╢рдВрднрд░ рдЫреЛрдЯреЗ рдирд┐рд░реНрдгрдп рдЯрд│рддрд╛рдд.
- Theming: light palette
:rootрд╡рд░ рдард░рд╡рд╛; рдлрдХреНрдд рд░рдВрдЧрд╛рдВрдЪреЗ tokens@media (prefers-color-scheme: dark)рдЦрд╛рд▓реА рдЖрдгрд┐[data-theme="dark"]attribute рдЦрд╛рд▓реА рдкреБрдиреНрд╣рд╛ рдард░рд╡рд╛, рдореНрд╣рдгрдЬреЗ рд╕реНрдкрд╖реНрдЯ рдирд┐рд╡рдб рджреЛрдиреНрд╣реА рджрд┐рд╢рд╛рдВрдиреА рдЬрд┐рдВрдХрддреЗ. - Contrast рд╣рд╛ token рдЪрд╛рдЪ рднрд╛рдЧ рдЖрд╣реЗ: рдкреНрд░рддреНрдпреЗрдХ рдЬреЛрдбреА (bg рд╡рд░ ink, card рд╡рд░ muted) рдПрдХрджрд╛ 4.5:1 рд╕рд╛рдареА рддрдкрд╛рд╕рд╛ тАФ рдордЧ рдкреНрд░рддреНрдпреЗрдХ component рд▓рд╛ рдкрд╛рд╕ рд╣реЛрдгрд╛рд░реА рдирд┐рд╡рдб рд╡рд╛рд░рд╢рд╛рдиреЗ рдорд┐рд│рддреЗ (рдзрдбрд╛ 06).
- Design system = tokens + components + рд╡рд╛рдкрд░рд╛рдЪреЗ рдирд┐рдпрдо + рдПрдХ рдорд╛рд▓рдХ. Tokens рд╣реА рдкрд╣рд┐рд▓реА рдкрд╛рдпрд░реА рдЖрд╣реЗ рдЖрдгрд┐ рдЫреЛрдЯреНрдпрд╛ рдлрд▓рдХрд╛рд╕рд╛рдареА рдмрд╣реБрддреЗрдХ рдлрд╛рдпрджрд╛ рддреЗрдЪ рджреЗрддрд╛рдд.
- Utility CSS (Tailwind) рд╣реАрдЪ рд╡рд┐рд╕реНрдХрд│реАрдд рд╣реЛрдгреНрдпрд╛рдЪреА рдЕрдбрдЪрдг рд╡реЗрдЧрд│реНрдпрд╛ рдкреНрд░рдХрд╛рд░реЗ рд╕реЛрдбрд╡рддреЗ: token config рдордзреВрди рдмрдирд╡рд▓реЗрд▓реЗ classes. рдХрд▓реНрдкрдирд╛ рддреАрдЪ, рдкреГрд╖реНрдарднрд╛рдЧ рд╡реЗрдЧрд│рд╛.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рдПрдХрд╕рд╛рд░рдЦреЗрдкрдгрд╛ рд╣реЗ рдЕрд╕реЗ рд╡реИрд╢рд┐рд╖реНрдЯреНрдп рдЖрд╣реЗ рдЬреЗ users рдирд╛ "рд╣реЗ рдЪрд╛рдВрдЧрд▓реЗ рдмрдирд╡рд▓реЗ рдЖрд╣реЗ" рдЕрд╕реЗ рдЬрд╛рдгрд╡рддреЗ, рдЖрдгрд┐ token рдкрддреНрд░рдХ redesign рд▓рд╛ "300 рдард┐рдХрд╛рдгреА рдмрджрд▓ рдХрд░рд╛" рд╡рд░реВрди "рд╕рд╣рд╛ рдХрд┐рдорддреА рдмрджрд▓рд╛" рд╡рд░ рдЖрдгрддреЗ. Dark mode, brand рдмрджрд▓ рдЖрдгрд┐ accessibility рджреБрд░реБрд╕реНрддреНрдпрд╛ рд╕рдЧрд│реНрдпрд╛ рдПрдХрд╛ рдУрд│реАрдЪреА рдХрд╛рдореЗ рдмрдирддрд╛рдд.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
ui/styles.css рдЪрд╛ рд╡рд░рдЪрд╛ рднрд╛рдЧ: tokens рдЪрд╛ рдПрдХ :root
block, рдордЧ prefers-color-scheme рдЦрд╛рд▓рдЪрд╛ dark-mode override, рдордЧ рд╕реНрдкрд╖реНрдЯ
[data-theme="dark"] block. рдЦрд╛рд▓рдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рдпрдо var(--тАж) рд╡рд╛рдкрд░рддреЛ.
ui/app.js рдЪреНрдпрд╛ section 5 рдордзрд▓рд╛ toggle data-theme рд▓рд╛рд╡рддреЛ,
aria-pressed рдЙрд▓рдЯрд╡рддреЛ, рдЖрдгрд┐ рдирд┐рд╡рдб save рдХрд░рддреЛ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 ui/mock_api.py
# 1) one-line rebrand: change --accent to #0d9488 in styles.css, reload тАФ buttons, links, focus rings, grades, all of it
# 2) dark mode three ways: the ЁЯМЩ toggle ┬╖ your OS setting (system тЖТ dark, with the toggle unset) ┬╖ DevTools тЖТ Rendering тЖТ Emulate prefers-color-scheme
# 3) break the uniform on purpose: set .card .grade { color: #ff00aa } and see how a raw colour survives the theme switch badly
# 4) add a token: --shadow: 0 1px 3px rgb(0 0 0 / .08); use it on .card, and add a darker one under the dark blocks
# 5) check contrast: DevTools тЖТ inspect .status тЖТ colour swatch shows the ratio (aim тЙе 4.5:1)
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
рдПрдХрд╛ token рдмрджрд▓рд╛рдиреЗ рд╕рдВрдкреВрд░реНрдг рдлрд▓рдХрд╛рдЪрд╛ accent рдкреБрдиреНрд╣рд╛ рд░рдВрдЧрддреЛ. Dark mode toggle рдиреЗ
рдЖрдгрд┐ OS setting рдиреЗ рдЪрд╛рд▓рддреЛ, рдЖрдгрд┐ toggle рд▓рд╛рд╡рд▓реЗрд▓рд╛ рдЕрд╕реЗрд▓ рддрд░ рддреЛ рдЬрд┐рдВрдХрддреЛ тАФ рдЖрдгрд┐
рдкреНрд░рддреНрдпреЗрдХ component рдЪрд╛ code рддрд╕рд╛рдЪ рд░рд╛рд╣рддреЛ. рддреБрдордЪрд╛ рдереЗрдЯ рдЧреБрд▓рд╛рдмреА .grade dark mode
рдордзреНрдпреЗрд╣реА рдЧреБрд▓рд╛рдмреАрдЪ рд░рд╛рд╣рддреЛ: tokens рдиреЗрдордХреЗ рд╣реЗрдЪ рд╡рд┐рд╕реНрдХрд│реАрдд рд╣реЛрдгреЗ рдерд╛рдВрдмрд╡рддрд╛рдд.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рджрд┐рд╕рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрдгрдп рдПрдХрд╛рдЪ рдард┐рдХрд╛рдгреА рд░рд╛рд╣рддреЛ, themes рдореНрд╣рдгрдЬреЗ token swap, рдЖрдгрд┐ рдХреЛрдгрддреА theme рдЪрд╛рд▓реВ рдЖрд╣реЗ рд╣реЗ component рд▓рд╛ рдХрдзреАрдЪ рдорд╛рд╣реАрдд рдЕрд╕рдгреНрдпрд╛рдЪреА рдЧрд░рдЬ рдирд╕рддреЗ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- components рдордзреНрдпреЗ рдЬрд╛рдЧреЛрдЬрд╛рдЧреА рд╢рд┐рдВрдкрдбрд▓реЗрд▓реЗ рдереЗрдЯ рд░рдВрдЧ рдЖрдгрд┐ magic numbers
- light stylesheet рдкрд╛рд╕реВрди рджреВрд░ рдЬрд╛рдгрд╛рд░реА рд╡реЗрдЧрд│реА dark stylesheet
- theming рд╕рд╛рдареА inline рд░рдВрдЧ рд▓рд╛рд╡рдгрд╛рд░реА JavaScript
- рднреВрдорд┐рдХрд╛рдВрдРрд╡рдЬреА (
--accent,--muted) рдирд┐рд░рд░реНрдердХ рдирд╛рд╡рд╛рдВрдЪреЗ tokens (--blue-2) - dark palette рд╕рд╛рдареА contrast рдкреБрдиреНрд╣рд╛ рддрдкрд╛рд╕рд╛рдпрд▓рд╛ рд╡рд┐рд╕рд░рдгреЗ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: design systems рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЖрд╣реЗрдд рдХрд╛рд░рдг рдорд╛рдгрд╕реЗ рд╡рд╛рдврд▓реА рдХреА рдПрдХрд╕рд╛рд░рдЦреЗрдкрдгрд╛ рдЯрд┐рдХрдд рдирд╛рд╣реА. Tokens рд╣реЗ рд╕рдЧрд│реНрдпрд╛рдд рд╕реНрд╡рд╕реНрдд 80% рдЖрд╣реЗрдд тАФ рдПрдХ file, рдХреЛрдгрддреЗрд╣реА tooling рдирд╛рд╣реА, рдкреНрд░рддреНрдпреЗрдХ framework рдордзреНрдпреЗ рдЖрдгрд┐ рд╕рд╛рдзреНрдпрд╛ CSS рдордзреНрдпреЗ рдЪрд╛рд▓рддрд╛рдд.
тПня╕П рдкреБрдвреЗ
рддреЗ рдмрд░реЛрдмрд░ рджрд┐рд╕рддреЗ тАФ рдЖрддрд╛ рддреЗ рдкрдЯрдХрди рдкреЛрд╣реЛрдЪрд╡рд╛: performance тАФ bytes, images, caching рдЖрдгрд┐ Core Web Vitals.
git checkout lesson-09-performance