Open demo

CSS code

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="clay-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="clay-i-volume" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M4 9.5h3.5L12 5.5v13l-4.5-4H4z"/><path d="M15.5 9a4 4 0 0 1 0 6M18 6.5a7.5 7.5 0 0 1 0 11"/></symbol>
  <symbol id="clay-i-trophy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8v5a4 4 0 0 1-8 0zM8 6H4.5a3.5 3.5 0 0 0 3.8 3.5M16 6h3.5a3.5 3.5 0 0 1-3.8 3.5M12 13v4M8.5 20.5h7M10 17h4"/></symbol>
  <symbol id="clay-i-chevDown" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9.5 6 6 6-6"/></symbol>
  <symbol id="clay-i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.8h.01"/></symbol>
  <symbol id="clay-i-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4 2.8 19.5h18.4z"/><path d="M12 10v4.5M12 17.2h.01"/></symbol>
  <symbol id="clay-i-error" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9 9l6 6M15 9l-6 6"/></symbol>
  <symbol id="clay-i-success" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="m8 12.3 2.7 2.7L16 9.6"/></symbol>
  <symbol id="clay-i-share" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5.5" r="2.5"/><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="18.5" r="2.5"/><path d="m8.2 10.8 7.6-4.1M8.2 13.2l7.6 4.1"/></symbol>
  <symbol id="clay-i-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><rect x="8" y="8" width="12" height="12" rx="3"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></symbol>
  <symbol id="clay-i-flag" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 21V4M5 4h11l-2 4 2 4H5"/></symbol>
  <symbol id="clay-i-logout" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M14 4h4.5a1.5 1.5 0 0 1 1.5 1.5v13a1.5 1.5 0 0 1-1.5 1.5H14M10 16.5 5.5 12 10 7.5M5.5 12H16"/></symbol>
  <symbol id="clay-i-spark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2.5 2.5M15.5 15.5 18 18M6 18l2.5-2.5M15.5 8.5 18 6"/></symbol>
  <symbol id="clay-i-download" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4v11M7 10.5l5 5 5-5M5 20h14"/></symbol>
</svg>
<section><span class="lbl">Alerts · the type is a word and an icon, not just a colour</span><div class="clay-alerts">
<div class="clay-alert clay-sky" role="note"><span class="clay-alert__icon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-info"/></svg></span><div><p class="clay-alert__title"><span class="clay-sr">Information: </span>Tip of the day</p><p class="clay-alert__text">Tap any word in a story to hear it read slowly.</p></div></div>
<div class="clay-alert clay-mint" role="note"><span class="clay-alert__icon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-success"/></svg></span><div><p class="clay-alert__title"><span class="clay-sr">Success: </span>Progress saved</p><p class="clay-alert__text">Juniper finished Counting in fives with 9 of 10 right.</p></div></div>
<div class="clay-alert clay-lemon" role="note"><span class="clay-alert__icon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-alert"/></svg></span><div><p class="clay-alert__title"><span class="clay-sr">Warning: </span>5 minutes of screen time left</p><p class="clay-alert__text">The app will suggest a break at 5:15 pm.</p></div></div>
<div class="clay-alert clay-peach" role="alert"><span class="clay-alert__icon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-error"/></svg></span><div><p class="clay-alert__title"><span class="clay-sr">Error: </span>Drawing did not upload</p><p class="clay-alert__text">Check the Wi-Fi and press Try again. Your drawing is kept on this tablet.</p></div></div>
</div></section>
<div class="clay-row">
<section><span class="lbl">Toasts · polite live region</span><div class="clay-toasts" role="status" aria-live="polite">
<div class="clay-toast" data-clay-toast><span class="clay-blob clay-lemon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-trophy"/></svg></span><div class="clay-toast__body"><p class="clay-toast__title">Badge unlocked: Bookworm</p><p class="clay-toast__text">5 stories read this week</p></div><button class="clay-iconbtn clay-iconbtn--sm" type="button" aria-label="Close notification" data-clay-dismiss><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-x"/></svg></button></div>
<div class="clay-toast" data-clay-toast><span class="clay-blob clay-mint"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-download"/></svg></span><div class="clay-toast__body"><p class="clay-toast__title">Saved for the car trip</p><p class="clay-toast__text">3 lessons work offline now</p></div><button class="clay-iconbtn clay-iconbtn--sm" type="button" aria-label="Close notification" data-clay-dismiss><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-x"/></svg></button></div>
</div></section>
<section><span class="lbl">Dialog, dropdown and tooltips</span><div class="clay-stack">
<div class="clay-cluster">
<button class="clay-btn clay-peach" type="button" data-clay-open="leave-dialog"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-logout"/></svg>Leave lesson</button>
<div class="clay-dd"><button class="clay-btn clay-sky" type="button" aria-expanded="false" aria-controls="lesson-menu" data-clay-dropdown>Lesson options<svg class="clay-ico clay-dd__chev" aria-hidden="true" focusable="false"><use href="#clay-i-chevDown"/></svg></button>
<ul class="clay-dd__menu" id="lesson-menu" hidden>
<li><a class="clay-dd__item" href="#"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-download"/></svg>Save for offline</a></li>
<li><a class="clay-dd__item" href="#"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-share"/></svg>Share with a parent</a></li>
<li><a class="clay-dd__item" href="#"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-copy"/></svg>Copy lesson link</a></li>
<li class="clay-dd__sep" role="presentation"></li>
<li><a class="clay-dd__item clay-dd__item--danger" href="#"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-flag"/></svg>Report a problem</a></li>
</ul></div>
</div>
<div class="clay-cluster">
<span class="clay-tip" data-clay-tip><button class="clay-iconbtn clay-mint" type="button" aria-label="Hint" aria-describedby="tip-hint"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-spark"/></svg></button><span class="clay-tip__bubble" role="tooltip" id="tip-hint">Costs 5 stars</span></span>
<span class="clay-tip" data-clay-tip><button class="clay-iconbtn clay-lemon" type="button" aria-label="Read aloud" aria-describedby="tip-read"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-volume"/></svg></button><span class="clay-tip__bubble" role="tooltip" id="tip-read">Plays the page at story speed</span></span>
<span class="clay-tip" data-clay-tip><button class="clay-iconbtn clay-lilac" type="button" aria-label="Help" aria-describedby="tip-help"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-info"/></svg></button><span class="clay-tip__bubble" role="tooltip" id="tip-help">Ask a grown-up for help</span></span>
</div>
</div></section>
</div>
<dialog class="clay-dialog" id="leave-dialog" aria-labelledby="leave-title" aria-describedby="leave-text">
<div class="clay-dialog__icon"><svg class="clay-ico clay-ico--lg" aria-hidden="true" focusable="false"><use href="#clay-i-flag"/></svg></div>
<h2 class="clay-dialog__title" id="leave-title">Leave this lesson?</h2>
<p class="clay-dialog__text" id="leave-text">You are on step 4 of 5. We will keep your stars, and you can finish the last step tomorrow.</p>
<form class="clay-dialog__actions" method="dialog"><button class="clay-btn" value="leave">Leave for now</button><button class="clay-btn clay-btn--accent" value="stay" autofocus>Keep learning</button></form>
</dialog>
CSS
/* ── Claymorphism UI kit tokens (uiCookies) — identical in every set ──────────────
   Every component is a puffy pastel object floating above --clay-bg: one big soft drop shadow
   below it, an inset highlight top left and an inset shade bottom right. Change a token and
   the whole kit follows; the shadow recipes below are built from these values. */
:root{
  --clay-bg:#f3effa;          /* page, a pale lilac white */
  --clay-surface:#fffcf8;     /* cards, fields and plain objects */
  --clay-peach:#ffd2bd;       /* object fills: ink text on every fill reaches 11:1 */
  --clay-lilac:#dccdff;
  --clay-mint:#bdeed6;
  --clay-sky:#c2e0ff;
  --clay-lemon:#ffe9a3;
  --clay-ink:#241a3d;         /* text, 14.4:1 on --clay-bg */
  --clay-muted:#51476a;       /* secondary text, 5.7:1 or more on every fill */
  --clay-edge:#7a6e96;        /* control boundary, 4.1:1 on --clay-bg, so shadows are never the only edge */
  --clay-line:rgba(36,26,61,.12); /* decorative edge on cards and panels */
  --clay-accent:#6236e8;      /* focus ring and on / selected / current states, 5.8:1 on --clay-bg */
  --clay-on-accent:#ffffff;   /* text and marks on accent fills, 6.5:1 */
  --clay-tint:#e9e1ff;        /* light accent wash behind current items */
  --clay-drop:rgba(86,56,168,.30); /* colour of the outer drop shadow */
  --clay-hi:rgba(255,255,255,.88);  /* inset highlight, top left */
  --clay-lo:rgba(52,30,112,.20);    /* inset shade, bottom right */
  --clay-lift:14px;           /* how high objects float; every shadow scales from it */
  --clay-radius:30px;         /* cards; buttons are pills, fields use .55 of it */
  --clay-bw:1.5px;            /* control border width */
  --clay-success:#17663d;--clay-warning:#8a4b00;--clay-danger:#b3261e;
  --clay-font:ui-rounded,"SF Pro Rounded","Nunito","Quicksand","Varela Round","Arial Rounded MT Bold",system-ui,sans-serif;
}
/* --clay-fill is set by .clay-peach, .clay-mint… on one object and must not leak into its children */
@property --clay-fill{syntax:"*";inherits:false}
/* Dark clay: data-clay="dark" on any wrapper, or a checked .clay-theme-input inside a [data-clay] element.
   :is() is a forgiving list, so browsers without :has() still apply data-clay="dark" */
