/* The surfbee.io design system.
   
   These are the CSS custom properties the live site declares on :root, read out of the
   running page rather than sampled from a screenshot. Same system, same names where the
   name still makes sense, so a change there is a findable change here.
   
   The desk is internal staff tooling, so the typeface is served from this origin rather
   than from Google's CDN. One fewer external dependency, and the desk does not announce
   to a third party who is looking at the fleet. */

@font-face {
  font-family: "Space Grotesk";
  /* The variable font: Google publishes no static cuts for this family. */
  src: url("space-grotesk.ttf") format("truetype-variations");
  font-weight: 300 700;
  font-display: swap;
}

:root {
  /* --figma-paper / --color-paper / --figma-mist */
  --bg: #f5f2e9;
  --surface: #ffffff;
  --surface-sunk: #eff9f0;
  --mist: #d9e8e2;

  /* --color-muted, and an outline with enough weight to read on cream */
  --border: #cfdbd7;

  /* --text-on-light-* */
  --text: #172b36;
  --muted: #465b60;
  --faint: #53676c;

  /* Ink leads on light, not yellow: --primary is used for text and borders as well as
     for buttons, and yellow text on cream cannot be read. The site solves the same
     problem with a separate --color-brand-text, and so do we. */
  --accent: #172b36;
  --accent-text: #eff9f0;

  /* --figma-brand and --color-brand-text */
  --brand: #ffc801;
  --brand-hover: #eab800;
  --brand-text: #806500;
  --brand-ink: #172b36;

  --teal: #114c5a;
  --focus: #0a7180;

  /* Status is not on the site, which never has to say "this failed". Amber is
     deliberately NOT brand yellow: a warning that looks like a button is a warning
     nobody reads as a warning. */
  --good-bg: #ddf0e4;
  --good-text: #14711a;
  --warn-bg: #fcebcf;
  --warn-text: #8a5a00;
  --bad-bg: #fbe4e4;
  --bad-text: #a32d2d;

  /* --radius-card, --radius-control, --radius-sm */
  --radius: 22px;
  --radius-control: 999px;
  --radius-sm: 4px;

  --font-heading: "Space Grotesk", system-ui, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* --knowledge-surface-* : the graded darks behind the site's dark sections */
    --bg: #0b1f28;
    --surface: #112934;
    --surface-sunk: #0d252d;
    --mist: #173540;

    --border: #2b4652;

    /* --text-on-dark-* */
    --text: #eff9f0;
    --muted: #bdccc8;
    --faint: #94a7a3;

    /* On dark the site does lead with yellow, and it has the contrast to carry it. */
    --accent: #ffc801;
    --accent-text: #172b36;

    --brand: #ffc801;
    --brand-hover: #eab800;
    --brand-text: #ffc801;
    --brand-ink: #172b36;

    --teal: #5fb8c6;
    --focus: #5fb8c6;

    --good-bg: #13302166;
    --good-text: #5fd964;
    --warn-bg: #3a2a10;
    --warn-text: #e8b86a;
    --bad-bg: #3a1e1e;
    --bad-text: #ef8c8c;
  }
}

* { box-sizing: border-box; }

/* A display rule beats the hidden attribute, and .gate sets display:grid. Without this the
   sign-in panel stays on screen after sign-in. */
[hidden] { display: none !important; }

body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}

.mono { font-family: ui-monospace, "Cascadia Mono", Consolas, "Courier New", monospace; }

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  /* The site never goes heavier than 500. Space Grotesk at 500 is already assertive. */
  font-weight: 500;
  letter-spacing: -.03em;
}
h1 { font-size: 1.5rem; margin: 0; }
h2 { font-size: 1.15rem; margin: 0 0 1rem; }
p { margin: 0; }
.muted { color: var(--muted); }
.hint { color: var(--faint); font-size: .85rem; margin-top: .35rem; }
.centre { text-align: center; }

/* ---------- sign in ---------- */
.gate {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 1rem;
}
.gate-card { width: min(100%, 380px); }
.gate-card h1 { margin-bottom: .25rem; }
.gate-card p { margin-bottom: 1.25rem; }
.gate-card label { display: block; font-weight: 500; margin-bottom: .35rem; }

/* ---------- layout ---------- */
header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.5rem 1rem 0;
  max-width: 1100px;
  margin: 0 auto;
}

main {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 880px) {
  main { grid-template-columns: 1.3fr 1fr; }
  .wide { grid-column: 1 / -1; }
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
}

/* ---------- form ---------- */
.field { margin-bottom: 1rem; }
.field > label, legend { display: block; font-weight: 500; margin-bottom: .35rem; }

.row { display: grid; gap: 1rem; grid-template-columns: 1fr 1fr; }

