/* ONE palette, ONE table, for every page.
 *
 * WHY THIS IS HERE
 * ----------------
 * Every page carried its own copy of these values, and copies drift. Measured
 * across the fourteen pages before this block existed:
 *
 *   - TWO navy blues. Eleven pages used #0d3b66; gearbid, po and top_products
 *     used #1F4E78. Since shell.css paints the header #0d3b66, those three
 *     pages showed both — a #0d3b66 bar with #1F4E78 table headers and buttons
 *     an inch below it. The most visible defect on the site, and nothing in any
 *     single file looked wrong.
 *   - Body ink #1c2733 on eleven pages, #1f2d3d on three. Borders #e3e8ef vs
 *     #d7dee5.
 *   - Five different table-header sizes (.70 / .73 / .74 / .75 / .78rem) for
 *     the same element.
 *   - Five different page widths, so the content edge moved as you navigated.
 *
 * shell.css was already linked from all fourteen pages, so the pipe existed;
 * only the values had never moved into it. They live here now and the pages
 * define only what is genuinely theirs.
 *
 * ADDING A COLOUR: put it here, not in a page. A value that appears in two
 * pages is a token that has not been written down yet.
 */
:root {
  /* Text */
  --ink: #1c2733;      /* body copy, table cells */
  --ink-2: #5b6875;    /* labels, column headers, secondary text */
  --ink-3: #8a97a6;    /* captions, hints, disabled */

  /* Surfaces and rules */
  --surface: #ffffff;
  --card: #f7f9fc;     /* tiles, panels, toolbars */
  --line: #e3e8ef;     /* borders, dividers, table header rule */
  --row-line: #eef2f7; /* the lighter rule BETWEEN table rows */
  --row-hover: #f2f7fc;

  /* Brand. --bar is a documented alias for --hero2, kept because four pages
     already use that name for the same colour and renaming them buys nothing. */
  --hero1: #0d3b66;    /* header bar, headings, primary buttons */
  --hero2: #1b5e94;    /* hover, accents, secondary bars */
  --bar: #1b5e94;

  /* Direction. Only ever these two — a third green or red is a bug. */
  --up: #1a7f37;
  --down: #c0392b;
  --down-bg: #fdf1ef;   /* the only red fill: a stale-data warning */

  /* Type scale for tables */
  --table-size: .86rem;
  --th-size: .73rem;

  /* Page widths. Named by JOB, not by number. There were six values across
     the pages; 1500px and 1320px were nobody's decision, just where those two
     pages happened to land, so they fold into the nearest real one. What is
     left is three widths that each answer a question:
        --page-w         dense tables — give them the room
        --page-w-narrow  report pages of cards and figures — read better tighter
        --page-w-form    the admin screen — a short form does not want 1560px
     index.html keeps its own 920px: it is a landing page of tiles, not data,
     and it is the only one of its kind. */
  --page-w: 1560px;
  --page-w-narrow: 1400px;
  --page-w-form: 1180px;
}

/* How old is this page's data?
 *
 * The landing tiles gained this stamp first, and stopping there was half a fix:
 * you were told "as of 7:20 AM" on the tile and then the page you opened said
 * nothing, or said it in one of six different wordings, and none of them ever
 * turned red. Three pages — baltimore, bidwl, gearbid — said nothing at all.
 *
 * A dead producer looks exactly like a healthy one from inside a dashboard: the
 * page loads, the numbers render, nothing moves. This estate has served stale
 * data for ten days, and for five, both found by accident. So the stamp belongs
 * where the numbers are READ, not only where they are chosen.
 *
 * Red is reserved for this. It is the only red fill in the shell, so when a bar
 * goes red it means one thing and it means it everywhere.
 */
.shell-asof {
  display: flex;
  align-items: center;
  gap: .45rem;
  padding: .3rem 1.2rem;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  font: 13px/1.4 "Segoe UI", system-ui, sans-serif;
  color: var(--ink-3);
}
.shell-asof .dot {
  width: .45rem; height: .45rem; border-radius: 50%;
  background: #7fb069; flex: none;
}
.shell-asof.stale {
  background: var(--down-bg);
  border-bottom-color: #f0c9c2;
  color: var(--down);
  font-weight: 600;
}
.shell-asof.stale .dot { background: var(--down); }

/* NO shared table rule here on purpose. Each page still writes its own, because
 * they genuinely differ — some columns sort and want cursor:pointer, purchasing
 * needs roomier cells for its wrapped action text. What they must NOT differ on
 * is the LOOK, and that is what the tokens above are for: every page's `th` now
 * reads font-size:var(--th-size), color:var(--ink-2), background:var(--surface),
 * border-bottom:1px solid var(--line). tests/test_page_styles.py pins that.
 *
 * A `.grid` class was written here first and removed before merging: no page
 * used it, and shipping a shared component nothing adopts just leaves the next
 * person guessing which of the two is authoritative.
 */