[data-clay]:is([data-clay="dark"],:has(.clay-theme-input:checked)){
  --clay-bg:#1a1530;--clay-surface:#2a2347;
  --clay-peach:#6e3f33;--clay-lilac:#4a3a8a;--clay-mint:#215a4a;--clay-sky:#26497c;--clay-lemon:#5f5220;
  --clay-ink:#f7f3ff;--clay-muted:#d2c9ea;--clay-edge:#8f83b8;--clay-line:rgba(255,255,255,.1);
  --clay-accent:#bba6ff;--clay-on-accent:#1a1530;--clay-tint:#3a2f66;
  --clay-drop:rgba(4,2,14,.62);--clay-hi:rgba(255,255,255,.2);--clay-lo:rgba(0,0,0,.34);
  --clay-success:#86e3b0;--clay-warning:#ffc76e;--clay-danger:#ffa196;color-scheme:dark}
/* More contrast requested: soft shading stays, but every edge and secondary text turns full ink */
@media (prefers-contrast:more){:root,[data-clay]:is([data-clay],:has(.clay-theme-input:checked)){
  --clay-edge:var(--clay-ink);--clay-line:var(--clay-ink);--clay-muted:var(--clay-ink);--clay-bw:2px}}
:root,[data-clay]{
  --clay-shadow:0 var(--clay-lift) calc(var(--clay-lift)*2.2) calc(var(--clay-lift)*-.3) var(--clay-drop),
    inset calc(var(--clay-lift)*.45) calc(var(--clay-lift)*.5) calc(var(--clay-lift)*.9) var(--clay-hi),
    inset calc(var(--clay-lift)*-.45) calc(var(--clay-lift)*-.6) calc(var(--clay-lift)*.9) var(--clay-lo);
  --clay-shadow-sm:0 calc(var(--clay-lift)*.55) calc(var(--clay-lift)*1.2) calc(var(--clay-lift)*-.15) var(--clay-drop),
    inset calc(var(--clay-lift)*.25) calc(var(--clay-lift)*.3) calc(var(--clay-lift)*.5) var(--clay-hi),
    inset calc(var(--clay-lift)*-.25) calc(var(--clay-lift)*-.35) calc(var(--clay-lift)*.5) var(--clay-lo);
  --clay-press:0 calc(var(--clay-lift)*.12) calc(var(--clay-lift)*.25) 0 var(--clay-drop),
    inset calc(var(--clay-lift)*.2) calc(var(--clay-lift)*.25) calc(var(--clay-lift)*.45) var(--clay-lo),
    inset calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*.3) var(--clay-hi);
  --clay-well:inset calc(var(--clay-lift)*.15) calc(var(--clay-lift)*.22) calc(var(--clay-lift)*.45) var(--clay-lo),
    inset calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*.3) var(--clay-hi);
}
[data-clay]{background:var(--clay-bg);color:var(--clay-ink)}
/* Components */
:where([class*="clay-"]),:where([class*="clay-"])::before,:where([class*="clay-"])::after{box-sizing:border-box}
.clay-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.clay-ico{width:22px;height:22px;flex:none}
.clay-ico--lg{width:28px;height:28px}
/* Fills: put one on any object; components read --clay-fill */
.clay-peach{--clay-fill:var(--clay-peach)}.clay-lilac{--clay-fill:var(--clay-lilac)}.clay-mint{--clay-fill:var(--clay-mint)}
.clay-sky{--clay-fill:var(--clay-sky)}.clay-lemon{--clay-fill:var(--clay-lemon)}
/* Card: a puffy panel that floats on the big drop shadow */
.clay-card{margin:0;padding:1.6rem;border:var(--clay-bw) solid var(--clay-line);border-radius:var(--clay-radius);
  background:var(--clay-fill,var(--clay-surface));color:var(--clay-ink);box-shadow:var(--clay-shadow)}
/* Layout helpers */
.clay-cluster{display:flex;flex-wrap:wrap;align-items:center;gap:18px}
.clay-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:22px}
.clay-stack{display:grid;gap:1.4rem}
/* Buttons: pastel pills that float; hover lifts them, pressing squashes the shadow flat */
.clay-btn{display:inline-flex;align-items:center;justify-content:center;gap:.55rem;min-height:50px;margin:0;padding:.7rem 1.5rem;
  border:var(--clay-bw) solid var(--clay-edge);border-radius:999px;background:var(--clay-fill,var(--clay-surface));color:var(--clay-ink);
  font-family:inherit;font-size:1rem;font-weight:800;line-height:1.2;text-decoration:none;cursor:pointer;
  box-shadow:var(--clay-shadow-sm);transition:transform .18s,box-shadow .18s}
.clay-btn:hover{transform:translateY(-2px);box-shadow:var(--clay-shadow)}
.clay-btn:active{transform:translateY(2px);box-shadow:var(--clay-press)}
.clay-btn:focus-visible{outline:3px solid var(--clay-accent);outline-offset:4px}
.clay-btn--accent{--clay-fill:var(--clay-accent);border-color:var(--clay-accent);color:var(--clay-on-accent)}
.clay-btn--sm{min-height:40px;padding:.45rem 1.05rem;font-size:.88rem}
.clay-btn--block{width:100%}
/* Icon buttons: round (or squircle) clay pebbles with a chunky icon and an aria-label */
.clay-iconbtn{display:inline-grid;place-items:center;width:58px;height:58px;margin:0;padding:0;border:var(--clay-bw) solid var(--clay-edge);border-radius:50%;
  background:var(--clay-fill,var(--clay-surface));color:var(--clay-ink);cursor:pointer;box-shadow:var(--clay-shadow-sm);transition:transform .18s,box-shadow .18s}
.clay-iconbtn:hover{transform:translateY(-2px);box-shadow:var(--clay-shadow)}
.clay-iconbtn:active{transform:translateY(2px);box-shadow:var(--clay-press)}
.clay-iconbtn:focus-visible{outline:3px solid var(--clay-accent);outline-offset:4px}
.clay-iconbtn--sq{border-radius:20px}
.clay-iconbtn--sm{width:44px;height:44px}
.clay-iconbtn--lg{width:72px;height:72px}
.clay-iconbtn--accent{--clay-fill:var(--clay-accent);border-color:var(--clay-accent);color:var(--clay-on-accent)}
@media (prefers-reduced-motion:reduce){.clay-btn,.clay-iconbtn{transition:none}.clay-btn:hover,.clay-btn:active,.clay-iconbtn:hover,.clay-iconbtn:active{transform:none}}
/* Blob: a small puffy icon tile that sits on any card */
.clay-blob{display:grid;place-items:center;flex:none;width:52px;height:52px;border:var(--clay-bw) solid var(--clay-line);border-radius:18px;
  background:var(--clay-fill,var(--clay-surface));color:var(--clay-ink);box-shadow:var(--clay-shadow-sm)}
.clay-chip{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .75rem;border:var(--clay-bw) solid var(--clay-line);border-radius:999px;
  background:var(--clay-surface);color:var(--clay-ink);font-size:.8rem;font-weight:800;line-height:1.3}
.clay-chip .clay-ico{width:16px;height:16px}
/* Stat cards: coloured clay slabs with a blob icon, a big number and a sentence that explains the change */
.clay-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:24px}
.clay-stat{display:grid;gap:.25rem;align-content:start}
.clay-stat__label{margin:.85rem 0 0;font-size:.9rem;font-weight:800;color:var(--clay-muted)}
.clay-stat__value{margin:0;font-size:2.2rem;font-weight:800;line-height:1.1;letter-spacing:-.01em}
.clay-stat__unit{font-size:1rem;font-weight:700}
.clay-stat__note{margin:0;font-size:.86rem;font-weight:600;color:var(--clay-muted)}
/* Content card: an illustration panel made of clay shapes, a chip, a title and a progress line */
.clay-lesson{display:flex;flex-direction:column;gap:1rem;padding:1rem 1rem 1.4rem}
.clay-art{position:relative;height:170px;overflow:hidden;border-radius:calc(var(--clay-radius)*.75);background:var(--clay-sky);box-shadow:var(--clay-well)}
.clay-art__shape{position:absolute;border-radius:50%;box-shadow:var(--clay-shadow-sm)}
.clay-art__shape--sun{top:22px;right:34px;width:58px;height:58px;background:var(--clay-lemon)}
.clay-art__shape--cloud{top:52px;left:40px;width:140px;height:54px;border-radius:999px;background:var(--clay-surface)}
.clay-art__shape--cloud2{top:30px;left:78px;width:70px;height:60px;background:var(--clay-surface)}
.clay-art__shape--hill{bottom:-70px;left:-20px;width:240px;height:140px;background:var(--clay-mint)}
.clay-art__shape--hill2{bottom:-90px;right:-40px;width:260px;height:150px;background:var(--clay-peach)}
.clay-art__shape--drop{top:116px;width:14px;height:20px;border-radius:50% 50% 50% 50%/60% 60% 40% 40%;background:var(--clay-accent);box-shadow:none}
.clay-lesson__body{display:grid;gap:.55rem;padding:0 .5rem}
.clay-lesson__tag{margin:0}
.clay-lesson__title{margin:0;font-size:1.3rem;font-weight:800;line-height:1.25}
.clay-lesson__text{margin:0;color:var(--clay-muted)}
.clay-lesson__foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1rem;padding:0 .5rem}
.clay-meter{display:grid;gap:.35rem;flex:1;min-width:140px;font-size:.84rem;font-weight:700;color:var(--clay-muted)}
.clay-meter__bar{height:14px;border:var(--clay-bw) solid var(--clay-edge);border-radius:999px;background:var(--clay-bg);box-shadow:var(--clay-well);overflow:hidden}
.clay-meter__fill{display:block;height:100%;width:var(--clay-pct,50%);border-radius:999px;background:var(--clay-accent)}
/* Profile card */
.clay-profile{display:grid;justify-items:center;gap:.4rem;text-align:center}
.clay-avatar{display:grid;place-items:center;width:96px;height:96px;margin-bottom:.6rem;border:var(--clay-bw) solid var(--clay-line);border-radius:50%;
  background:var(--clay-fill,var(--clay-lilac));font-size:2rem;font-weight:800;box-shadow:var(--clay-shadow)}
.clay-profile__name{margin:0;font-size:1.3rem;font-weight:800;line-height:1.25}
.clay-profile__role{margin:0;color:var(--clay-muted)}
.clay-profile__stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;width:100%;margin:.9rem 0 1.1rem;padding:0;list-style:none}
.clay-profile__stat{display:grid;padding:.6rem .3rem;border-radius:18px;background:var(--clay-fill,var(--clay-bg));box-shadow:var(--clay-well)}
.clay-profile__num{font-size:1.25rem;font-weight:800;line-height:1.2}
.clay-profile__key{font-size:.78rem;font-weight:700;color:var(--clay-muted)}
.clay-profile__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:12px}
/* Pricing pair */
.clay-plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:28px;align-items:start}
.clay-plan{position:relative;display:grid;gap:.9rem}
.clay-plan__badge{position:absolute;top:-14px;right:24px;padding:.3rem .85rem;border:var(--clay-bw) solid var(--clay-accent);border-radius:999px;
  background:var(--clay-accent);color:var(--clay-on-accent);font-size:.78rem;font-weight:800;box-shadow:var(--clay-shadow-sm)}
.clay-plan__name{margin:0;font-size:1.15rem;font-weight:800}
.clay-plan__price{margin:0;font-size:2.6rem;font-weight:800;line-height:1}
.clay-plan__per{font-size:1rem;font-weight:700;color:var(--clay-muted)}
.clay-plan__desc{margin:0;color:var(--clay-muted)}
.clay-plan__list{display:grid;gap:.6rem;margin:.2rem 0 .4rem;padding:0;list-style:none}
.clay-plan__item{display:flex;align-items:center;gap:.6rem;font-weight:600}
.clay-plan__tick{display:grid;place-items:center;flex:none;width:26px;height:26px;border-radius:50%;background:var(--clay-fill,var(--clay-surface));box-shadow:var(--clay-shadow-sm)}
.clay-plan__tick .clay-ico{width:16px;height:16px}
.clay-two{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:28px;align-items:start}
@media (max-width:767px){.clay-two{grid-template-columns:1fr}}
.clay-stats--two{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
/* Alerts: coloured clay slabs that name their type in a word, an icon and hidden text, not only in colour */
.clay-alerts{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,380px),1fr));gap:22px}
.clay-alert{display:flex;align-items:flex-start;gap:1rem;padding:1.1rem 1.2rem;border:var(--clay-bw) solid var(--clay-line);border-radius:calc(var(--clay-radius)*.8);
  background:var(--clay-fill,var(--clay-surface));color:var(--clay-ink);box-shadow:var(--clay-shadow)}
