diff --git a/mobile.html b/mobile.html
index 4f6e873..2993183 100644
--- a/mobile.html
+++ b/mobile.html
@@ -2,11 +2,9 @@
-
VARASYS PolyMeter β Mobile
-
@@ -47,78 +45,72 @@
--btn1:#ffffff; --btn2:#e7edf4; --btn-bd:#c8d2de; --chip-bg:#eef2f7; --chip-bd:#d3dbe5;
}
html,body{ height:100%; }
- body{
- margin:0; overflow:hidden; color:var(--txt);
+ body{ margin:0; overflow:hidden; color:var(--txt);
background:radial-gradient(circle at 50% -12%, var(--bg1), var(--bg2));
font-family:"Segoe UI", Roboto, Helvetica, Arial, sans-serif;
-webkit-user-select:none; user-select:none; -webkit-tap-highlight-color:transparent;
- touch-action:manipulation; overscroll-behavior:none;
- }
+ touch-action:manipulation; overscroll-behavior:none; }
#app{ position:fixed; inset:0; overflow:hidden; display:flex; flex-direction:column;
padding:max(8px,env(safe-area-inset-top)) max(12px,env(safe-area-inset-right))
max(8px,env(safe-area-inset-bottom)) max(12px,env(safe-area-inset-left)); }
- /* ---- top: set-list + track dropdowns, volume, theme/fullscreen ---- */
+ /* ---- top ---- */
#top{ flex:0 0 auto; display:flex; flex-direction:column; gap:8px; }
.sels{ display:flex; gap:8px; }
.sel{ flex:1 1 0; min-width:0; display:flex; flex-direction:column; gap:3px; }
.sel > span{ font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--muted); padding-left:3px; }
- .sel select{ width:100%; background:var(--field-bg); color:var(--txt); border:1px solid var(--field-bd);
- border-radius:10px; padding:10px 8px; font-size:15px; }
+ .sel select{ width:100%; background:var(--field-bg); color:var(--txt); border:1px solid var(--field-bd); border-radius:10px; padding:10px 8px; font-size:15px; }
.trow{ display:flex; align-items:center; gap:10px; }
.vol{ flex:1 1 auto; display:flex; align-items:center; gap:9px; color:var(--muted); font-size:15px; min-width:0; }
.vol input{ flex:1 1 auto; min-width:0; accent-color:var(--cyan); }
.icon{ flex:0 0 auto; width:42px; height:42px; border-radius:50%; display:flex; align-items:center; justify-content:center;
- font-size:18px; line-height:1; cursor:pointer; color:var(--txt);
- background:rgba(127,139,154,.14); border:1px solid var(--panel-bd); }
+ font-size:18px; line-height:1; cursor:pointer; color:var(--txt); background:rgba(127,139,154,.14); border:1px solid var(--panel-bd); }
.icon:active{ background:rgba(127,139,154,.30); }
- /* ---- middle: stage (beats+pulse) + right column (detail + transport) ---- */
+ /* ---- middle: stage (pulse) + right column (lanes/features + transport) ---- */
#mid{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; gap:6px; }
- #stage{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
- gap:clamp(10px,2.4vmin,30px); }
- #beats{ display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:clamp(8px,1.7vmin,16px); max-width:92%; }
- .dot{ width:clamp(12px,2.8vmin,28px); height:clamp(12px,2.8vmin,28px); border-radius:50%;
- background:var(--led-off); border:1px solid rgba(0,0,0,.35); transition:background .05s, box-shadow .05s, transform .05s; }
- .dot.group{ outline:1.5px solid var(--amber); outline-offset:3px; opacity:.95; }
- .dot.on{ background:var(--cyan); box-shadow:0 0 12px var(--glow); transform:scale(1.12); }
- .dot.on.group{ background:var(--amber); box-shadow:0 0 14px var(--aglow); }
-
- #pulse{ position:relative; width:clamp(160px,40vmin,380px); height:clamp(160px,40vmin,380px); border-radius:50%;
+ #stage{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:clamp(8px,2vmin,22px); }
+ #pulse{ position:relative; width:clamp(150px,36vmin,340px); height:clamp(150px,36vmin,340px); border-radius:50%;
display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center;
border:2px solid var(--ring); background:radial-gradient(circle at 50% 40%, rgba(127,139,154,.07), transparent 70%);
- transition:transform .12s ease-out, box-shadow .12s ease-out, border-color .12s ease-out;
- touch-action:none; cursor:pointer; }
+ transition:transform .12s ease-out, box-shadow .12s ease-out, border-color .12s ease-out; touch-action:none; cursor:pointer; }
#pulse.hit{ transform:scale(1.045); border-color:var(--cyan); box-shadow:0 0 60px var(--glow); }
#pulse.hit.acc{ border-color:var(--amber); box-shadow:0 0 72px var(--aglow); }
- #bpm{ font-size:clamp(50px,16vmin,150px); font-weight:800; line-height:.85; font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
+ #bpm{ font-size:clamp(46px,15vmin,140px); font-weight:800; line-height:.85; font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
#bpmlab{ font-size:clamp(10px,2vmin,16px); letter-spacing:.3em; color:var(--muted); margin-top:.6em; }
- #bpmhint{ font-size:clamp(9px,1.6vmin,12px); color:var(--muted); opacity:.7; margin-top:.5em; }
- #bpmIn{ display:none; width:64%; text-align:center; font:inherit; font-size:clamp(46px,14vmin,130px); font-weight:800;
- background:transparent; color:var(--txt); border:none; border-bottom:2px solid var(--cyan); outline:none;
- font-variant-numeric:tabular-nums; -moz-appearance:textfield; }
+ #bpmIn{ display:none; width:64%; text-align:center; font:inherit; font-size:clamp(42px,13vmin,120px); font-weight:800;
+ background:transparent; color:var(--txt); border:none; border-bottom:2px solid var(--cyan); outline:none; font-variant-numeric:tabular-nums; -moz-appearance:textfield; }
#bpmIn::-webkit-outer-spin-button, #bpmIn::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
#meterline{ font-size:clamp(12px,2.1vmin,16px); color:var(--muted); text-align:center; min-height:1.2em; letter-spacing:.02em; }
- /* ---- detail: lanes + features as chips ---- */
- #detail{ flex:0 0 auto; max-height:18vh; overflow-y:auto; display:flex; flex-direction:column; gap:5px; padding:2px 0; }
+ /* ---- editable lanes + feature chips ---- */
+ #detail{ flex:0 0 auto; max-height:30vh; overflow-y:auto; display:flex; flex-direction:column; gap:6px; padding:2px 0; }
+ #lanes{ display:flex; flex-direction:column; gap:6px; }
+ .lane{ display:flex; align-items:center; gap:8px; }
+ .lane.off{ opacity:.5; }
+ .lmeta{ flex:0 0 auto; width:30%; max-width:130px; min-width:64px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-align:left;
+ background:var(--chip-bg); border:1px solid var(--chip-bd); color:var(--txt); border-radius:8px; padding:6px 8px;
+ font-size:clamp(10px,1.8vmin,13px); font-family:"Courier New",monospace; cursor:pointer; }
+ .lmeta .lg{ color:var(--muted); }
+ .pads{ flex:1 1 auto; display:flex; gap:3px; overflow-x:auto; padding-bottom:2px; min-width:0; }
+ .pad{ flex:1 0 14px; min-width:14px; height:clamp(20px,3.6vmin,28px); border-radius:5px; border:1px solid var(--chip-bd); background:var(--led-off); cursor:pointer; padding:0; }
+ .pad.gs{ border-color:var(--amber); }
+ .pad.on{ background:var(--cyan); }
+ .pad.acc{ background:var(--amber); }
+ .pad.ghost{ background:var(--cyan); opacity:.42; }
+ .pad.cur{ outline:2px solid var(--txt); outline-offset:-1px; box-shadow:0 0 8px var(--glow); }
+ .addlane{ align-self:flex-start; background:transparent; border:1px dashed var(--chip-bd); color:var(--muted); border-radius:8px; padding:5px 11px; font-size:12px; cursor:pointer; }
.chips{ display:flex; flex-wrap:wrap; gap:6px; justify-content:center; }
- .chip{ font-size:clamp(10px,1.8vmin,13px); font-family:"Courier New",monospace; background:var(--chip-bg); border:1px solid var(--chip-bd);
- color:var(--txt); border-radius:7px; padding:3px 8px; white-space:nowrap; }
- .chip.off{ opacity:.45; text-decoration:line-through; }
- .chip.feat{ font-family:inherit; color:var(--muted); }
- .chip.feat.r{ border-color:var(--cyan); color:var(--cyan); }
- .chip.feat.g{ border-color:var(--amber); color:var(--amber); }
+ .chip.feat{ font-size:clamp(10px,1.8vmin,13px); color:var(--muted); background:var(--chip-bg); border:1px solid var(--chip-bd); border-radius:7px; padding:3px 8px; white-space:nowrap; }
+ .chip.feat.r{ border-color:var(--cyan); color:var(--cyan); } .chip.feat.g{ border-color:var(--amber); color:var(--amber); }
- /* ---- transport: tempo grid (β10/β +/+10) + prev/next + play/practice ---- */
- #transport{ flex:0 0 auto; display:flex; justify-content:center; padding-top:4px; }
- .tgrid{ display:grid; width:100%; max-width:560px; gap:clamp(6px,1.7vmin,13px);
- grid-template-columns:1fr 1.5fr 1.5fr 1fr;
- grid-template-areas:"dn10 prev next up10" "dn play prac up"; }
+ /* ---- transport ---- */
+ #transport{ flex:0 0 auto; display:flex; justify-content:center; padding-top:2px; }
+ .tgrid{ display:grid; width:100%; max-width:560px; gap:clamp(6px,1.6vmin,13px);
+ grid-template-columns:1fr 1.5fr 1.5fr 1fr; grid-template-areas:"dn10 prev next up10" "dn play prac up"; }
.tbtn{ background:linear-gradient(180deg,var(--btn1),var(--btn2)); color:var(--txt); border:1px solid var(--btn-bd);
- border-radius:14px; height:clamp(48px,12vmin,74px); font-size:clamp(18px,4.6vmin,28px); cursor:pointer;
- box-shadow:0 3px 0 rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.06);
- display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; }
+ border-radius:14px; height:clamp(46px,11vmin,72px); font-size:clamp(18px,4.4vmin,28px); cursor:pointer;
+ box-shadow:0 3px 0 rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.06); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; }
.tbtn small{ font-size:clamp(8px,1.5vmin,11px); letter-spacing:.1em; color:inherit; opacity:.85; }
.tbtn:active{ transform:translateY(2px); box-shadow:0 1px 0 rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.06); }
#bDn10{grid-area:dn10} #bPrev{grid-area:prev} #bNext{grid-area:next} #bUp10{grid-area:up10}
@@ -128,26 +120,53 @@
.tbtn.prac{ background:linear-gradient(180deg,#1c87b8,#136488); border-color:#1f9bd0; color:#eaf8ff; }
.tbtn.prac.on{ background:linear-gradient(180deg,#c8922a,#9c6f12); border-color:#e0a93a; color:#fff; }
- /* landscape phones: pulse left, right column = detail + transport */
@media (orientation:landscape) and (max-height:600px){
#mid{ flex-direction:row; align-items:stretch; gap:3vw; }
- #stage{ flex:1 1 50%; gap:clamp(6px,1.6vmin,14px); }
- #rightcol{ flex:1 1 50%; display:flex; flex-direction:column; justify-content:center; gap:6px; min-width:0; }
- #pulse{ width:clamp(140px,38vmin,280px); height:clamp(140px,38vmin,280px); }
- #bpmlab,#bpmhint{ display:none; }
- #detail{ max-height:30vh; }
+ #stage{ flex:1 1 46%; gap:clamp(6px,1.6vmin,14px); }
+ #rightcol{ flex:1 1 54%; display:flex; flex-direction:column; justify-content:center; gap:6px; min-width:0; }
+ #pulse{ width:clamp(130px,34vmin,260px); height:clamp(130px,34vmin,260px); }
+ #bpmlab{ display:none; }
+ #detail{ max-height:42vh; }
.tbtn{ height:clamp(40px,12vmin,60px); }
}
- #rightcol{ display:contents; } /* portrait: detail + transport flow normally in #mid */
+ #rightcol{ display:contents; }
- /* ---- session bar (bottom) ---- */
- #sessbar{ flex:0 0 auto; display:flex; align-items:center; gap:8px; width:100%; margin-top:6px;
- padding:9px 12px; border-radius:11px; cursor:pointer; text-decoration:none;
- background:rgba(127,139,154,.10); border:1px solid var(--panel-bd); color:var(--muted); font-size:13px; }
+ /* ---- session bar ---- */
+ #sessbar{ flex:0 0 auto; display:flex; align-items:center; gap:8px; width:100%; margin-top:6px; padding:9px 12px; border-radius:11px;
+ cursor:pointer; text-decoration:none; background:rgba(127,139,154,.10); border:1px solid var(--panel-bd); color:var(--muted); font-size:13px; }
#sessbar.rec{ background:rgba(192,57,43,.12); border-color:#c0392b; color:var(--txt); cursor:default; }
#sessbar .dotrec{ width:9px; height:9px; border-radius:50%; background:#e0493a; box-shadow:0 0 8px #e0493a; flex:0 0 auto; display:none; }
- #sessbar.rec .dotrec{ display:block; }
- #sessText{ flex:1 1 auto; }
+ #sessbar.rec .dotrec{ display:block; } #sessText{ flex:1 1 auto; }
+
+ /* ---- bottom sheet (lane editor) ---- */
+ #scrim{ position:fixed; inset:0; background:rgba(0,0,0,.55); opacity:0; pointer-events:none; transition:opacity .2s; z-index:40; }
+ #scrim.open{ opacity:1; pointer-events:auto; }
+ #laneSheet{ position:fixed; left:0; right:0; bottom:0; z-index:50; max-height:84vh; overflow-y:auto;
+ background:var(--panel-bg); border-top:1px solid var(--panel-bd); border-radius:18px 18px 0 0; transform:translateY(110%);
+ transition:transform .26s cubic-bezier(.2,.8,.2,1);
+ padding:12px max(16px,env(safe-area-inset-right)) max(18px,env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left)); }
+ #laneSheet.open{ transform:none; }
+ #laneSheet .grab{ width:42px; height:5px; border-radius:3px; background:var(--panel-bd); margin:0 auto 12px; }
+ #laneSheet h2{ margin:0 0 10px; font-size:16px; }
+ #laneSheet label{ display:block; font-size:12px; color:var(--muted); margin:10px 0 5px; }
+ #laneSheet select, #laneSheet input[type=text]{ width:100%; background:var(--field-bg); color:var(--txt); border:1px solid var(--field-bd); border-radius:10px; padding:11px; font-size:15px; }
+ .lrow{ display:flex; gap:14px; margin-top:10px; flex-wrap:wrap; }
+ .lrow .half{ flex:1 1 120px; margin:0; }
+ .chk{ display:flex; align-items:center; gap:8px; font-size:14px; color:var(--txt); margin-top:18px; }
+ .chk input{ width:20px; height:20px; accent-color:var(--cyan); }
+ .lfoot{ display:flex; justify-content:space-between; margin-top:18px; }
+ .lbtn{ cursor:pointer; color:var(--txt); background:linear-gradient(180deg,var(--btn1),var(--btn2)); border:1px solid var(--btn-bd); border-radius:10px; padding:10px 18px; font-size:14px; }
+ .lbtn.danger{ background:transparent; color:#ff7a7a; border-color:#ff7a7a; }
+
+ /* ---- help tour (coachmarks) ---- */
+ #tour{ position:fixed; inset:0; z-index:200; display:none; }
+ #tour.open{ display:block; }
+ #tourHole{ position:absolute; border-radius:12px; box-shadow:0 0 0 9999px rgba(0,0,0,.66); border:2px solid var(--cyan); transition:all .2s ease; pointer-events:none; }
+ #tourBox{ position:absolute; background:var(--panel-bg); border:1px solid var(--panel-bd); border-radius:12px; padding:14px; box-shadow:0 14px 44px rgba(0,0,0,.5); }
+ #tourBox h3{ margin:0 0 6px; font-size:15px; }
+ #tourBox p{ margin:0 0 12px; font-size:13px; color:var(--muted); line-height:1.45; }
+ #tourBox .trow{ display:flex; justify-content:space-between; align-items:center; gap:10px; }
+ .tdots{ font-size:12px; color:var(--muted); }
@@ -160,6 +179,7 @@
@@ -167,19 +187,17 @@
-
120
BPM
-
tap = tap tempo Β· hold = type Β· drag = scrub
@@ -190,7 +208,7 @@
-
+
@@ -200,16 +218,47 @@
Practice sessions β
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+