:root {
  /* Palette mirrors src/c2pa_probe/card.py so the live HTML report and the
     downloadable PNG card read as the same artifact. Mint on deep navy,
     yellow for "incomplete", coral for "broken". */
  --bg: #0d101a;
  --bg-deep: #080a12;
  --panel: #171c2c;
  --panel-hi: #20263a;
  --fg: #eaeef8;
  --muted: #969eb4;
  --dim: #969eb4;
  --dim2: #6e768c;
  --accent: #7ee6c2;
  --accent-dim: #50967d;
  --accent-soft: rgba(126, 230, 194, 0.12);
  --good: #7ee6c2;
  --bad: #f47280;
  --bad-soft: rgba(244, 114, 128, 0.12);
  --warn: #fac86e;
  --warn-soft: rgba(250, 200, 110, 0.12);
  --border: #343c5a;
  --border-hi: #4a5478;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.55), 0 6px 18px rgba(0, 0, 0, 0.35);
  --glow-accent: 0 0 0 1px rgba(126, 230, 194, 0.35), 0 0 24px rgba(126, 230, 194, 0.18);
  --glow-warn: 0 0 0 1px rgba(250, 200, 110, 0.35), 0 0 24px rgba(250, 200, 110, 0.16);
  --glow-bad: 0 0 0 1px rgba(244, 114, 128, 0.35), 0 0 24px rgba(244, 114, 128, 0.16);

  --motion-fast: 120ms cubic-bezier(0.2, 0.7, 0.2, 1);
  --motion-med: 220ms cubic-bezier(0.2, 0.7, 0.2, 1);

  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; }

/* The UA stylesheet's `[hidden] { display: none }` has no !important, so
   any explicit `display:` rule (flex, grid, inline-flex, ...) wins and
   leaves a hidden element rendered as an empty box. Restore the
   attribute's intended semantics across the whole sheet. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  background-image:
    radial-gradient(1100px 600px at 80% -10%, rgba(126, 230, 194, 0.06), transparent 60%),
    radial-gradient(900px 500px at -10% 0%, rgba(79, 140, 255, 0.05), transparent 55%);
  background-attachment: fixed;
  color: var(--fg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

main {
  max-width: 980px;
  margin: 0 auto;
  padding: 1.25rem 1.25rem 4rem;
}

/* Top nav: brand on the left, links on the right */
.topnav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0 1.5rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.5rem;
}
.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  text-decoration: none;
  color: var(--fg);
}
.brand__mark {
  font-size: 1.5rem;
  color: var(--accent);
}
.brand__wordmark {
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: -0.01em;
}
.brand__byline {
  color: var(--muted);
  font-size: 0.85rem;
}
.topnav nav {
  display: inline-flex;
  gap: 1.25rem;
}
.topnav nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
}
.topnav nav a:hover { color: var(--accent); }

.hero h1 {
  font-size: 2rem;
  margin: 0 0 0.5rem;
  letter-spacing: -0.02em;
}

.lede {
  color: var(--muted);
  margin: 0 0 1.25rem;
  max-width: 70ch;
}

.site-footer {
  max-width: 980px;
  margin: 0 auto;
  padding: 2rem 1.25rem;
  font-size: 0.85rem;
  color: var(--muted);
  border-top: 1px solid var(--border);
}
.site-footer a {
  color: var(--muted);
  text-decoration: underline;
  text-decoration-color: var(--border);
  text-underline-offset: 3px;
}
.site-footer a:hover { color: var(--accent); text-decoration-color: var(--accent); }

.back {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
  display: inline-block;
  margin-bottom: 0.5rem;
}
.back:hover { color: var(--accent); }

/* Drop zone */
.drop {
  border: 2px dashed var(--border);
  border-radius: 12px;
  padding: 3rem 1rem;
  text-align: center;
  margin: 1.5rem 0;
  transition: border-color 120ms, background 120ms;
}
.drop:hover, .drop--hot {
  border-color: var(--accent);
  background: rgba(79, 140, 255, 0.06);
}
.drop__label {
  display: block;
  cursor: pointer;
  color: var(--muted);
}
.drop__hint { font-size: 1rem; }

/* Add-to-recents toggle */
.recents-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.5rem 0 1.25rem;
  font-size: 0.9rem;
  color: var(--fg);
  cursor: pointer;
}
.recents-toggle input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  accent-color: var(--accent);
  cursor: pointer;
  flex: none;
}
.recents-toggle__hint {
  color: var(--muted);
  font-size: 0.85rem;
}

/* "or" divider between drop zone and generate panel */
.or-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.5rem 0 0.75rem;
  color: var(--muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}
.or-divider::before,
.or-divider::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--border);
}

/* Generate panel — always visible, primary CTA */
.generate {
  background: var(--panel);
  padding: 1.25rem 1.25rem 1rem;
  border-radius: 10px;
  border: 1px solid var(--border);
}
.generate__title {
  margin: 0 0 0.25rem;
  font-size: 1.1rem;
  letter-spacing: -0.01em;
}
.generate__lede {
  margin: 0 0 0.9rem;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.45;
}
.generate__row {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: stretch;
}
.generate__row input[type="text"] {
  flex: 1 1 18rem;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  font: inherit;
}
.generate__row input[type="text"]:focus {
  outline: 0;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(79, 140, 255, 0.15);
}
.generate .btn-primary {
  background: var(--accent);
  color: #0a1018;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 0.6rem 1.1rem;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(126, 230, 194, 0.18);
  transition: transform var(--motion-fast), box-shadow var(--motion-fast), filter var(--motion-fast);
}
.generate .btn-primary:hover {
  transform: translateY(-1px);
  filter: brightness(1.05);
  box-shadow: 0 10px 24px rgba(126, 230, 194, 0.25);
}
.generate .btn-primary:active { transform: translateY(0); }
.generate__advanced {
  margin-top: 0.75rem;
  font-size: 0.85rem;
  color: var(--muted);
}
.generate__advanced summary {
  cursor: pointer;
  user-select: none;
}
.generate__advanced label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-top: 0.5rem;
}
.generate__advanced input[type="text"] {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  font: inherit;
}

.status {
  margin-top: 1rem;
  color: var(--muted);
  font-size: 0.95rem;
}
.status--busy {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.55rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(79, 140, 255, 0.06);
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.status__msg { color: var(--fg); }
.status__elapsed { color: var(--muted); font-size: 0.85rem; }

.spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(255, 255, 255, 0.18);
  border-top-color: var(--accent);
  border-radius: 50%;
  display: inline-block;
  animation: spinner-spin 0.7s linear infinite;
  flex: none;
}
@keyframes spinner-spin {
  to { transform: rotate(360deg); }
}

/* While a probe / generate is in flight: dim the controls so the user can
   see the page is locked, and block pointer events on the drop zone so
   dragging a second image silently does nothing. */
