:root{
 --font-script:"Oleo Script",Georgia,serif;--font-display:"Anton","Arial Narrow",sans-serif;--font-body:"Lexend","Segoe UI","Helvetica Neue",sans-serif;
 --text-xs:.875rem;--text-sm:1rem;--text-base:1.125rem;
 --text-lg:clamp(1.25rem,1.15rem + .45vw,1.5rem);--text-xl:clamp(1.5rem,1.3rem + .9vw,2rem);
 --text-2xl:clamp(2rem,1.65rem + 1.6vw,2.75rem);--text-3xl:clamp(2.5rem,1.95rem + 2.6vw,3.75rem);--text-4xl:clamp(3.25rem,2.35rem + 4.2vw,5.5rem);
 --leading-body:1.5;--leading-display:1;--tracking-caps:.14em;
 --cream:#EAE0C5;--orange:#F07A1E;--olive:#546145;--sage:#8FAE78;--mustard:#D9C06A;--peach:#E8A06A;--burgundy:#6E0F16;--warm-grey:#BDB59C;
 --background:var(--cream);--surface:var(--peach);--surface-input:var(--cream);--text:var(--burgundy);--text-on-dark:var(--cream);
 --accent-solid:var(--burgundy);--on-accent:var(--cream);--accent-brand:var(--orange);--display-ink:var(--olive);--display-echo:var(--mustard);
 --border:var(--olive);--focus:var(--burgundy);--focus-on-dark:var(--cream);--error:var(--burgundy);--success:var(--olive);--on-success:var(--cream);
 --tile-where:var(--warm-grey);--tile-form:var(--mustard);--tile-success:var(--burgundy);--band-footer:var(--burgundy);
 --space-1:.25rem;--space-2:.5rem;--space-3:.75rem;--space-4:1rem;--space-5:1.5rem;--space-6:2rem;--space-7:3rem;--space-8:4rem;--space-9:6rem;
 --radius-tile:0;--radius-card:1.75rem;--radius-control:.75rem;--radius-pill:999px;--border-width:2px;--focus-ring:3px solid var(--focus);
 /* Collision tokens: phone values; desktop overrides at >=900px */
 --tilt-max:1deg;--overlap:var(--space-4);
 /* Motion tokens (DESIGN.md ## Motion) */
 --dur-micro:120ms;--dur-standard:300ms;--dur-entrance:600ms;--dur-burst:700ms;--stagger:80ms;--lift:3px;
 --ease-out:cubic-bezier(.16,1,.3,1);--ease-spring:cubic-bezier(.34,1.56,.64,1);
}
*{box-sizing:border-box;margin:0}
html,body{overflow-x:clip}
body{min-height:100svh;display:flex;flex-direction:column;background:var(--background);color:var(--text);font:400 var(--text-base)/var(--leading-body) var(--font-body)}
:focus-visible{outline:var(--focus-ring);outline-offset:3px}
.F.ok :focus-visible,.Z :focus-visible{outline-color:var(--focus-on-dark)}
h1,h2{font-weight:400}
.caps{font-weight:600;text-transform:uppercase;letter-spacing:var(--tracking-caps);font-size:var(--text-sm);line-height:1.3}
.display{font-family:var(--font-display);text-transform:uppercase;letter-spacing:.01em;line-height:var(--leading-display)}
.script{font-family:var(--font-script);font-weight:700;line-height:1.05}
main{flex:1;overflow-x:clip} /* wave bands bleed off-canvas; clip here so they never widen the page */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}

