realitydiff 0.4.0__py3-none-any.whl

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.
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2
+ <rect width="32" height="32" fill="#0c0d0a"/>
3
+ <text x="16" y="23" text-anchor="middle" font-family="Georgia, serif" font-size="20" fill="#b6e388">�</text>
4
+ </svg>
@@ -0,0 +1,175 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Reality Diff — Git for beliefs</title>
7
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
8
+ <link rel="stylesheet" href="/static/styles.css?v=0.4.6" />
9
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
10
+ <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Instrument+Serif:ital@0;1&display=swap" rel="stylesheet" />
11
+ </head>
12
+ <body>
13
+ <div class="grain" aria-hidden="true"></div>
14
+ <div class="app" id="app">
15
+ <div class="pane-switch" role="tablist" aria-label="Workspace panes">
16
+ <button type="button" id="show-claims" role="tab">claims</button>
17
+ <button type="button" id="show-stage" role="tab" class="on">belief</button>
18
+ <button type="button" id="show-log" role="tab">history</button>
19
+ </div>
20
+ <aside class="rail" id="rail">
21
+ <header class="brand">
22
+ <div class="mark">Δ</div>
23
+ <div>
24
+ <h1>Reality Diff</h1>
25
+ <p>git for beliefs</p>
26
+ </div>
27
+ </header>
28
+ <form id="open-form" class="open-form">
29
+ <label for="claim-input">New claim</label>
30
+ <textarea id="claim-input" rows="3" maxlength="2000" placeholder="Apple is going to replace Siri with an LLM." required></textarea>
31
+ <button type="submit" id="open-btn">claim.open()</button>
32
+ </form>
33
+ <label class="filter-label" for="claim-filter">Filter heads</label>
34
+ <input id="claim-filter" type="search" placeholder="search claims" />
35
+ <div class="seg" id="status-filter" role="tablist" aria-label="Claim status">
36
+ <button type="button" data-status="all" class="on" role="tab">all <span class="seg-n">0</span></button>
37
+ <button type="button" data-status="open" role="tab">open <span class="seg-n">0</span></button>
38
+ <button type="button" data-status="closed" role="tab">closed <span class="seg-n">0</span></button>
39
+ </div>
40
+ <section class="claim-list-wrap">
41
+ <h2>HEADS <span class="count" id="heads-count">0</span></h2>
42
+ <ul id="claim-list"></ul>
43
+ </section>
44
+ <p class="keys" id="keys"><kbd>/</kbd> filter · <kbd>j</kbd><kbd>k</kbd> claims · <kbd>w</kbd> watch · <kbd>d</kbd> diff · <kbd>b</kbd> blame · <kbd>esc</kbd> close</p>
45
+ </aside>
46
+ <div class="gutter" data-side="rail" title="Drag to resize"></div>
47
+
48
+ <main class="stage">
49
+ <div id="watch-status" class="watch-status hidden" role="status"></div>
50
+ <div id="empty" class="empty">
51
+ <p class="kicker">living claims</p>
52
+ <p class="serif">Give it a claim.</p>
53
+ <p class="hint why">News feeds overwrite your memory. Reality Diff keeps a git history of a belief: what the internet said, how confident we were, and why that number moved. Diff two weeks, blame a confidence jump, or revert a rumor panic — useful when a claim is still unfolding and you need a trail, not a vibe.</p>
54
+ <ol class="empty-steps">
55
+ <li>open a testable claim</li>
56
+ <li>inspect for / against / unknowns / predictions</li>
57
+ <li>watch, diff, blame, browse a commit, or revert</li>
58
+ </ol>
59
+ </div>
60
+ <section id="claim-view" class="hidden">
61
+ <div id="browse-banner" class="browse-banner hidden">
62
+ Browsing commit <span id="browse-sha"></span> — read-only snapshot.
63
+ <button type="button" class="ghost" id="browse-head">return to HEAD</button>
64
+ </div>
65
+ <header class="claim-head">
66
+ <div>
67
+ <div class="kicker-row">
68
+ <span class="kicker" id="claim-id"></span>
69
+ <button type="button" class="ghost" id="copy-id" title="Copy claim id">copy</button>
70
+ <span id="watching-chip" class="chip">watching</span>
71
+ <span id="closed-chip" class="chip hidden">closed</span>
72
+ <span id="dirty-chip" class="chip hidden">dirty</span>
73
+ </div>
74
+ <h2 class="serif" id="claim-title"></h2>
75
+ <p class="refined" id="claim-refined"></p>
76
+ </div>
77
+ <div class="confidence-card" id="confidence-card">
78
+ <div class="conf-label" id="conf-label">confidence</div>
79
+ <div class="conf-value" id="conf-value">—</div>
80
+ <div class="conf-delta" id="conf-delta"></div>
81
+ <div class="conf-bar"><span id="conf-fill"></span></div>
82
+ <svg id="spark" class="spark" viewBox="0 0 120 28" preserveAspectRatio="none"></svg>
83
+ </div>
84
+ </header>
85
+ <div id="outcome-banner" class="outcome-banner hidden">
86
+ <span class="kicker">final outcome</span>
87
+ <strong id="outcome-verdict"></strong>
88
+ <p id="outcome-summary"></p>
89
+ <a id="outcome-source" class="src hidden" target="_blank" rel="noreferrer"></a>
90
+ </div>
91
+ <p class="reason" id="claim-reason"></p>
92
+ <nav id="stat-strip" class="stat-strip" aria-label="Belief sections">
93
+ <a href="#sec-for">for <span data-count-for="count-for">0</span></a>
94
+ <a href="#sec-against">against <span data-count-for="count-against">0</span></a>
95
+ <a href="#sec-unknowns">unknowns <span data-count-for="count-unknowns">0</span></a>
96
+ <a href="#sec-predictions">predictions <span data-count-for="count-predictions">0</span></a>
97
+ </nav>
98
+ <div class="actions">
99
+ <div class="action-row">
100
+ <button id="watch-btn">claim.watch()</button>
101
+ <button id="diff-btn">claim.diff()</button>
102
+ <button id="blame-btn">claim.blame()</button>
103
+ <button id="revert-btn" class="danger">claim.revert()</button>
104
+ </div>
105
+ <div class="action-row" id="watch-controls">
106
+ <label class="watch-toggle">
107
+ <input type="checkbox" id="watching-toggle" />
108
+ live watch
109
+ </label>
110
+ <label class="watch-toggle" for="watch-interval">every
111
+ <select id="watch-interval">
112
+ <option value="60">1m</option>
113
+ <option value="300" selected>5m</option>
114
+ <option value="900">15m</option>
115
+ <option value="3600">1h</option>
116
+ <option value="21600">6h</option>
117
+ <option value="86400">1d</option>
118
+ </select>
119
+ </label>
120
+ </div>
121
+ <button type="button" id="service-btn" class="ghost">install timer service</button>
122
+ </div>
123
+ <div class="tree-grid">
124
+ <article id="sec-for">
125
+ <h3>Evidence FOR <span class="count" id="count-for">0</span></h3>
126
+ <ul id="ev-for" class="stack"></ul>
127
+ </article>
128
+ <article id="sec-against">
129
+ <h3>Evidence AGAINST <span class="count" id="count-against">0</span></h3>
130
+ <ul id="ev-against" class="stack"></ul>
131
+ </article>
132
+ <article id="sec-unknowns">
133
+ <h3>Unknowns <span class="count" id="count-unknowns">0</span></h3>
134
+ <ul id="unknowns" class="stack"></ul>
135
+ </article>
136
+ <article id="sec-predictions">
137
+ <h3>Predictions <span class="count" id="count-predictions">0</span></h3>
138
+ <ul id="predictions" class="stack"></ul>
139
+ </article>
140
+ </div>
141
+ <section class="summary-card">
142
+ <h3>Belief</h3>
143
+ <p class="summary" id="summary"></p>
144
+ </section>
145
+ </section>
146
+ </main>
147
+ <div class="gutter" data-side="log" title="Drag to resize"></div>
148
+
149
+ <aside class="log-pane" id="log-pane">
150
+ <header>
151
+ <h2>git tree</h2>
152
+ <span id="log-meta"></span>
153
+ </header>
154
+ <ol id="commit-log"></ol>
155
+ </aside>
156
+ </div>
157
+ <div id="inspector-backdrop" class="inspector-backdrop hidden"></div>
158
+ <section id="detail" class="detail hidden" role="dialog" aria-modal="true" aria-labelledby="detail-title">
159
+ <div class="detail-head">
160
+ <h2 id="detail-title">diff</h2>
161
+ <button type="button" class="ghost" id="detail-close">close</button>
162
+ </div>
163
+ <div id="detail-body" class="detail-body"></div>
164
+ </section>
165
+ <div id="overlay" class="overlay hidden" role="status">
166
+ <div class="overlay-card">
167
+ <div class="spinner" aria-hidden="true"></div>
168
+ <p class="serif" id="overlay-title">Surveying the internet</p>
169
+ <p class="hint" id="overlay-sub">Grok is searching the web and X… <span id="elapsed">0s</span></p>
170
+ </div>
171
+ </div>
172
+ <div id="toast" class="toast hidden"></div>
173
+ <script src="/static/app.js?v=0.4.6"></script>
174
+ </body>
175
+ </html>
@@ -0,0 +1,477 @@
1
+ :root {
2
+ --bg: #0b0c09;
3
+ --bg-2: #12130e;
4
+ --ink: #efe8cc;
5
+ --muted: #8f896f;
6
+ --line: #2c2e23;
7
+ --for: #b6e388;
8
+ --against: #e28b73;
9
+ --unknown: #d6c27a;
10
+ --accent: #9ad0c2;
11
+ --danger: #e28b73;
12
+ --space-1: 8px;
13
+ --space-2: 14px;
14
+ --space-3: 20px;
15
+ --space-4: 28px;
16
+ --space-5: 40px;
17
+ --space-6: 56px;
18
+ --space-7: 80px;
19
+ }
20
+
21
+ * { box-sizing: border-box; }
22
+ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink); }
23
+ body {
24
+ font-family: "IBM Plex Mono", ui-monospace, monospace;
25
+ font-size: 14px;
26
+ line-height: 1.6;
27
+ letter-spacing: -0.01em;
28
+ }
29
+ .grain {
30
+ pointer-events: none;
31
+ position: fixed;
32
+ inset: 0;
33
+ opacity: 0.045;
34
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8'/%3E%3C/filter%3E%3Crect width='80' height='80' filter='url(%23n)'/%3E%3C/svg%3E");
35
+ z-index: 4;
36
+ }
37
+ .serif { font-family: "Instrument Serif", Georgia, serif; font-weight: 400; letter-spacing: 0; }
38
+ .app {
39
+ display: grid;
40
+ grid-template-columns: var(--rail-w, 300px) 12px minmax(0, 1fr) 12px var(--log-w, 360px);
41
+ min-height: 100vh;
42
+ }
43
+ .gutter {
44
+ cursor: col-resize;
45
+ background: var(--bg);
46
+ border-left: 1px solid var(--line);
47
+ border-right: 1px solid var(--line);
48
+ }
49
+ .gutter:hover, .gutter.dragging { background: #1c1e16; }
50
+ .rail, .log-pane {
51
+ background: var(--bg-2);
52
+ border-right: 1px solid var(--line);
53
+ padding: 40px 28px;
54
+ overflow: auto;
55
+ }
56
+ .log-pane { border-right: 0; border-left: 1px solid var(--line); }
57
+ .log-pane header {
58
+ display: flex;
59
+ justify-content: space-between;
60
+ align-items: baseline;
61
+ gap: var(--space-2);
62
+ margin-bottom: var(--space-4);
63
+ }
64
+ .brand { display: flex; gap: 16px; align-items: center; margin-bottom: var(--space-5); }
65
+ .mark {
66
+ width: 40px; height: 40px; border: 1px solid var(--for);
67
+ display: grid; place-items: center; color: var(--for); font-size: 22px;
68
+ }
69
+ .brand h1 { margin: 0; font-size: 15px; font-weight: 600; }
70
+ .brand p { margin: 4px 0 0; color: var(--muted); font-size: 12px; }
71
+ .open-form { margin-bottom: var(--space-5); }
72
+ .claim-list-wrap { margin-top: var(--space-4); }
73
+ .claim-list-wrap h2 { margin: 0 0 var(--space-2); }
74
+ .open-form label, .claim-list-wrap h2, .log-pane h2, .tree-grid h3, .kicker, .conf-label,
75
+ .filter-label, .summary-card h3, .detail-head h2 {
76
+ font-size: 11px;
77
+ text-transform: uppercase;
78
+ letter-spacing: 0.16em;
79
+ color: var(--muted);
80
+ }
81
+ .filter-label { display: block; margin-bottom: 4px; }
82
+ .tree-grid h3, .summary-card h3 { margin: 0 0 var(--space-3); }
83
+ textarea, button, pre, input, select {
84
+ font: inherit;
85
+ color: inherit;
86
+ }
87
+ textarea, input[type="search"] {
88
+ width: 100%;
89
+ background: #0c0d0a;
90
+ border: 1px solid var(--line);
91
+ padding: 14px 16px;
92
+ margin: 10px 0 16px;
93
+ }
94
+ textarea { resize: vertical; min-height: 96px; }
95
+ textarea:focus, input:focus, button:focus-visible {
96
+ outline: 1px solid var(--accent);
97
+ outline-offset: 2px;
98
+ }
99
+ button {
100
+ background: transparent;
101
+ border: 1px solid var(--accent);
102
+ color: var(--accent);
103
+ padding: 10px 16px;
104
+ cursor: pointer;
105
+ }
106
+ button:hover { background: rgba(154, 208, 194, 0.08); }
107
+ button:disabled { opacity: 0.45; cursor: wait; }
108
+ button.danger { border-color: var(--danger); color: var(--danger); }
109
+ button.ghost {
110
+ border: 0;
111
+ padding: 0 8px;
112
+ color: var(--muted);
113
+ font-size: 11px;
114
+ letter-spacing: 0.12em;
115
+ text-transform: uppercase;
116
+ }
117
+ #claim-list, #commit-log, .stack { list-style: none; padding: 0; margin: 0; }
118
+ #claim-list li, #commit-log li, .stack li {
119
+ border-top: 1px solid var(--line);
120
+ padding: 18px 0;
121
+ }
122
+ #claim-list li, #commit-log li { cursor: pointer; }
123
+ #claim-list li.empty-item { cursor: default; color: var(--muted); }
124
+ #claim-list li.active {
125
+ color: var(--for);
126
+ background: rgba(182, 227, 136, 0.06);
127
+ margin: 0 -12px;
128
+ padding-left: 12px;
129
+ padding-right: 12px;
130
+ }
131
+ #claim-list li:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
132
+ #commit-log li.active { background: rgba(182, 227, 136, 0.06); }
133
+ .claim-meta { color: var(--muted); font-size: 12px; margin-top: 8px; display: flex; gap: 12px; align-items: center; }
134
+ .mini-spark { color: var(--for); }
135
+ .stage { padding: 52px 64px var(--space-7); overflow: auto; }
136
+ .empty { max-width: 580px; margin-top: 12vh; }
137
+ .empty .serif { font-size: 52px; margin: 16px 0 20px; }
138
+ .hint { color: var(--muted); line-height: 1.75; }
139
+ .empty-steps { color: var(--muted); padding-left: 22px; line-height: 2; margin-top: var(--space-4); }
140
+ .hidden { display: none !important; }
141
+ .claim-head {
142
+ display: flex;
143
+ justify-content: space-between;
144
+ gap: var(--space-5);
145
+ align-items: flex-start;
146
+ position: sticky;
147
+ top: 0;
148
+ z-index: 2;
149
+ background: linear-gradient(var(--bg) 78%, transparent);
150
+ padding-bottom: 12px;
151
+ }
152
+ .claim-head h2 { font-size: 36px; line-height: 1.28; margin: 16px 0 14px; max-width: 760px; }
153
+ .refined { color: var(--muted); max-width: 680px; line-height: 1.7; margin: 0; }
154
+ .kicker-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
155
+ .chip {
156
+ font-size: 11px;
157
+ letter-spacing: 0.12em;
158
+ text-transform: uppercase;
159
+ border: 1px solid var(--for);
160
+ color: var(--for);
161
+ padding: 4px 10px;
162
+ }
163
+ .chip.off { border-color: var(--muted); color: var(--muted); }
164
+ .chip.closed { border-color: var(--unknown); color: var(--unknown); }
165
+ .chip.closed.confirmed { border-color: var(--for); color: var(--for); }
166
+ .chip.closed.falsified { border-color: var(--against); color: var(--against); }
167
+ .confidence-card {
168
+ min-width: 200px;
169
+ border: 1px solid var(--line);
170
+ padding: 22px 24px;
171
+ background: rgba(12, 13, 10, 0.6);
172
+ }
173
+ .conf-value { font-size: 44px; font-family: "Instrument Serif", serif; line-height: 1.1; }
174
+ .conf-delta { font-size: 12px; color: var(--muted); min-height: 18px; margin-top: 6px; }
175
+ .conf-delta.up { color: var(--for); }
176
+ .conf-delta.down { color: var(--against); }
177
+ .conf-bar { height: 3px; background: var(--line); margin-top: 16px; }
178
+ .conf-bar span { display: block; height: 100%; background: var(--for); width: 0; transition: width 0.4s ease; }
179
+ .confidence-card.low .conf-value { color: var(--against); }
180
+ .confidence-card.low .conf-bar span { background: var(--against); }
181
+ .confidence-card.mid .conf-value { color: var(--unknown); }
182
+ .confidence-card.mid .conf-bar span { background: var(--unknown); }
183
+ .confidence-card.high .conf-value { color: var(--for); }
184
+ .spark { width: 100%; height: 32px; margin-top: 16px; display: block; }
185
+ .reason { color: var(--unknown); line-height: 1.8; max-width: 72ch; margin: var(--space-5) 0 0; }
186
+ .outcome-banner {
187
+ max-width: 72ch;
188
+ border: 1px solid var(--unknown);
189
+ color: var(--ink);
190
+ padding: 16px 18px;
191
+ margin: var(--space-5) 0 0;
192
+ }
193
+ .outcome-banner.confirmed { border-color: var(--for); }
194
+ .outcome-banner.falsified { border-color: var(--against); }
195
+ .outcome-banner .kicker { display: block; margin-bottom: 6px; }
196
+ .outcome-banner strong {
197
+ display: block;
198
+ letter-spacing: 0.12em;
199
+ text-transform: uppercase;
200
+ font-size: 12px;
201
+ margin-bottom: 8px;
202
+ }
203
+ .outcome-banner p { margin: 0; line-height: 1.7; color: var(--muted); }
204
+ .src, a.src {
205
+ color: var(--accent);
206
+ text-decoration: none;
207
+ font-size: 12px;
208
+ display: block;
209
+ margin-top: 10px;
210
+ word-break: break-all;
211
+ }
212
+ a.src:visited { color: var(--accent); }
213
+ a.src:hover { text-decoration: underline; }
214
+ #claim-view.is-closed #watch-btn,
215
+ #claim-view.is-closed #watch-controls,
216
+ #claim-view.is-closed #claim-reason { display: none; }
217
+ .actions {
218
+ display: flex;
219
+ flex-direction: column;
220
+ align-items: flex-start;
221
+ gap: var(--space-3);
222
+ margin: var(--space-5) 0 var(--space-6);
223
+ }
224
+ .action-row {
225
+ display: flex;
226
+ flex-wrap: wrap;
227
+ gap: 12px 14px;
228
+ align-items: center;
229
+ }
230
+ .watch-toggle { color: var(--muted); display: flex; gap: 10px; align-items: center; }
231
+ .tree-grid {
232
+ display: grid;
233
+ grid-template-columns: 1fr 1fr;
234
+ gap: var(--space-6) var(--space-6);
235
+ }
236
+ .count { color: var(--ink); letter-spacing: 0; text-transform: none; margin-left: 8px; }
237
+ .stack li { cursor: default; }
238
+ .stack li.empty-item { border-left: 0; padding-left: 0; color: var(--muted); }
239
+ .stack .src { color: var(--accent); font-size: 12px; display: block; margin-top: 8px; word-break: break-all; }
240
+ .weight { display: block; height: 3px; background: var(--line); margin-top: 12px; max-width: 180px; }
241
+ .weight span { display: block; height: 100%; background: currentColor; }
242
+ #ev-for .weight { color: var(--for); }
243
+ #ev-against .weight { color: var(--against); }
244
+ .stack .w { color: var(--muted); font-size: 12px; display: block; margin-top: 6px; }
245
+ .notes { color: var(--muted); display: block; margin-top: 10px; line-height: 1.65; }
246
+ #ev-for li { border-left: 2px solid var(--for); padding-left: 16px; }
247
+ #ev-against li { border-left: 2px solid var(--against); padding-left: 16px; }
248
+ #unknowns li { border-left: 2px solid var(--unknown); padding-left: 16px; }
249
+ #predictions li { border-left: 2px solid var(--accent); padding-left: 16px; }
250
+ .pred-status { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; margin-left: 10px; }
251
+ .pred-status.confirmed { color: var(--for); }
252
+ .pred-status.falsified { color: var(--against); }
253
+ .summary-card { margin-top: var(--space-6); max-width: 72ch; border-top: 1px solid var(--line); padding-top: var(--space-4); }
254
+ .summary { color: var(--muted); line-height: 1.8; margin: 0; }
255
+ #commit-log li { position: relative; padding: 22px 0 22px 20px; }
256
+ #commit-log li::before {
257
+ content: "";
258
+ position: absolute;
259
+ left: 0; top: 28px;
260
+ width: 7px; height: 7px;
261
+ border-radius: 50%;
262
+ background: var(--for);
263
+ }
264
+ #commit-log li .sha { color: var(--for); }
265
+ #commit-log li .msg { display: block; margin-top: 8px; line-height: 1.55; }
266
+ #commit-log li .why { color: var(--muted); display: block; margin-top: 8px; line-height: 1.65; }
267
+ .arrow.up { color: var(--for); }
268
+ .arrow.down { color: var(--against); }
269
+ .detail {
270
+ position: fixed;
271
+ top: 0;
272
+ right: 0;
273
+ bottom: 0;
274
+ width: min(680px, 100vw);
275
+ margin: 0;
276
+ border-left: 1px solid var(--line);
277
+ background: var(--bg-2);
278
+ padding: 40px 28px;
279
+ z-index: 8;
280
+ overflow: auto;
281
+ box-shadow: -28px 0 80px rgba(0, 0, 0, 0.45);
282
+ }
283
+ .detail-head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); position: sticky; top: 0; background: var(--bg-2); padding-bottom: 12px; }
284
+ .detail-body { margin-top: var(--space-3); }
285
+ .inspector-backdrop {
286
+ position: fixed;
287
+ inset: 0;
288
+ background: rgba(8, 9, 6, 0.5);
289
+ z-index: 7;
290
+ }
291
+ .hunk {
292
+ border: 1px solid var(--line);
293
+ margin-bottom: 14px;
294
+ padding: 14px 16px;
295
+ background: #0c0d0a;
296
+ }
297
+ .hunk .path { color: var(--accent); }
298
+ .hunk.add { border-left: 2px solid var(--for); }
299
+ .hunk.removed { border-left: 2px solid var(--against); }
300
+ .hunk.changed { border-left: 2px solid var(--unknown); }
301
+ .hunk .snip { color: var(--muted); margin-top: 10px; white-space: pre-wrap; word-break: break-word; line-height: 1.6; }
302
+ .blame-row {
303
+ border-top: 1px solid var(--line);
304
+ padding: 14px 0;
305
+ }
306
+ .blame-row .path { color: var(--accent); }
307
+ .overlay {
308
+ position: fixed; inset: 0;
309
+ background: rgba(8, 9, 6, 0.72);
310
+ display: grid; place-items: center;
311
+ z-index: 5;
312
+ }
313
+ .overlay-card {
314
+ text-align: center;
315
+ border: 1px solid var(--line);
316
+ background: var(--bg-2);
317
+ padding: 40px 44px;
318
+ min-width: 300px;
319
+ }
320
+ .spinner {
321
+ width: 28px; height: 28px;
322
+ border: 2px solid var(--line);
323
+ border-top-color: var(--for);
324
+ border-radius: 50%;
325
+ margin: 0 auto 20px;
326
+ animation: spin 0.8s linear infinite;
327
+ }
328
+ @keyframes spin { to { transform: rotate(360deg); } }
329
+ .toast {
330
+ position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
331
+ background: #1b1d14; border: 1px solid var(--line); padding: 12px 18px;
332
+ z-index: 6; max-width: min(640px, 90vw);
333
+ }
334
+ .status { color: var(--muted); font-size: 12px; }
335
+ @media (max-width: 1100px) {
336
+ .app { grid-template-columns: 1fr; }
337
+ .gutter { display: none; }
338
+ .tree-grid { grid-template-columns: 1fr; }
339
+ .rail, .log-pane { max-height: 42vh; padding: 28px 22px; }
340
+ .stage { padding: 36px 24px 64px; }
341
+ .claim-head { flex-direction: column; }
342
+ }
343
+ .watch-status {
344
+ border: 1px solid var(--line);
345
+ color: var(--muted);
346
+ padding: 12px 16px;
347
+ margin-bottom: var(--space-4);
348
+ display: flex;
349
+ gap: 12px;
350
+ align-items: center;
351
+ }
352
+ .watch-status::before {
353
+ content: "";
354
+ width: 8px;
355
+ height: 8px;
356
+ border-radius: 50%;
357
+ background: var(--for);
358
+ animation: pulse 1.4s ease infinite;
359
+ }
360
+ @keyframes pulse { 50% { opacity: 0.3; } }
361
+ .browse-banner {
362
+ border: 1px dashed var(--unknown);
363
+ color: var(--unknown);
364
+ padding: 12px 16px;
365
+ margin-bottom: var(--space-4);
366
+ display: flex;
367
+ gap: 12px;
368
+ align-items: center;
369
+ flex-wrap: wrap;
370
+ }
371
+ .git-node { display: flex; gap: 12px; align-items: flex-start; }
372
+ .git-graph {
373
+ color: var(--for);
374
+ white-space: pre;
375
+ line-height: 1.35;
376
+ margin-top: 4px;
377
+ min-width: 18px;
378
+ }
379
+ .commit-actions { display: flex; gap: 12px; margin-top: 12px; }
380
+ #watch-interval {
381
+ font: inherit;
382
+ color: var(--ink);
383
+ background: var(--bg-2);
384
+ border: 1px solid var(--line);
385
+ padding: 8px 10px;
386
+ color-scheme: dark;
387
+ }
388
+ #watch-interval option {
389
+ font: inherit;
390
+ color: var(--ink);
391
+ background: var(--bg-2);
392
+ }
393
+ .pane-switch { display: none; }
394
+ .seg { display: flex; gap: 8px; margin: 0 0 8px; }
395
+ .seg button {
396
+ flex: 1;
397
+ border-color: var(--line);
398
+ color: var(--muted);
399
+ padding: 8px 6px;
400
+ font-size: 11px;
401
+ letter-spacing: 0.12em;
402
+ text-transform: uppercase;
403
+ display: flex;
404
+ flex-direction: column;
405
+ align-items: center;
406
+ gap: 2px;
407
+ line-height: 1.3;
408
+ }
409
+ .seg button.on { border-color: var(--for); color: var(--for); }
410
+ .seg-n { letter-spacing: 0; }
411
+ .meter {
412
+ width: 52px;
413
+ height: 3px;
414
+ background: var(--line);
415
+ display: inline-block;
416
+ vertical-align: middle;
417
+ }
418
+ .meter > span { display: block; height: 100%; background: var(--for); }
419
+ #claim-list li.closed .meter > span { background: var(--unknown); }
420
+ #claim-list li.confirmed .meter > span { background: var(--for); }
421
+ #claim-list li.falsified .meter > span { background: var(--against); }
422
+ .mini-spark { width: 88px; height: 20px; display: block; margin-top: 10px; }
423
+ .stat-strip {
424
+ display: flex;
425
+ flex-wrap: wrap;
426
+ gap: 14px 20px;
427
+ margin-top: var(--space-4);
428
+ }
429
+ .stat-strip a {
430
+ color: var(--muted);
431
+ text-decoration: none;
432
+ font-size: 12px;
433
+ letter-spacing: 0.1em;
434
+ text-transform: uppercase;
435
+ }
436
+ .stat-strip a:hover, .stat-strip a:focus-visible { color: var(--ink); }
437
+ .keys {
438
+ color: var(--muted);
439
+ font-size: 11px;
440
+ line-height: 1.9;
441
+ margin-top: var(--space-5);
442
+ }
443
+ kbd {
444
+ font: inherit;
445
+ font-size: 11px;
446
+ color: var(--ink);
447
+ border: 1px solid var(--line);
448
+ padding: 0 6px;
449
+ }
450
+ .hunk.add .path { color: var(--for); }
451
+ .hunk.removed .path { color: var(--against); }
452
+ .hunk.changed .path { color: var(--unknown); }
453
+ @media (max-width: 1100px) {
454
+ .pane-switch {
455
+ display: flex;
456
+ gap: 8px;
457
+ position: sticky;
458
+ top: 0;
459
+ z-index: 3;
460
+ background: var(--bg);
461
+ padding: 12px 16px;
462
+ border-bottom: 1px solid var(--line);
463
+ }
464
+ .pane-switch button { flex: 1; border-color: var(--line); color: var(--muted); }
465
+ .pane-switch button.on { border-color: var(--for); color: var(--for); }
466
+ .app .rail, .app .log-pane { display: none; }
467
+ .app.show-rail .rail { display: block; max-height: none; }
468
+ .app.show-log .log-pane { display: block; max-height: none; }
469
+ .app.show-rail .stage, .app.show-log .stage { display: none; }
470
+ .keys { display: none; }
471
+ }
472
+ @media (prefers-reduced-motion: reduce) {
473
+ *, *::before, *::after {
474
+ animation: none !important;
475
+ transition: none !important;
476
+ }
477
+ }