/* ---------- Vorwerk web fonts ---------- */
@font-face {
  font-family: "Vorwerk";
  src: url("/static/fonts/Vorwerk-Light.woff2") format("woff2"),
    url("/static/fonts/Vorwerk-Light.woff") format("woff");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Vorwerk";
  src: url("/static/fonts/Vorwerk-Regular.woff2") format("woff2"),
    url("/static/fonts/Vorwerk-Regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Vorwerk";
  src: url("/static/fonts/Vorwerk-Medium.woff2") format("woff2"),
    url("/static/fonts/Vorwerk-Medium.woff") format("woff");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Vorwerk";
  src: url("/static/fonts/Vorwerk-Bold.woff2") format("woff2"),
    url("/static/fonts/Vorwerk-Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- Brand tokens + Bootstrap variable overrides ---------- */
:root {
  --vw-green: #00AC46;
  --vw-green-hover: #009B3F;
  --vw-green-active: #008A37;
  --vw-anthracite: #23282A;
  --vw-orange: #F5A01E;
  --vw-red: #F0415F;
  --vw-purple: #734BA5;
  --vw-blue: #3782CD;

  /* "Ink" variants of brand colours — darker shades used as TEXT on the
     tinted badge backgrounds. White / mid-brand on a ~12% tinted bg failed
     AA badly (1.9–2.6:1); these shades clear 5.7–8.4:1 against the
     compositied surface. In dark theme they map back to the bright brand
     tone, which already had enough contrast on the dark composite. */
  --vw-green-ink: #006B2B;
  --vw-orange-ink: #8A5300;
  --vw-blue-ink: #1E5C9E;
  --vw-red-ink: #A8253D;
  --vw-purple-ink: #4F2E80;

  --bg: #F7F8F9;
  --surface: #FFFFFF;
  --surface-2: #ECEEF0;
  --border: #DDE1E4;
  --text: #23282A;
  /* AA-compliant against --bg (#F7F8F9) — #5F6469 is ~5.0:1. The previous
     #7A8085 was 3.85:1, below the 4.5:1 floor for body text. Dark-theme
     muted (#9DA3A8) stays where it is; it already clears AA on dark bg. */
  --text-muted: #5F6469;
  --text-secondary: #3D4347;

  --shadow: 0 1px 2px rgba(35, 40, 42, 0.04), 0 4px 12px rgba(35, 40, 42, 0.06);

  /* Override Bootstrap CSS variables so components inherit Vorwerk palette */
  --bs-primary: var(--vw-green);
  --bs-primary-rgb: 0, 172, 70;
  --bs-secondary: var(--vw-anthracite);
  --bs-success: var(--vw-green);
  --bs-warning: var(--vw-orange);
  --bs-danger: var(--vw-red);
  --bs-info: var(--vw-blue);
  --bs-body-bg: var(--bg);
  --bs-body-color: var(--text);
  --bs-body-font-family: "Vorwerk", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --bs-border-color: var(--border);
}

[data-theme="dark"] {
  --vw-green: #1FC25E;
  --vw-green-hover: #1FB055;
  --vw-green-active: #1A9D4A;
  /* Dark-theme inks map back to the bright brand shades — those already
     have enough contrast against the darker tinted-bg composites
     (translucent fills on a dark surface). Keeping one rule per token
     means selectors below stay symmetrical. */
  --vw-green-ink: var(--vw-green);
  --vw-orange-ink: var(--vw-orange);
  --vw-blue-ink: var(--vw-blue);
  --vw-red-ink: var(--vw-red);
  --vw-purple-ink: var(--vw-purple);
  --bg: #15191B;
  --surface: #1E2326;
  --surface-2: #262C30;
  --border: #3A4045;
  --text: #ECEEF0;
  --text-muted: #9DA3A8;
  --text-secondary: #C7CCD0;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.35);

  --bs-primary: var(--vw-green);
  --bs-primary-rgb: 31, 194, 94;
  --bs-body-bg: var(--bg);
  --bs-body-color: var(--text);
  --bs-border-color: var(--border);
  --bs-emphasis-color: var(--text);
  --bs-secondary-color: var(--text-muted);
}

/* ---------- Base ---------- */
body {
  font-family: var(--bs-body-font-family);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main {
  flex: 1 0 auto;
}

a {
  color: inherit;
  text-decoration: none;
}

/* Even line lengths on headings. Cheap "considered" detail. */
h1, h2, h3, .card-title {
  text-wrap: balance;
}

/* ---------- Buttons: force Vorwerk green ---------- */
/* Text colour is anthracite, NOT white. White on Vorwerk green is 3.0:1,
   which fails AA for normal body text. Anthracite on Vorwerk green clears
   5.0:1, and it works on both the light-theme #00AC46 and the dark-theme
   #1FC25E. Hover/active use tokens so dark theme can override them. */
.btn-primary {
  --bs-btn-bg: var(--vw-green);
  --bs-btn-border-color: var(--vw-green);
  --bs-btn-hover-bg: var(--vw-green-hover);
  --bs-btn-hover-border-color: var(--vw-green-hover);
  --bs-btn-active-bg: var(--vw-green-active);
  --bs-btn-active-border-color: var(--vw-green-active);
  --bs-btn-disabled-bg: var(--vw-green);
  --bs-btn-disabled-border-color: var(--vw-green);
  --bs-btn-color: var(--vw-anthracite);
  --bs-btn-hover-color: var(--vw-anthracite);
  --bs-btn-active-color: var(--vw-anthracite);
  --bs-btn-disabled-color: var(--vw-anthracite);
}

.btn-primary:focus-visible,
.btn-primary:focus {
  box-shadow: 0 0 0 0.25rem rgba(0, 172, 70, 0.35);
}

/* ---------- Topbar ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 32px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
}

.topbar .brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.topbar .brand .logo {
  height: 28px;
}

.topbar .brand .title {
  font-weight: 500;
  font-size: 18px;
  letter-spacing: 0.2px;
}

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

/* Logo theme swap. Default-hide the dark/white logo so any moment where
   data-theme is unset (first paint pre-script, or an unexpected stored
   value) doesn't render both logos stacked. The light logo is the safe
   fallback; the dark one is only revealed in explicit dark theme. */
.logo-dark {
  display: none;
}
[data-theme="dark"] .logo-light {
  display: none;
}
[data-theme="dark"] .logo-dark {
  display: revert;
}

/* ---------- Stage pill (EXPERIMENTAL / BETA) ---------- */
/* Anthracite on the brand-orange / brand-blue clears 7:1+. White-on-orange
   was 2.1:1, white-on-blue ~3.2:1 — both AA fails for the 11px text. */
.stage-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: var(--vw-orange);
  color: var(--vw-anthracite);
  border: 1px solid var(--vw-orange);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.stage-pill::before {
  content: "";
  width: 6px;
  height: 6px;
  background: var(--vw-anthracite);
  border-radius: 50%;
  display: inline-block;
}

.stage-beta {
  background: var(--vw-blue);
  border-color: var(--vw-blue);
}

/* ---------- Theme toggle ---------- */
.theme-toggle {
  border-color: var(--border);
  color: var(--text-secondary);
  padding: 4px 10px;
  font-size: 14px;
  line-height: 1;
}

.theme-toggle:hover {
  background: var(--surface-2);
}

[data-theme="light"] .theme-icon-dark,
[data-theme="dark"] .theme-icon-light {
  display: none;
}

/* ---------- User chip ---------- */
.user-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-secondary);
}

.user-chip .avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--vw-green);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 11px;
}