.clay-alert__icon{display:grid;place-items:center;flex:none;width:44px;height:44px;border-radius:15px;background:var(--clay-surface);box-shadow:var(--clay-shadow-sm)}
.clay-alert__title{margin:0;font-weight:800;line-height:1.3}
.clay-alert__text{margin:.15rem 0 0;font-size:.92rem;color:var(--clay-muted)}
/* Toasts: a polite live region; each toast is a floating pebble with a close button */
.clay-toasts{display:grid;gap:16px;max-width:420px}
.clay-toast{display:flex;align-items:center;gap:.9rem;padding:.8rem .8rem .8rem 1rem;border:var(--clay-bw) solid var(--clay-line);border-radius:24px;
  background:var(--clay-surface);color:var(--clay-ink);box-shadow:var(--clay-shadow)}
.clay-toast[hidden]{display:none}
.clay-toast__body{flex:1;min-width:0}
.clay-toast__title{margin:0;font-weight:800;line-height:1.3}
.clay-toast__text{margin:0;font-size:.88rem;color:var(--clay-muted)}
/* Tooltips: shown on hover and keyboard focus, dismissed with Escape, tied to the button with aria-describedby */
.clay-tip{position:relative;display:inline-flex}
.clay-tip__bubble{position:absolute;bottom:calc(100% + 12px);left:50%;z-index:5;width:max-content;max-width:220px;padding:.5rem .8rem;border:var(--clay-bw) solid var(--clay-ink);
  border-radius:14px;background:var(--clay-ink);color:var(--clay-bg);font-size:.84rem;font-weight:700;line-height:1.35;text-align:center;
  box-shadow:var(--clay-shadow-sm);opacity:0;visibility:hidden;transform:translate(-50%,6px);transition:opacity .18s,transform .18s,visibility .18s;pointer-events:none}
.clay-tip__bubble::after{content:"";position:absolute;top:100%;left:50%;margin-left:-7px;border:7px solid transparent;border-top-color:var(--clay-ink)}
.clay-tip:hover .clay-tip__bubble,.clay-tip:focus-within .clay-tip__bubble{opacity:1;visibility:visible;transform:translate(-50%,0)}
.clay-tip.is-dismissed .clay-tip__bubble{opacity:0;visibility:hidden}
/* Dropdown: a button with aria-expanded and a floating clay menu */
.clay-dd{position:relative;display:inline-block}
.clay-dd__chev{transition:transform .18s}
.clay-dd [aria-expanded="true"] .clay-dd__chev{transform:rotate(180deg)}
.clay-dd__menu{position:absolute;top:calc(100% + 12px);left:0;z-index:10;min-width:250px;margin:0;padding:.5rem;list-style:none;border:var(--clay-bw) solid var(--clay-line);
  border-radius:22px;background:var(--clay-surface);box-shadow:var(--clay-shadow)}
.clay-dd__menu[hidden]{display:none}
.clay-dd__item{display:flex;align-items:center;gap:.7rem;width:100%;min-height:46px;padding:.45rem .7rem;border:0;border-radius:15px;background:transparent;
  color:var(--clay-ink);font-family:inherit;font-size:.95rem;font-weight:700;text-align:left;text-decoration:none;cursor:pointer}
.clay-dd__item:hover{background:var(--clay-bg)}
.clay-dd__item:focus-visible{outline:3px solid var(--clay-accent);outline-offset:-3px}
.clay-dd__item--danger{color:var(--clay-danger)}
.clay-dd__sep{height:0;margin:.35rem .5rem;border-top:var(--clay-bw) solid var(--clay-line)}
/* Dialog: native <dialog> opened with showModal(), so focus is trapped and Escape closes it */
.clay-dialog{width:min(440px,calc(100% - 32px));margin:auto;padding:1.8rem;border:var(--clay-bw) solid var(--clay-line);border-radius:var(--clay-radius);
  background:var(--clay-surface);color:var(--clay-ink);box-shadow:var(--clay-shadow);text-align:center}
.clay-dialog::backdrop{background:rgba(36,26,61,.45)}
.clay-dialog[open]{animation:clay-pop .25s ease-out}
@keyframes clay-pop{from{transform:scale(.92);opacity:0}}
.clay-dialog__icon{display:grid;place-items:center;width:70px;height:70px;margin:0 auto 1rem;border-radius:24px;background:var(--clay-peach);box-shadow:var(--clay-shadow-sm)}
.clay-dialog__title{margin:0;font-size:1.35rem;font-weight:800;line-height:1.25}
.clay-dialog__text{margin:.5rem 0 1.4rem;color:var(--clay-muted)}
.clay-dialog__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin:0}
.clay-row{display:flex;flex-wrap:wrap;align-items:flex-start;gap:56px}
.clay-row>section{flex:1 1 280px;min-width:0}
@media (prefers-reduced-motion:reduce){.clay-tip__bubble,.clay-dd__chev{transition:none}.clay-dialog[open]{animation:none}}
JavaScript
// Dialog: any button with data-clay-open="dialog-id" opens that <dialog>; focus returns to the button on close
document.querySelectorAll('[data-clay-open]').forEach(function (btn) {
  var dialog = document.getElementById(btn.getAttribute('data-clay-open'));
  if (!dialog) return;
  btn.addEventListener('click', function () {
    dialog.showModal();
    dialog.addEventListener('close', function () { btn.focus(); }, { once: true });
  });
  dialog.addEventListener('click', function (e) { if (e.target === dialog) dialog.close(); }); // backdrop click
});
// Tooltips: Escape hides the visible tooltip until the pointer or focus leaves it
document.addEventListener('keydown', function (e) {
  if (e.key !== 'Escape') return;
  document.querySelectorAll('[data-clay-tip]').forEach(function (t) { if (t.matches(':hover, :focus-within')) t.classList.add('is-dismissed'); });
});
document.querySelectorAll('[data-clay-tip]').forEach(function (t) {
  ['mouseleave', 'focusout'].forEach(function (ev) { t.addEventListener(ev, function () { t.classList.remove('is-dismissed'); }); });
});
// Toasts: a close button hides its toast
document.querySelectorAll('[data-clay-dismiss]').forEach(function (b) {
  b.addEventListener('click', function () { b.closest('[data-clay-toast]').hidden = true; });
});
// Dropdown: toggle on click; Escape (focus back to the button) or a click outside closes it
document.querySelectorAll('[data-clay-dropdown]').forEach(function (btn) {
  var menu = document.getElementById(btn.getAttribute('aria-controls'));
  function set(open) { btn.setAttribute('aria-expanded', open); menu.hidden = !open; }
  btn.addEventListener('click', function () { set(btn.getAttribute('aria-expanded') !== 'true'); });
  document.addEventListener('click', function (e) { if (!btn.parentNode.contains(e.target)) set(false); });
  btn.parentNode.addEventListener('keydown', function (e) { if (e.key === 'Escape' && btn.getAttribute('aria-expanded') === 'true') { set(false); btn.focus(); } });
});

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS, Bootstrap 5.3.8 JS bundle

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="clay-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="clay-i-volume" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M4 9.5h3.5L12 5.5v13l-4.5-4H4z"/><path d="M15.5 9a4 4 0 0 1 0 6M18 6.5a7.5 7.5 0 0 1 0 11"/></symbol>
  <symbol id="clay-i-trophy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8v5a4 4 0 0 1-8 0zM8 6H4.5a3.5 3.5 0 0 0 3.8 3.5M16 6h3.5a3.5 3.5 0 0 1-3.8 3.5M12 13v4M8.5 20.5h7M10 17h4"/></symbol>
  <symbol id="clay-i-chevDown" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9.5 6 6 6-6"/></symbol>
  <symbol id="clay-i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.8h.01"/></symbol>
  <symbol id="clay-i-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4 2.8 19.5h18.4z"/><path d="M12 10v4.5M12 17.2h.01"/></symbol>
  <symbol id="clay-i-error" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9 9l6 6M15 9l-6 6"/></symbol>
  <symbol id="clay-i-success" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="m8 12.3 2.7 2.7L16 9.6"/></symbol>
  <symbol id="clay-i-share" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5.5" r="2.5"/><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="18.5" r="2.5"/><path d="m8.2 10.8 7.6-4.1M8.2 13.2l7.6 4.1"/></symbol>
  <symbol id="clay-i-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><rect x="8" y="8" width="12" height="12" rx="3"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></symbol>
  <symbol id="clay-i-flag" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 21V4M5 4h11l-2 4 2 4H5"/></symbol>
  <symbol id="clay-i-logout" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M14 4h4.5a1.5 1.5 0 0 1 1.5 1.5v13a1.5 1.5 0 0 1-1.5 1.5H14M10 16.5 5.5 12 10 7.5M5.5 12H16"/></symbol>
  <symbol id="clay-i-spark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2.5 2.5M15.5 15.5 18 18M6 18l2.5-2.5M15.5 8.5 18 6"/></symbol>
  <symbol id="clay-i-download" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4v11M7 10.5l5 5 5-5M5 20h14"/></symbol>
