:root {
  /* Matched to the DEPLOYABLE.energy logo: near-black + orange accent.
     --de-navy/--de-blue names kept as-is rather than renamed, to avoid
     touching every rule below that references them — same colors,
     different values. */
  --de-navy: #14161a;
  --de-blue: #f5821f;
  --de-teal: #12879a;
  --de-bg: #f6f8fa;
  --de-border: #d8dee5;
  --de-text: #1b2733;
  --de-muted: #5b6b7a;
  --de-danger: #b3261e;
  --de-success: #1e7a34;

  /* Separate from --de-navy on purpose — that variable is also used for
     dark-on-light accents elsewhere (legend text, stat numbers, button
     hover), which a near-black topbar background shares no relationship
     with. The logo's own text is black, so a dark topbar background made
     it nearly unreadable — this needs to be light regardless of what
     --de-navy is set to. */
  --de-topbar-bg: #ffffff;
  --de-topbar-text: #14161a;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--de-bg);
  color: var(--de-text);
  line-height: 1.5;
}

.topbar {
  background: var(--de-topbar-bg);
  color: var(--de-topbar-text);
  border-bottom: 1px solid var(--de-border);
  padding: 18px 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.topbar .brand {
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
}

.topbar .brand-link { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--de-topbar-text); }
.topbar .brand-logo { height: 28px; display: block; }

.topbar a { color: var(--de-topbar-text); text-decoration: none; font-size: 0.9rem; opacity: 0.75; }