input[type="text"], input[type="password"], input:not([type]) {
  width: 100%;
  padding: .7rem .75rem;
  font-size: 1rem;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}
#serial { font-size: 1.25rem; letter-spacing: .03em; padding: .8rem .75rem; }

input:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

fieldset.verdict {
  border: 0;
  padding: 0;
  margin: 0 0 1rem;
}
.radio {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  margin-right: 1.25rem;
  font-weight: 400;
}

button {
  font: inherit;
  border-radius: 8px;
  cursor: pointer;
  padding: .7rem 1rem;
}
button.primary {
  width: 100%;
  background: var(--accent);
  color: var(--accent-text);
  border: 0;
  font-weight: 600;
  font-size: 1.05rem;
  padding: .85rem 1rem;
}
button.primary:disabled { opacity: .55; cursor: progress; }
button.ghost {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
}

/* ---------- serial echo: the safeguard ---------- */
.echo {
  margin-top: .5rem;
  padding: .6rem .7rem;
  border-radius: 8px;
  font-size: 1.05rem;
  min-height: 1rem;
  display: none;
}
.echo.ok { display: block; background: var(--good-bg); color: var(--good-text); }
.echo.bad { display: block; background: var(--bad-bg); color: var(--bad-text); }

.warnings { list-style: none; margin: .5rem 0 0; padding: 0; }
.warnings li {
  background: var(--warn-bg);
  color: var(--warn-text);
  padding: .5rem .65rem;
  border-radius: 8px;
  font-size: .9rem;
  margin-bottom: .35rem;
}

/* ---------- result ---------- */
.placeholder { color: var(--faint); }

.result-serial { font-size: 1.3rem; font-weight: 600; }
.result-model { color: var(--muted); margin-bottom: 1rem; }

.token {
  background: var(--warn-bg);
  color: var(--warn-text);
  border-radius: 8px;
  padding: .85rem;
  margin-top: 1rem;
}
.token strong { display: block; margin-bottom: .35rem; }
.token code {
  display: block;
  word-break: break-all;
  background: var(--surface);
  color: var(--text);
  padding: .55rem;
  border-radius: 6px;
  margin: .5rem 0;
  font-size: .9rem;
}
.token button { background: var(--surface); border: 1px solid var(--border); color: var(--text); padding: .45rem .8rem; }

.error {
  background: var(--bad-bg);
  color: var(--bad-text);
  padding: .65rem .75rem;
  border-radius: 8px;
  margin-top: .75rem;
}

/* ---------- recent ---------- */
table { width: 100%; border-collapse: collapse; font-size: .92rem; }
th {
  text-align: left;
  font-weight: 500;
  color: var(--faint);
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding-bottom: .5rem;
}
td { padding: .55rem 0; border-top: 1px solid var(--border); }
td:first-child { font-family: ui-monospace, Consolas, monospace; }

.pill {
  display: inline-block;
  padding: .15rem .5rem;
  border-radius: 999px;
  font-size: .78rem;
}
.pill.registered { background: var(--good-bg); color: var(--good-text); }
.pill.awaiting { background: var(--bg); color: var(--faint); border: 1px solid var(--border); }

/* ---------- organisation picking ---------- */
.newOrg {
  background: var(--warn-bg);
  color: var(--warn-text);
  padding: .6rem .7rem;
  border-radius: 8px;
  margin-bottom: 1rem;
  font-size: .92rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
}
button.link {
  background: transparent;
  border: 1px solid currentColor;
  color: inherit;
  padding: .3rem .7rem;
  font-size: .88rem;
  white-space: nowrap;
}

dialog {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  padding: 1.5rem;
  width: min(100%, 420px);
}
dialog::backdrop { background: rgba(0, 0, 0, .55); }
dialog h2 { margin-bottom: .35rem; }
dialog .hint { margin-bottom: 1.25rem; }
.dialog-actions { display: flex; gap: .75rem; margin-top: 1.25rem; }
.dialog-actions button { flex: 1; }

.owner-cell { color: var(--muted); }


/* ---------- the desk ---------- */

.tabs {
  display: flex;
  gap: .25rem;
  padding: 0 1.5rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--muted);
  padding: .7rem .9rem;
  font-size: .95rem;
}
.tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); }

/* A count beside a queue is the difference between a tab people open and one they
   remember to open. Hidden entirely at zero rather than showing a reassuring nought. */
.badge {
  display: inline-block;
  margin-left: .35rem;
  padding: .05rem .4rem;
  border-radius: 999px;
  background: var(--warn-bg);
  color: var(--warn-text);
  font-size: .78rem;
}

.stack { display: flex; flex-direction: column; gap: 1rem; }

