@muhammad_zihad/prless 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -1,97 +1,146 @@
1
- # PRless
1
+ <p align="center">
2
+ <img src="src/web/public/icon.svg" width="84" height="84" alt="PRless logo" />
3
+ </p>
2
4
 
3
- A local, GitHub-style code review tool with an agent-agnostic AI handoff. Review a local
4
- git diff in the browser, leave inline comments anchored to specific lines, then export the
5
- comments to a file that any CLI coding agent (Claude Code, Codex, …) can read and act on.
5
+ <h1 align="center">PRless</h1>
6
6
 
7
- ## Install
7
+ <p align="center">
8
+ <strong>PR-style code review without the pull request.</strong><br/>
9
+ Review a local git diff in your browser, comment inline, and hand the notes to an AI agent.
10
+ </p>
8
11
 
9
- Requires **Node.js 18+**. One command on every platform — macOS, Linux, and Windows:
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/@muhammad_zihad/prless"><img src="https://img.shields.io/npm/v/@muhammad_zihad/prless.svg?color=6d54e0&label=npm" alt="npm version" /></a>
14
+ <a href="https://www.npmjs.com/package/@muhammad_zihad/prless"><img src="https://img.shields.io/npm/dm/@muhammad_zihad/prless.svg?color=6d54e0" alt="npm downloads" /></a>
15
+ <img src="https://img.shields.io/node/v/@muhammad_zihad/prless.svg?color=6d54e0" alt="node version" />
16
+ <a href="./LICENSE"><img src="https://img.shields.io/npm/l/@muhammad_zihad/prless.svg?color=6d54e0" alt="license" /></a>
17
+ </p>
18
+
19
+ <!-- TODO: add a screenshot or short GIF of the diff view + Export for AI here -->
20
+
21
+ ---
22
+
23
+ ## Why PRless?
24
+
25
+ When you ask an AI agent to fix something, your feedback is usually disconnected from the
26
+ code: you describe a change in prose, or push a branch and open a PR just to review it.
27
+
28
+ PRless gives AI code review the thing human review already has: **comments pinned to exact
29
+ lines**. You review a diff like a GitHub PR, leave inline comments, then export them as a
30
+ clipboard-ready prompt for Claude Code, Codex, or any CLI agent. No remote, no PR, no API
31
+ keys. The whole loop stays on your machine.
32
+
33
+ ## Features
34
+
35
+ - 🧩 **GitHub-style diff view** for any local git repo (working tree, staged, or branch compare).
36
+ - 💬 **Inline comments** anchored to specific lines, with resolve / reopen / delete.
37
+ - 🤖 **One-click AI handoff** — copies agent-ready instructions to your clipboard and writes `.prless/review.md`.
38
+ - 🎨 **Light & dark themes** plus selectable syntax themes (GitHub, Dracula, Nord, One Dark, Monokai, Solarized).
39
+ - 🪶 **Token-savvy** — resolved comments stay on disk but are excluded from the AI export.
40
+ - 🖥️ **Cross-platform** — macOS, Linux, and Windows, with bundled offline fonts.
41
+
42
+ ## Installation
43
+
44
+ Requires **Node.js 18+**.
10
45
 
11
46
  ```bash
12
47
  npm install -g @muhammad_zihad/prless
13
48
  ```
14
49
 
15
- That puts a `prless` command on your PATH (on Windows, npm generates the `.cmd`/PowerShell
16
- shims automatically). Prefer not to install globally? Run it on demand with `npx`:
50
+ This adds a `prless` command to your `PATH` (on Windows, npm generates the `.cmd` /
51
+ PowerShell shims automatically). Prefer not to install globally? Run it on demand:
17
52
 
18
53
  ```bash
19
54
  npx @muhammad_zihad/prless open .
20
55
  ```
21
56
 
22
- ### macOS / Linux via Homebrew
57
+ ## Quick start
23
58
 
24
59
  ```bash
25
- brew install muhammadZihad/tap/prless
60
+ cd your-project
61
+ prless open .
26
62
  ```
27
63
 
28
- `brew` installs Node for you. See [packaging/README.md](packaging/README.md) for publishing
29
- the npm package and setting up the tap.
30
-
31
- ### From source
64
+ 1. Your browser opens with the diff of your uncommitted changes.
65
+ 2. Click a line's gutter to leave a comment, just like a GitHub PR.
66
+ 3. Hit **Export for AI** — the instructions are copied to your clipboard. Paste them into
67
+ your agent:
32
68
 
33
69
  ```bash
34
- git clone https://github.com/muhammadZihad/prless.git && cd prless
35
- npm install # builds automatically via the prepare script
36
- npm link # makes `prless` available globally
70
+ claude # then paste, or: "address the comments in .prless/review.md"
71
+ # or
72
+ codex "address the comments in .prless/review.md"
37
73
  ```
38
74
 
39
- ## Use
75
+ The agent reads each comment, makes the change, and you re-review. That is the whole loop.
76
+
77
+ ## Commands
40
78
 
41
79
  ```bash
42
- prless open . # review the git repo in the current directory
43
- prless open ~/projects/my-app # review a repo by path
44
- prless open ./my-app --port 4200
45
- prless help # show usage
80
+ prless open . # review the repo in the current directory
81
+ prless open ~/projects/my-app # review a repo by path
82
+ prless open . --port 4200 # serve on a custom port (default 4100)
83
+ prless open . --no-open # don't launch a browser automatically
84
+ prless help # show usage
46
85
  ```
47
86
 
48
- Works on macOS, Linux, and Windows. This starts a local server and opens the UI in your
49
- browser. You can:
50
-
51
- - **Pick a diff source** working tree vs HEAD, staged vs HEAD, or compare two branches.
52
- - **Comment inline** — click a line's gutter to leave a comment (⌘/Ctrl+Enter to submit).
53
- - **Resolve / delete** comments; toggle split / unified view.
54
- - **Switch the app theme** — light or dark (defaults to your OS setting, remembered per browser).
55
- - **Choose a syntax theme** — Auto, GitHub Light/Dark, One Dark, Dracula, Nord, Monokai,
56
- Solarized Light. The diff renders as a self-contained editor surface, so any code theme
57
- looks right regardless of the app theme.
58
- - **Export for AI** — writes open comments to `.prless/review.md`.
87
+ | Option | Description |
88
+ | --- | --- |
89
+ | `--port <n>` | Port to serve on (default `4100`, or `$PRLESS_PORT`). |
90
+ | `--no-open` | Skip auto-opening the browser. |
59
91
 
60
- Typography uses Geist (UI) and JetBrains Mono (code), bundled locally so it works offline.
92
+ ## How it works
61
93
 
62
- Comments persist in `.prless/comments.json` in the repo (gitignore the `.prless/` folder).
94
+ ```
95
+ ┌──────────┐ review ┌───────────┐ export ┌─────────────────┐ apply ┌───────────┐
96
+ │ git diff │ ──────────▶ │ PRless │ ──────────▶ │ .prless/review.md │ ───────▶ │ AI agent │
97
+ └──────────┘ inline │ (browser)│ + clipboard │ (open comments) │ └───────────┘
98
+ comments └───────────┘ └─────────────────┘
99
+ ```
63
100
 
