oxios-web 0.2.0

Web dashboard channel for Oxios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
/* Brutal theme - inspired by Soviet brutalism + Andy Matuschak's notes garden.
   Paper-cream background, near-black text, monospace italic blockquotes,
   marker-pen orange highlight on links, heavy bold for emphasis. Cloned
   from theme-light.css and re-skinned; structure stays identical so the
   editor wiring is unaffected.

   Scoped to `prefers-color-scheme: light` — brutal is the light-mode look,
   theme-dark.css continues to handle OS-dark systems untouched. */
@media (prefers-color-scheme: light) {
:root {
    --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
    --font-mono-brutal: ui-monospace, SFMono-Regular, "Cascadia Code", "IBM Plex Mono", "Roboto Mono", "DejaVu Sans Mono", "Liberation Mono", Menlo, Monaco, "Consolas", "Source Code Pro", monospace;
    --color-neo-bg: #F4F4F0;
    --color-neo-text: #1A1A1A;
    --color-neo-border: #000;
    --color-neo-blue: #2E5CFF;
    --color-neo-lime: #C2F970;
    --color-neo-orange: #FF6B35;
    --col-tx: #1A1A1A !important;
    --col-tx-alt: #6B6B5C !important;
    --col-bg: #F4F4F0 !important;
    --col-bg-alt: #EDEDE5 !important;
    --col-inline-code: #1A1A1A !important;
    --col-inline-code-bg: #E5E5DC !important;
    --col-link: #1A1A1A !important;
    --col-link-hover: #1A1A1A !important;
    --col-url: #6B6B5C !important;
    --col-tx-sel: #000 !important;
    --col-msg-sel: color-mix(in srgb, #000, transparent 60%) !important;
    --col-bg-active: #E0E0D8 !important;
    --col-border: #000 !important;
    --col-marker: var(--color-neo-orange);
    --col-accent: #000;
}

/* Checkbox icon: dark glyph PNG colorized to neo-blue via filter so it
   visually matches the ordered-list number color. Scoped to
   `.hmd-hidden-token` so app.css's `:not(.hmd-hidden-token)
   { background-image: none }` rule can still cancel the image when the
   cursor is on the line - otherwise you'd see both the graphic AND the
   raw `- [ ]` text on the active line. */
.cm-s-hypermd-light span.cm-formatting-task.hmd-hidden-token {
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAwCAMAAAA8VkqRAAAAclBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACa4vOeAAAAJXRSTlMADcjpDswcLZOzsvOYBvWdbtvTX0D69+ORa1dRJCDtuaF7ZDkoQyuUXgAAAMhJREFUOMvt0reywjAUhOFjKxmcrgMZboL//V8Rm6GwkNUx0LClvhkVZ1fEZoqHqMwO7wuUSb0YxcJKxtLpxIt2SzJRykkQp5RgdAjaIKRJCEn6gWdA9OzRoqLVRscQnc9bdtXX/eyurOF7N3erLVDPwCGHxoVwamH1LwGUBfBbhrCvoLlMitL9DY8trLtJg7qoCj18VAN1OYE/YJBuDe1RJtBVo5wbqPb+GL5yWG1GLX0YZYw5iQ93yQ/yAHfZzu5qt/mxr97VFS15JGSVM0C6AAAAAElFTkSuQmCC") !important;
    filter: brightness(0) saturate(100%) invert(28%) sepia(96%) saturate(3700%) hue-rotate(225deg) brightness(100%) contrast(101%);
}

@media (prefers-color-scheme: light) {
    :root {
        /* explicit empty: unconditional :root above already covers light. */
    }

    /* (Media-scoped overrides for light mode only - palette is forced
       at :root above so most of these duplicate the unconditional rules
       below; kept for parity with theme-light.css.) */

    #toolbar {
        padding-bottom: 8px !important;
    }

    #toolbar svg {
        stroke: var(--col-tx-alt) !important;
    }

    #toolbar button:hover svg {
        border-radius: 0;
        stroke: var(--color-neo-orange) !important;
    }

    #close-chat, #fullscreen-chat {
        color: var(--col-tx-alt) !important;
    }

    #open-chat-modal:hover svg {
       stroke: var(--col-accent) !important;
    }

    #close-chat:hover, #fullscreen-chat:hover {
        color: var(--color-neo-orange) !important;
    }

    #open-chat-modal svg {
        stroke: #F5F5F5 !important;
    }

    #close-sidebar, #close-editor2, #go-forward svg, #go-backward svg {
        color: var(--col-tx-alt) !important;
        stroke: var(--col-tx-alt) !important;
    }

    #close-sidebar:hover {
        color: var(--col-accent) !important;
        stroke: var(--col-accent) !important;
    }

    #close-editor2:hover, #go-forward:hover svg, #go-backward:hover svg {
        color: var(--color-neo-orange) !important;
        stroke: var(--color-neo-orange) !important;
    }

    /* The `×` glyph in Space Mono sits high in its line-box, so it
       visually lifts off the arrow row in light mode. In dark mode it
       already looks fine because theme-dark.css overrides --font back
       to system-ui (loads after brutal-dark). Match that by forcing a
       sans-serif on the button only - so the glyph renders at a
       natural baseline regardless of body font. */
    #close-editor2 {
        font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
    }

    #open-sidebar {
        background: var(--col-bg-active);
    }

    .message.own {
        background: color-mix(in srgb, var(--col-bg) 60%, transparent);
    }
}

