@aarwitz/tapp 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/AGENTS.md +123 -0
  2. package/Harness/OCQAHarness/AppDelegate.swift +21 -0
  3. package/Harness/OCQAHarness/Info.plist +26 -0
  4. package/Harness/OCQAHarness.xcodeproj/project.pbxproj +199 -0
  5. package/Harness/OCQAHarness.xcodeproj/xcshareddata/xcschemes/OCQAHarnessUITests.xcscheme +22 -0
  6. package/Harness/OCQAHarnessUITests/ExplorerTests.swift +4526 -0
  7. package/Harness/OCQAHarnessUITests/Info.plist +22 -0
  8. package/Harness/generate-harness-xcodeproj.rb +254 -0
  9. package/LICENSE +21 -0
  10. package/README.md +374 -0
  11. package/bin/tapp.js +1382 -0
  12. package/browser/app.css +227 -0
  13. package/browser/app.js +675 -0
  14. package/browser/index.html +195 -0
  15. package/browser/product-contract.js +25 -0
  16. package/browser/view-model.js +16 -0
  17. package/docs/BROWSER-PRODUCT.md +72 -0
  18. package/docs/PRODUCT-ENGINE.md +102 -0
  19. package/docs/application-model.md +276 -0
  20. package/docs/scenarios.md +95 -0
  21. package/mcp-server/src/android-driver.js +287 -0
  22. package/mcp-server/src/android-explorer.js +197 -0
  23. package/mcp-server/src/android-flow.js +89 -0
  24. package/mcp-server/src/application-model.js +1597 -0
  25. package/mcp-server/src/browser-product.js +659 -0
  26. package/mcp-server/src/browser-workspaces.js +234 -0
  27. package/mcp-server/src/ci-report.js +557 -0
  28. package/mcp-server/src/ci-setup.js +359 -0
  29. package/mcp-server/src/contract-authoring.js +10 -0
  30. package/mcp-server/src/enrich.js +57 -0
  31. package/mcp-server/src/flow-runtime.js +127 -0
  32. package/mcp-server/src/html-report.js +124 -0
  33. package/mcp-server/src/index.js +3775 -0
  34. package/mcp-server/src/maintenance-proposal.js +178 -0
  35. package/mcp-server/src/managed-operation.js +61 -0
  36. package/mcp-server/src/pr-selection.js +841 -0
  37. package/mcp-server/src/product-execution.js +155 -0
  38. package/mcp-server/src/product-operations.js +526 -0
  39. package/mcp-server/src/project-config.js +101 -0
  40. package/mcp-server/src/release-contract.d.ts +81 -0
  41. package/mcp-server/src/release-contract.js +226 -0
  42. package/mcp-server/src/report.js +363 -0
  43. package/mcp-server/src/scenario-runtime.js +139 -0
  44. package/mcp-server/src/static-server.js +44 -0
  45. package/mcp-server/src/task-runtime.js +266 -0
  46. package/mcp-server/src/ui-map.js +661 -0
  47. package/mcp-server/src/web-explorer.js +493 -0
  48. package/mcp-server/src/web-flow.js +238 -0
  49. package/package.json +82 -0
  50. package/scripts/android-corpus-e2e.sh +30 -0
  51. package/scripts/ci-gate.sh +323 -0
  52. package/scripts/cleanup-xcode.sh +157 -0
  53. package/scripts/compile-contract.js +27 -0
  54. package/scripts/compile-flow.js +18 -0
  55. package/scripts/corpus-apps.txt +9 -0
  56. package/scripts/corpus-sweep.sh +121 -0
  57. package/scripts/coverage-eval.sh +92 -0
  58. package/scripts/coverage_eval_parse.py +95 -0
  59. package/scripts/deploy-and-build.sh +99 -0
  60. package/scripts/flow-platform.js +18 -0
  61. package/scripts/flow_ai_judge.py +102 -0
  62. package/scripts/flow_lib.py +154 -0
  63. package/scripts/mutation-recall-desktop.sh +186 -0
  64. package/scripts/mutation-recall.sh +121 -0
  65. package/scripts/mutation_lib.py +128 -0
  66. package/scripts/mutation_operators.py +144 -0
  67. package/scripts/platform-gate.js +186 -0
  68. package/scripts/pr-plan.js +68 -0
  69. package/scripts/quick-capture.sh +419 -0
  70. package/scripts/run-android-flow.js +27 -0
  71. package/scripts/run-flow.sh +90 -0
  72. package/scripts/run-web-flow.js +28 -0
  73. package/scripts/run-web-scenario.js +23 -0
  74. package/scripts/validation-matrix.sh +146 -0
  75. package/scripts/vision-fp-eval.sh +206 -0
  76. package/scripts/vision_escalation_responder.py +147 -0
  77. package/scripts/vision_fp_probe.py +221 -0
