#!/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"{html.escape(label)}" 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()