</svg>
<section><span class="lbl">Alerts · the type is a word and an icon, not just a colour</span><div class="clay-alerts">
<div class="alert clay-balert clay-sky" role="note"><span class="clay-alert__icon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-info"/></svg></span><div><p class="clay-alert__title"><span class="visually-hidden">Information: </span>Tip of the day</p><p class="clay-alert__text">Tap any word in a story to hear it read slowly.</p></div></div>
<div class="alert clay-balert clay-mint" role="note"><span class="clay-alert__icon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-success"/></svg></span><div><p class="clay-alert__title"><span class="visually-hidden">Success: </span>Progress saved</p><p class="clay-alert__text">Juniper finished Counting in fives with 9 of 10 right.</p></div></div>
<div class="alert clay-balert clay-lemon" role="note"><span class="clay-alert__icon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-alert"/></svg></span><div><p class="clay-alert__title"><span class="visually-hidden">Warning: </span>5 minutes of screen time left</p><p class="clay-alert__text">The app will suggest a break at 5:15 pm.</p></div></div>
<div class="alert clay-balert clay-peach" role="alert"><span class="clay-alert__icon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-error"/></svg></span><div><p class="clay-alert__title"><span class="visually-hidden">Error: </span>Drawing did not upload</p><p class="clay-alert__text">Check the Wi-Fi and press Try again. Your drawing is kept on this tablet.</p></div></div>
</div></section>
<div class="clay-row">
<section><span class="lbl">Toasts · polite live region</span><div class="clay-btoasts" role="status" aria-live="polite">
<div class="toast show clay-btoast"><div class="toast-body"><span class="clay-blob clay-lemon"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-trophy"/></svg></span><div class="clay-toast__body"><p class="clay-toast__title">Badge unlocked: Bookworm</p><p class="clay-toast__text">5 stories read this week</p></div><button class="btn btn-clay btn-clay-icon btn-clay-sm" type="button" aria-label="Close notification" data-bs-dismiss="toast"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-x"/></svg></button></div></div>
<div class="toast show clay-btoast"><div class="toast-body"><span class="clay-blob clay-mint"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-download"/></svg></span><div class="clay-toast__body"><p class="clay-toast__title">Saved for the car trip</p><p class="clay-toast__text">3 lessons work offline now</p></div><button class="btn btn-clay btn-clay-icon btn-clay-sm" type="button" aria-label="Close notification" data-bs-dismiss="toast"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-x"/></svg></button></div></div>
</div></section>
<section><span class="lbl">Dialog, dropdown and tooltips</span><div class="d-grid gap-4">
<div class="d-flex flex-wrap align-items-center gap-3">
<button class="btn btn-clay clay-peach" type="button" data-bs-toggle="modal" data-bs-target="#leave-modal"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-logout"/></svg>Leave lesson</button>
<div class="dropdown clay-bdd"><button class="btn btn-clay clay-sky dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Lesson options<svg class="clay-ico clay-dd__chev" aria-hidden="true" focusable="false"><use href="#clay-i-chevDown"/></svg></button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-download"/></svg>Save for offline</a></li>
<li><a class="dropdown-item" href="#"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-share"/></svg>Share with a parent</a></li>
<li><a class="dropdown-item" href="#"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-copy"/></svg>Copy lesson link</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item clay-dd__item--danger" href="#"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-flag"/></svg>Report a problem</a></li>
</ul></div>
</div>
<div class="d-flex flex-wrap align-items-center gap-3">
<button class="btn btn-clay btn-clay-icon clay-mint" type="button" aria-label="Hint" data-bs-toggle="tooltip" data-bs-title="Costs 5 stars"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-spark"/></svg></button>
<button class="btn btn-clay btn-clay-icon clay-lemon" type="button" aria-label="Read aloud" data-bs-toggle="tooltip" data-bs-title="Plays the page at story speed"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-volume"/></svg></button>
<button class="btn btn-clay btn-clay-icon clay-lilac" type="button" aria-label="Help" data-bs-toggle="tooltip" data-bs-title="Ask a grown-up for help"><svg class="clay-ico" aria-hidden="true" focusable="false"><use href="#clay-i-info"/></svg></button>
</div>
</div></section>
</div>
<div class="modal fade clay-bmodal" id="leave-modal" tabindex="-1" aria-labelledby="leave-title" aria-describedby="leave-text" aria-hidden="true"><div class="modal-dialog modal-dialog-centered"><div class="modal-content"><div class="modal-body">
<div class="clay-dialog__icon"><svg class="clay-ico clay-ico--lg" aria-hidden="true" focusable="false"><use href="#clay-i-flag"/></svg></div>
<h2 class="clay-dialog__title" id="leave-title">Leave this lesson?</h2>
<p class="clay-dialog__text" id="leave-text">You are on step 4 of 5. We will keep your stars, and you can finish the last step tomorrow.</p>
<div class="clay-dialog__actions"><button class="btn btn-clay" type="button" data-bs-dismiss="modal">Leave for now</button><button class="btn btn-clay btn-clay-accent" type="button" data-bs-dismiss="modal" autofocus>Keep learning</button></div>
</div></div></div></div>
CSS
/* ── Claymorphism UI kit tokens (uiCookies) — identical in every set ──────────────
   Every component is a puffy pastel object floating above --clay-bg: one big soft drop shadow
   below it, an inset highlight top left and an inset shade bottom right. Change a token and
   the whole kit follows; the shadow recipes below are built from these values. */
:root{
  --clay-bg:#f3effa;          /* page, a pale lilac white */
  --clay-surface:#fffcf8;     /* cards, fields and plain objects */
  --clay-peach:#ffd2bd;       /* object fills: ink text on every fill reaches 11:1 */
  --clay-lilac:#dccdff;
  --clay-mint:#bdeed6;
  --clay-sky:#c2e0ff;
  --clay-lemon:#ffe9a3;
  --clay-ink:#241a3d;         /* text, 14.4:1 on --clay-bg */
  --clay-muted:#51476a;       /* secondary text, 5.7:1 or more on every fill */
  --clay-edge:#7a6e96;        /* control boundary, 4.1:1 on --clay-bg, so shadows are never the only edge */
  --clay-line:rgba(36,26,61,.12); /* decorative edge on cards and panels */
  --clay-accent:#6236e8;      /* focus ring and on / selected / current states, 5.8:1 on --clay-bg */
  --clay-on-accent:#ffffff;   /* text and marks on accent fills, 6.5:1 */
  --clay-tint:#e9e1ff;        /* light accent wash behind current items */
  --clay-drop:rgba(86,56,168,.30); /* colour of the outer drop shadow */
  --clay-hi:rgba(255,255,255,.88);  /* inset highlight, top left */
  --clay-lo:rgba(52,30,112,.20);    /* inset shade, bottom right */
  --clay-lift:14px;           /* how high objects float; every shadow scales from it */
  --clay-radius:30px;         /* cards; buttons are pills, fields use .55 of it */
  --clay-bw:1.5px;            /* control border width */
  --clay-success:#17663d;--clay-warning:#8a4b00;--clay-danger:#b3261e;
  --clay-font:ui-rounded,"SF Pro Rounded","Nunito","Quicksand","Varela Round","Arial Rounded MT Bold",system-ui,sans-serif;
}
/* --clay-fill is set by .clay-peach, .clay-mint… on one object and must not leak into its children */
@property --clay-fill{syntax:"*";inherits:false}
/* Dark clay: data-clay="dark" on any wrapper, or a checked .clay-theme-input inside a [data-clay] element.
   :is() is a forgiving list, so browsers without :has() still apply data-clay="dark" */
[data-clay]:is([data-clay="dark"],:has(.clay-theme-input:checked)){
  --clay-bg:#1a1530;--clay-surface:#2a2347;
  --clay-peach:#6e3f33;--clay-lilac:#4a3a8a;--clay-mint:#215a4a;--clay-sky:#26497c;--clay-lemon:#5f5220;
  --clay-ink:#f7f3ff;--clay-muted:#d2c9ea;--clay-edge:#8f83b8;--clay-line:rgba(255,255,255,.1);
  --clay-accent:#bba6ff;--clay-on-accent:#1a1530;--clay-tint:#3a2f66;
  --clay-drop:rgba(4,2,14,.62);--clay-hi:rgba(255,255,255,.2);--clay-lo:rgba(0,0,0,.34);
  --clay-success:#86e3b0;--clay-warning:#ffc76e;--clay-danger:#ffa196;color-scheme:dark}
/* More contrast requested: soft shading stays, but every edge and secondary text turns full ink */
@media (prefers-contrast:more){:root,[data-clay]:is([data-clay],:has(.clay-theme-input:checked)){
  --clay-edge:var(--clay-ink);--clay-line:var(--clay-ink);--clay-muted:var(--clay-ink);--clay-bw:2px}}
:root,[data-clay]{
  --clay-shadow:0 var(--clay-lift) calc(var(--clay-lift)*2.2) calc(var(--clay-lift)*-.3) var(--clay-drop),
    inset calc(var(--clay-lift)*.45) calc(var(--clay-lift)*.5) calc(var(--clay-lift)*.9) var(--clay-hi),
    inset calc(var(--clay-lift)*-.45) calc(var(--clay-lift)*-.6) calc(var(--clay-lift)*.9) var(--clay-lo);
  --clay-shadow-sm:0 calc(var(--clay-lift)*.55) calc(var(--clay-lift)*1.2) calc(var(--clay-lift)*-.15) var(--clay-drop),
    inset calc(var(--clay-lift)*.25) calc(var(--clay-lift)*.3) calc(var(--clay-lift)*.5) var(--clay-hi),
    inset calc(var(--clay-lift)*-.25) calc(var(--clay-lift)*-.35) calc(var(--clay-lift)*.5) var(--clay-lo);
  --clay-press:0 calc(var(--clay-lift)*.12) calc(var(--clay-lift)*.25) 0 var(--clay-drop),
    inset calc(var(--clay-lift)*.2) calc(var(--clay-lift)*.25) calc(var(--clay-lift)*.45) var(--clay-lo),
    inset calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*.3) var(--clay-hi);
  --clay-well:inset calc(var(--clay-lift)*.15) calc(var(--clay-lift)*.22) calc(var(--clay-lift)*.45) var(--clay-lo),
    inset calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*.3) var(--clay-hi);
}
[data-clay]{background:var(--clay-bg);color:var(--clay-ink)}
/* Bootstrap's own variables mapped onto the kit tokens */
:root,[data-clay]{--bs-body-bg:var(--clay-bg);--bs-body-color:var(--clay-ink);--bs-body-font-family:var(--clay-font);
  --bs-emphasis-color:var(--clay-ink);--bs-heading-color:var(--clay-ink);--bs-secondary-color:var(--clay-muted);--bs-tertiary-color:var(--clay-muted);
  --bs-border-color:var(--clay-edge);--bs-border-width:var(--clay-bw);--bs-border-radius:calc(var(--clay-radius)*.55);
  --bs-border-radius-lg:var(--clay-radius);--bs-border-radius-pill:999px;--bs-focus-ring-color:var(--clay-accent);
  --bs-link-color:var(--clay-accent);--bs-link-color-rgb:98,54,232;--bs-link-hover-color:var(--clay-ink);--bs-link-hover-color-rgb:36,26,61}
/* Components */
:where([class*="clay-"]),:where([class*="clay-"])::before,:where([class*="clay-"])::after{box-sizing:border-box}
.clay-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.clay-ico{width:22px;height:22px;flex:none}
.clay-ico--lg{width:28px;height:28px}
/* Fills: put one on any object; components read --clay-fill */
.clay-peach{--clay-fill:var(--clay-peach)}.clay-lilac{--clay-fill:var(--clay-lilac)}.clay-mint{--clay-fill:var(--clay-mint)}
.clay-sky{--clay-fill:var(--clay-sky)}.clay-lemon{--clay-fill:var(--clay-lemon)}
/* Card: a puffy panel that floats on the big drop shadow */
.clay-card{margin:0;padding:1.6rem;border:var(--clay-bw) solid var(--clay-line);border-radius:var(--clay-radius);
  background:var(--clay-fill,var(--clay-surface));color:var(--clay-ink);box-shadow:var(--clay-shadow)}