.candidate {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
}
.candidate header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0;
  margin-bottom: .5rem;
  background: none;
  border: none;
}
.candidate h3 { margin: 0; font-size: 1.05rem; font-weight: 600; }
.candidate .domains { font-size: .9rem; }
.candidate ul { margin: .5rem 0 0; padding-left: 1.1rem; font-size: .9rem; color: var(--muted); }
.candidate .actions { margin-top: .85rem; display: flex; gap: .6rem; align-items: center; }

/* Loud on purpose. Confirming a duplicate is the one mistake this queue exists to stop,
   and it is invisible afterwards. */
.flag {
  margin-top: .6rem;
  padding: .55rem .7rem;
  border-radius: 8px;
  font-size: .9rem;
}
.flag.match { background: var(--bad-bg); color: var(--bad-text); }
.flag.freemail { background: var(--warn-bg); color: var(--warn-text); }

.waiting { font-size: .85rem; color: var(--faint); white-space: nowrap; }
.waiting.stale { color: var(--warn-text); font-weight: 500; }

td.grounded { color: var(--bad-text); font-weight: 500; }
tr.is-grounded td:first-child { border-left: 3px solid var(--bad-text); padding-left: .5rem; }

.note {
  border-top: 1px solid var(--border);
  padding: .7rem 0;
}
.note h4 { margin: 0 0 .2rem; font-size: .8rem; font-weight: 500; color: var(--faint);
  text-transform: uppercase; letter-spacing: .04em; }
.note .age { float: right; text-transform: none; letter-spacing: 0; }
.note .age.stale { color: var(--warn-text); }
.note.sensitive { background: var(--warn-bg); padding-left: .6rem; padding-right: .6rem;
  border-radius: 6px; }

button.back { margin-bottom: 1rem; }


/* ---------------------------------------------------------------- the site's controls

   Two things carry most of the brand: the pill and the typeface on it. Buttons on
   surfbee.io are --radius-control, which is 999px, at every size. */

button,
.tab,
input[type="submit"] {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: -.01em;
}

button {
  border-radius: var(--radius-control);
}

/* The one filled-yellow action per view, as the site uses it: primary means "do this",
   and everything else is an outline. */
button.primary {
  background: var(--brand);
  color: var(--brand-ink);
  border-color: transparent;
}

button.primary:hover { background: var(--brand-hover); }

button.ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
}

/* The site's focus ring, which is a real colour rather than the browser default. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* Small, dense things keep --radius-sm. A 22px chip is a lozenge. */
.badge, .pill, .flag, code { border-radius: var(--radius-sm); }

/* ---------------------------------------------------------------- the mark

   The same bee that is on the vessels, on the operational app's splash, and on the
   tablet's front door. The desk had nothing, which made it the only Surfbee surface a
   member of staff could land on and not recognise. */

header {
  align-items: center;
}

.mark {
  flex: 0 0 auto;
  display: block;
}

.header-text {
  flex: 1 1 auto;
}

.gate-mark {
  display: block;
  margin: 0 auto .9rem;
}

.gate-card {
  text-align: center;
}

/* The fields stay left-aligned. Centred labels above left-aligned inputs read as a
   mistake, and the eye has to travel further to find where to type. */
.gate-card label,
.gate-card .hint,
.gate-card .error {
  text-align: left;
}

/* ---------------------------------------------------------------- opening a hull */

tbody tr.row-open {
  cursor: pointer;
}

tbody tr.row-open:hover {
  background: var(--surface-sunk);
}

#vessel-detail {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

.detail-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: .75rem;
}

.detail-head h3 {
  margin: 0;
  font-family: "Space Grotesk", system-ui, sans-serif;
  font-weight: 500;
}

.detail-head p {
  margin: .15rem 0 0;
}

#vessel-detail a {
  color: inherit;
}

.panel-actions {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.section-heading {
  margin: 1.5rem 0 .5rem;
  font-family: "Space Grotesk", system-ui, sans-serif;
  font-weight: 500;
  font-size: 1rem;
}

#buildStatus {
  margin-top: .6rem;
}

input[type="file"] {
  font: inherit;
  color: var(--muted);
}

.ghost.small {
  padding: .2rem .7rem;
  font-size: .8rem;
}

.fault {
  padding: .9rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.fault-head {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: baseline;
}

.fault p { margin: .4rem 0 0; }

.fault details { margin-top: .6rem; }

.fault summary {
  cursor: pointer;
  color: var(--muted);
  font-size: .9rem;
}

.fault pre {
  margin: .5rem 0 0;
  padding: .7rem;
  background: var(--surface-sunk);
  border-radius: var(--radius-sm);
  font-size: .82rem;
  white-space: pre-wrap;
  word-break: break-word;
}