.user-menu { position: relative; }
.user-menu summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 20px;
  font-size: 0.9rem;
  color: var(--de-topbar-text);
}
.user-menu summary::-webkit-details-marker { display: none; }
.user-menu summary:hover, .user-menu[open] summary { background: var(--de-bg); }
.user-menu .avatar {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--de-blue); color: white;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.75rem; font-weight: 700; flex-shrink: 0;
}
.user-menu-dropdown {
  position: absolute; right: 0; top: calc(100% + 6px);
  background: white; border: 1px solid var(--de-border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  min-width: 200px; padding: 6px; z-index: 20;
}
.user-menu-dropdown a, .user-menu-dropdown .menu-email {
  display: block; padding: 8px 10px; border-radius: 6px; font-size: 0.88rem;
  color: var(--de-text); text-decoration: none; opacity: 1;
}
.user-menu-dropdown a:hover { background: var(--de-bg); }
.user-menu-dropdown .menu-email {
  color: var(--de-muted); font-size: 0.8rem;
  border-bottom: 1px solid var(--de-border); margin-bottom: 4px; word-break: break-all;
}

.settings-topbar-right { display: flex; align-items: center; gap: 16px; }

.nav-menu { position: relative; }
.nav-menu summary {
  list-style: none; cursor: pointer; font-size: 1.3rem; line-height: 1;
  padding: 4px 10px; border-radius: 6px; color: var(--de-topbar-text);
}
.nav-menu summary::-webkit-details-marker { display: none; }
.nav-menu summary:hover, .nav-menu[open] summary { background: var(--de-bg); }
.nav-menu-dropdown {
  position: absolute; right: 0; top: calc(100% + 6px);
  background: white; border: 1px solid var(--de-border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  min-width: 160px; padding: 6px; z-index: 20;
}
.nav-menu-dropdown a { display: block; padding: 8px 10px; border-radius: 6px; font-size: 0.9rem; color: var(--de-text); text-decoration: none; opacity: 1; }
.nav-menu-dropdown a:hover { background: var(--de-bg); }
/* Separates "Settings" (account/notification prefs) from the working
   pages above it — different kind of destination, not another dashboard
   subpage. */
.nav-menu-divider { border: none; border-top: 1px solid var(--de-border); margin: 6px 4px; }

/* Hover-to-reveal sign out — deliberately a hover reveal, not a click
   dropdown, per spec: keep the username always visible, sign out shows
   on hover. Note this means it's mouse-only; touch devices would need a
   tap-equivalent (:focus via tabindex) if that becomes a real problem,
   not addressed here since the settings section is desktop admin use. */
.user-hover { position: relative; padding: 4px 0; }
.user-hover-name { font-size: 0.9rem; color: var(--de-topbar-text); opacity: 0.85; cursor: default; }
.user-hover-signout {
  display: none; position: absolute; right: 0; top: 100%;
  background: white; border: 1px solid var(--de-border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); padding: 6px; min-width: 120px; z-index: 20;
}
.user-hover:hover .user-hover-signout { display: block; }
.user-hover-signout a { display: block; padding: 8px 10px; border-radius: 6px; font-size: 0.88rem; color: var(--de-text); text-decoration: none; opacity: 1; }
.user-hover-signout a:hover { background: var(--de-bg); }
.topbar a:hover { opacity: 1; text-decoration: underline; }

.container {
  max-width: 880px;
  margin: 0 auto;
  padding: 40px 24px 80px;
}

.container.wide { max-width: 1200px; }

/* Left panel shown on every page once signed in (base.html), alongside the
   hamburger menu rather than replacing it — the hamburger stays the quick
   jump-anywhere menu, this is a persistent map of the app plus the newer
   Help/Changelog reference pages. CSS Grid rather than flex so the content
   column can center itself (via .container's own margin:0 auto) within
   whatever width is left over — a flex `flex: 1` item can't do that without
   fighting auto-margin/flex-grow interactions. No max-width/centering on
   .page-body itself: it spans the full viewport so wide tables get all the
   room a large monitor can give them, instead of being capped alongside
   the nav column the way an earlier version of this did. */
.page-body.has-side-nav {
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr);
  align-items: start;
}
body.nav-collapsed .page-body.has-side-nav { grid-template-columns: 40px minmax(0, 1fr); }

.page-body.has-side-nav > .container,
.page-body.has-side-nav > .container.wide,
.page-body.has-side-nav > .container.wide-table {
  /* NOT margin:0 auto — a grid item with auto inline margins sizes itself
     to its CONTENT's preferred width (shrink-to-fit) rather than filling
     the track, which let the vendors table's min-width push .container
     wider than the track and overlap/overflow. Plain margin:0 keeps the
     default grid "stretch" behavior instead: fills the track, still
     capped by each variant's own max-width above, left-aligned right
     after the nav rather than centered in the leftover space. */
  margin: 0;
  min-width: 0; /* lets the table scroll inside its own .table-scroll instead of forcing this wider than the track */
}

.side-nav {
  position: sticky;
  top: 0;
  align-self: stretch;
  /* Top padding matches .container's own 40px so "Navigate"/the page's
     h1 line up — previously 32px here read as visibly offset. Left
     padding matches the topbar's own 32px inset so the nav lines up
     under the logo instead of sitting further right than it. */
  padding: 40px 10px 40px 32px;
  display: flex;
  flex-direction: column;
  gap: 24px;
  min-width: 0;
}
body.nav-collapsed .side-nav { padding-left: 8px; padding-right: 8px; }

.side-nav-toggle {
  /* Absolutely positioned (not a normal flex child) so it never pushes
     the "Navigate" heading below the page's h1 — .side-nav's own
     position:sticky already establishes the containing block this needs.
     Sits in the quiet gap between the topbar and "Navigate" rather than
     beside "Navigate" itself (an earlier version overlapped the two) —
     right:9px keeps it roughly centered in both the 190px expanded and
     40px collapsed nav widths, so no separate collapsed-state override
     is needed here. */
  position: absolute;
  top: 10px;
  right: 9px;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--de-border);
  border-radius: 6px;
  background: none;
  color: var(--de-muted);
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.side-nav-toggle:hover { background: white; color: var(--de-text); }

.side-nav-heading {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--de-muted);
  padding: 0 10px;
  margin-bottom: 6px;
}
.side-nav-section { display: flex; flex-direction: column; gap: 2px; }
body.nav-collapsed .side-nav-section { display: none; }
.side-nav-link {
  display: block;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 0.92rem;
  color: var(--de-text);
  text-decoration: none;
  white-space: nowrap;
}
.side-nav-link:hover { background: white; }
.side-nav-link.active { background: white; color: var(--de-blue); font-weight: 600; box-shadow: 0 1px 3px rgba(15, 37, 64, 0.1); }

/* Desktop-admin surface, same posture as the rest of this app's nav (see
   .user-hover's own note) — collapses to a top bar rather than a squeezed
   column on narrow viewports instead of attempting a full mobile layout.
   The collapse toggle only makes sense for the left-column layout, so it's
   hidden here and the row is always shown expanded regardless of the
   nav-collapsed state carried over from a wider session. */
@media (max-width: 860px) {
  .page-body.has-side-nav,
  body.nav-collapsed .page-body.has-side-nav { display: block; }
  .side-nav {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 4px 8px;
    padding: 16px 24px;
    border-bottom: 1px solid var(--de-border);
  }
  .side-nav-toggle { display: none; }
  .side-nav-section,
  body.nav-collapsed .side-nav-section { display: flex; flex-direction: row; flex-wrap: wrap; gap: 4px; }
  .side-nav-heading { display: none; }
}

