/* Employee portal. Inherits the site's tokens from styles.css; this file only
   adds what a working application needs on top of a marketing page.

   The public site is a page you read top to bottom. This is a tool people use
   on a shift, so it is laid out as an application: a fixed rail of
   destinations on the left, one working surface on the right, and no scrolling
   to find the thing you came to press. */

.portal-body { background: var(--paper); }

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

.pshell { display: flex; min-height: 100vh; min-height: 100dvh; }

.pside {
  position: sticky;
  top: 0;
  align-self: flex-start;
  flex: 0 0 232px;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: 22px 14px 16px;
  background: var(--paper-2);
  border-right: 1px solid var(--line);
  z-index: 50;
}

/* The mark alone, sitting on the same left edge as the destinations below it.
   The rail pads 14px and each destination pads another 11 inside that, so the
   mark is inset to match: an icon that starts left of everything it sits above
   reads as a mistake, not as a logo. */
.pside-brand {
  display: block;
  width: max-content;
  padding: 2px 11px 22px;
  text-decoration: none;
  color: var(--ink);
}
.pside-brand .nav-mark { width: 42px; }

.pnav { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; }
.pnav-h {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--ink-3);
  padding: 16px 10px 7px;
}
.pnav-h[hidden] { display: none; }

.pnav-i {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  font-family: var(--nav); font-size: 14.5px; font-weight: 500;
  text-align: left;
  color: var(--ink-2);
  background: none;
  border: 0;
  border-radius: 10px;
  padding: 10px 11px;
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease;
}
.pnav-i[hidden] { display: none; }
.pnav-i svg {
  width: 17px; height: 17px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0.75;
}
.pnav-i:hover { color: var(--ink); background: rgba(255, 255, 255, 0.05); }
.pnav-i.is-on { color: var(--paper); background: var(--ink); }
.pnav-i.is-on svg { opacity: 1; }

.pside-foot { margin-top: auto; padding-top: 18px; }
.pside-lang { display: flex; margin: 0 0 10px; }
.pside-lang .lang-b { flex: 1; text-align: center; }
.login-lang { display: inline-flex; align-self: flex-start; margin-top: 24px; }

.pwho {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 10px 14px;
}
/* Initials rather than a photo: nobody is uploading one from a fuel truck, and
   two letters are enough to be sure you are looking at your own account. */
.pwho-av {
  flex: 0 0 auto;
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--nav); font-size: 12.5px; font-weight: 600;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid var(--line);
}
.pwho-t { display: grid; gap: 2px; min-width: 0; }
.pwho-n {
  font-family: var(--nav); font-size: 13.5px; font-weight: 500; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pwho-r {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-3);
}

.pmain { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

/* ------------------------------------------------------------------- top */

.ptop {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px clamp(16px, 3vw, 34px);
  background: rgba(10, 11, 13, 0.86);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--line);
}
.ptop-k {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 5px;
}
.ptop-h {
  font-family: var(--display); font-size: clamp(19px, 2.3vw, 25px);
  font-weight: 700; letter-spacing: -0.015em; line-height: 1;
}
.ptop-spacer { margin-left: auto; }

.pstatus {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 999px; padding: 7px 14px;
  font-variant-numeric: tabular-nums;
}
.pstatus.is-on { color: var(--ink); border-color: rgba(255, 255, 255, 0.34); }

/* three lines, becoming a cross once the rail is out */
.pside-btn {
  display: none;
  width: 38px; height: 38px; padding: 0; border: 0;
  border-radius: 50%; background: rgba(255, 255, 255, 0.08);
  color: var(--ink); cursor: pointer; flex: 0 0 auto;
}
.pside-btn span {
  display: block; width: 16px; height: 1.5px; margin: 3px auto;
  background: currentColor; border-radius: 2px;
  transition: transform 0.24s ease, opacity 0.18s ease;
}
.pshell.is-open .pside-btn span:nth-child(1) { transform: translateY(4.5px) rotate(45deg); }
.pshell.is-open .pside-btn span:nth-child(2) { opacity: 0; }
.pshell.is-open .pside-btn span:nth-child(3) { transform: translateY(-4.5px) rotate(-45deg); }

.pscrim {
  position: fixed; inset: 0; z-index: 45;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
}
.pscrim[hidden] { display: none; }

.pwrap { flex: 1 1 auto; padding: clamp(20px, 3vw, 34px) clamp(16px, 3vw, 34px) 80px; max-width: 1500px; width: 100%; }
.pview[hidden] { display: none; }