.btn{position:relative;isolation:isolate;display:flex;align-items:center;justify-content:center;width:100%;min-height:48px;padding:0 var(--space-5);border:0;background:none;border-radius:var(--radius-pill);font:600 var(--text-lg)/1.2 var(--font-body);text-decoration:none;cursor:pointer;margin-top:var(--space-3)}
.btn::before,.btn::after{content:"";position:absolute;inset:0;border-radius:inherit}
.btn::after{z-index:-1;background:var(--bg);border:var(--border-width) solid var(--burgundy)}
.btn::before{z-index:-2;background:var(--olive)} /* hard offset shadow, hidden under the button at rest */
.btn.p{--bg:var(--accent-solid);color:var(--on-accent)}
.btn.s{color:var(--text)}
.W .btn.s{--bg:var(--surface)}.R .btn.s{--bg:var(--tile-where)}
.btn:active{transform:translate(1px,1px)}

/* Tiles: every tile is pinned at a tilt (<= --tilt-max) and overlaps its neighbour by --overlap, inside padding only */
.t{position:relative;transform:rotate(var(--r,0deg))}

/* 1 Hero: calm, centered, no tilt */
.H{position:relative;text-align:center;padding:var(--space-8) var(--space-4) var(--space-8)}
.H>*:not(.wv){position:relative;z-index:1}
/* Pause control (WCAG 2.2.2): required while the band drift, mascot wave and stamp loops run. Hidden until JS confirms motion is on */
.H>.mo{position:absolute;z-index:2;top:var(--space-3);left:var(--space-3);display:grid;place-items:center;width:44px;height:44px;padding:0;border:var(--border-width) solid var(--burgundy);border-radius:50%;background:var(--cream);color:var(--burgundy);cursor:pointer}
.H>.mo[aria-pressed=true]{background:var(--burgundy);color:var(--cream)}
.mo svg{width:18px;height:18px}
.mo[aria-pressed=true] .i-pause,.mo[aria-pressed=false] .i-play{display:none}
.H>.mo[hidden]{display:none}
/* logo.svg ships with ~40% empty canvas; the frame crops whitespace only (asset untouched) so the plate itself is 560px */
.logo{width:min(100%,560px);aspect-ratio:2980/730;overflow:hidden;margin:0 auto}
.logo img{display:block;width:119.97%;max-width:none;height:auto;margin:-21.48% 0 0 -10.07%}
.lead{margin:var(--space-5) auto var(--space-5);max-width:22em;text-wrap:balance}
.names{display:flex;justify-content:center;align-items:center;gap:var(--space-2)} /* one row at every width (fits at 320px) */
.nm .j{display:block;font-size:var(--text-4xl);color:var(--display-ink);text-shadow:.06em .06em 0 var(--display-echo)}
.nm .s{display:block;font-size:var(--text-3xl)}
.plus{font-family:var(--font-display);font-size:var(--text-4xl);line-height:1;color:var(--display-ink)}

/* Poster-style wave bands (DESIGN.md Band rules): flat paper-cut ribbons, each = opaque cream underlay + pin at opacity.
   Hero: full bleed, 80px past its bottom (under the mascots + When card top); phone and >=600 path sets. Room: >=900 only. */
.H>.wv{position:absolute;z-index:0;left:0;top:0;width:100%;height:calc(100% + 80px);pointer-events:none}
.wv-d,.wv-r{display:none}
@media (min-width:600px){.wv-p{display:none}.H>.wv-d{display:block}}

/* the room: tiles on cream (+ two edge bands at >=900) */
.room{position:relative;padding:0 var(--space-3)}
.room>.wv-r{position:absolute;z-index:0;inset:0;width:100%;height:100%;pointer-events:none}

/* 2 When */
.Wwrap{position:relative;z-index:4;margin:0 var(--space-2)}
.W{--r:calc(var(--tilt-max) * -1);--card-offset:4px;background:var(--surface);border:3px solid var(--burgundy);border-radius:var(--radius-card);box-shadow:var(--card-offset) var(--card-offset) 0 var(--olive); /* hard offset, 0 blur: rides the card's transform, never animated */padding:var(--space-6) var(--space-5) var(--space-7);z-index:2}
.W h2,.R h2{margin-bottom:var(--space-2)}
.W .hdl,.R .vn{font-size:var(--text-2xl);margin-bottom:var(--space-2)}
.W .dt{font-weight:600;font-size:var(--text-lg)}
.W .venue{margin:var(--space-4) 0 var(--space-2)}
.W .venue a{color:inherit;text-underline-offset:.2em}
/* signature dot: Lexend's round U+00B7, kept out of the link underline */
.dot{display:inline-block;font:600 var(--text-2xl)/0 var(--font-body);color:var(--display-ink);vertical-align:-.12em;padding:0 .12em;text-decoration:none}

