aboutsummaryrefslogtreecommitdiff
path: root/docs/prototypes
diff options
context:
space:
mode:
Diffstat (limited to 'docs/prototypes')
-rw-r--r--docs/prototypes/panel-widget-gallery.html45
1 files changed, 45 insertions, 0 deletions
diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html
index 1ecfbaf..04cd0cf 100644
--- a/docs/prototypes/panel-widget-gallery.html
+++ b/docs/prototypes/panel-widget-gallery.html
@@ -712,6 +712,9 @@ card(C,'R14','Spade-pointer tuning knob',
card(C,'R15','Multi-band dial',
`<svg id="mband" class="rsvg" viewBox="0 0 190 110" width="190" height="110"></svg>`,
'<b>four scales, one needle.</b> Nested band arcs on a cream face; the active ring reads bold. Drag the left dial to tune; click the bandspread dial to switch bands. After a shortwave receiver dial pair.');
+card(C,'R16','Entry keypad',
+ `<svg id="keypad" class="rsvg" viewBox="0 0 150 190" width="150" height="190"></svg>`,
+ '<b>a composed entry instrument.</b> Worn keycaps feed the amber display; the lamp watches the buffer; the amber keys confirm and clear. Click the keys. After an industrial keypad prop.');
/* ============ METERS & GAUGES ============ */
const M=$('meters');
@@ -1554,6 +1557,48 @@ function setMband(v,b){mbandV=Math.max(0,Math.min(100,v));mbandB=b;
setRd('R15',`B${b+1} · ${mc.toFixed(2)} Mc`);}
setMband(45,2);
+/* R16 entry keypad: worn keys feed the amber display; lamps watch state */
+let kpBuf='',kpDisp=null,kpLampTop=null,kpLampBot=null;
+(function(){const s=$('keypad');
+ const defs=svgEl(s,'defs',{});
+ const kg=svgEl(defs,'linearGradient',{id:'kpKey',x1:0,y1:0,x2:0,y2:1});
+ svgEl(kg,'stop',{offset:'0','stop-color':'#dbd8cf'});
+ svgEl(kg,'stop',{offset:'1','stop-color':'#a29d92'});
+ const ag=svgEl(defs,'linearGradient',{id:'kpAmber',x1:0,y1:0,x2:0,y2:1});
+ svgEl(ag,'stop',{offset:'0','stop-color':'var(--amber-grad-top)'});
+ svgEl(ag,'stop',{offset:'1','stop-color':'var(--amber-grad-mid)'});
+ // lamp pod
+ const lamp=cy=>{const l=svgEl(s,'circle',{cx:13,cy,r:6.5,fill:'#3a0f0a',stroke:'#14100e','stroke-width':1.5});return l;};
+ kpLampTop=lamp(20);kpLampBot=lamp(38);
+ // display window
+ svgEl(s,'rect',{x:26,y:8,width:116,height:32,rx:5,fill:'#0a0806',stroke:'#2c261d','stroke-width':2});
+ kpDisp=svgEl(s,'text',{x:84,y:31,'text-anchor':'middle','font-size':16,'letter-spacing':'.22em',
+ 'font-family':'var(--mono)',fill:'var(--gold-hi)'});
+ // key plate
+ svgEl(s,'rect',{x:24,y:48,width:118,height:138,rx:8,fill:'#1a1714',stroke:'#0a0908','stroke-width':1.5});
+ const KEYS=[['1','2','3'],['4','5','6'],['7','8','9'],['✓','0','✗']];
+ const jitter=[-2,1,-1,2,0,-2,1,-1,2,0,-1,1];
+ KEYS.forEach((row,r)=>row.forEach((k,c)=>{
+ const x=47+c*36,y=68+r*32,amber=(k==='✓'||k==='✗');
+ const g=svgEl(s,'g',{});g.style.cursor='pointer';g.style.transition='transform .07s';
+ svgEl(g,'rect',{x:x-14,y:y-11,width:28,height:24,rx:4,fill:amber?'url(#kpAmber)':'url(#kpKey)',
+ stroke:'#4e4a42','stroke-width':1,'stroke-opacity':.8});
+ svgEl(g,'text',{x,y:y+6,'text-anchor':'middle','font-size':13,'font-weight':700,
+ 'font-family':'var(--mono)',fill:k==='✓'?'#3f5a1f':k==='✗'?'#7a2a1a':'#2b2721',
+ transform:`rotate(${jitter[r*3+c]},${x},${y})`}).textContent=k;
+ g.addEventListener('click',()=>{g.style.transform='translateY(1.5px)';
+ setTimeout(()=>g.style.transform='',80);kpPress(k);});}));
+ })();
+function kpRender(){kpDisp.textContent=kpBuf.padEnd(6,'–');
+ kpLampTop.setAttribute('fill',kpBuf?'var(--jewel-r)':'#3a0f0a');}
+function kpPress(k){
+ if(k==='✓'){setRd('R16',kpBuf?'OK · '+kpBuf:'empty');kpBuf='';kpRender();return;}
+ if(k==='✗'){kpBuf='';kpRender();setRd('R16','cleared');
+ kpLampBot.setAttribute('fill','var(--jewel-r)');
+ setTimeout(()=>kpLampBot.setAttribute('fill','#3a0f0a'),350);return;}
+ if(kpBuf.length<6){kpBuf+=k;kpRender();setRd('R16',kpBuf);}}
+kpRender();setRd('R16','enter a code');
+
/* ============ LIVE SIGNAL LOOPS ============ */
buildBars($('vuL'),16);buildBars($('vuR'),16);$('mini').innerHTML='<i></i><i></i><i></i><i></i>';
(function(){const eq=$('eq');for(let b=0;b<11;b++){const band=document.createElement('span');band.className='band';