:root{
  --bg:#0f1419; --panel:#171d24; --panel2:#1e252e; --line:#2a3441;
  --text:#e6edf3; --dim:#8b98a5; --dimmer:#5f6b78;
  --accent:#4a9eff; --accent2:#2b7fd9;
  --ok:#3fb950; --warn:#d29922; --bad:#f85149; --purple:#a371f7;
  --radius:10px; --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--text); font-size:15px; line-height:1.55;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
a{color:var(--accent); text-decoration:none}
a:hover{text-decoration:underline}
h1{font-size:1.55rem;margin:0 0 .2rem}
h2{font-size:1.15rem;margin:0 0 .6rem}
h3{font-size:1rem;margin:0 0 .4rem}
p{margin:.4rem 0}
code,kbd{font-family:var(--mono);font-size:.86em;background:var(--panel2);
  padding:.1rem .35rem;border-radius:4px;border:1px solid var(--line)}
hr{border:0;border-top:1px solid var(--line);margin:1.2rem 0}

/* ---------------- layout ---------------- */
.topbar{
  display:flex;align-items:center;gap:.25rem;flex-wrap:wrap;
  background:var(--panel);border-bottom:1px solid var(--line);
  padding:.5rem 1rem;position:sticky;top:0;z-index:50;
}
.brand{font-weight:700;font-size:1.05rem;margin-right:1rem;color:var(--text);
  display:flex;align-items:center;gap:.45rem}
.brand .dot{width:9px;height:9px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 8px var(--accent)}
.nav{display:flex;gap:.15rem;flex-wrap:wrap;flex:1}
.nav a{
  color:var(--dim);padding:.35rem .7rem;border-radius:7px;font-size:.9rem;
  white-space:nowrap;
}
.nav a:hover{background:var(--panel2);color:var(--text);text-decoration:none}
.nav a.active{background:var(--accent);color:#fff}
.userbox{display:flex;align-items:center;gap:.6rem;font-size:.85rem;color:var(--dim)}
.navtoggle{
  display:none;align-items:center;justify-content:center;gap:.4rem;
  background:var(--panel2);border:1px solid var(--line);color:var(--text);
  border-radius:8px;padding:.45rem .7rem;font-size:.85rem;font-weight:600;
  cursor:pointer;font-family:inherit;
}
.navtoggle:hover{border-color:var(--accent)}
.navtoggle .bars{display:inline-flex;flex-direction:column;gap:3px}
.navtoggle .bars i{display:block;width:15px;height:2px;background:currentColor;
  border-radius:2px}
.wrap{max-width:1400px;margin:0 auto;padding:1.2rem 1rem 4rem}
.page-head{display:flex;align-items:flex-start;justify-content:space-between;
  gap:1rem;flex-wrap:wrap;margin-bottom:1rem}
.sub{color:var(--dim);font-size:.9rem;margin:0}

/* ---------------- cards & grid ---------------- */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:1rem;margin-bottom:1rem}
.card.tight{padding:.7rem .9rem}
.grid{display:grid;gap:1rem}
.g2{grid-template-columns:repeat(auto-fit,minmax(330px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(175px,1fr))}
.stat{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:.85rem 1rem}
.stat .label{color:var(--dim);font-size:.76rem;text-transform:uppercase;
  letter-spacing:.05em;display:flex;align-items:center;gap:.3rem}
.stat .value{font-size:1.7rem;font-weight:700;line-height:1.2;margin-top:.15rem}
.stat .value.sm{font-size:1.25rem}
.stat .foot{color:var(--dimmer);font-size:.8rem}

/* ---------------- tables ---------------- */
table{width:100%;border-collapse:collapse;font-size:.9rem}
th{text-align:left;color:var(--dim);font-weight:600;font-size:.76rem;
  text-transform:uppercase;letter-spacing:.04em;padding:.5rem .55rem;
  border-bottom:1px solid var(--line);white-space:nowrap}
td{padding:.5rem .55rem;border-bottom:1px solid var(--line);vertical-align:middle}
tbody tr:hover{background:var(--panel2)}
tr.urgent td{background:rgba(248,81,73,.07)}
.num{text-align:right;font-variant-numeric:tabular-nums}
.tblwrap{overflow-x:auto}
.empty{color:var(--dim);text-align:center;padding:2rem 1rem}

/* ---------------- forms ---------------- */
label{display:block;font-size:.8rem;color:var(--dim);margin-bottom:.2rem;
  font-weight:500}
input,select,textarea{
  background:var(--panel2);color:var(--text);border:1px solid var(--line);
  border-radius:7px;padding:.45rem .6rem;font-size:.9rem;font-family:inherit;
  width:100%;
}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 2px rgba(74,158,255,.15)}
input[type=checkbox]{width:auto}
textarea{resize:vertical;min-height:90px}
textarea.code{font-family:var(--mono);font-size:.9rem;line-height:1.7}
.field{margin-bottom:.75rem}
.row{display:flex;gap:.6rem;flex-wrap:wrap}
.row>*{flex:1;min-width:130px}
.inline{display:flex;gap:.5rem;align-items:flex-end;flex-wrap:wrap}