/* 3 Where */
.R{--r:calc(var(--tilt-max) * .8);z-index:3;background:var(--tile-where);margin-top:calc(var(--overlap) * -1);padding:calc(var(--space-7) + var(--overlap)) var(--space-5) var(--space-7)}
.R address{font-style:normal;margin:var(--space-1) 0 var(--space-3);max-width:20em}
.R .btn{max-width:14em}

/* 4 Form */
.F{--r:0deg;z-index:2;background:var(--tile-form);margin-top:calc(var(--overlap) * -1);padding:calc(var(--space-7) + var(--overlap)) var(--space-5) calc(var(--space-7) + var(--overlap))}
.F.ok{background:var(--tile-success);color:var(--on-success)}
.F h2.f{font-size:var(--text-xl);margin-bottom:var(--space-5)}
.F .fld{margin-bottom:var(--space-4);max-width:28em}
.F label{display:block;font-weight:600;font-size:var(--text-sm);margin-bottom:var(--space-3)}
.F input{width:100%;min-height:48px;padding:0 var(--space-4);background:var(--surface-input);border:var(--border-width) solid var(--border);border-radius:var(--radius-control);font:400 var(--text-sm) var(--font-body);color:var(--text)}
.F .help{font-size:var(--text-xs);margin-top:var(--space-1)}
.F .err{display:none;margin-top:var(--space-1);font-weight:600;font-size:var(--text-sm)}
.F .invalid input{border-width:3px;border-color:var(--error)}
.F .invalid .err{display:block}
.F .btn{max-width:28em}
.F .priv{margin-top:var(--space-3);font-size:var(--text-xs);max-width:28em}
.hp{position:absolute;left:-9999px}
.F{display:grid}.F>form,.F>.done{grid-area:1/1}
.F .done{visibility:hidden;align-self:center}
.F.ok form{visibility:hidden}
.F.ok .done{visibility:visible}
.done{position:relative}
.done h2{font-size:var(--text-2xl);color:var(--mustard);margin:var(--space-3) 0}
.done h2:focus{outline:none}
.burst{position:absolute;left:20px;top:20px;pointer-events:none}
.burst i{position:absolute;width:14px;height:14px;margin:-7px;opacity:0}
.done p{max-width:24em}

/* 5 Illustrations: phone 2x2 = tree, sunglasses / bridge, windmill, so neither the mustard Form nor the olive success tile touches a same-color tile */
/* 5 Illustrations: a pinned band of overlapping tiles. Visible by default; motion is enhancement only */
.I{position:relative;z-index:4;display:grid;grid-template-columns:1fr 1fr;margin:calc(var(--overlap) * -1) var(--space-2) 0;padding-bottom:var(--space-6)}
.I svg{display:block;width:100%;height:auto;aspect-ratio:1}
.I .t:nth-child(odd){margin-right:calc(var(--overlap) * -.5)}
.I .t:nth-child(n+3){margin-top:calc(var(--overlap) * -.5)}
.i1{--r:calc(var(--tilt-max) * -1);z-index:1;--i:0}.i2{--r:var(--tilt-max);z-index:2;--i:1}.i3{--r:calc(var(--tilt-max) * .6);z-index:3;--i:2}.i4{--r:calc(var(--tilt-max) * -.8);z-index:2;--i:3}

