/* Cargo Console — road-freight consignment app. Dark, glassmorphic.
   Sibling of the OdysseyByte storage console and deliberately the same design
   language: an operator who uses both should never have to re-learn a control.
   Source of truth is this file; there is NO build step. Cache-busting is by
   mtime (ConsoleRenderer::assetUrl), so edit in place and flush the cache. */

/* [hidden] must always win — several toggled elements set an explicit display,
   which would otherwise override the UA rule. */
[hidden]{display:none !important}

:root{
  /* Two flip-able channels drive every neutral surface: --tint is the low-alpha
     colour layered over the background (borders, hovers, panels), --tint-deep is
     the recessed field colour. The light theme swaps only these plus the base
     hues, so every surface rule re-tints from one place. */
  --tint:255,255,255; --tint-deep:16,17,19;
  color-scheme:dark;
  --bg:#141517; --panel:rgba(28,29,32,.62); --panel-solid:#1c1d20;
  --stroke:rgba(var(--tint),.09); --stroke-2:rgba(var(--tint),.16);
  --text:#f2f1ec; --muted:#9fa09a; --muted-2:#6c6e69;
  --accent-rgb:245,163,0; --blue-rgb:95,155,222; --violet-rgb:164,139,240;
  --green-rgb:67,181,108; --amber-rgb:224,165,58; --red-rgb:224,87,74;
  --accent:rgb(var(--accent-rgb)); --blue:rgb(var(--blue-rgb)); --violet:rgb(var(--violet-rgb));
  --green:rgb(var(--green-rgb)); --amber:rgb(var(--amber-rgb)); --red:rgb(var(--red-rgb));
  --ink-on-accent:#231a00;
  --grad:linear-gradient(135deg,#f5a300 0%,#f5b829 100%);
  --grad-soft:linear-gradient(135deg,rgba(var(--accent-rgb),.16),rgba(var(--accent-rgb),.09));
  --radius:20px; --shadow:0 24px 60px -20px rgba(0,0,0,.7);
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
}

/* Light theme — emitted server-side as a body class before first paint. */
.cargo-body.theme-light{
  --tint:23,24,26; --tint-deep:255,255,255;
  color-scheme:light;
  --bg:#fafaf7; --panel:rgba(255,255,255,.80); --panel-solid:#fff;
  --stroke:rgba(var(--tint),.11); --stroke-2:rgba(var(--tint),.18);
  --text:#17181a; --muted:#6d6f6a; --muted-2:#9d9f99;
  --blue-rgb:47,106,176; --violet-rgb:109,84,196;
  --green-rgb:46,125,79; --amber-rgb:181,122,26; --red-rgb:192,57,43;
  --grad-soft:linear-gradient(135deg,rgba(var(--accent-rgb),.15),rgba(var(--accent-rgb),.08));
  --shadow:0 22px 50px -26px rgba(42,41,36,.16);
}
.cargo-body.theme-light::before{opacity:.5}
.cargo-body.theme-light .side{background:linear-gradient(180deg,rgba(255,255,255,.75),rgba(255,255,255,.35))}
.cargo-body.theme-light .scrim{background:rgba(42,41,36,.28)}
.cargo-body.theme-light .sheet.show{box-shadow:0 30px 64px -28px rgba(42,41,36,.28)}
.cargo-body.theme-light .modal{box-shadow:0 20px 50px -20px rgba(42,41,36,.20)}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
.cargo-body{
  font-family:'Inter',system-ui,sans-serif;color:var(--text);
  -webkit-font-smoothing:antialiased;min-height:100vh;background:var(--bg);
}
/* Ambient glows on a fixed layer so they stay put on a long page instead of
   scrolling into view again further down (which reads as a repeating tile). */
.cargo-body::before{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(900px 600px at 8% -8%, rgba(var(--accent-rgb),.14), transparent 55%),
    radial-gradient(1000px 700px at 100% 0%, rgba(var(--violet-rgb),.16), transparent 55%),
    radial-gradient(800px 600px at 60% 110%, rgba(var(--blue-rgb),.12), transparent 55%);
}
::selection{background:rgba(var(--accent-rgb),.3)}

.glass{background:var(--panel);border:1px solid var(--stroke);border-radius:var(--radius);backdrop-filter:blur(22px) saturate(140%);-webkit-backdrop-filter:blur(22px) saturate(140%);box-shadow:var(--shadow)}
.icn{width:18px;height:18px;display:inline-block;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex:none}
.icn-lg{width:44px;height:44px;stroke:currentColor;fill:none;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;color:var(--muted-2)}
.ta-r{text-align:right}
.mono{font-family:var(--mono);letter-spacing:-.02em}
.spacer{flex:1}

.btn{font:600 13.5px/1 'Inter',sans-serif;color:var(--text);border:1px solid var(--stroke-2);background:rgba(var(--tint),.04);padding:11px 16px;border-radius:11px;cursor:pointer;display:inline-flex;align-items:center;gap:8px;transition:.18s ease;white-space:nowrap}
.btn:hover{background:rgba(var(--tint),.09);transform:translateY(-1px)}
.btn:disabled{opacity:.45;cursor:not-allowed;transform:none}
.btn-primary{border:none;color:var(--ink-on-accent);font-weight:700;background:var(--grad);box-shadow:0 10px 30px -10px rgba(var(--accent-rgb),.6)}
.btn-primary:hover{filter:brightness(1.08)}
.btn-sm{padding:8px 12px;font-size:12.5px;border-radius:9px}
.btn-ghost{background:none;border-color:transparent}
/* A secondary way out of a step, not a second thing to do. Deliberately not a
   .btn: two buttons side by side read as a choice between equals, and verifying
   the number is what almost every counterparty should get. */
.btn-link{background:none;border:none;padding:0;margin-top:12px;font:inherit;font-size:12.5px;font-weight:600;
  color:var(--muted);cursor:pointer;text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px}
.btn-link:hover{color:var(--text)}
.btn-link:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
.btn-danger{color:var(--red)}
.btn-danger:hover{background:rgba(var(--red-rgb),.12)}
.icon-btn{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;background:none;border:1px solid transparent;color:var(--muted);cursor:pointer;transition:.15s}
.icon-btn:hover{color:var(--text);background:rgba(var(--tint),.07)}
.icon-btn.danger:hover{color:var(--red);background:rgba(var(--red-rgb),.12)}

/* ═══ login ═══ */
.login-stage{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;padding:24px}
.login-card{width:min(420px,100%);padding:40px 36px;text-align:center;position:relative;overflow:hidden}
.login-card::before{content:"";position:absolute;left:50%;top:-40%;width:300px;height:300px;transform:translateX(-50%);background:radial-gradient(circle,rgba(var(--accent-rgb),.4),transparent 60%);filter:blur(30px);pointer-events:none}
.brand-mark{width:58px;height:58px;border-radius:16px;margin:0 auto 20px;background:var(--grad);display:grid;place-items:center;box-shadow:0 14px 36px -10px rgba(var(--accent-rgb),.6);position:relative;z-index:1}
.brand-mark svg{width:30px;height:30px;stroke:var(--ink-on-accent);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.login-card h1{font:800 23px/1.2 'Manrope',sans-serif;letter-spacing:-.02em;position:relative;z-index:1}
.login-card .sub{color:var(--muted);font-size:13.5px;margin-top:7px;position:relative;z-index:1}
.login-error{margin-top:18px;background:rgba(var(--red-rgb),.12);border:1px solid rgba(var(--red-rgb),.3);color:var(--red);font-size:13px;padding:11px 14px;border-radius:12px;position:relative;z-index:1}
.login-form{position:relative;z-index:1}
.field{text-align:left;margin-top:18px}
.field label{display:block;font-size:11.5px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;margin-bottom:7px}
.field input{width:100%;padding:13px 14px;border-radius:12px;color:var(--text);font-size:14.5px;background:rgba(var(--tint-deep),.6);border:1px solid var(--stroke-2);transition:.18s;font-family:inherit}
.field input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px rgba(var(--accent-rgb),.14)}
.login-submit{width:100%;justify-content:center;margin-top:24px;padding:14px;font-size:14.5px}
.fe-note{margin-top:18px;font-size:11.5px;color:var(--muted-2);position:relative;z-index:1}

/* ═══ shell ═══ */
.shell{display:grid;grid-template-columns:248px 1fr;min-height:100vh}
.side{position:sticky;top:0;height:100vh;padding:22px 16px;display:flex;flex-direction:column;gap:6px;border-right:1px solid var(--stroke);background:linear-gradient(180deg,rgba(28,29,32,.6),rgba(var(--tint-deep),.3));backdrop-filter:blur(16px)}
.side .logo{display:flex;align-items:center;gap:11px;padding:6px 8px 20px;flex:none}
.side .logo .m{width:38px;height:38px;border-radius:11px;background:var(--grad);display:grid;place-items:center;flex:none}
.side .logo .m svg{width:21px;height:21px;stroke:var(--ink-on-accent);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.side .logo .t b{font:800 14.5px 'Manrope',sans-serif;display:block;letter-spacing:-.01em}
.side .logo .t span{font-size:11px;color:var(--muted)}
/* The nav scrolls on its own so the footer stays pinned however many items exist. */
.nav{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:6px;scrollbar-width:thin;scrollbar-color:var(--stroke-2) transparent}
.nav::-webkit-scrollbar{width:8px}
.nav::-webkit-scrollbar-thumb{background:var(--stroke-2);border-radius:8px}
.nav-label{font-size:10.5px;font-weight:700;letter-spacing:.12em;color:var(--muted-2);text-transform:uppercase;padding:14px 12px 6px}
.nav-item{width:100%;text-align:left;font:500 13.5px 'Inter',sans-serif;display:flex;align-items:center;gap:12px;padding:11px 12px;border-radius:12px;cursor:pointer;color:var(--muted);transition:.16s;position:relative;background:none;border:1px solid transparent}
.nav-item:hover{color:var(--text);background:rgba(var(--tint),.04)}
.nav-item.active{color:var(--text);background:var(--grad-soft);border-color:var(--stroke-2)}
.nav-item.active::before{content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:20px;border-radius:3px;background:var(--grad)}
.nav-item .badge{margin-left:auto;font-size:10.5px;font-weight:700;background:rgba(var(--red-rgb),.18);color:var(--red);padding:2px 7px;border-radius:20px}
.side-foot{margin-top:auto;padding:12px;border-radius:14px;border:1px solid var(--stroke);background:rgba(var(--tint),.03);display:flex;align-items:center;gap:11px}
.side-foot .av{width:36px;height:36px;border-radius:10px;background:linear-gradient(135deg,var(--blue),var(--violet));display:grid;place-items:center;font-weight:700;font-size:14px;flex:none;text-transform:uppercase}
.side-foot .t{min-width:0;flex:1}
.side-foot .t b{font-size:13px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.side-foot .t span{font-size:11px;color:var(--muted);text-transform:capitalize}
.sf-actions{display:flex;align-items:center;gap:2px}
.side-foot .logout,.theme-toggle{color:var(--muted);display:grid;place-items:center;width:32px;height:32px;border-radius:9px;flex:none;background:none;border:none;cursor:pointer;transition:.15s}
.side-foot .logout:hover,.theme-toggle:hover{color:var(--text);background:rgba(var(--tint),.07)}
/* Show the icon of the theme you would switch TO. */
.lang-pick{position:relative;display:grid;place-items:center;width:32px;height:32px;border-radius:9px;color:var(--muted);transition:.15s}
.lang-pick:hover{color:var(--text);background:rgba(var(--tint),.07)}
.lang-code{font:700 11px/1 'Manrope',sans-serif;letter-spacing:.04em;pointer-events:none}
/* The select carries the behaviour; the code carries the look. */
.lang-pick select{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;border:none;font-family:inherit}
.theme-toggle .ic-moon{display:none}
.cargo-body.theme-light .theme-toggle .ic-sun{display:none}
.cargo-body.theme-light .theme-toggle .ic-moon{display:block}

.main{padding:26px 32px 60px;min-width:0}
.topbar{display:flex;align-items:center;gap:14px;margin-bottom:22px;flex-wrap:wrap}
.crumbs{font-size:12.5px;color:var(--muted)}
.crumbs b{color:var(--text);font-weight:600}
.topbar h2{font:800 24px/1.1 'Manrope',sans-serif;letter-spacing:-.02em;margin-top:3px}
.search{margin-left:auto;display:flex;align-items:center;gap:9px;background:rgba(var(--tint-deep),.5);border:1px solid var(--stroke-2);border-radius:12px;padding:10px 14px;width:280px;max-width:100%}
.search input{background:none;border:none;outline:none;color:var(--text);font-size:13.5px;width:100%;font-family:inherit}
.search .icn{color:var(--muted)}

.page{display:none;animation:fade .35s ease}
.page.active{display:block}
@keyframes fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ═══ notices ═══ */
.notice{display:flex;align-items:flex-start;gap:14px;padding:16px 18px;border-radius:14px;margin-bottom:18px;border:1px solid}
.notice p{font-size:12.5px;color:var(--muted);margin-top:3px;line-height:1.5}
.notice b{font-size:13.5px}
.notice .btn{margin-left:auto;align-self:center}
.notice-warn{background:rgba(var(--amber-rgb),.10);border-color:rgba(var(--amber-rgb),.28);color:var(--amber)}
.notice-warn b{color:var(--text)}

/* ═══ stats ═══ */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-bottom:18px}
.stat{padding:20px;position:relative;overflow:hidden}
.stat .top{display:flex;align-items:flex-start;justify-content:space-between}
.stat .lab{font-size:12.5px;color:var(--muted);font-weight:500}
.stat .val{font:800 30px/1 'Manrope',sans-serif;margin-top:12px;letter-spacing:-.02em}
.stat .delta{font-size:12px;font-weight:600;margin-top:9px;color:var(--muted)}
.stat .tile{width:38px;height:38px;border-radius:11px;display:grid;place-items:center}
.stat .tile svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.tile.c1{background:rgba(var(--accent-rgb),.16);color:var(--accent)}
.tile.c2{background:rgba(var(--green-rgb),.16);color:var(--green)}
.tile.c3{background:rgba(var(--amber-rgb),.16);color:var(--amber)}
.tile.c4{background:rgba(var(--blue-rgb),.16);color:var(--blue)}
.tile.c5{background:rgba(var(--red-rgb),.16);color:var(--red)}
.stat-clickable{cursor:pointer;transition:.18s}
.stat-clickable:hover{transform:translateY(-2px);border-color:var(--stroke-2)}
/* Applied only when the number is non-zero. A tile that is permanently amber is
   a tile nobody reads, which is the opposite of what it is for. */
.stat-alert{border-color:rgba(var(--amber-rgb),.4)}
.stat-alert .val{color:var(--amber)}

/* Issued notes against shipments, per open trip. The bar is the glanceable part
   and the fraction is the exact one — "7/10" answers "how many left", which a
   percentage does not. */
.paper{display:inline-flex;align-items:center;gap:9px;justify-content:flex-end}
.paper-track{width:72px;height:6px;border-radius:99px;background:rgba(var(--tint),.10);overflow:hidden}
.paper-track i{display:block;height:100%;border-radius:99px;background:var(--amber);transition:width .3s}
.paper b{font-size:12px;font-weight:700;color:var(--amber);min-width:38px;text-align:right}
.paper.done .paper-track i{background:var(--green)}
.paper.done b{color:var(--green)}
#dash-trips tbody tr{cursor:pointer}

/* ═══ cards ═══ */
.card{padding:22px}
.card .head{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:16px}
.card h3{font:700 16px 'Manrope',sans-serif;letter-spacing:-.01em}
.card .sub{font-size:12.5px;color:var(--muted);margin-top:4px}

.empty-state{text-align:center;padding:56px 24px}
.empty-state h3{margin-top:16px}
.empty-state p{font-size:13px;color:var(--muted);margin-top:8px;max-width:52ch;margin-inline:auto;line-height:1.6}


/* ═══ chips ═══ */
.chips{display:flex;align-items:center;gap:8px;margin-bottom:16px;flex-wrap:wrap}
.chip{font:600 12.5px 'Inter',sans-serif;color:var(--muted);background:rgba(var(--tint),.04);border:1px solid var(--stroke);padding:8px 13px;border-radius:20px;cursor:pointer;transition:.16s;display:inline-flex;align-items:center;gap:7px}
.chip:hover{color:var(--text);background:rgba(var(--tint),.08)}
.chip.active{color:var(--text);background:var(--grad-soft);border-color:rgba(var(--accent-rgb),.35)}
.chip i{font-style:normal;font-family:var(--mono);font-size:11px;opacity:.75}
.chip-warn.active{background:rgba(var(--amber-rgb),.16);border-color:rgba(var(--amber-rgb),.35);color:var(--amber)}
.chip-bad.active{background:rgba(var(--red-rgb),.16);border-color:rgba(var(--red-rgb),.35);color:var(--red)}
.chip-sep{width:1px;height:20px;background:var(--stroke-2);margin:0 4px}

/* ═══ table ═══ */
.table-card{padding:0;overflow:hidden}
/* A head inside a table card has to bring its own padding: .table-card zeroes
   the card's so the table can run edge to edge, which otherwise leaves the
   title, the subtitle and the button jammed into the corner.
   18px matches the column padding, so the heading lines up over the first
   column rather than sitting a few pixels off it, and the rule beneath mirrors
   .tbl-foot's above.
   Scoped to the dashboard on purpose. Three other table cards — shipments, the
   log, the team — solve the same gap with an inline `padding:22px 22px 0`, and
   a rule here would win the padding but still add a border they were drawn
   without. Unifying those is worth doing as its own change. */
#page-dashboard .table-card .head{padding:18px 18px 16px;margin-bottom:0;gap:20px;border-bottom:1px solid var(--stroke)}
/* The subtitle is a sentence, not a label — measured so it wraps before it
   reaches the button rather than being squeezed by it. */
#page-dashboard .table-card .head .sub{max-width:70ch}
#page-dashboard .table-card .head .btn{flex:none}
.tbl-wrap{overflow-x:auto}
.tbl{width:100%;border-collapse:collapse;font-size:13.5px;min-width:760px}
.tbl th{text-align:left;font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2);padding:16px 18px;border-bottom:1px solid var(--stroke);white-space:nowrap}
.tbl td{padding:14px 18px;border-bottom:1px solid var(--stroke);vertical-align:middle}
.tbl tbody tr{transition:.14s;cursor:pointer}
.tbl tbody tr:hover{background:rgba(var(--tint),.035)}
.tbl tbody tr:last-child td{border-bottom:none}
.tbl .empty td{text-align:center;color:var(--muted-2);padding:44px 18px;cursor:default}
.tbl .empty tr:hover{background:none}

.row-party{display:flex;align-items:center;gap:12px;min-width:0}
.row-party .av{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;font-weight:700;font-size:14px;flex:none;background:var(--grad-soft);color:var(--accent);border:1px solid var(--stroke)}
.row-party .t{min-width:0}
.row-party .t b{display:block;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:34ch}
.row-party .t span{font-size:11.5px;color:var(--muted-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;max-width:34ch}
.row-actions{display:flex;align-items:center;gap:2px;justify-content:flex-end}

.pill{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;padding:4px 9px;border-radius:20px;letter-spacing:.02em;white-space:nowrap}
.pill::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
.pill.ok{background:rgba(var(--green-rgb),.14);color:var(--green)}
.pill.bad{background:rgba(var(--red-rgb),.14);color:var(--red)}
.pill.warn{background:rgba(var(--amber-rgb),.14);color:var(--amber)}
.pill.muted{background:rgba(var(--tint),.06);color:var(--muted-2)}
.role-tags{display:flex;gap:5px;flex-wrap:wrap}
.role-tag{font-size:10.5px;font-weight:600;padding:3px 8px;border-radius:6px;background:rgba(var(--blue-rgb),.13);color:var(--blue);white-space:nowrap}

.tbl-foot{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-top:1px solid var(--stroke);font-size:12.5px;color:var(--muted)}
.fld-inline{width:auto;padding:6px 10px;font-size:12px}
.pager{display:flex;gap:6px;align-items:center}
.pg-btn{width:30px;height:30px;border-radius:8px;background:rgba(var(--tint),.04);border:1px solid var(--stroke);color:var(--text);cursor:pointer;font-size:14px;line-height:1}
.pg-btn:disabled{opacity:.35;cursor:not-allowed}

/* ═══ sheet ═══ */
.scrim{position:fixed;inset:0;background:rgba(0,0,0,.55);backdrop-filter:blur(3px);opacity:0;pointer-events:none;transition:.25s;z-index:80}
.scrim.show{opacity:1;pointer-events:auto}
/* A centred modal sheet. It is a flex column with a fixed head and foot and a
   scrolling middle, so the Save/Issue row never scrolls out of reach however
   long the form is — the one property the side drawer had that a naive modal
   loses.
   `max-height` rather than a fixed height: a short form stays short instead of
   floating in a tall empty box. */
.sheet{
  position:fixed;left:50%;top:50%;z-index:90;
  width:min(620px,calc(100vw - 32px));max-height:calc(100vh - 56px);
  background:var(--panel-solid);border:1px solid var(--stroke-2);border-radius:18px;
  display:flex;flex-direction:column;overflow:hidden;
  transform:translate(-50%,-46%) scale(.98);opacity:0;
  transition:opacity .2s ease, transform .22s cubic-bezier(.4,0,.2,1);
}
.sheet.show{transform:translate(-50%,-50%) scale(1);opacity:1;box-shadow:0 34px 80px -24px rgba(0,0,0,.75)}
.sheet-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:22px 24px 18px;border-bottom:1px solid var(--stroke);flex:none}
.sheet-head h3{font:800 18px 'Manrope',sans-serif;letter-spacing:-.02em}
.sheet-head .sub{font-size:12.5px;color:var(--muted);margin-top:4px;font-family:var(--mono)}
.sheet-body{flex:1;overflow-y:auto;padding:22px 24px 32px;scrollbar-width:thin;scrollbar-color:var(--stroke-2) transparent}
.sheet-body::-webkit-scrollbar{width:8px}
.sheet-body::-webkit-scrollbar-thumb{background:var(--stroke-2);border-radius:8px}
.sheet-foot{display:flex;align-items:center;gap:10px;padding:16px 24px;border-top:1px solid var(--stroke);background:rgba(var(--tint-deep),.35);flex:none;flex-wrap:wrap}

/* The VAT block leads the sheet: identity before detail. */
.vat-block{padding:18px;border-radius:14px;background:var(--grad-soft);border:1px solid rgba(var(--accent-rgb),.22);margin-bottom:22px}
.vat-row{display:flex;gap:10px}
.vat-row .fld{flex:1}
.vat-result{margin-top:14px;padding:13px 15px;border-radius:11px;font-size:12.5px;line-height:1.55;border:1px solid}
.vat-result.ok{background:rgba(var(--green-rgb),.10);border-color:rgba(var(--green-rgb),.28)}
.vat-result.bad{background:rgba(var(--red-rgb),.10);border-color:rgba(var(--red-rgb),.28)}
.vat-result.warn{background:rgba(var(--amber-rgb),.10);border-color:rgba(var(--amber-rgb),.28)}
.vat-result.muted{background:rgba(var(--tint),.05);border-color:var(--stroke)}
.vat-result b{display:block;margin-bottom:4px;font-size:13px}
.vat-result .cn{font-family:var(--mono);font-size:10.5px;color:var(--muted);margin-top:7px;display:block;word-break:break-all}
.vat-result .btn{margin-top:10px}

/* Everything below the VAT block is inert until a number has been checked —
   a locked field is a hint, never the authority (the API re-validates). */
.fields-locked{opacity:.4;pointer-events:none;transition:opacity .25s}
.fields-locked.unlocked{opacity:1;pointer-events:auto}

.fld-group{margin-bottom:26px}
/* Title, then its explanation on the next line. Side by side, right-aligned,
   the note read as a second unrelated column — and every group heading set its
   own ragged left edge depending on how long the sentence was. */
.group-head{margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--stroke)}
.group-head h4{font:700 12px 'Inter',sans-serif;text-transform:uppercase;letter-spacing:.1em;color:var(--muted)}
.group-note{display:block;font-size:11.5px;color:var(--muted-2);max-width:64ch;line-height:1.5;margin-top:5px}
.fld-label{display:block;font-size:11.5px;font-weight:600;color:var(--muted);margin:12px 0 6px}
.fld-label:first-child{margin-top:0}
.fld{width:100%;padding:11px 13px;border-radius:11px;color:var(--text);font-size:13.5px;background:rgba(var(--tint-deep),.55);border:1px solid var(--stroke-2);transition:.16s;font-family:inherit;resize:vertical}
.fld:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px rgba(var(--accent-rgb),.13)}
.fld.narrow{width:70px;text-transform:uppercase}
/* Wide enough for "GR — Ελλάδα" without stealing the whole row from the town
   beside it, which is the field that actually varies. */
