Skip to content

Commit dcaccb0

Browse files
playground: LeetCode-style layout, collapsible sidebar, thin scrollbars
Rework the playground workspace into a LeetCode-style split: the README is now a full-height pane on the left, with the editor stacked over the terminal on the right. Vertical drag handle resizes README vs editor column; horizontal handle resizes editor vs terminal. - README pane collapses to a slim rail; project sidebar collapses to a rail too (state persisted to localStorage). - Thin, subtle scrollbars site-wide (scrollbar-width + ::-webkit-scrollbar). - Fix double border on the README body — it shared the .s-readme class, whose card chrome (border/shadow/radius) drew a second box inside the pane. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 6f8e623 commit dcaccb0

3 files changed

Lines changed: 279 additions & 191 deletions

File tree

web/src/app/globals.css

Lines changed: 116 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@
3232

3333
* { box-sizing: border-box; }
3434
html, body { margin: 0; padding: 0; }
35+
36+
/* ---- Thin, subtle scrollbars site-wide ---- */
37+
* {
38+
scrollbar-width: thin;
39+
scrollbar-color: rgba(29, 24, 48, 0.3) transparent;
40+
}
41+
::-webkit-scrollbar { width: 9px; height: 9px; }
42+
::-webkit-scrollbar-track { background: transparent; }
43+
::-webkit-scrollbar-thumb {
44+
background: rgba(29, 24, 48, 0.26);
45+
border-radius: 99px;
46+
border: 2.5px solid transparent;
47+
background-clip: padding-box;
48+
}
49+
::-webkit-scrollbar-thumb:hover {
50+
background: rgba(29, 24, 48, 0.46);
51+
background-clip: padding-box;
52+
}
53+
::-webkit-scrollbar-corner { background: transparent; }
3554
body {
3655
background: var(--s-bg);
3756
background-image:
@@ -674,9 +693,41 @@ a.s-contrib { display: block; text-decoration: none; color: inherit; }
674693
display: flex; flex-direction: column;
675694
background: rgba(255, 255, 255, 0.45);
676695
}
677-
.pg-side-head { padding: 18px 18px 12px; }
696+
.pg-side-head {
697+
padding: 18px 18px 12px;
698+
display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;
699+
}
678700
.pg-side-title { font-family: var(--pg-display); font-size: 22px; font-weight: 900; letter-spacing: -0.02em; line-height: 1; }
679701
.pg-side-sub { font-size: 12px; color: var(--pg-muted); margin-top: 4px; }
702+
.pg-side-collapse {
703+
flex-shrink: 0; width: 30px; height: 30px; border-radius: 9px;
704+
display: grid; place-items: center;
705+
background: var(--pg-paper); color: var(--pg-ink);
706+
border: var(--pg-border-thin); box-shadow: 2px 2px 0 var(--pg-ink);
707+
transition: transform .1s, box-shadow .1s;
708+
}
709+
.pg-side-collapse:hover { transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--pg-ink); }
710+
.pg-side-collapse:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--pg-ink); }
711+
712+
/* collapsed sidebar → slim rail */
713+
.pg-side.railed {
714+
width: 50px; flex-shrink: 0;
715+
align-items: center; gap: 16px; padding-top: 16px;
716+
}
717+
.pg-side-expand {
718+
flex-shrink: 0; width: 34px; height: 34px; border-radius: 10px;
719+
display: grid; place-items: center;
720+
background: var(--pg-accent); color: var(--pg-ink);
721+
border: var(--pg-border-thin); box-shadow: 2px 2px 0 var(--pg-ink);
722+
transition: transform .1s, box-shadow .1s;
723+
}
724+
.pg-side-expand:hover { transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--pg-ink); }
725+
.pg-side-expand:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--pg-ink); }
726+
.pg-side-rail-label {
727+
writing-mode: vertical-rl;
728+
font-family: var(--pg-mono); font-size: 11px; font-weight: 800;
729+
letter-spacing: 0.16em; text-transform: uppercase; color: var(--pg-muted);
730+
}
680731
.pg-side-search {
681732
margin: 0 14px 12px;
682733
padding: 10px 14px; border-radius: var(--pg-radius-pill);
@@ -795,9 +846,16 @@ a.s-contrib { display: block; text-decoration: none; color: inherit; }
795846
.pg-btn.stop { background: #ffb4a8; }
796847
.pg-btn .ic { font-size: 13px; }
797848

798-
/* editor + console split */
849+
/* workspace split — README pane | editor-over-console column */
799850
.pg-split { flex: 1; display: flex; gap: 0; min-height: 0; }
800851
.pg-split.row { flex-direction: row; }
852+
853+
/* right column: editor stacked over console */
854+
.pg-right-col {
855+
flex: 60 1 0; min-width: 0; min-height: 0;
856+
display: flex; flex-direction: column;
857+
}
858+
801859
.pg-window {
802860
display: flex; flex-direction: column; min-height: 0;
803861
background: var(--pg-dark);
@@ -830,14 +888,14 @@ a.s-contrib { display: block; text-decoration: none; color: inherit; }
830888
.pg-winbar .iconbtn:hover { background: rgba(29,24,48,0.1); border-color: var(--pg-ink); }
831889

832890
/* editor pane */
833-
.pg-editor { flex: var(--pg-ed-grow, 1.55) 1 0; min-width: 0; }
891+
.pg-editor { flex: var(--pg-ed-grow, 58) 1 0; min-width: 0; min-height: 96px; }
834892
.pg-editor-body { flex: 1; min-height: 0; min-width: 0; display: flex; }
835893
.pg-editor-body > * { flex: 1; min-width: 0; height: 100%; }
836894
.pg-editor-body .cm-editor { height: 100%; }
837895
.pg-editor-body .cm-scroller { font-size: 13.5px; padding: 6px 0; }
838896

839897
/* console pane */
840-
.pg-console { flex: var(--pg-co-grow, 1) 1 0; min-width: 280px; }
898+
.pg-console { flex: var(--pg-co-grow, 42) 1 0; min-width: 0; min-height: 96px; }
841899
.pg-console-body {
842900
flex: 1; min-height: 0; display: flex;
843901
background: var(--pg-dark);
@@ -851,15 +909,24 @@ a.s-contrib { display: block; text-decoration: none; color: inherit; }
851909
/* responsive */
852910
@media (max-width: 1200px) {
853911
.pg-split.row { flex-direction: column; gap: 14px; }
854-
.pg-split.row .pg-editor { flex: 1.4 1 0; }
855-
.pg-split.row .pg-console { flex: 1 1 0; min-height: 200px; min-width: 0; }
912+
.pg-readme-pane { min-width: 0; min-height: 200px; max-height: 40vh; }
913+
.pg-readme-rail {
914+
width: 100%; flex-direction: row; align-self: auto;
915+
margin-right: 0; padding: 10px 14px;
916+
}
917+
.pg-readme-rail-label { writing-mode: horizontal-tb; }
856918
.pg-resize-split { display: none; }
857919
}
858920
@media (max-width: 1100px) { .pg-side { width: 240px; } }
859921
@media (max-width: 880px) {
860922
.pg-app { height: auto; min-height: 100vh; }
861923
.pg-main { flex-direction: column; }
862924
.pg-side { width: 100%; }
925+
.pg-side.railed {
926+
width: 100%; flex-direction: row; align-items: center;
927+
gap: 12px; padding: 12px 16px;
928+
}
929+
.pg-side.railed .pg-side-rail-label { writing-mode: horizontal-tb; }
863930
.pg-side-resize { display: none; }
864931
.pg-nav-mid { display: none; }
865932
.pg-split.row { min-height: 70vh; }
@@ -991,59 +1058,44 @@ a.s-contrib { display: block; text-decoration: none; color: inherit; }
9911058
text-transform: uppercase; color: rgba(29, 24, 48, 0.55);
9921059
}
9931060

994-
/* ---- Playground: collapsible README strip (above the editor) ---- */
995-
.pg-readme-bar {
996-
flex-shrink: 0;
997-
border: var(--pg-border); border-radius: var(--pg-radius);
998-
background: var(--pg-paper); box-shadow: var(--pg-shadow);
999-
overflow: hidden;
1000-
}
1001-
.pg-readme-toggle {
1002-
display: flex; align-items: center; gap: 8px; width: 100%;
1003-
padding: 10px 18px; cursor: pointer;
1004-
background: var(--pg-paper-warm); border: 0;
1005-
font-family: var(--s-display, var(--pg-mono));
1006-
font-size: 13px; font-weight: 800; color: var(--pg-ink);
1007-
text-align: left;
1008-
}
1009-
.pg-readme-bar.open .pg-readme-toggle {
1010-
border-bottom: var(--pg-border-thin);
1011-
}
1012-
.pg-readme-emoji { color: var(--pg-accent); }
1013-
.pg-readme-label { letter-spacing: -0.01em; }
1014-
.pg-readme-hint {
1015-
font-family: var(--pg-mono); font-size: 11px; font-weight: 600;
1016-
color: var(--pg-muted);
1061+
/* ---- Playground: README pane (left side of the workspace) ---- */
1062+
.pg-readme-pane {
1063+
flex: 38 1 0; min-width: 240px;
1064+
background: var(--pg-paper);
10171065
}
1018-
/* The clearly-visible collapse / expand button at the end of the header */
1019-
.pg-readme-btn {
1020-
margin-left: auto;
1021-
display: inline-flex; align-items: center; gap: 5px;
1022-
padding: 5px 11px 5px 8px; border-radius: var(--pg-radius-pill);
1023-
border: var(--pg-border-thin); background: var(--pg-paper);
1024-
box-shadow: 2px 2px 0 var(--pg-ink);
1025-
font-family: var(--pg-mono); font-size: 11px; font-weight: 800;
1026-
letter-spacing: 0.02em; text-transform: uppercase;
1027-
color: var(--pg-ink);
1066+
.pg-readme-pane .pg-winbar { background: var(--pg-paper-yellow); }
1067+
/* shares the .s-readme class for typography — strip its card chrome so it
1068+
doesn't draw a second box inside the pane window */
1069+
.pg-readme-body {
1070+
flex: 1; min-height: 0; overflow: auto;
1071+
padding: 22px 26px; background: var(--pg-paper);
1072+
border: 0; border-radius: 0; box-shadow: none; margin: 0;
1073+
}
1074+
.pg-readme-body > :first-child { margin-top: 0; }
1075+
.pg-readme-body h1 { font-size: 22px; }
1076+
.pg-readme-body h2 { font-size: 18px; }
1077+
.pg-readme-body h3 { font-size: 15px; }
1078+
1079+
/* collapsed README → slim clickable rail */
1080+
.pg-readme-rail {
1081+
flex-shrink: 0; width: 46px; align-self: stretch;
1082+
margin-right: 14px;
1083+
display: flex; flex-direction: column; align-items: center; gap: 14px;
1084+
padding: 16px 0; cursor: pointer;
1085+
background: var(--pg-paper); color: var(--pg-ink);
1086+
border: var(--pg-border); border-radius: var(--pg-radius);
1087+
box-shadow: var(--pg-shadow);
10281088
transition: transform .1s, box-shadow .1s;
10291089
}
1030-
.pg-readme-toggle:hover .pg-readme-btn {
1031-
transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--pg-ink);
1032-
}
1033-
.pg-readme-toggle:active .pg-readme-btn {
1034-
transform: translate(2px, 2px); box-shadow: 0 0 0 var(--pg-ink);
1090+
.pg-readme-rail:hover {
1091+
transform: translate(-1px, -1px); box-shadow: 6px 6px 0 var(--pg-ink);
10351092
}
1036-
.pg-readme-bar.open .pg-readme-btn { background: var(--pg-accent); }
1037-
.pg-readme-content {
1038-
margin: 0; border: 0; border-radius: 0; box-shadow: none;
1039-
background: var(--pg-paper);
1040-
max-height: 23vh; overflow: auto;
1041-
padding: 18px 26px;
1093+
.pg-readme-rail > svg { color: var(--pg-accent); flex-shrink: 0; }
1094+
.pg-readme-rail-label {
1095+
writing-mode: vertical-rl;
1096+
font-family: var(--pg-mono); font-size: 11px; font-weight: 800;
1097+
letter-spacing: 0.16em; text-transform: uppercase;
10421098
}
1043-
.pg-readme-content > :first-child { margin-top: 0; }
1044-
.pg-readme-content h1 { font-size: 22px; }
1045-
.pg-readme-content h2 { font-size: 18px; }
1046-
.pg-readme-content h3 { font-size: 15px; }
10471099

10481100
/* ---- Playground: draggable resize handles ---- */
10491101
.pg-resize {
@@ -1066,7 +1118,7 @@ a.s-contrib { display: block; text-decoration: none; color: inherit; }
10661118
opacity: 1; background: var(--pg-accent);
10671119
}
10681120

1069-
/* between editor and console */
1121+
/* between README pane and the editor column */
10701122
.pg-resize-split {
10711123
width: 16px; align-self: stretch;
10721124
display: flex; align-items: center; justify-content: center;
@@ -1075,6 +1127,15 @@ a.s-contrib { display: block; text-decoration: none; color: inherit; }
10751127
.pg-resize-split:hover .pg-resize-grip,
10761128
.pg-resize-split.dragging .pg-resize-grip { height: 60px; }
10771129

1130+
/* between editor and console (stacked) */
1131+
.pg-resize-vert {
1132+
height: 16px; width: 100%;
1133+
display: flex; align-items: center; justify-content: center;
1134+
}
1135+
.pg-resize-vert .pg-resize-grip { width: 40px; height: 4px; }
1136+
.pg-resize-vert:hover .pg-resize-grip,
1137+
.pg-resize-vert.dragging .pg-resize-grip { width: 60px; }
1138+
10781139
/* sidebar right edge */
10791140
.pg-side-resize {
10801141
position: absolute; top: 0; right: -7px; width: 14px; height: 100%;
@@ -1084,13 +1145,3 @@ a.s-contrib { display: block; text-decoration: none; color: inherit; }
10841145
.pg-side-resize:hover .pg-resize-grip,
10851146
.pg-side-resize.dragging .pg-resize-grip { height: 72px; }
10861147

1087-
/* under the README panel */
1088-
.pg-resize-readme {
1089-
height: 13px; width: 100%;
1090-
display: flex; align-items: center; justify-content: center;
1091-
background: var(--pg-paper-warm);
1092-
border-top: var(--pg-border-thin);
1093-
}
1094-
.pg-resize-readme .pg-resize-grip { width: 46px; height: 4px; opacity: 0.32; }
1095-
.pg-resize-readme:hover .pg-resize-grip,
1096-
.pg-resize-readme.dragging .pg-resize-grip { width: 70px; }

0 commit comments

Comments
 (0)