Post-PR-#11 polish: demo UI, staffer console, face pool, icons, contractor profile (24 commits) #12

Merged
profit merged 44 commits from demo/post-pr11-polish-2026-04-28 into main 2026-05-03 05:16:17 +00:00
Showing only changes of commit f92b55615f - Show all commits

View File

@ -48,7 +48,18 @@ body{font-family:'Inter',-apple-system,system-ui,'Segoe UI',sans-serif;backgroun
/* Workers */
.iworker{display:flex;align-items:center;gap:12px;padding:10px 12px;background:#161b22;border-radius:8px;margin-bottom:4px;transition:background 0.15s}
.iworker:hover{background:#1c2333}
.iworker .av{width:36px;height:36px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:12px;color:#e6edf3;flex-shrink:0}
.iworker .av{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:13px;color:#c9d1d9;flex-shrink:0;background:#161b22;border:1px solid #21262d;letter-spacing:0.5px;font-family:'Inter',-apple-system,sans-serif}
.iworker .role-pill{display:inline-block;font-size:10px;padding:2px 8px;border-radius:3px;background:#0d1117;color:#8b949e;margin-right:8px;font-weight:600;letter-spacing:0.4px;text-transform:uppercase;border-left:2px solid #30363d}
.iworker[data-role-band="warehouse"]{border-left:3px solid #58a6ff}
.iworker[data-role-band="production"]{border-left:3px solid #d29922}
.iworker[data-role-band="trades"]{border-left:3px solid #bc8cff}
.iworker[data-role-band="driver"]{border-left:3px solid #3fb950}
.iworker[data-role-band="lead"]{border-left:3px solid #f0883e}
.iworker .role-pill[data-rb="warehouse"]{border-left-color:#58a6ff;color:#79c0ff}
.iworker .role-pill[data-rb="production"]{border-left-color:#d29922;color:#e3b341}
.iworker .role-pill[data-rb="trades"]{border-left-color:#bc8cff;color:#d2a8ff}
.iworker .role-pill[data-rb="driver"]{border-left-color:#3fb950;color:#56d364}
.iworker .role-pill[data-rb="lead"]{border-left-color:#f0883e;color:#ffa657}
.iworker .info{flex:1;min-width:0}
.iworker .nm{font-weight:600;color:#e6edf3;font-size:13px}
.iworker .detail{color:#545d68;font-size:11px}
@ -2249,6 +2260,34 @@ function addBigMeter(parent,label,val,desc){
d.appendChild(lb);d.appendChild(row);d.appendChild(ds);parent.appendChild(d);
}
// Role classification — sober, no illustrations. Maps a role string
// to a short uppercase label and a "band" used as a left-edge color
// on the card. Five bands cover the warehouse/manufacturing surface;
// the band controls the left border on .iworker and on the role pill.
// No emojis — staffer-readable, professional. Add bands here when
// new role families appear in the data.
var ROLE_BANDS = [
{ match: /forklift|warehouse|associate|material\s*handler|loader|loading|packag|shipping|logistics|inventory|sanitation|janit/i,
band: 'warehouse', label: 'Warehouse' },
{ match: /production|assembl/i,
band: 'production', label: 'Production' },
{ match: /welder|weld|electric|maint(enance)?\s*tech|cnc|machine\s*op|hvac|plumb|carpenter|mason/i,
band: 'trades', label: 'Skilled Trade' },
{ match: /driver|truck|haul|cdl/i,
band: 'driver', label: 'Driver' },
{ match: /line\s*lead|supervisor|foreman|coordinator/i,
band: 'lead', label: 'Lead' },
{ match: /quality/i,
band: 'production', label: 'Quality' },
];
function roleBand(role){
if(!role) return { band: 'warehouse', label: '' };
for (var i = 0; i < ROLE_BANDS.length; i++) {
if (ROLE_BANDS[i].match.test(role)) return ROLE_BANDS[i];
}
return { band: 'warehouse', label: role.split(' ')[0].toUpperCase().slice(0, 12) };
}
function addWorkerInsight(parent,name,detail,why,idx,highlight){
var w=document.createElement('div');w.className='iworker';
if(highlight)w.style.borderLeft='3px solid '+highlight;
@ -2256,7 +2295,13 @@ function addWorkerInsight(parent,name,detail,why,idx,highlight){
var workerDataRef=arguments[6]||null; // passed as 7th arg
var boostInfo=arguments[7]||null; // {boost, citations} — Phase 19
w.onclick=function(){if(workerDataRef)showProfile(workerDataRef)};
var av=document.createElement('div');av.className='av';av.style.background=AC[(idx||0)%AC.length];
// Sober avatar: monogram initials, dark muted background, subtle
// ring. Role classification adds a colored left-edge band on the
// card and on the role pill; no emoji, no illustrations.
var av=document.createElement('div');av.className='av';
var role = (workerDataRef && workerDataRef.role) || (detail||'').split(' · ')[0] || '';
var band = roleBand(role);
if(band.band) w.dataset.roleBand = band.band;
av.textContent=(name||'?').split(' ').map(function(n){return(n[0]||'').toUpperCase()}).join('').substring(0,2);
w.appendChild(av);
var info=document.createElement('div');info.className='info';
@ -2292,7 +2337,17 @@ function addWorkerInsight(parent,name,detail,why,idx,highlight){
chip.title=name+' — endorsed in '+n+' playbook'+(n!==1?'s':'');
});
}
var dt=document.createElement('div');dt.className='detail';dt.textContent=detail;
// Detail line. Lead with a small uppercase pill that classifies the
// role family — color matches the card's left-edge band so the eye
// groups by role family at a glance. No icons.
var dt=document.createElement('div');dt.className='detail';
if(band.label){
var pill=document.createElement('span'); pill.className='role-pill';
pill.dataset.rb = band.band;
pill.textContent = band.label;
dt.appendChild(pill);
}
dt.appendChild(document.createTextNode(detail));
info.appendChild(nm);info.appendChild(dt);
if(why){var wh=document.createElement('div');wh.className='why';wh.textContent=why;info.appendChild(wh)}
w.appendChild(info);