Arctiq / index.html
VSPAN's picture
Update index.html
4fb406e verified
Raw
History Blame Contribute Delete
75.3 kB
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>VICKERS</title>
<link rel="icon" type="image/png" href="image/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="image/favicon.svg" />
<link rel="shortcut icon" href="image/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="image/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="VICKERS" />
<link rel="manifest" href="/site.webmanifest" />
<link href="https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;1,300&family=Outfit:wght@200;300;400;500;600;700&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%;overflow-x:hidden}
body{
min-height:100vh;display:flex;flex-direction:column;align-items:center;
justify-content:flex-start;padding:20px 0 70px;
font-family:'Outfit',sans-serif;
user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;
background:var(--page-bg,#0e0e10);
transition:background 600ms;
}
/* ═══════════════════════════════════════════
THEMES
═══════════════════════════════════════════ */
:root{--page-bg:#0e0e10}
.remote{
--bg:#111316;--surf:#1a1c21;--surf2:#1e2026;
--hi:rgba(255,255,255,.045);--lo:rgba(0,0,0,.65);
--accent:#00e8ff;--accent2:#007a8a;--glow:rgba(0,232,255,.22);
--scr:#070a0d;--tdim:rgba(255,255,255,.18);--tmid:rgba(255,255,255,.45);
--tbright:rgba(255,255,255,.85);
--eye:#ff2d55;--eye-glow:rgba(255,45,85,.5);
--pwr:#ff3b5c;--pwr-glow:rgba(255,59,92,.35);
--r:28px;--btn-r:12px;
}
.remote.chalk{
--surf:#dedad3;--surf2:#e2ddd6;
--hi:rgba(255,255,255,.75);--lo:rgba(0,0,0,.11);
--accent:#7c5cfc;--accent2:#b8a6f8;--glow:rgba(124,92,252,.18);
--scr:#130e24;--tdim:rgba(0,0,0,.17);--tmid:rgba(0,0,0,.4);--tbright:rgba(0,0,0,.72);
--eye:#7c5cfc;--eye-glow:rgba(124,92,252,.55);
--pwr:#7c5cfc;--pwr-glow:rgba(124,92,252,.3);
--r:36px;--btn-r:18px;
}
.remote.grove{
--surf:#0f1f14;--surf2:#122318;
--hi:rgba(255,255,255,.04);--lo:rgba(0,0,0,.72);
--accent:#00e87a;--accent2:#007a40;--glow:rgba(0,232,122,.18);
--scr:#060d08;--tdim:rgba(255,255,255,.15);--tmid:rgba(255,255,255,.4);--tbright:rgba(255,255,255,.82);
--eye:#00e87a;--eye-glow:rgba(0,232,122,.55);
--pwr:#00e87a;--pwr-glow:rgba(0,232,122,.28);
--r:22px;--btn-r:8px;
}
.remote.lime{
--surf:#171b0c;--surf2:#1a1f0f;
--hi:rgba(255,255,255,.04);--lo:rgba(0,0,0,.72);
--accent:#c8ff00;--accent2:#607800;--glow:rgba(200,255,0,.18);
--scr:#060800;--tdim:rgba(255,255,255,.16);--tmid:rgba(255,255,255,.44);--tbright:rgba(255,255,255,.84);
--eye:#c8ff00;--eye-glow:rgba(200,255,0,.55);
--pwr:#c8ff00;--pwr-glow:rgba(200,255,0,.22);
--r:6px;--btn-r:3px;
}
.remote.dusk{
--surf:#1c1224;--surf2:#20162c;
--hi:rgba(255,255,255,.05);--lo:rgba(0,0,0,.65);
--accent:#ff6b9d;--accent2:#7a2040;--glow:rgba(255,107,157,.2);
--scr:#0a0612;--tdim:rgba(255,255,255,.17);--tmid:rgba(255,255,255,.44);--tbright:rgba(255,255,255,.84);
--eye:#ff6b9d;--eye-glow:rgba(255,107,157,.55);
--pwr:#ff6b9d;--pwr-glow:rgba(255,107,157,.3);
--r:32px;--btn-r:18px;
}
/* ═══════════════════════════════════════════
REMOTE SHELL
═══════════════════════════════════════════ */
.remote{
width:272px;background:var(--surf);border-radius:var(--r);
padding:20px 16px 24px;position:relative;
transition:background 500ms,border-radius 500ms,box-shadow 500ms;
box-shadow:-6px -6px 16px var(--hi),8px 8px 24px var(--lo),0 0 0 .5px rgba(255,255,255,.04);
}
.remote::before{
content:'';position:absolute;inset:0;border-radius:var(--r);
background:linear-gradient(155deg,var(--hi) 0%,transparent 50%);
pointer-events:none;z-index:0;
}
/* ═══════════════════════════════════════════
TOP BAR
═══════════════════════════════════════════ */
.topbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;position:relative;z-index:1}
.eyes{display:flex;gap:8px}
.eye{
width:8px;height:8px;border-radius:50%;
background:rgba(0,0,0,.65);
box-shadow:0 0 0 1.5px rgba(255,255,255,.05),inset 1px 1px 2px rgba(0,0,0,.9);
transition:background 60ms,box-shadow 60ms;
}
.eye.blink{background:var(--eye);box-shadow:0 0 5px 2px var(--eye),0 0 14px 4px var(--eye-glow)}
.brand{font-size:9px;letter-spacing:3.5px;font-weight:600;color:var(--tdim);text-transform:uppercase}
.power-btn{
width:36px;height:36px;border-radius:50%;border:none;cursor:pointer;
background:var(--surf2);
display:flex;align-items:center;justify-content:center;
box-shadow:-3px -3px 8px var(--hi),4px 4px 10px var(--lo);
transition:box-shadow 80ms,transform 80ms;
}
.power-btn:active,.power-btn.pr{box-shadow:inset 3px 3px 8px var(--lo),inset -2px -2px 5px var(--hi);transform:scale(.93)}
.power-btn svg{width:15px;height:15px}
.power-btn.off svg path{stroke:var(--tdim)}
.power-btn.on svg path{stroke:var(--pwr);filter:drop-shadow(0 0 3px var(--pwr))}
/* ═══════════════════════════════════════════
SCREEN
═══════════════════════════════════════════ */
.screen-wrap{margin-bottom:14px;position:relative;z-index:1}
.screen{
background:var(--scr);border-radius:calc(var(--r)*.55);
padding:13px 13px 11px;position:relative;overflow:hidden;
box-shadow:inset 0 2px 10px rgba(0,0,0,.95),inset 0 0 28px rgba(0,0,0,.5),0 0 0 .5px rgba(255,255,255,.04);
min-height:110px;
}
.screen::after{
content:'';position:absolute;inset:0;
background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,0,0,.11) 2px,rgba(0,0,0,.11) 3px);
pointer-events:none;z-index:8;border-radius:inherit;
}
.screen-shine{position:absolute;top:0;left:0;right:0;height:38%;background:linear-gradient(180deg,rgba(255,255,255,.04),transparent);border-radius:inherit;pointer-events:none;z-index:9}
.screen-glow{position:absolute;inset:-.5px;border-radius:inherit;opacity:0;transition:opacity 700ms;border:.5px solid var(--accent2);pointer-events:none;z-index:7}
.screen-glow.on{opacity:.7}
.sc{position:relative;z-index:5;opacity:0;transition:opacity 400ms}
.sc.on{opacity:1}
@keyframes crt{0%{opacity:0;transform:scaleY(.03)}20%{opacity:.8;transform:scaleY(.03)}32%{opacity:.2;transform:scaleY(1)}48%{opacity:.95;transform:scaleY(1)}58%{opacity:.25;transform:scaleY(1)}100%{opacity:1;transform:scaleY(1)}}
.sc.boot{animation:crt 360ms ease-out forwards}
.scr-row1{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1px}
.mode-txt{font-family:'DM Mono',monospace;font-size:9px;letter-spacing:2px;color:var(--accent2);text-shadow:0 0 6px var(--accent);font-style:italic}
.fan-dots{display:flex;gap:2.5px;align-items:flex-end}
.fd{width:2.5px;border-radius:2px;background:rgba(255,255,255,.07);transition:background 250ms,box-shadow 250ms}
.fd:nth-child(1){height:5px}.fd:nth-child(2){height:8px}.fd:nth-child(3){height:11px}.fd:nth-child(4){height:14px}.fd:nth-child(5){height:17px}
.fd.on{background:var(--accent);box-shadow:0 0 4px var(--accent)}
.temp-row{display:flex;align-items:flex-start;line-height:1;margin:1px 0 4px}
.tv{font-family:'DM Mono',monospace;font-size:58px;font-weight:400;color:var(--accent);letter-spacing:-3px;text-shadow:0 0 8px var(--accent),0 0 24px var(--glow);transition:color 200ms}
.tu{font-family:'DM Mono',monospace;font-size:17px;color:var(--accent2);margin-top:8px;margin-left:2px;text-shadow:0 0 5px var(--accent)}
@keyframes gp{0%,100%{text-shadow:0 0 8px var(--accent),0 0 24px var(--glow)}50%{text-shadow:0 0 14px var(--accent),0 0 38px var(--glow),0 0 50px var(--glow)}}
.tv.pulse{animation:gp 2.4s ease-in-out infinite}
.scr-bot{display:flex;justify-content:space-between;align-items:flex-end}
.mi-row{display:flex;gap:6px}
.mi{width:17px;height:17px;opacity:.13;transition:opacity 200ms,filter 200ms;color:var(--accent)}
.mi.on{opacity:1;filter:drop-shadow(0 0 3px var(--accent))}
.tmr{font-family:'DM Mono',monospace;font-size:10px;color:rgba(255,255,255,.18);letter-spacing:.5px;transition:color 200ms,text-shadow 200ms;cursor:pointer}
.tmr.on{color:#ffaa00;text-shadow:0 0 8px #ffaa00}
.tmr.active-countdown{color:#ff6b3d;text-shadow:0 0 8px #ff6b3d}
.ss-row{display:flex;gap:5px;margin-top:5px}
.ss{width:4px;height:4px;border-radius:50%;background:rgba(255,255,255,.06);transition:background 200ms,box-shadow 200ms}
.ss.on{background:var(--accent);box-shadow:0 0 4px var(--accent)}
/* ═══════════════════════════════════════════
DIVIDER
═══════════════════════════════════════════ */
.div{height:.5px;margin:11px 0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.07),transparent);position:relative;z-index:1}
/* ═══════════════════════════════════════════
RING
═══════════════════════════════════════════ */
.ring-wrap{display:flex;justify-content:center;margin-bottom:13px;position:relative;z-index:1}
.ring-out{
width:140px;height:140px;border-radius:50%;background:var(--surf);
box-shadow:-4px -4px 12px var(--hi),5px 5px 14px var(--lo),0 0 0 .5px rgba(255,255,255,.03);
position:relative;display:flex;align-items:center;justify-content:center;
}
.ring-in{
width:122px;height:122px;border-radius:50%;background:var(--surf);
box-shadow:inset 3px 3px 9px var(--lo),inset -2px -2px 5px var(--hi);
position:relative;display:flex;align-items:center;justify-content:center;
}
.rbtn{
position:absolute;width:36px;height:36px;border:none;cursor:pointer;
background:transparent;border-radius:50%;
display:flex;align-items:center;justify-content:center;
color:var(--tdim);transition:color 80ms;
}
.rbtn:active,.rbtn.pr{color:var(--accent)}
.rbtn svg{width:13px;height:13px;pointer-events:none}
.rbtn.up{top:5px;left:50%;transform:translateX(-50%)}
.rbtn.dn{bottom:5px;left:50%;transform:translateX(-50%)}
.rbtn.lt{left:5px;top:50%;transform:translateY(-50%)}
.rbtn.rt{right:5px;top:50%;transform:translateY(-50%)}
.rlabel{position:absolute;font-family:'DM Mono',monospace;font-size:7px;letter-spacing:.8px;color:var(--tdim);text-transform:uppercase;pointer-events:none}
.rlabel.t{top:-15px;left:50%;transform:translateX(-50%);white-space:nowrap}
.rlabel.b{bottom:-15px;left:50%;transform:translateX(-50%);white-space:nowrap}
.rlabel.l{left:-22px;top:50%;transform:translateY(-50%) rotate(-90deg);white-space:nowrap}
.rlabel.r{right:-22px;top:50%;transform:translateY(-50%) rotate(90deg);white-space:nowrap}
.rcenter{
width:42px;height:42px;border-radius:50%;border:none;cursor:pointer;
background:var(--surf2);
box-shadow:-2px -2px 7px var(--hi),3px 3px 8px var(--lo);
display:flex;align-items:center;justify-content:center;
transition:box-shadow 80ms,transform 80ms;
}
.rcenter:active,.rcenter.pr{box-shadow:inset 2px 2px 6px var(--lo),inset -1px -1px 4px var(--hi);transform:scale(.92)}
.rcd{width:7px;height:7px;border-radius:50%;background:var(--accent2);box-shadow:0 0 5px var(--accent2);transition:background 300ms,box-shadow 300ms}
.rcenter.on .rcd{background:var(--accent);box-shadow:0 0 10px var(--accent),0 0 18px var(--glow)}
/* ═══════════════════════════════════════════
FUNCTION BUTTONS
═══════════════════════════════════════════ */
.btn-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;position:relative;z-index:1}
.fbtn{
border:none;background:var(--surf2);border-radius:var(--btn-r);
padding:10px 4px 8px;cursor:pointer;
display:flex;flex-direction:column;align-items:center;gap:4px;
box-shadow:-2px -2px 6px var(--hi),3px 3px 8px var(--lo);
transition:box-shadow 80ms,transform 80ms,background 500ms;
position:relative;overflow:hidden;
}
.fbtn::before{content:'';position:absolute;top:0;left:0;right:0;height:.5px;background:linear-gradient(90deg,transparent,var(--hi),transparent)}
.fbtn:active,.fbtn.pr{box-shadow:inset 2px 2px 6px var(--lo),inset -1px -1px 4px var(--hi);transform:scale(.95)}
.ficon{width:20px;height:20px;color:var(--tdim);transition:color 200ms,filter 200ms}
.fbtn.act .ficon{color:var(--accent);filter:drop-shadow(0 0 4px var(--accent))}
.fbtn.turbo.act .ficon{color:#ff6b3d;filter:drop-shadow(0 0 4px #ff6b3d)}
.fbtn.eco.act .ficon{color:#00e87a;filter:drop-shadow(0 0 4px #00e87a)}
.fbtn.timer-btn.act .ficon{color:#ffaa00;filter:drop-shadow(0 0 4px #ffaa00)}
.flabel{font-size:8.5px;font-weight:600;letter-spacing:1.2px;color:var(--tdim);text-transform:uppercase;transition:color 200ms,text-shadow 200ms}
.fbtn.act .flabel{color:var(--accent);text-shadow:0 0 6px var(--glow)}
.fbtn.turbo.act .flabel{color:#ff6b3d;text-shadow:0 0 5px rgba(255,107,61,.4)}
.fbtn.eco.act .flabel{color:#00e87a;text-shadow:0 0 5px rgba(0,232,122,.4)}
.fbtn.timer-btn.act .flabel{color:#ffaa00;text-shadow:0 0 5px rgba(255,170,0,.4)}
.fdesc{font-size:7px;font-weight:300;color:var(--tdim);opacity:.65;text-align:center;line-height:1.2}
/* ═══════════════════════════════════════════
BOOK TRIGGER
═══════════════════════════════════════════ */
.book-trigger{
position:absolute;bottom:-14px;right:18px;
width:30px;height:30px;border-radius:50%;border:none;
background:var(--surf2);cursor:pointer;
box-shadow:-2px -2px 6px var(--hi),3px 3px 8px var(--lo),0 0 0 .5px rgba(255,255,255,.05);
display:flex;align-items:center;justify-content:center;
transition:box-shadow 80ms,transform 80ms,background 400ms;
z-index:10;color:var(--tmid);
}
.book-trigger:active{box-shadow:inset 2px 2px 5px var(--lo);transform:scale(.9)}
.book-trigger svg{width:14px;height:14px}
/* ═══════════════════════════════════════════
THEME SWITCHER
═══════════════════════════════════════════ */
.theme-switcher{display:flex;gap:10px;margin-top:28px;align-items:center;position:relative;z-index:1}
.tsw{width:22px;height:22px;border-radius:50%;border:2.5px solid transparent;cursor:pointer;transition:transform 200ms,border-color 200ms,box-shadow 200ms;box-shadow:0 2px 8px rgba(0,0,0,.4)}
.tsw:hover{transform:scale(1.15)}
.tsw.sel{border-color:rgba(255,255,255,.5);transform:scale(1.2)}
.tsw[data-t=noir]{background:#1a1c21}
.tsw[data-t=chalk]{background:#dedad3}
.tsw[data-t=grove]{background:#0f1f14}
.tsw[data-t=lime]{background:#171b0c}
.tsw[data-t=dusk]{background:#1c1224}
.theme-label{font-size:9px;letter-spacing:2px;color:rgba(255,255,255,.28);text-transform:uppercase;font-weight:500}
/* ═══════════════════════════════════════════
BOTTOM SHEETS & OVERLAYS (shared)
═══════════════════════════════════════════ */
.sheet-overlay{
position:fixed;inset:0;z-index:200;
display:flex;align-items:flex-end;justify-content:center;
pointer-events:none;opacity:0;transition:opacity 300ms;
}
.sheet-overlay.open{pointer-events:all;opacity:1}
.sheet-bg{position:absolute;inset:0;background:rgba(0,0,0,0);transition:background 350ms}
.sheet-overlay.open .sheet-bg{background:rgba(0,0,0,.62)}
.sheet{
position:relative;z-index:2;width:300px;
background:#f5f0e8;border-radius:20px 20px 0 0;
transform:translateY(100%);
transition:transform 480ms cubic-bezier(.34,1.3,.64,1);
box-shadow:0 -8px 40px rgba(0,0,0,.4);overflow:hidden;
}
.sheet-overlay.open .sheet{transform:translateY(0)}
.sheet-spine{position:absolute;top:0;left:0;right:0;height:4px;background:linear-gradient(90deg,#c8b89a,#ead8c0,#c8b89a)}
.sheet-drag{width:36px;height:4px;background:rgba(0,0,0,.12);border-radius:2px;margin:14px auto 0}
.sheet-head{display:flex;justify-content:space-between;align-items:center;padding:12px 18px 10px}
.sheet-title{font-size:14px;font-weight:600;color:#3a2e1e}
.sheet-subtitle{font-size:10px;color:#9a8a74;margin-top:1px;font-weight:300}
.sheet-x{width:26px;height:26px;border-radius:50%;border:none;background:rgba(0,0,0,.07);cursor:pointer;display:flex;align-items:center;justify-content:center;color:#6a5a44;transition:background 150ms}
.sheet-x:hover{background:rgba(0,0,0,.12)}
.sheet-x svg{width:10px;height:10px}
.sheet-body{padding:10px 18px 28px;max-height:70vh;overflow-y:auto}
.sheet-body::-webkit-scrollbar{width:3px}
.sheet-body::-webkit-scrollbar-thumb{background:#c8b89a;border-radius:2px}
/* ═══════════════════════════════════════════
TIMER SHEET
═══════════════════════════════════════════ */
.timer-presets{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:16px}
.tpre{
border:.5px solid rgba(0,0,0,.12);border-radius:10px;
background:rgba(0,0,0,.04);padding:10px 4px;
font-size:13px;font-weight:600;color:#4a3a28;
cursor:pointer;transition:background 150ms,border-color 150ms;
display:flex;flex-direction:column;align-items:center;gap:2px;
}
.tpre small{font-size:9px;font-weight:300;color:#9a8a74;letter-spacing:.5px}
.tpre:active,.tpre.sel{background:rgba(60,30,10,.1);border-color:rgba(60,30,10,.3)}
.tpre.sel{background:rgba(80,50,20,.12);border-color:#8b6a3e}
.timer-custom{margin-bottom:16px}
.tc-label{font-size:10px;letter-spacing:1px;text-transform:uppercase;color:#9a8a74;margin-bottom:8px;font-weight:500}
.tc-row{display:flex;align-items:center;gap:8px}
.tc-spin{display:flex;flex-direction:column;align-items:center;gap:4px;flex:1}
.tc-spin button{width:32px;height:32px;border-radius:8px;border:.5px solid rgba(0,0,0,.12);background:rgba(0,0,0,.04);cursor:pointer;font-size:16px;color:#4a3a28;display:flex;align-items:center;justify-content:center;transition:background 100ms}
.tc-spin button:active{background:rgba(0,0,0,.1)}
.tc-val{font-family:'DM Mono',monospace;font-size:28px;font-weight:400;color:#3a2e1e;width:48px;text-align:center}
.tc-sep{font-size:24px;color:#9a8a74;margin-top:-4px}
.timer-info{font-size:11px;color:#9a8a74;text-align:center;margin-bottom:14px;line-height:1.5}
.timer-confirm{
width:100%;padding:13px;border-radius:12px;border:none;cursor:pointer;
background:linear-gradient(135deg,#5a3e1e,#8b6a3e);
color:#f5ede0;font-family:'Outfit',sans-serif;font-size:14px;font-weight:600;
transition:opacity 150ms,transform 80ms;
}
.timer-confirm:active{transform:scale(.97);opacity:.9}
.timer-cancel{
width:100%;padding:10px;border-radius:12px;border:.5px solid rgba(0,0,0,.1);cursor:pointer;
background:transparent;color:#9a8a74;font-family:'Outfit',sans-serif;
font-size:13px;margin-top:6px;transition:background 150ms;
}
.timer-cancel:active{background:rgba(0,0,0,.05)}
/* ═══════════════════════════════════════════
BOOK SHEET
═══════════════════════════════════════════ */
.bi{width:28px;height:28px;flex-shrink:0;border-radius:7px;background:rgba(0,0,0,.06);display:flex;align-items:center;justify-content:center;color:#5a4a34}
.bi svg{width:14px;height:14px}
.book-item{display:flex;align-items:flex-start;gap:10px;margin-bottom:11px;opacity:0;transform:translateX(-10px);transition:opacity 280ms,transform 280ms}
.sheet-overlay.open .book-item{opacity:1;transform:translateX(0)}
.book-item:nth-child(1){transition-delay:80ms}.book-item:nth-child(2){transition-delay:130ms}
.book-item:nth-child(3){transition-delay:180ms}.book-item:nth-child(4){transition-delay:230ms}
.book-item:nth-child(5){transition-delay:280ms}.book-item:nth-child(6){transition-delay:330ms}
.book-item:nth-child(7){transition-delay:380ms}.book-item:nth-child(8){transition-delay:430ms}
.book-item:nth-child(9){transition-delay:480ms}
.bit-name{font-size:11.5px;font-weight:600;color:#3a2e1e;margin-bottom:2px}
.bit-desc{font-size:10px;font-weight:300;color:#6a5a44;line-height:1.5}
.bsec-title{font-size:8px;font-weight:600;letter-spacing:2px;color:#9a8a74;text-transform:uppercase;margin:14px 0 8px;border-bottom:.5px solid rgba(0,0,0,.07);padding-bottom:4px}
.ir-box{background:rgba(60,40,10,.07);border-radius:10px;padding:12px;margin-top:14px;border:.5px solid rgba(0,0,0,.08)}
.ir-title{font-size:11px;font-weight:600;color:#4a3a28;margin-bottom:6px}
.ir-item{font-size:10px;color:#6a5a44;margin-bottom:4px;padding-left:10px;position:relative;line-height:1.4}
.ir-item::before{content:'·';position:absolute;left:0;color:#9a8a74}
/* ═══════════════════════════════════════════
ONBOARDING
═══════════════════════════════════════════ */
.onb-overlay{
position:fixed;inset:0;z-index:500;
background:#0e0f13;
display:flex;flex-direction:column;align-items:center;justify-content:center;
padding:24px;
transition:opacity 400ms,transform 400ms;
}
.onb-overlay.hide{opacity:0;transform:scale(1.04);pointer-events:none}
.onb-step{display:none;flex-direction:column;align-items:center;width:100%;max-width:300px}
.onb-step.active{display:flex}
.onb-logo{
width:64px;height:64px;border-radius:20px;margin-bottom:24px;
background:linear-gradient(135deg,#1e2026,#252830);
box-shadow:-4px -4px 10px rgba(255,255,255,.05),5px 5px 14px rgba(0,0,0,.7);
display:flex;align-items:center;justify-content:center;
}
.onb-logo svg{width:28px;height:28px}
.onb-h{font-size:22px;font-weight:700;color:#f0f0f0;text-align:center;margin-bottom:8px;letter-spacing:-.5px}
.onb-sub{font-size:13px;font-weight:300;color:rgba(255,255,255,.4);text-align:center;line-height:1.6;margin-bottom:32px}
.onb-perm-card{
width:100%;background:#1a1c22;border-radius:16px;padding:16px;
border:.5px solid rgba(255,255,255,.07);margin-bottom:12px;
display:flex;align-items:center;gap:14px;
}
.onb-perm-icon{width:40px;height:40px;border-radius:12px;flex-shrink:0;display:flex;align-items:center;justify-content:center}
.onb-perm-icon.vib{background:rgba(0,232,255,.1)}
.onb-perm-icon.vib svg{color:#00e8ff}
.onb-perm-icon.notif{background:rgba(255,107,157,.1)}
.onb-perm-icon.notif svg{color:#ff6b9d}
.onb-perm-text .name{font-size:13px;font-weight:600;color:#e0e0e0;margin-bottom:2px}
.onb-perm-text .desc{font-size:11px;color:rgba(255,255,255,.35);line-height:1.4}
.onb-perm-badge{margin-left:auto;padding:5px 10px;border-radius:8px;font-size:10px;font-weight:600;letter-spacing:.5px}
.onb-perm-badge.ok{background:rgba(0,232,122,.15);color:#00e87a}
.onb-perm-badge.pending{background:rgba(255,255,255,.06);color:rgba(255,255,255,.3)}
.onb-brand-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;width:100%;margin-bottom:24px}
.onb-brand{
padding:12px 8px;border-radius:12px;border:.5px solid rgba(255,255,255,.08);
background:#1a1c22;cursor:pointer;text-align:center;
font-size:12px;font-weight:500;color:rgba(255,255,255,.45);
transition:background 150ms,border-color 150ms,color 150ms;
}
.onb-brand:active,.onb-brand.sel{background:rgba(0,232,255,.08);border-color:rgba(0,232,255,.25);color:#00e8ff}
.onb-test-card{
width:100%;background:#1a1c22;border-radius:16px;
border:.5px solid rgba(255,255,255,.07);overflow:hidden;margin-bottom:16px;
}
.onb-test-demo{
padding:20px;display:flex;flex-direction:column;align-items:center;gap:8px;
background:#111316;
}
.onb-demo-btn{
width:52px;height:52px;border-radius:50%;border:none;cursor:pointer;
display:flex;align-items:center;justify-content:center;
background:#1e2026;
box-shadow:-3px -3px 8px rgba(255,255,255,.04),4px 4px 10px rgba(0,0,0,.7);
transition:box-shadow 80ms,transform 80ms;
color:rgba(255,255,255,.3);
}
.onb-demo-btn:active,.onb-demo-btn.pr{
box-shadow:inset 3px 3px 8px rgba(0,0,0,.7),inset -2px -2px 5px rgba(255,255,255,.04);
transform:scale(.92);
}
.onb-demo-btn svg{width:22px;height:22px;pointer-events:none}
.onb-demo-label{font-size:11px;color:rgba(255,255,255,.3);letter-spacing:1px;font-weight:500}
.onb-test-q{padding:14px 16px;border-top:.5px solid rgba(255,255,255,.05)}
.onb-test-q p{font-size:12px;color:rgba(255,255,255,.55);margin-bottom:10px;line-height:1.5}
.onb-yn{display:flex;gap:8px}
.onb-y{flex:1;padding:10px;border-radius:10px;border:none;cursor:pointer;background:rgba(0,232,122,.12);border:.5px solid rgba(0,232,122,.2);color:#00e87a;font-size:13px;font-weight:600;font-family:'Outfit',sans-serif;transition:background 150ms}
.onb-n{flex:1;padding:10px;border-radius:10px;border:none;cursor:pointer;background:rgba(255,60,60,.08);border:.5px solid rgba(255,60,60,.15);color:#ff4444;font-size:13px;font-weight:600;font-family:'Outfit',sans-serif;transition:background 150ms}
.onb-y:active{background:rgba(0,232,122,.22)}
.onb-n:active{background:rgba(255,60,60,.15)}
.onb-compat{
width:100%;background:#1a1c22;border-radius:16px;padding:20px;
border:.5px solid rgba(255,255,255,.07);margin-bottom:24px;text-align:center;
}
.onb-score{font-size:48px;font-weight:700;color:#00e8ff;text-shadow:0 0 20px rgba(0,232,255,.4);font-family:'DM Mono',monospace}
.onb-score-label{font-size:12px;color:rgba(255,255,255,.4);margin-top:4px;margin-bottom:16px}
.onb-results{text-align:left}
.onb-res-item{display:flex;align-items:center;gap:8px;margin-bottom:8px;font-size:12px;color:rgba(255,255,255,.5)}
.onb-res-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.onb-res-dot.y{background:#00e87a;box-shadow:0 0 6px #00e87a}
.onb-res-dot.n{background:#ff4444;box-shadow:0 0 6px #ff4444}
.onb-step-dots{display:flex;gap:6px;margin-bottom:28px}
.onb-dot{width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.15);transition:background 300ms,width 300ms}
.onb-dot.a{background:#00e8ff;width:18px;border-radius:3px}
.onb-btn{
width:100%;padding:15px;border-radius:14px;border:none;cursor:pointer;
background:linear-gradient(135deg,#0a5a6a,#00e8ff);
color:#000e14;font-family:'Outfit',sans-serif;font-size:15px;font-weight:700;
transition:opacity 150ms,transform 80ms;letter-spacing:.3px;
box-shadow:0 4px 20px rgba(0,232,255,.25);
}
.onb-btn:active{transform:scale(.97);opacity:.9}
.onb-skip{font-size:12px;color:rgba(255,255,255,.25);cursor:pointer;margin-top:14px;transition:color 150ms}
.onb-skip:hover{color:rgba(255,255,255,.45)}
.onb-progress{width:100%;height:2px;background:rgba(255,255,255,.06);border-radius:1px;margin-bottom:28px}
.onb-progress-bar{height:100%;border-radius:1px;background:linear-gradient(90deg,#007a8a,#00e8ff);transition:width 400ms ease}
/* perm test vibrate button */
.vib-test-btn{
width:100%;padding:12px;border-radius:12px;border:none;cursor:pointer;margin-top:16px;
background:rgba(0,232,255,.1);border:.5px solid rgba(0,232,255,.2);
color:#00e8ff;font-family:'Outfit',sans-serif;font-size:13px;font-weight:600;
transition:background 150ms;
}
.vib-test-btn:active{background:rgba(0,232,255,.2)}
</style>
</head>
<body>
<!-- ═══════════════════════════════════════════
ONBOARDING OVERLAY
═══════════════════════════════════════════ -->
<div class="onb-overlay" id="onbOverlay">
<!-- STEP 0: WELCOME -->
<div class="onb-step active" id="onb0">
<div class="onb-logo">
<svg viewBox="0 0 32 32" fill="none" stroke="#00e8ff" stroke-width="1.6" stroke-linecap="round">
<circle cx="16" cy="16" r="6"/>
<line x1="16" y1="2" x2="16" y2="7"/><line x1="16" y1="25" x2="16" y2="30"/>
<line x1="2" y1="16" x2="7" y2="16"/><line x1="25" y1="16" x2="30" y2="16"/>
<line x1="5.5" y1="5.5" x2="9.3" y2="9.3"/><line x1="22.7" y1="22.7" x2="26.5" y2="26.5"/>
<line x1="5.5" y1="26.5" x2="9.3" y2="22.7"/><line x1="22.7" y1="9.3" x2="26.5" y2="5.5"/>
</svg>
</div>
<div class="onb-step-dots">
<div class="onb-dot a"></div><div class="onb-dot"></div>
<div class="onb-dot"></div><div class="onb-dot"></div>
</div>
<h1 class="onb-h">Добро пожаловать<br>в ARCTIQ</h1>
<p class="onb-sub">Умный пульт управления<br>кондиционером нового поколения.<br>Настроим всё за минуту.</p>
<button class="onb-btn" onclick="onbNext()">Начать настройку</button>
<div class="onb-skip" onclick="onbSkip()">Пропустить</div>
</div>
<!-- STEP 1: PERMISSIONS -->
<div class="onb-step" id="onb1">
<div class="onb-progress"><div class="onb-progress-bar" style="width:25%"></div></div>
<div class="onb-step-dots">
<div class="onb-dot"></div><div class="onb-dot a"></div>
<div class="onb-dot"></div><div class="onb-dot"></div>
</div>
<h1 class="onb-h" style="font-size:18px;margin-bottom:6px">Разрешения</h1>
<p class="onb-sub" style="margin-bottom:20px">Для максимального погружения<br>нам нужен доступ к:</p>
<div class="onb-perm-card">
<div class="onb-perm-icon vib">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" width="20" height="20">
<path d="M5 12a7 7 0 0 0 14 0"/>
<line x1="12" y1="3" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="21"/>
<line x1="3" y1="12" x2="5" y2="12"/><line x1="19" y1="12" x2="21" y2="12"/>
</svg>
</div>
<div class="onb-perm-text">
<div class="name">Вибрация</div>
<div class="desc">Тактильная отдача<br>при нажатии кнопок</div>
</div>
<div class="onb-perm-badge pending" id="vibBadge">ОЖИДАНИЕ</div>
</div>
<div class="onb-perm-card" style="opacity:.5">
<div class="onb-perm-icon notif">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" width="20" height="20">
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/>
<path d="M13.73 21a2 2 0 0 1-3.46 0"/>
</svg>
</div>
<div class="onb-perm-text">
<div class="name">Уведомления</div>
<div class="desc">Таймер и напоминания<br>о работе кондиционера</div>
</div>
<div class="onb-perm-badge pending" id="notifBadge">ОЖИДАНИЕ</div>
</div>
<button class="vib-test-btn" id="vibTestBtn" onclick="testVibration()">
📳 Проверить вибрацию
</button>
<button class="onb-btn" style="margin-top:16px" onclick="requestPermsAndNext()">Разрешить и продолжить</button>
<div class="onb-skip" onclick="onbNext()">Пропустить этот шаг</div>
</div>
<!-- STEP 2: BRAND -->
<div class="onb-step" id="onb2">
<div class="onb-progress"><div class="onb-progress-bar" style="width:50%"></div></div>
<div class="onb-step-dots">
<div class="onb-dot"></div><div class="onb-dot"></div>
<div class="onb-dot a"></div><div class="onb-dot"></div>
</div>
<h1 class="onb-h" style="font-size:18px;margin-bottom:6px">Ваш кондиционер</h1>
<p class="onb-sub" style="margin-bottom:20px">Выберите производителя для подбора протокола сигнала</p>
<div class="onb-brand-grid">
<div class="onb-brand" data-brand="Daikin" onclick="selBrand(this)">🌀 Daikin</div>
<div class="onb-brand" data-brand="Samsung" onclick="selBrand(this)">📱 Samsung</div>
<div class="onb-brand" data-brand="LG" onclick="selBrand(this)">🌀 LG</div>
<div class="onb-brand" data-brand="Mitsubishi" onclick="selBrand(this)">⭐ Mitsubishi</div>
<div class="onb-brand" data-brand="Haier" onclick="selBrand(this)">❄️ Haier</div>
<div class="onb-brand" data-brand="Другой" onclick="selBrand(this)">🔧 Другой</div>
</div>
<button class="onb-btn" onclick="onbNext()">Продолжить</button>
<div class="onb-skip" onclick="onbNext()">Пропустить</div>
</div>
<!-- STEP 3: BUTTON TESTS -->
<div class="onb-step" id="onb3">
<div class="onb-progress"><div class="onb-progress-bar" style="width:75%"></div></div>
<div class="onb-step-dots">
<div class="onb-dot"></div><div class="onb-dot"></div>
<div class="onb-dot"></div><div class="onb-dot a"></div>
</div>
<h1 class="onb-h" style="font-size:18px;margin-bottom:4px">Проверка сигналов</h1>
<p class="onb-sub" style="margin-bottom:16px">Нажимай кнопку и проверяй реакцию кондиционера</p>
<div class="onb-test-card" id="testCard">
<div class="onb-test-demo">
<button class="onb-demo-btn" id="testDemoBtn" onclick="pressTestBtn()">
<!-- Icon updated per test -->
</button>
<div class="onb-demo-label" id="testDemoLabel">ПИТАНИЕ</div>
</div>
<div class="onb-test-q">
<p id="testQ">Направь телефон на кондиционер и нажми кнопку выше. Кондиционер включился или среагировал?</p>
<div class="onb-yn">
<button class="onb-y" onclick="testAnswer(true)">✓ Да, работает</button>
<button class="onb-n" onclick="testAnswer(false)">✗ Нет реакции</button>
</div>
</div>
</div>
<div style="font-size:10px;color:rgba(255,255,255,.2);text-align:center;margin-top:8px">Тест <span id="testNum">1</span> из 4</div>
</div>
<!-- STEP 4: COMPLETE -->
<div class="onb-step" id="onb4">
<div class="onb-step-dots">
<div class="onb-dot"></div><div class="onb-dot"></div>
<div class="onb-dot"></div><div class="onb-dot"></div>
</div>
<div class="onb-compat">
<div class="onb-score" id="onbScore">0/4</div>
<div class="onb-score-label">Совместимость сигналов</div>
<div class="onb-results" id="onbResults"></div>
</div>
<div id="onbCompatMsg" style="font-size:12px;color:rgba(255,255,255,.4);text-align:center;margin-bottom:24px;line-height:1.6"></div>
<button class="onb-btn" onclick="finishOnboarding()">Открыть пульт</button>
</div>
</div>
<!-- ═══════════════════════════════════════════
TIMER SHEET
═══════════════════════════════════════════ -->
<div class="sheet-overlay" id="timerSheet">
<div class="sheet-bg" onclick="closeTimer()"></div>
<div class="sheet">
<div class="sheet-spine"></div>
<div class="sheet-drag"></div>
<div class="sheet-head">
<div>
<div class="sheet-title">⏱ Таймер</div>
<div class="sheet-subtitle">Авто-выключение кондиционера</div>
</div>
<button class="sheet-x" onclick="closeTimer()">
<svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="2" y1="2" x2="10" y2="10"/><line x1="10" y1="2" x2="2" y2="10"/></svg>
</button>
</div>
<div class="sheet-body">
<div class="tc-label">Быстрый выбор</div>
<div class="timer-presets" id="timerPresets">
<div class="tpre" data-h="0" data-m="30" onclick="selPreset(this)">30<small>мин</small></div>
<div class="tpre" data-h="1" data-m="0" onclick="selPreset(this)">1<small>час</small></div>
<div class="tpre" data-h="2" data-m="0" onclick="selPreset(this)">2<small>часа</small></div>
<div class="tpre" data-h="4" data-m="0" onclick="selPreset(this)">4<small>часа</small></div>
<div class="tpre" data-h="6" data-m="0" onclick="selPreset(this)">6<small>часов</small></div>
<div class="tpre" data-h="8" data-m="0" onclick="selPreset(this)">8<small>часов</small></div>
</div>
<div class="timer-custom">
<div class="tc-label">Точная настройка</div>
<div class="tc-row">
<div class="tc-spin">
<button onclick="adjH(1)"></button>
<div class="tc-val" id="tcH">01</div>
<button onclick="adjH(-1)"></button>
</div>
<div class="tc-sep">:</div>
<div class="tc-spin">
<button onclick="adjM(15)"></button>
<div class="tc-val" id="tcM">00</div>
<button onclick="adjM(-15)"></button>
</div>
</div>
</div>
<div class="timer-info" id="timerInfoTxt">Кондиционер выключится автоматически через <b id="timerInfoH">1 ч 0 мин</b></div>
<button class="timer-confirm" id="timerConfirmBtn" onclick="confirmTimer()">Установить таймер</button>
<button class="timer-cancel" id="timerCancelBtn" onclick="cancelTimer()" style="display:none">Отменить таймер</button>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════
BOOK / HELP SHEET
═══════════════════════════════════════════ -->
<div class="sheet-overlay" id="bookSheet">
<div class="sheet-bg" onclick="closeBook()"></div>
<div class="sheet">
<div class="sheet-spine"></div>
<div class="sheet-drag"></div>
<div class="sheet-head">
<div>
<div class="sheet-title">📖 Руководство</div>
<div class="sheet-subtitle">ARCTIQ Remote Control</div>
</div>
<button class="sheet-x" onclick="closeBook()">
<svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="2" y1="2" x2="10" y2="10"/><line x1="10" y1="2" x2="2" y2="10"/></svg>
</button>
</div>
<div class="sheet-body">
<div class="bsec-title">Управление кольцом</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="5 12 10 7 15 12"/></svg></div>
<div><div class="bit-name">▲ Вверх - Температура +1°C</div><div class="bit-desc">Нажатие повышает целевую температуру. Диапазон: 16–30°C.</div></div>
</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="5 8 10 13 15 8"/></svg></div>
<div><div class="bit-name">▼ Вниз - Температура −1°C</div><div class="bit-desc">Понижает целевую температуру с шагом 1 градус.</div></div>
</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="10" cy="10" r="2"/><path d="M10 8C11 5.5 12.5 3.5 13.5 2.5C13.5 2.5 12 3.5 11.5 7"/><path d="M12 10C14.5 9 17 9.5 18.5 9C18.5 9 16.5 11 13.5 10.5"/><path d="M10 12C9 14.5 7.5 16.5 6.5 17.5C6.5 17.5 8 16.5 8.5 13"/><path d="M8 10C5.5 11 3 10.5 1.5 11C1.5 11 3.5 9 6.5 9.5"/></svg></div>
<div><div class="bit-name">● Центр - Смена режима</div><div class="bit-desc">Цикл: Охлаждение → Обогрев → Осушение → Вентиляция.</div></div>
</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="12 5 8 10 12 15"/></svg></div>
<div><div class="bit-name">◀ Влево / ▶ Вправо - Вентилятор</div><div class="bit-desc">Скорость потока: уровни 1–5. Нажимай циклически.</div></div>
</div>
<div class="bsec-title">Функциональные кнопки</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="currentColor" stroke="none"><polygon points="11,2 3,12 10,12 9,18 17,8 10,8"/></svg></div>
<div><div class="bit-name">ТУРБО - Максимальная мощность</div><div class="bit-desc">Скорость вентилятора 5. Отключает ЭКО и ТИХИЙ. Быстрый выход на заданную температуру.</div></div>
</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"><path d="M14 6.5C7 8 5 13 3.5 17L5 17.5L5.8 15.5C6.5 15.8 7.3 16 8.2 16C15.5 16 18 3 18 3C17.2 4.5 12 7.5 12 7.5"/><path d="M9 9.5C8.5 11.5 8 13.5 8 15"/></svg></div>
<div><div class="bit-name">ЭКО - Энергосбережение</div><div class="bit-desc">Ограничивает вентилятор уровнем 2. Снижает потребление до 30%.</div></div>
</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"><circle cx="10" cy="11" r="6.5"/><polyline points="10 8 10 11 12 13"/><path d="M8 3.5 L6.5 5"/><path d="M12 3.5 L13.5 5"/></svg></div>
<div><div class="bit-name">ТАЙМЕР - Авто-выключение</div><div class="bit-desc">Нажми для открытия настройки. Выбери время: 30 мин - 8 часов. Долгое нажатие отменяет таймер.</div></div>
</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"><path d="M3 8L5 8L9 5L9 15L5 12L3 12Z"/><line x1="13" y1="8" x2="17" y2="12"/><line x1="17" y1="8" x2="13" y2="12"/></svg></div>
<div><div class="bit-name">ТИХИЙ - Ночной режим</div><div class="bit-desc">Вентилятор уровень 1, шум менее 20 дБ. Идеально для сна.</div></div>
</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"><path d="M17 10A7 7 0 0 0 4 6.5"/><polyline points="3 3 4 6.5 7 6.5"/><path d="M3 10A7 7 0 0 0 16 13.5"/><polyline points="17 17 16 13.5 13 13.5"/></svg></div>
<div><div class="bit-name">SWING - Авто-жалюзи</div><div class="bit-desc">Горизонтальные жалюзи автоматически поворачиваются для равномерного обдува.</div></div>
</div>
<div class="book-item">
<div class="bi"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"><line x1="5" y1="17" x2="5" y2="12"/><line x1="10" y1="17" x2="10" y2="4"/><line x1="15" y1="17" x2="15" y2="9"/><line x1="3.5" y1="12" x2="6.5" y2="12"/><line x1="8.5" y1="4" x2="11.5" y2="4"/><line x1="13.5" y1="9" x2="16.5" y2="9"/></svg></div>
<div><div class="bit-name">ПОТОК - Зоны воздуха</div><div class="bit-desc">Переключает направление: напольная зона > средняя > потолочная > авто.</div></div>
</div>
<div class="ir-box">
<div class="ir-title">📡 Как работает пульт?</div>
<div class="ir-item">Веб-браузер не имеет прямого доступа к ИК-порту телефона</div>
<div class="ir-item">Телефоны с ИК: Xiaomi, Redmi, POCO, Samsung (до 2020), Huawei - используй нативное приложение (Mi Remote, SmartThings)</div>
<div class="ir-item">Через умный хаб: Broadlink RM Pro, SwitchBot Hub > управление через Wi-Fi/Bluetooth</div>
<div class="ir-item">Этот пульт - полноценный UI-слой: добавь WebSocket-соединение к хабу для реальной работы</div>
<div class="ir-item">API: navigator.bluetooth > BLE-хаб > ИК-сигнал > кондиционер</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════
REMOTE
═══════════════════════════════════════════ -->
<div class="remote noir" id="remote">
<!-- TOP -->
<div class="topbar">
<div class="eyes"><div class="eye" id="e1"></div><div class="eye" id="e2"></div></div>
<div class="brand">Arctiq</div>
<button class="power-btn off" id="pwrBtn">
<svg viewBox="0 0 24 24" fill="none">
<path d="M12 3v8" stroke-width="2.2" stroke-linecap="round"/>
<path d="M6 5.5A9 9 0 1 0 18 5.5" stroke-width="2.2" stroke-linecap="round"/>
</svg>
</button>
</div>
<!-- SCREEN -->
<div class="screen-wrap">
<div class="screen">
<div class="screen-shine"></div>
<div class="screen-glow" id="scrGlow"></div>
<div id="scrOff" style="position:absolute;inset:0;z-index:6;display:flex;align-items:center;justify-content:center;transition:opacity 300ms">
<div style="width:70px;height:1px;background:linear-gradient(90deg,transparent,rgba(255,255,255,.04),transparent);transform:rotate(-10deg)"></div>
</div>
<div class="sc" id="sc">
<div class="scr-row1">
<span class="mode-txt" id="modeTxt">COOL ·</span>
<div class="fan-dots" id="fanDots">
<div class="fd"></div><div class="fd"></div><div class="fd"></div><div class="fd"></div><div class="fd"></div>
</div>
</div>
<div class="temp-row">
<span class="tv pulse" id="tv">22</span>
<span class="tu">°C</span>
</div>
<div class="scr-bot">
<div class="mi-row">
<!-- COOL -->
<svg class="mi on" id="mi0" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round">
<line x1="10" y1="2" x2="10" y2="18"/><line x1="2" y1="10" x2="18" y2="10"/>
<line x1="4.3" y1="4.3" x2="15.7" y2="15.7"/><line x1="15.7" y1="4.3" x2="4.3" y2="15.7"/>
<circle cx="10" cy="10" r="1.8" fill="currentColor" stroke="none"/>
<line x1="10" y1="2" x2="8.5" y2="3.8"/><line x1="10" y1="2" x2="11.5" y2="3.8"/>
<line x1="10" y1="18" x2="8.5" y2="16.2"/><line x1="10" y1="18" x2="11.5" y2="16.2"/>
</svg>
<!-- HEAT -->
<svg class="mi" id="mi1" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round">
<circle cx="10" cy="10" r="3.5"/>
<line x1="10" y1="1.5" x2="10" y2="4"/><line x1="10" y1="16" x2="10" y2="18.5"/>
<line x1="1.5" y1="10" x2="4" y2="10"/><line x1="16" y1="10" x2="18.5" y2="10"/>
<line x1="4.2" y1="4.2" x2="6" y2="6"/><line x1="14" y1="14" x2="15.8" y2="15.8"/>
<line x1="4.2" y1="15.8" x2="6" y2="14"/><line x1="14" y1="6" x2="15.8" y2="4.2"/>
</svg>
<!-- DRY -->
<svg class="mi" id="mi2" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round">
<path d="M10 3 Q13 7.5 13 11.5 A3 3 0 0 1 7 11.5 Q7 7.5 10 3Z"/>
<line x1="8.5" y1="13" x2="9.5" y2="14" opacity=".5"/>
</svg>
<!-- FAN -->
<svg class="mi" id="mi3" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round">
<circle cx="10" cy="10" r="1.6"/>
<path d="M10 8.4C10 5.8 11.3 3.5 12.5 2.5C12.5 2.5 11 3.8 10.5 7.2"/>
<path d="M11.6 10C14.2 10 16.5 11.3 17.5 12.5C17.5 12.5 16.2 11 12.8 10.5"/>
<path d="M10 11.6C10 14.2 8.7 16.5 7.5 17.5C7.5 17.5 9 16.2 9.5 12.8"/>
<path d="M8.4 10C5.8 10 3.5 8.7 2.5 7.5C2.5 7.5 3.8 9 7.2 9.5"/>
</svg>
</div>
<span class="tmr" id="tmrTxt" onclick="openTimer()" title="Нажми для настройки">--:--</span>
</div>
<div class="ss-row">
<div class="ss" id="ss0"></div><div class="ss" id="ss1"></div>
<div class="ss" id="ss2"></div><div class="ss" id="ss3"></div>
</div>
</div>
</div>
</div>
<div class="div"></div>
<!-- RING -->
<div class="ring-wrap">
<div class="ring-out">
<span class="rlabel t">ТЕМП ▲</span>
<span class="rlabel b">ТЕМП ▼</span>
<span class="rlabel l">ПОТ.</span>
<span class="rlabel r">ПОТ.</span>
<div class="ring-in">
<button class="rbtn up" id="rUp"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 10 8 6 12 10"/></svg></button>
<button class="rbtn lt" id="rLt"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="10 4 6 8 10 12"/></svg></button>
<button class="rcenter off" id="rCen"><div class="rcd"></div></button>
<button class="rbtn rt" id="rRt"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 4 10 8 6 12"/></svg></button>
<button class="rbtn dn" id="rDn"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 6 8 10 12 6"/></svg></button>
</div>
</div>
</div>
<div class="div"></div>
<!-- FUNC BUTTONS -->
<div class="btn-grid">
<button class="fbtn turbo" id="bTurbo">
<svg class="ficon" viewBox="0 0 24 24" fill="currentColor" stroke="none"><polygon points="13,2 3,14 12,14 11,22 21,10 12,10"/></svg>
<span class="flabel">Турбо</span>
<span class="fdesc">Макс. мощность</span>
</button>
<button class="fbtn eco" id="bEco">
<svg class="ficon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round">
<path d="M17 8C8 10 6 16 4 21L6 21.5L7 19C8 19.6 9.2 20 10.5 20C19.5 20 22 3 22 3C21 5 14 9 14 9"/>
<path d="M10 11A8 8 0 0 0 8.5 16.5"/>
</svg>
<span class="flabel">ЭКО</span>
<span class="fdesc">Энергосбережение</span>
</button>
<button class="fbtn timer-btn" id="bTimer">
<svg class="ficon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round">
<circle cx="12" cy="13" r="7.5"/>
<polyline points="12 9.5 12 13 14.5 15.5"/>
<path d="M9.5 3.5L7.5 5.5"/><path d="M14.5 3.5L16.5 5.5"/>
<line x1="12" y1="2" x2="12" y2="4"/>
</svg>
<span class="flabel">Таймер</span>
<span class="fdesc" id="timerBtnDesc">Авто-выключение</span>
</button>
<button class="fbtn quiet" id="bQuiet">
<svg class="ficon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round">
<path d="M3 9L6 9L11 5L11 19L6 15L3 15Z" fill="currentColor" stroke="none" opacity=".35"/>
<path d="M3 9L6 9L11 5L11 19L6 15L3 15"/>
<line x1="16" y1="9.5" x2="21" y2="14.5"/><line x1="21" y1="9.5" x2="16" y2="14.5"/>
</svg>
<span class="flabel">Тихий</span>
<span class="fdesc">Ночной режим</span>
</button>
<button class="fbtn swing" id="bSwing">
<svg class="ficon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12A9 9 0 0 0 4 7"/><polyline points="3.5 3.5 4 7 7.5 7"/>
<path d="M3 12A9 9 0 0 0 20 17"/><polyline points="20.5 20.5 20 17 16.5 17"/>
</svg>
<span class="flabel">Swing</span>
<span class="fdesc">Авто-жалюзи</span>
</button>
<button class="fbtn flow" id="bFlow">
<svg class="ficon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round">
<line x1="6" y1="20" x2="6" y2="14"/><line x1="12" y1="20" x2="12" y2="4"/>
<line x1="18" y1="20" x2="18" y2="10"/>
<line x1="4.5" y1="14" x2="7.5" y2="14"/>
<line x1="10.5" y1="4" x2="13.5" y2="4"/>
<line x1="16.5" y1="10" x2="19.5" y2="10"/>
</svg>
<span class="flabel">Поток</span>
<span class="fdesc">Зоны воздуха</span>
</button>
</div>
<!-- BOOK BTN -->
<button class="book-trigger" onclick="openBook()">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M2 3H8A4 4 0 0 1 12 7V21A3 3 0 0 0 9 18H2Z"/>
<path d="M22 3H16A4 4 0 0 0 12 7V21A3 3 0 0 1 15 18H22Z"/>
</svg>
</button>
</div>
<!-- THEME SWITCHER -->
<div class="theme-switcher">
<span class="theme-label">Стиль</span>
<div class="tsw sel" data-t="noir" title="Noir" onclick="setTheme(this)"></div>
<div class="tsw" data-t="chalk" title="Chalk" onclick="setTheme(this)"></div>
<div class="tsw" data-t="grove" title="Grove" onclick="setTheme(this)"></div>
<div class="tsw" data-t="lime" title="Lime" onclick="setTheme(this)"></div>
<div class="tsw" data-t="dusk" title="Dusk" onclick="setTheme(this)"></div>
</div>
<script>
/* ═══════════════════════════════════════════
STORAGE
═══════════════════════════════════════════ */
const SK = 'arctiq_v3';
function load(){ try{ return JSON.parse(localStorage.getItem(SK)||'{}') }catch(e){ return {} } }
function save(){
try{
localStorage.setItem(SK, JSON.stringify({
onboarded, theme: curTheme, temp, fan, mode, on: pwrOn,
timerH: tmH, timerM: tmM, timerActive, timerEnd,
st, acBrand, vibOk, testResults
}));
}catch(e){}
}
/* ═══════════════════════════════════════════
STATE
═══════════════════════════════════════════ */
const saved = load();
let onboarded = saved.onboarded || false;
let curTheme = saved.theme || 'noir';
let temp = saved.temp || 22;
let fan = saved.fan || 2;
let mode = saved.mode || 0;
let pwrOn = false; // never restore powered-on state
let tmH = saved.timerH || 1;
let tmM = saved.timerM || 0;
let timerActive = false; // always start with no timer
let timerEnd = null;
let timerInterval = null;
let st = saved.st || {turbo:0,eco:0,quiet:0,swing:0,flow:0};
let acBrand = saved.acBrand || '';
let vibOk = saved.vibOk || false;
let testResults = [];
let onbStep = 0;
let curTest = 0;
const pageBg = {noir:'#0e0e10',chalk:'#e8e4dc',grove:'#090f0c',lime:'#0d1006',dusk:'#0f0914'};
const modes = ['COOL ·','HEAT ·','DRY ·','FAN ·'];
/* test definitions */
const tests = [
{
label:'ПИТАНИЕ',
q:'Направь телефон на кондиционер и нажми кнопку выше. Кондиционер включился или среагировал?',
icon:`<svg viewBox="0 0 24 24" fill="none" width="22" height="22"><path d="M12 3v8" stroke="#00e8ff" stroke-width="2.2" stroke-linecap="round"/><path d="M6 5.5A9 9 0 1 0 18 5.5" stroke="#00e8ff" stroke-width="2.2" stroke-linecap="round"/></svg>`
},
{
label:'ОХЛАЖДЕНИЕ',
q:'Активирован режим охлаждения (снежинка). Кондиционер переключился в режим COOL?',
icon:`<svg viewBox="0 0 24 24" fill="none" width="22" height="22" stroke="#00e8ff" stroke-width="1.6" stroke-linecap="round"><line x1="12" y1="3" x2="12" y2="21"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="5.5" y1="5.5" x2="18.5" y2="18.5"/><line x1="18.5" y1="5.5" x2="5.5" y2="18.5"/><circle cx="12" cy="12" r="2.5" fill="#00e8ff"/></svg>`
},
{
label:'ВЕНТИЛЯТОР',
q:'Скорость вентилятора изменяется? Нажми кнопку несколько раз — слышны ли изменения шума?',
icon:`<svg viewBox="0 0 24 24" fill="none" width="22" height="22" stroke="#00e8ff" stroke-width="1.5" stroke-linecap="round"><circle cx="12" cy="12" r="2"/><path d="M12 10C12 7 14 4.5 15.5 3.5C15.5 3.5 13.5 5 13 9"/><path d="M14 12C17 11 20 11.5 21.5 10.5C21.5 10.5 19.5 13 16 12.5"/><path d="M12 14C12 17 10 19.5 8.5 20.5C8.5 20.5 10.5 19 11 15"/><path d="M10 12C7 13 4 12.5 2.5 13.5C2.5 13.5 4.5 11 8 11.5"/></svg>`
},
{
label:'ТУРБО',
q:'Нажата кнопка ТУРБО (максимальная мощность). Ощущается ли усиление воздушного потока?',
icon:`<svg viewBox="0 0 24 24" fill="#00e8ff" width="22" height="22"><polygon points="13,2 3,14 12,14 11,22 21,10 12,10"/></svg>`
}
];
/* ═══════════════════════════════════════════
DOM REFS
═══════════════════════════════════════════ */
const remote = document.getElementById('remote');
const pwrBtn = document.getElementById('pwrBtn');
const sc = document.getElementById('sc');
const scrOff = document.getElementById('scrOff');
const scrGlow = document.getElementById('scrGlow');
const tvEl = document.getElementById('tv');
const modeTxtEl = document.getElementById('modeTxt');
const tmrTxtEl = document.getElementById('tmrTxt');
const fanDots = document.querySelectorAll('.fd');
const modeIcons = [document.getElementById('mi0'),document.getElementById('mi1'),document.getElementById('mi2'),document.getElementById('mi3')];
const ssEls = [document.getElementById('ss0'),document.getElementById('ss1'),document.getElementById('ss2'),document.getElementById('ss3')];
const rCen = document.getElementById('rCen');
const timerBtnDesc = document.getElementById('timerBtnDesc');
/* ═══════════════════════════════════════════
AUDIO
═══════════════════════════════════════════ */
let ac2 = null;
function beep(type){
try{
if(!ac2) ac2 = new(window.AudioContext||window.webkitAudioContext)();
const o=ac2.createOscillator(),g=ac2.createGain();
o.connect(g);g.connect(ac2.destination);
if(type==='pwr'){
o.frequency.setValueAtTime(200,ac2.currentTime);
o.frequency.exponentialRampToValueAtTime(90,ac2.currentTime+.18);
g.gain.setValueAtTime(.07,ac2.currentTime);
g.gain.exponentialRampToValueAtTime(.001,ac2.currentTime+.18);
o.start();o.stop(ac2.currentTime+.18);
}else{
o.frequency.setValueAtTime(1200,ac2.currentTime);
o.frequency.exponentialRampToValueAtTime(850,ac2.currentTime+.035);
g.gain.setValueAtTime(.03,ac2.currentTime);
g.gain.exponentialRampToValueAtTime(.001,ac2.currentTime+.035);
o.start();o.stop(ac2.currentTime+.035);
}
}catch(e){}
}
function hap(p=[15]){ if(navigator.vibrate) navigator.vibrate(p) }
/* ═══════════════════════════════════════════
EYES
═══════════════════════════════════════════ */
function blink(ms=110){
const e1=document.getElementById('e1'),e2=document.getElementById('e2');
e1.classList.add('blink');e2.classList.add('blink');
setTimeout(()=>{e1.classList.remove('blink');e2.classList.remove('blink')},ms);
}
/* ═══════════════════════════════════════════
PRESS
═══════════════════════════════════════════ */
function press(el,cb){
el.classList.add('pr');
setTimeout(()=>el.classList.remove('pr'),160);
if(cb)cb();
}
/* ═══════════════════════════════════════════
SCREEN UPDATE
═══════════════════════════════════════════ */
function updFan(){ fanDots.forEach((d,i)=>d.classList.toggle('on',i<fan)) }
function updModes(){
modeTxtEl.textContent=modes[mode];
modeIcons.forEach((m,i)=>m.classList.toggle('on',i===mode));
}
function updSS(){
ssEls[0].classList.toggle('on',!!st.swing);
ssEls[1].classList.toggle('on',!!st.quiet);
ssEls[2].classList.toggle('on',!!st.eco);
ssEls[3].classList.toggle('on',!!st.turbo);
}
function updTimer(){
if(timerActive && timerEnd){
const rem = Math.max(0, timerEnd - Date.now());
const totalMin = Math.ceil(rem/60000);
const h = Math.floor(totalMin/60), m = totalMin%60;
const txt = h>0 ? `${h}:${String(m).padStart(2,'0')}` : `0:${String(m).padStart(2,'0')}`;
tmrTxtEl.textContent = txt;
tmrTxtEl.classList.add('on');
timerBtnDesc.textContent = txt + ' осталось';
document.getElementById('bTimer').classList.add('act','timer-btn');
if(rem <= 0) cancelTimer();
} else {
tmrTxtEl.textContent = '--:--';
tmrTxtEl.classList.remove('on','active-countdown');
timerBtnDesc.textContent = 'Авто-выключение';
document.getElementById('bTimer').classList.remove('act');
}
}
/* ═══════════════════════════════════════════
POWER
═══════════════════════════════════════════ */
function togglePower(){
hap([25,10,25]);beep('pwr');blink(200);
pwrOn=!pwrOn;
pwrBtn.classList.toggle('on',pwrOn);
pwrBtn.classList.toggle('off',!pwrOn);
scrGlow.classList.toggle('on',pwrOn);
rCen.classList.toggle('on',pwrOn);
if(pwrOn){
scrOff.style.opacity='0';
setTimeout(()=>scrOff.style.pointerEvents='none',300);
sc.classList.remove('boot');void sc.offsetWidth;
sc.classList.add('on','boot');
updFan();updModes();updSS();updTimer();
} else {
sc.classList.remove('on','boot');
setTimeout(()=>{scrOff.style.opacity='1';scrOff.style.pointerEvents=''},300);
}
save();
}
/* ═══════════════════════════════════════════
CONTROLS
═══════════════════════════════════════════ */
function changeTemp(d){
if(!pwrOn)return;
const t=temp+d;if(t<16||t>30)return;
temp=t;tvEl.textContent=temp;hap([15]);beep();blink();
save();
}
function fanUp(){if(!pwrOn)return;fan=fan>=5?1:fan+1;updFan();hap([15]);beep();blink();save()}
function fanDn(){if(!pwrOn)return;fan=fan<=1?5:fan-1;updFan();hap([15]);beep();blink();save()}
function nextMode(){if(!pwrOn)return;mode=(mode+1)%4;updModes();hap([15]);beep();blink();save()}
function toggle(key,el){
if(!pwrOn){hap([5]);return}
st[key]=st[key]?0:1;
el.classList.toggle('act',!!st[key]);
hap([15]);beep();blink();
if(key==='turbo'&&st.turbo){ st.eco=0;st.quiet=0;document.getElementById('bEco').classList.remove('act');document.getElementById('bQuiet').classList.remove('act');fan=5;updFan() }
if(key==='eco'&&st.eco){ st.turbo=0;document.getElementById('bTurbo').classList.remove('act');if(fan>2){fan=2;updFan()} }
if(key==='quiet'&&st.quiet){ st.turbo=0;document.getElementById('bTurbo').classList.remove('act');fan=1;updFan() }
updSS();save();
}
/* ═══════════════════════════════════════════
TIMER LOGIC
═══════════════════════════════════════════ */
let pickerH=1, pickerM=0;
function openTimer(){
if(!pwrOn){hap([5]);return}
hap([10]);
pickerH = timerActive ? tmH : 1;
pickerM = timerActive ? tmM : 0;
updatePickerUI();
document.getElementById('timerSheet').classList.add('open');
document.getElementById('timerCancelBtn').style.display = timerActive ? 'block' : 'none';
// deselect all presets
document.querySelectorAll('.tpre').forEach(p=>p.classList.remove('sel'));
}
function closeTimer(){ document.getElementById('timerSheet').classList.remove('open') }
function updatePickerUI(){
document.getElementById('tcH').textContent = String(pickerH).padStart(2,'0');
document.getElementById('tcM').textContent = String(pickerM).padStart(2,'0');
const total = pickerH*60+pickerM;
const h=Math.floor(total/60),m=total%60;
let txt='';
if(h>0)txt+=h+' ч ';
if(m>0)txt+=m+' мин';
if(!txt)txt='0 мин';
document.getElementById('timerInfoH').textContent=txt;
}
function adjH(d){ pickerH=Math.max(0,Math.min(12,pickerH+d));updatePickerUI();document.querySelectorAll('.tpre').forEach(p=>p.classList.remove('sel')) }
function adjM(d){ pickerM=((pickerM+d)+60)%60;if(d>0&&pickerM===0&&pickerH<12)pickerH++;updatePickerUI();document.querySelectorAll('.tpre').forEach(p=>p.classList.remove('sel')) }
function selPreset(el){
document.querySelectorAll('.tpre').forEach(p=>p.classList.remove('sel'));
el.classList.add('sel');
pickerH=parseInt(el.dataset.h);
pickerM=parseInt(el.dataset.m);
updatePickerUI();
hap([10]);
}
function confirmTimer(){
const total=pickerH*60+pickerM;
if(total===0){cancelTimer();return}
tmH=pickerH;tmM=pickerM;
timerActive=true;
timerEnd=Date.now()+total*60*1000;
if(timerInterval)clearInterval(timerInterval);
timerInterval=setInterval(updTimer,10000);
updTimer();
hap([15,10,15]);
closeTimer();
save();
}
function cancelTimer(){
timerActive=false;timerEnd=null;
if(timerInterval){clearInterval(timerInterval);timerInterval=null}
updTimer();
closeTimer();
save();
}
/* ═══════════════════════════════════════════
BOOK
═══════════════════════════════════════════ */
function openBook(){ hap([10]);document.getElementById('bookSheet').classList.add('open') }
function closeBook(){ document.getElementById('bookSheet').classList.remove('open') }
/* ═══════════════════════════════════════════
THEME
═══════════════════════════════════════════ */
function setTheme(el){
const t=el.dataset.t;
if(t===curTheme)return;
curTheme=t;
remote.className='remote '+t;
document.body.style.background=pageBg[t]||'#111';
document.querySelectorAll('.tsw').forEach(x=>x.classList.remove('sel'));
el.classList.add('sel');
hap([10]);
save();
}
/* ═══════════════════════════════════════════
ONBOARDING
═══════════════════════════════════════════ */
function showOnbStep(n){
document.querySelectorAll('.onb-step').forEach(s=>s.classList.remove('active'));
const el=document.getElementById('onb'+n);
if(el) el.classList.add('active');
onbStep=n;
}
function onbNext(){ showOnbStep(onbStep+1) }
function onbSkip(){ finishOnboarding() }
function selBrand(el){
document.querySelectorAll('.onb-brand').forEach(b=>b.classList.remove('sel'));
el.classList.add('sel');
acBrand=el.dataset.brand;
hap([10]);
}
function testVibration(){
if(navigator.vibrate){ navigator.vibrate([30,20,30,20,60]);vibOk=true;document.getElementById('vibBadge').textContent='ОК';document.getElementById('vibBadge').className='onb-perm-badge ok' }
else { document.getElementById('vibBadge').textContent='НЕТ';document.getElementById('vibBadge').className='onb-perm-badge pending' }
hap([30,20,30]);
document.getElementById('vibTestBtn').textContent='✓ Вибрация работает!';
document.getElementById('vibTestBtn').style.opacity='.7';
}
async function requestPermsAndNext(){
if(navigator.vibrate){ navigator.vibrate([15]);vibOk=true;document.getElementById('vibBadge').textContent='ОК';document.getElementById('vibBadge').className='onb-perm-badge ok' }
if('Notification' in window && Notification.permission==='default'){
try{ const p=await Notification.requestPermission();if(p==='granted'){ document.getElementById('notifBadge').textContent='ОК';document.getElementById('notifBadge').className='onb-perm-badge ok' } }catch(e){}
}
onbNext();
}
/* Test flow */
curTest=0;testResults=[];
function loadTest(i){
const t=tests[i];
document.getElementById('testDemoBtn').innerHTML=t.icon;
document.getElementById('testDemoLabel').textContent=t.label;
document.getElementById('testQ').textContent=t.q;
document.getElementById('testNum').textContent=i+1;
}
function pressTestBtn(){
const el=document.getElementById('testDemoBtn');
press(el,()=>{hap([20]);beep()});
}
function testAnswer(yes){
testResults.push({label:tests[curTest].label,ok:yes});
hap(yes?[15,10,30]:[15]);
curTest++;
if(curTest<tests.length){ loadTest(curTest) }
else { showResults();showOnbStep(4) }
}
function showResults(){
const score=testResults.filter(r=>r.ok).length;
document.getElementById('onbScore').textContent=score+'/4';
const msgs=['Вероятно, телефон не поддерживает ИК или протокол не совпадает.','Частичная совместимость. Некоторые команды работают.','Хорошая совместимость! Большинство функций работает.','Отличная совместимость! Все сигналы распознаются.'];
document.getElementById('onbCompatMsg').textContent=msgs[score];
const cont=document.getElementById('onbResults');
cont.innerHTML='';
testResults.forEach(r=>{
const d=document.createElement('div');
d.className='onb-res-item';
d.innerHTML=`<div class="onb-res-dot ${r.ok?'y':'n'}"></div>${r.label}: ${r.ok?'Работает':'Нет реакции'}`;
cont.appendChild(d);
});
}
function finishOnboarding(){
onboarded=true;save();
const ov=document.getElementById('onbOverlay');
ov.classList.add('hide');
setTimeout(()=>ov.style.display='none',400);
}
/* ═══════════════════════════════════════════
INIT
═══════════════════════════════════════════ */
// Apply saved theme
document.querySelectorAll('.tsw').forEach(t=>t.classList.remove('sel'));
remote.className='remote '+curTheme;
document.body.style.background=pageBg[curTheme]||'#111';
const savedTsw=document.querySelector(`.tsw[data-t="${curTheme}"]`);
if(savedTsw)savedTsw.classList.add('sel');
// Onboarding
if(onboarded){
document.getElementById('onbOverlay').style.display='none';
} else {
loadTest(0);
}
// Events
pwrBtn.addEventListener('click',()=>press(pwrBtn,togglePower));
document.getElementById('rUp').addEventListener('click',e=>press(e.currentTarget,()=>changeTemp(1)));
document.getElementById('rDn').addEventListener('click',e=>press(e.currentTarget,()=>changeTemp(-1)));
document.getElementById('rLt').addEventListener('click',e=>press(e.currentTarget,fanDn));
document.getElementById('rRt').addEventListener('click',e=>press(e.currentTarget,fanUp));
document.getElementById('rCen').addEventListener('click',e=>press(e.currentTarget,nextMode));
[['bTurbo','turbo'],['bEco','eco'],['bSwing','swing'],['bFlow','flow'],['bQuiet','quiet']].forEach(([id,k])=>{
const el=document.getElementById(id);
el.addEventListener('click',()=>press(el,()=>toggle(k,el)));
});
// Timer button - short tap = open sheet, long tap = cancel
const timerBtnEl = document.getElementById('bTimer');
let timerLongPress;
timerBtnEl.addEventListener('pointerdown',()=>{ timerLongPress=setTimeout(()=>{ if(timerActive){cancelTimer();hap([30,15,30])} },600) });
timerBtnEl.addEventListener('pointerup',()=>clearTimeout(timerLongPress));
timerBtnEl.addEventListener('pointerleave',()=>clearTimeout(timerLongPress));
timerBtnEl.addEventListener('click',()=>press(timerBtnEl,openTimer));
// Keyboard
document.addEventListener('keydown',e=>{
if(e.key==='p'||e.key==='P')togglePower();
if(e.key==='ArrowUp')changeTemp(1);
if(e.key==='ArrowDown')changeTemp(-1);
if(e.key==='ArrowRight')fanUp();
if(e.key==='ArrowLeft')fanDn();
if(e.key==='m'||e.key==='M')nextMode();
});
document.addEventListener('contextmenu',e=>e.preventDefault());
</script>
</body>
</html>