/* ===========================================================================
   Able Perfect - Daily Reports System
   Able Perfect internal design system.

   Structure is carried by 1px rules, not by shadows. Corners are 2px except
   on genuinely circular marks. There is one accent colour. Status colours are
   separate from the palette and are always paired with a word.
   =========================================================================== */

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/ibm-plex-sans-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/ibm-plex-sans-600.woff2") format("woff2");
}

:root {
  /* palette */
  --ink:        #1F2933;
  --steel:      #5B6673;
  --rule:       #D6DBE0;
  --ground:     #EDF0F3;
  --paper:      #FFFFFF;

  --blue:       #0A6FAA;
  --blue-dark:  #085A8A;
  --blue-tint:  #E6F0F7;
  --navy:       #0B3D66;

  /* signal, never used decoratively */
  --ok:         #1E7A46;  --ok-bg:    #E8F3EC;
  --hold:       #9A6300;  --hold-bg:  #FCF1DC;
  --busy:       #0A6FAA;  --busy-bg:  #E6F0F7;
  --stop:       #B3261E;  --stop-bg:  #FBEAE9;

  /* a figure the system worked out, not something to type into */
  --calc:    #176340;
  --calc-bg: #E8F3EC;
  --calc-br: #7FC49A;

  --radius: 2px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--ground);
  color: var(--ink);
  font-family: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--blue); }

/* every figure lines up column to column */
input[type=number], .num, .cell, .qbox, .rcell, .rowtot, .coltot, .grand,
.diff, .stat .v, .total .v, .datestamp .v, .mt, .reclist .val b,
.tbl td, .rjt td, .nozz input, .bignum input, .live {
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- masthead */

.masthead {
  max-width: 1420px; margin: 0 auto; padding: 14px 20px 10px;
  display: flex; align-items: center; justify-content: center; gap: 12px;
}
.masthead img { height: 30px; width: auto; display: block; }
.mh-text { display: flex; align-items: baseline; gap: 8px; }
.mh-text strong { font-size: 16px; font-weight: 600; letter-spacing: .4px; color: var(--ink); }
.mh-text span { font-size: 12px; color: var(--steel); }

/* ------------------------------------------------------------------ shell */

.shell {
  max-width: 1420px; margin: 0 auto 28px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}

.appbar {
  height: 56px; background: var(--navy); color: #fff;
  padding: 0 18px; display: flex; align-items: center;
  border-bottom: 1px solid #0D2E4F;
}

/* the person, spelled out properly: initial, name, and the role as its
   own clearly separated badge rather than a faint trailing word */
.userchip { display: inline-flex; align-items: center; gap: 11px; font-size: 13.5px; }
.userchip b {
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: #1C5A8E; border: 1px solid #3A7CB4;
  font-size: 14px; font-weight: 700; color: #fff;
}
.userchip .uname { font-weight: 600; color: #fff; }
.userchip .urole {
  font-size: 11px; font-weight: 600; letter-spacing: .3px;
  color: #DCEBFA; background: rgba(255,255,255,.12);
  border: 1px solid rgba(255,255,255,.22);
  border-radius: var(--radius); padding: 3px 9px; margin-left: 2px;
}

.tabs { display: flex; border-bottom: 1px solid var(--rule); background: var(--paper); }
.tab {
  padding: 11px 18px; text-decoration: none; color: var(--steel);
  font-size: 14px; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab:hover { background: var(--ground); color: var(--ink); }
.tab.active { color: var(--blue); font-weight: 600; border-bottom-color: var(--blue); }

.body { padding: 20px; }

/* --------------------------------------------------------------- headings */

.head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; margin-bottom: 16px;
}
h1 { font-size: 19px; font-weight: 600; margin: 0; }
.entryhead { display: block; }
.entryhead h1 { text-align: center; }
.sub { margin: 4px 0 0; color: var(--steel); font-size: 12.5px; }
.back { font-size: 13px; color: var(--blue); text-decoration: none; display: inline-flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.back:hover { text-decoration: underline; }
h2.sec {
  font-size: 14px; font-weight: 600; margin: 0 0 14px;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
h2.sec small { font-size: 12px; color: var(--steel); font-weight: 400; }

.datestamp {
  display: inline-flex; align-items: baseline; gap: 8px; margin-top: 8px;
  border: 1px solid var(--calc-br); border-radius: var(--radius); padding: 5px 10px;
  background: var(--calc-bg);
}
.datestamp .k { font-size: 12px; color: var(--calc); }
.datestamp .v { font-size: 14px; font-weight: 600; color: var(--calc); }

/* ----------------------------------------------------------------- fields */

.lbl { display: block; font-size: 12px; color: var(--steel); margin-bottom: 5px; }
.hint { font-size: 12px; color: var(--steel); margin: 5px 0 0; }
.hint.center { text-align: center; }
.err { font-size: 12px; color: var(--stop); margin: 5px 0 0; }

input[type=text], input[type=password], input[type=number], input[type=date],
input[type=time], select, textarea {
  width: 100%; font-family: inherit; font-size: 13.5px; color: var(--ink);
  background: var(--paper); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 7px 9px;
}
select { padding-right: 26px; }
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--blue); outline-offset: -1px; border-color: var(--blue);
}
input:disabled, input[readonly] { background: var(--ground); color: var(--steel); }

/* a field the page has set for the worker rather than one still open for
   them to choose - same look as a real disabled input, but this is a
   plain, still-enabled select that JS blocks interaction on, because a
   truly disabled select stops its value being submitted at all */
select.locked { background: var(--ground); color: var(--steel); cursor: not-allowed; }

.field { margin-bottom: 14px; }
.field.bad input, .field.bad select, .field.bad textarea { border-color: var(--stop); }

/* a figure the system works out. Not an input, so it reads as flat text in a
   bordered cell rather than something to type into. */
.box, .box.auto {
  border: 1px solid var(--calc-br); border-radius: var(--radius);
  background: var(--calc-bg); color: var(--calc);
  padding: 7px 9px; font-size: 13.5px; min-height: 33px;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.box small { color: var(--calc); opacity: .75; }

.timewrap { display: flex; gap: 8px; }
.timewrap input { flex: 1; min-width: 0; }
.ampm {
  flex: none; min-width: 42px; display: grid; place-items: center;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--ground); color: var(--steel); font-size: 12px; font-weight: 600;
}
.ampm.bad { border-color: var(--stop); color: var(--stop); }

/* ------------------------------------------------------------------ chips */

.chip {
  display: inline-block; padding: 2px 7px; border-radius: var(--radius);
  border: 1px solid var(--rule); background: var(--paper);
  font-size: 11.5px; color: var(--steel); white-space: nowrap;
}
.chip.vit { border-color: var(--blue); background: var(--blue-tint); color: var(--blue); }
.chip.add { border-color: var(--hold); background: var(--hold-bg); color: var(--hold); }
/* .chip.quality is the real, confirmed reading - green, same as every
   other confirmed figure in the app. A dedicated tank's PREVIEW of what
   it will hold, before anyone has actually read it, is deliberately
   different (.chip.preview, muted gray) so the two are never confused -
   green has meant "this is done" everywhere else in the app; it should
   not also mean "this is what it will probably be". */
.chip.quality { border-color: var(--ok); background: var(--ok-bg); color: var(--ok); font-weight: 600; }
.chip.preview {
  display: inline-flex; align-items: center; gap: 3px;
  border-color: var(--rule); background: var(--ground); color: var(--steel);
  font-weight: 600;
}
.chip.vit { border-color: var(--blue); color: var(--blue); }
.chip.add { border-color: var(--hold); color: var(--hold); }
.chip.sm { font-size: 11px; padding: 1px 6px; }

/* V and B are flags, so they read as set or not set, not as colour */
.flag {
  display: inline-grid; place-items: center; width: 20px; height: 20px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper); color: var(--rule); font-size: 11px; font-weight: 600;
}
.flag.on { border-color: var(--blue); background: var(--blue); color: #fff; }

/* ----------------------------------------------------------------- panels */

.panel {
  background: var(--paper); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 16px; margin-bottom: 14px;
}
.grid { display: grid; grid-template-columns: 1fr; gap: 14px; }

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border-radius: var(--radius); padding: 8px 16px; cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 600; text-decoration: none;
  border: 1px solid transparent;
}
.btn.primary, .btn.go { background: var(--blue); border-color: var(--blue); color: #fff; }
.btn.primary:hover, .btn.go:hover { background: var(--blue-dark); border-color: var(--blue-dark); }
.btn.ghost { background: transparent; border-color: var(--blue); color: var(--blue); }
.btn.ghost:hover { background: var(--ground); }
.btn.danger { background: transparent; border-color: var(--stop); color: var(--stop); }
.btn.danger:hover { background: var(--stop-bg); }
/* pointer-events: none stops a disabled button from ever matching :hover -
   without it, .btn.primary:hover's higher specificity overrode this rule,
   so a disabled Confirm And Lock / Submit For Approval button would flash
   its active hover colour on mouseover as if it were still clickable */
.btn[disabled] { border-color: var(--rule); background: var(--ground); color: var(--steel); cursor: default; pointer-events: none; }
.btn.block { width: 100%; }
.btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.actions {
  display: flex; gap: 10px; justify-content: flex-end; align-items: center;
  border-top: 1px solid var(--rule); margin-top: 18px; padding-top: 14px;
}
.actions .note { margin-right: auto; font-size: 12.5px; color: var(--steel); }

/* ---------------------------------------------------------------- banners */

.flash, .strip, .errbox {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; margin-bottom: 12px; font-size: 13px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper);
}
.flash-success, .strip.ok { border-color: var(--ok); background: var(--ok-bg); color: var(--ok); }
.flash-warning, .strip.warn { border-color: var(--hold); background: var(--hold-bg); color: var(--hold); }
.flash-error, .errbox { border-color: var(--stop); background: var(--stop-bg); color: var(--stop); }
.errbox b { display: block; font-weight: 600; }
.strip .ico, .errbox .ico, .flash .ico { flex: none; margin-top: 1px; }

/* ------------------------------------------------------------------ table */

.tbl { width: 100%; border-collapse: collapse; background: var(--paper); }

.c-tank  { width: 72px; }
.c-form  { width: 94px; }
.c-arrow { width: 120px; }
.c-mt    { width: 132px; }
.c-qual  { width: 268px; }

.tbl thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--navy); color: #fff;
  font-size: 12px; font-weight: 600; text-align: center;
  padding: 8px 9px; white-space: nowrap;
  border-right: 1px solid #14496F;
}
.tbl thead th:last-child { border-right: 0; }
.tbl tbody td {
  padding: 7px 9px; border-bottom: 1px solid var(--rule); vertical-align: top;
  text-align: center;
}
.tbl tbody td.tankcell { text-align: left; }
.tbl tbody tr:hover td { background: var(--ground); }
.t-no { font-weight: 600; }
.t-fm { color: var(--steel); }

