diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-12 20:24:11 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-12 20:24:11 -0500 |
| commit | 858caec5aa942ba621845d054c000269e0fe0384 (patch) | |
| tree | 987f5806c2318d2436aa6a08a77651a532e1cd98 /docs/prototypes/panel-widget-gallery.html | |
| parent | f536d4c9a9af306e33f52ca0772f7442695964f1 (diff) | |
| download | archsetup-858caec5aa942ba621845d054c000269e0fe0384.tar.gz archsetup-858caec5aa942ba621845d054c000269e0fe0384.zip | |
feat(gallery): validation lamps and the readout/options/text card order
Every card gets a status lamp at the upper-right for the pre-componentization validation pass: click cycles not-done, in-progress, done, and the state persists per card in localStorage. Below the stage the card now reads readout, then options, then descriptive text, with separators between the zones and no labels — chips moved into a generic options container that future selectors share.
Diffstat (limited to 'docs/prototypes/panel-widget-gallery.html')
| -rw-r--r-- | docs/prototypes/panel-widget-gallery.html | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html index fbf2e0a..99342bc 100644 --- a/docs/prototypes/panel-widget-gallery.html +++ b/docs/prototypes/panel-widget-gallery.html @@ -102,12 +102,21 @@ h2::after{content:"";height:1px;background:var(--wash);flex:1} box-shadow:inset 0 1px 0 rgba(255,255,255,.04),0 6px 14px rgba(0,0,0,.4)} .wname{color:var(--cream);font-size:.95rem;font-weight:700;display:flex;align-items:center;gap:8px} .wname .no{color:var(--panel);background:var(--gold);border-radius:4px;font-size:.7rem;padding:0 5px;font-weight:400} +/* validation lamp: off = not done, amber = in progress, green = done; click cycles, state persists */ +.vlamp{margin-left:auto;flex:0 0 auto;width:10px;height:10px;border-radius:50%;cursor:pointer; + background:#221f1b;border:1px solid #33302b} +.vlamp[data-v="amber"]{background:var(--gold);border-color:#7d5c16;box-shadow:0 0 6px 1px rgba(var(--glow-lo),.6)} +.vlamp[data-v="green"]{background:var(--pass);border-color:#4a5c22;box-shadow:0 0 6px 1px rgba(116,147,47,.6)} .stagew{background:var(--well);border:1px solid #201d17;border-radius:9px;padding:14px 12px; min-height:78px;display:flex;align-items:center;justify-content:center;gap:12px;flex-wrap:wrap} .wrd{color:var(--gold-hi);font-size:.8rem;letter-spacing:.06em;font-variant-numeric:tabular-nums; - min-height:.95rem;display:flex;align-items:center;gap:6px} + min-height:.95rem;display:flex;align-items:center;gap:6px; + border-top:1px solid var(--wash);padding-top:9px;margin-top:2px} .wrd::before{content:"▸";color:var(--steel);font-size:.7rem} -.wnote{color:var(--dim);font-size:.85rem;line-height:1.45} +.opts{display:flex;flex-direction:column;gap:5px} +.opts:empty{display:none} +.wnote{color:var(--dim);font-size:.85rem;line-height:1.45; + border-top:1px solid var(--wash);padding-top:9px;margin-top:2px} .wnote b{color:var(--steel);font-weight:400} /* per-card spec sheet (collapsible) */ @@ -795,7 +804,7 @@ function screenChips(no,el,fams,def){ row.querySelectorAll('.fc').forEach(x=>x.classList.toggle('on',x===b)); setRd(no,'screen '+f);}); row.appendChild(b);}); - cardEl.insertBefore(row,cardEl.querySelector('.wrd')); + cardEl.querySelector('.opts').appendChild(row); } /* ---- per-card spec sheets ---- input how you drive it, incl. the model: click widgets port to every target (Emacs click-regions @@ -1517,10 +1526,18 @@ const INFO={ }; const INFO_FIELDS=[['input','input'],['solves','solves'],['use','use'],['limits','limits'], ['origin','origin'],['difficulty','difficulty'],['prefer','prefer when'],['period','period']]; +const VLAMP_TITLES={off:'validation: not done',amber:'validation: in progress',green:'validation: done'}; function card(host, no, name, html, note){ const c=document.createElement('div'); c.className='card'; - c.innerHTML=`<div class="wname"><span class="no">${no}</span>${name}</div>`+ - `<div class="stagew">${html}</div><div class="wrd" id="rd-${no}">—</div><div class="wnote">${note}</div>`; + c.innerHTML=`<div class="wname"><span class="no">${no}</span>${name}<span class="vlamp" data-v="off"></span></div>`+ + `<div class="stagew">${html}</div><div class="wrd" id="rd-${no}">—</div>`+ + `<div class="opts"></div><div class="wnote">${note}</div>`; + const lamp=c.querySelector('.vlamp'), VKEY='gv-'+no, VSTATES=['off','amber','green']; + const setV=v=>{lamp.dataset.v=v;lamp.title=VLAMP_TITLES[v];}; + setV(localStorage.getItem(VKEY)||'off'); + lamp.addEventListener('click',e=>{e.stopPropagation(); + const v=VSTATES[(VSTATES.indexOf(lamp.dataset.v)+1)%3]; + setV(v);localStorage.setItem(VKEY,v);}); const inf=(typeof INFO!=='undefined')&&INFO[no]; if(inf){const d=document.createElement('details'); d.className='winfo'; let rows=''; @@ -4244,7 +4261,7 @@ BOOST.forEach(no=>{const rd=document.getElementById('rd-'+no); row.appendChild(b);}}; group('on',ON_OPTS,'amber'); group('off',OFF_OPTS,'dark'); - cardEl.insertBefore(row,cardEl.querySelector('.wrd'));})(); + cardEl.querySelector('.opts').appendChild(row);})(); </script> </body> </html> |
