/* ui · shape: Workbench · theme: Signal · nav: N4 · footer: F1 · tone: utilitarian */
* { box-sizing:border-box; }
body { margin:0; background:var(--color-paper); color:var(--color-ink); font-family:var(--font-body); font-size:var(--text-base); line-height:1.5; }
button,input,select { font:inherit; }
button,a,input,select { -webkit-tap-highlight-color:transparent; }
a { color:var(--color-accent); }
a:hover { color:var(--color-accent-hover); }
button { display:inline-flex; align-items:center; justify-content:center; gap:var(--space-2xs); min-height:var(--size-touch); padding:var(--space-2xs) var(--space-sm); border:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-md); background:var(--color-paper); color:var(--color-ink); cursor:pointer; font-weight:600; transition:transform var(--dur-fast) var(--ease-out); }
button:hover { background:var(--color-paper-2); }
button:active { transform:scale(.97); }
button:disabled { background:var(--color-disabled); color:var(--color-ink-2); cursor:not-allowed; transform:none; }
:focus-visible { outline:3px solid var(--color-focus); outline-offset:3px; }
.primary { background:var(--color-accent); color:var(--color-on-accent); border-color:var(--color-accent); }
.primary:hover { background:var(--color-accent-hover); }
.danger { color:var(--color-red); }
.quiet { border-color:transparent; background:transparent; color:var(--color-accent); }
.quiet:disabled { background:transparent; }
.full { width:100%; max-width:var(--size-form); }
.icon { flex:none; display:inline-block; width:var(--size-icon); height:var(--size-icon); background:currentColor; -webkit-mask:var(--icon) center / contain no-repeat; mask:var(--icon) center / contain no-repeat; }
.icon[data-icon=home] { --icon:var(--icon-home); }
.icon[data-icon=checkmark-done] { --icon:var(--icon-checkmark-done); }
.icon[data-icon=people] { --icon:var(--icon-people); }
.icon[data-icon=train] { --icon:var(--icon-train); }
.icon[data-icon=settings] { --icon:var(--icon-settings); }
.icon[data-icon=exit] { --icon:var(--icon-exit); }
.icon[data-icon=enter] { --icon:var(--icon-enter); }
.icon[data-icon=close] { --icon:var(--icon-close); }
.icon[data-icon=key] { --icon:var(--icon-key); }
.icon[data-icon=grid] { --icon:var(--icon-grid); }
.icon[data-icon=list] { --icon:var(--icon-list); }
.icon-button { width:var(--size-touch); padding:0; color:var(--color-ink); }
.icon-button .icon { width:var(--size-icon-dock); height:var(--size-icon-dock); }
input,select { width:100%; min-width:0; min-height:var(--size-touch); border:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-md); background:var(--color-paper); color:var(--color-ink); padding:var(--space-2xs) var(--space-xs); }
select { appearance:none; -webkit-appearance:none; padding-right:var(--space-lg); background-image:var(--icon-chevron); background-repeat:no-repeat; background-position:right var(--space-xs) center; background-size:var(--size-icon); }
input:hover,select:hover { border-color:var(--color-ink-2); }
input:disabled,select:disabled { background-color:var(--color-disabled); }
input[aria-invalid=true] { border-color:var(--color-red); }
label,.label { display:block; font-size:var(--text-sm); font-weight:600; margin-bottom:var(--space-3xs); }
/* Search and sort explain themselves (placeholder, option text); their labels stay for assistive tech only. */
.sr-only,.field:has(>[type=search])>label,.field:has(>[name=sort])>label { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
.field { margin-block:var(--space-sm); min-width:0; }
h1,h2,h3 { font-family:var(--font-display); font-style:normal; line-height:1.2; overflow-wrap:anywhere; margin:0 0 var(--space-2xs); }
h1 { font-size:var(--text-xl); letter-spacing:-.03em; }
h2 { font-size:var(--text-lg); letter-spacing:-.015em; }
h3 { font-size:var(--text-base); }
p { margin:0 0 var(--space-sm); max-width:65ch; }
small,.muted { color:var(--color-ink-2); }
small { font-size:var(--text-sm); }
.mono { font-family:var(--font-mono); font-variant-numeric:tabular-nums; }
.masthead { border-bottom:var(--rule-hair) solid var(--color-rule-soft); }
.header-inner { max-width:var(--size-content); margin:auto; display:flex; align-items:center; justify-content:space-between; gap:var(--space-xs); padding:var(--space-2xs) var(--space-sm); }
.brand { font-family:var(--font-display); font-weight:700; font-size:var(--text-base); letter-spacing:-.02em; line-height:1.2; }
.brand .eyebrow { margin:0; font-weight:400; letter-spacing:0; }
.header-inner .quiet { padding-inline:0; }
.header-inner .quiet:hover { background:transparent; color:var(--color-accent-hover); }
.identity { display:flex; flex-direction:column; align-items:flex-end; min-width:0; font-size:var(--text-sm); color:var(--color-ink-2); overflow-wrap:anywhere; }
.identity .quiet { min-height:var(--size-touch); margin-top:calc(var(--space-2xs) * -1); }
main { max-width:var(--size-content); margin:auto; padding:var(--space-md) var(--space-sm) var(--space-lg); }
main:has(+ .dock) { padding-bottom:calc(var(--size-dock) + var(--space-lg)); }
.eyebrow { font-family:var(--font-mono); font-size:var(--text-xs); color:var(--color-ink-2); margin-bottom:var(--space-2xs); }
.public-actions { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--space-xs); margin-block:0 var(--space-sm); }
.section { margin-block:var(--space-lg) 0; }
.section-head { display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-xs); margin-block:0 var(--space-2xs); }
.section-head h2 { margin:0; }
.columns { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--space-xs); }
.columns .field { margin:0; }
.roster-controls { display:grid; grid-template-columns:minmax(0,1fr) auto; column-gap:var(--space-xs); row-gap:var(--space-2xs); }
.roster-controls .field:first-child { grid-column:1 / -1; }
.roster-controls .field { margin-block:0 var(--space-2xs); }
.view-toggle { display:inline-flex; align-self:end; margin-bottom:var(--space-2xs); border:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-md); overflow:hidden; }
.view-toggle button { min-height:var(--size-touch); padding:0 var(--space-xs); border:0; border-radius:0; background:var(--color-paper); color:var(--color-ink-2); }
.view-toggle button+button { border-left:var(--rule-hair) solid var(--color-rule); }
.view-toggle button[aria-pressed=true] { background:var(--color-ink); color:var(--color-paper); }
.view-toggle button .icon { width:var(--size-icon-dock); height:var(--size-icon-dock); }
.legend { grid-column:1 / -1; display:flex; flex-wrap:wrap; gap:var(--space-3xs) var(--space-sm); list-style:none; margin:0 0 var(--space-2xs); padding:0; font-size:var(--text-sm); color:var(--color-ink-2); }
.legend li { display:inline-flex; align-items:center; gap:var(--space-2xs); }
.swatch { width:var(--space-xs); height:var(--space-xs); border-radius:var(--radius-sm); background:var(--swatch); }
.swatch[data-color=green] { --swatch:var(--color-green-vivid); }
.swatch[data-color=blue] { --swatch:var(--color-blue-vivid); }
.swatch[data-color=yellow] { --swatch:var(--color-yellow-vivid); }
.swatch[data-color=red] { --swatch:var(--color-red-vivid); }
.swatch[data-color=purple] { --swatch:var(--color-purple-vivid); }
.swatch[data-color=pending] { --swatch:var(--color-pending-vivid); }
.panel { max-width:var(--size-form); border:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-md); padding:var(--space-sm); }
.badge { display:inline-flex; align-items:center; gap:var(--space-2xs); padding:var(--space-3xs) var(--space-2xs); border:var(--rule-hair) solid var(--badge-fill,var(--color-rule)); border-radius:var(--radius-sm); font-size:var(--text-sm); font-weight:650; line-height:1.2; white-space:nowrap; color:var(--badge-ink,var(--color-ink)); background:var(--badge-fill,var(--color-paper-2)); }
.badge::before { content:""; width:var(--space-2xs); height:var(--space-2xs); flex-shrink:0; background:currentColor; border-radius:50%; }
.badge[data-color=green] { --badge-fill:var(--color-green-vivid); --badge-ink:var(--color-on-accent); }
.badge[data-color=blue] { --badge-fill:var(--color-blue-vivid); --badge-ink:var(--color-on-accent); }
.badge[data-color=yellow] { --badge-fill:var(--color-yellow-vivid); --badge-ink:var(--color-yellow); }
.badge[data-color=red] { --badge-fill:var(--color-red-vivid); --badge-ink:var(--color-on-accent); }
.badge[data-color=purple] { --badge-fill:var(--color-purple-vivid); --badge-ink:var(--color-on-accent); }
.badge[data-color=pending] { --badge-fill:var(--color-pending-vivid); --badge-ink:var(--color-pending); }
.list { list-style:none; padding:0; margin:0; border-top:var(--rule-hair) solid var(--color-rule-soft); }
.list>li { padding:var(--space-xs) 0; border-bottom:var(--rule-hair) solid var(--color-rule-soft); overflow-wrap:anywhere; }
/* Student rows and cards carry the status as colour only. The badge stays in the DOM for assistive tech; the legend explains the colours. */
.list:has(>li.person) { border-top:0; }
.list>li.person { min-height:calc(var(--size-touch) + var(--space-sm)); padding:var(--space-2xs) var(--space-xs); margin-bottom:var(--space-3xs); border:0; border-left:4px solid var(--color-rule); border-radius:var(--radius-sm); }
.person .badge { position:absolute; width:1px; height:1px; margin:-1px; padding:0; border:0; overflow:hidden; clip-path:inset(50%); }
.person { display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; column-gap:var(--space-xs); background:var(--color-paper); }
.person>:not(.person-main,.badge,.row-action,.actions) { grid-column:1 / -1; }
.person>.actions { margin-top:0; justify-self:end; }
.person-main { min-width:0; }
.row-action { justify-self:end; padding-inline:var(--space-2xs); white-space:nowrap; }
.row-reason { text-align:right; font-size:var(--text-sm); color:var(--color-ink-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.person-detail:empty { display:none; }
.person-name { font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.person-detail { font-family:var(--font-body); font-size:var(--text-sm); font-variant-numeric:tabular-nums; color:var(--color-ink-2); }
.actions { display:flex; flex-wrap:wrap; gap:var(--space-2xs); margin-top:var(--space-xs); }
/* Card mode (view toggle): the same coloured rows laid out as cards. The row frame reads the status from the badge with :has. */
.list.grid { display:grid; grid-auto-rows:1fr; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:var(--space-2xs); border-top:0; margin-block:var(--space-2xs); }
.list.grid>li { margin:0; padding:var(--space-xs); border:var(--rule-hair) solid var(--color-rule-soft); border-left:4px solid var(--color-rule); border-radius:var(--radius-md); background:var(--color-paper); }
.list.grid>li.empty { grid-column:1 / -1; border:0; border-bottom:var(--rule-hair) solid var(--color-rule-soft); border-radius:0; background:transparent; padding:var(--space-md) 0; }
.list.grid .person { grid-template-columns:minmax(0,1fr); align-content:start; min-height:88px; }
.list.grid .person>*+* { margin-top:var(--space-2xs); }
.list.grid .person .actions { margin-top:var(--space-2xs); justify-self:stretch; }
.list.grid .row-action { width:100%; justify-self:stretch; white-space:normal; line-height:1.2; }
.list.grid .row-reason { text-align:left; }
.list>li.person:has(.badge[data-color=green]) { border-left-color:var(--color-green-vivid); background:var(--color-green-card); }
.list>li.person:has(.badge[data-color=blue]) { border-left-color:var(--color-blue-vivid); background:var(--color-blue-card); }
.list>li.person:has(.badge[data-color=yellow]) { border-left-color:var(--color-yellow-vivid); background:var(--color-yellow-card); }
.list>li.person:has(.badge[data-color=red]) { border-left-color:var(--color-red-vivid); background:var(--color-red-card); }
.list>li.person:has(.badge[data-color=purple]) { border-left-color:var(--color-purple-vivid); background:var(--color-purple-card); }
.list>li.person:has(.badge[data-color=pending]) { border-left-color:var(--color-pending-vivid); background:var(--color-pending-card); }
.notice { padding:var(--space-xs) var(--space-sm); border:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-md); margin-block:var(--space-sm); }
.notice.error { color:var(--color-red); background:var(--color-red-bg); border-color:var(--color-red); }
.notice.success { color:var(--color-green); background:var(--color-green-bg); border-color:var(--color-green); }
.notice.info { background:var(--color-paper-2); }
.notice.warning { color:var(--color-yellow); background:var(--color-yellow-bg); border-color:var(--color-yellow); }
.empty { padding:var(--space-md) 0; color:var(--color-ink-2); }
.footer { font-size:var(--text-xs); color:var(--color-ink-2); margin-top:var(--space-lg); }
.skip { position:fixed; top:var(--space-2xs); left:var(--space-2xs); transform:translateY(-200%); padding:var(--space-xs); background:var(--color-paper); z-index:10; }
.skip:focus { transform:none; }
.credential { max-width:var(--size-form); overflow-wrap:anywhere; border:var(--rule-thick) solid var(--color-ink); border-radius:var(--radius-md); padding:var(--space-sm); margin-block:var(--space-sm); }
.credential code { font-family:var(--font-mono); }
.qr { display:block; width:min(100%,280px); margin:var(--space-md) auto; }
.print-url { overflow-wrap:anywhere; text-align:center; }
.print-sheet { max-width:var(--size-form); }
.print-sheet small { display:block; margin-top:var(--space-2xs); }
[hidden] { display:none !important; }

/* Staff dock: five tabs, icon above label. The node persists across renders, so the marker only moves on a tab change. */
.dock { position:fixed; bottom:0; left:0; right:0; background:var(--color-paper); border-top:var(--rule-hair) solid var(--color-rule); padding:var(--space-3xs) var(--space-2xs) max(var(--space-3xs),env(safe-area-inset-bottom)); display:flex; justify-content:center; gap:var(--space-3xs); }
.dock button { position:relative; flex:1; min-width:0; max-width:120px; min-height:calc(var(--size-touch) + var(--space-xs)); flex-direction:column; gap:var(--space-3xs); padding:var(--space-2xs) var(--space-3xs) var(--space-3xs); border:0; background:transparent; color:var(--color-ink-2); font-size:var(--text-xs); font-weight:600; white-space:nowrap; }
.dock button::before { content:""; position:absolute; top:var(--space-3xs); left:50%; width:var(--size-touch); height:calc(var(--size-icon-dock) + var(--space-2xs)); margin-left:calc(var(--size-touch) / -2); border-radius:var(--radius-lg); background:var(--color-blue-bg); opacity:0; transform:scaleX(.5); transition:opacity var(--dur-base) var(--ease-out),transform var(--dur-base) var(--ease-out); }
.dock button>* { position:relative; }
.dock button .icon { width:var(--size-icon-dock); height:var(--size-icon-dock); }
.dock button:hover { color:var(--color-ink); }
.dock button[aria-current=page] { color:var(--color-accent); }
.dock button[aria-current=page]::before { opacity:1; transform:none; }

/* Action popup. One persistent <dialog>; open/close fade through @starting-style and allow-discrete. */
.action-dialog { width:calc(100% - var(--space-dialog-edge) * 2); max-width:var(--size-dialog); max-height:calc(100dvh - var(--space-dialog-edge) * 2); border:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-lg); padding:var(--space-sm); background:var(--color-paper); color:var(--color-ink); overscroll-behavior:contain; opacity:0; transform:translateY(var(--space-xs)); transition:opacity var(--dur-fast) var(--ease-in),transform var(--dur-fast) var(--ease-in),overlay var(--dur-fast) allow-discrete,display var(--dur-fast) allow-discrete; }
.action-dialog[open] { opacity:1; transform:none; transition-duration:var(--dur-base); transition-timing-function:var(--ease-out); }
.action-dialog::backdrop { background:var(--color-backdrop); opacity:0; transition:opacity var(--dur-fast) var(--ease-in),overlay var(--dur-fast) allow-discrete,display var(--dur-fast) allow-discrete; }
.action-dialog[open]::backdrop { opacity:1; }
@starting-style { .action-dialog[open] { opacity:0; transform:translateY(var(--space-xs)); } .action-dialog[open]::backdrop { opacity:0; } }
.dialog-header { display:flex; align-items:center; justify-content:space-between; gap:var(--space-2xs); margin-bottom:var(--space-2xs); }
.dialog-header h2 { margin:0; outline:none; }
.notice-slot:empty { display:none; }
.action-dialog .columns { margin-block:var(--space-sm); }
.action-dialog .list { margin-bottom:var(--space-sm); }
.action-dialog form>button { margin-top:var(--space-2xs); }
.action-dialog .status-link { margin-top:0; justify-content:flex-start; padding-inline:0; }
.action-dialog .status-link:hover { background:transparent; color:var(--color-accent-hover); }
.action-dialog .full { max-width:none; }
body:has(dialog[open]) { overflow-y:hidden; }

/* Wheel time picker: native scroll-snap columns, selected row in the centre band. */
.wheel { box-sizing:content-box; position:relative; display:flex; align-items:center; justify-content:center; gap:var(--space-3xs); height:var(--size-wheel); border:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-md); background:var(--color-paper); overflow:hidden; }
.wheel::before { content:""; position:absolute; left:var(--space-3xs); right:var(--space-3xs); top:var(--size-wheel-pad); height:var(--size-touch); border-block:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-sm); background:var(--color-paper-2); pointer-events:none; }
.wheel[aria-invalid=true] { border-color:var(--color-red); }
.wheel[aria-invalid=true]::before { background:var(--color-red-bg); border-color:var(--color-red); }
.wheel-col { position:relative; flex:1; min-width:0; max-width:calc(var(--size-touch) * 1.5); height:100%; overflow-y:auto; scroll-snap-type:y mandatory; overscroll-behavior:contain; touch-action:pan-y; scrollbar-width:none; -webkit-mask-image:var(--mask-wheel); mask-image:var(--mask-wheel); }
.wheel-col::-webkit-scrollbar { display:none; }
.wheel-col.is-gliding { scroll-snap-type:none; }
.wheel-col::before,.wheel-col::after { content:""; display:block; height:var(--size-wheel-pad); }
.wheel-col:focus-visible { outline-color:transparent; }
.wheel-col:focus-visible .wheel-row.is-selected { outline:3px solid var(--color-focus); outline-offset:-3px; border-radius:var(--radius-sm); }
.wheel-row { height:var(--size-touch); display:flex; align-items:center; justify-content:center; scroll-snap-align:center; font-size:var(--text-lg); font-variant-numeric:tabular-nums; color:var(--color-ink-2); cursor:pointer; user-select:none; -webkit-user-select:none; }
.wheel-row.is-selected { color:var(--color-ink); font-weight:650; }
.wheel-sep { position:relative; font-size:var(--text-lg); font-weight:650; }