64
- ## Hand off to an agent
101
+ - Comments persist in `.prless/comments.json` in your repo. Add `.prless/` to `.gitignore`.
102
+ - `.prless/review.md` groups every **open** comment by file, with the target line and the
103
+ requested change. Resolved comments are kept in the JSON but left out of the export, so
104
+ the agent never spends tokens on them.
105
+ - The handoff is a plain file plus a clipboard copy, so it works with any agent. No MCP,
106
+ no API keys.
65
107
 
66
- After exporting, run your agent in the repo and point it at the file:
108
+ ## Configuration
67
109
 
68
- ```bash
69
- claude # then: "address the comments in .prless/review.md"
70
- # or
71
- codex "address the comments in .prless/review.md"
72
- ```
73
-
74
- `review.md` lists each open comment grouped by file, with the target line, side, and the
75
- requested change — no API keys or MCP required.
110
+ - **App theme** — light or dark, defaults to your OS setting and is remembered per browser.
111
+ - **Syntax theme** Auto, GitHub Light/Dark, One Dark, Dracula, Nord, Monokai, or
112
+ Solarized Light. The diff renders as a self-contained editor surface, so any code theme
113
+ looks right regardless of the app theme.
114
+ - **View** — split or unified.
76
115
 
77
- ## Develop
116
+ ## Development
78
117
 
79
118
  ```bash
119
+ git clone https://github.com/muhammadZihad/prless.git
120
+ cd prless
121
+ npm install # builds automatically via the prepare script
122
+
80
123
  npm run dev # Vite UI on :5174 (proxying /api) + API on :4100 with reload
81
- npm test # vitest (git, comments, export)
124
+ npm test # vitest: git, comments, export
82
125
  npm run typecheck
126
+ npm run build # bundle the web app and compile the server into dist/
83
127
  ```
84
128
 
85
- ## Layout
129
+ ### Project structure
86
130
 
87
131
  ```
88
132
  src/
89
- shared/types.ts # types shared by server + web
90
- server/ # Fastify API + CLI (git diff, comment store, review.md export)
91
- web/ # React + Vite UI (react-diff-view)
133
+ shared/ # types shared by the server and web app
134
+ server/ # Fastify API + CLI: git diff, comment store, review.md export
135
+ web/ # React + Vite UI (react-diff-view, syntax highlighting, theming)
92
136
  ```
93
137
 
94
138
  ## Scope
95
139
 