/* Shared header. Values match the per-page palettes already in use
   (--hero1 #0d3b66 / --hero2 #1b5e94) so the shell reads as part of each page
   rather than bolted on top of it. */
.shell-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: nowrap;   /* ONE row. Overflowing report links go into "More ▾" (shell.js fitNav). */
  padding: .5rem 1.2rem;
  background: #0d3b66;
  color: #fff;
  font: 14px/1.4 "Segoe UI", system-ui, sans-serif;
}
.shell-brand {
  color: #fff;
  font-weight: 700;
  text-decoration: none;
  letter-spacing: .2px;
  white-space: nowrap;
}
.shell-brand:hover { text-decoration: underline; }
.shell-nav {
  display: flex;
  align-items: center;
  gap: .15rem;
  flex-wrap: nowrap;
  flex: 1;
  min-width: 0;
  /* No overflow:hidden here: the More/Apps panels are positioned INSIDE this
     box and it would clip them. fitNav keeps the row from overflowing. */
}
.shell-nav-link {
  color: #cfe0ef;
  text-decoration: none;
  padding: .25rem .5rem;
  line-height: 1.4;
  border-radius: 6px;
  white-space: nowrap;
}
.shell-nav-link:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.shell-nav-link.on {
  background: rgba(255, 255, 255, .18);
  color: #fff;
  font-weight: 600;
}
/* Sibling-app menu. Anchored to the header, so it must escape the header's own
   stacking context — hence position:relative on the details and a high z-index
   on the panel; report pages have sticky toolbars that would otherwise sit on
   top of it. */
.shell-dd { position: relative; flex: none; }
/* fitNav hides with the `hidden` attribute; say so here too so no page rule
   that sets display on a link can bring an overflowed one back. */
.shell-nav-link[hidden], .shell-dd[hidden] { display: none; }
.shell-dd > summary { cursor: pointer; list-style: none; }
.shell-dd > summary::-webkit-details-marker { display: none; }
.shell-dd[open] > summary { background: rgba(255, 255, 255, .18); color: #fff; }
/* The More menu holds report links, not apps: plain rows, the active one marked.
   It sits at the end of the strip, so the panel hangs from its RIGHT edge or it
   would run off the viewport. */
.shell-more .shell-menu { min-width: 14rem; }
.shell-more .shell-menu a { font-weight: 500; color: #0d3b66; }
.shell-more .shell-menu a.on { background: #e8f0f8; font-weight: 700; }
.shell-menu {
  position: absolute;
  top: calc(100% + .35rem);
  right: 0;            /* both menus sit at the end of the strip; hang from the right edge */
  z-index: 50;
  min-width: 20rem;
  max-width: min(24rem, calc(100vw - 2rem));
  /* Ten apps with notes is taller than a 760px laptop viewport — measured, the
     last entry was clipped with no way to reach it. Scroll inside the panel
     rather than letting the estate's growth decide what is reachable. */
  max-height: calc(100vh - 4.5rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: .4rem;
  background: #fff;
  color: #1c2733;
  border: 1px solid #d6deea;
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(13, 59, 102, .22);
}
.shell-menu-head {
  margin: .1rem .5rem .35rem;
  font-size: .74rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #8a97a6;
}
.shell-menu a {
  display: block;
  padding: .4rem .5rem;
  border-radius: 7px;
  text-decoration: none;
  color: inherit;
}
.shell-menu a:hover { background: #eef3f9; }
.shell-menu a:focus-visible { outline: 2px solid #1b5e94; outline-offset: -2px; }
.shell-menu-label { display: block; font-weight: 600; color: #0d3b66; }
.shell-menu-note { display: block; font-size: .82rem; color: #5b6875; }

.shell-nav-link:focus-visible,
.shell-brand:focus-visible,
.shell-signout:focus-visible {
  outline: 2px solid #ffd27f;
  outline-offset: 2px;
}
.shell-right {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-left: auto;
  white-space: nowrap;
}
.shell-who { color: #cfe0ef; }
.shell-signout {
  cursor: pointer;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .3);
  border-radius: 6px;
  padding: .25rem .6rem;
  font: inherit;
}
.shell-signout:hover { background: rgba(255, 255, 255, .24); }

/* Sibling apps: a different sign-in and a different product, so the link is
   visibly a departure rather than another tab of this one. */
.shell-divider {
  width: 1px;
  height: 1.1rem;      /* fixed, not stretch: a stretched rule made the row tall */
  flex: none;
  margin: 0 .35rem;
  background: rgba(255, 255, 255, .25);
}
.shell-external { color: #e6d3b3; }
.shell-external:hover { color: #fff; }
