prreviewbuddy 0.44.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/dist/{delete_review-BWMmO81Q.js → delete_review-lmVdoybL.js} +25 -1
- package/dist/main.js +1 -1
- package/dist/server.js +933 -92
- package/package.json +1 -1
- package/static/shell.css +549 -1
- package/static/workspace.js +79 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prreviewbuddy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "Review a branch or pull request in an isolated checkout, from your terminal, with the coding agent you already have installed.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://prreviewbuddy.com",
|
package/static/shell.css
CHANGED
|
@@ -1529,6 +1529,9 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
1529
1529
|
}
|
|
1530
1530
|
.prb-bank-add:hover { border-color: var(--border-strong); color: var(--text-primary); }
|
|
1531
1531
|
.prb-bank-list { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
1532
|
+
/* Folded. The `display` above outranks the browser's own rule for `hidden`, so without this the
|
|
1533
|
+
fold flips the attribute and the chips stay on screen. */
|
|
1534
|
+
.prb-bank-list[hidden] { display: none; }
|
|
1532
1535
|
/* The pair reads as one chip: the label inserts, the pencil edits. They share a border so the
|
|
1533
1536
|
edit affordance is visibly part of the prompt it edits rather than a control floating beside it. */
|
|
1534
1537
|
.prb-bank-item {
|
|
@@ -3252,6 +3255,12 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
3252
3255
|
-webkit-box-orient: vertical;
|
|
3253
3256
|
overflow: hidden;
|
|
3254
3257
|
}
|
|
3258
|
+
.prb-card-summary code {
|
|
3259
|
+
padding: 0 4px;
|
|
3260
|
+
border-radius: 4px;
|
|
3261
|
+
background: var(--surface-2);
|
|
3262
|
+
font-size: var(--t-code);
|
|
3263
|
+
}
|
|
3255
3264
|
.prb-card-where,
|
|
3256
3265
|
.prb-card-meta {
|
|
3257
3266
|
display: flex;
|
|
@@ -3698,6 +3707,320 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
3698
3707
|
.prb-diagram-source > summary::before { content: '\25B8 '; }
|
|
3699
3708
|
.prb-diagram-source[open] > summary::before { content: '\25BE '; }
|
|
3700
3709
|
|
|
3710
|
+
/* ── The two diagram tabs ──
|
|
3711
|
+
Each says what question it answers, so the reviewer never has to open both to learn they differ.
|
|
3712
|
+
A segmented strip rather than the rail's style: these are two views of one place, not two places. */
|
|
3713
|
+
.prb-diagram-modes {
|
|
3714
|
+
display: inline-flex;
|
|
3715
|
+
gap: 2px;
|
|
3716
|
+
margin: 0 0 18px;
|
|
3717
|
+
padding: 4px;
|
|
3718
|
+
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
3719
|
+
border-radius: 10px;
|
|
3720
|
+
background: #f6f8fa;
|
|
3721
|
+
}
|
|
3722
|
+
.prb-diagram-mode {
|
|
3723
|
+
display: flex;
|
|
3724
|
+
flex-direction: column;
|
|
3725
|
+
align-items: flex-start;
|
|
3726
|
+
gap: 2px;
|
|
3727
|
+
min-width: 190px;
|
|
3728
|
+
padding: 8px 18px 9px;
|
|
3729
|
+
border: 0;
|
|
3730
|
+
border-radius: 8px;
|
|
3731
|
+
background: transparent;
|
|
3732
|
+
color: #57606a;
|
|
3733
|
+
font: inherit;
|
|
3734
|
+
text-align: left;
|
|
3735
|
+
cursor: pointer;
|
|
3736
|
+
}
|
|
3737
|
+
.prb-diagram-mode:hover { color: #1f2328; }
|
|
3738
|
+
.prb-diagram-mode[aria-selected='true'] {
|
|
3739
|
+
background: #fff;
|
|
3740
|
+
color: #1f2328;
|
|
3741
|
+
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.12);
|
|
3742
|
+
}
|
|
3743
|
+
.prb-diagram-mode:focus-visible { outline: 2px solid #9333ea; outline-offset: 1px; }
|
|
3744
|
+
.prb-diagram-mode-title { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-body); font-weight: 600; }
|
|
3745
|
+
/* The picture on this tab already exists: switching to it costs nothing. Passive, and a word for
|
|
3746
|
+
assistive technology rather than colour alone. */
|
|
3747
|
+
.prb-diagram-mode-ready {
|
|
3748
|
+
display: inline-flex;
|
|
3749
|
+
align-items: center;
|
|
3750
|
+
justify-content: center;
|
|
3751
|
+
width: 15px;
|
|
3752
|
+
height: 15px;
|
|
3753
|
+
border-radius: 50%;
|
|
3754
|
+
background: rgba(26, 127, 55, 0.12);
|
|
3755
|
+
color: #1a7f37;
|
|
3756
|
+
font-size: 10px;
|
|
3757
|
+
font-weight: 700;
|
|
3758
|
+
}
|
|
3759
|
+
.prb-diagram-mode-ready[hidden] { display: none; }
|
|
3760
|
+
.prb-diagram-mode-subtitle { font-size: var(--t-micro); color: #8c959f; }
|
|
3761
|
+
|
|
3762
|
+
/* ── Before anything is drawn ──
|
|
3763
|
+
Says what the view is for and offers the one action that spends a run. Not a dead end, and not a
|
|
3764
|
+
button that pretends to be free. */
|
|
3765
|
+
.prb-map-empty {
|
|
3766
|
+
max-width: 560px;
|
|
3767
|
+
margin: 8px 0 20px;
|
|
3768
|
+
padding: 18px 20px;
|
|
3769
|
+
border: 1px dashed rgba(15, 23, 42, 0.2);
|
|
3770
|
+
border-radius: 10px;
|
|
3771
|
+
background: #fff;
|
|
3772
|
+
font-size: var(--t-body);
|
|
3773
|
+
line-height: var(--lh-body);
|
|
3774
|
+
color: #57606a;
|
|
3775
|
+
}
|
|
3776
|
+
.prb-map-empty p { margin: 0 0 10px; }
|
|
3777
|
+
.prb-map-empty-title { margin: 0 0 6px; font-size: var(--t-section); font-weight: 600; color: #1f2328; }
|
|
3778
|
+
.prb-map-empty-note { font-size: var(--t-meta); color: #8c959f; }
|
|
3779
|
+
.prb-map-stale {
|
|
3780
|
+
padding: 7px 10px;
|
|
3781
|
+
border-radius: 7px;
|
|
3782
|
+
background: rgba(251, 191, 36, 0.12);
|
|
3783
|
+
font-size: var(--t-meta);
|
|
3784
|
+
color: #6b5514;
|
|
3785
|
+
}
|
|
3786
|
+
.prb-map-generate {
|
|
3787
|
+
margin-top: 4px;
|
|
3788
|
+
padding: 7px 14px;
|
|
3789
|
+
border: 1px solid #9333ea;
|
|
3790
|
+
border-radius: 6px;
|
|
3791
|
+
background: #9333ea;
|
|
3792
|
+
color: #fff;
|
|
3793
|
+
font: inherit;
|
|
3794
|
+
font-size: var(--t-meta);
|
|
3795
|
+
font-weight: 600;
|
|
3796
|
+
cursor: pointer;
|
|
3797
|
+
}
|
|
3798
|
+
.prb-map-generate:hover { background: #7e22ce; }
|
|
3799
|
+
.prb-map-generate[disabled] { opacity: 0.55; cursor: default; }
|
|
3800
|
+
/* While a map is being made there is one state on screen, the work and its Stop: the button that
|
|
3801
|
+
would start it again goes, whether this page asked or came back to a run already going. */
|
|
3802
|
+
.prb-view[data-map-running] .prb-map-generate { display: none; }
|
|
3803
|
+
/* The implementation tab's own empty state goes the moment its first card is in the pane. */
|
|
3804
|
+
.prb-view[data-diagram-pane]:has([data-diagram-card]) [data-diagram-empty] { display: none; }
|
|
3805
|
+
|
|
3806
|
+
/* ── The change map ── */
|
|
3807
|
+
.prb-map-body { container-type: inline-size; }
|
|
3808
|
+
.prb-map {
|
|
3809
|
+
margin: 0 0 20px;
|
|
3810
|
+
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
3811
|
+
border-radius: 10px;
|
|
3812
|
+
background: #fff;
|
|
3813
|
+
}
|
|
3814
|
+
.prb-map-head {
|
|
3815
|
+
display: flex;
|
|
3816
|
+
flex-wrap: wrap;
|
|
3817
|
+
align-items: flex-start;
|
|
3818
|
+
gap: 12px;
|
|
3819
|
+
padding: 14px 16px 12px;
|
|
3820
|
+
border-bottom: 1px solid rgba(15, 23, 42, 0.08);
|
|
3821
|
+
}
|
|
3822
|
+
.prb-map-heading { flex: 1 1 280px; min-width: 0; }
|
|
3823
|
+
.prb-map-title { margin: 0; font-size: var(--t-section); font-weight: 600; color: #1f2328; }
|
|
3824
|
+
.prb-map-intent { margin: 4px 0 0; font-size: var(--t-body); line-height: var(--lh-body); color: #57606a; }
|
|
3825
|
+
.prb-map-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; }
|
|
3826
|
+
.prb-map-registers {
|
|
3827
|
+
display: inline-flex;
|
|
3828
|
+
padding: 2px;
|
|
3829
|
+
border: 1px solid rgba(15, 23, 42, 0.15);
|
|
3830
|
+
border-radius: 7px;
|
|
3831
|
+
background: #f6f8fa;
|
|
3832
|
+
}
|
|
3833
|
+
.prb-map-register {
|
|
3834
|
+
padding: 3px 10px;
|
|
3835
|
+
border: 0;
|
|
3836
|
+
border-radius: 5px;
|
|
3837
|
+
background: transparent;
|
|
3838
|
+
color: #57606a;
|
|
3839
|
+
font: inherit;
|
|
3840
|
+
font-size: var(--t-micro);
|
|
3841
|
+
cursor: pointer;
|
|
3842
|
+
}
|
|
3843
|
+
.prb-map-register[aria-pressed='true'] { background: #fff; color: #1f2328; font-weight: 600; box-shadow: 0 1px 2px rgba(15, 23, 42, 0.12); }
|
|
3844
|
+
.prb-map-register:focus-visible { outline: 2px solid #9333ea; outline-offset: 1px; }
|
|
3845
|
+
.prb-map-hint { margin: 10px 16px 0; font-size: var(--t-micro); color: #8c959f; }
|
|
3846
|
+
|
|
3847
|
+
/* One graph in the page, two sets of words; the board says which to show. */
|
|
3848
|
+
.prb-map[data-register='simple'] [data-reg='technical'],
|
|
3849
|
+
.prb-map[data-register='technical'] [data-reg='simple'] { display: none; }
|
|
3850
|
+
|
|
3851
|
+
/* Stages as columns, read left to right. The gaps are wide on purpose: the relationship labels sit
|
|
3852
|
+
in them, and a label is the point of a line. */
|
|
3853
|
+
.prb-map-board {
|
|
3854
|
+
position: relative;
|
|
3855
|
+
display: grid;
|
|
3856
|
+
grid-template-columns: repeat(var(--prb-map-stages, 5), minmax(180px, 1fr));
|
|
3857
|
+
column-gap: 112px;
|
|
3858
|
+
padding: 14px 16px 22px;
|
|
3859
|
+
overflow-x: auto;
|
|
3860
|
+
}
|
|
3861
|
+
.prb-map-stage {
|
|
3862
|
+
position: relative;
|
|
3863
|
+
z-index: 1;
|
|
3864
|
+
display: flex;
|
|
3865
|
+
flex-direction: column;
|
|
3866
|
+
gap: 22px;
|
|
3867
|
+
}
|
|
3868
|
+
.prb-map-stage-title {
|
|
3869
|
+
align-self: flex-start;
|
|
3870
|
+
margin: 0 0 -8px;
|
|
3871
|
+
font-size: var(--t-micro);
|
|
3872
|
+
font-weight: 600;
|
|
3873
|
+
text-transform: uppercase;
|
|
3874
|
+
letter-spacing: 0.05em;
|
|
3875
|
+
color: #8c959f;
|
|
3876
|
+
}
|
|
3877
|
+
|
|
3878
|
+
.prb-map-node {
|
|
3879
|
+
--role: #8250df;
|
|
3880
|
+
position: relative;
|
|
3881
|
+
padding: 9px 11px 10px;
|
|
3882
|
+
border: 1px solid rgba(15, 23, 42, 0.14);
|
|
3883
|
+
border-left: 4px solid var(--role);
|
|
3884
|
+
border-radius: 8px;
|
|
3885
|
+
background: #fff;
|
|
3886
|
+
font-size: var(--t-meta);
|
|
3887
|
+
line-height: 1.45;
|
|
3888
|
+
color: #424a53;
|
|
3889
|
+
transition: opacity 0.15s ease, box-shadow 0.15s ease;
|
|
3890
|
+
cursor: pointer;
|
|
3891
|
+
}
|
|
3892
|
+
.prb-map-node:focus-visible { outline: 2px solid #9333ea; outline-offset: 2px; }
|
|
3893
|
+
.prb-map-node[data-role='intent'] { --role: #0969da; }
|
|
3894
|
+
.prb-map-node[data-role='actor'] { --role: #6e7781; }
|
|
3895
|
+
.prb-map-node[data-role='concept'] { --role: #8250df; }
|
|
3896
|
+
.prb-map-node[data-role='state'] { --role: #0f766e; }
|
|
3897
|
+
.prb-map-node[data-role='constraint'] { --role: #9a6700; }
|
|
3898
|
+
.prb-map-node[data-role='risk'] { --role: #cf222e; }
|
|
3899
|
+
.prb-map-node[data-role='outcome'] { --role: #1a7f37; }
|
|
3900
|
+
/* Importance is prominence: a heavier frame and a larger name, never a score. */
|
|
3901
|
+
.prb-map-node[data-weight='primary'] {
|
|
3902
|
+
border-width: 2px 2px 2px 5px;
|
|
3903
|
+
border-color: var(--role);
|
|
3904
|
+
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
|
|
3905
|
+
}
|
|
3906
|
+
.prb-map-node[data-weight='primary'] .prb-map-node-title { font-size: calc(var(--t-body) + 1px); }
|
|
3907
|
+
.prb-map-role {
|
|
3908
|
+
margin: 0 0 3px;
|
|
3909
|
+
font-size: var(--t-micro);
|
|
3910
|
+
font-weight: 600;
|
|
3911
|
+
text-transform: uppercase;
|
|
3912
|
+
letter-spacing: 0.04em;
|
|
3913
|
+
color: var(--role);
|
|
3914
|
+
}
|
|
3915
|
+
.prb-map-core { color: #57606a; font-weight: 500; }
|
|
3916
|
+
.prb-map-node-title { margin: 0 0 4px; font-size: var(--t-body); font-weight: 600; line-height: 1.3; color: #1f2328; }
|
|
3917
|
+
.prb-map-node-body { margin: 0; }
|
|
3918
|
+
.prb-map code:not(.prb-map-anchor) {
|
|
3919
|
+
padding: 0 3px;
|
|
3920
|
+
border-radius: 3px;
|
|
3921
|
+
background: #f6f8fa;
|
|
3922
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3923
|
+
font-size: var(--t-code);
|
|
3924
|
+
}
|
|
3925
|
+
.prb-map-why { margin: 6px 0 0; color: #57606a; }
|
|
3926
|
+
.prb-map-why-lead { font-weight: 600; color: #1f2328; }
|
|
3927
|
+
.prb-map-anchor {
|
|
3928
|
+
display: inline-block;
|
|
3929
|
+
max-width: 100%;
|
|
3930
|
+
margin-top: 6px;
|
|
3931
|
+
padding: 1px 5px;
|
|
3932
|
+
border-radius: 4px;
|
|
3933
|
+
background: #f6f8fa;
|
|
3934
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3935
|
+
font-size: var(--t-code);
|
|
3936
|
+
color: #57606a;
|
|
3937
|
+
overflow-wrap: anywhere;
|
|
3938
|
+
}
|
|
3939
|
+
/* Relationships the board could not draw cleanly, said in the idea they leave from. */
|
|
3940
|
+
.prb-map-inline {
|
|
3941
|
+
margin: 7px 0 0;
|
|
3942
|
+
padding: 6px 0 0;
|
|
3943
|
+
border-top: 1px dashed rgba(15, 23, 42, 0.14);
|
|
3944
|
+
list-style: none;
|
|
3945
|
+
font-size: var(--t-micro);
|
|
3946
|
+
color: #57606a;
|
|
3947
|
+
}
|
|
3948
|
+
.prb-map-inline:not(:has(li:not([hidden]))) { display: none; }
|
|
3949
|
+
.prb-map-inline li + li { margin-top: 2px; }
|
|
3950
|
+
.prb-map-inline em { color: #1f2328; }
|
|
3951
|
+
.prb-map-goto {
|
|
3952
|
+
display: block;
|
|
3953
|
+
margin-top: 8px;
|
|
3954
|
+
padding: 0;
|
|
3955
|
+
border: 0;
|
|
3956
|
+
background: none;
|
|
3957
|
+
color: #8250df;
|
|
3958
|
+
font: inherit;
|
|
3959
|
+
font-size: var(--t-micro);
|
|
3960
|
+
font-weight: 600;
|
|
3961
|
+
text-align: left;
|
|
3962
|
+
cursor: pointer;
|
|
3963
|
+
}
|
|
3964
|
+
.prb-map-goto:hover { text-decoration: underline; }
|
|
3965
|
+
|
|
3966
|
+
.prb-map-edges {
|
|
3967
|
+
position: absolute;
|
|
3968
|
+
top: 0;
|
|
3969
|
+
left: 0;
|
|
3970
|
+
z-index: 0;
|
|
3971
|
+
overflow: visible;
|
|
3972
|
+
pointer-events: none;
|
|
3973
|
+
}
|
|
3974
|
+
.prb-map-edge { fill: none; stroke: #8c959f; stroke-width: 1.5; transition: opacity 0.15s ease; }
|
|
3975
|
+
.prb-map-arrow { fill: #8c959f; }
|
|
3976
|
+
.prb-map-labels { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
|
|
3977
|
+
.prb-map-board:not([data-laid-out]) .prb-map-labels { visibility: hidden; }
|
|
3978
|
+
.prb-map-label {
|
|
3979
|
+
position: absolute;
|
|
3980
|
+
max-width: 100px;
|
|
3981
|
+
padding: 1px 6px;
|
|
3982
|
+
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
3983
|
+
border-radius: 10px;
|
|
3984
|
+
background: #fff;
|
|
3985
|
+
font-size: var(--t-micro);
|
|
3986
|
+
font-style: italic;
|
|
3987
|
+
line-height: 1.35;
|
|
3988
|
+
text-align: center;
|
|
3989
|
+
color: #424a53;
|
|
3990
|
+
transition: opacity 0.15s ease;
|
|
3991
|
+
}
|
|
3992
|
+
.prb-map-label[hidden] { display: none; }
|
|
3993
|
+
|
|
3994
|
+
/* Selecting an idea keeps it, its neighbours and the lines between them, and quiets the rest. */
|
|
3995
|
+
.prb-map-board[data-selecting] .prb-map-node:not([data-active]):not([data-near]) { opacity: 0.35; }
|
|
3996
|
+
.prb-map-board[data-selecting] .prb-map-edge:not([data-active]) { opacity: 0.15; }
|
|
3997
|
+
.prb-map-board[data-selecting] .prb-map-label:not([data-active]) { opacity: 0.2; }
|
|
3998
|
+
.prb-map-board .prb-map-edge[data-active] { stroke: #1f2328; stroke-width: 2; }
|
|
3999
|
+
.prb-map-board .prb-map-label[data-active] { border-color: #1f2328; color: #1f2328; }
|
|
4000
|
+
.prb-map-node[data-active] { box-shadow: 0 0 0 3px rgba(147, 51, 234, 0.25); }
|
|
4001
|
+
|
|
4002
|
+
.prb-map-list { margin: 0 16px 14px; font-size: var(--t-meta); color: #57606a; }
|
|
4003
|
+
.prb-map-list > summary { cursor: pointer; }
|
|
4004
|
+
.prb-map-list ol { margin: 8px 0 0; padding-left: 20px; line-height: var(--lh-body); }
|
|
4005
|
+
.prb-map-list li { margin-bottom: 4px; }
|
|
4006
|
+
.prb-map-list strong { color: #1f2328; font-weight: 600; }
|
|
4007
|
+
.prb-map-note { color: #57606a; }
|
|
4008
|
+
|
|
4009
|
+
/* Five stages side by side, with room between them for the words on the lines, need about 1360px:
|
|
4010
|
+
the expanded pane, not the one between the rail and Buddy AI. Narrower than that the stages stack, top to bottom, in the same reading order,
|
|
4011
|
+
and the lines follow them down. A board that scrolled sideways would hide the half of every line
|
|
4012
|
+
that explains it. */
|
|
4013
|
+
@container (max-width: 1360px) {
|
|
4014
|
+
.prb-map-board { grid-template-columns: minmax(0, 1fr); row-gap: 58px; overflow-x: visible; }
|
|
4015
|
+
.prb-map-stage { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: stretch; gap: 28px 36px; }
|
|
4016
|
+
.prb-map-stage-title { flex-basis: 100%; margin: 0; }
|
|
4017
|
+
.prb-map-node { flex: 1 1 210px; max-width: 300px; }
|
|
4018
|
+
}
|
|
4019
|
+
|
|
4020
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4021
|
+
.prb-map-node, .prb-map-edge, .prb-map-label { transition: none; }
|
|
4022
|
+
}
|
|
4023
|
+
|
|
3701
4024
|
/* ── The Overview's stat cards ──
|
|
3702
4025
|
The drawer stacks each card as a centred column: number, then label, then an optional note. At
|
|
3703
4026
|
460px that is the only thing that fits. Here it produced two faults at once. Every card is as
|
|
@@ -3791,6 +4114,21 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
3791
4114
|
}
|
|
3792
4115
|
.pr-helper-diagram-button:hover { background: rgba(147, 51, 234, 0.08); }
|
|
3793
4116
|
.pr-helper-diagram-button[disabled] { opacity: 0.55; cursor: default; }
|
|
4117
|
+
/* The Overview's way to the diagrams: the main visual path through the change, so a step above its
|
|
4118
|
+
neighbour with a tinted ground, yet no run behind it, so not the filled treatment Generate has. */
|
|
4119
|
+
.pr-helper-map-button {
|
|
4120
|
+
margin: 0 0 14px;
|
|
4121
|
+
padding: 7px 16px;
|
|
4122
|
+
border: 1px solid #9333ea;
|
|
4123
|
+
border-radius: 6px;
|
|
4124
|
+
background: rgba(147, 51, 234, 0.1);
|
|
4125
|
+
color: #7e22ce;
|
|
4126
|
+
font-family: inherit;
|
|
4127
|
+
font-size: var(--t-meta);
|
|
4128
|
+
font-weight: 600;
|
|
4129
|
+
cursor: pointer;
|
|
4130
|
+
}
|
|
4131
|
+
.pr-helper-map-button:hover { background: rgba(147, 51, 234, 0.16); }
|
|
3794
4132
|
/* In a theme card the button stands alone in the actions row, whose other occupant — the guided
|
|
3795
4133
|
review CTA — is hidden in this client. That CTA carried the gap below the review checklist, so
|
|
3796
4134
|
with it gone the row has to carry it, or the button sits flush against the checklist box: the
|
|
@@ -3863,8 +4201,15 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
3863
4201
|
line-height: var(--lh-tight);
|
|
3864
4202
|
}
|
|
3865
4203
|
|
|
3866
|
-
.prb-guide-
|
|
4204
|
+
.prb-guide-head {
|
|
4205
|
+
display: flex;
|
|
4206
|
+
align-items: center;
|
|
4207
|
+
gap: 12px;
|
|
3867
4208
|
margin: 0 0 20px;
|
|
4209
|
+
}
|
|
4210
|
+
.prb-guide-head .prb-focus-toggle { margin-left: auto; }
|
|
4211
|
+
.prb-guide-progress {
|
|
4212
|
+
margin: 0;
|
|
3868
4213
|
color: var(--pane-ink-faint);
|
|
3869
4214
|
font-size: var(--t-meta);
|
|
3870
4215
|
}
|
|
@@ -4517,3 +4862,206 @@ a.prb-notification-open:focus-visible { outline: 2px solid var(--brand-hover); o
|
|
|
4517
4862
|
.prb-toast-close:hover { color: var(--text-primary); background: rgba(255, 255, 255, 0.06); }
|
|
4518
4863
|
.prb-toast-open:focus-visible,
|
|
4519
4864
|
.prb-toast-close:focus-visible { outline: 2px solid var(--brand-hover); outline-offset: 2px; }
|
|
4865
|
+
|
|
4866
|
+
/* ── Focus mode ──
|
|
4867
|
+
One surface as the whole workspace, beneath the same header, which is outside `.prb-body` and so
|
|
4868
|
+
never changes. The client sets `data-focus` and nothing else: every pane stays in the DOM,
|
|
4869
|
+
hidden rather than removed, which is why a conversation, an open code panel and a scroll position
|
|
4870
|
+
are all still there on the way back.
|
|
4871
|
+
|
|
4872
|
+
`body` in front of every selector, deliberately. The responsive blocks above set the grid with
|
|
4873
|
+
(0,2,0) selectors inside media queries that come later in the cascade than anything this could
|
|
4874
|
+
be placed beside. One element of extra specificity wins at every width without `!important`,
|
|
4875
|
+
and without depending on this block staying last. */
|
|
4876
|
+
body .prb-body[data-focus] { grid-template-columns: minmax(0, 1fr); }
|
|
4877
|
+
body .prb-body[data-focus] .prb-rail { display: none; }
|
|
4878
|
+
|
|
4879
|
+
/* A document surface, which is every view but the assistant: the review pane takes the width, and
|
|
4880
|
+
gets more room to use it. Prose stays a readable measure; a diff and a drawing are the things here
|
|
4881
|
+
that genuinely want the width. */
|
|
4882
|
+
body .prb-body[data-focus]:not([data-focus='buddy']) .prb-ask { display: none; }
|
|
4883
|
+
body .prb-body[data-focus]:not([data-focus='buddy']) .pr-helper-sidebar.prb-pane { max-width: 1080px; }
|
|
4884
|
+
body .prb-body:is([data-focus='files'], [data-focus='diagram']) .pr-helper-sidebar.prb-pane { max-width: 1600px; }
|
|
4885
|
+
/* The rail is where the themes are listed, and it is hidden here, so the picker it stands in for
|
|
4886
|
+
below 860px stands in for it now. */
|
|
4887
|
+
body .prb-body[data-focus='guide'] .prb-guide-picker { display: flex; }
|
|
4888
|
+
/* An expanded map has room for every stage side by side, which is the point of expanding it. */
|
|
4889
|
+
body .prb-body[data-focus='map']:not([data-focus='buddy']) .pr-helper-sidebar.prb-pane { max-width: 1560px; }
|
|
4890
|
+
|
|
4891
|
+
/* The assistant: the review pane goes, and the assistant is a column in the grid again at every
|
|
4892
|
+
width. Below 860px it is otherwise a fixed overlay, and an overlay as the whole workspace would
|
|
4893
|
+
sit over the header this mode promises to keep. */
|
|
4894
|
+
body .prb-body[data-focus='buddy'] .prb-doc { display: none; }
|
|
4895
|
+
body .prb-body[data-focus='buddy'] .prb-ask {
|
|
4896
|
+
display: flex;
|
|
4897
|
+
position: relative;
|
|
4898
|
+
inset: auto;
|
|
4899
|
+
width: auto;
|
|
4900
|
+
border-left: 0;
|
|
4901
|
+
}
|
|
4902
|
+
body .prb-body[data-focus='buddy'] .prb-ask-resize { display: none; }
|
|
4903
|
+
|
|
4904
|
+
/* Prose at a reading measure, centred, with the column itself wider so a code block or a table in
|
|
4905
|
+
an answer can use the room the mode exists to give it. The padding does the centring rather than
|
|
4906
|
+
a max-width on the log, so the log's scrollbar stays at the window's edge. */
|
|
4907
|
+
body .prb-body[data-focus='buddy'] :is(.prb-ask-header, .prb-bank, .prb-ask-log, .prb-ask-form, .prb-ask-paused) {
|
|
4908
|
+
padding-inline: max(18px, calc((100% - 1040px) / 2));
|
|
4909
|
+
}
|
|
4910
|
+
body .prb-body[data-focus='buddy'] .prb-msg-assistant :is(p, ul, ol, blockquote, h1, h2, h3, h4, h5, h6) { max-width: 78ch; }
|
|
4911
|
+
body .prb-body[data-focus='buddy'] .prb-msg-user { max-width: min(90%, 78ch); }
|
|
4912
|
+
|
|
4913
|
+
/* The expand control. Icon-only, like Copy on a card, so it does not compete with a title. Both
|
|
4914
|
+
icons are in the markup and `aria-pressed` picks one, which is the state the client sets. */
|
|
4915
|
+
.prb-focus-toggle {
|
|
4916
|
+
display: inline-flex;
|
|
4917
|
+
align-items: center;
|
|
4918
|
+
justify-content: center;
|
|
4919
|
+
flex-shrink: 0;
|
|
4920
|
+
width: 26px;
|
|
4921
|
+
height: 26px;
|
|
4922
|
+
padding: 0;
|
|
4923
|
+
border: 1px solid transparent;
|
|
4924
|
+
border-radius: 7px;
|
|
4925
|
+
background: transparent;
|
|
4926
|
+
color: var(--text-muted);
|
|
4927
|
+
cursor: pointer;
|
|
4928
|
+
}
|
|
4929
|
+
.prb-focus-toggle:hover { color: var(--text-primary); background: var(--surface-2); }
|
|
4930
|
+
.prb-focus-toggle:focus-visible { outline: 2px solid var(--brand-hover); outline-offset: -2px; }
|
|
4931
|
+
.prb-focus-toggle .prb-focus-collapse,
|
|
4932
|
+
.prb-focus-toggle[aria-pressed='true'] .prb-focus-expand { display: none; }
|
|
4933
|
+
.prb-focus-toggle[aria-pressed='true'] .prb-focus-collapse { display: block; }
|
|
4934
|
+
/* In the assistant's header it follows the scope label, which takes the free space with
|
|
4935
|
+
`margin-left: auto`, so the control stays at the right edge beside it. */
|
|
4936
|
+
.prb-ask-header .prb-focus-toggle { align-self: center; }
|
|
4937
|
+
|
|
4938
|
+
/* The same control in the light document pane, in the pane's palette. */
|
|
4939
|
+
.prb-doc .prb-focus-toggle { color: var(--pane-ink-faint); }
|
|
4940
|
+
.prb-doc .prb-focus-toggle:hover { color: var(--pane-ink); background: var(--pane-bg); border-color: var(--pane-line); }
|
|
4941
|
+
/* The title row is baseline-aligned for the disclosure's text; an icon has no baseline worth
|
|
4942
|
+
aligning, so it centres on the title instead. */
|
|
4943
|
+
.prb-doc .prb-doc-head .prb-focus-toggle { align-self: center; margin-left: auto; }
|
|
4944
|
+
/* Beside Analysis details the pair sits together at the right: the disclosure takes the free space,
|
|
4945
|
+
and the toggle follows it rather than splitting the row in two. */
|
|
4946
|
+
.prb-doc .prb-doc-head .prb-doc-provenance { margin-left: auto; }
|
|
4947
|
+
.prb-doc .prb-doc-head .prb-doc-provenance + .prb-focus-toggle { margin-left: -8px; }
|
|
4948
|
+
|
|
4949
|
+
/* ── Your prompts, folded ──
|
|
4950
|
+
The heading is the toggle. Folded, it keeps a count, so a reviewer knows what is behind it
|
|
4951
|
+
without opening it, and Add stays beside it. */
|
|
4952
|
+
.prb-bank-toggle {
|
|
4953
|
+
display: inline-flex;
|
|
4954
|
+
align-items: center;
|
|
4955
|
+
gap: 6px;
|
|
4956
|
+
padding: 2px 4px 2px 0;
|
|
4957
|
+
border: 0;
|
|
4958
|
+
background: transparent;
|
|
4959
|
+
color: inherit;
|
|
4960
|
+
font: inherit;
|
|
4961
|
+
letter-spacing: inherit;
|
|
4962
|
+
text-transform: inherit;
|
|
4963
|
+
cursor: pointer;
|
|
4964
|
+
}
|
|
4965
|
+
.prb-bank-toggle:hover { color: var(--text-primary); }
|
|
4966
|
+
.prb-bank-toggle:focus-visible { outline: 2px solid var(--brand-hover); outline-offset: 2px; border-radius: 4px; }
|
|
4967
|
+
.prb-bank-chevron { transition: transform 120ms ease; transform: rotate(90deg); }
|
|
4968
|
+
.prb-bank-toggle[aria-expanded='false'] .prb-bank-chevron { transform: none; }
|
|
4969
|
+
.prb-bank-count {
|
|
4970
|
+
padding: 0 6px;
|
|
4971
|
+
border-radius: 999px;
|
|
4972
|
+
background: var(--surface-2);
|
|
4973
|
+
font-variant-numeric: tabular-nums;
|
|
4974
|
+
letter-spacing: normal;
|
|
4975
|
+
}
|
|
4976
|
+
.prb-bank-toggle[aria-expanded='true'] .prb-bank-count { display: none; }
|
|
4977
|
+
.prb-bank[data-collapsed] { padding-bottom: 8px; }
|
|
4978
|
+
.prb-bank[data-collapsed] .prb-bank-head { margin-bottom: 0; }
|
|
4979
|
+
|
|
4980
|
+
/* ── Ask Buddy on a finding card ──
|
|
4981
|
+
The page's `[data-menu]` menu, as the header's `...` is, dropped into a card's title row beside
|
|
4982
|
+
Copy. Positioned as the flex child it is, the way `.prb-header .prb-menu` is, so the panel hangs
|
|
4983
|
+
off the trigger rather than off a corner of the card. The panel is in the card's flow inside the
|
|
4984
|
+
scrolling pane, so near the bottom it extends the scroll rather than being cut off. */
|
|
4985
|
+
.prb-doc .pr-helper-issue-title-row .prb-menu {
|
|
4986
|
+
position: relative;
|
|
4987
|
+
top: auto;
|
|
4988
|
+
right: auto;
|
|
4989
|
+
display: inline-flex;
|
|
4990
|
+
flex-shrink: 0;
|
|
4991
|
+
/* Not the base rule's `z-index: 2`. That makes every card's wrapper a stacking context of its
|
|
4992
|
+
own at the same level, and the next card's sparkle, later in the document, then paints over
|
|
4993
|
+
this card's open panel. With no context here the panel's own z-index is measured against the
|
|
4994
|
+
whole pane. */
|
|
4995
|
+
z-index: auto;
|
|
4996
|
+
}
|
|
4997
|
+
.prb-doc .prb-ask-buddy-trigger {
|
|
4998
|
+
display: inline-flex;
|
|
4999
|
+
align-items: center;
|
|
5000
|
+
justify-content: center;
|
|
5001
|
+
width: 24px;
|
|
5002
|
+
height: 24px;
|
|
5003
|
+
margin-top: -3px;
|
|
5004
|
+
color: var(--pane-accent);
|
|
5005
|
+
}
|
|
5006
|
+
.prb-doc .prb-ask-buddy-trigger:hover,
|
|
5007
|
+
.prb-doc .prb-ask-buddy-trigger[aria-expanded='true'] { background: var(--pane-bg); color: var(--pane-accent-ink); }
|
|
5008
|
+
.prb-doc .prb-ask-buddy-trigger:focus-visible { outline: 2px solid var(--pane-accent); outline-offset: -2px; }
|
|
5009
|
+
|
|
5010
|
+
/* The tooltip Copy uses beside it, so the two icons explain themselves the same way. */
|
|
5011
|
+
.prb-doc .prb-ask-buddy-trigger::after {
|
|
5012
|
+
content: attr(data-tip);
|
|
5013
|
+
position: absolute;
|
|
5014
|
+
top: calc(100% + 6px);
|
|
5015
|
+
right: 0;
|
|
5016
|
+
z-index: 3;
|
|
5017
|
+
padding: 5px 8px;
|
|
5018
|
+
border-radius: 6px;
|
|
5019
|
+
background: #24292f;
|
|
5020
|
+
color: #ffffff;
|
|
5021
|
+
font-size: 11px;
|
|
5022
|
+
line-height: 1.4;
|
|
5023
|
+
white-space: nowrap;
|
|
5024
|
+
opacity: 0;
|
|
5025
|
+
pointer-events: none;
|
|
5026
|
+
transition: opacity 0.1s;
|
|
5027
|
+
}
|
|
5028
|
+
.prb-doc .prb-ask-buddy-trigger:hover::after,
|
|
5029
|
+
.prb-doc .prb-ask-buddy-trigger:focus-visible::after { opacity: 1; transition-delay: 0.35s; }
|
|
5030
|
+
.prb-doc .prb-ask-buddy-trigger[aria-expanded='true']::after { display: none; }
|
|
5031
|
+
|
|
5032
|
+
/* The panel in the pane's palette: the header's is dark on the dark shell, and a dark box in the
|
|
5033
|
+
middle of a light card is the mistake pane_palette.test.ts exists to catch. */
|
|
5034
|
+
.prb-doc .prb-ask-buddy-panel {
|
|
5035
|
+
top: 28px;
|
|
5036
|
+
width: 280px;
|
|
5037
|
+
max-width: min(280px, calc(100vw - 48px));
|
|
5038
|
+
border-color: var(--pane-line);
|
|
5039
|
+
background: var(--pane-surface);
|
|
5040
|
+
box-shadow: 0 10px 28px rgba(15, 23, 42, 0.16);
|
|
5041
|
+
color: var(--pane-ink);
|
|
5042
|
+
}
|
|
5043
|
+
.prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item {
|
|
5044
|
+
display: block;
|
|
5045
|
+
width: 100%;
|
|
5046
|
+
padding: 7px 9px;
|
|
5047
|
+
border: 0;
|
|
5048
|
+
border-radius: 6px;
|
|
5049
|
+
background: transparent;
|
|
5050
|
+
color: var(--pane-ink);
|
|
5051
|
+
font: inherit;
|
|
5052
|
+
font-size: var(--t-meta);
|
|
5053
|
+
text-align: left;
|
|
5054
|
+
cursor: pointer;
|
|
5055
|
+
}
|
|
5056
|
+
.prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item:hover,
|
|
5057
|
+
.prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item:focus-visible { background: var(--pane-bg); outline: none; }
|
|
5058
|
+
.prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item:focus-visible { box-shadow: inset 0 0 0 2px var(--pane-accent); }
|
|
5059
|
+
.prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item:disabled { opacity: 0.5; cursor: default; }
|
|
5060
|
+
.prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-group { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--pane-line); }
|
|
5061
|
+
.prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-heading {
|
|
5062
|
+
padding: 4px 9px 2px;
|
|
5063
|
+
color: var(--pane-ink-faint);
|
|
5064
|
+
font-size: var(--t-micro);
|
|
5065
|
+
letter-spacing: 0.04em;
|
|
5066
|
+
text-transform: uppercase;
|
|
5067
|
+
}
|