@media(min-width:768px) {
 main { padding-top:var(--space-lg); }
 .public-actions { grid-template-columns:repeat(2,minmax(160px,auto)); justify-content:start; }
 .roster-controls { grid-template-columns:minmax(0,1fr) var(--size-badge-column) auto; }
 .roster-controls .field:first-child { grid-column:auto; }
 .identity { flex-direction:row; align-items:center; gap:var(--space-sm); }
 .identity .quiet { margin-top:0; }
 .person-main { display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-2xs) var(--space-sm); flex-wrap:wrap; }
 .dock button { flex-direction:row; gap:var(--space-2xs); max-width:160px; font-size:var(--text-sm); padding:var(--space-2xs) var(--space-xs); }
 .dock button::before { top:var(--space-3xs); bottom:var(--space-3xs); left:0; width:100%; height:auto; margin:0; border-radius:var(--radius-md); }
}
@media(prefers-reduced-motion:reduce) { *,*::before,*::after { animation:none !important; transition:none !important; scroll-behavior:auto !important; } }
@media print { .masthead,.dock,.no-print,.footer,.skip,main>*:not(.print-sheet) { display:none !important; } main,main:has(+ .dock) { padding:0; } .qr { width:280px; } .print-sheet { max-width:none; text-align:center; margin:var(--space-xl); } }