body.is-busy .drop,
body.is-busy .generate {
  opacity: 0.55;
  pointer-events: none;
  user-select: none;
}
body.is-busy .recents-toggle {
  opacity: 0.55;
  pointer-events: none;
}
.drop--locked { cursor: not-allowed; }

/* Report page hero: lead with the human-readable description (prompt /
   AI caption / filename), then the verdict pill, then the cert-chain
   summary as small muted meta. Inverts the old "verdict first, prompt
   buried" layout — the boring pkix story belongs below the fold. */
.kicker {
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0.25rem 0 0.6rem;
}
.headline {
  font-size: clamp(1.6rem, 3vw + 0.5rem, 2.6rem);
  line-height: 1.18;
  letter-spacing: -0.02em;
  margin: 0 0 1rem;
  color: var(--fg);
  max-width: 62ch;
  word-break: break-word;
}

.verdict-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem 0.85rem;
  margin: 0.25rem 0 0.75rem;
}
.verdict-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.32rem 0.9rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--bg-deep);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.verdict-pill[data-verdict="VERIFIED"] {
  color: var(--good);
  border-color: var(--good);
  background: var(--accent-soft);
}
.verdict-pill[data-verdict="SIGNATURE OK"],
.verdict-pill[data-verdict="SIGNATURE_OK"] {
  color: var(--warn);
  border-color: var(--warn);
  background: var(--warn-soft);
}
.verdict-pill[data-verdict="UNTRUSTED"] {
  color: var(--bad);
  border-color: var(--bad);
  background: var(--bad-soft);
}
.verdict-pill[data-verdict="NO MANIFEST"],
.verdict-pill[data-verdict="NO_MANIFEST"] {
  color: var(--warn);
  border-color: var(--warn);
  background: var(--warn-soft);
}

.verdict-detail {
  color: var(--muted);
  font-size: 0.95rem;
  margin: 0;
}

.banner {
  font-size: 1.05rem;
  margin: 0.5rem 0 0.5rem;
  line-height: 1.5;
  color: var(--fg);
}
.banner--meta {
  font-size: 0.92rem;
  color: var(--muted);
  max-width: 80ch;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  align-items: center;
  margin-top: 0.75rem;
}
.actions button,
.actions a[download] {
  background: var(--panel);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.35rem 0.75rem;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  text-decoration: none;
}
.actions button:hover,
.actions a[download]:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.copy-status {
  color: var(--muted);
  font-size: 0.85rem;
}

/* Stack images vertically, each at full content width — the summary card
   is rendered at 1200×2100 so the previous 2-column grid was downscaling
   it by 60%+ and looked muddy. Single column gives ~980px, ≈18%
   downscale, sharp enough. Click-through opens the raw native PNG. */
.images {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  margin: 1.5rem 0;
}
.images figure {
  margin: 0;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.75rem;
}
.images figcaption {
  color: var(--muted);
  font-size: 0.8rem;
  margin-bottom: 0.5rem;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.images figcaption .hint {
  font-size: 0.7rem;
  opacity: 0.7;
}
.images a {
  display: block;
  line-height: 0;
  border-radius: 6px;
  outline: 0;
  transition: opacity 100ms ease;
  /* Center smaller-than-column images so they don't get stretched. */
  text-align: center;
}
.images a:hover {
  opacity: 0.85;
}
.images a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.images img {
  /* Don't upscale beyond native resolution — caps at the source's true
     pixel width so a small uploaded image stays sharp. */
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  display: inline-block;
  cursor: zoom-in;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1rem 1.25rem;
  margin: 1rem 0;
}
.panel h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.panel__head h2 { margin-bottom: 0; }

/* Inline copy buttons next to JSON / report blocks. */
.copy-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background: var(--bg);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.25rem 0.6rem;
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
  transition: color 100ms, border-color 100ms;
}
.copy-btn:hover,
.copy-btn:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
  outline: 0;
}
.copy-btn[data-state="copied"] {
  color: var(--good);
  border-color: var(--good);
}
.copy-btn svg { display: block; }

/* Glossary popovers — let visitors hover acronyms (OCSP, CRL, CA, …)
   for a definition. Underline gently so the affordance is discoverable
   without screaming "click me". */
abbr[title] {
  text-decoration: underline dotted var(--muted);
  text-underline-offset: 2px;
  cursor: help;
}

/* Index explainer block: "what does this tool actually do?" */
.explainer {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  color: var(--fg);
}
.explainer__title {
  font-size: 1.1rem;
  margin: 0 0 0.75rem;
}
.explainer__steps {
  margin: 0 0 1rem 1.25rem;
  padding: 0;
  font-size: 0.95rem;
  line-height: 1.5;
}
.explainer__steps li { margin-bottom: 0.5rem; }
.explainer__caveat {
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.55;
  border-left: 3px solid var(--warn);
  padding: 0.5rem 0 0.5rem 0.75rem;
  background: rgba(241, 196, 15, 0.04);
  border-radius: 0 4px 4px 0;
}

/* Report-page verdict explainer (collapsed by default) — addresses the
   "verdict laundering" concern: a green check is just a receipt, not a
   guarantee that the depicted content is real. */
.verdict-explainer {
  margin-top: 0.5rem;
  font-size: 0.9rem;
}
.verdict-explainer summary {
  cursor: pointer;
  color: var(--muted);
}
.verdict-explainer summary:hover { color: var(--accent); }
.verdict-explainer__body {
  margin-top: 0.5rem;
  padding: 0.75rem 0.9rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 0 6px 6px 0;
  color: var(--fg);
  line-height: 1.55;
}
.verdict-explainer__body p { margin: 0 0 0.5rem; }
.verdict-explainer__body p:last-child { margin-bottom: 0; }

/* The primary view on /r/{id}: render the CLI's long-form markdown
   report as the lead artifact. Everything else (panels, raw JSON) is
   reference material below. */
.md-report {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.5rem 1.75rem;
  margin: 1.25rem 0 1.5rem;
  line-height: 1.6;
  color: var(--fg);
}
.md-report h1 {
  font-size: 1.6rem;
  letter-spacing: -0.01em;
  margin: 0 0 0.75rem;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.5rem;
}
.md-report h2 {
  font-size: 1.15rem;
  margin: 1.5rem 0 0.5rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--fg);
}
.md-report h3 {
  font-size: 1rem;
  margin: 1.1rem 0 0.4rem;
  color: var(--fg);
}
.md-report p { margin: 0.5rem 0; }
.md-report blockquote {
  margin: 0.75rem 0;
  padding: 0.6rem 0.9rem;
  border-left: 3px solid var(--accent);
  background: rgba(79, 140, 255, 0.06);
  border-radius: 0 6px 6px 0;
  color: var(--fg);
}
.md-report blockquote em {
  color: var(--muted);
  font-style: italic;
}
.md-report ul, .md-report ol {
  margin: 0.5rem 0;
  padding-left: 1.5rem;
}
.md-report li { margin: 0.2rem 0; }
/* Inline code: just monospace, no box. The CLI report wraps almost
   every value (path, sha, manifest id) in backticks; rendering them
   all as bordered boxes turns the page into a wall of pills. Plain
   monospace keeps the prose scannable. */
