:root{--bg-primary: #0a0a0f;--bg-surface: #1a1a2e;--bg-elevated: #25253d;--text-primary: #e8e8f0;--text-secondary: #8888a0;--accent: #6c5ce7;--accent-glow: rgba(108, 92, 231, .3);--success: #00d68f;--success-glow: rgba(0, 214, 143, .25);--danger: #ff4757;--danger-glow: rgba(255, 71, 87, .25);--warning: #ffa502;--radius: 14px;--radius-sm: 10px}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}html,body{height:100%;overflow-y:auto;overflow-x:hidden;background:var(--bg-primary);color:var(--text-primary);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;user-select:none;-webkit-user-select:none;touch-action:manipulation}#app{min-height:100dvh;min-height:100vh;display:flex;flex-direction:column;width:100%;max-width:480px;min-width:300px;margin:0 auto;padding:0 14px;padding-top:env(safe-area-inset-top,8px);padding-bottom:env(safe-area-inset-bottom,8px)}.unsupported-banner{background:#ff47571f;border:1px solid var(--danger);border-radius:var(--radius-sm);padding:8px 12px;margin-bottom:2px;display:flex;flex-direction:column;gap:3px}.unsupported-banner-header{display:flex;justify-content:space-between;align-items:center}.unsupported-banner strong{color:var(--danger);font-size:12px}.unsupported-banner-close{background:none;border:none;color:var(--text-secondary);font-size:18px;line-height:1;padding:0 2px;cursor:pointer}.unsupported-banner>span{color:var(--text-secondary);font-size:11px;line-height:1.3}.unsupported-envs{display:flex;flex-wrap:wrap;align-items:center;gap:3px 5px}.unsupported-env-sep{color:var(--text-secondary);font-size:10px;opacity:.4}.unsupported-env{font-size:10px;padding:1px 5px;border-radius:3px;white-space:nowrap}.unsupported-env.ok{background:#00d68f1f;color:var(--success);border:1px solid rgba(0,214,143,.25)}.unsupported-env.no{background:#ff475714;color:var(--text-secondary);border:1px solid rgba(255,71,87,.2)}.no-ble .header{display:none}.unsupported{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center;gap:12px;padding:40px}.unsupported h2{color:var(--danger);font-size:22px}.unsupported p{color:var(--text-secondary);font-size:15px;line-height:1.5}#toast-container{position:fixed;top:env(safe-area-inset-top,12px);left:50%;transform:translate(-50%);z-index:9999;display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none}.toast{background:var(--bg-elevated);color:var(--text-primary);border:1px solid var(--text-secondary);border-radius:var(--radius-sm);padding:10px 20px;font-size:13px;font-weight:600;letter-spacing:.03em;box-shadow:0 4px 20px #00000040;opacity:0;transform:translateY(-12px);transition:opacity .25s ease,transform .25s ease;pointer-events:auto}.toast.visible{opacity:1;transform:translateY(0)}.toast.toast-error{color:var(--danger);border-color:var(--danger);box-shadow:0 4px 20px #ff475740}.toast.toast-success{color:var(--success);border-color:var(--success);box-shadow:0 4px 20px #00d68f40}.toast.toast-info{color:var(--text-primary);border-color:var(--text-secondary);box-shadow:0 4px 20px #00000040}.status-bar{display:flex;align-items:center;gap:10px;padding:8px 0 4px;flex-shrink:0}.status-dot{width:10px;height:10px;border-radius:50%;background:var(--text-secondary);transition:background .3s;flex-shrink:0}.status-dot.connecting{background:var(--warning);animation:pulse 1.2s ease-in-out infinite}.status-dot.connected{background:var(--success);box-shadow:0 0 8px var(--success-glow)}.status-text{font-size:13px;color:var(--text-secondary);font-weight:500;letter-spacing:.02em;flex:1}.help-btn{width:30px;height:30px;border-radius:50%;border:2px solid var(--accent);background:#6c5ce71f;color:var(--accent);font-size:15px;font-weight:800;cursor:pointer;flex-shrink:0;margin-left:auto;transition:all .2s ease;display:flex;align-items:center;justify-content:center;padding:0;line-height:1;box-shadow:0 0 8px var(--accent-glow)}.help-btn:active{transform:scale(.92)}.help-overlay{position:fixed;inset:0;z-index:9000;background:#000000b3;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;padding:16px}.help-overlay[hidden]{display:none}.help-modal{background:var(--bg-surface);border:1px solid var(--bg-elevated);border-radius:var(--radius);width:100%;max-width:440px;max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px);display:flex;flex-direction:column;overflow:hidden}.help-header{display:flex;align-items:center;justify-content:space-between;padding:14px 16px 10px;border-bottom:1px solid var(--bg-elevated);flex-shrink:0}.help-header h2{font-size:16px;font-weight:700;letter-spacing:.04em;color:var(--text-primary)}.help-close{width:32px;height:32px;border:none;background:transparent;color:var(--text-secondary);font-size:22px;cursor:pointer;border-radius:50%;display:flex;align-items:center;justify-content:center;padding:0;line-height:1;transition:color .15s}.help-close:active{color:var(--text-primary)}.help-body{overflow-y:auto;padding:14px 16px 20px;-webkit-overflow-scrolling:touch}.help-body section{margin-bottom:18px}.help-body section:last-child{margin-bottom:0}.help-body h3{font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-primary);margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid var(--bg-elevated)}.help-body p{font-size:12px;line-height:1.5;color:var(--text-secondary);margin-bottom:6px}.help-body p:last-child{margin-bottom:0}.help-body b{color:var(--text-primary);font-weight:600}.help-body ul{margin:4px 0 6px 16px;padding:0}.help-body li{font-size:12px;line-height:1.5;color:var(--text-secondary);margin-bottom:2px}.help-mode{margin-bottom:10px}.help-mode:last-child{margin-bottom:0}.help-mode h4{font-size:12px;font-weight:700;color:var(--warning);margin-bottom:2px}.help-mode-devotion{color:var(--accent)!important}.help-mode-brutal{color:var(--danger)!important}.help-mode-siren{color:#d084ff!important}@keyframes pulse{0%,to{opacity:1}50%{opacity:.3}}.header{text-align:center;padding:4px 0 2px;flex-shrink:0}.header h1{font-size:22px;font-weight:700;letter-spacing:.08em;color:var(--text-primary)}.header .subtitle{font-size:10px;color:var(--text-secondary);letter-spacing:.15em;text-transform:uppercase;margin-top:1px}.viz{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:0;padding:0}.viz-layout{display:grid;grid-template-columns:80px 1fr 60px;align-items:end;width:100%;height:clamp(100px,25dvh,400px);overflow:hidden}.viz-info{display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end;gap:1px;min-height:28px;padding-bottom:8px}.viz-mode{font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--warning)}.viz-mode.manual{color:var(--accent)}.viz-phase{font-size:9px;font-weight:600;letter-spacing:.08em;color:var(--text-secondary);text-transform:uppercase}.viz-device-row{display:flex;align-items:flex-end;justify-content:center;position:relative;height:399px;transform:scale(var(--viz-scale, 1));transform-origin:bottom center;flex-shrink:0;margin-top:calc(-399px * (1 - var(--viz-scale, 1)))}.keon-device{display:flex;align-items:flex-end;gap:0;height:173px;position:relative}.keon-grip{display:flex;flex-direction:column;justify-content:center;gap:6px;padding:29px 0}.keon-ridge{width:8px;height:17px;border-radius:4px;background:#2a2a3a;border:1px solid #3a3a50}.keon-grip-left .keon-ridge{border-radius:4px 1px 1px 4px}.keon-grip-right .keon-ridge{border-radius:1px 4px 4px 1px}.keon-led{width:5px;border-radius:2px;background:#6464ff14;margin:20px 0;transition:background .5s,box-shadow .5s}.keon-led.active{background:#648cff99;box-shadow:0 0 10px #648cff80}.keon-housing{position:relative;width:103px;height:173px;border-radius:20px;background:linear-gradient(180deg,#1a1a28,#222235 30%,#1e1e30 70%,#181828);border:2px solid #2e2e45;box-shadow:inset 0 2px 4px #ffffff0a,0 4px 16px #0006}.keon-housing:after{content:"";position:absolute;top:-3px;left:50%;transform:translate(-50%);width:66px;height:43px;background:var(--bg-primary);border-radius:0 0 50% 50%;z-index:3;border-bottom:2px solid #2e2e45;border-left:2px solid #2e2e45;border-right:2px solid #2e2e45}.keon-opening{position:absolute;top:-2px;left:-2px;right:-2px;height:14px;border-radius:20px 20px 0 0;background:linear-gradient(180deg,#282840,#1e1e30);border:2px solid #2e2e45;border-bottom:none;z-index:4}.keon-sleeve{position:absolute;left:14px;right:14px;height:216px;border-radius:12px;background:linear-gradient(180deg,#2a2a40,#232338 15%,#1e1e30,#252540 85%,#2e2e48);border:1.5px solid #3a3a55;top:-38px;transition:top var(--move-duration, .3s) linear;z-index:5;box-shadow:inset 0 1px 3px #ffffff0f,0 2px 10px #0006}.pb-attachment{position:absolute;top:-36px;left:50%;transform:translate(-50%);width:58px;height:36px;z-index:10}.pb-dome{position:absolute;top:0;left:0;right:0;height:26px;border-radius:29px 29px 6px 6px;background:linear-gradient(180deg,#2e2e4a,#252540 40%,#1e1e35);border:1.5px solid #3a3a58;border-bottom:none;box-shadow:inset 0 2px 4px #ffffff0d,0 -2px 8px #0000004d}.pb-ring{position:absolute;bottom:0;left:-2px;right:-2px;height:12px;border-radius:3px;background:linear-gradient(180deg,#353550,#2a2a42);border:1.5px solid #40405e}.pb-glow{position:absolute;top:2px;left:4px;right:4px;height:20px;border-radius:25px 25px 4px 4px;background:transparent;opacity:0;transition:opacity .15s ease,background .12s ease,box-shadow .12s ease;pointer-events:none;z-index:1}.pb-attachment.sucking .pb-dome{border-color:rgba(var(--pb-glow-r, 155),var(--pb-glow-g, 89),var(--pb-glow-b, 182),var(--pb-glow-alpha, .5));box-shadow:inset 0 2px 6px rgba(var(--pb-glow-r, 155),var(--pb-glow-g, 89),var(--pb-glow-b, 182),calc(var(--pb-glow-alpha, .3) * .4)),0 -3px 14px rgba(var(--pb-glow-r, 155),var(--pb-glow-g, 89),var(--pb-glow-b, 182),var(--pb-glow-alpha, .3));transition:border-color .15s ease,box-shadow .15s ease}.pb-attachment.sucking .pb-ring{border-color:rgba(var(--pb-glow-r, 155),var(--pb-glow-g, 89),var(--pb-glow-b, 182),calc(var(--pb-glow-alpha, .3) * .6));transition:border-color .15s ease}.keon-sleeve:before{content:"";position:absolute;top:-1px;left:-1px;right:-1px;height:12px;border-radius:12px 12px 0 0;background:linear-gradient(180deg,#3a3a58,#2e2e48);border:1.5px solid #45456a;border-bottom:none}.keon-sleeve-flare{position:absolute;bottom:0;left:-6px;right:-6px;height:43px;border-radius:0 0 17px 17px;background:linear-gradient(180deg,#2e2e48,#353550 40%,#3a3a58);border:1.5px solid #48486a;border-top:1px solid #3a3a55}.keon-sleeve-insert{position:absolute;bottom:6px;left:8px;right:8px;height:29px;border-radius:0 0 12px 12px;background:linear-gradient(180deg,#d2b4a00f,#d2b4a02e 60%,#c8aa9647);border:1px solid rgba(200,170,150,.15)}.stroke-range{display:flex;flex-direction:column;align-items:center;min-height:120px;max-height:200px;height:100%;gap:3px;align-self:end;padding-bottom:4px}.stroke-range-label{font-size:9px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--text-secondary)}.stroke-range-track{position:relative;width:44px;flex:1;border-radius:22px;background:var(--bg-elevated);cursor:pointer;touch-action:none;overflow:hidden}.stroke-range-fill{position:absolute;left:0;right:0;background:#6c5ce759;border-radius:22px;transition:top .15s ease,bottom .15s ease;top:var(--range-top, 30%);bottom:var(--range-bottom, 0%)}.stroke-range-handle{position:absolute;left:50%;transform:translate(-50%);width:36px;height:10px;border-radius:5px;background:var(--accent);box-shadow:0 0 8px var(--accent-glow);pointer-events:none;z-index:1}.stroke-range-handle-top{top:var(--range-top, 30%);margin-top:-5px}.stroke-range-handle-bottom{bottom:var(--range-bottom, 0%);margin-bottom:-5px}.stroke-range-value{font-size:11px;font-weight:700;color:var(--accent);font-variant-numeric:tabular-nums}.stroke-range.pattern-disabled{opacity:.35;pointer-events:none}.viz-stats{font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--text-secondary);font-variant-numeric:tabular-nums;min-height:14px;text-align:center}.controls{display:flex;flex-direction:column;gap:8px;padding-bottom:12px;flex-shrink:0}.speed-section,.powerblow-section{background:var(--bg-surface);border-radius:var(--radius-sm);padding:10px 14px}.speed-label-row{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px}.speed-label{font-size:10px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--text-secondary)}.speed-value{font-size:15px;font-weight:700;color:var(--accent);font-variant-numeric:tabular-nums}.speed-slider{-webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:3px;outline:none;cursor:pointer;background:linear-gradient(to right,var(--accent) 0%,var(--accent) var(--val, 30%),var(--bg-elevated) var(--val, 30%),var(--bg-elevated) 100%);transition:background .05s}.speed-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:28px;height:28px;border-radius:50%;background:var(--accent);box-shadow:0 0 10px var(--accent-glow),0 2px 6px #0006;border:3px solid var(--bg-surface);cursor:pointer;transition:transform .15s ease,box-shadow .15s ease}.speed-slider::-webkit-slider-thumb:hover,.speed-slider::-webkit-slider-thumb:active{transform:scale(1.15);box-shadow:0 0 16px var(--accent-glow),0 2px 10px #00000080}.speed-slider::-moz-range-thumb{width:28px;height:28px;border-radius:50%;background:var(--accent);box-shadow:0 0 10px var(--accent-glow),0 2px 6px #0006;border:3px solid var(--bg-surface);cursor:pointer}.speed-slider::-moz-range-track{height:6px;border-radius:3px;background:var(--bg-elevated)}.speed-slider::-moz-range-progress{height:6px;border-radius:3px;background:var(--accent)}.speed-hints{display:flex;justify-content:space-between;margin-top:4px}.speed-hints span{font-size:9px;color:var(--text-secondary);letter-spacing:.05em;text-transform:uppercase}.depth-section{display:flex;gap:6px}.depth-btn{flex:1;padding:8px 4px;border:2px solid var(--bg-elevated);border-radius:var(--radius-sm);background:var(--bg-surface);color:var(--text-secondary);font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;transition:all .2s ease;text-align:center;min-width:0}.depth-btn:active{transform:scale(.96)}.depth-btn.active{border-color:var(--accent);background:#6c5ce71f;color:var(--accent);box-shadow:0 0 12px var(--accent-glow)}.pattern-section{display:flex;flex-direction:column;gap:6px}.pattern-label{font-size:10px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--text-secondary)}.pattern-buttons{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}.pattern-btn{padding:8px 4px;border:2px solid var(--bg-elevated);border-radius:var(--radius-sm);background:var(--bg-surface);color:var(--text-secondary);font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;cursor:pointer;transition:all .2s ease;text-align:center;min-width:0}.pattern-btn:active{transform:scale(.96)}.pattern-btn.active{border-color:var(--warning);background:#ffa5021f;color:var(--warning);box-shadow:0 0 12px #ffa50240}.pattern-btn-devotion{background:var(--bg-elevated);border-color:var(--accent);color:var(--accent);font-size:10px;letter-spacing:.08em}.pattern-btn-devotion.active{border-color:var(--accent);background:#6c5ce733;color:#a78bfa;box-shadow:0 0 16px var(--accent-glow)}.pattern-btn-brutal{background:var(--bg-elevated);border-color:var(--danger);color:var(--danger);font-size:10px;letter-spacing:.08em}.pattern-btn-brutal.active{border-color:#ff1a1a;background:#ff1a1a2e;color:#ff1a1a;box-shadow:0 0 20px #ff1a1a66}.pattern-btn-siren{background:var(--bg-elevated);border-color:#b44dff;color:#d084ff;font-weight:700;font-size:10px;letter-spacing:.08em}.pattern-btn-siren.active{border-color:#c266ff;background:#b44dff26;color:#d084ff;box-shadow:0 0 18px #b44dff66}.stroke-range.pattern-disabled,.depth-btn.pattern-disabled{opacity:.35;pointer-events:none}.speed-value.auto-mode{color:var(--warning)}.start-stop-btn{width:100%;padding:12px;border:none;border-radius:var(--radius-sm);background:var(--success);color:#fff;font-size:15px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:all .2s ease;box-shadow:0 4px 20px var(--success-glow)}.start-stop-btn:active:not(:disabled){transform:scale(.97)}.start-stop-btn:disabled{background:var(--bg-elevated);color:var(--text-secondary);box-shadow:none;cursor:not-allowed}.start-stop-btn.active{background:var(--danger);box-shadow:0 4px 20px var(--danger-glow)}.connect-btn{width:100%;padding:10px;border:2px solid var(--bg-elevated);border-radius:var(--radius-sm);background:transparent;color:var(--text-secondary);font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;transition:all .2s ease}.connect-btn:active:not(:disabled){transform:scale(.97)}.connect-btn:disabled{opacity:.5;cursor:not-allowed}.connect-btn.unsupported{opacity:.3;text-decoration:line-through}.connect-btn.connected{border-color:var(--success);color:var(--success)}.pb-connect-btn,.pb-connect-btn.connected{border-color:#9b59b6;color:#9b59b6}.powerblow-section .speed-value{color:#9b59b6}.pb-slider{background:linear-gradient(to right,#9b59b6 0%,#9b59b6 var(--val, 70%),var(--bg-elevated) var(--val, 70%),var(--bg-elevated) 100%)!important}.pb-slider::-webkit-slider-thumb{background:#9b59b6!important;box-shadow:0 0 10px #9b59b666,0 2px 6px #0006!important}.pb-slider::-moz-range-thumb{background:#9b59b6!important;box-shadow:0 0 10px #9b59b666,0 2px 6px #0006!important}.pb-slider::-moz-range-progress{background:#9b59b6!important}.pb-blast-btn{width:100%;margin-top:8px;padding:10px;border:2px solid #9b59b6;border-radius:var(--radius-sm);background:var(--bg-surface);color:#9b59b6;font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:all .15s ease;touch-action:none;user-select:none;-webkit-user-select:none}.pb-blast-btn.active{background:#9b59b6;color:#fff;box-shadow:0 0 20px #9b59b699,0 0 40px #9b59b64d;transform:scale(.97);animation:blast-pulse .6s ease-in-out infinite alternate}@keyframes blast-pulse{0%{box-shadow:0 0 20px #9b59b699}to{box-shadow:0 0 30px #9b59b6cc,0 0 60px #9b59b666}}@media(max-height:800px){.header .subtitle{display:none}}@media(max-height:700px){.header{display:none}}
