/* Decorative waves only: the target, arena and judged radius never move. */
.pulse-impact-particles{pointer-events:none;fill:none;stroke:#c8ffff;stroke-width:1.6;stroke-linecap:round}
.pulse-impact-particles path{opacity:0}
.pulse-game{--impact-reach:1.65;--particle-travel:39px;--impact-accent:#8cf6ff}
.pulse-game[data-impact="1"]{--impact-reach:2.7;--particle-travel:120px}
.pulse-game[data-impact="2"]{--impact-reach:2.95;--particle-travel:140px;--impact-accent:#ac98ff}
.pulse-game[data-impact="3"]{--impact-reach:3.2;--particle-travel:160px;--impact-accent:#b9a6ff}
.pulse-game[data-impact="4"]{--impact-reach:3.45;--particle-travel:180px;--impact-accent:#e3c4ff}
.pulse-game[data-echo="perfect"] .pulse-echo-layer .pulse-wave-a{stroke:#efffff;stroke-width:2;stroke-dasharray:none;filter:drop-shadow(0 0 3px #97faff99);animation:impact-wave .72s cubic-bezier(.12,.7,.2,1) both;--impact-delay:0s}
.pulse-game[data-echo="perfect"] .pulse-echo-layer .pulse-wave-b{stroke:#80edff;stroke-width:1.4;stroke-dasharray:none;animation:impact-wave .78s .06s cubic-bezier(.12,.7,.2,1) both}
.pulse-game[data-echo="perfect"] .pulse-echo-layer .pulse-wave-c{stroke:var(--impact-accent);stroke-width:1;stroke-dasharray:1 6;animation:impact-wave .8s .12s cubic-bezier(.12,.7,.2,1) both}
.pulse-game[data-impact="3"][data-echo="perfect"] .pulse-wave-c,.pulse-game[data-impact="4"][data-echo="perfect"] .pulse-wave-c{stroke-dasharray:none;stroke-width:1.6}
@keyframes impact-wave{0%{opacity:.95;transform:scale(1)}12%{opacity:.85}55%{opacity:.32}100%{opacity:0;transform:scale(var(--impact-reach))}}
.pulse-game[data-echo="perfect"] .pulse-impact-particles path{animation:impact-particle .75s ease-out both}
.pulse-impact-particles g:nth-child(3n+2) path{animation-delay:.025s}
.pulse-impact-particles g:nth-child(3n) path{animation-delay:.055s;stroke:var(--impact-accent)}
.pulse-game[data-impact="0"] .pulse-impact-particles g:nth-child(3n+1),.pulse-game[data-impact="0"] .pulse-impact-particles g:nth-child(3n+2),.pulse-game[data-impact="1"] .pulse-impact-particles g:nth-child(3n+1),.pulse-game[data-impact="1"] .pulse-impact-particles g:nth-child(3n+2){display:none}
.pulse-game[data-impact="2"] .pulse-impact-particles g:nth-child(3n+2){display:none}
@keyframes impact-particle{0%{opacity:0;transform:translateX(0)}8%{opacity:.95}48%{opacity:.6}100%{opacity:0;transform:translateX(var(--particle-travel))}}
.pulse-game[data-hit="perfect"] .pulse-feedback{animation:impact-label .5s ease-out both!important;transform-origin:center;transform:scale(1)!important}
@keyframes impact-label{0%{scale:.96;color:#fff;text-shadow:0 0 15px #b5ffff}18%{scale:1.12;color:#fff;text-shadow:0 0 10px #b5ffff}100%{scale:1;color:#bbf6ff;text-shadow:0 0 5px #70e8f54d}}
.pulse-game[data-suspended="true"] .pulse-impact-particles path,.pulse-game[data-state="help"] .pulse-impact-particles path,.pulse-game[data-state="paused"] .pulse-impact-particles path{animation-play-state:paused}
@media(prefers-reduced-motion:reduce){.pulse-impact-particles{display:none}.pulse-game[data-echo="perfect"] .pulse-echo-layer circle,.pulse-game[data-hit="perfect"] .pulse-feedback{animation:none!important;scale:1!important}.pulse-game[data-hit="perfect"] .pulse-feedback{color:#d4ffff;text-shadow:0 0 5px #70e8f54d}}

/* Expanded combo waves may leave the arena, but never widen the page. */
#play-dialog{overflow-x:clip}
.pulse-game .pulse-arena>svg{overflow:visible}
/* Nine combos: a two-stage platinum finish, completed before the result screen. */
.pulse-game[data-impact="4"]{--impact-reach:4.15;--particle-travel:220px;--impact-accent:#ffe9ae}
.pulse-game[data-impact="4"][data-echo="perfect"] .pulse-echo-layer .pulse-wave-a{stroke:#eaffff;stroke-width:2.6;animation:impact-finale-first .76s cubic-bezier(.12,.7,.2,1) both;filter:drop-shadow(0 0 5px #baffff99)}
.pulse-game[data-impact="4"][data-echo="perfect"] .pulse-echo-layer .pulse-wave-b{stroke:#fff0c4;stroke-width:2;animation:impact-finale-second .78s .17s cubic-bezier(.12,.7,.2,1) both;filter:drop-shadow(0 0 5px #ffdf9299)}
.pulse-game[data-impact="4"][data-echo="perfect"] .pulse-echo-layer .pulse-wave-c{stroke:#fff8e5;stroke-width:1.6;stroke-dasharray:2 5;animation:impact-finale-second .72s .26s ease-out both}
.pulse-game[data-impact="4"][data-echo="perfect"] .pulse-impact-particles path{stroke:#ffefbe;stroke-width:2.2;animation:impact-finale-particle .94s ease-out both;filter:drop-shadow(0 0 2px #ffe2a688)}
.pulse-game[data-impact="4"] .pulse-impact-particles g:nth-child(3n) path{stroke:#c8ffff;animation-delay:.035s}
.pulse-game[data-impact="4"] .pulse-impact-particles g:nth-child(3n+2) path{stroke:#fff;animation-delay:.06s}
.pulse-game[data-impact="4"][data-hit="perfect"] #pulse-combo{color:#fff3cf;text-shadow:0 0 9px #ffd47799;transform-origin:center;animation:impact-finale-combo .98s ease-out both}
@keyframes impact-finale-first{0%{opacity:1;transform:scale(1)}16%{opacity:.85}65%{opacity:.28}100%{opacity:0;transform:scale(4.15)}}
@keyframes impact-finale-second{0%{opacity:0;transform:scale(1)}12%{opacity:.95}55%{opacity:.5}100%{opacity:0;transform:scale(3.7)}}
@keyframes impact-finale-particle{0%{opacity:0;transform:translateX(0) scaleX(1)}9%{opacity:1}40%{opacity:.85;transform:translateX(120px) scaleX(1.8)}100%{opacity:0;transform:translateX(220px) scaleX(.5)}}
@keyframes impact-finale-combo{0%{scale:1;color:#bdfaff}22%{scale:1.27;color:#fff}48%{scale:1.12;color:#fff3cf}100%{scale:1;color:#fff3cf}}
@media(prefers-reduced-motion:reduce){.pulse-game[data-impact="4"] #pulse-combo{animation:none!important;scale:1}}
/* PULSE type system: one family stack, white primary / muted secondary,
   restrained cyan glow reserved for success. Fixed line boxes prevent jumps. */
#play-dialog,#pulse-help,.pulse-share-dialog{--pulse-font:'Space Grotesk','Noto Sans JP',sans-serif;--pulse-ink:#fff;--pulse-muted:#a6bdcc;--pulse-glow:0 0 7px #70e8f566,0 0 18px #70e8f533;font-family:var(--pulse-font);color:var(--pulse-ink)}
.pulse-game :is(button,p,span,strong,b,h3),#pulse-help :is(button,p,span,strong,h2,h3,label,output),.pulse-share-dialog :is(button,p,h2,a){font-family:var(--pulse-font)}
.pulse-game :is(.pulse-stats strong,.pulse-rank-total,.pulse-hint){font-variant-numeric:tabular-nums;color:var(--pulse-ink);text-shadow:none}
.pulse-game .pulse-stats strong{font-size:clamp(22px,3dvh,28px);font-weight:500;line-height:1.25}
.pulse-game :is(.pulse-stats span,.pulse-rank-label){font-size:10px;font-weight:500;letter-spacing:.16em;color:var(--pulse-muted);text-shadow:none}
.pulse-game :is(.pulse-precision,.pulse-score-breakdown,.pulse-rank-counts){font-family:var(--pulse-font);font-size:12px;line-height:1.5;letter-spacing:.04em;color:var(--pulse-muted);text-shadow:none}
.pulse-game :is(.pulse-start,.pulse-share-button,.pulse-help-button){font-family:var(--pulse-font);font-size:12px;font-weight:500;letter-spacing:.12em}
.pulse-game .pulse-hint,.pulse-game .pulse-hint *{color:#fff;text-shadow:none}
.pulse-game .pulse-hint b,.pulse-game .pulse-tap-bonus{font-size:clamp(26px,4dvh,34px);font-weight:700;line-height:1}
.pulse-game .pulse-score-plus{font-size:22px;line-height:1}
.pulse-game .pulse-feedback{font-family:var(--pulse-font);font-size:clamp(24px,3.4dvh,30px);font-weight:500;letter-spacing:.1em;height:44px;min-height:44px;line-height:44px;color:#fff;text-shadow:none}
.pulse-game[data-hit="good"] .pulse-feedback,.pulse-game[data-hit="miss"] .pulse-feedback{font-size:24px;color:var(--pulse-muted);text-shadow:none}
.pulse-game[data-hit="great"] .pulse-feedback{font-size:28px;color:#fff;text-shadow:0 0 8px #70e8f533}
.pulse-game[data-hit="perfect"] .pulse-feedback{font-size:32px;color:#fff;text-shadow:var(--pulse-glow)}
.pulse-game .pulse-precision strong{font-size:14px;font-weight:600;letter-spacing:.08em}
.pulse-game[data-state="finished"] .pulse-rank-total{font-family:var(--pulse-font);font-size:clamp(25px,4.5dvh,38px);font-weight:500;line-height:1.2;color:#fff;text-shadow:none}
.pulse-game[data-state="finished"] #pulse-rank-name{font-family:var(--pulse-font);font-size:clamp(24px,3.8dvh,30px);font-weight:500;color:#fff;text-shadow:var(--pulse-glow)}
.pulse-game[data-state="finished"] #pulse-rank-copy{font-family:var(--pulse-font);font-size:13px;line-height:1.6;color:var(--pulse-muted);text-shadow:none}
.pulse-game[data-state="finished"] .pulse-feedback{height:auto;min-height:0;line-height:1.5;font-size:11px}
/* Anchor content beneath controls rather than centering in unused height. */
.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"],[data-state="finished"]) .pulse-content{flex:0 0 auto;justify-content:flex-start;margin:0 auto;padding:clamp(10px,2dvh,20px) 0 20px}
.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) .pulse-arena{width:min(100%,420px,43dvh);flex:0 0 auto;margin-top:12px;margin-bottom:calc(-1 * min(48px,4.8dvh))}
@media(max-width:600px){
.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) .pulse-arena{width:min(100%,350px,36dvh);margin-top:10px;margin-bottom:calc(-1 * min(36px,4dvh))}
.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"],[data-state="finished"]) .pulse-content{padding-top:10px}
.pulse-game[data-state="finished"] .rank-portrait{width:min(190px,24dvh)}
.pulse-game[data-state="finished"] .pulse-return-title{margin-top:12px}
}
@media(max-height:650px){
.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) .pulse-arena{width:min(100%,300px,34dvh);margin-top:8px;margin-bottom:-24px}
.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"],[data-state="finished"]) .pulse-content{padding-top:6px}
}
@media(prefers-reduced-motion:reduce){.pulse-game .pulse-feedback,.pulse-game[data-state="finished"] #pulse-rank-name{text-shadow:none}}
/* Leave room for the outer dialog padding on laptop-height screens. */
.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) .pulse-content{padding-bottom:4px}
/* Separate the performance summary from the rank heading. */
.pulse-game[data-state="finished"] .pulse-rank-label{margin-top:22px}
@media(max-height:650px){.pulse-game[data-state="finished"] .pulse-rank-label{margin-top:16px}}
/* Mobile result breathing room; preserve keyboard focus for sharing. */
@media(max-width:600px){.pulse-game[data-state="finished"] .pulse-content{padding-top:28px}}
@media(max-width:600px) and (max-height:650px){.pulse-game[data-state="finished"] .pulse-content{padding-top:20px}}
#play-dialog .pulse-share-button[data-focus-input="pointer"]:focus{outline:none;box-shadow:none}
/* Distinguish performance figures from the rank section label. */
.pulse-game[data-state="finished"] .pulse-rank-counts{color:#fff;text-shadow:none}
.pulse-game[data-state="finished"] .pulse-rank-label{color:#8ce3ef;text-shadow:0 0 8px #70e8f526}
/* Place the mobile in-play restart near the bottom without moving the beacon. */
@media(max-width:600px){
 .pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]){min-height:100dvh}
 .pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) .pulse-content{flex:1 0 auto;min-height:0;padding-bottom:max(12px,env(safe-area-inset-bottom))}
 .pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) #pulse-start{margin-top:auto;flex-shrink:0}
 .pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) .pulse-result{margin-bottom:20px}
}
/* Result text is white; only YOUR RANK retains its cyan accent. */
.pulse-game[data-state="finished"] :is(.pulse-rank-total,.pulse-score-breakdown,.pulse-rank-counts,#pulse-rank-name,#pulse-rank-copy){color:#fff}
/* Cyan identifies the incoming pulse; judged points remain white. */
.pulse-game .pulse-hint .pulse-round-label,.pulse-game .pulse-hint .pulse-round-number{color:#8ce3ef}
/* Keep combo glyphs sharp at every streak, including the finale. */
.pulse-game #pulse-combo{font-weight:600;color:#fff;text-shadow:none!important;filter:none!important;animation:none!important;transform:none!important;scale:1!important;opacity:1}
/* The moving SVG circle changes radius every frame: avoid rerasterizing two
   blur passes. Impact/echo rings keep their existing neon afterglow. */
.pulse-game #pulse-orbit{filter:none;stroke:#efffff;stroke-width:2.7}
/* Countdown stays inside the beacon; the full-screen dimming layer is retained. */
.pulse-game #pulse-countdown-number{position:absolute;left:var(--count-x,50%);top:var(--count-y,50%);transform:translate(-50%,-50%);font-family:var(--pulse-font);font-size:var(--count-size,80px);font-weight:500;line-height:1;letter-spacing:0;color:#fff;text-shadow:0 0 12px #70e8f533}

/* Keep countdown and live play geometry identical, with a little logo breathing room. */
.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) #pulse-title{width:min(100%,420px);margin-top:12px}
@media(max-width:600px){.pulse-game:is([data-state="playing"],[data-state="paused"],[data-state="countdown"]) #pulse-title{width:min(100%,300px)}}