.cell {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 84px; height: 28px; padding: 0 8px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper); font-size: 13px;
}
.cell.auto { background: var(--calc-bg); border-color: var(--calc-br); color: var(--calc); font-weight: 600; }
.cell.blank { border-style: dashed; color: var(--steel); background: transparent; }

.qcell { display: inline-flex; flex-direction: column; align-items: stretch; width: 248px; gap: 4px; }
.qcell .row1 { display: flex; align-items: center; gap: 5px; height: 28px; }
.qcell .row2 { display: flex; flex-wrap: wrap; gap: 3px; padding-right: 50px; }
.qcell .row2:empty { display: none; }

.qbox {
  flex: 1 1 auto; min-width: 0; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 8px; border: 1px solid var(--calc-br); border-radius: var(--radius);
  background: var(--calc-bg); color: var(--calc); font-weight: 600; font-size: 12.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qbox.is-empty, .qbox.blank {
  border-style: dashed; border-color: var(--rule);
  color: var(--steel); background: transparent; font-weight: 400;
}

.tapcell { text-decoration: none; display: block; color: inherit; }
.tapcell:hover .cell { border-color: var(--blue); }

.progbox { height: 100%; border: 1px solid var(--rule); border-radius: var(--radius); padding: 10px 12px; }
.progbox .top { display: flex; justify-content: space-between; font-size: 12.5px; }
.progbox .top b { font-weight: 600; }
.progbox .top > span { color: var(--steel); }
.progbox .top b .mer { font: inherit; color: inherit; }
.bar { height: 6px; background: var(--ground); border: 1px solid var(--rule); margin-top: 8px; }
.bar i { display: block; height: 100%; background: var(--blue); }

/* ------------------------------------------------------------ tank entry */

.bignum {
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper); padding: 16px; text-align: center; margin-bottom: 10px;
}
.bignum .k { display: block; font-size: 12px; color: var(--steel); margin-bottom: 6px; }
.bignum input {
  width: 100%; border: 0; background: transparent; text-align: center;
  font-size: 40px; font-weight: 600; padding: 0; font-family: inherit; color: var(--ink);
}
.bignum input:focus { outline: none; }
.bignum.bad { border-color: var(--stop); }
.live {
  display: inline-block; margin-top: 8px; padding: 5px 14px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--ground); color: var(--steel); font-size: 14px; font-weight: 600;
}
.live.ok { border-color: var(--calc-br); background: var(--calc-bg); color: var(--calc); }

.keypad { display: none; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.keypad button {
  font-family: inherit; font-size: 22px; font-weight: 600; color: var(--ink);
  background: var(--paper); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 16px 0; min-height: 52px;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  touch-action: manipulation; user-select: none;
  transition: transform .05s, background-color .05s;
}
/* a clear, immediate pressed state - a color change alone can be easy to
   miss on a bright phone screen outdoors, so the button also dips
   slightly, giving a tactile confirmation that the tap actually landed */
.keypad button:active {
  background: var(--blue); border-color: var(--blue); color: #fff;
  transform: scale(0.94);
}
.keypad[data-dim] button { color: var(--steel); }


/* a proper reference card, not a single cramped row - a labeled header,
   a genuinely prominent value, and the supporting detail kept visually
   separate from it, the same weight given to other read-only figures
   elsewhere in the app (Total Oil Packed, Reject Rate) */
.opening {
  border: 1px solid var(--calc-br); border-radius: var(--radius);
  background: var(--calc-bg); padding: 14px 16px; margin-bottom: 14px;
}
.op-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.op-label {
  font-size: 12px; font-weight: 700; color: var(--calc);
  text-transform: uppercase; letter-spacing: .4px;
}
.op-tag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 600; color: var(--calc);
  background: rgba(255,255,255,.65); border: 1px solid var(--calc-br);
  border-radius: 20px; padding: 3px 9px 3px 7px;
}
.op-body {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px;
}
.op-value { font-size: 25px; font-weight: 700; color: var(--calc); }
.op-detail { font-size: 12.5px; color: var(--calc); opacity: .85; }
.op-note {
  margin: 10px 0 0; padding-top: 10px; border-top: 1px solid var(--calc-br);
  font-size: 11.5px; color: var(--calc); opacity: .8;
}

.emptynote {
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 12px 14px; margin-bottom: 14px; font-size: 13px; color: var(--steel);
}
.emptynote b { display: block; color: var(--ink); font-weight: 600; margin-bottom: 2px; }

.checks > div, .checks ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 7px;
}
.checks > div > div, .checks li { margin: 0; }
.checks label {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 6px 11px; font-size: 13px; background: var(--paper);
}
.checks label:hover { background: var(--ground); }
.checks input { accent-color: var(--blue); margin: 0; }
.qfield { margin-bottom: 12px; }
.savebtn { margin-bottom: 8px; }

/* ----------------------------------------------------------------- totals */

.total {
  border: 1px solid var(--calc-br); border-radius: var(--radius);
  background: var(--calc-bg); padding: 14px; text-align: center; margin-top: 14px;
}
.total .k { font-size: 12px; color: var(--calc); }
.total .v { display: block; font-size: 24px; font-weight: 600; margin: 4px 0 2px; color: var(--calc); }
.total .c { font-size: 12px; color: var(--calc); opacity: .8; }

.stats { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; }
/* a button sitting beside these boxes should look like a button, not a
   slab stretched to match their height */
.stats > .btn { align-self: center; }
.stat { flex: 1; min-width: 160px; border: 1px solid var(--rule); border-radius: var(--radius); padding: 13px 15px; }
.stat.green { border-color: var(--calc-br); background: var(--calc-bg); }
.stat.green .k, .stat.green .v { color: var(--calc); }
.stat .k { font-size: 12px; color: var(--steel); }
.stat .v { display: block; font-size: 20px; font-weight: 600; margin-top: 3px; }

/* ------------------------------------------------------------ record list */

.reclist { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.reclist li { border-bottom: 1px solid var(--rule); }
.reclist a {
  display: flex; align-items: center; gap: 16px; padding: 13px 14px;
  text-decoration: none; color: inherit;
}
.reclist a:hover { background: var(--ground); }
.reclist .id { min-width: 140px; padding-right: 14px; border-right: 1px solid var(--rule); }
.reclist .id b { display: block; font-weight: 600; }
.reclist .id span { font-size: 12px; color: var(--steel); }
.reclist .mid { flex: 1; min-width: 0; }
.reclist .mid .chips { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.reclist .mid .det { font-size: 12px; color: var(--steel); margin-top: 4px; }
.reclist .val { text-align: right; white-space: nowrap; }
.reclist .val b { font-weight: 600; }
.reclist .val span { display: block; font-size: 12px; color: var(--steel); }
.tick { color: var(--ok); }
.cta { color: var(--blue); font-size: 13px; }

.empty, main .empty {
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 32px 16px; text-align: center; color: var(--steel);
}

/* ----------------------------------------------------------------- detail */

.spec { display: grid; grid-template-columns: 1fr; margin: 0; }
.spec dt { font-size: 12px; color: var(--steel); padding-top: 9px; }
.spec dd { margin: 2px 0 0; padding-bottom: 9px; border-bottom: 1px solid var(--rule); }
.calc { font-weight: 600; color: var(--calc); }
.muted { color: var(--steel); }
.scroller { overflow-x: auto; }

/* ---------------------------------------------------- weight check grid */


.wround { margin-bottom: 14px; }
.wround:last-child { margin-bottom: 0; }
.wrhead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 7px; }
.wrhead .rno { font-size: 12.5px; font-weight: 600; }
.roundsum { font-size: 12px; max-width: 100%; }

/* the live status text ("6 of 6 entered - average 4.500 kg - 0.00% over
   target") does not fit next to the round label on a narrow phone. Forcing
   it onto its own flex line with flex-basis stretches the badge to that
   whole line's width, which looks just as wrong the other way - an empty
   box around short text like "Not Yet Entered". Stacking the row itself
   (Round label, then the badge under it) instead keeps every state
   reading as a small chip sized to its own content. */
@media (max-width: 860px) {
  .wrhead { flex-direction: column; align-items: flex-start; }
}

.nozzgrid { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); }
.nozz { border: 1px solid var(--rule); border-radius: var(--radius); padding: 7px 8px; }
.nozz .n { display: block; font-size: 11.5px; color: var(--steel); margin-bottom: 4px; }
.nozz input { width: 100%; text-align: center; font-size: 14px; padding: 5px 3px; }
.nozz .g { display: block; text-align: center; font-size: 11px; color: var(--steel); margin-top: 4px; }
.nozz.off { border-color: var(--hold); }
.nozz.off .g { color: var(--hold); }

/* only the nozzles actually checked get a WeightCheck row at all - a
   round with just 4 or 5 entered has that many columns, not 12. The
   table used to stretch to the full panel width regardless, so fewer
   columns meant each one ballooned out with a big gap either side of the
   number instead of sitting at a normal, consistent width. Giving every
   nozzle column a fixed width, and letting the table itself size to
   however many of them there are, keeps a 4-nozzle round and a 12-nozzle
   one reading the same way - the label column is the only one still
   free to size to its own text. */
.tbl.wt { width: auto; }
.tbl.wt th, .tbl.wt td { text-align: center; font-size: 12.5px; width: 64px; }
.tbl.wt .rl { text-align: left; white-space: nowrap; color: var(--steel); width: auto; }
.tbl.wt th.rl { color: #fff; }
.tbl.wt .tare { color: var(--steel); }

/* ------------------------------------------------------------ reject grid */

.rjt { width: 100%; border-collapse: collapse; }
.rjt thead th {
  background: var(--navy); color: #fff; font-size: 12px; font-weight: 600;
  padding: 8px 9px; text-align: center; white-space: nowrap;
  border-right: 1px solid #14496F;
}
.rjt thead th:last-child { border-right: 0; }
.rjt td.d { text-align: left; }
.rjt td { padding: 7px 9px; text-align: right; border-bottom: 1px solid var(--rule); }
.rjt input { width: 84px; text-align: right; }
.rjt .rcell, .rjt .rowtot, .rjt .coltot, .rjt .grand {
  /* matches .rjt input's own width exactly, so a total box is never
     narrower than the entry boxes feeding it */
  display: inline-block; min-width: 84px; padding: 5px 8px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--ground); font-size: 13px; box-sizing: border-box;
}
.rjt .rowtot, .rjt .coltot, .rjt .grand {
  font-weight: 600; border-color: var(--calc-br);
  background: var(--calc-bg); color: var(--calc);
}
.rjt tfoot td { background: var(--ground); font-weight: 600; }

