beatrina 0.9.43 → 0.9.83
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/beatrina_V0.9.83.html +1903 -0
- package/beatrina_V0.9.83.html.inputs.json +1 -0
- package/build-info.json +1 -1
- package/host/journal-store.mjs +19 -3
- package/host/planes/choose.mjs +13 -2
- package/host/planes/expect-term.mjs +102 -0
- package/host/planes/terminal.mjs +23 -9
- package/kernel/check/knit-file.mjs +254 -38
- package/kernel/kernel-version +1 -1
- package/kernel/knitr-run.R +8 -1
- package/kernel/mcp/beatrina-mcp.mjs +6 -5
- package/kernel/worker.R +21 -1
- package/menu/Beatrina Menu.app/Contents/Info.plist +2 -2
- package/menu/Beatrina Menu.app/Contents/MacOS/Beatrina Menu +0 -0
- package/package.json +3 -3
- package/beatrina_V0.9.43.html +0 -1885
- package/beatrina_V0.9.43.html.inputs.json +0 -1
|
@@ -1629,10 +1629,18 @@ var BEATRINA_CSS = `
|
|
|
1629
1629
|
.cn-root .beatrina-ai-capability{
|
|
1630
1630
|
border:1px solid transparent;padding:3px 9px;
|
|
1631
1631
|
}
|
|
1632
|
-
/*
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
.cn-root .beatrina-ai-capability
|
|
1632
|
+
/* ONE entrance in every layout (2026-09-22): "Code \u25BE" \u2014 the word acts, the
|
|
1633
|
+
arrow holds Chat and Plan. The three capability buttons stay in the DOM,
|
|
1634
|
+
hidden; the destination toggle is still the sheet layout's alone. */
|
|
1635
|
+
.cn-root .beatrina-ai-capability{display:none;}
|
|
1636
|
+
.cn-root .beatrina-ai-destination-toggle{display:none;}
|
|
1637
|
+
.cn-root .beatrina-ai-capability-one,.cn-root .beatrina-ai-capability-more{
|
|
1638
|
+
display:inline-flex;align-items:center;color:#fff;background:var(--cn-accent,#4e79a7);border:1px solid transparent;
|
|
1639
|
+
}
|
|
1640
|
+
.cn-root .beatrina-ai-capability-one{font-weight:750;padding:3px 8px 3px 9px;border-radius:6px 0 0 6px;margin-right:0;}
|
|
1641
|
+
.cn-root .beatrina-ai-capability-more{padding:3px 6px;border-radius:0 6px 6px 0;margin-left:-1px;border-left:1px solid rgba(255,255,255,.35);}
|
|
1642
|
+
.cn-root .beatrina-ai-capability-one:hover:not(:disabled),.cn-root .beatrina-ai-capability-more:hover:not(:disabled){color:#fff;background:var(--cn-accent-deep,#3a6a9f);}
|
|
1643
|
+
.cn-root .beatrina-ai-capability-more .beatrina-ai-quickwrite-caret{font-size:10px;opacity:.9;pointer-events:none;}
|
|
1636
1644
|
.cn-root .beatrina-ai-capability[data-intent="ask"]{
|
|
1637
1645
|
color:var(--cn-accent-deep,#3a6a9f);background:transparent;
|
|
1638
1646
|
}
|
|
@@ -2327,6 +2335,12 @@ var BEATRINA_CSS = `
|
|
|
2327
2335
|
background:var(--cn-control-bg);color:var(--cn-text);
|
|
2328
2336
|
}
|
|
2329
2337
|
.cn-root .beatrina-prompt-input:focus{outline:none;border-color:var(--cn-accent);box-shadow:var(--cn-focus-ring);}
|
|
2338
|
+
/* The multi-line form (Writing mode's Edit source): Markdown, so the mono
|
|
2339
|
+
face and the size a source is read at; resizable downward only. */
|
|
2340
|
+
.cn-root textarea.beatrina-prompt-input{
|
|
2341
|
+
font-family:var(--cn-mono);font-size:var(--cn-fs);line-height:1.5;
|
|
2342
|
+
min-width:min(560px, 80vw);resize:vertical;
|
|
2343
|
+
}
|
|
2330
2344
|
|
|
2331
2345
|
/* \u2500\u2500 the prompt editor \u2014 the words, and the right to change them \u2500\u2500 */
|
|
2332
2346
|
.cn-root .beatrina-modal-panel.is-prompts{width:min(860px,95vw);}
|
|
@@ -3370,6 +3384,11 @@ var BEATRINA_CSS = `
|
|
|
3370
3384
|
color:rgba(255,255,255,.72);font:12px var(--cn-font);pointer-events:none;
|
|
3371
3385
|
animation:beatrina-focus-in .26s ease;
|
|
3372
3386
|
}
|
|
3387
|
+
/* A Text cell on its own: a LIGHT, quiet page around the prose (owner,
|
|
3388
|
+
2026-09-22: "it is all dark"). The code chunk keeps the dark haze. */
|
|
3389
|
+
.cn-root.beatrina-focus-prose .beatrina-focus-haze{background:color-mix(in srgb, var(--cn-bg,#fff) 94%, transparent);}
|
|
3390
|
+
.cn-root.beatrina-focus-prose .beatrina-focus-note{color:var(--cn-text-dim,#666);}
|
|
3391
|
+
.cn-root.beatrina-focus-prose .cell.beatrina-focus-cell{box-shadow:0 1px 0 var(--cn-border,#e3e7ef),0 12px 40px rgba(0,0,0,.08);}
|
|
3373
3392
|
/* Narrower than the notebook, and a WORKING surface rather than a card.
|
|
3374
3393
|
660px with the chunk's own height left a three-line chunk as a small box
|
|
3375
3394
|
adrift in a large dark screen (owner, 2026-09-11: "This is so small"). The
|
|
@@ -3721,6 +3740,65 @@ var BEATRINA_CSS = `
|
|
|
3721
3740
|
}
|
|
3722
3741
|
.cn-root .beatrina-source-view .beatrina-highlight .mdh-yaml{color:var(--cn-text);}
|
|
3723
3742
|
|
|
3743
|
+
/* \u2500\u2500 Source mode reads like a README on GitHub (owner, 2026-09-22: "the
|
|
3744
|
+
source mode is ugly and horrible, even reading a readme on github is
|
|
3745
|
+
better") \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
3746
|
+
Everything below is DECORATION of the same bytes: no glyph changes and no
|
|
3747
|
+
line moves, so the transparent textarea stays exactly over its colour.
|
|
3748
|
+
|
|
3749
|
+
A reading width. At Full page width a prose line ran 1,400 px; a README is
|
|
3750
|
+
read at about a thousand. Centred in whatever the page gives it. */
|
|
3751
|
+
.cn-root .beatrina-source-view{max-width:min(100%, 1080px);margin:0 auto;}
|
|
3752
|
+
/* Prose always wraps here, whatever the code-chunk wrap setting says
|
|
3753
|
+
(lib/source-view.js passes softWrap: "always" to the surface, which makes
|
|
3754
|
+
the gutter follow the wrapped rows). */
|
|
3755
|
+
.cn-root .beatrina-source-view textarea.beatrina-code,
|
|
3756
|
+
.cn-root .beatrina-source-view .beatrina-highlight{white-space:pre-wrap;overflow-wrap:break-word;}
|
|
3757
|
+
.cn-root .beatrina-source-view textarea.beatrina-code{overflow-x:hidden;}
|
|
3758
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span{display:block;}
|
|
3759
|
+
.cn-root .beatrina-source-view .beatrina-code-wrap::after,
|
|
3760
|
+
.cn-root .beatrina-source-view .beatrina-code-wrap::before{content:none;}
|
|
3761
|
+
/* Code blocks and the front matter on a band (lib/qmd-language.js names
|
|
3762
|
+
each line's region). Widened by a negative margin and an equal padding, so
|
|
3763
|
+
the band reaches past the text while the text itself stays exactly where
|
|
3764
|
+
the textarea puts it and wraps at the same width. */
|
|
3765
|
+
.cn-root .beatrina-source-view{
|
|
3766
|
+
--src-code-bg:color-mix(in srgb, var(--cn-text) 5%, var(--ed-bg, var(--cn-surface)));
|
|
3767
|
+
--src-yaml-bg:color-mix(in srgb, var(--cn-text) 3%, var(--ed-bg, var(--cn-surface)));
|
|
3768
|
+
}
|
|
3769
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span:is(.qmd-open, .qmd-code, .qmd-close),
|
|
3770
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span.qmd-yaml{
|
|
3771
|
+
margin:0 -10px;padding:0 10px;background:var(--src-code-bg);
|
|
3772
|
+
}
|
|
3773
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span.qmd-yaml{background:var(--src-yaml-bg);}
|
|
3774
|
+
/* A line is 13 \xD7 1.62 = 21.06 px tall, so neighbouring bands meet on a
|
|
3775
|
+
fraction of a pixel and the page shows through as a hairline seam. Each
|
|
3776
|
+
band line casts its own colour one pixel down to close it (not the last). */
|
|
3777
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span:is(.qmd-open, .qmd-code){box-shadow:0 1px 0 var(--src-code-bg);}
|
|
3778
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span.qmd-yaml:has(+ span.qmd-yaml){box-shadow:0 1px 0 var(--src-yaml-bg);}
|
|
3779
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span.qmd-open{border-radius:6px 6px 0 0;}
|
|
3780
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span.qmd-close{border-radius:0 0 6px 6px;}
|
|
3781
|
+
.cn-root .beatrina-source-view .beatrina-highlight > span.qmd-open + span.qmd-close{border-radius:6px;}
|
|
3782
|
+
/* Headings in the editor theme's function colour, so they lead in every
|
|
3783
|
+
theme \u2014 in Plain the accent is graphite and a heading read as bold text. */
|
|
3784
|
+
.cn-root .beatrina-source-view .beatrina-highlight .mdh-h{color:var(--rtok-fn, var(--cn-accent-deep));}
|
|
3785
|
+
/* Copy all above the text; Copy beside each block's opening fence
|
|
3786
|
+
(lib/source-copy.js). Quiet until pointed at; a done copy says so in words
|
|
3787
|
+
and in the Okabe-Ito green \u2014 never by colour alone. */
|
|
3788
|
+
.cn-root .beatrina-src-actions{display:flex;justify-content:flex-end;margin:0 0 6px;}
|
|
3789
|
+
.cn-root .beatrina-src-copies{position:absolute;inset:0;pointer-events:none;z-index:3;}
|
|
3790
|
+
.cn-root .beatrina-src-copy{
|
|
3791
|
+
display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 8px;
|
|
3792
|
+
font:500 var(--cn-fs-xs,11px)/1 var(--cn-font);color:var(--cn-text-muted);
|
|
3793
|
+
background:var(--cn-surface);border:1px solid var(--cn-border);border-radius:6px;cursor:pointer;
|
|
3794
|
+
}
|
|
3795
|
+
.cn-root .beatrina-src-copies .beatrina-src-copy{position:absolute;right:4px;margin-top:-1px;pointer-events:auto;opacity:.62;}
|
|
3796
|
+
.cn-root .beatrina-src-copy svg{width:13px;height:13px;flex:none;}
|
|
3797
|
+
.cn-root .beatrina-src-copy:hover,.cn-root .beatrina-src-copy:focus-visible{opacity:1;color:var(--cn-accent-deep);border-color:var(--cn-control-border);}
|
|
3798
|
+
.cn-root .beatrina-src-copy:focus-visible{outline:2px solid var(--cn-accent);outline-offset:1px;}
|
|
3799
|
+
.cn-root .beatrina-src-copy.is-done{opacity:1;color:#009E73;border-color:#009E73;}
|
|
3800
|
+
@media print{.cn-root .beatrina-src-actions,.cn-root .beatrina-src-copies{display:none!important;}}
|
|
3801
|
+
|
|
3724
3802
|
/* \u2500\u2500 result bar: fold / clear \u2500\u2500 */
|
|
3725
3803
|
.cn-root .beatrina-output-bar{
|
|
3726
3804
|
display:flex;align-items:center;gap:5px;margin:3px 0 0;
|
|
@@ -4471,10 +4549,10 @@ var BEATRINA_CSS = `
|
|
|
4471
4549
|
/* The row's fixed groups leave the bar roughly (viewport \u2212 1000) px. It
|
|
4472
4550
|
gives up its least essential pixels first, and every group it drops is
|
|
4473
4551
|
still on the \u22EE shelf, labelled, with its key \u2014 a narrow window costs a
|
|
4474
|
-
click, never a command. Order of surrender: the
|
|
4475
|
-
|
|
4552
|
+
click, never a command. Order of surrender: the count, breathing room,
|
|
4553
|
+
the insert group, the blocks group. (Cite is a word with no glyph now, so
|
|
4554
|
+
it is never shrunk to one.) */
|
|
4476
4555
|
@media (max-width:1640px){
|
|
4477
|
-
.cn-root header .beatrina-md-bar .is-cite .beatrina-md-tool-label{display:none;}
|
|
4478
4556
|
.cn-root header .beatrina-md-bar .beatrina-md-count{display:none;}
|
|
4479
4557
|
}
|
|
4480
4558
|
@media (max-width:1560px){
|
|
@@ -4493,7 +4571,7 @@ var BEATRINA_CSS = `
|
|
|
4493
4571
|
.cn-root header .beatrina-md-bar[data-fold="3"] .beatrina-md-group.is-insert,
|
|
4494
4572
|
.cn-root header .beatrina-md-bar[data-fold="3"] .beatrina-md-group.is-blocks,
|
|
4495
4573
|
.cn-root header .beatrina-md-bar[data-fold="3"] .beatrina-md-group.is-history{display:none;}
|
|
4496
|
-
.cn-root header .beatrina-md-bar[data-fold="4"] .beatrina-md-group:not(.is-text),
|
|
4574
|
+
.cn-root header .beatrina-md-bar[data-fold="4"] .beatrina-md-group:not(.is-text):not(.is-cite-lead),
|
|
4497
4575
|
.cn-root header .beatrina-md-bar[data-fold="4"] .is-text .beatrina-md-tool:not([data-command="prose.bold"]):not([data-command="prose.italic"]),
|
|
4498
4576
|
.cn-root header .beatrina-md-bar[data-fold="5"] .beatrina-md-group{display:none;}
|
|
4499
4577
|
/* At the last fold what is left (the \u22EE shelf and Done) is the bar's minimum:
|
|
@@ -4545,7 +4623,7 @@ var BEATRINA_CSS = `
|
|
|
4545
4623
|
.cn-root .beatrina-md-morebar{
|
|
4546
4624
|
display:block; /* .beatrina-pop is a column flexbox, and a flexbox has no CSS columns */
|
|
4547
4625
|
columns:var(--beatrina-menu-cols,2);column-gap:14px;column-rule:1px solid var(--cn-border-soft);
|
|
4548
|
-
width:min(calc(var(--beatrina-menu-cols,2) *
|
|
4626
|
+
width:min(calc(var(--beatrina-menu-cols,2) * var(--beatrina-menu-colw) + 30px), calc(100vw - 24px));
|
|
4549
4627
|
max-height:calc(100vh - 100px);overflow-y:auto;padding:6px 8px 2px;
|
|
4550
4628
|
}
|
|
4551
4629
|
.cn-root .beatrina-md-pop-group{break-inside:avoid;-webkit-column-break-inside:avoid;margin:0 0 8px;}
|
|
@@ -4851,18 +4929,22 @@ var BEATRINA_CSS = `
|
|
|
4851
4929
|
.cn-root .cell.beatrina-md-cell:focus-within .beatrina-cell-rail{
|
|
4852
4930
|
pointer-events:auto;
|
|
4853
4931
|
}
|
|
4932
|
+
/* A bit larger (owner, 2026-09-22): 24px buttons, 15px glyphs \u2014 the most the 32px gutter band holds. */
|
|
4854
4933
|
.cn-root .beatrina-cell-rail-btn{
|
|
4855
4934
|
position:relative;
|
|
4856
4935
|
display:flex;align-items:center;justify-content:center;
|
|
4857
|
-
width:
|
|
4936
|
+
width:24px;height:24px;padding:0;border:0;border-radius:7px;
|
|
4858
4937
|
background:transparent;cursor:pointer;
|
|
4859
|
-
color:color-mix(in srgb, var(--cn-text)
|
|
4938
|
+
color:color-mix(in srgb, var(--cn-text) 55%, transparent);
|
|
4860
4939
|
transition:color var(--cn-dur-1),background var(--cn-dur-1);
|
|
4861
4940
|
}
|
|
4862
4941
|
.cn-root .beatrina-cell-rail-btn svg{
|
|
4863
|
-
width:
|
|
4942
|
+
width:15px;height:15px;
|
|
4864
4943
|
transition:transform var(--cn-dur-1);
|
|
4865
4944
|
}
|
|
4945
|
+
/* The lock, once on, stays visible: a locked cell says so without a hover. */
|
|
4946
|
+
.cn-root .cell.locked .beatrina-cell-rail{pointer-events:auto;}
|
|
4947
|
+
.cn-root .cell.locked .beatrina-cell-rail-btn[data-command="text.lock"]{color:var(--cn-accent-deep);opacity:1;}
|
|
4866
4948
|
.cn-root .beatrina-cell-rail-btn:hover{
|
|
4867
4949
|
background:color-mix(in srgb, var(--cn-accent) 13%, transparent);
|
|
4868
4950
|
color:var(--cn-accent-deep);
|
|
@@ -5117,6 +5199,8 @@ var BEATRINA_CSS = `
|
|
|
5117
5199
|
font:700 var(--cn-fs-sm,12.5px) var(--cn-font);border:1px solid #E69F00;background:#E69F00;color:#1a1300;}
|
|
5118
5200
|
.cn-root .beatrina-tolatex:hover{filter:brightness(1.06);}
|
|
5119
5201
|
.cn-root .beatrina-tolatex:focus-visible{outline:2px solid var(--beatrina-hdr-focus,#fff);outline-offset:2px;}
|
|
5202
|
+
/* "Open <stem>.tex": a file name can be long; the button keeps its row. */
|
|
5203
|
+
.cn-root .beatrina-tolatex.is-open{max-width:220px;overflow:hidden;text-overflow:ellipsis;}
|
|
5120
5204
|
/* In LaTeX the same place SAYS where you are \u2014 green, a dot as well as the
|
|
5121
5205
|
colour, and not a button any more. */
|
|
5122
5206
|
.cn-root .beatrina-tolatex.is-latex{background:#009E73;border-color:#009E73;color:#fff;cursor:default;}
|
|
@@ -5168,10 +5252,13 @@ var BEATRINA_CSS = `
|
|
|
5168
5252
|
Import Data \xB7 Save drop their words) makes the room \u2014 the document's
|
|
5169
5253
|
name outranks three verbs that keep their icons. */
|
|
5170
5254
|
.cn-root .hdr-row-id .beatrina-docsw{order:7;flex:0 1 auto;min-width:120px;position:relative;}
|
|
5255
|
+
/* A BUTTON you can see (owner, 2026-09-22: "it should be open documents and
|
|
5256
|
+
should be clearer"): the header's own button face, the words on it, not a
|
|
5257
|
+
faint pill with a glyph. */
|
|
5171
5258
|
.cn-root .hdr-row-id .beatrina-docsw-btn{
|
|
5172
|
-
display:inline-flex;align-items:center;gap:
|
|
5173
|
-
border-radius:
|
|
5174
|
-
color:var(--beatrina-hdr-fg);font:
|
|
5259
|
+
display:inline-flex;align-items:center;gap:8px;height:30px;max-width:min(360px,100%);min-width:0;padding:0 12px 0 10px;
|
|
5260
|
+
border-radius:8px;border:1px solid var(--beatrina-hdr-line);background:var(--beatrina-hdr-wash);box-shadow:none;
|
|
5261
|
+
color:var(--beatrina-hdr-fg);font:600 var(--cn-fs-sm,12.5px) var(--cn-font);cursor:pointer;
|
|
5175
5262
|
}
|
|
5176
5263
|
.cn-root .hdr-row-id .beatrina-docsw-btn:hover{background:var(--beatrina-hdr-wash);}
|
|
5177
5264
|
.cn-root .hdr-row-id .beatrina-docsw-btn[aria-expanded="true"]{background:var(--beatrina-hdr-wash-2);}
|
|
@@ -5181,38 +5268,102 @@ var BEATRINA_CSS = `
|
|
|
5181
5268
|
}
|
|
5182
5269
|
.cn-root .beatrina-docsw-kind.is-notebook{border-color:transparent;background:var(--beatrina-hdr-wash-2);color:var(--beatrina-hdr-fg);}
|
|
5183
5270
|
.cn-root .beatrina-docsw-name{font:600 11px var(--cn-mono);color:var(--beatrina-hdr-fg);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
5271
|
+
.cn-root .beatrina-docsw-word{font:600 var(--cn-fs-sm,12.5px) var(--cn-font);color:var(--beatrina-hdr-fg);white-space:nowrap;}
|
|
5184
5272
|
.cn-root .beatrina-docsw-count{font:500 var(--cn-fs-xs) var(--cn-font);color:var(--beatrina-hdr-fg-faint);white-space:nowrap;}
|
|
5185
5273
|
.cn-root .beatrina-docsw-count:empty{display:none;}
|
|
5186
5274
|
.cn-root .beatrina-docsw-caret{font-size:9px;color:var(--beatrina-hdr-fg-faint);}
|
|
5187
|
-
.cn-root .beatrina-docsw .hdr-export-drop{left:auto;right:0;width:
|
|
5188
|
-
.cn-root .beatrina-docsw-drop .beatrina-docsw-badge{border-color:var(--cn-border);color:var(--cn-text-dim);background:var(--cn-surface);}
|
|
5275
|
+
.cn-root .beatrina-docsw .hdr-export-drop{left:auto;right:0;width:540px;max-width:calc(100vw - 24px);}
|
|
5276
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-badge{border-color:var(--cn-border);color:var(--cn-text-dim);background:var(--cn-surface);min-width:26px;height:20px;font-size:10px;}
|
|
5277
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-head{display:flex;align-items:center;justify-content:space-between;gap:8px;white-space:nowrap;}
|
|
5278
|
+
.cn-root .beatrina-docsw-head-note{font:500 10.5px var(--cn-font);color:var(--cn-text-dim);text-transform:none;letter-spacing:0;}
|
|
5279
|
+
.cn-root .beatrina-docsw-list{display:flex;flex-direction:column;gap:0;padding:2px 0;}
|
|
5280
|
+
.cn-root .beatrina-docsw-list > * + *{border-top:1px solid var(--cn-border-soft,#eef1f5);}
|
|
5281
|
+
/* A drawn icon per kind, the kind's badge under it. */
|
|
5282
|
+
.cn-root .beatrina-docsw-icon{display:inline-flex;flex-direction:column;align-items:center;gap:2px;width:36px;flex:0 0 36px;color:var(--cn-text-dim);}
|
|
5283
|
+
.cn-root .beatrina-docsw-icon svg{width:18px;height:18px;}
|
|
5284
|
+
.cn-root .beatrina-docsw-icon .beatrina-docsw-badge{min-width:0;height:14px;padding:0 4px;font-size:8.5px;}
|
|
5189
5285
|
.cn-root .beatrina-docsw-drop .beatrina-docsw-row{
|
|
5190
|
-
display:grid;grid-template-columns:
|
|
5191
|
-
align-items:center;column-gap:
|
|
5192
|
-
border:0;border-radius:
|
|
5286
|
+
display:grid;grid-template-columns:36px minmax(0,1fr) auto 30px;grid-template-rows:auto auto;
|
|
5287
|
+
align-items:center;column-gap:10px;row-gap:2px;text-align:left;width:100%;padding:8px 10px;margin:0;
|
|
5288
|
+
border:0;border-radius:8px;background:transparent;color:var(--cn-text);cursor:pointer;font:var(--cn-fs-sm) var(--cn-font);
|
|
5193
5289
|
}
|
|
5194
5290
|
.cn-root .beatrina-docsw-drop .beatrina-docsw-row:hover{background:var(--cn-control-bg);}
|
|
5195
5291
|
.cn-root .beatrina-docsw-drop .beatrina-docsw-row:focus-visible{outline:2px solid var(--cn-accent);outline-offset:-2px;}
|
|
5196
|
-
|
|
5292
|
+
/* The one on screen: a wash, a bar at its edge, and the words "on screen" \u2014 never colour alone. */
|
|
5293
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-row[aria-current="true"]{background:var(--cn-accent-soft,#eef3f8);box-shadow:inset 3px 0 0 var(--cn-accent);}
|
|
5294
|
+
/* Every cell PLACED, not auto-flowed: the path in row 2 of column 2 sat under
|
|
5295
|
+
the chip's would-be column, so auto-placement pushed the chip one column
|
|
5296
|
+
right and the \xD7 into an implicit fifth \u2014 measured 36px 374px 0 30px 28px. */
|
|
5297
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-row > .beatrina-docsw-icon{grid-column:1;grid-row:1 / span 2;}
|
|
5298
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-row > .beatrina-docsw-mode{grid-column:3;grid-row:1 / span 2;}
|
|
5299
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-row > .beatrina-docsw-x{grid-column:4;grid-row:1 / span 2;}
|
|
5300
|
+
.cn-root .beatrina-docsw-main{grid-column:2;grid-row:1;display:inline-flex;align-items:center;gap:7px;min-width:0;}
|
|
5301
|
+
.cn-root .beatrina-docsw-here{font:500 10.5px var(--cn-font);color:var(--cn-accent);white-space:nowrap;}
|
|
5197
5302
|
.cn-root .beatrina-docsw-dot{width:7px;height:7px;border-radius:50%;border:1px solid var(--cn-border);background:transparent;}
|
|
5198
5303
|
.cn-root .beatrina-docsw-dot.is-dirty{background:#E69F00;border-color:#E69F00;}
|
|
5199
5304
|
.cn-root .beatrina-docsw-dot.is-running{background:#56B4E9;border-color:#56B4E9;}
|
|
5200
|
-
.cn-root .beatrina-docsw-drop .beatrina-docsw-label{font:600
|
|
5305
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-label{font:600 12.5px var(--cn-font);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
5201
5306
|
.cn-root .beatrina-docsw-mode{
|
|
5202
5307
|
font:600 9.5px var(--cn-font);letter-spacing:.06em;text-transform:uppercase;color:var(--cn-text-dim);
|
|
5203
5308
|
border:1px solid var(--cn-border);border-radius:4px;padding:1px 4px;line-height:1.2;white-space:nowrap;
|
|
5204
5309
|
}
|
|
5205
5310
|
.cn-root .beatrina-docsw-mode:empty{visibility:hidden;}
|
|
5206
5311
|
.cn-root .beatrina-docsw-mode.is-writing{color:#8e5b00;border-color:#e6c47a;}
|
|
5207
|
-
.cn-root .beatrina-docsw-
|
|
5208
|
-
.
|
|
5209
|
-
.cn-root .beatrina-docsw-
|
|
5312
|
+
.cn-root .beatrina-docsw-mode.is-on{color:var(--cn-accent);border-color:var(--cn-accent);}
|
|
5313
|
+
/* A Close you can see: a bordered square on every row. */
|
|
5314
|
+
.cn-root .beatrina-docsw-x{
|
|
5315
|
+
width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;
|
|
5316
|
+
border:1px solid var(--cn-border);border-radius:7px;background:var(--cn-surface);
|
|
5317
|
+
color:var(--cn-text-dim);font-size:16px;line-height:1;text-align:center;
|
|
5318
|
+
}
|
|
5319
|
+
.cn-root .beatrina-docsw-x:hover{color:#c5221f;border-color:#c5221f;background:#fce8e6;}
|
|
5320
|
+
.cn-root .beatrina-docsw-x.is-off,.cn-root .beatrina-docsw-x.is-off:hover{opacity:.35;cursor:default;color:var(--cn-text-dim);border-color:var(--cn-border);background:var(--cn-surface);}
|
|
5321
|
+
.cn-root .beatrina-docsw-sub{grid-column:2;grid-row:2;display:flex;align-items:baseline;gap:5px;min-width:0;}
|
|
5322
|
+
.cn-root .beatrina-docsw-path{flex:0 1 auto;min-width:0;font:10.5px var(--cn-font);color:var(--cn-text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
|
5323
|
+
/* The footer: ONE row \u2014 New \u25BE \xB7 Open\u2026 on the left, Close apart on the right; an icon and a word each. */
|
|
5324
|
+
.cn-root .beatrina-docsw-foot{display:flex;flex-wrap:nowrap;gap:8px;align-items:center;padding:10px 8px 6px;margin-top:6px;border-top:1px solid var(--cn-border);}
|
|
5325
|
+
.cn-root .beatrina-docsw-new{position:relative;display:inline-flex;}
|
|
5326
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-fbtn{
|
|
5327
|
+
width:auto;flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;height:28px;min-height:28px;padding:0 11px 0 9px;
|
|
5328
|
+
border:1px solid var(--cn-border);border-radius:7px;background:var(--cn-surface);color:var(--cn-text);
|
|
5329
|
+
font:600 12px var(--cn-font);cursor:pointer;
|
|
5330
|
+
}
|
|
5331
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-fbtn svg{width:14px;height:14px;flex:0 0 auto;color:var(--cn-text-dim);}
|
|
5332
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-fbtn:not(:disabled):hover{background:var(--cn-control-bg);}
|
|
5333
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-fbtn:disabled{opacity:.45;cursor:default;}
|
|
5334
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-fbtn .beatrina-menu-label{overflow:visible;}
|
|
5335
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-fbtn .beatrina-docsw-caret{font-size:9px;color:var(--cn-text-dim);}
|
|
5336
|
+
.cn-root .beatrina-docsw-newmenu{
|
|
5337
|
+
position:absolute;left:0;bottom:calc(100% + 6px);display:flex;flex-direction:column;gap:2px;min-width:200px;padding:6px;
|
|
5338
|
+
background:var(--cn-bg,#fff);border:1px solid var(--cn-border);border-radius:9px;box-shadow:0 8px 24px rgba(0,0,0,.14);z-index:3;
|
|
5339
|
+
}
|
|
5340
|
+
.cn-root .beatrina-docsw-newmenu[hidden]{display:none;}
|
|
5341
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-newmenu button.beatrina-docsw-fbtn{border-color:transparent;background:transparent;width:100%;justify-content:flex-start;font-weight:500;}
|
|
5342
|
+
.cn-root .beatrina-docsw-drop .beatrina-docsw-newmenu button.beatrina-docsw-fbtn:not(:disabled):hover{background:var(--cn-control-bg);}
|
|
5343
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-fbtn.is-close{margin-left:auto;color:#c5221f;border-color:#e5b4b0;}
|
|
5344
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-fbtn.is-close .beatrina-docsw-x-glyph{font-size:16px;line-height:1;}
|
|
5345
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-fbtn.is-close:not(:disabled):hover{background:#fce8e6;}
|
|
5210
5346
|
.cn-root .beatrina-docsw-recent{display:flex !important;align-items:center;gap:8px;color:var(--cn-text-dim);}
|
|
5347
|
+
.cn-root .beatrina-docsw-facts{flex:0 0 auto;font:10.5px var(--cn-font);color:var(--cn-text);white-space:nowrap;}
|
|
5348
|
+
/* Specific enough to beat the drop's generic button rule (which stretched it to 434px, measured). */
|
|
5349
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-clear{
|
|
5350
|
+
margin-left:auto;width:auto;flex:0 0 auto;display:inline-flex;align-items:center;height:22px;min-height:22px;padding:0 9px;
|
|
5351
|
+
border:1px solid var(--cn-border);border-radius:6px;background:var(--cn-surface);
|
|
5352
|
+
color:var(--cn-text-dim);font:600 10.5px var(--cn-font);letter-spacing:0;text-transform:none;cursor:pointer;
|
|
5353
|
+
}
|
|
5354
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-clear:not(:disabled):hover{color:#c5221f;border-color:#c5221f;background:#fce8e6;}
|
|
5355
|
+
.cn-root .beatrina-docsw-drop button.beatrina-docsw-clear:disabled{opacity:.4;cursor:default;}
|
|
5356
|
+
.cn-root .beatrina-docsw-forget{
|
|
5357
|
+
flex:0 0 auto;width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;
|
|
5358
|
+
border:1px solid transparent;border-radius:6px;color:var(--cn-text-dim);font-size:14px;line-height:1;
|
|
5359
|
+
}
|
|
5360
|
+
.cn-root .beatrina-docsw-recent:hover .beatrina-docsw-forget{border-color:var(--cn-border);}
|
|
5361
|
+
.cn-root .beatrina-docsw-forget:hover{color:#c5221f;border-color:#c5221f !important;background:#fce8e6;}
|
|
5211
5362
|
.cn-root .beatrina-docsw-recent .beatrina-docsw-label{font:500 11.5px var(--cn-mono);}
|
|
5212
5363
|
/* A recent row: the name over its path, when it was at the right. */
|
|
5213
5364
|
.cn-root .beatrina-docsw-recent-text{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1 1 auto;}
|
|
5214
5365
|
.cn-root .beatrina-docsw-recent .beatrina-docsw-path{grid-column:auto;grid-row:auto;}
|
|
5215
|
-
.cn-root .beatrina-docsw-when{flex:0 0 auto;font:10.5px var(--cn-font);color:var(--cn-text
|
|
5366
|
+
.cn-root .beatrina-docsw-when{flex:0 0 auto;font:10.5px var(--cn-font);color:var(--cn-text);white-space:nowrap;}
|
|
5216
5367
|
.cn-root .beatrina-docsw-note{font:10.5px var(--cn-font);color:var(--cn-text-dim);padding:8px 8px 2px;}
|
|
5217
5368
|
|
|
5218
5369
|
.cn-root .hdr-row-id .beatrina-kernel{order:8;}
|
|
@@ -5485,11 +5636,18 @@ var BEATRINA_CSS = `
|
|
|
5485
5636
|
The Code menu read this way since 7.5 and the strips beside it did not;
|
|
5486
5637
|
the owner called that out (2026-09-03), so now File \u25BE through Help \u25BE all
|
|
5487
5638
|
do. Width is derived from the column count so every panel shares one
|
|
5488
|
-
recipe.
|
|
5639
|
+
recipe.
|
|
5640
|
+
|
|
5641
|
+
ONE column width for every panel, wide enough for the longest row a menu
|
|
5642
|
+
carries \u2014 icon, a sentence of a label, a shortcut. At 226 px, "Send
|
|
5643
|
+
Selection or Line to C\u2026", "Restart R and Run All Chunk\u2026", "Convert again
|
|
5644
|
+
from Markdo\u2026" were all cut with room to spare in the window (FINDINGS
|
|
5645
|
+
2026-09-22 B11); 272 px holds the longest with its key, measured. */
|
|
5646
|
+
.cn-root{--beatrina-menu-colw:272px;}
|
|
5489
5647
|
.cn-root .beatrina-menu-drop.beatrina-menu-cols{
|
|
5490
5648
|
columns:var(--beatrina-menu-cols,3);column-gap:16px;
|
|
5491
5649
|
column-rule:1px solid var(--cn-border-soft);
|
|
5492
|
-
width:min(calc(var(--beatrina-menu-cols,3) *
|
|
5650
|
+
width:min(calc(var(--beatrina-menu-cols,3) * var(--beatrina-menu-colw) + 40px), calc(100vw - 24px));
|
|
5493
5651
|
padding:10px 12px 6px;
|
|
5494
5652
|
}
|
|
5495
5653
|
.cn-root .beatrina-menu-cols .beatrina-menu-group{
|
|
@@ -5705,6 +5863,17 @@ var BEATRINA_CSS = `
|
|
|
5705
5863
|
.cn-root[data-app-theme="plain"] .beatrina-ai-capability[data-intent="plan"]{
|
|
5706
5864
|
background:var(--cn-accent-soft);color:var(--cn-text);
|
|
5707
5865
|
}
|
|
5866
|
+
/* Code \u25BE is an OUTLINED pill here, like Quick write and Pin beside it: a
|
|
5867
|
+
graphite fill read as a black block (owner, 2026-09-22: "overly 3d"). */
|
|
5868
|
+
.cn-root:is([data-app-theme="flat"],[data-app-theme="plain"]) .beatrina-ai-capability-one,
|
|
5869
|
+
.cn-root:is([data-app-theme="flat"],[data-app-theme="plain"]) .beatrina-ai-capability-more{
|
|
5870
|
+
background:transparent;color:var(--cn-text);border-color:var(--cn-border-strong,#c9ced6);box-shadow:none;font-weight:600;
|
|
5871
|
+
}
|
|
5872
|
+
.cn-root:is([data-app-theme="flat"],[data-app-theme="plain"]) .beatrina-ai-capability-more{border-left-color:var(--cn-border-strong,#c9ced6);}
|
|
5873
|
+
.cn-root:is([data-app-theme="flat"],[data-app-theme="plain"]) .beatrina-ai-capability-one:hover:not(:disabled),
|
|
5874
|
+
.cn-root:is([data-app-theme="flat"],[data-app-theme="plain"]) .beatrina-ai-capability-more:hover:not(:disabled){
|
|
5875
|
+
background:var(--cn-control-bg);color:var(--cn-text);
|
|
5876
|
+
}
|
|
5708
5877
|
.cn-root[data-app-theme="plain"] .beatrina-chunk-name-input{border-color:var(--cn-border-strong);}
|
|
5709
5878
|
/* Save is an ACTION, and its blue is a literal that predates the accent
|
|
5710
5879
|
token \u2014 in a monochrome theme it follows the accent like every other
|
|
@@ -5946,7 +6115,8 @@ var BEATRINA_CSS = `
|
|
|
5946
6115
|
destination is one toggle. All three controls exist in the DOM under every
|
|
5947
6116
|
layout (lib/ai-code-button.js) \u2014 this is where the layout chooses. */
|
|
5948
6117
|
.cn-root[data-chunk-layout="sheet"] .beatrina-ai-capability{display:none;}
|
|
5949
|
-
.cn-root[data-chunk-layout="sheet"] .beatrina-ai-capability-one
|
|
6118
|
+
.cn-root[data-chunk-layout="sheet"] .beatrina-ai-capability-one,.cn-root[data-chunk-layout="sheet"] .beatrina-ai-capability-more,
|
|
6119
|
+
.cn-root[data-chunk-layout="sheet"] .beatrina-ai-capability-one:hover:not(:disabled),.cn-root[data-chunk-layout="sheet"] .beatrina-ai-capability-more:hover:not(:disabled){display:inline-flex;align-items:center;color:var(--cn-text-muted);background:transparent;font-weight:500;border-color:transparent;}
|
|
5950
6120
|
.cn-root[data-chunk-layout="sheet"] .beatrina-ai-context-group{display:none;}
|
|
5951
6121
|
.cn-root[data-chunk-layout="sheet"] .beatrina-ai-destination-button{display:none;}
|
|
5952
6122
|
.cn-root[data-chunk-layout="sheet"] .beatrina-ai-destination-toggle{display:inline-flex;cursor:pointer;white-space:nowrap;font:500 var(--cn-fs-xs) var(--cn-font);}
|
|
@@ -7488,15 +7658,32 @@ var BEATRINA_CSS = `
|
|
|
7488
7658
|
position:sticky;top:0;z-index:1;background:var(--cn-surface);
|
|
7489
7659
|
border-bottom:1px solid var(--cn-border);padding:0;text-align:left;
|
|
7490
7660
|
}
|
|
7661
|
+
/* The header's first line is TWO sibling buttons in one band: the name
|
|
7662
|
+
(select the column) and the arrow (sort). Siblings, not nested \u2014 a button
|
|
7663
|
+
inside a button is invalid and the inner one had no keyboard path (N13).
|
|
7664
|
+
The band carries the hover and selected paint so the pair reads as one
|
|
7665
|
+
header; the 10 px outer padding is split across the two so the name still
|
|
7666
|
+
starts on the same vertical as the distribution line below it. */
|
|
7667
|
+
.cn-root .beatrina-grid-head{display:flex;align-items:stretch;}
|
|
7491
7668
|
.cn-root .beatrina-grid-sort{
|
|
7492
|
-
display:flex;align-items:center;gap:4px;width:
|
|
7669
|
+
display:flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0;padding:5px 4px 5px 10px;
|
|
7493
7670
|
font:600 11px var(--cn-font);color:var(--cn-text-muted);cursor:pointer;
|
|
7494
7671
|
background:transparent;border:0;white-space:nowrap;
|
|
7495
7672
|
}
|
|
7496
7673
|
.cn-root .beatrina-grid th.is-num .beatrina-grid-sort{justify-content:flex-end;}
|
|
7497
|
-
.cn-root .beatrina-grid-
|
|
7498
|
-
.cn-root .beatrina-grid
|
|
7499
|
-
.cn-root .beatrina-grid-arrow{
|
|
7674
|
+
.cn-root .beatrina-grid-head:hover{background:var(--cn-accent-soft);}
|
|
7675
|
+
.cn-root .beatrina-grid-head:hover .beatrina-grid-sort,
|
|
7676
|
+
.cn-root .beatrina-grid-head:hover .beatrina-grid-arrow{color:var(--cn-accent-deep);}
|
|
7677
|
+
.cn-root .beatrina-grid th.is-sorted .beatrina-grid-sort,
|
|
7678
|
+
.cn-root .beatrina-grid th.is-sorted .beatrina-grid-arrow{color:var(--cn-accent-deep);}
|
|
7679
|
+
.cn-root .beatrina-grid-arrow{
|
|
7680
|
+
flex:0 0 auto;padding:5px 10px 5px 4px;border:0;background:transparent;cursor:pointer;
|
|
7681
|
+
font:600 9px var(--cn-font);line-height:1;color:var(--cn-text-muted);
|
|
7682
|
+
}
|
|
7683
|
+
.cn-root .beatrina-grid-sort:focus-visible,
|
|
7684
|
+
.cn-root .beatrina-grid-arrow:focus-visible{
|
|
7685
|
+
outline:2px solid var(--cn-accent-deep);outline-offset:-2px;
|
|
7686
|
+
}
|
|
7500
7687
|
.cn-root .beatrina-grid td{
|
|
7501
7688
|
padding:3px 10px;border-bottom:1px solid var(--cn-border-soft);
|
|
7502
7689
|
white-space:nowrap;max-width:28ch;overflow:hidden;text-overflow:ellipsis;
|
|
@@ -7527,12 +7714,15 @@ var BEATRINA_CSS = `
|
|
|
7527
7714
|
.cn-root .beatrina-grid td.is-sel-bottom{--sel-b:var(--cn-accent-deep,#31537a);}
|
|
7528
7715
|
.cn-root .beatrina-grid td.is-sel-left{--sel-l:var(--cn-accent-deep,#31537a);}
|
|
7529
7716
|
.cn-root .beatrina-grid td.is-sel-right{--sel-r:var(--cn-accent-deep,#31537a);}
|
|
7530
|
-
.cn-root .beatrina-grid th.is-selected .beatrina-grid-sort
|
|
7531
|
-
|
|
7717
|
+
.cn-root .beatrina-grid th.is-selected .beatrina-grid-sort,
|
|
7718
|
+
.cn-root .beatrina-grid th.is-selected .beatrina-grid-arrow{color:var(--cn-accent-deep);}
|
|
7719
|
+
.cn-root .beatrina-grid th.is-selected .beatrina-grid-head{
|
|
7720
|
+
background:var(--cn-accent-soft);
|
|
7532
7721
|
box-shadow:inset 0 -2px 0 var(--cn-accent-deep,#31537a);
|
|
7533
7722
|
}
|
|
7534
7723
|
.cn-root .beatrina-grid-arrow.is-idle{opacity:.45;}
|
|
7535
|
-
.cn-root .beatrina-grid-
|
|
7724
|
+
.cn-root .beatrina-grid-head:hover .beatrina-grid-arrow.is-idle,
|
|
7725
|
+
.cn-root .beatrina-grid-arrow.is-idle:focus-visible{opacity:.9;}
|
|
7536
7726
|
.cn-root .beatrina-grid .beatrina-grid-idx{
|
|
7537
7727
|
position:sticky;left:0;background:var(--cn-surface);color:var(--cn-text-dim);
|
|
7538
7728
|
font-family:var(--cn-mono);font-size:10px;text-align:right;padding:3px 8px;
|
|
@@ -8806,6 +8996,22 @@ var BEATRINA_CSS = `
|
|
|
8806
8996
|
color:var(--cn-text-dim);font:500 var(--cn-fs-sm,11px) var(--cn-mono);white-space:nowrap;background:transparent;border:0;box-shadow:none;padding:0;
|
|
8807
8997
|
}
|
|
8808
8998
|
.cn-root .beatrina-context-separator{height:1px;margin:4px 8px;background:var(--cn-border-soft);}
|
|
8999
|
+
/* An icon row (the writing page's B \xB7 I \xB7 U \xB7 <>): the formats as one line of
|
|
9000
|
+
square buttons at the head of the menu, the way a word processor's
|
|
9001
|
+
right-click leads with them. Lit = the selection already carries it. */
|
|
9002
|
+
.cn-root .beatrina-context-iconrow{display:flex;gap:2px;padding:2px 6px;}
|
|
9003
|
+
.cn-root .beatrina-context-iconbtn{
|
|
9004
|
+
display:inline-flex;align-items:center;justify-content:center;width:32px;height:30px;padding:0;
|
|
9005
|
+
border:0;border-radius:var(--cn-radius-sm,6px);background:transparent;color:var(--cn-text-muted);cursor:pointer;
|
|
9006
|
+
}
|
|
9007
|
+
.cn-root .beatrina-context-iconbtn svg{display:block;width:16px;height:16px;}
|
|
9008
|
+
.cn-root .beatrina-context-iconbtn.is-word{width:auto;padding:0 9px;font:600 var(--cn-fs,13px)/1 var(--cn-font);}
|
|
9009
|
+
.cn-root .beatrina-context-iconbtn:hover,.cn-root .beatrina-context-iconbtn:focus{
|
|
9010
|
+
outline:0;background:color-mix(in srgb,var(--cn-accent) 10%,var(--cn-surface));color:var(--cn-accent-deep);
|
|
9011
|
+
}
|
|
9012
|
+
.cn-root .beatrina-context-iconbtn:focus-visible{outline:2px solid var(--cn-accent);outline-offset:-2px;}
|
|
9013
|
+
.cn-root .beatrina-context-iconbtn.is-on{background:color-mix(in srgb,var(--cn-accent) 16%,var(--cn-surface));color:var(--cn-accent-deep);}
|
|
9014
|
+
.cn-root .beatrina-context-iconbtn:disabled{opacity:.38;cursor:default;background:transparent;}
|
|
8809
9015
|
/* A group row opens a fly-out beside the menu (Beatrina AI on the selection). The
|
|
8810
9016
|
caret is the only sign; the row itself reads like every other item. */
|
|
8811
9017
|
.cn-root .beatrina-context-item.is-submenu.is-open{
|
|
@@ -11167,13 +11373,16 @@ body:has(.cn-root[data-beatrina-mode="writing"] > .beatrina-writing-bar){--beatr
|
|
|
11167
11373
|
.cn-root[data-beatrina-mode="latex"] main > .beatrina-mtab-page{margin-bottom:0;}
|
|
11168
11374
|
.cn-root[data-beatrina-mode="latex"] > .cn-footer{display:none;}
|
|
11169
11375
|
|
|
11170
|
-
/* What goes away. The tab strip goes because the workbench IS the tab
|
|
11376
|
+
/* What goes away. The tab strip goes because the workbench IS the tab \u2014 while
|
|
11377
|
+
a .tex is in front; with Jobs, a data view or the console in front
|
|
11378
|
+
(data-latex-front="other", stamped by src/notebook-entry.js) it stays, or
|
|
11379
|
+
there is no visible way back (owner, 2026-09-22). The
|
|
11171
11380
|
status line and the working-directory row go because the rail says where
|
|
11172
11381
|
you are; the notebook's own add-strip and width control are answering
|
|
11173
11382
|
questions this mode does not ask. The kernel badge and the session plug
|
|
11174
11383
|
STAY \u2014 unlike Writing mode, R is live here and a reader has to be able to
|
|
11175
11384
|
see that it is, because Compile is about to need it. */
|
|
11176
|
-
.cn-root[data-beatrina-mode="latex"] .beatrina-mtabs,
|
|
11385
|
+
.cn-root[data-beatrina-mode="latex"]:not([data-latex-front="other"]) .beatrina-mtabs,
|
|
11177
11386
|
.cn-root[data-beatrina-mode="latex"] .beatrina-status,
|
|
11178
11387
|
.cn-root[data-beatrina-mode="latex"] .beatrina-wd,
|
|
11179
11388
|
.cn-root[data-beatrina-mode="latex"] .beatrina-addstrip,
|
|
@@ -11368,6 +11577,10 @@ body:has(.cn-root[data-beatrina-mode="writing"] > .beatrina-writing-bar){--beatr
|
|
|
11368
11577
|
.cn-root .beatrina-latex-rail-problems{flex:1 1 auto;min-height:0;overflow:auto;}
|
|
11369
11578
|
.cn-root .beatrina-latex-rail-problems .beatrina-problems{padding:4px 0;}
|
|
11370
11579
|
.cn-root .beatrina-latex-rail-problems .beatrina-problem{padding:7px 10px;}
|
|
11580
|
+
/* The Log view: the compiler's lines, as the console draws them. */
|
|
11581
|
+
.cn-root .beatrina-latex-rail-log{flex:1 1 auto;min-height:0;overflow:auto;font-size:var(--cn-fs-xs,11px);}
|
|
11582
|
+
.cn-root .beatrina-latex-rail-log-head{padding:6px 10px;color:var(--cn-muted,#666);}
|
|
11583
|
+
.cn-root .beatrina-latex-rail-log .beatrina-latex-rail-pre{margin:0;padding:4px 10px;white-space:pre-wrap;word-break:break-word;}
|
|
11371
11584
|
|
|
11372
11585
|
/* \u2500\u2500 the start panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
11373
11586
|
What the workbench shows before there is a .tex in it: the notebook you
|
|
@@ -19470,6 +19683,9 @@ function normalizeTable(frame) {
|
|
|
19470
19683
|
rows,
|
|
19471
19684
|
nrow: frame.nrow,
|
|
19472
19685
|
ncol: frame.ncol,
|
|
19686
|
+
// The frame's own width, row names not counted (worker.R; FINDINGS
|
|
19687
|
+
// 2026-09-22 B10). Absent from an older kernel, and then the page says ncol.
|
|
19688
|
+
...Number.isFinite(frame.dataCols) ? { dataCols: frame.dataCols } : {},
|
|
19473
19689
|
truncated: Boolean(frame.truncated),
|
|
19474
19690
|
shown: rows.length,
|
|
19475
19691
|
// The name the frame was printed under, when the printed expression was a
|
package/kernel/kernel-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.9.
|
|
1
|
+
0.9.83
|
package/kernel/knitr-run.R
CHANGED
|
@@ -71,7 +71,14 @@ run_document_cell <- function(id, source, document, dims = NULL, srcname = NULL)
|
|
|
71
71
|
if (identical(frame$type, "stdout") && !is.null(options$comment) && nzchar(options$comment)) {
|
|
72
72
|
frame$text <- paste0(options$comment, " ", strsplit(frame$text, "\n", fixed = TRUE)[[1L]], collapse = "\n")
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
# A figure FILE is written only when the author asked for one by
|
|
75
|
+
# setting fig.path (a chunk option or the setup chunk's opts_chunk).
|
|
76
|
+
# knitr's own default, "figure/", is not a request: every plot of an
|
|
77
|
+
# ordinary run used to land as figure/<label>-1.png in the working
|
|
78
|
+
# directory, a folder nobody made (FINDINGS 2026-09-22 B17). The
|
|
79
|
+
# plot itself travels in the frame either way; nothing reads the file.
|
|
80
|
+
wants_file <- !identical(options$fig.path, KNIT_BASE$fig.path)
|
|
81
|
+
if (identical(frame$type, "plot") && save_figures && wants_file) {
|
|
75
82
|
plot_n <<- plot_n + 1L
|
|
76
83
|
suffix <- if (identical(frame$mime, "image/svg+xml")) ".svg" else ".png"
|
|
77
84
|
target <- paste0(options$fig.path, options$label, "-", plot_n, suffix)
|
|
@@ -437,11 +437,12 @@ const TOOLS = [
|
|
|
437
437
|
description:
|
|
438
438
|
"Run one chunk in the user's live session (its own engine: R, or Python where the session runs it) and return its output "
|
|
439
439
|
+ "(stdout, messages, errors, table/plot summaries). The run is visible "
|
|
440
|
-
+ "in the notebook exactly as if the user pressed Run.
|
|
441
|
-
+ "
|
|
442
|
-
+ "
|
|
443
|
-
+ "
|
|
444
|
-
+ "
|
|
440
|
+
+ "in the notebook exactly as if the user pressed Run. If the document is in "
|
|
441
|
+
+ "Writing mode the run first switches it to Develop — visibly, exactly as "
|
|
442
|
+
+ "pressing the Develop segment — and the reply says so (`modeChanged: "
|
|
443
|
+
+ "\"writing→development\"`); only when the page refuses that switch is the "
|
|
444
|
+
+ "run refused, and the error says to ask the user. Reading (notebook_read, "
|
|
445
|
+
+ "chunk_read) and authoring (chunk_insert, chunk_update) never change the mode. "
|
|
445
446
|
+ "A chunk with cache=TRUE and an unchanged source is RESTORED from knitr's "
|
|
446
447
|
+ "cache, not executed — the reply says so (`cached: true`) and none of the "
|
|
447
448
|
+ "chunk's side effects (setwd(), files written, seeds) happen; pass `force` "
|
package/kernel/worker.R
CHANGED
|
@@ -166,6 +166,13 @@ MAX_VIEW_COLS <- 100L
|
|
|
166
166
|
MAX_VIEW_BYTES <- 512L * 1024L
|
|
167
167
|
MAX_VIEW_CELL_CHARS <- 512L
|
|
168
168
|
MAX_VIEW_LABEL_CHARS <- 128L
|
|
169
|
+
# The viewer's page size, the same number as lib/panel.js's PAGE (pinned by
|
|
170
|
+
# spike/test-ide.R). View() pushes its first page unasked, and it
|
|
171
|
+
# used to take the `view` op's protocol default of 200, so the grid opened on
|
|
172
|
+
# "1–200 of N" and every page it asked for itself — next, search, clear — was
|
|
173
|
+
# 50 (N11, app-monkey soak 2026-09-22). The protocol default stays 200 for
|
|
174
|
+
# clients that name no limit; the push names the viewer's.
|
|
175
|
+
VIEWER_PAGE_ROWS <- 50L
|
|
169
176
|
MAX_STRUCT_CHILDREN <- 200L
|
|
170
177
|
MAX_COMPLETIONS <- 200L
|
|
171
178
|
|
|
@@ -2680,6 +2687,14 @@ emit_dataframe <- function(id, df, source = NULL) {
|
|
|
2680
2687
|
# R whether names are automatic without materialising them; explicit names
|
|
2681
2688
|
# are sliced from the raw attribute only AFTER the 10-row preview is taken.
|
|
2682
2689
|
explicit_rownames <- .row_names_info(df, type = 1L) > 0L
|
|
2690
|
+
# head(df) and df[1:n, ] store their row names EXPLICITLY as the integers
|
|
2691
|
+
# 1..n — automatic in all but storage. Shown, they were a "rowname" column of
|
|
2692
|
+
# 1, 2, 3 and the header said 5 x 3 for a 5 x 2 frame (FINDINGS 2026-09-22
|
|
2693
|
+
# B10). Only integer names are tested, so a character vector is never built.
|
|
2694
|
+
if (explicit_rownames) {
|
|
2695
|
+
raw_names <- attr(df, "row.names", exact = TRUE)
|
|
2696
|
+
if (is.integer(raw_names) && identical(raw_names, seq_len(total_rows))) explicit_rownames <- FALSE
|
|
2697
|
+
}
|
|
2683
2698
|
total_cols <- data_cols + as.integer(explicit_rownames)
|
|
2684
2699
|
data_col_cap <- max(0L, preview_cols - as.integer(explicit_rownames))
|
|
2685
2700
|
shown_cols <- if (data_cols && data_col_cap) {
|
|
@@ -2768,6 +2783,11 @@ emit_dataframe <- function(id, df, source = NULL) {
|
|
|
2768
2783
|
columns = I(names(head_df)),
|
|
2769
2784
|
types = I(source_types),
|
|
2770
2785
|
nrow = total_rows, ncol = total_cols,
|
|
2786
|
+
# The frame's OWN width: row names are labels, not a variable, so the
|
|
2787
|
+
# "n x m" a reader sees is nrow x dataCols (mtcars is 32 x 11, not 12).
|
|
2788
|
+
# `ncol` keeps counting the displayed row-name column, which is what the
|
|
2789
|
+
# column pager and `truncated` measure against.
|
|
2790
|
+
dataCols = data_cols,
|
|
2771
2791
|
shown = nrow(head_df), shownCols = ncol(head_df),
|
|
2772
2792
|
truncated = total_rows > nrow(head_df) || total_cols > ncol(head_df),
|
|
2773
2793
|
# jsonlite drops a NULL, so a frame with no name is byte-identical to what
|
|
@@ -3721,7 +3741,7 @@ beatrina_tools$View <- function(x, title = NULL) {
|
|
|
3721
3741
|
# mtcars lives in the datasets package rather than the global environment.
|
|
3722
3742
|
label <- if (!is.null(title)) title else deparse(substitute(x))
|
|
3723
3743
|
assign(".beatrina_view", x, envir = globalenv())
|
|
3724
|
-
emit_view("view-request", ".beatrina_view", label = label)
|
|
3744
|
+
emit_view("view-request", ".beatrina_view", label = label, limit = VIEWER_PAGE_ROWS)
|
|
3725
3745
|
invisible(NULL)
|
|
3726
3746
|
}
|
|
3727
3747
|
attach(beatrina_tools, name = "beatrina:tools", warn.conflicts = FALSE)
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<key>CFBundleExecutable</key><string>Beatrina Menu</string>
|
|
7
7
|
<key>CFBundleIdentifier</key><string>me.saqr.beatrina.menu</string>
|
|
8
8
|
<key>CFBundlePackageType</key><string>APPL</string>
|
|
9
|
-
<key>CFBundleShortVersionString</key><string>0.9.
|
|
10
|
-
<key>CFBundleVersion</key><string>0.9.
|
|
9
|
+
<key>CFBundleShortVersionString</key><string>0.9.83</string>
|
|
10
|
+
<key>CFBundleVersion</key><string>0.9.83</string>
|
|
11
11
|
<key>LSMinimumSystemVersion</key><string>13.0</string>
|
|
12
12
|
<!-- Menu bar only: no Dock tile, no window, nothing to close by accident. -->
|
|
13
13
|
<key>LSUIElement</key><true/>
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beatrina",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.83",
|
|
4
4
|
"description": "Beatrina is a modern, powerful, feature-rich integrated development environment (IDE) for R, Python, and JavaScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"lib",
|
|
25
25
|
"menu",
|
|
26
26
|
"build-info.json",
|
|
27
|
-
"beatrina_V0.9.
|
|
28
|
-
"beatrina_V0.9.
|
|
27
|
+
"beatrina_V0.9.83.html",
|
|
28
|
+
"beatrina_V0.9.83.html.inputs.json",
|
|
29
29
|
"README.md",
|
|
30
30
|
"LICENSE",
|
|
31
31
|
"NOTICES"
|