.country-col{flex:0 0 auto;width:200px;min-width:0}
.country-sel{font-family:inherit}
/* A <select> left to the UA draws its own arrow, positioned by the platform and
   ignoring the field's padding — next to a combobox, whose chevron sits where
   this stylesheet put it, the two read as different controls. Same glyph, same
   inset, so a native select and a learned-list combo look like one family.
   The colour is baked into the data URI (an SVG background cannot see
   currentColor), hence the light-theme twin below. */
select.fld{appearance:none;-webkit-appearance:none;padding-right:36px;cursor:pointer;
  background-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239fa09a' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");background-repeat:no-repeat;
  background-position:right 11px center;background-size:15px 15px}
.cargo-body.theme-light select.fld{background-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236d6f6a' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>")}
select.fld::-ms-expand{display:none}
.fld-hint{font-size:11.5px;color:var(--muted-2);margin-top:8px;line-height:1.5}
.fld-row{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
/* min-width, not 0: a growing field beside a fixed one (the country select is
   210px) would otherwise shrink to a few pixels in a narrow sheet and become
   untypable. With wrap on, the row breaks instead of crushing a field. */
.fld-row .grow{flex:1 1 165px;min-width:165px}
.fld-row>div>.fld-label{margin-top:12px}

.role-toggles{display:flex;flex-wrap:wrap;gap:8px}
.toggle{display:inline-flex;align-items:center;gap:8px;padding:9px 13px;border-radius:10px;background:rgba(var(--tint),.04);border:1px solid var(--stroke);cursor:pointer;font-size:12.5px;font-weight:500;transition:.16s;user-select:none}
.toggle:hover{background:rgba(var(--tint),.08)}
.toggle input{accent-color:rgb(var(--accent-rgb));width:15px;height:15px;cursor:pointer}
.toggle:has(input:checked){background:var(--grad-soft);border-color:rgba(var(--accent-rgb),.35);color:var(--text)}

/* Registry evidence: read-only on purpose. */
.registry{background:rgba(var(--tint),.03);border:1px solid var(--stroke);border-radius:14px;padding:16px 18px}
.registry .group-head{border-bottom-color:var(--stroke-2)}
.registry-list{display:grid;grid-template-columns:auto 1fr;gap:8px 16px;font-size:12.5px}
.registry-list dt{color:var(--muted-2);font-weight:600;white-space:nowrap}
.registry-list dd{color:var(--muted);white-space:pre-line;word-break:break-word}
.registry-list dd.mono{font-family:var(--mono);font-size:11px}

/* A parked registry change, shown where the operator will act on it. */
.pending-box{margin-bottom:20px;padding:16px 18px;border-radius:14px;background:rgba(var(--amber-rgb),.09);border:1px solid rgba(var(--amber-rgb),.3)}
.pending-box h4{font:700 13px 'Manrope',sans-serif;color:var(--amber);margin-bottom:6px}
.pending-box p{font-size:12px;color:var(--muted);line-height:1.55;margin-bottom:12px}
.diff{display:grid;gap:9px;margin-bottom:14px}
.diff-row{font-size:12px;background:rgba(var(--tint-deep),.4);border-radius:9px;padding:9px 11px}
.diff-row .k{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--muted-2);display:block;margin-bottom:5px}
.diff-row .was{color:var(--red);text-decoration:line-through;opacity:.8;display:block;word-break:break-word}
.diff-row .now{color:var(--green);display:block;word-break:break-word;margin-top:2px}
.pending-actions{display:flex;gap:8px}

/* ═══ merida detail ═══ */
.md-actions{margin-left:auto;display:flex;align-items:center;gap:9px}
.md-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;align-items:start}
.dim{color:var(--muted-2)}
.temp-on{color:var(--blue)}
.narrow-num{width:90px}
.req{color:var(--accent);font-weight:700}

