/* zeroquarry-ui — generated bundle. DO NOT EDIT.
   Source: tokens/*.json + src/css/*.css   Build: npm run build */

/* zeroquarry-ui — generated by scripts/build-tokens.mjs. DO NOT EDIT.
   Edit tokens/*.json and run `npm run build`. */

/* scales (theme-independent) */
:root {
  --zq-space-0: 0;
  --zq-space-1: 0.25rem;
  --zq-space-2: 0.5rem;
  --zq-space-3: 0.75rem;
  --zq-space-4: 1rem;
  --zq-space-5: 1.25rem;
  --zq-space-6: 1.5rem;
  --zq-space-7: 1.75rem;
  --zq-space-8: 2rem;
  --zq-space-10: 2.5rem;
  --zq-space-12: 3rem;
  --zq-space-16: 4rem;
  --zq-radius-none: 0;
  --zq-radius-xs: 3px;
  --zq-radius-sm: 4px;
  --zq-radius-md: 6px;
  --zq-radius-lg: 8px;
  --zq-radius-xl: 12px;
  --zq-radius-pill: 999px;
  --zq-radius-circle: 50%;
  --zq-border-width-hairline: 1px;
  --zq-border-width-thick: 2px;
  --zq-border-width-accent: 3px;
  --zq-font-family-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
  --zq-font-family-mono: "SF Mono", ui-monospace, Menlo, Consolas, "Liberation Mono", monospace;
  --zq-font-size-0: 0.6875rem;
  --zq-font-size-1: 0.75rem;
  --zq-font-size-2: 0.8125rem;
  --zq-font-size-3: 0.875rem;
  --zq-font-size-4: 1rem;
  --zq-font-size-5: 1.125rem;
  --zq-font-size-6: 1.25rem;
  --zq-font-size-7: 1.5rem;
  --zq-font-size-8: 1.75rem;
  --zq-font-size-9: 2rem;
  --zq-font-size-10: 2.5rem;
  --zq-font-weight-regular: 400;
  --zq-font-weight-medium: 500;
  --zq-font-weight-semibold: 600;
  --zq-font-weight-bold: 700;
  --zq-font-leading-tight: 1.15;
  --zq-font-leading-snug: 1.35;
  --zq-font-leading-normal: 1.5;
  --zq-font-leading-relaxed: 1.6;
  --zq-font-tracking-tight: -0.01em;
  --zq-font-tracking-normal: 0;
  --zq-font-tracking-wide: 0.06em;
  --zq-font-tracking-caps: 0.1em;
  --zq-shadow-none: none;
  --zq-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.24);
  --zq-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.28);
  --zq-shadow-lg: 0 24px 80px rgba(0, 0, 0, 0.22);
  --zq-motion-duration-instant: 0ms;
  --zq-motion-duration-fast: 120ms;
  --zq-motion-duration-normal: 200ms;
  --zq-motion-duration-slow: 320ms;
  --zq-motion-easing-standard: cubic-bezier(0.2, 0, 0, 1);
  --zq-motion-easing-decelerate: cubic-bezier(0, 0, 0, 1);
  --zq-motion-easing-accelerate: cubic-bezier(0.3, 0, 1, 1);
  --zq-breakpoint-sm: 560px;
  --zq-breakpoint-md: 820px;
  --zq-breakpoint-lg: 980px;
  --zq-breakpoint-xl: 1280px;
  --zq-z-base: 0;
  --zq-z-sticky: 10;
  --zq-z-dropdown: 100;
  --zq-z-overlay: 1000;
  --zq-z-modal: 1100;
  --zq-z-toast: 1200;
  --zq-opacity-disabled: 0.5;
  --zq-opacity-muted: 0.7;
}