/* 6 Footer: flat band */
.Z{position:relative;z-index:5;background:var(--band-footer);color:var(--text-on-dark);padding:var(--space-7) var(--space-5);text-align:center}
.Z .mk{font-size:var(--text-2xl);line-height:1.1;color:var(--mustard);margin-bottom:var(--space-3)}
.Z p{font-size:var(--text-sm)}
.Z .ask{max-width:34em;margin:0 auto;text-wrap:balance}

@media (min-width:600px){
 .names{gap:var(--space-6)}
}
@media (min-width:900px){
 :root{--tilt-max:2deg;--overlap:var(--space-5)}
 .H{padding:var(--space-8) var(--space-8) var(--space-9)}
 .room{display:grid;grid-template-columns:repeat(12,1fr);max-width:1200px;margin-inline:auto;padding:0 var(--space-6)}
 .Wwrap{grid-column:1/6;grid-row:1;margin:0}
 .room>.wv-r{display:block;left:calc(50% - 50vw);width:100vw} /* full viewport width behind the centred card wall */
 .W{--card-offset:6px;padding:var(--space-7) var(--space-6) calc(var(--space-7) + var(--overlap))}
 .R{grid-column:1/6;grid-row:2;margin-right:calc(var(--overlap) * -1);padding:calc(var(--space-7) + var(--overlap)) var(--space-8) var(--space-8)}
 .F{grid-column:6/13;grid-row:1/3;align-self:start;margin:var(--space-8) 0 0;padding:var(--space-8) var(--space-8) calc(var(--space-6) + var(--overlap)) calc(var(--space-8) + var(--overlap))}
 .I{grid-column:1/13;grid-row:3;display:flex;justify-content:center;margin:calc(var(--overlap) * -1) 0 0}
 .I .t{width:23%;margin:0 calc(var(--overlap) * -.5) 0 0}
 /* hills + toast first (under grey Where), so mustard/burgundy never touch the mustard/burgundy Form; --i drives the visual stagger */
 .i4{order:1;--i:0}.i3{order:2;--i:1}.i2{order:3;--i:2}.i1{order:4;--i:3}
}

/* Motion is opt-in. Default CSS = final, visible state (reduced motion, JS off, screenshots). Once-only, transform/opacity only. */
@media (prefers-reduced-motion:no-preference){
 /* e. wave bands: each drifts a few px and breathes <=3%, 22-38s, alternate, desynced. Paths overscan, so no edge ever shows */
 .wb{transform-box:fill-box;transform-origin:center;animation:wv var(--w) ease-in-out var(--wd,0s) infinite alternate}
 .wb1{--w:30s;--wx:10px;--wy:6px;--ws:1.015}
 .wb2{--w:24s;--wx:-8px;--wy:10px;--ws:1.02;--wd:-9s}
 .wb3{--w:34s;--wx:12px;--wy:-6px;--ws:1.02;--wd:-17s}
 .wb4{--w:27s;--wx:-10px;--wy:8px;--ws:1.01;--wd:-5s}
 .wb5{--w:38s;--wx:8px;--wy:-10px;--ws:1.02;--wd:-21s}
 .wb6{--w:22s;--wx:-6px;--wy:6px;--ws:1.03;--wd:-13s}
 .wb7{--w:32s;--wx:6px;--wy:-8px;--ws:1.02;--wd:-3s}
 .wb8{--w:26s;--wx:-8px;--wy:-6px;--ws:1.02;--wd:-19s}
 @keyframes wv{to{transform:translate(var(--wx),var(--wy)) scale(var(--ws))}}
 .paused .wb,.tab-hidden .wb,.wv.off .wb{animation-play-state:paused}
 /* a. hero entrance, ends ~1.15s */
 .logo{animation:drop var(--dur-entrance) var(--ease-spring) backwards}
 .nm>span{animation:rise var(--dur-entrance) var(--ease-out) backwards}
 .nm:first-child .j{animation-delay:200ms}.nm:last-child .j{animation-delay:280ms}
 .nm:first-child .s{animation-delay:400ms}.nm:last-child .s{animation-delay:480ms}
 .plus{animation:pop 500ms var(--ease-spring) 650ms backwards}
 @keyframes drop{from{transform:translateY(-40px);opacity:0}}
 @keyframes rise{from{transform:translateY(.5em);opacity:0}}
 @keyframes pop{from{transform:scale(0) rotate(-90deg);opacity:0}}
 /* b. tiles settle into their tilt as they enter the viewport. .pin is added by JS; no JS = already at rest */
 .pin .t{transition:transform var(--dur-entrance) var(--ease-out) calc(var(--i,0) * var(--stagger))}
 .pin .t:not(.in){transform:translateY(var(--space-5))}
 .pin .F:not(.in){transform:translateY(var(--space-2))}
 /* d. success swap + burst */
 .F.ok .done{animation:rise var(--dur-standard) var(--ease-out) backwards}
 .burst i{animation:burst var(--dur-burst) var(--ease-out)}
 @keyframes burst{from{transform:scale(.4);opacity:1}to{transform:translate(var(--dx),var(--dy)) rotate(var(--rot)) scale(1);opacity:0}}
}
/* c. hover: hover-capable pointers only */
@media (prefers-reduced-motion:no-preference) and (hover:hover) and (pointer:fine){
 .btn,.btn::before{transition:transform var(--dur-micro) var(--ease-out)}
 .btn:hover{transform:translate(calc(var(--lift) * -1),calc(var(--lift) * -1))}
 .btn:hover::before{transform:translate(var(--lift),var(--lift))}
 .btn:active,.btn:hover:active{transform:translate(1px,1px)}
 .btn:active::before{transform:none}
 .mv{transform-box:fill-box;transform-origin:center;transition:transform var(--dur-entrance) var(--ease-spring)}
 .sway{transform-origin:50% 100%}
}

