Open demo

CSS code

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="neu-i-bolt" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M13 3 5 13.5h6L10 21l8-10.5h-6z"/></symbol>
  <symbol id="neu-i-thermo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M14 14.5V5.5a2 2 0 0 0-4 0v9a4 4 0 1 0 4 0z"/><path d="M12 9.5V16"/></symbol>
  <symbol id="neu-i-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M4.6 4.6 6 6M18 18l1.4 1.4M2.5 12h2M19.5 12h2M4.6 19.4 6 18M18 6l1.4-1.4"/></symbol>
  <symbol id="neu-i-arrowDown" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M6.5 13.5 12 19l5.5-5.5"/></symbol>
  <symbol id="neu-i-arrowUp" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5M6.5 10.5 12 5l5.5 5.5"/></symbol>
  <symbol id="neu-i-drop" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5s6 6.6 6 11a6 6 0 0 1-12 0c0-4.4 6-11 6-11z"/></symbol>
  <symbol id="neu-i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12.5 4.5 4.5L19 7.5"/></symbol>
  <symbol id="neu-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="neu-i-message" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20.5 12a8.5 8.5 0 0 1-12.4 7.5L3.5 20.5l1-4.4A8.5 8.5 0 1 1 20.5 12z"/></symbol>
  <symbol id="neu-i-pin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 21s-6.5-6-6.5-11a6.5 6.5 0 0 1 13 0c0 5-6.5 11-6.5 11z"/><circle cx="12" cy="10" r="2.3"/></symbol>
  <symbol id="neu-i-star" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3.5 2.6 5.4 5.9.8-4.3 4.1 1 5.8L12 16.8l-5.2 2.8 1-5.8-4.3-4.1 5.9-.8z"/></symbol>
</svg>
<section><span class="lbl">Stat tiles</span><div class="neu-grid">
<article class="neu-stat"><span class="neu-stat__icon"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-bolt"/></svg></span><p class="neu-stat__label">Energy today</p><p class="neu-stat__value">12.4<small> kWh</small></p><p class="neu-stat__delta neu-stat__delta--good"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-arrowDown"/></svg>8% less than yesterday</p></article>
<article class="neu-stat"><span class="neu-stat__icon"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-thermo"/></svg></span><p class="neu-stat__label">Indoor temperature</p><p class="neu-stat__value">21.5<small> °C</small></p><p class="neu-stat__delta"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-drop"/></svg>Humidity 46%</p></article>
<article class="neu-stat"><span class="neu-stat__icon"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-sun"/></svg></span><p class="neu-stat__label">Solar output</p><p class="neu-stat__value">3.8<small> kW</small></p><p class="neu-stat__delta neu-stat__delta--good"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-arrowUp"/></svg>12% above forecast</p></article>
</div></section>
<div class="two">
<section><span class="lbl">Content card</span><article class="neu-card neu-post"><svg class="neu-post__media" viewBox="0 0 320 150" aria-hidden="true" focusable="false">
<rect class="sky" width="320" height="150"/><circle class="glow" cx="252" cy="44" r="34"/><circle class="sun" cx="252" cy="44" r="18"/>
<path class="line" d="M40 124h240M70 124V78l46-34 46 34v46M100 124V98h32v26"/><path class="line" d="M206 124V96a10 10 0 0 1 20 0v28M212 86v-8M220 86v-8"/><path class="glow" d="M200 72l-12 18h12l-6 16 18-22h-12l6-12z"/></svg>
<span class="neu-chip">Guide</span>
<h3 class="neu-post__title">Cut standby power in a weekend</h3>
<p class="neu-post__text">Smart plugs, a schedule and one honest look at the meter. Most homes find 40 to 90 kWh a year hiding in idle devices.</p>
<div class="neu-post__meta"><span>6 min read · Energy</span><a class="neu-link" href="#">Read the guide<span class="neu-sr">: Cut standby power in a weekend</span></a></div></article></section>
<section><span class="lbl">Profile card</span><article class="neu-card neu-profile">
<div class="neu-avatar"><span class="" aria-hidden="true">MO</span></div>
<h3 class="neu-profile__name">Mira Osei</h3>
<p class="neu-profile__role"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-pin"/></svg>Home energy coach, Accra</p>
<dl class="neu-profile__stats"><div><dt>Homes</dt><dd>128</dd></div><div><dt>Rating</dt><dd>4.9</dd></div><div><dt>Years</dt><dd>6</dd></div></dl>
<div class="neu-profile__actions"><button class="neu-btn neu-btn--accent" type="button">Follow</button><button class="neu-btn neu-btn--icon" type="button" aria-label="Message Mira Osei"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-message"/></svg></button></div></article></section>
</div>
<section><span class="lbl">Pricing cards</span><div class="two">
<article class="neu-card neu-price"><h3 class="neu-price__name">Basic</h3>
<p class="neu-price__amount"><strong>€0</strong> / month</p>
<p class="neu-price__note">Free for one home, forever</p>
<ul class="neu-price__list"><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="neu-sr">Included: </span>Up to 3 rooms</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="neu-sr">Included: </span>Live energy meter</li><li class="is-off"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="neu-sr">Not included: </span>Unlimited rooms and scenes</li><li class="is-off"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="neu-sr">Not included: </span>Away mode with geofencing</li><li class="is-off"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="neu-sr">Not included: </span>30 days of camera history</li></ul>
<button class="neu-btn neu-btn--block" type="button">Current plan</button></article>
<article class="neu-card neu-price neu-price--featured"><p class="neu-price__badge">Most popular</p><h3 class="neu-price__name">Plus</h3>
<p class="neu-price__amount"><strong>€4</strong> / month</p>
<p class="neu-price__note">Billed yearly at €48</p>
<ul class="neu-price__list"><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="neu-sr">Included: </span>Up to 3 rooms</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="neu-sr">Included: </span>Live energy meter</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="neu-sr">Included: </span>Unlimited rooms and scenes</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="neu-sr">Included: </span>Away mode with geofencing</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="neu-sr">Included: </span>30 days of camera history</li></ul>
<button class="neu-btn neu-btn--accent neu-btn--block" type="button">Upgrade to Plus</button></article>
</div></section>
CSS
/* ── Neumorphism UI kit tokens (uiCookies) — identical in every set ──────────────
   Every component is moulded from --neu-bg and lit from the top left. Change a token and
   the whole kit follows; the shadow recipes below are built from these values. */
:root{
  --neu-bg:#e0e5ec;          /* the one surface colour */
  --neu-light:#ffffff;       /* highlight, top left */
  --neu-dark:#a3b1c6;        /* shade, bottom right */
  --neu-distance:6px;        /* how far a shape rises */
  --neu-blur:14px;           /* how soft its shadow is */
  --neu-radius:18px;         /* cards; buttons use .75 of it, fields .6 */
  --neu-accent:#4f46e5;      /* focus ring and on / selected / current states, 4.9:1 on --neu-bg */
  --neu-on-accent:#ffffff;   /* text and marks on accent fills, 6.3:1 */
  --neu-ink:#1f2937;         /* text, 11.6:1 */
  --neu-muted:#4a5568;       /* secondary text, 5.9:1 */
  --neu-edge:#74819a;        /* control boundary (fields, tracks, boxes, buttons), 3.1:1 */
  --neu-line:rgba(255,255,255,.6); /* decorative edge on cards and panels */
  --neu-bw:1px;              /* control border width */
  --neu-success:#126b35;--neu-warning:#8a5300;--neu-danger:#b42318;
}
/* Dark neumorphism: data-neu="dark" on any wrapper, or a checked .neu-theme-input inside a [data-neu] element.
   :is() is a forgiving list, so browsers without :has() still apply data-neu="dark" */
