/**
 * shadcn/ui design language, as plain CSS.
 *
 * The portal has no build step, no npm and no framework — pages are server-rendered PHP with
 * their own <style> block. So this is not shadcn the library (React + Tailwind + Radix); it is
 * shadcn's DESIGN SYSTEM expressed as ordinary custom properties and classes that any of those
 * pages can opt into by linking this file.
 *
 * Token names and values are shadcn's own (zinc base, "new-york" style), kept as HSL triplets
 * so a colour can be used at any opacity with hsl(var(--x) / .5) exactly as Tailwind does.
 */

:root {
  --background: 0 0% 100%;
  --foreground: 240 10% 3.9%;
  --card: 0 0% 100%;
  --card-foreground: 240 10% 3.9%;
  --primary: 240 5.9% 10%;
  --primary-foreground: 0 0% 98%;
  --secondary: 240 4.8% 95.9%;
  --secondary-foreground: 240 5.9% 10%;
  --muted: 240 4.8% 95.9%;
  --muted-foreground: 240 3.8% 46.1%;
  --accent: 240 4.8% 95.9%;
  --accent-foreground: 240 5.9% 10%;
  --destructive: 0 72.2% 50.6%;
  --destructive-foreground: 0 0% 98%;
  --success: 142 71% 29%;
  --warning: 32 95% 34%;
  --info: 221 83% 45%;
  --border: 240 5.9% 90%;
  --input: 240 5.9% 90%;
  --ring: 240 5.9% 10%;
  --radius: 0.5rem;

  /* The warehouse's own meanings, mapped onto the palette above rather than invented again. */
  --ink: hsl(var(--foreground));
  --mut: hsl(var(--muted-foreground));
  --line: hsl(var(--border));
  /* css/nav.css is shared and unrestyled, and paints the CURRENT page's nav link as
     `color:#fff` on `background:var(--acc)`. Undefined, that background collapses to nothing
     and the label is white on white — the Reports link vanished the moment you were on
     Reports. It belongs here, not per page: nav.css also spends --acc on every focus outline
     and on the notification bell, so a page missing it lost those silently too. */
  --acc: hsl(var(--primary));
}

/* The dark palette ships with the tokens so a theme toggle is a one-line change later.
   Nothing opts into it yet — no page sets data-theme. */
[data-theme="dark"] {
  --background: 240 10% 3.9%;
  --foreground: 0 0% 98%;
  --card: 240 10% 3.9%;
  --card-foreground: 0 0% 98%;
  --primary: 0 0% 98%;
  --primary-foreground: 240 5.9% 10%;
  --secondary: 240 3.7% 15.9%;
  --secondary-foreground: 0 0% 98%;
  --muted: 240 3.7% 15.9%;
  --muted-foreground: 240 5% 64.9%;
  --accent: 240 3.7% 15.9%;
  --accent-foreground: 0 0% 98%;
  --destructive: 0 62.8% 30.6%;
  --border: 240 3.7% 15.9%;
  --input: 240 3.7% 15.9%;
  --ring: 240 4.9% 83.9%;
}

/* ---------- base ---------- */

.sh, .sh * { box-sizing: border-box; }

.sh {
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font: 14px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.006em;          /* shadcn's slightly tightened body text */
}

.sh h1, .sh h2, .sh h3 { margin: 0; font-weight: 600; letter-spacing: -0.02em; }

/* ---------- card ---------- */

.sh-card {
  background: hsl(var(--card));
  color: hsl(var(--card-foreground));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  /* shadcn's shadow-sm — a hairline lift, not a drop shadow */
  box-shadow: 0 1px 2px 0 hsl(var(--foreground) / .05);
}
.sh-card-head { padding: 20px 24px 12px; }
.sh-card-title { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
.sh-card-desc { margin-top: 4px; font-size: 13px; color: hsl(var(--muted-foreground)); }
.sh-card-body { padding: 0 0 4px; }

/* ---------- button ---------- */

.sh-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 36px; padding: 0 14px;
  border: 1px solid transparent; border-radius: calc(var(--radius) - 2px);
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  font: inherit; font-size: 13px; font-weight: 500; white-space: nowrap;
  cursor: pointer; transition: background-color .15s, color .15s, border-color .15s, opacity .15s;
}
.sh-btn:hover { background: hsl(var(--primary) / .9); }
.sh-btn:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; }
.sh-btn:disabled { opacity: .5; cursor: default; }