/* semantic colour — dark (default) */
:root,
[data-theme="dark"] {
  --zq-color-bg-body: #0e1013;
  --zq-color-bg-surface: #161a21;
  --zq-color-bg-surface-2: #141820;
  --zq-color-bg-inset: #0b0e13;
  --zq-color-bg-hover: #1a212b;
  --zq-color-bg-highlight: #24374f;
  --zq-color-border-base: #242a33;
  --zq-color-border-subtle: #1f252e;
  --zq-color-text-base: #d7dbe0;
  --zq-color-text-heading: #f0f3f7;
  --zq-color-text-muted: #8a93a0;
  --zq-color-text-code: #e8ecf1;
  --zq-color-accent-base: #3a7ad9;
  --zq-color-accent-hover: #4a8ae9;
  --zq-color-accent-contrast: #ffffff;
  --zq-color-accent-soft: rgba(80, 120, 200, 0.18);
  --zq-color-link-base: #6fb8ff;
  --zq-color-control-bg: #1f2632;
  --zq-color-control-border: #2b3444;
  --zq-color-control-hover: #26303f;
  --zq-color-control-input-bg: #14181f;
  --zq-color-control-input-border: #2a3240;
  --zq-color-status-success: #63d37e;
  --zq-color-status-warning: #ffc24d;
  --zq-color-status-danger: #ff9292;
  --zq-color-status-danger-solid-bg: #6b1111;
  --zq-color-status-danger-solid-fg: #ffcaca;
  --zq-color-notice-warn-bg: #2a1d08;
  --zq-color-notice-warn-border: #6a4a14;
  --zq-color-notice-warn-text: #ffd8a0;
  --zq-color-notice-error-bg: #1b1013;
  --zq-color-notice-error-border: #4a1f1f;
  --zq-color-severity-critical-bg: #6b1111;
  --zq-color-severity-critical-fg: #ffcaca;
  --zq-color-severity-high-bg: #7a3410;
  --zq-color-severity-high-fg: #ffd8b5;
  --zq-color-severity-medium-bg: #6a5a10;
  --zq-color-severity-medium-fg: #ffe89a;
  --zq-color-severity-low-bg: #2a4a1f;
  --zq-color-severity-low-fg: #bfe5aa;
  --zq-color-severity-info-bg: #1f3551;
  --zq-color-severity-info-fg: #b6d8ff;
  --zq-color-lifecycle-candidate-bg: #1f2632;
  --zq-color-lifecycle-candidate-fg: #8a93a0;
  --zq-color-lifecycle-needs-validation-bg: #4a3b10;
  --zq-color-lifecycle-needs-validation-fg: #ffd98a;
  --zq-color-lifecycle-validated-bg: #1e4d2b;
  --zq-color-lifecycle-validated-fg: #9ee6b0;
  --zq-color-lifecycle-disputed-bg: #4a1f1f;
  --zq-color-lifecycle-disputed-fg: #ffb8b8;
  --zq-color-lifecycle-mitigated-bg: #194a43;
  --zq-color-lifecycle-mitigated-fg: #9ee6db;
  --zq-color-lifecycle-retested-bg: #213e59;
  --zq-color-lifecycle-retested-fg: #a7d4ff;
  --zq-color-lifecycle-regression-bg: #573114;
  --zq-color-lifecycle-regression-fg: #ffc58d;
  --zq-color-lifecycle-accepted-risk-bg: #3f2f59;
  --zq-color-lifecycle-accepted-risk-fg: #d8c3ff;
  --zq-color-lifecycle-archived-bg: #343a40;
  --zq-color-lifecycle-archived-fg: #d7dbe0;
  --zq-color-lifecycle-active-bg: #203f2a;
  --zq-color-lifecycle-active-fg: #aee8bb;
  --zq-color-lifecycle-closed-bg: #303640;
  --zq-color-lifecycle-closed-fg: #d7dbe0;
  --zq-color-brand-node: #8b7cf6;
}

/* semantic colour — light */
[data-theme="light"] {
  --zq-color-bg-body: #f5f6f8;
  --zq-color-bg-surface: #ffffff;
  --zq-color-bg-surface-2: #f0f2f5;
  --zq-color-bg-inset: #e8eaee;
  --zq-color-bg-hover: #eceef2;
  --zq-color-bg-highlight: #dbe8ff;
  --zq-color-border-base: #d0d5dd;
  --zq-color-border-subtle: #e0e4ea;
  --zq-color-text-base: #1e2128;
  --zq-color-text-heading: #0d0f14;
  --zq-color-text-muted: #5a6270;
  --zq-color-text-code: #24292e;
  --zq-color-accent-base: #2f64c0;
  --zq-color-accent-hover: #1e52a8;
  --zq-color-accent-contrast: #ffffff;
  --zq-color-accent-soft: rgba(80, 120, 200, 0.18);
  --zq-color-link-base: #1a6dd3;
  --zq-color-control-bg: #e8ecf0;
  --zq-color-control-border: #c5ccd6;
  --zq-color-control-hover: #dbe0e6;
  --zq-color-control-input-bg: #ffffff;
  --zq-color-control-input-border: #c5ccd6;
  --zq-color-status-success: #27ae60;
  --zq-color-status-warning: #e67e22;
  --zq-color-status-danger: #c0392b;
  --zq-color-status-danger-solid-bg: #c0392b;
  --zq-color-status-danger-solid-fg: #ffffff;
  --zq-color-notice-warn-bg: #fff8e1;
  --zq-color-notice-warn-border: #e0b84a;
  --zq-color-notice-warn-text: #6d4c00;
  --zq-color-notice-error-bg: #fef0f0;
  --zq-color-notice-error-border: #e0a0a0;
  --zq-color-severity-critical-bg: #f8d7da;
  --zq-color-severity-critical-fg: #721c24;
  --zq-color-severity-high-bg: #ffe1cf;
  --zq-color-severity-high-fg: #8a3d12;
  --zq-color-severity-medium-bg: #fff3cd;
  --zq-color-severity-medium-fg: #856404;
  --zq-color-severity-low-bg: #d4edda;
  --zq-color-severity-low-fg: #155724;
  --zq-color-severity-info-bg: #dbeafe;
  --zq-color-severity-info-fg: #1d4f91;
  --zq-color-lifecycle-candidate-bg: #e2e3e5;
  --zq-color-lifecycle-candidate-fg: #495057;
  --zq-color-lifecycle-needs-validation-bg: #fff3cd;
  --zq-color-lifecycle-needs-validation-fg: #856404;
  --zq-color-lifecycle-validated-bg: #d4edda;
  --zq-color-lifecycle-validated-fg: #155724;
  --zq-color-lifecycle-disputed-bg: #f8d7da;
  --zq-color-lifecycle-disputed-fg: #721c24;
  --zq-color-lifecycle-mitigated-bg: #d2f4ea;
  --zq-color-lifecycle-mitigated-fg: #11614f;
  --zq-color-lifecycle-retested-bg: #d8ecff;
  --zq-color-lifecycle-retested-fg: #174a72;
  --zq-color-lifecycle-regression-bg: #ffe5c2;
  --zq-color-lifecycle-regression-fg: #7a3f08;
  --zq-color-lifecycle-accepted-risk-bg: #eadfff;
  --zq-color-lifecycle-accepted-risk-fg: #56318c;
  --zq-color-lifecycle-archived-bg: #e9ecef;
  --zq-color-lifecycle-archived-fg: #343a40;
  --zq-color-lifecycle-active-bg: #d4edda;
  --zq-color-lifecycle-active-fg: #155724;
  --zq-color-lifecycle-closed-bg: #e2e3e5;
  --zq-color-lifecycle-closed-fg: #495057;
  --zq-color-brand-node: #7a63e8;
}