/* Action buttons: copy theme-light.css's approach but pulled outside the
   color-scheme media query so it applies on dark-mode systems too.
   Fill-on-svg + stroke-on-svg is enough: outline icons declare
   `fill="none"` on the path so they ignore the inherited fill, while
   shop (no path-level fill attr) picks it up and becomes visible. */
.to-recent-btn,
.action-btn svg {
    fill: var(--col-tx-alt);
    color: var(--col-tx-alt) !important;
    stroke: var(--col-tx-alt) !important;
}
.to-recent-btn:hover,
.action-btn:hover svg {
    fill: var(--col-accent);
    color: var(--col-accent) !important;
    stroke: var(--col-accent) !important;
}

/* Headers: heavy weight + a hard black rule under H1 / H2, brutalist style. */
.cm-s-hypermd-light .cm-header.cm-header-1 {
    font-size: 32px !important;
    line-height: 38px !important;
    font-weight: 700 !important;
}

.cm-s-hypermd-light pre.HyperMD-header.HyperMD-header-1 {
    padding-top: 18px !important;
    /* ~14px breathing room on each side of the HR, drawn as a 1.5px
       slice inside a linear-gradient. Selection of the H1 will extend
       ~14px past the rule but that's the cost of keeping cursor math
       intact (no margins, no padding-top on the next pre). */
    padding-bottom: 32px !important;
    background-image: linear-gradient(
        to bottom,
        transparent 0,
        transparent calc(100% - 15.5px),
        var(--col-border) calc(100% - 15.5px),
        var(--col-border) calc(100% - 14px),
        transparent calc(100% - 14px)
    ) !important;
}

.cm-s-hypermd-light .CodeMirror-code > pre.HyperMD-header.HyperMD-header-1:first-child,
.cm-s-hypermd-light .CodeMirror-code > :first-child pre.HyperMD-header.HyperMD-header-1 {
    padding-top: 0 !important;
    padding-bottom: 32px !important;
}

/* Only the FIRST H1 in the document gets the hard underline. */
.cm-s-hypermd-light .CodeMirror-code pre.HyperMD-header.HyperMD-header-1:not(:nth-child(1 of pre.HyperMD-header.HyperMD-header-1)) {
    background-image: none !important;
    padding-bottom: 0 !important;
}

.cm-s-hypermd-light pre.HyperMD-header.HyperMD-header-2 {
    padding-top: 18px !important;
    font-size: 24px !important;
    line-height: 30px !important;
    font-weight: 700 !important;
}

.cm-s-hypermd-light pre.HyperMD-header.HyperMD-header-3 {
    padding-top: 16px !important;
    font-size: 22px !important;
    line-height: 28px !important;
    font-weight: 700 !important;
}

.cm-s-hypermd-light pre.HyperMD-header.HyperMD-header-4 {
    padding-top: 14px !important;
    font-size: 20px !important;
    line-height: 26px !important;
    font-weight: 700 !important;
}