/* ---------- Hero ---------- */
.hero {
  padding: 48px 32px 24px;
  max-width: 1280px;
  margin: 0 auto;
}

.hero h1 {
  font-size: 36px;
  font-weight: 700;
  margin: 0 0 8px;
  letter-spacing: -0.3px;
}

.hero .lede {
  font-size: 16px;
  color: var(--text-secondary);
  max-width: 720px;
  margin: 0;
}

.hero-actions {
  margin-top: 20px;
  display: flex;
  align-items: center;
  gap: 8px 16px;
  flex-wrap: wrap;
}

.hero-actions .btn-link {
  color: var(--text-secondary);
  padding: 0;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  text-decoration: none;
}

.hero-actions .btn-link:hover {
  color: var(--vw-green-ink);
}

/* ---------- Landing: stats strip ---------- */
.landing-stats {
  max-width: 1280px;
  margin: 4px auto 0;
  padding: 4px 32px 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 36px;
  align-items: baseline;
}

.stat {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.stat-value {
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  letter-spacing: -0.3px;
}

.stat-label {
  font-size: 13px;
  color: var(--text-muted);
}

/* `last updated` reads relative-time, not a count — lighter weight so it
   sits with the labels rather than competing with the headline numbers. */
.stat-meta .stat-value {
  font-weight: 500;
  font-size: 14px;
  letter-spacing: 0;
}

/* ---------- Landing: "How it works" ---------- */
.how-it-works {
  padding-top: 8px;
}

.how-it-works .hiw-grid {
  list-style: none;
  padding: 0;
  margin: 0 0 40px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}

.hiw-step {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px 20px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: border-color 160ms ease, transform 160ms ease;
}

.hiw-step:hover {
  border-color: color-mix(in oklab, var(--text-muted) 40%, var(--border));
  transform: translateY(-1px);
}

.hiw-step-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  color: var(--text-muted);
}

.hiw-index {
  font-size: 22px;
  font-weight: 300;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  line-height: 1;
}

.hiw-icon {
  width: 18px;
  height: 18px;
  color: var(--text-muted);
  flex-shrink: 0;
  transition: color 160ms ease;
}

.hiw-step:hover .hiw-icon {
  color: var(--vw-green-ink);
}

.hiw-step h3 {
  font-size: 15px;
  font-weight: 600;
  margin: 0;
  color: var(--text);
  letter-spacing: -0.1px;
}

.hiw-step p {
  font-size: 13px;
  color: var(--text-secondary);
  margin: 0;
  line-height: 1.55;
  text-wrap: pretty;
}

.hiw-classes {
  border-top: 1px solid var(--border);
  padding-top: 24px;
}

.hiw-classes-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.hiw-classes-head h3 {
  font-size: 14px;
  font-weight: 600;
  margin: 0;
  color: var(--text);
  letter-spacing: -0.1px;
}

.hiw-classes-head p {
  font-size: 12.5px;
  color: var(--text-muted);
  margin: 0;
}