/* the same weight as Total Oil Packed and Oil Per Unit - a reject rate is
   just as important a figure and should not read as an afterthought */
.rejrate {
  margin-top: 14px; padding: 13px 16px;
  border: 1px solid var(--calc-br); border-radius: var(--radius);
  background: var(--calc-bg);
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.rejrate .k { font-size: 12px; color: var(--calc); }
.rejrate .v { font-size: 24px; font-weight: 600; color: var(--calc); }
.rejrate .v.warn { color: var(--hold); }
.rejrate .c { font-size: 12px; color: var(--calc); opacity: .8; }

/* ------------------------------------------------------- output selection */

.optpair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.opt { border: 1px solid var(--rule); border-radius: var(--radius); padding: 13px 14px; cursor: pointer; }
.opt.on { border-color: var(--blue); }
.opt.off { background: var(--ground); }
.opt.off:hover { border-color: var(--blue); }
.opthead { display: flex; align-items: center; gap: 8px; margin-bottom: 11px; }
.opthead input { width: auto; accent-color: var(--blue); margin: 0; flex: none; }
.opthead b { font-size: 13px; font-weight: 600; }
.opthead em {
  display: none; font-style: normal; font-size: 11.5px; font-weight: 600;
  color: var(--blue); border: 1px solid var(--blue); border-radius: var(--radius);
  padding: 1px 6px;
}
.opt.on .opthead em { display: inline-block; }
.opt input:disabled { pointer-events: none; }
.opt.on .optbody input { cursor: auto; }
.cartonrow { display: flex; align-items: flex-start; gap: 8px; }
.cf { flex: 1; min-width: 0; }
.cf .cl { display: block; font-size: 11.5px; color: var(--steel); margin-top: 4px; text-align: center; }
.cartonrow .x, .cartonrow .eq { color: var(--steel); padding-top: 8px; flex: none; }
.optnote { display: block; font-size: 12px; color: var(--steel); margin-top: 9px; min-height: 14px; }

/* -------------------------------------------------------------- particulars */

.rjt.pt { table-layout: fixed; }
.rjt.pt col.pt-q    { width: 9%; }
.rjt.pt col.pt-n    { width: 9%; }
.rjt.pt col.pt-diff { width: 11%; }
.rjt.pt col.pt-pct  { width: 12%; }
.rjt.pt col.pt-rem  { width: 19%; }

/* the full table (everyone but a plain Weighbridge Worker) is laid out in
   fixed widths and scrolls sideways inside .scroller when the screen is
   narrower, rather than squeezing Remark down to a sliver - Remark takes
   whatever width is left, never less than 320px */
.rjt.pt.pt-full { min-width: 1560px; }
.rjt.pt.pt-full col.pt-q    { width: 160px; }
.rjt.pt.pt-full col.pt-n    { width: 120px; }
.rjt.pt.pt-full col.pt-diff { width: 136px; }
.rjt.pt.pt-full col.pt-pct  { width: 156px; }
.rjt.pt.pt-full col.pt-rem  { width: auto; }
.rjt.pt.pt-full .rem { min-width: 320px; }
.rjt.pt col.pt-act  { width: 70px; }

/* Incoming and Remark default to a plain read-only display once a row has
   been saved, with an Edit button to deliberately unlock them - so a
   saved figure cannot be nudged by an accidental click or a stray tab
   press while scrolling past it. Editing lasts until the page reloads,
   which a real Save Particulars submit always does, so a row that was
   unlocked to fix one figure does not stay unlocked afterwards. */
.rjt.pt tr.pt-saved .pt-edit-input { display: none; }
.rjt.pt tr.pt-saved.editing .pt-edit-input { display: block; }
.rjt.pt tr.pt-saved.editing .pt-view { display: none; }
.rjt.pt tr.pt-saved.editing .pt-edit-btn { display: none; }
.pt-view { font-weight: 600; color: var(--ink); }
td.rem .pt-view { font-weight: 400; color: var(--steel); }
td.act { text-align: center; }

.rjt.pt th { text-align: center; }
.rjt.pt .d { min-width: 130px; text-align: center; }
/* product name with its Draft / Awaiting Approval state stacked underneath,
   not squeezed side by side in one narrow cell */
.ptprod { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.ptprod .badge { white-space: nowrap; }
.rjt.pt .rem { min-width: 210px; text-align: left; }

/* the boxed figures sit centred under their centred headers - the base
   table style right-aligns plain cells, which is correct for a reject
   grid but left these numbers stranded under the wrong side of the column */
.rjt.pt td { text-align: center; vertical-align: middle; }
.rjt.pt tbody tr:hover { background: var(--ground); }
.qlab {
  display: inline-block; padding: 4px 9px; font-weight: 600;
  border: 1px solid var(--calc-br); border-radius: var(--radius);
  background: var(--calc-bg); color: var(--calc);
}
.rjt.pt input[type=number] { width: 92px; }
.rjt.pt .rem input, .rjt.pt .rem textarea { width: 100%; text-align: left; }
.rjt.pt .rem input.needed, .rjt.pt .rem textarea.needed { border-color: var(--hold); }
.rjt.pt textarea.remarkbox { resize: none; overflow: hidden; min-height: 36px;
                             line-height: 1.4; white-space: pre-wrap; }

.diff {
  display: inline-block; min-width: 108px; padding: 4px 8px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  font-size: 12.5px; font-weight: 600; white-space: nowrap; text-align: right;
}
.diff.level { background: var(--ground); }
.diff.extra { border-color: var(--ok); background: var(--ok-bg); color: var(--ok); }
.diff.loss  { border-color: var(--stop); background: var(--stop-bg); color: var(--stop); }

/* a product over the Internal Control limit - flagged on the row and in
   its Variance (%) cell, and raised on the Internal Control tab */
.rjt.pt tr.pt-flag { box-shadow: inset 3px 0 0 var(--stop); }
.pctwrap { display: inline-flex; flex-direction: column; align-items: stretch;
           gap: 5px; width: 132px; vertical-align: middle; }
.diff.pct { text-align: center; }
/* Pending sits in the middle of its box, not pushed to the right edge */
.rjt.pt .diff.pending { text-align: center; min-width: 108px; }
.rjt.pt td.pct-cell .diff.pending { min-width: 0; width: 132px; }

/* the Variance (%) limit, beside the Internal Control heading */
.iclimit { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.iclimit .lbl { font-size: 12.5px; font-weight: 600; color: var(--steel); margin: 0; }
.iclimit input { width: 100px; text-align: center; }
.pctwrap .diff.pct { min-width: 0; }
.icflag {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 4px 6px; border: 1px solid var(--stop); border-radius: var(--radius);
  background: var(--stop-bg); color: var(--stop); text-align: center; line-height: 1.2;
}
.icflag small { font-size: 9.5px; font-weight: 600; letter-spacing: .04em;
                text-transform: uppercase; opacity: .85; }
.icflag b { font-size: 11.5px; font-weight: 700; white-space: nowrap; }

/* open Internal Control alerts, counted on the tab itself */
.tabcount {
  display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px;
  border-radius: 9px; background: var(--stop); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
}

/* ------------------------------------------------------ internal control */
.icfilter { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.icfilter a { text-decoration: none; }
.rjt.ic { table-layout: auto; }
.rjt.ic th, .rjt.ic td { text-align: center; vertical-align: middle; }
.rjt.ic td.txt { text-align: left; min-width: 180px; white-space: normal; }
.rjt.ic tr.ic-open { box-shadow: inset 3px 0 0 var(--stop); }
.rjt.ic .badge { white-space: nowrap; display: inline-block; }
.icclose { display: flex; gap: 8px; align-items: center; min-width: 190px; }
.icclose input { flex: 1; min-width: 0; text-align: left; }
.rjt.ic td[data-label="Variance (MT)"] .diff { text-align: center; }
.rjt.ic th:nth-child(8), .rjt.ic th:nth-child(9) { text-align: left; }
.icmeta { display: block; font-size: 11.5px; color: var(--steel); margin-top: 3px; }

.ptfoot {
  display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--rule);
}
.addq { flex: 1; min-width: 260px; }
.addq input { width: 100%; }

.datepick input { min-width: 170px; }

/* ====================================================== phone ============ */

.mob-only { display: none; }

@media (max-width: 860px) {
  .desk-only { display: none !important; }
  .mob-only  { display: block; }

  /* the top tabs stay, under the username and sign out, and scroll
     sideways rather than wrap when there are more than two of them */
  .tabs {
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap; scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab { flex: none; white-space: nowrap; padding: 11px 14px; font-size: 13px; }
  .masthead { padding: 10px 14px 8px; }
  .masthead img { height: 24px; }
  .mh-text strong { font-size: 14px; }
  .shell { margin: 0 0 16px; border-left: 0; border-right: 0; }
  .body { padding: 14px; }
  /* Daily Bulk Oil Status: for a Weighbridge or Filling Worker, Submit
     For Approval moves to the very bottom of the page on a phone - below
     the tank grid, Oil Transfer and Variance Reconciliation alike -
     instead of sitting above all of it, unread, before a single tank has
     even been checked. A Supervisor or Admin keeps seeing it at the top,
     same as before: .mobend only exists on the lockbar when the viewer
     is neither. */
  .tankflow { display: flex; flex-direction: column; }
  .tankflow > .mobend { order: 99; }
  .keypad { display: grid; }
  /* the keypad plus product/additive checkboxes push Save well down a
     phone screen - stick it to the bottom of the viewport, edge to edge,
     so it stays one tap away instead of needing a scroll to reach */
  .savebtn {
    position: sticky; bottom: 0; z-index: 5;
    margin: 16px -14px -14px; width: calc(100% + 28px);
    padding: 12px 14px; border-radius: 0;
    border-top: 1px solid var(--rule); background: var(--paper);
  }
  .head { display: block; }
  /* View Another Day used to be desk-only, leaving Supervisors and Admin
     with no way to jump to a different date on a phone at all. Now it
     drops below the title and date badge instead of sitting beside them,
     and the date input already goes full-width from the ordinary input
     rule, so it just needs room to breathe from what's above it. */
  .datepick { margin-top: 12px; }
  /* Download PDF / Edit drop below the title and fact list the same way,
     once .head stacks - they need the same room to breathe, not to sit
     flush against the last row above them */
  .dtactions { margin-top: 16px; }
  /* Worker Manual / Supervisor Manual: Download PDF is a single button
     sitting directly in .head, not wrapped in .dtactions - same fix, same
     reason, once the title stacks above it */
  .head > a.btn { margin-top: 16px; }

  .mcards { list-style: none; margin: 12px 0 0; padding: 0; border-top: 1px solid var(--rule); }
  .mcards li { border-bottom: 1px solid var(--rule); }
  .mcards a { display: block; padding: 11px 12px; text-decoration: none; color: inherit; }
  .mcards a:hover { background: var(--ground); }
  .mc-top { display: flex; align-items: center; gap: 8px; }
  .mc-t { font-weight: 600; }
  .mc-r { margin-left: auto; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
  .mc-r b { font-weight: 600; }
  .mc-r .arr { color: var(--steel); }
  .mc-sub { font-size: 12px; color: var(--steel); margin-top: 4px; display: flex; gap: 5px; flex-wrap: wrap; align-items: center; }

  .optpair { grid-template-columns: 1fr; }
  .nozzgrid { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); }
  .rjt input { width: 64px; }
  /* the total boxes shrink to match the input, so the two stay the same
     size as a set instead of drifting apart below the tablet breakpoint */
  .rjt .rcell, .rjt .rowtot, .rjt .coltot, .rjt .grand { min-width: 64px; }
  .actions { flex-wrap: wrap; }
  .actions .note { width: 100%; margin-bottom: 8px; }
}

@media (min-width: 861px) {
  .grid.c2 { grid-template-columns: repeat(2, 1fr); }
  .grid.c3 { grid-template-columns: repeat(3, 1fr); }
  .grid.c4 { grid-template-columns: repeat(4, 1fr); }
  .spec { grid-template-columns: 210px 1fr; }
  .spec dt { padding: 9px 0; border-bottom: 1px solid var(--rule); }
  .spec dd { margin: 0; padding: 9px 0; }
}

/* =======================================================================
   Locking, people and the audit trail
   ======================================================================= */

.lockbar { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.lockcell {
  flex: 1; min-width: 300px;
  border: 1px solid var(--rule); border-radius: var(--radius); padding: 12px 14px;
}
.lockstate { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 9px; margin-bottom: 6px; }
.lockstate .badge { white-space: nowrap; }
.lockstate b { font-weight: 600; }
.lockmeta { font-size: 12px; color: var(--steel); margin-bottom: 8px; }
.lockcell form { display: flex; gap: 8px; align-items: center; }
.lockcell input { flex: 1; min-width: 0; }

.badge {
  font-size: 11.5px; font-weight: 600; padding: 2px 7px;
  border: 1px solid var(--rule); border-radius: var(--radius);
}
.badge.locked { border-color: var(--calc-br); background: var(--calc-bg); color: var(--calc); }
.badge.open   { border-color: var(--hold); background: var(--hold-bg); color: var(--hold); }
.badge.draft  { color: var(--steel); }
.badge.ok    { border-color: var(--ok); background: var(--ok-bg); color: var(--ok); }
.badge.busy  { border-color: var(--busy); background: var(--busy-bg); color: var(--busy); }
.badge.warn  { border-color: var(--hold); background: var(--hold-bg); color: var(--hold); }
.badge.stop  { border-color: var(--stop); background: var(--stop-bg); color: var(--stop); }
.badge.muted { color: var(--steel); }

.inline { display: inline-flex; gap: 6px; align-items: center; }
.inline select { width: auto; min-width: 130px; }
.btn.small { padding: 5px 11px; font-size: 12.5px; white-space: nowrap; }

/* the three account actions sit on one line and wrap together */
.unamecol { padding-left: 4px; }
.inline.center { justify-content: center; }

/* two tidy rows, centred under the "Actions" heading */
.actrow { display: flex; gap: 6px; align-items: center; justify-content: center; }
.pwform input[type=text] { width: 150px; }

.filterbar { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.filterbar .field { margin-bottom: 0; min-width: 180px; }

/* a change reads as before and after, not as a sentence to decode */
.chg { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 12.5px; }
.chg .fname { color: var(--steel); min-width: 110px; }
.chg .was { color: var(--steel); text-decoration: line-through; }
.chg .now { font-weight: 600; }

/* a reader without entry rights still sees the figures, but nothing
   presents itself as something to click */
.tapcell.noedit { pointer-events: none; }
.tapcell.noedit .cell.blank { opacity: .6; }

/* =======================================================================
   Sign in
   ======================================================================= */

body.signin {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; min-height: 100vh; padding: 20px;
}
body.signin .masthead { margin-bottom: 22px; }
.signbox {
  width: 100%; max-width: 380px;
  background: var(--paper); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 26px 24px;
}
.signbox h1 { font-size: 19px; font-weight: 600; margin: 0; }
.signbox .sub { margin: 4px 0 20px; }
.signbox .field { margin-bottom: 14px; }
.signbox .btn { margin-top: 6px; }
.signbox .hint { margin-top: 16px; text-align: center; }
.signbox .errbox { margin-bottom: 16px; }

/* sign out sits at the far end of the bar, quiet until wanted */
.signout { margin-left: auto; }
/* inside the grouped actions on the main app pages, the wrapper itself
   handles pushing the group right - signout does not need its own auto
   margin there too, only on standalone pages like Departments that use
   the sign-out form on its own with no such wrapper around it */
.appbar-actions .signout { margin-left: 0; }
/* matches .homelink exactly, so the two appbar buttons read as one
   family instead of the sign-out one looking like a different color */
.signout button {
  background: none; border: 1px solid rgba(255,255,255,.35);
  border-radius: var(--radius); color: #fff; font-weight: 600;
  font-family: inherit; font-size: 12.5px; padding: 7px 12px; cursor: pointer;
  transition: border-color .1s;
}
.signout button:hover { border-color: #fff; }

/* =======================================================================
   Reports
   ======================================================================= */

.healthgrid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.hcell { border: 1px solid var(--rule); border-radius: var(--radius); padding: 11px 13px; }
.hcell .k { display: block; font-size: 12px; color: var(--steel); }
.hcell .v { display: block; font-size: 20px; font-weight: 600; margin: 3px 0; }
.hcell .n { display: block; font-size: 12px; color: var(--steel); }
.hcell.ok   { border-color: var(--calc-br); }
.hcell.ok .v { color: var(--calc); }
.hcell.warn { border-color: var(--hold); }
.hcell.warn .v, .hcell.warn .n { color: var(--hold); }
.hcell.stop { border-color: var(--stop); }
.hcell.stop .v, .hcell.stop .n { color: var(--stop); }
.hcell.none .v { color: var(--steel); }

/* seven plain columns, drawn with two divs and no library */
.weekchart { display: flex; gap: 10px; align-items: flex-end; height: 150px; }
.wbar { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; height: 100%; }
.wval { font-size: 11.5px; color: var(--steel); margin-bottom: 4px; }
.wcol { flex: 1; width: 100%; display: flex; align-items: flex-end;
        border-bottom: 1px solid var(--rule); }
.wcol i { display: block; width: 100%; background: var(--blue-tint);
          border: 1px solid var(--blue); border-bottom: 0; min-height: 1px; }
.wbar.now .wcol i { background: var(--blue); }
.wbar.now .wval { color: var(--blue); font-weight: 600; }
.wday { font-size: 11.5px; color: var(--steel); margin-top: 5px; }

.repform { margin-bottom: 14px; }
.rephead {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 14px; flex-wrap: wrap; margin-bottom: 12px;
  padding-top: 12px; border-top: 1px solid var(--rule);
}
.rephead b { display: block; font-weight: 600; }
.rephead .muted { font-size: 12.5px; }
/* the Reports tables (report data + Recently Submitted) were the same
   story as My Submissions - centered headers over data that quietly
   inherited a left-align rule meant for a completely different table.
   Centered explicitly, with real row separation instead of default
   spacing so a table that can run to hundreds of rows stays readable. */
.rjt.rep td { font-size: 12.5px; white-space: nowrap; }
.rjt.rep td.d, .rjt.rep th.d { text-align: center; }
.rjt.rep td { padding: 10px 14px; }
.rjt.rep tbody tr:nth-child(even) { background: var(--ground); }
.rjt.rep tbody tr:hover { background: var(--blue-tint); }
.rjt.rep .empty-row td {
  padding: 30px 14px; color: var(--steel); font-size: 13px;
  text-align: center; white-space: normal; background: var(--paper);
}

.dtactions { display: flex; gap: 10px; }

.req { color: var(--stop); margin-left: 3px; }

.addround { display: block; margin: 0 0 16px; }
.addround:last-of-type { margin-bottom: 0; }
.addround[hidden] { display: none; }

/* =======================================================================
   Guide
   ======================================================================= */

/* fills the same width as every other tab's panels - just with a bit
   more breathing room throughout than the rest of the app's denser,
   data-heavy panels, since a manual is read top to bottom rather than
   scanned like a data screen */
.manual { }
.manual .panel { padding: 20px 22px; margin-bottom: 18px; }
.manual .panel[id] { scroll-margin-top: 14px; }
.manual h2.sec { margin-bottom: 16px; }
.manual .hint { margin-bottom: 10px; }
.manual .hint + .steps { margin-top: 2px; }
/* the steps list's own last li has no bottom margin, so a warning
   straight after one runs flush against it with no room to breathe */
.manual .steps + .strip { margin-top: 14px; }

.mnav {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  padding: 14px 16px; margin-bottom: 18px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--ground);
}
.mnav .mnt {
  flex: 1 1 100%; font-size: 11px; font-weight: 700; color: var(--steel);
  text-transform: uppercase; letter-spacing: .04em; margin-bottom: 2px;
}
.mnav a {
  font-size: 12.5px; font-weight: 600; color: var(--blue); text-decoration: none;
  padding: 6px 11px; border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper);
}
.mnav a:hover { background: var(--blue-tint); border-color: var(--blue); }

.backtotop {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 600; color: var(--blue); text-decoration: none;
}
.backtotop:hover { text-decoration: underline; }

.steps { margin: 0; padding-left: 22px; }
.steps li { margin-bottom: 13px; line-height: 1.6; }
.steps li:last-child { margin-bottom: 0; }
.steps code {
  background: var(--ground); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 1px 5px; font-size: 12.5px;
}

.faq dt {
  font-weight: 600; margin-top: 18px; padding-top: 15px;
  border-top: 1px solid var(--rule); line-height: 1.5;
}
.faq dt:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.faq dd { margin: 6px 0 0; color: var(--steel); line-height: 1.6; }

@media (max-width: 860px) {
  .manual .panel { padding: 16px; }
}

/* =======================================================================
   Particulars readiness
   ======================================================================= */

.readystate { display: flex; gap: 10px; flex-wrap: wrap; margin: 12px 0 4px; }
.rscell {
  flex: 1; min-width: 200px; display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 9px 12px; font-size: 12.5px; color: var(--steel);
}
.rscell .dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--rule); flex: none;
}
.rscell.ok { border-color: var(--calc-br); color: var(--calc); }
.rscell.ok .dot { background: var(--calc); }

/* =======================================================================
   People table
   ======================================================================= */

.rjt.people { table-layout: fixed; }
.rjt.people col.c-user   { width: 13%; }
.rjt.people col.c-name   { width: 14%; }
.rjt.people col.c-role   { width: 14%; }
.rjt.people col.c-last   { width: 15%; }
.rjt.people col.c-status { width: 9%; }
.rjt.people col.c-act    { width: 34%; }

/* headers are centred already; the plain-text cells default to right
   alignment for numeric tables elsewhere, which read oddly here */
.rjt.people td { text-align: center; vertical-align: middle; padding: 11px 12px; }
.rjt.people td.d { text-align: left; }
.rjt.people tbody tr:hover { background: var(--ground); }

.rjt.people select { width: 100%; max-width: 160px; }

/* one row of three actions by default. Resetting a password reveals its
   input only when asked for, instead of sitting open on every row all the
   time, which was the actual clutter - not just an alignment problem. */
.rjt.people .rowacts {
  display: flex; align-items: flex-start; justify-content: center;
  gap: 6px; flex-wrap: nowrap; margin: 0 auto;
}
/* Disable/Enable, Reset Password and Delete always sit on one line - the
   buttons size to their own labels rather than a fixed width that forced
   the third one to wrap underneath */
.rjt.people .rowacts .btn.small { width: auto; white-space: nowrap; padding-left: 12px; padding-right: 12px; }

.pwreveal { position: relative; }
.pwreveal summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.pwreveal summary::-webkit-details-marker { display: none; }
.pwreveal[open] summary {
  border-color: var(--blue); background: var(--blue-tint); color: var(--blue-dark);
}
.pwreveal .pwform {
  position: absolute; top: calc(100% + 6px); left: 50%;
  transform: translateX(-50%); z-index: 5;
  display: flex; gap: 6px; align-items: center;
  background: var(--paper); border: 1px solid var(--rule);
  border-radius: var(--radius); box-shadow: 0 2px 10px rgba(11,61,102,.12);
  padding: 10px; white-space: nowrap;
}
.pwreveal .pwform input[type=text] { width: 150px; }


/* =======================================================================
   Audit trail table
   ======================================================================= */

.rjt.audit { table-layout: fixed; }
.rjt.audit col.c-when   { width: 13%; }
.rjt.audit col.c-who    { width: 10%; }
.rjt.audit col.c-what   { width: 12%; }
.rjt.audit col.c-record { width: 20%; }
.rjt.audit col.c-change { width: 45%; }

/* every column centred under its heading, and vertically centred so a
   one-line cell sits level with a multi-line list of changes beside it */
.rjt.audit td, .rjt.audit td.d { text-align: center; vertical-align: middle; padding: 10px 12px; }
/* the list of changes is centred as a block, but its lines stay left-aligned
   with each other so "field: was > now" reads as a straight column */
.rjt.audit .chglist { display: inline-block; text-align: left; max-width: 100%; }
.rjt.audit td.nowrap { white-space: nowrap; }
.rjt.audit tbody tr:hover { background: var(--ground); }

.audit-filter .field { min-width: 210px; }
.audit-filter select { width: 100%; }

/* one row per changed field, arranged as a real two-column list: the
   field name in its own fixed-width column so every label lines up,
   the before-and-after value in the other. A second changed field gets
   a thin rule above it rather than just relying on a margin, so several
   changes on one entry read as a small table, not a run-on paragraph. */
.rjt.audit .chg {
  display: grid; grid-template-columns: 122px 1fr; align-items: baseline;
  column-gap: 10px; font-size: 12.5px; padding: 5px 0;
}
.rjt.audit .chg + .chg { border-top: 1px dashed var(--rule); }
.rjt.audit .fname {
  color: var(--ink); font-weight: 600;
}
.rjt.audit .fname::after { content: ":"; }
.rjt.audit .chgval {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; min-width: 0;
}
.rjt.audit .was {
  color: var(--steel); text-decoration: line-through;
}
.rjt.audit .now {
  font-weight: 600; color: var(--calc);
  background: var(--calc-bg); border: 1px solid var(--calc-br);
  border-radius: var(--radius); padding: 1px 7px;
}
.rjt.audit .chg .ico { color: var(--steel); flex: none; }
.rjt.audit .chgnote {
  margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--rule);
  font-size: 12px; color: var(--steel);
}

/* User Account, Add Worker and Audit Trail become one card per row on a
   phone, the same treatment Particulars and Oil Transfer already get.
   Without this the desktop <colgroup>'s percentage widths (Username 13%,
   Role 14%, Change 45%, and so on) squeeze every column into an
   unreadable, overlapping sliver instead of actually stacking. */
@media (max-width: 860px) {
  .rjt.people, .rjt.audit { table-layout: auto; min-width: 0; }
  .rjt.people colgroup, .rjt.people col,
  .rjt.audit colgroup, .rjt.audit col { display: none; }
  .rjt.people table, .rjt.people thead, .rjt.people tbody, .rjt.people tr,
  .rjt.people th, .rjt.people td,
  .rjt.audit table, .rjt.audit thead, .rjt.audit tbody, .rjt.audit tr,
  .rjt.audit th, .rjt.audit td {
    display: block; width: 100% !important; max-width: none !important;
  }
  .rjt.people thead tr, .rjt.audit thead tr { display: none; }
  .rjt.people tbody tr, .rjt.audit tbody tr {
    border: 1px solid var(--rule); border-radius: var(--radius);
    margin-bottom: 10px; padding: 4px 12px; background: var(--paper);
  }
  .rjt.people tbody tr:hover, .rjt.audit tbody tr:hover { background: var(--paper); }

  .rjt.people td, .rjt.audit td {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--rule);
    text-align: right; min-width: 0;
  }
  .rjt.people td:last-child, .rjt.audit td:last-child { border-bottom: 0; }
  .rjt.people td[data-label]::before, .rjt.audit td[data-label]::before {
    content: attr(data-label); font-size: 12.5px; font-weight: 600;
    color: var(--steel); text-align: left; flex: none;
  }

  /* the username, and the actor on an audit entry, are each card's own
     heading - not a label:value row like everything else on it */
  .rjt.people td.unamecol, .rjt.audit td.whocell {
    display: block; text-align: left;
    font-weight: 700; font-size: 14.5px; color: var(--ink);
    border-bottom: 1px solid var(--rule); padding-bottom: 10px;
  }

  /* Role's <select> and the row of action buttons need the card's full
     width to actually be usable - squeezed into the right half of a
     space-between row, a dropdown or three stacked buttons had nowhere
     to go but overlap the label beside them */
  .rjt.people td.rolecell, .rjt.people td.actcell {
    display: block; text-align: left;
  }
  .rjt.people td.rolecell form { width: 100%; }
  .rjt.people select { max-width: none; }
  .rjt.people .rowacts { justify-content: flex-start; margin: 8px 0 0; }
  .rjt.people .rowacts .btn.small { padding-left: 9px; padding-right: 9px; }
  .rjt.people .pwreveal .pwform {
    position: static; transform: none; margin-top: 8px; white-space: normal;
  }

  /* the list of changed fields is its own block under the label, the same
     as any other multi-line value on a phone - squeezed into the right
     half of a flex row it wrapped into an unreadable tangle */
  .rjt.audit td.changecell { display: block; text-align: left; }
  .rjt.audit td.changecell::before { display: block; margin-bottom: 6px; }
  .rjt.audit .chglist { display: block; }
}

/* the tank table is wider than the panel by design (two shifts, eleven
   columns) - this fades the right edge so it is visible there is more to
   scroll to, and removes itself once you have actually scrolled there */
.tablescroll { position: relative; }
.tablescroll::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 28px;
  background: linear-gradient(90deg, transparent, rgba(237,240,243,.85));
  pointer-events: none; opacity: 1; transition: opacity .15s;
}
.tablescroll.at-end::after { opacity: 0; }


