diff options
| -rw-r--r-- | docs/prototypes/README.org | 2 | ||||
| -rw-r--r-- | docs/prototypes/panel-widget-gallery.html (renamed from docs/prototypes/2026-07-03-panel-widget-gallery-prototype.html) | 91 | ||||
| -rw-r--r-- | docs/specs/2026-07-02-timer-panel-spec.org | 2 |
3 files changed, 40 insertions, 55 deletions
diff --git a/docs/prototypes/README.org b/docs/prototypes/README.org index 9df85cb..c9b2fd7 100644 --- a/docs/prototypes/README.org +++ b/docs/prototypes/README.org @@ -15,7 +15,7 @@ point at. affordance for the NETWORKS/NEARBY headers (busy-style throbber + list fade). - [[file:2026-07-03-sound-panel-prototype.html][2026-07-03-sound-panel-prototype.html]] — the audio/pulsemixer console; layout reference for [[file:../specs/2026-07-03-audio-panel-spec.org][the audio-panel spec]]. -- [[file:2026-07-03-panel-widget-gallery-prototype.html][2026-07-03-panel-widget-gallery-prototype.html]] — the shared instrument-console +- [[file:panel-widget-gallery.html][panel-widget-gallery.html]] — the shared instrument-console widget kit (lamps, engraved sections, console keys, needle gauges). - [[file:2026-07-03-waybar-redesign-prototype.html][2026-07-03-waybar-redesign-prototype.html]] — three directions for sprucing up waybar in the dupre instrument-console aesthetic (future work). diff --git a/docs/prototypes/2026-07-03-panel-widget-gallery-prototype.html b/docs/prototypes/panel-widget-gallery.html index 65973bd..5f1dcf3 100644 --- a/docs/prototypes/2026-07-03-panel-widget-gallery-prototype.html +++ b/docs/prototypes/panel-widget-gallery.html @@ -7,7 +7,7 @@ <style> :root{ --ground:#151311; --panel:#100f0f; --well:#0a0c0d; --raise:#1a1917; - --gold:#dab53d; --gold-hi:#ffd75f; --silver:#bfc4d0; --cream:#f3e7c5; + --gold:#e2a038; --gold-hi:#ffbe54; --silver:#bfc4d0; --cream:#f3e7c5; --steel:#969385; --dim:#7c838a; --slate:#424f5e; --slate-hi:#54677d; --wash:#2c2f32; --pass:#74932f; --fail:#cb6b4d; --mono:"BerkeleyMono Nerd Font","Berkeley Mono",monospace; @@ -43,10 +43,11 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} /* ---- shared primitives ---- */ .lamp{width:9px;height:9px;border-radius:50%;background:var(--pass);box-shadow:0 0 6px 1px rgba(116,147,47,.55)} -.lamp.gold{background:var(--gold);box-shadow:0 0 6px 1px rgba(218,181,61,.6)} +.lamp.gold{background:var(--gold);box-shadow:0 0 6px 1px rgba(226,160,56,.6)} .lamp.red{background:var(--fail);box-shadow:0 0 6px 1px rgba(203,107,77,.55)} .lamp.off{background:var(--wash);box-shadow:none} -.lamp.busy{background:var(--gold);animation:pulse .7s ease-in-out infinite} +.lamp.busy{background:var(--gold);animation:pulse 1s ease-in-out infinite} +/* standard pulse: 1s ease-in-out — the norm for every pulsing / flashing element */ @keyframes pulse{50%{opacity:.25}} .switch{width:40px;height:21px;border-radius:11px;background:var(--wash);border:1px solid var(--slate); @@ -63,7 +64,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} border-radius:8px;padding:8px 12px;box-shadow:inset 0 1px 0 rgba(255,255,255,.04),0 2px 3px rgba(0,0,0,.4)} .key:hover{color:var(--gold);border-color:var(--gold)} .key:active{transform:translateY(1px)} -.key.on{color:var(--panel);background:linear-gradient(180deg,#f0d879,var(--gold));border-color:var(--gold-hi);font-weight:700} +.key.on{color:var(--panel);background:linear-gradient(180deg,#f2c76a,var(--gold));border-color:var(--gold-hi);font-weight:700} .key.red{color:var(--cream);background:linear-gradient(180deg,#d98a6f,var(--fail));border-color:var(--fail)} .key.off{opacity:.4} @@ -77,22 +78,22 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} /* fader */ .fader{width:150px;height:16px;position:relative;cursor:pointer;touch-action:none} .fader .slot{position:absolute;top:6px;left:0;right:0;height:4px;border-radius:2px;background:#0d0f10;border:1px solid #231f18;overflow:hidden} -.fader .fill{position:absolute;top:0;left:0;bottom:0;background:linear-gradient(90deg,#8a7524,var(--gold))} +.fader .fill{position:absolute;top:0;left:0;bottom:0;background:linear-gradient(90deg,#8f671f,var(--gold))} .fader .cap{position:absolute;top:1px;width:7px;height:14px;border-radius:2px;margin-left:-3.5px; - background:linear-gradient(180deg,#f0d879,#caa233);border:1px solid #7a6414;box-shadow:0 1px 2px rgba(0,0,0,.5)} + background:linear-gradient(180deg,#f2c76a,#d29638);border:1px solid #7d5c16;box-shadow:0 1px 2px rgba(0,0,0,.5)} /* vertical fader */ .vfader{width:16px;height:64px;position:relative;cursor:pointer;touch-action:none} .vfader .slot{position:absolute;left:6px;top:0;bottom:0;width:4px;border-radius:2px;background:#0d0f10;border:1px solid #231f18;overflow:hidden} -.vfader .fill{position:absolute;left:0;right:0;bottom:0;background:linear-gradient(0deg,#8a7524,var(--gold))} +.vfader .fill{position:absolute;left:0;right:0;bottom:0;background:linear-gradient(0deg,#8f671f,var(--gold))} .vfader .cap{position:absolute;left:1px;height:7px;width:14px;border-radius:2px;margin-top:-3.5px; - background:linear-gradient(90deg,#caa233,#f0d879);border:1px solid #7a6414} + background:linear-gradient(90deg,#d29638,#f2c76a);border:1px solid #7d5c16} /* rotary knob */ .knob{width:52px;height:52px;border-radius:50%;position:relative;cursor:ns-resize;touch-action:none; background:radial-gradient(circle at 40% 35%,#2a2622,#141210);border:1px solid #3a352c; box-shadow:inset 0 2px 3px rgba(255,255,255,.05),0 3px 6px rgba(0,0,0,.5)} .knob .ind{position:absolute;left:50%;top:5px;width:2px;height:16px;background:var(--gold-hi); - margin-left:-1px;transform-origin:50% 21px;border-radius:1px;box-shadow:0 0 5px rgba(255,215,95,.6)} + margin-left:-1px;transform-origin:50% 21px;border-radius:1px;box-shadow:0 0 5px rgba(255,190,84,.6)} /* needle gauge */ .gauge{width:96px;cursor:ns-resize;touch-action:none} @@ -100,7 +101,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .gauge .arc{position:absolute;inset:0 0 -48px 0;border:2px solid var(--wash);border-radius:50%} .gauge .tk{position:absolute;left:50%;bottom:0;width:1.5px;height:8px;background:var(--steel);transform-origin:50% 48px} .gauge .ndl{position:absolute;left:50%;bottom:0;width:2px;height:40px;background:var(--gold-hi); - transform-origin:50% 100%;transform:rotate(0deg);border-radius:2px;box-shadow:0 0 6px rgba(255,215,95,.5); + transform-origin:50% 100%;transform:rotate(0deg);border-radius:2px;box-shadow:0 0 6px rgba(255,190,84,.5); transition:transform .12s cubic-bezier(.3,1.3,.5,1)} .gauge .hub{position:absolute;left:50%;bottom:-4px;width:8px;height:8px;margin-left:-4px;border-radius:50%;background:var(--gold)} .gauge .gv{color:var(--cream);text-align:center;font-size:12px;font-weight:700;margin-top:5px;font-variant-numeric:tabular-nums} @@ -128,7 +129,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} /* linear progress / fuel bar */ .bar{width:160px;height:12px;background:#0d0f10;border:1px solid #231f18;border-radius:6px;overflow:hidden;position:relative;cursor:pointer;touch-action:none} -.bar>span{position:absolute;left:0;top:0;bottom:0;background:linear-gradient(90deg,#8a7524,var(--gold));border-radius:6px} +.bar>span{position:absolute;left:0;top:0;bottom:0;background:linear-gradient(90deg,#8f671f,var(--gold));border-radius:6px} .bar.warn>span{background:linear-gradient(90deg,#a35a3f,var(--fail))} /* radial ring */ @@ -162,7 +163,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .seg{display:flex;border:1px solid #33302b;border-radius:8px;overflow:hidden} .seg button{font:inherit;font-size:11px;color:var(--silver);background:#191715;border:0;border-right:1px solid #33302b;padding:7px 11px;cursor:pointer} .seg button:last-child{border-right:0} -.seg button.on{background:linear-gradient(180deg,#f0d879,var(--gold));color:var(--panel);font-weight:700} +.seg button.on{background:linear-gradient(180deg,#f2c76a,var(--gold));color:var(--panel);font-weight:700} /* engraved section label */ .engrave{width:180px;color:var(--steel);font-size:.62rem;letter-spacing:.3em;text-transform:uppercase;cursor:pointer; @@ -188,15 +189,15 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .rotsel{position:relative;width:118px;height:74px} .rotsel>.knob{position:absolute;left:50%;top:20px;margin-left:-26px;cursor:pointer} .rotsel .pos{position:absolute;font-size:9px;color:var(--dim);transform:translate(-50%,-50%);letter-spacing:.02em} -.rotsel .pos.on{color:var(--gold-hi);text-shadow:0 0 6px rgba(255,215,95,.55)} +.rotsel .pos.on{color:var(--gold-hi);text-shadow:0 0 6px rgba(255,190,84,.55)} /* slide-rule tuner dial */ .tuner{width:180px;height:46px;position:relative;border-radius:6px;overflow:hidden;cursor:pointer; background:linear-gradient(180deg,#191510,#0b0908);border:1px solid #2a251c; - box-shadow:inset 0 0 20px rgba(218,181,61,.12),inset 0 1px 0 rgba(255,255,255,.03)} + box-shadow:inset 0 0 20px rgba(226,160,56,.12),inset 0 1px 0 rgba(255,255,255,.03)} .tuner .tick{position:absolute;top:6px;width:1px;height:11px;background:var(--steel);transform:translateX(-50%)} .tuner .mk{position:absolute;bottom:8px;transform:translateX(-50%);color:var(--steel);font-size:10px} -.tuner .mk.on{color:var(--gold-hi);text-shadow:0 0 6px rgba(255,215,95,.6)} +.tuner .mk.on{color:var(--gold-hi);text-shadow:0 0 6px rgba(255,190,84,.6)} .tuner:focus-visible{outline:2px solid var(--gold);outline-offset:2px} .tuner .ndl{position:absolute;top:3px;bottom:3px;width:2px;margin-left:-1px;border-radius:1px; background:var(--fail);box-shadow:0 0 7px rgba(203,107,77,.85);transition:left .25s} @@ -212,16 +213,6 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .nixie .tube::after{content:"";position:absolute;inset:0;pointer-events:none; background:linear-gradient(180deg,rgba(255,255,255,.06),transparent 32%)} -/* magic-eye tube */ -.magiceye{width:52px;height:52px;border-radius:50%;position:relative;overflow:hidden;cursor:ns-resize;touch-action:none; - background:radial-gradient(circle,#08160a 55%,#040c05);border:1px solid #1b2c1b; - box-shadow:inset 0 0 14px rgba(0,0,0,.7)} -.magiceye .fan{position:absolute;inset:5px;border-radius:50%; - background:conic-gradient(from 140deg,#0c1e0c 0 var(--gap,64deg),#6fce33 0 360deg); - box-shadow:0 0 12px rgba(111,206,51,.4)} -.magiceye::after{content:"";position:absolute;left:50%;top:50%;width:9px;height:9px;margin:-4.5px; - border-radius:50%;background:#08160a;box-shadow:0 0 3px rgba(0,0,0,.6)} - /* ===== candidate-unique CSS ===== */ /* rocker */ .rocker{width:66px;height:40px;border-radius:7px;cursor:pointer;position:relative; @@ -231,7 +222,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} font-size:12px;letter-spacing:.06em;color:var(--dim)} .rocker .top{top:0;border-bottom:1px solid #0c0b0a;background:linear-gradient(180deg,#211d19,#181513)} .rocker .bot{bottom:0;background:linear-gradient(180deg,#141210,#100e0c);box-shadow:inset 0 3px 5px rgba(0,0,0,.55)} -.rocker.on .top{background:linear-gradient(180deg,#f0d879,var(--gold));color:var(--panel);font-weight:700;box-shadow:0 0 10px rgba(255,215,95,.35)} +.rocker.on .top{background:linear-gradient(180deg,#f2c76a,var(--gold));color:var(--panel);font-weight:700;box-shadow:0 0 10px rgba(255,190,84,.35)} .rocker.on .bot{color:var(--steel)} .rocker:not(.on) .top{color:var(--steel)} .rocker:not(.on) .bot{background:linear-gradient(180deg,#2a1512,#1c0f0d);color:var(--fail);box-shadow:inset 0 3px 5px rgba(0,0,0,.55),0 0 8px rgba(203,107,77,.25)} @@ -241,13 +232,14 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .reel{width:26px;height:26px;border-radius:50%;border:2px solid #34302a;position:relative; background:radial-gradient(circle at 45% 40%,#211d18,#0d0b09)} .reel::before{content:"";position:absolute;inset:9px;border-radius:50%;border:1px solid #4a443a;background:#161310} -.reel i{position:absolute;left:50%;top:50%;width:2px;height:11px;background:#4a443a;margin:-5.5px 0 0 -1px;transform-origin:50% 5.5px} +.reel i{position:absolute;left:50%;top:50%;width:2px;height:11px;background:var(--steel);margin:-5.5px 0 0 -1px;transform-origin:50% 5.5px} +.reel i:nth-child(1){background:var(--gold-hi);box-shadow:0 0 4px rgba(255,190,84,.55)} .reel i:nth-child(2){transform:rotate(120deg)}.reel i:nth-child(3){transform:rotate(240deg)} .transport{display:flex;gap:5px} .tbtn{font:inherit;font-size:12px;color:var(--silver);cursor:pointer;width:30px;height:26px;display:grid;place-items:center; background:linear-gradient(180deg,#23211e,#191715);border:1px solid #33302b;border-bottom-color:#0c0b0a;border-radius:6px} .tbtn:hover{color:var(--gold);border-color:var(--gold)} -.tbtn.on{color:var(--panel);background:linear-gradient(180deg,#f0d879,var(--gold));border-color:var(--gold-hi)} +.tbtn.on{color:var(--panel);background:linear-gradient(180deg,#f2c76a,var(--gold));border-color:var(--gold-hi)} .tbtn.rec.on{color:var(--cream);background:linear-gradient(180deg,#d98a6f,var(--fail));border-color:var(--fail)} /* radio bank */ @@ -257,7 +249,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} background:linear-gradient(180deg,#211d19,#161310);box-shadow:inset 0 1px 0 rgba(255,255,255,.04)} .preset+.preset{margin-left:3px} .preset:hover{color:var(--silver)} -.preset.on{color:var(--panel);background:linear-gradient(180deg,#f0d879,var(--gold));font-weight:700; +.preset.on{color:var(--panel);background:linear-gradient(180deg,#f2c76a,var(--gold));font-weight:700; box-shadow:inset 0 2px 4px rgba(0,0,0,.4)} /* concentric dual knob */ @@ -269,13 +261,13 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .dualknob .inner{width:34px;height:34px;border-radius:50%;position:absolute;left:15px;top:15px;cursor:ns-resize;touch-action:none; background:radial-gradient(circle at 40% 35%,#37322a,#1a1713);border:1px solid #4a443a;box-shadow:0 2px 4px rgba(0,0,0,.5)} .dualknob .inner .ind{position:absolute;left:50%;top:3px;width:2px;height:11px;background:var(--gold-hi);margin-left:-1px; - transform-origin:50% 14px;border-radius:1px;box-shadow:0 0 5px rgba(255,215,95,.6)} + transform-origin:50% 14px;border-radius:1px;box-shadow:0 0 5px rgba(255,190,84,.6)} /* rotary encoder + LED ring */ .encoder{position:relative;width:66px;height:66px;display:grid;place-items:center;cursor:ns-resize;touch-action:none} .encoder .led{position:absolute;width:5px;height:5px;border-radius:50%;background:var(--wash); left:50%;top:50%;margin:-2.5px} -.encoder .led.on{background:var(--gold);box-shadow:0 0 5px 1px rgba(218,181,61,.7)} +.encoder .led.on{background:var(--gold);box-shadow:0 0 5px 1px rgba(226,160,56,.7)} .encoder .knob{width:40px;height:40px;cursor:ns-resize} .encoder .knob .ind{transform-origin:50% 15px;top:4px;height:12px} @@ -287,9 +279,9 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .keylock .barrel{position:absolute;left:50%;top:50%;width:5px;height:5px;margin:-2.5px;border-radius:1px;background:#0a0908; box-shadow:0 0 2px rgba(0,0,0,.8)} .keylock .bit{position:absolute;left:50%;top:50%;width:3px;height:15px;margin:-15px 0 0 -1.5px;background:var(--gold-hi); - border-radius:1px;transform-origin:50% 100%;box-shadow:0 0 5px rgba(255,215,95,.55);transition:transform .2s} + border-radius:1px;transform-origin:50% 100%;box-shadow:0 0 5px rgba(255,190,84,.55);transition:transform .2s} .keylock .kpos{position:absolute;font-size:9px;color:var(--dim);letter-spacing:.05em;transform:translate(-50%,-50%)} -.keylock .kpos.on{color:var(--gold-hi);text-shadow:0 0 6px rgba(255,215,95,.55)} +.keylock .kpos.on{color:var(--gold-hi);text-shadow:0 0 6px rgba(255,190,84,.55)} /* crossfader */ .xfader{width:160px;height:22px;position:relative;cursor:pointer;touch-action:none} @@ -297,7 +289,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .xfader .detent{position:absolute;top:2px;left:50%;width:1px;height:18px;background:var(--steel);margin-left:-.5px;opacity:.7} .xfader .end{position:absolute;top:11px;font-size:9px;color:var(--steel);transform:translateY(-50%)} .xfader .cap{position:absolute;top:3px;width:9px;height:16px;border-radius:2px;margin-left:-4.5px;transition:left .05s; - background:linear-gradient(180deg,#f0d879,#caa233);border:1px solid #7a6414;box-shadow:0 1px 2px rgba(0,0,0,.5)} + background:linear-gradient(180deg,#f2c76a,#d29638);border:1px solid #7d5c16;box-shadow:0 1px 2px rgba(0,0,0,.5)} /* thumbwheel */ .thumbw{display:flex;align-items:center;gap:10px} @@ -314,7 +306,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .dipsw{width:12px;height:26px;background:#0a1220;border-radius:2px;position:relative;cursor:pointer;border:1px solid #1c2c42} .dipsw i{position:absolute;left:1px;right:1px;height:11px;border-radius:1px;background:linear-gradient(180deg,#eae4d2,#b4ad98); bottom:1px;transition:bottom .12s,top .12s} -.dipsw.on i{bottom:auto;top:1px;background:linear-gradient(180deg,#f0d879,var(--gold))} +.dipsw.on i{bottom:auto;top:1px;background:linear-gradient(180deg,#f2c76a,var(--gold))} /* jog / shuttle */ .jog{position:relative;width:74px;height:74px;cursor:ns-resize;touch-action:none} @@ -350,7 +342,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .crossm .face{position:relative;height:56px;overflow:hidden;cursor:ns-resize;touch-action:none} .crossm .arc{position:absolute;inset:2px 4px -56px;border:2px solid var(--wash);border-radius:50%} .crossm .nA{position:absolute;left:14px;bottom:2px;width:2px;height:52px;background:var(--gold-hi);transform-origin:50% 100%; - border-radius:2px;box-shadow:0 0 5px rgba(255,215,95,.5);transition:transform .12s cubic-bezier(.3,1.2,.5,1)} + border-radius:2px;box-shadow:0 0 5px rgba(255,190,84,.5);transition:transform .12s cubic-bezier(.3,1.2,.5,1)} .crossm .nB{position:absolute;right:14px;bottom:2px;width:2px;height:52px;background:var(--fail);transform-origin:50% 100%; border-radius:2px;box-shadow:0 0 5px rgba(203,107,77,.5);transition:transform .12s cubic-bezier(.3,1.2,.5,1)} .crossm .lbl{display:flex;justify-content:space-between;color:var(--steel);font-size:9px;margin-top:2px} @@ -370,7 +362,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} box-shadow:inset 0 2px 5px rgba(0,0,0,.6)} .bourdon svg{position:absolute;inset:0} .bourdon .ndl{position:absolute;left:50%;top:50%;width:2px;height:32px;margin:-32px 0 0 -1px;background:var(--gold-hi); - transform-origin:50% 100%;border-radius:2px;box-shadow:0 0 5px rgba(255,215,95,.55);transition:transform .12s cubic-bezier(.3,1.2,.5,1)} + transform-origin:50% 100%;border-radius:2px;box-shadow:0 0 5px rgba(255,190,84,.55);transition:transform .12s cubic-bezier(.3,1.2,.5,1)} .bourdon .hub{position:absolute;left:50%;top:50%;width:8px;height:8px;margin:-4px;border-radius:50%;background:var(--gold)} .bourdon .cap{position:absolute;left:0;right:0;bottom:12px;text-align:center;font-size:8px;letter-spacing:.16em;color:var(--steel)} @@ -382,7 +374,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .strip svg{position:absolute;inset:0;width:100%;height:100%} .strip polyline{fill:none;stroke:var(--gold);stroke-width:1.4} .strip .pen{position:absolute;right:2px;width:6px;height:6px;margin:-3px;border-radius:50%;background:var(--gold-hi); - box-shadow:0 0 6px rgba(255,215,95,.8);transition:top .08s linear} + box-shadow:0 0 6px rgba(255,190,84,.8);transition:top .08s linear} /* correlation */ .corr{width:150px;cursor:pointer;touch-action:none} @@ -390,7 +382,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .corr .arc{position:absolute;inset:0 0 -44px;border:2px solid var(--wash);border-radius:50%} .corr .zero{position:absolute;left:50%;top:2px;width:1px;height:10px;background:var(--gold);margin-left:-.5px} .corr .ndl{position:absolute;left:50%;bottom:0;width:2px;height:38px;background:var(--gold-hi);transform-origin:50% 100%; - border-radius:2px;box-shadow:0 0 5px rgba(255,215,95,.5);transition:transform .1s ease-out} + border-radius:2px;box-shadow:0 0 5px rgba(255,190,84,.5);transition:transform .1s ease-out} .corr .lbl{display:flex;justify-content:space-between;color:var(--steel);font-size:9px;margin-top:2px} /* battery */ @@ -431,7 +423,7 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .annun{display:grid;grid-template-columns:repeat(3,1fr);gap:3px} .acell{font-size:8.5px;letter-spacing:.08em;text-align:center;color:var(--dim);padding:6px 4px;border-radius:3px;cursor:pointer; background:#141210;border:1px solid #262320;line-height:1.2} -.acell.warn{color:var(--panel);background:linear-gradient(180deg,#f0c25f,var(--gold));font-weight:700;box-shadow:0 0 8px rgba(218,181,61,.4)} +.acell.warn{color:var(--panel);background:linear-gradient(180deg,#f0b552,var(--gold));font-weight:700;box-shadow:0 0 8px rgba(226,160,56,.4)} .acell.fault{color:var(--cream);background:linear-gradient(180deg,#d98a6f,var(--fail));font-weight:700;box-shadow:0 0 8px rgba(203,107,77,.4);animation:pulse 1s ease-in-out infinite} /* jewel */ @@ -465,13 +457,13 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .clock .mh{position:absolute;left:50%;top:50%;width:2px;height:28px;margin:-28px 0 0 -1px;background:var(--silver); transform-origin:50% 100%;border-radius:2px} .clock .sh{position:absolute;left:50%;top:50%;width:1px;height:30px;margin:-30px 0 0 -.5px;background:var(--gold-hi); - transform-origin:50% 100%;box-shadow:0 0 4px rgba(255,215,95,.5)} + transform-origin:50% 100%;box-shadow:0 0 4px rgba(255,190,84,.5)} .clock .pin{position:absolute;left:50%;top:50%;width:6px;height:6px;margin:-3px;border-radius:50%;background:var(--gold)} /* frequency-dial scale */ .freqscale{width:184px;height:44px;position:relative;border-radius:5px;overflow:hidden;cursor:pointer;touch-action:none; background:linear-gradient(180deg,#191510,#0b0908);border:1px solid #2a251c; - box-shadow:inset 0 0 16px rgba(218,181,61,.1)} + box-shadow:inset 0 0 16px rgba(226,160,56,.1)} .freqscale .tick{position:absolute;top:5px;width:1px;background:var(--steel);transform:translateX(-50%)} .freqscale .mk{position:absolute;bottom:6px;transform:translateX(-50%);color:var(--steel);font-size:9px} .freqscale .band{position:absolute;bottom:2px;left:6px;color:var(--gold);font-size:8px;letter-spacing:.18em} @@ -484,8 +476,8 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} .patch .row+.row{margin-top:9px} .patch .jack{width:13px;height:13px;border-radius:50%;cursor:pointer;background:radial-gradient(circle at 40% 35%,#3a352c,#0a0908 70%); border:1px solid #4a443a;box-shadow:inset 0 1px 2px rgba(0,0,0,.8)} -.patch .jack.hot{background:radial-gradient(circle at 40% 35%,#7a6414,#1a1408 70%)} -.patch .jack.sel{border-color:var(--gold-hi);box-shadow:0 0 6px 1px rgba(255,215,95,.7)} +.patch .jack.hot{background:radial-gradient(circle at 40% 35%,#7d5c16,#1a1408 70%)} +.patch .jack.sel{border-color:var(--gold-hi);box-shadow:0 0 6px 1px rgba(255,190,84,.7)} .patch svg{position:absolute;inset:0;pointer-events:none;width:100%;height:100%} .patch svg path{fill:none;stroke:var(--gold);stroke-width:2.4;opacity:.85;stroke-linecap:round} @@ -725,7 +717,7 @@ card(M,'N18','Battery-cell gauge', /* ============ INDICATORS & READOUTS ============ */ const I=$('indicators'); card(I,'18','Status lamp', - `<span id="lamp18"><span class="lamp"></span><span class="lamp gold"></span><span class="lamp red"></span><span class="lamp off"></span><span class="lamp busy"></span></span>`, + `<span id="lamp18" style="display:inline-flex;gap:9px;align-items:center"><span class="lamp"></span><span class="lamp gold"></span><span class="lamp red"></span><span class="lamp off"></span><span class="lamp busy"></span></span>`, '<b>one-glance health.</b> Green ok · gold engaged · red fail · dim off · pulsing busy. Click any lamp to cycle its state.'); card(I,'19','Badge / tag', `<span id="badge19"><span class="badge">TUNNEL</span> <span class="badge red">LOW BATT</span> <span class="badge ghost">2.4G</span></span>`, @@ -746,9 +738,6 @@ card(I,'23','Toast / status line', card(I,'26','Nixie tube', `<span class="nixie" id="nixie"><span class="tube off"><b>0</b></span><span class="tube"><b>8</b></span></span>`, '<b>a single warm-glowing numeral.</b> One lit digit per tube, leading zeros dark. Click to increment the count.'); -card(I,'27','Magic-eye tube', - `<span class="magiceye" id="meye"><span class="fan"></span></span>`, - '<b>the glowing tuning eye.</b> A phosphor tube whose dark wedge narrows as the value peaks. Drag up/down to set; readout tracks.'); card(I,'N20','Split-flap display', `<span class="flap" id="flap"><span class="flapd"><b>D</b></span><span class="flapd"><b>N</b></span><span class="flapd"><b>S</b></span></span>`, '<b>flips to the new value.</b> Each card drops to the next glyph with the mechanical clack. Auto-flips; click to flip now.'); @@ -765,7 +754,7 @@ card(I,'N23','Annunciator panel', </div>`, '<b>a grid of named alarms.</b> Cells light amber to warn, red to fault (faults pulse). Click a cell to cycle its state.'); card(I,'N24','Jewel pilot lamps', - `<span id="jewels"><span class="jewel" style="--jc:var(--jewel-r)"></span><span class="jewel" style="--jc:var(--jewel-a)"></span> + `<span id="jewels" style="display:inline-flex;gap:10px;align-items:center"><span class="jewel" style="--jc:var(--jewel-r)"></span><span class="jewel" style="--jc:var(--jewel-a)"></span> <span class="jewel" style="--jc:var(--jewel-g)"></span><span class="jewel dim"></span></span>`, '<b>a faceted glass indicator.</b> The chunky bezel pilot lamp with a real bloom. Click a jewel to cycle red · amber · green · dark.'); card(I,'N25','Tape counter', @@ -957,10 +946,6 @@ let nixV=8; function setNix(v){nixV=v;const t=$('nixie').children,s=String(v).padStart(2,'0'); t[0].classList.toggle('off',v<10);t[0].querySelector('b').textContent=s[0];t[1].querySelector('b').textContent=s[1];setRd('26',s);} $('nixie').onclick=()=>setNix((nixV+1)%100);setNix(8); -/* 27 magic-eye */ -let meV=48; -function setEye(v){meV=v;$('meye').querySelector('.fan').style.setProperty('--gap',(8+(100-v)/100*118)+'deg');setRd('27',Math.round(v)+'%');} -dragDelta($('meye'),()=>meV,setEye,{min:0,max:100});setEye(48); /* N23 annunciator */ (function(){const st=['acell','acell warn','acell fault'];const nm=['ok','warn','fault']; $('annun').querySelectorAll('.acell').forEach(cell=>{const label=cell.textContent;cell.onclick=()=>{ diff --git a/docs/specs/2026-07-02-timer-panel-spec.org b/docs/specs/2026-07-02-timer-panel-spec.org index 275bb2c..e5f0f4e 100644 --- a/docs/specs/2026-07-02-timer-panel-spec.org +++ b/docs/specs/2026-07-02-timer-panel-spec.org @@ -127,7 +127,7 @@ panel proves out. * Build scope (decided design — folds the prototype-3 redesign into the shipped =timer/= package) -The panel is the existing =timer/= dotfiles package (src-layout, GTK4 + gtk4-layer-shell, humble-object PanelModel, instrument-console faceplate). wtimer stays the state engine; the panel is a view over it. This rebuild reshapes the layout (see Layout sketch) and adds the per-type functionality below. UI idioms draw from the widget gallery (=docs/prototypes/2026-07-03-panel-widget-gallery-prototype.html=); the reference build is prototype-3. +The panel is the existing =timer/= dotfiles package (src-layout, GTK4 + gtk4-layer-shell, humble-object PanelModel, instrument-console faceplate). wtimer stays the state engine; the panel is a view over it. This rebuild reshapes the layout (see Layout sketch) and adds the per-type functionality below. UI idioms draw from the widget gallery (=docs/prototypes/panel-widget-gallery.html=); the reference build is prototype-3. Queue + primary: - Up to 10 items, auto-sorted by soonest fire time (four buckets: active countdown < paused countdown < active stopwatch < paused stopwatch). The soonest-firing is the hero/primary (the bar glyph slot). Promote via a row's promote key or by cycling ‹ ›; cycling and promotion include stopwatches and wrap around the whole list. |
