:root{
  --bg:#f6f7f9; --panel:#fff; --ink:#15181d; --muted:#6b7280; --line:#e3e6ea;
  --accent:#1f4e79; --block:#b3261e; --warn:#8a5a00; --warn-bg:#fff6e5; --block-bg:#fdeceb;
  --ok:#1e6b3a; --edited:#e8f0fa; --anchor:#f3ecff;
}
*{box-sizing:border-box}
/* `hidden` must win, always. Twice now a `display` rule has beaten the attribute and left an
   element on screen that the script believed it had hidden: first `.modal{display:grid}` (a hidden
   dialog swallowing every click), then `#login{display:grid}` -- an ID, so it also beat the
   `.screen[hidden]` fix written for the first one, and the sign-in screen simply would not go away
   after a successful sign-in. One rule that outranks anything, rather than a list to keep extending. */
[hidden]{display:none!important}
body{margin:0;font:14px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  color:var(--ink);background:var(--bg)}
.screen{min-height:100vh}
#login{display:grid;place-items:center}
#login .card{background:var(--panel);padding:32px;border-radius:10px;width:340px;
  box-shadow:0 1px 3px rgba(0,0,0,.08),0 8px 24px rgba(0,0,0,.06)}
#login h1{margin:0;font-size:22px}
#login .muted{margin:4px 0 22px}
label{display:block;margin-bottom:14px;font-weight:600;font-size:12px;color:var(--muted);
  text-transform:uppercase;letter-spacing:.04em}
input[type=text],input[type=password],input:not([type]){width:100%;margin-top:5px;padding:9px 10px;
  border:1px solid var(--line);border-radius:6px;font-size:14px;font-weight:400;color:var(--ink)}
button{font:inherit;padding:9px 14px;border:1px solid var(--accent);background:var(--accent);color:#fff;
  border-radius:6px;cursor:pointer}
button:disabled{opacity:.45;cursor:not-allowed}
button.link{background:none;border:none;color:var(--accent);padding:4px 6px;text-decoration:underline}
.muted{color:var(--muted)}
.error{color:var(--block);font-size:13px;margin:10px 0 0}

header{display:flex;align-items:center;gap:18px;padding:10px 16px;background:var(--panel);
  border-bottom:1px solid var(--line)}
