19 / 20
All 20 in 20 CSS Claymorphism
- 01Claymorphism Shadow Recipe Reference Build
- 02Inner Highlight and Inner Shadow Layering
- 03Border Radius Scale for Puffy Shapes
- 04Claymorphism vs Neumorphism Side by Side
- 05Claymorphism with Glassmorphism Hybrid
- 06Light Source Consistency Across a Clay Layout
- 07Clay Depth Tiers for Visual Hierarchy
- 08Tailwind CSS Claymorphism Implementation
- 09Clay Button Press and Squish States
- 10Clay Toggle Switch and Checkbox Set
- 11Clay Input Field and Search Bar
- 12Clay Badge & Pill Tag System
- 13Claymorphism Card Component
- 14Clay Modal Dialog with Floating Depth
- 15Clay Pricing Table with Raised Popular Tier
- 16Clay Bottom Tab Bar for Mobile
- 17Clay Icon Tiles and App Grid
- 18Clay Toast & Floating Alert Bubbles
- 19Clay Dark Mode Shadow Recalibration
- 20Clay Animation Performance & Transform Optimization
Clay Dark Mode Shadow Recalibration
Dark mode is where naive clay dies: black shadows on a dark page are invisible, so the object flattens. This demo recalibrates all three layers for dark — a near-black drop with higher alpha, a much weaker inset shade, and a top rim highlight that becomes the primary depth cue — and ships both themes from one token block using light-dark(), with a clay switch to compare instantly.
Untitled UI Pro: a 10,000+ component Figma UI kit · from $129 one-time
Untitled UI · Affiliate link
The code
<section class="cl-19" aria-label="Clay dark mode shadow recalibration demo">
<div class="cl-19__stage">
<header class="cl-19__head">
<h2 class="cl-19__h">Same object, recalibrated</h2>
<p class="cl-19__lede">Flip the theme. The drop shadow gets darker and longer, the inset shade halves, and a 1px rim highlight takes over as the edge.</p>
<div class="cl-19__toggleWrap">
<input class="cl-19__chk" type="checkbox" id="cl-19-dark">
<label class="cl-19__toggle" for="cl-19-dark">
<span class="cl-19__tTrack" aria-hidden="true"><span class="cl-19__tKnob"></span></span>
Dark mode
</label>
</div>
</header>
<div class="cl-19__pane">
<article class="cl-19__card">
<span class="cl-19__puck" aria-hidden="true"></span>
<p class="cl-19__kicker">Tier 3 · floating</p>
<h3 class="cl-19__title">Recalibrated clay</h3>
<p class="cl-19__body">Fill sits 8% lighter than the page in both themes, so the object stays lifted rather than dissolving into the background.</p>
<ul class="cl-19__tokens">
<li><b>drop</b><span class="cl-19__v cl-19__v--drop"></span></li>
<li><b>inset shade</b><span class="cl-19__v cl-19__v--shade"></span></li>
<li><b>rim + sheen</b><span class="cl-19__v cl-19__v--light"></span></li>
</ul>
<div class="cl-19__btns">
<button class="cl-19__btn cl-19__btn--go" type="button">Apply theme</button>
<button class="cl-19__btn" type="button">Copy tokens</button>
</div>
</article>
<aside class="cl-19__rules">
<h4 class="cl-19__rulesH">Dark-mode rules</h4>
<ol class="cl-19__list">
<li><b>Lift the fill</b> — +6 to 10% lightness over the page.</li>
<li><b>Add a 1px rim</b> — <code>inset 0 1px 0 oklch(1 0 0/.16)</code>.</li>
<li><b>Halve the inset shade</b> — dark on dark is mud.</li>
<li><b>Longer, darker drop</b> — near-black at 70%+ alpha.</li>
</ol>
</aside>
</div>
<p class="cl-19__chip" aria-hidden="true">light-dark() tokens · color-scheme override · highlight-led depth in dark</p>
</div>
</section><section class="cl-19" aria-label="Clay dark mode shadow recalibration demo">
<div class="cl-19__stage">
<header class="cl-19__head">
<h2 class="cl-19__h">Same object, recalibrated</h2>
<p class="cl-19__lede">Flip the theme. The drop shadow gets darker and longer, the inset shade halves, and a 1px rim highlight takes over as the edge.</p>
<div class="cl-19__toggleWrap">
<input class="cl-19__chk" type="checkbox" id="cl-19-dark">
<label class="cl-19__toggle" for="cl-19-dark">
<span class="cl-19__tTrack" aria-hidden="true"><span class="cl-19__tKnob"></span></span>
Dark mode
</label>
</div>
</header>
<div class="cl-19__pane">
<article class="cl-19__card">
<span class="cl-19__puck" aria-hidden="true"></span>
<p class="cl-19__kicker">Tier 3 · floating</p>
<h3 class="cl-19__title">Recalibrated clay</h3>
<p class="cl-19__body">Fill sits 8% lighter than the page in both themes, so the object stays lifted rather than dissolving into the background.</p>
<ul class="cl-19__tokens">
<li><b>drop</b><span class="cl-19__v cl-19__v--drop"></span></li>
<li><b>inset shade</b><span class="cl-19__v cl-19__v--shade"></span></li>
<li><b>rim + sheen</b><span class="cl-19__v cl-19__v--light"></span></li>
</ul>
<div class="cl-19__btns">
<button class="cl-19__btn cl-19__btn--go" type="button">Apply theme</button>
<button class="cl-19__btn" type="button">Copy tokens</button>
</div>
</article>
<aside class="cl-19__rules">
<h4 class="cl-19__rulesH">Dark-mode rules</h4>
<ol class="cl-19__list">
<li><b>Lift the fill</b> — +6 to 10% lightness over the page.</li>
<li><b>Add a 1px rim</b> — <code>inset 0 1px 0 oklch(1 0 0/.16)</code>.</li>
<li><b>Halve the inset shade</b> — dark on dark is mud.</li>
<li><b>Longer, darker drop</b> — near-black at 70%+ alpha.</li>
</ol>
</aside>
</div>
<p class="cl-19__chip" aria-hidden="true">light-dark() tokens · color-scheme override · highlight-led depth in dark</p>
</div>
</section>.cl-19,
.cl-19 *,
.cl-19 *::before,
.cl-19 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-19 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
color-scheme: light;
background: var(--cl-19-bg);
--cl-19-bg: light-dark(oklch(0.94 0.025 285),oklch(0.19 0.02 285));
--cl-19-clay: light-dark(oklch(0.9 0.05 285),oklch(0.3 0.03 285));
--cl-19-clay2: light-dark(oklch(0.94 0.03 285),oklch(0.26 0.025 285));
--cl-19-accent: light-dark(oklch(0.79 0.13 290),oklch(0.62 0.16 290));
--cl-19-drop: light-dark(oklch(0.55 0.09 285/.5),oklch(0 0 0/.72));
--cl-19-inShade: light-dark(oklch(0.55 0.09 285/.55),oklch(0 0 0/.5));
--cl-19-inLight: light-dark(oklch(1 0 0/.9),oklch(1 0 0/.1));
--cl-19-rim: light-dark(oklch(1 0 0/0),oklch(1 0 0/.16));
--cl-19-ink: light-dark(oklch(0.27 0.05 285),oklch(0.96 0.01 285));
--cl-19-mut: light-dark(oklch(0.5 0.04 285),oklch(0.74 0.02 285));
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-19-ink);
transition: background .45s;
}
.cl-19:has(#cl-19-dark:checked) {
color-scheme: dark;
}
.cl-19__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: clamp(20px,3.5vw,32px);
padding: clamp(20px,5vw,56px);
}
.cl-19__head {
display: grid;
gap: 14px;
justify-items: center;
text-align: center;
max-width: 60ch;
}
.cl-19__h {
font-size: clamp(23px,3.8vw,34px);
font-weight: 780;
letter-spacing: -.022em;
text-wrap: balance;
}
.cl-19__lede {
font-size: 15px;
line-height: 1.6;
color: var(--cl-19-mut);
text-wrap: pretty;
}
.cl-19__chk {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
clip-path: inset(50%);
}
.cl-19__toggle {
display: inline-flex;
align-items: center;
gap: 12px;
min-height: 50px;
padding: 0 22px 0 12px;
border-radius: 99px;
font-size: 14px;
font-weight: 640;
cursor: pointer;
background: var(--cl-19-clay2);
box-shadow: 0 14px 24px -14px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -8px 14px -10px var(--cl-19-inShade),inset 0 10px 14px -8px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__tTrack {
position: relative;
width: 50px;
height: 28px;
border-radius: 99px;
background: color-mix(in oklch,var(--cl-19-bg) 82%,var(--cl-19-mut));
box-shadow: inset 0 8px 13px -6px var(--cl-19-inShade),inset 0 -5px 10px -8px var(--cl-19-inLight);
}
.cl-19__tKnob {
position: absolute;
top: 3px;
left: 3px;
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--cl-19-clay);
box-shadow: 0 6px 11px -5px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 7px 9px -5px var(--cl-19-inLight);
transition: translate .34s cubic-bezier(.34,1.5,.5,1),background .45s;
}
.cl-19__chk:checked+.cl-19__toggle .cl-19__tKnob {
translate: 22px 0;
background: var(--cl-19-accent);
}
.cl-19__chk:focus-visible+.cl-19__toggle {
outline: 3px solid var(--cl-19-ink);
outline-offset: 3px;
}
.cl-19__pane {
display: grid;
grid-template-columns: 1fr;
gap: clamp(16px,2.6vw,24px);
width: min(100%,880px);
align-items: center;
}
@media (min-width: 820px) {
.cl-19__pane {
grid-template-columns: 1.15fr .85fr;
}
}
.cl-19__card {
display: grid;
gap: 11px;
padding: clamp(24px,3.2vw,34px);
border-radius: 40px;
background: var(--cl-19-clay);
box-shadow: 0 30px 56px -18px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -16px 26px -12px var(--cl-19-inShade),inset 0 18px 30px -10px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s,translate .4s cubic-bezier(.34,1.3,.5,1);
}
.cl-19__card:hover {
translate: 0 -6px;
}
.cl-19__puck {
width: 56px;
height: 56px;
border-radius: 22px;
background: var(--cl-19-accent);
box-shadow: 0 14px 24px -10px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -10px 16px -9px var(--cl-19-inShade),inset 0 12px 16px -7px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__kicker {
margin-top: 4px;
font-size: 11px;
font-weight: 700;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--cl-19-mut);
}
.cl-19__title {
font-size: clamp(20px,2.8vw,25px);
font-weight: 770;
letter-spacing: -.02em;
}
.cl-19__body {
font-size: 14px;
line-height: 1.6;
color: var(--cl-19-mut);
text-wrap: pretty;
}
.cl-19__tokens {
list-style: none;
display: grid;
gap: 8px;
margin: 6px 0 2px;
padding: 16px 18px;
border-radius: 24px;
background: var(--cl-19-clay2);
box-shadow: inset 0 9px 16px -8px var(--cl-19-inShade),inset 0 -6px 12px -10px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__tokens li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 12px;
color: var(--cl-19-mut);
}
.cl-19__v {
width: 74px;
height: 16px;
border-radius: 99px;
}
.cl-19__v--drop {
background: var(--cl-19-drop);
}
.cl-19__v--shade {
background: var(--cl-19-inShade);
}
.cl-19__v--light {
background: var(--cl-19-inLight);
box-shadow: inset 0 0 0 1px var(--cl-19-mut);
}
.cl-19__btns {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 6px;
}
.cl-19__btn {
min-height: 50px;
padding: 0 22px;
border: 0;
border-radius: 22px;
font: inherit;
font-size: 14px;
font-weight: 660;
color: var(--cl-19-ink);
cursor: pointer;
background: var(--cl-19-clay2);
box-shadow: 0 12px 20px -12px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -9px 15px -9px var(--cl-19-inShade),inset 0 11px 15px -7px var(--cl-19-inLight);
transition: translate .18s,scale .18s cubic-bezier(.2,.8,.3,1.4),background .45s,box-shadow .3s;
}
.cl-19__btn--go {
color: light-dark(oklch(0.24 0.06 290),oklch(0.98 0.01 290));
background: var(--cl-19-accent);
}
.cl-19__btn:hover {
translate: 0 -3px;
}
.cl-19__btn:active {
scale: 1 .94;
translate: 0 3px;
box-shadow: inset 0 12px 18px -8px var(--cl-19-inShade);
}
.cl-19__btn:focus-visible {
outline: 3px solid var(--cl-19-ink);
outline-offset: 3px;
}
.cl-19__rules {
display: grid;
gap: 10px;
padding: clamp(22px,3vw,30px);
border-radius: 36px;
background: var(--cl-19-clay2);
box-shadow: 0 22px 42px -20px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -14px 24px -14px var(--cl-19-inShade),inset 0 16px 26px -12px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__rulesH {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--cl-19-mut);
}
.cl-19__list {
display: grid;
gap: 10px;
padding-left: 20px;
font-size: 13.5px;
line-height: 1.5;
}
.cl-19__list li {
color: var(--cl-19-mut);
}
.cl-19__list b {
color: var(--cl-19-ink);
}
.cl-19__list code {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
}
.cl-19__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-19-mut);
padding: 9px 16px;
border-radius: 99px;
text-align: center;
background: var(--cl-19-clay2);
box-shadow: inset 0 1px 0 0 var(--cl-19-rim),inset 0 -4px 10px -8px var(--cl-19-inShade),inset 0 6px 10px -6px var(--cl-19-inLight);
transition: background .45s;
}
@media (prefers-reduced-motion: reduce) {
.cl-19 * {
transition-duration: .01ms !important;
}
}.cl-19,
.cl-19 *,
.cl-19 *::before,
.cl-19 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-19 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
color-scheme: light;
background: var(--cl-19-bg);
--cl-19-bg: light-dark(oklch(0.94 0.025 285),oklch(0.19 0.02 285));
--cl-19-clay: light-dark(oklch(0.9 0.05 285),oklch(0.3 0.03 285));
--cl-19-clay2: light-dark(oklch(0.94 0.03 285),oklch(0.26 0.025 285));
--cl-19-accent: light-dark(oklch(0.79 0.13 290),oklch(0.62 0.16 290));
--cl-19-drop: light-dark(oklch(0.55 0.09 285/.5),oklch(0 0 0/.72));
--cl-19-inShade: light-dark(oklch(0.55 0.09 285/.55),oklch(0 0 0/.5));
--cl-19-inLight: light-dark(oklch(1 0 0/.9),oklch(1 0 0/.1));
--cl-19-rim: light-dark(oklch(1 0 0/0),oklch(1 0 0/.16));
--cl-19-ink: light-dark(oklch(0.27 0.05 285),oklch(0.96 0.01 285));
--cl-19-mut: light-dark(oklch(0.5 0.04 285),oklch(0.74 0.02 285));
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-19-ink);
transition: background .45s;
}
.cl-19:has(#cl-19-dark:checked) {
color-scheme: dark;
}
.cl-19__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: clamp(20px,3.5vw,32px);
padding: clamp(20px,5vw,56px);
}
.cl-19__head {
display: grid;
gap: 14px;
justify-items: center;
text-align: center;
max-width: 60ch;
}
.cl-19__h {
font-size: clamp(23px,3.8vw,34px);
font-weight: 780;
letter-spacing: -.022em;
text-wrap: balance;
}
.cl-19__lede {
font-size: 15px;
line-height: 1.6;
color: var(--cl-19-mut);
text-wrap: pretty;
}
.cl-19__chk {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
clip-path: inset(50%);
}
.cl-19__toggle {
display: inline-flex;
align-items: center;
gap: 12px;
min-height: 50px;
padding: 0 22px 0 12px;
border-radius: 99px;
font-size: 14px;
font-weight: 640;
cursor: pointer;
background: var(--cl-19-clay2);
box-shadow: 0 14px 24px -14px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -8px 14px -10px var(--cl-19-inShade),inset 0 10px 14px -8px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__tTrack {
position: relative;
width: 50px;
height: 28px;
border-radius: 99px;
background: color-mix(in oklch,var(--cl-19-bg) 82%,var(--cl-19-mut));
box-shadow: inset 0 8px 13px -6px var(--cl-19-inShade),inset 0 -5px 10px -8px var(--cl-19-inLight);
}
.cl-19__tKnob {
position: absolute;
top: 3px;
left: 3px;
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--cl-19-clay);
box-shadow: 0 6px 11px -5px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 7px 9px -5px var(--cl-19-inLight);
transition: translate .34s cubic-bezier(.34,1.5,.5,1),background .45s;
}
.cl-19__chk:checked+.cl-19__toggle .cl-19__tKnob {
translate: 22px 0;
background: var(--cl-19-accent);
}
.cl-19__chk:focus-visible+.cl-19__toggle {
outline: 3px solid var(--cl-19-ink);
outline-offset: 3px;
}
.cl-19__pane {
display: grid;
grid-template-columns: 1fr;
gap: clamp(16px,2.6vw,24px);
width: min(100%,880px);
align-items: center;
}
@media (min-width: 820px) {
.cl-19__pane {
grid-template-columns: 1.15fr .85fr;
}
}
.cl-19__card {
display: grid;
gap: 11px;
padding: clamp(24px,3.2vw,34px);
border-radius: 40px;
background: var(--cl-19-clay);
box-shadow: 0 30px 56px -18px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -16px 26px -12px var(--cl-19-inShade),inset 0 18px 30px -10px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s,translate .4s cubic-bezier(.34,1.3,.5,1);
}
.cl-19__card:hover {
translate: 0 -6px;
}
.cl-19__puck {
width: 56px;
height: 56px;
border-radius: 22px;
background: var(--cl-19-accent);
box-shadow: 0 14px 24px -10px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -10px 16px -9px var(--cl-19-inShade),inset 0 12px 16px -7px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__kicker {
margin-top: 4px;
font-size: 11px;
font-weight: 700;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--cl-19-mut);
}
.cl-19__title {
font-size: clamp(20px,2.8vw,25px);
font-weight: 770;
letter-spacing: -.02em;
}
.cl-19__body {
font-size: 14px;
line-height: 1.6;
color: var(--cl-19-mut);
text-wrap: pretty;
}
.cl-19__tokens {
list-style: none;
display: grid;
gap: 8px;
margin: 6px 0 2px;
padding: 16px 18px;
border-radius: 24px;
background: var(--cl-19-clay2);
box-shadow: inset 0 9px 16px -8px var(--cl-19-inShade),inset 0 -6px 12px -10px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__tokens li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 12px;
color: var(--cl-19-mut);
}
.cl-19__v {
width: 74px;
height: 16px;
border-radius: 99px;
}
.cl-19__v--drop {
background: var(--cl-19-drop);
}
.cl-19__v--shade {
background: var(--cl-19-inShade);
}
.cl-19__v--light {
background: var(--cl-19-inLight);
box-shadow: inset 0 0 0 1px var(--cl-19-mut);
}
.cl-19__btns {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 6px;
}
.cl-19__btn {
min-height: 50px;
padding: 0 22px;
border: 0;
border-radius: 22px;
font: inherit;
font-size: 14px;
font-weight: 660;
color: var(--cl-19-ink);
cursor: pointer;
background: var(--cl-19-clay2);
box-shadow: 0 12px 20px -12px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -9px 15px -9px var(--cl-19-inShade),inset 0 11px 15px -7px var(--cl-19-inLight);
transition: translate .18s,scale .18s cubic-bezier(.2,.8,.3,1.4),background .45s,box-shadow .3s;
}
.cl-19__btn--go {
color: light-dark(oklch(0.24 0.06 290),oklch(0.98 0.01 290));
background: var(--cl-19-accent);
}
.cl-19__btn:hover {
translate: 0 -3px;
}
.cl-19__btn:active {
scale: 1 .94;
translate: 0 3px;
box-shadow: inset 0 12px 18px -8px var(--cl-19-inShade);
}
.cl-19__btn:focus-visible {
outline: 3px solid var(--cl-19-ink);
outline-offset: 3px;
}
.cl-19__rules {
display: grid;
gap: 10px;
padding: clamp(22px,3vw,30px);
border-radius: 36px;
background: var(--cl-19-clay2);
box-shadow: 0 22px 42px -20px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -14px 24px -14px var(--cl-19-inShade),inset 0 16px 26px -12px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__rulesH {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--cl-19-mut);
}
.cl-19__list {
display: grid;
gap: 10px;
padding-left: 20px;
font-size: 13.5px;
line-height: 1.5;
}
.cl-19__list li {
color: var(--cl-19-mut);
}
.cl-19__list b {
color: var(--cl-19-ink);
}
.cl-19__list code {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
}
.cl-19__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-19-mut);
padding: 9px 16px;
border-radius: 99px;
text-align: center;
background: var(--cl-19-clay2);
box-shadow: inset 0 1px 0 0 var(--cl-19-rim),inset 0 -4px 10px -8px var(--cl-19-inShade),inset 0 6px 10px -6px var(--cl-19-inLight);
transition: background .45s;
}
@media (prefers-reduced-motion: reduce) {
.cl-19 * {
transition-duration: .01ms !important;
}
}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: Clay Dark Mode Shadow Recalibration
Source: https://codefronts.com/design-styles/css-claymorphism/clay-dark-mode-shadow-recalibration/
Dark mode is where naive clay dies: black shadows on a dark page are invisible, so the object flattens. This demo recalibrates all three layers for dark — a near-black drop with higher alpha, a much weaker inset shade, and a top rim highlight that becomes the primary depth cue — and ships both themes from one token block using light-dark(), with a clay switch to compare instantly.
## HTML
```html
<section class="cl-19" aria-label="Clay dark mode shadow recalibration demo">
<div class="cl-19__stage">
<header class="cl-19__head">
<h2 class="cl-19__h">Same object, recalibrated</h2>
<p class="cl-19__lede">Flip the theme. The drop shadow gets darker and longer, the inset shade halves, and a 1px rim highlight takes over as the edge.</p>
<div class="cl-19__toggleWrap">
<input class="cl-19__chk" type="checkbox" id="cl-19-dark">
<label class="cl-19__toggle" for="cl-19-dark">
<span class="cl-19__tTrack" aria-hidden="true"><span class="cl-19__tKnob"></span></span>
Dark mode
</label>
</div>
</header>
<div class="cl-19__pane">
<article class="cl-19__card">
<span class="cl-19__puck" aria-hidden="true"></span>
<p class="cl-19__kicker">Tier 3 · floating</p>
<h3 class="cl-19__title">Recalibrated clay</h3>
<p class="cl-19__body">Fill sits 8% lighter than the page in both themes, so the object stays lifted rather than dissolving into the background.</p>
<ul class="cl-19__tokens">
<li><b>drop</b><span class="cl-19__v cl-19__v--drop"></span></li>
<li><b>inset shade</b><span class="cl-19__v cl-19__v--shade"></span></li>
<li><b>rim + sheen</b><span class="cl-19__v cl-19__v--light"></span></li>
</ul>
<div class="cl-19__btns">
<button class="cl-19__btn cl-19__btn--go" type="button">Apply theme</button>
<button class="cl-19__btn" type="button">Copy tokens</button>
</div>
</article>
<aside class="cl-19__rules">
<h4 class="cl-19__rulesH">Dark-mode rules</h4>
<ol class="cl-19__list">
<li><b>Lift the fill</b> — +6 to 10% lightness over the page.</li>
<li><b>Add a 1px rim</b> — <code>inset 0 1px 0 oklch(1 0 0/.16)</code>.</li>
<li><b>Halve the inset shade</b> — dark on dark is mud.</li>
<li><b>Longer, darker drop</b> — near-black at 70%+ alpha.</li>
</ol>
</aside>
</div>
<p class="cl-19__chip" aria-hidden="true">light-dark() tokens · color-scheme override · highlight-led depth in dark</p>
</div>
</section>
```
## CSS
```css
.cl-19,
.cl-19 *,
.cl-19 *::before,
.cl-19 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-19 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
color-scheme: light;
background: var(--cl-19-bg);
--cl-19-bg: light-dark(oklch(0.94 0.025 285),oklch(0.19 0.02 285));
--cl-19-clay: light-dark(oklch(0.9 0.05 285),oklch(0.3 0.03 285));
--cl-19-clay2: light-dark(oklch(0.94 0.03 285),oklch(0.26 0.025 285));
--cl-19-accent: light-dark(oklch(0.79 0.13 290),oklch(0.62 0.16 290));
--cl-19-drop: light-dark(oklch(0.55 0.09 285/.5),oklch(0 0 0/.72));
--cl-19-inShade: light-dark(oklch(0.55 0.09 285/.55),oklch(0 0 0/.5));
--cl-19-inLight: light-dark(oklch(1 0 0/.9),oklch(1 0 0/.1));
--cl-19-rim: light-dark(oklch(1 0 0/0),oklch(1 0 0/.16));
--cl-19-ink: light-dark(oklch(0.27 0.05 285),oklch(0.96 0.01 285));
--cl-19-mut: light-dark(oklch(0.5 0.04 285),oklch(0.74 0.02 285));
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-19-ink);
transition: background .45s;
}
.cl-19:has(#cl-19-dark:checked) {
color-scheme: dark;
}
.cl-19__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: clamp(20px,3.5vw,32px);
padding: clamp(20px,5vw,56px);
}
.cl-19__head {
display: grid;
gap: 14px;
justify-items: center;
text-align: center;
max-width: 60ch;
}
.cl-19__h {
font-size: clamp(23px,3.8vw,34px);
font-weight: 780;
letter-spacing: -.022em;
text-wrap: balance;
}
.cl-19__lede {
font-size: 15px;
line-height: 1.6;
color: var(--cl-19-mut);
text-wrap: pretty;
}
.cl-19__chk {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
clip-path: inset(50%);
}
.cl-19__toggle {
display: inline-flex;
align-items: center;
gap: 12px;
min-height: 50px;
padding: 0 22px 0 12px;
border-radius: 99px;
font-size: 14px;
font-weight: 640;
cursor: pointer;
background: var(--cl-19-clay2);
box-shadow: 0 14px 24px -14px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -8px 14px -10px var(--cl-19-inShade),inset 0 10px 14px -8px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__tTrack {
position: relative;
width: 50px;
height: 28px;
border-radius: 99px;
background: color-mix(in oklch,var(--cl-19-bg) 82%,var(--cl-19-mut));
box-shadow: inset 0 8px 13px -6px var(--cl-19-inShade),inset 0 -5px 10px -8px var(--cl-19-inLight);
}
.cl-19__tKnob {
position: absolute;
top: 3px;
left: 3px;
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--cl-19-clay);
box-shadow: 0 6px 11px -5px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 7px 9px -5px var(--cl-19-inLight);
transition: translate .34s cubic-bezier(.34,1.5,.5,1),background .45s;
}
.cl-19__chk:checked+.cl-19__toggle .cl-19__tKnob {
translate: 22px 0;
background: var(--cl-19-accent);
}
.cl-19__chk:focus-visible+.cl-19__toggle {
outline: 3px solid var(--cl-19-ink);
outline-offset: 3px;
}
.cl-19__pane {
display: grid;
grid-template-columns: 1fr;
gap: clamp(16px,2.6vw,24px);
width: min(100%,880px);
align-items: center;
}
@media (min-width: 820px) {
.cl-19__pane {
grid-template-columns: 1.15fr .85fr;
}
}
.cl-19__card {
display: grid;
gap: 11px;
padding: clamp(24px,3.2vw,34px);
border-radius: 40px;
background: var(--cl-19-clay);
box-shadow: 0 30px 56px -18px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -16px 26px -12px var(--cl-19-inShade),inset 0 18px 30px -10px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s,translate .4s cubic-bezier(.34,1.3,.5,1);
}
.cl-19__card:hover {
translate: 0 -6px;
}
.cl-19__puck {
width: 56px;
height: 56px;
border-radius: 22px;
background: var(--cl-19-accent);
box-shadow: 0 14px 24px -10px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -10px 16px -9px var(--cl-19-inShade),inset 0 12px 16px -7px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__kicker {
margin-top: 4px;
font-size: 11px;
font-weight: 700;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--cl-19-mut);
}
.cl-19__title {
font-size: clamp(20px,2.8vw,25px);
font-weight: 770;
letter-spacing: -.02em;
}
.cl-19__body {
font-size: 14px;
line-height: 1.6;
color: var(--cl-19-mut);
text-wrap: pretty;
}
.cl-19__tokens {
list-style: none;
display: grid;
gap: 8px;
margin: 6px 0 2px;
padding: 16px 18px;
border-radius: 24px;
background: var(--cl-19-clay2);
box-shadow: inset 0 9px 16px -8px var(--cl-19-inShade),inset 0 -6px 12px -10px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__tokens li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 12px;
color: var(--cl-19-mut);
}
.cl-19__v {
width: 74px;
height: 16px;
border-radius: 99px;
}
.cl-19__v--drop {
background: var(--cl-19-drop);
}
.cl-19__v--shade {
background: var(--cl-19-inShade);
}
.cl-19__v--light {
background: var(--cl-19-inLight);
box-shadow: inset 0 0 0 1px var(--cl-19-mut);
}
.cl-19__btns {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 6px;
}
.cl-19__btn {
min-height: 50px;
padding: 0 22px;
border: 0;
border-radius: 22px;
font: inherit;
font-size: 14px;
font-weight: 660;
color: var(--cl-19-ink);
cursor: pointer;
background: var(--cl-19-clay2);
box-shadow: 0 12px 20px -12px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -9px 15px -9px var(--cl-19-inShade),inset 0 11px 15px -7px var(--cl-19-inLight);
transition: translate .18s,scale .18s cubic-bezier(.2,.8,.3,1.4),background .45s,box-shadow .3s;
}
.cl-19__btn--go {
color: light-dark(oklch(0.24 0.06 290),oklch(0.98 0.01 290));
background: var(--cl-19-accent);
}
.cl-19__btn:hover {
translate: 0 -3px;
}
.cl-19__btn:active {
scale: 1 .94;
translate: 0 3px;
box-shadow: inset 0 12px 18px -8px var(--cl-19-inShade);
}
.cl-19__btn:focus-visible {
outline: 3px solid var(--cl-19-ink);
outline-offset: 3px;
}
.cl-19__rules {
display: grid;
gap: 10px;
padding: clamp(22px,3vw,30px);
border-radius: 36px;
background: var(--cl-19-clay2);
box-shadow: 0 22px 42px -20px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -14px 24px -14px var(--cl-19-inShade),inset 0 16px 26px -12px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__rulesH {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--cl-19-mut);
}
.cl-19__list {
display: grid;
gap: 10px;
padding-left: 20px;
font-size: 13.5px;
line-height: 1.5;
}
.cl-19__list li {
color: var(--cl-19-mut);
}
.cl-19__list b {
color: var(--cl-19-ink);
}
.cl-19__list code {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
}
.cl-19__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-19-mut);
padding: 9px 16px;
border-radius: 99px;
text-align: center;
background: var(--cl-19-clay2);
box-shadow: inset 0 1px 0 0 var(--cl-19-rim),inset 0 -4px 10px -8px var(--cl-19-inShade),inset 0 6px 10px -6px var(--cl-19-inLight);
transition: background .45s;
}
@media (prefers-reduced-motion: reduce) {
.cl-19 * {
transition-duration: .01ms !important;
}
}
```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: Clay Dark Mode Shadow Recalibration
Source: https://codefronts.com/design-styles/css-claymorphism/clay-dark-mode-shadow-recalibration/
Dark mode is where naive clay dies: black shadows on a dark page are invisible, so the object flattens. This demo recalibrates all three layers for dark — a near-black drop with higher alpha, a much weaker inset shade, and a top rim highlight that becomes the primary depth cue — and ships both themes from one token block using light-dark(), with a clay switch to compare instantly.
## HTML
```html
<section class="cl-19" aria-label="Clay dark mode shadow recalibration demo">
<div class="cl-19__stage">
<header class="cl-19__head">
<h2 class="cl-19__h">Same object, recalibrated</h2>
<p class="cl-19__lede">Flip the theme. The drop shadow gets darker and longer, the inset shade halves, and a 1px rim highlight takes over as the edge.</p>
<div class="cl-19__toggleWrap">
<input class="cl-19__chk" type="checkbox" id="cl-19-dark">
<label class="cl-19__toggle" for="cl-19-dark">
<span class="cl-19__tTrack" aria-hidden="true"><span class="cl-19__tKnob"></span></span>
Dark mode
</label>
</div>
</header>
<div class="cl-19__pane">
<article class="cl-19__card">
<span class="cl-19__puck" aria-hidden="true"></span>
<p class="cl-19__kicker">Tier 3 · floating</p>
<h3 class="cl-19__title">Recalibrated clay</h3>
<p class="cl-19__body">Fill sits 8% lighter than the page in both themes, so the object stays lifted rather than dissolving into the background.</p>
<ul class="cl-19__tokens">
<li><b>drop</b><span class="cl-19__v cl-19__v--drop"></span></li>
<li><b>inset shade</b><span class="cl-19__v cl-19__v--shade"></span></li>
<li><b>rim + sheen</b><span class="cl-19__v cl-19__v--light"></span></li>
</ul>
<div class="cl-19__btns">
<button class="cl-19__btn cl-19__btn--go" type="button">Apply theme</button>
<button class="cl-19__btn" type="button">Copy tokens</button>
</div>
</article>
<aside class="cl-19__rules">
<h4 class="cl-19__rulesH">Dark-mode rules</h4>
<ol class="cl-19__list">
<li><b>Lift the fill</b> — +6 to 10% lightness over the page.</li>
<li><b>Add a 1px rim</b> — <code>inset 0 1px 0 oklch(1 0 0/.16)</code>.</li>
<li><b>Halve the inset shade</b> — dark on dark is mud.</li>
<li><b>Longer, darker drop</b> — near-black at 70%+ alpha.</li>
</ol>
</aside>
</div>
<p class="cl-19__chip" aria-hidden="true">light-dark() tokens · color-scheme override · highlight-led depth in dark</p>
</div>
</section>
```
## CSS
```css
.cl-19,
.cl-19 *,
.cl-19 *::before,
.cl-19 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cl-19 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
color-scheme: light;
background: var(--cl-19-bg);
--cl-19-bg: light-dark(oklch(0.94 0.025 285),oklch(0.19 0.02 285));
--cl-19-clay: light-dark(oklch(0.9 0.05 285),oklch(0.3 0.03 285));
--cl-19-clay2: light-dark(oklch(0.94 0.03 285),oklch(0.26 0.025 285));
--cl-19-accent: light-dark(oklch(0.79 0.13 290),oklch(0.62 0.16 290));
--cl-19-drop: light-dark(oklch(0.55 0.09 285/.5),oklch(0 0 0/.72));
--cl-19-inShade: light-dark(oklch(0.55 0.09 285/.55),oklch(0 0 0/.5));
--cl-19-inLight: light-dark(oklch(1 0 0/.9),oklch(1 0 0/.1));
--cl-19-rim: light-dark(oklch(1 0 0/0),oklch(1 0 0/.16));
--cl-19-ink: light-dark(oklch(0.27 0.05 285),oklch(0.96 0.01 285));
--cl-19-mut: light-dark(oklch(0.5 0.04 285),oklch(0.74 0.02 285));
font-family: system-ui,-apple-system,'Segoe UI',sans-serif;
color: var(--cl-19-ink);
transition: background .45s;
}
.cl-19:has(#cl-19-dark:checked) {
color-scheme: dark;
}
.cl-19__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
align-content: center;
gap: clamp(20px,3.5vw,32px);
padding: clamp(20px,5vw,56px);
}
.cl-19__head {
display: grid;
gap: 14px;
justify-items: center;
text-align: center;
max-width: 60ch;
}
.cl-19__h {
font-size: clamp(23px,3.8vw,34px);
font-weight: 780;
letter-spacing: -.022em;
text-wrap: balance;
}
.cl-19__lede {
font-size: 15px;
line-height: 1.6;
color: var(--cl-19-mut);
text-wrap: pretty;
}
.cl-19__chk {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
clip-path: inset(50%);
}
.cl-19__toggle {
display: inline-flex;
align-items: center;
gap: 12px;
min-height: 50px;
padding: 0 22px 0 12px;
border-radius: 99px;
font-size: 14px;
font-weight: 640;
cursor: pointer;
background: var(--cl-19-clay2);
box-shadow: 0 14px 24px -14px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -8px 14px -10px var(--cl-19-inShade),inset 0 10px 14px -8px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__tTrack {
position: relative;
width: 50px;
height: 28px;
border-radius: 99px;
background: color-mix(in oklch,var(--cl-19-bg) 82%,var(--cl-19-mut));
box-shadow: inset 0 8px 13px -6px var(--cl-19-inShade),inset 0 -5px 10px -8px var(--cl-19-inLight);
}
.cl-19__tKnob {
position: absolute;
top: 3px;
left: 3px;
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--cl-19-clay);
box-shadow: 0 6px 11px -5px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 7px 9px -5px var(--cl-19-inLight);
transition: translate .34s cubic-bezier(.34,1.5,.5,1),background .45s;
}
.cl-19__chk:checked+.cl-19__toggle .cl-19__tKnob {
translate: 22px 0;
background: var(--cl-19-accent);
}
.cl-19__chk:focus-visible+.cl-19__toggle {
outline: 3px solid var(--cl-19-ink);
outline-offset: 3px;
}
.cl-19__pane {
display: grid;
grid-template-columns: 1fr;
gap: clamp(16px,2.6vw,24px);
width: min(100%,880px);
align-items: center;
}
@media (min-width: 820px) {
.cl-19__pane {
grid-template-columns: 1.15fr .85fr;
}
}
.cl-19__card {
display: grid;
gap: 11px;
padding: clamp(24px,3.2vw,34px);
border-radius: 40px;
background: var(--cl-19-clay);
box-shadow: 0 30px 56px -18px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -16px 26px -12px var(--cl-19-inShade),inset 0 18px 30px -10px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s,translate .4s cubic-bezier(.34,1.3,.5,1);
}
.cl-19__card:hover {
translate: 0 -6px;
}
.cl-19__puck {
width: 56px;
height: 56px;
border-radius: 22px;
background: var(--cl-19-accent);
box-shadow: 0 14px 24px -10px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -10px 16px -9px var(--cl-19-inShade),inset 0 12px 16px -7px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__kicker {
margin-top: 4px;
font-size: 11px;
font-weight: 700;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--cl-19-mut);
}
.cl-19__title {
font-size: clamp(20px,2.8vw,25px);
font-weight: 770;
letter-spacing: -.02em;
}
.cl-19__body {
font-size: 14px;
line-height: 1.6;
color: var(--cl-19-mut);
text-wrap: pretty;
}
.cl-19__tokens {
list-style: none;
display: grid;
gap: 8px;
margin: 6px 0 2px;
padding: 16px 18px;
border-radius: 24px;
background: var(--cl-19-clay2);
box-shadow: inset 0 9px 16px -8px var(--cl-19-inShade),inset 0 -6px 12px -10px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__tokens li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 12px;
color: var(--cl-19-mut);
}
.cl-19__v {
width: 74px;
height: 16px;
border-radius: 99px;
}
.cl-19__v--drop {
background: var(--cl-19-drop);
}
.cl-19__v--shade {
background: var(--cl-19-inShade);
}
.cl-19__v--light {
background: var(--cl-19-inLight);
box-shadow: inset 0 0 0 1px var(--cl-19-mut);
}
.cl-19__btns {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 6px;
}
.cl-19__btn {
min-height: 50px;
padding: 0 22px;
border: 0;
border-radius: 22px;
font: inherit;
font-size: 14px;
font-weight: 660;
color: var(--cl-19-ink);
cursor: pointer;
background: var(--cl-19-clay2);
box-shadow: 0 12px 20px -12px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -9px 15px -9px var(--cl-19-inShade),inset 0 11px 15px -7px var(--cl-19-inLight);
transition: translate .18s,scale .18s cubic-bezier(.2,.8,.3,1.4),background .45s,box-shadow .3s;
}
.cl-19__btn--go {
color: light-dark(oklch(0.24 0.06 290),oklch(0.98 0.01 290));
background: var(--cl-19-accent);
}
.cl-19__btn:hover {
translate: 0 -3px;
}
.cl-19__btn:active {
scale: 1 .94;
translate: 0 3px;
box-shadow: inset 0 12px 18px -8px var(--cl-19-inShade);
}
.cl-19__btn:focus-visible {
outline: 3px solid var(--cl-19-ink);
outline-offset: 3px;
}
.cl-19__rules {
display: grid;
gap: 10px;
padding: clamp(22px,3vw,30px);
border-radius: 36px;
background: var(--cl-19-clay2);
box-shadow: 0 22px 42px -20px var(--cl-19-drop),inset 0 1px 0 0 var(--cl-19-rim),inset 0 -14px 24px -14px var(--cl-19-inShade),inset 0 16px 26px -12px var(--cl-19-inLight);
transition: background .45s,box-shadow .45s;
}
.cl-19__rulesH {
font-size: 11.5px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--cl-19-mut);
}
.cl-19__list {
display: grid;
gap: 10px;
padding-left: 20px;
font-size: 13.5px;
line-height: 1.5;
}
.cl-19__list li {
color: var(--cl-19-mut);
}
.cl-19__list b {
color: var(--cl-19-ink);
}
.cl-19__list code {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
}
.cl-19__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--cl-19-mut);
padding: 9px 16px;
border-radius: 99px;
text-align: center;
background: var(--cl-19-clay2);
box-shadow: inset 0 1px 0 0 var(--cl-19-rim),inset 0 -4px 10px -8px var(--cl-19-inShade),inset 0 6px 10px -6px var(--cl-19-inLight);
transition: background .45s;
}
@media (prefers-reduced-motion: reduce) {
.cl-19 * {
transition-duration: .01ms !important;
}
}
```How this works
The physics change. In light mode the shadow does the work; in dark mode the highlight does.
/* LIGHT: shadow-led */
--drop: 0 24px 44px -12px oklch(0.55 0.09 280 / .5);
--in-shade: inset 0 -16px 26px -10px oklch(0.55 0.09 280 / .55);
--in-light: inset 0 18px 26px -8px oklch(1 0 0 / .9);
/* DARK: highlight-led */
--drop: 0 26px 50px -14px oklch(0 0 0 / .75); /* darker, longer */
--in-shade: inset 0 -14px 24px -12px oklch(0 0 0 / .5); /* weaker */
--in-light: inset 0 1px 0 0 oklch(1 0 0 / .16), /* crisp rim */
inset 0 18px 30px -14px oklch(1 0 0 / .1); /* soft sheen */Three rules for dark clay: (1) raise the fill's lightness above the page by 6-10% — dark clay must still be a lifted object; (2) add a 1px inset rim highlight, because a soft glow alone cannot define an edge against a dark background; (3) cut the inset shade's alpha roughly in half, since dark-on-dark just muddies.
All of it ships as one declaration per token with light-dark():
:root{ color-scheme: light dark; }
.clay{ background: light-dark(oklch(0.9 0.05 280), oklch(0.32 0.03 280)); }No duplicated @media (prefers-color-scheme) block, no class toggling — and because color-scheme is declared, form controls, scrollbars and focus rings follow the theme for free. The demo's switch overrides color-scheme on a wrapper so you can compare without changing your OS setting.
Make it yours
- Elevation in dark mode should come from fill lightness as much as shadow: tier 3 = +10% L, tier 1 = +4% L. Shadows alone cannot carry four tiers on a dark page.
- Accent glows: in dark mode a coloured outer shadow (
0 18px 40px -12px var(--accent)/.35) reads as emitted light and is very effective on primary CTAs — avoid it in light mode, where it looks like a printing error. - Respect the user by default: no toggle at all is a valid answer if you ship light-dark() — the OS preference just works.
- AMOLED variant: push the page to oklch(0.16) and keep the clay fill at 0.28+; below that the rim highlight is the only thing visible.
Gotchas — read before shipping
- Do not simply invert the light-mode shadow colors. A white outer shadow on a dark page looks like fog, not depth.
- light-dark() only responds to
color-scheme, not to a class — you must declarecolor-scheme:light darkon the element or an ancestor or it returns the light value. - Dark pastel text is a contrast trap in the other direction: light text on a mid-dark clay fill often lands at 3.8:1. Test the dark theme separately.
- Pure white rim highlights at more than ~20% alpha look like a chrome bevel from 2003. Keep them subtle and 1px.
- Shadows on dark backgrounds need more blur AND more alpha, but not more spread — a positive spread turns into a visible grey halo.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 123+ | 17.5+ | 120+ | 123+ |
light-dark(): Chrome 123 / Safari 17.5 / Firefox 120. For older engines duplicate the token block inside @media (prefers-color-scheme:dark) — same values, one extra block.