/* ===========================================================================
   FutureIK console design system.

   Colours are taken from FutureIK Technologies Brand Identity Guidelines 2025,
   page 8. The primary palette is exactly four values:

       deep purple  #5C03BC   creativity, innovation, sophistication
       vibrant pink #E536AB   energy, a bold forward-thinking spirit
       black        #000000   professionalism, reliability
       white        #FFFFFF   clarity, openness

   The console is dark because it is looked at all day, so the base is black
   carrying a purple cast rather than the Asta navy: this is a FutureIK product
   surface first and a family member second.

   Two derived values, and the reason for each:

   --accent (#A76BFF) is the brand purple lightened for TEXT. #5C03BC on this
   background has a contrast ratio of 2.0:1, which is unreadable; the tint is
   5.7:1. The true brand purple is still used everywhere it belongs — as a fill
   behind white text, where it measures 9.6:1.

   --accent-2 (#E536AB) is the brand pink unmodified, used for the gradient and
   for focus rings. It is never put behind white text: that pairing is 3.9:1,
   which is below the line for anything but large type.

   Typography: the guideline names Manrope (corporate) and Verdana (dynamic).
   Manrope is listed first and used where it is installed. It is deliberately
   NOT fetched from a font CDN — this console is served entirely by one binary
   with no outbound requests, and a webfont would be the only thing on the page
   that could fail, hang, or tell someone else who is logging in.
   =========================================================================== */
:root{
  --bg:#0D0715; --panel:#170E28; --ink:#F3EEFB; --mut:#A99BC4; --line:#2E1F4D;
  --brand:#5C03BC; --brand-2:#E536AB;
  --accent:#A76BFF; --accent-dim:#7A28D9;
  --grad:linear-gradient(135deg,#5C03BC,#E536AB);
  --ok:#35d07f; --warn:#e0b256; --bad:#f0797a;
  --radius:12px;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font:15px/1.5 Manrope,system-ui,-apple-system,"Segoe UI",Verdana,Roboto,sans-serif;
}
a{color:var(--accent)}
button{font:inherit}

/* ---- login ---------------------------------------------------------------*/
#login{position:fixed;inset:0;display:grid;place-items:center;background:var(--bg);z-index:50}
.loginCard{width:min(400px,92vw);background:var(--panel);border:1px solid var(--line);
  border-radius:16px;padding:30px}
.brand{display:flex;align-items:center;gap:10px;margin-bottom:22px}
/* The FutureIK mark itself, served from /logo.png. Fixed box and
   object-fit:contain so a future re-export at a different aspect ratio cannot
   stretch the logo — the one thing a brand guideline is most emphatic about. */
.brandMark{width:26px;height:26px;flex:0 0 auto;object-fit:contain;display:block}
#shell.mini aside .brandMark,aside .brandMark{width:24px;height:24px}
.brand b{font-size:17px;letter-spacing:.2px}
.brand span{color:var(--mut);font-size:13px}
label.f{display:block;font-size:12.5px;color:var(--mut);margin:14px 0 6px}
input,select,textarea{
  width:100%;background:#0A0512;border:1px solid var(--line);color:var(--ink);
  border-radius:9px;padding:10px 12px;font:inherit;
}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent);outline-offset:0}
.btn{background:#241640;border:1px solid var(--line);color:var(--ink);
  border-radius:9px;padding:9px 15px;cursor:pointer}
