/*
 * app.css — Phase 5 visual language.
 *
 * Palette and component shapes are carried over deliberately from the
 * Apps Script build (v1.6) — same Nan Pao red, same card/tab/badge language —
 * so the people who already use this tool are not relearning it. What
 * changes is layout discipline (a settlement strip that is always on screen)
 * and the things ruling out of v1.6's weak points call for: no more
 * innerHTML string concatenation, no more inline onclick.
 */
:root{
  --bg:#f4f5f7; --card:#fff; --ink:#111827; --muted:#6b7280; --line:#e6e8ec;
  --accent:#dd1825; --accent-dark:#b30f1b;
  --ok:#047857; --ok-bg:#d1fae5;
  --wait:#b45309; --wait-bg:#fef3c7;
  --transit:#0070c0; --transit-bg:#dbeafe;
  --err:#b91c1c; --err-bg:#fee2e2;
  --ring:rgba(221,24,37,.14);
  --sh-sm:0 1px 2px rgba(16,24,40,.06),0 1px 3px rgba(16,24,40,.08);
  --sh-md:0 4px 8px -2px rgba(16,24,40,.1),0 2px 4px -2px rgba(16,24,40,.06);
  --sh-lg:0 12px 24px -6px rgba(16,24,40,.16),0 4px 8px -4px rgba(16,24,40,.08);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;font-family:'Inter',-apple-system,"Segoe UI",Roboto,Arial,sans-serif;background:var(--bg);color:var(--ink)}

/* ------------------------------------------------------------ layout shell */
header{background:rgba(255,255,255,.85);backdrop-filter:saturate(1.6) blur(10px);-webkit-backdrop-filter:saturate(1.6) blur(10px);
  padding:10px 20px;display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;
  border-bottom:1px solid var(--line);box-shadow:var(--sh-sm);position:sticky;top:0;z-index:50}