/* Layout helpers */
.clay-cluster{display:flex;flex-wrap:wrap;align-items:center;gap:18px}
.clay-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:22px}
.clay-stack{display:grid;gap:1.4rem}
/* Cards: Bootstrap .card through its --bs-card-* variables */
.card.clay-card{--bs-card-bg:var(--clay-fill,var(--clay-surface));--bs-card-color:var(--clay-ink);--bs-card-border-color:var(--clay-line);
  --bs-card-border-width:var(--clay-bw);--bs-card-border-radius:var(--clay-radius);--bs-card-inner-border-radius:var(--clay-radius);
  --bs-card-spacer-x:1.6rem;--bs-card-spacer-y:1.6rem;padding:0}
/* Buttons: Bootstrap .btn with a .btn-clay variant set through --bs-btn-* variables.
   Hover lifts the pill, pressing squashes the shadow flat */
.btn-clay{--bs-btn-padding-x:1.5rem;--bs-btn-padding-y:.7rem;--bs-btn-font-family:inherit;--bs-btn-font-size:1rem;--bs-btn-font-weight:800;--bs-btn-line-height:1.2;
  --bs-btn-border-width:var(--clay-bw);--bs-btn-border-radius:999px;
  --bs-btn-bg:var(--clay-fill,var(--clay-surface));--bs-btn-color:var(--clay-ink);--bs-btn-border-color:var(--clay-edge);
  --bs-btn-hover-bg:var(--bs-btn-bg);--bs-btn-hover-color:var(--bs-btn-color);--bs-btn-hover-border-color:var(--bs-btn-border-color);
  --bs-btn-active-bg:var(--bs-btn-bg);--bs-btn-active-color:var(--bs-btn-color);--bs-btn-active-border-color:var(--bs-btn-border-color);
  --clay-btn-shadow:var(--clay-shadow-sm);
  display:inline-flex;align-items:center;justify-content:center;gap:.55rem;min-height:50px;
  box-shadow:var(--clay-btn-shadow);transition:transform .18s,box-shadow .18s}
.btn-clay:hover{--clay-btn-shadow:var(--clay-shadow);transform:translateY(-2px)}
.btn-clay:active,.btn-clay:first-child:active{--clay-btn-shadow:var(--clay-press);transform:translateY(2px)}
.btn-clay:focus-visible,.btn-check:focus-visible+.btn-clay{box-shadow:var(--clay-btn-shadow);outline:3px solid var(--clay-accent);outline-offset:4px}
.btn-clay-accent{--clay-fill:var(--clay-accent);--bs-btn-color:var(--clay-on-accent);--bs-btn-border-color:var(--clay-accent)}
.btn-clay.btn-sm{--bs-btn-padding-x:1.05rem;--bs-btn-padding-y:.45rem;--bs-btn-font-size:.88rem;min-height:40px}
/* Icon buttons: a round or squircle .btn-clay with an aria-label */
.btn-clay-icon{--bs-btn-padding-x:0;--bs-btn-padding-y:0;width:58px;height:58px;min-height:0;border-radius:50%}
.btn-clay-icon.btn-clay-sq{border-radius:20px}
.btn-clay-icon.btn-clay-sm{width:44px;height:44px}
.btn-clay-icon.btn-clay-lg{width:72px;height:72px}
@media (prefers-reduced-motion:reduce){.btn-clay{transition:none}.btn-clay:hover,.btn-clay:active,.btn-clay:first-child:active{transform:none}}
/* Blob: a small puffy icon tile that sits on any card */
.clay-blob{display:grid;place-items:center;flex:none;width:52px;height:52px;border:var(--clay-bw) solid var(--clay-line);border-radius:18px;
  background:var(--clay-fill,var(--clay-surface));color:var(--clay-ink);box-shadow:var(--clay-shadow-sm)}
.clay-chip{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .75rem;border:var(--clay-bw) solid var(--clay-line);border-radius:999px;
  background:var(--clay-surface);color:var(--clay-ink);font-size:.8rem;font-weight:800;line-height:1.3}
.clay-chip .clay-ico{width:16px;height:16px}
/* Stat cards: coloured clay slabs with a blob icon, a big number and a sentence that explains the change */
.clay-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:24px}
.clay-stat{display:grid;gap:.25rem;align-content:start}
.clay-stat__label{margin:.85rem 0 0;font-size:.9rem;font-weight:800;color:var(--clay-muted)}
.clay-stat__value{margin:0;font-size:2.2rem;font-weight:800;line-height:1.1;letter-spacing:-.01em}
.clay-stat__unit{font-size:1rem;font-weight:700}
.clay-stat__note{margin:0;font-size:.86rem;font-weight:600;color:var(--clay-muted)}
/* Content card: an illustration panel made of clay shapes, a chip, a title and a progress line */
.clay-lesson{display:flex;flex-direction:column;gap:1rem;padding:1rem 1rem 1.4rem}
.clay-art{position:relative;height:170px;overflow:hidden;border-radius:calc(var(--clay-radius)*.75);background:var(--clay-sky);box-shadow:var(--clay-well)}
.clay-art__shape{position:absolute;border-radius:50%;box-shadow:var(--clay-shadow-sm)}
.clay-art__shape--sun{top:22px;right:34px;width:58px;height:58px;background:var(--clay-lemon)}
.clay-art__shape--cloud{top:52px;left:40px;width:140px;height:54px;border-radius:999px;background:var(--clay-surface)}
.clay-art__shape--cloud2{top:30px;left:78px;width:70px;height:60px;background:var(--clay-surface)}
.clay-art__shape--hill{bottom:-70px;left:-20px;width:240px;height:140px;background:var(--clay-mint)}
.clay-art__shape--hill2{bottom:-90px;right:-40px;width:260px;height:150px;background:var(--clay-peach)}
.clay-art__shape--drop{top:116px;width:14px;height:20px;border-radius:50% 50% 50% 50%/60% 60% 40% 40%;background:var(--clay-accent);box-shadow:none}
.clay-lesson__body{display:grid;gap:.55rem;padding:0 .5rem}
.clay-lesson__tag{margin:0}
.clay-lesson__title{margin:0;font-size:1.3rem;font-weight:800;line-height:1.25}
.clay-lesson__text{margin:0;color:var(--clay-muted)}
.clay-lesson__foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1rem;padding:0 .5rem}
.clay-meter{display:grid;gap:.35rem;flex:1;min-width:140px;font-size:.84rem;font-weight:700;color:var(--clay-muted)}
.clay-meter__bar{height:14px;border:var(--clay-bw) solid var(--clay-edge);border-radius:999px;background:var(--clay-bg);box-shadow:var(--clay-well);overflow:hidden}
.clay-meter__fill{display:block;height:100%;width:var(--clay-pct,50%);border-radius:999px;background:var(--clay-accent)}
/* Profile card */
.clay-profile{display:grid;justify-items:center;gap:.4rem;text-align:center}
.clay-avatar{display:grid;place-items:center;width:96px;height:96px;margin-bottom:.6rem;border:var(--clay-bw) solid var(--clay-line);border-radius:50%;
  background:var(--clay-fill,var(--clay-lilac));font-size:2rem;font-weight:800;box-shadow:var(--clay-shadow)}
.clay-profile__name{margin:0;font-size:1.3rem;font-weight:800;line-height:1.25}
.clay-profile__role{margin:0;color:var(--clay-muted)}
.clay-profile__stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;width:100%;margin:.9rem 0 1.1rem;padding:0;list-style:none}
.clay-profile__stat{display:grid;padding:.6rem .3rem;border-radius:18px;background:var(--clay-fill,var(--clay-bg));box-shadow:var(--clay-well)}
.clay-profile__num{font-size:1.25rem;font-weight:800;line-height:1.2}
.clay-profile__key{font-size:.78rem;font-weight:700;color:var(--clay-muted)}
.clay-profile__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:12px}
/* Pricing pair */
.clay-plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:28px;align-items:start}
.clay-plan{position:relative;display:grid;gap:.9rem}
.clay-plan__badge{position:absolute;top:-14px;right:24px;padding:.3rem .85rem;border:var(--clay-bw) solid var(--clay-accent);border-radius:999px;
  background:var(--clay-accent);color:var(--clay-on-accent);font-size:.78rem;font-weight:800;box-shadow:var(--clay-shadow-sm)}
.clay-plan__name{margin:0;font-size:1.15rem;font-weight:800}
.clay-plan__price{margin:0;font-size:2.6rem;font-weight:800;line-height:1}
.clay-plan__per{font-size:1rem;font-weight:700;color:var(--clay-muted)}
.clay-plan__desc{margin:0;color:var(--clay-muted)}
.clay-plan__list{display:grid;gap:.6rem;margin:.2rem 0 .4rem;padding:0;list-style:none}
.clay-plan__item{display:flex;align-items:center;gap:.6rem;font-weight:600}
.clay-plan__tick{display:grid;place-items:center;flex:none;width:26px;height:26px;border-radius:50%;background:var(--clay-fill,var(--clay-surface));box-shadow:var(--clay-shadow-sm)}
.clay-plan__tick .clay-ico{width:16px;height:16px}
.clay-two{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:28px;align-items:start}
@media (max-width:767px){.clay-two{grid-template-columns:1fr}}
.clay-stats--two{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
/* Alerts: Bootstrap .alert through --bs-alert-* variables */
.clay-alerts{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,380px),1fr));gap:22px}
.alert.clay-balert{--bs-alert-bg:var(--clay-fill,var(--clay-surface));--bs-alert-color:var(--clay-ink);--bs-alert-border-color:var(--clay-line);--bs-alert-border-radius:calc(var(--clay-radius)*.8);
  --bs-alert-padding-x:1.2rem;--bs-alert-padding-y:1.1rem;--bs-alert-margin-bottom:0;display:flex;align-items:flex-start;gap:1rem;border-width:var(--clay-bw);box-shadow:var(--clay-shadow)}
.clay-alert__icon{display:grid;place-items:center;flex:none;width:44px;height:44px;border-radius:15px;background:var(--clay-surface);box-shadow:var(--clay-shadow-sm)}
.clay-alert__title{margin:0;font-weight:800;line-height:1.3}
.clay-alert__text{margin:.15rem 0 0;font-size:.92rem;color:var(--clay-muted)}
/* Toasts: Bootstrap .toast inside a polite live region; the close button uses data-bs-dismiss="toast" */
.clay-btoasts{display:grid;gap:16px;max-width:420px}
.toast.clay-btoast{--bs-toast-max-width:100%;--bs-toast-bg:var(--clay-surface);--bs-toast-color:var(--clay-ink);--bs-toast-border-color:var(--clay-line);--bs-toast-border-width:var(--clay-bw);
  --bs-toast-border-radius:24px;--bs-toast-box-shadow:var(--clay-shadow);--bs-toast-font-size:1rem;width:100%}
