/* ============================================================
   ProQ — the shared design foundation (APQP Manager – Enterprise parity)

   The tokens, the shell (navbar, sub-bar, page gutter) and the handful of
   components every screen is built from, taken from Enterprise's
   `static/css/app.css` so the two applications read as one product. It loads
   BEFORE `custom.css`: this file is the foundation, custom.css holds the
   module screens, and a module rule of equal weight still wins where a
   screen genuinely needs something of its own.

   One deliberate difference from Enterprise, about behaviour rather than look:
   the navbar is NOT sticky here. Staging's worksheet ribbons (`.docbar`), the
   change matrix and the team Gantt pin their own headers to `top:0`; under a
   sticky 60px bar every one of them would slide beneath it.

   The Midnight theme is `proq-midnight.css`, loaded after this file and
   custom.css; every rule there is scoped under :root[data-theme="midnight"],
   so nothing here needs a dark variant written beside it.
   ============================================================ */

/* Inter is declared once, in inter.css — base.html and the stand-alone pages
   (sign-in, pricing) all link it. */

:root {
  --brand-900: #0a1020;
  --brand-800: #101c38;
  --brand-700: #16264c;
  --accent: #2563eb;
  --accent-600: #1d4ed8;
  --accent-soft: #eaf1fe;
  --sky: #0ea5e9;
  --indigo: #6366f1;
  --violet: #8b5cf6;
  --amber: #f59e0b;
  --emerald: #10b981;
  --teal: #14b8a6;
  --rose: #f43f5e;
  --ok: #10b981;
  --ok-soft: #e7f7ef;
  --warn: #d97706;
  --warn-soft: #fdf3e3;
  --danger: #e11d48;
  --danger-soft: #fdeaef;
  --ink: #0f172a;
  --ink-soft: #64748b;
  --line: #e6eaf1;
  --bg: #f4f6fb;
  --card: #ffffff;
  --surface-1: #ffffff;
  --surface-2: #f4f7fb;
  --muted: var(--ink-soft);
  --radius: 16px;
  --radius-sm: 12px;
  --shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.05);
  --shadow-sm: 0 4px 18px rgba(16, 24, 40, 0.07);
  --shadow: 0 12px 30px rgba(16, 24, 40, 0.13);
  --shadow-lg: 0 18px 46px rgba(8, 17, 45, 0.30);
}

html, body { height: 100%; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 0.9rem;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6, .fw-bold, .fw-semibold, .page-title, .kpi-value { letter-spacing: -0.02em; }
a { text-decoration: none; }
.proq-body { background: var(--bg); }

/* ============================================================
   The navbar — glass bar, brand, co-brand, quick icons, account chip
   ============================================================ */
.proq-nav {
  background: linear-gradient(120deg, #0e225a 0%, #16308f 38%, #1d4ed8 74%, #2f6bf6 100%) !important;
  box-shadow: 0 6px 22px rgba(8, 17, 45, .35), inset 0 1px 0 rgba(255, 255, 255, .14);
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  padding: .5rem 0; position: relative; z-index: 1030;
  /* The beam parks past the right edge for most of its cycle; a box
     positioned past the edge still widens the page. `clip` (not `hidden`)
     leaves the vertical axis alone, so the menus still drop out of the bar. */
  overflow-x: clip;
}
.proq-nav::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 52%;
  background: linear-gradient(180deg, rgba(255, 255, 255, .12), rgba(255, 255, 255, 0));
  pointer-events: none;
}
.proq-nav::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, rgba(56, 189, 248, 0), rgba(96, 165, 250, .65), rgba(56, 189, 248, 0));
  pointer-events: none;
}
.proq-nav .container-fluid { position: relative; z-index: 1; padding-left: 22px; padding-right: 22px; }

/* ---- The bar never pushes its own controls off the edge ----------------
   Across the top the bar is one nowrap flex line, and when the content no
   longer fits, what runs past the right edge is simply CLIPPED — the page
   does not scroll sideways. The account chip is the LAST thing in the line,
   so it is the first to go: between 992 and about 1100px the bell and the
   whole chip were off-screen, with nothing on the bar to say so. Clicking
   where they ought to be hit the pencil or empty space, which is what "I
   click on my name and nothing happens" looks like.

   The threshold is not fixed, either — it moves with the length of the
   person's name and the company's, so the same window is fine for one
   account and broken for the next.

   So the right-hand group is pinned (`flex: 0 0 auto`) and the module list
   is what yields: it may shrink below its content and scrolls if it has to.
   Losing the end of a menu label is a small loss that is visible; losing the
   way to sign out is a large one that is not. */
.proq-nav .nav-foot { flex: 0 0 auto; }
@media (min-width: 992px) {
  .proq-nav #navMain { min-width: 0; }
  .proq-nav #navMain > .navbar-nav:first-child { min-width: 0; flex: 1 1 auto; }
  .proq-nav #navMain > .navbar-nav:first-child > .nav-item { min-width: 0; }
  /* The clipping goes on the TOGGLE, never on the list that holds the menus.
     A mega-menu is a sibling of its toggle inside the `.nav-item`, so an
     `overflow` on the toggle shortens the label and leaves the menu alone —
     while an `overflow` on the `<ul>` makes a clipping context that swallows
     all three menus whole. (Tried; they opened and could not be clicked.) */
  .proq-nav #navMain > .navbar-nav:first-child > .nav-item > .qt-sec-head {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
}
/* A name identifies; it is not a headline. Without a ceiling a long one
   ("Guadalupe Alejandra Prado Domínguez") takes 330px of the bar and every
   menu label pays for it. The chip is `d-flex`, and a flex item is
   blockified, so `max-width` and `overflow` apply here even though Bootstrap
   marks the span `d-inline !important`. */