.md-report code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.88em;
  color: var(--accent);
  background: transparent;
  border: 0;
  padding: 0;
  word-break: break-all;
}
/* Two-column "key: value" layout for the bulleted lists that follow each
   ## heading (File, Manifest, TSA). Reads like a spec sheet, not a
   shopping list. */
.md-report ul {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1.25rem;
  align-items: baseline;
  margin: 0.5rem 0 1.25rem;
}
.md-report ul li {
  display: contents;
}
.md-report ul li strong {
  color: var(--muted);
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}
.md-report ul li::before {
  content: "";
  display: none;
}

/* Long inline values inside the md-report (italic disclaimers, comma-
   separated codes, full URLs) need to wrap at any character on mobile,
   otherwise they push the parent ul wider than the viewport. */
@media (max-width: 640px) {
  .md-report {
    padding: 1rem 1rem;
  }
  .md-report ul {
    /* Stack key/value pairs vertically so a long value isn't cut off
       by a max-content key column. */
    grid-template-columns: 1fr;
    gap: 0.1rem 0;
  }
  .md-report ul li strong { margin-top: 0.4rem; }
  .md-report p,
  .md-report blockquote,
  .md-report blockquote em,
  .md-report ul li,
  .md-report ul li * {
    overflow-wrap: anywhere;
    word-break: break-word;
  }
  .md-report code {
    word-break: break-all;
    overflow-wrap: anywhere;
  }
}
/* Section separators between the major H2 blocks make the page feel
   like a designed report instead of a markdown dump. */
.md-report h2 {
  margin-top: 1.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  font-weight: 600;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.md-report h2:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.md-report h3 {
  margin-top: 1.25rem;
  font-size: 0.92rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 500;
}
.md-report pre {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.75rem 0.9rem;
  overflow-x: auto;
  font-size: 0.85rem;
}
.md-report pre code {
  background: transparent;
  border: 0;
  padding: 0;
}
.md-report a { color: var(--accent); }
.md-report img {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  margin: 0.75rem 0;
}
.md-report table {
  width: 100%;
  margin: 0.75rem 0;
  border-collapse: collapse;
  font-size: 0.9rem;
}
.md-report table th,
.md-report table td {
  text-align: left;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--border);
}
.md-report table th {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
}

/* RFC 3161 TSA panel: small summary dl + a left-rail chain list with
   each cert as a row. Mirrors the revocation panel's visual language
   so signing-chain + TSA-chain feel like a pair. */
.tsa-block__lede {
  margin: 0 0 0.85rem;
  color: var(--muted);
  font-size: 0.92rem;
}
.tsa-block__summary {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1rem;
  margin: 0 0 1rem;
  font-size: 0.92rem;
}
.tsa-block__summary dt { color: var(--muted); }
.tsa-block__summary dd { margin: 0; word-break: break-word; }
.tsa-yn { font-weight: 700; }
.tsa-yn--ok { color: var(--good); }
.tsa-yn--no { color: var(--bad); }
.tsa-yn--na { color: var(--muted); }
.tsa-block__chain-title {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin: 0.5rem 0 0.5rem;
  font-weight: 500;
}
.tsa-chain {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.tsa-chain__empty {
  color: var(--muted);
  font-size: 0.88rem;
  padding: 0.5rem 0.75rem;
  border: 1px dashed var(--border);
  border-radius: 6px;
}
/* Live-card "no timestamp" placeholder — same shape as the empty TSA
   chain notice in the bigger panel below, just sized for the live card. */
.chain-viz .chain-empty {
  color: var(--muted);
  font-size: 0.88rem;
  padding: 0.5rem 0.75rem;
  border: 1px dashed var(--border);
  border-radius: 6px;
  font-style: italic;
}
.tsa-chain__row {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.2rem 0.85rem;
  padding: 0.5rem 0.75rem;
  background: var(--bg-deep, var(--bg));
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-hi, var(--border));
  border-radius: 6px;
  font-size: 0.9rem;
}
.tsa-chain__row[data-role="leaf"]         { border-left-color: var(--accent); }
.tsa-chain__row[data-role="intermediate"] { border-left-color: var(--accent-dim, var(--accent)); }
.tsa-chain__row[data-role="root"]         { border-left-color: var(--muted); }
.tsa-chain__role {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.72rem;
  color: var(--muted);
  align-self: baseline;
}
.tsa-chain__cn {
  font-weight: 500;
  color: var(--fg);
  word-break: break-word;
}
.tsa-chain__issuer,
.tsa-chain__meta {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 0.82rem;
}

/* Per-cert revocation status: one row per non-root cert with OCSP +
   CRL outcomes inline. Visible by default so an intermediate
   "no responder answer" surfaces without diving into the markdown. */
.revocation {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.revocation__lede {
  margin: 0 0 0.85rem;
  color: var(--muted);
  font-size: 0.92rem;
}
.revocation__row {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1rem;
  padding: 0.55rem 0.75rem;
  background: var(--bg-deep, var(--bg));
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.92rem;
  align-items: baseline;
}
.revocation__row[data-tier="warn"] { border-left: 3px solid var(--warn); }
.revocation__row[data-tier="fail"] { border-left: 3px solid var(--bad); }
.revocation__row[data-tier="ok"]   { border-left: 3px solid var(--good); }
.revocation__row[data-tier="skip"] {
  border-left: 3px dashed var(--border-hi, var(--border));
  opacity: 0.78;
}
.revocation__ocsp[data-tier="skip"] { color: var(--muted); font-style: italic; }
.revocation__role {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.75rem;
  color: var(--muted);
}
.revocation__cn {
  font-weight: 500;
  color: var(--fg);
  word-break: break-word;
}
.revocation__ocsp,
.revocation__crl {
  grid-column: 1 / -1;
  color: var(--fg);
  font-size: 0.88rem;
}
.revocation__ocsp[data-tier="warn"] { color: var(--warn); }
.revocation__ocsp[data-tier="fail"] { color: var(--bad); }
.revocation__ocsp[data-tier="ok"]   { color: var(--good); }
.revocation__glyph {
  display: inline-block;
  font-weight: 700;
  margin-right: 0.35rem;
}

/* Edit-history timeline — c2pa.actions rendered as a vertical thread
   with a glyph-and-pill per entry. Reads like a build log: timestamp,
   what happened, what tool. */
.timeline-panel { padding-bottom: 1.25rem; }
.timeline__lede {
  margin: 0 0 1rem;
  color: var(--muted);
  font-size: 0.92rem;
}
.timeline {
  list-style: none;
  padding: 0;
  margin: 0;
  position: relative;
}
.timeline::before {
  content: "";
  position: absolute;
  left: 11px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: var(--border);
  border-radius: 2px;
}
.timeline__entry {
  position: relative;
  padding-left: 2rem;
  padding-top: 0.45rem;
  padding-bottom: 0.95rem;
}
.timeline__entry[data-source^="ingredient"] {
  opacity: 0.78;
}
.timeline__glyph {
  position: absolute;
  left: 0;
  top: 0.35rem;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--panel-hi, var(--panel));
  border: 1px solid var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  color: var(--accent);
}
.timeline__body {
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: var(--radius-sm);
  padding: 0.65rem 0.75rem;
}
.timeline__head {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
}
.timeline__label {
  font-weight: 600;
  color: var(--fg);
}
.timeline__ordinal {
  color: var(--dim2);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}