/* Opt-in: follow the OS when the app sets data-theme="auto". */
@media (prefers-color-scheme: light) {
  [data-theme="auto"] {
    --zq-color-bg-body: #f5f6f8;
    --zq-color-bg-surface: #ffffff;
    --zq-color-bg-surface-2: #f0f2f5;
    --zq-color-bg-inset: #e8eaee;
    --zq-color-bg-hover: #eceef2;
    --zq-color-bg-highlight: #dbe8ff;
    --zq-color-border-base: #d0d5dd;
    --zq-color-border-subtle: #e0e4ea;
    --zq-color-text-base: #1e2128;
    --zq-color-text-heading: #0d0f14;
    --zq-color-text-muted: #5a6270;
    --zq-color-text-code: #24292e;
    --zq-color-accent-base: #2f64c0;
    --zq-color-accent-hover: #1e52a8;
    --zq-color-accent-contrast: #ffffff;
    --zq-color-accent-soft: rgba(80, 120, 200, 0.18);
    --zq-color-link-base: #1a6dd3;
    --zq-color-control-bg: #e8ecf0;
    --zq-color-control-border: #c5ccd6;
    --zq-color-control-hover: #dbe0e6;
    --zq-color-control-input-bg: #ffffff;
    --zq-color-control-input-border: #c5ccd6;
    --zq-color-status-success: #27ae60;
    --zq-color-status-warning: #e67e22;
    --zq-color-status-danger: #c0392b;
    --zq-color-status-danger-solid-bg: #c0392b;
    --zq-color-status-danger-solid-fg: #ffffff;
    --zq-color-notice-warn-bg: #fff8e1;
    --zq-color-notice-warn-border: #e0b84a;
    --zq-color-notice-warn-text: #6d4c00;
    --zq-color-notice-error-bg: #fef0f0;
    --zq-color-notice-error-border: #e0a0a0;
    --zq-color-severity-critical-bg: #f8d7da;
    --zq-color-severity-critical-fg: #721c24;
    --zq-color-severity-high-bg: #ffe1cf;
    --zq-color-severity-high-fg: #8a3d12;
    --zq-color-severity-medium-bg: #fff3cd;
    --zq-color-severity-medium-fg: #856404;
    --zq-color-severity-low-bg: #d4edda;
    --zq-color-severity-low-fg: #155724;
    --zq-color-severity-info-bg: #dbeafe;
    --zq-color-severity-info-fg: #1d4f91;
    --zq-color-lifecycle-candidate-bg: #e2e3e5;
    --zq-color-lifecycle-candidate-fg: #495057;
    --zq-color-lifecycle-needs-validation-bg: #fff3cd;
    --zq-color-lifecycle-needs-validation-fg: #856404;
    --zq-color-lifecycle-validated-bg: #d4edda;
    --zq-color-lifecycle-validated-fg: #155724;
    --zq-color-lifecycle-disputed-bg: #f8d7da;
    --zq-color-lifecycle-disputed-fg: #721c24;
    --zq-color-lifecycle-mitigated-bg: #d2f4ea;
    --zq-color-lifecycle-mitigated-fg: #11614f;
    --zq-color-lifecycle-retested-bg: #d8ecff;
    --zq-color-lifecycle-retested-fg: #174a72;
    --zq-color-lifecycle-regression-bg: #ffe5c2;
    --zq-color-lifecycle-regression-fg: #7a3f08;
    --zq-color-lifecycle-accepted-risk-bg: #eadfff;
    --zq-color-lifecycle-accepted-risk-fg: #56318c;
    --zq-color-lifecycle-archived-bg: #e9ecef;
    --zq-color-lifecycle-archived-fg: #343a40;
    --zq-color-lifecycle-active-bg: #d4edda;
    --zq-color-lifecycle-active-fg: #155724;
    --zq-color-lifecycle-closed-bg: #e2e3e5;
    --zq-color-lifecycle-closed-fg: #495057;
    --zq-color-brand-node: #7a63e8;
  }
}

/* ==== badge.css =================================================== */
/* Badge / severity chip — one primitive for every label-shaped status.
   Variants: --critical --high --medium --low --info --success --warning
             --neutral --danger */