.sh-btn-outline {
  background: hsl(var(--background)); color: hsl(var(--foreground));
  border-color: hsl(var(--border));
}
.sh-btn-outline:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }

.sh-btn-ghost { background: transparent; color: hsl(var(--foreground)); }
.sh-btn-ghost:hover { background: hsl(var(--accent)); }

.sh-btn-destructive { background: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
.sh-btn-destructive:hover { background: hsl(var(--destructive) / .9); }

.sh-btn-sm { height: 32px; padding: 0 10px; font-size: 12px; }

/* ---------- input ---------- */

.sh-input {
  display: block; width: 100%; height: 40px; padding: 0 12px;
  border: 1px solid hsl(var(--input)); border-radius: calc(var(--radius) - 2px);
  background: hsl(var(--background)); color: hsl(var(--foreground));
  font: inherit; font-size: 14px;
}
.sh-input::placeholder { color: hsl(var(--muted-foreground)); }
.sh-input:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: -1px; border-color: transparent; }

/* ---------- badge ---------- */

.sh-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px; border: 1px solid transparent; border-radius: 9999px;
  font-size: 11.5px; font-weight: 600; line-height: 1.45; white-space: nowrap;
}
.sh-badge-secondary { background: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); }
.sh-badge-outline   { border-color: hsl(var(--border)); color: hsl(var(--foreground)); }
.sh-badge-success   { background: hsl(var(--success) / .10); color: hsl(var(--success)); }
.sh-badge-warning   { background: hsl(var(--warning) / .12); color: hsl(var(--warning)); }
.sh-badge-info      { background: hsl(var(--info) / .10);    color: hsl(var(--info)); }
.sh-badge-destructive { background: hsl(var(--destructive) / .10); color: hsl(var(--destructive)); }

/* ---------- table ---------- */

.sh-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.sh-table thead th {
  height: 44px; padding: 0 16px; text-align: left; vertical-align: middle;
  font-size: 12px; font-weight: 500; color: hsl(var(--muted-foreground));
  border-bottom: 1px solid hsl(var(--border));
  background: transparent;                      /* shadcn headers are plain, not filled */
}
.sh-table tbody td { padding: 12px 16px; border-bottom: 1px solid hsl(var(--border)); vertical-align: top; }
.sh-table tbody tr:last-child td { border-bottom: 0; }
.sh-table tbody tr { transition: background-color .12s; }
.sh-table tbody tr:hover { background: hsl(var(--muted) / .5); }
.sh-num { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- misc ---------- */

.sh-muted { color: hsl(var(--muted-foreground)); }
.sh-sep { height: 1px; background: hsl(var(--border)); border: 0; margin: 0; }
.sh-empty { padding: 48px 24px; text-align: center; color: hsl(var(--muted-foreground)); font-size: 14px; }

/* Skeleton rows: shadcn shows shape while data loads rather than the word "Loading". */
.sh-skel { height: 14px; border-radius: 4px; background: hsl(var(--muted)); animation: sh-pulse 1.6s ease-in-out infinite; }
@keyframes sh-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .45 } }
@media (prefers-reduced-motion: reduce) { .sh-skel { animation: none } }

/* =====================================================================
   PORTAL CHROME MAPPING
   ---------------------------------------------------------------------
   Everything above is the design system itself. What follows maps the
   portal's OWN long-standing class names onto it, so a page adopts the
   look by linking this file LAST — after nav.css and portal.css and after
   its own <style> block — rather than by having its markup rewritten.

   Load order is the whole mechanism: same selectors, same specificity,
   last one wins. Anything a page must keep (its dialogs, its bespoke
   widgets) simply stays in that page's own block and is not named here.
   ===================================================================== */

body {
  margin: 0;
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font: 14px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.006em;
}