.timeline__time {
  display: block;
  margin-top: 0.15rem;
  color: var(--accent);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}
.timeline__meta {
  margin-top: 0.45rem;
  font-size: 0.82rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
}
.timeline__agent { color: var(--fg); }
.timeline__details {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.2rem 0.55rem;
  margin: 0.55rem 0 0;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.78rem;
  color: var(--muted);
}
.timeline__details dt {
  margin: 0;
  color: var(--dim2);
}
.timeline__details dd {
  margin: 0;
  word-break: break-all;
}
.timeline__source {
  margin-top: 0.45rem;
  font-size: 0.75rem;
  color: var(--muted);
  font-style: italic;
}
.timeline__pill {
  display: inline-block;
  padding: 0.05rem 0.5rem;
  border-radius: 999px;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1px solid var(--border);
  color: var(--muted);
}
.timeline__pill--ai {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft, rgba(126, 230, 194, 0.1));
}
.timeline__pill--cam {
  border-color: var(--warn);
  color: var(--warn);
  background: var(--warn-soft, rgba(250, 200, 110, 0.1));
}
.timeline__pill--region {
  border-color: var(--border-hi);
  color: var(--fg);
  background: rgba(255, 255, 255, 0.04);
}

/* Confidence panel — plain-English bullets summarising why we trust
   (or don't trust) the verdict. The headline tier sets the colour. */
.confidence-headline {
  font-size: 1.05rem;
  margin: 0 0 0.6rem;
  color: var(--fg);
}
.confidence-headline[data-tier="high"]   { color: var(--good); }
.confidence-headline[data-tier="medium"] { color: var(--warn); }
.confidence-headline[data-tier="low"]    { color: var(--bad); }
.confidence-bullets {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.92rem;
}
.confidence-bullets li {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
}
.confidence-bullets li[data-ok="yes"] .confidence-icon { color: var(--good); }
.confidence-bullets li[data-ok="no"]  .confidence-icon { color: var(--bad); }
.confidence-icon { font-weight: 700; flex: none; width: 0.9rem; }

/* External-verifier cross-check panel: a row of external links that take
   the same image to other public C2PA verifiers. Disagreements between
   verifiers are the highest-signal check this tool can give a journalist. */
.cross-check__lede {
  margin: 0 0 0.6rem;
  color: var(--muted);
  font-size: 0.92rem;
}
.cross-check__links {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
}
.cross-check__links a {
  display: inline-block;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--fg);
  text-decoration: none;
  font-size: 0.85rem;
}
.cross-check__links a:hover,
.cross-check__links a:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: 0;
}

/* Drop-zone secondary line — file-format hint under the main affordance. */
.drop__sub {
  display: block;
  margin-top: 0.4rem;
  font-size: 0.78rem;
  color: var(--muted);
}

dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1rem;
  margin: 0;
  font-size: 0.92rem;
}
dt {
  color: var(--muted);
}
dd {
  margin: 0;
  word-break: break-word;
}

.chain-row {
  border-top: 1px solid var(--border);
  padding: 0.6rem 0;
}
.chain-row:first-child { border-top: 0; }
.chain-row summary {
  cursor: pointer;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.92rem;
}
.chain-row dl {
  margin-top: 0.5rem;
  padding-left: 1rem;
}

/* Raw JSON sits in a <details> collapsed by default — it's reference
   material for power users, not part of the primary read. */
.raw-panel { padding: 0; }
.raw-panel > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.85rem 1.1rem;
  font-size: 0.95rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.raw-panel > summary::-webkit-details-marker { display: none; }
.raw-panel > summary::before {
  content: "▸ ";
  margin-right: 0.4rem;
  color: var(--muted);
  transition: transform 100ms;
}
.raw-panel[open] > summary::before { content: "▾ "; }
.raw-panel > summary:hover { color: var(--accent); }
.raw-panel[open] #raw-json {
  margin: 0 1.1rem 1rem;
}

#raw-json {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.75rem;
  overflow-x: auto;
  font-size: 0.78rem;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Recent runs table */
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}
table th, table td {
  text-align: left;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
}
table th {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
}
table a {
  color: var(--accent);
  text-decoration: none;
}
table a:hover { text-decoration: underline; }
.badge {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  font-size: 0.78rem;
  background: var(--bg);
  border: 1px solid var(--border);
}
.badge[data-verdict="VERIFIED"] { color: var(--good); border-color: var(--good); background: var(--accent-soft); }
.badge[data-verdict="SIGNATURE OK"] { color: var(--warn); border-color: var(--warn); background: var(--warn-soft); }
.badge[data-verdict="UNTRUSTED"] { color: var(--bad); border-color: var(--bad); background: var(--bad-soft); }
.badge[data-verdict="NO MANIFEST"] { color: var(--warn); border-color: var(--warn); background: var(--warn-soft); }

/* Recent runs: label column ellipsizes long prompts/filenames so the
   table stays readable. Hover to see the full text via title attr. */
.label-cell {
  max-width: 32ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.label-cell .muted { color: var(--muted); }
table time { font-variant-numeric: tabular-nums; color: var(--muted); }

/* Whole-row clickable navigation in the recent runs table. */
.runs-table tbody .row-link {
  cursor: pointer;
  transition: background-color 100ms ease;
}
.runs-table tbody .row-link:hover,
.runs-table tbody .row-link:focus-visible {
  background: rgba(79, 140, 255, 0.08);
  outline: 0;
}
.runs-table tbody .row-link:focus-visible td:first-child {
  box-shadow: inset 3px 0 0 var(--accent);
}
.runs-table code {
  color: var(--muted);
  font-size: 0.85rem;
}

/* Day-grouping separator: subtle, non-interactive, sits between rows
   and visually breaks the feed into "Today / Yesterday / Apr 24"
   chunks so a long list reads as a stream rather than one wall. */
.runs-table tr.day-separator td {
  padding: 0.95rem 0 0.3rem;
  border: 0 !important;
  background: transparent;
}
.runs-table tr.day-separator td span {
  display: inline-block;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim2, var(--muted));
  font-weight: 700;
}
.runs-table tr.day-separator:first-child td { padding-top: 0.2rem; }
.runs-table tr.day-separator:hover { background: transparent; }