.clay-btoast .toast-body{display:flex;align-items:center;gap:.9rem;padding:.8rem .8rem .8rem 1rem}
.clay-toast__body{flex:1;min-width:0}
.clay-toast__title{margin:0;font-weight:800;line-height:1.3}
.clay-toast__text{margin:0;font-size:.88rem;color:var(--clay-muted)}
/* Tooltips: Bootstrap's tooltip plugin, restyled through --bs-tooltip-* */
.tooltip{--bs-tooltip-bg:var(--clay-ink);--bs-tooltip-color:var(--clay-bg);--bs-tooltip-border-radius:14px;--bs-tooltip-padding-x:.8rem;--bs-tooltip-padding-y:.5rem;
  --bs-tooltip-font-size:.84rem;--bs-tooltip-opacity:1;--bs-tooltip-max-width:220px;--bs-tooltip-arrow-width:14px;--bs-tooltip-arrow-height:7px;font-family:var(--clay-font);font-weight:700}
/* Dropdown: Bootstrap .dropdown-menu as a floating clay menu */
.clay-bdd .dropdown-toggle::after{display:none}
.clay-bdd .clay-dd__chev{transition:transform .18s}
.clay-bdd [aria-expanded="true"] .clay-dd__chev{transform:rotate(180deg)}
.clay-bdd .dropdown-menu{--bs-dropdown-min-width:250px;--bs-dropdown-padding-x:.5rem;--bs-dropdown-padding-y:.5rem;--bs-dropdown-bg:var(--clay-surface);--bs-dropdown-color:var(--clay-ink);
  --bs-dropdown-border-color:var(--clay-line);--bs-dropdown-border-width:var(--clay-bw);--bs-dropdown-border-radius:22px;--bs-dropdown-box-shadow:var(--clay-shadow);--bs-dropdown-spacer:12px;
  --bs-dropdown-link-color:var(--clay-ink);--bs-dropdown-link-hover-color:var(--clay-ink);--bs-dropdown-link-hover-bg:var(--clay-bg);--bs-dropdown-link-active-color:var(--clay-ink);--bs-dropdown-link-active-bg:var(--clay-bg);
  --bs-dropdown-item-padding-x:.7rem;--bs-dropdown-item-padding-y:.45rem;--bs-dropdown-item-border-radius:15px;--bs-dropdown-divider-bg:var(--clay-line);--bs-dropdown-divider-margin-y:.35rem;box-shadow:var(--bs-dropdown-box-shadow)}
.clay-bdd .dropdown-item{display:flex;align-items:center;gap:.7rem;min-height:46px;font-size:.95rem;font-weight:700}
.clay-bdd .dropdown-item:focus-visible{outline:3px solid var(--clay-accent);outline-offset:-3px}
.clay-bdd .dropdown-item.clay-dd__item--danger{color:var(--clay-danger)}
.clay-bdd .dropdown-divider{margin-left:.5rem;margin-right:.5rem;border-top-width:var(--clay-bw);opacity:1}
/* Modal: Bootstrap .modal; focus is kept inside and Escape closes it */
.modal.clay-bmodal{--bs-modal-width:440px;--bs-modal-padding:1.8rem;--bs-modal-bg:var(--clay-surface);--bs-modal-color:var(--clay-ink);--bs-modal-border-color:var(--clay-line);
  --bs-modal-border-width:var(--clay-bw);--bs-modal-border-radius:var(--clay-radius);--bs-modal-box-shadow:var(--clay-shadow);--bs-backdrop-bg:rgb(36,26,61);--bs-backdrop-opacity:.45}
.clay-bmodal .modal-content{box-shadow:var(--bs-modal-box-shadow);text-align:center}
.clay-dialog__icon{display:grid;place-items:center;width:70px;height:70px;margin:0 auto 1rem;border-radius:24px;background:var(--clay-peach);box-shadow:var(--clay-shadow-sm)}
.clay-dialog__title{margin:0;font-size:1.35rem;font-weight:800;line-height:1.25}
.clay-dialog__text{margin:.5rem 0 1.4rem;color:var(--clay-muted)}
.clay-dialog__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin:0}
.clay-row{display:flex;flex-wrap:wrap;align-items:flex-start;gap:56px}
.clay-row>section{flex:1 1 280px;min-width:0}
@media (prefers-reduced-motion:reduce){.clay-bdd .clay-dd__chev{transition:none}}
JavaScript
// Tooltips: Bootstrap's plugin is opt-in, so start it on every element that asks for one
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(function (el) { new bootstrap.Tooltip(el); });

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="clay-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="clay-i-volume" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M4 9.5h3.5L12 5.5v13l-4.5-4H4z"/><path d="M15.5 9a4 4 0 0 1 0 6M18 6.5a7.5 7.5 0 0 1 0 11"/></symbol>
  <symbol id="clay-i-trophy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8v5a4 4 0 0 1-8 0zM8 6H4.5a3.5 3.5 0 0 0 3.8 3.5M16 6h3.5a3.5 3.5 0 0 1-3.8 3.5M12 13v4M8.5 20.5h7M10 17h4"/></symbol>
  <symbol id="clay-i-chevDown" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9.5 6 6 6-6"/></symbol>
  <symbol id="clay-i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.8h.01"/></symbol>
  <symbol id="clay-i-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4 2.8 19.5h18.4z"/><path d="M12 10v4.5M12 17.2h.01"/></symbol>
  <symbol id="clay-i-error" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9 9l6 6M15 9l-6 6"/></symbol>
  <symbol id="clay-i-success" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="m8 12.3 2.7 2.7L16 9.6"/></symbol>
  <symbol id="clay-i-share" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5.5" r="2.5"/><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="18.5" r="2.5"/><path d="m8.2 10.8 7.6-4.1M8.2 13.2l7.6 4.1"/></symbol>
  <symbol id="clay-i-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><rect x="8" y="8" width="12" height="12" rx="3"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></symbol>
  <symbol id="clay-i-flag" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 21V4M5 4h11l-2 4 2 4H5"/></symbol>
  <symbol id="clay-i-logout" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M14 4h4.5a1.5 1.5 0 0 1 1.5 1.5v13a1.5 1.5 0 0 1-1.5 1.5H14M10 16.5 5.5 12 10 7.5M5.5 12H16"/></symbol>
  <symbol id="clay-i-spark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2.5 2.5M15.5 15.5 18 18M6 18l2.5-2.5M15.5 8.5 18 6"/></symbol>
  <symbol id="clay-i-download" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4v11M7 10.5l5 5 5-5M5 20h14"/></symbol>