/* ------------------------------------------------------------------ pieces */

.pcard {
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: clamp(18px, 2.2vw, 26px);
}
.pcard-quiet { background: transparent; }
.pcard-top { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 14px; }
.pcard-top .btn { margin-left: auto; }

.pgrid { display: grid; gap: 16px; }
.pgrid.two { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.pgrid.stats { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

.phead {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 14px;
}

.stat-n {
  font-family: var(--display); font-size: clamp(28px, 3.4vw, 42px);
  font-weight: 700; letter-spacing: -0.02em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.stat-l { margin-top: 8px; font-family: var(--nav); font-size: 13px; color: var(--ink-2); }

/* clock */
.pcard-clock { display: flex; flex-direction: column; }
.clock-state { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.clock-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ink-3); flex: 0 0 auto; }
.clock-dot.is-on { background: #fff; box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.14); }

/* A running clock is the one number on this page that changes while you look
   at it, so it is set at the size of a headline and in tabular figures: the
   digits must not shuffle sideways every second. */
.clock-since {
  font-family: var(--display); font-size: clamp(34px, 5vw, 56px);
  font-weight: 700; letter-spacing: -0.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.clock-since.is-idle { color: var(--ink-3); }
.clock-sub { font-family: var(--nav); font-size: 13.5px; color: var(--ink-2); margin-top: 8px; }
.clock-acts { margin-top: auto; padding-top: 22px; display: flex; gap: 10px; flex-wrap: wrap; }

/* forms */
.pform { display: grid; gap: 15px; }
.prow { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 15px; }

.field { display: grid; gap: 7px; }
.field-l {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-2);
}
.field-wrap { position: relative; display: block; }
.field-wrap input { width: 100%; padding-right: 66px; }
.field-eye {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--ink-2);
  background: none; border: 0; border-radius: 7px; padding: 7px 8px; cursor: pointer;
}
.field-eye:hover { color: var(--ink); background: rgba(255, 255, 255, 0.07); }
.field-hint { font-family: var(--nav); font-size: 12.5px; color: var(--ink-2); }
.field-hint[hidden] { display: none; }

.pform input, .pform select, .pform textarea {
  font-family: var(--nav); font-size: 15px; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 10px; padding: 12px 13px; outline: none;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.pform input::placeholder, .pform textarea::placeholder { color: var(--ink-3); }
.pform input:focus, .pform select:focus, .pform textarea:focus {
  border-color: rgba(255, 255, 255, 0.5);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.07);
}
.pform textarea { resize: vertical; min-height: 74px; }

.btn {
  font-family: var(--nav); font-size: 14.5px; font-weight: 500;
  padding: 12px 20px; border-radius: 999px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.28); background: transparent; color: var(--ink);
  transition: background 0.16s ease, opacity 0.16s ease, border-color 0.16s ease;
}
.btn:hover { background: rgba(255, 255, 255, 0.09); }
.btn.solid { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn.solid:hover { opacity: 0.86; background: var(--ink); }
.btn.ghost { border-color: var(--line); color: var(--ink-2); }
.btn.ghost:hover { color: var(--ink); border-color: rgba(255, 255, 255, 0.3); }
.btn.wide { width: 100%; }
.btn.slim { padding: 8px 14px; font-size: 13px; }
/* A grid stretches its children, and a submit pill the width of the form reads
   as a banner rather than as a button. The sign-in door is the exception: one
   field, one action, nothing to aim at but that. */
.pform > .btn { justify-self: start; }
.login-form > .btn { justify-self: stretch; }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* tables */
.ptable-wrap { overflow-x: auto; }
.ptable { width: 100%; border-collapse: collapse; font-family: var(--nav); font-size: 14px; min-width: 720px; }
.ptable th {
  font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; text-align: left; color: var(--ink-2);
  padding: 10px 14px 10px 0; border-bottom: 1px solid var(--ink);
  position: sticky; top: 0; background: var(--paper-2);
}
.ptable td { padding: 12px 14px 12px 0; border-bottom: 1px solid var(--line); color: var(--ink-2); vertical-align: top; }
.ptable td.n { text-align: right; padding-right: 0; font-variant-numeric: tabular-nums; color: var(--ink); font-weight: 500; }
.ptable tr.is-void td { opacity: 0.45; text-decoration: line-through; }
.ptable .who { color: var(--ink); font-weight: 500; }

.pill {
  display: inline-block; font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase;
  border: 1px solid var(--line); border-radius: 999px; padding: 3px 8px; color: var(--ink-2);
}
.pill.on { color: var(--ink); border-color: rgba(255, 255, 255, 0.5); }

.pmsg { font-family: var(--nav); font-size: 13.5px; padding: 11px 14px; border-radius: 10px; border: 1px solid var(--line); }
.pmsg.bad { border-color: rgba(255, 255, 255, 0.4); color: var(--ink); }
.pmsg.good { border-color: rgba(255, 255, 255, 0.28); color: var(--ink-2); }
.pmsg[hidden] { display: none; }

.pempty { font-family: var(--nav); font-size: 14px; color: var(--ink-3); padding: 26px 0; }

.ptools { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 16px; }
.ptools input, .ptools select {
  font-family: var(--nav); font-size: 14px; color: var(--ink);
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 13px; outline: none;
}
.ptools input:focus, .ptools select:focus { border-color: rgba(255, 255, 255, 0.4); }

/* ------------------------------------------------------------------- login */

/* Two panels: the ramp on one side so the door looks like the place it opens
   onto, the form on the other. Below the breakpoint the photograph goes rather
   than shrinking to a stripe, because a phone screen is all form. */
.login { min-height: 100vh; min-height: 100dvh; display: grid; grid-template-columns: 1.05fr 1fr; }

.login-plate { position: relative; overflow: hidden; background: #000; }
/* A truck being fuelled, which is the job, rather than an aircraft, which is
   the customer. The people signing in here work the hose. */
.login-shot {
  position: absolute; inset: 0;
  background: url('../assets/portal-plate.jpg') center / cover no-repeat;
  filter: grayscale(1) contrast(1.06) brightness(0.58);
  transform: scale(1.03);
}
.login-grain {
  position: absolute; inset: -50%;
  background: url('../assets/grain.png') repeat;
  opacity: 0.16; mix-blend-mode: overlay; pointer-events: none;
}
.login-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.15) 40%, rgba(0,0,0,0.88) 100%);
}
.login-plate-copy { position: absolute; left: clamp(28px, 4vw, 56px); right: clamp(28px, 4vw, 56px); bottom: clamp(30px, 4vw, 54px); }
.login-plate-eyebrow {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: rgba(255, 255, 255, 0.62); margin-bottom: 12px;
}
.login-plate-line {
  font-family: var(--display); font-size: clamp(28px, 3.4vw, 46px);
  font-weight: 700; text-transform: uppercase; letter-spacing: -0.025em; line-height: 0.98;
}