.brand{font-weight:700;letter-spacing:-.01em}
.brand span{font-weight:400;color:var(--muted);margin-left:10px}
nav{display:flex;gap:4px;margin-left:12px}
.tab{background:none;border:1px solid transparent;color:var(--muted);padding:6px 12px}
.tab.is-active{background:var(--edited);border-color:#c9d9ec;color:var(--accent);font-weight:600}
.who{margin-left:auto;display:flex;align-items:center;gap:8px;color:var(--muted)}

.advisory{padding:9px 16px;font-size:13px;background:var(--warn-bg);border-bottom:1px solid #f0dcb4}
.advisory.is-ack{background:#eef7f0;border-bottom-color:#cfe6d6}
.advisory button{margin-left:10px;padding:5px 11px;font-size:13px}

.toolbar{display:flex;align-items:center;gap:16px;padding:10px 16px;background:var(--panel);
  border-bottom:1px solid var(--line)}
.toolbar .right{margin-left:auto;display:flex;align-items:center;gap:14px}
.toggle{text-transform:none;letter-spacing:0;font-size:13px;color:var(--ink);margin:0;
  display:flex;align-items:center;gap:6px;font-weight:400}
.toggle input{margin:0}

main{display:grid;grid-template-columns:1fr 300px;gap:0;align-items:start}
#grid-wrap{overflow:auto;max-height:calc(100vh - 148px)}
table{border-collapse:collapse;width:100%;background:var(--panel)}
th,td{border:1px solid var(--line);padding:0;text-align:left;vertical-align:top}
thead th{position:sticky;top:0;z-index:2;background:#eef1f5;padding:7px 8px;font-size:12px;
  text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
tbody th{padding:6px 8px;font-weight:600;font-size:13px;white-space:nowrap;background:var(--panel);
  position:sticky;left:0;z-index:1}
tbody th .meta{display:block;font-weight:400;font-size:11px;color:var(--muted)}
tr.band td,tr.band th{background:#f0f2f5;font-size:11px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);padding:4px 8px;font-weight:700}
td.day{min-width:118px;height:46px;position:relative}
td.day.drop-ok{outline:2px solid var(--ok);outline-offset:-2px;background:#eef7f0}
td.day.drop-no{outline:2px solid var(--block);outline-offset:-2px;background:var(--block-bg)}
/* Every layer gets its OWN colour, and every colour is paired with a text tag inside the shift, so
   nothing on this grid is encoded by colour alone. The legend is generated from the same table. */
.shift,.swatch{background:#eef1f5;border:1px solid #d3dae3}
.shift[data-layer=anchor],.swatch[data-layer=anchor]{background:var(--anchor);border-color:#d9c9f2}
.shift[data-layer=manager],.swatch[data-layer=manager]{background:#fdf0e3;border-color:#f0d3ae}
.shift[data-layer=opener],.swatch[data-layer=opener]{background:#e6f4ea;border-color:#bcdcc6}
.shift[data-layer=closer],.swatch[data-layer=closer]{background:#e9e9f7;border-color:#c5c5e8}
.shift{margin:3px;padding:4px 6px;border-radius:5px;font-size:12px;cursor:grab;line-height:1.3}
.shift[data-origin=edited],.shift[data-origin=added]{box-shadow:inset 3px 0 0 var(--accent)}
.shift .pos{display:block;color:var(--muted);font-size:11px}
.shift .tag{font-weight:700;letter-spacing:.03em}
.shift:focus-visible{outline:2px solid var(--accent)}
.shift{position:relative;padding-right:18px}
.shift.is-selected{outline:2px solid var(--accent);outline-offset:1px;background:#dbe8f7}
.shift .more{position:absolute;top:1px;right:1px;padding:0 3px;background:none;border:none;color:var(--muted);
  font-size:13px;line-height:1.1;cursor:pointer;border-radius:3px}
.shift .more:hover{background:rgba(0,0,0,.07);color:var(--ink)}
.avail{display:block;padding:1px 7px 4px;font-size:11px;color:var(--muted)}
.row-block th{box-shadow:inset 3px 0 0 var(--block);background:#fff7f6}
.row-warn th{box-shadow:inset 3px 0 0 var(--warn);background:#fffdf7}
/* a name is flagged with a WORD, not just a coloured bar */
.pill{display:inline-block;margin-left:6px;padding:0 5px;border-radius:9px;font-size:10px;font-weight:700;
  letter-spacing:.04em;vertical-align:1px}
.pill.block{background:var(--block);color:#fff}
.pill.warn{background:#f0c04a;color:#3d2c00}

.legend{font-size:12px}
.legend .row{display:flex;align-items:flex-start;gap:8px;padding:4px 0}
.swatch{width:26px;height:16px;border-radius:4px;flex:none;margin-top:1px;font-size:8px;font-weight:700;
  display:grid;place-items:center;color:var(--muted)}
.swatch.bar{background:var(--panel);box-shadow:inset 3px 0 0 var(--accent);border-color:var(--line)}
.swatch.rowblock{background:#fff7f6;box-shadow:inset 3px 0 0 var(--block);border-color:var(--line)}
.swatch.rowwarn{background:#fffdf7;box-shadow:inset 3px 0 0 var(--warn);border-color:var(--line)}
.legend b{display:block;font-weight:600}
.legend span{color:var(--muted)}

.flagged{list-style:none;margin:0;padding:0;font-size:12px}
.flagged li{padding:5px 0;border-bottom:1px solid var(--line);cursor:pointer}
.flagged li:hover{background:#f4f6f9}
.flagged .nm{font-weight:600}
.flagged .msg{color:var(--muted);display:block}
.flagged .none{color:var(--ok);cursor:default}
.detail{font-size:12px;min-height:32px}
.detail .hd{font-weight:600;margin-bottom:3px}
.detail p{margin:3px 0;color:var(--muted)}
.detail .block{background:var(--block-bg);color:var(--block);padding:5px 7px;border-radius:5px;margin:4px 0}
.detail .warn{background:var(--warn-bg);color:var(--warn);padding:5px 7px;border-radius:5px;margin:4px 0}
.detail .ok{color:var(--ok)}
.hrs{font-variant-numeric:tabular-nums}

#side{padding:12px 14px;border-left:1px solid var(--line);background:var(--panel);
  max-height:calc(100vh - 148px);overflow:auto}
#side h2{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:14px 0 6px}
#side section:first-child h2{margin-top:0}
.findings div{padding:6px 8px;border-radius:5px;margin-bottom:5px;font-size:12px}
.findings .block{background:var(--block-bg);color:var(--block)}
.findings .warn{background:var(--warn-bg);color:var(--warn)}
.findings .ok{color:var(--ok)}
.open,.edits{list-style:none;margin:0;padding:0;font-size:12px}
.open li,.edits li{padding:5px 0;border-bottom:1px solid var(--line);color:var(--muted)}
.open b{color:var(--ink)}

.modal{position:fixed;inset:0;background:rgba(15,18,23,.45);display:grid;place-items:center;z-index:50}
.modal .card{background:var(--panel);padding:24px;border-radius:10px;width:420px}
.modal h2{margin:0 0 6px;font-size:17px}
.modal button{display:block;width:100%;margin-bottom:8px;text-align:left}
.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--ink);color:#fff;
  padding:10px 16px;border-radius:7px;font-size:13px;max-width:70vw;z-index:60}
.toast.bad{background:var(--block)}

/* Demo logins on the sign-in screen. Usernames only -- a password never renders here. */
#demo-logins { margin-top: 1rem; border-top: 1px solid var(--line, #d7d7d7); padding-top: .75rem; }
#demo-logins p { margin: .35rem 0; font-size: .85rem; }
.demo-list { list-style: none; margin: .4rem 0; padding: 0; display: grid; gap: .35rem; }
.demo-list li { display: flex; align-items: center; gap: .5rem; }
.demo-fill { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .85rem;
             padding: .15rem .5rem; cursor: pointer; }

/* The last-resort error banner. Deliberately loud: it only appears when something broke. */
#js-error { background: #b3261e; color: #fff; padding: .75rem 1rem; font-size: .9rem;
            text-align: center; }

/* ----------------------------------------------------------------- roster screen */
#view-roster main{display:grid;grid-template-columns:1fr 340px;gap:18px;padding:0 18px 24px}
#roster-wrap{overflow:auto;background:var(--panel);border:1px solid var(--line);border-radius:8px}
#roster-table{border-collapse:collapse;width:100%;font-size:13px}
#roster-table th{position:sticky;top:0;background:var(--panel);text-align:left;padding:9px 10px;
  border-bottom:2px solid var(--line);font-size:11px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted)}
#roster-table td{padding:8px 10px;border-bottom:1px solid var(--line);vertical-align:top}
#roster-table tr.is-edited{background:var(--edited)}
#roster-table tr.is-edited td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
#roster-table .small{font-size:11.5px;color:var(--muted)}
#roster-table .missing{color:var(--warn);font-weight:600}
.chip{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:9px;font-size:10px;
  font-weight:700;letter-spacing:.04em;background:var(--anchor);color:var(--ink)}
#roster-side section{background:var(--panel);border:1px solid var(--line);border-radius:8px;
  padding:12px 14px;margin-bottom:14px}
#roster-side h2{margin:0 0 6px;font-size:13px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted)}
#roster-side .was{color:var(--muted);text-decoration:line-through}
#roster-search{padding:7px 9px;border:1px solid var(--line);border-radius:6px;min-width:220px;
  font:inherit}
button.danger{background:var(--block);border-color:var(--block)}

/* the one-person editor */
.modal .card.wide{width:min(760px,94vw);max-height:88vh;overflow:auto}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:10px 16px}
label.f{display:block;margin:0 0 6px;font-weight:600;font-size:11px;text-transform:uppercase;
  letter-spacing:.04em;color:var(--muted)}
label.f input{width:100%;margin-top:4px;padding:7px 9px;border:1px solid var(--line);
  border-radius:6px;font:inherit;font-weight:400;color:var(--ink);text-transform:none}
label.f em{display:block;margin-top:3px;font-size:11px;font-weight:400;text-transform:none;
  letter-spacing:0;font-style:normal}
#person-form h3{margin:16px 0 6px;font-size:12px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted)}
#person-form h3 em{font-weight:400;text-transform:none;letter-spacing:0;font-style:normal}
.checks{display:flex;gap:18px;flex-wrap:wrap;margin-top:12px;font-size:13px}
.checks label,.cert{font-weight:400;text-transform:none;letter-spacing:0;color:var(--ink)}
.certs{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;font-size:13px}
.days{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
label.day{display:block;font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase}
label.day input{width:100%;margin-top:3px;padding:6px 8px;border:1px solid var(--line);
  border-radius:6px;font:inherit;font-weight:400;color:var(--ink);text-transform:none}
#person-form .actions{margin-top:18px}
#person-form code{background:var(--bg);padding:1px 4px;border-radius:3px}
/* Availability must say WHICH day. A bare list of times in a fixed order is only readable by
   someone who already knows the order, which is the guessing the schedule screen banned. */
.avail7{display:grid;gap:0;font-size:11px;line-height:1.5}
.avail7 span{white-space:nowrap;color:var(--ink)}
.avail7 b{display:inline-block;min-width:54px;color:var(--muted);font-weight:700}
.avail7 .dayoff{color:var(--muted)}
/* fixed widths so a long value can never bleed into the column beside it */
#roster-table td:nth-child(5),#roster-table th:nth-child(5){width:150px}
#roster-table td:nth-child(4),#roster-table th:nth-child(4){width:190px}
#roster-table td:nth-child(6),#roster-table th:nth-child(6){width:200px;font-size:11.5px}
#roster-table td:nth-child(7),#roster-table th:nth-child(7){width:110px}

/* ----------------------------------------------------------------- coverage by hour and position */
.stack{display:flex;flex-direction:column;gap:16px;min-width:0}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:12px 14px}
.panel-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap}
.panel h2{margin:0;font-size:13px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.panel .small{font-size:11.5px;margin:6px 0 10px}
.bad-text{color:var(--block);font-weight:700;text-transform:none;letter-spacing:0}
.ok-text{color:var(--ok);font-weight:700;text-transform:none;letter-spacing:0}
.daytabs{display:flex;gap:4px}
.daytab{background:var(--bg);color:var(--ink);border:1px solid var(--line);padding:4px 9px;
  border-radius:6px;font-size:12px}
.daytab.is-active{background:var(--accent);color:#fff;border-color:var(--accent)}
.daytab b{margin-left:5px;padding:0 5px;border-radius:8px;font-size:10px}
.daytab .cov-uncovered{background:var(--block);color:#fff}
.daytab .cov-short{background:var(--warn);color:#fff}
.daytab.is-active b{background:#fff;color:var(--accent)}
#cov-wrap{overflow-x:auto}
#cov-table{border-collapse:collapse;font-size:12px;width:100%}
#cov-table th{padding:4px 6px;font-size:10.5px;text-transform:uppercase;letter-spacing:.03em;
  color:var(--muted);text-align:center;border-bottom:1px solid var(--line);white-space:nowrap}
#cov-table tbody th{text-align:left;font-size:11.5px;color:var(--ink);text-transform:none;
  letter-spacing:0;white-space:nowrap;padding-right:10px}
#cov-table td{text-align:center;padding:5px 4px;border:1px solid var(--line);min-width:38px;
  cursor:pointer;position:relative}
#cov-table td:focus{outline:2px solid var(--accent);outline-offset:-2px}
#cov-table td i{font-style:normal;font-weight:700;margin-left:2px}
/* colour AND a character AND the numbers -- three signals, per the legend rule */
.cov-uncovered{background:var(--block);color:#fff;font-weight:700}
.cov-short{background:var(--warn-bg);color:var(--warn);font-weight:700}
.cov-ok{background:#eef6f0;color:var(--ok)}
.cov-extra{background:var(--edited);color:var(--accent)}
.cov-none{background:transparent;color:var(--muted)}
#cov-legend{margin-top:10px}
#cov-detail{margin-top:8px;font-size:12px}
#cov-detail h3{margin:0 0 4px;font-size:12.5px}
#cov-detail p{margin:3px 0}
.legend-item .swatch.cov-uncovered,.legend-item .swatch.cov-short,.legend-item .swatch.cov-ok,
.legend-item .swatch.cov-extra,.legend-item .swatch.cov-none{
  display:inline-block;min-width:20px;text-align:center;border:1px solid var(--line)}

/* Sortable headers. The arrow alone is a guess; the readout beside the count says it in words. */
#roster-table th .sort{background:none;border:0;padding:0;font:inherit;color:var(--muted);
  text-transform:uppercase;letter-spacing:.04em;font-size:11px;font-weight:700;cursor:pointer}
#roster-table th .sort:hover{color:var(--ink);text-decoration:underline}
#roster-table th .sort.is-sorted{color:var(--accent)}
#roster-table th .arrow{font-size:9px}
#sort-state{margin-left:10px;font-size:12px}

/* "Fix this person" from the schedule screen, so a lapsed date is a 10-second edit in place. */
#detail .edit-roster{margin-top:10px;width:100%;font-size:12px}

/* ----------------------------------------------------------------- config screen */
#view-config main{display:grid;grid-template-columns:1fr 340px;gap:18px;padding:0 18px 24px}
#config-sections{display:flex;flex-direction:column;gap:14px;min-width:0}
.cfg-section{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:14px 16px}
.cfg-section h2{margin:0 0 4px;font-size:13px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.cfg-section>p.muted{margin:0 0 12px;font-size:12px}
.cfg-section.is-dol{border-color:var(--warn);background:var(--warn-bg)}
.cfg-section.is-dol h2{color:var(--warn)}
/* the flag is a WORD, not only a colour */
i.dol{font-style:normal;font-size:9.5px;font-weight:800;letter-spacing:.05em;background:var(--warn);color:#fff;
  padding:1px 5px;border-radius:8px;vertical-align:middle;margin-left:4px}
.cfg-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px 16px}
label.cf{display:block;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
label.cf input:not([type=checkbox]){width:100%;margin-top:4px;padding:6px 8px;border:1px solid var(--line);
  border-radius:6px;font:inherit;font-weight:400;font-size:13px;color:var(--ink);text-transform:none;letter-spacing:0}
label.cf input[type=checkbox]{margin:8px 0 0 2px;transform:scale(1.2)}
label.cf em{display:block;margin-top:3px;font-size:11px;font-weight:400;text-transform:none;letter-spacing:0;font-style:normal}
label.cf.is-bad input{border-color:var(--block);background:var(--block-bg)}
.cf-msg{display:block;margin-top:3px;font-size:11px;font-weight:600;text-transform:none;letter-spacing:0}
.cf-msg.bad{color:var(--block)}
.cf-msg.ok{color:var(--ok)}
.cfg-editor{margin-top:10px}
.cfg-editor h3{margin:8px 0 6px;font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.cfg-editor h3 em{font-weight:400;text-transform:none;letter-spacing:0;font-style:normal}
.cfg-table{border-collapse:collapse;font-size:12.5px}
.cfg-table th{text-align:left;padding:4px 8px 4px 0;font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.cfg-table td{padding:3px 8px 3px 0}
.cfg-table input{padding:5px 7px;border:1px solid var(--line);border-radius:5px;font:inherit;font-size:12.5px;min-width:56px}
.cfg-table input.t-name,.cfg-table input.p-name,.cfg-table input.f-name{min-width:120px}
.cfg-actions{display:flex;align-items:center;gap:12px;margin-top:8px}
.cfg-actions .save{padding:6px 12px;font-size:12px}
#config-side section{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:12px 14px;margin-bottom:14px}
#config-side h2{margin:0 0 6px;font-size:13px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
#config-side .was{color:var(--muted);text-decoration:line-through}
#config-side section.dol{border-color:var(--warn);background:var(--warn-bg)}
#config-side .edits li b{word-break:break-all}
dl.effects{display:grid;grid-template-columns:1fr auto;gap:4px 12px;margin:8px 0 0;font-size:12.5px}
dl.effects dt{color:var(--muted)}
dl.effects dd{margin:0;text-align:right}
dl.effects dd.worse b{color:var(--block)}
dl.effects dd.better b{color:var(--ok)}
dl.effects dd s{color:var(--muted)}

/* ----------------------------------------------------------------- reports screen */
main.reports{display:flex;flex-direction:column;gap:14px;padding:0 18px 24px}
main.reports .panel h2{margin:0 0 8px}
main.reports .panel h3{margin:14px 0 6px;font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.warn-text{color:var(--warn);font-weight:700;text-transform:none;letter-spacing:0}
dl.headline{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:8px 24px;margin:0 0 8px;font-size:13px}
dl.headline dt{color:var(--muted);font-size:11.5px}
dl.headline dd{margin:0 0 6px;font-size:15px}
.two{display:grid;grid-template-columns:1fr 1fr;gap:18px;align-items:start}
table.rep{border-collapse:collapse;width:100%;font-size:12.5px}
table.rep th{text-align:left;padding:5px 8px;font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);border-bottom:1px solid var(--line)}
table.rep td{padding:5px 8px;border-bottom:1px solid var(--line);vertical-align:top}
table.rep code{background:var(--bg);padding:1px 4px;border-radius:3px;font-size:11.5px}
a.button{display:inline-block;padding:9px 14px;border:1px solid var(--accent);background:var(--accent);color:#fff;border-radius:6px;text-decoration:none;font-size:13px}
#rep-rq details{margin:4px 0;font-size:12.5px}
#rep-rq summary{cursor:pointer}