</svg>
<section><span class="mb-5 block text-[.74rem] font-extrabold tracking-[.12em] text-clay-muted uppercase">Alerts · the type is a word and an icon, not just a colour</span><div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,380px),1fr))] gap-[22px]">
<div class="flex items-start gap-4 rounded-[calc(var(--clay-radius)*.8)] border-(length:--clay-bw) border-clay-line bg-[var(--clay-fill,var(--clay-surface))] px-[1.2rem] py-[1.1rem] text-clay-ink shadow-clay [--clay-fill:var(--clay-sky)]" role="note"><span class="grid size-11 flex-none place-items-center rounded-[15px] bg-clay-surface shadow-clay-sm"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-info"/></svg></span><div><p class="m-0 leading-[1.3] font-extrabold"><span class="sr-only">Information: </span>Tip of the day</p><p class="mt-[.15rem] mb-0 text-[.92rem] text-clay-muted">Tap any word in a story to hear it read slowly.</p></div></div>
<div class="flex items-start gap-4 rounded-[calc(var(--clay-radius)*.8)] border-(length:--clay-bw) border-clay-line bg-[var(--clay-fill,var(--clay-surface))] px-[1.2rem] py-[1.1rem] text-clay-ink shadow-clay [--clay-fill:var(--clay-mint)]" role="note"><span class="grid size-11 flex-none place-items-center rounded-[15px] bg-clay-surface shadow-clay-sm"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-success"/></svg></span><div><p class="m-0 leading-[1.3] font-extrabold"><span class="sr-only">Success: </span>Progress saved</p><p class="mt-[.15rem] mb-0 text-[.92rem] text-clay-muted">Juniper finished Counting in fives with 9 of 10 right.</p></div></div>
<div class="flex items-start gap-4 rounded-[calc(var(--clay-radius)*.8)] border-(length:--clay-bw) border-clay-line bg-[var(--clay-fill,var(--clay-surface))] px-[1.2rem] py-[1.1rem] text-clay-ink shadow-clay [--clay-fill:var(--clay-lemon)]" role="note"><span class="grid size-11 flex-none place-items-center rounded-[15px] bg-clay-surface shadow-clay-sm"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-alert"/></svg></span><div><p class="m-0 leading-[1.3] font-extrabold"><span class="sr-only">Warning: </span>5 minutes of screen time left</p><p class="mt-[.15rem] mb-0 text-[.92rem] text-clay-muted">The app will suggest a break at 5:15 pm.</p></div></div>
<div class="flex items-start gap-4 rounded-[calc(var(--clay-radius)*.8)] border-(length:--clay-bw) border-clay-line bg-[var(--clay-fill,var(--clay-surface))] px-[1.2rem] py-[1.1rem] text-clay-ink shadow-clay [--clay-fill:var(--clay-peach)]" role="alert"><span class="grid size-11 flex-none place-items-center rounded-[15px] bg-clay-surface shadow-clay-sm"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-error"/></svg></span><div><p class="m-0 leading-[1.3] font-extrabold"><span class="sr-only">Error: </span>Drawing did not upload</p><p class="mt-[.15rem] mb-0 text-[.92rem] text-clay-muted">Check the Wi-Fi and press Try again. Your drawing is kept on this tablet.</p></div></div>
</div></section>
<div class="flex flex-wrap items-start gap-14 [&>section]:min-w-0 [&>section]:flex-[1_1_280px]">
<section><span class="mb-5 block text-[.74rem] font-extrabold tracking-[.12em] text-clay-muted uppercase">Toasts · polite live region</span><div class="grid max-w-[420px] gap-4" role="status" aria-live="polite">
<div class="flex items-center gap-[.9rem] rounded-3xl border-(length:--clay-bw) border-clay-line bg-clay-surface py-[.8rem] pr-[.8rem] pl-4 text-clay-ink shadow-clay" data-clay-toast><span class="grid size-[52px] flex-none place-items-center rounded-[18px] border-(length:--clay-bw) border-clay-line bg-[var(--clay-fill,var(--clay-surface))] text-clay-ink shadow-clay-sm [--clay-fill:var(--clay-lemon)]"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-trophy"/></svg></span><div class="min-w-0 flex-1"><p class="m-0 leading-[1.3] font-extrabold">Badge unlocked: Bookworm</p><p class="m-0 text-[.88rem] text-clay-muted">5 stories read this week</p></div><button class="m-0 inline-grid cursor-pointer place-items-center rounded-full border-(length:--clay-bw) border-clay-edge bg-[var(--clay-fill,var(--clay-surface))] p-0 text-clay-ink shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent size-11" type="button" aria-label="Close notification" data-clay-dismiss><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-x"/></svg></button></div>
<div class="flex items-center gap-[.9rem] rounded-3xl border-(length:--clay-bw) border-clay-line bg-clay-surface py-[.8rem] pr-[.8rem] pl-4 text-clay-ink shadow-clay" data-clay-toast><span class="grid size-[52px] flex-none place-items-center rounded-[18px] border-(length:--clay-bw) border-clay-line bg-[var(--clay-fill,var(--clay-surface))] text-clay-ink shadow-clay-sm [--clay-fill:var(--clay-mint)]"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-download"/></svg></span><div class="min-w-0 flex-1"><p class="m-0 leading-[1.3] font-extrabold">Saved for the car trip</p><p class="m-0 text-[.88rem] text-clay-muted">3 lessons work offline now</p></div><button class="m-0 inline-grid cursor-pointer place-items-center rounded-full border-(length:--clay-bw) border-clay-edge bg-[var(--clay-fill,var(--clay-surface))] p-0 text-clay-ink shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent size-11" type="button" aria-label="Close notification" data-clay-dismiss><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-x"/></svg></button></div>
</div></section>
<section><span class="mb-5 block text-[.74rem] font-extrabold tracking-[.12em] text-clay-muted uppercase">Dialog, dropdown and tooltips</span><div class="grid gap-[1.4rem]">
<div class="flex flex-wrap items-center gap-[18px]">
<button class="m-0 inline-flex min-h-[50px] cursor-pointer items-center justify-center gap-[.55rem] rounded-full border-(length:--clay-bw) border-clay-edge bg-[var(--clay-fill,var(--clay-surface))] px-6 py-[.7rem] font-[inherit] text-base leading-[1.2] font-extrabold text-clay-ink no-underline shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent [--clay-fill:var(--clay-peach)]" type="button" data-clay-open="leave-dialog"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-logout"/></svg>Leave lesson</button>
<div class="group/dd relative inline-block"><button class="m-0 inline-flex min-h-[50px] cursor-pointer items-center justify-center gap-[.55rem] rounded-full border-(length:--clay-bw) border-clay-edge bg-[var(--clay-fill,var(--clay-surface))] px-6 py-[.7rem] font-[inherit] text-base leading-[1.2] font-extrabold text-clay-ink no-underline shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent [--clay-fill:var(--clay-sky)]" type="button" aria-expanded="false" aria-controls="lesson-menu" data-clay-dropdown>Lesson options<svg class="size-[22px] shrink-0 transition-transform duration-[180ms] motion-reduce:transition-none group-has-[[aria-expanded=true]]/dd:rotate-180" aria-hidden="true" focusable="false"><use href="#clay-i-chevDown"/></svg></button>
<ul class="absolute top-[calc(100%+12px)] left-0 z-10 m-0 min-w-[250px] list-none rounded-[22px] border-(length:--clay-bw) border-clay-line bg-clay-surface p-2 shadow-clay" id="lesson-menu" hidden>
<li><a class="flex min-h-[46px] w-full cursor-pointer items-center gap-[.7rem] rounded-[15px] border-0 bg-transparent px-[.7rem] py-[.45rem] text-left font-[inherit] text-[.95rem] font-bold text-clay-ink no-underline hover:bg-clay-bg focus-visible:outline-3 focus-visible:-outline-offset-3 focus-visible:outline-clay-accent" href="#"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-download"/></svg>Save for offline</a></li>
<li><a class="flex min-h-[46px] w-full cursor-pointer items-center gap-[.7rem] rounded-[15px] border-0 bg-transparent px-[.7rem] py-[.45rem] text-left font-[inherit] text-[.95rem] font-bold text-clay-ink no-underline hover:bg-clay-bg focus-visible:outline-3 focus-visible:-outline-offset-3 focus-visible:outline-clay-accent" href="#"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-share"/></svg>Share with a parent</a></li>
<li><a class="flex min-h-[46px] w-full cursor-pointer items-center gap-[.7rem] rounded-[15px] border-0 bg-transparent px-[.7rem] py-[.45rem] text-left font-[inherit] text-[.95rem] font-bold text-clay-ink no-underline hover:bg-clay-bg focus-visible:outline-3 focus-visible:-outline-offset-3 focus-visible:outline-clay-accent" href="#"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-copy"/></svg>Copy lesson link</a></li>
<li class="mx-2 my-[.35rem] h-0 border-t-(length:--clay-bw) border-clay-line" role="presentation"></li>
<li><a class="flex min-h-[46px] w-full cursor-pointer items-center gap-[.7rem] rounded-[15px] border-0 bg-transparent px-[.7rem] py-[.45rem] text-left font-[inherit] text-[.95rem] font-bold no-underline hover:bg-clay-bg focus-visible:outline-3 focus-visible:-outline-offset-3 focus-visible:outline-clay-accent text-clay-danger" href="#"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-flag"/></svg>Report a problem</a></li>
</ul></div>
</div>
<div class="flex flex-wrap items-center gap-[18px]">
<span class="group/tip relative inline-flex" data-clay-tip><button class="m-0 inline-grid size-[58px] cursor-pointer place-items-center rounded-full border-(length:--clay-bw) border-clay-edge bg-[var(--clay-fill,var(--clay-surface))] p-0 text-clay-ink shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent [--clay-fill:var(--clay-mint)]" type="button" aria-label="Hint" aria-describedby="tip-hint"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-spark"/></svg></button><span class="pointer-events-none invisible absolute bottom-[calc(100%+12px)] left-1/2 z-5 w-max max-w-[220px] -translate-x-1/2 translate-y-1.5 rounded-[14px] border-(length:--clay-bw) border-clay-ink bg-clay-ink px-[.8rem] py-2 text-center text-[.84rem] leading-[1.35] font-bold text-clay-bg opacity-0 shadow-clay-sm transition-[opacity,translate,visibility] duration-[180ms] motion-reduce:transition-none after:absolute after:top-full after:left-1/2 after:-ml-[7px] after:border-[7px] after:border-transparent after:border-t-clay-ink after:content-[''] group-hover/tip:visible group-hover/tip:translate-y-0 group-hover/tip:opacity-100 group-focus-within/tip:visible group-focus-within/tip:translate-y-0 group-focus-within/tip:opacity-100 [.is-dismissed>&]:invisible! [.is-dismissed>&]:opacity-0!" role="tooltip" id="tip-hint">Costs 5 stars</span></span>
<span class="group/tip relative inline-flex" data-clay-tip><button class="m-0 inline-grid size-[58px] cursor-pointer place-items-center rounded-full border-(length:--clay-bw) border-clay-edge bg-[var(--clay-fill,var(--clay-surface))] p-0 text-clay-ink shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent [--clay-fill:var(--clay-lemon)]" type="button" aria-label="Read aloud" aria-describedby="tip-read"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-volume"/></svg></button><span class="pointer-events-none invisible absolute bottom-[calc(100%+12px)] left-1/2 z-5 w-max max-w-[220px] -translate-x-1/2 translate-y-1.5 rounded-[14px] border-(length:--clay-bw) border-clay-ink bg-clay-ink px-[.8rem] py-2 text-center text-[.84rem] leading-[1.35] font-bold text-clay-bg opacity-0 shadow-clay-sm transition-[opacity,translate,visibility] duration-[180ms] motion-reduce:transition-none after:absolute after:top-full after:left-1/2 after:-ml-[7px] after:border-[7px] after:border-transparent after:border-t-clay-ink after:content-[''] group-hover/tip:visible group-hover/tip:translate-y-0 group-hover/tip:opacity-100 group-focus-within/tip:visible group-focus-within/tip:translate-y-0 group-focus-within/tip:opacity-100 [.is-dismissed>&]:invisible! [.is-dismissed>&]:opacity-0!" role="tooltip" id="tip-read">Plays the page at story speed</span></span>
<span class="group/tip relative inline-flex" data-clay-tip><button class="m-0 inline-grid size-[58px] cursor-pointer place-items-center rounded-full border-(length:--clay-bw) border-clay-edge bg-[var(--clay-fill,var(--clay-surface))] p-0 text-clay-ink shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent [--clay-fill:var(--clay-lilac)]" type="button" aria-label="Help" aria-describedby="tip-help"><svg class="size-[22px] shrink-0" aria-hidden="true" focusable="false"><use href="#clay-i-info"/></svg></button><span class="pointer-events-none invisible absolute bottom-[calc(100%+12px)] left-1/2 z-5 w-max max-w-[220px] -translate-x-1/2 translate-y-1.5 rounded-[14px] border-(length:--clay-bw) border-clay-ink bg-clay-ink px-[.8rem] py-2 text-center text-[.84rem] leading-[1.35] font-bold text-clay-bg opacity-0 shadow-clay-sm transition-[opacity,translate,visibility] duration-[180ms] motion-reduce:transition-none after:absolute after:top-full after:left-1/2 after:-ml-[7px] after:border-[7px] after:border-transparent after:border-t-clay-ink after:content-[''] group-hover/tip:visible group-hover/tip:translate-y-0 group-hover/tip:opacity-100 group-focus-within/tip:visible group-focus-within/tip:translate-y-0 group-focus-within/tip:opacity-100 [.is-dismissed>&]:invisible! [.is-dismissed>&]:opacity-0!" role="tooltip" id="tip-help">Ask a grown-up for help</span></span>
</div>
</div></section>
</div>
<dialog class="m-auto w-[min(440px,calc(100%-32px))] rounded-clay border-(length:--clay-bw) border-clay-line bg-clay-surface p-7 text-center text-clay-ink shadow-clay backdrop:bg-[rgba(36,26,61,.45)] open:animate-[clay-pop_.25s_ease-out] motion-reduce:open:animate-none" id="leave-dialog" aria-labelledby="leave-title" aria-describedby="leave-text">
<div class="mx-auto mb-4 grid size-[70px] place-items-center rounded-3xl bg-clay-peach shadow-clay-sm"><svg class="shrink-0 size-7" aria-hidden="true" focusable="false"><use href="#clay-i-flag"/></svg></div>
<h2 class="m-0 text-[1.35rem] leading-[1.25] font-extrabold" id="leave-title">Leave this lesson?</h2>
<p class="mt-2 mb-[1.4rem] text-clay-muted" id="leave-text">You are on step 4 of 5. We will keep your stars, and you can finish the last step tomorrow.</p>
<form class="m-0 flex flex-wrap justify-center gap-3" method="dialog"><button class="m-0 inline-flex min-h-[50px] cursor-pointer items-center justify-center gap-[.55rem] rounded-full border-(length:--clay-bw) border-clay-edge bg-[var(--clay-fill,var(--clay-surface))] px-6 py-[.7rem] font-[inherit] text-base leading-[1.2] font-extrabold text-clay-ink no-underline shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent" value="leave">Leave for now</button><button class="m-0 inline-flex min-h-[50px] cursor-pointer items-center justify-center gap-[.55rem] rounded-full border-(length:--clay-bw) bg-[var(--clay-fill,var(--clay-surface))] px-6 py-[.7rem] font-[inherit] text-base leading-[1.2] font-extrabold no-underline shadow-clay-sm transition-[translate,box-shadow] duration-[180ms] motion-reduce:transition-none hover:-translate-y-0.5 hover:shadow-clay active:translate-y-0.5 active:shadow-clay-press motion-reduce:hover:translate-y-0 motion-reduce:active:translate-y-0 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-clay-accent [--clay-fill:var(--clay-accent)] border-clay-accent text-clay-on-accent" value="stay" autofocus>Keep learning</button></form>
</dialog>
CSS
/* ── Claymorphism UI kit tokens (uiCookies) — identical in every set ──────────────
   Every component is a puffy pastel object floating above --clay-bg: one big soft drop shadow
   below it, an inset highlight top left and an inset shade bottom right. Change a token and
   the whole kit follows; the shadow recipes below are built from these values. */
