/* Engineer portal — engineer.g3e.co.uk
 *
 * Phone-first. The layout, spacing and components come from
 * g3e-engineer-portal-mockup.html; the colour and typography values come from
 * admin.css, which is the estate's source of truth for both. Where the mockup
 * and admin.css name the same role differently, admin's name and value win and
 * the mockup's usage is translated onto it — so there is one palette across the
 * three front ends rather than two that drift.
 *
 * The translation, recorded because it is not obvious from either file:
 *
 *   mockup            role                     here (admin.css)
 *   --dark            dark chrome              --ink
 *   --dark2           chrome hover             --ink-2
 *   --ink             body text                --text
 *   --teal            primary action           --teal-deep
 *   --teal-bright     accent / active nav      --teal
 *   --teal-tint       tint behind teal text    --teal-soft
 *   --teal-ink        text on that tint        --teal-deeper
 *   --amber-tint/ink  pending pill             --amber-bg / --amber
 *   --red-tint/ink    error                    --red-bg / --red
 *
 * Two judgement calls inside that:
 *
 *  · --teal-ink and admin's --teal-deeper are within a shade of each other and
 *    both mean "the darkest teal". They are kept as ONE token rather than two,
 *    because two tokens a shade apart for one role is exactly what the
 *    precedence rules exist to prevent.
 *  · The mockup's --faint is a green-grey (#8B9692) one step lighter than its
 *    --muted. Admin's grey ramp is blue-grey, so adopting that value verbatim
 *    would put two different grey ramps on one screen. --muted-2 below is the
 *    same step down taken in admin's hue instead. This is the one place a
 *    mockup value was not adopted as-is.
 *
 * A hard-coded colour in engineer.html or engineer-shell.js is a bug, exactly
 * as it is in the admin pages.
 */

:root{
  --ink:#141B26;          /* dark chrome: header, bottom nav */
  --ink-2:#1C2634;        /* chrome hover/active */
  --ink-3:#26313F;        /* chrome borders */
  --paper:#F3F4F1;        /* page background */
  --card:#FFFFFF;
  --line:#E2E5E1;         /* card borders, dividers */
  --line-2:#CBD0CC;       /* input borders */
  --text:#1B222C;
  --muted:#5D6773;
  --muted-2:#8A939E;      /* the mockup's --faint, in admin's hue — see above */
  --teal:#5BC4B6;         /* accent: active nav, badges */
  --teal-soft:#DDF2EF;
  --teal-deep:#127065;    /* primary buttons, links */
  --teal-deeper:#0C5A51;  /* primary hover, and text on --teal-soft */
  --amber:#A66E10;  --amber-bg:#FCF2DD;
  --green:#1E7B44;  --green-bg:#E5F3EA;
  --red:#B0362E;    --red-bg:#FAEAE8;
  --grey-bg:#EEF0EE;

  --mono:'IBM Plex Mono',ui-monospace,monospace;
  --sans:'Archivo',system-ui,-apple-system,sans-serif;
  --shadow:0 1px 2px rgba(20,27,38,.05),0 4px 14px rgba(20,27,38,.05);
  --r:10px;
  --focus:0 0 0 3px rgba(18,112,101,.15);

  /* Chrome text, matching the admin sidebar rather than inventing a second
     set of on-dark greys. */
  --on-dark:#C4CBD4;
  --on-dark-dim:#79838F;

  /* The smallest a control may be. Every previous pass over this estate has
     had to retrofit tap targets; on a portal that only ever runs on a phone,
     it is a token so it cannot be forgotten. */
  --tap:44px;
}

/* Dark mode exists here and not in admin.css. It comes from the mockup, and it
   earns its place: this is the one front end used outdoors, in vans and in
   plant rooms. The cost is that every component added later needs both sets of
   values — if that stops being paid, delete this block rather than let half
   the portal have a dark treatment. */
@media (prefers-color-scheme: dark){
  :root{
    --paper:#171E1C; --card:#1E2725; --line:#2C3734; --line-2:#3A4744;
    --text:#EDF1EF; --muted:#9AA6A2; --muted-2:#75827D;
    --teal-soft:#123A2E; --teal-deeper:#8FDCC3; --teal-deep:#178B6C;
    --amber-bg:#3A2F16; --green-bg:#14301F; --red-bg:#3A211E; --grey-bg:#26302D;
    --shadow:none;
  }
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  font-family:var(--sans);
  background:var(--ink);
  color:var(--text);
  font-size:15px;line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
.mono{font-family:var(--mono)}

/* The mockup caps the app at 480px and centres it, so a tablet or laptop gets
   the phone layout centred rather than a stretched one nobody designed. */
.app{max-width:480px;margin:0 auto;min-height:100vh;background:var(--paper);display:flex;flex-direction:column;position:relative}

/* ── chrome ───────────────────────────────────────────────────────────────── */
header.top{background:var(--ink);color:#fff;padding:14px 18px;display:flex;align-items:center;justify-content:space-between;gap:12px}
header.top img{height:26px;display:block}
.avatar{width:34px;height:34px;border-radius:50%;background:var(--teal-soft);color:var(--teal-deep);font-size:12px;font-weight:700;display:grid;place-items:center;letter-spacing:.02em;flex-shrink:0}
.crumb{font-family:var(--mono);font-size:11px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted-2);padding:14px 18px 0}
.crumb b{color:var(--teal-deep);font-weight:600}
main{flex:1;padding:10px 18px 96px}

nav.bottom{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:480px;background:var(--ink);display:flex;z-index:20;padding-bottom:env(safe-area-inset-bottom)}
nav.bottom button{
  flex:1;background:none;border:none;color:var(--on-dark-dim);
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  padding:12px 0 14px;min-height:var(--tap);cursor:pointer;
  display:flex;flex-direction:column;align-items:center;gap:4px;
}
nav.bottom button svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
nav.bottom button.on{color:var(--teal)}
nav.bottom button:focus-visible{outline:2px solid var(--teal);outline-offset:-3px}

/* ── shared ───────────────────────────────────────────────────────────────── */
h1{font-size:20px;font-weight:650;margin:4px 0 14px;letter-spacing:-.01em}
.card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:14px;margin-bottom:12px;box-shadow:var(--shadow)}
.card.stripe-amber{border-left:3px solid var(--amber)}
.card.stripe-teal{border-left:3px solid var(--teal-deep)}