.login-panel { display: grid; place-items: center; padding: 40px clamp(20px, 4vw, 56px); }
.login-card { width: 100%; max-width: 390px; }

/* The mark on its own, at a size that reads as a mark rather than an icon.
   Nothing else identifies this page, so it carries the whole job. */
.login-brand {
  display: inline-block;
  text-decoration: none;
  color: var(--ink);
  margin-bottom: 40px;
}
.login-mark { width: 78px; }

.login-h {
  font-family: var(--display); font-size: clamp(30px, 3.4vw, 38px);
  font-weight: 700; text-transform: uppercase; letter-spacing: -0.025em; margin-bottom: 8px;
}
.login-sub { font-family: var(--nav); font-size: 14.5px; color: var(--ink-2); margin-bottom: 28px; }
.login-form { gap: 17px; }
.login-foot { margin-top: 26px; display: grid; gap: 16px; justify-items: start; align-self: stretch; }

/* One target, the whole line. A locked-out person is not looking for a number
   to copy down, they are looking for help, so the question dials too. */
/* The question is the link and looks like it: underlined, and out of the dim
   grey a field label wears. The digits used to sit beside it carrying the only
   underline, which said the number was the link and the question a caption —
   the reverse of what the markup does. The digits are gone now; the number is
   in the label, for a screen reader and for anyone who cannot dial from the
   device they are on.

   Kept inline rather than inline-flex so the underline belongs to the text and
   breaks with it, which matters in Spanish where the question is longer. The
   vertical padding moves nothing but enlarges the hit area, worth having on
   the one control a locked-out person on a phone actually needs. */
.login-call {
  display: inline;
  font-family: var(--nav);
  font-size: 14px;
  color: var(--ink-2);
  line-height: 1.9;
  padding: 6px 0;
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.24);
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
  transition: color 0.16s ease, text-decoration-color 0.16s ease;
}
.login-call:hover,
.login-call:focus-visible {
  color: var(--ink);
  text-decoration-color: var(--ink);
}