96
- Local, single-user. No GitHub PR ingestion, no auth/DB, no MCP — handoff is the exported
97
- file. These are deliberate non-goals and can be layered on later.
140
+ PRless is intentionally local and single-user: no GitHub PR ingestion, no accounts, no
141
+ database, no MCP. The handoff is the exported file. These are deliberate non-goals that
142
+ could be layered on later.
143
+
144
+ ## License
145
+
146
+ [MIT](./LICENSE) © Muhammad AR Zihad
@@ -41,7 +41,8 @@ export function renderReviewMarkdown(comments) {
41
41
  export async function exportReview(repoRoot, comments) {
42
42
  const dir = path.join(repoRoot, '.prless');
43
43
  const file = path.join(dir, 'review.md');
44
+ const content = renderReviewMarkdown(comments);
44
45
  await mkdir(dir, { recursive: true });
45
- await writeFile(file, renderReviewMarkdown(comments), 'utf8');
46
- return { path: file, count: comments.filter((c) => c.status === 'open').length };
46
+ await writeFile(file, content, 'utf8');
47
+ return { path: file, count: comments.filter((c) => c.status === 'open').length, content };
47
48
  }
@@ -1 +1 @@
1
- @font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2) format("woff2-variations");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-latin-wght-normal-BgDaEnEv.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,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) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2) format("woff2-variations");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2) format("woff2-variations");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--diff-background-color:initial;--diff-text-color:initial;--diff-font-family:Consolas,Courier,monospace;--diff-selection-background-color:#b3d7ff;--diff-selection-text-color:var(--diff-text-color);--diff-gutter-insert-background-color:#d6fedb;--diff-gutter-insert-text-color:var(--diff-text-color);--diff-gutter-delete-background-color:#fadde0;--diff-gutter-delete-text-color:var(--diff-text-color);--diff-gutter-selected-background-color:#fffce0;--diff-gutter-selected-text-color:var(--diff-text-color);--diff-code-insert-background-color:#eaffee;--diff-code-insert-text-color:var(--diff-text-color);--diff-code-delete-background-color:#fdeff0;--diff-code-delete-text-color:var(--diff-text-color);--diff-code-insert-edit-background-color:#c0dc91;--diff-code-insert-edit-text-color:var(--diff-text-color);--diff-code-delete-edit-background-color:#f39ea2;--diff-code-delete-edit-text-color:var(--diff-text-color);--diff-code-selected-background-color:#fffce0;--diff-code-selected-text-color:var(--diff-text-color);--diff-omit-gutter-line-color:#cb2a1d}.diff{background-color:var(--diff-background-color);border-collapse:collapse;color:var(--diff-text-color);table-layout:fixed;width:100%}.diff::-moz-selection{background-color:#b3d7ff;background-color:var(--diff-selection-background-color);color:var(--diff-text-color);color:var(--diff-selection-text-color)}.diff::selection{background-color:#b3d7ff;background-color:var(--diff-selection-background-color);color:var(--diff-text-color);color:var(--diff-selection-text-color)}.diff td{padding-bottom:0;padding-top:0;vertical-align:top}.diff-line{font-family:Consolas,Courier,monospace;font-family:var(--diff-font-family);line-height:1.5}.diff-gutter>a{color:inherit;display:block}.diff-gutter{cursor:pointer;padding:0 1ch;text-align:right;-webkit-user-select:none;-moz-user-select:none;user-select:none}.diff-gutter-insert{background-color:#d6fedb;background-color:var(--diff-gutter-insert-background-color);color:var(--diff-text-color);color:var(--diff-gutter-insert-text-color)}.diff-gutter-delete{background-color:#fadde0;background-color:var(--diff-gutter-delete-background-color);color:var(--diff-text-color);color:var(--diff-gutter-delete-text-color)}.diff-gutter-omit{cursor:default}.diff-gutter-selected{background-color:#fffce0;background-color:var(--diff-gutter-selected-background-color);color:var(--diff-text-color);color:var(--diff-gutter-selected-text-color)}.diff-code{word-wrap:break-word;padding:0 0 0 .5em;white-space:pre-wrap;word-break:break-all}.diff-code-edit{color:inherit}.diff-code-insert{background-color:#eaffee;background-color:var(--diff-code-insert-background-color);color:var(--diff-text-color);color:var(--diff-code-insert-text-color)}.diff-code-insert .diff-code-edit{background-color:#c0dc91;background-color:var(--diff-code-insert-edit-background-color);color:var(--diff-text-color);color:var(--diff-code-insert-edit-text-color)}.diff-code-delete{background-color:#fdeff0;background-color:var(--diff-code-delete-background-color);color:var(--diff-text-color);color:var(--diff-code-delete-text-color)}.diff-code-delete .diff-code-edit{background-color:#f39ea2;background-color:var(--diff-code-delete-edit-background-color);color:var(--diff-text-color);color:var(--diff-code-delete-edit-text-color)}.diff-code-selected{background-color:#fffce0;background-color:var(--diff-code-selected-background-color);color:var(--diff-text-color);color:var(--diff-code-selected-text-color)}.diff-widget-content{vertical-align:top}.diff-gutter-col{width:7ch}.diff-gutter-omit{height:0}.diff-gutter-omit:before{background-color:#cb2a1d;background-color:var(--diff-omit-gutter-line-color);content:" ";display:block;height:100%;margin-left:4.6ch;overflow:hidden;white-space:pre;width:2px}.diff-decoration{line-height:1.5;-webkit-user-select:none;-moz-user-select:none;user-select:none}.diff-decoration-content{font-family:Consolas,Courier,monospace;font-family:var(--diff-font-family);padding:0}:root{--font-ui: "Geist Variable", system-ui, sans-serif;--font-mono: "JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, monospace;--radius-sm: 6px;--radius-md: 9px;--radius-lg: 14px;--shadow-sm: 0 1px 2px oklch(.2 .02 285 / .06);--shadow-md: 0 6px 24px -8px oklch(.2 .04 285 / .18);--shadow-pop: 0 12px 40px -10px oklch(.2 .04 285 / .28);--ease: cubic-bezier(.22, 1, .36, 1);--accent: oklch(.56 .19 285);--accent-hover: oklch(.51 .2 285);--accent-fg: oklch(.99 .01 285);--accent-soft: oklch(.56 .19 285 / .12)}:root[data-theme=light]{color-scheme:light;--bg: oklch(.991 .003 285);--bg-subtle: oklch(.975 .005 285);--bg-inset: oklch(.955 .007 285);--bg-hover: oklch(.945 .009 285);--border: oklch(.905 .008 285);--border-strong: oklch(.84 .012 285);--text: oklch(.28 .025 285);--text-muted: oklch(.52 .018 285);--text-faint: oklch(.64 .014 285);--open: oklch(.66 .15 65);--open-soft: oklch(.66 .15 65 / .16);--resolved: oklch(.6 .13 150);--resolved-soft: oklch(.6 .13 150 / .16);--danger: oklch(.56 .2 25);--add: oklch(.55 .13 150);--del: oklch(.57 .2 25)}:root[data-theme=dark]{color-scheme:dark;--accent: oklch(.74 .15 286);--accent-hover: oklch(.8 .15 286);--accent-fg: oklch(.17 .02 285);--accent-soft: oklch(.74 .15 286 / .16);--bg: oklch(.178 .012 285);--bg-subtle: oklch(.214 .014 285);--bg-inset: oklch(.246 .016 285);--bg-hover: oklch(.28 .018 285);--border: oklch(.31 .016 285);--border-strong: oklch(.4 .02 285);--text: oklch(.93 .008 285);--text-muted: oklch(.7 .015 285);--text-faint: oklch(.58 .016 285);--open: oklch(.78 .14 70);--open-soft: oklch(.78 .14 70 / .18);--resolved: oklch(.74 .14 152);--resolved-soft: oklch(.74 .14 152 / .18);--danger: oklch(.7 .17 25);--add: oklch(.78 .14 152);--del: oklch(.72 .16 25)}*{box-sizing:border-box}html,body{margin:0;height:100%}body{font-family:var(--font-ui);font-size:14px;line-height:1.5;color:var(--text);background:var(--bg);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}::selection{background:var(--accent-soft)}.app{height:100vh;display:flex;flex-direction:column}.topbar{display:flex;align-items:center;gap:14px;padding:12px 20px;border-bottom:1px solid var(--border);background:color-mix(in oklch,var(--bg-subtle) 86%,transparent);-webkit-backdrop-filter:saturate(1.4) blur(6px);backdrop-filter:saturate(1.4) blur(6px);position:sticky;top:0;z-index:20}.brand{display:flex;align-items:center;gap:9px;font-weight:600;letter-spacing:-.01em}.brand h1{font-size:15px;margin:0;font-weight:600}.brand .mark{width:22px;height:22px;border-radius:7px;background:linear-gradient(140deg,var(--accent),oklch(.62 .17 320));box-shadow:var(--shadow-sm)}.spacer{flex:1}.toolset{display:flex;align-items:center;gap:8px}button{font:inherit;font-weight:500;display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);color:var(--text);cursor:pointer;transition:background .14s var(--ease),border-color .14s var(--ease),transform .1s var(--ease)}button:hover{background:var(--bg-hover);border-color:var(--border-strong)}button:active{transform:translateY(1px)}button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}button.primary{background:var(--accent);color:var(--accent-fg);border-color:transparent}button.primary:hover{background:var(--accent-hover)}button.icon{padding:7px;width:34px;height:34px;justify-content:center}button:disabled{opacity:.45;cursor:not-allowed}.count-pill{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 6px;border-radius:999px;font-size:11px;font-weight:600;background:var(--accent-fg);color:var(--accent)}.field{display:inline-flex;flex-direction:column;gap:0;position:relative}.select{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;font-weight:500;padding:6px 30px 6px 11px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);color:var(--text);cursor:pointer;transition:border-color .14s var(--ease),background .14s var(--ease)}.select:hover{border-color:var(--border-strong)}.select:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.field:after{content:"";position:absolute;right:11px;top:50%;width:8px;height:8px;border-right:1.5px solid var(--text-muted);border-bottom:1.5px solid var(--text-muted);transform:translateY(-65%) rotate(45deg);pointer-events:none}.ref-picker{display:flex;align-items:center;gap:8px}.divider{width:1px;height:22px;background:var(--border)}.banner{padding:10px 20px;font-size:13px;display:flex;align-items:center;gap:8px;border-bottom:1px solid var(--border)}.banner.error{background:color-mix(in oklch,var(--danger) 12%,var(--bg));color:var(--danger)}.banner.info{background:var(--accent-soft);color:var(--accent)}.layout{flex:1;display:grid;grid-template-columns:290px 1fr;overflow:hidden}aside{border-right:1px solid var(--border);overflow-y:auto;background:var(--bg-subtle)}main{overflow-y:auto;padding:22px 26px 80px;scroll-behavior:smooth}.empty{color:var(--text-muted);padding:80px 24px;text-align:center;font-size:15px}.file-list{padding:16px 12px}.file-list h2{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.07em;color:var(--text-faint);margin:0 8px 10px}.file-list ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px}.file-list a{display:flex;align-items:center;gap:9px;padding:7px 9px;border-radius:var(--radius-sm);text-decoration:none;color:var(--text);transition:background .12s var(--ease)}.file-list a:hover{background:var(--bg-hover)}.file-list-path{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-family:var(--font-mono);font-feature-settings:"liga" 0}.tag{display:inline-flex;width:18px;height:18px;align-items:center;justify-content:center;border-radius:5px;font-size:10px;font-weight:700;color:var(--accent-fg);background:var(--text-faint);flex-shrink:0}.tag-add{background:var(--add)}.tag-delete{background:var(--del)}.tag-modify{background:var(--open)}.tag-rename,.tag-copy{background:var(--accent)}.badge{background:var(--open);color:#1f1306;border-radius:999px;padding:0 7px;font-size:11px;font-weight:600;line-height:18px;min-width:18px;text-align:center;flex-shrink:0}.file-diff{border:1px solid var(--border);border-radius:var(--radius-lg);margin-bottom:22px;overflow:hidden;box-shadow:var(--shadow-sm)}.file-diff-header{display:flex;align-items:center;gap:10px;padding:11px 16px;background:var(--bg-subtle);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:2}.file-diff-header .file-path{font-family:var(--font-mono);font-size:12.5px;font-weight:500;font-feature-settings:"liga" 0}.diff{--diff-font-family: var(--font-mono);font-size:12.5px}.diff-line{font-feature-settings:"liga" 0,"calt" 0}.diff-gutter{color:var(--code-gutter-fg);transition:background .1s var(--ease)}.diff-gutter:hover{background:var(--accent-soft)!important}.diff-gutter:hover>a:after{content:"+";position:absolute;margin-left:.4ch;color:var(--accent);font-weight:700}.thread{background:var(--bg-subtle);border-top:1px solid var(--border-strong);border-bottom:1px solid var(--border-strong);padding:14px 18px;display:flex;flex-direction:column;gap:10px;font-family:var(--font-ui)}.comment{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-md);padding:11px 13px;box-shadow:var(--shadow-sm)}.comment.resolved{opacity:.62}.comment-body{white-space:pre-wrap;word-break:break-word;margin-bottom:9px;line-height:1.55}.comment-actions{display:flex;align-items:center;gap:8px;font-size:12px}.status-chip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;text-transform:capitalize;padding:2px 9px;border-radius:999px}.status-chip:before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}.status-chip.open{color:var(--open);background:var(--open-soft)}.status-chip.resolved{color:var(--resolved);background:var(--resolved-soft)}.comment-actions .spacer{flex:1}.comment-actions button{padding:3px 9px;font-size:12px}.composer{display:flex;flex-direction:column;gap:8px}.composer textarea{font:inherit;width:100%;min-height:64px;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg);color:var(--text);resize:vertical;transition:border-color .14s var(--ease),box-shadow .14s var(--ease)}.composer textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}.composer textarea::placeholder{color:var(--text-faint)}.composer-actions{display:flex;align-items:center;gap:10px}.hint{color:var(--text-faint);font-size:11px}kbd{font-family:var(--font-mono);font-size:10.5px;padding:1px 5px;border:1px solid var(--border);border-bottom-width:2px;border-radius:5px;background:var(--bg-inset);color:var(--text-muted)}[data-code-theme]{--diff-background-color: var(--code-bg);--diff-text-color: var(--code-fg);--diff-selection-background-color: var(--code-sel);--diff-gutter-insert-background-color: var(--code-ins-gutter);--diff-gutter-delete-background-color: var(--code-del-gutter);--diff-code-insert-background-color: var(--code-ins-bg);--diff-code-delete-background-color: var(--code-del-bg);--diff-gutter-selected-background-color: var(--code-sel);--diff-code-selected-background-color: var(--code-sel)}.file-diff .diff{background:var(--code-bg)}.token.comment,.token.prolog,.token.cdata,.token.doctype{color:var(--tk-comment);font-style:italic}.token.punctuation{color:var(--tk-punct)}.token.keyword,.token.atrule,.token.rule,.token.important{color:var(--tk-keyword)}.token.number,.token.boolean,.token.constant,.token.symbol,.token.unit{color:var(--tk-number)}.token.string,.token.char,.token.attr-value,.token.url,.token.inserted{color:var(--tk-string)}.token.function,.token.function-name{color:var(--tk-function)}.token.class-name,.token.maybe-class-name,.token.builtin,.token.namespace{color:var(--tk-class)}.token.variable,.token.property,.token.attr-name,.token.parameter{color:var(--tk-variable)}.token.operator,.token.entity{color:var(--tk-operator)}.token.tag,.token.selector{color:var(--tk-tag)}.token.regex,.token.deleted{color:var(--tk-regex)}.token.bold{font-weight:600}.token.italic{font-style:italic}[data-code-theme=github-light]{--code-bg: #fcfcfd;--code-fg: #1f2328;--code-gutter-fg: #8c959f;--code-sel: #dbe9ff;--code-ins-bg: #e6ffec;--code-del-bg: #ffebe9;--code-ins-gutter: #c6f6d0;--code-del-gutter: #ffd7d5;--tk-comment: #6e7781;--tk-punct: #24292f;--tk-keyword: #cf222e;--tk-number: #0550ae;--tk-string: #0a3069;--tk-function: #8250df;--tk-class: #953800;--tk-variable: #953800;--tk-operator: #cf222e;--tk-tag: #116329;--tk-regex: #116329}[data-code-theme=github-dark]{--code-bg: #0d1117;--code-fg: #c9d1d9;--code-gutter-fg: #6e7681;--code-sel: #214283;--code-ins-bg: #12261c;--code-del-bg: #25171b;--code-ins-gutter: #1b4524;--code-del-gutter: #5d2025;--tk-comment: #8b949e;--tk-punct: #c9d1d9;--tk-keyword: #ff7b72;--tk-number: #79c0ff;--tk-string: #a5d6ff;--tk-function: #d2a8ff;--tk-class: #ffa657;--tk-variable: #ffa657;--tk-operator: #ff7b72;--tk-tag: #7ee787;--tk-regex: #7ee787}[data-code-theme=one-dark]{--code-bg: #282c34;--code-fg: #abb2bf;--code-gutter-fg: #5c6370;--code-sel: #3e4451;--code-ins-bg: #2a3a2f;--code-del-bg: #3a2a30;--code-ins-gutter: #36513e;--code-del-gutter: #51343c;--tk-comment: #5c6370;--tk-punct: #abb2bf;--tk-keyword: #c678dd;--tk-number: #d19a66;--tk-string: #98c379;--tk-function: #61afef;--tk-class: #e5c07b;--tk-variable: #e06c75;--tk-operator: #56b6c2;--tk-tag: #e06c75;--tk-regex: #98c379}[data-code-theme=dracula]{--code-bg: #282a36;--code-fg: #f8f8f2;--code-gutter-fg: #6272a4;--code-sel: #44475a;--code-ins-bg: #233a2c;--code-del-bg: #3d2231;--code-ins-gutter: #2f5339;--code-del-gutter: #5a2d3f;--tk-comment: #6272a4;--tk-punct: #f8f8f2;--tk-keyword: #ff79c6;--tk-number: #bd93f9;--tk-string: #f1fa8c;--tk-function: #50fa7b;--tk-class: #8be9fd;--tk-variable: #f8f8f2;--tk-operator: #ff79c6;--tk-tag: #ff79c6;--tk-regex: #f1fa8c}[data-code-theme=nord]{--code-bg: #2e3440;--code-fg: #d8dee9;--code-gutter-fg: #4c566a;--code-sel: #434c5e;--code-ins-bg: #34453a;--code-del-bg: #43353a;--code-ins-gutter: #3f5a45;--code-del-gutter: #5a4046;--tk-comment: #616e88;--tk-punct: #d8dee9;--tk-keyword: #81a1c1;--tk-number: #b48ead;--tk-string: #a3be8c;--tk-function: #88c0d0;--tk-class: #8fbcbb;--tk-variable: #d8dee9;--tk-operator: #81a1c1;--tk-tag: #81a1c1;--tk-regex: #ebcb8b}[data-code-theme=monokai]{--code-bg: #272822;--code-fg: #f8f8f2;--code-gutter-fg: #75715e;--code-sel: #49483e;--code-ins-bg: #2d3327;--code-del-bg: #382528;--code-ins-gutter: #3c4a2f;--code-del-gutter: #55323a;--tk-comment: #88846f;--tk-punct: #f8f8f2;--tk-keyword: #f92672;--tk-number: #ae81ff;--tk-string: #e6db74;--tk-function: #a6e22e;--tk-class: #a6e22e;--tk-variable: #f8f8f2;--tk-operator: #f92672;--tk-tag: #f92672;--tk-regex: #e6db74}[data-code-theme=solarized-light]{--code-bg: #fdf6e3;--code-fg: #586e75;--code-gutter-fg: #93a1a1;--code-sel: #eee8d5;--code-ins-bg: #e9efd0;--code-del-bg: #f6e0d8;--code-ins-gutter: #d9e4b0;--code-del-gutter: #f0cfc4;--tk-comment: #93a1a1;--tk-punct: #586e75;--tk-keyword: #859900;--tk-number: #d33682;--tk-string: #2aa198;--tk-function: #268bd2;--tk-class: #b58900;--tk-variable: #268bd2;--tk-operator: #859900;--tk-tag: #268bd2;--tk-regex: #2aa198}
1
+ @font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2) format("woff2-variations");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-latin-wght-normal-BgDaEnEv.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAfsABQAAAAAEAwAAAeCAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoP0hWQVJbBmA/U1RBVIFiJyYAdC9qEQgKhGSEAAsgADCGCAE2AiQDOgQgBYlMB4EUDAcbLQ4onoexrSC/2ZyLAa8p8VHB8/x3Vue+V0hVJalMJg2nx/TCrQXxBeqLjQG7FyM1WEa/X1tEXN7cFz9EJEMmMUz3RihWSSKeQCbcIou0izz/C8v+fq3VfajEa9gDD11CImXS7qL/RJFVzC1qiB6KmKeD6TZdQ6IRGv78dL6uSVVCfgni5mzu7kcgQBgAEAQTQRCoL++STTYybkJxNfQxAAIAGu8OdEB9teW2jh4BpgDqFjAeSEByW3zFP0CBBgNMsMCGEDjgggdhiEAUAeIIED7ABTDUEnkIE9Q9ahFgKttcVhApo4ACB4qobHaccgDfEjFO6aaWUhjMLt2SyIvHKoDqoA4CSUwEIYQCEjhAO9R1G6keDeDZGjNo+AhxOjCEGTr1WeIF3kYBiLAOKvkJSMiKX0VdAyQt3SDJClCkxJCHkCzfqyVTriJZLcolS32JZHUekq2TYNkYtCtjYHMQXSxGjXDz2t/yLWXzDzxz+o3zFwDEaN23F+13pyMdQAEaSKAR9vcGq4A4MTSKCElGW+M7UcY7xqkggITb28ZJhlqc9q2twYKTt0NjixBgYvO9BIihEBLYuOFXQzfIQ7dXGUEEEgFDooBfAzqiQbpJrhiWSuKJCRFKYbHCyJKI2G5GiZbNAvgAu5pc3vwx4G+g3aDkhklABiSz0BICXrYghtYhx/cdJ+44rY2oZ0aMNRFz3VZjb6W33F3gzltqtOCV8tTHSpOeXuItfvr5lCdfzFpqtEitvqdcdGGFd28ZqqC0tPbeChGXgrIlnhSWu/eUso4uKWFLugyDzQJhflY4659+WjQ++6x72WUMv9G8mw6QJl7BVxX5fe/kpUsOvnZwee9uQ0cGXYd0o89XB2748sDSnt8d2VphdOTTgceDVvOds0v9P/s7HPq15aGun/6Vllb56f1dl0t1LejqrNkpdRZsG8TOnM5vkBG5oiVyVGnS8LHps5cfNWJs6qKPfaNSxiQNBUm3cKNWROr0GSur7Za31k1vieq7LH11VF+jXdRIasRKflc7jkobm1Z9te1IyZA0pDkhLR98+H37Zf1c/8at+dB7x+7GfVyTfJMPiYztsnl59Y5l4j+0n1RXlpHnF3Tq7HecmNF/CJodEMAikruxiyJaGLvHOdAfoA+oDvpjBm2b91cHGRZMU9n25xEU0A8fgEEAdKI3Q1iDtc034sug5YVMkE2jsE+BIkwSoQ3gxXMqz9tELp48bd0cFKOKS7xYjEuXBnZP5ia7DyiO/X/YI+PQSbt2uSdqAkWL9nQbV1XB94/+uPfdZz8dnXYFBYrcTl2SIR/ybxJNJPz/Gupb0JaZeens2ekC7EKr8t+Ls/P5VJPYJdHKyqfg2nqU6bhlidzcddQV/7MmecTzJ5VPcKXkNKSEogHjYFx6QZ7rQ+FSe8njaiNuOnXS8H2ScQ619c2mC3VTtauL0rRbXd/CkSOP37FY9Zkjz8+GibYUMOEWF+RdrFS8Ecv1SHOpPUPZGEIpjPvFyU5cXKjd6OXqorTqy9GwRd++HVufPGnVsW+aO3vggKZ18jR9sXaTC1PWTEsVUaK0FkNySbTQDqlm2PfDjZcu4aalnSLKjnOoYQ0nUlqqXcGpPu/4VgV/xU2pAqW4BW3qzhQ8/hFKhV2qE3+BKAtDqBXjfgnVdH4y0wg5tbVNRenNdTWOrenWLcupQdmsbq5b+18piTe/xRdp1xbILxNPJGInm2z6hoB21Lal0i+ePTtd7B45+3XhFJ329evskXm7qurUVREotqSluSo/L29d3qDhI4YOQqWhI4YNvBNfsMHeXKemXrxQfKeuPOGRVayA3JtkJKEgbPp+dXUDluddutRYLFoXGXWX6N3WFaGLbQtRSitVYNacTNSdy7AaG/HSaUEANcBoGXNdcZvZsOqQ1icBDv21/gzAoYPHH/WDW0qNR3QTYKEAEHig6o13NXbND06CQPlRtYjGNnSktRc09k1mAMDvAlDKfQjgy6fssInlfzmNAjKkDxoxHOBLdVRAIVt9j4qo+hA1w9T1aNBNTUOTTNUHLbqokE+UAfJXCIGw/IxCSL5GRUJeR40rL/UxTm4Q08H6MbCs70ObuNyIIXrINHQYInF06UUlevTjbQzTh5upiDMzMMogUtEnjPs/Y7jAHCJeB0GBHh04tC6FiB6ZFB1oArUSIoFoqhzCeAN6lHwm0T4C3VVPWvjpSMXReuWesMEcoqrmgtNBGd2noWeV0hNAz9rFeShNJxHGsPa3HXeKTk8b55hahySYHaYKKFFLpCfN8rsoaJn01CR04Gkc+5k7KVTCmClX8Q10HCrUEkVlSX+XO33oQR9609tJ516H497WSobWs5Up6TLaS10/dessIskgJSLiDlWvHVUywpkQ7hdPZqGyiEF0uVQerVcPamT1A3eKXdyI1vG9OoflrSXihZ1qqGE3nhmAgiIbRCQgPLEPtOM3UQwTLYaYYomNlpA44opnjV6jkD6id80OOrzf6BzmMD6eEa1zKyeYG1fzfEf16V6jw9XYOaar1/b2kP/IYX8oR2mcFvv2GtBV3JXgd437AQAA) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2) format("woff2-variations");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2) format("woff2-variations");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--diff-background-color:initial;--diff-text-color:initial;--diff-font-family:Consolas,Courier,monospace;--diff-selection-background-color:#b3d7ff;--diff-selection-text-color:var(--diff-text-color);--diff-gutter-insert-background-color:#d6fedb;--diff-gutter-insert-text-color:var(--diff-text-color);--diff-gutter-delete-background-color:#fadde0;--diff-gutter-delete-text-color:var(--diff-text-color);--diff-gutter-selected-background-color:#fffce0;--diff-gutter-selected-text-color:var(--diff-text-color);--diff-code-insert-background-color:#eaffee;--diff-code-insert-text-color:var(--diff-text-color);--diff-code-delete-background-color:#fdeff0;--diff-code-delete-text-color:var(--diff-text-color);--diff-code-insert-edit-background-color:#c0dc91;--diff-code-insert-edit-text-color:var(--diff-text-color);--diff-code-delete-edit-background-color:#f39ea2;--diff-code-delete-edit-text-color:var(--diff-text-color);--diff-code-selected-background-color:#fffce0;--diff-code-selected-text-color:var(--diff-text-color);--diff-omit-gutter-line-color:#cb2a1d}.diff{background-color:var(--diff-background-color);border-collapse:collapse;color:var(--diff-text-color);table-layout:fixed;width:100%}.diff::-moz-selection{background-color:#b3d7ff;background-color:var(--diff-selection-background-color);color:var(--diff-text-color);color:var(--diff-selection-text-color)}.diff::selection{background-color:#b3d7ff;background-color:var(--diff-selection-background-color);color:var(--diff-text-color);color:var(--diff-selection-text-color)}.diff td{padding-bottom:0;padding-top:0;vertical-align:top}.diff-line{font-family:Consolas,Courier,monospace;font-family:var(--diff-font-family);line-height:1.5}.diff-gutter>a{color:inherit;display:block}.diff-gutter{cursor:pointer;padding:0 1ch;text-align:right;-webkit-user-select:none;-moz-user-select:none;user-select:none}.diff-gutter-insert{background-color:#d6fedb;background-color:var(--diff-gutter-insert-background-color);color:var(--diff-text-color);color:var(--diff-gutter-insert-text-color)}.diff-gutter-delete{background-color:#fadde0;background-color:var(--diff-gutter-delete-background-color);color:var(--diff-text-color);color:var(--diff-gutter-delete-text-color)}.diff-gutter-omit{cursor:default}.diff-gutter-selected{background-color:#fffce0;background-color:var(--diff-gutter-selected-background-color);color:var(--diff-text-color);color:var(--diff-gutter-selected-text-color)}.diff-code{word-wrap:break-word;padding:0 0 0 .5em;white-space:pre-wrap;word-break:break-all}.diff-code-edit{color:inherit}.diff-code-insert{background-color:#eaffee;background-color:var(--diff-code-insert-background-color);color:var(--diff-text-color);color:var(--diff-code-insert-text-color)}.diff-code-insert .diff-code-edit{background-color:#c0dc91;background-color:var(--diff-code-insert-edit-background-color);color:var(--diff-text-color);color:var(--diff-code-insert-edit-text-color)}.diff-code-delete{background-color:#fdeff0;background-color:var(--diff-code-delete-background-color);color:var(--diff-text-color);color:var(--diff-code-delete-text-color)}.diff-code-delete .diff-code-edit{background-color:#f39ea2;background-color:var(--diff-code-delete-edit-background-color);color:var(--diff-text-color);color:var(--diff-code-delete-edit-text-color)}.diff-code-selected{background-color:#fffce0;background-color:var(--diff-code-selected-background-color);color:var(--diff-text-color);color:var(--diff-code-selected-text-color)}.diff-widget-content{vertical-align:top}.diff-gutter-col{width:7ch}.diff-gutter-omit{height:0}.diff-gutter-omit:before{background-color:#cb2a1d;background-color:var(--diff-omit-gutter-line-color);content:" ";display:block;height:100%;margin-left:4.6ch;overflow:hidden;white-space:pre;width:2px}.diff-decoration{line-height:1.5;-webkit-user-select:none;-moz-user-select:none;user-select:none}.diff-decoration-content{font-family:Consolas,Courier,monospace;font-family:var(--diff-font-family);padding:0}:root{--font-ui: "Geist Variable", system-ui, sans-serif;--font-mono: "JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, monospace;--radius-sm: 6px;--radius-md: 9px;--radius-lg: 14px;--shadow-sm: 0 1px 2px oklch(.2 .02 285 / .06);--shadow-md: 0 6px 24px -8px oklch(.2 .04 285 / .18);--shadow-pop: 0 12px 40px -10px oklch(.2 .04 285 / .28);--ease: cubic-bezier(.22, 1, .36, 1);--accent: oklch(.56 .19 285);--accent-hover: oklch(.51 .2 285);--accent-fg: oklch(.99 .01 285);--accent-soft: oklch(.56 .19 285 / .12)}:root[data-theme=light]{color-scheme:light;--bg: oklch(.991 .003 285);--bg-subtle: oklch(.975 .005 285);--bg-inset: oklch(.955 .007 285);--bg-hover: oklch(.945 .009 285);--border: oklch(.905 .008 285);--border-strong: oklch(.84 .012 285);--text: oklch(.28 .025 285);--text-muted: oklch(.52 .018 285);--text-faint: oklch(.64 .014 285);--open: oklch(.66 .15 65);--open-soft: oklch(.66 .15 65 / .16);--resolved: oklch(.6 .13 150);--resolved-soft: oklch(.6 .13 150 / .16);--danger: oklch(.56 .2 25);--add: oklch(.55 .13 150);--del: oklch(.57 .2 25)}:root[data-theme=dark]{color-scheme:dark;--accent: oklch(.74 .15 286);--accent-hover: oklch(.8 .15 286);--accent-fg: oklch(.17 .02 285);--accent-soft: oklch(.74 .15 286 / .16);--bg: oklch(.178 .012 285);--bg-subtle: oklch(.214 .014 285);--bg-inset: oklch(.246 .016 285);--bg-hover: oklch(.28 .018 285);--border: oklch(.31 .016 285);--border-strong: oklch(.4 .02 285);--text: oklch(.93 .008 285);--text-muted: oklch(.7 .015 285);--text-faint: oklch(.58 .016 285);--open: oklch(.78 .14 70);--open-soft: oklch(.78 .14 70 / .18);--resolved: oklch(.74 .14 152);--resolved-soft: oklch(.74 .14 152 / .18);--danger: oklch(.7 .17 25);--add: oklch(.78 .14 152);--del: oklch(.72 .16 25)}*{box-sizing:border-box}html,body{margin:0;height:100%}body{font-family:var(--font-ui);font-size:14px;line-height:1.5;color:var(--text);background:var(--bg);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}::selection{background:var(--accent-soft)}.app{height:100vh;display:flex;flex-direction:column}.topbar{display:flex;align-items:center;gap:14px;padding:12px 20px;border-bottom:1px solid var(--border);background:color-mix(in oklch,var(--bg-subtle) 86%,transparent);-webkit-backdrop-filter:saturate(1.4) blur(6px);backdrop-filter:saturate(1.4) blur(6px);position:sticky;top:0;z-index:20}.brand{display:flex;align-items:center;gap:9px;font-weight:600;letter-spacing:-.01em}.brand h1{font-size:15px;margin:0;font-weight:600}.brand .mark{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:7px;color:#fff;background:linear-gradient(140deg,var(--accent),oklch(.62 .17 320));box-shadow:var(--shadow-sm)}.spacer{flex:1}.toolset{display:flex;align-items:center;gap:8px}button{font:inherit;font-weight:500;display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);color:var(--text);cursor:pointer;transition:background .14s var(--ease),border-color .14s var(--ease),transform .1s var(--ease)}button:hover{background:var(--bg-hover);border-color:var(--border-strong)}button:active{transform:translateY(1px)}button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}button.primary{background:var(--accent);color:var(--accent-fg);border-color:transparent}button.primary:hover{background:var(--accent-hover)}button.primary.is-exported{background:var(--resolved);border-color:transparent}button.primary.is-exported:hover{filter:brightness(.96)}button.icon{padding:7px;width:34px;height:34px;justify-content:center}button:disabled{opacity:.45;cursor:not-allowed}.count-pill{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 6px;border-radius:999px;font-size:11px;font-weight:600;background:var(--accent-fg);color:var(--accent)}.field{display:inline-flex;flex-direction:column;gap:0;position:relative}.select{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;font-weight:500;padding:6px 30px 6px 11px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);color:var(--text);cursor:pointer;transition:border-color .14s var(--ease),background .14s var(--ease)}.select:hover{border-color:var(--border-strong)}.select:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.field:after{content:"";position:absolute;right:11px;top:50%;width:8px;height:8px;border-right:1.5px solid var(--text-muted);border-bottom:1.5px solid var(--text-muted);transform:translateY(-65%) rotate(45deg);pointer-events:none}.ref-picker{display:flex;align-items:center;gap:8px}.divider{width:1px;height:22px;background:var(--border)}.banner{padding:10px 20px;font-size:13px;display:flex;align-items:center;gap:8px;border-bottom:1px solid var(--border)}.banner.error{background:color-mix(in oklch,var(--danger) 12%,var(--bg));color:var(--danger)}.banner.info{background:var(--accent-soft);color:var(--accent)}.layout{flex:1;display:grid;grid-template-columns:290px 1fr;overflow:hidden}aside{border-right:1px solid var(--border);overflow-y:auto;background:var(--bg-subtle)}main{overflow-y:auto;padding:22px 26px 80px;scroll-behavior:smooth}.empty{color:var(--text-muted);padding:80px 24px;text-align:center;font-size:15px}.file-list{padding:16px 12px}.file-list h2{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.07em;color:var(--text-faint);margin:0 8px 10px}.file-list ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px}.file-list a{display:flex;align-items:center;gap:9px;padding:7px 9px;border-radius:var(--radius-sm);text-decoration:none;color:var(--text);transition:background .12s var(--ease)}.file-list a:hover{background:var(--bg-hover)}.file-list-path{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-family:var(--font-mono);font-feature-settings:"liga" 0}.ftype{display:inline-flex;width:18px;height:18px;align-items:center;justify-content:center;border-radius:5px;font-size:10px;font-weight:700;color:var(--accent-fg);background:var(--text-faint);flex-shrink:0}.ftype-add{background:var(--add)}.ftype-delete{background:var(--del)}.ftype-modify{background:var(--open)}.ftype-rename,.ftype-copy{background:var(--accent)}.badge{background:var(--open);color:#1f1306;border-radius:999px;padding:0 7px;font-size:11px;font-weight:600;line-height:18px;min-width:18px;text-align:center;flex-shrink:0}.file-diff{border:1px solid var(--border);border-radius:var(--radius-lg);margin-bottom:22px;overflow:hidden;box-shadow:var(--shadow-sm)}.file-diff-header{display:flex;align-items:center;gap:10px;padding:11px 16px;background:var(--bg-subtle);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:2}.file-diff-header .file-path{font-family:var(--font-mono);font-size:12.5px;font-weight:500;font-feature-settings:"liga" 0}.diff{--diff-font-family: var(--font-mono);font-size:12.5px}.diff-line{font-feature-settings:"liga" 0,"calt" 0}.diff-gutter{color:var(--code-gutter-fg);transition:background .1s var(--ease)}.diff-gutter:hover{background:var(--accent-soft)!important}.diff-gutter:hover>a:after{content:"+";position:absolute;margin-left:.4ch;color:var(--accent);font-weight:700}.thread{background:var(--bg-subtle);border-top:1px solid var(--border-strong);border-bottom:1px solid var(--border-strong);padding:14px 18px;display:flex;flex-direction:column;gap:10px;font-family:var(--font-ui)}.review-comment{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-md);padding:11px 13px;box-shadow:var(--shadow-sm)}.review-comment.resolved{opacity:.62}.comment-body{white-space:pre-wrap;word-break:break-word;margin-bottom:9px;line-height:1.55}.comment-actions{display:flex;align-items:center;gap:8px;font-size:12px}.status-chip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;text-transform:capitalize;padding:2px 9px;border-radius:999px}.status-chip:before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}.status-chip.open{color:var(--open);background:var(--open-soft)}.status-chip.resolved{color:var(--resolved);background:var(--resolved-soft)}.comment-actions .spacer{flex:1}.comment-actions button{padding:3px 9px;font-size:12px}.composer{display:flex;flex-direction:column;gap:8px}.composer textarea{font:inherit;width:100%;min-height:64px;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg);color:var(--text);resize:vertical;transition:border-color .14s var(--ease),box-shadow .14s var(--ease)}.composer textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}.composer textarea::placeholder{color:var(--text-faint)}.composer-actions{display:flex;align-items:center;gap:10px}.hint{color:var(--text-faint);font-size:11px}kbd{font-family:var(--font-mono);font-size:10.5px;padding:1px 5px;border:1px solid var(--border);border-bottom-width:2px;border-radius:5px;background:var(--bg-inset);color:var(--text-muted)}.toast{position:fixed;bottom:24px;left:50%;z-index:100;display:flex;align-items:center;gap:10px;max-width:min(460px,calc(100vw - 32px));padding:11px 12px 11px 14px;border:1px solid var(--border-strong);border-radius:var(--radius-md);background:var(--bg);color:var(--text);box-shadow:var(--shadow-pop);transform:translate(-50%);animation:toast-in .32s var(--ease)}@keyframes toast-in{0%{opacity:0;transform:translate(-50%,12px)}to{opacity:1;transform:translate(-50%)}}.toast-icon{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:999px;flex-shrink:0}.toast-success .toast-icon{color:var(--resolved);background:var(--resolved-soft)}.toast-error .toast-icon{color:var(--danger);background:color-mix(in oklch,var(--danger) 16%,transparent)}.toast-message{flex:1;font-size:13px;line-height:1.4}.toast-close{border:none;background:none;padding:0 4px;font-size:18px;line-height:1;color:var(--text-faint);cursor:pointer}.toast-close:hover{background:none;color:var(--text)}@media (prefers-reduced-motion: reduce){.toast{animation:none}}[data-code-theme]{--diff-background-color: var(--code-bg);--diff-text-color: var(--code-fg);--diff-selection-background-color: var(--code-sel);--diff-gutter-insert-background-color: var(--code-ins-gutter);--diff-gutter-delete-background-color: var(--code-del-gutter);--diff-code-insert-background-color: var(--code-ins-bg);--diff-code-delete-background-color: var(--code-del-bg);--diff-gutter-selected-background-color: var(--code-sel);--diff-code-selected-background-color: var(--code-sel)}.file-diff .diff{background:var(--code-bg)}.token.comment,.token.prolog,.token.cdata,.token.doctype{color:var(--tk-comment);font-style:italic}.token.punctuation{color:var(--tk-punct)}.token.keyword,.token.atrule,.token.rule,.token.important{color:var(--tk-keyword)}.token.number,.token.boolean,.token.constant,.token.symbol,.token.unit{color:var(--tk-number)}.token.string,.token.char,.token.attr-value,.token.url,.token.inserted{color:var(--tk-string)}.token.function,.token.function-name{color:var(--tk-function)}.token.class-name,.token.maybe-class-name,.token.builtin,.token.namespace{color:var(--tk-class)}.token.variable,.token.property,.token.attr-name,.token.parameter{color:var(--tk-variable)}.token.operator,.token.entity{color:var(--tk-operator)}.token.tag,.token.selector{color:var(--tk-tag)}.token.regex,.token.deleted{color:var(--tk-regex)}.token.bold{font-weight:600}.token.italic{font-style:italic}[data-code-theme=github-light]{--code-bg: #fcfcfd;--code-fg: #1f2328;--code-gutter-fg: #8c959f;--code-sel: #dbe9ff;--code-ins-bg: #e6ffec;--code-del-bg: #ffebe9;--code-ins-gutter: #c6f6d0;--code-del-gutter: #ffd7d5;--tk-comment: #6e7781;--tk-punct: #24292f;--tk-keyword: #cf222e;--tk-number: #0550ae;--tk-string: #0a3069;--tk-function: #8250df;--tk-class: #953800;--tk-variable: #953800;--tk-operator: #cf222e;--tk-tag: #116329;--tk-regex: #116329}[data-code-theme=github-dark]{--code-bg: #0d1117;--code-fg: #c9d1d9;--code-gutter-fg: #6e7681;--code-sel: #214283;--code-ins-bg: #12261c;--code-del-bg: #25171b;--code-ins-gutter: #1b4524;--code-del-gutter: #5d2025;--tk-comment: #8b949e;--tk-punct: #c9d1d9;--tk-keyword: #ff7b72;--tk-number: #79c0ff;--tk-string: #a5d6ff;--tk-function: #d2a8ff;--tk-class: #ffa657;--tk-variable: #ffa657;--tk-operator: #ff7b72;--tk-tag: #7ee787;--tk-regex: #7ee787}[data-code-theme=one-dark]{--code-bg: #282c34;--code-fg: #abb2bf;--code-gutter-fg: #5c6370;--code-sel: #3e4451;--code-ins-bg: #2a3a2f;--code-del-bg: #3a2a30;--code-ins-gutter: #36513e;--code-del-gutter: #51343c;--tk-comment: #5c6370;--tk-punct: #abb2bf;--tk-keyword: #c678dd;--tk-number: #d19a66;--tk-string: #98c379;--tk-function: #61afef;--tk-class: #e5c07b;--tk-variable: #e06c75;--tk-operator: #56b6c2;--tk-tag: #e06c75;--tk-regex: #98c379}[data-code-theme=dracula]{--code-bg: #282a36;--code-fg: #f8f8f2;--code-gutter-fg: #6272a4;--code-sel: #44475a;--code-ins-bg: #233a2c;--code-del-bg: #3d2231;--code-ins-gutter: #2f5339;--code-del-gutter: #5a2d3f;--tk-comment: #6272a4;--tk-punct: #f8f8f2;--tk-keyword: #ff79c6;--tk-number: #bd93f9;--tk-string: #f1fa8c;--tk-function: #50fa7b;--tk-class: #8be9fd;--tk-variable: #f8f8f2;--tk-operator: #ff79c6;--tk-tag: #ff79c6;--tk-regex: #f1fa8c}[data-code-theme=nord]{--code-bg: #2e3440;--code-fg: #d8dee9;--code-gutter-fg: #4c566a;--code-sel: #434c5e;--code-ins-bg: #34453a;--code-del-bg: #43353a;--code-ins-gutter: #3f5a45;--code-del-gutter: #5a4046;--tk-comment: #616e88;--tk-punct: #d8dee9;--tk-keyword: #81a1c1;--tk-number: #b48ead;--tk-string: #a3be8c;--tk-function: #88c0d0;--tk-class: #8fbcbb;--tk-variable: #d8dee9;--tk-operator: #81a1c1;--tk-tag: #81a1c1;--tk-regex: #ebcb8b}[data-code-theme=monokai]{--code-bg: #272822;--code-fg: #f8f8f2;--code-gutter-fg: #75715e;--code-sel: #49483e;--code-ins-bg: #2d3327;--code-del-bg: #382528;--code-ins-gutter: #3c4a2f;--code-del-gutter: #55323a;--tk-comment: #88846f;--tk-punct: #f8f8f2;--tk-keyword: #f92672;--tk-number: #ae81ff;--tk-string: #e6db74;--tk-function: #a6e22e;--tk-class: #a6e22e;--tk-variable: #f8f8f2;--tk-operator: #f92672;--tk-tag: #f92672;--tk-regex: #e6db74}[data-code-theme=solarized-light]{--code-bg: #fdf6e3;--code-fg: #586e75;--code-gutter-fg: #93a1a1;--code-sel: #eee8d5;--code-ins-bg: #e9efd0;--code-del-bg: #f6e0d8;--code-ins-gutter: #d9e4b0;--code-del-gutter: #f0cfc4;--tk-comment: #93a1a1;--tk-punct: #586e75;--tk-keyword: #859900;--tk-number: #d33682;--tk-string: #2aa198;--tk-function: #268bd2;--tk-class: #b58900;--tk-variable: #268bd2;--tk-operator: #859900;--tk-tag: #268bd2;--tk-regex: #2aa198}