Pure CSSMIT licensed

Claymorphism Shadow Recipe Reference Build

The reference build for the whole trend: one clay object, four radio steps, and the shadow assembled one layer at a time — flat fill, outer drop, inset far-side shadow, inset lit-side highlight. The code panel lights up line by line as you step, so the formula is learned rather than copied. All three layers are always present and only their colors change, so every step animates.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: a 10,000+ component Figma UI kit · from $129 one-time

Untitled UI · Affiliate link

Get Untitled UI Pro

The code

<section class="cl-01" aria-label="Claymorphism shadow recipe reference build">
  <div class="cl-01__stage">
    <header class="cl-01__head">
      <p class="cl-01__eyebrow">Recipe reference</p>
      <h2 class="cl-01__h">Clay is three shadow layers</h2>
      <p class="cl-01__lede">Step through the build. One outer drop for mass, one inset shade for thickness, one inset highlight for the sheen.</p>
    </header>
    <div class="cl-01__lab">
      <fieldset class="cl-01__steps">
        <legend class="cl-01__legend">Shadow layers</legend>
        <input class="cl-01__r" type="radio" name="cl-01-step" id="cl-01-s1">
        <label class="cl-01__step" for="cl-01-s1"><b>1</b> Flat fill</label>
        <input class="cl-01__r" type="radio" name="cl-01-step" id="cl-01-s2">
        <label class="cl-01__step" for="cl-01-s2"><b>2</b> + outer drop</label>
        <input class="cl-01__r" type="radio" name="cl-01-step" id="cl-01-s3">
        <label class="cl-01__step" for="cl-01-s3"><b>3</b> + inset shade</label>
        <input class="cl-01__r" type="radio" name="cl-01-step" id="cl-01-s4" checked>
        <label class="cl-01__step" for="cl-01-s4"><b>4</b> + inset highlight</label>
      </fieldset>
      <div class="cl-01__object">
        <div class="cl-01__clay">
          <span class="cl-01__glyph" aria-hidden="true"></span>
          <p class="cl-01__caption">clay</p>
        </div>
      </div>
      <pre class="cl-01__code"><code><span class="cl-01__ln cl-01__ln--0">.clay {
  border-radius: 44px;
  background: var(--clay);</span>
<span class="cl-01__ln cl-01__ln--1">  box-shadow:
    0 22px 40px -10px var(--shade),</span><span class="cl-01__ln cl-01__ln--2">
    inset 0 -16px 26px -10px var(--shade),</span><span class="cl-01__ln cl-01__ln--3">
    inset 0 18px 26px -8px var(--light)</span><span class="cl-01__ln cl-01__ln--0">;
}</span></code></pre>
    </div>
    <p class="cl-01__chip" aria-hidden="true">3-layer formula · :has() stepper · fixed layer count = animatable box-shadow</p>
  </div>
</section>
.cl-01,
.cl-01 *,
.cl-01 *::before,
.cl-01 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cl-01 {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: block;
  background: var(--cl-01-bg);
  --cl-01-bg: oklch(0.94 0.028 60);
  --cl-01-clay: oklch(0.83 0.11 32);
  --cl-01-shade: color-mix(in oklch,var(--cl-01-clay) 55%,oklch(0.42 0.12 30));
  --cl-01-light: oklch(0.99 0.03 85/.9);
  --cl-01-ink: oklch(0.31 0.05 40);
  --cl-01-mut: oklch(0.53 0.04 45);
  font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
  color: var(--cl-01-ink);
}

.cl-01__stage {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  align-content: center;
  gap: clamp(24px,4vw,40px);
  padding: clamp(22px,5vw,60px);
  background: radial-gradient(90% 70% at 20% 0%,oklch(0.97 0.04 70),transparent 65%);
}

.cl-01__head {
  max-width: 58ch;
  text-align: center;
  display: grid;
  gap: 8px;
}

.cl-01__eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--cl-01-mut);
}

.cl-01__h {
  font-size: clamp(24px,4vw,36px);
  font-weight: 780;
  letter-spacing: -.02em;
  text-wrap: balance;
}

.cl-01__lede {
  font-size: 15px;
  line-height: 1.6;
  color: var(--cl-01-mut);
  text-wrap: pretty;
}

.cl-01__lab {
  display: grid;
  gap: clamp(20px,3vw,34px);
  grid-template-columns: 1fr;
  justify-items: center;
  width: min(100%,940px);
}

@media (min-width: 900px) {
  .cl-01__lab {
    grid-template-columns: auto auto 1fr;
    align-items: center;
  }
}