.login-back { font-family: var(--nav); font-size: 13px; color: var(--ink-3); }
.login-back:hover { color: var(--ink-2); }

.btn-go { position: relative; margin-top: 4px; padding: 14px 20px; }
.btn-spin {
  display: none;
  width: 14px; height: 14px; margin-left: 10px; vertical-align: -2px;
  border: 1.6px solid rgba(0, 0, 0, 0.28); border-top-color: var(--paper);
  border-radius: 50%;
  animation: pspin 0.7s linear infinite;
}
.btn-go.is-busy .btn-spin { display: inline-block; }
@keyframes pspin { to { transform: rotate(360deg); } }

/* the handover, drawn over the card once the password is accepted */
.login-pass {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center; align-content: center; gap: 20px;
  background: var(--paper);
}
.login-pass[hidden] { display: none; }
.login-pass-mark { width: 74px; }
.login-pass-t {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-2);
}

/* ------------------------------------------------------------------ narrow */

/* Below the split, the photograph does not go away: it moves behind the form
   and fills the screen. Hiding it was the easy answer and the wrong one, since
   the phone is where most people sign in and it left them a black box. The
   scrim below carries the contrast the type needs. */
@media (max-width: 980px) {
  .login { grid-template-columns: 1fr; position: relative; }
  .login-plate {
    position: fixed;
    inset: 0;
    z-index: 0;
  }
  .login-plate-copy { display: none; }

  /* Light at the top so the photograph is a photograph, heavy where the form
     sits so the type has something solid under it. */
  .login-scrim {
    background: linear-gradient(180deg,
      rgba(10, 11, 13, 0.34) 0%,
      rgba(10, 11, 13, 0.60) 14%,
      rgba(10, 11, 13, 0.94) 34%,
      rgba(10, 11, 13, 0.99) 100%);
  }
  .login-shot { filter: grayscale(1) contrast(1.04) brightness(0.66); }

  /* The card fills the panel and splits: the mark pinned to the top edge, the
     form resting on the bottom. Bottom-aligning the whole card left the mark
     wherever the content happened to end, so it drifted with the length of the
     copy and never sat on a line of its own. */
  /* The gap under the mark is a set distance rather than whatever is left
     over, so the card is its own natural height. That means it can simply be
     centred: pinning it to the top with a fixed offset moved the dead space to
     the bottom instead of removing it — 81px above the card and 149px below,
     measured, which is what read as sitting too high. Centred, the space falls
     evenly on both sides at any height. Padding is the floor, so on a short
     phone the card stops rather than running off the top. */
  .login-panel {
    position: relative;
    z-index: 1;
    align-items: center;
    padding: calc(clamp(24px, 4vh, 48px) + env(safe-area-inset-top)) 20px
             calc(clamp(24px, 4vh, 48px) + env(safe-area-inset-bottom));
  }
  .login-card {
    max-width: none;
    display: flex;
    flex-direction: column;
  }
  .login-brand { margin: 0 0 clamp(34px, 7vh, 64px); }

  /* The brand rides on the picture at the top; the form is a plate resting on
     the dark end of it, so the two read as layers rather than one flat wash. */
  /* Over the bright end of the photograph the mark needs to be lifted off it,
     the way the copy over the hero is. */
  .login-mark { width: 88px; filter: drop-shadow(0 2px 14px rgba(0, 0, 0, 0.6)); }

  .login-h {
    font-size: clamp(30px, 8.6vw, 40px);
    line-height: 0.94;
    text-shadow: 0 2px 20px rgba(0, 0, 0, 0.5);
  }
  .login-sub { margin-bottom: 20px; }
  .login-form { gap: 14px; }
  .login-foot { margin-top: 20px; gap: 12px; }
}

@media (max-width: 900px) {
  /* The rail slides out over the work rather than squeezing it. */
  .pside {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: 250px; flex: none;
    transform: translateX(-100%);
    transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
  }
  .pshell.is-open .pside { transform: none; }
  .pside-btn { display: block; }
  .ptop { padding-top: max(14px, env(safe-area-inset-top)); }
  .pstatus { padding: 6px 11px; font-size: 9.5px; }
}

@media (max-width: 700px) {
  .ptable { min-width: 560px; }
  .ptop-k { display: none; }
  .pwrap { padding-bottom: max(60px, env(safe-area-inset-bottom)); }
}

@media (prefers-reduced-motion: reduce) {
  .pside { transition: none; }
  .btn-spin { animation-duration: 2s; }
}