/* Two-line "signed by" cell: signer CN on top, root CN dimmed below.
   Truncate each line independently so a long DN doesn't push the cell
   wider; the row's tooltip-on-hover surfaces the full text. */
.runs-table .signer-cell {
  max-width: 28ch;
  font-size: 0.88rem;
  line-height: 1.25;
}
.runs-table .signer-cell .signed-by__signer,
.runs-table .signer-cell .signed-by__root {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.runs-table .signer-cell .signed-by__root {
  color: var(--dim, var(--muted));
  font-size: 0.78rem;
}

/* Two-line ID cell: friendly slug on top, short hash underneath. */
.runs-table .run-id {
  display: inline-flex;
  flex-direction: column;
  gap: 0.05rem;
  line-height: 1.15;
}
.runs-table .run-id__slug {
  font-size: 0.8rem;
  color: var(--fg);
}
.runs-table .run-id__sha {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.72rem;
  color: var(--muted);
}

/* Shimmer placeholder rows shown during pager fetches so the table never
   collapses to a blank panel between clicks. */
.row-skeleton td {
  height: 2.25rem;
}
.row-skeleton td::after {
  content: "";
  display: block;
  height: 0.75rem;
  width: 70%;
  border-radius: 4px;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.04) 0%,
    rgba(255, 255, 255, 0.10) 50%,
    rgba(255, 255, 255, 0.04) 100%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.1s linear infinite;
}
.row-skeleton td:nth-child(2)::after { width: 90%; }
.row-skeleton td:nth-child(5)::after { width: 50%; }
@keyframes skeleton-shimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

/* Pagination controls beneath the recent runs table. */
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}
.pager__btn {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.4rem 0.85rem;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color 100ms, color 100ms;
}
.pager__btn:hover:not(:disabled),
.pager__btn:focus-visible:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
  outline: 0;
}
.pager__btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.pager__meta {
  color: var(--muted);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

/* Datatable toolbar: filter input + verdict chips above the runs table. */
.table-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}
.table-toolbar__filter {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex: 1 1 18rem;
  min-width: 12rem;
}
#filter {
  flex: 1;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.45rem 0.7rem;
  font: inherit;
  font-size: 0.9rem;
}
#filter:focus {
  outline: 0;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(79, 140, 255, 0.18);
}
#filter::-webkit-search-cancel-button { filter: invert(0.7); }
.filter__count {
  color: var(--muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.chips {
  display: inline-flex;
  gap: 0.3rem;
  flex-wrap: wrap;
}
.chip {
  background: var(--bg);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
  transition: border-color 100ms, color 100ms, background 100ms;
}
.chip:hover { color: var(--fg); border-color: var(--accent); }
.chip.is-active {
  color: var(--fg);
  border-color: var(--accent);
  background: rgba(79, 140, 255, 0.12);
}

/* Sticky thead so the column labels stay visible while scrolling a long
   table, plus sortable header buttons. */
.runs-wrap { position: relative; }
.runs-table thead th {
  position: sticky;
  top: 0;
  background: var(--bg);
  z-index: 1;
}
.th-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  padding: 0;
}
.th-sort:hover { color: var(--fg); }
.th-sort__arrow::after {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0;
  transition: opacity 100ms, transform 100ms;
}
.runs-table th.is-sorted .th-sort { color: var(--accent); }
.runs-table th.is-sorted .th-sort__arrow::after { opacity: 1; }
.runs-table th.is-sorted.is-asc .th-sort__arrow::after {
  transform: rotate(180deg);
}

.no-match {
  color: var(--muted);
  padding: 1rem 0;
  text-align: center;
  font-size: 0.9rem;
}

.kbd-hint {
  margin-top: 0.75rem;
  color: var(--muted);
  font-size: 0.78rem;
  text-align: right;
}
.kbd-hint kbd {
  display: inline-block;
  padding: 0.05rem 0.4rem;
  margin: 0 0.1rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.72rem;
  color: var(--fg);
}

/* Floating thumbnail of the rendered summary card on row hover. Lives at
   the document root in fixed-position so it can escape the table's stacking
   context and follow the cursor without scrolling oddities. */
.row-preview {
  position: fixed;
  width: 320px;
  pointer-events: none;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 6px 6px 4px;
  box-shadow:
    0 18px 40px rgba(0, 0, 0, 0.55),
    0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 100;
  opacity: 0;
  transform: translateY(-6px) scale(0.98);
  transition: opacity 130ms ease, transform 130ms ease;
}
.row-preview.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.row-preview img {
  display: block;
  width: 100%;
  border-radius: 6px;
  background: var(--bg);
}
.row-preview__hint {
  text-align: center;
  font-size: 0.7rem;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 0 2px;
}

/* ===== mobile breakpoint ====================================================
   The desktop layout assumed a 980px column. Below ~640px (most phones),
   we collapse the recent runs table into stacked cards, drop hover-only
   affordances, and grow the hero text so it reads on a 375px screen. */

/* Hard backstop against page-level horizontal overflow. A single rogue
   wide element (long token, un-wrapped pre, flex container without
   min-width:0) used to push the whole document past 100vw and force a
   horizontal scrollbar; this clips at the body edge so the viewport
   stays anchored. */
html, body { max-width: 100%; overflow-x: hidden; }

@media (max-width: 640px) {
  main { padding: 0.75rem 0.75rem 4rem; }
  .hero h1 { font-size: 1.5rem; line-height: 1.2; }
  .hero--report h1 { font-size: 1.6rem; }

  /* Stack the cert-chain visualizer vertically on mobile instead of
     horizontal-scrolling pills nobody can see. The arrow connectors
     between nodes already adapt to a column layout via card.py's
     desktop-only "→" icons (set in JS), so we just flip the flex axis. */
  .chain-viz {
    flex-direction: column;
    overflow-x: visible;
    gap: 0.45rem;
  }
  .chain-node {
    min-width: 0;
    width: 100%;
  }

  /* Capture-group key/value lists: keys can be long ("c2pa.signature"),
     so on mobile we break them onto their own line above the value
     instead of squeezing both columns into a 332-px container. */
  .capture-group__list {
    grid-template-columns: 1fr;
    gap: 0.1rem 0;
  }
  .capture-group__list dt {
    margin-top: 0.4rem;
  }

  /* Long signer / root strings shouldn't push the whole page wider. */
  .capture-group__list dd,
  .capture-group__value-pre,
  .capture-group__value-code {
    overflow-wrap: anywhere;
    word-break: break-word;
  }

  /* Drop zone: tap-to-pick on touch, drag prompt off — mobile users can't
     drag images from another app. */
  .drop { padding: 2rem 0.75rem; }
  @media (hover: none) {
    .drop__hint::before { content: "tap to pick a photo"; }
    .drop__hint { font-size: 0; }
    .drop__hint::before { font-size: 1rem; }
  }

  .generate__row { flex-direction: column; }
  .generate .btn-primary { width: 100%; }

  /* /recent on mobile: each row becomes a card you can scan in one
     glance. The table cells flow into a CSS grid:
       row 1: verdict badge | label
       row 2: signer · root · sha   (one dim metadata strip)
       row 3: relative time         (right-aligned, smallest)
     Cells we don't want to render get hidden via :nth-child instead of
     dom changes, so the mobile-only layout is purely a stylesheet flip. */
  .runs-table thead { display: none; }
  .runs-table,
  .runs-table tbody { display: block; width: 100%; }
  .runs-table tr.row-link {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas:
      "verdict label"
      "meta meta"
      "ts ts";
    column-gap: 0.55rem;
    row-gap: 0.2rem;
    align-items: center;
    padding: 0.7rem 0.6rem;
    border-top: 1px solid var(--border);
  }
  .runs-table tr.row-link:first-child { border-top: 0; }
  .runs-table td {
    display: block;
    width: auto;
    padding: 0;
    border: 0;
    min-width: 0;
  }
  /* td:1 = ts, 2 = label, 3 = verdict, 4 = signer, 5 = root, 6 = sha */
  .runs-table td:nth-child(1) {
    grid-area: ts;
    justify-self: end;
    color: var(--dim);
    font-size: 0.74rem;
    letter-spacing: 0.04em;
  }
  .runs-table td:nth-child(2) {
    grid-area: label;
    font-weight: 500;
    overflow-wrap: anywhere;
    /* Two-line clamp keeps long AI captions from blowing the card up. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .runs-table td:nth-child(3) {
    grid-area: verdict;
    align-self: start;
  }
  /* Signer + root cell: two stacked lines (signer on top, root dim
     below). Each line truncates independently so a long DN doesn't
     push the card wider. The id cell is hidden — power users tap
     into the row to see the sha. */
  .runs-table td:nth-child(4) {
    grid-area: meta;
    font-size: 0.8rem;
    min-width: 0;
    max-width: 100%;
  }
  .runs-table td:nth-child(5) { display: none; }
  /* Day-separator on mobile: ensure the row spans full width without
     trying to shoehorn into the row-link grid layout. */
  .runs-table tr.day-separator {
    display: block;
    border: 0;
    padding: 0.5rem 0 0.15rem;
  }
  .runs-table tr.day-separator td { padding: 0; }
  .label-cell {
    max-width: 100%;
    white-space: normal;
    font-weight: 500;
  }

  /* Hero report card stacks at full width; verdict pill becomes block-level. */
  .verdict-row { flex-wrap: wrap; gap: 0.4rem; }
  .actions { gap: 0.4rem; }

  /* Pager buttons: full-width, sticky to thumb zone for one-handed use. */
  .pager {
    position: sticky;
    bottom: env(safe-area-inset-bottom, 0);
    background: var(--bg);
    margin: 1rem -0.75rem 0;
    padding: 0.75rem 0.75rem env(safe-area-inset-bottom, 0.75rem);
  }

  /* Toolbar wraps so chips don't overflow viewport. */
  .table-toolbar { flex-direction: column; align-items: stretch; gap: 0.5rem; }
}

/* ============================================================================
   UI Kit — components shared by the report page's live "card" hero.

   The downloadable PNG card (src/c2pa_probe/card.py) and this page should
   read as the same artifact: dark navy panel, mint accent, image + meta
   side-by-side, trust-chain pills, ✓/✗ checks grid, glowing verdict.
   ========================================================================= */

/* The lead artifact on /r/{id}: a live HTML twin of the rendered PNG card.
   Image + signing metadata sit side-by-side at the top, then the trust
   chain visualizer, then the checks grid, then the verdict badge. */
.live-card {
  position: relative;
  margin: 0.5rem 0 1.5rem;
  padding: 1.5rem 1.5rem 1.75rem;
  background:
    linear-gradient(180deg, rgba(126, 230, 194, 0.04), transparent 40%),
    var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.live-card::before {
  /* Hairline gradient sheen along the top edge, like the card.py header rule. */
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(126, 230, 194, 0.4) 18%,
    rgba(126, 230, 194, 0.4) 82%,
    transparent 100%
  );
}

.live-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.25rem;
}
.live-card__title {
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg);
  font-weight: 700;
  margin: 0;
}
.live-card__title-mark {
  color: var(--accent);
  margin-right: 0.4rem;
}
.live-card__timestamp {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.78rem;
  color: var(--dim2);
  font-variant-numeric: tabular-nums;
}