/* The box number a field maps to on the printed consignment note. Shown next to
   the label so the operator can tie a screen field to the paper they know —
   and so `box-ref-none` can say out loud that the Πελάτης prints nowhere. */
.box-ref{font:600 9.5px var(--mono);letter-spacing:.06em;background:rgba(var(--tint),.07);color:var(--muted-2);padding:2px 6px;border-radius:5px;margin-left:6px;vertical-align:middle;text-transform:uppercase}
.box-ref-none{background:rgba(var(--violet-rgb),.14);color:var(--violet)}
/* On a table header the badge competes with the caption it annotates, which is
   already uppercase and letter-spaced. Quieter here, and it inherits none of
   the header's tracking. */
.tbl th .box-ref{letter-spacing:0;opacity:.6;margin-left:5px;padding:1px 5px}

.fld.has-error{border-color:var(--red);box-shadow:0 0 0 3px rgba(var(--red-rgb),.14)}
.inline-error,.fld-error{font-size:11.5px;color:var(--red);margin-top:6px}

/* ═══ settings ═══ */
.settings-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:18px;align-items:start}
.set-field{margin-bottom:16px}
.set-field:last-child{margin-bottom:0}

/* ═══ the party's CMR template ═══ */
.tpl-group{background:rgba(var(--green-rgb),.05);border:1px solid rgba(var(--green-rgb),.20);border-radius:14px;padding:16px 18px}
.tpl-group .group-head{border-bottom-color:rgba(var(--green-rgb),.22)}
.tpl-sub{font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2);margin:14px 0 8px}
.tpl-sub:first-child{margin-top:0}
.tpl-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px 12px}
.tpl-row-bool{grid-column:1/-1;display:flex;align-items:center;gap:8px}
.tpl-row .fld{padding:8px 11px;font-size:12.5px}
.tpl-row .fld-label{margin:0 0 5px}
/* A field the template just filled, so the operator can see what arrived by
   itself rather than wondering whether they typed it last week. */