/* Form states beyond the mock: submitting, network alert, phone error */
.btn:disabled{cursor:progress}
.F .alert{margin-top:var(--space-4);max-width:28em;padding:var(--space-3) var(--space-4);background:var(--surface-input);border:3px solid var(--error);border-radius:var(--radius-control);font-weight:600;font-size:var(--text-sm)}
.F input:read-only{cursor:progress}
/* phone: keep "Add to Google Calendar" on one line inside the When card */
@media (max-width:599px){.W .btn{font-size:var(--text-base);padding:0 var(--space-3)}}

/* 2-4 Card stamps: One complete band tile, shrunk, pinned in each info card's header row. Band after the form unchanged.
   Stamps are flat square tiles (no outline, no offset): the 3px burgundy outline + olive offset stays the When card's alone. */
.st{--ss:56px;display:block;width:var(--ss);aspect-ratio:1;transform:rotate(var(--sr));grid-column:2;grid-row:1/3;align-self:start}
.st svg{display:block;width:100%;height:100%}
/* header row (.hd wraps the heading lines + stamp): text column shrinks, stamp column is fixed; rest of the card untouched.
   Grid, not float: the heading wraps inside its own column at any width. */
.hd{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:var(--space-3)}
.hd>:not(.st){grid-column:1}
.F .hd h2{text-wrap:balance} /* stamp narrows the column; balance avoids a lone "INVITE?" line */
/* tilt: decorative, <= 6deg, opposite the card's lean (When leans left, Where right, Form flat) */
.W .st{--sr:5deg}.R .st{--sr:-5deg}.F .st{--sr:4deg}
@media (min-width:600px){.st{--ss:64px}}
@media (min-width:900px){.st{--ss:96px}.hd{column-gap:var(--space-4)}}
@media (prefers-reduced-motion:no-preference){
 /* tiny pop-in, once, as the card settles (transform only) */
 .pin .st{transition:transform var(--dur-entrance) var(--ease-spring) calc(var(--i,0) * var(--stagger) + 250ms)}
 .pin .t:not(.in) .st{transform:scale(.6) rotate(0deg)}
}