/* =======================================================================
   Reject grid
   ======================================================================= */

.rjt.reject { table-layout: fixed; min-width: 480px; }
.rjt.reject col.rj-d   { width: 22%; }
.rjt.reject col.rj-n   { width: 26%; }
.rjt.reject td { text-align: center; }
.rjt.reject tbody tr:hover { background: var(--ground); }
.rjt.reject input { text-align: center; }

/* the browser's up/down spinner arrows sit inside the input's own box, on
   the right, and text-align:center then centers the digit within the
   space that is LEFT after the arrows - not within the box itself. Next
   to the plain total boxes, which have no arrows and stay genuinely
   centered, that made the two look mismatched. A worker types a reject
   count directly; nobody needs the tiny arrows for it. */
.rjt input[type=number]::-webkit-inner-spin-button,
.rjt input[type=number]::-webkit-outer-spin-button {
  -webkit-appearance: none; margin: 0;
}
.rjt input[type=number] { -moz-appearance: textfield; }

/* weight check nozzles: a touch more room and a visible hover, so a
   fifty-nozzle grid still reads as individually tappable cells */
.nozz { transition: border-color .1s; }
.nozz:hover { border-color: var(--blue); }
.nozz .n { font-weight: 600; color: var(--ink); }

/* same reasoning as the reject grid above - a nozzle weight is typed, not
   nudged with tiny arrows, and without this the digit centers within the
   space left over after the arrows rather than in the cell itself. Scoped
   to the record form as a whole so every plain number field on it (tare
   weight, stoppage minutes, carton counts, and the nozzle inputs) centers
   and looks the same way. */