.from-template{border-color:rgba(var(--green-rgb),.45);background:rgba(var(--green-rgb),.07)}

/* ═══ party picker ═══ */
.lg-changes{max-width:340px}
.lg-change{font-size:11.5px;color:var(--muted);line-height:1.5}
.lg-change b{color:var(--text);font-weight:600;font-family:var(--mono);font-size:10.5px}
.nowrap{white-space:nowrap}
.fld-inline{width:auto;padding:6px 10px;font-size:12px}
.pager{display:flex;align-items:center;justify-content:center;gap:12px;padding:14px 22px 18px}
.picker{position:relative}
.picker-input.picker-chosen{border-color:rgba(var(--accent-rgb),.45);background:var(--grad-soft);font-weight:600}
.picker-clear{position:absolute;right:10px;top:9px;width:26px;height:26px;border-radius:7px;border:none;background:rgba(var(--tint),.08);color:var(--muted);cursor:pointer;font-size:17px;line-height:1}
.picker-clear:hover{background:rgba(var(--red-rgb),.16);color:var(--red)}
.picker-menu{position:absolute;left:0;right:0;top:calc(100% + 5px);z-index:20;background:var(--panel-solid);border:1px solid var(--stroke-2);border-radius:12px;box-shadow:0 20px 48px -16px rgba(0,0,0,.65);overflow:hidden;max-height:280px;overflow-y:auto}
.picker-opt{width:100%;display:flex;align-items:center;gap:10px;padding:11px 13px;background:none;border:none;border-bottom:1px solid var(--stroke);cursor:pointer;text-align:left;color:var(--text);font:inherit;font-size:13px}
.picker-opt:last-child{border-bottom:none}
.picker-opt:hover{background:var(--grad-soft)}
.po-name{flex:1;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.po-meta{font-size:11px;color:var(--muted-2);flex:none}
.picker-opt .pill{padding:0;width:8px;height:8px;border-radius:50%;flex:none}
.picker-opt .pill::before{display:none}
.picker-opt .pill.ok{background:var(--green)}
.picker-opt .pill.bad{background:var(--red)}
.picker-opt .pill.muted{background:var(--muted-2)}
.picker-empty{padding:14px;font-size:12.5px;color:var(--muted-2);text-align:center}
/* Why these results are being offered even though none carries the role. */
.picker-note{padding:9px 13px;font-size:11.5px;line-height:1.45;color:var(--muted-2);
  background:rgba(var(--tint),.05);border-bottom:1px solid var(--stroke)}

/* ═══ CMR box editor ═══ */
/* The consignment note editor. 26 boxes in one column is a long scroll; at
   this width they go two-up and the whole note is closer to one screen. */
.sheet-wide{width:min(1080px,calc(100vw - 32px))}
.sheet-wide #cmr-boxes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 22px;align-items:start}
/* The party blocks are the tall ones and read better full width. */
.sheet-wide .bx-row.bx-span{grid-column:1/-1}
.notice-bad{background:rgba(var(--red-rgb),.10);border-color:rgba(var(--red-rgb),.28);color:var(--red)}
.notice-bad b{color:var(--text)}

/* The provenance dot. Four states, one glance: derived from the data, from the
   company settings, typed by hand, or deliberately blank. This is what makes
   "every field is editable" legible instead of alarming. */
.prov{width:8px;height:8px;border-radius:50%;display:inline-block;flex:none}
.prov-derived{background:var(--blue)}
.prov-company{background:var(--violet)}
/* Distinct from manual on purpose: "the template did this" and "I did this" are
   different levels of trust, and the operator should be able to tell them apart
   without opening anything. */
.prov-template{background:var(--green)}
.prov-manual{background:var(--accent)}
.prov-blank{background:transparent;border:1.5px dashed var(--muted-2)}
.prov-legend{display:flex;gap:16px;flex-wrap:wrap;font-size:11.5px;color:var(--muted);margin-bottom:8px}
.prov-legend span{display:inline-flex;align-items:center;gap:6px}
.prov-note{font-size:11.5px;color:var(--muted-2);line-height:1.5;margin-bottom:18px}

.bx-row{margin-bottom:14px;padding-left:10px;border-left:2px solid transparent}
.bx-row.is-overridden{border-left-color:var(--accent)}
.bx-row.is-missing{border-left-color:var(--red)}
.bx-head{display:flex;align-items:center;gap:8px;margin-bottom:5px}
.bx-no{font:700 10px var(--mono);min-width:20px;height:18px;padding:0 5px;border-radius:5px;background:rgba(var(--tint),.08);color:var(--muted);display:inline-flex;align-items:center;justify-content:center;flex:none}
.bx-no-hdr{opacity:.45}
.bx-label{font-size:11.5px;font-weight:600;color:var(--muted)}
.bx-revert{margin-left:auto;width:24px;height:24px;border-radius:6px;border:none;background:rgba(var(--accent-rgb),.16);color:var(--accent);cursor:pointer;font-size:13px;line-height:1}
.bx-revert:hover{background:rgba(var(--accent-rgb),.3)}
.bx-input{font-size:13px;padding:9px 11px}
/* Box 20's grid, laid out as the paper has it rather than as thirteen rows. */
.ch-block{padding-left:10px}
.ch-tbl{width:100%;border-collapse:collapse;margin-top:6px}
.ch-tbl th{font:700 9.5px 'Inter',sans-serif;letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted-2);padding:4px 6px;text-align:center}
.ch-tbl th:first-child{width:36%}
.ch-tbl td{padding:2px 3px}
.ch-tbl .ch-lbl{font-size:11.5px;color:var(--muted);padding-right:8px}
.ch-tbl .ch-mid{width:16%}
.ch-tbl .ch-in{padding:6px 8px;font-size:12.5px;text-align:right;font-family:var(--mono)}
.ch-tbl .ch-cur .ch-in{text-align:center;text-transform:uppercase}
.ch-tbl .ch-total .ch-lbl{color:var(--text);font-weight:700}
.ch-tbl .ch-total .ch-in{font-weight:700}
.cmr-link{display:flex;align-items:center;gap:9px;padding:10px 14px;margin-right:auto;
  background:rgba(var(--tint),.05);border:1px solid var(--stroke);border-radius:11px;max-width:520px}
