#!/usr/bin/env python3
"""Static layout contract for Review Studio HTML."""

import html


SCRIPT_INTERFACE = "internal-module"
SCRIPT_INTERFACE_REASON = "Imported by render_review_studio.py to keep Review Studio layout and CSS out of gate logic."


REVIEW_STUDIO_NAV = [
    ("#overview", "审查总览"),
    ("#intent", "意图画布"),
    ("#trigger", "触发实验"),
    ("#output", "输出实验"),
    ("#actions", "修复动作"),
    ("#annotations", "审查批注"),
    ("#runtime", "运行矩阵"),
    ("#trust", "信任报告"),
    ("#permissions", "权限批准"),
    ("#permission-probes", "权限探针"),
    ("#atlas", "组合治理"),
    ("#telemetry", "运营回路"),
    ("#waivers", "人工批准"),
    ("#world-class", "世界证据"),
    ("#registry", "注册审计"),
    ("#release", "发布路线"),
]


def render_review_nav(nav_items: list[tuple[str, str]] | None = None) -> str:
    items = REVIEW_STUDIO_NAV if nav_items is None else nav_items
    return "".join(
        f"<a href='{html.escape(href)}'>{html.escape(label)}</a>"
        for href, label in items
    )


def review_studio_css() -> str:
    return """
    :root {
      --ink: #1B365D;
      --text: #24201d;
      --muted: #746d66;
      --line: #e7ded2;
      --soft: #faf8f5;
      --pass: #1e6b52;
      --warn: #9a6718;
      --block: #9b2c2c;
    }
    * { box-sizing: border-box; }
    html { scroll-behavior: smooth; }
    body {
      margin: 0;
      background: #ffffff;
      color: var(--text);
      font-family: Georgia, "Times New Roman", "Songti SC", serif;
      line-height: 1.58;
    }
    nav {
      position: sticky;
      top: 0;
      z-index: 10;
      display: flex;
      gap: 4px;
      justify-content: center;
      flex-wrap: wrap;
      padding: 10px 16px;
      background: rgba(255,255,255,0.94);
      border-bottom: 1px solid var(--line);
      backdrop-filter: blur(10px);
    }
    nav a {
      color: var(--ink);
      text-decoration: none;
      font-size: 14px;
      padding: 7px 10px;
      border-radius: 6px;
    }
    nav a:hover { background: var(--soft); }
    main { max-width: 1180px; margin: 0 auto; padding: 44px 28px 76px; }
    header { border-bottom: 1px solid var(--line); padding-bottom: 28px; margin-bottom: 28px; }
    .eyebrow { color: var(--ink); font-size: 14px; letter-spacing: .08em; text-transform: uppercase; }
    h1, h2, h3 { color: var(--text); font-weight: 500; margin: 0; letter-spacing: 0; }
    h1 { font-size: clamp(34px, 5vw, 64px); line-height: 1.03; max-width: 920px; margin-top: 12px; }
    h2 { font-size: 30px; margin-bottom: 14px; }
    h3 { font-size: 19px; }
    p { margin: 0; }
    .lede { max-width: 820px; color: var(--muted); font-size: 20px; margin-top: 18px; }
    .decision {
      display: inline-flex;
      align-items: baseline;
      gap: 12px;
      margin-top: 24px;
      padding: 12px 16px;
      border: 1px solid var(--line);
      border-radius: 8px;
      color: var(--ink);
      background: var(--soft);
    }
    .decision strong { font-size: 28px; }
    section { padding: 30px 0; border-bottom: 1px solid var(--line); scroll-margin-top: 76px; }
    .metrics, .gates {
      display: grid;
      grid-template-columns: repeat(5, minmax(0, 1fr));
      gap: 14px;
    }
    .gates { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .metric, .gate {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 16px;
      background: #fff;
      min-width: 0;
    }
    .metric span, .gate span { display: block; color: var(--muted); font-size: 13px; }
    .metric strong { display: block; color: var(--ink); font-size: 34px; line-height: 1.1; margin: 8px 0; }
    .metric p, .gate p, .gate footer, .issues span, .evidence span { color: var(--muted); font-size: 14px; overflow-wrap: anywhere; }
    .gate { display: flex; flex-direction: column; gap: 10px; }
    .gate.pass { border-top: 4px solid var(--pass); }
    .gate.warn { border-top: 4px solid var(--warn); }
    .gate.block { border-top: 4px solid var(--block); }
    .gate footer { border-top: 1px solid var(--line); padding-top: 10px; }
    a { color: var(--ink); }
    .twocol {
      display: grid;
      grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
      gap: 22px;
      align-items: start;
    }
    .panel {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 18px;
      background: #fff;
    }
    .panel p { color: var(--muted); }
    .kv-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 10px 12px;
      margin: 2px 0 0;
    }
    .kv-grid div {
      min-width: 0;
      padding: 9px 0 0;
      border-top: 1px solid var(--line);
    }
    .kv-grid dt {
      color: var(--muted);
      font-size: 13px;
    }
    .kv-grid dd {
      margin: 2px 0 0;
      color: var(--ink);
      font-size: 15px;
      overflow-wrap: anywhere;
    }
    .issues, .evidence {
      list-style: none;
      padding: 0;
      margin: 0;
      display: grid;
      gap: 12px;
    }
    .issues li, .evidence li {
      border-left: 3px solid var(--line);
      padding-left: 12px;
      display: grid;
      gap: 3px;
    }
    .muted { color: var(--muted); }
    .actions-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 16px;
    }
    .annotations-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 16px;
    }
    .action-card {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 18px;
      background: #fff;
      display: grid;
      gap: 10px;
      min-width: 0;
    }
    .action-card.warn { border-left: 4px solid var(--warn); }
    .action-card.block { border-left: 4px solid var(--block); }
    .action-card.with-evidence {
      grid-column: 1 / -1;
    }
    .action-evidence-panel {
      display: grid;
      gap: 12px;
      border-top: 1px solid var(--line);
      padding-top: 12px;
      margin-top: 2px;
    }
    .action-evidence-panel h4 {
      margin: 0;
      color: var(--ink);
      font-size: 16px;
      font-weight: 500;
    }
    .action-evidence-panel p {
      color: var(--muted);
      font-size: 14px;
    }
    .action-evidence-grid {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 14px;
    }
    .action-evidence-item {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 14px;
      display: grid;
      gap: 10px;
      min-width: 0;
      background: var(--soft);
    }
    .action-evidence-item.pending { border-left: 4px solid var(--warn); }
    .action-evidence-item.accepted { border-left: 4px solid var(--pass); }
    .action-evidence-item h4,
    .action-evidence-item h5 {
      margin: 0;
      color: var(--ink);
      font-weight: 500;
    }
    .action-evidence-item h4 { font-size: 16px; }
    .action-evidence-item h5 { font-size: 14px; }
    .action-evidence-item section {
      border-top: 1px solid var(--line);
      padding-top: 10px;
      display: grid;
      gap: 8px;
    }
    .action-command-details,
    .action-runbook-details {
      border-top: 1px solid var(--line);
      padding-top: 10px;
      display: grid;
      gap: 8px;
    }
    .action-command-details summary,
    .action-runbook-details summary {
      cursor: pointer;
      color: var(--ink);
      font-size: 14px;
      font-weight: 500;
    }
    .action-command-details[open] summary,
    .action-runbook-details[open] summary {
      margin-bottom: 8px;
    }
    .action-evidence-item dl {
      display: grid;
      grid-template-columns: 76px minmax(0, 1fr);
      gap: 6px 10px;
      margin: 0;
    }
    .action-evidence-item dt {
      color: var(--ink);
      font-size: 14px;
    }
    .action-evidence-item dd {
      margin: 0;
      min-width: 0;
    }
    .action-evidence-checks,
    .action-command-list,
    .action-runbook-list {
      margin: 0;
      display: grid;
      gap: 8px;
    }
    .action-evidence-checks,
    .action-command-list {
      padding: 0;
      list-style: none;
    }
    .action-runbook-list {
      padding-left: 20px;
    }
    .action-evidence-check,
    .action-command-list li {
      display: grid;
      gap: 3px;
      min-width: 0;
      border-top: 1px solid var(--line);
      padding-top: 8px;
    }
    .action-evidence-check.blocked { border-left: 3px solid var(--warn); padding-left: 8px; }
    .action-evidence-check.pass { border-left: 3px solid var(--pass); padding-left: 8px; }
    .action-evidence-check span,
    .action-command-list span {
      color: var(--ink);
      font-size: 13px;
    }
    .action-evidence-check code,
    .action-evidence-check small,
    .action-command-list code,
    .action-runbook-list li {
      color: var(--muted);
      font-size: 13px;
      overflow-wrap: anywhere;
    }
    .action-command-list code {
      display: block;
      white-space: normal;
    }
    .annotation-card {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 18px;
      background: #fff;
      display: grid;
      gap: 10px;
      min-width: 0;
    }
    .annotation-card.warning { border-left: 4px solid var(--warn); }
    .annotation-card.blocker { border-left: 4px solid var(--block); }
    .annotation-card.resolved { opacity: .72; }
    .world-evidence-grid {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      gap: 16px;
      margin-top: 16px;
    }
    .world-evidence-card {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 18px;
      background: #fff;
      display: grid;
      gap: 12px;
      min-width: 0;
    }
    .world-evidence-card.pending { border-left: 4px solid var(--warn); }
    .world-evidence-card.accepted { border-left: 4px solid var(--pass); }
    .world-evidence-card span,
    .world-evidence-card p,
    .world-evidence-card dd,
    .world-evidence-card li {
      color: var(--muted);
      font-size: 14px;
      overflow-wrap: anywhere;
    }
    .world-evidence-card dl {
      display: grid;
      grid-template-columns: 86px minmax(0, 1fr);
      gap: 6px 10px;
      margin: 0;
    }
    .world-evidence-card dt { color: var(--ink); font-size: 14px; }
    .world-evidence-card dd { margin: 0; }
    .world-evidence-columns {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 12px;
      border-top: 1px solid var(--line);
      padding-top: 12px;
    }
    .world-evidence-columns h4 {
      margin: 0 0 6px;
      color: var(--ink);
      font-size: 14px;
      font-weight: 500;
    }
    .world-evidence-columns ul {
      margin: 0;
      padding-left: 18px;
    }
    .world-source-panel {
      border-top: 1px solid var(--line);
      padding-top: 12px;
    }
    .world-runbook-panel {
      border-top: 1px solid var(--line);
      padding-top: 12px;
    }
    .world-runbook-panel h4,
    .world-source-panel h4 {
      margin: 0 0 8px;
      color: var(--ink);
      font-size: 14px;
      font-weight: 500;
    }
    .world-runbook-panel ul {
      margin: 0;
      padding-left: 18px;
    }
    .world-source-checks {
      list-style: none;
      padding: 0;
      margin: 0;
      display: grid;
      gap: 8px;
    }
    .world-source-check {
      display: grid;
      grid-template-columns: minmax(0, .7fr) minmax(0, .6fr) minmax(0, 1fr);
      gap: 10px;
      align-items: start;
      min-width: 0;
      padding: 9px 0 0;
      border-top: 1px solid var(--line);
    }
    .world-source-check span {
      color: var(--ink);
      font-size: 14px;
    }
    .world-source-check code,
    .world-source-check small {
      color: var(--muted);
      font-size: 13px;
      overflow-wrap: anywhere;
    }
    .world-source-check.pass { border-left: 3px solid var(--pass); padding-left: 8px; }
    .world-source-check.blocked { border-left: 3px solid var(--warn); padding-left: 8px; }
    .output-review-grid {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      gap: 16px;
      margin-top: 16px;
    }
    .output-review-card {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 18px;
      background: #fff;
      display: grid;
      gap: 12px;
      min-width: 0;
    }
    .output-review-card.awaiting-decision,
    .output-review-card.fix-decision { border-left: 4px solid var(--warn); }
    .output-review-card.adjudicated { border-left: 4px solid var(--pass); }
    .output-review-card span,
    .output-review-card p,
    .output-review-card dd,
    .output-review-card li {
      color: var(--muted);
      font-size: 14px;
      overflow-wrap: anywhere;
    }
    .output-review-card dl {
      display: grid;
      grid-template-columns: 86px minmax(0, 1fr);
      gap: 6px 10px;
      margin: 0;
    }
    .output-review-card dt { color: var(--ink); font-size: 14px; }
    .output-review-card dd { margin: 0; min-width: 0; }
    .output-review-steps {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 12px;
      border-top: 1px solid var(--line);
      padding-top: 12px;
    }
    .output-review-steps h4 {
      margin: 0 0 6px;
      color: var(--ink);
      font-size: 14px;
      font-weight: 500;
    }
    .output-review-steps ul {
      margin: 0;
      padding-left: 18px;
    }
    .output-review-commands,
    .output-review-fields {
      list-style: none;
      padding: 0;
      display: grid;
      gap: 8px;
    }
    .output-review-commands li,
    .output-review-fields li {
      display: grid;
      gap: 2px;
      min-width: 0;
      padding: 8px 0 0;
      border-top: 1px solid var(--line);
    }
    .output-review-commands code {
      overflow-wrap: anywhere;
      white-space: normal;
      display: block;
    }
    .world-intake-grid {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      gap: 16px;
      margin-top: 16px;
    }
    .world-intake-card {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 18px;
      background: #fff;
      display: grid;
      gap: 12px;
      min-width: 0;
    }
    .world-intake-card.awaiting-submission,
    .world-intake-card.fix-submission,
    .world-intake-card.fix-template { border-left: 4px solid var(--warn); }
    .world-intake-card.ready-for-ledger-review,
    .world-intake-card.accepted { border-left: 4px solid var(--pass); }
    .world-intake-card span,
    .world-intake-card p,
    .world-intake-card dd,
    .world-intake-card li {
      color: var(--muted);
      font-size: 14px;
      overflow-wrap: anywhere;
    }
    .world-intake-card dl {
      display: grid;
      grid-template-columns: 86px minmax(0, 1fr);
      gap: 6px 10px;
      margin: 0;
    }
    .world-intake-card dt { color: var(--ink); font-size: 14px; }
    .world-intake-card dd { margin: 0; min-width: 0; }
    .world-intake-steps {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 12px;
      border-top: 1px solid var(--line);
      padding-top: 12px;
    }
    .world-intake-steps h4 {
      margin: 0 0 6px;
      color: var(--ink);
      font-size: 14px;
      font-weight: 500;
    }
    .world-intake-steps ul {
      margin: 0;
      padding-left: 18px;
    }
    .world-intake-commands {
      list-style: none;
      padding: 0;
      display: grid;
      gap: 8px;
    }
    .world-intake-commands li {
      display: grid;
      gap: 2px;
      min-width: 0;
      padding: 8px 0 0;
      border-top: 1px solid var(--line);
    }
    .world-intake-commands code {
      overflow-wrap: anywhere;
      white-space: normal;
      display: block;
    }
    .section-subtitle {
      margin-top: 22px;
      margin-bottom: 12px;
      color: var(--ink);
    }
    .waiver-summary { margin-top: 16px; }
    .waiver-candidate-grid {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      gap: 16px;
    }
    .waiver-card {
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 18px;
      background: #fff;
      display: grid;
      gap: 12px;
      min-width: 0;
    }
    .waiver-card.allowed { border-left: 4px solid var(--warn); }
    .waiver-card.blocked { border-left: 4px solid var(--block); }
    .waiver-card span,
    .waiver-card p,
    .waiver-card dd,
    .waiver-card li {
      color: var(--muted);
      font-size: 14px;
      overflow-wrap: anywhere;
    }
    .waiver-card dl {
      display: grid;
      grid-template-columns: 86px minmax(0, 1fr);
      gap: 6px 10px;
      margin: 0;
    }
    .waiver-card dt {
      color: var(--ink);
      font-size: 14px;
    }
    .waiver-card dd { margin: 0; min-width: 0; }
    .waiver-review {
      border-top: 1px solid var(--line);
      padding-top: 12px;
    }
    .waiver-review h4 {
      margin: 0 0 6px;
      color: var(--ink);
      font-size: 14px;
      font-weight: 500;
    }
    .waiver-review ul {
      margin: 0;
      padding-left: 18px;
    }
    .waiver-command {
      display: grid;
      gap: 4px;
      border-top: 1px solid var(--line);
      padding-top: 12px;
    }
    .waiver-command span {
      color: var(--ink);
      font-size: 14px;
    }
    .waiver-command code {
      display: block;
      max-width: 100%;
      overflow-wrap: anywhere;
      white-space: normal;
    }
    .action-card span,
    .annotation-card span,
    .action-card small,
    .annotation-card small,
    .action-card footer,
    .annotation-card footer,
    .action-card dd {
      color: var(--muted);
      font-size: 14px;
      overflow-wrap: anywhere;
    }
    .annotation-card dd { color: var(--muted); font-size: 14px; overflow-wrap: anywhere; }
    .action-card dl, .annotation-card dl {
      display: grid;
      grid-template-columns: 80px minmax(0, 1fr);
      gap: 6px 10px;
      margin: 0;
    }
    .action-card dt, .annotation-card dt { color: var(--ink); font-size: 14px; }
    .action-card dd, .annotation-card dd { margin: 0; }
    .source-ref-list {
      list-style: none;
      padding: 0;
      margin: 0;
      display: grid;
      gap: 6px;
    }
    .source-ref-list li {
      display: grid;
      gap: 2px;
      min-width: 0;
      padding: 8px 0 0;
      border-top: 1px solid var(--line);
    }
    .source-ref-list a,
    .source-ref-list span {
      overflow-wrap: anywhere;
      font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
      font-size: 13px;
    }
    .source-ref-list small {
      font-size: 12px;
      color: var(--muted);
    }
    code {
      font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
      font-size: 13px;
    }
    @media (max-width: 980px) {
      .metrics, .gates, .twocol, .actions-grid, .annotations-grid, .action-evidence-grid, .action-evidence-item dl, .output-review-grid, .output-review-steps, .world-evidence-grid, .world-evidence-columns, .world-source-check, .world-intake-grid, .world-intake-steps, .waiver-candidate-grid, .waiver-card dl, .kv-grid { grid-template-columns: 1fr; }
      main { padding: 32px 18px 60px; }
      nav { justify-content: flex-start; overflow-x: auto; flex-wrap: nowrap; }
      nav a { flex: 0 0 auto; }
    }
    """.strip()
