/*
 * Colour is defined once, as tokens, in three places:
 *
 *   :root                                     the light palette, always defined
 *   @media (prefers-color-scheme: dark)       dark, unless the account chose light
 *   :root[data-theme="dark"]                  dark, because the account chose it
 *
 * The media block is guarded by :not([data-theme="light"]) so that "Light" wins on a
 * machine set to dark, and the [data-theme="dark"] block exists so that "Dark" wins on a
 * machine set to light. Without both, one of the two choices silently does nothing.
 *
 * Nothing outside these blocks may name a colour. A literal anywhere else is a colour
 * that stays light when everything around it goes dark.
 */
:root{
  color-scheme:light;
  --bg:#f4f5f7; --panel:#fff; --ink:#1c2430; --muted:#65707e; --line:#dfe3e8;
  --accent:#12507e; --accent-ink:#fff; --accent-soft:#e8f0f7;
  --ok:#1c6b3f; --ok-bg:#e4f3ea; --warn:#8a5a00; --warn-bg:#fdf3dd;
  --bad:#a12a2a; --bad-bg:#fbe7e7; --bad-line:#d9b3b3;
  --field-bg:#f7f9fb; --field-line:#c8d0d9; --head-bg:#fafbfc; --hover:#f7f9fb;
  --row-line:#eef1f4; --row-hover:#f8fafc; --chip-bg:#eceff3; --chip-ink:#46525f;
  --btn-hover:#f4f6f8; --accent-hover:#0e4269; --plate:#fff;
  --ok-line:#bfe0cd; --warn-line:#ecd9a8; --login-bg:#0f3f66;
  --radius:5px; --shadow:0 1px 2px rgba(20,30,45,.08),0 1px 8px rgba(20,30,45,.04);
  --lift:0 2px 10px rgba(16,24,40,.10);
}

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --bg:#14181d; --panel:#1b2027; --ink:#e6eaef; --muted:#98a3b1; --line:#2c343e;
    --accent:#6fb3e8; --accent-ink:#0d1218; --accent-soft:#1e2f3f;
    --ok:#63c48c; --ok-bg:#16301f; --warn:#e0b357; --warn-bg:#332a12;
    --bad:#f08a8a; --bad-bg:#3a1c1c; --bad-line:#5c3535;
    --field-bg:#222831; --field-line:#3a434e; --head-bg:#20262e; --hover:#232a33;
    --row-line:#262d36; --row-hover:#20262e; --chip-bg:#2a323c; --chip-ink:#b6c1cd;
    --btn-hover:#262e37; --accent-hover:#8cc4f0; --plate:#fff;
    --ok-line:#2b5c3d; --warn-line:#5c4a1e; --login-bg:#0b1a26;
    --shadow:0 1px 2px rgba(0,0,0,.45),0 1px 8px rgba(0,0,0,.25);
    --lift:0 2px 12px rgba(0,0,0,.45);
  }
}

:root[data-theme="dark"]{
  color-scheme:dark;
  --bg:#14181d; --panel:#1b2027; --ink:#e6eaef; --muted:#98a3b1; --line:#2c343e;
  --accent:#6fb3e8; --accent-ink:#0d1218; --accent-soft:#1e2f3f;
  --ok:#63c48c; --ok-bg:#16301f; --warn:#e0b357; --warn-bg:#332a12;
  --bad:#f08a8a; --bad-bg:#3a1c1c; --bad-line:#5c3535;
  --field-bg:#222831; --field-line:#3a434e; --head-bg:#20262e; --hover:#232a33;
  --row-line:#262d36; --row-hover:#20262e; --chip-bg:#2a323c; --chip-ink:#b6c1cd;
  --btn-hover:#262e37; --accent-hover:#8cc4f0; --plate:#fff;
  --ok-line:#2b5c3d; --warn-line:#5c4a1e; --login-bg:#0b1a26;
  --shadow:0 1px 2px rgba(0,0,0,.45),0 1px 8px rgba(0,0,0,.25);
  --lift:0 2px 12px rgba(0,0,0,.45);
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink); font:14px/1.45 -apple-system,BlinkMacSystemFont,
  "Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; -webkit-font-smoothing:antialiased;
}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}

/* ---------- top bar ---------- */
.topbar{
  display:flex;align-items:center;gap:20px;background:var(--panel);color:var(--ink);
  padding:0 18px;height:58px;position:sticky;top:0;z-index:20;
  border-bottom:1px solid var(--line);box-shadow:var(--shadow)
}
.brand{display:flex;align-items:center;gap:10px;white-space:nowrap}
.brand:hover{text-decoration:none}
/* The logo is a PNG on white, so on a dark page it needs a deliberate plate or it
   reads as a broken image. --plate is white in every palette; it is a token so that this
   rule names no colour of its own. */