h1 { font-size: 1.7rem; margin-bottom: 6px; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1rem; color: var(--de-navy); margin: 22px 0 10px; }
.subtitle { color: var(--de-muted); margin-top: 0; margin-bottom: 32px; }

.card {
  background: white;
  border: 1px solid var(--de-border);
  border-radius: 10px;
  padding: 28px 32px;
  margin-bottom: 24px;
}

.option-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
  margin-top: 24px;
}

.option-card {
  display: block;
  background: white;
  border: 1px solid var(--de-border);
  border-radius: 10px;
  padding: 24px;
  text-decoration: none;
  color: var(--de-text);
  transition: box-shadow 0.15s, border-color 0.15s;
}

.option-card:hover { box-shadow: 0 4px 14px rgba(15, 37, 64, 0.1); border-color: var(--de-blue); }
.option-card .icon { font-size: 1.6rem; }
.option-card h3 { margin: 10px 0 6px; font-size: 1.05rem; }
.option-card p { margin: 0; color: var(--de-muted); font-size: 0.9rem; }

fieldset { border: none; padding: 0; margin: 0 0 22px; }
legend { font-weight: 600; margin-bottom: 10px; padding: 0; font-size: 1rem; color: var(--de-navy); }

hr.section-divider { border: none; border-top: 1px solid var(--de-border); margin: 0 0 22px; }

.field { margin-bottom: 18px; }
.field label { display: block; font-weight: 500; margin-bottom: 6px; font-size: 0.92rem; }
.field .hint { color: var(--de-muted); font-size: 0.82rem; margin-top: 4px; }

.required-mark { color: var(--de-danger); margin-left: 3px; font-weight: 700; }
.checkbox-field .required-mark { margin-left: 5px; }

input[type=text], input[type=email], input[type=tel], input[type=password],
input[type=date], input[type=number], select, textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--de-border);
  border-radius: 6px;
  font-size: 0.95rem;
  font-family: inherit;
  background: white;
}

textarea { min-height: 90px; resize: vertical; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--de-blue); outline-offset: 1px; }

input[type=file] {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--de-border);
  border-radius: 6px;
  font-size: 0.95rem;
  font-family: inherit;
  background: white;
  color: var(--de-muted);
}
input[type=file]::file-selector-button {
  padding: 11px 22px;
  margin: -9px 16px -9px -11px;
  border: none;
  border-radius: 6px 0 0 6px;
  background: var(--de-blue);
  color: white;
  font-weight: 600;
  font-size: 0.95rem;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s;
}
input[type=file]::file-selector-button:hover { background: var(--de-navy); }

.steps-list { margin: 0 0 18px; padding-left: 22px; color: var(--de-text); font-size: 0.92rem; }
.steps-list li { margin-bottom: 10px; }
.steps-list li:last-child { margin-bottom: 0; }

.checkbox-field { display: flex; align-items: flex-start; gap: 10px; }
.checkbox-field input { width: auto; margin-top: 3px; }
.checkbox-field label { font-weight: 400; }

.radio-group .radio-option { display: flex; align-items: flex-start; gap: 10px; margin-top: 8px; }
.radio-group .radio-option input { width: auto; margin-top: 3px; }
.radio-group .radio-option label { font-weight: 400; }
.option-desc { font-size: 0.82rem; color: var(--de-muted); }

.checkbox-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px 16px; }
.checkbox-grid label { font-weight: 400; display: flex; align-items: center; gap: 8px; }
.checkbox-grid input { width: auto; }
/* One column instead of the auto-fit multi-column layout above — used on
   the New Invite form's Form(s) field, where a couple of long option
   labels ("Vendor / Supplier Registration") read better stacked than
   wrapping awkwardly in a narrow grid cell. */
.checkbox-grid.stacked { grid-template-columns: 1fr; }

/* Radio options rendered as full clickable cards — the whole card is the
   click target, not just the small circle, and the selected one is
   visually distinct rather than relying only on the tiny filled dot. */