/* Hero: image on the left, meta column on the right. Mirrors _draw_hero. */
.live-card__hero {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}
.live-card__media {
  position: relative;
  align-self: start;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--panel-hi);
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.live-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.live-card__media--placeholder {
  color: var(--dim2);
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.live-card__meta {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  min-width: 0;
}
.meta-kicker {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}
.meta-headline {
  font-size: clamp(1.4rem, 2vw + 0.5rem, 2rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--fg);
  word-break: break-word;
}
.meta-list {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 1rem;
  row-gap: 0.5rem;
  margin: 0.25rem 0 0;
  font-size: 0.92rem;
}
.meta-list dt {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim2);
  font-weight: 700;
  align-self: center;
}
.meta-list dd {
  margin: 0;
  color: var(--fg);
  word-break: break-word;
  font-variant-numeric: tabular-nums;
}
.meta-list dd .mono {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.86em;
  color: var(--dim);
}

/* Section header inside the live card: "TRUST CHAIN", "CHECKS", etc. */
.section-eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim);
  font-weight: 700;
  margin: 1.5rem 0 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.section-eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--border), transparent);
}

/* Trust chain visualizer: one node per cert, status-colored border + dot,
   arrow connectors between. Mirrors card.py _draw_chain. */
.chain-viz {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
  padding-bottom: 0.25rem;
  /* Without this, a flex parent will let the children push the page wider
     than the viewport — the overflow-x:auto only kicks in when the
     container actually has a constrained width. */
  min-width: 0;
  max-width: 100%;
}
.chain-viz::-webkit-scrollbar { height: 6px; }
.chain-viz::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.chain-node {
  flex: 1 1 0;
  min-width: 180px;
  position: relative;
  background: var(--panel-hi);
  border: 1.5px solid var(--accent);
  border-radius: var(--radius-md);
  padding: 0.8rem 0.95rem 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  text-decoration: none;
  color: var(--fg);
  transition: transform var(--motion-fast), box-shadow var(--motion-fast);
}
.chain-node:hover,
.chain-node:focus-visible {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
  outline: 0;
}
.chain-node[data-status="warn"] { border-color: var(--warn); }
.chain-node[data-status="bad"] { border-color: var(--bad); }
.chain-node[data-status="ok"] { border-color: var(--accent); }

/* TSA chain: neutral grey by default. The C2PA Conformance Trust List
   anchors claim-signing roots, not TSA roots — most CAs run their own
   internal TSAs — so colouring TSA "yellow because untrusted" implied
   trouble where there was none. ``data-status="warn"`` and
   ``data-status="bad"`` still take over for actual issues (truncated
   chain, bad signature, bad imprint). */