.btn:hover{background:#301d55}
/* The brand CTA: a purple-to-pink fill with white on it (guideline p.9).
   White on #5C03BC measures 9.6:1, so the label is readable at the pink end
   of the gradient too. */
.btn.primary{background:var(--grad);border-color:transparent;color:#fff;font-weight:600}
.btn.primary:hover{filter:brightness(1.12)}
.btn.danger{border-color:#5d2b2b;color:#f0a0a0}
.btn:disabled{opacity:.5;cursor:default}
.err{margin-top:14px;padding:10px 12px;border-radius:9px;border:1px solid #5d2b2b;
  background:#2b1018;color:#f0a0a0;font-size:13px}
.err:empty{display:none}

/* ---- shell ---------------------------------------------------------------*/
#shell{display:none;grid-template-columns:236px 1fr;min-height:100vh}
#shell.mini{grid-template-columns:70px 1fr}
aside{background:var(--panel);border-right:1px solid var(--line);
  display:flex;flex-direction:column;padding:16px 12px;gap:4px}
aside .brand{padding:4px 8px 18px}
#shell.mini aside .brand span,#shell.mini .nav span{display:none}
.nav{display:flex;align-items:center;gap:11px;padding:10px 11px;border-radius:9px;
  color:var(--mut);cursor:pointer;font-size:14px;border:1px solid transparent}
.nav:hover{background:#211436;color:var(--ink)}
.nav.active{background:#2A1948;color:var(--ink);border-color:var(--line)}
.nav.active svg{stroke:var(--accent)}
.nav svg{width:18px;height:18px;flex:0 0 auto;stroke:currentColor;fill:none;stroke-width:1.8}
.navSpacer{flex:1}
main{display:flex;flex-direction:column;min-width:0}
.topbar{position:sticky;top:0;z-index:5;background:rgba(13,7,21,.92);
  backdrop-filter:blur(6px);border-bottom:1px solid var(--line);
  padding:14px 24px;display:flex;align-items:center;gap:14px}
.topbar h1{font-size:17px;margin:0;font-weight:600}
.who{margin-left:auto;display:flex;align-items:center;gap:12px;font-size:13px;color:var(--mut)}
.content{padding:24px;display:grid;gap:22px}
.page{display:none}
.page.on{display:grid;gap:22px}

/* ---- components ----------------------------------------------------------*/
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px}
.kpi{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:16px 18px}
.kpi .n{font-size:28px;font-weight:650;letter-spacing:-.5px}
.kpi .l{font-size:12.5px;color:var(--mut);margin-top:2px}
.kpi.warn .n{color:var(--warn)} .kpi.bad .n{color:var(--bad)} .kpi.good .n{color:var(--ok)}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:18px}
.card h2{font-size:12.5px;text-transform:uppercase;letter-spacing:.8px;color:var(--mut);
  margin:0 0 14px;font-weight:600}
table{width:100%;border-collapse:collapse;font-size:13.5px}
th,td{text-align:left;padding:9px 10px;border-bottom:1px solid var(--line)}
th{color:var(--mut);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.5px}
tbody tr:hover{background:#1F1436}
.empty{padding:26px;text-align:center;color:var(--mut);font-size:13.5px}
.pill{display:inline-block;padding:2px 9px;border-radius:999px;font-size:11.5px;font-weight:600}
.pill.ok{background:#10331f;color:#46d98a}
.pill.warn{background:#33280f;color:#e0b256}
.pill.bad{background:#331414;color:#f08a8a}
.pill.mut{background:#241640;color:var(--mut)}
.gauge{height:6px;border-radius:99px;background:#0A0512;overflow:hidden;margin-top:6px}
.gauge i{display:block;height:100%;background:var(--grad)}
.gauge i.over{background:var(--bad)}
.row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.grow{flex:1}
.mut{color:var(--mut)}
.sm{font-size:12.5px}
.modalBack{position:fixed;inset:0;background:rgba(6,2,12,.72);display:grid;place-items:center;z-index:40}
.modal{
  width:min(460px,92vw);background:var(--panel);border:1px solid var(--line);
  border-radius:16px;padding:24px;
  /* A dialog taller than the screen used to run off the bottom with no way to
     reach the buttons. Six fields on a 13" laptop is enough to do it. */
  max-height:min(88vh,900px);overflow-y:auto;overscroll-behavior:contain;
}
.modal h3{margin:0 0 4px;font-size:17px}

/* Vertical rhythm inside a dialog.
   A field carries its own top margin on the label, but a loose sentence — a
   hint, an explanation, a warning — carried none, so it sat flush against the
   input above it and read as if it were inside the box. Every direct child now
   gets space of its own, and no rule anywhere uses a negative margin to claw
   it back. */
.modal > *{margin-top:14px}
.modal > *:first-child{margin-top:0}
.modal > div > label.f:first-child{margin-top:0}
.modal .hint{margin-top:6px}
/* Two fields side by side — a date range, mostly. Stacks on a phone. */
.fieldRow{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media (max-width:520px){ .fieldRow{grid-template-columns:1fr;gap:0} }
.toast{position:fixed;right:20px;bottom:20px;z-index:60;background:var(--panel);
  border:1px solid var(--line);border-left:3px solid var(--brand-2);
  border-radius:10px;padding:12px 16px;font-size:13.5px;max-width:380px}
.toast.bad{border-left-color:var(--bad)}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:#3A2662;border-radius:99px}

/* ---- group headings (machines by client) ----------------------------------*/
.groupHead{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin:18px 0 6px;padding:0 2px}
.groupHead:first-child{margin-top:4px}
.groupHead b{font-size:14px}

/* ---- alert bar ------------------------------------------------------------*/
/* Not dismissible on purpose — see console.js. Full width so it cannot be
   mistaken for a toast that will go away by itself. */
.alertBar{background:#3a2410;border-bottom:1px solid #6b4415;color:#f0c48a;
  padding:11px 24px;font-size:13.5px;line-height:1.45}
.alertBar b{color:#ffb765}

/* ===========================================================================
   Responsive.
   Four bands, and the rule for each is about what the person is doing rather
   than about pixels: on a phone the sidebar is a bottom bar and tables become
   cards; on a tablet the sidebar is icons only; on a laptop everything shows;
   on a wide screen the content stops growing so lines stay readable.

   Tables are the hard part. A six-column table cannot shrink to 380px, so
   below 720px each row is re-laid-out as a stacked card and every cell gets
   its column name from a data-head attribute the table builder writes. No
   horizontal scrolling anywhere — a table you have to drag sideways on a phone
   is a table nobody reads.
   =========================================================================== */

/* Wide: stop the content sprawling. */
@media (min-width:1600px){
  .content{max-width:1500px;width:100%}
}

/* Laptop and below: tighten the padding before anything else changes. */
@media (max-width:1100px){
  .content{padding:18px}
  .topbar{padding:12px 18px}
  .alertBar{padding:10px 18px}
}

/* Tablet: icons-only sidebar, and let it be forced back open. */
@media (max-width:900px){
  #shell{grid-template-columns:64px 1fr}
  aside .brand span,.nav span{display:none}
  aside{padding:14px 8px}
  .nav{justify-content:center}
  #collapse{display:none}          /* nothing left to collapse */
  .kpis{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
}

/* Phone: sidebar becomes a bottom bar; tables become cards. */
@media (max-width:720px){
  #shell,#shell.mini{grid-template-columns:1fr;min-height:100dvh}
  aside{
    position:fixed;left:0;right:0;bottom:0;z-index:30;
    flex-direction:row;align-items:center;justify-content:space-around;
    border-right:none;border-top:1px solid var(--line);
    padding:6px 4px;gap:0;
    padding-bottom:calc(6px + env(safe-area-inset-bottom));
  }
  aside .brand,.navSpacer,#collapse{display:none}
  .nav{flex:1;flex-direction:column;gap:3px;padding:7px 4px;font-size:11px}
  .nav span{display:block;font-size:10.5px;line-height:1.1}
  .nav svg{width:20px;height:20px}
  main{padding-bottom:74px}        /* clear of the bottom bar */

  .topbar{padding:11px 14px;gap:8px}
  .topbar h1{font-size:15.5px}
  .who{font-size:12px;gap:8px}
  #whoami{max-width:38vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .content{padding:14px;gap:14px}
  .alertBar{padding:10px 14px;font-size:12.5px}
  .card{padding:14px}
  .kpis{grid-template-columns:1fr 1fr;gap:10px}
  .kpi{padding:13px 14px}
  .kpi .n{font-size:23px}

  /* Table → cards. */
  table,thead,tbody,tr,th,td{display:block}
  thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  tbody tr{
    border:1px solid var(--line);border-radius:10px;
    padding:10px 12px;margin-bottom:10px;background:#1B1130;
  }
  tbody tr:hover{background:#1B1130}
  td{
    border-bottom:none;padding:5px 0;
    display:flex;gap:12px;align-items:baseline;justify-content:space-between;
  }
  /* The column name, carried on the cell so it survives the reflow. */
  td::before{
    content:attr(data-head);
    color:var(--mut);font-size:11.5px;text-transform:uppercase;
    letter-spacing:.5px;flex:0 0 auto;
  }
  td:empty{display:none}
  td[data-head=""]{justify-content:flex-end}
  td[data-head=""]::before{content:none}

  .modal{width:min(460px,94vw);padding:18px;border-radius:14px}
  .toast{left:14px;right:14px;bottom:82px;max-width:none}
  .row{gap:9px}
  input,select,textarea{font-size:16px}   /* 16px stops iOS zooming on focus */
}

/* Short screens (a phone in landscape): give the content the height back. */
@media (max-height:520px) and (max-width:900px){
  .content{padding:10px}
  .kpi .n{font-size:20px}
}

/* Someone who has asked for less motion should not get a transition. */
@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
}

/* ---- detail sheet ---------------------------------------------------------*/
.modal.wide{width:min(620px,94vw)}
.detail{display:grid;grid-template-columns:minmax(120px,180px) 1fr;gap:2px 18px;
  margin-top:14px}
.detailRow{display:contents}
.detailRow>div{padding:7px 0;border-bottom:1px solid var(--line);min-width:0;
  overflow-wrap:anywhere}
@media (max-width:720px){
  .detail{grid-template-columns:1fr;gap:0}
  .detailRow>div:first-child{border-bottom:none;padding-bottom:0}
}
.btn.sm{padding:5px 10px;font-size:12.5px}

/* ---- pair codes -----------------------------------------------------------
   A code exists to be read off a screen and typed into another one, usually by
   somebody standing up. So it is set large, in a monospaced face with wide
   letter-spacing, and it is selectable — the two things that go wrong are
   misreading a character and failing to select the whole thing. */
.codeList{display:grid;gap:10px;margin-top:14px}
.bigCode{
  display:flex;align-items:center;gap:12px;justify-content:space-between;
  background:#0A0512;border:1px solid var(--line);border-radius:10px;
  padding:12px 14px;
}
.bigCode code{
  font:600 22px/1.2 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  letter-spacing:3px;color:var(--ink);user-select:all;
}
/* The instruction that goes with the codes. Kept next to them rather than in a
   help page, because this is the moment somebody needs it. */
.handover{margin-top:16px;padding:12px 14px;border-radius:10px;
  border:1px solid var(--line);background:#130B22;font-size:13px;color:var(--mut)}
.handover b{color:var(--ink)}
.handover ol{margin:8px 0 0;padding-left:20px}
.handover li{margin:3px 0}
@media (max-width:720px){
  .bigCode code{font-size:19px;letter-spacing:2px}
  .bigCode{flex-wrap:wrap}
}

/* A short explanation under a field, so the console teaches rather than
   assumes. Muted enough to skip once you know it. */
.hint{display:block;margin-top:5px;font-size:12px;color:var(--mut);line-height:1.4}