.hiw-chips {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

.hiw-chip {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.hiw-chip.is-locked {
  background: transparent;
  border-style: dashed;
}

.hiw-chip-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.hiw-chip-state {
  font-size: 11px;
  color: var(--text-muted);
  font-variant-caps: all-small-caps;
  letter-spacing: 0.3px;
}

.hiw-chip.is-locked .hiw-chip-state {
  color: var(--vw-orange-ink);
}

.hiw-chip p {
  font-size: 12.5px;
  color: var(--text-secondary);
  margin: 0;
  line-height: 1.5;
}

.hiw-chip.is-locked p {
  color: var(--text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .hiw-step,
  .hiw-icon {
    transition: none;
  }
  .hiw-step:hover {
    transform: none;
  }
}

/* ---------- Landing: Featured products (the curated shelf) ---------- */
/* Breaks out of .section's 1280px cage into an edge-to-edge tinted band so
   the block reads as its own architectural shelf, not just another card
   grid. Inner content stays gutter-aligned with the rest of the page. */
.featured-products {
  max-width: none;
  padding-inline: max(32px, calc(50vw - 640px));
  padding-block: 28px 32px;
  margin-block: 8px;
  background: var(--surface-2);
  border-block: 1px solid var(--border);
  border-radius: 0;
}

.featured-products > h2,
.featured-products > .featured-grid {
  max-width: 1216px;
  margin-inline: auto;
}

.featured-products > h2 {
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.featured-heading {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}

.featured-view-all {
  font-size: 13px;
  font-weight: 500;
  color: var(--vw-green-ink);
  text-decoration: none;
  white-space: nowrap;
  transition: color 160ms ease;
}

.featured-view-all:hover,
.featured-view-all:focus-visible {
  color: var(--vw-green);
  text-decoration: underline;
  text-underline-offset: 3px;
  outline: none;
}

/* Cards inside the shelf lift slightly higher on hover than elsewhere,
   selling the "curated" idea without restyling the shared .card. */
.featured-grid .card {
  transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}

.featured-grid .card:hover {
  transform: translateY(-3px);
  box-shadow: 0 1px 2px rgba(35, 40, 42, 0.04), 0 12px 24px -10px rgba(35, 40, 42, 0.16);
}

[data-theme="dark"] .featured-grid .card:hover {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 24px -10px rgba(0, 0, 0, 0.5);
}

@media (prefers-reduced-motion: reduce) {
  .featured-view-all,
  .featured-grid .card {
    transition: none;
  }
  .featured-grid .card:hover {
    transform: none;
  }
}

/* ---------- Landing: browse-by-domain tiles ---------- */
.domain-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}

.domain-tile {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease;
  min-height: 110px;
}

.domain-tile:hover {
  border-color: var(--vw-green);
}

.domain-tile-name {
  font-size: 15px;
  font-weight: 700;
  margin: 0;
  color: var(--text);
  letter-spacing: -0.1px;
}

.domain-tile-desc {
  font-size: 12.5px;
  color: var(--text-secondary);
  margin: 0;
  line-height: 1.45;
}

.domain-tile-count {
  font-size: 11.5px;
  color: var(--text-muted);
  margin-top: auto;
  font-variant-numeric: tabular-nums;
}

/* ---------- Section ---------- */
.section {
  padding: 24px 32px;
  max-width: 1280px;
  margin: 0 auto;
}

.section h2 {
  font-size: 20px;
  font-weight: 500;
  margin: 0 0 16px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

.section h2 .count {
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 400;
}

/* ---------- Catalog grid ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 16px;
}

.card-link {
  color: inherit;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: transform 0.15s ease, border-color 0.15s ease;
  box-shadow: var(--shadow);
  height: 100%;
}

.card:hover {
  transform: translateY(-2px);
  border-color: var(--vw-green);
}

.card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}

.card-title {
  font-size: 17px;
  font-weight: 700;
  margin: 0;
  line-height: 1.3;
  color: var(--text);
}

.card-desc {
  font-size: 13.5px;
  color: var(--text-secondary);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 60px;
}

.badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.3px;
  border: 1px solid transparent;
}

.badge-live {
  background: rgba(0, 172, 70, 0.12);
  color: var(--vw-green-ink);
  border-color: rgba(0, 172, 70, 0.25);
}

.badge-soon {
  background: rgba(245, 160, 30, 0.14);
  color: var(--vw-orange-ink);
  border-color: rgba(245, 160, 30, 0.3);
}

.badge-planned {
  background: rgba(115, 75, 165, 0.14);
  color: var(--vw-purple-ink);
  border-color: rgba(115, 75, 165, 0.3);
}

[data-theme="dark"] .badge-live {
  background: rgba(31, 194, 94, 0.15);
}

[data-theme="dark"] .badge-soon {
  background: rgba(245, 160, 30, 0.18);
}

[data-theme="dark"] .badge-planned {
  background: rgba(155, 115, 205, 0.18);
  color: #B89BE0;
  border-color: rgba(155, 115, 205, 0.35);
}

.badge-stage,
.badge-version,
.badge-server {
  background: var(--surface-2);
  color: var(--text-secondary);
  border-color: var(--border);
  font-family: monospace;
  font-size: 10.5px;
}

.badge-server {
  font-family: inherit;
  font-size: 11px;
}

[data-theme="dark"] .badge-stage,
[data-theme="dark"] .badge-version,
[data-theme="dark"] .badge-server {
  background: rgba(255, 255, 255, 0.08);
  color: #DDE1E4;
  border-color: rgba(255, 255, 255, 0.14);
}

.badge-status-active {
  background: rgba(0, 172, 70, 0.12);
  color: var(--vw-green-ink);
  border-color: rgba(0, 172, 70, 0.25);
}

.badge-status-draft {
  background: rgba(115, 75, 165, 0.12);
  color: var(--vw-purple-ink);
  border-color: rgba(115, 75, 165, 0.25);
}

/* Outlined treatment so the deprecated-contract warning is visually distinct
   from in-flight orange states (pending request, EXPERIMENTAL pill). Same
   semantic colour, different weight. */
.badge-status-deprecated {
  background: transparent;
  color: var(--vw-orange-ink);
  border-color: var(--vw-orange);
}

.badge-status-retired {
  background: rgba(35, 40, 42, 0.07);
  color: var(--text-muted);
  border-color: var(--border);
}

[data-theme="dark"] .badge-status-active {
  background: rgba(31, 194, 94, 0.18);
}

[data-theme="dark"] .badge-status-deprecated {
  background: transparent;
}

[data-theme="dark"] .badge-status-draft {
  background: rgba(155, 115, 205, 0.2);
  color: #B89BE0;
}

[data-theme="dark"] .badge-status-retired {
  background: rgba(255, 255, 255, 0.06);
  color: #9CA0A5;
}

/* Access-request status badges (apps/access). Doubled-up selector
   (.badge.badge-status-*) lifts specificity over Bootstrap's `.badge` color rule
   so these win regardless of stylesheet load order. */
.badge.badge-status-pending {
  background: rgba(245, 160, 30, 0.14);
  color: var(--vw-orange-ink);
  border-color: rgba(245, 160, 30, 0.3);
}

.badge.badge-status-approved,
.badge.badge-status-auto_approved {
  background: rgba(0, 172, 70, 0.12);
  color: var(--vw-green-ink);
  border-color: rgba(0, 172, 70, 0.25);
}

.badge.badge-status-auto_approved {
  font-style: italic;
}

.badge.badge-status-rejected {
  background: rgba(240, 65, 95, 0.12);
  color: var(--vw-red-ink);
  border-color: rgba(240, 65, 95, 0.3);
}

/* cancel_pending shares the orange "in-flight" palette with pending; cancelled
   stays muted like retired contracts. */
.badge.badge-status-cancel_pending {
  background: rgba(245, 160, 30, 0.14);
  color: var(--vw-orange-ink);
  border-color: rgba(245, 160, 30, 0.3);
}

.badge.badge-status-cancelled {
  background: rgba(35, 40, 42, 0.07);
  color: var(--text-muted);
  border-color: var(--border);
}

/* Revoked shares the red palette with Rejected: from the requester's point
   of view they're the same outcome ("no access"), and the badge text already
   distinguishes the workflow history. Anything softer read as ambiguous. */
.badge.badge-status-revoked {
  background: rgba(240, 65, 95, 0.12);
  color: var(--vw-red-ink);
  border-color: rgba(240, 65, 95, 0.3);
}

[data-theme="dark"] .badge.badge-status-cancel_pending {
  background: rgba(245, 160, 30, 0.2);
}

[data-theme="dark"] .badge.badge-status-cancelled {
  background: rgba(255, 255, 255, 0.06);
  color: #9CA0A5;
}

[data-theme="dark"] .badge.badge-status-pending {
  background: rgba(245, 160, 30, 0.2);
}

[data-theme="dark"] .badge.badge-status-approved,
[data-theme="dark"] .badge.badge-status-auto_approved {
  background: rgba(31, 194, 94, 0.18);
}

[data-theme="dark"] .badge.badge-status-rejected {
  background: rgba(240, 65, 95, 0.18);
}

[data-theme="dark"] .badge.badge-status-revoked {
  background: rgba(240, 65, 95, 0.18);
}

.badge-latest {
  background: var(--vw-green);
  color: #FFFFFF;
  border-color: var(--vw-green);
  font-weight: 600;
}

[data-theme="dark"] .badge-latest {
  background: #1FC25E;
  border-color: #1FC25E;
  color: #0B1A12;
}

.version-selector {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 6px;
  max-width: 360px;
}

.version-selector-help {
  margin: 0 0 14px;
  max-width: 460px;
  line-height: 1.5;
}

.badge-info-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}

.badge-info-button:hover,
.badge-info-button:focus-visible {
  color: var(--text);
  border-color: var(--text-muted);
  background: var(--surface-2);
  outline: none;
}

.request-intro {
  margin-bottom: 24px;
  max-width: 720px;
  line-height: 1.55;
  font-size: 14px;
}

.request-intro strong { color: var(--text); }

.status-legend {
  margin: 4px 0 12px;
  font-size: 12px;
}

.status-legend > summary {
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.status-legend > summary::-webkit-details-marker { display: none; }

.status-legend > summary::before {
  content: "?";
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 10px;
  font-weight: 700;
  margin-right: 6px;
  vertical-align: -2px;
}

.status-legend > summary:hover,
.status-legend[open] > summary { color: var(--text-secondary); }

.status-legend ul {
  list-style: none;
  padding: 10px 0 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-secondary);
  line-height: 1.5;
}

.status-legend strong { color: var(--text); }

.version-selector label {
  white-space: nowrap;
  margin-bottom: 0;
}

.version-selector select {
  max-width: 280px;
}

.sla-table {
  margin-top: 6px;
}

.badge-class-public {
  background: rgba(55, 130, 205, 0.12);
  color: var(--vw-blue-ink);
  border-color: rgba(55, 130, 205, 0.25);
}

.badge-class-internal {
  background: rgba(35, 40, 42, 0.07);
  color: var(--text-secondary);
  border-color: var(--border);
}

.badge-class-confidential {
  background: rgba(245, 160, 30, 0.12);
  color: var(--vw-orange-ink);
  border-color: rgba(245, 160, 30, 0.25);
}

.badge-class-secret {
  background: rgba(240, 65, 95, 0.12);
  color: var(--vw-red-ink);
  border-color: rgba(240, 65, 95, 0.25);
}

[data-theme="dark"] .badge-class-internal {
  background: rgba(255, 255, 255, 0.06);
}

.badge-dpclass-source-aligned {
  background: rgba(55, 130, 205, 0.08);
  color: var(--vw-blue-ink);
  border-color: rgba(55, 130, 205, 0.2);
}

.badge-dpclass-curated {
  background: rgba(0, 172, 70, 0.1);
  color: var(--vw-green-ink);
  border-color: rgba(0, 172, 70, 0.22);
}

.badge-dpclass-analytics {
  background: rgba(115, 75, 165, 0.1);
  color: var(--vw-purple-ink);
  border-color: rgba(115, 75, 165, 0.22);
}

.badge-dpclass-applied-ai {
  background: rgba(240, 65, 95, 0.1);
  color: var(--vw-red-ink);
  border-color: rgba(240, 65, 95, 0.22);
}

[data-theme="dark"] .badge-dpclass-analytics {
  color: #B89BE0;
}

.card-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--border);
  padding-top: 10px;
  margin-top: auto;
  gap: 12px;
  min-height: 36px;
}

.entities {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  font-size: 16px;
}

.entities .icon-globe {
  font-size: 18px;
}

.entities .icon-group {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  color: var(--vw-green-ink);
}

.entities .flag {
  font-size: 16px;
  line-height: 1;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.08));
}

