/* ── 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}}
/* ── 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}}
/* ── 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.