Andrey Sitnik, Travis Turner · Evil Martians

"{"slug":[0,"oklch-in-css-why-quit-rgb-hsl"],"body":[0,"/*@jsxRuntime automatic @jsxImportSource react*/\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = Object.assign({\n p: \"p\",\n a: \"a\",\n code: \"code\",\n h2: \"h2\",\n ul: \"ul\",\n li: \"li\",\n em: \"em\",\n pre: \"pre\",\n span: \"span\",\n ol: \"ol\",\n strong: \"strong\",\n h3: \"h3\",\n blockquote: \"blockquote\"\n }, props.components), {Intro, ConsultationCta, Sidenote, ReferenceBlogPost, Figure, Image, Figcaption, MediaGroup} = _components;\n if (!ConsultationCta) _missingMdxReference(\"ConsultationCta\", true);\n if (!Figcaption) _missingMdxReference(\"Figcaption\", true);\n if (!Figure) _missingMdxReference(\"Figure\", true);\n if (!Image) _missingMdxReference(\"Image\", true);\n if (!Intro) _missingMdxReference(\"Intro\", true);\n if (!MediaGroup) _missingMdxReference(\"MediaGroup\", true);\n if (!ReferenceBlogPost) _missingMdxReference(\"ReferenceBlogPost\", true);\n if (!Sidenote) _missingMdxReference(\"Sidenote\", true);\n return _jsxs(_Fragment, {\n children: [_jsx(Intro, {\n children: _jsxs(_components.p, {\n children: [\"The new \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-4/\",\n children: \"CSS Color 4\"\n }), \" specification has added the new \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" notation for declaring colors. In this post, we explain why this is important for design systems and color palettes.\"]\n })\n }), \"\\n\", _jsx(_components.h2, {\n id: \"the-extremely-short-version\",\n children: \"The extremely short version\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" is a new way to define CSS colors. In \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch(L C H)\"\n }), \" or \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch(L C H / a)\"\n }), \", each item corresponds as follows:\"]\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"L\"\n }), \" is \", _jsx(_components.em, {\n children: \"perceived\"\n }), \" lightness (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \"-\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"1\"\n }), \"). “Perceived” means that it has consistent lightness for our eyes, unlike \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"L\"\n }), \" in \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"hsl()\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"C\"\n }), \" is chroma, from gray to the most saturated color.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"H\"\n }), \" is the hue angle (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \"-\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"360\"\n }), \").\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"a\"\n }), \" is opacity (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \"-\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"1\"\n }), \" or \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \"-\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"100%\"\n }), \").\"]\n }), \"\\n\"]\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(0.21, 50.42, 225.59)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"#fff\",\n top: \"calc(2 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgba(0, 0, 0, 0.5)\",\n top: \"calc(3 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [\"a\", _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":hover\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.45\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.26\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"264\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* blue */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* white */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"/\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"50\"\n }), _jsx(_components.span, {\n className: \"token unit\",\n children: \"%\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* black with 50% opacity */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsx(ConsultationCta, {\n align: `content`,\n title: `Hire Evil Martians`,\n text: `Evil Martians built open source projects PostCSS and Autoprefixer, used by millions of engineers. Hire us to design and build your developer product!`,\n secondaryButtonText: `See our services`,\n secondaryLink: `/services`,\n kind: `martians`\n }), \"\\n\", _jsx(_components.p, {\n children: \"The benefits of OKLCH:\"\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsx(ReferenceBlogPost, {\n slug: `exploring-the-oklch-ecosystem-and-its-tools`,\n randomColorIndex: 0,\n title: `Exploring the OKLCH ecosystem and its tools`,\n theme: {\n \"colors\": {\n \"logo\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"title\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"navigation\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"text\": {\n \"color\": \"73 105 117\",\n \"oklchColor\": \"50.0751% 0.0416 223.2631\",\n \"opacity\": \"17.52%\"\n },\n \"button\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"background\": {\n \"color\": \"255 255 255\",\n \"oklchColor\": \"100.0000% 0.0000 0.0000\",\n \"opacity\": \"100%\"\n }\n },\n \"meta\": {\n \"whiteBg\": true,\n \"isDefault\": false\n }\n },\n createdAt: `May 28, 2025`,\n dateISO: \"2025-05-28T00:00:00.000Z\",\n coverImage: {\n \"publicURL\": \"/static/13d9f406e755a1596aa700d238a6f47e/cover.png?v=0dc04103\",\n \"relativePath\": \"2025-05-28-exploring-the-oklch-ecosystem-and-its-tools/cover.png\",\n \"width\": 3840,\n \"height\": 2560,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/3XDDUv7dDqxx23FtlkkP9Q2SB26T4cz8Gs0jpF5IU5c/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/jlN7b4xKB9BOBrzZyVCkd9ySDCiAgxz9YzNnPOUPNcc/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/-8BftRfU8tTz6a3-bbdJMd1TQulHeb_4mRdb2ufpC_k/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/6zj7SvAaNmWOaQ6H1D_9QiOKmvO-ofqxjEmf7zKCQD8/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/HflOsEu3bEGrrYFVhR2uKdGbPqORnEV8mVhMPQL2ETs/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/X-zPF7NJaVnEyCul9VpKQ0n8uDyh-8WoEw-PDLqMze8/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/S9k1g04etURVmLrS_D8fc3exbeAy-pVKIubL8Ir8P58/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/pB0OrbkDF4qiV36wqc-60Qc0FuCCPhcUt2MjH9qMj24/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/2ww1cq2yxRXaUd2dQ7HOW2V4iDLwekDof20oJ5W3Jeo/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/j6wedH_W_B7KOLtcwNCuN9BphUknavAs_On9TBwmn68/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/n-1rIIyNQ1Chc2tGEJw5GIJbuDLDyBF_-kA-HvzDXvQ/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/RA5kVPuSexZIZITCmNjHSCucTEYRSAFdKWNDRM4nUkE/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }, {\n \"width\": 1440,\n \"avif\": \"https://imgproxy.evilmartians.com/hdgDGBtpINrj54zpILxjE7ntqZ4lP4PiptgFXzwgx54/width:1440/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/G2ttuK_X9mu_Xe2UuqDNUVCE__W2cLthNKZWx-AUgkA/width:1440/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }, {\n \"width\": 1920,\n \"avif\": \"https://imgproxy.evilmartians.com/hQINlLLPxgsczZVMr85ule5R9Rv4OFxBbN5NPF78jQk/width:1920/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/jKEFWFqPPlBxSOsj_8zyw6YaXAiC8T85lNI34U1bgzU/width:1920/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }, {\n \"width\": 2880,\n \"avif\": \"https://imgproxy.evilmartians.com/Wha0ZVWPj50vfKnKCripFtLwb2q-arIykGuQBB6kTCY/width:2880/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\",\n \"webp\": \"https://imgproxy.evilmartians.com/6MTNzLQmRh6bd-VdVCwUpz6rDFnec2IFm86tSUeU3QQ/width:2880/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xM2Q5ZjQwNmU3NTVhMTU5NmFhNzAwZDIzOGE2ZjQ3ZS9jb3Zlci5wbmc_dj0wZGMwNDEwMw\"\n }]\n },\n bgColorOverflow: true,\n isBgFullSize: false,\n type: `blogPost`\n })\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"OKLCH frees designers from the need to manually choose every color. Designers can define a formula, choose a few colors, and an entire design system \", _jsx(_components.strong, {\n children: \"palette is automatically generated\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"OKLCH can be used for wide-gamut \", _jsx(_components.strong, {\n children: \"P3 colors\"\n }), \". For instance, new devices (like those from Apple) can display more colors than old sRGB monitors, and we can use OKLCH to specify these new colors.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Unlike \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"hsl()\"\n }), \", OKLCH is \", _jsx(_components.strong, {\n children: \"better for color modifications\"\n }), \" and palette generation. It uses perceptual lightness, so no more unexpected results, like we had with \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"darken()\"\n }), \" in Sass.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Further, with its predictable lightness, OKLCH provides \", _jsx(_components.strong, {\n children: \"better a11y\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Unlike \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"rgb()\"\n }), \" or hex (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"#ca0000\"\n }), \"), OKLCH is \", _jsx(_components.strong, {\n children: \"human readable\"\n }), \". You can quickly and easily know which color an OKLCH value represents simply by looking at the numbers. OKLCH works like HSL, but it encodes lightness better than HSL.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(Sidenote, {\n children: [_jsx(_components.p, {\n children: \"Read how we’re helping develop the OKLCH ecosystem:\"\n }), _jsx(ReferenceBlogPost, {\n slug: `oklch-a-color-picker-made-to-help-think-perceptively`,\n randomColorIndex: 5,\n title: `OK, OKLCH: a color picker made to help think perceptively`,\n theme: {\n \"colors\": {\n \"logo\": {\n \"color\": \"39 12 67\",\n \"oklchColor\": \"23.4183% 0.0973 301.5514\",\n \"opacity\": \"10.85%\"\n },\n \"title\": {\n \"color\": \"39 12 67\",\n \"oklchColor\": \"23.4183% 0.0973 301.5514\",\n \"opacity\": \"10.85%\"\n },\n \"navigation\": {\n \"color\": \"39 12 67\",\n \"oklchColor\": \"23.4183% 0.0973 301.5514\",\n \"opacity\": \"10.85%\"\n },\n \"text\": {\n \"color\": \"178 6 89\",\n \"oklchColor\": \"49.4957% 0.1971 2.0126\",\n \"opacity\": \"17.37%\"\n },\n \"button\": {\n \"color\": \"39 12 67\",\n \"oklchColor\": \"23.4183% 0.0973 301.5514\",\n \"opacity\": \"10.85%\"\n },\n \"background\": {\n \"color\": \"150 223 213\",\n \"oklchColor\": \"85.2834% 0.0741 185.1394\",\n \"opacity\": \"100%\"\n }\n },\n \"meta\": {\n \"whiteBg\": false,\n \"isDefault\": false\n }\n },\n createdAt: `February 7, 2023`,\n dateISO: \"2023-02-07T00:00:00.000Z\",\n coverImage: {\n \"publicURL\": \"/static/3d9fb7ecdb19a921736ca6a0b3ee3e7f/cover.png?v=4747b886\",\n \"relativePath\": \"2023-02-07-oklch-a-color-picker-made-to-help-think-perceptively/cover.png\",\n \"width\": 1200,\n \"height\": 1000,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/3o7vRsxO1VmaWPy_DjzgwBzWOYZrfsSEayu6R4WoHWY/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/SAq3fAoDf_uk5_fp16NjpAXMTqnL6275CfxuB8MSJcs/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/xOl6zZJl6xhn0_Ex4pEyiKHpmPw9TNiS6cadeX8pqGs/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/aGMXiPcoG3_dCNBdXhhwbALoHtojgeILgsQTLBEitUI/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/5OZ0WKh3olEoT9LBUZIrjPWJ1-Mqq_ZQmoIiAFL6rpo/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/04V73YGm6LH87tNZVJADC13euYAU8tUmFEyS_DNWY0A/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/lLilE1aSnYBw92Gl5ITp-8dR0Quq-ssRbF72-k-XmN8/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/SopR0FbNiUXU_7mxQmbMpeACi6Rh5lqoEe5HhTBzSTQ/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/EfAMItDv2iwgfbxKjoRAzUo--3XYrBj9z0dTffW9-Tk/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/6hTanpQ84gIos_LjNuz7ZbRk_GidHG2m3Pf7_O_vCMY/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/6HuM4e0_MtNpY7IY7zRC5UXmFjaATmS0Td9rR82l4ps/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/jEsCO0GDj6350wxjBpKoVQgIUF90gZ7JIG9cRb1GmJg/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\"\n }, {\n \"width\": 1200,\n \"avif\": \"https://imgproxy.evilmartians.com/7mh4yx4d62oUEhxBjJEX6LvyhYUP8_QtF1_p4eYPZbA/width:1200/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/rJ6aFxRRpf8F5uuN9DT_ZPW2Mot8w4NbpObtSB4cdag/width:1200/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8zZDlmYjdlY2RiMTlhOTIxNzM2Y2E2YTBiM2VlM2U3Zi9jb3Zlci5wbmc_dj00NzQ3Yjg4Ng\"\n }]\n },\n bgColorOverflow: true,\n isBgFullSize: false,\n type: `blogPost`\n })]\n }), \"\\n\", _jsx(_components.p, {\n children: \"But, that being said, OKLCH comes with two challenges:\"\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"With OKLCH and LCH, not all combinations of \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"L\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"C\"\n }), \", and \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"H\"\n }), \" will result in colors that are supported by every monitor. Although browsers will try to find the closest supported color, it’s still safer to check colors using our \", _jsx(_components.a, {\n href: \"https://oklch.com/\",\n children: \"color picker\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"OKLCH is a new color space. At the time of this writing in 2024, its ecosystem is still limited (for Figma we have \", _jsx(_components.a, {\n href: \"https://www.figma.com/community/plugin/1173638098109123591/okcolor\",\n children: \"the plugin\"\n }), \" but not \", _jsx(_components.a, {\n href: \"https://forum.figma.com/t/support-oklab-and-oklch/18287\",\n children: \"official support\"\n }), \"), but we already have a \", _jsx(_components.a, {\n href: \"https://huetone.ardov.me/\",\n children: \"palette generator\"\n }), \", \", _jsx(_components.a, {\n href: \"https://oklch.com/\",\n children: \"color picker\"\n }), \", and \", _jsx(_components.a, {\n href: \"https://bottosson.github.io/posts/oklab/#oklab-implementations\",\n children: \"many converters\"\n }), \".\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `oklch-picker.png`,\n linkUrl: `https://oklch.com/`,\n useOriginal: true,\n alt: `The OKLCH color picker by Evil Martians shows the OKLCH space and lightness, chroma, alpha, and hue sliders.`,\n expandToEdges: undefined,\n src: `/static/6a2410421d022095da498de7ce6721c3/oklch-picker.png`,\n width: 1156,\n height: 586\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"OKLCH space in color picker\"\n })\n })]\n }), \"\\n\", _jsx(_components.p, {\n children: \"So, that’s the short version, but if you want the whole story, let’s start from the beginning in the next section.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Table of contents\"\n }), \":\"]\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsx(_components.li, {\n children: _jsx(_components.a, {\n href: \"#how-css-colors-have-changed\",\n children: \"How CSS colors have changed\"\n })\n }), \"\\n\", _jsx(_components.li, {\n children: _jsx(_components.a, {\n href: \"#comparing-oklch-with-other-css-color-formats\",\n children: \"Comparing OKLCH with other CSS color formats\"\n })\n }), \"\\n\", _jsx(_components.li, {\n children: _jsx(_components.a, {\n href: \"#how-oklch-works\",\n children: \"How OKLCH works\"\n })\n }), \"\\n\", _jsx(_components.li, {\n children: _jsx(_components.a, {\n href: \"#how-to-add-oklch-to-your-project\",\n children: \"How to add OKLCH to your project\"\n })\n }), \"\\n\", _jsx(_components.li, {\n children: _jsx(_components.a, {\n href: \"#summing-up-the-results\",\n children: \"Summing up the results\"\n })\n }), \"\\n\"]\n }), \"\\n\", _jsx(_components.h2, {\n id: \"how-css-colors-have-changed\",\n children: \"How CSS colors have changed\"\n }), \"\\n\", _jsx(_components.h3, {\n id: \"css-colors-module-4\",\n children: \"CSS Colors Module 4\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Some recent history: the \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-4/\",\n children: \"CSS Color Module Level 4\"\n }), \" specification become a candidate recommendation on July 5, 2022.\"]\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsxs(_components.p, {\n children: [_jsx(_components.a, {\n href: \"https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/oklch?utm_source=chatgpt.com#browser_compatibility\",\n children: \"According to MDN\"\n }), \", as of August September 2025, \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" is available in all the latest devices and browser versions.\"]\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"It added new syntactic sugar to color functions, which we will use in this article:\"\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(51, 170, 51)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(51 170 51 / 50%)\",\n top: \"calc(2 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(51, 170, 51)\",\n top: \"calc(5 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(51 170 51 / 50%)\",\n top: \"calc(6 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".old\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsxs(_components.span, {\n className: \"token color\",\n children: [_jsx(_components.span, {\n className: \"token function\",\n children: \"rgb\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"51\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"170\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"51\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n })]\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsxs(_components.span, {\n className: \"token color\",\n children: [_jsx(_components.span, {\n className: \"token function\",\n children: \"rgba\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"51\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"170\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"51\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.5\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n })]\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".new\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"rgb\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"51\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"170\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"51\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"rgb\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"51\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"170\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"51\"\n }), \" \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"/\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"50\"\n }), _jsx(_components.span, {\n className: \"token unit\",\n children: \"%\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsxs(_components.blockquote, {\n children: [\"\\n\", _jsxs(_components.p, {\n children: [\"But more importantly, CSS Color 4 also added 14 new ways to define colors—and these are not just syntactic sugar. These new color-writing methods (like \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \") improve code readability, a11y, and have the potential to add new features to your website.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsx(_components.h3, {\n id: \"p3-colors\",\n children: \"P3 colors\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"Modern displays can’t actually display all the colors which are visible to the human eye. The current standard color subset is called sRGB and it can render only 35% of these human-visible colors.\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"New screens fix this a bit, since they add 30% more new colors; this set of colors is called P3 (also known as wide-gamut). In terms of adoption, all modern Apple devices, and many OLED screens, have P3 color support. So, this isn’t something from the distant future—this is happening now.\"\n }), \"\\n\", _jsxs(Sidenote, {\n children: [_jsx(Figure, {\n align: `max`,\n padding: undefined,\n children: _jsx(Image, {\n path: `producthunt.jpg`,\n alt: `OKLCH Color Picker on Product Hunt`,\n expandToEdges: undefined,\n imgproxyImageData: {\n \"publicURL\": \"/static/1a7533c99bf41ffff1771c91c4dfcf04/producthunt.jpg\",\n \"width\": 300,\n \"height\": 179,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/vxu2xRvTBpdTSKUnin_mZYUeXXRh8770Hv9jbHcojMc/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\",\n \"webp\": \"https://imgproxy.evilmartians.com/XNQ942KXSo3skLFgAcZo_1RrG8stiSTij3wynyblX7Y/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/IknAEPwmQIkIlEsj2yu_8fPmav9qjS8Elm-5AryN4vw/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\",\n \"webp\": \"https://imgproxy.evilmartians.com/rm1OfhGG7PVUvGBJkJ_5tVnexO5LhcfmoDjiKxA6NIY/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/FXQV5SEeidGsB_pFMB0aFD8_CAmJEh4mjKpqCXc6swA/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\",\n \"webp\": \"https://imgproxy.evilmartians.com/1pp3x5KOpYUBxp31INxdx8mmKSyKA7iKNnvL7N2hgx0/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/qsYrsjCKntIw94HYfRs_s2fnWF8RMae8dRzpcYt24M0/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\",\n \"webp\": \"https://imgproxy.evilmartians.com/VR5ryC7w_VCEXg0JBONNEXDu29xalybUlXmhnQD-Frc/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\"\n }, {\n \"width\": 600,\n \"avif\": \"https://imgproxy.evilmartians.com/m6KJT4hHAl3zMLO7tRMtLq5M-vI7TAh-sMaYXghc2Zo/width:600/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\",\n \"webp\": \"https://imgproxy.evilmartians.com/79MCJK8h0oSexYH3h5vHboST-kRA4oTpqrzjDg3rm0A/width:600/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYTc1MzNjOTliZjQxZmZmZjE3NzFjOTFjNGRmY2YwNC9wcm9kdWN0aHVudC5qcGc\"\n }]\n },\n width: 300,\n height: 179\n })\n }), _jsxs(_components.p, {\n children: [\"You can find and support OKLCH Color Picker with your votes and comments \", _jsx(_components.a, {\n href: \"https://www.producthunt.com/posts/oklch-color-picker-converter\",\n children: \"on Product Hunt\"\n }), \"!\"]\n })]\n }), \"\\n\", _jsx(_components.p, {\n children: \"This additional 30% of color can be very useful for designers:\"\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsx(_components.li, {\n children: \"Some of these new colors are more saturated. Thus, you can produce more eye-catching landing pages.\"\n }), \"\\n\", _jsx(_components.li, {\n children: \"The additional colors give your designers more flexibility with palette generation for their design systems.\"\n }), \"\\n\"]\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `p3.png`,\n useOriginal: true,\n alt: `On the left side, a shape shows the extra P3 colors extending from sRGB, represented as an extended wedge from the original shape. On the right side, the left icon is rendered in sRGB, and the right icon is rendered with P3 colors, showing how they are more vibrant.`,\n expandToEdges: undefined,\n src: `/static/34e8eeed150629f41555c92b01f36644/p3.png`,\n width: 842,\n height: 300\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"Newly available P3 colors for green on the left. Real-world icon comparison with sRGB vs. P3 on the right.\"\n })\n })]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"So, we have P3 colors! That’s great and all, but to actually use them, we’ll need to find a color format in order to support P3. \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"rgb()\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"hsl()\"\n }), \", or hex formats can’t be used to specify P3 colors. We could, however, use the new \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"color(display-p3 1 0 0)\"\n }), \", but it still shares the readability problems of the RGB format.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"Luckily, OKLCH has good readability, supports P3 and beyond, as well as any color visible to the human eye.\"\n }), \"\\n\", _jsx(_components.h3, {\n id: \"css-native-color-manipulations\",\n children: \"CSS native color manipulations\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"While it’s true that CSS Color 4 is a big step forward, the upcoming \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-5/\",\n children: \"CSS Color 5\"\n }), \" will be even more useful; it will finally give us native color manipulation in CSS.\"]\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"hsl(63, 61%, 40%)\",\n top: \"calc(3 * var(--c))\",\n left: \"calc(12 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"hsl(20, 61%, 40%)\",\n top: \"calc(7 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"hsl(63, 61%, 50%)\",\n top: \"calc(11 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsx(_components.span, {\n className: \"code-line\",\n children: _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* These examples use hsl() for illustrative purposes.\\n\"\n })\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token comment\",\n children: \"Don't use it in real code since hsl() format has bad a11y. */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"hsl\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"63\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"61\"\n }), _jsx(_components.span, {\n className: \"token unit\",\n children: \"%\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"40\"\n }), _jsx(_components.span, {\n className: \"token unit\",\n children: \"%\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".error\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Red version of accent color */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"hsl\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"20\"\n }), \" s l\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":hover\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* 10% lighter version */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"hsl\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" h s \", _jsx(_components.span, {\n className: \"token function\",\n children: \"calc\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"l \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"With this new syntax, you can take one color (for instance, from a custom property) and change the individual components of the color format.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Still, as mentioned, there is a drawback to this approach as using the \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"hsl()\"\n }), \" format is bad for a11y. Results will have unpredictable lightness because the \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"l\"\n }), \" values are different for different hues.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"A familiar refrain emerges: we need a color space where color manipulations produce expected results. Like, for instance, OKLCH.\"\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(160, 167, 45)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(12 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(232, 119, 130)\",\n top: \"calc(5 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(190, 199, 82)\",\n top: \"calc(9 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.7\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.14\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"113\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".error\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Red version of accent color */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" l c \", _jsx(_components.span, {\n className: \"token number\",\n children: \"15\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":hover\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* 10% lighter version */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"calc\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"l \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" c h\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Note: You don’t need to use OKLCH to input the \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"--accent\"\n }), \" colors of \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch(from …)\"\n }), \", but using a consistent format is better for code readability.\"]\n }), \"\\n\", _jsx(_components.h2, {\n id: \"comparing-oklch-with-other-css-color-formats\",\n children: \"Comparing OKLCH with other CSS color formats\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Hopefully, the previous section gave you some context about where we’ve been, where we are, and where we’re going, as well as \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \", P3 colors, native color manipulation, and how they all fit together.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Of course, rather than just going all in with \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \", we could mix and match formats, using different color formats for things like custom properties, P3, or color modifications as needed—but, naturally, having the same color format for most tasks is much better for code maintainability.\"]\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsx(ReferenceBlogPost, {\n slug: `better-dynamic-themes-in-tailwind-with-oklch-color-magic`,\n randomColorIndex: 1,\n title: `Better dynamic themes in Tailwind with OKLCH color magic`,\n theme: {\n \"colors\": {\n \"logo\": {\n \"color\": \"237 211 148\",\n \"oklchColor\": \"87.4072% 0.0856 88.0816\",\n \"opacity\": \"12.52%\"\n },\n \"title\": {\n \"color\": \"237 211 148\",\n \"oklchColor\": \"87.4072% 0.0856 88.0816\",\n \"opacity\": \"12.52%\"\n },\n \"navigation\": {\n \"color\": \"237 211 148\",\n \"oklchColor\": \"87.4072% 0.0856 88.0816\",\n \"opacity\": \"12.52%\"\n },\n \"text\": {\n \"color\": \"242 211 37\",\n \"oklchColor\": \"86.7277% 0.1721 97.8466\",\n \"opacity\": \"12.65%\"\n },\n \"button\": {\n \"color\": \"237 211 148\",\n \"oklchColor\": \"87.4072% 0.0856 88.0816\",\n \"opacity\": \"12.52%\"\n },\n \"background\": {\n \"color\": \"50 74 157\",\n \"oklchColor\": \"43.8161% 0.1380 268.1152\",\n \"opacity\": \"100%\"\n }\n },\n \"meta\": {\n \"whiteBg\": false,\n \"isDefault\": false\n }\n },\n createdAt: `October 31, 2023`,\n dateISO: \"2023-10-31T00:00:00.000Z\",\n coverImage: {\n \"publicURL\": \"/static/ee9d755c037cc653efd9a5d2a2f88ec9/cover.png?v=9bed9c0c\",\n \"relativePath\": \"2023-10-31-better-dynamic-themes-in-tailwind-with-oklch-color-magic/cover.png\",\n \"width\": 1200,\n \"height\": 1000,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/xYx2ehKzOi0sLKoWEthlq7sZrUCM7ygSehF4S7rbQ08/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\",\n \"webp\": \"https://imgproxy.evilmartians.com/VytMF8d7EMBbhwNiXWTAuec63lRgsDyGdimXb3bayxM/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/F02c8YzcVNvMgf-7LNP6d4mbFvTqCkhhATxoosRDpJE/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\",\n \"webp\": \"https://imgproxy.evilmartians.com/ipf9znZK0n5wt2VwUBhtSEOgfrzA04syRsaOaJZ-1l8/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/Qc0c0ua_pvFvDilgLkwxlpQCpwp_UOYZxeMyy-Ow57g/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\",\n \"webp\": \"https://imgproxy.evilmartians.com/JYWF_h1U5b2hMrv1O7pn_RJMpnTqryhnvU-j4mF3el4/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/pouJK-HEJPR6mX2Q4ABsF-EkvPQHfGf-VFfCTvK8Chs/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\",\n \"webp\": \"https://imgproxy.evilmartians.com/7G-hAXHm8Ozcl5At5USdMFYo4dfnL8A1b7AtdyhoJFI/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/aztR5msXVsipIPttYYFsdHGcdkwXjCBznkcDHc4rWMM/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\",\n \"webp\": \"https://imgproxy.evilmartians.com/qVdsQH3qcVYpnYDurX28-Mj3oGNPbuxzAIyHr83AJQ4/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/mH3PdXcxFIAuH9t7pMcnHjIdkdS-470o6XcFlZxR8fs/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\",\n \"webp\": \"https://imgproxy.evilmartians.com/2jToHAM6N7-BZsA6WIM93ldeHDo7VRlyY129BENBCgc/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\"\n }, {\n \"width\": 1200,\n \"avif\": \"https://imgproxy.evilmartians.com/UIpnPVqukuokzLREqQsJOc_VO2Pw1lisTooITVZ8Pzw/width:1200/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\",\n \"webp\": \"https://imgproxy.evilmartians.com/mUCUE2CoB1MNoyml81SBj-_yu3Bvc_k7EAuc0uNH60U/width:1200/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9lZTlkNzU1YzAzN2NjNjUzZWZkOWE1ZDJhMmY4OGVjOS9jb3Zlci5wbmc_dj05YmVkOWMwYw\"\n }]\n },\n bgColorOverflow: true,\n isBgFullSize: false,\n type: `blogPost`\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"So, with this in mind, let’s go ahead and assume that we’ll try to find \", _jsx(_components.strong, {\n children: \"just one color format\"\n }), \" for the future of CSS. I believe that format should meet the following criteria:\"]\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsx(_components.li, {\n children: \"It should have native CSS support.\"\n }), \"\\n\", _jsx(_components.li, {\n children: \"The format must be able to encode wide-gamut color: P3 and beyond.\"\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"It should be well suited to color modification:\", \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"This includes a human-readable axis (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"lightness\"\n }), \" instead of \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"amount of red\"\n }), \").\"]\n }), \"\\n\", _jsx(_components.li, {\n children: \"All axes should be independent. Changing the value of a hue’s axis color should maintain the same level of contrast. Saturation changes should not change hue.\"\n }), \"\\n\"]\n }), \"\\n\"]\n }), \"\\n\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"So, now that we have our criteria in mind, let’s compare formats.\"\n }), \"\\n\", _jsx(_components.h3, {\n id: \"oklch-vs-rgbhex\",\n children: \"OKLCH vs. RGB/Hex\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The color formats \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"rgb(109 162 218)\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"#6ea3db\"\n }), \", or the P3-analog \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"color(display-p3 0.48 0.63 0.84)\"\n }), \", each contain 3 numbers that represent the amount of red, green and blue. Note: \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"1\"\n }), \" in \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"color(display-p3)\"\n }), \" encodes a larger value than \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"255\"\n }), \" in RGB.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"The above formats all share essentially the same problem: they’re completely unreadable for most developers. Instead, people just use them like they are some sort of magic number, absent of any real understanding or way to compare them.\"\n }), \"\\n\", _jsxs(_components.blockquote, {\n children: [\"\\n\", _jsx(_components.p, {\n children: \"RGB, hex and color(display-p3) aren’t convenient for color modifications because, for the vast majority of humans, it’s difficult to intuitively set colors by changing the amount of red, blue and green. Further, RGB and hex also can’t encode P3 colors.\"\n }), \"\\n\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"On the other hand, OKLCH, LCH, HSL have values we can set that are much closer to the way people naturally think about colors. OKLCH and LCH contain 3 numbers which, respectively, represent the following: lightness, chroma (or saturation), and hue.\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"Compare hex and OKLCH:\"\n }), \"\\n\", _jsxs(MediaGroup, {\n adaptive: true,\n children: [_jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#6ea3db\",\n top: \"calc(2 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"#7db3eb\",\n top: \"calc(6 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"#d68585\",\n top: \"calc(10 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Blue */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token hexcode color\",\n children: \"#6ea3db\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":hover\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* More bright blue */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token hexcode color\",\n children: \"#7db3eb\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-delete\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Red with the same saturation */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token hexcode color\",\n children: \"#d68585\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n }), _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#6ea3db\",\n top: \"calc(2 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"#7db3eb\",\n top: \"calc(6 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"#d68585\",\n top: \"calc(10 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Blue */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.7\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"250\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":hover\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* A brighter blue */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.75\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"250\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-delete\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Red with the same saturation */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.7\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"20\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })]\n }), \"\\n\", _jsx(_components.p, {\n children: \"OKLCH’s intuitive values sound great, no? But, here’s where we need to talk about the flip side of the coin. The main disadvantage of OKLCH is that, unlike the others, it has a “young” color space and the ecosystem is still in the development process.\"\n }), \"\\n\", _jsx(_components.h3, {\n id: \"oklch-vs-hsl\",\n children: \"OKLCH vs. HSL\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Now, let’s move on and compare OKLCH with HSL. HSL contains 3 numbers to encode hue, saturation, and lightness, like so: \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"hsl(210 60% 64%)\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The main problem with HSL is that it has a cylindrical color space. Every hue has the same amount of saturation (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0—100%\"\n }), \"). But in reality, our displays and eyes have different max saturations for different hues. HSL hides this complexity by deforming the color space and extending colors to have the same max values.\"]\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `hsl-vs-oklch.png`,\n alt: `There are 4 illustrations. The two in the top row show HSL and OKLCH color spaces with the same chroma/saturation values. The two illustrations in the bottom row show the same color spaces, but in black and white.`,\n expandToEdges: undefined,\n imgproxyImageData: {\n \"publicURL\": \"/static/d75be34c77afcc756a653cc400821711/hsl-vs-oklch.png\",\n \"width\": 1070,\n \"height\": 517,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/Nj5vAB-K3xeKa2uk7F6szs2N4isWyGZO3maTqXy6Ffw/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/7W5dPXnlCD0cUtIWu7ce8RSNsdbTGUpUMKTVPGj2yIc/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/6NEiXXxIZokeXhqbbMw7uWvAl-WSFqwxAficVa82hT8/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/TZR15ue1DlqcvXctCaCdTeMNvKRN3RGMtABeb870tV4/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/QO4Xf9J9c7__phh-8ObeMXa5r1wDiizeZxAFM3NfZPc/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/oa26KMf08rcV3VhJOKfFn2tHuG-sZ-rrZ27gmcN0uHg/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/2FvqbMFE5-UnNYKeVIL-ADfKcq7t913oqnhhsvykL54/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/jNdKhgopD2lUHkdPnIuFGEWqFmzOx7VEowA4ZF6YECs/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/2OQ5XBZpLXo5eJ4cGpbhFwgmWvQ924-TyUcWJBKi4K8/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/J6XK0hCAUPaQY9DWPcbwj7iTEXGX_Wvnsefs0J0cMV4/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/d5EYMwlvmngU8Uv4M3wo10jTlLf_m3L9aYJso0aGES8/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/vDtds9hlW5Fm_Jp4wC974in4rfnsHJtJC19VjxwGhEw/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 1440,\n \"avif\": \"https://imgproxy.evilmartians.com/6v1a92e64xpYpj2HYimqUE_Dt6dTLbe7jhbhIPwthSk/width:1440/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/x39Cow2FLbAn5s0bwrVJFhkeosTi7lNmhgctKSfjGAg/width:1440/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 1920,\n \"avif\": \"https://imgproxy.evilmartians.com/DhutcsWRHanqL1yoFP952h5C_GQ6ljoZZLHqJlaeHDY/width:1920/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/q_5fsuDNkwRMU4OeI6eFMelQlwBoui38FKBJEvBdgbY/width:1920/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 2140,\n \"avif\": \"https://imgproxy.evilmartians.com/a5OxAosTeCbqdXY6sD9RW0T-KHGoI9ApZQiChHPOxo0/width:2140/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/wGt9W0giPMSWqOHbxr89F6aeM8f5MfgTMAr4ScOvmVY/width:2140/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9kNzViZTM0Yzc3YWZjYzc1NmE2NTNjYzQwMDgyMTcxMS9oc2wtdnMtb2tsY2gucG5n\"\n }]\n },\n width: 1070,\n height: 517\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"Hue-Lightness slice of HSL and OKLCH spaces with the same chroma/saturation and black-and-white versions below. HSL lightness is not consistent across hue axes.\"\n })\n })]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"As a result, an HSL-deformed color space can’t be used for proper color modifications; here, the \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"L\"\n }), \" (lightness) component is not accurate. Different hues represent different “real” lightness values. This leads to issues with contrast and bad accessibility.\"]\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsx(ReferenceBlogPost, {\n slug: `accessible-design-from-the-get-go`,\n randomColorIndex: 1,\n title: `Accessible design from the get-go`,\n theme: {\n \"colors\": {\n \"logo\": {\n \"color\": \"128 28 194\",\n \"oklchColor\": \"48.3823% 0.2307 305.9882\",\n \"opacity\": \"17.10%\"\n },\n \"title\": {\n \"color\": \"128 28 194\",\n \"oklchColor\": \"48.3823% 0.2307 305.9882\",\n \"opacity\": \"17.10%\"\n },\n \"navigation\": {\n \"color\": \"128 28 194\",\n \"oklchColor\": \"48.3823% 0.2307 305.9882\",\n \"opacity\": \"17.10%\"\n },\n \"text\": {\n \"color\": \"128 28 194\",\n \"oklchColor\": \"48.3823% 0.2307 305.9882\",\n \"opacity\": \"17.10%\"\n },\n \"button\": {\n \"color\": \"128 28 194\",\n \"oklchColor\": \"48.3823% 0.2307 305.9882\",\n \"opacity\": \"17.10%\"\n },\n \"background\": {\n \"color\": \"255 255 255\",\n \"oklchColor\": \"100.0000% 0.0000 0.0000\",\n \"opacity\": \"100%\"\n }\n },\n \"meta\": {\n \"whiteBg\": true,\n \"isDefault\": false\n }\n },\n createdAt: `July 26, 2021`,\n dateISO: \"2021-07-26T00:00:00.000Z\",\n coverImage: {\n \"publicURL\": \"/static/92375d00827e0b0fae8866205a2db267/cover.png?v=1daca564\",\n \"relativePath\": \"2021-07-26-accessible-design-from-the-get-go/cover.png\",\n \"width\": 1200,\n \"height\": 1000,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/fvGtuyQt_wJcALoACEbDLkI1wVi1_xhAVZbuX5pJEb0/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\",\n \"webp\": \"https://imgproxy.evilmartians.com/3Ts_ud8XzEqbKLwGD59BwP7Ke6AfRQLIiPqRbzOZBR0/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/qKF9TrjfKvCZsWhhIOos0MuoE8K92FA2tWFrz1WOqA4/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\",\n \"webp\": \"https://imgproxy.evilmartians.com/zLoimuGq8wP1jn3u8Ighsn0GYnpKun-6Nq3sDM7BFBo/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/lEmJN2Q7z4h_rgKTwrnjztj6a3iMrR9Y4O3kYKBO_28/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\",\n \"webp\": \"https://imgproxy.evilmartians.com/XmjuxF5ALVoskyyyVFCAT1K48JcHagwhDmzKy44ub0I/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/HeIm-XeL0Qd595RTUqMHgc8IOtEU5XAsWdw9E5843JA/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\",\n \"webp\": \"https://imgproxy.evilmartians.com/JB6geWSMMHY3A6NdICqBOGR9od9sXVv0cN9bUCdMqn8/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/2V0jFoLdOMT4yqOo-eqU7a_dbS7FovNkQHbRSD-8eNA/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\",\n \"webp\": \"https://imgproxy.evilmartians.com/-wZW4zwJrqkKhDBSXiAxRIb171GjUWnK2JjhrIFnqOw/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/0CxPTFiaEwnOai2w3SB6Gj5zR8660lL4sYdd1G93Wds/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\",\n \"webp\": \"https://imgproxy.evilmartians.com/dTK6StkUFljZ-COiTVXszFbZajebha_i2rj4zgE5leA/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\"\n }, {\n \"width\": 1200,\n \"avif\": \"https://imgproxy.evilmartians.com/IKEAvw90STO4EU9G-H6aYsTM-NG-gTuc1ycylO3jQ4w/width:1200/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\",\n \"webp\": \"https://imgproxy.evilmartians.com/HMFf7kPQRreCy-schzWsuXYLpz8t5GdzzhJ5uBXMhKc/width:1200/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy85MjM3NWQwMDgyN2UwYjBmYWU4ODY2MjA1YTJkYjI2Ny9jb3Zlci5wbmc_dj0xZGFjYTU2NA\"\n }]\n },\n bgColorOverflow: true,\n isBgFullSize: false,\n type: `blogPost`\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"Here are a few real use case examples to demonstrate this problem:\"\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"Adding 10% lightness will have different results for blue and purple colors. (SASS users may remember how \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"darken()\"\n }), \" generates unexpected results.)\"]\n }), \"\\n\", _jsx(_components.li, {\n children: \"Hue changes (for instance, producing an error-like red color using a company’s accent color) could also change lightness, thus making text unreadable.\"\n }), \"\\n\"]\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `buttons-hsl-vs-oklch.png`,\n alt: `There are 4 buttons. The first column has two buttons and represents the HSL space before and after using the rotation angle, and the second column with the other two buttons represents the OKLCH space before and after using the rotation angle. After changes in HSL, the contrast between the background and text is lower, unlike OKLCH.`,\n expandToEdges: undefined,\n imgproxyImageData: {\n \"publicURL\": \"/static/aa9c5f16846bf4d62a124a3da058c3e4/buttons-hsl-vs-oklch.png\",\n \"width\": 343,\n \"height\": 218,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/Bg0niQgaP7SWg9aAS3BqXx0gcrVv2drOG1jWNZVrZDA/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/oxdXqOmxyAbq3cVJjExcnRc8Yv3QBpAKQuKFAKmkzqY/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/zWtho-7Dy6EKUrQe0gnNWNf5en4-_eciaJp7tBu5wnw/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/TQm-BvmPFMa41i56AFfPSSjLk7dI_K-JpaRmHXvckgE/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/1C2aRQ_jJkVfLykfPQV2e7-k97euh-CrfyLowWlbKNM/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/I_jL8tm5fbZb56gFC9loYCe_MHGuW1pqLQsOO44pxLQ/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/APKMNmdakqt8Kf8l-QceG3wlVSRP6ULnVgXE6PL4H6Q/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/27Q98cqDwLRm8_gkcwR_69s0HsZwH3aOSZsxRQFRy5A/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 686,\n \"avif\": \"https://imgproxy.evilmartians.com/9ZY6qJxuptvK4A_Mg3AS9ArYSETxLWPFueCXfWswpl8/width:686/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/zDQWzDYa_Ejnpz5Mzk-8mP-V8CEtSSMjGOKbUCzv1m8/width:686/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9hYTljNWYxNjg0NmJmNGQ2MmExMjRhM2RhMDU4YzNlNC9idXR0b25zLWhzbC12cy1va2xjaC5wbmc\"\n }]\n },\n width: 343,\n height: 218\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"In HSL, hue changes could lead to accessibility issues from low contrast\"\n })\n })]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"HSL is bad for color modification. Many teams have asked the community to \", _jsx(_components.a, {\n href: \"https://wildbit.com/blog/accessible-palette-stop-using-hsl-for-color-systems\",\n children: \"avoid HSL\"\n }), \" for design system palette generation. Additionally, like RGB and hex, HSL can’t be used to define P3 colors.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"OKLCH doesn’t deform the space; it shows the real color space with all its complexity. On one hand, this feature allows us to have predictable lightness values after color transformations and P3 color definition. But, on other hand, not all number combinations in OKLCH generate visible colors: some are only visible on P3 monitors. But there’s still some good here: browsers will render the closest supported color.\"\n }), \"\\n\", _jsx(_components.h3, {\n id: \"oklch-vs-oklab--lch-vs-lab\",\n children: \"OKLCH vs. Oklab & LCH vs. Lab\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"CSS has two functions for Oklab space: \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklab()\"\n }), \" and \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" and the same for Lab: \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"lab()\"\n }), \" and \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"lch()\"\n }), \". So, what’s the difference?\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"While they use the same space, they use different ways of encoding a point in this space. Oklab and Lab cartesian coordinates (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"a\"\n }), \": the green/red value of a color, \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"b\"\n }), \": blue/yellow value), and OKLCH and LCH use polar coordinates (angle for hue and distance for chroma).\"]\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `oklab-vs-oklch.png`,\n alt: `There are two circles to illustrate the difference between Oklab's cartesian coordinates, with a right angle showing a and b, and OKLCH's polar coordinates, which appear as an acute angle with the top ray labeled as 'chroma' and the angle itself labeled as 'hue'.`,\n expandToEdges: undefined,\n imgproxyImageData: {\n \"publicURL\": \"/static/2a08d3d2ca022b7d57d8ad75ac9459ba/oklab-vs-oklch.png\",\n \"width\": 601,\n \"height\": 273,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/lZvEzaoPqiTGDxMmGuVw6bEvvF3YBCfCqox-s09hg8M/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/f2tJ5T6exPK9zygP9ksJBE87RQaXgqg1V3CXjySBNtM/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/ZOOIg7erG5qf8neUkBbMXpARw54_007xLaeImzc6e74/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/spjI_Lv9GiZGuDafnTYAUOKyHDD78I09nxUF_yXSgcc/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/AOGEpEKu23TWbYXQZ5qr4Alr3ABk1QJrlZEt1iaHiFU/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/Yoc-Jwdumt_sk894IbZK7MnB-p-RnRBb_1Vz57YR7Hg/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/ovIHmHY5aGbx_vQ4SI8vX37hhqdFnToEFv9dBFXn5Aw/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/c0zeQ6IAopaOQih5zGWD_6zbw-PlgyH27lvKNhKcMQ0/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/IJ8MeZSD1QFMSOWOLrrhrUNe6opDP_SxCJKaVMts9HI/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/_h1Y8l_6YEZggIWRHEY4wBRay6JZlrlTrs_jHPcrYx8/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/_HQtkVy7AyTcePmHxIzTsu7eOkcWlBfOr4EXcQ6b84Y/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/CLqCZ7XEWYNbiBx8cJZ3p3ziBbQ28RKx588AaGXI6hU/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\"\n }, {\n \"width\": 1202,\n \"avif\": \"https://imgproxy.evilmartians.com/wlaB2vZwyyBPb9IEgDN3MK_egEBhdp299QncZyw1Bzs/width:1202/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\",\n \"webp\": \"https://imgproxy.evilmartians.com/tghhhdsm5PE5lUUSPncLHOYGJfSIvADZzx4QGj3vlR4/width:1202/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yYTA4ZDNkMmNhMDIyYjdkNTdkOGFkNzVhYzk0NTliYS9va2xhYi12cy1va2xjaC5wbmc\"\n }]\n },\n width: 601,\n height: 273\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"Cartesian coordinates (Oklab) vs. polar coordinates (OKLCH) in Oklab space\"\n })\n })]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"In short, OKLCH and LCH are both better choices for developer readability and color modification because the chroma and hue values are closer to how people actually think about color, rather than simply \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"a\"\n }), \" and \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"b\"\n }), \".\"]\n }), \"\\n\", _jsx(_components.h3, {\n id: \"oklch-vs-lch\",\n children: \"OKLCH vs. LCH\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.a, {\n href: \"https://lea.verou.me/2020/04/lch-colors-in-css-what-why-and-how/\",\n children: \"LCH\"\n }), \" is a good format on top of the CIE LAB (Lab) space that was created to solve all the problems of HSL and RGB. It can encode P3 colors and, in most cases, produces predictable color modification results.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"But LCH has one painful bug: an unexpected hue shift on chroma and lightness changes in blue colors (between hue values of \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"270\"\n }), \" and \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"330\"\n }), \").\"]\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `lch-vs-oklch.png`,\n alt: `Two triangles that are constant-hue slice of LCH and OKLCH spaces with the same hue. The LCH slice, the leftmost triangular shape, is blue on one side and purple on the other. The right shape, OKLCH, keeps a constant hue, as expected.`,\n expandToEdges: undefined,\n imgproxyImageData: {\n \"publicURL\": \"/static/0bdcb6be282c87ca198aaf61ce808faf/lch-vs-oklch.png\",\n \"width\": 842,\n \"height\": 333,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/hMeXHQC6XpPnGFZ_BZwvxUGarahDotlsrNDzwkNXalA/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/Q_fTkZLfipeKW9Fx3kMyIVoYEi_oQveEYVt9NftReNI/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/qlz61KAvcxux1WUPusZ1zxFCl_XS89BsFbyT5QYuSwk/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/7Ui4XS79vCojiamUzEDrUkQ8LRhxdEEZNB2dsDAzy78/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/ENCKMFI3xuj0Tj5VQAFlz5lTdjUsyIzfKZO-QvcEFpA/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/4f2AUHzuVlAt07X08DwKL2hf8UvWM5LEv-l7rihE9qM/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/TGik3OvVeau0918nYVxA2xqQ1Cmdxhfd8_QjLW1OSVI/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/Vp8crdkXzacB6mHR0kWBAdpn8NVXgcsqBuYvYYdaRVc/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/axMgJ8LTs6ZKc1REhgycxXXRn5qeGB8_Fu6ie80hYrg/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/6IggUWIpYlYTJ1otKHAIKBPtkxpndQm9kinipSQ6b1Q/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/q9jxJK5nhDP0n2a9zQUQTlbtPaPGGaaFRi00Ghw0LLI/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/OK1Ka1zAgWSWncy3fO43XA5DavuTpUhdgcYkzkt-JYc/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 1440,\n \"avif\": \"https://imgproxy.evilmartians.com/ZG7POJUKGrAyGiOiUD3VFr894UUS0datpSnIBFSkk9w/width:1440/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/iaG9w8pP_bkRwLE-JeS0tj6wEHk8-z25ljzTbc9vj-I/width:1440/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\"\n }, {\n \"width\": 1684,\n \"avif\": \"https://imgproxy.evilmartians.com/j9evT82s6iCoWqav5ewUTjQiyFKGwHzuqt-p_2bqi4g/width:1684/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/RRVd5GO5JqhrXYRpfFbfiob8bgVUpS2nMDmJqyTXL0s/width:1684/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8wYmRjYjZiZTI4MmM4N2NhMTk4YWFmNjFjZTgwOGZhZi9sY2gtdnMtb2tsY2gucG5n\"\n }]\n },\n width: 842,\n height: 333\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"A constant-hue slice of LCH and OKLCH spaces with the same hue. The LCH slice is blue on one side and purple on the other. OKLCH keeps a constant hue as expected.\"\n })\n })]\n }), \"\\n\", _jsx(_components.p, {\n children: \"Here is a small real case:\"\n }), \"\\n\", _jsxs(MediaGroup, {\n adaptive: true,\n children: [_jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(65, 46, 241)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(86, 61, 189)\",\n top: \"calc(5 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(90, 72, 138)\",\n top: \"calc(10 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".temperature\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-very-very-cold\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"lch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.35\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"110\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"300\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Looks blue */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".temperature\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-very-cold\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"lch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.35\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"75\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"300\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* We changed only lightness,\\n\"\n })]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token comment\",\n children: \" but blue became purple */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".temperature\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-cold\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"lch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.35\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"40\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"300\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Very purple */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n }), _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(64, 43, 241)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(66, 75, 195)\",\n top: \"calc(5 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n style: {\n background: \"rgb(76, 88, 150)\",\n top: \"calc(10 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".temperature\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-very-very-cold\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.48\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.27\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"274\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Looks blue */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".temperature\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-very-cold\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.48\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.185\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"274\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Still blue */\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".temperature\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-cold\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.48\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"274\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Still blue */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The Oklab and OKLCH spaces \", _jsx(_components.a, {\n href: \"https://bottosson.github.io/posts/oklab/\",\n children: \"were created\"\n }), \" to solve this hue shift bug.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"But OKLCH isn’t merely a bugfix, it also has \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-4/#ok-lab\",\n children: \"nice new features\"\n }), \" related to the math behind color axes. For instance, it has improved \", _jsx(_components.a, {\n href: \"https://bottosson.github.io/posts/gamutclipping/\",\n children: \"gamut correction\"\n }), \" and CSSWG \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-4/#css-gamut-mapping\",\n children: \"recommends using OKLCH\"\n }), \" for gamut mapping.\"]\n }), \"\\n\", _jsx(_components.h2, {\n id: \"how-oklch-works\",\n children: \"How OKLCH works\"\n }), \"\\n\", _jsx(_components.h3, {\n id: \"a-little-bit-of-history\",\n children: \"A little bit of history\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The Oklab & OKLCH color spaces were created by \", _jsx(_components.a, {\n href: \"https://twitter.com/bjornornorn\",\n children: \"Björn Ottosson\"\n }), \" in 2020. The primary reason they were created was to fix the CIE LAB & LCH issue. Björn wrote \", _jsx(_components.a, {\n href: \"https://bottosson.github.io/posts/oklab/\",\n children: \"a great article\"\n }), \" detailing the reasons he made them and their implementation details.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"To be clear, Oklab is very young and this is its primary weak point.\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"But, after just 4 years, Oklab has already seen very good adoption:\"\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"It was added to the \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-4/#ok-lab\",\n children: \"CSS specification\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Chrome, Safari, and Firefox have \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" support.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Photoshop \", _jsx(_components.a, {\n href: \"https://helpx.adobe.com/photoshop/using/gradient-interpolation.html\",\n children: \"added\"\n }), \" Oklab for gradient interpolation.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Oklab is used in \", _jsx(_components.a, {\n href: \"https://huetone.ardov.me/\",\n children: \"color palette generators\"\n }), \" for good accessibility.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"OKLCH already can be used in Figma using \", _jsx(_components.a, {\n href: \"https://www.figma.com/community/plugin/1173638098109123591/OkColor\",\n children: \"this plugin\"\n }), \".\"]\n }), \"\\n\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"I personally think that the big changes coming with CSS Colors 4 and 5 are a good time to grab the latest and best solution. In any case, we’ll need to create a new ecosystem around new features from new CSS specs.\"\n }), \"\\n\", _jsx(_components.h3, {\n id: \"axes\",\n children: \"Axes\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Colors in OKLCH are encoded with 4 numbers. In CSS, it looks like this: \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch(L C H)\"\n }), \" or \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch(L C H / a)\"\n }), \".\"]\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `oklch-axes.png`,\n alt: `Four bars show the OKLCH axes. The top-left is lightness; it begins with a dark purple, becoming a light purple as it moves to the right, and eventually there is a hard change to white. The top-right bar is chroma; it begins as a grayish purple and transitions to a light purple, from roughly 33% of the bar to the right there is a hard change to white. The bottom-left is alpha: an alpha channel transitions to a light purple as it stretches to the right. The light purple reaches the end of the bar's left side. The bottom-right is hue: a range of vibrant colors transition as the bar goes from left to right.`,\n expandToEdges: undefined,\n imgproxyImageData: {\n \"publicURL\": \"/static/1ba334bc155f6d4652884281b72aa948/oklch-axes.png\",\n \"width\": 1073,\n \"height\": 235,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/gkEAK50z_ZE2nRXm91fwtecg1q0xQSdic_DM7YYPxPo/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/FprLHH4lhpFbhY1rbRvjo57ZCAHwfVgeDnAL43X5q2E/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/jBlWdohB4Ij4HGNd5VrJ5s1c11QN-w-Mp3_woAwU4uk/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/EXQ5vAXeUuofkAJNPNjLjK208T1zmPXKfexJXs1Q4F4/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/NcvbBgqD1bNrfwVJdOnt8IfLBA45GZQTs1nTBORY0O4/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/LyvVER8R5aVzYRvLuzX1pI5DUg0jvi6Z5ngJk-BnkXI/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/fHyzacUW6uFQ4gp8qRIR9Gqb7vylB0J0fPPqprmICco/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/yaxTms6xM8imZquCvCfBPcx5EpP27_GW7fdAbp2GLP0/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/WfqMJlb6HhTmdorBoGGVkBPWi9qiQiRxVZasd2si7Sg/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/qWIjkICPOv3ASd6NnmiYZ1E_FYacJ9Ms31CEDsWR8fI/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/NjMOClyjpXKNNx4I_WuzUMN1gu8Nummz8khDpebZ0YE/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/ddGKL6VKNa3OSAS42JI8M8LTccbz5FaLLCrNwKLcSSc/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }, {\n \"width\": 1440,\n \"avif\": \"https://imgproxy.evilmartians.com/ZArFPLSo-OkQ3cRzEutbAaqglxO_NLBkPeRXjOdabxY/width:1440/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/gfdP0-_niv-MWQjcm4-iWae-_s-trvIKMGMlx931_w8/width:1440/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }, {\n \"width\": 1920,\n \"avif\": \"https://imgproxy.evilmartians.com/Oaok26ZBzlvWYxDidW6Fkr_kEIrFDCUlSuH1G-ELsko/width:1920/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/59rjFWDyIOXRs-xZYsXZt-IcY_bEJMRS6H6wlXXTBtU/width:1920/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }, {\n \"width\": 2146,\n \"avif\": \"https://imgproxy.evilmartians.com/mZrF7-2eFAoPJbQUnbqQXYQK_vrzw_RdOCD5fcSvQ2g/width:2146/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/q1O-gWWYKA-DejBAKlAMWYB9fmrU_HGewxDsqOCc29Q/width:2146/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xYmEzMzRiYzE1NWY2ZDQ2NTI4ODQyODFiNzJhYTk0OC9va2xjaC1heGVzLnBuZw\"\n }]\n },\n width: 1073,\n height: 235\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"OKLCH axes\"\n })\n })]\n }), \"\\n\", _jsx(_components.p, {\n children: \"Here’s a more detailed explanation of each value:\"\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"L\"\n }), \" is \", _jsx(_components.em, {\n children: \"perceived\"\n }), \" \", _jsx(_components.strong, {\n children: \"lightness\"\n }), \". It ranges from \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \" (black) to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"1\"\n }), \" (white). It accepts percentage too (from \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0%\"\n }), \" to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"100%\"\n }), \"), but \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"%\"\n }), \" doesn’t work in \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"calc()\"\n }), \" or relative colors.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"C\"\n }), \" is \", _jsx(_components.strong, {\n children: \"chroma\"\n }), \", the saturation of color. It goes from \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \" (gray) to infinity. In practice there is actually a limit, but it depends on a screen’s color gamut (P3 colors will have bigger values than sRGB) and each hue has a different maximum chroma. For both P3 and sRGB the value will be always below \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0.37\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"H\"\n }), \" is the \", _jsx(_components.strong, {\n children: \"hue\"\n }), \" angle. It goes from \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \" to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"360\"\n }), \", through red \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"20\"\n }), \", yellow \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"90\"\n }), \", green \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"140\"\n }), \", blue \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"220\"\n }), \", purple \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"320\"\n }), \" and then back to red. You can use \", _jsx(_components.a, {\n href: \"https://en.wikipedia.org/wiki/ROYGBIV\",\n children: \"Roy G. Biv\"\n }), \" mnemonic by giving around 50° to each letter. Since it is an angle, \", _jsx(_components.a, {\n href: \"https://oklch.com/#70,0.1,0,100\",\n children: _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n })\n }), \" and \", _jsx(_components.a, {\n href: \"https://oklch.com/#70,0.1,360,100\",\n children: _jsx(_components.code, {\n className: \"language-text\",\n children: \"360\"\n })\n }), \" encode the same hue. \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"H\"\n }), \" can be written with units \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"60deg\"\n }), \", or without \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"60\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n className: \"language-text\",\n children: \"a\"\n }), \" is \", _jsx(_components.strong, {\n children: \"opacity\"\n }), \" (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \"-\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"1\"\n }), \" or \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \"-\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"100%\"\n }), \").\"]\n }), \"\\n\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"Here is a few examples of OKLCH colors:\"\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#000\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#fff\",\n top: \"calc(2 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#fff\",\n top: \"calc(3 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(99, 99, 99)\",\n top: \"calc(4 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(208, 191, 94)\",\n top: \"calc(7 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(145, 129, 18)\",\n top: \"calc(8 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(197, 191, 154)\",\n top: \"calc(9 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(88, 206, 248)\",\n top: \"calc(10 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgba(208, 191, 94, 0.5)\",\n top: \"calc(13 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".bw\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* black */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* white */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.2\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"100\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* also white, any hue with 100% L is white */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.5\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* gray */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".colors\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.8\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.12\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"100\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* yellow */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.6\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.12\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"100\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* much darker yellow */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.8\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.05\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"100\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* quite grayish yellow */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.8\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.12\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"225\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* blue, with the same perceived lightness */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".opacity\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.8\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.12\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"100\"\n }), \" \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"/\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"50\"\n }), _jsx(_components.span, {\n className: \"token unit\",\n children: \"%\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* transparent yellow */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Note, that some components could have \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-4/#valdef-color-none\",\n children: _jsx(_components.code, {\n className: \"language-text\",\n children: \"none\"\n })\n }), \" as a value. This may occur after a color transformation. For instance, white has no hue, and browsers will parse \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"none\"\n }), \" as \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0\"\n }), \".\"]\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsx(\"div\", {\n className: \"oklch-overlay\",\n children: _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#fff\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n })\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".white\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" none\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* valid syntax */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsx(_components.h3, {\n id: \"color-modifications-in-css\",\n children: \"Color modifications in CSS\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"In \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-5/\",\n children: \"CSS Colors 5\"\n }), \", we’ll be able to have native color modifications. This will shine a light on one of my favorite perks of OKLCH: it’s the best color space for color modification because it has very predictable results.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"Color modification syntax looks like this:\"\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#0f0\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(12 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#0f0\",\n top: \"calc(4 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--origin\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token hexcode color\",\n children: \"#ff0000\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".foo\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--origin\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" l c h\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The origin color (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"var(--origin)\"\n }), \" in the example above) can be:\"]\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"A color in any format: \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"#ff0000\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"rgb(255, 0, 0)\"\n }), \", or \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch(62.8% 0.25 30)\"\n }), \".\"]\n }), \"\\n\", _jsx(_components.li, {\n children: \"A CSS custom property with a color in any format.\"\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Each component (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"l\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"c\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"h\"\n }), \") after \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"from X\"\n }), \" can be:\"]\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"A letter (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"l\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"c\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"h\"\n }), \"), indicating to keep the component the same as it was in the origin color.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"A \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"calc()\"\n }), \" expression. You can use a letter (\", _jsx(_components.code, {\n className: \"language-text\",\n children: \"l\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"c\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"h\"\n }), \") instead of a number to reference the value in the origin color.\"]\n }), \"\\n\", _jsx(_components.li, {\n children: \"A new value, which will replace the component.\"\n }), \"\\n\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"It may sound complex, but seeing some examples can help illustrate:\"\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(206, 83, 66)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(11 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgba(206, 83, 66, 0.6)\",\n top: \"calc(5 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(172, 50, 37)\",\n top: \"calc(7 * var(--c))\",\n left: \"calc(16 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(68, 150, 48)\",\n top: \"calc(11 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--error\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.6\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.16\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"30\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".message\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-error\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* The same color but with different opacity */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--error\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" l c h \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"/\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"60\"\n }), _jsx(_components.span, {\n className: \"token unit\",\n children: \"%\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* 10% darker */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"border-color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--error\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"calc\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"l \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"-\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" c h\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".message\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-success\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Another hue (green) with the same lightness and saturation */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--error\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" l c \", _jsx(_components.span, {\n className: \"token number\",\n children: \"140\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The predicted lightness of OKLCH is very useful when generating accent colors from user input (check an example with our \", _jsx(_components.a, {\n href: \"https://oklch.com/\",\n children: \"OKLCH color picker\"\n }), \"):\"]\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* Replace lightness and saturation to a certain lightness */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--user-input\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.87\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.06\"\n }), \" h\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: \"body\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* We do not need to detect text color with color-contrast()\\n\"\n })]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: _jsx(_components.span, {\n className: \"token comment\",\n children: \" because OKLCH has predicted lightness.\\n\"\n })\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token comment\",\n children: \" All backgrounds with L≥87% have good contrast with black text. */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token color\",\n children: \"black\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n }), \"\\n\", _jsx(_components.h3, {\n id: \"gamut-correction\",\n children: \"Gamut correction\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"OKLCH has another interesting feature: device independence. That is, OKLCH wasn’t just created for current monitors with sRGB colors.\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"You can encode any possible color with OKLCH: sRGB, P3, Rec2020 and beyond. Some number combinations will require a P3 monitor to be displayed. For some other combinations, the proper monitors necessary for their display have still yet to be created.\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"But really, don’t worry about being out of the gamut (the colors supported by a user’s monitor) because browsers will render the closest possible color. Finding the closest color in another gamut is called “gamut mapping” or “gamut correction”.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"And this is why you can see holes in axes of the \", _jsx(_components.a, {\n href: \"https://oklch.com/#60,0.16,140,100\",\n children: \"OKLCH color picker\"\n }), \": every hue has a different maximum chroma. Unfortunately, this isn’t just a problem with OKLCH color encoding; it’s a limit both of currently available monitors, and our own sense of vision. For some lightness values, there is only a blue color with a large chroma. For other lightness values, a green color will not have a corresponding pair in a blue or a red with the same chroma.\"]\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `oklch-l-44.png`,\n alt: `A graph with two axes, C on the left and H on the bottom, shows a shape that has huge circular bites missing; as the shape moves from left to right, various colors are seen, appearing as multiple transitioning gradients.`,\n expandToEdges: undefined,\n imgproxyImageData: {\n \"publicURL\": \"/static/26212691a88eaba1dbf9e4609bf7373b/oklch-l-44.png\",\n \"width\": 511,\n \"height\": 214,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/t7gXuX5H1lSNrDfnFDkzvY075QRXztH1Z_iK0uilBRU/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/0U34sRiXE6xQc9t5j5RSrMwogev8u3XCgbLnQwK_VxI/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/eIwZDTcPVnrlFPHk2BS7nt5a8b1U2O1N_y6gAKYS9BI/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/WsV81TwhZGNVQk_O7AKbL-GE-WzNaahC_Ljo8WW7rbI/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/JUienlbtpVTXJf95dKb8BTtcF8ZHO3h3zC9C-h7f67s/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/FAif71z2v43wH6m4Yatp6tL0u3iQe15oCIrj_BLkISU/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/QBgcjmhu_4KBxCzOWbNWpOCjO0u240C8lTJJ_RGU-oA/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/TD6SUCA1k_SDD0t5-uZHppRokw8WXsOaZlKl8jfuSwA/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/Io5aYYAzMr_Y6881m_fZ-jqeQMMFRx7fEvc169TwCfw/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/Kf8frjmYrdt7IS-T9PWU5U6zriqNWVlBO7rGfX1ZypI/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\"\n }, {\n \"width\": 1022,\n \"avif\": \"https://imgproxy.evilmartians.com/I_XMY7D9IJdd3-tsn0tXKqx4PZE5kaCdZnpScDTiGnM/width:1022/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\",\n \"webp\": \"https://imgproxy.evilmartians.com/2grA-aeQpIBXtKQiGw7tNnh6Hz5Qjs-Y6Nk-MuKzUaY/width:1022/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8yNjIxMjY5MWE4OGVhYmExZGJmOWU0NjA5YmY3MzczYi9va2xjaC1sLTQ0LnBuZw\"\n }]\n },\n width: 511,\n height: 214\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"For 44% lightness only blue has high chrome colors visible on sRGB screens\"\n })\n })]\n }), \"\\n\", _jsx(_components.p, {\n children: \"There are 2 ways of gamut mapping:\"\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"Convert the color to RGB (or P3) and clip values above 100% or below 0%: \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"rgb(150% -20% 30%)\"\n }), \" → \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"rgb(100% 0 30%)\"\n }), \". This is the fastest method, but it has the worst results—it could change a color’s hue and this change will be visible to users.\"]\n }), \"\\n\", _jsx(_components.li, {\n children: \"Convert the color to OKLCH and reduce the chroma and lightness. This keeps the origin hue but is a little slower to render.\"\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Chris Lilley has created \", _jsx(_components.a, {\n href: \"https://svgees.us/Color/ok-clip-lch-explorer.html\",\n children: \"a nice comparison between different gamut mapping methods\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The CSS Colors 4 spec \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-4/#css-gamut-mapping\",\n children: \"requires\"\n }), \" browsers to use the OKLCH method for gamut mapping. But still, right now, Chrome and Safari use the fast, but inaccurate, clipping method. That’s why we currently recommend manual gamut mapping and adding both sRGB and P3 colors to CSS:\"]\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(159, 166, 1)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"color(display-p3 0.6327 0.6542 0.0677)\",\n top: \"calc(5 * var(--c))\",\n left: \"calc(16 * var(--l))\"\n },\n className: \"oklch-preview without-opacity\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".martian\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.6973\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.155\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"112.79\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token atrule\",\n children: [_jsx(_components.span, {\n className: \"token rule\",\n children: \"@media\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token property\",\n children: \"color-gamut\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" p3\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".martian\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.6973\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.176\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"112.79\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* You'll only see the preview with P3 monitors */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"And here’s some good news: \", _jsx(_components.a, {\n href: \"https://github.com/fpetrakov/stylelint-gamut\",\n children: \"stylelint-gamut\"\n }), \" can automatically detect all P3 colors which need to be wrapped with \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"@media\"\n }), \".\"]\n }), \"\\n\", _jsx(_components.h2, {\n id: \"how-to-add-oklch-to-your-project\",\n children: \"How to add OKLCH to your project\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Right now, all browsers \", _jsx(_components.a, {\n href: \"https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/oklch\",\n children: \"support\"\n }), \" \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \". You don’t need \", _jsx(_components.a, {\n href: \"https://preset-env.cssdb.org/\",\n children: \"old polyfills\"\n }), \".\"]\n }), \"\\n\", _jsx(_components.h3, {\n id: \"step-1-converting-currently-existing-colors\",\n children: \"Step 1: Converting currently existing colors\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"You can replace all colors using hex, \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"rgb()\"\n }), \" or \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"hsl()\"\n }), \" formats to OKLCH; they’ll work in every browser.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Search for any colors in your CSS source code and convert them to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" using the \", _jsx(_components.a, {\n href: \"https://oklch.com/\",\n children: \"OKLCH convertor\"\n }), \".\"]\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-diff-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".header\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line deleted\",\n children: [_jsx(_components.span, {\n className: \"token operator\",\n children: \"-\"\n }), \" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token hexcode color\",\n children: \"#f3f7fa\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line inserted\",\n children: [_jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.97\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.006\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"240\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"You may also use \", _jsx(_components.a, {\n href: \"https://github.com/fpetrakov/convert-to-oklch\",\n children: \"this script\"\n }), \" to automatically convert all the colors:\"]\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-sh\",\n children: _jsx(_components.code, {\n className: \"language-sh code-highlight\",\n children: _jsx(_components.span, {\n className: \"code-line\",\n children: \"npx convert-to-oklch ./src/**/*.css\\n\"\n })\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"If you only have a Figma file, you can use the \", _jsx(_components.a, {\n href: \"https://www.figma.com/community/plugin/1173638098109123591/OkColor\",\n children: \"OkColor\"\n }), \" plugin to copy colors in \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" directly from Figma (using the \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"OkLCH (CSS)\"\n }), \" format).\"]\n }), \"\\n\", _jsx(_components.h3, {\n id: \"extra-adding-a-color-palette\",\n children: \"Extra: Adding a color palette\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"Perhaps this little bit of refactoring is also a good time to increase your CSS code’s maintainability by moving the colors onto a palette:\"\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsx(ReferenceBlogPost, {\n slug: `5-signs-your-project-needs-a-design-system`,\n randomColorIndex: 2,\n title: `5 signs your project needs a design system`,\n theme: {\n \"colors\": {\n \"logo\": {\n \"color\": \"188 6 177\",\n \"oklchColor\": \"55.2646% 0.2475 331.5726\",\n \"opacity\": \"18.82%\"\n },\n \"title\": {\n \"color\": \"188 6 177\",\n \"oklchColor\": \"55.2646% 0.2475 331.5726\",\n \"opacity\": \"18.82%\"\n },\n \"navigation\": {\n \"color\": \"188 6 177\",\n \"oklchColor\": \"55.2646% 0.2475 331.5726\",\n \"opacity\": \"18.82%\"\n },\n \"text\": {\n \"color\": \"74 68 74\",\n \"oklchColor\": \"39.4762% 0.0127 325.8150\",\n \"opacity\": \"14.87%\"\n },\n \"button\": {\n \"color\": \"188 6 177\",\n \"oklchColor\": \"55.2646% 0.2475 331.5726\",\n \"opacity\": \"18.82%\"\n },\n \"background\": {\n \"color\": \"231 233 227\",\n \"oklchColor\": \"93.0815% 0.0083 121.6361\",\n \"opacity\": \"100%\"\n }\n },\n \"meta\": {\n \"whiteBg\": false,\n \"isDefault\": false\n }\n },\n createdAt: `September 8, 2022`,\n dateISO: \"2022-09-08T00:00:00.000Z\",\n coverImage: {\n \"publicURL\": \"/static/1944850d342cc8b431831fe159504740/cover.png?v=5fe3cfb1\",\n \"relativePath\": \"2022-09-08-5-signs-your-project-needs-a-design-system/cover.png\",\n \"width\": 1200,\n \"height\": 1000,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/GuDnY7df89UFfYtPRtYkyswvX5zumQWlYmj0RpzWViU/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\",\n \"webp\": \"https://imgproxy.evilmartians.com/0amPhMW4nUIGhSGp3POseW57Vhk9n8G0zw_i8LC40gA/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/R24slHfe4Ad_ly5IPnfjnnhx-61nMBlYmkmZMIqGMl8/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\",\n \"webp\": \"https://imgproxy.evilmartians.com/QXwNtxiIbrV3Tk2e7tAwuh4kXs5JhsPMuQR5ERc8-6w/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/r0hY7lDjCj8MAMUhGYNvcE4DYXeejUsj0YrTfvuiy9Q/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\",\n \"webp\": \"https://imgproxy.evilmartians.com/iNQvCFTWMZtN79DONgTFiiPjMLRbhEebyhYtJjJH6bw/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/ZLPibfGy1HZvWT3OVQGmMxegrJVOvdNoBigbVk3fB9w/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\",\n \"webp\": \"https://imgproxy.evilmartians.com/c_7zej7Y6Vse7VAvPPMeZu6GDS_f4PVVM_STB4Hxn40/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/JIbTczT3NkTyZebawkB1mJqllhBhv6oaJo71jXLKynY/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\",\n \"webp\": \"https://imgproxy.evilmartians.com/IgCbbfE_2n_P-JiA4yz_gsilX4RmlthxDaMVIbSHMRM/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/tAnVTlQNKPknkxukwIscODh5p2R3eCsG6_8pvygychY/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\",\n \"webp\": \"https://imgproxy.evilmartians.com/fXwGiiiIpsuBsaawpTdkaDhVST0w1l2_RWnhjLUP68Y/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\"\n }, {\n \"width\": 1200,\n \"avif\": \"https://imgproxy.evilmartians.com/2a_NK7vmsJTdC7SD3jmr1j2g1RYEywmLQ7-ZZtWjWHY/width:1200/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\",\n \"webp\": \"https://imgproxy.evilmartians.com/8MJR94C1-UZs4tn74eEPIdNRv2A3EqP6ORvGQqKdOMM/width:1200/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy8xOTQ0ODUwZDM0MmNjOGI0MzE4MzFmZTE1OTUwNDc0MC9jb3Zlci5wbmc_dj01ZmUzY2ZiMQ\"\n }]\n },\n bgColorOverflow: true,\n isBgFullSize: false,\n type: `blogPost`\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"These are the requirements for color palettes:\"\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsx(_components.li, {\n children: \"All colors are described as CSS Custom Properties.\"\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"React/Vue/etc. components only use these colors as \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"var(--error)\"\n }), \".\"]\n }), \"\\n\", _jsx(_components.li, {\n children: \"Designers should try to re-use colors to reduce number of color variations.\"\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"For a dark or high-contrast theme, you do not need \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"@media\"\n }), \" in your components’ CSS, you just change CSS Custom Properties in the palette.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Here’s \", _jsx(_components.a, {\n href: \"https://github.com/evilmartians/oklch-picker/blob/main/view/base/colors.css\",\n children: \"an example\"\n }), \" of this approach.\"]\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--surface-0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.96\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.005\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"300\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--surface-1\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--surface-2\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.99\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"/\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"85\"\n }), _jsx(_components.span, {\n className: \"token unit\",\n children: \"%\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--text-primary\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--text-secondary\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.54\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.57\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.18\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"286\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--danger\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.59\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.23\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"7\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token atrule\",\n children: [_jsx(_components.span, {\n className: \"token rule\",\n children: \"@media\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token property\",\n children: \"prefers-color-scheme\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" dark\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--surface-0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--surface-1\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.29\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.01\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"300\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--surface-2\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.29\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"/\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"85\"\n }), _jsx(_components.span, {\n className: \"token unit\",\n children: \"%\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--text-primary\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"1\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"And plus, moving over to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" will be a little easier after palette creation.\"]\n }), \"\\n\", _jsx(_components.h3, {\n id: \"step-2-maintaining-oklch-with-stylelint\",\n children: \"Step 2: Maintaining OKLCH with Stylelint\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.a, {\n href: \"https://stylelint.io/\",\n children: \"Stylelint\"\n }), \" is a style linter that’s useful for finding common mistakes and promoting best practices. It’s like ESLint, but for CSS, SASS, or CSS-in-JS.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Stylelint can be very useful when migrating to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" because you can:\"]\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [\"Specify that colors using hex, \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"rgb()\"\n }), \", \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"hsl()\"\n }), \" will not be used and instead keep all the colors in \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" to improve consistency.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Double-check that all P3 colors are inside \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"@media (color-gamut: p3)\"\n }), \" to avoid browser gamut correction (right now, Chrome and Safari don’t do this correctly).\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Let’s install Stylelint and the \", _jsx(_components.a, {\n href: \"https://www.npmjs.com/package/stylelint-gamut\",\n children: \"stylelint-gamut\"\n }), \" plugin using your package manager. With NPM, run:\"]\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-sh\",\n children: _jsx(_components.code, {\n className: \"language-sh code-highlight\",\n children: _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token function\",\n children: \"npm\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"install\"\n }), \" stylelint stylelint-gamut\\n\"]\n })\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Create \", _jsx(_components.code, {\n className: \"language-text\",\n children: \".stylelintrc\"\n }), \" config with:\"]\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-json\",\n children: _jsxs(_components.code, {\n className: \"language-json code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"\\\"plugins\\\"\"\n }), _jsx(_components.span, {\n className: \"token operator\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"[\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"stylelint-gamut\\\"\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"]\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"\\\"rules\\\"\"\n }), _jsx(_components.span, {\n className: \"token operator\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"\\\"gamut/color-no-out-gamut-range\\\"\"\n }), _jsx(_components.span, {\n className: \"token operator\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token boolean\",\n children: \"true\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"\\\"function-disallowed-list\\\"\"\n }), _jsx(_components.span, {\n className: \"token operator\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"[\"\n }), _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"rgba\\\"\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"hsla\\\"\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"rgb\\\"\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"hsl\\\"\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"]\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"\\\"color-function-notation\\\"\"\n }), _jsx(_components.span, {\n className: \"token operator\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"modern\\\"\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"\\\"color-no-hex\\\"\"\n }), _jsx(_components.span, {\n className: \"token operator\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token boolean\",\n children: \"true\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Add the Stylelint call to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"npm test\"\n }), \" to run it on CI. Change \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"package.json\"\n }), \" like so:\"]\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-diff-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"scripts\\\"\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line deleted\",\n children: [_jsx(_components.span, {\n className: \"token operator\",\n children: \"-\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"test\\\"\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"eslint .\\\"\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line inserted\",\n children: [_jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"test\\\"\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"\\\"eslint . && stylelint **/*.css\\\"\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Run \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"npm test\"\n }), \" to find any colors which should be converted to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Evil Martians also recommend adding the \", _jsx(_components.a, {\n href: \"https://github.com/stylelint/stylelint-config-recommended\",\n children: _jsx(_components.code, {\n className: \"language-text\",\n children: \"stylelint-config-recommended\"\n })\n }), \" to \", _jsx(_components.code, {\n className: \"language-text\",\n children: \".stylelintrc\"\n }), \". This Stylelint sharable config will ensure that your CSS code is using the popular best practices.\"]\n }), \"\\n\", _jsx(_components.h3, {\n id: \"extra-p3-colors\",\n children: \"Extra: P3 colors\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Replacing colors with \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \" will improve code readability and maintainability, but it will not add new features for users. However, there is an additional feature of OKLCH which \", _jsx(_components.em, {\n children: \"will\"\n }), \" be visible to users: we can add rich, wide-gamut P3 colors to our websites. For instance, we could add deep colors to a landing page.\"]\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsx(_components.p, {\n children: \"P3 colors are very useful when creating palettes for design systems. However, this is not super useful right now because only Chrome and Safari (with the right hardware) support P3 colors.\"\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"Here’s how to do it:\"\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsx(_components.li, {\n children: \"In your CSS, choose some saturated color, like an accent color.\"\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Copy it into \", _jsx(_components.a, {\n href: \"https://oklch.com/\",\n children: \"OKLCH Color Picker\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Change the \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"Chroma\"\n }), \" and \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"Lightness\"\n }), \" values to move the color into the P3 area. The \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"Lightness\"\n }), \" chart will provide the best feedback. Simply move the color above the thin white line.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Copy the result and wrap it with a \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"color-gamut: p3\"\n }), \" media query.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(48, 189, 68)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"color(display-p3 0.1530 0.7673 0.0793)\",\n top: \"calc(5 * var(--c))\",\n left: \"calc(16 * var(--l))\"\n },\n className: \"oklch-preview without-opacity\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-diff-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.7\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.2\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"145\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line inserted\",\n children: [_jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsxs(_components.span, {\n className: \"token atrule\",\n children: [_jsx(_components.span, {\n className: \"token rule\",\n children: \"@media\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token property\",\n children: \"color-gamut\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" p3\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line inserted\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token combinator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":root\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line inserted\",\n children: [_jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token number\",\n children: \"0.7\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.29\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"145\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line inserted\",\n children: [_jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line inserted\",\n children: [_jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsx(_components.h3, {\n id: \"extra-oklch-in-svg\",\n children: \"Extra: OKLCH in SVG\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"You can use OKLCH, not only in CSS, but also in SVGs (or HTML). For instance, this could be useful for adding unique, rich colors to \", _jsx(_components.a, {\n href: \"https://codepen.io/egodyston/pen/rNJRgBo\",\n children: \"app icons\"\n }), \".\"]\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsx(ReferenceBlogPost, {\n slug: `how-to-use-p3-colors-in-svg`,\n randomColorIndex: 1,\n title: `How to use P3 colors with SVGs`,\n theme: {\n \"colors\": {\n \"logo\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"title\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"navigation\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"text\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"button\": {\n \"color\": \"0 0 0\",\n \"oklchColor\": \"0.0000% 0.0000 0.0000\",\n \"opacity\": \"5.00%\"\n },\n \"background\": {\n \"color\": \"242 191 240\",\n \"oklchColor\": \"86.4881% 0.0864 327.5589\",\n \"opacity\": \"100%\"\n }\n },\n \"meta\": {\n \"whiteBg\": false,\n \"isDefault\": false\n }\n },\n createdAt: `May 25, 2022`,\n dateISO: \"2022-05-25T00:00:00.000Z\",\n bgImage: {\n \"publicURL\": \"/static/c17e33ec8745a956320e2e17b547bb52/bg.jpg?v=fde39066\",\n \"relativePath\": \"2022-05-25-how-to-use-p3-colors-in-svg/bg.jpg\",\n \"width\": 2048,\n \"height\": 2048,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/worgaKSNhp2VF7TgzBLuV-OaKorRShxjYTeyL_wpwzM/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/wkfF5UV8BHFJFHkVv04f5Kkfctvcr1cIQfI4Per8DCA/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/yTovVxH40jYDR4-geRrdaxpb75vWpx4ZQQvfLd4K21s/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/Xizvzioy-bynihY-26PF1pwg92zQNBgHXOg62jgSNq8/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/Kh4N61Dbm1-z7juuEflw4zCFFUT1K0AkVbQul1qQGGE/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/ZkbMhVlzyR0u3joGNXlWoxYZ3o_CykkCUzrkA0SiXsQ/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/A4RuzXiYuw7WjuqHC6YK2tt8qtmkWO4no36u611JQ2Y/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/EXARrtdJt4WZ9jj6XCcLvvNDz3kMgCtUo7tZrBi9WXU/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/xcKH6RNeE8kgyCw7spvOwNqAPFkAKP6wcUnIls1Bixk/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/G0FxUEnADNR2h58mWErRsRGtj_mLeHBXdqgEy275U4c/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/ZPp0wJiSXTe8eu3HBE93nU8u9nyoA_1kRxm1Km09BT0/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/nI_OiV0ANie-4kSB9zB8Uy3mOi0aW48DlIVVok6Z5sM/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }, {\n \"width\": 1440,\n \"avif\": \"https://imgproxy.evilmartians.com/TA4aGpS3XOeJcTYSzFLDQ-3bJsjpJv7T7RIUuYwiL0A/width:1440/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/j8jRzUcj4QQ80h7kOdKUxXG1b7Fq8Ca0-96MkV7hP3Q/width:1440/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }, {\n \"width\": 1920,\n \"avif\": \"https://imgproxy.evilmartians.com/H8wrCD8FniEE7io-SNJ17hAN-Wt58Iblonx9H_eyUPg/width:1920/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/SK0gsQxRzpt1VM7Q6uh7wYcH1-ff1ADtpVA2AZZMpLg/width:1920/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }, {\n \"width\": 2048,\n \"avif\": \"https://imgproxy.evilmartians.com/TMoCJpgdASyJFsmP8AEaHeZOcuQcITzGZACaEa75l-8/width:2048/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\",\n \"webp\": \"https://imgproxy.evilmartians.com/ac1bPKGkaEHsRpqPT2yiJIdhLDnRMpTOum3BzL0kihE/width:2048/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jMTdlMzNlYzg3NDVhOTU2MzIwZTJlMTdiNTQ3YmI1Mi9iZy5qcGc_dj1mZGUzOTA2Ng\"\n }]\n },\n bgColorOverflow: false,\n isBgFullSize: false,\n type: `blogPost`\n })\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"color(display-p3 0.0505 0.5557 0.0653)\",\n top: \"calc(4 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview without-opacity\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#048c2c\",\n top: \"calc(9 * var(--c))\",\n left: \"calc(15 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-xml\",\n children: _jsxs(_components.code, {\n className: \"language-xml code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"<\"\n }), \"svg\"]\n }), \" \", _jsx(_components.span, {\n className: \"token attr-name\",\n children: \"viewBox\"\n }), _jsxs(_components.span, {\n className: \"token attr-value\",\n children: [_jsx(_components.span, {\n className: \"token punctuation attr-equals\",\n children: \"=\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n }), \"0 0 120 120\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token attr-name\",\n children: \"xmlns\"\n }), _jsxs(_components.span, {\n className: \"token attr-value\",\n children: [_jsx(_components.span, {\n className: \"token punctuation attr-equals\",\n children: \"=\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n }), \"http://www.w3.org/2000/svg\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n })]\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \">\"\n })]\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"<\"\n }), \"style\"]\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \">\"\n })]\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \" @media (color-gamut: p3) {\\n\"\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \" rect {\\n\"\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \" fill: oklch(0.55 0.23 146)\\n\"\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \" }\\n\"\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \" }\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\"\n })]\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"<\"\n }), \"rect\"]\n }), \" \", _jsx(_components.span, {\n className: \"token attr-name\",\n children: \"x\"\n }), _jsxs(_components.span, {\n className: \"token attr-value\",\n children: [_jsx(_components.span, {\n className: \"token punctuation attr-equals\",\n children: \"=\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n }), \"10\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token attr-name\",\n children: \"y\"\n }), _jsxs(_components.span, {\n className: \"token attr-value\",\n children: [_jsx(_components.span, {\n className: \"token punctuation attr-equals\",\n children: \"=\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n }), \"10\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token attr-name\",\n children: \"width\"\n }), _jsxs(_components.span, {\n className: \"token attr-value\",\n children: [_jsx(_components.span, {\n className: \"token punctuation attr-equals\",\n children: \"=\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n }), \"100\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token attr-name\",\n children: \"height\"\n }), _jsxs(_components.span, {\n className: \"token attr-value\",\n children: [_jsx(_components.span, {\n className: \"token punctuation attr-equals\",\n children: \"=\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n }), \"100\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n })]\n }), \"\\n\"]\n })]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token tag\",\n children: [\" \", _jsx(_components.span, {\n className: \"token attr-name\",\n children: \"fill\"\n }), _jsxs(_components.span, {\n className: \"token attr-value\",\n children: [_jsx(_components.span, {\n className: \"token punctuation attr-equals\",\n children: \"=\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n }), \" #048c2c\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\\\"\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"/>\"\n })]\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsxs(_components.span, {\n className: \"token tag\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"\"\n })]\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsx(_components.h3, {\n id: \"extra-oklchoklab-in-gradients\",\n children: \"Extra: OKLCH/Oklab in gradients\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"A gradient is a path through a color space between 2 or more dots. This means that if you change your color space, you’ll end up with a very different gradient for the same starting and ending colors.\"\n }), \"\\n\", _jsxs(Figure, {\n align: `max`,\n padding: undefined,\n children: [_jsx(Image, {\n path: `color-space-gradients.png`,\n alt: `There are four squares. Each square shows the code for gradients with sRBG, Oklab, and OKLCH. The code in each block is the same, but for each color space, the gradient is slightly different.`,\n expandToEdges: undefined,\n imgproxyImageData: {\n \"publicURL\": \"/static/c6a285357558ad9f86f206d7f92fbe5c/color-space-gradients.png\",\n \"width\": 842,\n \"height\": 261,\n \"imgproxySources\": [{\n \"width\": 48,\n \"avif\": \"https://imgproxy.evilmartians.com/g6hadb-a9cofjIro01x_9lllx32diF3rl-cLb80R4nU/width:48/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/YP3RVnA22QYeWFQ8vJ5uB8sksQ9GSIoRnUWAmP1Zu6c/width:48/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\"\n }, {\n \"width\": 96,\n \"avif\": \"https://imgproxy.evilmartians.com/Cgz8-BWC2cXiATVE_UhgV-HDS9V50Jbp8L1ovfkwSEc/width:96/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/WNFBsAYpFPKdk3VAmwux2O2xnNY2dekYFNKaJ4PL6yw/width:96/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\"\n }, {\n \"width\": 192,\n \"avif\": \"https://imgproxy.evilmartians.com/6ATa3vaJ9xv7DtFNfeSp5zlHTKM2dKPtlzohNXVKiEk/width:192/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/zAMF_DosiFvD8R6xbAKi14KkQXo0FEBcS9ryihIGp4A/width:192/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\"\n }, {\n \"width\": 384,\n \"avif\": \"https://imgproxy.evilmartians.com/tbnHqxxOhisak9tsPPfhCoHrlcz7kvq5VX9Ymv8pyIw/width:384/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/U0DyZmzGFwGExY97NtcQmPwVgd0GpgVSCJE3hY54i94/width:384/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\"\n }, {\n \"width\": 768,\n \"avif\": \"https://imgproxy.evilmartians.com/KJkWcdeeu92ykluH-3q8iZp3qPjuaBaU7V5v273M1Qo/width:768/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/6bMqyyGSPHqivdo0EORc2g3cac3T9xTQl17Irn0VB6U/width:768/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\"\n }, {\n \"width\": 1080,\n \"avif\": \"https://imgproxy.evilmartians.com/Kxe_wyrn-yCdh631D272m4eMQZq_MNgk6Y95WxYltDo/width:1080/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/vjqiC-ZI7jxANh5EpJRAb6nmsYGg7qRTn79Br00l0L8/width:1080/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\"\n }, {\n \"width\": 1440,\n \"avif\": \"https://imgproxy.evilmartians.com/SF0wUr48L4hDxkMJTXLtMkRVgdp4ePFc2FB9QJb0tis/width:1440/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/tE9e-WnP_zNo5BPLeJuE2PC4DPslepWLsbupqVajw80/width:1440/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\"\n }, {\n \"width\": 1684,\n \"avif\": \"https://imgproxy.evilmartians.com/qpqduaviQD9KwCROZNq_vHYxCYj7sf64vLJfVZ4cinE/width:1684/quality:80/format:avif/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\",\n \"webp\": \"https://imgproxy.evilmartians.com/AADKrlrd35NG6v7-P4GJRgh1aQoZzGHJu30WTcOk0ys/width:1684/quality:80/format:webp/aHR0cHM6Ly9ldmlsbWFydGlhbnMuY29tL3N0YXRpYy9jNmEyODUzNTc1NThhZDlmODZmMjA2ZDdmOTJmYmU1Yy9jb2xvci1zcGFjZS1ncmFkaWVudHMucG5n\"\n }]\n },\n width: 842,\n height: 261\n }), _jsx(Figcaption, {\n children: _jsx(_components.p, {\n children: \"Gradients in different color spaces\"\n })\n })]\n }), \"\\n\", _jsx(_components.p, {\n children: \"For gradients, there is no silver bullet; different tasks will require a different color space. But the Oklab color space (OKLCH’s sister that lives on top of cartesian coordinates) often has good results:\"\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsxs(_components.p, {\n children: [\"You can make gradients even more beautiful by changing the colors \", _jsx(_components.a, {\n href: \"https://larsenwork.com/easing-gradients/\",\n children: \"with easing\"\n }), \".\"]\n })\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsx(_components.li, {\n children: \"It has no grayish area in the middle as default (sRGB) gradients.\"\n }), \"\\n\", _jsx(_components.li, {\n children: \"It has not blue-to-purple shift as Lab.\"\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.a, {\n href: \"https://drafts.csswg.org/css-images-4/#linear-gradients\",\n children: \"CSS Image 4 specification\"\n }), \" has a special syntax to change the color space in gradients:\"]\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".oklch\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\"\\t\", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"linear-gradient\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"in oklab\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token color\",\n children: \"blue\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" \", _jsx(_components.span, {\n className: \"token color\",\n children: \"green\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n }), \"\\n\", _jsx(_components.h3, {\n id: \"extra-color-modification-with-oklch\",\n children: \"Extra: Color modification with OKLCH\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Right now all browsers support native CSS color modification (relative colors) from \", _jsx(_components.a, {\n href: \"https://www.w3.org/TR/css-color-5/#relative-colors\",\n children: \"CSS Colors 5\"\n }), \".\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"OKLCH is incredibly good for color modification: unlike HSL, it has predicted lightness, and unlike LCH, it doesn’t have any problems with hue shifts upon chroma changes.\"\n }), \"\\n\", _jsx(Sidenote, {\n children: _jsxs(_components.p, {\n children: [\"No, we \", _jsx(_components.a, {\n href: \"https://github.com/w3c/csswg-drafts/issues/9955\",\n children: \"can’t use\"\n }), \" \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"%\"\n }), \" in \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"calc\"\n }), \" inside relative colors. This is why instead of \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"10%\"\n }), \" we are using \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"0.1\"\n }), \" here.\"]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Here’s how you can define a 10% darker \", _jsx(_components.code, {\n className: \"language-text\",\n children: \":hover\"\n }), \" background for a button:\"]\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(165, 145, 213)\",\n top: \"calc(1 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(135, 115, 181)\",\n top: \"calc(4 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":hover\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"calc\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"l \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"-\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" c h\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"With CSS Custom Properties, we can define the \", _jsx(_components.code, {\n className: \"language-text\",\n children: \":hover\"\n }), \" logic just once and then create many variants simply by changing the source color.\"]\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(117, 161, 220)\",\n top: \"calc(9 * var(--c))\",\n left: \"calc(18 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgba(117, 161, 220, 0.5)\",\n top: \"calc(12 * var(--c))\",\n left: \"calc(18 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(214, 133, 131)\",\n top: \"calc(15 * var(--c))\",\n left: \"calc(18 * var(--l))\"\n },\n className: \"oklch-preview\"\n })]\n }), _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--button-color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token pseudo-class\",\n children: \":hover\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* One :hover for normal, secondary, and error states */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--button-color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"calc\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"l \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"+\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" c h\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--button-color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--accent\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-secondary\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--button-color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--dimmed\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsxs(_components.span, {\n className: \"token selector\",\n children: [_jsx(_components.span, {\n className: \"token class\",\n children: \".button\"\n }), _jsx(_components.span, {\n className: \"token class\",\n children: \".is-error\"\n })]\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token variable\",\n children: \"--button-color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--error\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n })]\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"Thanks to OKLCH’s predictable lightness, we can work with colors from user input and have good a11y on our sites.\"\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-css\",\n children: _jsxs(_components.code, {\n className: \"language-css code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token selector\",\n children: _jsx(_components.span, {\n className: \"token class\",\n children: \".header\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* JS will set --user-avatar-dominant */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"background\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token function\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"from \", _jsx(_components.span, {\n className: \"token function\",\n children: \"var\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token variable\",\n children: \"--user-avatar-dominant\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.8\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.17\"\n }), \" h\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token comment\",\n children: \"/* With OKLCH, we're sure that black text will\\n\"\n })]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token comment\",\n children: \" always be readable on any hue, since we set L to 80% */\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" \", _jsx(_components.span, {\n className: \"token property\",\n children: \"color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token color\",\n children: \"black\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \";\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n })]\n })\n }), \"\\n\", _jsx(_components.h3, {\n id: \"extra-oklch-in-js\",\n children: \"Extra: OKLCH in JS\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"With \", _jsx(_components.a, {\n href: \"https://colorjs.io/\",\n children: \"Color.js\"\n }), \" or \", _jsx(_components.a, {\n href: \"https://culorijs.org/\",\n children: \"culori\"\n }), \", you can transform colors in JS while reaping all the benefits of OKLCH color space. You can check examples with culori using the \", _jsx(_components.a, {\n href: \"https://github.com/evilmartians/oklch-picker\",\n children: \"OKLCH Color Picker source code\"\n }), \". In this article, I’ll use Color.js.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"Here’s an example that shows off making an accent color from a custom color:\"\n }), \"\\n\", _jsx(_components.pre, {\n className: \"language-js\",\n children: _jsxs(_components.code, {\n className: \"language-js code-highlight\",\n children: [_jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token keyword module\",\n children: \"import\"\n }), \" \", _jsx(_components.span, {\n className: \"token imports\",\n children: _jsx(_components.span, {\n className: \"token maybe-class-name\",\n children: \"Color\"\n })\n }), \" \", _jsx(_components.span, {\n className: \"token keyword module\",\n children: \"from\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"'colorjs.io'\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token comment\",\n children: \"// Parse any CSS color\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token keyword\",\n children: \"let\"\n }), \" accent \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"=\"\n }), \" \", _jsx(_components.span, {\n className: \"token keyword\",\n children: \"new\"\n }), \" \", _jsx(_components.span, {\n className: \"token class-name\",\n children: \"Color\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), \"userAvatarDominant\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token comment\",\n children: \"// Set lightness and chroma\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\"accent\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"l\"\n }), \" \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"=\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.8\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\"accent\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"c\"\n }), \" \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"=\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.17\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token comment\",\n children: \"// Gamut mapping to sRGB if we are out of sRGB\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token keyword control-flow\",\n children: \"if\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token operator\",\n children: \"!\"\n }), \"accent\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"inGamut\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token string\",\n children: \"'srgb'\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\" accent \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"=\"\n }), \" accent\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"toGamut\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"{\"\n }), \" \", _jsx(_components.span, {\n className: \"token literal-property property\",\n children: \"space\"\n }), _jsx(_components.span, {\n className: \"token operator\",\n children: \":\"\n }), \" \", _jsx(_components.span, {\n className: \"token string\",\n children: \"'srgb'\"\n }), \" \", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token punctuation\",\n children: \"}\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token comment\",\n children: \"// Make the color 10% lighter\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token keyword\",\n children: \"let\"\n }), \" hover \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"=\"\n }), \" accent\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"clone\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [\"hover\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"oklch\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"l\"\n }), \" \", _jsx(_components.span, {\n className: \"token operator\",\n children: \"+=\"\n }), \" \", _jsx(_components.span, {\n className: \"token number\",\n children: \"0.1\"\n }), \"\\n\"]\n }), _jsx(_components.span, {\n className: \"code-line\",\n children: \"\\n\"\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token dom variable\",\n children: \"document\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"body\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"style\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"setProperty\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token string\",\n children: \"'--accent'\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" accent\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"to\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token string\",\n children: \"'srgb'\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"toString\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \"\\n\"]\n }), _jsxs(_components.span, {\n className: \"code-line\",\n children: [_jsx(_components.span, {\n className: \"token dom variable\",\n children: \"document\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"body\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token property-access\",\n children: \"style\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"setProperty\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token string\",\n children: \"'--accent-hover'\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \",\"\n }), \" hover\", _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"to\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token string\",\n children: \"'srgb'\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \".\"\n }), _jsx(_components.span, {\n className: \"token method function property-access\",\n children: \"toString\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \"(\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), _jsx(_components.span, {\n className: \"token punctuation\",\n children: \")\"\n }), \"\\n\"]\n })]\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"You can use these libraries to generate an entire design system palette in the OKLCH color space. This allows you to have predicted contrast and better accessibility. As an example of this in practice, \", _jsx(_components.a, {\n href: \"https://huetone.ardov.me/\",\n children: \"Huetone\"\n }), \", an accessible palette generator, uses Oklab by default.\"]\n }), \"\\n\", _jsx(_components.h2, {\n id: \"summing-why-we-moved-to-oklch\",\n children: \"Summing why we moved to OKLCH\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"At our company, we already use OKLCH in our projects—as a matter of fact, the website you’re on right now uses \", _jsx(_components.code, {\n className: \"language-text\",\n children: \"oklch()\"\n }), \", too. So, here’s the question of the moment: what benefits have we gained after moving to OKLCH?\"]\n }), \"\\n\", _jsx(_components.h3, {\n id: \"1-better-readability\",\n children: \"1. Better readability\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"With OKLCH, we can understand colors just by looking at code.\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"For instance, we can compare darkness in the code and find some contrast-related accessibility issues:\"\n }), \"\\n\", _jsx(\"div\", {\n className: \"em-highlight\",\n children: _jsxs(\"div\", {\n className: \"manual-wrapper-language-css\",\n children: [_jsxs(\"div\", {\n className: \"oklch-overlay\",\n children: [_jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(191, 187, 201)\",\n top: \"calc(2 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"#fff\",\n top: \"calc(3 * var(--c))\",\n left: \"calc(9 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n style: {\n background: \"rgb(248, 213, 207)\",\n top: \"calc(8 * var(--c))\",\n left: \"calc(14 * var(--l))\"\n },\n className: \"oklch-preview\"\n }), _jsx(\"div\", {\n \"data-l\": \"1\",\n

Read the original on evilmartians.com ↗