.entities .more {
  font-size: 11px;
  color: var(--text-muted);
  background: var(--surface-2);
  border-radius: 999px;
  padding: 2px 7px;
}

.owner {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-muted);
}

.owner .dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--vw-purple);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 9.5px;
  font-weight: 700;
}

/* ---------- Topbar nav ---------- */
.topbar-nav {
  display: flex;
  gap: 16px;
}

.topbar-nav-link {
  font-size: 14px;
  color: var(--text-secondary);
  padding: 6px 10px;
  border-radius: 6px;
  text-decoration: none;
}

.topbar-nav-link:hover {
  background: var(--surface-2);
  color: var(--text);
}

.topbar-nav-link.active {
  color: var(--vw-green-ink);
  font-weight: 500;
}

/* Status filter strip used by the Approvals view. Same pill vocabulary as
   .filter-chip, with an .active state replacing the hover treatment for the
   currently-selected status. */
.status-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 8px 0 16px;
}

.status-tab {
  display: inline-flex;
  align-items: center;
  padding: 3px 12px;
  font-size: 12.5px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  text-decoration: none;
  transition: background-color 0.15s, border-color 0.15s;
}

.status-tab:hover {
  background: var(--surface-2);
}

.status-tab.active {
  background: var(--vw-green);
  border-color: var(--vw-green);
  color: #fff;
  font-weight: 500;
}

/* Pending-count pill next to the Approvals link. Stays visible in both light
   and dark themes; sized to sit inline with 14px nav text. */
.nav-count {
  display: inline-block;
  min-width: 18px;
  padding: 1px 6px;
  margin-left: 4px;
  border-radius: 999px;
  background: var(--vw-orange);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  text-align: center;
  line-height: 1.4;
}

/* Hamburger toggle that replaces the inline nav below md. The dropdown panel
   itself reuses .dropdown-menu styling (caret, hover, shadow). */
.topbar-menu {
  position: relative;
}

.topbar-menu-toggle {
  color: var(--text-secondary);
  font-size: 22px;
  line-height: 1;
  padding: 0 4px;
  background: transparent;
  transition: color 0.12s ease, background-color 0.12s ease;
  border-radius: 6px;
}

.topbar-menu-toggle:hover,
.topbar-menu-toggle:focus-visible {
  color: var(--text);
  background: var(--surface-2);
  outline: none;
}

.topbar-menu-toggle .hamburger-icon {
  display: inline-block;
}