.cm-s-hypermd-light pre.HyperMD-header.HyperMD-header-5 {
    padding-top: 12px;
    font-size: 18px;
    line-height: 24px !important;
    font-weight: 700 !important;
}

.cm-s-hypermd-light pre.HyperMD-header.HyperMD-header-6 .cm-header-6 {
    padding-top: 12px;
    font-size: 16px;
    font-weight: 700;
    line-height: 22px;
}

.cm-s-hypermd-light .cm-header {
    font-family: 'Inter', sans-serif !important;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.cm-s-hypermd-light .cm-strong, .cm-s-hypermd-light span.cm-url {
    font-family: var(--font) !important;
    font-weight: 400;
}

/* Ordered-list numbers: render in the sans-serif header font + neo-blue
   accent so they read as labels, not slabs of mono text. Light/dark
   themes get a clean look for free because their body font is already
   sans-serif; in brutal the body is Space Mono so we have to override. */
.cm-s-hypermd-light span.cm-formatting-list-ol {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
    color: var(--color-neo-blue) !important;
    font-weight: 700 !important;
}

/* Unordered-list dash: match the neo-blue accent used by ordered-list
   numbers and the colorized checkbox - keeps every list-marker style
   on the same hue. Overrides app.css's `.cm-formatting-list-ul`
   slate-grey rule (same specificity, brutal loads later). */
.cm-formatting-list-ul {
    color: var(--color-neo-blue) !important;
}

/* Heavy bold - brutalist emphasis. */
.cm-s-hypermd-light .cm-strong {
    font-weight: 800;
}

.cm-s-hypermd-light pre.HyperMD-list-line {
    padding-top: 0 !important;
}

.cm-s-hypermd-light span.cm-url:not(.cm-string) {
    color: var(--col-url) !important;
    font-weight: 400;
}

/* Link default: classic blue + thin underline, no marker bg. The `span`
   in the selector is required to beat app.css's `span.cm-link` rule;
   without it our brutal `.cm-link` rule loses on specificity (0,2,0 vs
   0,2,1) and only the wikilink variant ends up blue. */
.cm-s-hypermd-light span.cm-link,
.cm-s-hypermd-light span.cm-string.cm-url.cm-hmd-barelink {
    line-height: 1.6 !important;
    color: var(--color-neo-blue) !important;
    background: transparent !important;
    border-bottom: 1px solid var(--color-neo-blue) !important;
    font-weight: 500;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    transition: background .15s, color .15s;
}

/* Active line (cursor on the line): lime-green chip + blue text.
   No padding because adding any horizontal padding makes the text
   jump as the cursor moves between lines. */
.cm-s-hypermd-light pre.CodeMirror-activeline span.cm-link,
.cm-s-hypermd-light pre.CodeMirror-activeline span.cm-string.cm-url.cm-hmd-barelink {
    background: var(--color-neo-lime) !important;
    color: var(--color-neo-blue) !important;
    border-bottom: none !important;
}

/* Hover: orange text + thick orange underline. No background swap
   and no padding so the line doesn't shift under the cursor as the
   user mouses over links. */
.cm-s-hypermd-light span.cm-link:hover,
.cm-s-hypermd-light span.cm-string.cm-url.cm-hmd-barelink:hover {
    background: transparent !important;
    color: var(--color-neo-orange) !important;
    border-bottom: 3px solid var(--color-neo-orange) !important;
}

/* Blockquote: dark-theme behavior, plus a thicker 4px neo-blue left bar
   so it matches the codeblock's left border weight. */
.cm-s-hypermd-light pre.HyperMD-quote-1:before {
    background: var(--color-neo-blue) !important;
    width: 4px !important;
}

/* Subtle blue-tinted wash behind quoted text - reinforces the left bar
   without competing with the body text. */
.cm-s-hypermd-light pre.HyperMD-quote-1 {
    background: color-mix(in srgb, var(--color-neo-blue) 5%, var(--col-bg)) !important;
}

/* `>` marker in neo-blue. No !important so hypermd.css's
   `pre.hmd-inactive-line span.cm-formatting-quote { color: transparent }`
   still wins on inactive lines and keeps the arrow hidden until the
   cursor is on the quote line. */
.cm-s-hypermd-light span.cm-formatting-quote {
    color: var(--color-neo-blue);
    position: relative;
    left: 1px;
}

.cm-s-hypermd-light pre.HyperMD-quote-1.hmd-inactive-line {
    text-indent: -8px !important;
}

.cm-s-hypermd-light pre.HyperMD-quote-1:not(:has(span.cm-formatting-quote)) {
    text-indent: 0 !important;
}



/* Inline code: lime-green chip with bold mono text and a thin dark
   outline. Bigger padding now that the body has 1.9 line-height to
   accommodate the taller chip without breaking flow. */
.cm-s-hypermd-light .cm-inline-code,
.cm-s-hypermd-light code {
    font-family: var(--font-mono-brutal) !important;
}

.cm-s-hypermd-light span.cm-inline-code:not(.cm-formatting):not(.cm-hmd-indented-code) {
    font-family: var(--font-mono-brutal) !important;
    background: transparent !important;
    color: #42A92C !important;
    border: 1px solid #42A92C !important;
    border-radius: 4px !important;
    padding: 0.1em 0.4em !important;
    font-size: 0.9em !important;
    position: relative;
    top: -1px;
}

/* Codeblocks: paper-darker background, sharp edges, mono font. */
.cm-s-hypermd-light div.HyperMD-codeblock-bg {
    background: var(--col-bg-alt) !important;
    border-left: none !important;
    border-right: none !important;
    border-radius: 0 !important;
}

.cm-s-hypermd-light pre.HyperMD-codeblock {
    font-family: var(--font-mono-brutal) !important;
    font-size: 1em !important;
    padding-left: 20px !important;
}

.cm-hmd-comment,
.cm-hmd-comment-marker {
    color: #42A92C !important;
}
.cm-s-hypermd-light pre.hmd-inactive-line .cm-hmd-comment-marker {
    display: none;
}

/* Sidebar blink: re-skin the highlight animation to the neo-orange accent
   (matches the rest of the app's "attention" treatment). Same timing as
   app.css's `sidebar-highlight` keyframes, just colored differently. */
@keyframes sidebar-highlight-brutal {
    0%   { color: var(--color-neo-orange); opacity: 1; }
    20%  { color: var(--color-neo-orange); opacity: 0.7; }
    25%  { color: var(--color-neo-orange); opacity: 0.5; }
    30%  { color: var(--color-neo-orange); opacity: 0.7; }
    45%  { color: var(--color-neo-orange); opacity: 1; }
    50%  { color: var(--color-neo-orange); opacity: 0.5; }
    55%  { color: var(--color-neo-orange); opacity: 0.7; }
    75%  { color: var(--color-neo-orange); opacity: 1; }
    100% { color: var(--color-neo-orange); opacity: 1; }
}
.sidebar-blink {
    animation-name: sidebar-highlight-brutal !important;
}

/* Images: no border, slightly rounded corners (matching the chat modal). */
.cm-s-hypermd-light img.hmd-image {
    border-radius: 7px !important;
    border: none !important;
}

/* Horizontal rule: hard solid bar - core brutalist motif. */
.cm-s-hypermd-light pre.HyperMD-hr {
    color: var(--col-border) !important;
    background: transparent !important;
}

.cm-s-hypermd-light div.HyperMD-hr-bg {
    background: var(--col-border) !important;
    height: 2px !important;
}

/* Text selection: semi-transparent neo-blue so dark body text underneath
   stays readable (CodeMirror draws the overlay BEHIND the text; an
   opaque bg + the editor's per-span `color: ... !important` makes text
   invisible during selection). Matches the theme's accent blue. */
::selection {
    background: rgba(46, 92, 255, 0.35) !important;
}
::-moz-selection {
    background: rgba(46, 92, 255, 0.35) !important;
}
.CodeMirror-selected,
.CodeMirror-focused .CodeMirror-selected {
    background: rgba(46, 92, 255, 0.35) !important;
}

/* Sidebar tree: brutalist palette - blue on hover (focused),
   orange on selected (current open file). Font inherits from body. */

/* Sharp corners on every selectable row - brutalist motif. Kills the 5px
   radius set on the base tree-item in sidebar.css. */
.tree-container li span.tree-item {
    border-radius: 0 !important;
}

.tree-container li span.tree-item:hover {
    background-color: var(--color-neo-orange) !important;
    color: #1A1A1A !important;
}
.tree-container li span.tree-item:hover .tree-mod_icon svg {
    stroke: #1A1A1A !important;
}

.tree-container span.tree-item.selected,
.tree-container span.tree-item.selected:hover {
    background-color: var(--color-neo-blue) !important;
    color: #FFF !important;
}
.tree-container span.tree-item.selected .tree-mod_icon svg,
.tree-container span.tree-item.selected:hover .tree-mod_icon svg {
    stroke: #FFF !important;
}

/* Search/move dialog: highlight the focused row in neo-orange - matches
   the sidebar's hover treatment so "the thing under the pointer" is
   always orange across the app. */
#search-results .focused,
#move-results .focused {
    background-color: var(--color-neo-orange) !important;
    color: #1A1A1A !important;
    border-radius: 0 !important;
}