/* ---- header ---------------------------------------------------------- */
header {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  min-height: 56px; padding: 0 24px;
  background: hsl(var(--background));
  border-bottom: 1px solid hsl(var(--border));
}
header h1 { margin: 0; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; }
header nav { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: 2px; }
header nav a {
  display: inline-flex; align-items: center; height: 32px; padding: 0 10px; margin: 0;
  border-radius: calc(var(--radius) - 2px);
  color: hsl(var(--muted-foreground)); text-decoration: none;
  font-size: 13px; font-weight: 500;
  transition: background-color .12s, color .12s;
}
header nav a:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
header nav a[aria-current="page"] { background: hsl(var(--secondary)); color: hsl(var(--foreground)); }
header nav .muted { font-size: 13px; margin-right: 8px; }
.muted { color: hsl(var(--muted-foreground)); }

/* Always reserve the scrollbar's width, whether or not this page needs one. A short page
   (Reports) has no scrollbar and a long one (My Orders) does, so the viewport changed width
   between them and every centred thing on the bar slid by half a scrollbar. Reserving it
   costs 15px of a screen nobody was using and makes the bar identical on both. */
html { scrollbar-gutter: stable; }

/* The buttons must not move when you change page.
   Centring them inside the nav was not enough: the nav starts where the title ends, so
   "Manager — Incoming orders" pushed every button ~60px right of where "Reports" put them,
   and a button that moves is one you have to look for each time.
   So the header itself becomes the ruler — a 1fr/auto/1fr grid whose middle column is the
   links. Both outer columns take the same share of whatever is left, which pins the middle
   column to the centre of the HEADER no matter how wide the title or the end group are.
   `display: contents` lets the nav's own children become those grid items, so this needs no
   extra wrapper element around the title. */
@media (min-width: 1100px) {
  header { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
  header nav { display: contents; }
  header nav .navlinks { display: flex; align-items: center; gap: 2px; justify-self: center; }
  header nav .navend {
    display: flex; align-items: center; gap: 6px; justify-self: end;
  }
}

/* Below that the title, the buttons and the end group cannot all share one row without the
   middle colliding with the sides, so they go back to wrapping — which is what phones and
   the van have always had. */
header nav .navlinks, header nav .navend { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }

main { max-width: 1560px; margin: 24px auto 64px; padding: 0 24px; }

/* ---- surfaces -------------------------------------------------------- */
.wrap, .card, .box, .panel {
  background: hsl(var(--card)); color: hsl(var(--card-foreground));
  border: 1px solid hsl(var(--border)); border-radius: var(--radius);
  box-shadow: 0 1px 2px 0 hsl(var(--foreground) / .05);
}

/* ---- tables ---------------------------------------------------------- */
table { border-collapse: collapse; font-size: 13.5px; }
th {
  height: 44px; padding: 0 16px; text-align: left; vertical-align: middle;
  font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none;
  color: hsl(var(--muted-foreground)); border-bottom: 1px solid hsl(var(--border));
  background: transparent;
}
td { padding: 12px 16px; border-bottom: 1px solid hsl(var(--border)); vertical-align: top; }
tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ---- controls -------------------------------------------------------- */
input[type=text], input[type=search], input[type=number], input[type=date],
input[type=password], select, textarea {
  height: 40px; padding: 0 12px;
  border: 1px solid hsl(var(--input)); border-radius: calc(var(--radius) - 2px);
  background: hsl(var(--background)); color: hsl(var(--foreground));
  font: inherit; font-size: 14px;
}
textarea { height: auto; padding: 10px 12px; }
input::placeholder, textarea::placeholder { color: hsl(var(--muted-foreground)); }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid hsl(var(--ring)); outline-offset: -1px; border-color: transparent;
}

button {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 36px; padding: 0 14px;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) - 2px);
  background: hsl(var(--background)); color: hsl(var(--foreground));
  font: inherit; font-size: 13px; font-weight: 500; white-space: nowrap; cursor: pointer;
  transition: background-color .12s, color .12s, border-color .12s;
}
button:hover:not(:disabled) { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
button:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; }
button:disabled { opacity: .5; cursor: default; }
/* the one filled action per screen keeps its weight */
button.primary {
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); border-color: transparent;
}
button.primary:hover:not(:disabled) { background: hsl(var(--primary) / .9); color: hsl(var(--primary-foreground)); }