.pill{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;font-weight:600;padding:3px 10px;border-radius:11px;display:inline-block}
.pill.teal{background:var(--teal-soft);color:var(--teal-deeper)}
.pill.amber{background:var(--amber-bg);color:var(--amber)}
.pill.green{background:var(--green-bg);color:var(--green)}
.pill.gray{background:var(--grey-bg);color:var(--muted)}

button.btn{
  font-family:var(--sans);font-size:14px;font-weight:500;
  border:1px solid var(--line-2);background:var(--card);color:var(--text);
  border-radius:var(--r);padding:11px 14px;width:100%;min-height:var(--tap);cursor:pointer;
}
button.btn:active{transform:scale(.99)}
button.btn:focus-visible{outline:none;box-shadow:var(--focus);border-color:var(--teal-deep)}
button.btn[disabled]{opacity:.55;cursor:not-allowed}
button.primary{background:var(--teal-deep);border-color:var(--teal-deep);color:#fff;font-weight:600}
button.primary:not([disabled]):hover{background:var(--teal-deeper);border-color:var(--teal-deeper)}
button.linkish{width:auto;border:none;background:none;padding:10px 2px;min-height:var(--tap);font-size:13px;color:var(--teal-deep);text-decoration:underline;cursor:pointer;font-family:var(--sans)}

label.f{display:block;font-size:12px;color:var(--muted);margin-bottom:4px;font-weight:500}
input{
  font-family:var(--sans);font-size:16px; /* 16px: anything smaller and iOS zooms the page on focus */
  width:100%;border:1px solid var(--line-2);border-radius:var(--r);
  padding:11px 12px;min-height:var(--tap);background:var(--card);color:var(--text);
}
input:focus{outline:none;box-shadow:var(--focus);border-color:var(--teal-deep)}
.field{margin-bottom:14px}
.hint{font-size:12px;color:var(--muted-2)}

.empty{border:1.5px dashed var(--line-2);border-radius:12px;padding:22px 14px;text-align:center;font-size:13px;color:var(--muted-2)}
.tabs{display:flex;gap:6px;margin-bottom:14px}
.tabs button{
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  border:1px solid var(--line);background:var(--card);color:var(--muted);
  border-radius:8px;padding:9px 12px;min-height:38px;cursor:pointer;
}
.tabs button.on{background:var(--ink);border-color:var(--ink);color:#fff}

.kv{display:flex;font-size:13px;margin-bottom:6px}
.kv .k{font-family:var(--mono);font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted-2);width:78px;flex-shrink:0;padding-top:2px}
.kv .v{flex:1}

.scr{display:none}
.scr.on{display:block}

/* ── login ────────────────────────────────────────────────────────────────── */
.loginwrap{padding:44px 26px}
.loginwrap .card{padding:26px 20px;margin-top:40px}
.loginwrap img{height:34px;display:block;margin:0 auto 8px}
.loginwrap .sub{text-align:center;font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted-2);margin-bottom:28px}
.loginnote{font-size:12px;color:var(--muted-2);text-align:center;margin-top:12px;line-height:1.5}
.loginwrap h2{font-size:17px;font-weight:650;margin-bottom:6px}
.loginwrap p.lede{font-size:13px;color:var(--muted);margin-bottom:18px}

/* Messages. `.err` is not display:none by default here — the booking page
   carried a rule that hid these unless a second class was added, and three
   error messages were written and never shown for months as a result. */
.msg{border-radius:var(--r);padding:10px 12px;font-size:13px;margin-bottom:14px}
.msg.err{background:var(--red-bg);color:var(--red)}
.msg.ok{background:var(--green-bg);color:var(--green)}
.msg[hidden]{display:none}

/* The Turnstile widget is interaction-only, so on almost every load it is 0px
   tall. Nothing may add margin around it — that margin is the whole gap the
   reader sees when the widget is not there, which is the bug this estate has
   already hit twice on the booking page. */
#tsWidget{margin:0}

/* ── toast ────────────────────────────────────────────────────────────────── */
.toast{
  position:fixed;left:50%;bottom:calc(70px + env(safe-area-inset-bottom));transform:translateX(-50%);
  background:var(--ink);color:#fff;font-size:13px;padding:11px 16px;border-radius:var(--r);
  box-shadow:0 6px 24px rgba(0,0,0,.25);z-index:40;max-width:min(420px,calc(100vw - 36px));text-align:center;
}
.toast[hidden]{display:none}

/* Respect the system setting, as the marketing site does. */
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;transition-duration:.01ms !important}
  button.btn:active{transform:none}
}