.zq-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--zq-space-1);
  font-size: var(--zq-font-size-1);
  font-weight: var(--zq-font-weight-semibold);
  line-height: 1;
  padding: var(--zq-space-1) var(--zq-space-2);
  border: var(--zq-border-width-hairline) solid transparent;
  border-radius: var(--zq-radius-sm);
  text-transform: uppercase;
  letter-spacing: var(--zq-font-tracking-wide);
  white-space: nowrap;
}

.zq-badge--critical { background: var(--zq-color-severity-critical-bg); color: var(--zq-color-severity-critical-fg); }
.zq-badge--high     { background: var(--zq-color-severity-high-bg);     color: var(--zq-color-severity-high-fg); }
.zq-badge--medium   { background: var(--zq-color-severity-medium-bg);   color: var(--zq-color-severity-medium-fg); }
.zq-badge--low      { background: var(--zq-color-severity-low-bg);      color: var(--zq-color-severity-low-fg); }
.zq-badge--info     { background: var(--zq-color-severity-info-bg);     color: var(--zq-color-severity-info-fg); }

.zq-badge--success {
  background: color-mix(in srgb, var(--zq-color-status-success) 18%, transparent);
  color: var(--zq-color-status-success);
}
.zq-badge--warning {
  background: color-mix(in srgb, var(--zq-color-status-warning) 18%, transparent);
  color: var(--zq-color-status-warning);
}
.zq-badge--neutral {
  background: var(--zq-color-bg-surface-2);
  color: var(--zq-color-text-muted);
  border-color: var(--zq-color-border-subtle);
}
/* Semantic danger for non-severity error states (failed, revoked,
   integrity-failed); visually the critical ramp. */
.zq-badge--danger {
  background: var(--zq-color-severity-critical-bg);
  color: var(--zq-color-severity-critical-fg);
}

/* Finding-lifecycle tones — the review workflow's own state ramp: scans
   propose, reviewers validate / dispute / mitigate / retest, outcomes
   land as regression, accepted-risk, archived or closed. Candidate is
   the not-yet-reviewed neutral of the ramp. Paired with the severity
   ramp, which describes impact rather than workflow. */
.zq-badge--candidate        { background: var(--zq-color-lifecycle-candidate-bg);        color: var(--zq-color-lifecycle-candidate-fg); }
.zq-badge--needs-validation { background: var(--zq-color-lifecycle-needs-validation-bg); color: var(--zq-color-lifecycle-needs-validation-fg); }
.zq-badge--validated        { background: var(--zq-color-lifecycle-validated-bg);        color: var(--zq-color-lifecycle-validated-fg); }
.zq-badge--disputed         { background: var(--zq-color-lifecycle-disputed-bg);         color: var(--zq-color-lifecycle-disputed-fg); }
.zq-badge--mitigated        { background: var(--zq-color-lifecycle-mitigated-bg);        color: var(--zq-color-lifecycle-mitigated-fg); }
.zq-badge--retested         { background: var(--zq-color-lifecycle-retested-bg);         color: var(--zq-color-lifecycle-retested-fg); }
.zq-badge--regression       { background: var(--zq-color-lifecycle-regression-bg);       color: var(--zq-color-lifecycle-regression-fg); }
.zq-badge--accepted-risk    { background: var(--zq-color-lifecycle-accepted-risk-bg);    color: var(--zq-color-lifecycle-accepted-risk-fg); }
.zq-badge--archived         { background: var(--zq-color-lifecycle-archived-bg);         color: var(--zq-color-lifecycle-archived-fg); }
.zq-badge--active           { background: var(--zq-color-lifecycle-active-bg);           color: var(--zq-color-lifecycle-active-fg); }
.zq-badge--closed           { background: var(--zq-color-lifecycle-closed-bg);           color: var(--zq-color-lifecycle-closed-fg); }

/* ==== breadcrumbs.css ============================================= */
/* Breadcrumbs — trail of links above a page title, inside .zq-page-header.
   Parts: __item (an <a> or a <span> for the current location); the
   separator is drawn between items, never authored in markup. */

.zq-breadcrumbs {
  margin: 0;
  padding: 0;
  font-size: var(--zq-font-size-2);
  color: var(--zq-color-text-muted);
}
.zq-breadcrumbs__item {
  color: inherit;
  text-decoration: none;
}
a.zq-breadcrumbs__item:hover {
  color: var(--zq-color-text-base);
  text-decoration: underline;
}
.zq-breadcrumbs__item + .zq-breadcrumbs__item::before {
  content: "/";
  margin: 0 var(--zq-space-2);
  opacity: 0.55;
}
.zq-breadcrumbs__item[aria-current="page"] {
  color: var(--zq-color-text-base);
}

/* ==== button.css ================================================== */
/* Button — the one button primitive.
   Variants  : default (secondary), --primary, --danger, --ghost, --ghost-danger
   Sizes     : default, --sm
   Modifiers : --block
   Every value maps to a --zq-* token; never hard-code colour or size. */