#recordform input[type=number]::-webkit-inner-spin-button,
#recordform input[type=number]::-webkit-outer-spin-button {
  -webkit-appearance: none; margin: 0;
}
#recordform input[type=number] { -moz-appearance: textfield; }

.searchbox {
  display: flex; align-items: center; gap: 8px; margin: 10px 0 4px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 8px 12px; color: var(--steel);
}
.searchbox input {
  border: 0; outline: none; flex: 1; font-family: inherit;
  font-size: 13.5px; background: transparent; padding: 0;
}
.searchbox .ico { flex: none; }
.searchbox #searchcount { font-size: 12px; white-space: nowrap; }

/* the detail header meta line: several small labeled facts instead of one
   run-on sentence, and production/entry dates named separately so the two
   are never mistaken for each other again */
.metarow {
  display: flex; flex-wrap: wrap; gap: 18px; margin-top: 8px;
}
.metaitem {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  text-align: center;
}
/* the label ("PRODUCED", "TIME ENTERED") is one short word or two - it
   should never wrap onto a second line under itself */
.metaitem .mk { font-size: 11px; color: var(--steel); text-transform: uppercase; letter-spacing: .3px; white-space: nowrap; }
.metaitem .mv { font-size: 13.5px; font-weight: 600; }

/* on a phone, five facts side by side (or even two per row) never has
   quite enough room to also read as neatly organized - something is
   always either cramped or landing in a spot that does not line up with
   what is above it. A plain, full-width list - one fact per row, label
   on the left, value on the right, a hairline between rows - is the same
   pattern this very page already uses for "Details" below, so a phone
   gets one consistent, properly arranged way of reading a fact list
   instead of two different ones. */