/* Active nav item inside the hamburger dropdown — match the inline nav's
   green-accent treatment so it stays visually consistent. */
.topbar-menu .dropdown-item.active {
  color: var(--vw-green-ink);
  background: transparent;
  font-weight: 500;
}

.topbar-menu .dropdown-item.active:hover {
  background: var(--surface-2);
}

/* ---------- Catalog page ---------- */
.catalog-section {
  padding-top: 32px;
}

.catalog-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 24px;
  margin-bottom: 24px;
}

.catalog-header h1 {
  font-size: 28px;
  font-weight: 700;
  margin: 0 0 4px;
}

.catalog-search {
  flex: 0 1 360px;
}

.catalog-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 32px;
}

@media (max-width: 768px) {
  .catalog-layout {
    grid-template-columns: 1fr;
  }
}

.catalog-filters {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  height: fit-content;
  position: sticky;
  top: 80px;
}

.filter-group {
  border-bottom: 1px solid var(--border);
  padding: 8px 0;
}

.filter-group:last-of-type {
  border-bottom: 0;
}

.filter-group summary {
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  padding: 4px 0;
  color: var(--text);
}

.filter-check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-secondary);
  padding: 4px 0;
  cursor: pointer;
}

.filter-check input {
  accent-color: var(--vw-green);
}

.filter-actions {
  margin-top: 16px;
}

.active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
}

.active-filters-label {
  font-size: 12px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-right: 4px;
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  font-size: 12.5px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  text-decoration: none;
  transition: background-color 0.15s, border-color 0.15s;
}

.filter-chip:hover {
  background: var(--vw-green);
  border-color: var(--vw-green);
  color: #fff;
}

.filter-chip-group {
  color: var(--text-muted);
}

.filter-chip:hover .filter-chip-group {
  color: rgba(255, 255, 255, 0.85);
}

.filter-chip-x {
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
}

.filter-chip-clear {
  font-size: 12px;
  color: var(--text-muted);
  text-decoration: underline;
  margin-left: auto;
}

.filter-chip-clear:hover {
  color: var(--vw-green-ink);
}

.empty-state {
  grid-column: 1 / -1;
  text-align: center;
  padding: 48px 24px;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: 12px;
  color: var(--text-muted);
}

.pagination-nav {
  margin-top: 24px;
  text-align: center;
}

/* ---------- Detail page ---------- */
.detail-section {
  padding-top: 24px;
  max-width: 1100px;
}

.detail-breadcrumb {
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 16px;
  display: flex;
  gap: 6px;
  align-items: center;
}

.detail-breadcrumb a {
  color: var(--vw-green-ink);
}

.detail-breadcrumb a:hover {
  text-decoration: underline;
}

.detail-header {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 16px 24px;
  margin-bottom: 24px;
  align-items: start;
}

.detail-title {
  min-width: 0;
}

.detail-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .detail-header {
    grid-template-columns: 1fr;
  }

  .detail-cta {
    align-items: flex-start;
    text-align: left;
  }
}

.detail-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 32px;
  padding: 12px 16px;
  margin-bottom: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  font-size: 13px;
}

.detail-fact {
  display: flex;
  align-items: center;
  gap: 8px;
}

.detail-fact .label {
  color: var(--text-muted);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.04em;
}

.detail-fact .value {
  color: var(--text);
  font-weight: 500;
}

.detail-fact .value.entities {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.detail-fact .tag {
  display: inline-block;
  padding: 2px 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 400;
  margin-right: 4px;
}

.detail-title h1 {
  font-size: 32px;
  font-weight: 700;
  margin: 0 0 8px;
}

.detail-title .lede {
  font-size: 16px;
  color: var(--text-secondary);
  margin: 0 0 16px;
}

.detail-aside {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
}

.detail-aside-row {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}

.detail-aside-row:last-child {
  border-bottom: 0;
}

.detail-aside-row .label {
  color: var(--text-muted);
}

.detail-aside-row .value {
  color: var(--text);
  font-weight: 500;
  text-align: right;
}

.detail-aside-row .tag {
  display: inline-block;
  background: var(--surface-2);
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 11px;
  margin-left: 4px;
}

.detail-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 24px;
  /* On phones the 5 tabs (~80px each) run past the viewport. Allow
     horizontal scroll instead of wrapping — single-row tab UI reads
     more like a real productized control than a stacked block. */
  overflow-x: auto;
  scrollbar-width: none;
}

.detail-tabs::-webkit-scrollbar {
  display: none;
}

.detail-tabs .tab {
  flex-shrink: 0;
}

.detail-tabs .tab {
  background: transparent;
  border: 0;
  padding: 10px 16px;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
}

.detail-tabs .tab.active {
  color: var(--vw-green-ink);
  border-bottom-color: var(--vw-green);
}

.detail-tabs .tab:hover:not(.disabled) {
  color: var(--text);
}

.detail-tabs .tab.disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.detail-tabs .tab .muted {
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 400;
}

.tab-panel {
  display: none;
}

.tab-panel.active {
  display: block;
}

.tab-panel h3 {
  font-size: 18px;
  font-weight: 500;
  margin: 24px 0 8px;
}

.tab-panel h4 {
  font-size: 14px;
  font-weight: 700;
  margin: 0 0 8px;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.overview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  margin-top: 16px;
}

/* Two-column Overview: main content on the left, Team aside on the right.
   Collapses to one column below 900px so the Team grid lands at the bottom. */
.overview-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 32px;
  margin-top: 24px;
}

@media (max-width: 900px) {
  .overview-layout {
    grid-template-columns: 1fr;
  }
}

.overview-aside h3 {
  font-size: 18px;
  font-weight: 500;
  margin: 0 0 12px;
}

.overview-aside-heading {
  margin-bottom: 12px;
}

.overview-aside-heading h3 {
  margin: 0 0 4px;
}

.roles-legend {
  font-size: 12px;
}

.roles-legend > summary {
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.roles-legend > summary::-webkit-details-marker {
  display: none;
}

.roles-legend > summary::before {
  content: "?";
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 10px;
  font-weight: 700;
  margin-right: 6px;
  vertical-align: -2px;
}

.roles-legend > summary:hover,
.roles-legend[open] > summary {
  color: var(--text-secondary);
}

.roles-legend ul {
  list-style: none;
  padding: 12px 0 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-secondary);
  line-height: 1.5;
}

.roles-legend li {
  position: relative;
  padding-left: 16px;
}

.roles-legend strong {
  color: var(--text);
}