.zq-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--zq-space-2);
  font-family: inherit;
  font-size: var(--zq-font-size-3);
  font-weight: var(--zq-font-weight-medium);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  user-select: none;
  padding: var(--zq-space-3) var(--zq-space-4);
  border: var(--zq-border-width-hairline) solid var(--zq-color-control-border);
  border-radius: var(--zq-radius-md);
  background: var(--zq-color-control-bg);
  color: var(--zq-color-text-base);
  cursor: pointer;
  transition: background var(--zq-motion-duration-fast) var(--zq-motion-easing-standard),
              border-color var(--zq-motion-duration-fast) var(--zq-motion-easing-standard),
              color var(--zq-motion-duration-fast) var(--zq-motion-easing-standard);
}
.zq-btn:hover { background: var(--zq-color-control-hover); }
.zq-btn:focus-visible { outline: 2px solid var(--zq-color-accent-base); outline-offset: 2px; }
.zq-btn:disabled,
.zq-btn[aria-disabled="true"] {
  opacity: var(--zq-opacity-disabled);
  cursor: not-allowed;
}

.zq-btn--primary {
  background: var(--zq-color-accent-base);
  border-color: var(--zq-color-accent-base);
  color: var(--zq-color-accent-contrast);
}
.zq-btn--primary:hover {
  background: var(--zq-color-accent-hover);
  border-color: var(--zq-color-accent-hover);
}

.zq-btn--danger {
  background: var(--zq-color-status-danger-solid-bg);
  border-color: var(--zq-color-status-danger-solid-bg);
  color: var(--zq-color-status-danger-solid-fg);
}
.zq-btn--danger:hover {
  background: color-mix(in srgb, var(--zq-color-status-danger-solid-bg) 86%, var(--zq-color-status-danger-solid-fg));
  border-color: color-mix(in srgb, var(--zq-color-status-danger-solid-bg) 86%, var(--zq-color-status-danger-solid-fg));
}

.zq-btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--zq-color-link-base);
}
.zq-btn--ghost:hover { background: var(--zq-color-bg-hover); }

.zq-btn--ghost-danger {
  background: transparent;
  border-color: transparent;
  color: var(--zq-color-status-danger);
}
.zq-btn--ghost-danger:hover {
  background: color-mix(in srgb, var(--zq-color-status-danger) 12%, transparent);
}

.zq-btn--sm { font-size: var(--zq-font-size-2); padding: var(--zq-space-2) var(--zq-space-3); }
.zq-btn--block { width: 100%; }

.zq-btn__icon { display: inline-flex; align-items: center; font-size: 1.15em; line-height: 1; }

/* ==== card.css ==================================================== */
/* Card — the shared surface container.
   Sections: .zq-card__header / __title / __subtitle / __actions / __body / __footer
   Modifier: --interactive (whole card is a link/button) */

.zq-card {
  display: flex;
  flex-direction: column;
  background: var(--zq-color-bg-surface);
  border: var(--zq-border-width-hairline) solid var(--zq-color-border-base);
  border-radius: var(--zq-radius-lg);
  color: var(--zq-color-text-base);
}
.zq-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--zq-space-3);
  padding: var(--zq-space-4) var(--zq-space-5);
  border-bottom: var(--zq-border-width-hairline) solid var(--zq-color-border-subtle);
}
.zq-card__titles { min-width: 0; }
.zq-card__title {
  margin: 0;
  font-size: var(--zq-font-size-4);
  font-weight: var(--zq-font-weight-semibold);
  letter-spacing: var(--zq-font-tracking-tight);
  color: var(--zq-color-text-heading);
}
.zq-card__subtitle {
  margin: var(--zq-space-1) 0 0;
  font-size: var(--zq-font-size-2);
  color: var(--zq-color-text-muted);
}
.zq-card__actions { display: flex; align-items: center; gap: var(--zq-space-2); flex: none; }
.zq-card__body { padding: var(--zq-space-5); }
.zq-card__footer {
  display: flex;
  align-items: center;
  gap: var(--zq-space-2);
  padding: var(--zq-space-4) var(--zq-space-5);
  border-top: var(--zq-border-width-hairline) solid var(--zq-color-border-subtle);
}

.zq-card--interactive {
  cursor: pointer;
  text-decoration: none;
  transition: border-color var(--zq-motion-duration-fast) var(--zq-motion-easing-standard),
              background var(--zq-motion-duration-fast) var(--zq-motion-easing-standard);
}
.zq-card--interactive:hover { background: var(--zq-color-bg-hover); border-color: var(--zq-color-border-base); }
.zq-card--interactive:focus-visible { outline: 2px solid var(--zq-color-accent-base); outline-offset: 2px; }

/* --danger — destructive-zone cards (account deletion, key revocation). */
.zq-card--danger {
  border-color: color-mix(in srgb, var(--zq-color-status-danger) 45%, transparent);
}

/* ==== dialog.css ================================================== */
/* Dialog — styling for the native <dialog> element opened by src/js/dialog.js.
   Parts: __header __title __body __footer */