/* Chat panel: brutal-palette overrides for the few spots in chat.css
   that hard-code colors instead of using CSS variables. */
.message {
    transition: background 0.15s ease !important;
}
.message:hover {
    background: var(--color-neo-orange) !important;
}
.complete-btn:hover {
    background: transparent !important;
}
#chat .message-content,
#chat .message-content:hover {
    background: transparent !important;
    cursor: pointer !important;
}
.message-content.editing {
    background: color-mix(in srgb, var(--color-neo-lime) 35%, transparent) !important;
    border: 1px solid var(--color-neo-blue) !important;
}
.message-time {
    color: var(--col-tx-alt) !important;
}
/* Quick-action buttons inside chat messages: hover neo-blue, matching
   the sidebar's "selected file" treatment. */
.action-btn:hover {
    background: var(--color-neo-blue) !important;
}
/* Selected/pinned message: neo-orange tint. */
.message.actions-pinned,
.message.selected {
    background: color-mix(in srgb, var(--color-neo-orange) 18%, transparent) !important;
    border-color: var(--color-neo-orange) !important;
}

/* Editor body line-height: brutalist body text breathes more. Headers
   keep their own explicit line-heights set above so they don't inherit. */
.cm-s-hypermd-light .CodeMirror-line {
    line-height: 1.9 !important;
}