.brand img{height:30px;width:auto;display:block;border-radius:3px}
:root[data-theme="dark"] .brand img{background:var(--plate);padding:3px 5px}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .brand img{background:var(--plate);padding:3px 5px}
}
.brand .sys{color:var(--muted);font-size:12px;font-weight:600;letter-spacing:.6px;
  text-transform:uppercase;border-left:1px solid var(--line);padding-left:10px}
.globalsearch{flex:1;max-width:460px}
.globalsearch input{
  width:100%;padding:7px 12px;border:1px solid var(--field-line);border-radius:20px;
  background:var(--field-bg);color:var(--ink);font-size:13px
}
.globalsearch input::placeholder{color:var(--muted)}
.globalsearch input:focus{outline:2px solid var(--accent-soft);background:var(--panel)}
.userbox{margin-left:auto;display:flex;align-items:center;gap:14px;font-size:12.5px}
.userbox a{color:var(--accent);font-weight:600}
.uname{font-weight:600}
.urole{color:var(--muted)}

/* ---------- layout ---------- */
.shell{display:flex;min-height:calc(100vh - 58px - 34px);align-items:flex-start}
.sidenav{
  width:186px;flex:0 0 186px;background:var(--panel);border-right:1px solid var(--line);
  padding:12px 0 0;position:sticky;top:58px;align-self:flex-start;
  /* Exactly the height of what is on screen below the header, not the height of the page.
     Stretching it to the page would put "the bottom of the menu" a thousand pixels below
     the fold, which is where the account block was when this was first written. The links
     scroll inside it; the account block stays at the bottom of the screen. */
  height:calc(100vh - 58px);
  display:flex;flex-direction:column
}
.navlinks{flex:1 1 auto;overflow-y:auto}
.navfoot{flex:none;border-top:1px solid var(--line);padding:10px 12px;background:var(--panel)}
.navlinks a{
  display:block;padding:7px 18px;color:var(--ink);font-size:13.5px;border-left:3px solid transparent
}
.navsection{padding:12px 18px 4px;color:var(--muted);font-size:10.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.7px}
.navsection:first-child{padding-top:2px}
.navlinks a:hover{background:var(--hover);text-decoration:none}
.navlinks a.on{background:var(--accent-soft);border-left-color:var(--accent);font-weight:600;color:var(--accent)}
.main{flex:1;padding:20px 24px;min-width:0}
.foot{padding:9px 24px;color:var(--muted);font-size:12px;border-top:1px solid var(--line);background:var(--panel)}

/* ---------- page furniture ---------- */
.pagehead{display:flex;align-items:center;gap:14px;margin:0 0 16px}
.pagehead h1{font-size:20px;margin:0;font-weight:650}
.pagehead .sub{color:var(--muted);font-size:13px}
.pagehead .actions{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap}

.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);margin-bottom:18px}
.panel > h2{font-size:13px;text-transform:uppercase;letter-spacing:.6px;color:var(--muted);
  margin:0;padding:11px 14px;border-bottom:1px solid var(--line);font-weight:650}
.panel .body{padding:14px}
.panel .body.tight{padding:0}