/* Mascots peek out from BEHIND the When card, outside its face. Zero-height anchor before .W inside .Wwrap (z 1 < W 2), as in corner-peeks.
   Phone/tablet/small desktop: heads + hats rise above the card's top edge near the top-left corner. */
.kl{stroke:var(--burgundy);stroke-width:3px;paint-order:stroke;stroke-linejoin:round;vector-effect:non-scaling-stroke} /* keyline on cream hat/brim/socks only */
.pk{position:relative;z-index:1;height:0;--mh:88px;--vis:.48}
.pm{position:absolute;top:calc(var(--mh) * var(--vis) * -1);height:var(--mh);aspect-ratio:36/92;transform:rotate(var(--lean));transform-origin:50% 96%}
.pm svg{display:block;width:100%;height:100%;overflow:visible}
.pm-her{left:var(--space-6);--lean:-6deg}
.pm-him{left:calc(var(--space-6) + var(--mh) * .42);--lean:5deg;--vis:.45}
.arm{transform-box:fill-box;transform-origin:50% 6%} /* shoulder ~(-12,47) in viewBox units */
/* Pets join the lineup after him (user pick 2026-10-13): same anchor, ~mascot scale, ~55% showing */
.pm-cat{height:calc(var(--mh) * .6);aspect-ratio:32/43;top:calc(var(--mh) * .6 * -.55);left:calc(var(--space-6) + var(--mh) * .98);--lean:-4deg}
.pm-dog{height:calc(var(--mh) * .64);aspect-ratio:37/46;top:calc(var(--mh) * .64 * -.56);left:calc(var(--space-6) + var(--mh) * 1.4);--lean:4deg}
@media (min-width:600px){.pk{--mh:96px}}
@media (min-width:900px){.pk{--mh:120px}.pm-her{left:var(--space-7)}.pm-him{left:calc(var(--space-7) + var(--mh) * .42)}.pm-cat{left:calc(var(--space-7) + var(--mh) * .98)}.pm-dog{left:calc(var(--space-7) + var(--mh) * 1.4)}}
/* Mascot wave: always on (user pin). Wave ~0.9s, then rest, on a 3s loop; him 120ms behind her.
   It loops, so the hero Pause control covers it (WCAG 2.2.2), as does a hidden tab. Reduced motion = static. */
@media (prefers-reduced-motion:no-preference){
 @keyframes wave{0%,30%,100%{rotate:0deg}5.4%{rotate:150deg}9.6%{rotate:120deg}14.4%{rotate:160deg}19.2%{rotate:122deg}24%{rotate:150deg}}
 @keyframes peekup{0%,30%,100%{translate:0 0}5.4%,24%{translate:0 -10px}}
 .pm{animation:peekup 3s var(--ease-out) infinite}
 .arm{animation:wave 3s var(--ease-out) infinite}
 .pm-him,.pm-him .arm{animation-delay:120ms}
 .pm-cat{animation-delay:240ms}.pm-dog{animation-delay:360ms}
 .paused .pm,.paused .arm,.tab-hidden .pm,.tab-hidden .arm{animation-play-state:paused}
}

/* Card stamps animate on a loop by default (user pin): blades turn, olives swing, sunglasses rock.
   Loops are covered by the Pause control and a hidden tab (WCAG 2.2.2). Reduced motion = static. */
@media (prefers-reduced-motion:no-preference){
 .st .mv{transform-box:fill-box;transform-origin:center}
 .st .blades{animation:st-spin 8s linear infinite}
 .st .swing{transform-origin:50% 0;animation:st-swing 3s ease-in-out infinite alternate}
 .st .lens{animation:st-rock 3.5s ease-in-out infinite alternate}
 @keyframes st-spin{to{transform:rotate(360deg)}}
 @keyframes st-swing{from{transform:rotate(-8deg)}to{transform:rotate(8deg)}}
 @keyframes st-rock{from{transform:rotate(-5deg)}to{transform:rotate(5deg)}}
 .paused .st .mv,.tab-hidden .st .mv{animation-play-state:paused}
}

