/* ============================================================================
   FORTHEO 2.0 — visual system
   Built for: riders one-handed in traffic and sunlight, warehouse staff with
   gloves and a scanner, finance reading money at a desk.
   Therefore: high contrast, big targets, tabular figures, colour only where it
   carries meaning (stage status, money state, SLA).
   ========================================================================= */

/* Deliberately no web fonts. A downloaded typeface costs a DNS lookup, a TLS
   handshake and a render-blocking wait on every first view — paid for by a rider
   on cellular data. The system stack is instant and, on the devices actually in
   use here (Android, Windows, iOS), already sets numbers cleanly. */

:root{
  /* Base — deep slate, the colour of equipment, not of a marketing page */
  --ink:        #10151C;   /* text, and the app bar */
  --ink-soft:   #4A5563;
  --ink-faint:  #7A8698;
  --paper:      #FFFFFF;
  --shell:      #EEF1F5;   /* page background */
  --line:       #D5DCE5;
  --line-soft:  #E7ECF2;

  /* Signal — used ONLY for meaning, never decoration */
  --brand:      #026312;   /* the green in the logo, sampled from the artwork */
  --brand-dk:   #01480D;
  --go:         #026312;   /* delivered, verified, available — the brand green */
  --go-bg:      #E4F0E6;
  --wait:       #A96A00;   /* in transit, awaiting, amber SLA */
  --wait-bg:    #FDF1DC;
  --stop:       #B3261E;   /* failed, overdue, mismatch, loss */
  --stop-bg:    #FBE7E5;
  --money:      #1B4D8F;   /* amounts, cash, balances */
  --money-bg:   #E6EEF8;

  --radius: 6px;
  --tap: 48px;             /* minimum touch target */
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  background:var(--shell); color:var(--ink);
  font-size:16px; line-height:1.5;
  -webkit-text-size-adjust:100%;
}
/* Numbers must line up: serials, amounts, counts */
.num,td.num,.amount,.serial{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.serial,.mono{font-family:ui-monospace,'Cascadia Mono','Segoe UI Mono','Roboto Mono',monospace;letter-spacing:-0.01em}

/* ---------- app bar ---------- */
.bar{
  background:var(--ink); color:#fff; position:sticky; top:0; z-index:20;
  display:flex; align-items:center; gap:14px; padding:0 16px; height:56px;
}
.bar a{color:#fff;text-decoration:none}
.bar .mark{
  display:flex; align-items:center; gap:9px;
  font-weight:700; letter-spacing:.06em; font-size:16px;
}
.bar .mark img{display:block; flex:none}
.bar .who{margin-left:auto;font-size:13px;color:#A9B4C4;text-align:right;line-height:1.25}
.bar .who b{display:block;color:#fff;font-weight:600}
.bar .who .out-top{display:none;color:#A9B4C4;margin-left:8px;text-decoration:underline}
@media (max-width:900px){ .bar .who .out-top{display:inline} }   /* no sidebar on a phone, so the sign-out lives in the header */

/* role strip: tells you at a glance whose screen this is */
.rolestrip{height:3px;background:var(--brand)}




/* ---------- brand presence -------------------------------------------------
   The mark appears twice: large and in colour on the sign-in and customer
   pages, where the screen is mostly empty; and very faintly behind the app
   shell, where there is room below the content.

   Deliberately NOT behind tables or forms. This is a tool people read all day,
   and a watermark under a column of figures costs legibility for decoration.
   It sits low and to the right, where the page usually runs out of content. */

body.app{
  background-color:var(--shell);
  background-image:url("/mark-watermark.png");
  background-repeat:no-repeat;
  background-position:right -90px bottom -110px;
  background-size:420px 420px;
  background-attachment:fixed;
}

/* Sign-in and the customer's own pages: a soft green wash and the mark large
   behind it. There is nothing to read here yet, so it can be felt. */
body:not(.app){
  background:
    radial-gradient(900px 520px at 50% -10%, #E9F1EA 0%, rgba(233,241,234,0) 62%),
    linear-gradient(180deg, #FFFFFF 0%, var(--shell) 100%);
  min-height:100vh;
}
.login{position:relative}
.login::before{
  content:""; position:absolute; z-index:-1;
  width:440px; height:440px; left:50%; top:40px;
  transform:translateX(-50%);
  background:url("/mark-gradient.png") no-repeat center/contain;
  opacity:.045; pointer-events:none;
}

/* A thin band of brand colour under the header, so the green is present on
   every screen without being loud about it. */
.rolestrip{
  height:3px;
  background:linear-gradient(90deg, var(--brand) 0%, var(--brand-dk) 46%, var(--brand) 100%);
}

@media (prefers-reduced-motion:reduce){ body.app{background-attachment:scroll} }
@media (max-width:860px){
  /* On a phone the screen is small and the content is the whole point. */
  body.app{background-image:none}
  .login::before{width:300px;height:300px;top:30px}
}

/* ---------- the page ------------------------------------------------------
   Content needs room to breathe beside the menu. The left padding is larger
   than the right because the menu already puts a hard edge on that side —
   without it, a heading sits against the border and the page feels cramped. */

.wrap{
  max-width:1080px; padding:26px 30px 96px 38px;
}
body.app .wrap{ margin-left:var(--nav-w); max-width:930px }
body.app .wrap.narrow{ margin-left:var(--nav-w); max-width:660px }
body.app .wrap.wide{ margin-left:var(--nav-w); max-width:none; margin-right:0 }

h1{font-size:24px;font-weight:600;letter-spacing:-0.02em;margin:0 0 4px;line-height:1.2}
h2{font-size:16px;font-weight:600;margin:30px 0 12px;letter-spacing:-0.01em}
.sub{color:var(--ink-faint);font-size:14px;margin:0 0 22px;line-height:1.5;max-width:70ch}
.page-head{
  display:flex;justify-content:space-between;align-items:flex-start;
  gap:20px;margin-bottom:22px;flex-wrap:wrap;
}
.page-head h1{margin-bottom:2px}
.page-head .sub{margin-bottom:0}

/* ---------- shell -----------------------------------------------------------
   The sidebar width lives in one variable that both the menu and the page read.
   The previous version had the width written in one place and the page margin
   in another; they drifted apart and the content slid underneath the menu.
   Two numbers that must agree should be one number. */

:root{ --nav-w: 206px; }

.bar .crumb{color:#A9B4C4;font-size:14px}

.side{
  position:fixed; top:59px; left:0; bottom:0; width:var(--nav-w);
  overflow-y:auto; background:var(--paper); border-right:1px solid var(--line);
  padding:8px 0 24px; z-index:10;
}

.side a.solo,
.side .grp a{
  display:block; color:var(--ink-soft); text-decoration:none;
  font-size:14.5px; font-weight:500; border-left:3px solid transparent;
}
.side a.solo{padding:11px 18px}
.side .grp a{padding:9px 18px 9px 30px; font-size:14px}
.side a:hover{background:var(--shell); color:var(--ink)}
.side a.on{
  color:var(--ink); background:var(--go-bg);
  border-left-color:var(--brand); font-weight:600;
}

.side .grp{border:0}
.side .grp > summary{
  list-style:none; cursor:pointer; user-select:none;
  padding:12px 18px 7px; font-size:11.5px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-faint);
  display:flex; align-items:center; gap:7px;
}
.side .grp > summary::-webkit-details-marker{display:none}
.side .grp > summary::before{
  content:"\203A"; font-size:15px; line-height:1; color:var(--ink-faint);
  transition:transform .12s ease; display:inline-block;
}
.side .grp[open] > summary::before{transform:rotate(90deg)}
.side .grp > summary:hover{color:var(--ink)}

.side a.out{
  margin-top:18px; padding:14px 18px 0; border-top:1px solid var(--line-soft);
  color:var(--ink-faint); font-size:14px; font-weight:400; display:block;
}
.side a.out:hover{color:var(--ink);background:none}

/* The page always starts where the menu ends, because it is the same number. */
.tabs{display:none}
.menu-btn{display:none}
.nav-scrim{display:none}

@media (max-width:860px){
  :root{ --nav-w: 0px; }
  /* the full menu is a drawer, opened from the ☰ in the header */
  .menu-btn{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;margin-right:8px;background:transparent;border:1px solid rgba(255,255,255,.25);border-radius:8px;color:#fff;font-size:20px;line-height:1;cursor:pointer}
  .side{display:block;width:280px;max-width:85vw;top:0;transform:translateX(-100%);transition:transform .18s ease;z-index:40;box-shadow:0 0 0 rgba(0,0,0,0)}
  body.nav-open .side{transform:none;box-shadow:12px 0 30px rgba(0,0,0,.25)}
  body.nav-open .nav-scrim{display:block;position:fixed;inset:0;background:rgba(10,14,20,.45);z-index:30}
  .side .out{display:block}
  body.app .wrap, body.app .wrap.narrow, body.app .wrap.wide{margin-left:0; max-width:100%}
  body.app{padding-bottom:calc(24px + env(safe-area-inset-bottom))}
  .tabs{
    display:flex; position:fixed; left:0; right:0; bottom:0; z-index:20;
    background:var(--paper); border-top:1px solid var(--line);
    padding-bottom:env(safe-area-inset-bottom);
  }
  .tabs a{
    flex:1; text-align:center; padding:14px 4px 14px; min-height:58px; display:flex; align-items:center; justify-content:center; text-decoration:none;
    color:var(--ink-faint); font-size:14px; font-weight:700; line-height:1.15; -webkit-tap-highlight-color:transparent;
    border-top:3px solid transparent;
  }
  .tabs a.on{color:var(--brand); border-top-color:var(--brand)}
}

/* ---------- dashboard tiles ------------------------------------------------
   One number, one plain sentence saying what it counts. Restored: these were
   lost when the navigation styles were rewritten, which left the dashboard as
   a column of bare links. */

.tiles{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(215px,1fr));
  gap:10px; margin-bottom:8px;
}
.tile{
  background:var(--paper); border:1px solid var(--line); border-radius:var(--radius);
  padding:16px; text-decoration:none; color:inherit; display:block; min-height:94px;
}
.tile:hover{border-color:var(--ink-faint)}
.tile .n{
  font-size:30px; font-weight:600; letter-spacing:-0.03em; line-height:1.05;
  font-variant-numeric:tabular-nums; color:var(--ink);
}
.tile .t{font-size:14px; color:var(--ink-soft); margin-top:6px; line-height:1.35}
.tile .n.go{color:var(--go)}
.tile .n.wait{color:var(--wait)}
.tile .n.stop{color:var(--stop)}

/* ---------- ORDERS AS A WORK BOARD ---------------------------------------
   Not a table of records. An order is always waiting for someone to do
   something, so the screen groups by what it is waiting FOR, names the action
   and its owner, and shows how long it has been waiting. Age is the number that
   matters operationally, so it gets its own column and turns red on its own. */


.queue{margin-bottom:20px;background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.queue.q-warn{border-left:4px solid var(--wait)}

.q-head{
  display:flex;align-items:baseline;gap:12px;padding:12px 16px;
  background:#F7F9FC;border-bottom:1px solid var(--line);flex-wrap:wrap;
}
.q-count{
  font-size:22px;font-weight:700;color:var(--ink);letter-spacing:-0.03em;
  font-variant-numeric:tabular-nums;min-width:26px;
}
.q-title{font-size:16px;font-weight:600;color:var(--ink)}
.q-action{margin-left:auto;font-size:13px;color:var(--ink-faint)}
.q-action b{color:var(--ink-soft);font-weight:600}

/* One order = one row. Flexbox rather than grid: it degrades predictably
   everywhere, including older Android browsers a rider might be on. */
.ord{
  display:flex;align-items:center;gap:14px;
  padding:12px 16px;border-bottom:1px solid var(--line-soft);
  text-decoration:none;color:inherit;
}
.ord:last-child{border-bottom:0}
.ord:hover{background:#F7F9FC}
.ord-no{flex:0 0 112px;font-size:14px;font-weight:600;color:var(--money)}
.ord-cust{flex:1 1 auto;min-width:0;font-size:15px;line-height:1.35}
.ord-where{display:block;font-size:13px;color:var(--ink-faint)}
.ord-amt{flex:0 0 150px;text-align:right;font-size:15px;font-weight:600;line-height:1.35}
.ord-owed{display:block;font-size:13px;font-weight:600;color:var(--stop)}
.ord-age{
  flex:0 0 68px;text-align:right;font-size:13px;color:var(--ink-faint);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
.ord-age.late{color:var(--stop);font-weight:600}

.finished{
  background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);
  overflow:hidden;margin-top:24px;
}
.finished summary{
  padding:13px 16px;cursor:pointer;font-size:14px;color:var(--ink-faint);
  font-weight:500;list-style:none;
}
.finished summary::-webkit-details-marker{display:none}
.finished summary::before{content:"▸ ";color:var(--ink-faint)}
.finished[open] summary::before{content:"▾ "}
.finished summary:hover{background:#F7F9FC;color:var(--ink)}

@media (max-width:640px){
  .ord{flex-wrap:wrap;gap:2px 12px;padding:12px 14px}
  .ord-no{flex:1 1 auto;font-size:13px}
  .ord-age{flex:0 0 auto;order:2}
  .ord-cust{flex:1 1 100%;order:3}
  .ord-amt{flex:1 1 100%;order:4;text-align:left}
  .q-action{margin-left:0;flex:1 1 100%}
}


/* ---------- ERP-style data grid -------------------------------------------
   Dense, scannable, every column always in the same place. Numbers right-
   aligned and tabular so they compare down the column. This is the shape
   people expect from an order register. */
.wrap.wide{max-width:1400px}

/* tab rows stay on one line and slide sideways on a phone — never two ragged rows */
.tabs-row{display:flex;gap:2px;margin-bottom:16px;border-bottom:1px solid var(--line);flex-wrap:nowrap;overflow-x:auto;scrollbar-width:thin;align-items:flex-end}
.tabs-row .tab{white-space:nowrap;flex:0 0 auto}
.tabs-row .tab-more{margin-left:auto;flex:0 0 auto;display:flex;align-items:center;gap:6px;padding:0 0 6px 10px}
.tabs-row .tab-more select{min-height:32px;font-size:13px;padding:0 8px;width:auto}
.tabs-row .tab{
  padding:9px 15px;font-size:14px;font-weight:500;color:var(--ink-faint);
  text-decoration:none;border-bottom:2px solid transparent;margin-bottom:-1px;
}
.tabs-row .tab:hover{color:var(--brand)}
.tabs-row .tab.on{color:var(--brand);border-bottom-color:var(--brand);font-weight:700}

table.grid{width:100%;border-collapse:collapse;font-size:13.5px}
table.grid th{
  text-align:left;font-weight:700;font-size:11.5px;letter-spacing:.03em;
  text-transform:uppercase;color:var(--brand);
  padding:10px 12px;background:var(--go-bg);border-bottom:1px solid var(--line);white-space:nowrap;
}
table.grid th.r,table.grid td.r{text-align:right}
/* cells wrap by default: long text (concerns, reasons, addresses, notes) stays in its
   own column. Numbers, serials, dates and pills keep to one line. */
table.grid td{padding:9px 12px;border-bottom:1px solid var(--line-soft);white-space:normal;overflow-wrap:anywhere;vertical-align:top}
table.grid td.r,table.grid td.num,table.grid td.serial,table.grid td.date,table.grid td.nowrap,
table.grid td .pill,table.grid td .serial,table.grid td .num,table.grid td time,table.grid td form,table.grid td .btn{white-space:nowrap}
table.grid td form{white-space:normal}
table.grid td a.serial{white-space:nowrap}
table.grid td.actions{white-space:nowrap}
table.grid tbody tr:hover{background:#F7F9FC}
table.grid tbody tr:last-child td{border-bottom:0}
table.grid .muted{color:var(--ink-faint)}
table.grid .tick{color:var(--go);font-weight:700}

.aging{font-variant-numeric:tabular-nums;font-weight:600;color:var(--ink-soft)}
.aging.warn{color:var(--wait)}
.aging.over{color:var(--stop)}
.overdue{font-size:11.5px;color:var(--stop);font-weight:600;white-space:nowrap}

/* the grid scrolls sideways on a phone rather than crushing the columns */
@media (max-width:900px){
  /* wide tables scroll sideways inside their panel; the first column stays put
     so the order number is always in view while you swipe */
  .panel{overflow-x:auto;-webkit-overflow-scrolling:touch}
  table.grid{min-width:720px}
  table.grid th:first-child,table.grid td:first-child{position:sticky;left:0;background:var(--paper);z-index:1;box-shadow:2px 0 0 var(--line-soft)}
  table.grid thead th:first-child{background:#EEF4EE}
}

/* ---------- lists / tables ---------- */
.panel{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
table{width:100%;border-collapse:collapse;font-size:14px}
th{
  text-align:left;font-weight:600;font-size:12px;color:var(--ink-faint);
  padding:10px 12px;border-bottom:1px solid var(--line);white-space:nowrap;
}
td{padding:11px 12px;border-bottom:1px solid var(--line-soft);vertical-align:top}
tr:last-child td{border-bottom:0}
tbody tr:hover{background:#F7F9FC}
td a{color:var(--money);font-weight:500;text-decoration:none}
td a:hover{text-decoration:underline}

/* ---------- status pills: the vocabulary of the system ---------- */
.pill{
  display:inline-block;padding:2px 8px;border-radius:100px;font-size:12px;
  font-weight:600;white-space:nowrap;
}
.pill.go{background:var(--go-bg);color:var(--go)}
.pill.wait{background:var(--wait-bg);color:var(--wait)}
.pill.stop{background:var(--stop-bg);color:var(--stop)}
.pill.idle{background:#EDF0F4;color:var(--ink-soft)}
.pill.money{background:var(--money-bg);color:var(--money)}

/* aging: days matter more than words for courier + pickup */
.days{font-variant-numeric:tabular-nums;font-weight:600}
.days.ok{color:var(--ink-soft)} .days.watch{color:var(--wait)} .days.bad{color:var(--stop)}

/* ---------- the rider job card: the most-used screen in the company ---------- */
.job{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);margin-bottom:12px;overflow:hidden}
.job .head{padding:14px 16px;border-bottom:1px solid var(--line-soft)}
.job .cust{font-size:19px;font-weight:600;letter-spacing:-0.01em}
.job .addr{color:var(--ink-soft);font-size:15px;margin-top:3px}
.job .inst{
  margin:12px 16px;padding:11px 13px;background:var(--wait-bg);
  border-left:3px solid var(--wait);border-radius:0 var(--radius) var(--radius) 0;font-size:15px;
}
.job .collect{padding:14px 16px;background:var(--money-bg);border-top:1px solid var(--line-soft)}
.job .collect .lbl{font-size:13px;color:var(--money);font-weight:600}
.job .collect .amt{font-size:30px;font-weight:700;color:var(--money);letter-spacing:-0.02em;font-variant-numeric:tabular-nums}
.job .alt{font-size:14px;color:var(--ink-soft);margin-top:4px}
.job .items{padding:12px 16px;font-size:14px;color:var(--ink-soft)}
.job .acts{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--line-soft)}

/* ---------- forms & buttons ---------- */
label{display:block;font-size:13px;font-weight:600;color:var(--ink-soft);margin:14px 0 5px}
input,select,textarea{
  width:100%;padding:12px;border:1px solid var(--line);border-radius:var(--radius);
  font:inherit;font-size:16px;background:#fff;min-height:var(--tap);
}
input:focus,select:focus,textarea:focus{outline:2px solid var(--money);outline-offset:-1px;border-color:var(--money)}
textarea{min-height:88px;resize:vertical}
/* controls inside a grid cell are compact and never taller than the row needs */
table.grid td input,table.grid td select,table.grid td button.btn{min-height:32px;font-size:13px}
table.grid td input[type=number]{width:110px}
table.grid td input[type=date]{width:150px}
/* a set of actions: every button the same size, in a grid that fills the width */
.actions:not(td):not(th){display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px}
.actions:not(td)>form{display:contents}
.actions:not(td) .btn{width:100%;min-height:44px;display:inline-flex;align-items:center;justify-content:center;text-align:center;padding:0 12px;white-space:normal;line-height:1.2}
.actions .btn[disabled]{opacity:.55}
/* the action cell of a table row stays a plain, narrow cell */
table.grid td.actions,table.grid th.actions{width:1%;white-space:nowrap;text-align:right}
/* the numbers in tables read as numbers */
table.grid td.num,table.grid td.r{font-variant-numeric:tabular-nums}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:var(--tap);padding:0 20px;border-radius:var(--radius);
  font:inherit;font-size:16px;font-weight:600;cursor:pointer;text-decoration:none;
  background:rgba(2,99,18,.10); color:var(--brand);
  border:1px solid rgba(2,99,18,.28);
}
.btn:hover{background:rgba(2,99,18,.16);border-color:rgba(2,99,18,.45)}
.btn.wide{width:100%}
.btn.ghost{background:#fff;color:var(--ink);border-color:var(--line)}
.btn.go{background:rgba(2,99,18,.14);color:var(--brand);border-color:rgba(2,99,18,.35);font-weight:700}
.btn.go:hover{background:rgba(2,99,18,.22)}
.btn.stop{background:var(--stop);color:#fff;border-color:var(--stop)}
.btn.stop:hover{background:#8E1D17;border-color:#8E1D17}
.btn.money{background:rgba(2,99,18,.14);color:var(--brand);border-color:rgba(2,99,18,.35);font-weight:700}
.btn.money:hover{background:var(--brand-dk);border-color:var(--brand-dk)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end}
.row > *{flex:1;min-width:150px}
/* buttons in a row keep their natural width and a single line — they never
   stretch to fill leftover space or wrap their label, so a set of buttons
   reads as one set */
.row > .btn,.row > form:not(.panel){flex:0 0 auto;min-width:0}
.btn{white-space:nowrap;line-height:1.2}
/* every button outside a table is the same height and type size, whatever a
   screen wrote inline; inside a table they are compact, also all alike */
.btn:not(table.grid .btn){min-height:var(--tap) !important;font-size:15px !important;padding-left:18px !important;padding-right:18px !important}
table.grid .btn{min-height:32px !important;font-size:13px !important;padding:0 10px !important}
/* inputs and selects beside a button share its height */
.row > div > input,.row > div > select,.panel > form > div > input,.panel > form > div > select,form.row input,form.row select{min-height:var(--tap)}
/* one button on its own line, or in a phone column, fills the width */
@media (max-width:600px){.row > .btn,.row > form:not(.panel){flex:1 1 100%} .row > form:not(.panel) .btn{width:100%}}

/* ---------- messages ---------- */
.note{padding:12px 14px;border-radius:var(--radius);margin-bottom:16px;font-size:15px}
.note.err{background:var(--stop-bg);color:var(--stop);border-left:3px solid var(--stop)}
.note.ok{background:var(--go-bg);color:var(--go);border-left:3px solid var(--go)}
.note.info{background:var(--money-bg);color:var(--money);border-left:3px solid var(--money)}

/* empty states are an invitation, not an apology */
.empty{padding:44px 20px;text-align:center;color:var(--ink-faint)}
.empty b{display:block;color:var(--ink);font-size:17px;font-weight:600;margin-bottom:5px}

/* ---------- detail rows ---------- */
.kv{display:flex;justify-content:space-between;gap:16px;padding:11px 16px;border-bottom:1px solid var(--line-soft);font-size:15px}
.kv:last-child{border-bottom:0}
.kv .k{color:var(--ink-faint)}
.kv .v{font-weight:500;text-align:right}
.kv .v.big{font-size:19px;font-weight:600;font-variant-numeric:tabular-nums}

/* ---------- timeline (order history, rule 14) ---------- */
.tl{padding:6px 16px 14px}
.tl .ev{display:flex;gap:12px;padding:9px 0;border-bottom:1px solid var(--line-soft);font-size:14px}
.tl .ev:last-child{border-bottom:0}
.tl .when{color:var(--ink-faint);white-space:nowrap;font-variant-numeric:tabular-nums;min-width:96px}
.tl .what{font-weight:500}
.tl .who{color:var(--ink-faint)}

/* ---------- login ---------- */
.login{max-width:380px;margin:9vh auto;padding:0 16px}
.login .mark{
  display:flex; align-items:center; gap:12px;
  font-size:24px; font-weight:700; letter-spacing:.06em; margin-bottom:6px;
}
.login .mark img{display:block; flex:none}
.login .tag{color:var(--ink-faint);font-size:14px;margin-bottom:26px}
.login form{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);padding:22px}

@media (max-width:640px){
  .wrap{padding:14px 12px 90px}
  /* the old rule hid every column past the fourth on every table, which on a
     phone removed Status, Outcome and the amounts. Plain tables (the dashboard
     queues) keep it; .grid tables scroll instead. */
  table:not(.grid) th:nth-child(n+5),table:not(.grid) td:nth-child(n+5){display:none}
  h1{font-size:20px}
  .page-head{flex-direction:column;align-items:flex-start;gap:8px}
  .tiles{grid-template-columns:repeat(2,1fr);gap:8px}
  .tile{padding:12px;min-height:76px}
  .tile .n{font-size:22px}
  .tile .t{font-size:12px}
  .kv{flex-direction:column;align-items:flex-start;gap:2px}
  .kv .v{text-align:left}
  .kv .v.big{font-size:20px}
  .row > *{flex:1 1 100%}
  .btn.wide{width:100%}
  input,select,textarea{font-size:16px}   /* stops iOS zooming into every field */
  .tabs-row{overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch}
  .tabs-row .tab{display:inline-block}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* day navigation on the Daily Report */
.daynav{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.daynav .btn{min-height:40px;padding:0 14px;font-size:14px}
.daynav input{min-height:40px;width:auto}

/* date group header with the day's total, the way the old app grouped orders */
table.grid tr.daygroup td{
  background:#EDF1F7;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:8px 12px;font-size:13.5px;color:var(--ink);
}
table.grid tr.daygroup .daycount{color:var(--ink-faint);font-weight:400;margin-left:10px;font-size:12.5px}
table.grid tr.daygroup:hover td{background:#EDF1F7}
table.grid tfoot td{
  background:var(--ink);color:#fff;padding:11px 12px;font-size:13.5px;border:0;
}

/* a button that reads as a link, for small inline actions in lists */
.linkbtn{
  background:none;border:0;padding:0;font:inherit;font-size:13px;
  color:var(--money);cursor:pointer;text-decoration:underline;min-height:0;
}
.linkbtn:hover{color:var(--ink)}

/* proof photos: small enough to scan a list, big enough to recognise */
.thumb{
  width:38px;height:38px;object-fit:cover;border-radius:4px;
  border:1px solid var(--line);vertical-align:middle;margin-right:4px;
}
.thumb:hover{border-color:var(--money)}
.proofs{display:flex;gap:18px;flex-wrap:wrap}
.proofs figure{margin:0}
.proofs img{
  max-width:230px;max-height:230px;border-radius:var(--radius);
  border:1px solid var(--line);display:block;
}
.proofs figcaption{font-size:13px;color:var(--ink-faint);margin-top:6px}

/* order line entry: model and quantity side by side, up to ten rows */
table.lines{width:100%;border-collapse:collapse;margin-top:4px}
table.lines th{
  text-align:left;font-size:11.5px;text-transform:uppercase;letter-spacing:.02em;
  color:var(--ink-faint);font-weight:600;padding:6px 8px 8px 0;
}
table.lines th.r,table.lines td.r{text-align:right}
table.lines td{padding:4px 8px 4px 0;vertical-align:middle}
table.lines td:last-child{width:60px;padding-right:0}
table.lines select,table.lines input{min-height:42px;margin:0}
table.lines .line-total{font-size:14px;color:var(--ink-soft);white-space:nowrap}

/* ---------- charts ---------------------------------------------------------
   Drawn as inline SVG rather than loaded from a charting library: they arrive
   with the page, they print, and there is nothing extra to download on a
   rider's phone. Horizontal bars because the labels are product names — long
   text reads better along a row than rotated under a column. */

.chartbox{padding:20px 22px}
.chart{display:block;overflow:visible}
.chart .c-label{
  font-family:inherit;font-size:13.5px;fill:var(--ink);font-weight:500;
}
.chart .c-value{
  font-family:inherit;font-size:13.5px;fill:var(--ink);font-weight:600;
  font-variant-numeric:tabular-nums;
}
.chart .c-note{font-family:inherit;font-size:11.5px;fill:var(--ink-faint)}
.chart .c-track{fill:var(--line-soft)}
.chart .c-rest{fill:#BFD4C4}

/* the exact numbers, folded away under the picture */
.figures{margin-top:10px}
.figures summary{
  cursor:pointer;list-style:none;font-size:13.5px;color:var(--ink-faint);
  padding:8px 2px;font-weight:500;
}
.figures summary::-webkit-details-marker{display:none}
.figures summary::before{content:"› ";display:inline-block;transition:transform .12s}
.figures[open] summary::before{content:"⌄ "}
.figures summary:hover{color:var(--ink)}

@media (max-width:640px){
  .chartbox{padding:14px}
  .chart .c-label{font-size:12px}
  .chart .c-value{font-size:12px}
}

/* movement between two months. Up is not automatically good — more cancelled
   orders is a worse month — so the arrow shows direction and the colour shows
   whether that direction is welcome. */
.up{color:var(--go);font-weight:600;font-size:13.5px;white-space:nowrap}
.down{color:var(--stop);font-weight:600;font-size:13.5px;white-space:nowrap}
.flat{color:var(--ink-faint);font-size:13.5px}

/* What the rider must physically carry. Sits above the address, because it is
   decided before they leave rather than when they arrive. */
.job .bring{
  margin:10px 0 0; padding:10px 12px; border-radius:6px;
  background:var(--money-bg); color:var(--money);
  font-size:14.5px; font-weight:600; line-height:1.35;
}

/* the access matrix: many columns, so it has to stay readable while scrolling */
table.matrix th.capname, table.matrix td.capname{
  min-width:250px; position:sticky; left:0; background:var(--paper); z-index:2;
}
table.matrix thead th.capname{background:#F7F9FC}
table.matrix th.tick, table.matrix td.tick{text-align:center; min-width:84px}
table.matrix td.tick input{width:20px;height:20px;min-height:0;margin:0;cursor:pointer}
table.matrix td.tick input:disabled{cursor:not-allowed;opacity:.45}
table.matrix tr.secrow td{
  background:#DCE6F1; font-weight:700; font-size:11px; letter-spacing:.05em;
  text-transform:uppercase; color:var(--navy,#1F3864); padding:7px 12px;
}
.savedflag{
  position:fixed; right:22px; bottom:22px; padding:9px 16px; border-radius:6px;
  background:var(--go); color:#fff; font-size:14px; font-weight:600;
  opacity:0; transform:translateY(6px); transition:opacity .15s, transform .15s;
  pointer-events:none; z-index:40;
}
.savedflag.show{opacity:1; transform:translateY(0)}

/* the decision column on Stock Transfers: one question, one answer, in a row */
table.transfers td.decide, table.transfers th.decide{min-width:330px}
.decideform{display:flex;gap:6px;align-items:center;margin:0}
.decideform select{flex:0 0 178px;min-height:36px;margin:0;font-size:13.5px}
.decideform .notefield{flex:1;min-width:90px;min-height:36px;margin:0;font-size:13.5px}
.decideform .notefield.needed{border-color:var(--stop);background:var(--stop-bg)}
.decideform .btn{min-height:36px;padding:0 14px;font-size:13.5px;flex:0 0 auto}
@media (max-width:1100px){
  .decideform{flex-wrap:wrap}
  .decideform select, .decideform .notefield{flex:1 1 100%}
}

/* selecting several transfers and deciding once */
table.transfers th.pick, table.transfers td.pick{width:38px;text-align:center;padding-left:14px}
table.transfers td.pick input, table.transfers th.pick input{
  width:19px;height:19px;min-height:0;margin:0;cursor:pointer;
}
.bulkbar{
  display:flex;gap:10px;align-items:center;flex-wrap:wrap;
  padding:12px 14px;margin-bottom:10px;border-radius:var(--radius);
  background:var(--shell);border:1px solid var(--line);
  transition:background .12s,border-color .12s;
}
.bulkbar.active{background:var(--go-bg);border-color:var(--brand)}
.bulkbar span{font-size:14px;font-weight:600;color:var(--ink-soft);min-width:150px}
.bulkbar.active span{color:var(--brand-dk)}
.bulkbar select{flex:0 0 210px;min-height:38px;margin:0;font-size:14px}
.bulkbar .notefield{flex:1;min-width:150px;min-height:38px;margin:0;font-size:14px}
.bulkbar .notefield.needed{border-color:var(--stop);background:var(--stop-bg)}
.bulkbar .btn{min-height:38px;padding:0 20px;font-size:14px;flex:0 0 auto}
.bulkbar .btn:disabled{opacity:.4;cursor:not-allowed}
@media (max-width:820px){
  .bulkbar select,.bulkbar .notefield{flex:1 1 100%}
}

/* the "or" divider on the allocate screen */
.orline{
  display:flex;align-items:center;gap:12px;margin:18px 0 4px;
  color:var(--ink-faint);font-size:13px;
}
.orline::before,.orline::after{
  content:"";flex:1;height:1px;background:var(--line);
}

/* one search box, used on every list */
.searchbar{display:flex;gap:8px;align-items:center;margin:0 0 16px;max-width:520px}
.searchbar input{flex:1;min-height:40px;margin:0;font-size:14.5px}
.searchbar .btn{min-height:40px;padding:0 16px;font-size:14px;flex:0 0 auto}
.searchbar .clear{font-size:13px;color:var(--ink-faint);text-decoration:none;flex:0 0 auto}
.searchbar .clear:hover{color:var(--ink)}
.foundnote{font-size:13.5px;color:var(--ink-faint);margin:-8px 0 14px}

/* folded sections on long pages: closed by default, one click opens */
details.fold > summary{cursor:pointer;list-style:none;display:flex;align-items:baseline;gap:8px;padding:6px 0}
details.fold > summary::-webkit-details-marker{display:none}
details.fold > summary::before{content:"▸";color:var(--brand);font-size:14px}
details.fold[open] > summary::before{content:"▾"}

/* Configuration: sections, not one long strip */
/* Configuration: one row of groups, then the pages of the chosen group */
.setup-nav{margin:0 0 18px;border-bottom:1px solid var(--line)}
.setup-groups{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.setup-groupbtn{display:inline-flex;align-items:center;min-height:36px;padding:0 14px;border-radius:999px;border:1px solid var(--line);background:#fff;
  font-size:12.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-soft);text-decoration:none}
.setup-groupbtn:hover{border-color:var(--brand);color:var(--brand)}
.setup-groupbtn.on{background:var(--brand);border-color:var(--brand);color:#fff}
.setup-pages{display:flex;gap:2px 4px;flex-wrap:wrap}
.setup-pages .tab{padding:8px 12px;font-size:14px}
@media (max-width:640px){ .setup-groupbtn{min-height:34px;padding:0 10px;font-size:11.5px} }

@media (max-width:640px){
  form.row > div{flex:1 1 45%}
  form.row > button, form.row > a.btn{flex:1 1 30%}
}

/* the journey strip — where it is, what happens next */
.journey{margin:0 0 14px}
.journey .journey-head{font-size:14.5px}
.journey .journey-dots{display:flex;gap:4px;flex-wrap:wrap;margin:8px 0 0}
.journey .jd{width:22px;height:22px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;background:var(--line);color:var(--ink-faint)}
.journey .jd.done{background:var(--go);color:#fff}
.journey .jd.here{background:var(--ink);color:#fff}
.journey .journey-names{display:none;gap:10px;flex-wrap:wrap;margin-top:6px;font-size:11.5px;color:var(--ink-faint)}
.journey .journey-names .done{color:var(--go)}
.journey .journey-names .on{color:var(--ink);font-weight:700}
@media (min-width:900px){.journey .journey-names{display:flex}}

/* the dashboard in sections, like the menu */
.dash-section{margin:0 0 6px}
.dash-h{font-size:12.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#fff;background:var(--brand);padding:8px 14px;border-radius:var(--radius);margin:18px 0 10px;display:flex;align-items:center;gap:8px}
.dash-h .muted{font-weight:600;letter-spacing:0;text-transform:none;font-size:12px;color:rgba(255,255,255,.85)}
.dash-section:first-of-type .dash-h{margin-top:6px}
/* a details block opened by a button elsewhere: its own title shows only when open */
details#correct-details > summary{display:none}
details#correct-details[open] > summary{display:block}
details#correct-details > summary::-webkit-details-marker{display:none}
/* section headings inside a document page (order, case): the same words as the menu */
h2.sect{font-size:12.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--brand-dk);background:var(--tint);border-left:3px solid var(--brand);border-radius:4px;margin:22px 0 10px;padding:9px 14px;display:flex;align-items:center;gap:10px}
h2.sect .muted{font-weight:500;letter-spacing:0;text-transform:none;font-size:12.5px;color:var(--ink-faint)}
h2.sect:first-of-type{margin-top:16px}
/* document sections fold; Sales and Finance start open, the rest closed */
details.sect-fold>summary{list-style:none;cursor:pointer}
details.sect-fold>summary::-webkit-details-marker{display:none}
details.sect-fold>summary h2.sect{margin-bottom:0}
details.sect-fold>summary h2.sect::after{content:"▸";margin-left:auto;font-size:14px;color:var(--ink-faint)}
details.sect-fold[open]>summary h2.sect::after{content:"▾"}
details.sect-fold>.sect-body{padding-top:4px}


/* =====================================================================
   FORTHEO look — brand green, light on the eyes (set 10 Sep 2026)
   Green is the accent, not the wallpaper: pale tints for surfaces and
   highlights, solid green only for small things — the active menu item,
   the current step, thin rules, the mark. Red stays for stop / overdue.
   ===================================================================== */
:root{
  --tint:       #F3F8F4;   /* pale green surface */
  --tint-2:     #E7F1E9;   /* a shade deeper, for bands and hover */
  --tint-line:  #CFE0D3;   /* green-grey line */
  --shell:      #F6F8F6;   /* page background, near-white */
  --money-bg:   var(--tint-2);
  --go-bg:      var(--tint-2);
  --wait:       #4E6B1F; --wait-bg: #EEF3DF;
}
body{background:var(--shell)}
/* highlights: pale green with green text and a thin green rule — not solid */
.note.info,.note.ok,.note.wait,.journey.note{background:var(--tint);color:var(--brand-dk);border-left:3px solid var(--brand)}
.note.info b,.note.ok b,.note.wait b,.journey b{color:var(--brand-dk)}
.note.info a,.note.ok a,.note.wait a,.journey a{color:var(--brand)}
.note.info .muted,.note.ok .muted,.note.wait .muted,.journey .muted{color:var(--ink-faint)}
.journey .journey-names span{color:var(--ink-faint)} .journey .journey-names .done{color:var(--brand)} .journey .journey-names .on{color:var(--ink);font-weight:700}
.journey .jd{background:#fff;border:1px solid var(--tint-line);color:var(--ink-faint)}
.journey .jd.done{background:var(--brand);border-color:var(--brand);color:#fff}
.journey .jd.here{background:var(--ink);border-color:var(--ink);color:#fff}
/* buttons: transparent green with green text; the primary action is a firmer tint */
.btn,.btn.money{background:var(--tint-2);color:var(--brand-dk);border-color:var(--tint-line)}
.btn:hover,.btn.money:hover{background:#DCEBDF;border-color:var(--brand)}
.btn.go{background:var(--brand);color:#fff;border-color:var(--brand)}            /* the one primary action on a screen */
.btn.go:hover{background:var(--brand-dk)}
.btn.ghost{background:#fff;color:var(--ink);border-color:var(--line)}
.btn.stop{background:#fff;color:var(--stop);border-color:var(--stop)}            /* red outline, not a red block */
.btn.stop:hover{background:var(--stop-bg)}
/* totals band on an order */
.kv[style*="--money-bg"]{background:var(--tint-2) !important}
.kv[style*="--money-bg"] .k b,.kv[style*="--money-bg"] .v{color:var(--brand-dk) !important}
/* section headings: green text on a pale band, thin rule */
.dash-h{background:var(--tint);color:var(--brand-dk);border-left:3px solid var(--brand);padding:8px 12px;border-radius:4px}
.dash-h .muted{color:var(--ink-faint)}
/* urgent section: the same pale band with a red rule and red title (inline style sets the colour) */
h2.sect[style*="--stop"]{background:var(--stop-bg)}
/* configuration groups and tabs */
.setup-groupbtn{background:#fff;border-color:var(--tint-line);color:var(--ink-soft)}
.setup-groupbtn.on{background:var(--tint-2);border-color:var(--brand);color:var(--brand-dk)}
.tabs-row .tab.on{color:var(--brand-dk);border-bottom:2px solid var(--brand)}
/* tables: pale green header, faint zebra, green-grey lines */
table.grid thead th{background:var(--tint);color:var(--brand-dk);border-bottom:1px solid var(--tint-line)}
table.grid td{border-bottom-color:var(--line-soft)}
table.grid tbody tr:hover{background:var(--tint)}
/* panels and tiles: white on the near-white shell, soft green line */
.panel,.tile{border:1px solid var(--tint-line);box-shadow:0 1px 2px rgba(2,99,18,.05)}
.tile .n.stop{color:var(--stop)} .tile .n.wait{color:var(--wait)} .tile .n.money{color:var(--brand)}
/* the side menu: white, green only on the active item */
.side a.on,.side .on{background:var(--tint-2);color:var(--brand-dk);border-left:3px solid var(--brand)}
/* pills */
.pill.go{background:var(--tint-2);color:var(--brand-dk)} .pill.money{background:var(--tint-2);color:var(--brand-dk)}
.pill.wait{background:var(--wait-bg);color:var(--wait)} .pill.stop{background:var(--stop-bg);color:var(--stop)}
/* inputs: white, green focus */
input:focus,select:focus,textarea:focus{outline:2px solid rgba(2,99,18,.25);border-color:var(--brand)}
/* buttons inside a note keep their own colours (a solid button never inherits the note's link colour) */
.note a.btn,.note .btn{color:var(--brand-dk);text-decoration:none}
.note a.btn.go,.note .btn.go{color:#fff}
.note a.btn.stop,.note .btn.stop{color:var(--stop)}
/* wide tables: the panel scrolls sideways instead of squeezing the last column off the screen */
.panel:has(> table.grid){overflow-x:auto}
table.grid td.actions .btn{min-height:32px !important;padding:0 12px !important;font-size:13px !important}
/* the customer's order form, one step at a time */
.stepnav{display:flex;gap:10px;align-items:center;margin-top:18px}
.stepnav .btn{min-width:110px}
section.step h2{margin-top:0}

/* the fourteen-day strip: rider load per route */
.daystrip{display:flex;gap:4px;flex-wrap:wrap;margin-top:8px}
.daystrip .day{flex:1 1 60px;min-width:60px;border:1px solid var(--tint-line);border-radius:6px;padding:6px 4px;text-align:center;background:#fff;font-size:12px;line-height:1.25}
.daystrip .day .dow{display:block;color:var(--ink-faint);text-transform:uppercase;font-size:10.5px;letter-spacing:.04em}
.daystrip .day .dt{display:block;font-weight:600}
.daystrip .day .n{display:block;color:var(--brand-dk);font-variant-numeric:tabular-nums}
.daystrip .day.tight{background:var(--wait-bg);border-color:var(--wait)} .daystrip .day.tight .n{color:var(--wait)}
.daystrip .day.full{background:var(--stop-bg);border-color:var(--stop)} .daystrip .day.full .n{color:var(--stop)}
.daystrip a.day{text-decoration:none;color:inherit} .daystrip .day.here{outline:2px solid var(--brand);outline-offset:-2px}
table.grid td a.btn,table.grid td > a{white-space:nowrap}
/* picking: the same column widths in every group, long text wraps inside its column */
table.pickgrid{table-layout:fixed;width:100%} table.pickgrid td{overflow-wrap:anywhere;vertical-align:top}
/* the after-sales conversation: a panel on the right of the case page */
.chat-drawer{position:fixed;top:56px;right:0;bottom:0;width:440px;max-width:100vw;background:var(--paper);border-left:1px solid var(--tint-line);box-shadow:-6px 0 18px rgba(2,99,18,.08);transform:translateX(100%);transition:transform .18s ease;z-index:30;display:flex;flex-direction:column}
body.chat-open .chat-drawer{transform:none}
.chat-drawer-head{display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:1px solid var(--tint-line);background:var(--tint)}
.chat-drawer-body{padding:12px 14px;overflow-y:auto;flex:1;display:flex;flex-direction:column}
.chat-drawer .chat{max-height:none;flex:1;min-height:200px}
.chat-fab{position:fixed;right:18px;bottom:18px;z-index:31;background:var(--brand);color:#fff;border:0;border-radius:999px;padding:12px 18px;font-weight:700;font-size:14px;box-shadow:0 4px 14px rgba(0,0,0,.18);cursor:pointer;display:inline-flex;align-items:center;gap:8px}
body.chat-open .chat-fab{display:none}
@media (min-width:1180px){ body.chat-open .wrap{margin-right:460px} }
@media (max-width:640px){ .chat-drawer{width:100vw;top:0} }
@media print{ .chat-drawer,.chat-fab{display:none} }
.chat-tools{display:flex;gap:6px;margin-top:8px} .chat-tools .btn{flex:1;min-height:38px;padding:0 8px;font-size:13px;white-space:nowrap}
/* the conversation composer: full-width box, one toolbar under it */
.chat-drawer .chat-compose{flex-direction:column;align-items:stretch;gap:0;margin-top:10px} .chat-drawer .chat-compose textarea{min-height:64px;border-bottom-left-radius:0;border-bottom-right-radius:0}
.chat-bar{display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:6px;border:1px solid var(--tint-line);border-top:0;border-radius:0 0 8px 8px;background:var(--tint)}
.chat-bar .btn{min-height:34px;padding:0 10px;font-size:13px;white-space:nowrap} .chat-bar label.btn{display:inline-flex;align-items:center;cursor:pointer}
.chat-tools{display:flex;gap:6px;margin-top:8px} .chat-tools .btn{flex:1;min-height:38px;padding:0 8px;font-size:13px;white-space:nowrap}