:root{
  --clay-bg:#f3effa;          /* page, a pale lilac white */
  --clay-surface:#fffcf8;     /* cards, fields and plain objects */
  --clay-peach:#ffd2bd;       /* object fills: ink text on every fill reaches 11:1 */
  --clay-lilac:#dccdff;
  --clay-mint:#bdeed6;
  --clay-sky:#c2e0ff;
  --clay-lemon:#ffe9a3;
  --clay-ink:#241a3d;         /* text, 14.4:1 on --clay-bg */
  --clay-muted:#51476a;       /* secondary text, 5.7:1 or more on every fill */
  --clay-edge:#7a6e96;        /* control boundary, 4.1:1 on --clay-bg, so shadows are never the only edge */
  --clay-line:rgba(36,26,61,.12); /* decorative edge on cards and panels */
  --clay-accent:#6236e8;      /* focus ring and on / selected / current states, 5.8:1 on --clay-bg */
  --clay-on-accent:#ffffff;   /* text and marks on accent fills, 6.5:1 */
  --clay-tint:#e9e1ff;        /* light accent wash behind current items */
  --clay-drop:rgba(86,56,168,.30); /* colour of the outer drop shadow */
  --clay-hi:rgba(255,255,255,.88);  /* inset highlight, top left */
  --clay-lo:rgba(52,30,112,.20);    /* inset shade, bottom right */
  --clay-lift:14px;           /* how high objects float; every shadow scales from it */
  --clay-radius:30px;         /* cards; buttons are pills, fields use .55 of it */
  --clay-bw:1.5px;            /* control border width */
  --clay-success:#17663d;--clay-warning:#8a4b00;--clay-danger:#b3261e;
  --clay-font:ui-rounded,"SF Pro Rounded","Nunito","Quicksand","Varela Round","Arial Rounded MT Bold",system-ui,sans-serif;
}
/* --clay-fill is set by .clay-peach, .clay-mint… on one object and must not leak into its children */
@property --clay-fill{syntax:"*";inherits:false}
/* Dark clay: data-clay="dark" on any wrapper, or a checked .clay-theme-input inside a [data-clay] element.
   :is() is a forgiving list, so browsers without :has() still apply data-clay="dark" */
[data-clay]:is([data-clay="dark"],:has(.clay-theme-input:checked)){
  --clay-bg:#1a1530;--clay-surface:#2a2347;
  --clay-peach:#6e3f33;--clay-lilac:#4a3a8a;--clay-mint:#215a4a;--clay-sky:#26497c;--clay-lemon:#5f5220;
  --clay-ink:#f7f3ff;--clay-muted:#d2c9ea;--clay-edge:#8f83b8;--clay-line:rgba(255,255,255,.1);
  --clay-accent:#bba6ff;--clay-on-accent:#1a1530;--clay-tint:#3a2f66;
  --clay-drop:rgba(4,2,14,.62);--clay-hi:rgba(255,255,255,.2);--clay-lo:rgba(0,0,0,.34);
  --clay-success:#86e3b0;--clay-warning:#ffc76e;--clay-danger:#ffa196;color-scheme:dark}
/* More contrast requested: soft shading stays, but every edge and secondary text turns full ink */
@media (prefers-contrast:more){:root,[data-clay]:is([data-clay],:has(.clay-theme-input:checked)){
  --clay-edge:var(--clay-ink);--clay-line:var(--clay-ink);--clay-muted:var(--clay-ink);--clay-bw:2px}}
:root,[data-clay]{
  --clay-shadow:0 var(--clay-lift) calc(var(--clay-lift)*2.2) calc(var(--clay-lift)*-.3) var(--clay-drop),
    inset calc(var(--clay-lift)*.45) calc(var(--clay-lift)*.5) calc(var(--clay-lift)*.9) var(--clay-hi),
    inset calc(var(--clay-lift)*-.45) calc(var(--clay-lift)*-.6) calc(var(--clay-lift)*.9) var(--clay-lo);
  --clay-shadow-sm:0 calc(var(--clay-lift)*.55) calc(var(--clay-lift)*1.2) calc(var(--clay-lift)*-.15) var(--clay-drop),
    inset calc(var(--clay-lift)*.25) calc(var(--clay-lift)*.3) calc(var(--clay-lift)*.5) var(--clay-hi),
    inset calc(var(--clay-lift)*-.25) calc(var(--clay-lift)*-.35) calc(var(--clay-lift)*.5) var(--clay-lo);
  --clay-press:0 calc(var(--clay-lift)*.12) calc(var(--clay-lift)*.25) 0 var(--clay-drop),
    inset calc(var(--clay-lift)*.2) calc(var(--clay-lift)*.25) calc(var(--clay-lift)*.45) var(--clay-lo),
    inset calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*.3) var(--clay-hi);
  --clay-well:inset calc(var(--clay-lift)*.15) calc(var(--clay-lift)*.22) calc(var(--clay-lift)*.45) var(--clay-lo),
    inset calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*-.12) calc(var(--clay-lift)*.3) var(--clay-hi);
}
[data-clay]{background:var(--clay-bg);color:var(--clay-ink)}
/* The tokens above, exposed as Tailwind utilities: bg-clay-peach, text-clay-muted, border-clay-edge,
   shadow-clay, shadow-clay-sm, shadow-clay-press, shadow-clay-well, rounded-clay, rounded-clay-field, font-clay… */
@theme inline {
  --color-clay-bg: var(--clay-bg); --color-clay-surface: var(--clay-surface);
  --color-clay-peach: var(--clay-peach); --color-clay-lilac: var(--clay-lilac); --color-clay-mint: var(--clay-mint);
  --color-clay-sky: var(--clay-sky); --color-clay-lemon: var(--clay-lemon);
  --color-clay-ink: var(--clay-ink); --color-clay-muted: var(--clay-muted); --color-clay-edge: var(--clay-edge); --color-clay-line: var(--clay-line);
  --color-clay-accent: var(--clay-accent); --color-clay-on-accent: var(--clay-on-accent); --color-clay-tint: var(--clay-tint);
  --color-clay-success: var(--clay-success); --color-clay-warning: var(--clay-warning); --color-clay-danger: var(--clay-danger);
  --shadow-clay: var(--clay-shadow); --shadow-clay-sm: var(--clay-shadow-sm); --shadow-clay-press: var(--clay-press); --shadow-clay-well: var(--clay-well);
  --radius-clay: var(--clay-radius); --radius-clay-field: calc(var(--clay-radius) * .55); --radius-clay-sm: calc(var(--clay-radius) * .4);
  --font-clay: var(--clay-font);
}
@keyframes clay-pop{from{transform:scale(.92);opacity:0}}
JavaScript
// Dialog: any button with data-clay-open="dialog-id" opens that <dialog>; focus returns to the button on close
document.querySelectorAll('[data-clay-open]').forEach(function (btn) {
  var dialog = document.getElementById(btn.getAttribute('data-clay-open'));
  if (!dialog) return;
  btn.addEventListener('click', function () {
    dialog.showModal();
    dialog.addEventListener('close', function () { btn.focus(); }, { once: true });
  });
  dialog.addEventListener('click', function (e) { if (e.target === dialog) dialog.close(); }); // backdrop click
});
// Tooltips: Escape hides the visible tooltip until the pointer or focus leaves it
document.addEventListener('keydown', function (e) {
  if (e.key !== 'Escape') return;
  document.querySelectorAll('[data-clay-tip]').forEach(function (t) { if (t.matches(':hover, :focus-within')) t.classList.add('is-dismissed'); });
});
document.querySelectorAll('[data-clay-tip]').forEach(function (t) {
  ['mouseleave', 'focusout'].forEach(function (ev) { t.addEventListener(ev, function () { t.classList.remove('is-dismissed'); }); });
});
// Toasts: a close button hides its toast
document.querySelectorAll('[data-clay-dismiss]').forEach(function (b) {
  b.addEventListener('click', function () { b.closest('[data-clay-toast]').hidden = true; });
});
// Dropdown: toggle on click; Escape (focus back to the button) or a click outside closes it
document.querySelectorAll('[data-clay-dropdown]').forEach(function (btn) {
  var menu = document.getElementById(btn.getAttribute('aria-controls'));
  function set(open) { btn.setAttribute('aria-expanded', open); menu.hidden = !open; }
  btn.addEventListener('click', function () { set(btn.getAttribute('aria-expanded') !== 'true'); });
  document.addEventListener('click', function (e) { if (!btn.parentNode.contains(e.target)) set(false); });
  btn.parentNode.addEventListener('keydown', function (e) { if (e.key === 'Escape' && btn.getAttribute('aria-expanded') === 'true') { set(false); btn.focus(); } });
});

About this set

Feedback and overlay patterns in soft clay. Four alerts in sky, mint, lemon and peach cover a tip, a saved message, a screen-time warning and a failed upload; each names its type in a title, an icon and hidden text such as Warning, so colour is never the only signal, and the error uses role=”alert”. Two toasts, a badge unlocked and a lesson saved for offline, sit in a polite live region and each has a round close button. Three round icon buttons show tooltips on hover and keyboard focus that Escape dismisses. A Lesson options button opens a floating clay menu with save, share, copy and report actions, and closes on Escape or a click outside. A Leave lesson button opens a confirmation dialog with a flag badge, a short explanation and Leave for now and Keep learning buttons. In the plain CSS and Tailwind versions the dialog is the native dialog element opened with showModal(), so focus is trapped, Escape closes it and focus returns to the button; the Bootstrap version uses its modal, toast, tooltip and dropdown plugins.

What’s included

  • Alerts that name their type in words, an icon and hidden text
  • Toasts in a polite live region with close buttons
  • Tooltips on hover and focus, dismissed with Escape
  • Dropdown menu with aria-expanded, Escape and outside-click closing
  • Confirmation dialog on the native dialog element

Accessibility

The dialog is labelled and described by its heading and text, traps focus and returns it on close. Tooltips are tied to their buttons with aria-describedby and can be dismissed with Escape, the dropdown button reports aria-expanded, and toasts are announced through a polite live region. The dialog pop-in animation and every transition stop under prefers-reduced-motion.

Customise it

Alert colours come from the fill classes and the tooltip uses --clay-ink on --clay-bg, so it inverts in dark mode. Bootstrap maps the tokens onto --bs-alert-*, --bs-toast-*, --bs-tooltip-*, --bs-dropdown-* and --bs-modal-* variables; Tailwind uses bg-clay-*, shadow-clay and backdrop: utilities.