.cl-01__steps {
  border: 0;
  display: grid;
  gap: 10px;
  min-width: 190px;
}

.cl-01__legend {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cl-01-mut);
  padding-bottom: 8px;
}

.cl-01__r {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  clip-path: inset(50%);
}

.cl-01__step {
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 46px;
  padding: 0 18px;
  border-radius: 20px;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  color: var(--cl-01-mut);
  background: color-mix(in oklch,var(--cl-01-bg) 88%,white);
  box-shadow: 0 8px 16px -8px var(--cl-01-shade),inset 0 -6px 12px -8px var(--cl-01-shade),inset 0 8px 12px -6px var(--cl-01-light);
  transition: color .3s,translate .3s cubic-bezier(.34,1.4,.5,1),box-shadow .3s;
}

.cl-01__step b {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 12px;
  background: color-mix(in oklch,var(--cl-01-clay) 40%,white);
  color: var(--cl-01-ink);
}

.cl-01__step:hover {
  translate: 2px 0;
}

.cl-01__r:checked+.cl-01__step {
  color: var(--cl-01-ink);
  background: var(--cl-01-clay);
  translate: 6px 0;
  box-shadow: 0 14px 24px -10px var(--cl-01-shade),inset 0 -8px 14px -8px var(--cl-01-shade),inset 0 10px 16px -6px var(--cl-01-light);
}

.cl-01__r:checked+.cl-01__step b {
  background: oklch(1 0 0/.75);
}

.cl-01__r:focus-visible+.cl-01__step {
  outline: 3px solid var(--cl-01-ink);
  outline-offset: 3px;
}

.cl-01__object {
  display: grid;
  place-items: center;
  padding: 14px;
}

.cl-01__clay {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 10px;
  width: clamp(180px,26vw,224px);
  aspect-ratio: 1;
  border-radius: 44px;
  background: var(--cl-01-clay);
  box-shadow: 0 22px 40px -10px var(--cl-01-c1,transparent),inset 0 -16px 26px -10px var(--cl-01-c2,transparent),inset 0 18px 26px -8px var(--cl-01-c3,transparent);
  transition: box-shadow .55s cubic-bezier(.4,0,.2,1),translate .55s cubic-bezier(.34,1.3,.5,1);
}

.cl-01__glyph {
  width: 64px;
  height: 64px;
  border-radius: 26px;
  background: color-mix(in oklch,var(--cl-01-clay) 60%,white);
  box-shadow: inset 0 -8px 14px -8px var(--cl-01-shade),inset 0 10px 14px -6px var(--cl-01-light);
}

.cl-01__caption {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 12px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: color-mix(in oklch,var(--cl-01-ink) 75%,var(--cl-01-clay));
}

.cl-01__lab:has(#cl-01-s2:checked) .cl-01__clay {
  --cl-01-c1: var(--cl-01-shade);
  translate: 0 -4px;
}

.cl-01__lab:has(#cl-01-s3:checked) .cl-01__clay {
  --cl-01-c1: var(--cl-01-shade);
  --cl-01-c2: var(--cl-01-shade);
  translate: 0 -6px;
}

.cl-01__lab:has(#cl-01-s4:checked) .cl-01__clay {
  --cl-01-c1: var(--cl-01-shade);
  --cl-01-c2: var(--cl-01-shade);
  --cl-01-c3: var(--cl-01-light);
  translate: 0 -8px;
}

.cl-01__code {
  width: min(100%,420px);
  margin: 0;
  padding: 22px 24px;
  border-radius: 28px;
  background: color-mix(in oklch,var(--cl-01-bg) 82%,white);
  box-shadow: inset 0 -10px 20px -12px var(--cl-01-shade),inset 0 12px 20px -10px var(--cl-01-light),0 16px 30px -14px var(--cl-01-shade);
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 12.5px;
  line-height: 1.85;
  overflow-x: auto;
  color: var(--cl-01-ink);
}

.cl-01__ln {
  opacity: .24;
  transition: opacity .45s;
}

.cl-01__ln--0 {
  opacity: 1;
}