.btn{
  display:inline-flex;align-items:center;gap:.35rem;
  background:var(--accent);color:#fff;border:1px solid transparent;
  padding:.45rem .9rem;border-radius:7px;font-size:.88rem;font-weight:600;
  cursor:pointer;font-family:inherit;white-space:nowrap;
}
.btn:hover{background:var(--accent2);text-decoration:none}
.btn.ghost{background:transparent;border-color:var(--line);color:var(--text)}
.btn.ghost:hover{background:var(--panel2)}
.btn.danger{background:transparent;border-color:var(--bad);color:var(--bad)}
.btn.danger:hover{background:rgba(248,81,73,.12)}
.btn.sm{padding:.25rem .6rem;font-size:.8rem}
.btn:disabled{opacity:.5;cursor:not-allowed}

/* ---------------- badges ---------------- */
.badge{display:inline-block;padding:.15rem .5rem;border-radius:20px;
  font-size:.74rem;font-weight:600;white-space:nowrap;border:1px solid}
.b-draft{color:var(--dimmer);border-color:var(--line);background:var(--panel2)}
.b-quoted{color:#c9a3ff;border-color:rgba(163,113,247,.4);background:rgba(163,113,247,.12)}
.b-paid{color:#6cb6ff;border-color:rgba(74,158,255,.4);background:rgba(74,158,255,.12)}
.b-shipped,.b-in_transit{color:#e3b341;border-color:rgba(210,153,34,.4);
  background:rgba(210,153,34,.12)}
.b-customs{color:#ff9a5c;border-color:rgba(255,154,92,.4);background:rgba(255,154,92,.12)}
.b-received{color:#56d364;border-color:rgba(63,185,80,.4);background:rgba(63,185,80,.12)}
.b-cancelled{color:var(--bad);border-color:rgba(248,81,73,.4);background:rgba(248,81,73,.1)}
.pill{display:inline-block;padding:.1rem .45rem;border-radius:5px;font-size:.75rem;
  background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  font-family:var(--mono)}
.ok{color:var(--ok)} .warn{color:var(--warn)} .bad{color:var(--bad)}
.dim{color:var(--dim)} .dimmer{color:var(--dimmer)}
.mono{font-family:var(--mono)}
.small{font-size:.82rem}

/* ---------------- notices ---------------- */
.notice{padding:.7rem .9rem;border-radius:8px;margin-bottom:1rem;font-size:.9rem;
  border:1px solid}
.notice.info{background:rgba(74,158,255,.1);border-color:rgba(74,158,255,.35)}
.notice.good{background:rgba(63,185,80,.1);border-color:rgba(63,185,80,.35)}
.notice.warnbox{background:rgba(210,153,34,.1);border-color:rgba(210,153,34,.35)}
.notice.err{background:rgba(248,81,73,.1);border-color:rgba(248,81,73,.35)}

/* ---------------- tooltips ---------------- */
.tip{position:relative;display:inline-flex;align-items:center;
  justify-content:center;width:15px;height:15px;border-radius:50%;
  background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  font-size:10px;font-weight:700;cursor:help;flex:none;vertical-align:middle;
  margin-left:.25rem;font-style:normal}
.tip::after{
  content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;
  transform:translateX(-50%);background:#0b0f14;color:var(--text);
  border:1px solid var(--line);border-radius:8px;padding:.55rem .7rem;
  font-size:.8rem;font-weight:400;line-height:1.45;width:max-content;
  max-width:290px;text-align:left;opacity:0;pointer-events:none;
  transition:opacity .12s;z-index:100;box-shadow:0 6px 20px rgba(0,0,0,.5);
  white-space:pre-line;
}
.tip:hover::after,.tip:focus::after,.tip.show::after{opacity:1}
.tip.left::after{left:auto;right:-6px;transform:none}
.tip.down::after{bottom:auto;top:calc(100% + 8px)}
/* Touch devices have no hover, so app.js toggles .show on tap. Anchor the
   bubble to the viewport edges instead of the icon so it can't overflow. */
@media (hover:none){
  .tip{width:20px;height:20px;font-size:11px}
  .tip::after{
    position:fixed;left:1rem;right:1rem;bottom:auto;
    top:var(--tip-y,50%);transform:none;width:auto;max-width:none;
  }
  .tip.tip-above::after{top:auto;bottom:calc(100vh - var(--tip-y,50%))}
  .tip:hover::after,.tip:focus::after{opacity:0}
  .tip.show::after{opacity:1}
}

/* ---------------- board ---------------- */
.board{display:grid;grid-template-columns:repeat(7,minmax(215px,1fr));
  gap:.7rem;overflow-x:auto;padding-bottom:1rem}
.bcol{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:.6rem;min-height:180px}
.bcol.over{border-color:var(--accent);background:rgba(74,158,255,.06)}
.bcol h3{font-size:.8rem;text-transform:uppercase;letter-spacing:.04em;
  color:var(--dim);display:flex;justify-content:space-between;margin-bottom:.6rem}
.bcard{background:var(--panel2);border:1px solid var(--line);border-radius:8px;
  padding:.55rem .65rem;margin-bottom:.5rem;cursor:grab;font-size:.85rem}
.bcard:active{cursor:grabbing}
.bcard.dragging{opacity:.4}
.bcard .t{font-weight:600;display:flex;justify-content:space-between;gap:.4rem}
.bcard .m{color:var(--dim);font-size:.78rem;margin-top:.15rem}
/* Touch has no HTML5 drag-and-drop, so every card carries a status picker.
   Hidden on pointer devices where dragging works. */
.bcard .movebar{display:none;align-items:center;gap:.35rem;margin-top:.5rem}
.bcard .movebar select{font-size:.8rem;padding:.3rem .4rem;flex:1}
.bcard .movebar .lbl{color:var(--dimmer);font-size:.72rem;flex:none}
@media (hover:none){
  .bcard{cursor:default}
  .bcard .movebar{display:flex}
}

/* ---------------- chat ---------------- */
.chatwrap{display:flex;flex-direction:column;
  height:calc(100vh - 175px);height:calc(100dvh - 175px);
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius)}
.chatlog{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;
  gap:.8rem}
.msg{max-width:min(760px,88%);padding:.65rem .85rem;border-radius:12px;
  font-size:.92rem;white-space:pre-wrap;word-wrap:break-word}
.msg.user{align-self:flex-end;background:var(--accent);color:#fff;
  border-bottom-right-radius:3px}
.msg.bot{align-self:flex-start;background:var(--panel2);border:1px solid var(--line);
  border-bottom-left-radius:3px}
.msg .meta{font-size:.72rem;opacity:.7;margin-top:.4rem;display:flex;gap:.5rem;
  flex-wrap:wrap;align-items:center}
.msg strong{font-weight:700}
.chatbar{border-top:1px solid var(--line);padding:.7rem;display:flex;gap:.5rem;
  align-items:flex-end}
.chatbar textarea{min-height:44px;max-height:170px}
.chips{display:flex;gap:.4rem;flex-wrap:wrap;padding:0 .7rem .6rem}
.chip{background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  border-radius:20px;padding:.25rem .7rem;font-size:.78rem;cursor:pointer}
.chip:hover{border-color:var(--accent);color:var(--text)}
.typing{color:var(--dim);font-size:.85rem;font-style:italic}

/* ---------------- misc ---------------- */
details.help{border:1px solid var(--line);border-radius:8px;padding:.6rem .8rem;
  margin-bottom:.6rem;background:var(--panel)}
details.help summary{cursor:pointer;font-weight:600;color:var(--text)}
details.help[open] summary{margin-bottom:.5rem;color:var(--accent)}
.kv{display:grid;grid-template-columns:auto 1fr;gap:.3rem .9rem;font-size:.88rem}
.kv dt{color:var(--dim)}
.kv dd{margin:0}
.hist{list-style:none;padding:0;margin:0;font-size:.85rem}
.hist li{padding:.4rem 0;border-bottom:1px solid var(--line)}
.hist li:last-child{border:0}
.center-card{max-width:400px;margin:5vh auto}
.footer{color:var(--dimmer);font-size:.8rem;text-align:center;margin-top:2rem}
/* ================================================================
   MOBILE
   Phones were an afterthought in v1. Everything below fixes that.
   Notes on the non-obvious bits:
   - Inputs must be >=16px or iOS Safari zooms the page on focus and
     never zooms back out. That alone caused most of the "scrolling
     feels wrong" symptoms.
   - 100vh on mobile includes the browser chrome, so a 100vh panel
     puts its bottom edge under the address bar. dvh fixes it.
   - Tables become stacked cards; app.js copies each column header
     onto its cells as data-label so the labels below have something
     to show.
   ================================================================ */

/* Tap targets and text sizing on any touch device, at any width */
@media (hover:none){
  input,select,textarea{font-size:16px}
  .btn{padding:.55rem 1rem}
  .btn.sm{padding:.4rem .75rem;font-size:.85rem}
  .nav a{padding:.6rem .75rem}
  a{-webkit-tap-highlight-color:rgba(74,158,255,.2)}
}

@media (max-width:900px){
  .board{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
}

@media (max-width:760px){
  html{-webkit-text-size-adjust:100%}
  body{overflow-x:hidden}
  .wrap{padding:.75rem .7rem 3.5rem}

  h1{font-size:1.3rem}
  h2{font-size:1.05rem}

  /* ---- header: collapse the 13-link nav behind a toggle ---- */
  .topbar{
    padding:.5rem .7rem;gap:.5rem;
    padding-left:max(.7rem,env(safe-area-inset-left));
    padding-right:max(.7rem,env(safe-area-inset-right));
    flex-wrap:wrap;
  }
  .brand{margin-right:auto;font-size:1rem}
  .navtoggle{display:inline-flex}
  .nav{
    display:none;order:3;flex-basis:100%;flex-direction:column;gap:.1rem;
    margin-top:.4rem;padding-top:.5rem;border-top:1px solid var(--line);
    max-height:70vh;overflow-y:auto;-webkit-overflow-scrolling:touch;
  }
  .nav.open{display:flex}
  .nav a{padding:.65rem .8rem;border-radius:8px;font-size:.95rem}
  .userbox{font-size:.8rem;gap:.5rem}

  /* ---- page furniture ---- */
  .page-head{gap:.6rem;margin-bottom:.8rem}
  .page-head > .inline,.page-head > div:last-child{width:100%}
  .page-head .btn{flex:1;justify-content:center}
  .card{padding:.8rem;border-radius:9px}
  .grid{gap:.7rem}
  .g2,.g3,.g4{grid-template-columns:1fr}
  .stat{padding:.7rem .8rem}
  .stat .value{font-size:1.45rem}

  /* two stats side by side reads better than one giant column */
  .grid.g4{grid-template-columns:1fr 1fr}
  .grid.g4 .stat .label{font-size:.7rem}

  /* ---- forms ---- */
  .row{gap:.5rem}
  .row>*{min-width:100%}
  .inline{gap:.5rem}
  .inline>*{min-width:0}
  .inline .btn{width:100%;justify-content:center}
  .inline form{width:100%}
  .inline form .btn{width:100%}
  textarea{min-height:110px}

  /* ---- tables become cards ---- */
  .tblwrap{overflow-x:visible}
  .tblwrap[data-mobile="scroll"]{
    overflow-x:auto;-webkit-overflow-scrolling:touch;
    background:linear-gradient(90deg,var(--panel) 30%,transparent),
               linear-gradient(90deg,transparent,var(--panel) 70%) 100% 0;
    background-size:28px 100%,28px 100%;background-repeat:no-repeat;
    background-attachment:local,local;
  }
  .tblwrap[data-mobile="scroll"]::before{
    content:"Swipe sideways to see every column";
    display:block;color:var(--dimmer);font-size:.75rem;padding:0 0 .4rem;
  }
  .tblwrap[data-mobile="scroll"] table{min-width:560px}

  .tblwrap:not([data-mobile="scroll"]) table,
  .tblwrap:not([data-mobile="scroll"]) thead,
  .tblwrap:not([data-mobile="scroll"]) tbody,
  .tblwrap:not([data-mobile="scroll"]) tfoot,
  .tblwrap:not([data-mobile="scroll"]) tr,
  .tblwrap:not([data-mobile="scroll"]) th,
  .tblwrap:not([data-mobile="scroll"]) td{display:block}

  .tblwrap:not([data-mobile="scroll"]) thead{
    position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  }
  .tblwrap:not([data-mobile="scroll"]) tbody tr,
  .tblwrap:not([data-mobile="scroll"]) tfoot tr{
    background:var(--panel2);border:1px solid var(--line);border-radius:9px;
    padding:.5rem .65rem;margin-bottom:.6rem;
  }
  .tblwrap:not([data-mobile="scroll"]) tbody tr:hover{background:var(--panel2)}
  .tblwrap:not([data-mobile="scroll"]) tr.urgent{
    border-color:rgba(248,81,73,.45);background:rgba(248,81,73,.08);
  }
  .tblwrap:not([data-mobile="scroll"]) td{
    border:0;padding:.28rem 0;display:flex;gap:.7rem;align-items:center;
    justify-content:space-between;text-align:right;
  }
  .tblwrap:not([data-mobile="scroll"]) td::before{
    content:attr(data-label);color:var(--dim);font-size:.74rem;
    text-transform:uppercase;letter-spacing:.04em;font-weight:600;
    text-align:left;flex:0 0 38%;
  }
  .tblwrap:not([data-mobile="scroll"]) td[data-label=""]::before{content:none}
  /* the first cell is the row's title - give it the full width */
  .tblwrap:not([data-mobile="scroll"]) td:first-child{
    display:block;text-align:left;font-weight:600;font-size:1rem;
    padding-bottom:.4rem;margin-bottom:.35rem;
    border-bottom:1px solid var(--line);
  }
  .tblwrap:not([data-mobile="scroll"]) td:first-child::before{
    display:block;flex:none;margin-bottom:.1rem;font-weight:600;
  }
  .tblwrap:not([data-mobile="scroll"]) td.num{text-align:right}
  .tblwrap:not([data-mobile="scroll"]) td:empty{display:none}

  /* A control-only first cell (the tick box on the price sheet review) is not
     the row's title, so don't style it like one. */
  .tblwrap:not([data-mobile="scroll"]) td.cell-control{
    display:flex;text-align:left;font-weight:400;font-size:.9rem;
    border-bottom:0;padding-bottom:.28rem;margin-bottom:0;
  }
  .tblwrap:not([data-mobile="scroll"]) td.cell-control::before{
    display:inline;flex:0 0 40%;
  }

  /* ---- beat the inline width attributes in the templates ----
     Several tables set style="min-width:230px" on their selects. An inline
     style outranks a stylesheet rule, so without !important those cells stay
     230px wide, add the 40% label column, and push the page off the screen.
     This is the one place the override is worth it. */
  .row>*,.inline>*{min-width:0 !important}
  .inline>div,.inline>form{flex-basis:100%}
  .card input,.card select,.card textarea{max-width:100% !important}
  .tblwrap:not([data-mobile="scroll"]) td input:not([type=checkbox]),
  .tblwrap:not([data-mobile="scroll"]) td select{
    width:auto !important;min-width:0 !important;max-width:58% !important;
    flex:1 1 auto;
  }
  .tblwrap:not([data-mobile="scroll"]) td:first-child input:not([type=checkbox]),
  .tblwrap:not([data-mobile="scroll"]) td:first-child select{
    width:100% !important;max-width:100% !important;
  }
  .tblwrap:not([data-mobile="scroll"]) td.cell-control input{
    width:auto !important;flex:none;
  }
  .empty{padding:1.2rem .5rem}

  /* ---- board: stack the columns, move cards with the dropdown ---- */
  .board{display:block;overflow-x:visible;padding-bottom:0}
  .bcol{margin-bottom:.7rem;min-height:0}
  .bcol h3{font-size:.85rem;margin-bottom:.5rem}
  .bcard{cursor:default}
  .bcard .movebar{display:flex}

  /* ---- chat ---- */
  .chatwrap{height:calc(100dvh - 210px);min-height:340px}
  .chatlog{padding:.7rem;gap:.6rem}
  .msg{max-width:94%;font-size:.95rem}
  .chatbar{padding:.55rem;gap:.4rem;
    padding-bottom:max(.55rem,env(safe-area-inset-bottom))}
  .chatbar .btn{width:auto;flex:0 0 auto}
  .chips{padding:0 .55rem .5rem;flex-wrap:nowrap;overflow-x:auto;
    -webkit-overflow-scrolling:touch;scrollbar-width:none}
  .chips::-webkit-scrollbar{display:none}
  .chip{flex:0 0 auto}

  /* ---- misc ---- */
  .center-card{max-width:100%;margin:2vh auto}
  .kv{grid-template-columns:1fr;gap:.1rem .5rem}
  .kv dt{margin-top:.5rem;font-size:.78rem;text-transform:uppercase;
    letter-spacing:.03em}
  .kv dd{font-size:.95rem}
  pre{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .footer{margin-top:1.4rem}
}

@media (max-width:420px){
  .grid.g4{grid-template-columns:1fr}
  .tblwrap:not([data-mobile="scroll"]) td::before{flex-basis:42%}
  .stat .value{font-size:1.35rem}
}

@media print{
  .topbar,.navtoggle,.chatbar,.chips,.btn{display:none}
  body{background:#fff;color:#000}
  .card{border:1px solid #ccc;break-inside:avoid}
}