[data-neu]:is([data-neu="dark"],:has(.neu-theme-input:checked)){
  --neu-bg:#262b33;--neu-light:#323944;--neu-dark:#14171c;
  --neu-accent:#8f88ff;--neu-on-accent:#14161b;--neu-ink:#e7ebf2;--neu-muted:#aab4c3;--neu-edge:#717d90;
  --neu-line:rgba(255,255,255,.06);--neu-success:#6fdc9a;--neu-warning:#f3c164;--neu-danger:#ff8f84;color-scheme:dark}
/* More contrast requested: the soft shadows go, every control and panel gets a solid outline */
@media (prefers-contrast:more){:root,[data-neu]:is([data-neu],:has(.neu-theme-input:checked)){
  --neu-light:transparent;--neu-dark:transparent;--neu-edge:var(--neu-ink);--neu-line:var(--neu-ink);--neu-muted:var(--neu-ink);--neu-bw:2px}}
:root,[data-neu]{
  --neu-raised:var(--neu-distance) var(--neu-distance) var(--neu-blur) var(--neu-dark),calc(var(--neu-distance)*-1) calc(var(--neu-distance)*-1) var(--neu-blur) var(--neu-light);
  --neu-raised-sm:calc(var(--neu-distance)*.5) calc(var(--neu-distance)*.5) calc(var(--neu-blur)*.5) var(--neu-dark),calc(var(--neu-distance)*-.5) calc(var(--neu-distance)*-.5) calc(var(--neu-blur)*.5) var(--neu-light);
  --neu-inset:inset calc(var(--neu-distance)*.6) calc(var(--neu-distance)*.6) calc(var(--neu-blur)*.6) var(--neu-dark),inset calc(var(--neu-distance)*-.6) calc(var(--neu-distance)*-.6) calc(var(--neu-blur)*.6) var(--neu-light);
  --neu-inset-sm:inset calc(var(--neu-distance)*.35) calc(var(--neu-distance)*.35) calc(var(--neu-blur)*.35) var(--neu-dark),inset calc(var(--neu-distance)*-.35) calc(var(--neu-distance)*-.35) calc(var(--neu-blur)*.35) var(--neu-light);
}
[data-neu]{background:var(--neu-bg);color:var(--neu-ink)}
/* Components */
:where([class*="neu-"]),:where([class*="neu-"])::before,:where([class*="neu-"])::after{box-sizing:border-box}
.neu-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.neu-ico{width:20px;height:20px;flex:none}
/* Buttons: raised by default, pressed (inset) while held, accent ring on keyboard focus */
.neu-btn{display:inline-flex;align-items:center;justify-content:center;gap:.55rem;min-height:46px;padding:.65rem 1.35rem;
  border:var(--neu-bw) solid var(--neu-edge);border-radius:calc(var(--neu-radius)*.75);background:var(--neu-bg);color:var(--neu-ink);
  font-family:inherit;font-size:.95rem;font-weight:600;line-height:1.2;text-decoration:none;cursor:pointer;
  box-shadow:var(--neu-raised-sm);transition:box-shadow .2s,color .2s,background-color .2s}
.neu-btn:hover{box-shadow:var(--neu-raised)}
.neu-btn:active{box-shadow:var(--neu-inset-sm)}
.neu-btn:focus-visible{outline:3px solid var(--neu-accent);outline-offset:3px}
.neu-btn--accent{background:var(--neu-accent);border-color:var(--neu-accent);color:var(--neu-on-accent)}
.neu-btn--sm{min-height:38px;padding:.45rem 1rem;font-size:.85rem}
.neu-btn--block{width:100%}
.neu-btn--icon{width:50px;height:50px;min-height:0;padding:0;border-radius:50%}
.neu-btn--square{border-radius:calc(var(--neu-radius)*.75)}
.neu-btn--icon-sm{width:42px;height:42px}
.neu-btn--icon-lg{width:64px;height:64px}
.neu-btn--icon .neu-ico{width:22px;height:22px}
/* Card: a raised panel with a faint highlight edge (a solid outline under prefers-contrast: more) */
.neu-card{padding:1.5rem;border:var(--neu-bw) solid var(--neu-line);border-radius:var(--neu-radius);background:var(--neu-bg);color:var(--neu-ink);box-shadow:var(--neu-raised)}
.neu-card h2,.neu-card h3,.neu-card p{margin:0}
/* Stat tile: icon in a pressed well, label, a big value, and a change line that says which way in words */
.neu-stat{display:grid;gap:.2rem;padding:1.25rem;border:var(--neu-bw) solid var(--neu-line);border-radius:var(--neu-radius);background:var(--neu-bg);box-shadow:var(--neu-raised)}
.neu-stat__icon{display:grid;place-items:center;width:44px;height:44px;margin-bottom:.6rem;border-radius:50%;color:var(--neu-accent);box-shadow:var(--neu-inset-sm)}
.neu-stat__label{margin:0;font-size:.85rem;font-weight:600;color:var(--neu-muted)}
.neu-stat__value{margin:0;font-size:1.9rem;font-weight:700;line-height:1.15;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.neu-stat__value small{font-size:.9rem;font-weight:600;letter-spacing:0;color:var(--neu-muted)}
.neu-stat__delta{display:flex;align-items:center;gap:.3rem;margin:.35rem 0 0;font-size:.82rem;font-weight:600;color:var(--neu-muted)}
.neu-stat__delta .neu-ico{width:16px;height:16px}
.neu-stat__delta--good{color:var(--neu-success)}
.neu-stat__delta--warn{color:var(--neu-warning)}
/* Content card: an illustration in a pressed well, a category chip, title, excerpt and a link */
.neu-post{display:grid;gap:.85rem}
.neu-post__media{display:block;width:100%;height:auto;margin-bottom:.35rem;border:var(--neu-bw) solid var(--neu-line);border-radius:calc(var(--neu-radius)*.7);box-shadow:var(--neu-inset)}
.neu-post__media .sky{fill:var(--neu-bg)}.neu-post__media .sun{fill:var(--neu-accent);opacity:.9}
.neu-post__media .line{fill:none;stroke:var(--neu-muted);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.neu-post__media .glow{fill:var(--neu-accent);opacity:.18}
.neu-chip{justify-self:start;display:inline-flex;align-items:center;padding:.3rem .75rem;border:var(--neu-bw) solid var(--neu-line);border-radius:999px;
  font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--neu-accent);box-shadow:var(--neu-inset-sm)}
.neu-post__title{margin:0;font-size:1.2rem;font-weight:700;line-height:1.3}
.neu-post__text{margin:0;color:var(--neu-muted)}
.neu-post__meta{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.6rem;margin-top:.2rem;font-size:.88rem;color:var(--neu-muted)}
.neu-link{color:var(--neu-accent);font-weight:600;text-decoration:underline;text-underline-offset:3px;border-radius:4px}
.neu-link:hover{text-decoration-thickness:2px}
.neu-link:focus-visible{outline:3px solid var(--neu-accent);outline-offset:3px}
/* Profile card: avatar in a raised ring, name, role, stats in a pressed well, two actions */
.neu-profile{display:grid;justify-items:center;gap:.25rem;text-align:center}
.neu-avatar{display:grid;place-items:center;width:104px;height:104px;margin-bottom:.9rem;border-radius:50%;box-shadow:var(--neu-raised)}
.neu-avatar span{display:grid;place-items:center;width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,#4f46e5,#0e7490);color:#fff;
  font-size:1.6rem;font-weight:700;letter-spacing:.02em;box-shadow:var(--neu-inset-sm)}
.neu-profile__name{margin:0;font-size:1.2rem;font-weight:700}
.neu-profile__role{display:flex;align-items:center;gap:.3rem;margin:0;font-size:.9rem;color:var(--neu-muted)}
.neu-profile__role .neu-ico{width:16px;height:16px}
.neu-profile__stats{display:grid;grid-template-columns:repeat(3,1fr);width:100%;margin:1.1rem 0 1.2rem;padding:.9rem .5rem;border:var(--neu-bw) solid var(--neu-line);border-radius:calc(var(--neu-radius)*.7);box-shadow:var(--neu-inset-sm)}
.neu-profile__stats div{display:flex;flex-direction:column-reverse}
.neu-profile__stats dt{font-size:.78rem;font-weight:400;color:var(--neu-muted)}
.neu-profile__stats dd{margin:0;font-size:1.15rem;font-weight:700;font-variant-numeric:tabular-nums}
.neu-profile__actions{display:flex;align-items:center;justify-content:center;gap:14px}
/* Pricing cards: the recommended plan has an accent edge and a visible "Most popular" badge, not colour alone.
   Every feature line says Included or Not included to screen readers. */
.neu-price{position:relative;display:grid;align-content:start;gap:.5rem;padding:1.75rem}
.neu-price--featured{border-color:var(--neu-accent);border-width:2px}
.neu-price__badge{position:absolute;top:1.25rem;right:1.25rem;margin:0;padding:.3rem .75rem;border-radius:999px;background:var(--neu-accent);color:var(--neu-on-accent);
  font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.neu-price__name{margin:0;font-size:1.05rem;font-weight:700}
.neu-price__amount{margin:0;font-size:.95rem;color:var(--neu-muted)}
.neu-price__amount strong{font-size:2.4rem;font-weight:700;letter-spacing:-.03em;color:var(--neu-ink)}
.neu-price__note{margin:0;font-size:.85rem;color:var(--neu-muted)}
.neu-price__list{display:grid;gap:.6rem;margin:.9rem 0 1.4rem;padding:1rem 1.1rem;list-style:none;border:var(--neu-bw) solid var(--neu-line);border-radius:calc(var(--neu-radius)*.7);box-shadow:var(--neu-inset-sm)}
.neu-price__list li{display:flex;align-items:center;gap:.6rem;font-size:.92rem}
.neu-price__list .neu-ico{width:18px;height:18px;color:var(--neu-accent)}
.neu-price__list .is-off{color:var(--neu-muted)}
.neu-price__list .is-off .neu-ico{color:var(--neu-muted)}
.neu-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr));gap:28px}
@media (prefers-reduced-motion:reduce){.neu-btn{transition:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="neu-i-bolt" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M13 3 5 13.5h6L10 21l8-10.5h-6z"/></symbol>
  <symbol id="neu-i-thermo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M14 14.5V5.5a2 2 0 0 0-4 0v9a4 4 0 1 0 4 0z"/><path d="M12 9.5V16"/></symbol>
  <symbol id="neu-i-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M4.6 4.6 6 6M18 18l1.4 1.4M2.5 12h2M19.5 12h2M4.6 19.4 6 18M18 6l1.4-1.4"/></symbol>
  <symbol id="neu-i-arrowDown" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M6.5 13.5 12 19l5.5-5.5"/></symbol>
  <symbol id="neu-i-arrowUp" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5M6.5 10.5 12 5l5.5 5.5"/></symbol>
  <symbol id="neu-i-drop" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5s6 6.6 6 11a6 6 0 0 1-12 0c0-4.4 6-11 6-11z"/></symbol>
  <symbol id="neu-i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12.5 4.5 4.5L19 7.5"/></symbol>
  <symbol id="neu-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="neu-i-message" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20.5 12a8.5 8.5 0 0 1-12.4 7.5L3.5 20.5l1-4.4A8.5 8.5 0 1 1 20.5 12z"/></symbol>
  <symbol id="neu-i-pin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 21s-6.5-6-6.5-11a6.5 6.5 0 0 1 13 0c0 5-6.5 11-6.5 11z"/><circle cx="12" cy="10" r="2.3"/></symbol>
  <symbol id="neu-i-star" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3.5 2.6 5.4 5.9.8-4.3 4.1 1 5.8L12 16.8l-5.2 2.8 1-5.8-4.3-4.1 5.9-.8z"/></symbol>
</svg>
<section><span class="lbl">Stat tiles</span><div class="row row-cols-1 row-cols-md-3 g-4">
<div class="col"><article class="neu-stat"><span class="neu-stat__icon"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-bolt"/></svg></span><p class="neu-stat__label">Energy today</p><p class="neu-stat__value">12.4<small> kWh</small></p><p class="neu-stat__delta neu-stat__delta--good"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-arrowDown"/></svg>8% less than yesterday</p></article></div>
<div class="col"><article class="neu-stat"><span class="neu-stat__icon"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-thermo"/></svg></span><p class="neu-stat__label">Indoor temperature</p><p class="neu-stat__value">21.5<small> °C</small></p><p class="neu-stat__delta"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-drop"/></svg>Humidity 46%</p></article></div>
<div class="col"><article class="neu-stat"><span class="neu-stat__icon"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-sun"/></svg></span><p class="neu-stat__label">Solar output</p><p class="neu-stat__value">3.8<small> kW</small></p><p class="neu-stat__delta neu-stat__delta--good"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-arrowUp"/></svg>12% above forecast</p></article></div>
</div></section>
<div class="row g-4 align-items-start">
<div class="col-md-6"><section><span class="lbl">Content card</span><article class="card neu-card neu-post"><div class="card-body"><svg class="neu-post__media" viewBox="0 0 320 150" aria-hidden="true" focusable="false">
<rect class="sky" width="320" height="150"/><circle class="glow" cx="252" cy="44" r="34"/><circle class="sun" cx="252" cy="44" r="18"/>
<path class="line" d="M40 124h240M70 124V78l46-34 46 34v46M100 124V98h32v26"/><path class="line" d="M206 124V96a10 10 0 0 1 20 0v28M212 86v-8M220 86v-8"/><path class="glow" d="M200 72l-12 18h12l-6 16 18-22h-12l6-12z"/></svg>
<span class="badge rounded-pill neu-chip">Guide</span>
<h3 class="neu-post__title">Cut standby power in a weekend</h3>
<p class="neu-post__text">Smart plugs, a schedule and one honest look at the meter. Most homes find 40 to 90 kWh a year hiding in idle devices.</p>
<div class="neu-post__meta"><span>6 min read · Energy</span><a class="neu-link" href="#">Read the guide<span class="visually-hidden">: Cut standby power in a weekend</span></a></div></div></article></section></div>
<div class="col-md-6"><section><span class="lbl">Profile card</span><article class="card neu-card neu-profile"><div class="card-body">
<div class="neu-avatar"><span class="" aria-hidden="true">MO</span></div>
<h3 class="neu-profile__name">Mira Osei</h3>
<p class="neu-profile__role"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-pin"/></svg>Home energy coach, Accra</p>
<dl class="neu-profile__stats"><div><dt>Homes</dt><dd>128</dd></div><div><dt>Rating</dt><dd>4.9</dd></div><div><dt>Years</dt><dd>6</dd></div></dl>
<div class="neu-profile__actions"><button class="btn btn-neu btn-neu-accent" type="button">Follow</button><button class="btn btn-neu btn-neu-icon" type="button" aria-label="Message Mira Osei"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-message"/></svg></button></div></div></article></section></div>
</div>
<section><span class="lbl">Pricing cards</span><div class="row g-4 align-items-start">
<div class="col-md-6"><article class="card neu-card neu-price"><div class="card-body"><h3 class="neu-price__name">Basic</h3>
<p class="neu-price__amount"><strong>€0</strong> / month</p>
<p class="neu-price__note">Free for one home, forever</p>
<ul class="neu-price__list"><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="visually-hidden">Included: </span>Up to 3 rooms</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="visually-hidden">Included: </span>Live energy meter</li><li class="is-off"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="visually-hidden">Not included: </span>Unlimited rooms and scenes</li><li class="is-off"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="visually-hidden">Not included: </span>Away mode with geofencing</li><li class="is-off"><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="visually-hidden">Not included: </span>30 days of camera history</li></ul>
<button class="btn btn-neu w-100" type="button">Current plan</button></div></article></div>
<div class="col-md-6"><article class="card neu-card neu-price neu-price--featured"><div class="card-body"><p class="badge rounded-pill">Most popular</p><h3 class="neu-price__name">Plus</h3>
<p class="neu-price__amount"><strong>€4</strong> / month</p>
<p class="neu-price__note">Billed yearly at €48</p>
<ul class="neu-price__list"><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="visually-hidden">Included: </span>Up to 3 rooms</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="visually-hidden">Included: </span>Live energy meter</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="visually-hidden">Included: </span>Unlimited rooms and scenes</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="visually-hidden">Included: </span>Away mode with geofencing</li><li><svg class="neu-ico" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="visually-hidden">Included: </span>30 days of camera history</li></ul>
<button class="btn btn-neu btn-neu-accent w-100" type="button">Upgrade to Plus</button></div></article></div>
</div></section>
CSS
/* ── Neumorphism UI kit tokens (uiCookies) — identical in every set ──────────────
   Every component is moulded from --neu-bg and lit from the top left. Change a token and
   the whole kit follows; the shadow recipes below are built from these values. */
:root{
  --neu-bg:#e0e5ec;          /* the one surface colour */
  --neu-light:#ffffff;       /* highlight, top left */
  --neu-dark:#a3b1c6;        /* shade, bottom right */
  --neu-distance:6px;        /* how far a shape rises */
  --neu-blur:14px;           /* how soft its shadow is */
  --neu-radius:18px;         /* cards; buttons use .75 of it, fields .6 */
  --neu-accent:#4f46e5;      /* focus ring and on / selected / current states, 4.9:1 on --neu-bg */
  --neu-on-accent:#ffffff;   /* text and marks on accent fills, 6.3:1 */
  --neu-ink:#1f2937;         /* text, 11.6:1 */
  --neu-muted:#4a5568;       /* secondary text, 5.9:1 */
  --neu-edge:#74819a;        /* control boundary (fields, tracks, boxes, buttons), 3.1:1 */
  --neu-line:rgba(255,255,255,.6); /* decorative edge on cards and panels */
  --neu-bw:1px;              /* control border width */
  --neu-success:#126b35;--neu-warning:#8a5300;--neu-danger:#b42318;
}
/* Dark neumorphism: data-neu="dark" on any wrapper, or a checked .neu-theme-input inside a [data-neu] element.
   :is() is a forgiving list, so browsers without :has() still apply data-neu="dark" */
[data-neu]:is([data-neu="dark"],:has(.neu-theme-input:checked)){
  --neu-bg:#262b33;--neu-light:#323944;--neu-dark:#14171c;
  --neu-accent:#8f88ff;--neu-on-accent:#14161b;--neu-ink:#e7ebf2;--neu-muted:#aab4c3;--neu-edge:#717d90;
  --neu-line:rgba(255,255,255,.06);--neu-success:#6fdc9a;--neu-warning:#f3c164;--neu-danger:#ff8f84;color-scheme:dark}
/* More contrast requested: the soft shadows go, every control and panel gets a solid outline */
@media (prefers-contrast:more){:root,[data-neu]:is([data-neu],:has(.neu-theme-input:checked)){
  --neu-light:transparent;--neu-dark:transparent;--neu-edge:var(--neu-ink);--neu-line:var(--neu-ink);--neu-muted:var(--neu-ink);--neu-bw:2px}}
:root,[data-neu]{
  --neu-raised:var(--neu-distance) var(--neu-distance) var(--neu-blur) var(--neu-dark),calc(var(--neu-distance)*-1) calc(var(--neu-distance)*-1) var(--neu-blur) var(--neu-light);
  --neu-raised-sm:calc(var(--neu-distance)*.5) calc(var(--neu-distance)*.5) calc(var(--neu-blur)*.5) var(--neu-dark),calc(var(--neu-distance)*-.5) calc(var(--neu-distance)*-.5) calc(var(--neu-blur)*.5) var(--neu-light);
  --neu-inset:inset calc(var(--neu-distance)*.6) calc(var(--neu-distance)*.6) calc(var(--neu-blur)*.6) var(--neu-dark),inset calc(var(--neu-distance)*-.6) calc(var(--neu-distance)*-.6) calc(var(--neu-blur)*.6) var(--neu-light);
  --neu-inset-sm:inset calc(var(--neu-distance)*.35) calc(var(--neu-distance)*.35) calc(var(--neu-blur)*.35) var(--neu-dark),inset calc(var(--neu-distance)*-.35) calc(var(--neu-distance)*-.35) calc(var(--neu-blur)*.35) var(--neu-light);
}
[data-neu]{background:var(--neu-bg);color:var(--neu-ink)}
/* Bootstrap's own variables mapped onto the kit tokens */
:root,[data-neu]{--bs-body-bg:var(--neu-bg);--bs-body-color:var(--neu-ink);--bs-emphasis-color:var(--neu-ink);
  --bs-heading-color:var(--neu-ink);--bs-secondary-color:var(--neu-muted);--bs-tertiary-color:var(--neu-muted);
  --bs-border-color:var(--neu-edge);--bs-border-width:var(--neu-bw);--bs-border-radius:calc(var(--neu-radius)*.6);
  --bs-border-radius-lg:var(--neu-radius);--bs-focus-ring-color:var(--neu-accent)}
/* Components */
.neu-ico{width:20px;height:20px;flex:none}
/* Buttons: Bootstrap .btn with a .btn-neu variant set through --bs-btn-* variables */
.btn-neu{--bs-btn-padding-x:1.35rem;--bs-btn-padding-y:.65rem;--bs-btn-font-size:.95rem;--bs-btn-font-weight:600;--bs-btn-line-height:1.2;
  --bs-btn-border-width:var(--neu-bw);--bs-btn-border-radius:calc(var(--neu-radius)*.75);
  --bs-btn-bg:var(--neu-bg);--bs-btn-color:var(--neu-ink);--bs-btn-border-color:var(--neu-edge);
  --bs-btn-hover-bg:var(--neu-bg);--bs-btn-hover-color:var(--neu-ink);--bs-btn-hover-border-color:var(--neu-edge);
  --bs-btn-active-bg:var(--neu-bg);--bs-btn-active-color:var(--neu-ink);--bs-btn-active-border-color:var(--neu-edge);
  --neu-btn-shadow:var(--neu-raised-sm);
  display:inline-flex;align-items:center;justify-content:center;gap:.55rem;min-height:46px;
  box-shadow:var(--neu-btn-shadow);transition:box-shadow .2s,color .2s,background-color .2s}
.btn-neu:hover{--neu-btn-shadow:var(--neu-raised)}
.btn-neu:active{--neu-btn-shadow:var(--neu-inset-sm)}
.btn-neu:focus-visible,.btn-check:focus-visible+.btn-neu{box-shadow:var(--neu-btn-shadow);outline:3px solid var(--neu-accent);outline-offset:3px}
.btn-neu-accent{--bs-btn-bg:var(--neu-accent);--bs-btn-color:var(--neu-on-accent);--bs-btn-border-color:var(--neu-accent);
  --bs-btn-hover-bg:var(--neu-accent);--bs-btn-hover-color:var(--neu-on-accent);--bs-btn-hover-border-color:var(--neu-accent);
  --bs-btn-active-bg:var(--neu-accent);--bs-btn-active-color:var(--neu-on-accent);--bs-btn-active-border-color:var(--neu-accent)}
.btn-neu.btn-sm{--bs-btn-padding-x:1rem;--bs-btn-padding-y:.45rem;--bs-btn-font-size:.85rem;min-height:38px}
.btn-neu-icon{--bs-btn-padding-x:0;--bs-btn-padding-y:0;width:50px;height:50px;min-height:0;border-radius:50%}
.btn-neu-icon.btn-neu-square{border-radius:calc(var(--neu-radius)*.75)}
.btn-neu-icon-sm{width:42px;height:42px}
.btn-neu-icon-lg{width:64px;height:64px}
.btn-neu-icon .neu-ico{width:22px;height:22px}
/* Card: Bootstrap .card restyled through --bs-card-* */
.card.neu-card{--bs-card-bg:var(--neu-bg);--bs-card-color:var(--neu-ink);--bs-card-border-color:var(--neu-line);--bs-card-border-width:var(--neu-bw);
  --bs-card-border-radius:var(--neu-radius);--bs-card-inner-border-radius:calc(var(--neu-radius) - var(--neu-bw));--bs-card-spacer-x:1.5rem;--bs-card-spacer-y:1.5rem;box-shadow:var(--neu-raised)}
.neu-card h2,.neu-card h3,.neu-card p{margin:0}
/* Stat tile: icon in a pressed well, label, a big value, and a change line that says which way in words */
.neu-stat{display:grid;gap:.2rem;padding:1.25rem;border:var(--neu-bw) solid var(--neu-line);border-radius:var(--neu-radius);background:var(--neu-bg);box-shadow:var(--neu-raised)}
.neu-stat__icon{display:grid;place-items:center;width:44px;height:44px;margin-bottom:.6rem;border-radius:50%;color:var(--neu-accent);box-shadow:var(--neu-inset-sm)}
.neu-stat__label{margin:0;font-size:.85rem;font-weight:600;color:var(--neu-muted)}
.neu-stat__value{margin:0;font-size:1.9rem;font-weight:700;line-height:1.15;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.neu-stat__value small{font-size:.9rem;font-weight:600;letter-spacing:0;color:var(--neu-muted)}
.neu-stat__delta{display:flex;align-items:center;gap:.3rem;margin:.35rem 0 0;font-size:.82rem;font-weight:600;color:var(--neu-muted)}
.neu-stat__delta .neu-ico{width:16px;height:16px}
.neu-stat__delta--good{color:var(--neu-success)}
.neu-stat__delta--warn{color:var(--neu-warning)}
/* Content card: an illustration in a pressed well, a category chip, title, excerpt and a link */
.neu-post .card-body{display:grid;gap:.85rem}
.neu-post__media{display:block;width:100%;height:auto;margin-bottom:.35rem;border:var(--neu-bw) solid var(--neu-line);border-radius:calc(var(--neu-radius)*.7);box-shadow:var(--neu-inset)}
.neu-post__media .sky{fill:var(--neu-bg)}.neu-post__media .sun{fill:var(--neu-accent);opacity:.9}
.neu-post__media .line{fill:none;stroke:var(--neu-muted);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.neu-post__media .glow{fill:var(--neu-accent);opacity:.18}
.neu-chip{--bs-badge-padding-x:.75rem;--bs-badge-padding-y:.4rem;--bs-badge-font-size:.72rem;--bs-badge-color:var(--neu-accent);justify-self:start;border:var(--neu-bw) solid var(--neu-line);border-radius:999px;
  font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--neu-accent);box-shadow:var(--neu-inset-sm)}
.neu-post__title{margin:0;font-size:1.2rem;font-weight:700;line-height:1.3}
.neu-post__text{margin:0;color:var(--neu-muted)}
.neu-post__meta{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.6rem;margin-top:.2rem;font-size:.88rem;color:var(--neu-muted)}
.neu-link{color:var(--neu-accent);font-weight:600;text-decoration:underline;text-underline-offset:3px;border-radius:4px}
.neu-link:hover{text-decoration-thickness:2px}
.neu-link:focus-visible{outline:3px solid var(--neu-accent);outline-offset:3px}
/* Profile card: avatar in a raised ring, name, role, stats in a pressed well, two actions */
.neu-profile .card-body{display:grid;justify-items:center;gap:.25rem;text-align:center}
.neu-avatar{display:grid;place-items:center;width:104px;height:104px;margin-bottom:.9rem;border-radius:50%;box-shadow:var(--neu-raised)}
.neu-avatar span{display:grid;place-items:center;width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,#4f46e5,#0e7490);color:#fff;
  font-size:1.6rem;font-weight:700;letter-spacing:.02em;box-shadow:var(--neu-inset-sm)}
.neu-profile__name{margin:0;font-size:1.2rem;font-weight:700}
.neu-profile__role{display:flex;align-items:center;gap:.3rem;margin:0;font-size:.9rem;color:var(--neu-muted)}
.neu-profile__role .neu-ico{width:16px;height:16px}
.neu-profile .neu-profile__stats{display:grid;grid-template-columns:repeat(3,1fr);width:100%;margin:1.1rem 0 1.2rem;padding:.9rem .5rem;border:var(--neu-bw) solid var(--neu-line);border-radius:calc(var(--neu-radius)*.7);box-shadow:var(--neu-inset-sm)}
.neu-profile__stats div{display:flex;flex-direction:column-reverse}
.neu-profile__stats dt{font-size:.78rem;font-weight:400;color:var(--neu-muted)}
.neu-profile__stats dd{margin:0;font-size:1.15rem;font-weight:700;font-variant-numeric:tabular-nums}
.neu-profile__actions{display:flex;align-items:center;justify-content:center;gap:14px}
/* Pricing cards: the recommended plan has an accent edge and a visible "Most popular" badge, not colour alone.
   Every feature line says Included or Not included to screen readers. */
.neu-price .card-body{position:relative;display:grid;align-content:start;gap:.5rem;padding:1.75rem}
.card.neu-price--featured{--bs-card-border-color:var(--neu-accent);--bs-card-border-width:2px}
.neu-price .badge{--bs-badge-padding-x:.75rem;--bs-badge-padding-y:.4rem;--bs-badge-font-size:.72rem;--bs-badge-color:var(--neu-on-accent);position:absolute;top:1.25rem;right:1.25rem;background:var(--neu-accent);letter-spacing:.06em;text-transform:uppercase}
.neu-price__name{margin:0;font-size:1.05rem;font-weight:700}
.neu-price__amount{margin:0;font-size:.95rem;color:var(--neu-muted)}
.neu-price__amount strong{font-size:2.4rem;font-weight:700;letter-spacing:-.03em;color:var(--neu-ink)}
.neu-price__note{margin:0;font-size:.85rem;color:var(--neu-muted)}
.neu-price__list{display:grid;gap:.6rem;margin:.9rem 0 1.4rem;padding:1rem 1.1rem;list-style:none;border:var(--neu-bw) solid var(--neu-line);border-radius:calc(var(--neu-radius)*.7);box-shadow:var(--neu-inset-sm)}
.neu-price__list li{display:flex;align-items:center;gap:.6rem;font-size:.92rem}
.neu-price__list .neu-ico{width:18px;height:18px;color:var(--neu-accent)}
.neu-price__list .is-off{color:var(--neu-muted)}
.neu-price__list .is-off .neu-ico{color:var(--neu-muted)}
@media (prefers-reduced-motion:reduce){.btn-neu{transition:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="neu-i-bolt" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M13 3 5 13.5h6L10 21l8-10.5h-6z"/></symbol>
  <symbol id="neu-i-thermo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M14 14.5V5.5a2 2 0 0 0-4 0v9a4 4 0 1 0 4 0z"/><path d="M12 9.5V16"/></symbol>
  <symbol id="neu-i-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2.5v2M12 19.5v2M4.6 4.6 6 6M18 18l1.4 1.4M2.5 12h2M19.5 12h2M4.6 19.4 6 18M18 6l1.4-1.4"/></symbol>
  <symbol id="neu-i-arrowDown" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M6.5 13.5 12 19l5.5-5.5"/></symbol>
  <symbol id="neu-i-arrowUp" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5M6.5 10.5 12 5l5.5 5.5"/></symbol>
  <symbol id="neu-i-drop" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5s6 6.6 6 11a6 6 0 0 1-12 0c0-4.4 6-11 6-11z"/></symbol>
  <symbol id="neu-i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12.5 4.5 4.5L19 7.5"/></symbol>
  <symbol id="neu-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="neu-i-message" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20.5 12a8.5 8.5 0 0 1-12.4 7.5L3.5 20.5l1-4.4A8.5 8.5 0 1 1 20.5 12z"/></symbol>
  <symbol id="neu-i-pin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 21s-6.5-6-6.5-11a6.5 6.5 0 0 1 13 0c0 5-6.5 11-6.5 11z"/><circle cx="12" cy="10" r="2.3"/></symbol>
  <symbol id="neu-i-star" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3.5 2.6 5.4 5.9.8-4.3 4.1 1 5.8L12 16.8l-5.2 2.8 1-5.8-4.3-4.1 5.9-.8z"/></symbol>
</svg>
<section><span class="mb-[18px] block text-[.72rem] font-semibold tracking-[.12em] text-neu-muted uppercase">Stat tiles</span><div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,260px),1fr))] gap-7">
<article class="grid gap-[.2rem] rounded-neu border-(length:--neu-bw) border-neu-line bg-neu-bg p-5 shadow-neu"><span class="mb-[.6rem] grid size-11 place-items-center rounded-full text-neu-accent shadow-neu-in-sm"><svg class="size-5 shrink-0" aria-hidden="true" focusable="false"><use href="#neu-i-bolt"/></svg></span><p class="text-[.85rem] font-semibold text-neu-muted">Energy today</p><p class="text-[1.9rem] leading-[1.15] font-bold tracking-[-.02em] tabular-nums">12.4<small class="text-[.9rem] font-semibold tracking-normal text-neu-muted"> kWh</small></p><p class="mt-[.35rem] flex items-center gap-[.3rem] text-[.82rem] font-semibold text-neu-success"><svg class="size-4 shrink-0" aria-hidden="true" focusable="false"><use href="#neu-i-arrowDown"/></svg>8% less than yesterday</p></article>
<article class="grid gap-[.2rem] rounded-neu border-(length:--neu-bw) border-neu-line bg-neu-bg p-5 shadow-neu"><span class="mb-[.6rem] grid size-11 place-items-center rounded-full text-neu-accent shadow-neu-in-sm"><svg class="size-5 shrink-0" aria-hidden="true" focusable="false"><use href="#neu-i-thermo"/></svg></span><p class="text-[.85rem] font-semibold text-neu-muted">Indoor temperature</p><p class="text-[1.9rem] leading-[1.15] font-bold tracking-[-.02em] tabular-nums">21.5<small class="text-[.9rem] font-semibold tracking-normal text-neu-muted"> °C</small></p><p class="mt-[.35rem] flex items-center gap-[.3rem] text-[.82rem] font-semibold text-neu-muted"><svg class="size-4 shrink-0" aria-hidden="true" focusable="false"><use href="#neu-i-drop"/></svg>Humidity 46%</p></article>
<article class="grid gap-[.2rem] rounded-neu border-(length:--neu-bw) border-neu-line bg-neu-bg p-5 shadow-neu"><span class="mb-[.6rem] grid size-11 place-items-center rounded-full text-neu-accent shadow-neu-in-sm"><svg class="size-5 shrink-0" aria-hidden="true" focusable="false"><use href="#neu-i-sun"/></svg></span><p class="text-[.85rem] font-semibold text-neu-muted">Solar output</p><p class="text-[1.9rem] leading-[1.15] font-bold tracking-[-.02em] tabular-nums">3.8<small class="text-[.9rem] font-semibold tracking-normal text-neu-muted"> kW</small></p><p class="mt-[.35rem] flex items-center gap-[.3rem] text-[.82rem] font-semibold text-neu-success"><svg class="size-4 shrink-0" aria-hidden="true" focusable="false"><use href="#neu-i-arrowUp"/></svg>12% above forecast</p></article>
</div></section>
<div class="grid items-start gap-7 min-[761px]:grid-cols-2">
<section><span class="mb-[18px] block text-[.72rem] font-semibold tracking-[.12em] text-neu-muted uppercase">Content card</span><article class="rounded-neu border-(length:--neu-bw) border-neu-line bg-neu-bg text-neu-ink shadow-neu grid gap-[.85rem] p-6"><svg class="mb-[.35rem] block h-auto w-full rounded-[calc(var(--neu-radius)*.7)] border-(length:--neu-bw) border-neu-line shadow-neu-in" viewBox="0 0 320 150" aria-hidden="true" focusable="false">
<rect class="fill-neu-bg" width="320" height="150"/><circle class="fill-neu-accent opacity-[.18]" cx="252" cy="44" r="34"/><circle class="fill-neu-accent opacity-90" cx="252" cy="44" r="18"/>
<path class="fill-none stroke-neu-muted stroke-[2.5] [stroke-linecap:round] [stroke-linejoin:round]" d="M40 124h240M70 124V78l46-34 46 34v46M100 124V98h32v26"/><path class="fill-none stroke-neu-muted stroke-[2.5] [stroke-linecap:round] [stroke-linejoin:round]" d="M206 124V96a10 10 0 0 1 20 0v28M212 86v-8M220 86v-8"/><path class="fill-neu-accent opacity-[.18]" d="M200 72l-12 18h12l-6 16 18-22h-12l6-12z"/></svg>
<span class="inline-flex items-center justify-self-start rounded-full border-(length:--neu-bw) border-neu-line px-3 py-[.3rem] text-[.72rem] font-bold tracking-[.08em] text-neu-accent uppercase shadow-neu-in-sm">Guide</span>
<h3 class="text-[1.2rem] leading-[1.3] font-bold">Cut standby power in a weekend</h3>
<p class="text-neu-muted">Smart plugs, a schedule and one honest look at the meter. Most homes find 40 to 90 kWh a year hiding in idle devices.</p>
<div class="mt-[.2rem] flex flex-wrap items-center justify-between gap-[.6rem] text-[.88rem] text-neu-muted"><span>6 min read · Energy</span><a class="rounded font-semibold text-neu-accent underline underline-offset-3 hover:decoration-2 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-neu-accent" href="#">Read the guide<span class="sr-only">: Cut standby power in a weekend</span></a></div></article></section>
<section><span class="mb-[18px] block text-[.72rem] font-semibold tracking-[.12em] text-neu-muted uppercase">Profile card</span><article class="rounded-neu border-(length:--neu-bw) border-neu-line bg-neu-bg text-neu-ink shadow-neu grid justify-items-center gap-1 p-6 text-center">
<div class="mb-[.9rem] grid size-[104px] place-items-center rounded-full shadow-neu"><span class="grid size-20 place-items-center rounded-full bg-[linear-gradient(135deg,#4f46e5,#0e7490)] text-[1.6rem] font-bold tracking-[.02em] text-white shadow-neu-in-sm" aria-hidden="true">MO</span></div>
<h3 class="text-[1.2rem] font-bold">Mira Osei</h3>
<p class="flex items-center gap-[.3rem] text-[.9rem] text-neu-muted"><svg class="size-4 shrink-0" aria-hidden="true" focusable="false"><use href="#neu-i-pin"/></svg>Home energy coach, Accra</p>
<dl class="mt-[1.1rem] mb-[1.2rem] grid w-full grid-cols-3 rounded-[calc(var(--neu-radius)*.7)] border-(length:--neu-bw) border-neu-line px-2 py-[.9rem] shadow-neu-in-sm"><div class="flex flex-col-reverse"><dt class="text-[.78rem] text-neu-muted">Homes</dt><dd class="text-[1.15rem] font-bold tabular-nums">128</dd></div><div class="flex flex-col-reverse"><dt class="text-[.78rem] text-neu-muted">Rating</dt><dd class="text-[1.15rem] font-bold tabular-nums">4.9</dd></div><div class="flex flex-col-reverse"><dt class="text-[.78rem] text-neu-muted">Years</dt><dd class="text-[1.15rem] font-bold tabular-nums">6</dd></div></dl>
<div class="flex items-center justify-center gap-3.5"><button class="inline-flex items-center justify-center gap-[.55rem] border-(length:--neu-bw) font-semibold leading-[1.2] no-underline cursor-pointer shadow-neu-sm transition-[box-shadow,color,background-color] duration-200 hover:shadow-neu active:shadow-neu-in-sm motion-reduce:transition-none focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-neu-accent min-h-[46px] rounded-neu-btn px-[1.35rem] py-[.65rem] text-[.95rem] border-neu-accent bg-neu-accent text-neu-on-accent" type="button">Follow</button><button class="inline-flex items-center justify-center gap-[.55rem] border-(length:--neu-bw) font-semibold leading-[1.2] no-underline cursor-pointer shadow-neu-sm transition-[box-shadow,color,background-color] duration-200 hover:shadow-neu active:shadow-neu-in-sm motion-reduce:transition-none focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-neu-accent size-[50px] rounded-full border-neu-edge bg-neu-bg text-neu-ink" type="button" aria-label="Message Mira Osei"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#neu-i-message"/></svg></button></div></article></section>
</div>
<section><span class="mb-[18px] block text-[.72rem] font-semibold tracking-[.12em] text-neu-muted uppercase">Pricing cards</span><div class="grid items-start gap-7 min-[761px]:grid-cols-2">
<article class="relative grid content-start gap-2 rounded-neu border-(length:--neu-bw) border-neu-line bg-neu-bg p-7 text-neu-ink shadow-neu"><h3 class="text-[1.05rem] font-bold">Basic</h3>
<p class="text-[.95rem] text-neu-muted"><strong class="text-[2.4rem] font-bold tracking-[-.03em] text-neu-ink">€0</strong> / month</p>
<p class="text-[.85rem] text-neu-muted">Free for one home, forever</p>
<ul class="mt-[.9rem] mb-[1.4rem] grid list-none gap-[.6rem] rounded-[calc(var(--neu-radius)*.7)] border-(length:--neu-bw) border-neu-line px-[1.1rem] py-4 shadow-neu-in-sm"><li class="flex items-center gap-[.6rem] text-[.92rem]"><svg class="size-[18px] shrink-0 text-neu-accent" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="sr-only">Included: </span>Up to 3 rooms</li><li class="flex items-center gap-[.6rem] text-[.92rem]"><svg class="size-[18px] shrink-0 text-neu-accent" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="sr-only">Included: </span>Live energy meter</li><li class="flex items-center gap-[.6rem] text-[.92rem] text-neu-muted"><svg class="size-[18px] shrink-0 text-neu-muted" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="sr-only">Not included: </span>Unlimited rooms and scenes</li><li class="flex items-center gap-[.6rem] text-[.92rem] text-neu-muted"><svg class="size-[18px] shrink-0 text-neu-muted" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="sr-only">Not included: </span>Away mode with geofencing</li><li class="flex items-center gap-[.6rem] text-[.92rem] text-neu-muted"><svg class="size-[18px] shrink-0 text-neu-muted" aria-hidden="true" focusable="false"><use href="#neu-i-x"/></svg><span class="sr-only">Not included: </span>30 days of camera history</li></ul>
<button class="inline-flex items-center justify-center gap-[.55rem] border-(length:--neu-bw) font-semibold leading-[1.2] no-underline cursor-pointer shadow-neu-sm transition-[box-shadow,color,background-color] duration-200 hover:shadow-neu active:shadow-neu-in-sm motion-reduce:transition-none focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-neu-accent min-h-[46px] rounded-neu-btn px-[1.35rem] py-[.65rem] text-[.95rem] border-neu-edge bg-neu-bg text-neu-ink w-full" type="button">Current plan</button></article>
<article class="relative grid content-start gap-2 rounded-neu border-2 border-neu-accent bg-neu-bg p-7 text-neu-ink shadow-neu"><p class="absolute top-5 right-5 rounded-full bg-neu-accent px-3 py-[.3rem] text-[.72rem] font-bold tracking-[.06em] text-neu-on-accent uppercase">Most popular</p><h3 class="text-[1.05rem] font-bold">Plus</h3>
<p class="text-[.95rem] text-neu-muted"><strong class="text-[2.4rem] font-bold tracking-[-.03em] text-neu-ink">€4</strong> / month</p>
<p class="text-[.85rem] text-neu-muted">Billed yearly at €48</p>
<ul class="mt-[.9rem] mb-[1.4rem] grid list-none gap-[.6rem] rounded-[calc(var(--neu-radius)*.7)] border-(length:--neu-bw) border-neu-line px-[1.1rem] py-4 shadow-neu-in-sm"><li class="flex items-center gap-[.6rem] text-[.92rem]"><svg class="size-[18px] shrink-0 text-neu-accent" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="sr-only">Included: </span>Up to 3 rooms</li><li class="flex items-center gap-[.6rem] text-[.92rem]"><svg class="size-[18px] shrink-0 text-neu-accent" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="sr-only">Included: </span>Live energy meter</li><li class="flex items-center gap-[.6rem] text-[.92rem]"><svg class="size-[18px] shrink-0 text-neu-accent" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="sr-only">Included: </span>Unlimited rooms and scenes</li><li class="flex items-center gap-[.6rem] text-[.92rem]"><svg class="size-[18px] shrink-0 text-neu-accent" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="sr-only">Included: </span>Away mode with geofencing</li><li class="flex items-center gap-[.6rem] text-[.92rem]"><svg class="size-[18px] shrink-0 text-neu-accent" aria-hidden="true" focusable="false"><use href="#neu-i-check"/></svg><span class="sr-only">Included: </span>30 days of camera history</li></ul>
<button class="inline-flex items-center justify-center gap-[.55rem] border-(length:--neu-bw) font-semibold leading-[1.2] no-underline cursor-pointer shadow-neu-sm transition-[box-shadow,color,background-color] duration-200 hover:shadow-neu active:shadow-neu-in-sm motion-reduce:transition-none focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-neu-accent min-h-[46px] rounded-neu-btn px-[1.35rem] py-[.65rem] text-[.95rem] border-neu-accent bg-neu-accent text-neu-on-accent w-full" type="button">Upgrade to Plus</button></article>
</div></section>
CSS
/* ── Neumorphism UI kit tokens (uiCookies) — identical in every set ──────────────
   Every component is moulded from --neu-bg and lit from the top left. Change a token and
   the whole kit follows; the shadow recipes below are built from these values. */
:root{
  --neu-bg:#e0e5ec;          /* the one surface colour */
  --neu-light:#ffffff;       /* highlight, top left */
  --neu-dark:#a3b1c6;        /* shade, bottom right */
  --neu-distance:6px;        /* how far a shape rises */
  --neu-blur:14px;           /* how soft its shadow is */
  --neu-radius:18px;         /* cards; buttons use .75 of it, fields .6 */
  --neu-accent:#4f46e5;      /* focus ring and on / selected / current states, 4.9:1 on --neu-bg */
  --neu-on-accent:#ffffff;   /* text and marks on accent fills, 6.3:1 */
  --neu-ink:#1f2937;         /* text, 11.6:1 */
  --neu-muted:#4a5568;       /* secondary text, 5.9:1 */
  --neu-edge:#74819a;        /* control boundary (fields, tracks, boxes, buttons), 3.1:1 */
  --neu-line:rgba(255,255,255,.6); /* decorative edge on cards and panels */
  --neu-bw:1px;              /* control border width */
  --neu-success:#126b35;--neu-warning:#8a5300;--neu-danger:#b42318;
}
/* Dark neumorphism: data-neu="dark" on any wrapper, or a checked .neu-theme-input inside a [data-neu] element.
   :is() is a forgiving list, so browsers without :has() still apply data-neu="dark" */
[data-neu]:is([data-neu="dark"],:has(.neu-theme-input:checked)){
  --neu-bg:#262b33;--neu-light:#323944;--neu-dark:#14171c;
  --neu-accent:#8f88ff;--neu-on-accent:#14161b;--neu-ink:#e7ebf2;--neu-muted:#aab4c3;--neu-edge:#717d90;
  --neu-line:rgba(255,255,255,.06);--neu-success:#6fdc9a;--neu-warning:#f3c164;--neu-danger:#ff8f84;color-scheme:dark}
/* More contrast requested: the soft shadows go, every control and panel gets a solid outline */
@media (prefers-contrast:more){:root,[data-neu]:is([data-neu],:has(.neu-theme-input:checked)){
  --neu-light:transparent;--neu-dark:transparent;--neu-edge:var(--neu-ink);--neu-line:var(--neu-ink);--neu-muted:var(--neu-ink);--neu-bw:2px}}
:root,[data-neu]{
  --neu-raised:var(--neu-distance) var(--neu-distance) var(--neu-blur) var(--neu-dark),calc(var(--neu-distance)*-1) calc(var(--neu-distance)*-1) var(--neu-blur) var(--neu-light);
  --neu-raised-sm:calc(var(--neu-distance)*.5) calc(var(--neu-distance)*.5) calc(var(--neu-blur)*.5) var(--neu-dark),calc(var(--neu-distance)*-.5) calc(var(--neu-distance)*-.5) calc(var(--neu-blur)*.5) var(--neu-light);
  --neu-inset:inset calc(var(--neu-distance)*.6) calc(var(--neu-distance)*.6) calc(var(--neu-blur)*.6) var(--neu-dark),inset calc(var(--neu-distance)*-.6) calc(var(--neu-distance)*-.6) calc(var(--neu-blur)*.6) var(--neu-light);
  --neu-inset-sm:inset calc(var(--neu-distance)*.35) calc(var(--neu-distance)*.35) calc(var(--neu-blur)*.35) var(--neu-dark),inset calc(var(--neu-distance)*-.35) calc(var(--neu-distance)*-.35) calc(var(--neu-blur)*.35) var(--neu-light);
}
[data-neu]{background:var(--neu-bg);color:var(--neu-ink)}
/* The tokens above, exposed as Tailwind utilities: bg-neu-bg, text-neu-muted, border-neu-edge,
   shadow-neu, shadow-neu-sm, shadow-neu-in, shadow-neu-in-sm, rounded-neu, rounded-neu-btn, rounded-neu-field… */
@theme inline {
  --color-neu-bg: var(--neu-bg); --color-neu-ink: var(--neu-ink); --color-neu-muted: var(--neu-muted);
  --color-neu-edge: var(--neu-edge); --color-neu-line: var(--neu-line);
  --color-neu-accent: var(--neu-accent); --color-neu-on-accent: var(--neu-on-accent);
  --color-neu-success: var(--neu-success); --color-neu-warning: var(--neu-warning); --color-neu-danger: var(--neu-danger);
  --shadow-neu: var(--neu-raised); --shadow-neu-sm: var(--neu-raised-sm);
  --shadow-neu-in: var(--neu-inset); --shadow-neu-in-sm: var(--neu-inset-sm);
  --radius-neu: var(--neu-radius); --radius-neu-btn: calc(var(--neu-radius) * .75); --radius-neu-field: calc(var(--neu-radius) * .6);
}

About this set

Four kinds of card in one soft style. Stat tiles show energy use, indoor temperature and solar output, each with an icon in a pressed well, a large value with its unit, and a change line that says less than yesterday or above forecast in words beside its arrow. A content card sets a line illustration of a house in an inset frame above a category chip, a title, an excerpt and a read-the-guide link. A profile card holds initials in a raised ring, a name and role, three stats in a pressed strip built as a description list, and Follow and Message actions. Two pricing cards compare a free and a paid plan; the recommended one has an accent edge and a visible Most popular badge, and each feature line says Included or Not included to screen readers. Use the stat tiles at the top of a dashboard, the content card for articles or guides, and the pricing pair on an upgrade page. Cards are raised panels with a faint highlight edge, which turns into a solid outline when more contrast is requested.

What’s included

  • Stat tiles whose change is written in words, not only shown by colour
  • Content card with an inline SVG illustration and a named link
  • Profile card with stats as a description list
  • Pricing cards with a text badge and Included or Not included labels
  • Bootstrap version built on .card, .badge and the grid

Accessibility

Headings, lists and a description list give the cards structure. The illustration is decorative and hidden from screen readers, the guide link includes the article title in hidden text, and the icon-only message button has an aria-label. Buttons and links show a 3px accent focus ring. Button transitions stop under prefers-reduced-motion and prefers-contrast: more outlines every card.

Customise it

Change the --neu-* tokens for the surface, depth and accent, and --neu-success for the positive change lines. In Bootstrap the cards are .card.neu-card with --bs-card-* mapped to the tokens; in Tailwind use rounded-neu, shadow-neu and border-neu-line.