/* Dot renders as an absolute-positioned bullet so the strong + description
   flow as normal inline prose. Using flex on the <li> forced each of (dot,
   strong, text-node) into its own flex column, which wrapped "Data Owner"
   awkwardly inside the narrow 300px aside. */
.roles-legend-dot {
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.roles-legend-dot--owner { background: var(--vw-green); }
.roles-legend-dot--product-owner { background: var(--vw-blue); }
.roles-legend-dot--steward { background: var(--vw-purple); }
.roles-legend-dot--platform { background: var(--vw-orange); }

/* Aside variant of the stakeholder grid: stack to one column so the rail
   stays compact next to the main content. */
.stakeholder-grid-aside {
  grid-template-columns: 1fr;
}

/* Compact schema preview inside Overview. Reuses .schema-table chrome with
   a tighter row padding so the at-a-glance view doesn't dominate. */
.schema-preview {
  table-layout: fixed;
}

.schema-preview tbody td,
.schema-preview thead th {
  padding: 8px 12px;
}

/* The Object cell can hold long physical names (up to ~60 chars in Unity
   Catalog). Wrap on token boundaries — underscores are legal break points
   — so the row grows in height instead of forcing horizontal scroll. */
.schema-preview-name {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.schema-preview-name .font-monospace {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* Right-align the count and lock its width — the header is short and the
   value is a small integer, so a narrow fixed column leaves the Object
   cell the full remaining width. */
.schema-preview .schema-preview-cols {
  width: 88px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}

.schema-preview-more {
  margin: 8px 0 0;
  font-size: 13px;
}

.schema-preview-more a {
  color: var(--vw-green-ink);
}

.schema-preview-more a:hover {
  text-decoration: underline;
}

.detail-coming-next {
  margin-top: 28px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: 13px;
}

.overview-block {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
}

.overview-block p:last-child {
  margin-bottom: 0;
}

.overview-block ul {
  padding-left: 18px;
  margin-bottom: 0;
}

.stakeholders {
  list-style: none;
  padding: 0;
  margin: 0;
}

.stakeholders li {
  padding: 4px 0;
  font-size: 13.5px;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chip {
  display: inline-block;
  background: var(--surface-2);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 11.5px;
  color: var(--text-secondary);
}

.prio-table {
  width: 100%;
  font-size: 13px;
}

.prio-table th {
  font-weight: 400;
  color: var(--text-secondary);
  padding: 4px 0;
  text-align: left;
}

.prio-table td {
  text-align: right;
  padding: 4px 0;
}

.rating {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

.rating-high {
  background: rgba(0, 172, 70, 0.15);
  color: var(--vw-green-ink);
}

.rating-medium {
  background: rgba(245, 160, 30, 0.15);
  color: var(--vw-orange-ink);
}

.rating-low {
  background: rgba(240, 65, 95, 0.15);
  color: var(--vw-red-ink);
}

.request-access-cta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
  margin-top: 24px;
}

/* ---------- Request detail: two-column layout with sticky CTA aside ---------- */
.request-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 32px;
  margin-top: 8px;
}

@media (max-width: 900px) {
  .request-layout {
    grid-template-columns: 1fr;
  }
}

/* Quote-led content card for the request detail page. The requester's
   justification is rendered as a pull-quote with a leading Vorwerk-green
   typographic quote mark — the single permitted green accent on the page,
   marking this as the requester's voice. Decision rationale (when present)
   sits in a quiet shaded callout below; grant facts condense to a single
   labelled row separated by a hairline. */
.request-quote-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 28px 32px;
}

.request-quote-card .quote {
  margin: 0 0 22px;
  padding: 0;
}

.request-quote-card .quote blockquote {
  margin: 0;
  font-size: 23px;
  font-style: italic;
  line-height: 1.4;
  color: var(--text);
  text-wrap: balance;
  position: relative;
  padding-left: 0.5em;
}

.request-quote-card .quote blockquote::before {
  content: "\201C";
  position: absolute;
  left: -0.35em;
  top: -0.3em;
  font-size: 2.4em;
  line-height: 1;
  color: var(--vw-green);
  font-style: normal;
  font-family: Georgia, "Times New Roman", serif;
}

.request-quote-card .quote figcaption {
  margin-top: 14px;
  font-size: 13px;
  color: var(--text-muted);
}

.request-quote-card .rationale {
  margin: 0 0 22px;
  padding: 14px 16px;
  background: var(--surface-2);
  border-radius: 8px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
}

.request-quote-card .rationale-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-bottom: 6px;
}

/* Grant block: a small timeline. Granted stays muted (historical fact);
   Revoked is the news, so it takes the danger palette + a solid marker.
   Reason moves onto its own inline sub-clause so long reasons don't wrap
   awkwardly inside parentheses. */
.request-quote-card .grant {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 18px;
  margin: 0;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.request-quote-card .grant dt {
  margin: 0;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.06em;
  padding-top: 3px;
}

.request-quote-card .grant dd {
  margin: 0;
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
}

.request-quote-card .grant-target {
  color: var(--text);
  font-weight: 600;
  margin-bottom: 10px;
}

.request-quote-card .grant-events {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.request-quote-card .grant-event {
  display: grid;
  grid-template-columns: 72px 1fr;
  gap: 12px;
  align-items: baseline;
  position: relative;
  padding-left: 14px;
}

.request-quote-card .grant-event::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.request-quote-card .grant-event--granted {
  color: var(--vw-green-ink);
}

.request-quote-card .grant-event--revoked {
  color: var(--vw-red-ink);
}

.request-quote-card .grant-event-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: inherit;
}

.request-quote-card .grant-event-detail {
  color: var(--text);
}

.request-quote-card .grant-event--revoked .grant-event-detail {
  color: var(--vw-red-ink);
  font-weight: 500;
}

.request-quote-card .grant-event-actor,
.request-quote-card .grant-event-reason {
  color: var(--text-secondary);
  font-weight: 400;
  margin-left: 4px;
}

.request-cta-aside {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px;
  position: sticky;
  top: 80px;
  height: fit-content;
}

@media (max-width: 900px) {
  .request-cta-aside {
    position: static;
  }
}

/* Status pills row at the top of the aside, separated from the form below
   with a subtle hairline. Same approach across all states (pending,
   approved, revoked, …) so the aside reads consistently. */
.decision-status-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

/* The decision form is a single vertical stack: label, textarea, action row.
   One form serves both Approve and Reject via the Reject button's formaction
   attribute — same comment field, two destinations. Mirrors the GitHub PR
   review pattern: one shared comment, binary decision. */
.decision-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* When the retry form sits above the standard decision form (provisioning
   failed and the approver may either retry or change their mind), give the
   second form a clear break so the two read as distinct options. */
.decision-form + .decision-form {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}

.decision-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  margin: 0;
}

.decision-textarea {
  font-size: 14px;
  background: var(--bg);
  border-color: var(--border);
  color: var(--text);
  resize: vertical;
  min-height: 84px;
}

.decision-textarea::placeholder {
  color: var(--text-muted);
  opacity: 1;
}

.decision-textarea:focus {
  background: var(--bg);
  border-color: var(--vw-green);
  color: var(--text);
  box-shadow: 0 0 0 0.2rem rgba(0, 172, 70, 0.18);
}

/* Side-by-side buttons of equal width. The primary Approve fills the room
   with green; the outlined Reject is visibly secondary without reading as
   disabled — that's why we ditched the grey filled secondary. */
.decision-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}