.zq-dialog {
  width: min(32rem, calc(100vw - var(--zq-space-8)));
  padding: 0;
  border: var(--zq-border-width-hairline) solid var(--zq-color-border-base);
  border-radius: var(--zq-radius-lg);
  background: var(--zq-color-bg-surface);
  color: var(--zq-color-text-base);
  box-shadow: var(--zq-shadow-lg);
}
.zq-dialog::backdrop { background: color-mix(in srgb, var(--zq-color-bg-inset) 72%, transparent); }
.zq-dialog__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--zq-space-3);
  padding: var(--zq-space-4) var(--zq-space-5);
  border-bottom: var(--zq-border-width-hairline) solid var(--zq-color-border-subtle);
}
.zq-dialog__title { margin: 0; font-size: var(--zq-font-size-4); font-weight: var(--zq-font-weight-semibold); color: var(--zq-color-text-heading); }
.zq-dialog__body { padding: var(--zq-space-5); }
.zq-dialog__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--zq-space-2);
  padding: var(--zq-space-4) var(--zq-space-5);
  border-top: var(--zq-border-width-hairline) solid var(--zq-color-border-subtle);
}

/* ==== forms.css =================================================== */
/* Form controls — the one input/select/textarea/label treatment.
   The app previously re-styled these per form family; pages opt in by
   classing the control (.zq-input / .zq-select / .zq-textarea) and the
   label (.zq-label). __hint sits under a control; .zq-checkbox is an
   inline label+control row. */

.zq-input,
.zq-select,
.zq-textarea {
  display: block;
  width: 100%;
  padding: var(--zq-space-2) var(--zq-space-3);
  background: var(--zq-color-control-bg);
  border: var(--zq-border-width-hairline) solid var(--zq-color-control-border);
  border-radius: var(--zq-radius-md);
  color: var(--zq-color-text-base);
  font: inherit;
  font-size: var(--zq-font-size-3);
}
.zq-textarea {
  font-family: var(--zq-font-family-mono);
  font-size: var(--zq-font-size-2);
  min-height: 6em;
  resize: vertical;
}
.zq-input:focus-visible,
.zq-select:focus-visible,
.zq-textarea:focus-visible {
  outline: 2px solid var(--zq-color-accent-base);
  outline-offset: -1px;
}
.zq-input[disabled],
.zq-select[disabled],
.zq-textarea[disabled],
.zq-input[aria-disabled="true"],
.zq-select[aria-disabled="true"],
.zq-textarea[aria-disabled="true"] {
  opacity: var(--zq-opacity-disabled);
  cursor: not-allowed;
}

.zq-label {
  display: block;
  margin-bottom: var(--zq-space-2);
  font-weight: var(--zq-font-weight-medium);
}
.zq-hint {
  margin: var(--zq-space-1) 0 0;
  font-size: var(--zq-font-size-2);
  color: var(--zq-color-text-muted);
}

.zq-checkbox {
  display: flex;
  align-items: center;
  gap: var(--zq-space-2);
}

/* ==== notice.css ================================================== */
/* Notice — inline banner for feedback, warnings and empty/error states.
   Variants: --info --success --warning --danger --compact
   Parts   : __icon __content __title __body __actions __dismiss
             __line __sample */

.zq-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--zq-space-3);
  padding: var(--zq-space-3) var(--zq-space-4);
  font-size: var(--zq-font-size-3);
  border: var(--zq-border-width-hairline) solid var(--zq-color-border-base);
  border-radius: var(--zq-radius-md);
  background: var(--zq-color-bg-surface-2);
  color: var(--zq-color-text-base);
}
.zq-notice__icon { flex: none; display: inline-flex; align-items: center; font-size: 1.15em; line-height: 1.4; }
.zq-notice__content { min-width: 0; flex: 1; }
.zq-notice__title { margin: 0; font-weight: var(--zq-font-weight-semibold); }
.zq-notice__body { margin: 0; }
.zq-notice__title + .zq-notice__body { margin-top: var(--zq-space-1); }
.zq-notice__actions { display: flex; gap: var(--zq-space-2); flex: none; align-items: center; }

.zq-notice--info {
  background: var(--zq-color-severity-info-bg);
  border-color: color-mix(in srgb, var(--zq-color-severity-info-fg) 40%, transparent);
  color: var(--zq-color-severity-info-fg);
}
.zq-notice--success {
  background: color-mix(in srgb, var(--zq-color-status-success) 14%, transparent);
  border-color: color-mix(in srgb, var(--zq-color-status-success) 45%, transparent);
  color: var(--zq-color-status-success);
}
.zq-notice--warning {
  background: var(--zq-color-notice-warn-bg);
  border-color: var(--zq-color-notice-warn-border);
  color: var(--zq-color-notice-warn-text);
}
.zq-notice--danger {
  background: var(--zq-color-notice-error-bg);
  border-color: var(--zq-color-notice-error-border);
  color: var(--zq-color-status-danger);
}
/* Links inside a tinted banner inherit the banner colour; the accent link
   colour is unreadable on notice backgrounds. */
.zq-notice a { color: inherit; }

/* --compact — dense operational strip (scan health, nudges): a title line
   with a dismiss action, then optional per-item lines carrying a label,
   a sample and an inline action. The dismiss button also works in
   full-size notices. */
.zq-notice--compact { padding: var(--zq-space-2) var(--zq-space-3); }
.zq-notice__dismiss {
  appearance: none;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  font-size: 1.05em;
  line-height: 1;
  padding: 0 var(--zq-space-1);
  cursor: pointer;
  opacity: 0.6;
}
.zq-notice__dismiss:hover { opacity: 1; }
.zq-notice__line {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--zq-space-2);
  margin-top: var(--zq-space-2);
}
.zq-notice__sample { flex-basis: 100%; }