header:after{content:'';position:absolute;left:0;right:0;top:0;height:3px;background:linear-gradient(90deg,var(--accent),#ff5a63)}
header h1{margin:0;font-size:19px;font-weight:800;letter-spacing:-.01em}
.who{font-size:12px;color:var(--muted)}
.brand{display:flex;align-items:center;gap:12px;min-width:0}
.brand img{height:44px;width:auto;flex:none;border-radius:8px}
.brand .co{font-size:12px;font-weight:800;color:var(--accent);letter-spacing:.05em}
.wrap{padding:20px 20px 60px;max-width:1400px;margin:0 auto}
.hide{display:none !important}

/* ----------------------------------------------------------------- inputs */
button{padding:9px 15px;border:1px solid var(--line);background:#fff;border-radius:10px;cursor:pointer;
  font-size:13px;min-height:38px;font-family:inherit;font-weight:500;transition:all .15s ease}
button:hover{background:#f8fafc;border-color:#d3d6dc;box-shadow:var(--sh-sm)}
button:disabled{opacity:.55;cursor:not-allowed;box-shadow:none}
.btn-primary{background:var(--accent);color:#fff;border:none;font-weight:600;box-shadow:0 1px 2px rgba(221,24,37,.35)}
.btn-primary:hover{background:var(--accent-dark);box-shadow:0 4px 10px rgba(221,24,37,.3);transform:translateY(-1px)}
.btn-ghost{background:transparent;color:var(--ink);border:1px solid var(--line)}
.btn-ghost:hover{background:#f8fafc}
.btn-danger{color:var(--err);border-color:#fecaca;background:#fff}
.btn-danger:hover{background:var(--err-bg);border-color:#f5a3a3}

input,select,textarea{padding:9px 12px;border:1px solid var(--line);border-radius:10px;font-size:14px;width:100%;
  min-height:38px;background:#fff;font-family:inherit;transition:border-color .15s,box-shadow .15s}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
input[readonly]{background:#f8fafc;color:var(--muted)}
label{display:block;font-size:11px;font-weight:600;color:var(--muted);margin-bottom:5px;letter-spacing:.02em}
.field{margin-bottom:14px}

/* ------------------------------------------------------------------ badges */
.badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;font-size:11.5px;
  font-weight:600;white-space:nowrap;letter-spacing:.01em}
.badge:before{content:'';width:6px;height:6px;border-radius:99px;background:currentColor;opacity:.7}
.b-ok{background:var(--ok-bg);color:var(--ok)}
.b-wait{background:var(--wait-bg);color:var(--wait)}
.b-transit{background:var(--transit-bg);color:var(--transit)}
.b-none{background:#eef0f3;color:var(--muted)}
.b-del{background:var(--err-bg);color:var(--err)}

/* ------------------------------------------------------------------- msgs */
.msg{padding:10px 12px;border-radius:8px;font-size:13px;margin-bottom:12px}
.msg.ok{background:var(--ok-bg);color:var(--ok)}
.msg.err{background:var(--err-bg);color:var(--err)}
.warnbar{background:var(--err-bg);color:var(--err);border:1px solid #fecaca;border-radius:8px;padding:10px 12px;
  font-size:13px;font-weight:600;margin-bottom:12px}

/* A button that reads as a link — the way back out of "+ Add new…" without
   putting a second full-size button inside a form field. */
.linklike{background:none;border:none;padding:4px 0 0;min-height:0;font-size:12px;
  color:var(--accent);text-decoration:underline;cursor:pointer;font-weight:500}
.linklike:hover{color:var(--accent-dark)}

/* ------------------------------------------------------------------ toast
   Save confirmations, pinned to the viewport rather than the document.

   The first cut rendered these as the first child of .wrap — above the Back
   button, settlement strip and tab row. Saving from a panel further down the
   page therefore drew "Saved." several hundred pixels above the viewport, and
   it was never seen. Reported 19 Jul 2026 as "changes save but no green
   banner": the banner was there, just off-screen.

   Deliberately NOT used for data warnings. Those stay inline next to the data
   they concern (approved visual direction) — a warning that disappears after
   three seconds is a warning nobody read. */
.toast{position:fixed;top:16px;left:50%;transform:translateX(-50%);z-index:300;
  max-width:min(520px,calc(100vw - 32px));padding:12px 18px;border-radius:10px;
  font-size:13px;font-weight:600;box-shadow:var(--sh-lg);cursor:pointer;
  animation:toastIn .18s ease}
.toast.ok{background:var(--ok);color:#fff}
.toast.err{background:var(--err);color:#fff}
@keyframes toastIn{from{opacity:0;transform:translate(-50%,-10px)}
                     to{opacity:1;transform:translate(-50%,0)}}

/* ------------------------------------------------------------------ login */
#login{max-width:400px;margin:6vh auto;background:var(--card);padding:28px;border-radius:14px;
  box-shadow:0 4px 14px rgba(0,0,0,.08);border-top:5px solid var(--accent);animation:popIn .25s ease}

/* ---------------------------------------------------------------- toolbar */
.toolbar{display:flex;gap:10px;margin-bottom:18px;flex-wrap:wrap;align-items:center}
#search{flex:1;min-width:160px}
.state{padding:34px;text-align:center;color:var(--muted)}

/* ------------------------------------------------------------------ cards */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(295px,1fr));gap:14px}
.card{background:var(--card);border-radius:13px;padding:14px 14px 10px;box-shadow:var(--sh-sm);border:1px solid var(--line);
  cursor:pointer;position:relative;overflow:hidden;transition:box-shadow .18s ease,transform .18s ease,border-color .18s}
.card:before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(180deg,var(--accent),#ff5a63)}
.card:hover{box-shadow:var(--sh-md);transform:translateY(-2px);border-color:#dcdfe4}
.card .cid{font-weight:800;font-size:14.5px;letter-spacing:.01em}
.card .csup{font-size:11.5px;color:var(--muted);margin:2px 0 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card .crow{display:flex;justify-content:space-between;gap:8px;margin-bottom:8px;align-items:baseline}
.card .badges{display:flex;gap:5px;flex-wrap:wrap;margin:0 0 8px}
.card .badge{font-size:10.5px;padding:2px 8px}
.card .cfoot{display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--line);padding-top:8px;gap:8px}
.card .bl{font-size:10.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Route, and the small label/value pairs beneath it — restored from v1.6,
   which the first cut of the tile dropped. */
.card .route{font-size:11px;color:var(--ink);opacity:.75;margin:0 0 9px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card .kd{font-size:9.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.card .kvv{font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Short Delivery (tab 3): red = short delivered, yellow = rate moved. */
.row-short{background:var(--err-bg)}
.row-ratediff{background:var(--wait-bg)}
/* Payments (tab 9): amount paid differs from payable. */
.row-paydiff{background:var(--wait-bg)}

/* Negative money. DECIDED 19 Jul 2026: accounting parentheses + red.
   format.js renders the parentheses; views attach .neg via fmt.isNeg(). */
.neg{color:var(--err)}

/* Derived-figure strip inside a panel (duty variance, settlement lines). */
.derived{background:#f8fafc;border-left:4px solid var(--accent);border-radius:8px;
  padding:10px 12px;font-size:13px;margin-top:12px}

/* BoE verification chip. */
.vchip{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;border-radius:999px;
  font-size:12px;font-weight:600}
.vchip.vyes{background:var(--ok-bg);color:var(--ok)}
.vchip.vno{background:var(--wait-bg);color:var(--wait)}

/* Documents summary. */
.miss{color:var(--err);font-weight:600}
.have{color:var(--ok);font-weight:600}

/* Multi-line entry rows (POs/Invoices product lines, bill lines, packing). */
.linerow{display:grid;grid-template-columns:2fr 1fr 1fr 1fr 1fr auto;gap:10px;
  align-items:end;padding:8px 0;border-bottom:1px dashed var(--line)}
.billrow{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr 1.4fr 1fr auto;gap:10px;
  align-items:end;padding:8px 0;border-bottom:1px dashed var(--line)}
.packrow{display:grid;grid-template-columns:2fr 1.2fr 1fr 1fr 1fr auto;gap:10px;
  align-items:end;padding:8px 0;border-bottom:1px dashed var(--line)}
@media(max-width:900px){.linerow,.billrow,.packrow{grid-template-columns:1fr 1fr}}

/* ------------------------------------------------------------------- tabs */
/* Tightened 27 Jul 2026 so all 14 tabs fit without a horizontal scrollbar on a
   normal desktop width; on narrow screens the strip WRAPS to a second row
   rather than showing a scrollbar (a scrollbar on the primary nav was the
   objection). */
.tabs{display:flex;flex-wrap:wrap;gap:2px;margin:16px 0;padding:3px;
  background:#e9ebee;border-radius:12px;max-width:100%}
.tab{padding:6px 10px;border:none;border-radius:9px;background:transparent;cursor:pointer;font-size:12.5px;
  font-weight:600;color:var(--muted);white-space:nowrap;flex:none;transition:all .15s;min-height:auto}
.tab:hover{background:rgba(255,255,255,.65)}
.tab.active{background:#fff;color:var(--accent);box-shadow:var(--sh-sm)}
.tab[disabled]{opacity:.4;cursor:not-allowed}

/* ----------------------------------------------------------------- panels */
.panel{background:var(--card);border-radius:16px;padding:20px;box-shadow:var(--sh-sm);border:1px solid var(--line);margin-bottom:18px}
.panel h3{margin:0 0 15px;font-size:15px;font-weight:700;letter-spacing:-.01em;display:flex;align-items:center;gap:8px}
.panel h3 .right{margin-left:auto}
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:11px}
.kv .k{color:var(--muted);font-size:11px}
.kv .v{margin-top:2px;font-size:14px}
.rowbar{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px;align-items:center}
.small{font-size:12px;color:var(--muted)}

/* ------------------------------------------------------------ settlement */
.settlement-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:0;background:var(--card);
  border-radius:16px;box-shadow:var(--sh-sm);border:1px solid var(--line);margin-bottom:18px;overflow:hidden}
.settlement-strip .cell{padding:16px 18px;border-right:1px solid var(--line)}
.settlement-strip .cell:last-child{border-right:none}
.settlement-strip .cell .lbl{font-size:10.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;font-weight:600}
.settlement-strip .cell .val{margin-top:5px;font-size:19px;font-weight:800;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.settlement-strip .cell.owed .val{color:var(--accent)}
.settlement-strip .cell .val.neg{color:var(--err)}

/* -------------------------------------------------------------------- tbl */
.tblwrap{overflow-x:auto;border-radius:12px;box-shadow:var(--sh-sm);border:1px solid var(--line)}
table{width:100%;border-collapse:collapse;background:var(--card)}
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);font-size:13px;vertical-align:top}
th{background:#fafbfc;color:var(--muted);font-weight:600;font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap}
tbody tr:last-child td{border-bottom:none}
tbody tr.clk{cursor:pointer;transition:background .12s}
tbody tr.clk:hover{background:#fafbfc}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}

/* ------------------------------------------------------------------- seg */
.seg{display:flex;background:#e9ebee;border-radius:11px;padding:3px;gap:2px}
.seg button{border:none;border-radius:9px;min-height:32px;padding:5px 16px;background:transparent;font-weight:600;color:var(--muted)}
.seg button:hover{box-shadow:none;background:rgba(255,255,255,.6)}
.seg button.on{background:#fff;color:var(--ink);box-shadow:var(--sh-sm)}

@keyframes popIn{from{opacity:0;transform:scale(.96) translateY(6px)}to{opacity:1;transform:none}}

/* =========================================================== cost-sheet doc
   THE PRINTED COST SHEET.

   This block is the PDF. `.csdoc` is rendered by CostSheet.js on every visit
   but hidden on screen; printing hides the app's panels and shows it instead,
   so "Save as PDF" produces the reference format in
   `reference-cost-sheet-format/` rather than a screenshot of an application.

   It is defined OUTSIDE @media print, with only the display switch inside,
   so the layout can be inspected by flipping one property — a print-only
   stylesheet that nobody can see until they print is a stylesheet nobody
   maintains.

   Colours are the same brand values the Excel export writes:
   red DD1825, pink FDE8E9, grey F3F4F6, rules D9B8BA. */
.csdoc{display:none;background:#fff;color:#000;
  font-family:Calibri,Carlito,"Segoe UI",Arial,sans-serif;font-size:10pt;line-height:1.25}
/* Masthead (his instruction 27 Jul 2026): the logo sits immediately to the
   LEFT of the company name, and the logo+titles group is centred together on
   the page — a letterhead, not a stacked badge. */
.cshead{display:flex;flex-direction:row;align-items:center;justify-content:center;
  gap:12px;margin-bottom:10px}
.cslogo{width:44px;height:auto;flex:none}
.cshead-titles{display:flex;flex-direction:column;gap:2px;align-items:center;
  text-align:center}
.cstitle{font-size:17pt;font-weight:700;color:#dd1825;letter-spacing:-.01em;white-space:nowrap}
.cssub{font-size:12pt;font-weight:700;color:#444;white-space:nowrap}
/* Breathing room between a document number and its date. */
.csdt{margin-left:18px}
/* Two label/value pairs per line, matching the reference's A|B  E|F columns.
   A TABLE, not a CSS grid: `display:contents` on the pairs is what a grid
   would need, and support for it is uneven across print engines. This has to
   render the same in Chrome, Edge and whatever the office actually uses. */
.csgrid{width:100%;border-collapse:collapse;margin-bottom:10px;table-layout:fixed}
.csgrid td{border:none;padding:1px 0;font-size:10pt;vertical-align:top}
.csgrid td.k{width:145px;font-size:9pt;font-weight:700;color:#8a8f98;padding-right:8px}
.csgrid td.v{font-weight:700;color:#000;padding-right:24px}
.csbar{background:#dd1825;color:#fff;font-weight:700;font-size:11pt;
  padding:3px 8px;margin:10px 0 0}
.cstbl{width:100%;border-collapse:collapse;table-layout:fixed}
.cstbl th,.cstbl td{padding:2px 8px;font-size:9.5pt;vertical-align:middle;
  border-left:1px solid #d9b8ba;border-right:1px solid #d9b8ba;border-bottom:none;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The app's global `th` rule uppercases and mutes headings. That is right for
   a data grid and wrong for a document, so it is undone here explicitly. */
/* Headings may wrap; figures may not. A wrapped heading costs a line, a
   clipped one ("Landing Rate ₹/…") costs the reader the column's meaning. */
.cstbl th{background:#fde8e9;color:#000;font-weight:700;font-size:9.5pt;
  text-transform:none;letter-spacing:0;white-space:normal;
  border-top:1px solid #d9b8ba}
.cstbl tfoot td{background:#f3f4f6;font-weight:700;border-bottom:1px solid #d9b8ba}
.cstbl .r{text-align:right;font-variant-numeric:tabular-nums}
.cstbl tbody tr.muted td{color:#8a8f98;font-style:italic}
/* Column A carries the long charge labels; the rest are figures. */
.cstbl th:first-child,.cstbl td:first-child{width:33%;white-space:normal}
.csline{display:flex;justify-content:space-between;padding:2px 0;font-size:10pt}
.csline.muted{color:#8a8f98;font-style:italic}
.csnote{margin:3px 0;font-size:9.5pt;font-style:italic;color:#555}

/* ------------------------------------------------------------------ print
   "Print / Save as PDF" on the Cost Sheet tab. The app header, tab strip,
   settlement strip, back button, toasts and the buttons themselves are
   chrome, not the document, and go. On the Cost Sheet tab the screen panels
   go too, replaced by `.csdoc`; that swap is scoped to `.costsheet` so every
   other tab still prints the way it always did. */
@page{size:A4 landscape;margin:10mm}
@media print{
  header,.tabs,.settlement-strip,.toast,.no-print,.warnbar{display:none !important}
  body{background:#fff}
  .wrap{padding:0;max-width:none}
  .panel{box-shadow:none;border:1px solid #ccc;break-inside:avoid;page-break-inside:avoid}
  table{font-size:11px}
  tr,td,th{break-inside:avoid}
  h2{margin-top:0}
  a[href]:after{content:''}

  /* The cost sheet prints as the document, not as the app. */
  .costsheet > .panel{display:none !important}
  .costsheet .csdoc{display:block !important}
  /* WITHOUT THIS THE RED BARS VANISH. Browsers strip background colours when
     printing to save ink; a cost sheet whose section headings print as white
     on white is exactly the unprofessional output this rebuild exists to fix. */
  .csdoc,.csdoc *{-webkit-print-color-adjust:exact;print-color-adjust:exact}
  /* Pagination. A table is allowed to SPLIT across pages, with its heading
     repeated at the top of the continuation — because the number of products
     varies per shipment, and a rule that keeps a whole table together works
     on this shipment and produces a page of white space plus an orphaned
     table on the next one. Rows stay atomic; a section bar never ends a page
     with its table starting on the next. */
  .cstbl{break-inside:auto;page-break-inside:auto}
  .cstbl thead{display:table-header-group}
  .cstbl tr,.csline,.csnote{break-inside:avoid;page-break-inside:avoid}
  .csbar{break-inside:avoid;page-break-inside:avoid;break-after:avoid;page-break-after:avoid}
}

@media(max-width:900px){
  .grid{grid-template-columns:1fr 1fr}
  .settlement-strip{grid-template-columns:1fr 1fr}
  .settlement-strip .cell:nth-child(2){border-right:none}
}
@media(max-width:600px){
  .grid{grid-template-columns:1fr}
  .cards{grid-template-columns:1fr}
  .wrap{padding:12px 10px 60px}
  header{padding:8px 10px}
  .brand img{height:36px}
  header h1{font-size:16px}
  #login{margin:3vh 12px}
  .settlement-strip{grid-template-columns:1fr}
  .settlement-strip .cell{border-right:none;border-bottom:1px solid var(--line)}
  .settlement-strip .cell:last-child{border-bottom:none}
}