.decision-actions .btn {
  flex: 1;
}

.decision-actions .btn.decision-action-wide {
  flex: 1 1 100%;
}

.decision-help,
.decision-note {
  font-size: 12.5px;
  color: var(--text-muted);
  margin: 8px 0 0;
  line-height: 1.5;
}

.decision-note {
  margin: 0;
}

/* Support tab: each channel renders as a card matching the .overview-block
   treatment so the list reads as structured content, not raw bullets. */
.support-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.support-list li {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
}

.support-list li .muted {
  color: var(--text-muted);
  font-weight: 400;
}

.support-list li p {
  margin: 8px 0 0;
}

.schema-block {
  margin-bottom: 32px;
  /* Leave headroom below the sticky topbar when a nav item scrolls a
     block into view. Matches the topbar height + a comfortable gap. */
  scroll-margin-top: 96px;
}

.schema-block h3 .muted {
  color: var(--text-muted);
  font-weight: 400;
  font-size: 14px;
  font-family: monospace;
}

/* --- Schema tab layout: sticky nav rail + main column ------------------- */

.schema-layout {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 32px;
  align-items: start;
}

.schema-nav {
  position: sticky;
  top: 84px;
  max-height: calc(100vh - 108px);
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  padding: 12px;
}

.schema-nav-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 2px 4px 10px;
}

.schema-nav-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.schema-nav-count {
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.schema-nav-filter {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text-muted);
  margin-bottom: 8px;
}

.schema-nav-filter:focus-within {
  border-color: var(--vw-green);
  box-shadow: 0 0 0 3px rgba(0, 172, 70, 0.15);
}

.schema-nav-filter input {
  border: 0;
  background: transparent;
  padding: 0;
  font-size: 13px;
  color: var(--text);
  flex: 1;
  min-width: 0;
  outline: none;
}

.schema-nav-list {
  list-style: none;
  padding: 0;
  margin: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

.schema-nav-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  column-gap: 8px;
  align-items: baseline;
  padding: 8px 10px;
  border-radius: 8px;
  color: var(--text);
  text-decoration: none;
  border-left: 0;
}

.schema-nav-item:hover {
  background: var(--surface-2);
  color: var(--text);
}

.schema-nav-item.is-active {
  background: rgba(0, 172, 70, 0.10);
  color: var(--vw-green-ink);
}

.schema-nav-item-name {
  grid-column: 1;
  font-size: 13.5px;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.schema-nav-item-phys {
  grid-column: 1;
  grid-row: 2;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.schema-nav-item.is-active .schema-nav-item-phys {
  color: var(--vw-green-ink);
  opacity: 0.75;
}

.schema-nav-item-count {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  padding: 2px 7px;
  background: var(--surface-2);
  border-radius: 999px;
  min-width: 26px;
  text-align: center;
}

.schema-nav-item.is-active .schema-nav-item-count {
  background: var(--vw-green);
  color: #fff;
}

.schema-nav-empty {
  margin: 10px 6px 4px;
  font-size: 12px;
  color: var(--text-muted);
}

/* Below 900px the rail collapses into a horizontal chip strip that stays
   pinned under the topbar. Filter input and count badges fold away —
   the strip is a jump-to shortcut, not a browser. */
@media (max-width: 900px) {
  .schema-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .schema-nav {
    position: sticky;
    top: 60px;
    max-height: none;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    margin: 0 -4px 20px;
    overflow-x: auto;
    scrollbar-width: none;
    z-index: 5;
    background: var(--surface);
  }

  .schema-nav::-webkit-scrollbar { display: none; }
  .schema-nav-header,
  .schema-nav-filter,
  .schema-nav-empty { display: none; }

  .schema-nav-list {
    display: flex;
    flex-direction: row;
    gap: 6px;
    overflow: visible;
  }

  .schema-nav-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    white-space: nowrap;
  }

  .schema-nav-item-phys { display: none; }

  .schema-nav-item-name {
    white-space: nowrap;
    overflow: visible;
    font-size: 13px;
  }

  .schema-nav-item-count {
    background: var(--surface-2);
    padding: 1px 6px;
    font-size: 10px;
  }

  .schema-block {
    scroll-margin-top: 120px;
  }
}

.schema-table {
  width: 100%;
  font-size: 13.5px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  border-collapse: separate;
  border-spacing: 0;
}

.schema-table thead th {
  background: var(--surface-2);
  color: var(--text-secondary);
  font-weight: 500;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 10px 14px;
  text-align: left;
  border-bottom: 1px solid var(--border);
}

.schema-table tbody td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
}

.schema-table tbody tr:last-child td {
  border-bottom: 0;
}

.schema-table code {
  background: var(--surface-2);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12.5px;
}

/* Wrap data tables in `.table-wrap` so they scroll horizontally on phones
   instead of overflowing the viewport. The wrap retains the table's
   border-radius via overflow: hidden on the table itself. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Bootstrap default form-check input is 1em (~16px) — adjacent labels
   expand the click area for sighted-mouse users, but the hit zone for
   touchscreen / motor-impaired users is small. Bump to ~18.4px. */
.form-check-input {
  width: 1.15em;
  height: 1.15em;
  margin-top: 0.25em;
}

/* Heading scale step on phones — fixed product-register sizes are right
   for desktop / tablet, but the h1 sizes cramp under ~600px and "Vorwerk
   Data Marketplace" / long product names wrap awkwardly. */