.cmr-link.is-off{border-color:rgba(var(--red-rgb),.35);background:rgba(var(--red-rgb),.06)}
.cmr-link-label{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--muted-2);flex:none}
.cmr-link .fld{flex:1;min-width:0;padding:6px 9px;font-size:11.5px}
.cmr-link.is-off .fld{text-decoration:line-through;opacity:.6}
/* The scanned page: a stranger's phone, so it is one column and large text. */
.pub-stage{min-height:100dvh;display:grid;place-items:center;padding:22px 16px}
.pub-card{width:100%;max-width:640px;padding:0;overflow:hidden}
.pub-card-msg{padding:38px 28px;text-align:center}
.pub-card-msg h1{font:800 20px/1.25 'Manrope',sans-serif;margin:14px 0 8px}
.pub-card-msg p{color:var(--muted);font-size:13.5px;line-height:1.55}
.pub-banner{display:flex;align-items:center;gap:10px;padding:16px 22px;font:800 15px/1.2 'Manrope',sans-serif}
.pub-banner.is-valid{background:rgba(var(--green-rgb),.16);color:var(--green)}
.pub-banner.is-void{background:rgba(var(--red-rgb),.18);color:var(--red)}
.pub-head{padding:20px 22px 4px}
.pub-ref{font:800 26px/1.1 'Manrope',sans-serif;letter-spacing:-.02em}
.pub-sub{font-size:12.5px;color:var(--muted);font-family:var(--mono);margin-top:4px}
.pub-note-void{margin:14px 22px;padding:12px 14px;border-radius:10px;background:rgba(var(--red-rgb),.08);font-size:13px}
.pub-note-void p{color:var(--muted);margin-top:4px;line-height:1.5}
.pub-boxes{padding:14px 22px 6px}
.pub-boxes dt{display:flex;align-items:center;gap:8px;font-size:11px;font-weight:600;color:var(--muted-2);
  text-transform:uppercase;letter-spacing:.06em;margin-top:14px}