.chain-viz--tsa .chain-node[data-status="ok"] { border-color: var(--border); }
.chain-viz--tsa .chain-node[data-status="ok"] .chain-node__dot {
  background: var(--dim);
  color: var(--dim);
}

.chain-node__role {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.chain-node[data-role="root"] .chain-node__role { color: var(--accent-dim); }
.chain-node[data-role="intermediate"] .chain-node__role { color: var(--dim); }
.chain-node__cn {
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--fg);
  /* Clamp to two lines so a long DN doesn't blow up the row. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.chain-node__ocsp {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  align-self: flex-start;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-pill);
  border: 1px solid currentColor;
  background: rgba(255, 255, 255, 0.02);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--accent);
}
.chain-node__ocsp[data-tier="ok"] { color: var(--accent); background: var(--accent-soft); }
.chain-node__ocsp[data-tier="warn"] { color: var(--warn); background: var(--warn-soft); }
.chain-node__ocsp[data-tier="bad"] { color: var(--bad); background: var(--bad-soft); }

.chain-node__key {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.78rem;
  color: var(--dim);
  margin-top: auto;
}
.chain-node__dot {
  position: absolute;
  top: 0.7rem;
  right: 0.75rem;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px currentColor;
  color: var(--accent);
}
.chain-node[data-status="warn"] .chain-node__dot { background: var(--warn); color: var(--warn); }
.chain-node[data-status="bad"] .chain-node__dot { background: var(--bad); color: var(--bad); }

.chain-arrow {
  flex: none;
  align-self: center;
  color: var(--border);
  display: flex;
  align-items: center;
  font-size: 1.1rem;
  user-select: none;
}

/* Checks grid: ✓/✗ items in two columns. Mirrors card.py _draw_checks. */
.checks-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.check-item {
  display: grid;
  grid-template-columns: 1.25rem 1fr;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.45rem 0.6rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.012);
}
.check-item[data-ok="false"] {
  border-color: rgba(244, 114, 128, 0.25);
  background: var(--bad-soft);
}
.check-item__icon {
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
  color: var(--accent);
}
.check-item[data-ok="false"] .check-item__icon { color: var(--bad); }
.check-item[data-ok="null"] .check-item__icon { color: var(--dim2); }
.check-item__name {
  font-size: 0.92rem;
  color: var(--fg);
}
.check-item__detail {
  grid-column: 2;
  font-size: 0.8rem;
  color: var(--dim);
  line-height: 1.4;
  margin-top: 0.15rem;
  word-break: break-word;
}

/* Verdict badge: oversized colored pill with glow, centered. */
.verdict-zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  margin: 1.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}
.verdict-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.85rem 2rem;
  border-radius: var(--radius-pill);
  border: 2px solid var(--accent);
  background: var(--bg-deep);
  color: var(--accent);
  font-size: 1.4rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  box-shadow: var(--glow-accent);
  transition: transform var(--motion-med), box-shadow var(--motion-med);
}
.verdict-badge:hover { transform: translateY(-1px) scale(1.01); }
.verdict-badge[data-verdict="SIGNATURE OK"],
.verdict-badge[data-verdict="SIGNATURE_OK"],
.verdict-badge[data-verdict="NO MANIFEST"],
.verdict-badge[data-verdict="NO_MANIFEST"] {
  color: var(--warn);
  border-color: var(--warn);
  box-shadow: var(--glow-warn);
}
.verdict-badge[data-verdict="UNTRUSTED"] {
  color: var(--bad);
  border-color: var(--bad);
  box-shadow: var(--glow-bad);
}
.verdict-detail-lg {
  color: var(--dim);
  font-size: 0.95rem;
  text-align: center;
  max-width: 60ch;
  margin: 0;
}

/* Share-card affordance: small footer-row inside the live card pointing to
   the downloadable PNG version (the OG image, the slack-paste artifact). */
.share-card {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px dashed var(--border);
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.85rem;
  color: var(--dim);
}
.share-card__thumb {
  flex: none;
  width: 88px;
  height: 88px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  overflow: hidden;
  background: var(--panel-hi);
  display: block;
  transition: transform var(--motion-fast), border-color var(--motion-fast);
}
.share-card__thumb:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
}
.share-card__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}
.share-card__body { flex: 1 1 14rem; min-width: 0; }
.share-card__title {
  margin: 0 0 0.15rem;
  color: var(--fg);
  font-size: 0.92rem;
  font-weight: 600;
}
.share-card__lede { margin: 0; line-height: 1.4; }

/* The legacy ``hero--report`` block (kicker + headline + verdict pill row +
   action buttons) collapses underneath the live card — keep its bones for
   the actions row but trim the duplicate headline since the live card now
   carries that affordance. */
.hero--report.hero--collapsed h1,
.hero--report.hero--collapsed .verdict-row,
.hero--report.hero--collapsed .kicker,
.hero--report.hero--collapsed .banner {
  display: none;
}
.hero--report.hero--collapsed { margin-bottom: 0.5rem; }
.hero--report.hero--collapsed .actions { margin-top: 0; }

/* Cross-check findings: yellow/red callout above the chain viz when the
   embedded EXIF/IPTC/XMP disagrees with the C2PA claim. The callout's
   border colour rolls up the highest-severity finding inside it. */
.findings {
  margin: 1.25rem 0 1.5rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--warn);
  border-left-width: 4px;
  background: var(--warn-soft);
  border-radius: var(--radius-md);
}
.findings[data-severity="high"] {
  border-color: var(--bad);
  background: var(--bad-soft);
}
.findings__title {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 0.75rem;
  font-size: 1rem;
  letter-spacing: 0.01em;
  color: var(--fg);
}
.findings__glyph {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--warn);
  color: #2a1f06;
  font-weight: 700;
}
.findings[data-severity="high"] .findings__glyph {
  background: var(--bad);
  color: #2a0a0e;
}
.findings__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.findings__item {
  padding: 0.55rem 0.7rem;
  background: rgba(0, 0, 0, 0.2);
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--warn);
}
.findings__item[data-severity="high"] { border-left-color: var(--bad); }
.findings__item[data-severity="low"] { border-left-color: var(--dim); }
.findings__item-headline {
  margin: 0 0 0.2rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--fg);
}
.findings__item-detail {
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--dim);
}

/* Capture metadata foldout: EXIF / IPTC / XMP grouped into labelled cards.
   Closed by default; opens to reveal a stack of sub-tables. */