/* ==== page-header.css ============================================= */
/* Page header — one primitive to replace the per-page <h1> layouts.
   Parts: __titles __title __subtitle __meta __actions
   NOTE: media queries cannot read custom properties, so the 560px here is
   the literal of --zq-breakpoint-sm. Keep the two in sync. */

.zq-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--zq-space-4);
  padding-bottom: var(--zq-space-4);
  margin-bottom: var(--zq-space-5);
  border-bottom: var(--zq-border-width-hairline) solid var(--zq-color-border-subtle);
}
.zq-page-header__titles { min-width: 0; }
.zq-page-header__title {
  margin: 0;
  font-size: var(--zq-font-size-6);
  font-weight: var(--zq-font-weight-semibold);
  letter-spacing: var(--zq-font-tracking-tight);
  color: var(--zq-color-text-heading);
}
.zq-page-header__subtitle {
  margin: var(--zq-space-1) 0 0;
  font-size: var(--zq-font-size-3);
  color: var(--zq-color-text-muted);
}
.zq-page-header__meta {
  margin: var(--zq-space-2) 0 0;
  display: flex;
  align-items: center;
  gap: var(--zq-space-3);
  font-family: var(--zq-font-family-mono);
  font-size: var(--zq-font-size-1);
  color: var(--zq-color-text-muted);
}
.zq-page-header__actions { display: flex; align-items: center; gap: var(--zq-space-2); flex: none; }

@media (max-width: 560px) {
  .zq-page-header { flex-direction: column; }
  .zq-page-header__actions { width: 100%; }
}

/* ==== pager.css =================================================== */
/* Pager — one pagination control.
   Parts: __summary __pages __link __gap */

.zq-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--zq-space-3);
  font-size: var(--zq-font-size-2);
  color: var(--zq-color-text-muted);
}
.zq-pager__summary { font-family: var(--zq-font-family-mono); font-size: var(--zq-font-size-1); }
.zq-pager__pages { display: flex; align-items: center; gap: var(--zq-space-1); }
.zq-pager__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--zq-space-8);
  height: var(--zq-space-8);
  padding: 0 var(--zq-space-2);
  font-size: var(--zq-font-size-2);
  color: var(--zq-color-text-base);
  background: var(--zq-color-control-bg);
  border: var(--zq-border-width-hairline) solid var(--zq-color-border-base);
  border-radius: var(--zq-radius-md);
  text-decoration: none;
}
.zq-pager__link:hover { background: var(--zq-color-control-hover); }
.zq-pager__link[aria-current="page"] {
  background: var(--zq-color-accent-base);
  border-color: var(--zq-color-accent-base);
  color: var(--zq-color-accent-contrast);
}
.zq-pager__link[aria-disabled="true"] { opacity: var(--zq-opacity-disabled); pointer-events: none; }
.zq-pager__gap { padding: 0 var(--zq-space-1); }

@media (max-width: 560px) {
  .zq-pager { flex-direction: column; align-items: flex-start; }
}

/* ==== stat.css ==================================================== */
/* Stat tile — a labelled number at a glance (scan counts, usage totals).
   Parts: __value __label. Lay tiles out in a flex/grid row on the page;
   the tile itself only styles one. */

.zq-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--zq-space-1);
  min-width: 5rem;
  padding: var(--zq-space-3) var(--zq-space-5);
  background: var(--zq-color-bg-surface-2);
  border: var(--zq-border-width-hairline) solid var(--zq-color-border-base);
  border-radius: var(--zq-radius-md);
}
.zq-stat__value {
  font-size: var(--zq-font-size-5);
  font-weight: var(--zq-font-weight-bold);
  line-height: 1.1;
  color: var(--zq-color-text-heading);
}
.zq-stat__label {
  font-size: var(--zq-font-size-0);
  text-transform: uppercase;
  letter-spacing: var(--zq-font-tracking-caps);
  color: var(--zq-color-text-muted);
}

/* ==== states.css ================================================== */
/* States — empty / loading / error placeholders, so no page invents its own.
   Parts: .zq-empty__icon/__title/__body/__actions · .zq-error__title/__body · .zq-spinner */

.zq-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--zq-space-2);
  padding: var(--zq-space-10) var(--zq-space-5);
  border: var(--zq-border-width-hairline) dashed var(--zq-color-border-base);
  border-radius: var(--zq-radius-lg);
  color: var(--zq-color-text-muted);
}
.zq-empty__icon { font-size: var(--zq-font-size-8); line-height: 1; }
.zq-empty__title { margin: 0; font-size: var(--zq-font-size-4); font-weight: var(--zq-font-weight-semibold); color: var(--zq-color-text-heading); }
.zq-empty__body { margin: 0; max-width: 46ch; }
.zq-empty__actions { display: flex; gap: var(--zq-space-2); margin-top: var(--zq-space-2); }