.pub-boxes dd{font-size:14px;line-height:1.5;margin-top:3px}
.pub-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:16px 22px;border-top:1px solid var(--stroke);margin-top:14px;font-size:12.5px;color:var(--muted)}
.pub-brand{padding:0 22px 18px;font-size:11px;color:var(--muted-2);text-align:center}
.bx-ticks{display:flex;gap:8px;flex-wrap:wrap;margin-top:2px}
.bx-tick{display:inline-flex;align-items:center;gap:7px;padding:9px 13px;border-radius:10px;
  background:rgba(var(--tint-deep),.55);border:1px solid var(--stroke-2);cursor:pointer;
  font-size:13px;color:var(--text);transition:.15s;font-family:inherit}
.bx-tick:hover{border-color:var(--stroke)}
.bx-tick.is-on{border-color:var(--accent);background:var(--grad-soft);font-weight:600}
.bx-tick-clear{color:var(--muted-2);padding:9px 12px}
.agr-row{display:flex;align-items:center;gap:10px;margin-top:5px}
.agr-lbl{flex:none;width:190px;font-size:11.5px;color:var(--muted)}
.agr-in{flex:1;text-align:left}
.agr-tick{display:inline-flex;align-items:center;gap:8px;margin-top:9px;font-size:13px;cursor:pointer}
.ch-frozen{font-size:12.5px;font-family:var(--mono);color:var(--text)}
.bx-derived{font-size:11px;color:var(--muted-2);margin-top:5px;font-style:italic}
.bx-frozen{font-size:13px;line-height:1.45;padding:9px 11px;border-radius:9px;background:rgba(var(--tint),.04);border:1px solid var(--stroke);white-space:pre-line}
.act-cmr{color:var(--accent)}
.act-cmr:hover{background:rgba(var(--accent-rgb),.14)}
.vr{font-size:11px;font-style:italic}

