/* ============================================================
   Client portal.

   Same rule as the admin: NOT ONE COLOUR VALUE IN THIS FILE.
   Every colour is var(--token), emitted into <head> from the
   settings table. The rebrand has to reach the client-facing side
   too, or the handover is only half done.

   Different job from the admin, though. The admin is a tool you
   work in; this is a record you read. So: wider measure, calmer
   rows, and the visits are a timeline rather than a table —
   somebody scanning for "were you here in March" reads down a
   column of dates, not across a grid.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
html { scroll-padding-top: 74px; }

body {
  margin: 0;
  background: var(--void);
  color: var(--text);
  font: 15.5px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  /* The same engineering grid as the public site, at the same
     pitch. A client who arrives from the front page should land
     somewhere that is obviously the same company. */
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 64px 64px, 64px 64px;
  background-attachment: fixed;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* The display face and the chrome fill, same rules as the public
   site — including the per-line background-size, without which a
   heading that wraps fades to grey at the bottom. */
.display, h1, .record .big, .signin-card .mark .brand-word {
  font-family: "Saira Condensed", "Oswald", "Arial Narrow", system-ui, sans-serif;
}
h1, .brand-word {
  color: var(--chrome-1);
  background-image: linear-gradient(180deg,
              var(--chrome-1) 0%, var(--chrome-1) 26%,
              var(--chrome-2) 52%, var(--chrome-3) 74%,
              var(--chrome-2) 100%);
  background-repeat: repeat;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

.wrap { max-width: 900px; margin: 0 auto; padding: 26px 24px 80px; }

/* ---------- Top bar ---------- */
.topbar {
  background: var(--panel); border-bottom: 1px solid var(--edge);
  box-shadow: 0 1px 0 var(--glow-soft);
  position: sticky; top: 0; z-index: 20;
}
.topbar-in {
  max-width: 900px; margin: 0 auto; padding: 0 24px;
  display: flex; align-items: center; gap: 16px; min-height: 64px; flex-wrap: wrap;
}
.brand-lockup { display: inline-flex; align-items: center; gap: 9px; }
.brand-crest {
  height: 34px; width: auto; display: block; flex: none;
  filter: drop-shadow(0 0 14px var(--glow-soft));
}
.brand-word {
  font-weight: 800; font-size: 17px; text-transform: uppercase;
  letter-spacing: 0.01em; line-height: 1.1; background-size: 100% 1.1em;
  white-space: nowrap;
}
.brand-tick {
  font-family: "Saira", system-ui, sans-serif;
  font-size: 10px; color: var(--void); background: var(--accent);
  padding: 3px 6px; border-radius: 2px; margin-left: 2px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  box-shadow: 0 0 14px var(--glow);
}
.brand-logo { height: 34px; display: block; }
.topbar nav { display: flex; gap: 2px; margin-left: auto; flex-wrap: wrap; }
.topbar nav a {
  font-family: "Saira", system-ui, sans-serif;
  color: var(--text-dim); padding: 8px 11px; border-radius: 4px; font-size: 12px;
  text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600;
  position: relative; white-space: nowrap;
}
.topbar nav a:hover { background: var(--rise); color: var(--text); text-decoration: none; }
.topbar nav a.on { background: none; color: var(--text); }
.topbar nav a.on::after {
  content: ""; position: absolute; left: 11px; right: 11px; bottom: 1px;
  height: 2px; background: var(--accent); box-shadow: 0 0 10px var(--glow);
}

h1 {
  font-size: 34px; margin: 0 0 6px; letter-spacing: 0.005em;
  text-transform: uppercase; font-weight: 800; line-height: 1.1;
  background-size: 100% 1.1em;
  filter: drop-shadow(0 2px 14px var(--glow-soft));
}
h2 { font-family: "Saira", system-ui, sans-serif;
     font-size: 11px; margin: 0 0 14px; text-transform: uppercase;
     letter-spacing: 0.16em; color: var(--text-faint); font-weight: 700; }
.sub { color: var(--text-dim); font-size: 14px; margin: 0 0 24px; }

.panel {
  background: var(--panel); border: 1px solid var(--edge);
  border-radius: 6px; padding: 20px 22px; margin-bottom: 20px;
  position: relative; overflow: hidden;
}
/* The lit top edge, same as the cards on the public site. */
.panel::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--glow), transparent);
  opacity: .45;
}

/* ---------- The headline ---------- */
/* The sentence a client needs when somebody asks whether they were
   exercising due diligence. Not a list they have to count. */
