/* Brand details: one reusable set (v1 vocabulary), shared by any page that links it + details.js.
   .spark       gold 4-point sparkle. <span class="spark tw" style="--s:22px"><svg><use href="#i-spark"/></svg></span>; position it with top/left/right/bottom.
   .tw          twinkles once when scrolled into view (details.js adds .in). Without .tw a spark is static.
   .spark-host  inline-block, position:relative wrapper, so a spark can sit on a corner of a word, number or button.
   .dots        lilac halftone cluster (CSS dots, radially masked), painted under all text. Put .has-dots on the section that holds it. --w size, --dot colour.
   .burst       purple starburst sticker with a glyph: <span class="burst"><svg><use href="#i-burst"/></svg><b>%</b></span>. --s size.
   .glyph       lilac % / + glyph, the "magic smoke" from the logo's lamp. --s size.
   .pen-u       hand-drawn pen underline on one key phrase (details.js: SS.penUnderline(el, words)).
   .spark/.burst rules match span only (:where keeps specificity), so dg.html's own svg.spark / svg.burst keep their sizes.
   step 16      scroll reveal (no class needed: matches details.js REVEAL), .drift (hero sticker floats up ≤10px with scroll), header shadow on html.ss-scrolled. */
:where(span).spark{position:absolute;width:var(--s,20px);height:var(--s,20px);color:var(--gold,#fbbf24);pointer-events:none}
.spark svg{display:block;width:100%;height:100%;fill:currentColor}
.spark-host{position:relative;display:inline-block}

.dots{position:absolute;z-index:-1;width:var(--w,420px);aspect-ratio:1;pointer-events:none;
  background:radial-gradient(circle,var(--dot,#e5ceff) 0 2.4px,transparent 2.9px) 0 0/12px 12px;
  -webkit-mask:radial-gradient(closest-side,#000 0,rgb(0 0 0/.85) 30%,transparent 100%);mask:radial-gradient(closest-side,#000 0,rgb(0 0 0/.85) 30%,transparent 100%)}
.has-dots{position:relative;overflow:clip;isolation:isolate}

.burst:where(span){position:absolute;display:grid;place-items:center;width:var(--s,44px);height:var(--s,44px);rotate:12deg;pointer-events:none}
.burst:where(span) svg{position:absolute;inset:0;width:100%;height:100%;fill:var(--purple,#6310c3)}
.burst:where(span) b{position:relative;color:var(--white,#fff);font:700 calc(var(--s,44px)*.38)/1 var(--sans,system-ui);margin-top:-1px}

.glyph{position:absolute;color:var(--lilac,#e5ceff);font:700 var(--s,18px)/1 var(--sans,system-ui);pointer-events:none;user-select:none}

.pen-u{position:relative;white-space:nowrap}
.pen-u>svg{position:absolute;left:-3%;bottom:-.14em;width:106%;height:.24em;overflow:visible;pointer-events:none}
/* one continuous stroke: no dasharray (with non-scaling-stroke Chrome measured dashes in screen px, so wide svgs broke into dashes); the draw-on is a left-to-right clip wipe */
.pen-u>svg path{fill:none;stroke:var(--purple-2,#6c13d2);stroke-width:3.5;stroke-linecap:round;vector-effect:non-scaling-stroke}
.tw-on .pen-u:not(.in)>svg{clip-path:inset(-100% 100% -100% -10%)}
.tw-on .pen-u.in>svg{animation:pen-u .7s .3s ease-out both}
@keyframes pen-u{from{clip-path:inset(-100% 100% -100% -10%)}to{clip-path:inset(-100% -10% -100% -10%)}}

/* twinkle once on scroll-in; html.tw-on is set by details.js only when motion is allowed, so no JS / reduced motion = static and visible */
.tw-on .tw:not(.in){opacity:0}
.tw-on .tw.in{animation:twinkle .9s var(--d,0s) cubic-bezier(.2,.7,.3,1.4) both}
@keyframes twinkle{0%{opacity:0;scale:.2;rotate:-45deg}55%{opacity:1;scale:1.25}100%{opacity:1;scale:1;rotate:0deg}}
/* step 16: content is visible by default; hidden only under html.tw-on (JS + motion allowed). :where() = zero specificity, so page animations (.flash) still win */
.tw-on section:not(.hero) :is(h2,.card,.tile,.qcard,.step):not(.in){opacity:0}
:where(.tw-on section:not(.hero) :is(h2,.card,.tile,.qcard,.step).in){animation:rise .5s var(--rd,0s) cubic-bezier(.2,.7,.3,1) both}
@keyframes rise{from{opacity:0;translate:0 14px}}
.tw-on .drift{translate:0 var(--dy,0px)}
:where(body>header,.hdr){transition:box-shadow .3s ease-out}
:where(.ss-scrolled) :where(body>header,.hdr){box-shadow:0 8px 20px -14px rgb(30 27 52/.45)}
@media (prefers-reduced-motion:reduce){.tw,.pen-u>svg{animation:none!important;opacity:1!important;clip-path:none!important}}