/* Empty-chat hero ("Free your head" / "Drop whatever's on your mind here"):
   styled like an editor H1 - Inter, uppercase, heavy weight, tracking,
   with a hard rule under the title. Description gets the same uppercase
   tracking at a lighter weight so it reads as a subtitle. */
.empty-title,
.empty-desc {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
    letter-spacing: 0.04em;
}
.empty-title {
    font-weight: 800 !important;
    padding-bottom: 14px;
    border-bottom: 2px solid var(--col-border);
    margin-bottom: 20px !important;
}
.empty-desc {
    font-weight: 500 !important;
    letter-spacing: 0.08em;
    color: var(--color-neo-orange) !important;
}

/* Sharp corners everywhere - core brutalist motif. Covers the search/move
   modals + their inputs, the chat panel and its input, individual chat
   messages and their content/action surfaces, the quick-action icons, the
   link-insert autocomplete dropdown, and the sidebar's right-click menu. */
#search, #move,
#search-input, #move-input,
#nav-buttons,
.message,
.message:first-child,
.message:last-child,
.message:only-child,
.message-content,
.message-actions,
.action-btn,
.complete-btn,
.btn-label,
.CodeMirror-hints,
.CodeMirror-hint,
.sidebar-ctx-menu {
    border-radius: 0 !important;
}

/* Chat modal + input keep softened corners (not full brutal-sharp) - half
   the chat.css defaults so they read as friendlier surfaces than the
   rest of the app's hard rectangles. */
#chat-container.modal {
    border-radius: 7px !important;
}
#chat-input {
    border-radius: 6px !important;
}

/* Selection inside the link-insert dropdown and sidebar context menu uses
   the same neo-orange as every other "thing under the pointer" surface. */
.CodeMirror-hints,
.CodeMirror-hint {
    font-family: var(--font) !important;
}
.CodeMirror-hint-active {
    background-color: var(--color-neo-orange) !important;
    color: #1A1A1A !important;
}
.sidebar-ctx-menu-item:hover {
    background: var(--color-neo-orange) !important;
    color: #1A1A1A !important;
}
} /* end @media (prefers-color-scheme: light) */