/* ═══ combobox ═══
   A list AND a text field at once. It has to look like both: the chevron says
   "there is a list", the caret says "you may type". The native <datalist> popup
   said neither — it was invisible until you started typing. */
.combo{position:relative;display:block}
.combo-input{width:100%;padding-right:36px !important}
.combo-toggle{position:absolute;right:6px;top:50%;transform:translateY(-50%);width:26px;height:26px;
  border:none;background:none;color:var(--muted-2);cursor:pointer;display:grid;place-items:center;
  border-radius:7px;transition:.15s}
.combo-toggle:hover{color:var(--text);background:rgba(var(--tint),.08)}
.combo-toggle .icn{width:15px;height:15px;transition:transform .18s}
.combo.is-open .combo-toggle .icn{transform:rotate(180deg)}
.combo.is-open .combo-input{border-color:var(--accent);box-shadow:0 0 0 4px rgba(var(--accent-rgb),.13)}
/* On a textarea the chevron belongs on the first line, not floating halfway
   down a growing paragraph. */
.combo textarea.combo-input+.combo-toggle{top:7px;transform:none}

.combo-menu{position:absolute;left:0;right:0;min-width:230px;top:calc(100% + 5px);z-index:30;
  background:var(--panel-solid);border:1px solid var(--stroke-2);border-radius:12px;
  box-shadow:0 20px 48px -16px rgba(0,0,0,.65);overflow-y:auto;max-height:264px;padding:4px}
.combo-opt{width:100%;display:flex;align-items:center;gap:9px;padding:9px 11px;background:none;
  border:none;border-radius:8px;cursor:pointer;text-align:left;color:var(--text);font:inherit;font-size:13px}
.combo-opt:hover,.combo-opt.is-active{background:var(--grad-soft)}
/* The live section sits under the saved one, visibly second — the office's own
   words are the answer, the map is the fallback. */
.combo-sec{padding:8px 11px 5px;font:700 9.5px 'Inter',sans-serif;letter-spacing:.11em;
  text-transform:uppercase;color:var(--muted-2);border-top:1px solid var(--stroke)}
/* A map result is two lines, not two columns: the town on top, the country and
   region small underneath. Side by side, the hint took whatever width it wanted
   and the name — the only part anyone reads — got the ellipsis. */
.combo-place{flex-direction:column;align-items:stretch;gap:1px;padding-top:8px;padding-bottom:8px}
.combo-place .co-value{flex:none;white-space:normal;overflow:visible;text-overflow:clip;line-height:1.3}
.combo-place .co-hint{font:500 10px var(--mono);color:var(--muted-2);letter-spacing:.03em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.35}
.combo-attr{padding:6px 11px 8px;font-size:9.5px;color:var(--muted-2);opacity:.75;text-align:right}
.co-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.combo-empty{padding:13px 11px;font-size:12.5px;color:var(--muted-2);text-align:center;font-style:italic}

/* The explicit "none" choice, set apart because it means the opposite of
   every other row in the list. */
.combo-none{color:var(--muted-2);font-style:italic;border-bottom:1px solid var(--stroke);
  border-radius:8px 8px 0 0;margin-bottom:4px;padding-bottom:11px}

/* The "use what I typed" row. Separated by a rule and marked with a + so it
   reads as an action rather than as another existing entry. */
.combo-new{border-top:1px solid var(--stroke);border-radius:0 0 8px 8px;margin-top:4px;padding-top:11px}
.co-new-mark{width:18px;height:18px;border-radius:5px;background:rgba(var(--green-rgb),.16);color:var(--green);
  display:grid;place-items:center;font:700 13px/1 'Inter',sans-serif;flex:none}
.combo-new .co-value{font-weight:600}
.co-hint{font-size:10.5px;color:var(--muted-2);flex:none}

/* Inside the two-column CMR editor the menu must escape its grid cell. */
.bx-row .combo-menu{min-width:100%}