.grid{display:grid;gap:16px;align-items:start}
.grid.c2{grid-template-columns:repeat(auto-fit,minmax(330px,1fr))}
.grid.c3{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.grid.c4{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}

/* ---------- stat tiles ---------- */
.tile{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 16px;box-shadow:var(--shadow)}
.tile .k{color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:.5px}
.tile .v{font-size:24px;font-weight:650;margin-top:4px;font-variant-numeric:tabular-nums}
.tile .n{color:var(--muted);font-size:12px;margin-top:2px}
.tile a{display:block;color:inherit}
.tile a:hover{text-decoration:none}

/* ---------- tables ---------- */
.tablewrap{overflow-x:auto}
table.data{width:100%;border-collapse:collapse;font-size:13px}
table.data th{
  text-align:left;font-weight:650;color:var(--muted);font-size:11.5px;text-transform:uppercase;
  letter-spacing:.5px;padding:8px 10px;border-bottom:1px solid var(--line);white-space:nowrap;
  background:var(--head-bg);position:sticky;top:0
}
table.data td{padding:7px 10px;border-bottom:1px solid var(--row-line);vertical-align:top}
table.data tr:last-child td{border-bottom:0}
table.data tbody tr:hover{background:var(--row-hover)}
table.data td.num,table.data th.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
table.data td.mid,table.data th.mid{text-align:center}
table.data .dim{color:var(--muted)}
/* A figure edited where it is read: narrow enough not to widen the column, right-aligned
   so it still lines up with the plain numbers in the rows above and below it. */
table.data .cellnum{width:5.5em;padding:3px 6px;text-align:right;font-size:13px;
  font-variant-numeric:tabular-nums}
/* Typed into but not yet saved. The line total beside it is arithmetic done in the
   browser, not the figure in the database, and a row that does not say so is a row
   somebody will read a number off and believe. */
table.data tr.unsaved > td{background:var(--warn-bg)}
table.data tr.unsaved:hover > td{background:var(--warn-bg)}
table.data td.provisional{color:var(--warn);font-style:italic}
table.data tfoot td{font-weight:650;border-top:2px solid var(--line);background:var(--head-bg)}
/* The row for adding a line. Each box sits under the heading it belongs to, which is the
   whole reason it is a table row rather than a block of fields below the table. */
table.data tr.addrow td{font-weight:400;padding:8px 10px;vertical-align:middle}
table.data tr.addrow input[type=text],table.data tr.addrow select{
  padding:3px 6px;font-size:13px;min-width:6em}
table.data tr.addrow .cellnum{width:100%;min-width:4.5em}
table.data tr.addrow input[type=date],table.data tr.addrow select{padding:3px 6px;font-size:13px}

/* ---------- things to do on a job ---------- */
/* The standing of a task is carried by the row, so a list of twenty reads at a glance:
   late in red, due within days in amber, done greyed and struck through. */
table.data tr.task-overdue > td{background:var(--bad-bg)}
table.data tr.task-today > td,table.data tr.task-soon > td{background:var(--warn-bg)}
table.data tr.task-doneRow > td{color:var(--muted)}
table.data tr.task-doneRow td:nth-child(2){text-decoration:line-through}
.tickbtn{font-size:15px;line-height:1;padding:1px 7px}

/* ---------- a comment thread ---------- */
.thread{list-style:none;margin:0 0 18px;padding:0}
.thread li{padding:10px 0;border-bottom:1px solid var(--row-line)}
.thread li:last-child{border-bottom:0}
.thread .who{display:flex;align-items:center;gap:8px;margin-bottom:4px;font-size:13px}
.thread .said{white-space:pre-wrap;padding-left:34px}
.chip{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;
  border-radius:50%;background:var(--accent-soft);color:var(--accent);
  font-size:11px;font-weight:700;letter-spacing:.3px}
.empty{padding:26px;text-align:center;color:var(--muted)}

/* ---------- badges ---------- */
.badge{display:inline-block;padding:1px 7px;border-radius:10px;font-size:11.5px;font-weight:600;
  white-space:nowrap;background:var(--chip-bg);color:var(--chip-ink)}
.badge.ok{background:var(--ok-bg);color:var(--ok)}
.badge.warn{background:var(--warn-bg);color:var(--warn)}
.badge.bad{background:var(--bad-bg);color:var(--bad)}
.badge.info{background:var(--accent-soft);color:var(--accent)}

/* ---------- forms ---------- */
.field{margin-bottom:12px}
.field label{display:block;font-size:12px;font-weight:600;color:var(--muted);margin-bottom:3px}
input[type=text],input[type=search],input[type=password],input[type=email],input[type=number],
input[type=date],input[type=time],select,textarea{
  width:100%;padding:6px 9px;border:1px solid var(--field-line);border-radius:4px;font-size:13.5px;
  font-family:inherit;background:var(--panel);color:var(--ink)
}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
textarea{min-height:70px;resize:vertical}
.field.check{display:flex;align-items:center;gap:7px}
.field.check label{margin:0;font-size:13px;color:var(--ink);font-weight:500}
.field.check input{width:auto}
.formgrid{display:grid;gap:0 16px;grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
.formgrid .wide{grid-column:1/-1}
.hint{font-size:12px;color:var(--muted);margin-top:3px}

.btn{display:inline-block;padding:6px 14px;border-radius:4px;border:1px solid var(--field-line);
  background:var(--panel);color:var(--ink);font-size:13px;font-weight:600;cursor:pointer;font-family:inherit}
.btn:hover{background:var(--btn-hover);text-decoration:none}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.btn.primary:hover{background:var(--accent-hover)}
.btn.danger{background:var(--panel);border-color:var(--bad-line);color:var(--bad)}
.btn.danger:hover{background:var(--bad-bg)}
.btn.sm{padding:3px 9px;font-size:12px}
.btnrow{display:flex;gap:8px;align-items:center;margin-top:14px}
.btnrow .right{margin-left:auto}

/* ---------- filters ---------- */
.filters{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px 14px;margin-bottom:16px;box-shadow:var(--shadow)}
.filters .field{margin:0;min-width:150px}
.filters .field.narrow{min-width:110px}

/* ---------- flash + errors ---------- */
.flash{padding:10px 14px;border-radius:var(--radius);margin-bottom:16px;font-size:13.5px;font-weight:500}
.flash.ok{background:var(--ok-bg);color:var(--ok);border:1px solid var(--ok-line)}
.flash.err{background:var(--bad-bg);color:var(--bad);border:1px solid var(--bad-line)}
.flash.warn{background:var(--warn-bg);color:var(--warn);border:1px solid var(--warn-line)}
ul.errors{margin:0 0 14px;padding:10px 14px 10px 30px;background:var(--bad-bg);color:var(--bad);
  border:1px solid var(--bad-line);border-radius:var(--radius);font-size:13px}

/* ---------- pagination ---------- */
.pager{display:flex;gap:6px;align-items:center;margin-top:14px;font-size:13px;color:var(--muted)}
.pager a,.pager span.cur{padding:4px 9px;border:1px solid var(--line);border-radius:4px;background:var(--panel)}
.pager span.cur{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
.pager .count{margin-left:auto}

/* ---------- detail lists ---------- */
dl.kv{display:grid;grid-template-columns:auto 1fr;gap:5px 14px;margin:0;font-size:13.5px}
dl.kv dt{color:var(--muted);font-size:12px;font-weight:600;padding-top:2px;white-space:nowrap}
dl.kv dd{margin:0}
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:0}
.tabs a{padding:8px 14px;font-size:13px;font-weight:600;color:var(--muted);
  border:1px solid transparent;border-bottom:none;border-radius:4px 4px 0 0}
.tabs a.on{background:var(--panel);border-color:var(--line);color:var(--accent);margin-bottom:-1px}
.tabs a:hover{text-decoration:none;color:var(--accent)}

/* ---------- login ---------- */
.loginwrap{max-width:340px;margin:9vh auto;background:var(--panel);border:1px solid var(--line);
  border-radius:8px;padding:26px;box-shadow:var(--lift)}
.loginlogo{display:block;width:100%;max-width:230px;height:auto;margin:0 0 18px}
.loginwrap h1{font-size:16px;margin:0 0 4px}
.loginwrap p.sub{color:var(--muted);font-size:13px;margin:0 0 18px}
/* Nobody is signed in here, so there is no stored preference to read: the sign-in page
   follows the machine and nothing else. */
body.loginpage{background:var(--login-bg)}

/* ---------- print ---------- */
@media print{
  /* Paper is white whatever the screen is. Without this the dark palette prints as pale
     grey text on a white page, which is the sort of thing nobody notices until a job card
     comes off the printer blank. */
  :root, :root[data-theme="dark"], :root[data-theme="light"]{
    color-scheme:light;
    --bg:#fff; --panel:#fff; --ink:#111; --muted:#555; --line:#bbb;
    --accent:#111; --accent-ink:#fff; --accent-soft:#eee;
    --ok:#1c6b3f; --ok-bg:#fff; --warn:#7a5100; --warn-bg:#fff;
    --bad:#a12a2a; --bad-bg:#fff; --bad-line:#bbb;
    --field-bg:#fff; --field-line:#bbb; --head-bg:#fff; --hover:#fff;
    --row-line:#ddd; --row-hover:#fff; --chip-bg:#fff; --chip-ink:#333;
    --btn-hover:#fff; --accent-hover:#111; --plate:#fff;
    --ok-line:#bbb; --warn-line:#bbb; --login-bg:#fff;
    --shadow:none; --lift:none;
  }
  .topbar,.sidenav,.foot,.actions,.filters,.pager,.noprint{display:none!important}
  .shell{display:block}
  .main{padding:0}
  .panel{border:none;box-shadow:none;page-break-inside:avoid}
  body{background:#fff;font-size:11px}
  table.data th{background:#fff}
  @page{margin:12mm}
}

@media (max-width:820px){
  .shell{flex-direction:column}
  .sidenav{width:100%;flex:none;position:static;display:flex;padding:0;height:auto;
    border-right:none;border-bottom:1px solid var(--line)}
  .navlinks a{border-left:none;border-bottom:3px solid transparent;white-space:nowrap;padding:10px 14px}
  .navlinks a.on{border-left:none;border-bottom-color:var(--accent)}
  /* The strip is horizontal on a phone; section headings would break the run. */
  .navsection{display:none}
  .main{padding:14px}
  .globalsearch{display:none}
}

/* ---------- health checks ---------- */
table.data.checks td{padding:11px 12px;vertical-align:top}
table.data.checks tbody tr:hover{background:transparent}
.checkdetail{color:var(--muted);font-size:12.5px;margin-top:3px;line-height:1.5;
  white-space:pre-wrap;word-break:break-word;font-variant-numeric:tabular-nums}
.checkdetail strong{color:var(--ink)}
details summary{outline:none}

/* ---------- tick-box grids (job specification and tool list) ---------- */
.tickgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:4px 16px}
.tickgrid label{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:400;
  padding:3px 0;cursor:pointer;line-height:1.35}
.tickgrid input{flex:none;margin:0}
.tickgrid label:hover{color:var(--accent)}

/* A tile that is itself a link (the dashboard and the certificate board). */
a.tile:hover{border-color:var(--accent)}

/* Inline certificate and standard forms opened from a table row. */
.certform{background:var(--bg);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px 14px;text-align:left;min-width:min(560px,72vw)}

/* A two-up row for panels whose rows carry a sentence rather than a number. */
.grid.wide{grid-template-columns:repeat(auto-fit,minmax(560px,1fr))}

/* ---------- who is signed in, at the bottom of the menu ---------- */
.whoami{display:flex;flex-direction:column;gap:1px;line-height:1.25;padding:6px 6px 8px;
  border-radius:4px;text-decoration:none;color:inherit}
.whoami:hover{background:var(--hover);text-decoration:none}
.whoami.on{background:var(--accent-soft)}
.whoami .uname{font-weight:650;font-size:13px;color:var(--ink)}
.whoami.on .uname{color:var(--accent)}
.whoami .urole{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.4px}

/* Light / dark / auto: three form buttons, so it works with the script blocked. */
.themepick{display:flex;margin-top:8px;border:1px solid var(--field-line);border-radius:4px;
  overflow:hidden}
.themepick button{flex:1;padding:5px 0;border:0;border-right:1px solid var(--field-line);
  background:var(--panel);color:var(--muted);font:600 11px/1.2 inherit;cursor:pointer}
.themepick button:last-child{border-right:0}
.themepick button:hover{background:var(--hover);color:var(--ink)}
.themepick button.on{background:var(--accent);color:var(--accent-ink)}

@media print{.navfoot{display:none}}
@media (max-width:820px){
  /* The menu is a horizontal strip on a phone, so the account block goes back to being
     one more item on the end of it rather than sitting under everything. */
  .sidenav{min-height:0}
  .navlinks{overflow-x:auto;display:flex}
  .navfoot{border-top:0;border-left:1px solid var(--line);display:flex;align-items:center;
    gap:10px;padding:6px 10px}
  .themepick{margin-top:0}
  .whoami .urole{display:none}
}

/* ---------- dashboard widgets ---------- */
.dashgrid{display:grid;grid-template-columns:repeat(12,1fr);gap:0 18px;align-items:start}
.dashwidget.w-full{grid-column:span 12}
.dashwidget.w-half{grid-column:span 6}
@media (max-width:1100px){.dashwidget.w-half{grid-column:span 12}}

/* The customise list: works as buttons, and as a drag target when the script loads. */
.widgetlist{list-style:none;margin:0;padding:0}
.widgetlist li{display:flex;align-items:center;gap:12px;padding:11px 14px;
  border-bottom:1px solid var(--line);background:var(--panel)}
.widgetlist li:last-child{border-bottom:none}
.widgetlist .wl-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.widgetlist .wl-text strong{font-size:13.5px}
.widgetlist .wl-text .dim{font-size:12px;line-height:1.4}
.widgetlist .wl-width{flex:none;white-space:nowrap}
.widgetlist .wl-buttons{flex:none;display:flex;gap:4px;white-space:nowrap}
.widgetlist .grip{display:none;color:var(--muted);font-size:16px;cursor:grab;flex:none}
.widgetlist.draggable .grip{display:inline}
.widgetlist.draggable li{cursor:grab}
.widgetlist li.dragging{opacity:.45;background:var(--bg)}

/* ---------- admin hub ---------- */
.adminlinks{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:10px}
.adminlink{display:flex;flex-direction:column;gap:3px;padding:12px 14px;border-radius:var(--radius);
  border:1px solid var(--line);background:var(--bg);color:inherit;text-decoration:none}
.adminlink:hover{border-color:var(--accent);text-decoration:none}
.adminlink strong{font-size:13.5px;color:var(--accent)}
.adminlink span{font-size:12.5px;color:var(--muted);line-height:1.45}