@@ -0,0 +1,227 @@
1
+ :root {
2
+ --ink:#18201c; --muted:#66706a; --faint:#8c958f; --line:#dce4de; --paper:#fcfdfb; --wash:#f2f5f2;
3
+ --green:#176a46; --green-2:#2f8a61; --green-3:#73bd8f; --lime:#dff3e4; --amber:#94600d;
4
+ --amber-bg:#fff3d5; --red:#a33a33; --red-bg:#fde8e5; --blue:#315b77; --sidebar:#18231d;
5
+ --shadow:0 16px 50px rgba(31,55,42,.08); --small-shadow:0 7px 22px rgba(31,55,42,.07);
6
+ }
7
+ * { box-sizing:border-box; }
8
+ html { scroll-behavior:smooth; }
9
+ body { margin:0; min-height:100vh; background:#eef2ee; color:var(--ink); font:15px/1.5 Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
10
+ button,input,select { font:inherit; }
11
+ button { cursor:pointer; }
12
+ button:focus-visible,input:focus-visible,select:focus-visible,[tabindex]:focus-visible { outline:3px solid rgba(47,138,97,.24); outline-offset:2px; }
13
+ .hidden { display:none!important; }
14
+ .muted { color:var(--muted); }
15
+ .eyebrow { margin:0 0 8px; color:var(--green); font-size:10px; font-weight:850; letter-spacing:.14em; }
16
+ h1,h2,h3,p { margin-top:0; }
17
+ h1 { margin-bottom:10px; font-size:40px; line-height:1.08; letter-spacing:-.045em; }
18
+ h2 { margin-bottom:7px; font-size:23px; letter-spacing:-.028em; }
19
+ h3 { margin-bottom:6px; }
20
+ code { font:11px/1.45 ui-monospace,SFMono-Regular,Menlo,monospace; }
21
+
22
+ .topbar { height:64px; padding:0 22px; display:flex; align-items:center; justify-content:space-between; background:rgba(252,253,251,.96); border-bottom:1px solid var(--line); position:sticky; top:0; z-index:40; backdrop-filter:blur(18px); }
23
+ .brand { display:flex; align-items:center; gap:9px; padding:0; border:0; background:transparent; color:var(--ink); font-weight:800; font-size:18px; letter-spacing:-.02em; }
24
+ .brand small { margin-left:4px; padding-left:12px; border-left:1px solid var(--line); color:var(--muted); font-size:11px; font-weight:650; letter-spacing:.02em; }
25
+ .brand-mark { display:grid; place-items:center; width:29px; height:29px; border-radius:9px; background:var(--green); color:white; font:bold 20px/1 Georgia,serif; }
26
+ .top-actions,.button-row,.plan-toolbar { display:flex; align-items:center; gap:10px; }
27
+ .mode-pill,.status-chip { border:1px solid var(--line); background:white; color:var(--muted); border-radius:999px; padding:5px 10px; font-size:11px; white-space:nowrap; }
28
+ .repository-switcher { max-width:330px; padding:7px 30px 7px 10px; border:1px solid var(--line); border-radius:9px; background:white; color:var(--ink); font-size:12px; }
29
+
30
+ button { border-radius:9px; padding:9px 14px; border:1px solid transparent; font-weight:720; font-size:12px; }
31
+ button.primary { background:var(--green); color:white; } button.primary:hover { background:#105b3b; }
32
+ button.secondary { color:var(--green); border-color:#b9d2c1; background:white; } button.secondary:hover,button.quiet:hover { background:var(--wash); }
33
+ button.quiet { border-color:var(--line); background:transparent; color:var(--muted); padding:7px 11px; }
34
+ button:disabled { cursor:not-allowed; opacity:.45; }
35
+ .button-link { display:inline-flex; align-items:center; margin-top:10px; padding:8px 11px; border:1px solid #bbd2c2; border-radius:9px; color:var(--green); font-size:11px; font-weight:750; text-decoration:none; }
36
+ .button-link:hover { background:var(--wash); }
37
+
38
+ /* Repository source onboarding */
39
+ .source-onboarding { width:min(1140px,calc(100% - 48px)); margin:0 auto; padding:70px 0 90px; }
40
+ .welcome-copy { max-width:790px; margin:0 auto 42px; text-align:center; }
41
+ .welcome-copy h1 { font-size:58px; letter-spacing:-.06em; }
42
+ .welcome-copy>p:not(.eyebrow) { max-width:720px; margin:0 auto; color:var(--muted); font-size:17px; }
43
+ .platform-row { display:flex; justify-content:center; gap:8px; margin-top:22px; }
44
+ .platform-row span { min-width:72px; padding:5px 12px; border:1px solid #cddbd1; border-radius:999px; background:rgba(255,255,255,.75); color:var(--green); font-size:11px; font-weight:800; }
45
+ .source-choices { display:grid; grid-template-columns:1fr 1fr; gap:18px; }
46
+ .source-card { min-height:320px; padding:34px; border:1px solid var(--line); border-radius:20px; background:var(--paper); box-shadow:var(--shadow); display:flex; flex-direction:column; align-items:flex-start; transition:.18s ease; }
47
+ .source-card:hover,.source-card.dragging { transform:translateY(-2px); border-color:#9ec6aa; box-shadow:0 20px 56px rgba(31,75,49,.12); }
48
+ .source-card.dragging { background:#f0faf2; box-shadow:inset 0 0 0 2px var(--green-3),var(--shadow); }
49
+ .source-card .source-icon { width:45px; height:45px; display:grid; place-items:center; margin-bottom:24px; border-radius:13px; background:var(--lime); color:var(--green); font-size:23px; font-weight:800; }
50
+ .github-card .source-icon { background:#e8edf1; color:#324a58; }
51
+ .source-card h2 { font-size:27px; }
52
+ .source-card>p:not(.eyebrow) { flex:1; color:var(--muted); max-width:430px; }
53
+ .source-card>small { margin-top:16px; color:var(--faint); font-size:10px; }
54
+ .privacy-note { max-width:810px; margin:26px auto 0; padding:16px 20px; display:flex; align-items:center; justify-content:center; gap:10px; color:var(--muted); font-size:12px; }
55
+ .privacy-note strong { color:var(--ink); }
56
+
57
+ /* Product shell */
58
+ .product-shell { min-height:calc(100vh - 64px); display:grid; grid-template-columns:224px minmax(0,1fr); }
59
+ .sidebar { position:sticky; top:64px; height:calc(100vh - 64px); padding:19px 13px 15px; background:var(--sidebar); color:#eef5f0; display:flex; flex-direction:column; z-index:20; }
60
+ .project-identity { display:flex; align-items:center; gap:10px; padding:4px 8px 20px; border-bottom:1px solid rgba(255,255,255,.09); }
61
+ .project-avatar { width:34px; height:34px; display:grid; place-items:center; border-radius:10px; background:linear-gradient(135deg,#73bd8f,#3b825c); color:white; font-weight:800; }
62
+ .project-identity div { min-width:0; display:flex; flex-direction:column; }
63
+ .project-identity strong { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; }
64
+ .project-identity small { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:#95a79b; font-size:9px; }
65
+ .primary-nav { margin-top:17px; display:flex; flex-direction:column; gap:3px; }
66
+ .primary-nav button { width:100%; padding:10px 11px; display:grid; grid-template-columns:20px 1fr auto; gap:7px; text-align:left; border:0; background:transparent; color:#9faea4; font-weight:650; }
67
+ .primary-nav button:hover { color:white; background:rgba(255,255,255,.055); }
68
+ .primary-nav button.active { color:white; background:rgba(115,189,143,.14); }
69
+ .primary-nav button>span { color:#7f9587; text-align:center; }.primary-nav button.active>span { color:#8dd0a5; }
70
+ .primary-nav i { min-width:19px; padding:1px 5px; border-radius:999px; background:rgba(255,255,255,.08); color:#a9b8ae; font-size:9px; font-style:normal; text-align:center; }
71
+ .sidebar-context { margin-top:auto; padding:13px 10px; border-radius:10px; background:rgba(255,255,255,.045); display:flex; flex-direction:column; }
72
+ .sidebar-context .eyebrow { color:#70bd8e; }.sidebar-context strong { font-size:11px; }.sidebar-context small { color:#91a298; font-size:9px; margin-top:3px; }
73
+ .sidebar-source { margin-top:8px; padding:8px; border:0; background:transparent; color:#92a59a; text-align:left; font-size:10px; }.sidebar-source:hover { color:white; }
74
+ .keyless-note { margin-top:7px; padding:12px 9px 4px; display:flex; align-items:flex-start; gap:8px; border-top:1px solid rgba(255,255,255,.08); }
75
+ .keyless-note>span { color:#64c586; font-size:9px; }.keyless-note div { display:flex; flex-direction:column; }.keyless-note strong { font-size:10px; }.keyless-note small { color:#83968a; font-size:8px; }
76
+ .workspace { width:min(1420px,100%); padding:32px clamp(24px,4vw,58px) 80px; }
77
+ .workspace-view { display:none; }.workspace-view.active { display:block; }
78
+ .view-heading { display:grid; grid-template-columns:1fr 320px; gap:38px; align-items:center; margin-bottom:20px; }
79
+ .view-heading.simple { display:flex; justify-content:space-between; align-items:flex-start; }
80
+ .view-heading>div:first-child>p:last-child { max-width:830px; color:var(--muted); margin-bottom:0; }
81
+ .panel { background:var(--paper); border:1px solid var(--line); border-radius:16px; box-shadow:var(--small-shadow); }
82
+ .section { padding:28px 31px; margin-top:16px; scroll-margin-top:82px; }
83
+ .section-heading { display:flex; justify-content:space-between; gap:28px; align-items:flex-start; margin-bottom:20px; }
84
+ .section-heading.compact { margin-bottom:14px; align-items:center; }
85
+ .section-heading p:not(.eyebrow) { color:var(--muted); max-width:760px; margin-bottom:0; }
86
+ .metric { font-size:24px; font-weight:780; white-space:nowrap; }
87
+ .decision-card { min-height:136px; padding:20px; border-radius:15px; display:flex; flex-direction:column; justify-content:center; border:1px solid var(--line); background:white; }
88
+ .decision-card.ready { background:var(--lime); border-color:#b7dfc3; }.decision-card.blocked { background:var(--red-bg); border-color:#efc4bd; }.decision-card.caution { background:var(--amber-bg); border-color:#edd69a; }
89
+ .decision-label { font-size:9px; font-weight:850; letter-spacing:.12em; color:var(--muted); }.decision-card strong { font-size:21px; margin:4px 0; }.decision-card span:last-child { color:var(--muted); font-size:11px; }
90
+ .journey { margin:18px 0 3px; display:grid; grid-template-columns:repeat(6,1fr); gap:1px; overflow:hidden; border:1px solid var(--line); border-radius:13px; background:var(--line); }
91
+ .journey button { display:grid; grid-template-columns:26px 1fr; column-gap:8px; padding:13px 11px; text-align:left; border:0; border-radius:0; background:var(--paper); color:var(--ink); }
92
+ .journey button:hover { background:#f5f8f5; }.journey button span { grid-row:1/3; display:grid; place-items:center; width:25px; height:25px; border:1px solid var(--line); border-radius:50%; color:var(--muted); font-size:10px; }.journey button.done span { background:var(--green); border-color:var(--green); color:white; }.journey b { font-size:11px; }.journey small { color:var(--muted); font-size:9px; }
93
+
94
+ /* Targets and configuration */
95
+ .target-choice-callout { margin:-2px 0 14px; padding:12px 14px; display:flex; align-items:center; gap:11px; border:1px solid #bdd8c4; border-radius:12px; background:linear-gradient(135deg,#f1faf3,#fbfdfb); }
96
+ .target-choice-callout>span { width:28px; height:28px; flex:0 0 auto; display:grid; place-items:center; border-radius:50%; background:var(--green); color:white; font-size:11px; font-weight:850; }
97
+ .target-choice-callout>div { display:flex; flex-direction:column; gap:2px; }.target-choice-callout strong { font-size:12px; }.target-choice-callout small { color:var(--muted); font-size:9px; }
98
+ .target-choice-callout.hidden { display:none; }
99
+ .requires-choice .target-grid { padding:6px; margin:-6px; border-radius:15px; background:rgba(42,125,67,.045); }
100
+ .target-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:10px; }
101
+ .target-card { min-height:94px; padding:14px; display:grid; grid-template-columns:38px 1fr 17px; gap:12px; text-align:left; border:1px solid var(--line); border-radius:12px; background:white; color:var(--ink); }
102
+ .target-card:hover { border-color:#78ad87; background:#f8fbf8; transform:translateY(-1px); box-shadow:0 7px 18px rgba(19,56,31,.08); }.target-card:focus-visible { outline:3px solid rgba(42,125,67,.2); outline-offset:2px; }.target-card.selected { border-color:var(--green-2); box-shadow:inset 0 0 0 1px var(--green-2),0 8px 20px rgba(23,86,43,.09); background:#f2faf4; }
103
+ .target-card>span:nth-child(2) { display:flex; flex-direction:column; }.target-card b { font-size:13px; }.target-card small { margin:2px 0 6px; color:var(--muted); font-size:9px; font-weight:500; }.target-card>i { color:var(--green); font-style:normal; }
104
+ .platform-icon { width:36px; height:36px; display:grid!important; place-items:center; border-radius:10px; background:#e7eef2; color:#315b77; font-size:10px; font-weight:850; }.platform-icon.ios { background:#e8e9eb; color:#30363a; }.platform-icon.android { background:#e3f2e5; color:#277844; }
105
+ .target-state { align-self:flex-start; width:max-content; padding:2px 6px; border-radius:999px; background:var(--wash); color:var(--muted); font-size:8px; font-style:normal; text-transform:uppercase; letter-spacing:.06em; }.target-state.configured { background:var(--lime); color:var(--green); }
106
+ .runtime-row { display:grid; grid-template-columns:minmax(260px,1fr) auto; gap:14px; align-items:stretch; margin-top:14px; }
107
+ .field { display:flex; flex-direction:column; gap:6px; padding:12px 13px; border:1px solid var(--line); background:white; border-radius:11px; }.field span { font-size:10px; font-weight:750; }.field i { color:var(--muted); font-weight:500; }.field small { color:var(--muted); font-size:9px; }.field input { min-width:0; padding:7px 0; border:0; border-bottom:1px solid var(--line); outline:none; background:transparent; }.field input:focus { border-color:var(--green-2); }
108
+ .run-cta { min-width:235px; padding:12px 14px; display:flex; flex-direction:column; justify-content:center; align-items:flex-start; gap:6px; border-radius:11px; background:var(--wash); }.run-cta small { max-width:300px; color:var(--muted); font-size:9px; }
109
+ .requirements { margin:14px 0 0; padding:0; list-style:none; }.requirements li { margin-top:7px; padding:10px 12px; display:flex; gap:9px; border-radius:9px; background:var(--amber-bg); color:#6d4b16; font-size:11px; }.requirements li>span { width:19px; height:19px; display:grid; place-items:center; flex:0 0 auto; border-radius:50%; background:rgba(148,96,13,.12); font-weight:850; }.requirements li div { display:flex; flex-direction:column; }.requirements li small { margin-top:2px; }.requirements li.blocking { background:var(--red-bg); color:#79332f; }
110
+ .overview-grid { display:grid; grid-template-columns:1.2fr .8fr; gap:16px; margin-top:16px; }.summary-panel { padding:24px; }.latest-run-line { display:flex; align-items:flex-start; gap:10px; }.latest-run-line div { display:flex; flex-direction:column; }.latest-run-line small { color:var(--muted); font-size:9px; }.latest-run-line+p { margin:11px 0 0; color:var(--muted); font-size:11px; }.verdict-dot { width:10px; height:10px; margin-top:5px; border-radius:50%; background:var(--amber); }.verdict-dot.ready { background:var(--green-2); }.verdict-dot.blocked { background:var(--red); }
111
+ .metric-grid { display:grid; grid-template-columns:1fr 1fr; gap:9px; }.metric-grid div { padding:11px; border-radius:10px; background:var(--wash); display:flex; flex-direction:column; }.metric-grid strong { font-size:20px; }.metric-grid small { color:var(--muted); font-size:9px; }
112
+
113
+ /* Shared live application surface */
114
+ .live-layout { display:grid; grid-template-columns:minmax(360px,1fr) minmax(300px,.85fr); gap:14px; align-items:start; }
115
+ .live-frame-shell,.live-controls { border:1px solid var(--line); border-radius:13px; background:white; overflow:hidden; }
116
+ .live-frame-head,.live-controls-heading { min-height:42px; padding:10px 13px; display:flex; align-items:center; justify-content:space-between; border-bottom:1px solid var(--line); background:var(--wash); color:var(--muted); font-size:9px; }
117
+ .live-frame { position:relative; min-height:430px; display:grid; place-items:center; overflow:hidden; background:#101612; }
118
+ .live-frame img { display:block; max-width:100%; max-height:680px; object-fit:contain; }
119
+ .live-frame #live-frame-loading { position:absolute; inset:0; display:grid; place-items:center; color:#9db0a3; font-size:10px; background:#101612; }
120
+ .flow-recorder { padding:13px; display:grid; grid-template-columns:minmax(180px,1fr) minmax(170px,.7fr) auto; gap:12px; align-items:end; border-top:1px solid var(--line); }
121
+ .flow-recorder>div { display:flex; flex-direction:column; gap:3px; }.flow-recorder strong { font-size:10px; }.flow-recorder small { color:var(--muted); font-size:8px; line-height:1.5; }.flow-recorder label { display:flex; flex-direction:column; gap:4px; }.flow-recorder label span { color:var(--muted); font-size:8px; }.flow-recorder input { width:100%; }
122
+ .live-controls-heading div { display:flex; flex-direction:column; }.live-controls-heading strong { color:var(--ink); font-size:11px; }.live-controls-heading small { font-size:8px; }
123
+ #live-control-list { max-height:380px; overflow:auto; }
124
+ .live-control { width:100%; padding:10px 12px; display:grid; grid-template-columns:1fr auto; gap:10px; text-align:left; border:0; border-bottom:1px solid var(--line); border-radius:0; background:white; color:var(--ink); }
125
+ .live-control:hover { background:#f3f8f4; }.live-control:disabled { opacity:.5; }.live-control span { min-width:0; display:flex; flex-direction:column; }.live-control strong { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:10px; }.live-control small { color:var(--muted); font-size:8px; }.live-control em { align-self:center; padding:2px 6px; border-radius:999px; background:var(--wash); color:var(--muted); font-size:7px; font-style:normal; text-transform:uppercase; }
126
+ .manual-action { padding:12px; border-top:1px solid var(--line); background:var(--wash); }.manual-action label { display:flex; flex-direction:column; gap:3px; margin-bottom:8px; }.manual-action label span { color:var(--muted); font-size:8px; font-weight:750; }.manual-action label i { font-weight:500; }.manual-action input { padding:7px 8px; border:1px solid var(--line); border-radius:7px; background:white; font-size:10px; }
127
+
128
+ /* Runs and findings */
129
+ .split-view { display:grid; grid-template-columns:minmax(300px,.8fr) minmax(480px,1.2fr); gap:14px; align-items:start; }.list-panel,.detail-panel { overflow:hidden; }.detail-panel { padding:24px; min-height:420px; }
130
+ .run-row,.finding-row { width:100%; padding:14px 15px; display:grid; grid-template-columns:34px 1fr auto; gap:10px; align-items:center; text-align:left; border:0; border-bottom:1px solid var(--line); border-radius:0; background:white; color:var(--ink); }.run-row:last-child,.finding-row:last-child { border-bottom:0; }.run-row:hover,.finding-row:hover { background:#f6f9f6; }.run-row.selected,.finding-row.selected { background:#eef8f1; box-shadow:inset 3px 0 var(--green-2); }
131
+ .run-row>span:nth-child(2),.finding-row>span:nth-child(2) { min-width:0; display:flex; flex-direction:column; }.run-row strong,.finding-row strong { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:11px; }.run-row small,.finding-row small { color:var(--muted); font-size:9px; }.run-row em,.finding-row em { color:var(--muted); font-size:8px; font-style:normal; text-transform:uppercase; letter-spacing:.05em; }
132
+ .run-status { width:28px; height:28px; display:grid; place-items:center; border-radius:50%; background:var(--lime); color:var(--green); }.run-status.blocked { background:var(--red-bg); color:var(--red); }.run-status.inconclusive,.run-status.caution { background:var(--amber-bg); color:var(--amber); }
133
+ .severity { width:8px; height:30px; border-radius:999px; background:#9ba49e; }.severity.critical,.severity.high { background:var(--red); }.severity.medium { background:var(--amber); }.severity.low { background:var(--blue); }
134
+ .run-detail-head { display:flex; justify-content:space-between; gap:20px; align-items:flex-start; padding-bottom:18px; border-bottom:1px solid var(--line); }.run-detail-head small { color:var(--muted); }.run-stats { margin:16px 0 22px; display:grid; grid-template-columns:repeat(4,1fr); gap:8px; }.run-stats div { padding:10px; background:var(--wash); border-radius:9px; display:flex; flex-direction:column; }.run-stats strong { font-size:18px; }.run-stats small { color:var(--muted); font-size:9px; }.detail-panel>h3 { margin-top:20px; font-size:12px; }.detail-list { margin:6px 0 0; padding-left:18px; color:var(--muted); font-size:10px; }.detail-list.boundary { color:#86612b; }.contract-result { padding:9px 0; display:flex; gap:9px; border-bottom:1px solid var(--line); }.contract-result>span { font-weight:850; }.contract-result .pass { color:var(--green); }.contract-result .fail { color:var(--red); }.contract-result div { display:flex; flex-direction:column; }.contract-result strong { font-size:10px; }.contract-result small { color:var(--muted); font-size:9px; }
135
+ .findings-layout { grid-template-columns:minmax(330px,.85fr) minmax(430px,1.15fr); }.detail-dl,.settings-dl { margin:16px 0; }.detail-dl div,.settings-dl div { display:grid; grid-template-columns:110px 1fr; gap:10px; padding:7px 0; border-bottom:1px solid var(--line); }.detail-dl dt,.settings-dl dt { color:var(--muted); font-size:10px; }.detail-dl dd,.settings-dl dd { margin:0; overflow-wrap:anywhere; font-size:10px; }.detail-panel pre { max-height:220px; overflow:auto; padding:12px; background:#111a15; color:#dce8df; border-radius:9px; font-size:9px; }.honesty { padding:10px 12px; border-left:3px solid var(--amber); background:var(--amber-bg); color:#73531e; font-size:9px; }
136
+
137
+ /* Coverage */
138
+ .subnav { display:flex; gap:4px; margin-bottom:13px; padding:4px; width:max-content; border:1px solid var(--line); border-radius:10px; background:var(--paper); }.subnav button { border:0; background:transparent; color:var(--muted); }.subnav button.active { background:var(--ink); color:white; }
139
+ .coverage-panel { display:none; }.coverage-panel.active { display:block; }
140
+ .map-layout { display:grid; grid-template-columns:minmax(0,1fr) 270px; gap:14px; }.map-canvas { min-height:330px; border:1px solid var(--line); border-radius:14px; background:linear-gradient(90deg,transparent 31px,#e8ede9 32px,transparent 33px),linear-gradient(transparent 31px,#e8ede9 32px,transparent 33px),white; background-size:32px 32px; padding:20px; display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:12px; align-content:start; }
141
+ .map-node { background:var(--paper); border:1px solid #cdd9d0; border-left:4px solid var(--green-2); border-radius:11px; padding:13px; box-shadow:var(--small-shadow); }.map-node-title { display:flex; gap:7px; }.map-node-title>span { color:var(--green-2); font-size:9px; font-weight:850; }.map-node small { color:var(--muted); font-size:9px; }.map-node .coverage { margin-top:9px; display:flex; gap:5px; flex-wrap:wrap; }.tag { border-radius:999px; padding:2px 7px; background:var(--wash); color:var(--muted); font-size:8px; }.tag.covered { background:var(--lime); color:var(--green); }.tag.warning { background:var(--amber-bg); color:var(--amber); }
142
+ .coverage-summary { border:1px solid var(--line); border-radius:14px; background:white; padding:18px; }.coverage-summary dl { margin:0; }.coverage-summary dl div { display:flex; justify-content:space-between; padding:9px 0; border-bottom:1px solid var(--line); }.coverage-summary dt { color:var(--muted); }.coverage-summary dd { margin:0; font-weight:760; }.coverage-honesty { margin:15px 0 0; color:var(--muted); font-size:9px; }
143
+ .transition-list { margin-top:13px; border:1px solid var(--line); border-radius:12px; background:white; overflow:hidden; }.transition-list h3 { margin:0; padding:13px 15px; border-bottom:1px solid var(--line); font-size:11px; }.transition-list>div { display:grid; grid-template-columns:1fr auto 1fr auto; gap:10px; align-items:center; padding:9px 15px; border-bottom:1px solid var(--line); font-size:9px; }.transition-list>div:last-child { border-bottom:0; }.transition-list span,.transition-list em { color:var(--muted); }.transition-list em { font-style:normal; }
144
+ .table-panel { overflow:auto; }.table-panel table { width:100%; border-collapse:collapse; }.table-panel th,.table-panel td { padding:12px 14px; border-bottom:1px solid var(--line); text-align:left; font-size:10px; }.table-panel th { color:var(--muted); font-size:9px; text-transform:uppercase; letter-spacing:.06em; }.table-panel td:first-child { display:flex; flex-direction:column; }.table-panel td small { color:var(--muted); }
145
+ .application-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:12px; }.model-card { padding:18px; }.model-card>strong { font-size:28px; }.model-card ul { margin:12px 0 0; padding:0; list-style:none; }.model-card li { padding:6px 0; display:flex; justify-content:space-between; gap:10px; border-bottom:1px solid var(--line); font-size:9px; }.model-card li small { color:var(--muted); text-align:right; }
146
+
147
+ /* Contracts */
148
+ .spacer { flex:1; }.plan-toolbar { margin-bottom:12px; }.plan-list { display:flex; flex-direction:column; gap:8px; }
149
+ .plan-item { display:grid; grid-template-columns:1fr 140px; gap:18px; align-items:center; padding:15px 16px; border:1px solid var(--line); border-radius:12px; background:white; }.plan-title { display:flex; align-items:center; gap:9px; }.plan-item h3 { font-size:13px; margin:0; }.plan-item p { margin:3px 0; color:var(--muted); font-size:10px; }.plan-item .risk { color:var(--faint); font-size:9px; }.plan-meta { display:flex; gap:5px; flex-wrap:wrap; margin-top:8px; }.criticality { text-transform:uppercase; font-size:8px; letter-spacing:.08em; font-weight:850; }.criticality.critical,.criticality.high { color:var(--red); }.plan-item select { width:100%; padding:8px; border:1px solid var(--line); border-radius:8px; background:var(--paper); font-size:10px; }
150
+ .pipeline { display:grid; grid-template-columns:repeat(3,1fr); gap:11px; }.pipeline article { min-height:180px; padding:17px; border:1px solid var(--line); border-radius:12px; background:white; display:flex; flex-direction:column; align-items:flex-start; }.pipeline article>span { color:var(--green-2); font-weight:850; font-size:9px; }.pipeline article p { color:var(--muted); font-size:10px; flex:1; }
151
+ .artifact-list { margin-top:14px; }.artifact { display:flex; justify-content:space-between; gap:20px; padding:9px 0; border-bottom:1px solid var(--line); font-size:10px; }.artifact>span:last-child { display:flex; align-items:center; gap:5px; min-width:0; }.artifact i { padding:2px 5px; border-radius:5px; background:var(--wash); color:var(--muted); font-style:normal; font-size:8px; }.artifact code { color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
152
+
153
+ /* Settings and evidence */
154
+ .settings-grid { display:grid; grid-template-columns:1fr 1fr; gap:14px; }.settings-section { padding:22px; }.settings-section>p:not(.eyebrow) { color:var(--muted); font-size:10px; }.settings-section .field { margin-top:8px; }.runner-row,.actor-row { display:flex; gap:10px; align-items:center; padding:10px 0; border-bottom:1px solid var(--line); }.runner-row div,.actor-row div { display:flex; flex-direction:column; }.runner-row strong,.actor-row strong { font-size:11px; }.runner-row small,.actor-row small { color:var(--muted); font-size:9px; }.runner-dot { width:9px; height:9px; border-radius:50%; background:var(--amber); }.runner-dot.available { background:var(--green-2); }.runner-dot.unavailable { background:var(--red); }.actor-row>span { width:29px; height:29px; display:grid; place-items:center; border-radius:50%; background:var(--lime); color:var(--green); font-weight:800; }
155
+ .setting-row { display:flex; justify-content:space-between; gap:15px; }.setting-row div { display:flex; flex-direction:column; }.setting-row small { color:var(--muted); font-size:9px; }
156
+ .evidence-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:9px; }.evidence-card { padding:14px; border:1px solid var(--line); border-radius:11px; background:white; }.evidence-card strong { display:block; font-size:20px; }.evidence-card strong.good { color:var(--green); }.evidence-card strong.bad { color:var(--red); }.evidence-card small { color:var(--muted); font-size:9px; }.evidence-card.wide { grid-column:span 2; }.findings-list { margin:9px 0 0; padding-left:16px; color:var(--muted); font-size:9px; }.code-preview { max-height:430px; overflow:auto; margin-top:14px; padding:16px; border-radius:12px; background:#101612; color:#d9e7dc; font:10px/1.55 ui-monospace,SFMono-Regular,Menlo,monospace; white-space:pre; }
157
+
158
+ /* Dialog, progress and shared empty states */
159
+ dialog { width:min(720px,calc(100vw - 40px)); max-height:min(760px,calc(100vh - 40px)); padding:0; border:1px solid var(--line); border-radius:18px; background:var(--paper); box-shadow:0 30px 90px rgba(13,28,19,.28); }.dialog-shell { padding:25px; }.dialog-heading { display:flex; justify-content:space-between; gap:20px; }.dialog-heading p:not(.eyebrow) { color:var(--muted); font-size:10px; }.search-input { width:100%; padding:11px 13px; border:1px solid var(--line); border-radius:10px; background:white; }
160
+ .github-repositories { margin-top:12px; max-height:480px; overflow:auto; border:1px solid var(--line); border-radius:11px; }.github-repositories button { width:100%; padding:11px 13px; display:grid; grid-template-columns:34px 1fr auto; gap:10px; align-items:center; text-align:left; border:0; border-bottom:1px solid var(--line); border-radius:0; background:white; color:var(--ink); }.github-repositories button:hover { background:var(--wash); }.github-repositories button span:nth-child(2) { display:flex; flex-direction:column; }.github-repositories button small { color:var(--muted); font-size:9px; }.github-repositories button em { color:var(--green); font-size:9px; font-style:normal; }.repository-icon { width:31px; height:31px; display:grid!important; place-items:center; border-radius:8px; background:var(--wash); font-weight:800; }.remediation { padding:24px; background:var(--amber-bg); color:#75531e; }.remediation p { margin:5px 0 0; font-size:10px; }
161
+ .empty { grid-column:1/-1; padding:34px; color:var(--muted); text-align:center; font-size:11px; }
162
+ .operation-drawer { position:fixed; right:24px; bottom:24px; z-index:60; width:min(470px,calc(100vw - 48px)); display:flex; align-items:center; gap:13px; padding:15px 17px; color:white; background:#14251b; border-radius:14px; box-shadow:0 18px 50px rgba(0,0,0,.25); }.operation-copy { min-width:0; flex:1; }.operation-drawer p { margin:3px 0 7px; color:#b9c8be; font-size:10px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }.spinner { width:23px; height:23px; border:3px solid #5e7667; border-top-color:#8de0a9; border-radius:50%; animation:spin .8s linear infinite; flex:0 0 auto; }.progress-track { height:3px; border-radius:999px; background:#3e5547; overflow:hidden; }.progress-track span { display:block; width:0; height:100%; background:#83d6a0; transition:width .25s ease; } @keyframes spin { to { transform:rotate(360deg); } }
163
+ .toast { position:fixed; left:50%; bottom:28px; transform:translateX(-50%); z-index:70; max-width:650px; padding:12px 16px; border-radius:10px; color:white; background:#26342b; box-shadow:var(--shadow); font-size:11px; }.toast.error { background:#842f2b; }
164
+
165
+ @media (max-width:1040px) {
166
+ .product-shell { grid-template-columns:190px minmax(0,1fr); }.sidebar { padding-left:9px; padding-right:9px; }.workspace { padding-left:24px; padding-right:24px; }
167
+ .journey { grid-template-columns:repeat(3,1fr); }.view-heading { grid-template-columns:1fr 280px; }.application-grid { grid-template-columns:1fr 1fr; }
168
+ .split-view,.findings-layout { grid-template-columns:1fr; }.list-panel { max-height:350px; overflow:auto; }
169
+ }
170
+ @media (max-width:760px) {
171
+ .topbar { padding:0 12px; }.brand small,.mode-pill { display:none; }.repository-switcher { max-width:190px; }
172
+ .source-onboarding { width:calc(100% - 28px); padding-top:42px; }.welcome-copy h1 { font-size:42px; }.source-choices { grid-template-columns:1fr; }.privacy-note { flex-direction:column; text-align:center; }
173
+ .product-shell { display:block; }.sidebar { position:static; width:100%; height:auto; padding:10px; }.project-identity,.sidebar-context,.sidebar-source,.keyless-note { display:none; }.primary-nav { margin:0; display:grid; grid-template-columns:repeat(3,1fr); }.primary-nav button { grid-template-columns:16px 1fr; }.primary-nav i { display:none; }
174
+ .workspace { padding:22px 14px 60px; }.view-heading,.view-heading.simple { display:flex; flex-direction:column; align-items:stretch; }.view-heading .decision-card { min-height:auto; }.journey { grid-template-columns:1fr 1fr; }
175
+ .section { padding:21px 18px; }.section-heading,.runtime-row,.overview-grid,.map-layout,.settings-grid,.live-layout,.flow-recorder { grid-template-columns:1fr; }.section-heading { flex-direction:column; }.run-cta { min-width:0; }.pipeline,.evidence-grid,.application-grid { grid-template-columns:1fr; }.evidence-card.wide { grid-column:auto; }.plan-item { grid-template-columns:1fr; }.artifact { flex-direction:column; gap:5px; }.transition-list>div { grid-template-columns:1fr; }.top-actions .quiet { display:none; }
176
+ }
177
+
178
+ /* Desktop-parity dark product skin. The component structure remains shared by
179
+ local and hosted Tapp; this palette follows the native Command Center. */
180
+ :root {
181
+ color-scheme:dark;
182
+ --ink:#edf2f8; --muted:#929ba8; --faint:#687280; --line:#303844; --paper:#171c24; --wash:#20262f;
183
+ --green:#58a6ff; --green-2:#4f9cf3; --green-3:#7bb8ff; --lime:#102d4d; --amber:#e2a826;
184
+ --amber-bg:#302817; --red:#ff5c57; --red-bg:#392125; --blue:#58a6ff; --sidebar:#0c1118;
185
+ --shadow:0 18px 55px rgba(0,0,0,.28); --small-shadow:0 8px 24px rgba(0,0,0,.18);
186
+ }
187
+ body { background:#0d1117; }
188
+ .topbar { background:rgba(13,17,23,.96); border-color:var(--line); }
189
+ .brand-mark { width:auto; background:transparent; color:var(--green); font-family:inherit; font-size:24px; }
190
+ .mode-pill,.status-chip,.repository-switcher,.source-card,.panel,.decision-card,.target-card,.field,
191
+ .live-frame-shell,.live-controls,.coverage-summary,.transition-list,.plan-item,.pipeline article,
192
+ .evidence-card,.search-input,.github-repositories,.github-repositories button,.manual-action input,
193
+ .run-row,.finding-row,.live-control { background:var(--paper); color:var(--ink); border-color:var(--line); }
194
+ .source-onboarding { min-height:calc(100vh - 64px); }
195
+ .source-card:hover,.source-card.dragging { border-color:var(--green-2); box-shadow:0 20px 56px rgba(0,0,0,.36); }
196
+ .source-card.dragging,.target-card.selected,.run-row.selected,.finding-row.selected { background:#132237; }
197
+ .platform-row span,.button-link { background:#131a23; border-color:#385a7c; color:var(--green); }
198
+ button.primary { background:var(--green); color:#07111d; }
199
+ button.primary:hover { background:#79b8ff; }
200
+ button.secondary { color:#d8e9fb; border-color:#3b526a; background:#202731; }
201
+ button.secondary:hover,button.quiet:hover,.journey button:hover,.live-control:hover,.run-row:hover,.finding-row:hover,.github-repositories button:hover { background:#252d37; }
202
+ .sidebar { border-right:1px solid var(--line); }
203
+ .project-avatar { background:linear-gradient(135deg,#3f8ee8,#7657d9); }
204
+ .primary-nav button.active { background:#122743; }
205
+ .primary-nav button.active>span { color:var(--green); }
206
+ .workspace { background:#0d1117; }
207
+ .journey { background:var(--line); }
208
+ .journey button { background:var(--paper); color:var(--ink); }
209
+ .journey button.done span { background:var(--green); border-color:var(--green); color:#07111d; }
210
+ .target-choice-callout { border-color:#315c88; background:linear-gradient(135deg,#13243a,#171c24); }
211
+ .target-choice-callout>span { background:var(--green); color:#07111d; }
212
+ .target-card:hover { border-color:var(--green); background:#1c2633; box-shadow:0 7px 18px rgba(0,0,0,.3); }
213
+ .target-card.selected { border-color:var(--green); box-shadow:inset 0 0 0 1px var(--green),0 8px 20px rgba(0,0,0,.25); }
214
+ .platform-icon,.platform-icon.ios,.platform-icon.android { background:#242c36; color:#c4d3e3; }
215
+ .field input { color:var(--ink); }
216
+ .live-frame { background:#090c11; }
217
+ .live-frame #live-frame-loading { background:#090c11; color:var(--muted); }
218
+ .live-frame-head,.live-controls-heading,.manual-action,.run-cta { background:var(--wash); }
219
+ .detail-panel pre,.code-preview { background:#090c11; color:#dbe9f8; }
220
+ .subnav { background:var(--paper); }
221
+ .subnav button.active { background:var(--green); color:#07111d; }
222
+ .map-canvas { border-color:var(--line); background:linear-gradient(90deg,transparent 31px,#18202a 32px,transparent 33px),linear-gradient(transparent 31px,#18202a 32px,transparent 33px),#0d1218; background-size:32px 32px; }
223
+ .map-node { background:var(--paper); border-color:#34404e; border-left-color:var(--green); }
224
+ .operation-drawer { background:#17202a; border:1px solid #334252; }
225
+ .progress-track { background:#344150; }.progress-track span { background:var(--green); }
226
+ .spinner { border-color:#3a4857; border-top-color:var(--green); }
227
+ .toast { background:#263342; }.toast.error { background:#842f3a; }