{
    "version": "https://jsonfeed.org/version/1",
    "title": "EverShop Blog",
    "home_page_url": "https://evershop.io/blog",
    "description": "Release notes, upgrade guides and announcements from the EverShop team.",
    "items": [
        {
            "id": "https://evershop.io/blog/re-skinning-a-store",
            "content_html": "<p>There are four ways to change how the storefront looks, and they are not equal. Each step down this ladder gives you more control and costs you more on every upgrade.</p>\n<p><strong>Start at step 1 and stop as soon as the design is achieved.</strong> A theme built entirely on steps 1 and 2 survives a major EverShop upgrade untouched. A theme that forks twenty components does not — as the React 17 → 19 upgrade demonstrated, forked components keep their old assumptions and break silently.</p>\n<!-- -->\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"A default EverShop storefront showing a featured product grid and a collection section. Everything visible here — the type scale, colours, card layout and grid — is reachable from steps 1 and 2 without forking a single component.\" src=\"https://evershop.io/assets/images/storefront-8ef74389fc1ddad76ad209bb740a8dda.jpg\" width=\"1200\" height=\"630\" class=\"img_ev3q\"></p>\n<p>Everything visible above — type scale, colours, card layout, grid columns — is reachable from steps 1 and 2. Reach for step 4 only when the <em>structure</em> has to change.</p>\n<table class=\"table-auto not-prose\"><thead><tr><th>Step</th><th>Technique</th><th>Upgrade cost</th><th>Use when</th></tr></thead><tbody><tr><td>1</td><td>Design tokens</td><td>None</td><td>Colour, radius, spacing, type scale</td></tr><tr><td>2</td><td>CSS against core class hooks</td><td>Near zero</td><td>Layout tweaks, decoration, spacing on specific blocks</td></tr><tr><td>3</td><td>Additive components in existing Areas</td><td>Low</td><td>Adding something core does not render</td></tr><tr><td>4</td><td>Component override</td><td>High — you own it forever</td><td>The markup or behaviour itself must change</td></tr></tbody></table>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-1--design-tokens\">Step 1 — Design tokens<a href=\"https://evershop.io/blog/re-skinning-a-store#step-1--design-tokens\" class=\"hash-link\" aria-label=\"Direct link to Step 1 — Design tokens\" title=\"Direct link to Step 1 — Design tokens\">​</a></h2>\n<p>Most re-skins are entirely a token exercise. Core's components are built on CSS custom properties, so redefining them in your theme's <code>tailwind.css</code> restyles every component at once, including ones added in future releases.</p>\n<div class=\"language-css codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-css codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token selector pseudo-class\" style=\"color:rgb(199, 146, 234)\">:root</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.55</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.18</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">264</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.98</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.75</span><span class=\"token unit\">rem</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>See <a href=\"https://evershop.io/docs/development/theme/styling\">Styling</a> for the full token set and the Tailwind v4 setup.</p>\n<div class=\"theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z\"></path></svg></span>Carry over the dark-mode variant</div><div class=\"admonitionContent_BuS1\"><p>If your theme replaces <code>TailwindCss.tsx</code> and ships its own <code>tailwind.css</code>, it must carry over the class-based <code>@custom-variant dark (&amp;:is(.dark *))</code> line. Without it every <code>dark:</code> utility inside the shared <code>ui/*</code> primitives activates from the OS setting while your <code>.dark</code> tokens stay inactive — half-dark components on a light page.</p></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-2--css-against-core-class-hooks\">Step 2 — CSS against core class hooks<a href=\"https://evershop.io/blog/re-skinning-a-store#step-2--css-against-core-class-hooks\" class=\"hash-link\" aria-label=\"Direct link to Step 2 — CSS against core class hooks\" title=\"Direct link to Step 2 — CSS against core class hooks\">​</a></h2>\n<p>Core markup carries stable, semantic class names intended as styling targets. Writing CSS against them changes appearance without owning any component.</p>\n<div class=\"language-css codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-css codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token selector class\" style=\"color:rgb(199, 146, 234)\">.category__hero</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token property\">padding-block</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">4</span><span class=\"token unit\">rem</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token selector class\" style=\"color:rgb(199, 146, 234)\">.product__grid</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token property\">gap</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">2.5</span><span class=\"token unit\">rem</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token selector class\" style=\"color:rgb(199, 146, 234)\">.product__filters</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token property\">border-inline-end</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token unit\">px</span><span class=\"token plain\"> solid </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--divider</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>Verified hooks include <code>header__middle__left</code>, <code>category__hero</code>, <code>product__grid</code>, <code>product__filters</code> and <code>variant-option-list</code>. Inspect the rendered page to find others.</p>\n<div class=\"theme-admonition theme-admonition-danger admonition_xJq3 alert alert--danger\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 12 16\"><path fill-rule=\"evenodd\" d=\"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z\"></path></svg></span>Write these rules outside every <code>@layer</code></div><div class=\"admonitionContent_BuS1\"><p>Tailwind v4 puts its utilities in <code>@layer utilities</code>. Unlayered author CSS wins against <strong>any</strong> layered rule regardless of specificity, so a plain rule beats core's utilities. Put the same rule inside a layer and it loses — which reads as \"my CSS is being ignored\".</p></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-3--additive-components-in-existing-areas\">Step 3 — Additive components in existing Areas<a href=\"https://evershop.io/blog/re-skinning-a-store#step-3--additive-components-in-existing-areas\" class=\"hash-link\" aria-label=\"Direct link to Step 3 — Additive components in existing Areas\" title=\"Direct link to Step 3 — Additive components in existing Areas\">​</a></h2>\n<p>To add something core does not render, drop a component into an existing Area rather than forking the component that surrounds it. Your file is additive: core's component keeps receiving upgrades, and yours keeps rendering beside it.</p>\n<div class=\"language-tsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-tsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// themes/my-theme/src/pages/productView/SizeGuideLink.tsx</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">default</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">SizeGuideLink</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\">a</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\"> </span><span class=\"token tag attr-name\" style=\"color:rgb(255, 203, 107)\">href</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:rgb(199, 146, 234)\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:rgb(199, 146, 234)\">\"</span><span class=\"token tag attr-value\" style=\"color:rgb(255, 85, 114)\">/size-guide</span><span class=\"token tag attr-value punctuation\" style=\"color:rgb(199, 146, 234)\">\"</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\"> </span><span class=\"token tag attr-name\" style=\"color:rgb(255, 203, 107)\">className</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:rgb(199, 146, 234)\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:rgb(199, 146, 234)\">\"</span><span class=\"token tag attr-value\" style=\"color:rgb(255, 85, 114)\">text-sm underline</span><span class=\"token tag attr-value punctuation\" style=\"color:rgb(199, 146, 234)\">\"</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain-text\">Size guide</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;/</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\">a</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">const</span><span class=\"token plain\"> layout </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  areaId</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'productNameAfter'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  sortOrder</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">10</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>Useful storefront Areas include <code>productNameBefore</code>, <code>productNameAfter</code>, <code>productPageMiddleRight</code>, <code>beforeCategoryInfo</code> and <code>searchPageBottom</code>. See <a href=\"https://evershop.io/docs/development/theme/view-system\">View System</a> for how Areas resolve and <a href=\"https://evershop.io/docs/development/theme/templating\">Templating</a> for the full list.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-4--component-override\">Step 4 — Component override<a href=\"https://evershop.io/blog/re-skinning-a-store#step-4--component-override\" class=\"hash-link\" aria-label=\"Direct link to Step 4 — Component override\" title=\"Direct link to Step 4 — Component override\">​</a></h2>\n<p>Only when the markup or behaviour itself must change. <code>npm run theme:twizz</code> ejects a core component and its relative-import closure into your theme, after which <strong>you own that file permanently</strong> — it stops receiving fixes, accessibility improvements and framework migrations.</p>\n<p>Before overriding, check whether steps 1–3 get you there. If you must override:</p>\n<ul>\n<li>Re-read the component after every EverShop upgrade and diff it against the new core version.</li>\n<li>Preserve the accessibility contract — see <a href=\"https://evershop.io/docs/development/theme/accessibility\">Accessibility</a>. Forks are exactly where <code>aria-describedby</code> wiring and keyboard-reachable Add-to-Cart quietly disappear.</li>\n<li>Preserve React 19 rules — see <a href=\"https://evershop.io/blog/upgrading-to-react-19\">Upgrading To React 19</a>. Module-scope <code>_()</code> calls and <code>defaultProps</code> are the two that fail silently.</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"a-worked-decision\">A worked decision<a href=\"https://evershop.io/blog/re-skinning-a-store#a-worked-decision\" class=\"hash-link\" aria-label=\"Direct link to A worked decision\" title=\"Direct link to A worked decision\">​</a></h2>\n<p>Say the design calls for product cards with a coloured badge, tighter grid spacing and the price above the title.</p>\n<ul>\n<li>Badge colour and card radius → <strong>step 1</strong>, tokens.</li>\n<li>Grid spacing → <strong>step 2</strong>, <code>.product__grid { gap: … }</code>.</li>\n<li>Adding the badge → <strong>step 3</strong>, a component in <code>productNameBefore</code>.</li>\n<li>Moving the price above the title → <strong>step 4</strong>. Reordering is a markup change, so this one genuinely needs an override — and it is the only part of the design that costs you on upgrades.</li>\n</ul>\n<p>Three of the four requirements never touch a core component.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"see-also\">See also<a href=\"https://evershop.io/blog/re-skinning-a-store#see-also\" class=\"hash-link\" aria-label=\"Direct link to See also\" title=\"Direct link to See also\">​</a></h2>\n<ul>\n<li><a href=\"https://evershop.io/docs/development/theme/styling\">Styling</a> — tokens, Tailwind v4, SCSS and global CSS</li>\n<li><a href=\"https://evershop.io/docs/development/theme/theme-overview\">Theme Overview</a> — theme structure and the override seams</li>\n<li><a href=\"https://evershop.io/docs/development/theme/view-system\">View System</a> — how Areas compose a page</li>\n<li><a href=\"https://evershop.io/docs/development/theme/accessibility\">Accessibility</a> — the contract an override must preserve</li>\n<li><a href=\"https://evershop.io/blog/upgrading-to-react-19\">Upgrading To React 19</a> — why forks break silently</li>\n</ul>",
            "url": "https://evershop.io/blog/re-skinning-a-store",
            "title": "Re-skinning A Store Without Forking Core",
            "summary": "Four ways to change how an EverShop storefront looks, ordered by what each one costs you at upgrade time.",
            "date_modified": "2026-08-13T00:00:00.000Z",
            "author": {
                "name": "Evershop Team",
                "url": "https://evershop.io"
            },
            "tags": [
                "themes"
            ]
        },
        {
            "id": "https://evershop.io/blog/release-notes-v2-2-1",
            "content_html": "<p><strong>EverShop v2.2.1 is out.</strong> It is the largest release since 2.0: four months of work that adds a visual page builder, a blog module, typed custom fields on every entity, a completely rebuilt shipping and fulfillment stack, built-in cloud file storage and product recommendations — on top of a move to React 19.</p>\n<p>It also fixes several security vulnerabilities, so upgrading promptly is recommended.</p>\n<!-- -->\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"-visual-page-builder\">🎨 Visual Page Builder<a href=\"https://evershop.io/blog/release-notes-v2-2-1#-visual-page-builder\" class=\"hash-link\" aria-label=\"Direct link to 🎨 Visual Page Builder\" title=\"Direct link to 🎨 Visual Page Builder\">​</a></h2>\n<p>A new core module gives you drag-and-drop storefront editing at <code>/admin/page-builder</code>.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"The EverShop page builder: a widget palette on the left with Content and Commerce categories, the live storefront canvas in the middle, and device preview, undo/redo and Publish controls in the top bar.\" src=\"https://evershop.io/assets/images/page-builder-75fe8f776be9710a073147c0e9da242b.jpg\" width=\"1568\" height=\"736\" class=\"img_ev3q\"></p>\n<p>You compose widgets into your theme's areas and edit text and images directly on the canvas. Everything you change goes into a <strong>draft</strong> that only you see — one draft per admin, per theme — so two people can work on the same store without colliding, and nothing reaches shoppers until you publish.</p>\n<p>When the draft is ready you can publish it immediately or <strong>schedule a rollout</strong>. Rollout plans stay editable and cancelable right up until they run, so a campaign scheduled for Friday can still be adjusted on Thursday.</p>\n<p>The editor also gives you a layers panel, per-widget styling controls, device preview modes, undo/redo tracked per route, and a \"Globals\" view for areas that appear on every page.</p>\n<p>For theme developers: a route opts into the builder by adding <code>\"editable\": true</code> to its <code>route.json</code>. Thirteen core routes ship with it, including the homepage, category, product, search, cart, checkout and the blog pages.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"-blog\">📝 Blog<a href=\"https://evershop.io/blog/release-notes-v2-2-1#-blog\" class=\"hash-link\" aria-label=\"Direct link to 📝 Blog\" title=\"Direct link to 📝 Blog\">​</a></h2>\n<p>A full blog module — posts, categories, tags, comments and reactions — with storefront pages, an RSS feed and page-builder widgets.</p>\n<p>Comment moderation policy lives on the <strong>category</strong>, not the post: each category is <code>open</code>, <code>moderated</code> or <code>closed</code>, which lets you run an open comment section on tutorials while locking it on announcements. Posts support four reaction types; comments support likes.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Creating a blog category in the EverShop admin, with the comment policy set to Moderated — hold for review, alongside the Open and Closed options, and a Custom fields card on the same form.\" src=\"https://evershop.io/assets/images/blog-comment-policy-a459ed1b5e1a75210d8986780129152d.jpg\" width=\"1568\" height=\"736\" class=\"img_ev3q\"></p>\n<p>Blog posts and categories are also metafield owners (below), so you can add your own typed fields to them.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"️-metafields\">🏷️ Metafields<a href=\"https://evershop.io/blog/release-notes-v2-2-1#%EF%B8%8F-metafields\" class=\"hash-link\" aria-label=\"Direct link to 🏷️ Metafields\" title=\"Direct link to 🏷️ Metafields\">​</a></h2>\n<p>Typed custom fields, now on products, categories, collections, customers, orders, blog posts, blog categories and the shop itself.</p>\n<p>Ten field types ship — short text, long text, rich text, integer, number, boolean, date, colour, URL and nested groups — each available as a single value or a list. Values are validated on write against the definition, and every field declares whether it is visible to customers or admin-only, so a field marked internal never reaches the storefront GraphQL schema.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Defining a metafield in the EverShop admin: name, description, key and type, with toggles for Allow multiple, Required and Visible to customer, and a collapsible Validation section.\" src=\"https://evershop.io/assets/images/metafields-ff72a9b397fe7a6284b53819baade374.jpg\" width=\"1568\" height=\"736\" class=\"img_ev3q\"></p>\n<p>The part worth knowing for theme authors: <strong>a theme can declare its own field definitions in <code>theme.json</code></strong>. They are provisioned when the theme is activated and re-checked on every boot, with attribution recorded so you can see which theme created which field. A new <code>&lt;Metafield&gt;</code> component renders them on the storefront.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"-shipping-and-fulfillment-rebuilt\">📦 Shipping and fulfillment, rebuilt<a href=\"https://evershop.io/blog/release-notes-v2-2-1#-shipping-and-fulfillment-rebuilt\" class=\"hash-link\" aria-label=\"Direct link to 📦 Shipping and fulfillment, rebuilt\" title=\"Direct link to 📦 Shipping and fulfillment, rebuilt\">​</a></h2>\n<p>This is the largest change in the release, and the one most likely to affect existing extensions.</p>\n<p><strong>Shipping is now provider-based.</strong> The old flat zone → method → rate model is gone. Zones now have <em>providers</em> attached to them, and each provider supplies its own methods — either statically or by quoting live rates against a carrier API, with a per-provider timeout so a slow API degrades that one provider instead of hanging checkout. Your existing zones, methods and rates are migrated automatically into a built-in <strong>Core provider</strong> that behaves like the old system.</p>\n<p>Zones also became multi-country: a single \"EU\" zone can now cover every member state instead of needing one zone per country.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"The Shipping Providers settings page showing the built-in Core Shipping provider with its methods, each row listing status and the zones it serves.\" src=\"https://evershop.io/assets/images/shipping-providers-95f9536ee7946f2c2e98b61f91dc9208.jpg\" width=\"1568\" height=\"736\" class=\"img_ev3q\"></p>\n<p><strong>Fulfillment went multi-shipment.</strong> An order can now be shipped in several packages, each with its own items, status, tracking number and purchased label. The order's own shipment status became a <strong>rollup</strong> computed from those shipments — <code>pending</code>, <code>partially_shipped</code>, <code>shipped</code>, <code>partially_delivered</code>, <code>delivered</code>, <code>partially_canceled</code> or <code>canceled</code> — so an order with two of three parcels dispatched reports that accurately rather than being either \"shipped\" or not.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"A shipment card on an order in the EverShop admin, listing the items in that parcel with its own Shipped status, carrier, tracking number, and per-shipment actions to mark delivered, edit tracking or cancel.\" src=\"https://evershop.io/assets/images/shipments-5eb94b2bb4195ce363e29b26234c16d0.jpg\" width=\"1568\" height=\"736\" class=\"img_ev3q\"></p>\n<p><strong>Carriers are a registry.</strong> An extension can register a carrier that creates labels, generates tracking URLs and pushes status updates back into EverShop. Purchased labels are stored against the shipment. A <code>custom</code> carrier ships in core for manual tracking numbers.</p>\n<p><strong>Packages</strong> round it out: define your box and envelope sizes once, assign one to each product, and dimensions flow through the cart into the order and on to the carrier when a label is bought.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"️-cloud-file-storage\">☁️ Cloud file storage<a href=\"https://evershop.io/blog/release-notes-v2-2-1#%EF%B8%8F-cloud-file-storage\" class=\"hash-link\" aria-label=\"Direct link to ☁️ Cloud file storage\" title=\"Direct link to ☁️ Cloud file storage\">​</a></h2>\n<p>S3, Azure Blob and Google Cloud Storage are now built into core — previously these were separate extensions.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"The System Setting page in the EverShop admin, offering local file system, Amazon S3, Azure Blob Storage and Google Cloud Storage as file storage providers, with a warning that local storage is not recommended for production.\" src=\"https://evershop.io/assets/images/cloud-storage-001a63a84cfe35e4c89b4f9c46352f32.jpg\" width=\"1568\" height=\"736\" class=\"img_ev3q\"></p>\n<p>Credentials are configured on a new System Setting page and applied per call, so switching providers takes effect without a restart. Environment variables override the stored settings for anyone who prefers to keep secrets out of the database, and secrets that come from the environment render masked in the admin. The storage host is automatically allowed for the image optimizer, so images served from your bucket keep working without extra configuration.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"-product-recommendations\">🛒 Product recommendations<a href=\"https://evershop.io/blog/release-notes-v2-2-1#-product-recommendations\" class=\"hash-link\" aria-label=\"Direct link to 🛒 Product recommendations\" title=\"Direct link to 🛒 Product recommendations\">​</a></h2>\n<p>Four new shelves, all with page-builder widgets:</p>\n<ul>\n<li><strong>Related products</strong> — rule-based, matching on the same category, collection or attribute values, with an optional price band and manual overrides per product.</li>\n<li><strong>Frequently bought together</strong> — derived from real co-purchase statistics using association confidence and lift, rebuilt nightly and on demand.</li>\n<li><strong>Upsell</strong> — derived automatically from your related-products rules, restricted to pricier items. Nothing to configure.</li>\n<li><strong>Cart cross-sell</strong> — aggregates co-purchase candidates across everything in the cart, excluding what's already in it.</li>\n</ul>\n<p>Each product can inherit the global rules, override them, or pin manual picks — and the edit page previews exactly what shoppers will see, with the reason each match was chosen.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"The Recommendations card on a product edit page, with rules set to inherit category or global rules, a manual picks list, and a preview of what shoppers will see, annotated with why each product matched.\" src=\"https://evershop.io/assets/images/recommendations-468dfce866af70951f437c089246f287.jpg\" width=\"1568\" height=\"736\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"️-react-19\">⚛️ React 19<a href=\"https://evershop.io/blog/release-notes-v2-2-1#%EF%B8%8F-react-19\" class=\"hash-link\" aria-label=\"Direct link to ⚛️ React 19\" title=\"Direct link to ⚛️ React 19\">​</a></h2>\n<p>The framework moved from React 17 to React 19. Because EverShop resolves React through a single hoisted copy, your theme and extensions run on it too.</p>\n<p>Most of the breaking changes <strong>fail silently</strong> — no build error, just a blank area or an ignored default at runtime. <a href=\"https://evershop.io/blog/upgrading-to-react-19\">Upgrading Your Theme And Extensions To React 19</a> walks through every one and its fix.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"and-more\">And more<a href=\"https://evershop.io/blog/release-notes-v2-2-1#and-more\" class=\"hash-link\" aria-label=\"Direct link to And more\" title=\"Direct link to And more\">​</a></h2>\n<ul>\n<li><strong>Landing pages</strong> — standalone marketing pages built entirely in the page builder, served at root-level URLs, with duplication and scheduling.</li>\n<li><strong>Automatic URL redirects</strong> — renaming a product, category or page slug now records a redirect from the old path, so existing links and bookmarks keep working. Redirect chains collapse automatically.</li>\n<li><strong>Sitemap and robots.txt</strong> — generated automatically, refreshed on a schedule, with an extension point for adding your own URL sources.</li>\n<li><strong>CMS pages moved to root-level URLs</strong> (<code>/about-us</code> rather than <code>/page/about-us</code>), with the old paths permanently redirecting.</li>\n<li><strong>Zero-total checkout</strong> — orders that come to zero through a full discount or free products now complete through an automatic \"No payment required\" method instead of erroring.</li>\n<li><strong>Guest checkout toggle</strong> — enforced both on the checkout page and at order creation, so it can't be bypassed by an API client.</li>\n<li><strong>Product duplication</strong> — duplicate from the product grid into a pre-filled creation form.</li>\n<li><strong>Per-IP rate limiting</strong> — built in, with a stricter tier on login, registration and password-reset endpoints.</li>\n<li><strong>Accessibility</strong> — field errors are now wired to their inputs for screen readers, and product-card Add-to-Cart is reachable by keyboard and touch rather than hover only.</li>\n<li><strong>Large-catalog performance</strong> — several fixes found while load-testing a 500,000-product catalog, including a query pattern that could stall the event loop and a search plan that bypassed its index.</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"-security\">🔒 Security<a href=\"https://evershop.io/blog/release-notes-v2-2-1#-security\" class=\"hash-link\" aria-label=\"Direct link to 🔒 Security\" title=\"Direct link to 🔒 Security\">​</a></h2>\n<p>This release fixes unauthenticated SSRF, an IDOR on customer endpoints, stored XSS, and an account-takeover path via a missing authorization check on customer update. All high-severity dependency alerts were cleared. If you are running 2.1.x, upgrade.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"breaking-changes\">Breaking changes<a href=\"https://evershop.io/blog/release-notes-v2-2-1#breaking-changes\" class=\"hash-link\" aria-label=\"Direct link to Breaking changes\" title=\"Direct link to Breaking changes\">​</a></h2>\n<p>The full list is in the <a href=\"https://github.com/evershopcommerce/evershop/releases/tag/v2.2.1\" target=\"_blank\" rel=\"noopener noreferrer\">changelog</a>. The ones most likely to affect you:</p>\n<table class=\"table-auto not-prose\"><thead><tr><th>Change</th><th>What to do</th></tr></thead><tbody><tr><td><strong>React 19</strong></td><td><code>defaultProps</code> is ignored on function components, <code>propTypes</code> is gone, and <code>react-toastify</code> was replaced by <code>sonner</code>. See <a href=\"https://evershop.io/blog/upgrading-to-react-19\">the migration guide</a>.</td></tr><tr><td><strong>Shipping providers</strong></td><td>The <code>shipping_method</code> and <code>shipping_zone_method</code> tables are dropped. Extensions built on them must move to the provider registry. Your data migrates automatically.</td></tr><tr><td><strong>Multi-shipment</strong></td><td>Order and shipment went one-to-many. <code>order.shipment_status</code> is now derived — never write it directly. Shipment statuses must declare a phase.</td></tr><tr><td><strong>Widget storage</strong></td><td><code>widget</code> was renamed to <code>widget_instance</code> and placement moved to its own table. Direct SQL against the old table breaks.</td></tr><tr><td><strong>Settings moved out of config.json</strong></td><td>Currency, timezone, units, branding, catalog and tax options are admin settings now, with config kept as a fallback — except <code>themeConfig.logo</code>, which was removed outright.</td></tr><tr><td><strong>Dropped columns</strong></td><td><code>category.include_in_nav</code> (use the menu widgets) and <code>url_rewrite.language</code>.</td></tr><tr><td><strong>Build and deps</strong></td><td>The <code>--skip-minify</code> flag and <code>build-fast</code> script were removed; <code>node-cron</code> went 3 → 4, so verify custom job schedules.</td></tr></tbody></table>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"upgrading\">Upgrading<a href=\"https://evershop.io/blog/release-notes-v2-2-1#upgrading\" class=\"hash-link\" aria-label=\"Direct link to Upgrading\" title=\"Direct link to Upgrading\">​</a></h2>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">npm install @evershop/evershop@2.2.1</span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">npm run build</span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">npm run start</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>Or with Docker:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">docker pull evershop/evershop:2.2.1</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<div class=\"theme-admonition theme-admonition-danger admonition_xJq3 alert alert--danger\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 12 16\"><path fill-rule=\"evenodd\" d=\"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z\"></path></svg></span>Back up your database first</div><div class=\"admonitionContent_BuS1\"><p>This release applies <strong>32 database migrations</strong>, several of which transform data or drop legacy tables — the shipping tables are replaced by the provider model, <code>widget</code> is renamed, and shipment statuses are collapsed and recomputed. Migrations run automatically on first start and there is no down-migration. Take a backup before you begin.</p></div></div>\n<p>After upgrading:</p>\n<ol>\n<li><strong>Re-upload your logo</strong> under Store Setting → Branding. <code>themeConfig.logo</code> was removed with no fallback.</li>\n<li><strong>Check your shipping setup</strong> under the new provider-based settings. The data migrates automatically, but verify your rates.</li>\n<li><strong>Rebuild your navigation</strong> with the menu widgets if it relied on <code>include_in_nav</code>.</li>\n<li><strong>Verify custom cron schedules</strong> against node-cron 4.</li>\n<li>For custom themes and extensions, work through the <a href=\"https://evershop.io/blog/upgrading-to-react-19\">React 19 guide</a> — those changes don't announce themselves at build time.</li>\n</ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"thanks\">Thanks<a href=\"https://evershop.io/blog/release-notes-v2-2-1#thanks\" class=\"hash-link\" aria-label=\"Direct link to Thanks\" title=\"Direct link to Thanks\">​</a></h2>\n<p>Thanks to everyone who contributed to this release and to those who reported the issues it fixes. The upgrade path from 2.1.2 was rehearsed against a seeded store before release — but if you hit something, <a href=\"https://github.com/evershopcommerce/evershop/issues\" target=\"_blank\" rel=\"noopener noreferrer\">open an issue</a>.</p>",
            "url": "https://evershop.io/blog/release-notes-v2-2-1",
            "title": "EverShop v2.2.1: Page Builder, Blog, Metafields and a Rebuilt Shipping Stack",
            "summary": "The largest EverShop release since 2.0 — a visual page builder, a blog module, typed custom fields, pluggable shipping providers, multi-shipment fulfillment, built-in cloud storage and React 19.",
            "date_modified": "2026-08-12T00:00:00.000Z",
            "author": {
                "name": "Evershop Team",
                "url": "https://evershop.io"
            },
            "tags": [
                "release"
            ]
        },
        {
            "id": "https://evershop.io/blog/upgrading-to-react-19",
            "content_html": "<p>EverShop <strong>2.2.1</strong> upgraded the framework from React 17 to <strong>React 19</strong>.</p>\n<p>Because EverShop resolves React through a single hoisted copy (a webpack alias), your theme and your extensions run on the same React as the core. There is no opt-out: once you upgrade EverShop, your components are React 19 components.</p>\n<!-- -->\n<div class=\"theme-admonition theme-admonition-danger admonition_xJq3 alert alert--danger\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 12 16\"><path fill-rule=\"evenodd\" d=\"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z\"></path></svg></span>Most of these break silently</div><div class=\"admonitionContent_BuS1\"><p>None of the changes below produce a build error. Your theme compiles, the server starts, and the damage shows up at runtime as a blank area, an ignored default value, or a hydration mismatch that only appears in production. Read the whole page before upgrading a live store.</p></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"quick-checklist\">Quick checklist<a href=\"https://evershop.io/blog/upgrading-to-react-19#quick-checklist\" class=\"hash-link\" aria-label=\"Direct link to Quick checklist\" title=\"Direct link to Quick checklist\">​</a></h2>\n<p>Search your theme and extension source for each of these:</p>\n<table class=\"table-auto not-prose\"><thead><tr><th>Search for</th><th>Status</th><th>Fix</th></tr></thead><tbody><tr><td><code>defaultProps</code></td><td>Ignored on function components</td><td>ES default parameters</td></tr><tr><td><code>propTypes</code></td><td>Removed from React</td><td>Delete, or use TypeScript</td></tr><tr><td><code>react-toastify</code></td><td>No longer a dependency</td><td><code>sonner</code>, via the core re-export</td></tr><tr><td><code>ReactDOM.render</code>, <code>ReactDOM.hydrate</code></td><td>Removed</td><td><code>createRoot</code> / <code>hydrateRoot</code></td></tr><tr><td><code>findDOMNode</code></td><td>Removed</td><td>Refs</td></tr><tr><td>String refs (<code>ref=\"name\"</code>)</td><td>Removed</td><td>Callback refs or <code>useRef</code></td></tr><tr><td><code>_(</code> at module scope</td><td>Freezes the translation</td><td>Call it inside the component</td></tr><tr><td><code>useState(window...)</code></td><td>Hydration mismatch</td><td>Read it in <code>useEffect</code></td></tr></tbody></table>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"defaultprops-is-ignored-on-function-components\"><code>defaultProps</code> is ignored on function components<a href=\"https://evershop.io/blog/upgrading-to-react-19#defaultprops-is-ignored-on-function-components\" class=\"hash-link\" aria-label=\"Direct link to defaultprops-is-ignored-on-function-components\" title=\"Direct link to defaultprops-is-ignored-on-function-components\">​</a></h2>\n<p>This is the change most likely to break an EverShop theme, because the component system itself used to rely on it.</p>\n<p>React 19 ignores <code>Component.defaultProps</code> on function components entirely. It does not warn at build time. Your component simply receives <code>undefined</code> where it used to receive a default.</p>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Before — silently broken on React 19</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">function</span><span class=\"token plain\"> </span><span class=\"token function maybe-class-name\" style=\"color:rgb(130, 170, 255)\">ProductBadge</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token parameter punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token parameter\"> label</span><span class=\"token parameter punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token parameter\"> tone </span><span class=\"token parameter punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\">span</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\"> </span><span class=\"token tag attr-name\" style=\"color:rgb(255, 203, 107)\">className</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:rgb(199, 146, 234)\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token tag script language-javascript template-string template-punctuation string\" style=\"color:rgb(195, 232, 141)\">`</span><span class=\"token tag script language-javascript template-string string\" style=\"color:rgb(195, 232, 141)\">badge badge--</span><span class=\"token tag script language-javascript template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(199, 146, 234)\">${</span><span class=\"token tag script language-javascript template-string interpolation\" style=\"color:rgb(255, 85, 114)\">tone</span><span class=\"token tag script language-javascript template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token tag script language-javascript template-string template-punctuation string\" style=\"color:rgb(195, 232, 141)\">`</span><span class=\"token tag script language-javascript punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\">label</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;/</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\">span</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ProductBadge</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">defaultProps</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">tone</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'default'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// After</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">function</span><span class=\"token plain\"> </span><span class=\"token function maybe-class-name\" style=\"color:rgb(130, 170, 255)\">ProductBadge</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> label</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> tone </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'default'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\">span</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\"> </span><span class=\"token tag attr-name\" style=\"color:rgb(255, 203, 107)\">className</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:rgb(199, 146, 234)\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token tag script language-javascript template-string template-punctuation string\" style=\"color:rgb(195, 232, 141)\">`</span><span class=\"token tag script language-javascript template-string string\" style=\"color:rgb(195, 232, 141)\">badge badge--</span><span class=\"token tag script language-javascript template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(199, 146, 234)\">${</span><span class=\"token tag script language-javascript template-string interpolation\" style=\"color:rgb(255, 85, 114)\">tone</span><span class=\"token tag script language-javascript template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token tag script language-javascript template-string template-punctuation string\" style=\"color:rgb(195, 232, 141)\">`</span><span class=\"token tag script language-javascript punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\">label</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;/</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\">span</span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-area-case\">The <code>Area</code> case<a href=\"https://evershop.io/blog/upgrading-to-react-19#the-area-case\" class=\"hash-link\" aria-label=\"Direct link to the-area-case\" title=\"Direct link to the-area-case\">​</a></h3>\n<p>If you previously passed components into an <code>Area</code> by assigning to <code>Area.defaultProps.components</code>, that channel no longer works — and because an <code>Area</code> with no components renders nothing, the symptom is a <strong>blank page section</strong> rather than an error.</p>\n<p>Use the exported helpers instead:</p>\n<div class=\"language-js codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-js codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword module\" style=\"font-style:italic\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token imports\"> setAreaComponents</span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token imports\"> getAreaComponents </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"font-style:italic\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'@components/common/Area.js'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// The first argument is a ROUTE id, not an area id, and the second is a nested</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// areaId -&gt; componentId map:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">setAreaComponents</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'productView'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token literal-property property\">productPageTop</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token literal-property property\">mySection</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">id</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'mySection'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">sortOrder</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">10</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">component</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"font-style:italic\">default</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">MySection</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<div class=\"theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z\"></path></svg></span><code>setAreaComponents</code> replaces, it does not merge</div><div class=\"admonitionContent_BuS1\"><p>It assigns the whole map for that route, clobbering the one the build already\ngenerated. For a theme or extension that just wants to add to an area, the supported\nroute is still an <code>export const layout = { areaId, sortOrder }</code> in the route folder —\nreach for <code>setAreaComponents</code> only when you genuinely want to take over a route's map.</p></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"proptypes-is-removed\"><code>propTypes</code> is removed<a href=\"https://evershop.io/blog/upgrading-to-react-19#proptypes-is-removed\" class=\"hash-link\" aria-label=\"Direct link to proptypes-is-removed\" title=\"Direct link to proptypes-is-removed\">​</a></h2>\n<p>React 19 removed <code>propTypes</code> support. Declarations are ignored; nothing validates and nothing warns. The <code>prop-types</code> package is still installed as a dependency of <code>@evershop/evershop</code> — 37 legacy <code>.jsx</code> files in core still import it — but React no longer reads it, so it has no effect on your components either way.</p>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Before</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">MyWidget</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">propTypes</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token literal-property property\">title</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">PropTypes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">string</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">isRequired</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token literal-property property\">count</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">PropTypes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">number</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>Delete them. If you want the safety back, write the component in TypeScript and type its props — which is what core does now.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"toast-notifications-react-toastify--sonner\">Toast notifications: <code>react-toastify</code> → <code>sonner</code><a href=\"https://evershop.io/blog/upgrading-to-react-19#toast-notifications-react-toastify--sonner\" class=\"hash-link\" aria-label=\"Direct link to toast-notifications-react-toastify--sonner\" title=\"Direct link to toast-notifications-react-toastify--sonner\">​</a></h2>\n<p><code>react-toastify</code> v6 depended on <code>react-transition-group</code>, which used the removed <code>findDOMNode</code>. It has been replaced by <a href=\"https://sonner.emilkowal.ski/\" target=\"_blank\" rel=\"noopener noreferrer\"><code>sonner</code></a>.</p>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Before</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"font-style:italic\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token imports\"> toast </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"font-style:italic\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'react-toastify'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// After — prefer the core re-export so you always match the mounted Toaster</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"font-style:italic\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token imports\"> toast </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"font-style:italic\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'@components/common/ui/Sonner.js'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">toast</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token method function property-access\" style=\"color:rgb(130, 170, 255)\">success</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'Saved'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">toast</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token method function property-access\" style=\"color:rgb(130, 170, 255)\">error</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'Something went wrong'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>The <code>toast.*</code> call surface is close to drop-in. Two structural differences:</p>\n<ul>\n<li><code>&lt;ToastContainer /&gt;</code> becomes <code>&lt;Toaster /&gt;</code>.</li>\n<li>You almost certainly do not need to mount one at all. Core already renders the <code>Toaster</code> on the storefront, so importing <code>toast</code> and calling it is enough.</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"rendering-apis\">Rendering APIs<a href=\"https://evershop.io/blog/upgrading-to-react-19#rendering-apis\" class=\"hash-link\" aria-label=\"Direct link to Rendering APIs\" title=\"Direct link to Rendering APIs\">​</a></h2>\n<p><code>ReactDOM.render</code> and <code>ReactDOM.hydrate</code> are gone. This only affects you if you wrote custom entry/mount code — normal page and widget components are mounted by EverShop.</p>\n<div class=\"language-js codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-js codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Before</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ReactDOM</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token method function property-access\" style=\"color:rgb(130, 170, 255)\">hydrate</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&lt;</span><span class=\"token maybe-class-name\">App</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">/</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> container</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ReactDOM</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token method function property-access\" style=\"color:rgb(130, 170, 255)\">render</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&lt;</span><span class=\"token maybe-class-name\">App</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">/</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> container</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<div class=\"language-js codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-js codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// After</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"font-style:italic\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token imports\"> createRoot</span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token imports\"> hydrateRoot </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"font-style:italic\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'react-dom/client'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">hydrateRoot</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">container</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&lt;</span><span class=\"token maybe-class-name\">App</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">/</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\">      </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// server-rendered markup</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">createRoot</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">container</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token method function property-access\" style=\"color:rgb(130, 170, 255)\">render</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&lt;</span><span class=\"token maybe-class-name\">App</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">/</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// client-only</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>Also removed: <code>findDOMNode</code>, string refs (<code>ref=\"input\"</code>), and legacy context (<code>contextTypes</code> / <code>getChildContext</code>). Use <code>useRef</code>/callback refs and <code>createContext</code>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ssr-traps\">SSR traps<a href=\"https://evershop.io/blog/upgrading-to-react-19#ssr-traps\" class=\"hash-link\" aria-label=\"Direct link to SSR traps\" title=\"Direct link to SSR traps\">​</a></h2>\n<p>EverShop server-renders every storefront page and hydrates it on the client. React 19 is far stricter about the two renders producing identical markup — a mismatch that React 17 patched over now discards the server HTML and re-renders on the client.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"never-call-_-at-module-scope\">Never call <code>_()</code> at module scope<a href=\"https://evershop.io/blog/upgrading-to-react-19#never-call-_-at-module-scope\" class=\"hash-link\" aria-label=\"Direct link to never-call-_-at-module-scope\" title=\"Direct link to never-call-_-at-module-scope\">​</a></h3>\n<p>The translation helper resolves against the <strong>active dictionary</strong>, which is per-request on the server and per-page on the client. Calling it at module scope freezes the result at import time, so the server and client can disagree.</p>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword module\" style=\"font-style:italic\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token imports\"> _ </span><span class=\"token imports punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"font-style:italic\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'@evershop/evershop/lib/locale/translate/_'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Broken — evaluated once, at import</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">const</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">SORT_OPTIONS</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">value</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'price'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">label</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">_</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'Price'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">value</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'name'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">label</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">_</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'Name'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"font-style:italic\">export</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"font-style:italic\">default</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">function</span><span class=\"token plain\"> </span><span class=\"token function maybe-class-name\" style=\"color:rgb(130, 170, 255)\">ProductSorting</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token tag class-name\" style=\"color:rgb(255, 203, 107)\">Select</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\"> </span><span class=\"token tag attr-name\" style=\"color:rgb(255, 203, 107)\">options</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:rgb(199, 146, 234)\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token tag script language-javascript constant\" style=\"color:rgb(130, 170, 255)\">SORT_OPTIONS</span><span class=\"token tag script language-javascript punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\"> </span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">/&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Correct — evaluated per render, inside the component</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"font-style:italic\">export</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"font-style:italic\">default</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">function</span><span class=\"token plain\"> </span><span class=\"token function maybe-class-name\" style=\"color:rgb(130, 170, 255)\">ProductSorting</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">const</span><span class=\"token plain\"> sortOptions </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">value</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'price'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">label</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">_</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'Price'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">value</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'name'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token literal-property property\">label</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">_</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'Name'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token tag class-name\" style=\"color:rgb(255, 203, 107)\">Select</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\"> </span><span class=\"token tag attr-name\" style=\"color:rgb(255, 203, 107)\">options</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:rgb(199, 146, 234)\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token tag script language-javascript\" style=\"color:rgb(255, 85, 114)\">sortOptions</span><span class=\"token tag script language-javascript punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token tag\" style=\"color:rgb(255, 85, 114)\"> </span><span class=\"token tag punctuation\" style=\"color:rgb(199, 146, 234)\">/&gt;</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>This applies to any module-scope <code>const</code> — arrays, objects, and default parameter values.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"read-client-only-state-in-an-effect\">Read client-only state in an effect<a href=\"https://evershop.io/blog/upgrading-to-react-19#read-client-only-state-in-an-effect\" class=\"hash-link\" aria-label=\"Direct link to Read client-only state in an effect\" title=\"Direct link to Read client-only state in an effect\">​</a></h3>\n<p><code>window</code>, <code>localStorage</code> and <code>document</code> do not exist during the server render. Reading them in a <code>useState</code> initializer makes the first client render differ from the server's.</p>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Broken — server renders '', client renders the real URL</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">const</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token plain\">current</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> setCurrent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">useState</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token dom variable\" style=\"color:rgb(191, 199, 213)\">window</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">location</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">search</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<div class=\"language-jsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-jsx codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Correct</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">const</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token plain\">current</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> setCurrent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">useState</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">''</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">useEffect</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:rgb(137, 221, 255)\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">setCurrent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token dom variable\" style=\"color:rgb(191, 199, 213)\">window</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">location</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">search</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"dependency-notes\">Dependency notes<a href=\"https://evershop.io/blog/upgrading-to-react-19#dependency-notes\" class=\"hash-link\" aria-label=\"Direct link to Dependency notes\" title=\"Direct link to Dependency notes\">​</a></h2>\n<ul>\n<li><strong><code>@types/react</code></strong> must resolve to <strong>v19</strong>. <code>@types/react@18</code> against <code>react@^19</code> produces JSX type errors in a theme's <code>tsc</code> build.</li>\n<li><strong>CKEditor</strong> packages (<code>@ckeditor/ckeditor5-build-classic</code>, <code>@ckeditor/ckeditor5-react</code>) were removed from core. If your extension imported them through EverShop, add them to your own <code>package.json</code>.</li>\n<li><strong>Node.js 20 or newer</strong> is required. EverShop is tested on Node 20 and 22.</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"verifying-the-upgrade\">Verifying the upgrade<a href=\"https://evershop.io/blog/upgrading-to-react-19#verifying-the-upgrade\" class=\"hash-link\" aria-label=\"Direct link to Verifying the upgrade\" title=\"Direct link to Verifying the upgrade\">​</a></h2>\n<p>A clean build proves almost nothing here, so check behaviour:</p>\n<ol>\n<li><strong>Open a storefront page and watch the browser console.</strong> Hydration mismatches are logged as errors. Core installs a root error boundary plus <code>onRecoverableError</code> reporting, so a mismatch is reported rather than silently swallowed.</li>\n<li><strong>Load a page in a non-default language.</strong> Module-scope <code>_()</code> calls surface here first.</li>\n<li><strong>Look for empty areas.</strong> A section that renders nothing is the signature of a lost <code>defaultProps</code> component channel.</li>\n<li><strong>Trigger a form submission.</strong> If a toast never appears, an old <code>react-toastify</code> import is still in the tree.</li>\n</ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"see-also\">See also<a href=\"https://evershop.io/blog/upgrading-to-react-19#see-also\" class=\"hash-link\" aria-label=\"Direct link to See also\" title=\"Direct link to See also\">​</a></h2>\n<ul>\n<li><a href=\"https://evershop.io/docs/development/theme/theme-overview\">Theme Overview</a> — theme structure and the override seams</li>\n<li><a href=\"https://evershop.io/docs/development/theme/view-system\">View System</a> — how components compose into pages via Areas</li>\n<li><a href=\"https://evershop.io/docs/development/theme/templating\">Templating</a> — overriding and extending components</li>\n</ul>",
            "url": "https://evershop.io/blog/upgrading-to-react-19",
            "title": "Upgrading Your Theme And Extensions To React 19",
            "summary": "EverShop 2.2.1 moved from React 17 to React 19. Every breaking change that affects themes and extensions, and the fix for each one.",
            "date_modified": "2026-08-12T00:00:00.000Z",
            "author": {
                "name": "Evershop Team",
                "url": "https://evershop.io"
            },
            "tags": [
                "upgrade",
                "themes"
            ]
        },
        {
            "id": "https://evershop.io/blog/release-notes-v2-1-1",
            "content_html": "<p>We are excited to announce the release of <strong>Evershop v2.1.1</strong>! This release brings highly requested features like reusable UI components based on Shadcn UI, support for digital products, and a significant upgrade to Tailwind CSS v4.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"highlights\">Highlights<a href=\"https://evershop.io/blog/release-notes-v2-1-1#highlights\" class=\"hash-link\" aria-label=\"Direct link to Highlights\" title=\"Direct link to Highlights\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"-shadcn-ui--tailwind-css-v4\">🎨 Shadcn UI &amp; Tailwind CSS v4<a href=\"https://evershop.io/blog/release-notes-v2-1-1#-shadcn-ui--tailwind-css-v4\" class=\"hash-link\" aria-label=\"Direct link to 🎨 Shadcn UI &amp; Tailwind CSS v4\" title=\"Direct link to 🎨 Shadcn UI &amp; Tailwind CSS v4\">​</a></h3>\n<p>We have completely revamped our UI foundation. We are now adopting <strong>Shadcn UI</strong> for our component library, providing accessible and customizable components that you can copy and paste into your apps.</p>\n<p>Alongside this, we've updated dependencies to use <strong>Tailwind CSS v4</strong>, taking advantage of the latest performance improvements and features in the ecosystem. We also replaced <code>@heroicons/react</code> with <code>lucide-react</code> for a more modern icon implementation.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"-digital-products-support\">📦 Digital Products Support<a href=\"https://evershop.io/blog/release-notes-v2-1-1#-digital-products-support\" class=\"hash-link\" aria-label=\"Direct link to 📦 Digital Products Support\" title=\"Direct link to 📦 Digital Products Support\">​</a></h3>\n<p>Selling non-physical goods just got easier. V2.1.1 introduces native support for <strong>Digital Products</strong>. You can now manage downloadable files, license keys, and other digital assets directly within Evershop.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"-improved-developer-experience\">⚡ Improved Developer Experience<a href=\"https://evershop.io/blog/release-notes-v2-1-1#-improved-developer-experience\" class=\"hash-link\" aria-label=\"Direct link to ⚡ Improved Developer Experience\" title=\"Direct link to ⚡ Improved Developer Experience\">​</a></h3>\n<p>We've streamlined the development environment: Evershop now runs with just two Webpack instances — one for the backend and one for the frontend—instead of multiple processes. This reduces memory usage and speeds up hot module replacement (HMR), resulting in a faster, smoother development workflow.</p>\n<hr>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"upgrade-guide\">Upgrade Guide<a href=\"https://evershop.io/blog/release-notes-v2-1-1#upgrade-guide\" class=\"hash-link\" aria-label=\"Direct link to Upgrade Guide\" title=\"Direct link to Upgrade Guide\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-to-upgrade\">How to Upgrade<a href=\"https://evershop.io/blog/release-notes-v2-1-1#how-to-upgrade\" class=\"hash-link\" aria-label=\"Direct link to How to Upgrade\" title=\"Direct link to How to Upgrade\">​</a></h3>\n<p>To update your Evershop project to v2.1.1, run the standard update command:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">npm update @evershop/evershop</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"️-breaking-changes--migration\">⚠️ Breaking Changes &amp; Migration<a href=\"https://evershop.io/blog/release-notes-v2-1-1#%EF%B8%8F-breaking-changes--migration\" class=\"hash-link\" aria-label=\"Direct link to ⚠️ Breaking Changes &amp; Migration\" title=\"Direct link to ⚠️ Breaking Changes &amp; Migration\">​</a></h3>\n<p>This release includes breaking changes, primarily due to the UI architecture shift.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-component-removals\">1. Component Removals<a href=\"https://evershop.io/blog/release-notes-v2-1-1#1-component-removals\" class=\"hash-link\" aria-label=\"Direct link to 1. Component Removals\" title=\"Direct link to 1. Component Removals\">​</a></h4>\n<p>We have deprecated and removed several custom UI components in favor of standard Shadcn UI components. If your custom themes or extensions import the following, you will need to update them:</p>\n<table class=\"not-prose table-auto\"><thead><tr><th>Removed Component</th><th>Replacement</th></tr></thead><tbody><tr><td><code>components/common/Button.tsx</code></td><td>Use Shadcn <code>Button</code></td></tr><tr><td><code>components/common/modal/Modal.tsx</code></td><td>Use Shadcn <code>Dialog</code></td></tr><tr><td><code>components/admin/Badge.tsx</code></td><td>Use Shadcn <code>Badge</code></td></tr><tr><td><code>components/admin/Card.tsx</code></td><td>Use Shadcn <code>Card</code></td></tr></tbody></table>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-upgrade-tailwind-css-from-v3-to-v4\">2. Upgrade Tailwind CSS from v3 to v4<a href=\"https://evershop.io/blog/release-notes-v2-1-1#2-upgrade-tailwind-css-from-v3-to-v4\" class=\"hash-link\" aria-label=\"Direct link to 2. Upgrade Tailwind CSS from v3 to v4\" title=\"Direct link to 2. Upgrade Tailwind CSS from v3 to v4\">​</a></h4>\n<p>In previous versions, customizing the Tailwind configuration required creating a file named <code>frontstore.tailwind.js</code> in the theme folder.</p>\n<p>Starting from v2.1.1 with Tailwind CSS v4, the customization process has changed:</p>\n<ul>\n<li>To customize Tailwind, you now overwrite the <code>TailwindCss.tsx</code> component by running the following command:<!-- -->\n<div class=\"codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">npm run theme:twizz</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n</li>\n<li>This command generates a <code>tailwind.css</code> file in your theme folder, which you can edit to adjust your Tailwind 4 settings.</li>\n</ul>\n<p>For example, you can update your <code>tailwind.css</code> as follows:</p>\n<div class=\"language-css codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-css codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token atrule rule\">@import</span><span class=\"token atrule\"> </span><span class=\"token atrule string\" style=\"color:rgb(195, 232, 141)\">\"tailwindcss\"</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token atrule rule\">@plugin</span><span class=\"token atrule\"> </span><span class=\"token atrule string\" style=\"color:rgb(195, 232, 141)\">\"@tailwindcss/typography\"</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token atrule rule\">@import</span><span class=\"token atrule\"> </span><span class=\"token atrule string\" style=\"color:rgb(195, 232, 141)\">\"tw-animate-css\"</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token atrule rule\">@import</span><span class=\"token atrule\"> </span><span class=\"token atrule string\" style=\"color:rgb(195, 232, 141)\">\"./shadcn.css\"</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token atrule rule\">@custom-variant</span><span class=\"token atrule\"> dark </span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token atrule\">&amp;</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token atrule function\" style=\"color:rgb(130, 170, 255)\">is</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token atrule\">.dark *</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token atrule punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token atrule rule\">@theme</span><span class=\"token atrule\"> inline</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-background</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--background</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--font-sans</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--font-sans</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--font-mono</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--font-geist-mono</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-sidebar-ring</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-ring</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-sidebar-border</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-border</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-sidebar-accent-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-accent-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-sidebar-accent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-accent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-sidebar-primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-sidebar-primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-sidebar-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-sidebar</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-chart-5</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-5</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-chart-4</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-4</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-chart-3</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-3</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-chart-2</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-2</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-chart-1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-ring</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--ring</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-input</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--input</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-border</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--border</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-divider</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--divider</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-destructive</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--destructive</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-accent-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--accent-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-accent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--accent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-muted-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--muted-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-muted</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--muted</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-secondary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--secondary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-secondary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--secondary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-popover-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--popover-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-popover</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--popover</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-card-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--card-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--color-card</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--card</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius-sm</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">calc</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">-</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">4</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius-md</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">calc</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">-</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">2</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius-lg</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius-xl</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">calc</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">+</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">4</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius-2xl</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">calc</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">+</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">8</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius-3xl</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">calc</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">+</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">12</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius-4xl</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">calc</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">var</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">+</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">16</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token selector pseudo-class\" style=\"color:rgb(199, 146, 234)\">:root</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--radius</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.325</span><span class=\"token unit\">rem</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--background</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.145</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--card</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--card-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.145</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--popover</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--popover-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.145</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--secondary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.97</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--secondary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--muted</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.97</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--muted-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.556</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--accent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.97</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--accent-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--destructive</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.577</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.245</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">27.325</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--border</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.922</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--divider</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.922</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--input</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.922</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--ring</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.708</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.646</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.222</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">41.116</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-2</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.6</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.118</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">184.704</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-3</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.398</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.07</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">227.392</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-4</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.828</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.189</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">84.429</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-5</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.769</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.188</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">70.08</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.145</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-accent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.97</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-accent-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-border</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.922</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-ring</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.708</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token selector class\" style=\"color:rgb(199, 146, 234)\">.dark</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--background</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.145</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--card</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--card-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--popover</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--popover-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.922</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--secondary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.269</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--secondary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--muted</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.269</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--muted-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.708</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--accent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.269</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--accent-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--destructive</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.704</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.191</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">22.216</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--border</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">/</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">10</span><span class=\"token unit\">%</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--input</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">/</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">15</span><span class=\"token unit\">%</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--ring</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.556</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.488</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.243</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">264.376</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-2</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.696</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.17</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">162.48</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-3</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.769</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.188</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">70.08</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-4</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.627</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.265</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">303.9</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--chart-5</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.645</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.246</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">16.439</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.205</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-primary</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.488</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.243</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">264.376</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-primary-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-accent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.269</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-accent-foreground</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.985</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-border</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">/</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">10</span><span class=\"token unit\">%</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token variable\" style=\"color:rgb(191, 199, 213)\">--sidebar-ring</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">oklch</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.556</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-email-service-refactoring\">2. Email Service Refactoring<a href=\"https://evershop.io/blog/release-notes-v2-1-1#2-email-service-refactoring\" class=\"hash-link\" aria-label=\"Direct link to 2. Email Service Refactoring\" title=\"Direct link to 2. Email Service Refactoring\">​</a></h4>\n<p>The email service architecture has been simplified to use a single instance.</p>\n<h5 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-changed\">What Changed<a href=\"https://evershop.io/blog/release-notes-v2-1-1#what-changed\" class=\"hash-link\" aria-label=\"Direct link to What Changed\" title=\"Direct link to What Changed\">​</a></h5>\n<ul>\n<li><strong>Unified Email Service</strong>: Previously, Evershop supported multiple email service instances, which could lead to configuration complexity and maintenance overhead. In v2.1.1, the architecture has been refactored to use a single, centralized email service instance for all transactional and notification emails.</li>\n<li><strong>Simplified Configuration</strong>: Email provider configuration is now streamlined. Instead of configuring multiple services, you only need to specify your provider (e.g., Sendgrid, Resend) and credentials in one place.</li>\n</ul>\n<h5 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"migration-steps\">Migration Steps<a href=\"https://evershop.io/blog/release-notes-v2-1-1#migration-steps\" class=\"hash-link\" aria-label=\"Direct link to Migration Steps\" title=\"Direct link to Migration Steps\">​</a></h5>\n<ol>\n<li>\n<p><strong>Upgrade Extensions</strong>:<br>\n<!-- -->Update your Sendgrid or Resend extension to the latest version:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">npm update @evershop/sendgrid</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n</li>\n<li>\n<p><strong>Update Configuration</strong>:</p>\n<ul>\n<li>Update your email configuration to reflect the new unified service structure. Here’s an example configuration:</li>\n</ul>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockTitle_Ktv7\">config/config.json</div><div class=\"codeBlockContent_biex\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">   </span><span class=\"token property\">\"system\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">     </span><span class=\"token property\">\"notification_emails\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">       </span><span class=\"token property\">\"from\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"noreply@example.com\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">       </span><span class=\"token property\">\"order_confirmation\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">         </span><span class=\"token property\">\"enabled\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">true</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">         </span><span class=\"token property\">\"templatePath\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token null keyword\" style=\"font-style:italic\">null</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">       </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">       </span><span class=\"token property\">\"customer_welcome\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">         </span><span class=\"token property\">\"enabled\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">true</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">         </span><span class=\"token property\">\"templatePath\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token null keyword\" style=\"font-style:italic\">null</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">       </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">       </span><span class=\"token property\">\"reset_password\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">         </span><span class=\"token property\">\"enabled\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">true</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">         </span><span class=\"token property\">\"templatePath\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token null keyword\" style=\"font-style:italic\">null</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">       </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">     </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">   </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></span></code></pre><div class=\"buttonGroup__atx\"><button type=\"button\" aria-label=\"Copy code to clipboard\" title=\"Copy\" class=\"clean-btn\"><span class=\"copyButtonIcons_eSgA\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_y97N\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_LjdS\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p><code>templatePath</code> lets you manage an email template from source instead of using\nEverShop's default. It is a path relative to the project root; omit it or set it\nto <code>null</code> to keep the built-in template. Note the reset-password key is\n<code>reset_password</code> — not <code>customer_password_reset</code>.</p>\n</li>\n<li>\n<p><strong>Test Email Delivery</strong>:<br>\n<!-- -->After upgrading, send a test email (e.g., password reset or order confirmation) to verify that your configuration works as expected.</p>\n</li>\n</ol>",
            "url": "https://evershop.io/blog/release-notes-v2-1-1",
            "title": "Announcing Evershop v2.1.1: Digital Products, Shadcn UI, and Improved DX",
            "summary": "We are excited to announce the release of Evershop v2.1.1! This release brings highly requested features like reusable UI components based on Shadcn UI, support for digital products, and a significant upgrade to Tailwind CSS v4.",
            "date_modified": "2026-01-31T00:00:00.000Z",
            "author": {
                "name": "Evershop Team",
                "url": "https://evershop.io"
            },
            "tags": []
        }
    ]
}