.record {
  background: var(--panel); border: 1px solid var(--edge);
  border-left: 3px solid var(--clear);
  border-radius: 6px; padding: 24px 26px; margin-bottom: 24px;
  box-shadow: 0 18px 44px -30px var(--void);
}
/* The one sentence this whole product exists to produce. Set in the
   display face at a size nothing else on the page competes with —
   the status colour on the number does the pointing, so the metal
   treatment stays off it. */
.record .big {
  font-size: 27px; font-weight: 800; line-height: 1.25;
  text-transform: uppercase; letter-spacing: 0.005em;
}
.record .big em { font-style: normal; color: var(--clear); }
.record .since { color: var(--text-dim); font-size: 13.5px; margin-top: 7px; }

/* ---------- The timeline ---------- */
.visit {
  display: grid; grid-template-columns: 132px minmax(0,1fr) auto;
  gap: 18px; align-items: start;
  padding: 16px 0; border-bottom: 1px solid var(--edge-soft);
}
.visit:last-child { border-bottom: none; }
.visit .date { color: var(--text-dim); font-size: 13.5px; }
.visit .date strong { display: block; color: var(--text); font-size: 15px; }
.visit .site { font-weight: 600; }
.visit .times { color: var(--text-faint); font-size: 13px; margin-top: 3px; }
.visit .outcome { text-align: right; white-space: nowrap; }
@media (max-width: 640px) {
  .visit { grid-template-columns: minmax(0,1fr); gap: 6px; }
  .visit .outcome { text-align: left; }
}

.tag {
  display: inline-block; font-size: 11px; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 3px; border: 1px solid currentColor;
}
.tag.clear   { color: var(--clear); }
.tag.finding { color: var(--finding); }
.tag.soon    { color: var(--accent); }
/* Archived visits wear no status colour at all — deliberately.
   The old records carry no per-item result, so any of the four
   status colours would assert an outcome nobody ever recorded. */
.tag.archive { color: var(--text-faint); text-transform: none; letter-spacing: 0.02em; }

/* Contract terms. "expiring" borrows the warning colour rather than
   the overdue one: a term coming to an end is a date, not a fault. */
/* Invoice states. "issued" means owing — the accent, not a status
   colour, because owing money is not a fault. "overdue" is. */
.tag.issued  { color: var(--accent); }
.tag.overdue { color: var(--overdue); }
.tag.paid    { color: var(--clear); }
.tag.void    { color: var(--text-faint); }

.tag.live       { color: var(--clear); }
.tag.expiring   { color: var(--finding); }
.tag.expired    { color: var(--text-faint); }
.tag.superseded { color: var(--text-faint); }
.tag.ended      { color: var(--text-faint); }

/* ---------- Archived visits ---------- */
.archive-note { border-left: 3px solid var(--edge); }
.archive-note p { margin: 9px 0 0; color: var(--text-dim); font-size: 13.5px; }
.archive-log {
  margin: 0; padding: 15px 17px; overflow-x: auto;
  background: var(--rise); border: 1px solid var(--edge); border-radius: 6px;
  font: 13.5px/1.65 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--text); white-space: pre-wrap; word-break: break-word;
}

