chamba 0.6.1 → 0.8.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/LICENSE +53 -14
- package/README.md +38 -11
- package/dist/commands/advanced.js +7 -278
- package/dist/commands/dev.js +11 -612
- package/dist/commands/doctor.js +1 -29
- package/dist/commands/menu.js +1 -80
- package/dist/commands/onboard.js +6 -230
- package/dist/commands/settings.js +15 -349
- package/dist/lib/agent-commands.js +2 -0
- package/dist/lib/agent-context.js +6 -184
- package/dist/lib/browser.js +1 -40
- package/dist/lib/chamba-yaml.js +10 -191
- package/dist/lib/constants.js +1 -125
- package/dist/lib/dockerfile-builder.js +41 -260
- package/dist/lib/env.js +2 -78
- package/dist/lib/git-env.js +1 -21
- package/dist/lib/global-config.js +4 -66
- package/dist/lib/pnpm-store.js +1 -19
- package/dist/lib/ports.js +1 -210
- package/dist/lib/safe-rm.js +1 -26
- package/dist/lib/sessions.js +2 -34
- package/dist/lib/shadows.js +1 -176
- package/dist/lib/skills.js +2 -0
- package/dist/lib/templates.js +1 -0
- package/dist/lib/webterm.js +1 -305
- package/dist/lib/workspace-identity.js +4 -260
- package/package.json +6 -6
- package/templates/Dockerfile +24 -12
- package/templates/claude-statusline.sh +5 -7
- package/templates/context/baseline.md +2 -0
- package/templates/pane-apps/client/assets/c-BNa-DeUl.json +3552 -0
- package/templates/pane-apps/client/assets/cpp-B-T4NRoH.json +20239 -0
- package/templates/pane-apps/client/assets/csharp-BbxHChhA.json +6010 -0
- package/templates/pane-apps/client/assets/css-CWCxuwmz.json +1860 -0
- package/templates/pane-apps/client/assets/diff-B-2N89g8.json +154 -0
- package/templates/pane-apps/client/assets/docker-DWTvYW26.json +103 -0
- package/templates/pane-apps/client/assets/files-D0nJgFAA.js +12 -0
- package/templates/pane-apps/client/assets/files-h0K1vZyQ.css +1 -0
- package/templates/pane-apps/client/assets/go-B2hyYeNg.json +3156 -0
- package/templates/pane-apps/client/assets/graphql-Z6Id2aNO.json +1292 -0
- package/templates/pane-apps/client/assets/html-BtzvlIfu.json +2627 -0
- package/templates/pane-apps/client/assets/ini-Bn3Twap1.json +108 -0
- package/templates/pane-apps/client/assets/java-C7t2dwLO.json +1885 -0
- package/templates/pane-apps/client/assets/javascript-DuC2v0C0.json +5996 -0
- package/templates/pane-apps/client/assets/json-CwdkWeV5.json +206 -0
- package/templates/pane-apps/client/assets/jsonc-MYWDbTU3.json +206 -0
- package/templates/pane-apps/client/assets/jsx-Cn8EZuIC.json +5996 -0
- package/templates/pane-apps/client/assets/kotlin-CFNOz1gw.json +580 -0
- package/templates/pane-apps/client/assets/make-BVnlFCcl.json +629 -0
- package/templates/pane-apps/client/assets/markdown-B4Xk2WM_.json +3263 -0
- package/templates/pane-apps/client/assets/php-CAQzQmmI.json +4188 -0
- package/templates/pane-apps/client/assets/python-CYQee8m4.json +4174 -0
- package/templates/pane-apps/client/assets/reviews-BsoGZ35r.css +1 -0
- package/templates/pane-apps/client/assets/reviews-iW0Mbn4e.js +153 -0
- package/templates/pane-apps/client/assets/ruby-D7R58tus.json +3114 -0
- package/templates/pane-apps/client/assets/rust-BFBbFiei.json +1103 -0
- package/templates/pane-apps/client/assets/scss-TQRhBkPG.json +1874 -0
- package/templates/pane-apps/client/assets/shellscript-DieAkC4W.json +2375 -0
- package/templates/pane-apps/client/assets/specs-D9z3neR-.js +13 -0
- package/templates/pane-apps/client/assets/sql-Bxd030LV.json +634 -0
- package/templates/pane-apps/client/assets/toml-ChrKGzsV.json +430 -0
- package/templates/pane-apps/client/assets/tsx-D2e90MFw.json +5996 -0
- package/templates/pane-apps/client/assets/typescript-DonXQ_n1.json +5747 -0
- package/templates/pane-apps/client/assets/xml-B17r2RXF.json +382 -0
- package/templates/pane-apps/client/assets/yaml-CKn4h1zy.json +627 -0
- package/templates/pane-apps/client/reviews/index.html +15 -0
- package/templates/pane-apps/client/specs/index.html +14 -0
- package/templates/pane-apps/server/reviews.mjs +20 -0
- package/templates/pane-apps/server/specs.mjs +5 -0
- package/templates/skills/chamba-statusline/SKILL.md +7 -19
- package/templates/skills/dx-review/SKILL.md +123 -0
- package/templates/skills/dx-review/references/acts.md +162 -0
- package/templates/skills/dx-spec/SKILL.md +561 -0
- package/templates/skills/dx-spec/references/imagination-guide.md +140 -0
- package/templates/skills/dx-spec/references/principles-template.md +2 -0
- package/templates/skills/dx-spec/references/review-guide.md +127 -0
- package/templates/skills/dx-spec/references/spec-guide.md +145 -0
- package/templates/skills/dx-spec/references/stages.md +484 -0
- package/templates/skills/dx-spec-execute/SKILL.md +437 -0
- package/templates/startup.mjs +10 -4
- package/templates/tool-helper.sh +166 -0
- package/templates/webterm/README.md +79 -9
- package/templates/webterm/color.js +61 -0
- package/templates/webterm/config.js +74 -0
- package/templates/webterm/context/claude.md +0 -1
- package/templates/webterm/public/app/alerts.js +4 -4
- package/templates/webterm/public/app/anchored.js +81 -0
- package/templates/webterm/public/app/composer.js +4 -1
- package/templates/webterm/public/app/connection.js +9 -0
- package/templates/webterm/public/app/dom.js +15 -5
- package/templates/webterm/public/app/frames.js +51 -10
- package/templates/webterm/public/app/main.js +26 -6
- package/templates/webterm/public/app/new-session.js +13 -41
- package/templates/webterm/public/app/palette.js +58 -0
- package/templates/webterm/public/app/pane-shape.js +167 -0
- package/templates/webterm/public/app/pane-shell.js +380 -0
- package/templates/webterm/public/app/pane.js +77 -193
- package/templates/webterm/public/app/reviews-host.js +15 -0
- package/templates/webterm/public/app/specs-host.js +16 -0
- package/templates/webterm/public/app/state.js +5 -0
- package/templates/webterm/public/app/tabs.js +6 -2
- package/templates/webterm/public/app/terminal.js +8 -0
- package/templates/webterm/public/app/theme.js +75 -27
- package/templates/webterm/public/app/tool-host.js +302 -0
- package/templates/webterm/public/app/workspace-color.js +192 -0
- package/templates/webterm/public/index.html +68 -30
- package/templates/webterm/public/styles.css +270 -34
- package/templates/webterm/server.js +321 -0
- package/templates/webterm/tool-document.js +67 -0
- package/templates/webterm/tools/commands.js +61 -0
- package/templates/webterm/tools/index.js +25 -0
- package/templates/webterm/tools/mount.js +337 -0
- package/templates/webterm/tools/paths.js +34 -0
- package/templates/webterm/tools/reviews.js +133 -0
- package/templates/webterm/tools/specs.js +154 -0
- package/templates/webterm/typed-line.js +148 -0
- package/templates/context/context-usage.md +0 -1
- package/templates/context-usage.sh +0 -266
|
@@ -527,6 +527,13 @@ body {
|
|
|
527
527
|
display: flex;
|
|
528
528
|
flex: 1;
|
|
529
529
|
min-height: 0;
|
|
530
|
+
/* Stated once because two rules need it: the grip is this wide, and a full-width pane is the row less
|
|
531
|
+
the grip - which is what keeps the grip on the screen with the terminal squeezed out behind it. */
|
|
532
|
+
--grip-width: 12px;
|
|
533
|
+
/* The terminal's own inset, on both sides. A margin does not shrink with the box it is on, so a
|
|
534
|
+
full-width pane has to leave it as well or the row is wider than the window and the pane's own
|
|
535
|
+
controls, which sit at its far end, go off the screen. */
|
|
536
|
+
--term-gutter: 24px;
|
|
530
537
|
}
|
|
531
538
|
|
|
532
539
|
#termwrap {
|
|
@@ -537,7 +544,7 @@ body {
|
|
|
537
544
|
/* Spacing via margin, not padding: FitAddon measures the wrapper height but does not subtract
|
|
538
545
|
its padding, so wrapper padding makes it propose one row too many and the last line clips.
|
|
539
546
|
Margin gives the same visual inset (page and terminal share a background) without breaking fit. */
|
|
540
|
-
margin: 8px
|
|
547
|
+
margin: 8px calc(var(--term-gutter) / 2);
|
|
541
548
|
}
|
|
542
549
|
|
|
543
550
|
#term {
|
|
@@ -595,7 +602,7 @@ body {
|
|
|
595
602
|
#grip {
|
|
596
603
|
position: relative;
|
|
597
604
|
flex: none;
|
|
598
|
-
width:
|
|
605
|
+
width: var(--grip-width);
|
|
599
606
|
background: var(--panel);
|
|
600
607
|
border-left: 1px solid var(--border);
|
|
601
608
|
border-right: 1px solid var(--border);
|
|
@@ -626,17 +633,28 @@ body.dragging {
|
|
|
626
633
|
user-select: none;
|
|
627
634
|
}
|
|
628
635
|
|
|
629
|
-
/* The width is app/pane.js's, in a custom property so the
|
|
630
|
-
the narrow-screen layout - still do. The value here
|
|
636
|
+
/* The width is app/pane-shell.js's, in a custom property so the three rules that must win - the collapsed
|
|
637
|
+
spine, the full row and the narrow-screen layout - still do. The value here shows for the moment before the
|
|
638
|
+
first draw sets the property, so it is the same half the pane's own default is. */
|
|
631
639
|
#pane {
|
|
632
640
|
display: flex;
|
|
633
641
|
flex: none;
|
|
634
642
|
flex-direction: column;
|
|
635
|
-
width: var(--pane-width,
|
|
643
|
+
width: var(--pane-width, 50%);
|
|
636
644
|
min-width: 0;
|
|
637
645
|
background: var(--bg);
|
|
638
646
|
}
|
|
639
647
|
|
|
648
|
+
/* The far end of the range: the pane takes the row and the terminal is squeezed out of it rather than hidden,
|
|
649
|
+
so the terminal keeps its place in the layout and comes back at whatever the next width is. The grip is
|
|
650
|
+
what the row leaves over, which is what keeps the way back on the screen, and the terminal's gutter is left
|
|
651
|
+
as well - it is a margin, so it stays whatever the box it is on shrinks to, and taking the row without it
|
|
652
|
+
would push the pane's own controls past the right edge of the window. Both are the same background, so what
|
|
653
|
+
the terminal leaves behind reads as part of the pane. */
|
|
654
|
+
#pane.full {
|
|
655
|
+
width: calc(100% - var(--grip-width) - var(--term-gutter));
|
|
656
|
+
}
|
|
657
|
+
|
|
640
658
|
/* A page arrived and opened itself: one pulse of the workspace colour along the pane's own edge, and nothing
|
|
641
659
|
moves. Inset, so it is drawn over the pane rather than pushing the layout about, and over the frame's edge
|
|
642
660
|
rather than under it. ARRIVAL_MS in app/pane.js must match the duration - it is what takes the class off
|
|
@@ -664,20 +682,8 @@ body.dragging {
|
|
|
664
682
|
}
|
|
665
683
|
}
|
|
666
684
|
|
|
667
|
-
/* The
|
|
668
|
-
|
|
669
|
-
truth about which page is open. */
|
|
670
|
-
#pagebar {
|
|
671
|
-
display: flex;
|
|
672
|
-
flex: none;
|
|
673
|
-
align-items: center;
|
|
674
|
-
gap: 6px;
|
|
675
|
-
padding: 7px 10px;
|
|
676
|
-
background: var(--panel);
|
|
677
|
-
border-bottom: 1px solid var(--border);
|
|
678
|
-
overflow: hidden;
|
|
679
|
-
}
|
|
680
|
-
|
|
685
|
+
/* The small square buttons of the pane's two bars: the width controls up in the pane's own chrome, and the
|
|
686
|
+
chip arrows down in the Pages bar. */
|
|
681
687
|
.pane-nav {
|
|
682
688
|
flex: none;
|
|
683
689
|
padding: 1px 6px;
|
|
@@ -695,6 +701,127 @@ body.dragging {
|
|
|
695
701
|
color: var(--text);
|
|
696
702
|
}
|
|
697
703
|
|
|
704
|
+
/* The pane's own bar: which tool is open, and how wide the pane is. Nothing in it belongs to a tool, which is
|
|
705
|
+
what stops a tool from moving the pane or from saying which tool the user is looking at. */
|
|
706
|
+
#panebar {
|
|
707
|
+
display: flex;
|
|
708
|
+
flex: none;
|
|
709
|
+
align-items: center;
|
|
710
|
+
gap: 2px;
|
|
711
|
+
padding: 0 8px;
|
|
712
|
+
background: var(--bg);
|
|
713
|
+
border-bottom: 1px solid var(--border);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
#tool-tabs {
|
|
717
|
+
display: flex;
|
|
718
|
+
gap: 2px;
|
|
719
|
+
min-width: 0;
|
|
720
|
+
overflow: hidden;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/* A tab is a label with a line under it: the pane's bar is chrome rather than a surface of its own, and the
|
|
724
|
+
workspace's colour under the open one is what says which tool is on the screen. */
|
|
725
|
+
.tool-tab {
|
|
726
|
+
display: flex;
|
|
727
|
+
flex: none;
|
|
728
|
+
align-items: center;
|
|
729
|
+
gap: 6px;
|
|
730
|
+
height: 34px;
|
|
731
|
+
padding: 0 12px;
|
|
732
|
+
border: none;
|
|
733
|
+
/* On every tab, transparent until one is open, so the open one takes no extra height and the row of them
|
|
734
|
+
does not move as the tool changes. */
|
|
735
|
+
border-bottom: 2px solid transparent;
|
|
736
|
+
background: none;
|
|
737
|
+
color: var(--muted);
|
|
738
|
+
font: inherit;
|
|
739
|
+
font-size: 13px;
|
|
740
|
+
cursor: pointer;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
.tool-tab:hover {
|
|
744
|
+
color: var(--text);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.tool-tab.on {
|
|
748
|
+
border-bottom-color: var(--ws);
|
|
749
|
+
color: var(--text);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/* What is waiting in a tool nobody is looking at. The same green as everything else that means "something
|
|
753
|
+
happened here". */
|
|
754
|
+
.tool-mark {
|
|
755
|
+
padding: 0 5px;
|
|
756
|
+
border-radius: 8px;
|
|
757
|
+
background: var(--accent);
|
|
758
|
+
color: #04140b;
|
|
759
|
+
font-size: 9.5px;
|
|
760
|
+
font-weight: 700;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/* A tool that counts nothing says only that something arrived, so its mark carries no number and is drawn
|
|
764
|
+
as the dot it means. */
|
|
765
|
+
.tool-mark.dot {
|
|
766
|
+
width: 6px;
|
|
767
|
+
height: 6px;
|
|
768
|
+
padding: 0;
|
|
769
|
+
border-radius: 50%;
|
|
770
|
+
align-self: center;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
#pane-ctl {
|
|
774
|
+
display: flex;
|
|
775
|
+
flex: none;
|
|
776
|
+
margin-left: auto;
|
|
777
|
+
gap: 2px;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/* The three widths, drawn as one row: the whole window, half of it, and away. */
|
|
781
|
+
#pane-ctl .pane-nav {
|
|
782
|
+
display: flex;
|
|
783
|
+
align-items: center;
|
|
784
|
+
justify-content: center;
|
|
785
|
+
width: 28px;
|
|
786
|
+
height: 28px;
|
|
787
|
+
padding: 0;
|
|
788
|
+
border-radius: 6px;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/* The pane is already in the state the button names, so the button says so - and for the far end it is also
|
|
792
|
+
the way back from it. */
|
|
793
|
+
#pane-ctl .pane-nav.on {
|
|
794
|
+
background: #10151c;
|
|
795
|
+
color: var(--accent);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/* One tool's panel. Only the open one is on the screen, and each fills whatever the pane's bar leaves. */
|
|
799
|
+
.tool-panel {
|
|
800
|
+
display: flex;
|
|
801
|
+
flex: 1;
|
|
802
|
+
flex-direction: column;
|
|
803
|
+
min-width: 0;
|
|
804
|
+
min-height: 0;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
.tool-panel[hidden] {
|
|
808
|
+
display: none;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/* The pagination bar: this session's pages as chips, the arrows for a bar too narrow to hold them, and where
|
|
812
|
+
in the history the open page sits. Drawn by the interface, outside the page's frame, so it always says the
|
|
813
|
+
truth about which page is open. */
|
|
814
|
+
#pagebar {
|
|
815
|
+
display: flex;
|
|
816
|
+
flex: none;
|
|
817
|
+
align-items: center;
|
|
818
|
+
gap: 6px;
|
|
819
|
+
padding: 7px 10px;
|
|
820
|
+
background: var(--panel);
|
|
821
|
+
border-bottom: 1px solid var(--border);
|
|
822
|
+
overflow: hidden;
|
|
823
|
+
}
|
|
824
|
+
|
|
698
825
|
#chips {
|
|
699
826
|
display: flex;
|
|
700
827
|
gap: 6px;
|
|
@@ -810,15 +937,6 @@ body.dragging {
|
|
|
810
937
|
letter-spacing: 0.02em;
|
|
811
938
|
}
|
|
812
939
|
|
|
813
|
-
/* Out of the way, at the end of the bar: the pane is put away far more often than the chips are paged. */
|
|
814
|
-
#pane-collapse {
|
|
815
|
-
display: flex;
|
|
816
|
-
align-items: center;
|
|
817
|
-
justify-content: center;
|
|
818
|
-
margin-left: 4px;
|
|
819
|
-
padding: 2px 5px;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
940
|
#page-doc {
|
|
823
941
|
flex: 1;
|
|
824
942
|
min-width: 0;
|
|
@@ -841,10 +959,21 @@ body.dragging {
|
|
|
841
959
|
zoom: var(--page-zoom, 1);
|
|
842
960
|
}
|
|
843
961
|
|
|
962
|
+
/* A tool's own client, in a frame of its own. It fills the panel and this side styles nothing inside it: the
|
|
963
|
+
tool ships its own document, its own stylesheet and its own theme, and the shell cannot reach in anyway. */
|
|
964
|
+
.tool-frame {
|
|
965
|
+
display: block;
|
|
966
|
+
width: 100%;
|
|
967
|
+
height: 100%;
|
|
968
|
+
border: none;
|
|
969
|
+
background: var(--bg);
|
|
970
|
+
}
|
|
971
|
+
|
|
844
972
|
/* A page is a document with an event loop of its own, and a pointer that crosses into it during a drag is a
|
|
845
973
|
pointer the grip has to keep. Capture does that in every engine that has it; taking the frame out of the
|
|
846
974
|
hit test for the length of the drag is what makes it true everywhere. */
|
|
847
|
-
body.dragging .page-frame
|
|
975
|
+
body.dragging .page-frame,
|
|
976
|
+
body.dragging .tool-frame {
|
|
848
977
|
pointer-events: none;
|
|
849
978
|
}
|
|
850
979
|
|
|
@@ -893,8 +1022,8 @@ body.dragging .page-frame {
|
|
|
893
1022
|
width: 30px;
|
|
894
1023
|
}
|
|
895
1024
|
|
|
896
|
-
#pane.collapsed #
|
|
897
|
-
#pane.collapsed
|
|
1025
|
+
#pane.collapsed #panebar,
|
|
1026
|
+
#pane.collapsed .tool-panel {
|
|
898
1027
|
display: none;
|
|
899
1028
|
}
|
|
900
1029
|
|
|
@@ -939,6 +1068,14 @@ body.dragging .page-frame {
|
|
|
939
1068
|
writing-mode: horizontal-tb;
|
|
940
1069
|
}
|
|
941
1070
|
|
|
1071
|
+
#spine-badge.dot {
|
|
1072
|
+
display: inline-block;
|
|
1073
|
+
width: 6px;
|
|
1074
|
+
height: 6px;
|
|
1075
|
+
padding: 0;
|
|
1076
|
+
border-radius: 50%;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
942
1079
|
#spine-badge[hidden] {
|
|
943
1080
|
display: none;
|
|
944
1081
|
}
|
|
@@ -957,13 +1094,17 @@ body.dragging .page-frame {
|
|
|
957
1094
|
|
|
958
1095
|
/* ---- Overlay cards (take over / end session / limit reached) ---- */
|
|
959
1096
|
|
|
1097
|
+
/* Fixed to the viewport and above every pop, so the card is in the middle of the screen whatever the width of
|
|
1098
|
+
the terminal column beside the pane. */
|
|
960
1099
|
#overlay {
|
|
961
1100
|
display: none;
|
|
962
|
-
position:
|
|
1101
|
+
position: fixed;
|
|
963
1102
|
inset: 0;
|
|
1103
|
+
z-index: 70;
|
|
964
1104
|
background: rgba(13, 17, 23, 0.82);
|
|
965
1105
|
align-items: center;
|
|
966
1106
|
justify-content: center;
|
|
1107
|
+
padding: 16px;
|
|
967
1108
|
}
|
|
968
1109
|
|
|
969
1110
|
#overlay.show {
|
|
@@ -971,7 +1112,9 @@ body.dragging .page-frame {
|
|
|
971
1112
|
}
|
|
972
1113
|
|
|
973
1114
|
.card {
|
|
1115
|
+
width: 100%;
|
|
974
1116
|
max-width: 460px;
|
|
1117
|
+
box-sizing: border-box;
|
|
975
1118
|
padding: 18px 20px;
|
|
976
1119
|
background: var(--panel);
|
|
977
1120
|
border: 1px solid var(--border);
|
|
@@ -1087,9 +1230,102 @@ body.dragging .page-frame {
|
|
|
1087
1230
|
}
|
|
1088
1231
|
}
|
|
1089
1232
|
|
|
1233
|
+
/* ---- The workspace colour ---- */
|
|
1234
|
+
|
|
1235
|
+
/* The one control in the bar about what this window *is* rather than what it does, so it sits beside the name
|
|
1236
|
+
it belongs with. It carries no colour of its own, and is drawn exactly as the bell and the power button
|
|
1237
|
+
are: the bar already says which colour is in force, on the edge of the active tab, and a filled swatch in
|
|
1238
|
+
a row of glyphs reads as something that wandered in rather than as one of the row. */
|
|
1239
|
+
#wscolorbtn {
|
|
1240
|
+
display: flex;
|
|
1241
|
+
align-items: center;
|
|
1242
|
+
justify-content: center;
|
|
1243
|
+
padding: 4px;
|
|
1244
|
+
background: transparent;
|
|
1245
|
+
color: var(--muted);
|
|
1246
|
+
border: 1px solid transparent;
|
|
1247
|
+
border-radius: 7px;
|
|
1248
|
+
cursor: pointer;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
#wscolorbtn:hover:not(:disabled),
|
|
1252
|
+
#wscolorbtn.open {
|
|
1253
|
+
color: var(--text);
|
|
1254
|
+
border-color: var(--border);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
/* Nothing to open while this window is not talking to the server: a pick it could not send would be undone by
|
|
1258
|
+
the next frame, which is worse than not offering it. */
|
|
1259
|
+
#wscolorbtn:disabled {
|
|
1260
|
+
opacity: 0.45;
|
|
1261
|
+
cursor: default;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
/* Anchored under the button and hung off the body, like the new-session panel: the bar is emptied on every
|
|
1265
|
+
frame, and picking a colour is itself a frame, so a panel inside the bar would close as it was used. */
|
|
1266
|
+
#wscolorpop {
|
|
1267
|
+
position: fixed;
|
|
1268
|
+
z-index: 60;
|
|
1269
|
+
display: flex;
|
|
1270
|
+
flex-direction: column;
|
|
1271
|
+
width: 268px;
|
|
1272
|
+
padding: 12px;
|
|
1273
|
+
background: var(--panel);
|
|
1274
|
+
border: 1px solid var(--border);
|
|
1275
|
+
border-radius: 10px;
|
|
1276
|
+
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.5);
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
.wsgrid {
|
|
1280
|
+
display: grid;
|
|
1281
|
+
grid-template-columns: repeat(6, 1fr);
|
|
1282
|
+
gap: 8px;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
.wscell {
|
|
1286
|
+
display: flex;
|
|
1287
|
+
align-items: center;
|
|
1288
|
+
justify-content: center;
|
|
1289
|
+
aspect-ratio: 1;
|
|
1290
|
+
padding: 0;
|
|
1291
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
1292
|
+
border-radius: 7px;
|
|
1293
|
+
cursor: pointer;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
/* Two rings rather than a thicker border, so the mark reads on every one of the eleven and the cell does not
|
|
1297
|
+
move when it lands. The mark says what is *stored*, so it sits on the automatic cell when nothing is. */
|
|
1298
|
+
.wscell.chosen {
|
|
1299
|
+
box-shadow:
|
|
1300
|
+
0 0 0 2px var(--panel),
|
|
1301
|
+
0 0 0 3.5px var(--text);
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
/* Automatic takes the last cell: it is one of the choices rather than a button underneath them. */
|
|
1305
|
+
.wscell.auto {
|
|
1306
|
+
background: repeating-linear-gradient(135deg, var(--border) 0 4px, #21262d 4px 8px);
|
|
1307
|
+
color: var(--muted);
|
|
1308
|
+
font-size: 15px;
|
|
1309
|
+
line-height: 1;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
.wscolorfoot {
|
|
1313
|
+
margin: 11px 0 0;
|
|
1314
|
+
padding-top: 10px;
|
|
1315
|
+
color: var(--muted);
|
|
1316
|
+
border-top: 1px solid var(--border);
|
|
1317
|
+
font-size: 11.5px;
|
|
1318
|
+
line-height: 1.45;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1090
1321
|
/* The moment the socket drops, before any curtain: a control whose answer goes nowhere must stop taking
|
|
1091
|
-
clicks. The composer disables itself, so this is about the bar - its tabs, its X, its + New session.
|
|
1092
|
-
body
|
|
1322
|
+
clicks. The composer disables itself, so this is about the bar - its tabs, its X, its + New session.
|
|
1323
|
+
The two anchored panels are named as well: they hang off the body rather than the bar, so the bar's own
|
|
1324
|
+
selector does not cover them. connection.js closes them outright when the socket goes, and this is the second
|
|
1325
|
+
line - a rule that holds whatever order things happen in. */
|
|
1326
|
+
body.offline #tabbar,
|
|
1327
|
+
body.offline #newpop,
|
|
1328
|
+
body.offline #wscolorpop {
|
|
1093
1329
|
pointer-events: none;
|
|
1094
1330
|
}
|
|
1095
1331
|
|