/* ---- status vocabulary ----------------------------------------------- */
.chip, .tag, .st, span.ret, .badge {
  /* span.ret, not bare .ret: 'ret' is also used as a MODIFIER elsewhere
     (reports.php has <div class="kpi ret">, a stat tile), and a bare rule here
     turned that tile into a pill. Every element that actually wants the return
     badge is a span; the ones that do not are not. */
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px; border: 1px solid transparent; border-radius: 9999px;
  font-size: 11.5px; font-weight: 600; line-height: 1.45;
}
.chip.ok,    .st.f, .tag.ok    { background: hsl(var(--success) / .10);     color: hsl(var(--success)); }
.chip.miss,  .st.r, .tag.miss  { background: hsl(var(--destructive) / .10); color: hsl(var(--destructive)); }
.chip.warn,  .st.p, .tag.short { background: hsl(var(--warning) / .12);     color: hsl(var(--warning)); }
.chip.wait,  .st.h             { background: hsl(var(--secondary));         color: hsl(var(--secondary-foreground)); }
.chip.type,  .st.a             { background: hsl(var(--info) / .10);        color: hsl(var(--info)); }
span.ret                       { background: hsl(322 80% 43% / .10);        color: hsl(322 80% 43%); }
.short { color: hsl(var(--destructive)); }

/* ---- odds and ends --------------------------------------------------- */
.empty { padding: 48px 24px; text-align: center; color: hsl(var(--muted-foreground)); font-size: 14px; }
.pager { display: flex; justify-content: space-between; align-items: center; gap: 14px;
         padding: 12px 16px; border-top: 1px solid hsl(var(--border)); }
.pager button { height: 32px; padding: 0 12px; font-size: 12px; }
.warnbox {
  padding: 12px 14px; border: 1px solid hsl(var(--warning) / .3); border-radius: var(--radius);
  background: hsl(var(--warning) / .08); color: hsl(var(--warning));
}
a { color: hsl(var(--info)); }

/* =====================================================================
   TOAST
   ---------------------------------------------------------------------
   The portal used to announce failure with alert() and success with
   nothing at all, so a save that worked looked identical to a dead
   button. This is the quiet half of that pair. js/toast.js drives it.
   ===================================================================== */

.toast-tray {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  z-index: 9999; display: flex; flex-direction: column; gap: 8px;
  align-items: center; pointer-events: none; width: max-content; max-width: 92vw;
}
.toast {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 14px; border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  background: hsl(var(--card)); color: hsl(var(--foreground));
  box-shadow: 0 8px 24px hsl(var(--foreground) / .12);
  font-size: 13.5px; font-weight: 500; text-align: left;
  animation: toast-in .22s cubic-bezier(.16, 1, .3, 1);
}
.toast.out { animation: toast-out .16s ease-in forwards; }
.toast .dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; }
.toast.ok   .dot { background: hsl(var(--success)); }
.toast.warn .dot { background: hsl(var(--warning)); }
.toast.bad  .dot { background: hsl(var(--destructive)); }

@keyframes toast-in  { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px) } }
@media (prefers-reduced-motion: reduce) {
  .toast, .toast.out { animation: none; }
}

/* Waiting: shape, not the word "Loading". A stalled fetch and a slow one look
   different, which is the whole point — .sh-skel is defined further up. */
.skelrow { display: flex; gap: 12px; align-items: center; padding: 12px 16px;
           border-bottom: 1px solid hsl(var(--border)); }
.skelrow > span { display: block; height: 12px; border-radius: 4px;
                  background: hsl(var(--muted)); animation: sh-pulse 1.6s ease-in-out infinite; }

/* How long an order has been waiting. Neutral until it is genuinely old. */
.age { font-variant-numeric: tabular-nums; }
.age.old   { color: hsl(var(--warning)); font-weight: 600; }
.age.stale { color: hsl(var(--destructive)); font-weight: 700; }