.radio-card {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  border: 1px solid var(--de-border);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 10px;
  cursor: pointer;
  background: white;
  transition: border-color 0.15s, background 0.15s;
}
.radio-card:hover { border-color: var(--de-blue); }
.radio-card input[type=radio] { width: auto; margin-top: 3px; flex-shrink: 0; accent-color: var(--de-blue); }
.radio-card-body { display: flex; flex-direction: column; gap: 3px; }
.radio-card-title { font-weight: 600; color: var(--de-navy); }
.radio-card-desc { color: var(--de-muted); font-size: 0.88rem; }
.radio-card.selected { border-color: var(--de-blue); background: #fdf1e6; }

/* Content specific to whichever card is currently selected (the Sign and
   View controls, or the Download + attach controls) — rendered as a
   sibling right after its card with a left accent border, so it reads as
   "belongs to" that option without nesting interactive content inside
   the card's own <label> (which would fight the label's own click
   handling). */
.radio-card-nested {
  margin: -2px 0 14px 20px;
  padding: 18px 20px;
  border-left: 3px solid var(--de-blue);
  border-radius: 0 8px 8px 0;
  background: var(--de-bg);
}

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
  padding: 26px 20px;
  border: 2px dashed var(--de-border);
  border-radius: 10px;
  cursor: pointer;
  background: white;
  transition: border-color 0.15s, background 0.15s;
}
.dropzone:hover, .dropzone.dragover { border-color: var(--de-blue); background: #fff8f2; }
.dropzone-icon { color: var(--de-muted); }
.dropzone-title { font-weight: 600; color: var(--de-navy); }
.dropzone-hint { color: var(--de-muted); font-size: 0.85rem; }

.errors { color: var(--de-danger); font-size: 0.82rem; margin-top: 4px; }

.field-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.btn-link {
  background: none;
  border: none;
  color: var(--de-blue);
  font-size: 0.82rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
}
.btn-link:hover { color: var(--de-navy); }

/* Compact circular icon button that expands into a pill revealing its
   label on hover/focus — collapsed by default so a row of these doesn't
   compete with the page's primary actions, but still fully labeled for
   anyone who isn't hovering (aria-label) or can't (keyboard nav via
   :focus-visible triggers the same expansion). max-width (not width) is
   what's animated: CSS can't transition to/from an intrinsic size like
   auto/max-content, so this transitions toward a fixed value comfortably
   wider than any of our current labels — the pill just stops growing
   once its content fits, so it still looks correct even though the
   endpoint isn't the exact content width. */
.btn-download {
  display: inline-flex;
  align-items: center;
  height: 46px;
  max-width: 46px;
  padding: 0;
  border: none;
  border-radius: 23px;
  background: var(--de-blue);
  color: white;
  overflow: hidden;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: max-width 0.3s ease, background 0.15s ease;
  vertical-align: middle;
}
.btn-download:hover, .btn-download:focus-visible {
  max-width: 320px;
  background: var(--de-navy);
}
.btn-download-icon {
  flex: 0 0 46px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.btn-download-label {
  padding-right: 20px;
  font-weight: 600;
  font-size: 0.92rem;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.btn-download:hover .btn-download-label, .btn-download:focus-visible .btn-download-label { opacity: 1; transition-delay: 0.08s; }

.btn {
  display: inline-block;
  background: var(--de-blue);
  color: white;
  border: none;
  padding: 11px 22px;
  border-radius: 6px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}
.btn:hover { background: var(--de-navy); }
.btn.secondary { background: transparent; color: var(--de-blue); border: 1px solid var(--de-blue); }
.btn.secondary.active { background: var(--de-blue); color: white; }
.btn.small { padding: 6px 14px; font-size: 0.82rem; }
/* Non-interactive placeholder (a <span>, not a real disabled <button> —
   used where the "why" needs a hover tooltip, e.g. an NDA's own copy once
   Doc Control is the real source of truth). */
.btn.disabled { opacity: 0.5; cursor: default; }
.btn.disabled:hover { background: transparent; }

/* Generic form-submit loading state — see base.html's shared submit
   handler. A plain full-page POST here can take a couple of seconds
   (file upload + hashing, PDF generation, or a synchronous notification
   send on the public forms — see notify/service.py) with otherwise zero
   visual feedback, easy to mistake for a dead click / failed submission.
   color:transparent (not opacity/visibility) keeps the button's own
   width from jumping in either direction — the label text still occupies
   its normal layout space, just invisible, while the spinner overlays it. */
@keyframes btn-spin { to { transform: rotate(360deg); } }
.btn.btn-loading {
  color: transparent;
  pointer-events: none;
  position: relative;
}
.btn.btn-loading::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 15px; height: 15px;
  margin: -8px 0 0 -8px;
  border: 2px solid rgba(255, 255, 255, 0.45);
  border-top-color: white;
  border-radius: 50%;
  animation: btn-spin 0.6s linear infinite;
}
.btn.secondary.btn-loading::after { border-color: rgba(245, 130, 31, 0.3); border-top-color: var(--de-blue); }
.btn.small.btn-loading::after { width: 12px; height: 12px; margin: -6px 0 0 -6px; }

.flash { padding: 10px 14px; border-radius: 6px; margin-bottom: 18px; font-size: 0.9rem; word-break: break-all; }
.flash.error { background: #fbe9e7; color: var(--de-danger); }
.flash.success { background: #e7f5ea; color: var(--de-success); }

.badge.invited { background: #e8f7ee; color: #1a7f4e; }
.badge.public { background: #f1f2f4; color: #5c6270; }
.badge.revoked { background: #f0f0f0; color: var(--de-muted); }

table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--de-border); vertical-align: top; }
th { color: var(--de-muted); font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; }
tr:hover td { background: #fafcfe; }

.badge { display: inline-block; padding: 2px 8px; border-radius: 20px; font-size: 0.75rem; font-weight: 600; }
/* Vendor status colors — exact hex from design/vendor-registrations-redesign.html */
.badge.new { background: #eef0f3; color: #5c6270; }
.badge.sensitive { background: #fbe9e7; color: var(--de-danger); }
.badge.under_review { background: #e7f0fd; color: #1d5fb8; }
.badge.approved { background: #e8f7ee; color: #1a7f4e; }
.badge.conditionally_approved { background: #fdf3d9; color: #92650a; }
.badge.rejected { background: #fdeceb; color: #b3261e; }

/* NDA list's "Signatures" column group (list_ndas.html/view_nda.html) — ties
   "Vendor signed" and "DE signature" together as one visual unit instead of
   scattering signer state/actions across the row. Tinted with --de-teal
   (the app's third accent, otherwise unused in tables) rather than an
   unrelated new hue, so it stays within the existing 3-accent palette. */
.table-card thead tr.group-row th { padding: 8px 10px 0; border-bottom: none; background: transparent; }
.table-card thead tr.group-row th.sig-group { background: rgba(18, 135, 154, 0.07); color: var(--de-teal); }
.table-card thead tr:not(.group-row) th.sig-col { background: rgba(18, 135, 154, 0.07); }
.table-card tbody td.sig-col { background: rgba(18, 135, 154, 0.035); border-left: 1px solid rgba(18, 135, 154, 0.15); }
.table-card tbody td.sig-col:last-of-type { border-right: 1px solid rgba(18, 135, 154, 0.15); }
.table-card tbody tr:hover td.sig-col { background: rgba(18, 135, 154, 0.06); }

.sig-cell { min-width: 130px; white-space: normal; }
.sig-name { font-weight: 600; font-size: 0.85rem; margin-bottom: 2px; }
.sig-sub { color: var(--de-muted); font-size: 0.8rem; }
.stack { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }

/* Amber = "in progress, nothing to do yet" — reuses the same hex already
   used for .badge.conditionally_approved so "pending" reads consistently
   across the app. Status here is pulled on demand via "Check status" —
   see list_ndas.html's comment — never auto-advances on its own, so this
   is deliberately a static label, not a spinner implying an active wait. */
.sig-pending { color: #92650a; font-weight: 600; font-size: 0.85rem; }
.sig-pending-sub { color: var(--de-muted); font-size: 0.78rem; margin-top: 2px; }

/* Terminal state — doc-control-app's document reached Approved/Effective/
   Obsolete, nothing left to check. Labeled "Doc Control: {status}", not
   "Signed" — see _nda_sig_cell.html's docstring for why that distinction
   is deliberate, not an oversight. */
.sig-done { display: flex; align-items: flex-start; gap: 6px; color: var(--de-success); font-weight: 600; font-size: 0.85rem; }
.sig-done-sub { display: block; color: var(--de-muted); font-weight: 400; font-size: 0.78rem; margin-top: 2px; }

/* Brief highlight on a "Check status" cell after it updates in place, so
   the flash is visible without a page-level banner telling you what
   changed or where — fades back into the Signatures group's own teal
   tint (not plain white) so it settles into the right resting state
   whichever sig-cell state it lands on. */
@keyframes flash-cell { 0% { background: #fdf3d9; } 100% { background: rgba(18, 135, 154, 0.035); } }
td.just-updated, div.just-updated { animation: flash-cell 1.1s ease-out; }

.btn-link.muted { color: var(--de-muted); }
.btn-link.muted:hover { color: var(--de-text); }

/* Vendor review dialog (settings/list_vendors.html) — the only <dialog>
   in the app; there's no existing modal convention to match, so this is
   styled fresh but sized/spaced consistently with .card. */
dialog.review-modal {
  position: relative;
  border: none;
  border-radius: 10px;
  padding: 0;
  max-width: 640px;
  width: 92vw;
  max-height: 88vh;
  overflow: hidden;
}
dialog.review-modal::backdrop { background: rgba(20, 22, 26, 0.55); }
dialog.review-modal h2 { margin-top: 0; padding-right: 28px; }
.dialog-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 8px; }

/* Scrolling lives on this inner wrapper, not the <dialog> itself, so
   .modal-close (positioned relative to the dialog) stays pinned in the
   corner instead of scrolling away with the content. */
.review-modal-body { padding: 28px 32px; max-height: 88vh; overflow-y: auto; }

.modal-close {
  position: absolute; top: 16px; right: 16px; z-index: 1;
  width: 30px; height: 30px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: 6px;
  font-size: 1.4rem; line-height: 1; color: var(--de-muted); cursor: pointer;
}
.modal-close:hover { background: #eef0f3; color: var(--de-text); }
.modal-close:focus-visible { outline: 2px solid var(--de-blue); outline-offset: 1px; }

.rating-grid { margin: 10px 0 22px; }
.rating-grid th, .rating-grid td { text-align: center; }
.rating-grid th:first-child, .rating-grid td:first-child { text-align: left; }
.rating-grid input[type=radio] { width: auto; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; margin: 20px 0 32px; }
.stat-card { background: white; border: 1px solid var(--de-border); border-radius: 10px; padding: 20px; }
.stat-card .num { font-size: 1.8rem; font-weight: 700; color: var(--de-navy); }
.stat-card .label { color: var(--de-muted); font-size: 0.85rem; }

.toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 16px; flex-wrap: wrap; }

.notice {
  background: #fff8e1;
  border: 1px solid #f0d78c;
  border-radius: 8px;
  padding: 14px 18px;
  font-size: 0.85rem;
  color: #6b5300;
  margin-bottom: 24px;
}

.detail-row { display: grid; grid-template-columns: 220px 1fr; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--de-border); }
.detail-row:last-child { border-bottom: none; }
.detail-label { font-weight: 600; color: var(--de-muted); font-size: 0.85rem; }
.detail-value { word-break: break-word; white-space: pre-wrap; }

.copy-btn { background: none; border: 1px solid var(--de-border); border-radius: 6px; padding: 3px 8px; cursor: pointer; font-size: 0.85rem; }
.copy-btn:hover { border-color: var(--de-blue); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---- Vendor registrations page (settings/list_vendors.html) ----
   Matched to design/vendor-registrations-redesign.html. The mockup's own
   --orange/--orange-dark tokens are deliberately NOT reused here — every
   other primary action in the app already uses .btn (var(--de-blue)), so
   this page's Start Review/Re-evaluate buttons stay on that same system
   rather than introducing a second, slightly different orange just for
   this page. Structural colors with no existing equivalent (the filter
   track, sticky header background, faint table-rule color) are matched
   to the mockup's exact hex. */
/* Wider than the standard .container.wide (1200px) — used by every
   dashboard list page (vendors, engagements, ndas, invites, reports),
   which are basically all table, and a wide multi-column table has real
   content to fill on a big monitor. Still just a max-width cap, not a
   fixed width, so .table-scroll's overflow-x:auto keeps working exactly
   the same on narrow viewports: the table shrinks the container down
   with the page, then scrolls once it hits its own 1080px min-width
   floor. Source order matters here — this rule must come after
   .container.wide (same specificity, 0,0,2,0) to win the cascade. */
.container.wide-table { max-width: 1600px; }

.page-head { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: 20px; gap: 16px; flex-wrap: wrap; }
.page-head h1 { margin: 0; }
.page-head .count { color: var(--de-muted); font-size: 0.82rem; margin-top: 4px; }

.filter-bar {
  display: flex; align-items: center; justify-content: space-between;
  background: white; border: 1px solid var(--de-border); border-radius: 12px;
  padding: 12px 14px; margin-bottom: 18px; gap: 12px; flex-wrap: wrap;
}
.filter-left { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.filter-right { display: flex; align-items: center; gap: 14px; }

.search-box {
  display: flex; align-items: center; gap: 7px; border: 1.5px solid var(--de-border); border-radius: 8px;
  padding: 8px 12px; min-width: 220px; color: var(--de-muted); margin: 0;
}
.search-box input[type=text] { border: none; outline: none; font-size: 0.85rem; width: 100%; color: var(--de-text); background: transparent; padding: 0; }
.search-box svg { flex-shrink: 0; }
.search-box:focus-within { border-color: var(--de-blue); }

.seg-group { display: flex; gap: 6px; padding: 2px; background: #eef0f3; border-radius: 9px; }
.seg-btn {
  font-size: 0.85rem; font-weight: 600; padding: 7px 12px; border-radius: 7px; border: none;
  background: transparent; color: var(--de-muted); cursor: pointer; text-decoration: none; display: inline-block;
  transition: background 0.12s ease, color 0.12s ease;
}
.seg-btn.active { background: white; color: var(--de-blue); box-shadow: 0 1px 2px rgba(20, 20, 30, 0.08); }
.seg-btn:hover:not(.active) { color: var(--de-text); }
.seg-btn:focus-visible { outline: 2px solid var(--de-blue); outline-offset: 1px; }

.select-wrap { position: relative; }
.select-btn {
  display: flex; align-items: center; gap: 8px; font-size: 0.85rem; font-weight: 600; color: var(--de-text);
  border: 1.5px solid var(--de-border); background: white; border-radius: 8px; padding: 8px 12px; cursor: pointer;
  min-width: 170px; justify-content: space-between;
}
.select-btn:hover { border-color: #c9cdd6; }
.select-btn.open, .select-btn[aria-expanded="true"] { border-color: var(--de-blue); }
.select-btn:focus-visible { outline: 2px solid var(--de-blue); outline-offset: 1px; }
.select-panel {
  display: none; position: absolute; top: calc(100% + 6px); left: 0; background: white;
  border: 1px solid var(--de-border); border-radius: 10px; box-shadow: 0 8px 24px rgba(20, 20, 30, 0.12);
  min-width: 210px; z-index: 50; padding: 6px;
}
.select-panel.show { display: block; }
.select-opt {
  padding: 8px 10px; border-radius: 7px; font-size: 0.85rem; cursor: pointer; color: var(--de-text);
}
.select-opt:hover, .select-opt.focused { background: #fdecd9; }
.select-opt.selected { color: var(--de-blue); font-weight: 700; }

.clear-link { font-size: 0.82rem; font-weight: 600; color: var(--de-muted); text-decoration: underline; }
.clear-link:hover { color: var(--de-text); }

.table-card { background: white; border: 1px solid var(--de-border); border-radius: 12px; overflow: hidden; margin-bottom: 24px; }
.table-scroll { overflow-x: auto; }
.table-scroll table { width: 100%; min-width: 1080px; border-collapse: collapse; font-size: 0.85rem; }
.table-card thead th {
  position: sticky; top: 0; background: #fbfbfc; z-index: 5;
  text-align: left; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em; color: #9298a5;
  text-transform: uppercase; padding: 12px 16px; border-bottom: 1px solid var(--de-border); white-space: nowrap;
}
.table-card tbody td { padding: 14px 16px; border-bottom: 1px solid #eef0f3; vertical-align: middle; white-space: nowrap; }
.table-card tbody tr:last-child td { border-bottom: none; }
.table-card tbody tr:hover td { background: #fafafb; }
.date-cell { color: var(--de-muted); }
.company-cell { font-weight: 700; }
.contact-name { font-weight: 600; }
.contact-email { color: var(--de-muted); font-size: 0.78rem; }
.muted { color: var(--de-muted); }

/* The company/employer name in a list-page row, linking to the same
   detail page as the row's "View" action — color:inherit + no underline
   so it reads as plain table text at rest (matching .company-cell's/
   .contact-name's own weight, which it inherits) and only reveals itself
   as a link on hover, rather than looking like a normal blue link
   sitting inside a dense data table. */
.row-link { color: inherit; text-decoration: none; }
.row-link:hover { text-decoration: underline; }

.attach-link { display: inline-flex; align-items: center; gap: 6px; color: var(--de-blue); font-weight: 600; text-decoration: none; font-size: 0.82rem; }
.attach-link:hover { color: var(--de-navy); }
.attach-link svg { flex-shrink: 0; }
/* Once an NDA is pushed to Doc Control, its file lives there — leaving
   this copy downloadable too would give the document two sources of
   truth. Grayed out (not hidden) so it's clear the attachment still
   exists, just not the copy to hand out anymore; cursor:default + no
   href communicates non-interactive without JS. */
.attach-link.disabled { color: var(--de-muted); cursor: default; }
.no-attach { color: #9298a5; font-size: 0.82rem; }

.row-actions { display: flex; align-items: center; gap: 14px; justify-content: flex-end; white-space: nowrap; }
/* NDA list's Actions column — "View Details" + "View Document" (Doc
   Control) read better stacked than side by side. */
.row-actions.stacked { flex-direction: column; align-items: flex-end; gap: 4px; }
.view-link { font-size: 0.78rem; font-weight: 700; color: var(--de-muted); text-decoration: none; }
.view-link:hover { color: var(--de-text); text-decoration: underline; }

.table-footer { padding: 12px 18px; border-top: 1px solid #eef0f3; font-size: 0.78rem; color: var(--de-muted); }

/* ---------------------------------------------------- Changelog page --- */
.changelog-list { list-style: none; margin: 0; padding: 0; }
.changelog-entry {
  background: white; border: 1px solid var(--de-border); border-radius: 10px;
  padding: 20px 24px; margin-bottom: 16px;
}
.changelog-entry-header { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.changelog-version { font-weight: 700; color: var(--de-blue); font-size: 0.95rem; }
.changelog-date { color: var(--de-muted); font-size: 0.82rem; }
.changelog-title { font-weight: 600; }
.changelog-changes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.changelog-change { display: flex; align-items: baseline; gap: 10px; font-size: 0.9rem; }
.changelog-change-badge {
  flex-shrink: 0; padding: 2px 9px; border-radius: 20px; font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em;
}
.changelog-change-added { background: #e4f4e8; color: var(--de-success); }
.changelog-change-changed { background: #fdecd9; color: var(--de-blue); }
.changelog-change-fixed { background: #fdeceb; color: var(--de-danger); }

/* -------------------------------------------------------- Help page --- */
.help-page-layout { display: flex; align-items: flex-start; gap: 32px; }
.help-toc {
  flex: 0 0 220px; position: sticky; top: 24px;
  background: white; border: 1px solid var(--de-border); border-radius: 10px; padding: 14px;
  max-height: calc(100vh - 48px); overflow-y: auto;
}
.help-toc-search {
  width: 100%; padding: 8px 10px; border: 1px solid var(--de-border); border-radius: 6px;
  font-size: 0.85rem; margin-bottom: 10px;
}
.help-toc-list { list-style: none; margin: 0; padding: 0; }
.help-toc-item button {
  display: block; width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  padding: 6px 8px; border-radius: 6px; font-size: 0.85rem; color: var(--de-text); font-family: inherit;
}
.help-toc-item button:hover { background: var(--de-bg); }
.help-toc-level-3 button { padding-left: 20px; font-size: 0.8rem; color: var(--de-muted); }
.help-toc-empty { padding: 6px 8px; font-size: 0.82rem; color: var(--de-muted); }
.help-content { flex: 1; min-width: 0; }
.help-content section { margin-bottom: 32px; }
.help-content h2 { scroll-margin-top: 20px; }
.help-content h3 { scroll-margin-top: 20px; }
.help-content ul { padding-left: 22px; }
.help-content li { margin-bottom: 6px; }
@media (max-width: 860px) {
  .help-page-layout { display: block; }
  .help-toc { position: static; max-height: none; margin-bottom: 20px; }
}

/* Non-production environment indicator (APP_ENVIRONMENT=test|dev, see base.html).
   Purple/blue on purpose: neither resembles the brand orange, so it can't be read as
   part of the normal design. Banner is in normal flow (not sticky) so it can't
   collide with the sticky side-nav; the corner badge stays visible while scrolling
   and ignores clicks so it never blocks a control. */
.env-banner {
  background: var(--env-color);
  color: #fff;
  text-align: center;
  padding: 8px 16px;
  font-size: 0.9rem;
  line-height: 1.35;
}
.env-banner strong { letter-spacing: 0.06em; margin-right: 4px; }
.env-badge {
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 50;
  background: var(--env-color);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 4px 10px;
  border-radius: 999px;
  opacity: 0.9;
  pointer-events: none;
}
body.env-test { --env-color: #6d28d9; }
body.env-dev { --env-color: #1d4ed8; }
@media print { .env-badge { display: none; } }