@media (max-width: 600px) {
  .hero h1 { font-size: 28px; }
  .detail-title h1 { font-size: 24px; }
  .catalog-header h1 { font-size: 22px; }
}

/* Row-as-link affordance for inbox + my-requests. Hover and focus give the
   "this row is an interactive target" cue; inner <a> tags keep their own
   click semantics so the product column still goes to product detail. */
.row-table tbody tr.row-link {
  cursor: pointer;
  transition: background-color 0.12s ease;
}

.row-table tbody tr.row-link:hover {
  background: var(--surface-2);
}

.row-table tbody tr.row-link:focus-visible {
  outline: none;
  background: var(--surface-2);
  /* Full inset ring as the focus indicator — `outline` on <tr> renders
     unreliably across engines. NOT a side-stripe; it wraps the row on
     all four sides. */
  box-shadow: inset 0 0 0 2px var(--vw-green);
}

.type-pill {
  display: inline-block;
  background: var(--surface-2);
  padding: 1px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-family: monospace;
  color: var(--text-secondary);
}

.pk-mark {
  color: var(--vw-orange-ink);
  font-weight: 700;
  font-size: 11px;
}

/* ---------- Auth pages (login / logged out) ---------- */
.auth-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  padding: 32px;
}

/* Override the global `main { flex: 1 0 auto }` so auth pages can vertically
   center the shell. Without this, main grows to full viewport height and the
   logo + card cluster at the top. */
.auth-page > main {
  flex: 0 0 auto;
}

.auth-shell {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
}

.auth-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin: 0;
}

.auth-brand-logo {
  height: 90px;
}

.auth-brand h1 {
  font-size: 22px;
  font-weight: 500;
  margin: 0;
  letter-spacing: 0.2px;
  color: var(--text);
}

.auth-card {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 28px;
  box-shadow: var(--shadow);
}

.auth-card .login-hint {
  text-align: center;
}

/* ---------- Dropdown menu (theme-aware Bootstrap override) ---------- */
.dropdown-menu {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 6px;
  margin-top: 10px;
  min-width: 180px;
  color: var(--text);
}

/* Caret pointing up at the user-chip trigger. Two stacked triangles so the
   border colour wraps the fill. Centered horizontally on the menu —
   `left: 50%` is enough because the element is 0-width, so the triangle
   (drawn by the borders) sits symmetrically around the center point. */
.dropdown-menu::before,
.dropdown-menu::after {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  border-style: solid;
  left: 50%;
}

.dropdown-menu::before {
  top: -8px;
  border-width: 0 8px 8px;
  border-color: transparent transparent var(--border);
}

.dropdown-menu::after {
  top: -7px;
  border-width: 0 7px 7px;
  border-color: transparent transparent var(--surface);
}

/* Caret anchored to the right edge for dropdowns that open from a
   right-aligned trigger (user-chip uses `dropdown-menu-end`). */
.user-dropdown .dropdown-menu::before,
.user-dropdown .dropdown-menu::after {
  left: auto;
  right: 14px;
}

/* Caret anchored to the left edge for dropdowns that open from a
   left-aligned trigger (hamburger sits on the left of the topbar). */
.topbar-menu .dropdown-menu::before,
.topbar-menu .dropdown-menu::after {
  left: 14px;
}

.dropdown-item {
  color: var(--text);
  border-radius: 6px;
  padding: 7px 10px;
  font-size: 14px;
  transition: background-color 0.12s ease, color 0.12s ease;
}

.dropdown-item:hover,
.dropdown-item:focus,
.dropdown-item:focus-visible {
  background: var(--surface-2);
  color: var(--text);
  outline: none;
}

.dropdown-item:active {
  background: var(--surface-2);
  color: var(--text);
}

.dropdown-divider {
  border-color: var(--border);
  margin: 6px 4px;
}

/* Theme toggle inside the user dropdown. Reuses .dropdown-item for hover
   and focus treatment; the .theme-icon-* spans inside flip visibility based
   on the current data-theme. */
.theme-toggle-item {
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
}

/* External link in the user dropdown: label on the left, arrow on the right. */
.dropdown-item-external {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.dropdown-item-external .external-arrow {
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1;
  transition: transform 0.12s ease, color 0.12s ease;
}

.dropdown-item-external:hover .external-arrow {
  color: var(--vw-green-ink);
  transform: translate(2px, -2px);
}

[data-theme="dark"] .dropdown-divider {
  border-color: var(--border);
}

.user-chip.btn:focus {
  box-shadow: none;
}

/* ---------- Footer ---------- */
/* Utility footer: help anchor on the left, copyright on the right. The
   theme toggle moved into the user-chip dropdown — see .theme-toggle-item.
   The brand logo is not repeated here; it's already in the topbar. */
.footer {
  flex-shrink: 0;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 14px 32px;
  margin-top: 48px;
  color: var(--text-muted);
  font-size: 12.5px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 8px 24px;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 24px;
}

.footer-link {
  color: var(--text-secondary);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: color 0.12s ease;
}

.footer-link:hover,
.footer-link:focus-visible {
  color: var(--vw-green-ink);
  text-decoration: underline;
}

.footer-link-meta {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.footer-link .external-arrow {
  font-size: 11px;
  color: var(--text-muted);
}

.footer-copy {
  color: var(--text-muted);
}

/* ---------- Stakeholder cards (detail Overview) ---------- */
.stakeholder-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

.stakeholder-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}

.stakeholder-avatar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.5px;
  background: var(--text-muted);
}

.stakeholder-card[data-role="owner"] .stakeholder-avatar {
  background: var(--vw-green);
}

.stakeholder-card[data-role="data_product_owner"] .stakeholder-avatar {
  background: var(--vw-blue);
}

.stakeholder-card[data-role="steward"] .stakeholder-avatar {
  background: var(--vw-purple);
}

.stakeholder-card[data-role="platform_owner"] .stakeholder-avatar {
  background: var(--vw-orange);
}

.stakeholder-card[data-role="producer"] .stakeholder-avatar {
  background: var(--vw-red);
}

.stakeholder-card.stakeholder-empty .stakeholder-avatar {
  background: transparent;
  border: 1px dashed var(--border);
  color: var(--text-muted);
}

.stakeholder-meta {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.stakeholder-meta .role-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}

.stakeholder-meta .name {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.stakeholder-meta .entity-chip {
  display: inline-block;
  width: fit-content;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 6px;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-secondary);
  letter-spacing: 0.3px;
  margin-top: 2px;
}