@media (max-width: 860px) {
  .metarow { display: flex; flex-direction: column; gap: 0; margin-top: 10px; }
  .metaitem {
    flex-direction: row; align-items: baseline; justify-content: space-between;
    text-align: left; gap: 14px;
    padding: 9px 0; border-bottom: 1px solid var(--rule);
  }
  .metaitem:last-child { border-bottom: 0; }
  .metaitem .mk { flex: none; }
  .metaitem .mv { text-align: right; }
}

/* a proper header over the record list, so "428.93 kg" and "12,998 pcs"
   read as labeled columns instead of unexplained numbers. Same padding
   and column widths as the rows themselves, so the two line up exactly. */
.rechead {
  display: flex; align-items: center; gap: 14px; padding: 9px 14px;
  background: var(--navy); color: #fff; font-size: 12px; font-weight: 600;
  border-radius: var(--radius) var(--radius) 0 0;
}
.rechead .id { min-width: 140px; }
.rechead .mid { flex: 1; }
.rechead .val { text-align: right; white-space: nowrap; }
.reclist { border-top: 0; }

/* a row nobody has entered Incoming for yet, kept visually distinct from
   a genuine zero so the two are never confused */
.rcell.pending { color: var(--steel); background: var(--ground); border-color: var(--rule); }
.diff.pending {
  display: inline-block; font-size: 12px; font-weight: 600; color: var(--steel);
  background: var(--ground); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 4px 10px;
}

/* the moment a nozzle reading was actually saved, not when it happened to
   be typed - shown once a record has been through a real save */
.nozz .stamp {
  display: block; text-align: center; font-size: 10px; color: var(--steel);
  margin-top: 2px;
}

/* facts about a lock - who, when, why - as clearly labeled rows instead
   of one run-on sentence mashing a name, a date and a reason together */
.lockfacts { margin: 8px 0; display: flex; flex-direction: column; gap: 4px; }
.factrow { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.factrow .fk {
  font-size: 11px; font-weight: 600; color: var(--steel);
  text-transform: uppercase; letter-spacing: .3px; min-width: 72px;
}
.factrow .fv { font-size: 12.5px; }
.factrow .fv.reason { font-style: italic; color: var(--ink); }

/* =======================================================================
   Reject grid on a real phone: the classic responsive-table reflow.
   Same table, same inputs, same JS - CSS alone turns each row into its
   own labeled card instead of a table a worker has to scroll sideways
   to read on a small screen.
   ======================================================================= */

@media (max-width: 480px) {
  .rjt.reject { min-width: 0; }
  /* the desktop <colgroup> still has a say in column sizing even once
     the table itself is told to stop behaving like a table - a browser
     quirk that squeezed every cell into ~30px no matter what the rest of
     this block said. Taking the columns out of the picture entirely is
     what actually fixes it, not just re-stating display:block louder. */
  .rjt.reject colgroup, .rjt.reject col,
  .rjt.subs colgroup, .rjt.subs col { display: none; }
  .rjt.reject table, .rjt.subs table,
  .rjt.reject thead, .rjt.subs thead,
  .rjt.reject tbody, .rjt.subs tbody,
  .rjt.reject tfoot, .rjt.subs tfoot,
  .rjt.reject tr, .rjt.subs tr,
  .rjt.reject th, .rjt.subs th,
  .rjt.reject td, .rjt.subs td {
    display: block; width: auto !important; max-width: none !important;
  }
  .rjt.reject thead tr, .rjt.subs thead tr { display: none; }
  .rjt.reject tbody tr, .rjt.reject tfoot tr,
  .rjt.subs tbody tr {
    border: 1px solid var(--rule); border-radius: var(--radius);
    margin-bottom: 10px; padding: 4px 12px;
  }
  .rjt.reject tbody tr:hover, .rjt.subs tbody tr:hover { background: none; }
  .rjt.reject td, .rjt.subs td {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--rule);
  }
  .rjt.reject td:last-child, .rjt.subs td:last-child { border-bottom: 0; }
  .rjt.reject td.d, .rjt.subs td.d {
    font-weight: 700; font-size: 14.5px; color: var(--ink);
    border-bottom: 1px solid var(--rule); padding-bottom: 10px;
  }

  /* the automated total box is a flex child here too, same as the input
     beside it in every other row - it needs the same width and the same
     centered text explicitly, because neither is guaranteed to carry over
     from the desktop rules once this becomes a flex row instead of a
     table cell */
  .rjt.reject .rcell, .rjt.reject .rowtot,
  .rjt.reject .coltot, .rjt.reject .grand {
    width: 96px; text-align: center;
  }

  /* on the desktop table, a single thin gray stripe marks the totals row.
     Here each cell is its own full-width block, so that same fill applied
     to five stacked cells turned into one solid gray card - heavier than
     every other card on the page, not a subtle highlight. The bold
     "Total" label and the same green value boxes every other card already
     uses are enough to mark this one as the summary; the card itself
     stays plain white like the rest. */
  .rjt.reject tfoot td { background: none; }
  .rjt.reject td[data-label]::before, .rjt.subs td[data-label]::before {
    content: attr(data-label); font-size: 12.5px; font-weight: 600;
    color: var(--steel); text-align: left;
  }
  .rjt.reject input { width: 96px; }
}

/* stays one row on a phone - smaller logo, smaller text, tighter gaps,
   and nowrap so it genuinely fits instead of wrapping mid-word */
@media (max-width: 480px) {
  .masthead { gap: 8px; padding: 16px 12px 4px; flex-wrap: nowrap; }
  .masthead img { height: 22px; flex: none; }
  .mh-text { gap: 5px; white-space: nowrap; }
  .mh-text strong { font-size: 12.5px; letter-spacing: 0; white-space: nowrap; }
  .mh-text span { font-size: 10.5px; white-space: nowrap; }
}

/* plain, calm text instead of tight all-caps micro-labels crammed against
   their values - a little more size and letter spacing so it reads at a
   glance rather than feeling dense */
.mc-sub { font-size: 12.5px; color: var(--steel); line-height: 1.6; }

/* =======================================================================
   Department and Form selection - the landing screens after sign-in
   ======================================================================= */

.deptgrid, .formgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px; margin-top: 18px;
}
.deptcard, .formcard {
  display: flex; flex-direction: column; gap: 6px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper); padding: 16px 18px; text-decoration: none;
  transition: border-color .1s;
}
a.deptcard:hover, a.formcard:hover { border-color: var(--blue); }
.dc-name, .fc-name { font-size: 15px; font-weight: 700; color: var(--ink); }
.dc-desc, .fc-desc { font-size: 12.5px; color: var(--steel); line-height: 1.5; }
.dc-go, .fc-go {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 6px;
  font-size: 12.5px; font-weight: 600; color: var(--blue);
}
.deptcard.disabled, .formcard.disabled {
  background: var(--ground); cursor: default;
}
.deptcard.disabled .dc-name, .formcard.disabled .fc-name { color: var(--steel); }
.dc-soon, .fc-soon {
  display: inline-flex; align-self: flex-start; margin-top: 6px;
  font-size: 11px; font-weight: 600; color: var(--steel);
  border: 1px solid var(--rule); border-radius: 20px; padding: 3px 10px;
}

/* the appbar's own way back out to Department Selection, grouped with
   Sign Out on the right as a proper action rather than bare text
   squeezed between the user chip and the role badge, which wrapped
   awkwardly on a phone and read as an afterthought rather than a real
   button */
.appbar-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.homelink {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font-size: 12.5px; font-weight: 600; color: #fff;
  border: 1px solid rgba(255,255,255,.35); border-radius: var(--radius);
  padding: 7px 12px; text-decoration: none; transition: border-color .1s;
}
.homelink:hover { border-color: #fff; }

/* icon-only on a phone - both buttons have to share very little space
   next to the user chip, and shrinking the label rather than letting
   either button wrap or spill off the edge is the reliable fix */
@media (max-width: 480px) {
  .homelink { padding: 7px 9px; gap: 0; }
  .homelink .label { display: none; }
}

/* =======================================================================
   My Submissions / All Submissions / Review Exceptions - the .rjt.subs
   tables were quietly inheriting the reject grid's base rules (Date
   left-aligned via td.d, everything else right-aligned), so the header
   row looked centered but no data cell actually was. Centered here
   explicitly, with real row separation and breathing room instead of
   barely-visible borders and default spacing.
   ======================================================================= */
.rjt.subs td.d, .rjt.subs td { text-align: center; }
.rjt.subs td { padding: 11px 14px; font-size: 13px; }
.rjt.subs td.d { font-weight: 600; color: var(--ink); }
.rjt.subs tbody tr:nth-child(even) { background: var(--ground); }
.rjt.subs tbody tr:hover { background: var(--blue-tint); }
.rjt.subs thead th.act { width: 90px; }
.rjt.subs .badge { font-size: 11.5px; }
.rjt.subs .empty-row td {
  padding: 30px 14px; color: var(--steel); font-size: 13px;
  background: var(--paper);
}
/* one look for every "nothing here" row - grey, centred, same size - on the
   Internal Control and Variance Reconciliation tables as on the rest */
.rjt.ic .empty-row td, .rjt.pt .empty-row td, .rjt.xfer .empty-row td {
  padding: 30px 14px; color: var(--steel); font-size: 13px; font-weight: 400;
  text-align: center; white-space: normal; background: var(--paper);
}
/* Form used to carry its own identifying detail crammed into the same
   string ("Filling Record, SC12345"), which read as one long run-on
   value. Splitting it - the form's own name in bold, the batch/shift/
   product that made this row distinct underneath - is the same
   bold-plus-subtitle pairing .reclist already uses for a Sales Contract
   and its tank/machine. */
.rjt.subs .formcell b { display: block; font-weight: 600; }
.rjt.subs .formcell .sub { font-size: 12px; color: var(--steel); }

/* Round heading + its average/status badge, side by side on the detail
   page - a concise stand-in for the live per-nozzle math the entry form
   shows while a worker is actively typing, which is too much detail for
   someone glancing back over an already-saved record. */
.wcheadrow {
  display: flex; align-items: center; gap: 10px; margin-bottom: 6px;
}
.wcheadrow .sec { margin: 0; }

/* each extra round (2, 3, 4) otherwise sat flush against the table above
   it, with no gap and no visual break between one round and the next -
   a clear top border plus real breathing room marks where a new round
   starts, every time one is added */
.scroller + .wcheadrow { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--rule); }