/* ---------- One report ---------- */
.item {
  border: 1px solid var(--edge); border-radius: 6px;
  padding: 15px 17px; margin-bottom: 11px; background: var(--rise);
}
.item.is-finding { border-left: 3px solid var(--finding); }
.item.is-clear   { border-left: 3px solid var(--clear); }
.item-head { display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.item-label { font-weight: 600; }
.item-note { margin: 9px 0 0; }

.facts { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 14px; }
@media (max-width: 620px) { .facts { grid-template-columns: minmax(0,1fr); } }
.fact { background: var(--rise); border: 1px solid var(--edge-soft);
        border-radius: 5px; padding: 12px 14px; }
.fact .k { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
           color: var(--text-faint); }
.fact .v { font-size: 15px; margin-top: 3px; }

.photo-strip { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 11px; }
.thumb {
  width: 96px; height: 96px; object-fit: cover; border-radius: 4px;
  border: 1px solid var(--edge); display: block; background: var(--void);
}
.thumb-missing {
  display: flex; align-items: center; justify-content: center;
  color: var(--overdue); font-weight: 700; border-style: dashed;
}

/* A photograph of something that was not on the checklist has no
   item label above it, so its caption is the only thing saying what
   the client is looking at. It gets the room to do that. */
.photo-fig { margin: 0; width: 160px; }
.photo-fig .thumb { width: 160px; height: 120px; }
.photo-fig figcaption {
  font-size: 12.5px; color: var(--text-faint); margin-top: 5px; line-height: 1.35;
}

/* A list that is a list of facts, not of links — the units that
   attended an incident. No bullets, because each line already starts
   with the service name doing that job. */
ul.plain { list-style: none; padding: 0; margin: 0; }
ul.plain li {
  padding: 7px 0; border-bottom: 1px solid var(--edge); font-size: 14px;
}
ul.plain li:last-child { border-bottom: none; }

/* ---------- Documents ---------- */
/* A table wider than the phone must scroll inside its own box.
   Left alone it pushes the whole page sideways, and then every
   other screen scrolls horizontally too. */
.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
th { text-align: left; font-size: 11px; text-transform: uppercase;
     letter-spacing: 0.08em; color: var(--text-faint);
     padding: 0 12px 9px; border-bottom: 1px solid var(--edge); }
td { padding: 12px; border-bottom: 1px solid var(--edge-soft); }
tbody tr:last-child td { border-bottom: none; }
.empty { color: var(--text-faint); padding: 22px 12px; }

/* ---------- Forms / sign-in ---------- */
label { display: block; font-size: 12px; color: var(--text-dim); margin-bottom: 5px; }
input[type=text], input[type=email], input[type=password] {
  width: 100%; background: var(--void); color: var(--text);
  border: 1px solid var(--edge); border-radius: 5px;
  padding: 10px 12px; font: inherit; font-size: 15px;
}
input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--edge-soft); }
.field { margin-bottom: 15px; }
button, .btn {
  background: var(--accent); color: var(--void); border: 1px solid var(--accent);
  padding: 11px 20px; border-radius: 4px; font-weight: 700; cursor: pointer;
  font-family: "Saira Condensed", "Oswald", "Arial Narrow", system-ui, sans-serif;
  font-size: 15px; text-transform: uppercase; letter-spacing: 0.08em;
  box-shadow: 0 8px 24px -10px var(--glow);
}
button:hover, .btn:hover { background: var(--accent-dark); color: var(--text); text-decoration: none; }
.btn-quiet {
  background: var(--rise); color: var(--text-dim); border: 1px solid var(--edge);
  box-shadow: none;
}
.btn-quiet:hover { border-color: var(--accent); color: var(--text); }

.flash { padding: 10px 14px; border-radius: 5px; margin: 0 0 16px;
         border: 1px solid var(--edge); background: var(--rise); }
.flash-error { border-color: var(--overdue); color: var(--overdue); }

.signin-wrap { min-height: 100vh; display: flex; align-items: center;
               justify-content: center; padding: 24px; position: relative; }
/* One light behind the card, so the sign-in screen is not a grey
   box on black — it is the first thing a new client ever sees. */
.signin-wrap::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(closest-side at 50% 34%, var(--glow-soft), transparent 70%);
  pointer-events: none;
}
.signin-card {
  width: 100%; max-width: 400px; background: var(--panel);
  border: 1px solid var(--edge); border-radius: 8px; padding: 32px 30px;
  position: relative; overflow: hidden;
  box-shadow: 0 30px 70px -40px var(--void);
}
.signin-card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--glow), transparent);
}
/* The lockup stacks here rather than sitting in a row — there is
   room, and centred under its own badge is how the mark was drawn. */
.signin-card .mark { text-align: center; margin-bottom: 8px; font-size: 19px; }
/* The stacked lockup on a sign-in card. A grid rather than a
   column: the crest takes a row of its own, and the name and its
   badge stay side by side on the next one — as a column the badge
   dropped onto a third line and read as a stray blue chip. */
.signin-card .mark .brand-lockup {
  display: grid; grid-template-columns: auto auto;
  justify-content: center; align-items: center; gap: 12px 7px;
}
.signin-card .mark .brand-crest { grid-column: 1 / -1; justify-self: center; }
.signin-card .mark .brand-crest { height: 66px; }
.signin-card .mark .brand-word { font-size: 22px; }
.signin-card .mark .brand-tick { margin-left: 0; }
.signin-card .tag-line, .signin-card .tag {
  display: block;
  text-align: center; color: var(--accent); font-size: 11px;
  font-family: "Saira", system-ui, sans-serif; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase; margin-bottom: 26px;
  border: none; padding: 0;
}