/* Success road trip (user pick 2026-10-13, replaces the dance): the four drive off in the camper under the success copy.
   Default = still picture (reduced motion, no JS). Loops, so Pause / hidden tab stop it (WCAG 2.2.2). */
.trip{margin-top:var(--space-5);max-width:440px}
.trip svg{display:block;width:100%;height:auto;overflow:hidden;border-radius:6px}
.vn-wheel,.vn-puffs circle{transform-box:fill-box;transform-origin:center}
@media (prefers-reduced-motion:no-preference){
 .F.ok .vn-drive{animation:vn-in 1.4s cubic-bezier(.2,.8,.2,1) .3s backwards}
 .F.ok .vn-bob{animation:vn-bob .45s ease-in-out infinite alternate}
 .F.ok .vn-wheel{animation:vn-spin .6s linear infinite}
 .F.ok .vn-dash{animation:vn-road .5s linear infinite}
 .F.ok .vn-hills{animation:vn-hills 9s linear infinite}
 .F.ok .vn-puffs circle{animation:vn-puff 1.2s ease-out infinite}
 .F.ok .vn-puffs circle:nth-child(2){animation-delay:-.4s}.F.ok .vn-puffs circle:nth-child(3){animation-delay:-.8s}
 @keyframes vn-in{from{transform:translateX(-300px)}}
 @keyframes vn-bob{to{transform:translateY(-2px)}}
 @keyframes vn-spin{to{transform:rotate(360deg)}}
 @keyframes vn-road{to{stroke-dashoffset:30}}
 @keyframes vn-hills{to{transform:translateX(-360px)}}
 @keyframes vn-puff{0%{transform:translate(0,0) scale(.6);opacity:.9}100%{transform:translate(-26px,-10px) scale(1.6);opacity:0}}
 .paused .trip *,.tab-hidden .trip *{animation-play-state:paused}
}

/* Band loops (user pick 2026-10-13: gentle, always on, replaces the hover wiggles so phones see them too).
   Slow, small and staggered so the four tiles never move in sync. Paused by the Pause control, a hidden tab,
   and while the band is offscreen (.I.off). Reduced motion = static. */
@media (prefers-reduced-motion:no-preference){
 .I .mv{transform-box:fill-box;transform-origin:center}
 .I .sun{animation:bd-sun 6s ease-in-out infinite alternate}
 .I .clinkL,.I .clinkR{transform-origin:50% 100%;animation:bd-clink 4s ease-in-out infinite}
 .I .clinkR{animation-name:bd-clinkR}
 .I .spark{animation:bd-twinkle 4s ease-in-out infinite}
 .I .i2 .spark{animation-delay:-1.5s}.I .i2 .spark+.spark{animation-delay:-3s}
 /* pivot pinned in viewBox units at the rope's top (50,0): fill-box pivots drift in some browsers and the ball leaves the rope */
 .I .dangle{transform-box:view-box;transform-origin:50px 0;animation:bd-sway 5s ease-in-out -1s infinite alternate}
 .I .sw{transform-origin:50% 100%;animation:bd-sway 4s ease-in-out -2s infinite alternate}
 @keyframes bd-sun{from{transform:translateY(0)}to{transform:translateY(-5px)}}
 @keyframes bd-clink{0%,70%,100%{transform:rotate(0)}80%{transform:rotate(5deg)}90%{transform:rotate(0)}}
 @keyframes bd-clinkR{0%,70%,100%{transform:rotate(0)}80%{transform:rotate(-5deg)}90%{transform:rotate(0)}}
 @keyframes bd-twinkle{0%,70%,100%{transform:scale(1)}82%{transform:scale(1.35) rotate(45deg)}}
 @keyframes bd-sway{from{transform:rotate(-4deg)}to{transform:rotate(4deg)}}
 .paused .I *,.tab-hidden .I *,.I.off *{animation-play-state:paused}
}