.proq-nav .user-chip-name {
  min-width: 0; max-width: 13rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The chevron is its own control now, beside the name rather than inside it.
   It sits tight against the chip so the two still read as one thing, and it
   keeps a real hit area — a caret you have to aim at is a caret nobody uses. */
.proq-nav .foot-person { display: flex; align-items: center; }
.proq-nav .user-chip { padding-right: .35rem; }
.proq-nav .user-chip-more { padding-left: .2rem; padding-right: .5rem; }
.proq-nav .user-chip-more::after { display: none; }

/* ---- The account page ----
   The same `<li>`s the dropdown renders, laid out as a page. One source, two
   presentations — a second copy of "what is in my account" would be wrong
   within a month. */
.acct-page { list-style: none; margin: 0; padding: 0;
  display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.acct-page > li { margin: 0; }
.acct-page .dropdown-item {
  display: flex; align-items: center; gap: .1rem; width: 100%;
  background: var(--surface-1, #fff); border: 1px solid var(--line, #e2e8f0);
  border-radius: var(--radius, 12px); padding: .8rem .9rem;
  font-weight: 600; color: var(--ink, #0f172a); white-space: normal;
}
.acct-page .dropdown-item:hover { border-color: var(--accent, #1e3a8a); background: var(--bg, #f8fafc); }
.acct-page .dropdown-item i { color: var(--accent, #1e3a8a); }
/* The menu's own furniture is not a card: its dividers and its "who you are"
   header are already the page header, and the preference blocks (navigation,
   theme, language, time zone) are panels that span the grid. */
/* A divider `<li>` holds nothing but an `<hr>`. Hiding the rule alone leaves
   the `<li>` standing as an empty cell in the grid, which is what put a gap
   in front of the first card; `:has()` takes the whole row out. Where it is
   not supported the gap comes back and nothing else changes. */
.acct-page > li:has(> hr.dropdown-divider) { display: none; }
.acct-page > li > hr.dropdown-divider { display: none; }
.acct-page > li:first-child { display: none; }
.acct-page > li.px-3 {
  grid-column: 1 / -1;
  background: var(--surface-1, #fff); border: 1px solid var(--line, #e2e8f0);
  border-radius: var(--radius, 12px); padding: .9rem 1rem !important;
}
.acct-page form.logout-form { grid-column: 1 / -1; }

/* A light beam that sweeps the bar once every 10 s. */
.proq-nav-beam {
  position: absolute; top: 0; bottom: 0; left: 0; width: 150px; z-index: 2;
  pointer-events: none; mix-blend-mode: screen; filter: blur(2px); opacity: 0;
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%, rgba(255,255,255,.16) 42%,
    rgba(173,216,255,.42) 50%, rgba(255,255,255,.16) 58%, rgba(255,255,255,0) 100%);
  transform: translateX(-180px);
  animation: proqNavBeam 10s ease-in-out infinite;
  will-change: transform, opacity;
}
@keyframes proqNavBeam {
  0%   { transform: translateX(-180px); opacity: 0; }
  3%   { opacity: 1; }
  22%  { transform: translateX(calc(100vw + 40px)); opacity: 1; }
  26%  { opacity: 0; }
  100% { transform: translateX(calc(100vw + 40px)); opacity: 0; }
}

/* ---- Brand ---- */
.proq-nav .navbar-brand { font-weight: 800; color: #fff; padding-top: 0; padding-bottom: 0; }
.brand-badge {
  width: 38px; height: 38px; border-radius: 11px; flex: 0 0 auto;
  background: linear-gradient(135deg, #38bdf8 0%, #2563eb 55%, #14b8a6 100%);
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 800; font-size: 0.9rem; letter-spacing: .5px;
  box-shadow: 0 6px 16px rgba(37, 99, 235, .5), inset 0 1px 0 rgba(255, 255, 255, .4);
}
.brand-word {
  display: inline-flex; flex-direction: column; line-height: 1;
  font-size: 1.22rem; font-weight: 800; letter-spacing: .3px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .3);
}
.brand-tag { font-size: .5rem; font-weight: 700; letter-spacing: .22em; color: rgba(255, 255, 255, .62); margin-top: 3px; }

/* ---- Company co-branding: the tenant's logo beside the retained ProQ mark.
   The bar is navy, so the logo sits in a white chip — legible for any artwork. */
.co-brand { display: inline-flex; align-items: center; gap: .55rem; margin-right: .75rem; }
.co-brand-divider { width: 1px; height: 34px; background: rgba(255,255,255,.28); border-radius: 1px; }
.co-brand-logo {
  height: 42px; max-width: 200px; width: auto; object-fit: contain; display: block;
  background: #fff; border-radius: 7px; padding: 3px 8px;
  box-shadow: 0 1px 2px rgba(2,6,23,.22); border: 1px solid rgba(255,255,255,.55);
}
@media (max-width: 991.98px) { .co-brand-logo { height: 36px; max-width: 150px; } }
@media (max-width: 575.98px) { .co-brand-logo { height: 30px; max-width: 112px; } }

/* ---- Text nav links: pill hover with glow ---- */
.proq-nav .navbar-nav > .nav-item > .nav-link {
  color: rgba(255, 255, 255, .84) !important; font-weight: 600; font-size: .86rem;
  letter-spacing: .1px; padding: .46rem .8rem; margin: 0 .06rem; border-radius: 10px;
  transition: background .18s ease, color .18s ease, box-shadow .18s ease, transform .12s ease;
}
.proq-nav .navbar-nav > .nav-item > .nav-link:hover,
.proq-nav .navbar-nav > .nav-item.show > .nav-link,
.proq-nav .navbar-nav > .nav-item > .nav-link.active {
  color: #fff !important; background: rgba(255, 255, 255, .14);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 3px 10px rgba(0, 0, 0, .16);
}
.proq-nav .nav-link i { filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .22)); }
.proq-nav .dropdown-toggle::after { opacity: .65; margin-left: .4rem; }
.proq-nav .navbar-toggler { border: 1px solid rgba(255, 255, 255, .25); border-radius: 9px; }
/* a count on a menu toggle */
.proq-nav .nav-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 17px; height: 17px; padding: 0 4px; margin-left: .3rem; border-radius: 9px;
  background: var(--danger); color: #fff; font-size: .62rem; font-weight: 700;
  box-shadow: 0 2px 8px rgba(239, 68, 68, .45);
}

/* ---- Quick-access icons: 3D glass buttons ---- */
.nav-quick { margin-left: .35rem; }
.nav-quick-icon {
  width: 40px; height: 40px; border-radius: 11px; padding: 0 !important; position: relative;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.05rem;
  color: rgba(255, 255, 255, .92) !important;
  background: linear-gradient(160deg, rgba(255, 255, 255, .18), rgba(255, 255, 255, .045));
  border: 1px solid rgba(255, 255, 255, .12);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), inset 0 -1px 0 rgba(0, 0, 0, .12), 0 2px 6px rgba(0, 0, 0, .2);
  transition: transform .14s ease, box-shadow .18s ease, background .18s ease;
}
.nav-quick-icon:hover {
  color: #fff !important; transform: translateY(-2px);
  background: linear-gradient(160deg, rgba(255, 255, 255, .3), rgba(255, 255, 255, .12));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 7px 16px rgba(0, 0, 0, .3);
}
.nav-quick-icon:active { transform: translateY(0); }
.nav-quick-icon.active {
  color: #fff !important;
  background: linear-gradient(160deg, rgba(56, 189, 248, .55), rgba(37, 99, 235, .35));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 5px 16px rgba(37, 99, 235, .55);
}
.nav-quick-icon i { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .25)); }

/* ---- User chip + avatar ---- */
.user-chip {
  border-radius: 12px; padding: .28rem .5rem !important; color: #fff !important;
  background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .14);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
}
.user-chip:hover { background: rgba(255, 255, 255, .2); }
.user-chip-name { font-weight: 600; font-size: .82rem; white-space: nowrap; }
.avatar-badge {
  width: 32px; height: 32px; border-radius: 50%; flex: 0 0 auto;
  background: linear-gradient(135deg, #38bdf8, #6366f1); color: #fff;
  font-weight: 700; font-size: 0.74rem; display: inline-flex; align-items: center;
  justify-content: center; box-shadow: 0 4px 12px rgba(37, 99, 235, .45), inset 0 1px 0 rgba(255, 255, 255, .35);
}

/* ---- Notification bell + badge ---- */
.notif-bell { border-radius: 10px; padding: .4rem .55rem !important; transition: background .18s ease; }
.notif-bell:hover { background: rgba(255, 255, 255, .14); }
.notif-badge {
  position: absolute; top: 1px; right: 1px; min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 9px; background: var(--danger); color: #fff; font-size: .62rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 8px rgba(239, 68, 68, .55), 0 0 0 1.5px rgba(255, 255, 255, .9);
}
.notif-badge.is-warn { background: var(--warn); box-shadow: 0 2px 8px rgba(217, 119, 6, .5), 0 0 0 1.5px rgba(255, 255, 255, .9); }

/* ---- Premium dropdown menus ----
   `.pq-foot-menu` is a sidebar foot menu lifted to <body> while it is open
   (proq.js) — the same menu, so the same look. */
.proq-nav .dropdown-menu, .dropdown-menu.pq-foot-menu {
  border: 1px solid rgba(15, 23, 42, .06); border-radius: 14px; padding: .4rem;
  margin-top: .55rem !important;
  box-shadow: 0 16px 40px rgba(8, 17, 45, .22), 0 2px 8px rgba(8, 17, 45, .1);
  animation: navDrop .16s ease;
  /* A menu is never taller than the window it opens in.

     Bootstrap turns Popper OFF inside a `.navbar` and leaves placement to
     CSS. The sidebar's own rule says that is fine across the top, "where
     under the toggle is always on screen" — and that was true when it was
     written. It stopped being true as the menus grew: the account menu
     reached 924px and the Operations mega-menu 800px, so on an ordinary
     laptop (about 700px of page below a 60px bar) the bottom of each ran
     off the foot of the window with nothing to scroll. `Sign out`, the
     language and the time zone were not merely hard to reach —
     `elementFromPoint` returned nothing there, so the clicks landed on
     the page behind and the menu simply closed.

     `.notif-menu` and the sidebar's foot menus were each given this
     treatment separately, for the same reason; this is the rule they were
     both local answers to. `overscroll-behavior` keeps the wheel inside
     the menu, so scrolling to `Sign out` does not scroll the page under
     it as well. */
  max-height: calc(100vh - 5.5rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}
@keyframes navDrop { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.proq-nav .dropdown-menu .dropdown-item, .pq-foot-menu .dropdown-item {
  border-radius: 9px; font-weight: 500; font-size: .85rem; padding: .5rem .7rem;
  transition: background .14s ease, color .14s ease;
}
.proq-nav .dropdown-menu .dropdown-item:hover,
.pq-foot-menu .dropdown-item:hover { background: linear-gradient(135deg, #eff4ff, #e6edff); color: #1d4ed8; }
.proq-nav .dropdown-menu .dropdown-item i, .pq-foot-menu .dropdown-item i { color: #2563eb; }
/* Lifted, the menu is placed by the script beside the column, on the bottom
   of the window, above anything the page draws. */
.dropdown-menu.pq-foot-menu { position: fixed; z-index: 1085; margin: 0 !important;
  max-height: calc(100vh - 24px); }
.pq-foot-menu.notif-menu { max-height: min(460px, calc(100vh - 24px)); }
.account-menu { min-width: 272px; }

/* The bell keeps its own, tighter cap — a list of alerts is read a few at a
   time and a menu the height of the window is not a better list. `min()`
   because the window still wins on a short screen. */
.proq-nav .notif-menu { max-height: min(460px, calc(100vh - 5.5rem)); }

/* "Tell the assistant what to do" — the box behind the sparkle in the bar (apps/ai) */
/* the box is a piece of the AI studio (proq-ai-studio.css): navy with the
   field's dot grid, the orb's hue on its edge, light words in both themes —
   the textarea stays paper, because that is where somebody types.
   It is a child of <body>, placed by ai-quick.js (fixed, beside the sidebar
   column or under the sparkle): a fixed box INSIDE the column was clipped by
   it in Safari, and nothing in the bar may reach it from here on. */
.proq-nav .ai-quick-toggle { color: #c4b5fd; text-shadow: 0 0 10px rgba(167, 139, 250, .6); }
.proq-nav .ai-quick-toggle:hover, .proq-nav .ai-quick-toggle.show { color: #fff; }
.ai-quick-menu { position: fixed; z-index: 1045; width: min(400px, calc(100vw - 24px)); padding: .8rem .9rem; display: none; gap: .5rem;
  margin: 0; font-size: .875rem; color: #e9edff; border: 1px solid rgba(148, 163, 255, .32); border-radius: 14px;
  background:
    radial-gradient(60% 80% at 100% 0%, rgba(124, 58, 237, .42), transparent 60%),
    radial-gradient(rgba(148, 163, 255, .16) 1px, transparent 1.3px) 0 0 / 22px 22px,
    linear-gradient(160deg, #0b1536, #121a48 55%, #0a1230);
  box-shadow: 0 0 0 1px rgba(139, 92, 246, .35), 0 24px 56px rgba(2, 6, 23, .55); }
.ai-quick-menu.show { display: grid; animation: navDrop .16s ease; }
.ai-quick-menu[hidden] { display: none; }
.ai-quick-h { font-size: .8rem; font-weight: 700; color: #fff; }
.ai-quick-h i { color: #c4b5fd; }
.ai-quick-foot { display: flex; align-items: center; gap: .6rem; }
.ai-quick-menu .ai-chat-attach { display: inline-flex; align-items: center; gap: .3rem; font-size: .76rem;
  color: #7dd3fc; cursor: pointer; margin: 0; }
.ai-quick-menu a { color: #c4b5fd; }
.ai-quick-menu .btn-primary { background: linear-gradient(135deg, #8b5cf6, #2563eb); border-color: transparent; }
.ai-quick-note { font-size: .7rem; color: #b9c4ec; }
@media (prefers-reduced-motion: reduce) { .ai-quick-menu.show { animation: none; } }

/* ---- Notification menu rows ---- */
.notif-menu .notif-item { border-radius: 9px; }
.notif-title { font-weight: 600; font-size: .82rem; display: flex; align-items: center; gap: 6px; color: var(--ink); }
.notif-msg { font-size: .74rem; color: var(--ink-soft); margin-top: 2px; }
.notif-menu .dropdown-item:hover .notif-msg { color: #475569; }

/* ---- The ⌘K hint on the bar ---- */
.cmdk-hint { display: inline-flex; align-items: center; gap: .3rem; margin-right: .5rem;
  padding: .28rem .6rem; border-radius: 8px; cursor: pointer; font-size: .72rem; font-weight: 600;
  color: rgba(255,255,255,.75); border: 1px solid rgba(255,255,255,.22); background: rgba(255,255,255,.08); }
.cmdk-hint:hover { background: rgba(255,255,255,.16); color: #fff; }
.cmdk-hint kbd { font-size: .64rem; background: rgba(255,255,255,.14); color: inherit;
  border-radius: 5px; padding: .05rem .35rem; box-shadow: none; }

/* ============================================================
   The sub-bar (page context + page actions) and the page gutter
   ============================================================ */
.subbar { background: rgba(255, 255, 255, .9);
  -webkit-backdrop-filter: saturate(1.4) blur(10px); backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line); }
.subbar-inner {
  max-width: var(--app-max, none); margin: 0 auto; padding: 9px 24px; min-height: 46px;
  display: flex; align-items: center; gap: 14px;
}
.subbar .page-context { font-weight: 700; color: var(--ink); font-size: .95rem; }
/* A page that says nothing in the strip gets no strip. No whitespace inside
   the blocks in base.html — `:empty` depends on it. */
.subbar:not(:has(.page-context:not(:empty))):not(:has(.subbar-actions > *)) { display: none; }
.btn-icon {
  border: 1px solid var(--line); background: #fff; border-radius: 11px;
  width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-soft); position: relative; transition: all .15s ease;
}
.btn-icon:hover { border-color: var(--accent); color: var(--accent); box-shadow: var(--shadow-xs); }

/* The gutter is two variables so a full-bleed screen (the app map, the FMEA
   tree) can cancel exactly the padding it sits in instead of a number that
   was true once: `margin: calc(-1 * var(--page-pad-y)) calc(-1 * var(--page-pad-x))`. */
.content { --page-pad-y: 24px; --page-pad-x: 24px;
  padding: var(--page-pad-y) var(--page-pad-x); max-width: var(--app-max, none); width: 100%; margin: 0 auto; }
.content-plain { padding: 0; max-width: none; }
@media (min-width: 1900px) { .content { --page-pad-y: 26px; --page-pad-x: 40px; } .subbar-inner { padding: 9px 40px; } }
@media (max-width: 575.98px) { .content { --page-pad-y: 16px; --page-pad-x: 16px; } }

/* ============================================================
   Components
   ============================================================ */
.card { border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm);
  background: var(--card); }
.card-header { background: transparent; border-bottom: 1px solid var(--line); font-weight: 600;
  padding: 13px 18px; }
.table { --bs-table-hover-bg: #f6f9ff; margin-bottom: 0; }
.table thead th {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-soft); border-bottom: 1px solid var(--line);
  background: #fafbff; font-weight: 700; padding: 11px 12px;
}
.table td { vertical-align: middle; }
.table-responsive { border-radius: var(--radius); }

.badge-soft { border-radius: 999px; font-weight: 600; padding: 0.36em 0.75em; font-size: 0.72rem;
  display: inline-flex; align-items: center; gap: 4px; line-height: 1; }
.badge-soft.ok { background: var(--ok-soft); color: #047857; }
.badge-soft.warn { background: var(--warn-soft); color: #b45309; }
.badge-soft.danger { background: var(--danger-soft); color: var(--danger); }
.badge-soft.info { background: var(--accent-soft); color: var(--accent-600); }
.badge-soft.muted { background: #eef1f6; color: var(--ink-soft); }
.badge-soft.purple { background: #f1e9fe; color: #7c3aed; }

/* ---- Phase stepper ---- */
.phase-stepper { display: flex; gap: 8px; flex-wrap: wrap; }
.phase-step {
  flex: 1; min-width: 128px; border-radius: 14px; padding: 12px 14px;
  border: 1px solid var(--line); background: #fff; position: relative;
  box-shadow: var(--shadow-xs); transition: transform .14s ease, box-shadow .16s ease;
}
.phase-step:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.phase-step .ph-num {
  width: 28px; height: 28px; border-radius: 50%; font-size: 0.8rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  background: #eef1f6; color: var(--ink-soft);
}
.phase-step.done { border-color: rgba(16, 185, 129, .35); background: linear-gradient(180deg,#f4fdf8,#fff); }
.phase-step.done .ph-num { background: linear-gradient(135deg,#34d399,#059669); color: #fff;
  box-shadow: 0 4px 10px rgba(16,185,129,.34); }
.phase-step.active { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.phase-step.active .ph-num { background: linear-gradient(135deg,#38bdf8,#2563eb); color: #fff;
  box-shadow: 0 4px 10px rgba(37,99,235,.34); }
.phase-step .ph-name { font-weight: 600; font-size: 0.8rem; margin-top: 6px; }
.phase-step .ph-meta { font-size: 0.72rem; color: var(--ink-soft); }
.phase-step.na {
  border-style: dashed; opacity: .78;
  background: repeating-linear-gradient(45deg,#f8fafc,#f8fafc 6px,#f1f5f9 6px,#f1f5f9 12px);
}
.phase-step.na:hover { transform: none; box-shadow: var(--shadow-xs); }
.phase-step.na .ph-num { background: #e2e8f0; color: var(--ink-soft); box-shadow: none; }

/* ---- KPI tiles ---- */
.kpi-tile {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 17px 19px; height: 100%; box-shadow: var(--shadow-sm);
  transition: box-shadow .18s ease, transform .18s ease; position: relative; overflow: hidden;
}
.kpi-tile:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.kpi-tile .kpi-ic {
  width: 44px; height: 44px; border-radius: 13px; display: inline-grid; place-items: center;
  color: #fff; font-size: 1.25rem; margin-bottom: 12px;
  box-shadow: 0 6px 16px rgba(16,24,40,.16), inset 0 1px 0 rgba(255,255,255,.3);
}
.kpi-ic.g-blue { background: linear-gradient(135deg,#38bdf8,#2563eb); }
.kpi-ic.g-indigo { background: linear-gradient(135deg,#818cf8,#4f46e5); }
.kpi-ic.g-emerald { background: linear-gradient(135deg,#34d399,#059669); }
.kpi-ic.g-amber { background: linear-gradient(135deg,#fbbf24,#d97706); }
.kpi-ic.g-rose { background: linear-gradient(135deg,#fb7185,#e11d48); }
.kpi-ic.g-violet { background: linear-gradient(135deg,#a78bfa,#7c3aed); }
.kpi-ic.g-teal { background: linear-gradient(135deg,#2dd4bf,#0d9488); }
.kpi-tile .kpi-label { font-size: 0.7rem; color: var(--ink-soft); text-transform: uppercase;
  letter-spacing: .06em; font-weight: 700; }
.kpi-tile .kpi-value { font-size: 1.75rem; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi-tile .kpi-sub { font-size: 0.74rem; color: var(--ink-soft); }
.kpi-tile.kpi-ok::after, .kpi-tile.kpi-warn::after, .kpi-tile.kpi-danger::after,
.kpi-tile.kpi-info::after { content:""; position:absolute; left:0; top:0; bottom:0; width:4px; }
.kpi-tile.kpi-ok::after { background: var(--ok); }
.kpi-tile.kpi-warn::after { background: var(--warn); }
.kpi-tile.kpi-danger::after { background: var(--danger); }
.kpi-tile.kpi-info::after { background: var(--accent); }

/* ---- Progress, forms, buttons ---- */
.progress { height: 8px; border-radius: 6px; background: #eef1f6; }
.progress-bar { background: linear-gradient(90deg, #2563eb, #38bdf8); border-radius: 6px; }
.form-label { font-weight: 600; font-size: 0.82rem; }
.form-control, .form-select { border-color: var(--line); border-radius: 10px; }
.form-control:focus, .form-select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.form-control-sm, .form-select-sm { border-radius: 8px; }
.btn { border-radius: 11px; font-weight: 600; }
.btn-primary { background: linear-gradient(180deg,#2f6bf6,#2054d6); border-color: #2054d6;
  box-shadow: 0 6px 16px rgba(37,99,235,.28); }
.btn-primary:hover { background: linear-gradient(180deg,#2a61e6,#1b49c0); border-color: #1b49c0; }
.btn-sm { border-radius: 9px; }

/* ---- The ISO week beside every date field (static/js/proq.js) ----
   In a table cell the date and its week share one line (.wk-field), and the
   field keeps room for a whole date so the badge never clips it. */
.wk-badge { display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 6px;
  font-size: .62rem; font-weight: 700; letter-spacing: .03em; white-space: nowrap;
  vertical-align: middle; color: var(--accent-600); background: var(--accent-soft); }
.wk-field { display: flex; align-items: center; gap: 6px; min-width: 0; }
.wk-field > input { flex: 0 1 auto; min-width: calc(10ch + 1.65rem); }
.wk-field > .wk-badge { flex: none; margin-left: 0; }
/* the opt-in "clear this date" button (data-clearable, static/js/proq.js) */
.wk-clear { border: none; background: transparent; color: var(--ink-soft); cursor: pointer;
  font-size: 1rem; line-height: 1; padding: 0 5px; margin-left: 2px; border-radius: 6px;
  vertical-align: middle; transition: color .15s, background .15s; }
.wk-clear:hover { color: var(--danger); background: var(--danger-soft); }
.wk-field > .wk-clear { flex: none; margin-left: 0; }
.flatpickr-day.selected, .flatpickr-day.selected:hover,
.flatpickr-day.startRange, .flatpickr-day.endRange { background: var(--accent); border-color: var(--accent); }

/* ---- Sign-in (templates/account/login.html) — Enterprise's card ---- */
.auth-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(1100px 520px at 85% -10%, rgba(37, 99, 235, 0.16), transparent),
    radial-gradient(800px 420px at -10% 110%, rgba(20, 184, 166, 0.13), transparent),
    linear-gradient(180deg, #eef2fb, var(--bg));
  padding: 24px;
}
.auth-card { width: 100%; max-width: 440px; }
.auth-card .card { box-shadow: var(--shadow); border-radius: 20px; }
.auth-badge {
  width: 58px; height: 58px; border-radius: 17px; display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #38bdf8 0%, #2563eb 55%, #14b8a6 100%);
  color: #fff; font-weight: 800; font-size: 1.3rem; letter-spacing: .5px;
  box-shadow: 0 12px 28px rgba(37, 99, 235, .45), inset 0 1px 0 rgba(255, 255, 255, .45);
}

/* ============================================================
   Page headers — one rule for the whole application
   * a portfolio or management screen opens on the navy `.hero-band`
     (components/hero.html);
   * a module register or an admin screen opens on `.page-head`: the title on
     the left, its actions on the same row on the right, a KPI strip under it;
   * a document (worksheet, flow, plan) opens on the white `.doc-hero` with
     the Draft → In review → Released stepper and its KPI chips.
   Enterprise calls the document header `.fmea-hero`; here that name already
   belongs to the navy FMEA hero, so it is `.doc-hero` — same look.
   ============================================================ */
.page-head { display: flex; align-items: flex-end; flex-wrap: wrap; gap: .75rem 1rem; margin-bottom: 1.25rem; }
.page-head-text { min-width: 0; }
.page-eyebrow { font-size: .64rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-600); margin-bottom: .2rem; }
.page-title { font-weight: 800; font-size: 1.35rem; margin: 0; color: var(--ink); }
.page-sub { color: var(--ink-soft); font-size: .8rem; margin: .2rem 0 0; max-width: 78ch; }
.page-actions { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.text-muted-2 { color: var(--ink-soft) !important; }
.empty-state { text-align: center; padding: 48px 20px; color: var(--ink-soft); }
.empty-state > i { font-size: 2.4rem; color: #b9c3d4; }
.empty-state h2 { font-size: 1.05rem; font-weight: 700; color: var(--ink); margin: .75rem 0 .25rem; }
.empty-state p { margin: 0 auto; max-width: 56ch; }

/* ---- the KPI strip under a register's title ---- */
.kpi-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; margin-bottom: 20px; }
.kpi-tile .kpi-value small { font-size: .8rem; font-weight: 600; color: var(--ink-soft); margin-left: 2px; }
a.kpi-tile { display: block; color: inherit; }
a.kpi-tile:hover { color: inherit; }

/* ---- the document header ---- */
/* `overflow` stays visible: the Export and More menus drop out of this header,
   and a clipped header cuts them off. The rail rounds its own corners instead. */
.doc-hero { position: relative; background: var(--card);
  border: 1px solid var(--line); border-radius: 18px; box-shadow: var(--shadow-sm);
  padding: 16px 22px 18px; margin-bottom: 1rem; }
.doc-hero::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
  border-radius: 18px 0 0 18px; background: linear-gradient(180deg, var(--accent), var(--accent-600)); }
.doc-hero.is-draft::before { background: linear-gradient(180deg, #94a3b8, #64748b); }
.doc-hero.is-review::before { background: linear-gradient(180deg, var(--warn), #c2820a); }
.doc-hero.is-released::before { background: linear-gradient(180deg, var(--ok), #0f9d6e); }
.doc-hero.is-rejected::before { background: linear-gradient(180deg, var(--danger), #b91c1c); }
.doc-hero-top { display: flex; align-items: flex-start; gap: 14px; }
.doc-hero-back { flex: none; }
.doc-hero-id { min-width: 0; }
.doc-hero-title { font-size: 1.42rem; font-weight: 800; letter-spacing: -.01em; margin: 0; }
.doc-hero-sub { color: var(--ink-soft); font-size: .82rem; margin-top: 3px; }
.doc-hero-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.doc-stepper { display: inline-flex; align-items: center; font-size: .68rem; font-weight: 600; }
.ds-step { padding: 4px 11px; color: var(--ink-soft); background: var(--bg); border: 1px solid var(--line);
  border-right-width: 0; white-space: nowrap; }
.ds-step:first-child { border-radius: 8px 0 0 8px; }
.ds-step:last-child { border-radius: 0 8px 8px 0; border-right-width: 1px; }
.ds-step.done { color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent); }
.ds-step.on { color: #fff; background: var(--accent); border-color: var(--accent); font-weight: 700; }
.doc-hero-kpis { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 15px; }
.doc-kpi { display: flex; align-items: center; gap: 11px; background: var(--bg); border: 1px solid var(--line);
  border-radius: 13px; padding: 9px 15px 9px 11px; min-width: 148px; color: inherit;
  transition: box-shadow .15s ease, transform .15s ease; }
a.doc-kpi:hover { box-shadow: var(--shadow-sm); transform: translateY(-1px); color: inherit; }
.dk-ic { width: 36px; height: 36px; border-radius: 10px; display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 1.05rem; flex: none; box-shadow: var(--shadow-xs); background: #64748b; }
.dk-ic.g-blue { background: linear-gradient(135deg, #38bdf8, #2563eb); }
.dk-ic.g-indigo { background: linear-gradient(135deg, #818cf8, #4f46e5); }
.dk-ic.g-rose { background: linear-gradient(135deg, #fb7185, #e11d48); }
.dk-ic.g-amber { background: linear-gradient(135deg, #fbbf24, #d97706); }
.dk-ic.g-emerald { background: linear-gradient(135deg, #34d399, #059669); }
.dk-ic.g-violet { background: linear-gradient(135deg, #a78bfa, #7c3aed); }
.dk-ic.g-teal { background: linear-gradient(135deg, #2dd4bf, #0d9488); }
.dk-val { font-size: 1.3rem; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.dk-lbl { font-size: .64rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .4px; margin-top: 3px; font-weight: 600; }
/* On a phone the identity keeps its line and the actions take the next one;
   sized by their content they would squeeze the title to two words wide. */
@media (max-width: 991.98px) {
  .doc-hero { padding: 14px 16px 16px; }
  .doc-hero-top { flex-wrap: wrap; gap: 10px; }
  .doc-hero-id { flex: 1 1 0; }
  .doc-hero-actions { flex: 1 1 100%; margin-left: 0; justify-content: flex-start; row-gap: 8px; }
  .doc-hero-title { font-size: 1.14rem; line-height: 1.25; }
  .doc-kpi { flex: 1 1 calc(50% - 5px); min-width: 0; }
}
@media (max-width: 575.98px) { .page-actions { margin-left: 0; } }

/* ============================================================
   The portfolio hero — Projects, Timeline, the Charter cockpit
   Enterprise's `.ch-hero` (the navy card) and its "isometric quality world"
   (`.pl-*`: a five-slab phase ziggurat and four dark-glass status tiles).
   Enterprise calls the wrapper `.pl-hero`; the FMEA planning page here already
   owns that name, so it is `.pf-hero`. Perspective sits on `.pl-stage` and
   `preserve-3d` on the solids — never put overflow or filter on
   `.pl-world`/`.pl-slab`, it flattens them.
   ============================================================ */
.ch-hero { position:relative; overflow:hidden; border-radius:20px; color:#eef3ff; padding:20px 24px; margin-bottom:14px;
  background:
    radial-gradient(120% 130% at 100% 0%, rgba(56,189,248,.20), transparent 55%),
    radial-gradient(120% 130% at 0% 100%, rgba(139,92,246,.18), transparent 55%),
    linear-gradient(120deg,#0a1020 0%,#122a52 55%,#1a3a78 100%);
  border:1px solid rgba(139,92,246,.22); box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255,255,255,.07); }
.ch-hero-top { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; flex-wrap:wrap;
  position:relative; z-index:1; }
.ch-hero h1 { font-size:1.5rem; font-weight:800; letter-spacing:-.015em; margin:0; color:#fff; }
.ch-hero .ch-sub { color:#9fb0da; font-size:.78rem; margin-top:3px; max-width:62ch; }
.ch-hero .ch-sub a { color:#c7d6f7; text-decoration:underline; text-underline-offset:2px; }
.ch-hero .ch-tag { font-size:.6rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  background:rgba(255,255,255,.12); color:#dfe7fb; padding:3px 8px; border-radius:6px; }
.ch-hero .ch-tag.ok{ background:rgba(52,211,153,.2); color:#6ee7b7; } .ch-hero .ch-tag.warn{ background:rgba(251,191,36,.2); color:#fcd34d; }
.btn-ghost { background:rgba(255,255,255,.09); border:1px solid rgba(255,255,255,.16); color:#dfe7fb; }
.btn-ghost:hover { background:rgba(255,255,255,.18); color:#fff; border-color:rgba(255,255,255,.28); }
.btn-ghost:focus-visible { outline: 2px solid #93c5fd; outline-offset: 2px; }
.ch-hero-divider { height:1px; margin:16px 0 14px; position:relative; z-index:1;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.14) 15%,rgba(255,255,255,.14) 85%,transparent); }
.ch-metrics { display:flex; flex-wrap:wrap; gap:14px 0; position:relative; z-index:1; }
.ch-metric { flex:1 1 150px; min-width:130px; padding:0 20px; border-left:1px solid rgba(255,255,255,.1); }
.ch-metric:first-child { border-left:none; padding-left:0; }
.cm-label { font-size:.58rem; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:#8fa0c8; }
.cm-value { font-size:1.4rem; font-weight:800; line-height:1.1; color:#fff; margin-top:3px; letter-spacing:-.01em; }
.cm-sub { font-size:.68rem; color:#9fb0da; margin-top:2px; }
.cm-ok{ color:#6ee7b7!important; } .cm-warn{ color:#fcd34d!important; } .cm-danger{ color:#fda4af!important; }
.min-w-0 { min-width: 0; }
/* the project's own hero: a part-number chip, a thin progress bar, a status dot */
.prj-hero .prj-pn { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 700; color: #dbe7ff;
  background: rgba(255,255,255,.1); padding: 1px 7px; border-radius: 6px; }
.prj-bar { height: 5px; margin-top: 6px; max-width: 160px; border-radius: 99px; background: rgba(255,255,255,.14); overflow: hidden; }
.prj-bar > span { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg,#38bdf8,#818cf8); }
.prj-dot { font-size: .5rem; vertical-align: middle; }
.prj-dot-active { color: #60a5fa; } .prj-dot-completed { color: #34d399; } .prj-dot-closed { color: #94a3b8; }
.prj-dot-on_hold { color: #fbbf24; } .prj-dot-cancelled { color: #fb7185; }

.pf-hero { position: relative; padding-bottom: 18px; }
.pf-hero .ch-hero-top { min-height: 172px; }
.pl-stage { position: absolute; inset: 0 0 0 auto; width: min(46%, 500px); z-index: 0;
  pointer-events: none; perspective: 1400px; perspective-origin: 58% 36%;
  overflow: hidden; border-radius: 20px; }
.pl-orb { position: absolute; border-radius: 50%; filter: blur(42px); pointer-events: none; }
.pl-orb.a { width: 240px; height: 240px; top: -60px; right: -30px; opacity: .5;
  background: radial-gradient(circle at 42% 40%, rgba(56,189,248,.65), transparent 70%); }
.pl-orb.b { width: 210px; height: 210px; bottom: -66px; right: 34%; opacity: .45;
  background: radial-gradient(circle at 50% 50%, rgba(139,92,246,.55), transparent 70%); }
.pl-world { position: absolute; left: 50%; top: 52%; width: 0; height: 0;
  transform-style: preserve-3d; transform: rotateX(58deg) rotateZ(-45deg);
  will-change: transform; animation: plWorldSway 17s ease-in-out infinite; }
@keyframes plWorldSway {
  0%,100% { transform: rotateX(58deg) rotateZ(-45deg); }
  50%     { transform: rotateX(56deg) rotateZ(-51deg); }
}
.pl-slab { position: absolute; left: 0; top: 0; width: var(--sz); height: var(--sz);
  transform-style: preserve-3d; transform: translate(-50%,-50%) translateZ(var(--lift)); }
.pl-slab .fc { position: absolute; left: 50%; top: 50%; }
.pl-slab .top { width: var(--sz); height: var(--sz);
  transform: translate(-50%,-50%) translateZ(calc(var(--th)/2));
  background: var(--f-top); box-shadow: inset 0 0 0 1px rgba(224,242,254,.30); }
.pl-slab .nS, .pl-slab .nN { width: var(--sz); height: var(--th); }
.pl-slab .nE, .pl-slab .nW { width: var(--th); height: var(--sz); }
.pl-slab .nS { transform: translate(-50%,-50%) rotateX(-90deg) translateZ(calc(var(--sz)/2)); background: var(--f-south); }
.pl-slab .nN { transform: translate(-50%,-50%) rotateX(90deg)  translateZ(calc(var(--sz)/2)); background: var(--f-south); }
.pl-slab .nE { transform: translate(-50%,-50%) rotateY(90deg)  translateZ(calc(var(--sz)/2)); background: var(--f-east); }
.pl-slab .nW { transform: translate(-50%,-50%) rotateY(-90deg) translateZ(calc(var(--sz)/2)); background: var(--f-east); }
.pl-slab .top b { position: absolute; right: 8px; bottom: 6px; transform: rotate(45deg);
  font: 800 .6rem/1 Inter, sans-serif; letter-spacing: .05em;
  color: rgba(255,255,255,.88); text-shadow: 0 1px 1px rgba(2,6,23,.4); }
.pl-gate { position: absolute; left: 50%; top: 50%; border-radius: 50%;
  border: 2px solid rgba(56,189,248,.5); transform: translate(-50%,-50%) translateZ(var(--gz)); }
.pl-gate--base { width: 210px; height: 210px; --gz: 3px; }
.pl-gate--apex { width: 84px; height: 84px; --gz: 121px; border-color: rgba(52,211,153,.75);
  box-shadow: 0 0 12px rgba(52,211,153,.45), inset 0 0 8px rgba(52,211,153,.30);
  animation: plGateGlow 4.5s ease-in-out infinite; }
@keyframes plGateGlow {
  0%,100% { box-shadow: 0 0 12px rgba(52,211,153,.45), inset 0 0 8px rgba(52,211,153,.30); }
  50%     { box-shadow: 0 0 22px rgba(52,211,153,.75), inset 0 0 12px rgba(52,211,153,.50); }
}
.pl-floor { position: absolute; left: 50%; top: 50%; width: 320px; height: 320px;
  transform: translate(-50%,-50%) translateZ(0);
  background:
    repeating-linear-gradient(0deg,  rgba(148,197,253,.13) 0 1px, transparent 1px 26px),
    repeating-linear-gradient(90deg, rgba(148,197,253,.13) 0 1px, transparent 1px 26px);
  -webkit-mask-image: radial-gradient(50% 50% at 50% 50%, #000 42%, transparent 78%);
          mask-image: radial-gradient(50% 50% at 50% 50%, #000 42%, transparent 78%); }
.pl-shadow { position: absolute; left: 50%; top: 50%; width: 250px; height: 250px;
  transform: translate(-50%,-50%) translateZ(-1px);
  background: radial-gradient(50% 50% at 50% 50%, rgba(2,6,23,.55), rgba(2,6,23,0) 70%); }
.pl-stats { display: grid; grid-template-columns: repeat(4,1fr); gap: 12px; position: relative; z-index: 1; }
.pl-stat { position: relative; display: flex; align-items: center; gap: 12px;
  padding: 13px 15px; border-radius: 14px; border: 1px solid rgba(255,255,255,.12);
  background: rgba(10,16,32,.44); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06); overflow: hidden; color: #fff; }
a.pl-stat:hover { color: #fff; border-color: rgba(255,255,255,.26); background: rgba(10,16,32,.56); }
.pl-stat > div { min-width: 0; }
.pl-stat .kpi-ic { width: 38px; height: 38px; flex: 0 0 38px; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 1rem; }
.pl-stat-lbl { font-size: .58rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: #a9b8dc; }
.pl-stat-val { font-size: 1.5rem; font-weight: 800; line-height: 1.1; color: #fff; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; }
.pl-stat-val.cm-ok { color: #6ee7b7; } .pl-stat-val.cm-warn { color: #fcd34d; } .pl-stat-val.cm-danger { color: #fda4af; }
.pl-stat-sub { font-size: .62rem; color: #93a4cc; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-cube { position: absolute; top: 12px; right: 13px; width: 28px; height: 28px;
  opacity: .9; pointer-events: none; transform-style: preserve-3d; transform: rotateX(58deg) rotateZ(-45deg); }
.pl-cube .cf { position: absolute; left: 50%; top: 50%; width: 20px; height: 20px; }
.pl-cube .t { transform: translate(-50%,-50%) translateZ(10px); background: var(--cb-top);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.4); }
.pl-cube .s { transform: translate(-50%,-50%) rotateX(-90deg) translateZ(10px); background: var(--cb-s); }
.pl-cube .e { transform: translate(-50%,-50%) rotateY(90deg)  translateZ(10px); background: var(--cb-e); }
@media (max-width: 991.98px) { .pl-stats { grid-template-columns: repeat(2,1fr); } }
/* On a phone the two tiles of a row are ~160px wide and the decorative cube
   sat ON the label ("TOTAL PROJECTS" under a diamond). The project board's
   hero already hid it; the portfolio and timeline heroes follow. */
@media (max-width: 575.98px) {
  .pl-cube { display: none; }
  .pl-stat { padding: 10px 11px; gap: 8px; }
}
@media (max-width: 767.98px) { .pl-stage { display: none; } .pf-hero .ch-hero-top { min-height: auto; } }
@media (prefers-reduced-motion: reduce) { .pl-world, .pl-gate--apex { animation: none; } }

/* ============================================================
   The dashboard's command centre — Enterprise's `.command-hero` with its
   "recommended next actions". Enterprise brands that panel as AI; here every
   line is a count the application already computes (apps/projects/
   command_centre.py), so the classes are `cmd-*` and nothing says AI.
   ============================================================ */
.command-hero { position: relative; overflow: hidden; border-radius: 22px; color: #eef3ff; padding: 24px 26px;
  background:
    url("../img/hero-automotive.3133761112b9.svg") right -6px bottom -14px / auto 150% no-repeat,
    radial-gradient(120% 110% at 100% 0%, rgba(139,92,246,.26) 0%, transparent 52%),
    radial-gradient(110% 120% at 0% 100%, rgba(56,189,248,.22) 0%, transparent 55%),
    linear-gradient(120deg, #0a1020 0%, #122a52 46%, #1a3a78 76%, #24489e 100%);
  border: 1px solid rgba(139,92,246,.24); box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255,255,255,.08); }
.command-hero .ch-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px;
  flex-wrap: wrap; position: relative; z-index: 1; }
.command-hero .ch-divider { height: 1px; margin: 18px 0; position: relative; z-index: 1;
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.14) 30%, rgba(255,255,255,.14) 70%, rgba(255,255,255,0)); }
.command-hero .hero-eyebrow { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 2px;
  color: #93c5fd; text-shadow: 0 1px 6px rgba(37,99,235,.45); }
.command-hero .hero-title { font-size: 1.9rem; font-weight: 800; margin: 0 0 6px; color: #fff; text-shadow: 0 2px 10px rgba(0,0,0,.35); }
.command-hero .hero-sub { font-size: .92rem; color: #d4def0; }
.hero-stats { display: flex; gap: 26px; flex-wrap: wrap; }
.hero-stat .hs-val { font-size: 1.5rem; font-weight: 800; line-height: 1; color: #fff; font-variant-numeric: tabular-nums; }
.hero-stat .hs-val.cm-danger { color: #fda4af; }
.hero-stat .hs-lab { font-size: .68rem; text-transform: uppercase; letter-spacing: .08em; color: #9fb4dc; margin-top: 3px; }
.live-badge { display: inline-flex; align-items: center; gap: 6px; font-size: .64rem; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: #6ee7b7; padding: 3px 10px; border-radius: 999px;
  background: rgba(16,185,129,.14); border: 1px solid rgba(16,185,129,.3); }
.live-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; background: #10b981; animation: livepulse 1.8s infinite; }
@keyframes livepulse { 0% { box-shadow: 0 0 0 0 rgba(16,185,129,.55); } 70% { box-shadow: 0 0 0 8px rgba(16,185,129,0); } 100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); } }
.cmd-head { display: flex; align-items: center; gap: 12px; position: relative; z-index: 1; margin-bottom: 16px; }
.cmd-orb { width: 44px; height: 44px; border-radius: 14px; display: grid; place-items: center; font-size: 1.3rem; color: #fff;
  background: linear-gradient(135deg,#8b5cf6,#6366f1 45%,#38bdf8); box-shadow: 0 8px 22px rgba(139,92,246,.55), inset 0 1px 0 rgba(255,255,255,.4); }
.cmd-title { font-weight: 800; font-size: 1.05rem; letter-spacing: -.01em; }
.cmd-caption { font-size: .72rem; color: #9fb0da; }
/* minmax(0, …): a grid track's minimum is otherwise its content, and a long
   no-wrap action line widened the column past the hero, which clips it */
.cmd-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: 18px; position: relative; z-index: 1; }
@media (max-width: 991.98px) { .cmd-grid { grid-template-columns: minmax(0, 1fr); } }
.cmd-summary { border-left: 3px solid #64748b; padding-left: 14px; }
.cmd-summary.tone-ok { border-color: #34d399; } .cmd-summary.tone-warn { border-color: #fbbf24; } .cmd-summary.tone-danger { border-color: #fb7185; }
.cmd-summary-head { font-size: 1.15rem; font-weight: 800; line-height: 1.25; margin-bottom: 6px; }
.cmd-summary-body { font-size: .9rem; color: #cdd8f2; margin: 0; }
.cmd-label { font-size: .64rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: #9fb0da; margin-bottom: 8px; }
.cmd-dates { margin-top: 16px; }
.cmd-chip { display: inline-flex; align-items: center; gap: 7px; margin: 0 6px 6px 0; padding: 5px 10px; border-radius: 10px;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12); color: #eef3ff; font-size: .76rem; transition: .15s; }
.cmd-chip:hover { background: rgba(255,255,255,.12); color: #fff; transform: translateY(-1px); }
.cmd-chip.crit { border-color: rgba(251,113,133,.5); }
.cmd-chip b { font-weight: 700; }
.cmd-chip .cmd-risk { font-size: .6rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: #fda4af; }
.cmd-chip .cmd-days { color: #9fb0da; }
.cmd-rec { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 13px; color: #eef3ff;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.09); margin-bottom: 8px;
  transition: transform .16s cubic-bezier(.34,1.56,.64,1), background .16s ease, border-color .16s ease; }
.cmd-rec:hover { background: rgba(255,255,255,.1); border-color: rgba(139,92,246,.4); transform: translateX(3px); color: #fff; }
.cmd-rec-ic { width: 36px; height: 36px; flex: 0 0 36px; border-radius: 10px; display: grid; place-items: center; font-size: 1.05rem; color: #fff;
  background: linear-gradient(135deg,#fbbf24,#d97706); box-shadow: inset 0 1px 0 rgba(255,255,255,.25); }
.cmd-rec.is-high .cmd-rec-ic { background: linear-gradient(135deg,#fb7185,#e11d48); }
.cmd-rec-body { flex: 1 1 auto; min-width: 0; line-height: 1.25; }
.cmd-rec-title { display: block; font-weight: 650; font-size: .86rem; }
.cmd-rec-detail { display: block; font-size: .74rem; color: #a9b7dc; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmd-rec-level { flex: 0 0 auto; font-size: .56rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; padding: 2px 7px; border-radius: 6px;
  background: rgba(251,191,36,.2); color: #fcd34d; }
.cmd-rec.is-high .cmd-rec-level { background: rgba(251,113,133,.2); color: #fda4af; }
.cmd-rec-go { color: #7f8fc0; flex: 0 0 auto; }
.cmd-rec:hover .cmd-rec-go { color: #c4b5fd; }
.cmd-clear { display: flex; align-items: center; gap: 10px; padding: 12px; border-radius: 13px; color: #cdd8f2;
  background: rgba(52,211,153,.08); border: 1px solid rgba(52,211,153,.25); font-size: .86rem; }
/* the lines the five could not hold — named, never dropped */
.cmd-more { margin-top: 8px; padding: 0 12px; font-size: .74rem; color: #a9b7dc; line-height: 1.5; }
.cmd-more span { font-weight: 700; color: #cdd8f2; margin-right: 4px; }
.cmd-more a { color: #c7d2fe; text-decoration: underline; text-decoration-color: rgba(199,210,254,.4); }
.cmd-more a:hover { color: #fff; }
@media (prefers-reduced-motion: reduce) { .live-dot { animation: none; } .cmd-rec:hover, .cmd-chip:hover { transform: none; } }

/* ============================================================
   The portfolio gate map (Gate Reviews) — Enterprise's `.gr-matrix`. Here
   `rag-*` and `gr-dot` already mean other things, so it is `gmap-*`.
   ============================================================ */
.gmap-sheet { overflow: clip; }
.gmap-matrix thead th { font-size: .6rem; padding: 8px 10px; background: #fbfcfe; }
.gmap-matrix tbody td { padding: 7px 10px; border-bottom: 1px solid var(--line); }
.gmap-matrix tbody tr:last-child td { border-bottom: 0; }
.gmap-matrix tbody tr:hover td { background: #f9fbfe; }
.gmap-cell { position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 34px; border-radius: 9px; font-weight: 800; font-size: .82rem;
  color: #1f2937; border: 1px solid transparent; transition: transform .1s ease, box-shadow .12s ease; }
a.gmap-cell:hover { transform: translateY(-1px); box-shadow: var(--shadow-xs); color: inherit; }
.gmap-cell.is-current { outline: 2px solid rgba(37,99,235,.55); outline-offset: 1px; }
.gmap-ok   { background: var(--ok-soft); color: #047857; }
a.gmap-ok:hover { color: #047857; }
.gmap-cond { background: #f1e9fe; color: #7c3aed; }
.gmap-rej  { background: var(--danger-soft); color: #dc2626; }
.gmap-open { background: var(--accent-soft); color: var(--accent-600); box-shadow: inset 0 0 0 1px rgba(37,99,235,.14); }
.gmap-pend { background: #eef1f6; color: #64748b; }
.gmap-none { background: repeating-linear-gradient(45deg,#f5f7fa,#f5f7fa 4px,#eef1f6 4px,#eef1f6 8px); color: #cbd5e1; }
.gmap-frac { font-size: .66rem; font-weight: 700; }
.gmap-missing { position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px; border-radius: 9px;
  background: var(--danger); color: #fff; font-size: .6rem; font-weight: 700; display: inline-flex;
  align-items: center; justify-content: center; padding: 0 3px; box-shadow: 0 0 0 2px #fff; }
.gmap-missing-key { position: static; box-shadow: none; }
.gmap-dot { position: absolute; left: 4px; bottom: 4px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--danger); box-shadow: 0 0 0 2px rgba(255,255,255,.9); }
.gmap-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-size: .66rem; color: var(--ink-soft); }
.gmap-legend > span { display: inline-flex; align-items: center; gap: 5px; }
.gmap-key { width: 13px; height: 13px; border-radius: 4px; display: inline-block; }
.gmap-kpis { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
@media (prefers-reduced-motion: reduce) { a.gmap-cell { transition: none; } }

/* ============================================================
   Polish layer — micro-interactions, toasts, command palette
   ============================================================ */
.card { transition: box-shadow .25s ease, transform .2s cubic-bezier(.2,.7,.3,1); }
.kpi-tile, .kpi-card { transition: box-shadow .25s ease, transform .2s cubic-bezier(.2,.7,.3,1); }
.kpi-tile:hover, .kpi-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }

@keyframes riseIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
/* `backwards`, not `both`: the rise must leave NOTHING on the element once it
   is over. Filled forwards, the last keyframe is interpolated to
   translateY(0) — not `none` — so every card and every document header stayed
   a stacking context for good, and a menu that opens out of one (the PFMEA's
   Export, a Control Plan's More) was painted UNDER the next card down: the
   identification header covered "Full PFMEA (Excel)" and the results report
   (ACS Mexico, Oct 2026). Backwards keeps the first frame during the delay,
   which is all the fill was for. */
main .card, .kpi-tile, .doc-hero { animation: riseIn .45s cubic-bezier(.2,.7,.3,1) backwards; }
main .card:nth-child(2), .kpi-tile:nth-of-type(2) { animation-delay: .05s; }
main .card:nth-child(3), .kpi-tile:nth-of-type(3) { animation-delay: .1s; }
main .card:nth-child(4), .kpi-tile:nth-of-type(4) { animation-delay: .15s; }
main .card:nth-child(n+5) { animation-delay: .2s; }
/* A transform on an ancestor makes it the containing block of every
   `position:fixed` inside it — while the rise runs (and, before the fill went
   to `backwards`, for good), a fixed popover inside a card is placed against
   the card. The FMEA and Control Plan worksheets pin editors and pickers
   inside cards, so those cards do not rise at all. */
main .card:has(.docbar), main .card:has(.fmea-table), main .card:has(.fmea-ap-table) { animation: none; }

:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent) !important; border-radius: 6px; }

* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, #94a3b8 45%, transparent) transparent; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb { background: color-mix(in srgb, #94a3b8 40%, transparent); border-radius: 8px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, #94a3b8 65%, transparent); background-clip: content-box; border: 2px solid transparent; }
*::-webkit-scrollbar-track { background: transparent; }

.btn:active { transform: scale(.97); }

/* ---- Flash messages → floating glass toasts ---- */
.toast-stack { position: fixed; top: 76px; right: 18px; z-index: 1085;
  display: flex; flex-direction: column; gap: .6rem; width: min(400px, calc(100vw - 36px)); }
.toast-stack .alert.toastified { position: relative; overflow: hidden; margin: 0;
  border: 1px solid var(--line); border-radius: 14px;
  background: color-mix(in srgb, var(--card) 88%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 18px 44px rgba(8,17,45,.28), inset 0 1px 0 rgba(255,255,255,.25);
  animation: toastIn .38s cubic-bezier(.2,.8,.25,1.1) both; }
.toast-stack .alert-success.toastified { border-left: 4px solid var(--ok); }
.toast-stack .alert-warning.toastified { border-left: 4px solid var(--warn); }
.toast-stack .alert-danger.toastified,
.toast-stack .alert-error.toastified { border-left: 4px solid var(--danger); }
.toast-stack .alert-info.toastified { border-left: 4px solid var(--accent); }
@keyframes toastIn { from { opacity: 0; transform: translateX(24px) scale(.97); } to { opacity: 1; transform: none; } }
.toast-stack .alert.toast-out { transition: opacity .3s ease, transform .3s ease; opacity: 0; transform: translateX(24px); }
.toast-life { position: absolute; left: 0; bottom: 0; height: 3px; width: 100%;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 40%, transparent));
  transform-origin: left; animation: toastLife linear forwards; border-radius: 0 2px 2px 0; }
@keyframes toastLife { from { transform: scaleX(1); } to { transform: scaleX(0); } }

/* ---- Command palette (⌘K / Ctrl+K) ---- */
.cmdk-overlay { position: fixed; inset: 0; z-index: 1090; display: none;
  background: rgba(8, 13, 28, .45); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.cmdk-overlay.open { display: flex; align-items: flex-start; justify-content: center;
  padding: min(14vh, 130px) 16px 16px; animation: cmdkFade .18s ease both; }
@keyframes cmdkFade { from { opacity: 0; } to { opacity: 1; } }
.cmdk { width: min(620px, 100%); border-radius: 18px; overflow: hidden;
  background: color-mix(in srgb, var(--card) 94%, transparent);
  border: 1px solid color-mix(in srgb, var(--line) 80%, transparent);
  box-shadow: 0 40px 90px rgba(4, 9, 24, .5), inset 0 1px 0 rgba(255,255,255,.2);
  animation: cmdkPop .22s cubic-bezier(.2,.8,.25,1.1) both; }
@keyframes cmdkPop { from { opacity: 0; transform: translateY(-14px) scale(.98); } to { opacity: 1; transform: none; } }
.cmdk-input { display: flex; align-items: center; gap: .7rem; padding: .95rem 1.1rem;
  border-bottom: 1px solid var(--line); }
.cmdk-input i { color: #64748b; font-size: 1.05rem; }
.cmdk-input input { flex: 1; border: 0; outline: none; background: transparent;
  color: var(--ink); font-size: 1.02rem; }
.cmdk-input input::placeholder { color: #94a3b8; }
.cmdk-input kbd { font-size: .68rem; color: #64748b; border: 1px solid var(--line);
  border-radius: 6px; padding: .15rem .45rem; background: var(--bg); box-shadow: none; }
.cmdk-list { max-height: 340px; overflow-y: auto; padding: .45rem; }
.cmdk-item { display: flex; align-items: center; gap: .7rem; padding: .6rem .75rem;
  border-radius: 10px; cursor: pointer; color: var(--ink); font-size: .93rem; }
.cmdk-item i { color: #64748b; width: 18px; text-align: center; }
.cmdk-item .cmdk-sec { margin-left: auto; flex: 0 0 auto; font-size: .7rem;
  color: #94a3b8; text-transform: uppercase; letter-spacing: .04em; }
.cmdk-item .cmdk-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .05rem; }
.cmdk-item .cmdk-body > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-item .cmdk-sub { font-size: .76rem; color: #94a3b8; }
.cmdk-item.active .cmdk-sub { color: #475569; }
.cmdk-item.active { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.cmdk-item.active i { color: var(--accent); }
.cmdk-empty { padding: 1.2rem; text-align: center; color: #64748b; font-size: .9rem; }

/* ============================================================
   The project dashboard (projects/project_detail.html) — Enterprise's
   charter cards. The card shell, header chip and rows (.charter-card,
   .cc-head, .cc-row) already live in custom.css; these are the pieces
   the dashboard adds.
   ============================================================ */
.cc-accent-violet { --cc: #8b5cf6; --cc-soft: #f1ecfe; }
.cc-accent-slate  { --cc: #5b6b8c; --cc-soft: #edf0f6; }
.charter-card--feature { box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 1px 2px rgba(16,24,40,.05),
  0 16px 34px -16px rgba(16,24,40,.22); }
.charter-card--feature::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, #38bdf8, var(--accent)); }
@keyframes attnbg { 0%, 100% { background: rgba(220,38,38,.07); } 50% { background: rgba(220,38,38,.18); } }
.cc-head.cc-head-alert { color: #b02a37; background: rgba(220,38,38,.08); animation: attnbg 1.4s ease-in-out infinite; }
.cc-head.cc-head-alert > .bi:first-child { color: var(--danger); background: var(--danger-soft); }

/* Needs attention: severity rail + ringed icon squares */
.charter-attn { position: relative; display: flex; align-items: center; gap: 10px;
  padding: 8px 10px 8px 14px; border-radius: 10px; text-decoration: none;
  transition: background .12s ease, transform .12s ease; }
.charter-attn::before { content: ""; position: absolute; left: 4px; top: 8px; bottom: 8px;
  width: 3px; border-radius: 2px; background: #cbd3e1; }
.charter-attn.danger::before { background: var(--danger); }
.charter-attn.warn::before { background: var(--warn); }
.charter-attn.info::before { background: var(--accent); }
.charter-attn:hover { background: var(--cc-soft); transform: translateX(2px); }
.charter-attn .a-txt { flex: 1 1 auto; color: var(--ink); font-size: .86rem; font-weight: 500; }
.charter-ico { width: 26px; height: 26px; flex: none; border-radius: 8px; display: grid;
  place-items: center; font-size: .8rem; }
.charter-ico.danger { background: var(--danger-soft); color: var(--danger); }
.charter-ico.warn { background: var(--warn-soft); color: var(--warn); }
.charter-ico.info { background: var(--accent-soft); color: var(--accent); }

/* Phase progress: medallion numbers + gradient bars */
.charter-phase { display: flex; align-items: center; gap: 10px; padding: 5px 6px;
  border-radius: 9px; text-decoration: none; transition: background .12s ease; }
.charter-phase:hover, .charter-phase-current { background: var(--cc-soft); }
.charter-phase-n { width: 24px; height: 24px; flex: none; border-radius: 8px; display: grid;
  place-items: center; font-weight: 800; font-size: .72rem; color: #64748b;
  background: linear-gradient(155deg, #f2f5fa, #dde4ee);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9), inset 0 -2px 3px rgba(16,24,40,.09); }
.charter-phase-n.current { color: #fff; background: linear-gradient(155deg, #38bdf8 8%, var(--accent-600) 92%);
  box-shadow: inset 0 1.5px 0 rgba(255,255,255,.5), 0 4px 9px -3px rgba(37,99,235,.55); }
.charter-phase-n.done { color: #fff; background: linear-gradient(155deg, #34d399 8%, #059669 92%);
  box-shadow: inset 0 1.5px 0 rgba(255,255,255,.5), 0 4px 9px -3px rgba(5,150,105,.5); }
.charter-phase .cp-name { min-width: 150px; flex: 0 0 auto; }
.charter-phase .cp-name b { display: block; font-size: .82rem; line-height: 1.2; color: var(--ink); font-weight: 600; }
.charter-phase .cp-name small { font-size: .68rem; color: var(--ink-soft); }
.charter-phase .cp-name small.ok { color: var(--ok); }
.charter-phase .cp-name small.bad { color: var(--danger); }
.charter-phase .progress { flex: 1 1 auto; height: 5px; border-radius: 99px; background: #eef1f7; }
.charter-phase .progress-bar { border-radius: 99px; background: linear-gradient(90deg, #d3dae6, #aab4c6); }
.charter-phase .progress-bar.cur { background: linear-gradient(90deg, #38bdf8, var(--accent)); }
.charter-phase .progress-bar.done { background: linear-gradient(90deg, #34d399, #059669); }
.charter-phase .cp-pct { width: 36px; text-align: right; font-size: .72rem; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; }

/* Quality tools: glossy medallions, one colour per tool */
.qt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
.qt-tool { display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 13px 4px 10px; border-radius: 15px; text-decoration: none; border: 1px solid transparent;
  transition: background .2s ease, border-color .2s ease; }
.qt-tool:hover { background: linear-gradient(180deg, rgba(148,163,184,.10), rgba(148,163,184,0)); border-color: var(--line); }
.qt-ico { width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center;
  color: #fff; font-size: 1.4rem; line-height: 1;
  background: linear-gradient(155deg, var(--qt-c1) 8%, var(--qt-c2) 92%);
  box-shadow: 0 7px 15px -4px var(--qt-shadow), 0 2px 4px rgba(16,24,40,.14),
    inset 0 1.5px 0 rgba(255,255,255,.6), inset 0 -4px 7px rgba(0,0,0,.22);
  transition: transform .22s cubic-bezier(.2,.75,.3,1.45), box-shadow .22s ease; }
.qt-ico i { filter: drop-shadow(0 1.5px 1.5px rgba(0,0,0,.3)); }
.qt-tool:hover .qt-ico { transform: translateY(-4px) scale(1.18) rotate(-4deg); }
.qt-count { font-weight: 800; font-size: 1.15rem; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.qt-label { font-size: .64rem; color: var(--ink-soft); text-align: center; line-height: 1.2; }
.qt-tool:hover .qt-count { color: var(--qt-c2); }
.qt-t-amber   { --qt-c1: #fbbf24; --qt-c2: #f59e0b; --qt-shadow: rgba(245,158,11,.55); }
.qt-t-emerald { --qt-c1: #34d399; --qt-c2: #059669; --qt-shadow: rgba(5,150,105,.5); }
.qt-t-teal    { --qt-c1: #2dd4bf; --qt-c2: #0d9488; --qt-shadow: rgba(13,148,136,.5); }
.qt-t-blue    { --qt-c1: #60a5fa; --qt-c2: #2563eb; --qt-shadow: rgba(37,99,235,.5); }
.qt-t-rose    { --qt-c1: #fb7185; --qt-c2: #e11d48; --qt-shadow: rgba(225,29,72,.45); }
.qt-t-violet  { --qt-c1: #c084fc; --qt-c2: #7c3aed; --qt-shadow: rgba(124,58,237,.5); }
.qt-t-sky     { --qt-c1: #22d3ee; --qt-c2: #0891b2; --qt-shadow: rgba(8,145,178,.5); }
.qt-t-indigo  { --qt-c1: #818cf8; --qt-c2: #4f46e5; --qt-shadow: rgba(79,70,229,.5); }
.qt-t-slate   { --qt-c1: #94a3b8; --qt-c2: #475569; --qt-shadow: rgba(71,85,105,.45); }
.qt-t-red     { --qt-c1: #f87171; --qt-c2: #dc2626; --qt-shadow: rgba(220,38,38,.45); }

/* The Charter's notifier inside the dashboard's Notice board card: the card
   header already names it, so the sheet's own title shrinks to the count and
   the "Mark all read" button, and the box sizes to what it holds. */
.nb-card #notifier .cstatus-title { margin: 0 0 6px !important; font-size: .72rem; min-height: 0; }
.nb-card #notifier .cstatus-title > .bi:first-child,
.nb-card #notifier .cstatus-title { color: var(--ink-soft); }
.nb-card #notifier .notif { height: auto; max-height: 320px; border: 0; }
.nb-card #notifier .notif-empty { padding: 8px; }
.qt-grid { grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); }

/* ---- The program board (projects/phase_detail.html) ---- */
.prj-board-hero .ch-hero-top h1 { font-size: 1.55rem; }
.prj-board-hero .prj-back { flex: none; }
.ch-tag.here { background: rgba(16,185,129,.18); color: #6ee7b7; border-color: rgba(110,231,183,.35); }
.pl-stat-sub { font-size: .68rem; color: rgba(226,232,240,.7); margin-top: 2px; }
.pb-phases { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px; margin-bottom: 1rem; }
.pb-phase { display: grid; grid-template-columns: auto 1fr; gap: 4px 10px; align-items: center;
  padding: 14px 14px 12px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-xs); text-decoration: none; color: var(--ink);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; }
.pb-phase:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.pb-phase.is-done { background: linear-gradient(180deg, #f0fdf6, var(--card)); border-color: #bbf7d0; }
.pb-phase.is-on { border: 2px solid var(--accent); padding: 13px 13px 11px;
  box-shadow: 0 0 0 4px var(--accent-soft), var(--shadow-sm); }
.pb-n { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font-weight: 800;
  font-size: .82rem; color: #64748b; background: #eef2f7; }
.pb-phase.is-done .pb-n { color: #fff; background: linear-gradient(155deg, #34d399, #059669); }
.pb-phase.is-on .pb-n { color: #fff; background: linear-gradient(155deg, #38bdf8, var(--accent-600)); }
.pb-t b { display: block; font-size: .86rem; font-weight: 600; color: var(--accent); line-height: 1.15; }
.pb-t small { font-size: .7rem; color: var(--ink-soft); }
.pb-name { grid-column: 1 / -1; font-size: .78rem; color: var(--ink); line-height: 1.3; margin-top: 4px; }
.pb-head { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; margin-top: 1rem;
  padding: 14px 18px; background: var(--card); border: 1px solid var(--line); border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0; }
.pb-head-ic { width: 34px; height: 34px; flex: none; border-radius: 10px; display: grid; place-items: center;
  color: #fff; background: linear-gradient(155deg, #818cf8, #4f46e5); box-shadow: 0 6px 14px -6px rgba(79,70,229,.6); }
.pb-title { font-size: 1.12rem; font-weight: 700; margin: 0 0 2px; color: var(--ink); }
.pb-head #phase-stats { font-size: .8rem; }
.pb-head-side { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.pb-gate { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 10px;
  font-weight: 600; font-size: .86rem; text-decoration: none; border: 1.5px solid var(--accent);
  color: var(--accent); background: var(--accent-soft); }
.pb-gate-approved { color: #fff; background: linear-gradient(180deg, #16a34a, #15803d); border-color: #15803d; }
.pb-gate-conditional { color: #92400e; background: var(--warn-soft); border-color: var(--warn); }
.pb-gate-rejected { color: #fff; background: linear-gradient(180deg, #e11d48, #be123c); border-color: #be123c; }
.pb-gate-na { color: #475569; background: #f1f5f9; border-color: #cbd5e1; border-style: dashed; }
.pb-legend { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.pb-head + .prem-table-card { border-top-left-radius: 0; border-top-right-radius: 0; }
.pb-table .prem-table thead th { font-size: .62rem; }   /* Enterprise's board table head */
@media (max-width: 1199.98px) { .pb-phases { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.prj-board-hero .pl-stat > div { min-width: 0; }
@media (max-width: 575.98px) {
  /* two tiles to a row on a phone: the words wrap inside the tile instead of
     running out of it, and the decorative cube stops sitting on the label */
  .prj-board-hero .pl-cube { display: none; }
  .prj-board-hero .pl-stat { padding: 10px 11px; gap: 8px; align-items: flex-start; }
  .prj-board-hero .pl-stat .kpi-ic { width: 30px; height: 30px; font-size: .9rem; }
  .prj-board-hero .pl-stat-val { font-size: 1.25rem; }
  .prj-board-hero .pl-stat-sub { overflow-wrap: anywhere; }
  .pb-phases { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .pb-head-side { margin-left: 0; align-items: flex-start; }
}

/* A month where nothing was on time is a real 0 %, not a month with no data:
   the bar keeps a visible stub and its number sits above it (a 0-height bar
   hid its own white label and read exactly like an empty month). */
.got-bar.got-zero { height: 4px !important; }
.got-bar.got-zero .got-pct { position: absolute; left: 0; right: 0; bottom: 6px; color: var(--danger); }

/* ---- The two Pareto cards on the dashboard (projects/partials/pareto_card.html) ---- */
.pareto-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: .72rem; color: var(--ink-soft);
  margin: 2px 0 6px; }
.pareto-legend span { display: inline-flex; align-items: center; gap: 6px; }
.pl-sw { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.pl-sw.pl-b { background: #f59e0b; }
.pl-sw.pl-a { background: #e11d48; }
.pl-line { width: 16px; height: 2px; background: #1e293b; display: inline-block; position: relative; }
.pl-line::after { content: ""; position: absolute; left: 5px; top: -3px; width: 6px; height: 6px;
  border-radius: 50%; border: 2px solid #1e293b; background: var(--card); box-sizing: border-box; }
.pl-dash { width: 16px; height: 0; border-top: 2px dashed #64748b; display: inline-block; }
.pareto-canvas { position: relative; height: 250px; }
.pareto-foot { margin-top: 6px; }
.pareto-table { margin-top: 8px; }
.pareto-table > summary { font-size: .74rem; color: var(--accent); cursor: pointer; width: max-content; }
.pareto-table table { font-size: .76rem; margin-top: 6px; }
.pareto-table tr.pareto-vital td:first-child { box-shadow: inset 3px 0 0 #e11d48; }

/* Customer milestones table on the dashboard */
.ms-table td, .ms-table th { vertical-align: middle; }
.ms-table .ms-code { font-weight: 700; }
.ms-table .ms-rule { display: block; font-size: .68rem; color: var(--ink-soft); }
.ms-table { min-width: 620px; }   /* scrolls in its own box on a phone rather than folding each word */
@media (prefers-reduced-motion: reduce) {
  .cc-head.cc-head-alert { animation: none; }
  .qt-tool:hover .qt-ico { transform: scale(1.06); }
}

/* ============================================================
   The side shell — additions for the elements above. The column itself
   (width, sections, rail, foot menus) lives in custom.css; these follow its
   selectors so they weigh the same.
   ============================================================ */
@media (min-width: 992px) {
  /* the beam does not sweep down a column: it becomes the edge light */
  nav.navbar.pq-side .proq-nav-beam { inset: 0 auto 0 0; width: 2px; height: auto;
    background: linear-gradient(180deg, #38bdf8, #2563eb 46%, transparent);
    animation: none; transform: none; opacity: 1; filter: none; mix-blend-mode: normal; }
  nav.navbar.pq-side .brand-word { font-size: 1.02rem; }
  nav.navbar.pq-side .co-brand { flex: 0 0 auto; padding: 0 16px 8px; margin: 0; }
  nav.navbar.pq-side .co-brand-divider { display: none; }
  nav.navbar.pq-side .co-brand-logo { height: 34px; max-width: 100%; }
  nav.navbar.pq-side .nav-search-slot { flex: 0 0 auto; padding: 0 12px 10px; }
  nav.navbar.pq-side .cmdk-hint {
    display: flex !important; width: 100%; justify-content: flex-start; margin: 0;
    gap: 8px; padding: 7px 10px; border-radius: 9px;
    background: rgba(255, 255, 255, .09); border: 1px solid rgba(255, 255, 255, .13);
    color: #b9cdec; font-size: .8rem;
  }
  nav.navbar.pq-side .cmdk-hint kbd { margin-left: auto; }
  /* the quick icons carry Bootstrap's `d-lg-flex`, which is !important — the
     column's labelled links replace them, so the hide has to match it */
  nav.navbar.pq-side .nav-quick { display: none !important; }
  nav.navbar.pq-side .nav-foot .nav-foot-label { display: inline !important; }
  /* signatures and notifications share a row; the person keeps one of their own */
  nav.navbar.pq-side .nav-foot > .nav-item.foot-half { flex: 1 1 calc(50% - 10px); min-width: 0; }
  nav.navbar.pq-side .nav-foot > .nav-item.foot-person { flex: 1 1 100%; }
  body.pqs-rail nav.navbar.pq-side .nav-foot > .nav-item.foot-half,
  body.pqs-rail nav.navbar.pq-side .nav-foot > .nav-item.foot-person { flex: 0 0 auto; }
  nav.navbar.pq-side .user-chip { width: 100%; padding: 7px 8px !important; }
  nav.navbar.pq-side .user-chip-name { font-size: .8rem; }
  body:not(.pqs-rail) nav.navbar.pq-side .user-chip-name { display: inline !important; }
  nav.navbar.pq-side .nav-count { margin-left: auto; }

  body.pqs-rail nav.navbar.pq-side .brand-word,
  body.pqs-rail nav.navbar.pq-side .co-brand,
  body.pqs-rail nav.navbar.pq-side .cmdk-hint span,
  body.pqs-rail nav.navbar.pq-side .cmdk-hint kbd,
  body.pqs-rail nav.navbar.pq-side .nav-foot .nav-foot-label,
  body.pqs-rail nav.navbar.pq-side .user-chip-name,
  body.pqs-rail nav.navbar.pq-side .user-chip .bi-chevron-down { display: none !important; }
  body.pqs-rail nav.navbar.pq-side .cmdk-hint,
  body.pqs-rail nav.navbar.pq-side .user-chip { justify-content: center; padding-left: 0 !important; padding-right: 0 !important; }

  /* the sub-bar moves over with the page */
  html[data-nav="side"] body > .subbar {
    margin-left: var(--pqs-w); width: calc(100% - var(--pqs-w));
    transition: margin-left .16s ease, width .16s ease;
  }
  .proq-nav:not(.pq-side) .nav-search-slot { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .proq-nav-beam { animation: none; opacity: 0; }
  main .card, .kpi-tile, .doc-hero, .toast-stack .alert.toastified, .cmdk, .cmdk-overlay.open,
  .proq-nav .dropdown-menu, .dropdown-menu.pq-foot-menu { animation: none !important; }
  .card, .kpi-tile, .kpi-card, .btn { transition: none !important; }
  .btn:active { transform: none; }
}

/* ============================================================
   Special-characteristic class badge with customer-symbol reveal
   ------------------------------------------------------------
   A worksheet cell stores the class CODE (CC, CS, KPC…); hovering
   it reveals how THIS customer draws that class — a picture they
   gave us, else their text symbol. `{% special_class %}` renders
   it; the map is one query per screen (special_chars_tags.py).
   Tokens flip themselves in Midnight; the image plate stays white
   on purpose — a customer's symbol is inked on paper. ============ */
.scx { position: relative; display: inline-flex; }
.scx-code {
  display: inline-flex; align-items: center; border-radius: 999px;
  font-weight: 700; font-size: .68rem; line-height: 1; letter-spacing: .01em;
  padding: .26em .6em; background: #eef1f6; color: var(--ink-soft);
}
.scx-c-CC  { background: var(--danger-soft); color: var(--danger); }
.scx-c-CS,
.scx-c-SC  { background: var(--warn-soft); color: #b45309; }
.scx-c-KPC,
.scx-c-KCC { background: var(--accent-soft); color: var(--accent-600); }
.scx-has { cursor: help; }
.scx-has .scx-code { box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 34%, transparent); }

/* The reveal is position:fixed and placed by proq.js from the badge's rect —
   NOT absolute — so the worksheet's own overflow:auto scroll container cannot
   clip it (the recurring clipping trap in this codebase). It defaults hidden;
   the script adds .scx-open and the coordinates together. */
.scx-pop {
  position: fixed; left: 0; top: 0; z-index: 3000;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  min-width: 58px; max-width: 160px; padding: 7px 9px 5px;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 30px rgba(15,23,42,.22); pointer-events: none;
  opacity: 0; visibility: hidden; transform: translateY(3px);
  transition: opacity .12s ease, transform .12s ease;
}
.scx-pop.scx-open { opacity: 1; visibility: visible; transform: translateY(0); }
.scx-pop-img {
  max-height: 46px; max-width: 128px; object-fit: contain;
  background: #fff; border-radius: 5px; padding: 3px;
}
.scx-pop-txt {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 1rem; font-weight: 700; color: var(--ink);
  padding: 2px 4px; white-space: nowrap;
}
.scx-pop-cap {
  font-size: .58rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-soft);
}