.cl-01__lab:has(#cl-01-s2:checked) .cl-01__ln--1,
.cl-01__lab:has(#cl-01-s3:checked) .cl-01__ln--1,
.cl-01__lab:has(#cl-01-s4:checked) .cl-01__ln--1 {
  opacity: 1;
}

.cl-01__lab:has(#cl-01-s3:checked) .cl-01__ln--2,
.cl-01__lab:has(#cl-01-s4:checked) .cl-01__ln--2 {
  opacity: 1;
}

.cl-01__lab:has(#cl-01-s4:checked) .cl-01__ln--3 {
  opacity: 1;
}

.cl-01__chip {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 11.5px;
  color: var(--cl-01-mut);
  padding: 8px 16px;
  border-radius: 99px;
  text-align: center;
  background: oklch(1 0 0/.5);
  box-shadow: inset 0 -4px 10px -8px var(--cl-01-shade),inset 0 6px 10px -6px oklch(1 0 0);
}

@media (prefers-reduced-motion: reduce) {
  .cl-01 * {
    transition-duration: .01ms !important;
    animation: none !important;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Claymorphism from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Claymorphism Shadow Recipe Reference Build
Source: https://codefronts.com/design-styles/css-claymorphism/claymorphism-shadow-recipe-reference-build/

The reference build for the whole trend: one clay object, four radio steps, and the shadow assembled one layer at a time — flat fill, outer drop, inset far-side shadow, inset lit-side highlight. The code panel lights up line by line as you step, so the formula is learned rather than copied. All three layers are always present and only their colors change, so every step animates.
## HTML
```html
<section class="cl-01" aria-label="Claymorphism shadow recipe reference build">
  <div class="cl-01__stage">
    <header class="cl-01__head">
      <p class="cl-01__eyebrow">Recipe reference</p>
      <h2 class="cl-01__h">Clay is three shadow layers</h2>
      <p class="cl-01__lede">Step through the build. One outer drop for mass, one inset shade for thickness, one inset highlight for the sheen.</p>
    </header>
    <div class="cl-01__lab">
      <fieldset class="cl-01__steps">
        <legend class="cl-01__legend">Shadow layers</legend>
        <input class="cl-01__r" type="radio" name="cl-01-step" id="cl-01-s1">
        <label class="cl-01__step" for="cl-01-s1"><b>1</b> Flat fill</label>
        <input class="cl-01__r" type="radio" name="cl-01-step" id="cl-01-s2">
        <label class="cl-01__step" for="cl-01-s2"><b>2</b> + outer drop</label>
        <input class="cl-01__r" type="radio" name="cl-01-step" id="cl-01-s3">
        <label class="cl-01__step" for="cl-01-s3"><b>3</b> + inset shade</label>
        <input class="cl-01__r" type="radio" name="cl-01-step" id="cl-01-s4" checked>
        <label class="cl-01__step" for="cl-01-s4"><b>4</b> + inset highlight</label>
      </fieldset>
      <div class="cl-01__object">
        <div class="cl-01__clay">
          <span class="cl-01__glyph" aria-hidden="true"></span>
          <p class="cl-01__caption">clay</p>
        </div>
      </div>
      <pre class="cl-01__code"><code><span class="cl-01__ln cl-01__ln--0">.clay {
  border-radius: 44px;
  background: var(--clay);</span>
<span class="cl-01__ln cl-01__ln--1">  box-shadow:
    0 22px 40px -10px var(--shade),</span><span class="cl-01__ln cl-01__ln--2">
    inset 0 -16px 26px -10px var(--shade),</span><span class="cl-01__ln cl-01__ln--3">
    inset 0 18px 26px -8px var(--light)</span><span class="cl-01__ln cl-01__ln--0">;
}</span></code></pre>
    </div>
    <p class="cl-01__chip" aria-hidden="true">3-layer formula · :has() stepper · fixed layer count = animatable box-shadow</p>
  </div>
</section>
```
## CSS
```css
.cl-01,
.cl-01 *,
.cl-01 *::before,
.cl-01 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cl-01 {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: block;
  background: var(--cl-01-bg);
  --cl-01-bg: oklch(0.94 0.028 60);
  --cl-01-clay: oklch(0.83 0.11 32);
  --cl-01-shade: color-mix(in oklch,var(--cl-01-clay) 55%,oklch(0.42 0.12 30));
  --cl-01-light: oklch(0.99 0.03 85/.9);
  --cl-01-ink: oklch(0.31 0.05 40);
  --cl-01-mut: oklch(0.53 0.04 45);
  font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
  color: var(--cl-01-ink);
}

.cl-01__stage {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  align-content: center;
  gap: clamp(24px,4vw,40px);
  padding: clamp(22px,5vw,60px);
  background: radial-gradient(90% 70% at 20% 0%,oklch(0.97 0.04 70),transparent 65%);
}

.cl-01__head {
  max-width: 58ch;
  text-align: center;
  display: grid;
  gap: 8px;
}

.cl-01__eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--cl-01-mut);
}

.cl-01__h {
  font-size: clamp(24px,4vw,36px);
  font-weight: 780;
  letter-spacing: -.02em;
  text-wrap: balance;
}

.cl-01__lede {
  font-size: 15px;
  line-height: 1.6;
  color: var(--cl-01-mut);
  text-wrap: pretty;
}

.cl-01__lab {
  display: grid;
  gap: clamp(20px,3vw,34px);
  grid-template-columns: 1fr;
  justify-items: center;
  width: min(100%,940px);
}

@media (min-width: 900px) {
  .cl-01__lab {
    grid-template-columns: auto auto 1fr;
    align-items: center;
  }
}

.cl-01__steps {
  border: 0;
  display: grid;
  gap: 10px;
  min-width: 190px;
}

.cl-01__legend {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cl-01-mut);
  padding-bottom: 8px;
}

.cl-01__r {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  clip-path: inset(50%);
}

.cl-01__step {
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 46px;
  padding: 0 18px;
  border-radius: 20px;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  color: var(--cl-01-mut);
  background: color-mix(in oklch,var(--cl-01-bg) 88%,white);
  box-shadow: 0 8px 16px -8px var(--cl-01-shade),inset 0 -6px 12px -8px var(--cl-01-shade),inset 0 8px 12px -6px var(--cl-01-light);
  transition: color .3s,translate .3s cubic-bezier(.34,1.4,.5,1),box-shadow .3s;
}

.cl-01__step b {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 12px;
  background: color-mix(in oklch,var(--cl-01-clay) 40%,white);
  color: var(--cl-01-ink);
}

.cl-01__step:hover {
  translate: 2px 0;
}

.cl-01__r:checked+.cl-01__step {
  color: var(--cl-01-ink);
  background: var(--cl-01-clay);
  translate: 6px 0;
  box-shadow: 0 14px 24px -10px var(--cl-01-shade),inset 0 -8px 14px -8px var(--cl-01-shade),inset 0 10px 16px -6px var(--cl-01-light);
}

.cl-01__r:checked+.cl-01__step b {
  background: oklch(1 0 0/.75);
}

.cl-01__r:focus-visible+.cl-01__step {
  outline: 3px solid var(--cl-01-ink);
  outline-offset: 3px;
}

.cl-01__object {
  display: grid;
  place-items: center;
  padding: 14px;
}

.cl-01__clay {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 10px;
  width: clamp(180px,26vw,224px);
  aspect-ratio: 1;
  border-radius: 44px;
  background: var(--cl-01-clay);
  box-shadow: 0 22px 40px -10px var(--cl-01-c1,transparent),inset 0 -16px 26px -10px var(--cl-01-c2,transparent),inset 0 18px 26px -8px var(--cl-01-c3,transparent);
  transition: box-shadow .55s cubic-bezier(.4,0,.2,1),translate .55s cubic-bezier(.34,1.3,.5,1);
}

.cl-01__glyph {
  width: 64px;
  height: 64px;
  border-radius: 26px;
  background: color-mix(in oklch,var(--cl-01-clay) 60%,white);
  box-shadow: inset 0 -8px 14px -8px var(--cl-01-shade),inset 0 10px 14px -6px var(--cl-01-light);
}

.cl-01__caption {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 12px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: color-mix(in oklch,var(--cl-01-ink) 75%,var(--cl-01-clay));
}

.cl-01__lab:has(#cl-01-s2:checked) .cl-01__clay {
  --cl-01-c1: var(--cl-01-shade);
  translate: 0 -4px;
}

.cl-01__lab:has(#cl-01-s3:checked) .cl-01__clay {
  --cl-01-c1: var(--cl-01-shade);
  --cl-01-c2: var(--cl-01-shade);
  translate: 0 -6px;
}

.cl-01__lab:has(#cl-01-s4:checked) .cl-01__clay {
  --cl-01-c1: var(--cl-01-shade);
  --cl-01-c2: var(--cl-01-shade);
  --cl-01-c3: var(--cl-01-light);
  translate: 0 -8px;
}

.cl-01__code {
  width: min(100%,420px);
  margin: 0;
  padding: 22px 24px;
  border-radius: 28px;
  background: color-mix(in oklch,var(--cl-01-bg) 82%,white);
  box-shadow: inset 0 -10px 20px -12px var(--cl-01-shade),inset 0 12px 20px -10px var(--cl-01-light),0 16px 30px -14px var(--cl-01-shade);
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 12.5px;
  line-height: 1.85;
  overflow-x: auto;
  color: var(--cl-01-ink);
}

.cl-01__ln {
  opacity: .24;
  transition: opacity .45s;
}

.cl-01__ln--0 {
  opacity: 1;
}

.cl-01__lab:has(#cl-01-s2:checked) .cl-01__ln--1,
.cl-01__lab:has(#cl-01-s3:checked) .cl-01__ln--1,
.cl-01__lab:has(#cl-01-s4:checked) .cl-01__ln--1 {
  opacity: 1;
}

.cl-01__lab:has(#cl-01-s3:checked) .cl-01__ln--2,
.cl-01__lab:has(#cl-01-s4:checked) .cl-01__ln--2 {
  opacity: 1;
}

.cl-01__lab:has(#cl-01-s4:checked) .cl-01__ln--3 {
  opacity: 1;
}

.cl-01__chip {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: 11.5px;
  color: var(--cl-01-mut);
  padding: 8px 16px;
  border-radius: 99px;
  text-align: center;
  background: oklch(1 0 0/.5);
  box-shadow: inset 0 -4px 10px -8px var(--cl-01-shade),inset 0 6px 10px -6px oklch(1 0 0);
}

@media (prefers-reduced-motion: reduce) {
  .cl-01 * {
    transition-duration: .01ms !important;
    animation: none !important;
  }
}
```

How this works

Claymorphism is not a blur value, it is a three-layer contract. Every clay object in this collection is this:

--drop:  0 22px 40px -10px var(--shade);      /* 1. mass + contact  */
--shade-in: inset 0 -16px 26px -10px var(--shade); /* 2. far-side thickness */
--light-in: inset 0 18px 26px -8px  var(--light);  /* 3. lit-side sheen   */

.clay{
  border-radius:44px;                 /* puffy, never 8px */
  background:var(--clay);             /* lighter than the page */
  box-shadow:var(--drop),var(--shade-in),var(--light-in);
}

Layer 1 gives the object mass: a large, soft, slightly downward drop with a negative spread so it hugs the shape instead of haloing it. Layer 2 is the trick everyone misses — an inset shadow on the side away from the light makes the wall of the object look thick, which is what separates clay from a flat pastel rectangle. Layer 3 is the plasticine gloss: a wide, soft inset highlight on the lit side.

The stepper is pure CSS. Four radios sit in the lab, and :has() reads which one is checked:

.lab:has(#s3:checked) .clay{ --c1:var(--shade); --c2:var(--shade); --c3:transparent; }

Why swap colors instead of adding layers? box-shadow only interpolates between lists with the same number of layers. Declare all three permanently and toggle each one's color between the real value and transparent, and the browser animates the build-up smoothly — the same technique demo 20 uses to get 60 fps depth changes.

Make it yours

  • Re-hue the whole object in one line: change --cl-01-clay and both shadow colors follow, because they are color-mix() derivations of it rather than hand-picked hex values.
  • Softer / harder clay: scale the blur radii together (40px / 26px / 26px → 28px / 18px / 18px) for a firmer, more matte material; raise them for marshmallow.
  • Deeper object: increase the inset shadow's negative offset (-16px → -26px) and the object reads as a thicker slab.
  • Bake it into a token file: expose the three layers as --clay-drop, --clay-inner-shade, --clay-inner-light and every component in your app can compose them in one box-shadow declaration.

Gotchas — read before shipping

  • Layer count must match to animate: box-shadow with 1 layer → 3 layers snaps. Keep the list length fixed and animate the colors (or use @property registered lengths).
  • Don't fill the object darker than the page — clay is lifted material. A fill darker than the background reads as a hole, which is inset neumorphism, not claymorphism (see demo 04).
  • One light direction only. If the inset highlight is on top, the drop shadow must fall down and the inset shade must sit at the bottom. Mixed directions are the tell of hand-tuned, uncoordinated shadows.
  • Big soft shadows are expensive to repaint. Never animate the blur or offset on hover — animate transform and the shadow colors (demo 20 measures the difference).
  • Contrast still applies: pastel-on-pastel text fails WCAG 1.4.3 fast. Keep body copy at 4.5:1 against the clay fill, not against the page.

Browser support

ChromeSafariFirefoxEdge
114+17.5+121+114+

Floor set by :has(), oklch(), color-mix(), text-wrap as this demo is written. The core technique itself goes back further — Chrome 105+.

:has() is the only modern requirement (Chrome 105 / Safari 15.4 / Firefox 121); layered inset box-shadow itself works in every engine since IE9. Replace oklch()/color-mix() with hex and the recipe runs anywhere.

Techniques used in this demo

Search CodeFronts

Loading…