.zq-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--zq-space-3);
  padding: var(--zq-space-10);
  color: var(--zq-color-text-muted);
  font-size: var(--zq-font-size-3);
}
.zq-spinner {
  width: var(--zq-space-5);
  height: var(--zq-space-5);
  border: var(--zq-border-width-thick) solid var(--zq-color-border-base);
  border-top-color: var(--zq-color-accent-base);
  border-radius: var(--zq-radius-circle);
  animation: zq-spin var(--zq-motion-duration-slow) linear infinite;
}
@keyframes zq-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .zq-spinner { animation-duration: calc(var(--zq-motion-duration-slow) * 4); }
}

.zq-error {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--zq-space-2);
  padding: var(--zq-space-5);
  border: var(--zq-border-width-hairline) solid var(--zq-color-notice-error-border);
  border-radius: var(--zq-radius-lg);
  background: var(--zq-color-notice-error-bg);
  color: var(--zq-color-status-danger);
}
.zq-error__title { margin: 0; font-weight: var(--zq-font-weight-semibold); }
.zq-error__body { margin: 0; }

/* ==== table.css =================================================== */
/* Table — the shared data table. Wrap in .zq-table-wrap for horizontal scroll.
   Modifiers: --compact  Parts: __num __select __actions */

.zq-table-wrap {
  overflow-x: auto;
  border: var(--zq-border-width-hairline) solid var(--zq-color-border-base);
  border-radius: var(--zq-radius-lg);
  background: var(--zq-color-bg-surface);
}
.zq-table { width: 100%; border-collapse: collapse; font-size: var(--zq-font-size-3); color: var(--zq-color-text-base); }
.zq-table th,
.zq-table td {
  text-align: left;
  vertical-align: middle;
  padding: var(--zq-space-3) var(--zq-space-4);
  border-bottom: var(--zq-border-width-hairline) solid var(--zq-color-border-subtle);
}
.zq-table thead th {
  font-family: var(--zq-font-family-mono);
  font-size: var(--zq-font-size-0);
  font-weight: var(--zq-font-weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--zq-font-tracking-caps);
  color: var(--zq-color-text-muted);
  border-bottom-color: var(--zq-color-border-base);
  white-space: nowrap;
}
.zq-table tbody tr:last-child td { border-bottom: 0; }
.zq-table tbody tr:hover { background: var(--zq-color-bg-hover); }
.zq-table--compact th,
.zq-table--compact td { padding: var(--zq-space-2) var(--zq-space-3); }

.zq-table__num { text-align: right; font-family: var(--zq-font-family-mono); font-variant-numeric: tabular-nums; }
.zq-table__select { width: 1%; white-space: nowrap; }
.zq-table__actions { text-align: right; white-space: nowrap; }

/* ==== tabs.css ==================================================== */
/* Tabs — one tab primitive for every tabbed surface.
   Behaviour (src/js/tabs.js) drives aria-selected / hidden; style follows it.
   Modifier: --pills */

.zq-tabs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--zq-space-5);
  border-bottom: var(--zq-border-width-hairline) solid var(--zq-color-border-base);
}
.zq-tab {
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: var(--zq-border-width-thick) solid transparent;
  margin-bottom: calc(var(--zq-border-width-hairline) * -1);
  padding: var(--zq-space-3) 0;
  font: inherit;
  font-size: var(--zq-font-size-3);
  font-weight: var(--zq-font-weight-medium);
  color: var(--zq-color-text-muted);
  cursor: pointer;
  white-space: nowrap;
}
.zq-tab:hover { color: var(--zq-color-text-base); }
/* ARIA tabs mark the active tab with aria-selected; a nav strip of plain
   links (server-rendered section navs) marks it with aria-current="page".
   Support both so one primitive serves either. */
.zq-tab[aria-selected="true"],
.zq-tab[aria-current="page"] {
  color: var(--zq-color-text-heading);
  border-bottom-color: var(--zq-color-accent-base);
}
.zq-tab:focus-visible { outline: 2px solid var(--zq-color-accent-base); outline-offset: 2px; }

/* Count pill inside a tab (e.g. the audit-log issue count). Muted by
   default; emphasised on the active tab, whichever ARIA convention
   marks it. */
.zq-tab__count {
  display: inline-block;
  padding: 0 var(--zq-space-2);
  border: var(--zq-border-width-hairline) solid var(--zq-color-border-subtle);
  border-radius: var(--zq-radius-pill);
  background: var(--zq-color-bg-surface-2);
  color: var(--zq-color-text-muted);
  font-size: var(--zq-font-size-1);
  font-weight: var(--zq-font-weight-regular);
  line-height: 1.5;
}
.zq-tab[aria-selected="true"] .zq-tab__count,
.zq-tab[aria-current="page"] .zq-tab__count {
  background: var(--zq-color-bg-highlight);
  color: var(--zq-color-text-heading);
}

.zq-tabs--pills { border-bottom: 0; gap: var(--zq-space-2); }
.zq-tabs--pills .zq-tab {
  padding: var(--zq-space-2) var(--zq-space-3);
  border: var(--zq-border-width-hairline) solid transparent;
  border-radius: var(--zq-radius-md);
  margin-bottom: 0;
}
.zq-tabs--pills .zq-tab[aria-selected="true"],
.zq-tabs--pills .zq-tab[aria-current="page"] {
  background: var(--zq-color-bg-surface-2);
  border-color: var(--zq-color-border-base);
  color: var(--zq-color-text-heading);
}