/* rows on My Submissions, All Submissions and Review Exceptions are
   clickable anywhere - the whole row leads to that submission, not just
   a small button off to the side */
.rjt.subs tr.rowlink { cursor: pointer; }

/* "+ Add Others" under the reject table - its own class, not .addround,
   because the Weight Check script hides and wires up every .addround */
.addother { display: block; margin: 10px 0 0; }
.addother[hidden] { display: none; }
/* on a phone every reject row is display:block, which would otherwise
   override the hidden attribute and show all the empty Others rows */
.rjt.reject tr.otherrow[hidden] { display: none !important; }
.rjt.reject .othername { width: 100%; text-align: left; }
/* the defect name box with its remove (x) button beside it */
.otherwrap { display: flex; align-items: center; gap: 6px; width: 100%; }
.otherwrap .othername { flex: 1; min-width: 0; }
.otherdel {
  flex: none; width: 30px; height: 30px; padding: 0; cursor: pointer;
  font-size: 18px; line-height: 1; color: var(--stop);
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius);
}
.otherdel:hover { border-color: var(--stop); background: var(--stop-bg); }
/* the Able/Supplier/Carton count boxes on an "+ Add Others" row - centred
   and aligned the same as every other reject row's count boxes, not just
   inheriting whatever width the defect-name flex row next to them implies.
   Desktop only (table layout) - on a phone the row is already a flex card
   (see the max-width:480px block below), and this same margin:auto would
   be read as a flex auto-margin there, pulling the box away from the
   right edge that every other card's box sits flush against. */
@media (min-width: 481px) {
  .rjt.reject tr.otherrow td:not(.d) input[type="number"] {
    display: block; margin: 0 auto; text-align: center;
  }
}

/* =====================================================================
   Daily Bulk Oil Status - one reading a day
   ===================================================================== */
/* Opening Balance over its three columns, Closing Balance over its four -
   each band the same width as the columns underneath it */
.c-prod { width: 220px; }
.tbl.shifts { min-width: 1254px; table-layout: fixed; }
.tablewrap { min-width: 1254px; }
.prog, .shiftband { display: flex; }
.prog .sp, .shiftband .sp { flex: 166 0 0; }
.prog .pcell, .shiftband .bcell { flex: 472 0 0; }
.prog .pcell.closing, .shiftband .bcell.closing { flex: 616 0 0; }
.prog { margin-bottom: 12px; }
.prog .pcell:not(.closing) { padding-right: 12px; }
.shiftband { font-size: 12px; font-weight: 600; }
.shiftband .sb-opening, .shiftband .sb-closing {
  padding: 7px 0; text-align: center;
  border: 1px solid var(--rule); border-bottom: 0;
}
.shiftband .sb-opening { background: #FFE7B4; }
.shiftband .sb-closing { background: #BFD8FA; }
.tbl.shifts tbody td:nth-child(3),
.tbl.shifts tbody td:nth-child(4),
.tbl.shifts tbody td:nth-child(5) { background: rgba(255,238,199,.45); }
.tbl.shifts tbody td:nth-child(6),
.tbl.shifts tbody td:nth-child(7),
.tbl.shifts tbody td:nth-child(8),
.tbl.shifts tbody td:nth-child(9) { background: rgba(198,220,250,.42); }
.tbl.shifts .qcell { width: 100%; }
.progbox.mprog { margin: 12px 0 0; }
.mc-close .diff { font-size: 11.5px; padding: 1px 6px; min-width: 0; height: auto; display: inline-block; }
.lockbar.daylock .lockcell { flex: 0 1 520px; }
/* each box is only as tall as its own contents - the Sunday Off Day box
   used to stretch to match the Bulk Oil Status box beside it, which grows
   with every submit / confirm / reopen line added to its history */
.lockbar.daylock { align-items: flex-start; }
.lockbar.daylock .lockcell > .btn { align-self: flex-start; }
/* the day-status bar at the top of Daily Bulk Oil Status sits straight
   above the tank table's progress box - give it the same breathing room
   the stat row gets under Daily Filling Record's bar */
.lockbar.topbar { margin-bottom: 16px; }
/* the Sunday Off Day box sits at the far right, under the date picker */
.lockbar.topbar .offcell { margin-left: auto; }
@media (max-width: 860px) { .lockbar.topbar { margin-bottom: 0; } }

/* Oil Transfer */
.rjt.xfer td { text-align: center; vertical-align: middle; padding: 10px 12px; }
.rjt.xfer td.act, .rjt.xfer th.act { width: 100px; }
.rjt.xfer .empty-row td { padding: 24px 12px; color: var(--steel); }

/* one row of the Oil Transfer form: From/To/Quantity/Remark, then the
   Product and Additives it moved. "+ Add Oil Transfer" reveals another of
   these, same idiom as "+ Add Round" under Weight Check. */
.xferrow { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--rule); }
.xferrow:first-of-type { border-top: 0; }
.xrhead { font-size: 12.5px; font-weight: 600; margin-bottom: 7px; }
.xferform {
  display: grid; grid-template-columns: 1fr 1fr 1fr 2fr;
  gap: 12px; align-items: end;
}
.xferform .field { margin: 0; }
.xferrow .qfield { margin-top: 12px; margin-bottom: 0; }
.addxfer { display: block; margin: 16px 0 0; }
.addxfer[hidden] { display: none; }
.xfersubmit { margin-top: 20px; }
/* Oil Transfer: room between the list, the form and the box edges */
.xferbox { padding: 18px 20px 22px; }
.xferwrap { margin-top: 24px; }
.xferform { gap: 16px 18px; }
.xferform .field .lbl { display: block; margin-bottom: 8px; }
.rjt.xfer th { padding: 11px 14px; }

@media (max-width: 860px) {
  .lockbar.daylock .lockcell { flex: 1 1 auto; }
  .lockbar.daylock .btn { width: 100%; }
  .lockbar.daylock form { flex-wrap: wrap; }
  .lockbar.daylock form input { flex: 1 1 100%; }


  .xferform { grid-template-columns: 1fr 1fr; }
  .xferform .field:nth-child(4) { grid-column: 1 / -1; }

  /* Particulars and Oil Transfer become one card per row on a phone */
  .rjt.pt, .rjt.xfer { table-layout: auto; min-width: 0; }
  .rjt.pt.pt-full { min-width: 0; }
  .rjt.pt.pt-full .rem { min-width: 0; }
  .pctwrap { width: auto; min-width: 132px; }
  .rjt.ic thead { display: none; }
  .rjt.ic, .rjt.ic tbody, .rjt.ic tr, .rjt.ic td { display: block; width: 100%; }
  .rjt.ic tbody tr { border: 1px solid var(--rule); border-radius: var(--radius);
                     margin-bottom: 10px; background: var(--paper); }
  .rjt.ic td { display: flex; justify-content: space-between; align-items: center;
               gap: 10px; text-align: right; border: 0; border-bottom: 1px solid var(--rule);
               padding: 8px 12px; }
  .rjt.ic td:last-child { border-bottom: 0; }
  .rjt.ic td[data-label]::before { content: attr(data-label); font-size: 12px;
               color: var(--steel); text-align: left; flex: none; }
  .rjt.ic td.txt { flex-direction: column; align-items: stretch; text-align: left; min-width: 0; }
  .icclose { min-width: 0; width: 100%; }
  .rjt.ic .empty-row td { justify-content: center; }
  .rjt.pt colgroup, .rjt.pt thead, .rjt.xfer thead { display: none; }
  .rjt.pt, .rjt.pt tbody, .rjt.pt tr, .rjt.pt td,
  .rjt.xfer, .rjt.xfer tbody, .rjt.xfer tr, .rjt.xfer td { display: block; width: 100%; }
  .rjt.pt tbody tr, .rjt.xfer tbody tr {
    border: 1px solid var(--rule); border-radius: var(--radius);
    margin-bottom: 10px; padding: 4px 12px; background: var(--paper);
  }
  .rjt.pt tbody tr:hover, .rjt.xfer tbody tr:hover { background: var(--paper); }
  .rjt.pt td, .rjt.xfer td {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--rule);
    text-align: right; min-width: 0;
  }
  .rjt.pt td:last-child, .rjt.xfer td:last-child { border-bottom: 0; }
  .rjt.pt td[data-label]::before, .rjt.xfer td[data-label]::before {
    content: attr(data-label); font-size: 12.5px; font-weight: 600;
    color: var(--steel); text-align: left;
  }
  .rjt.pt td.d {
    justify-content: flex-start; padding-bottom: 10px; min-width: 0;
  }
  .ptprod { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px; }
  /* the remark is what explains a variance, so it gets its own full-width
     line under the label instead of being squeezed into the right-hand
     half of the row like a plain figure */
  .rjt.pt td.rem { min-width: 0; flex-direction: column; align-items: stretch; gap: 4px; }
  .rjt.pt td.rem::before { text-align: left; }
  .rjt.pt td.rem input, .rjt.pt td.rem textarea { width: 100%; text-align: left; }
  .rjt.pt td.act, .rjt.xfer td.act { justify-content: flex-end; }
  .rjt.pt td.act:empty { display: none; }
  .rjt.pt tr.pt-saved.editing .pt-edit-input { display: inline-block; }
  .rjt.pt input[type=number] { width: 120px; }
  .rjt.pt .empty-row td, .rjt.xfer .empty-row td { justify-content: center; }
  .ptfoot { flex-direction: column; align-items: stretch; }
  .xfersubmit { width: 100%; }
  .ptfoot .btn { width: 100%; }
}
/* a value the viewer can see but not change stays visible while editing */
.pt-static { font-weight: 600; color: var(--ink); }
td.rem .pt-static { font-weight: 400; color: var(--steel); }