/* ═══ learned lists ═══ */
.lists-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:18px;align-items:start}
.list-card{padding:18px 20px}
.list-card .head{margin-bottom:12px}
.term-list{list-style:none;display:flex;flex-direction:column;gap:2px;max-height:280px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--stroke-2) transparent}
.term{display:flex;align-items:center;gap:9px;padding:7px 9px;border-radius:9px;font-size:13px;transition:.14s}
.term:hover{background:rgba(var(--tint),.05)}
.term-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Usage count, quiet until it matters — a learned one-off sits at 1 next to a
   word used two hundred times, and that contrast is the whole signal. */
.term-uses{font:600 10.5px var(--mono);color:var(--muted-2);background:rgba(var(--tint),.06);padding:2px 6px;border-radius:5px;flex:none}
.term-learned{font-size:9.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--green);background:rgba(var(--green-rgb),.13);padding:2px 6px;border-radius:5px;flex:none}
.term-off .term-value{opacity:.42;text-decoration:line-through}
.term-empty{color:var(--muted-2);font-size:12.5px;font-style:italic;padding:12px 9px}
.term-empty:hover{background:none}
.term-actions{display:flex;gap:1px;flex:none;opacity:0;transition:.14s}
.term:hover .term-actions,.term:focus-within .term-actions{opacity:1}
.term-actions .icon-btn{width:28px;height:28px}
.term-add{display:flex;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--stroke)}
.term-add .fld{flex:1;padding:8px 11px;font-size:12.5px}

/* ═══ modal + toasts ═══ */
.modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-46%);width:min(420px,calc(100vw - 32px));background:var(--panel-solid);border:1px solid var(--stroke-2);border-radius:18px;padding:26px;z-index:100;opacity:0;transition:.22s;box-shadow:0 30px 70px -20px rgba(0,0,0,.75)}
.modal.show{opacity:1;transform:translate(-50%,-50%)}
.modal h3{font:800 17px 'Manrope',sans-serif;margin-bottom:9px}
/* pre-line: the issue-anyway dialog lists one warning per line. */
.modal p{font-size:13px;color:var(--muted);line-height:1.6;white-space:pre-line}
.modal .fld{margin-top:14px}
.modal-foot{display:flex;justify-content:flex-end;gap:9px;margin-top:22px}

.toast-stack{position:fixed;right:22px;bottom:22px;z-index:120;display:flex;flex-direction:column;gap:9px;pointer-events:none}
.toast{background:var(--panel-solid);border:1px solid var(--stroke-2);border-left:3px solid var(--accent);border-radius:12px;padding:13px 17px;font-size:13px;font-weight:500;box-shadow:0 18px 44px -16px rgba(0,0,0,.6);animation:toastIn .28s cubic-bezier(.4,0,.2,1);max-width:360px}
.toast.ok{border-left-color:var(--green)}
.toast.bad{border-left-color:var(--red)}
.toast.warn{border-left-color:var(--amber)}
@keyframes toastIn{from{opacity:0;transform:translateX(20px)}to{opacity:1;transform:none}}

.spin{display:inline-block;width:14px;height:14px;border:2px solid rgba(var(--tint),.25);border-top-color:currentColor;border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ═══ responsive ═══ */
@media (max-width:1100px){
  .stats{grid-template-columns:repeat(2,1fr)}
  .md-grid{grid-template-columns:1fr}
}
@media (max-width:720px){
  .sheet, .sheet-wide{width:100vw;max-width:100vw;max-height:100vh;height:100vh;border-radius:0;border:none;
    top:0;left:0;transform:translateY(2%);}
  .sheet.show{transform:none}
  .sheet-wide #cmr-boxes{grid-template-columns:1fr}
  /* Side by side there is no width left for either: the sentence would wrap to
     four lines to make room for a button that then sits alone in a corner. */
  #page-dashboard .table-card .head{flex-direction:column;align-items:stretch;gap:14px}
}
@media (max-width:860px){
  .shell{grid-template-columns:1fr}
  .side{position:static;height:auto;flex-direction:row;flex-wrap:wrap;align-items:center;border-right:none;border-bottom:1px solid var(--stroke)}
  .side .logo{padding:0 12px 0 0}
  .nav{flex-direction:row;overflow-x:auto;flex-wrap:nowrap;gap:4px}
  .nav-label{display:none}
  .nav-item.active::before{display:none}
  .side-foot{margin:0 0 0 auto}
  .main{padding:18px 16px 48px}
  .search{width:100%;margin-left:0;order:3}
}
@media (max-width:560px){
  .stats{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}
}

/* The password sheet is three short fields; the party sheet's width would leave
   it mostly empty and read as an unfinished form. */
.sheet-narrow{max-width:440px}
.fld-hint.bad{color:var(--red)}

/* 404. The numeral is the fastest way to say "wrong address, not broken server",
   so it leads — but quietly: it is a fact about the URL, not an error the reader
   caused. */
.nf-code{font:800 56px/1 'Manrope',sans-serif;letter-spacing:-.04em;color:var(--muted-2);opacity:.5;margin-bottom:6px}
.nf-back{margin-top:22px}

/* The per-shipment load breakdown. Chips rather than a comma list: ten numbers
   run together are unreadable, and a separator character is one more thing to
   scan past. Wraps rather than scrolling — a ten-consignment trailer is a tall
   row, which is honest about what it is carrying. */
.loads{max-width:220px}
.load{display:inline-block;font:600 11px/1 var(--mono);padding:3px 6px;margin:2px 3px 2px 0;border-radius:6px;
  background:rgba(var(--tint),.06);color:var(--muted);white-space:nowrap}
/* A shipment nobody has weighed yet. Visible rather than hidden: it is the one
   that makes the total wrong. */
.load.zero{color:var(--muted-2);border:1px dashed var(--stroke-2);background:none}
.load.more{background:none;color:var(--muted-2);padding-left:2px}

/* The load cell is a button in all but name — say so, or nobody discovers the
   manifest behind it. The whole cell is the target, not each chip: eight small
   click targets for one action is eight chances to miss. */
td.loads{cursor:pointer}
td.loads:hover .load{background:rgba(var(--accent-rgb),.14);color:var(--accent)}
td.loads:hover .load.zero{background:none;border-color:rgba(var(--accent-rgb),.4)}
#cargo-table tfoot td{border-top:1px solid var(--stroke-2);padding-top:12px;font-size:12.5px}