.capture {
  margin: 1.25rem 0 0;
  padding: 0.75rem 0.9rem;
  background: var(--panel-hi);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.capture > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  user-select: none;
}
.capture > summary::-webkit-details-marker { display: none; }
.capture > summary::after {
  content: "▾";
  margin-left: auto;
  color: var(--dim);
  transition: transform var(--motion-fast);
}
.capture[open] > summary::after { transform: rotate(180deg); }
.capture__eyebrow { margin: 0; }
.capture__hint {
  font-size: 0.78rem;
  color: var(--dim);
}
.capture__body {
  margin-top: 1rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.85rem;
}
.capture-group {
  background: var(--bg-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.7rem 0.85rem;
}
.capture-group__title {
  margin: 0 0 0.5rem;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 700;
}
.capture-group__list {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.25rem 0.75rem;
  margin: 0;
  font-size: 0.86rem;
}
@media (max-width: 640px) {
  /* Repeat the mobile override here so it lands AFTER the unscoped
     rule above and actually wins the cascade — the breakpoint block
     near the top of the file is too early in source order. */
  .capture-group__list {
    grid-template-columns: 1fr;
    gap: 0.1rem 0;
  }
  .capture-group__list dt { margin-top: 0.4rem; }
  .capture-group__list dd,
  .capture-group__value-pre,
  .capture-group__value-code {
    overflow-wrap: anywhere;
    word-break: break-word;
  }
}
.capture-group__list dt {
  color: var(--dim2);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.capture-group__list dd {
  margin: 0;
  color: var(--fg);
  word-break: break-word;
  font-variant-numeric: tabular-nums;
}
.capture-group__value-code,
.capture-group__value-pre {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.82rem;
}
.capture-group__value-code {
  color: var(--fg);
}
.capture-group__value-pre {
  margin: 0.1rem 0 0;
  max-height: 16rem;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  color: var(--fg);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.55rem 0.65rem;
}
.capture-group__list dd a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(126, 230, 194, 0.5);
}
.capture-group__list dd a:hover {
  text-decoration-color: var(--accent);
}
.capture-group--other dt {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  text-transform: none;
  letter-spacing: 0;
  color: var(--dim);
}
.capture-group--other {
  grid-column: 1 / -1;
}

/* Mobile: stack the hero, ease padding, let the chain scroll horizontally. */
@media (max-width: 720px) {
  .live-card { padding: 1rem 1rem 1.25rem; border-radius: var(--radius-md); }
  .live-card__hero { grid-template-columns: 1fr; gap: 1rem; }
  .live-card__media {
    max-width: 280px;
    margin: 0 auto;
    aspect-ratio: 1 / 1;
  }
  .checks-grid { grid-template-columns: 1fr; }
  .verdict-badge { font-size: 1.1rem; padding: 0.7rem 1.4rem; }
  .meta-list { grid-template-columns: 1fr; row-gap: 0.15rem; }
  .meta-list dt { padding-top: 0.4rem; }
}

/* ============================================================
   /sign sandbox — the SSL.com cert + manifest editor + sign flow
   ============================================================ */

.sign-warn {
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  background: var(--warn-soft);
  border: 1px solid rgba(250, 200, 110, 0.3);
  border-radius: var(--radius-sm);
  color: var(--fg);
  font-size: 0.92rem;
}
.sign-warn strong { color: var(--warn); }

.sign-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
  margin-top: 1.5rem;
}
@media (max-width: 880px) {
  .sign-grid { grid-template-columns: 1fr; }
}

.sign-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 1rem 1.1rem 1.25rem;
}
.sign-card__title {
  margin: 0 0 0.75rem;
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.sign-tabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}
.sign-tab {
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  font: inherit;
  font-weight: 600;
  padding: 0.55rem 0.75rem;
  cursor: pointer;
  transition: color var(--motion-fast), border-color var(--motion-fast);
}
.sign-tab:hover { color: var(--fg); }
.sign-tab.is-active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.sign-help {
  margin: 0 0 0.75rem;
  color: var(--muted);
  font-size: 0.92rem;
}

.sign-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: flex-end;
  margin-bottom: 0.75rem;
}
.sign-row > label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: 1 1 8rem;
  font-size: 0.85rem;
  color: var(--muted);
}
.sign-card label {
  display: block;
  margin-bottom: 0.6rem;
  font-size: 0.85rem;
  color: var(--muted);
}
.sign-card input[type="text"],
.sign-card select,
.sign-card textarea {
  display: block;
  width: 100%;
  margin-top: 0.25rem;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.65rem;
  font: inherit;
}
.sign-card textarea {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.82rem;
  resize: vertical;
}
.sign-card input[type="text"]:focus,
.sign-card select:focus,
.sign-card textarea:focus {
  outline: 0;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(126, 230, 194, 0.18);
}

.sign-card .btn-primary {
  background: var(--accent);
  color: #0a1018;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 0.6rem 1.1rem;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(126, 230, 194, 0.18);
  transition: transform var(--motion-fast), box-shadow var(--motion-fast), filter var(--motion-fast);
}
.sign-card .btn-primary:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.05);
  box-shadow: 0 10px 24px rgba(126, 230, 194, 0.25);
}
.sign-card .btn-primary:disabled {
  cursor: not-allowed;
  opacity: 0.5;
  box-shadow: none;
}

.sign-status {
  margin: 0.5rem 0 0;
  font-size: 0.88rem;
  color: var(--muted);
}
.sign-status--busy { color: var(--accent); }
.sign-status--good { color: var(--accent); }
.sign-status--bad { color: var(--bad); }

.sign-card details summary {
  cursor: pointer;
  user-select: none;
  margin: 0.5rem 0;
  color: var(--muted);
}

.sign-card .recents-toggle {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin: 0.5rem 0 0.75rem;
  color: var(--muted);
  font-size: 0.88rem;
}

.footer {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--dim2);
  font-size: 0.85rem;
  text-align: center;
}
.footer a { color: var(--accent); }

/* ==== /sign post-sign inline verify panel ============================
   When /api/sign/sign returns a successful outcome, instead of
   redirecting to /r/{id} we expand this panel below the sign button.
   Lets a user sign multiple images in a row without losing the cert
   they just issued or the preset they tuned. The link inside opens
   the full report in a new tab when they want to dig in. */
.sign-result {
  margin-top: 1rem;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-deep);
}
.sign-result__header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.5rem;
}
.sign-result__detail {
  color: var(--muted);
  font-size: 0.88rem;
}
.sign-result__banner {
  margin: 0.25rem 0 0.75rem;
  color: var(--fg);
  font-size: 0.9rem;
  line-height: 1.5;
}
.sign-result__actions {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.sign-result__actions .btn-primary,
.sign-result__actions .btn-secondary {
  padding: 0.5rem 0.95rem;
  font-size: 0.88rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
}
.sign-result__actions .btn-secondary {
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--border);
}
.sign-result__actions .btn-secondary:hover { border-color: var(--accent); }

/* Inline secondary help next to a label, e.g. "this is what gets
   embedded in the image" beside the manifest editor's label. Sits to
   the right of the label text without breaking onto its own line. */
.sign-help-inline {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.78rem;
  margin-left: 0.4rem;
}

/* Preset description blurb below the picker. Helps users pick the
   right preset without reading the JSON. */
#preset-help {
  margin-top: 0.4rem;
  font-size: 0.85rem;
}