/* header on a phone: the role badge and the buttons never wrap onto two
   lines - "Weighbridge Worker" is the longest role, and a long username
   shortens with "..." instead of pushing everything else over */
.userchip .urole, .userchip .uname, .signout button { white-space: nowrap; }
@media (max-width: 480px) {
  .userchip { min-width: 0; flex: 1 1 auto; gap: 8px; }
  .userchip .uname { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .userchip .urole { font-size: 10px; padding: 2px 6px; flex: none; }
  .signout button { padding: 7px 10px; }
  .appbar-actions { gap: 6px; flex: none; }
}

/* the 7-day chart on a phone: seven bars share the width instead of each
   value label pushing its bar - and the whole page - wider than the screen */
@media (max-width: 480px) {
  .weekchart { gap: 4px; }
  .wval, .wday { font-size: 9.5px; white-space: nowrap; }
}

/* Delete on each Daily Filling Record row - Supervisor and Admin only.
   Its own fixed-width column, divided from the row the way Sales Contract
   is, so the header, every button and the hover highlight line up */
.reclist li { display: flex; align-items: stretch; }
/* the Sales Contract search hides a non-matching row by setting its
   [hidden] attribute - display:flex above overrides the browser's own
   [hidden]{display:none} default, so every row kept showing regardless
   of what was typed. Same gotcha as the reject grid's otherrow. */
.reclist li[hidden] { display: none !important; }
.reclist li:hover { background: var(--ground); }
.reclist li > a { flex: 1; min-width: 0; }
.reclist li > a:hover { background: transparent; }
.reclist .recact {
  flex: 0 0 340px; margin: 0; padding: 0 14px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  border-left: 1px solid var(--rule);
}
/* the same Download PDF / Edit / Delete buttons the record's own page uses */
.reclist .recact { gap: 10px; }
/* .reclist a is the whole-row link and pads itself - the buttons keep the
   padding every other .btn has */
.reclist .recact a.btn { padding: 8px 16px; gap: 7px; }
.reclist .recact .btn { white-space: nowrap; height: 36px; box-sizing: border-box; }
.reclist .recdelform { display: contents; }
.rechead .del { flex: 0 0 340px; margin: 0 -14px 0 0; padding: 0 14px; text-align: center; }
.dtactions form.inline { display: contents; }
/* Possible Duplicate on the filling record form */
.dupcheck { border-color: var(--stop); }
.dupcheck label.check { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-weight: 600; cursor: pointer; }
.dupcheck label.check input { width: 18px; height: 18px; margin: 0; }
/* desktop: every column has a fixed, compact width and the header shares the
   same widths, so the list reads as one tidy table starting at the left with
   no empty stretch in the middle. Packaging, Size, Brand and the run time get
   their own columns here; on a phone they stay folded into the Product line. */
.reclist .sz, .reclist .tm, .reclist .br, .rechead .sz, .rechead .tm, .rechead .br { display: none; }
@media (min-width: 861px) {
  .reclist .id, .rechead .id { flex: 0 0 170px; }
  .reclist .mid, .rechead .mid { flex: 0 0 210px; }
  .reclist .mid .det { display: none; }
  .reclist .sz, .rechead .sz { display: block; flex: 0 0 150px; }
  .reclist .br, .rechead .br { display: block; flex: 0 0 140px; }
  .reclist .br b { display: block; font-weight: 600; overflow-wrap: anywhere; }
  .reclist .tm, .rechead .tm { display: block; flex: 0 0 120px; }
  .reclist .sz b, .reclist .tm b { display: block; font-weight: 600; }
  .reclist .sz span, .reclist .tm span { display: block; font-size: 12px; color: var(--steel); margin-top: 2px; }
  .reclist .val, .rechead .val { flex: 0 0 140px; text-align: left; }
  .rechead { gap: 16px; justify-content: flex-start; }
  .rechead .val { margin-right: -2px; }
  .reclist li > a { flex: 0 0 auto; gap: 16px; }
  .reclist .id { padding-right: 14px; }
}
@media (max-width: 860px) {
  .reclist li { flex-wrap: wrap; }
  .reclist li > a { flex: 1 1 100%; }
  .reclist .recact { flex: 1 1 100%; border-left: 0; padding: 0 14px 12px; }
  .reclist .recact .btn { padding: 8px 12px; }
  .rechead .del { display: none; }
}

/* Contract & FCL: the two figure boxes in each row */
.rjt.subs.fcl input.fclin { width: 130px; max-width: 100%; text-align: right; }

/* Submit / confirm / reopen history in the shift and filling-day boxes:
   one line per event - the same coloured tag the Submissions tabs use
   (Submitted blue, Confirmed green, Reopened amber), then who, when and
   the reason on the same line */
.lockhist {
  list-style: none; margin: 8px 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px; font-size: 12.5px;
}
.lockhist li { display: flex; align-items: flex-start; gap: 14px; }
.lockhist .badge { flex: none; min-width: 78px; text-align: center; white-space: nowrap; }
.lockhist .ht { flex: 1 1 0; min-width: 0; overflow-wrap: anywhere; padding-top: 1px; }
.lockhist .hr { font-style: italic; }
.lockhist li.pend .badge { min-width: 78px; }
.lockhist li.pend .ht { color: var(--steel); }


/* Oil Per Unit: the green calculated box, with a button to type over it */
.oilrow { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.oilrow .box, .oilrow input { flex: 1 1 120px; min-width: 120px; margin: 0; }
.oilrow [hidden] { display: none !important; }
.oilrow .btn { flex: none; white-space: nowrap; min-width: 138px; padding: 9px 18px; text-align: center; }

/* Bulk Oil Status / Filling Records For This Day boxes (desktop): a header
   strip with the title on the left and its state on the right, the history
   under it, and the action row at the bottom - the same shape in every box */
@media (min-width: 861px) {
  .lockbar.daylock .lockcell { flex: 0 1 520px; padding: 0; overflow: hidden; }
  .lockbar.daylock .lockstate {
    flex-wrap: nowrap; justify-content: space-between; gap: 12px; margin: 0;
    padding: 11px 16px; background: var(--ground); border-bottom: 1px solid var(--rule);
  }
  .lockbar.daylock .lockcell > :not(.lockstate) { margin: 12px 16px 0; }
  .lockbar.daylock .lockcell > :last-child { margin-bottom: 16px; }
  .lockbar.daylock .lockcell > form { margin-top: 14px; }
  .lockbar.daylock .lockcell > form input { height: 36px; }
  .lockbar.daylock .lockcell > form .btn { flex: none; min-width: 120px; height: 36px; }
  .lockbar.daylock .lockcell > .btn { align-self: flex-start; min-width: 160px; margin-top: 14px; }
}

}

/* a .box sets its own display, which beats the hidden attribute */
.box[hidden] { display: none !important; }

/* Blending Records worked out for VEG.GHEE - same green as other figures
   the system calculates */
input.autoin { background: var(--calc-bg); border-color: var(--calc-br); color: var(--calc); font-weight: 600; }

/* Audit Trail filters, search and paging */
.audit-filter { align-items: flex-end; flex-wrap: wrap; }
.audit-filter .field { min-width: 170px; }
.auditsearch { flex: 1 1 100%; margin-top: 2px; }
.auditsearch .searchrow { display: flex; gap: 8px; align-items: center; }
.auditsearch input[type=text] { flex: 1; min-width: 0; }
.auditsearch .btn { flex: none; white-space: nowrap; height: 35px; }
.auditsearch input[type=text] { height: 35px; }
.auditbar { display: flex; align-items: center; justify-content: space-between;
            gap: 12px; flex-wrap: wrap; margin: 4px 0 12px; }
.auditinfo { margin: 0; font-size: 12.5px; color: var(--steel); line-height: 1.5; }
.auditinfo b { color: var(--ink); }
.auditpager { display: flex; align-items: center; gap: 10px; }
.auditpager.bottom { justify-content: center; margin-top: 14px; }
.auditpager .pg { font-size: 12.5px; color: var(--steel); white-space: nowrap; }
.auditpager .off { opacity: .45; pointer-events: none; }

/* Packed Volume: the morning / night split under each day, and its note */
.weekchart { height: 170px; }
.wshift { display: flex; flex-direction: column; align-items: center; margin-top: 3px;
          font-size: 10.5px; color: var(--steel); line-height: 1.35; white-space: nowrap; }
.weeknote { margin: 18px 0 0; padding: 14px 18px; font-size: 13.5px; color: var(--steel);
            line-height: 1.7; background: var(--ground); border-radius: var(--radius); }
.weeknote b { color: var(--ink); font-weight: 600; }
@media (max-width: 860px) { .wshift { display: none; } }

/* Reports: Total Packed By Product */
.packedform { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 12px; margin-bottom: 14px; }
.packedform .field { margin-bottom: 0; min-width: 190px; }
.packedform .btn { height: 35px; }
.packedwhen { margin: 0; flex: 1 1 280px; font-size: 12.5px; color: var(--steel); line-height: 1.5; }
.packedwhen b { color: var(--ink); }
.packedtbl td, .packedtbl th { text-align: center; }
.packedtbl .packedsum td { font-weight: 700; background: var(--ground); border-top: 2px solid var(--rule); }

/* Reports dashboard cards - the same cards, with the same class names, as the
   Jerrycan Reports page: label, large figure, a line under it; green when the
   figure is worked out and fine, red when it needs a look */
.jc-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.jc-kpi { background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 12px 14px; min-width: 0; }
.jc-kpi .k { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--steel); }
.jc-kpi .v { display: block; margin-top: 4px; font-size: 22px; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jc-kpi .sub { display: block; margin-top: 2px; font-size: 12px; color: var(--steel); }
.jc-kpi.calc { background: var(--calc-bg); border-color: var(--calc-br); }
.jc-kpi.calc .k, .jc-kpi.calc .v { color: var(--calc); }
.jc-kpi.calc .sub { color: var(--calc); opacity: .85; }
.jc-kpi.warn { background: var(--stop-bg); border-color: var(--stop); }
.jc-kpi.warn .k, .jc-kpi.warn .v, .jc-kpi.warn .sub { color: var(--stop); }
@media (max-width: 860px) {
  .jc-kpis { grid-template-columns: repeat(2, 1fr); }
  .jc-kpi { padding: 10px 12px; }
  .jc-kpi .v { font-size: 18px; }
}
