@nynb/sandpaper 0.1.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.
@@ -0,0 +1,220 @@
1
+ /* toolbar.css — Sandpaper conversation surface. Warm palette to match the documents. */
2
+
3
+ /* Self-sufficient token copy = the FALLBACK skin. Injected into arbitrary host pages, so the
4
+ toolbar must stand alone: these mirror theme.css and are scoped to #sp-panel. On a themed
5
+ Sandpaper surface, toolbar.js reads the host's theme.css :root tokens at runtime and overrides
6
+ these (see adoptHostSkin) — so a /sandpaper:theme re-skin reaches the toolbar with no hand-sync.
7
+ These values only show through on a host page that defines no theme. */
8
+ #sp-panel{
9
+ --sp-paper:#F4F0E6; --sp-paper-2:#EFEADD; --sp-ink:#17150F;
10
+ --sp-clay:#C75B39; --sp-pine:#3F5247; --sp-moss:#4E7C59;
11
+ --sp-rust:#B23A2E; --sp-mute:#8A8578;
12
+ --sp-text-quote:#3a372e; --sp-plate:#1c1a13;
13
+ }
14
+
15
+ #sp-panel{
16
+ position:fixed; right:20px; bottom:20px; z-index:2147483600;
17
+ width:380px; max-width:calc(100vw - 32px); max-height:78vh;
18
+ display:flex; flex-direction:column;
19
+ font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
20
+ background:var(--sp-paper); color:var(--sp-ink);
21
+ border:1px solid rgba(23,21,15,.32); border-radius:14px;
22
+ box-shadow:0 16px 44px rgba(23,21,15,.28); overflow:hidden;
23
+ }
24
+ #sp-panel.sp-collapsed{ max-height:none; }
25
+
26
+ /* dark "console" head — carries the brain's drafting-plate grid so it reads as the same manual */
27
+ #sp-head{ display:flex; align-items:center; gap:9px; padding:12px 15px;
28
+ font-family:'IBM Plex Mono',ui-monospace,Menlo,monospace; background:var(--sp-ink); color:var(--sp-paper);
29
+ background-image:linear-gradient(rgba(244,240,230,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(244,240,230,.05) 1px,transparent 1px);
30
+ background-size:18px 18px; }
31
+ /* who is working + its state — readable light text on the dark head; the dot carries the state colour */
32
+ #sp-chip{ display:inline-flex; align-items:center; gap:8px; min-width:0; flex:0 1 auto; overflow:hidden;
33
+ font-size:12px; font-weight:500; }
34
+ #sp-who{ flex:none; color:var(--sp-paper); font-weight:600; letter-spacing:.02em; }
35
+ #sp-label{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--sp-paper-2); letter-spacing:.02em; }
36
+ #sp-label::before{ content:"·"; color:var(--sp-mute); margin-right:7px; }
37
+ #sp-led{ width:8px; height:8px; border-radius:50%; background:var(--sp-mute); flex:none; transition:background .2s; box-shadow:0 0 0 3px rgba(244,240,230,.08); }
38
+ #sp-chip.sp-busy #sp-led{ animation:sp-pulse 1.2s ease-in-out infinite; }
39
+ @keyframes sp-pulse{ 0%,100%{ box-shadow:0 0 0 0 currentColor; opacity:1; } 50%{ box-shadow:0 0 0 5px transparent; opacity:.5; } }
40
+ #sp-cost{ margin-left:auto; font-size:11px; color:var(--sp-mute); }
41
+ #sp-toggle{ border:0; background:transparent; color:var(--sp-paper-2); cursor:pointer; font-size:13px; padding:2px 4px; line-height:1; }
42
+ #sp-min{ border:0; background:transparent; color:var(--sp-paper-2); cursor:pointer; font-size:17px; padding:0 6px 3px; line-height:1; }
43
+ #sp-min:hover, #sp-toggle:hover{ color:var(--sp-clay); }
44
+ /* minimized → a small status pill; click it to restore */
45
+ #sp-panel.sp-min{ width:auto; max-width:300px; cursor:pointer; }
46
+ #sp-panel.sp-min #sp-thread, #sp-panel.sp-min #sp-target, #sp-panel.sp-min #sp-form,
47
+ #sp-panel.sp-min #sp-cost, #sp-panel.sp-min #sp-undo, #sp-panel.sp-min #sp-min, #sp-panel.sp-min #sp-toggle{ display:none; }
48
+ #sp-panel.sp-min #sp-head{ border-bottom:0; padding:9px 15px; }
49
+ #sp-panel.sp-min #sp-chip::after{ content:"▸"; color:var(--sp-paper-2); margin-left:9px; font-size:11px; opacity:.7; }
50
+
51
+ #sp-thread{ overflow-y:auto; padding:12px; display:flex; flex-direction:column; gap:14px; min-height:0; max-height:58vh; }
52
+ .sp-turn{ display:flex; flex-direction:column; gap:6px; }
53
+ .sp-user{ align-self:flex-end; max-width:90%; display:flex; flex-direction:column; align-items:flex-end; }
54
+ .sp-bubble{ background:var(--sp-ink); color:var(--sp-paper); padding:8px 11px; border-radius:13px 13px 4px 13px; font-size:13px; line-height:1.45; white-space:pre-wrap; word-break:break-word; }
55
+ .sp-attach{ font-family:'IBM Plex Mono',monospace; font-size:10.5px; color:var(--sp-pine); margin-top:3px; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
56
+ .sp-asst{ align-self:flex-start; max-width:96%; }
57
+ .sp-prose{ font-size:13.5px; line-height:1.55; color:var(--sp-ink); word-break:break-word; }
58
+ .sp-prose > :first-child{ margin-top:0; }
59
+ .sp-md-p{ margin:0 0 8px; }
60
+ .sp-md-h{ font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:13px; font-weight:600; margin:12px 0 5px; }
61
+ .sp-md-list{ margin:0 0 8px; padding-left:20px; }
62
+ .sp-md-list li{ margin:2px 0; }
63
+ .sp-md-quote{ margin:0 0 8px; padding:4px 10px; border-left:2px solid var(--sp-clay); color:var(--sp-text-quote); background:rgba(199,91,57,.05); }
64
+ .sp-md-hr{ border:0; border-top:1px solid rgba(23,21,15,.15); margin:10px 0; }
65
+ .sp-prose a{ color:var(--sp-clay); }
66
+ .sp-md-code{ font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:.86em; background:rgba(23,21,15,.07); padding:1px 5px; border-radius:3px; word-break:break-all; }
67
+ .sp-md-pre{ position:relative; margin:0 0 9px; }
68
+ .sp-md-pre pre{ margin:0; background:var(--sp-plate); color:var(--sp-paper-2); border-radius:7px; padding:11px 12px; overflow-x:auto; }
69
+ .sp-md-pre code{ font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:12px; line-height:1.5; white-space:pre; }
70
+ .sp-md-copy{ position:absolute; top:6px; right:6px; font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:10px; border:1px solid rgba(244,240,230,.25); background:rgba(244,240,230,.1); color:var(--sp-paper-2); border-radius:5px; padding:2px 7px; cursor:pointer; }
71
+ .sp-md-copy:hover{ background:rgba(244,240,230,.2); }
72
+ .sp-md-table{ width:100%; border-collapse:collapse; margin:0 0 9px; font-size:12px; display:block; overflow-x:auto; }
73
+ .sp-md-table th, .sp-md-table td{ border:1px solid rgba(23,21,15,.14); padding:5px 8px; text-align:left; vertical-align:top; }
74
+ .sp-md-table th{ background:var(--sp-paper-2); font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:10.5px; letter-spacing:.04em; text-transform:uppercase; color:var(--sp-pine); }
75
+
76
+ .sp-think-toggle{ font-family:'IBM Plex Mono',monospace; font-size:10.5px; color:var(--sp-mute); cursor:pointer; user-select:none; }
77
+ .sp-think-body{ display:none; font-size:11.5px; line-height:1.45; color:var(--sp-mute); white-space:pre-wrap; border-left:2px solid rgba(23,21,15,.12); padding-left:8px; margin:4px 0; }
78
+
79
+ .sp-card{ margin-top:8px; border:1px solid rgba(23,21,15,.16); border-radius:9px; overflow:hidden; }
80
+ .sp-card-head{ display:flex; align-items:center; justify-content:space-between; padding:7px 10px; background:var(--sp-paper-2); cursor:pointer; font-size:12px; font-weight:600; color:var(--sp-clay); }
81
+ .sp-card-chev{ color:var(--sp-mute); }
82
+ .sp-card-body{ padding:8px 10px; font-family:'IBM Plex Mono',monospace; font-size:11px; max-height:240px; overflow:auto; background:#fff; }
83
+ .sp-hunkfile{ color:var(--sp-mute); margin-bottom:5px; }
84
+ .sp-add{ color:#2f6b40; background:rgba(78,124,89,.10); white-space:pre-wrap; word-break:break-word; padding:1px 5px; border-radius:3px; margin:1px 0; }
85
+ .sp-del{ color:#9a3128; background:rgba(178,58,46,.10); white-space:pre-wrap; word-break:break-word; padding:1px 5px; border-radius:3px; margin:1px 0; }
86
+
87
+ .sp-turnmeta{ display:flex; align-items:center; gap:2px; margin-top:6px; font-family:'IBM Plex Mono',monospace; font-size:11px; }
88
+ .sp-tag{ font-weight:600; }
89
+ .sp-talked .sp-tag{ color:var(--sp-moss); }
90
+ .sp-edited .sp-tag{ color:var(--sp-clay); }
91
+ .sp-tagcost{ color:var(--sp-mute); }
92
+ .sp-undo{ margin-left:8px; font-family:'IBM Plex Mono',monospace; font-size:10.5px; border:1px solid rgba(23,21,15,.18); background:#fff; color:var(--sp-ink); border-radius:5px; padding:2px 9px; cursor:pointer; }
93
+ .sp-undo:hover{ border-color:var(--sp-clay); color:var(--sp-clay); }
94
+ .sp-undo:disabled{ opacity:.6; cursor:default; }
95
+ .sp-err{ color:var(--sp-rust); font-size:12px; margin-top:4px; }
96
+
97
+ #sp-target{ margin:0 12px 8px; font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--sp-pine); background:var(--sp-paper-2);
98
+ border:1px solid rgba(23,21,15,.12); border-radius:6px; padding:5px 8px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
99
+
100
+ #sp-form{ display:flex; flex-direction:column; gap:9px; padding:12px; }
101
+ /* the composer's top rule is a divider FROM the conversation — show it only when there is one */
102
+ #sp-panel.sp-has-thread:not(.sp-collapsed) #sp-form{ border-top:1px solid rgba(23,21,15,.1); }
103
+ #sp-actions{ display:flex; gap:7px; align-items:center; }
104
+ .sp-spring{ flex:1; }
105
+ /* one monochrome icon family (ink glyph on raised paper); the active toggle fills ink, like SAND */
106
+ #sp-pick, #sp-edit{ flex:none; width:36px; height:36px; border:1px solid rgba(23,21,15,.2); border-radius:9px;
107
+ background:var(--sp-paper-2); color:var(--sp-ink); font-size:15px; cursor:pointer; line-height:1;
108
+ display:inline-flex; align-items:center; justify-content:center; transition:background .15s,border-color .15s,color .15s; }
109
+ #sp-pick:hover, #sp-edit:hover{ border-color:var(--sp-ink); }
110
+ #sp-pick.sp-on, #sp-edit.sp-on{ background:var(--sp-ink); color:var(--sp-paper); border-color:var(--sp-ink); }
111
+ #sp-pick svg, #sp-edit svg{ display:block; } /* kill the inline baseline gap so the glyph is dead-centre */
112
+ #sp-sling{ flex:none; height:36px; padding:0 12px; border:1px solid rgba(23,21,15,.2); border-radius:9px;
113
+ background:var(--sp-paper-2); color:var(--sp-ink); font-family:'IBM Plex Mono',ui-monospace,monospace;
114
+ font-size:13px; font-weight:600; letter-spacing:-1px; cursor:pointer; line-height:1; transition:background .15s,border-color .15s; }
115
+ #sp-sling:hover{ border-color:var(--sp-ink); }
116
+ #sp-input{ width:100%; height:42px; border:1px solid rgba(23,21,15,.22); border-radius:10px; background:#fff; color:var(--sp-ink); padding:0 14px; font:inherit; font-size:13.5px; box-shadow:inset 0 1px 2px rgba(23,21,15,.05); transition:border-color .15s, box-shadow .15s; }
117
+ #sp-input::placeholder{ color:var(--sp-mute); }
118
+ #sp-input:focus{ outline:none; border-color:var(--sp-clay); box-shadow:0 0 0 3px rgba(199,91,57,.15); }
119
+ #sp-input:disabled{ background:var(--sp-paper-2); color:var(--sp-mute); }
120
+ #sp-send{ flex:none; height:36px; padding:0 18px; border:0; border-radius:9px; cursor:pointer; background:var(--sp-ink); color:var(--sp-paper); font:inherit; font-size:11.5px; font-weight:600; letter-spacing:.12em; text-transform:uppercase; font-family:'IBM Plex Mono',monospace; transition:background .15s; }
121
+ #sp-send:hover{ background:var(--sp-clay); }
122
+ #sp-send:disabled{ opacity:.55; cursor:default; background:var(--sp-mute); }
123
+
124
+ /* element-pick affordances applied to the host document */
125
+ body.sp-picking, body.sp-picking *{ cursor:crosshair !important; }
126
+ .sp-hl{ outline:2px solid #C75B39 !important; outline-offset:2px; background:rgba(199,91,57,.06) !important; }
127
+
128
+ /* ✎ edit-in-place affordances applied to the host document (only while editing) */
129
+ body.sp-editing .sp-editable{ cursor:text; border-radius:4px; transition:box-shadow .12s, background .12s; }
130
+ body.sp-editing .sp-editable:hover{ box-shadow:0 0 0 1px rgba(63,82,71,.5), 0 0 0 5px rgba(63,82,71,.08); background:rgba(63,82,71,.04); }
131
+ .sp-editable[contenteditable="true"], .sp-editable[contenteditable="true"]:focus{ outline:2px solid #3F5247 !important; outline-offset:3px; background:rgba(63,82,71,.06); cursor:text; }
132
+ @keyframes sp-saved-pulse{ from{ box-shadow:0 0 0 3px rgba(78,124,89,.5);} to{ box-shadow:0 0 0 3px rgba(78,124,89,0);} }
133
+ .sp-saved{ animation:sp-saved-pulse 1.2s ease-out; border-radius:4px; }
134
+
135
+ /* Hands: the floating drag/delete handle cluster (host-document affordance — literal colors) */
136
+ #sp-rowctl{ position:absolute; z-index:2147483500; display:flex; gap:1px; align-items:center;
137
+ background:#F4F0E6; border:1px solid rgba(23,21,15,.2); border-radius:7px; padding:1px;
138
+ box-shadow:0 3px 10px rgba(23,21,15,.18); transform:translate(-2px,-100%); }
139
+ #sp-rowctl.sp-ctl-below{ transform:translate(-2px,2px); }
140
+ .sp-grip{ cursor:grab; padding:3px 5px; color:#8A8578; font-size:13px; line-height:1; user-select:none; }
141
+ .sp-grip:active{ cursor:grabbing; color:#3F5247; }
142
+ .sp-del{ border:0; background:transparent; cursor:pointer; padding:2px 7px 3px; color:#B23A2E; font-size:15px; line-height:1; border-radius:5px; }
143
+ .sp-del:hover{ background:rgba(178,58,46,.12); }
144
+ body.sp-dragging, body.sp-dragging *{ cursor:grabbing !important; }
145
+ body.sp-dragging .sp-editable{ transition:none; }
146
+ .sp-drop-before{ box-shadow:inset 0 3px 0 -1px #C75B39 !important; }
147
+ .sp-drop-after{ box-shadow:inset 0 -3px 0 -1px #C75B39 !important; }
148
+
149
+ /* the undo chip in the panel head (inside #sp-panel — scoped tokens ok) */
150
+ #sp-undo{ border:1px solid rgba(23,21,15,.18); background:var(--sp-paper-2); color:var(--sp-pine);
151
+ font-family:'IBM Plex Mono',monospace; font-size:10.5px; border-radius:6px; padding:2px 8px; cursor:pointer; }
152
+ #sp-undo:hover{ border-color:var(--sp-pine); color:var(--sp-ink); }
153
+
154
+ /* flash the elements Claude just changed, on the host document */
155
+ .sp-flash{ animation:sp-flash 2.2s ease-out 1; }
156
+ @keyframes sp-flash{ 0%{ box-shadow:0 0 0 3px rgba(199,91,57,.6); background:rgba(199,91,57,.14); } 100%{ box-shadow:0 0 0 0 transparent; background:transparent; } }
157
+
158
+ /* ---------- first-run welcome (one-time on-page tour) ----------
159
+ Lives OUTSIDE #sp-panel, so it can't read the panel's scoped tokens. It wears the host skin via
160
+ var(--sp-*, …) — toolbar.js applies the adopted tokens to #sp-welcome; the fallbacks are the
161
+ shipped warm defaults, so on an un-themed page it looks identical. */
162
+ #sp-welcome{ position:fixed; inset:0; z-index:2147483646; display:flex; align-items:center; justify-content:center;
163
+ padding:24px; background:rgba(23,21,15,.46); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
164
+ font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
165
+ opacity:0; transition:opacity .24s ease; }
166
+ #sp-welcome.sp-w-in{ opacity:1; }
167
+ .sp-w-card{ width:460px; max-width:100%; max-height:88vh; overflow:auto;
168
+ background:var(--sp-paper,#F4F0E6); color:var(--sp-ink,#17150F); border:1px solid rgba(23,21,15,.3); border-radius:16px;
169
+ box-shadow:0 24px 70px rgba(23,21,15,.42); transform:translateY(10px) scale(.985);
170
+ transition:transform .26s cubic-bezier(.2,.7,.3,1); }
171
+ #sp-welcome.sp-w-in .sp-w-card{ transform:none; }
172
+
173
+ .sp-w-head{ display:flex; align-items:center; justify-content:space-between; padding:14px 18px;
174
+ background:var(--sp-ink,#17150F); color:var(--sp-paper,#F4F0E6);
175
+ background-image:linear-gradient(rgba(244,240,230,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(244,240,230,.05) 1px,transparent 1px);
176
+ background-size:18px 18px; }
177
+ .sp-w-mark{ font-family:'IBM Plex Mono',ui-monospace,Menlo,monospace; font-size:14px; font-weight:600; letter-spacing:.02em; }
178
+ .sp-w-mark span{ color:var(--sp-clay,#C75B39); }
179
+ .sp-w-x{ border:0; background:transparent; color:var(--sp-paper-2,#EFEADD); font-size:20px; line-height:1; cursor:pointer; padding:0 2px; opacity:.7; }
180
+ .sp-w-x:hover{ opacity:1; color:var(--sp-clay,#C75B39); }
181
+
182
+ .sp-w-body{ padding:20px 18px 4px; }
183
+ .sp-w-title{ font-family:'Fraunces','Georgia',serif; font-size:23px; font-weight:600; line-height:1.16; letter-spacing:-.01em; margin:0 0 8px; }
184
+ .sp-w-lede{ font-size:13.5px; line-height:1.5; color:var(--sp-text-quote,#3a372e); margin:0 0 16px; }
185
+ .sp-w-tools{ list-style:none; margin:0 0 15px; padding:0; display:flex; flex-direction:column; gap:11px; }
186
+ .sp-w-tools li{ display:flex; gap:12px; align-items:flex-start; }
187
+ .sp-w-g{ flex:none; width:48px; height:31px; display:inline-flex; align-items:center; justify-content:center;
188
+ border-radius:8px; font-family:'IBM Plex Mono',ui-monospace,monospace; line-height:1; margin-top:1px; }
189
+ .sp-w-sand{ background:var(--sp-ink,#17150F); color:var(--sp-paper,#F4F0E6); font-size:10px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; }
190
+ .sp-w-hands{ background:var(--sp-paper-2,#EFEADD); color:var(--sp-pine,#3F5247); border:1px solid rgba(63,82,71,.4); font-size:15px; }
191
+ .sp-w-sling{ background:var(--sp-paper-2,#EFEADD); color:var(--sp-pine,#3F5247); border:1px solid rgba(23,21,15,.2); font-size:13px; font-weight:600; letter-spacing:-1px; }
192
+ .sp-w-tools b{ display:block; font-size:13px; font-weight:600; color:var(--sp-ink,#17150F); margin-bottom:1px; }
193
+ .sp-w-tools .d{ display:block; font-size:12.5px; line-height:1.42; color:#6b6657; }
194
+ .sp-w-tip{ font-size:12.5px; line-height:1.5; color:var(--sp-text-quote,#3a372e); background:var(--sp-paper-2,#EFEADD); border-left:2px solid var(--sp-clay,#C75B39);
195
+ border-radius:0 7px 7px 0; padding:9px 12px; margin:0; }
196
+ .sp-w-tip code{ font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:.92em; background:rgba(23,21,15,.07); padding:1px 5px; border-radius:3px; }
197
+
198
+ .sp-w-foot{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:14px 18px 18px; }
199
+ .sp-w-point{ font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:11px; color:var(--sp-mute,#8A8578); }
200
+ .sp-w-go{ flex:none; border:0; border-radius:9px; cursor:pointer; background:var(--sp-ink,#17150F); color:var(--sp-paper,#F4F0E6);
201
+ font-family:'IBM Plex Mono',ui-monospace,monospace; font-size:11.5px; font-weight:600; letter-spacing:.1em; text-transform:uppercase;
202
+ padding:11px 18px; transition:background .15s; }
203
+ .sp-w-go:hover{ background:var(--sp-clay,#C75B39); }
204
+
205
+ /* after the tour closes, pulse the real toolbar so the eye finds it */
206
+ @keyframes sp-attn{ 0%,100%{ box-shadow:0 16px 44px rgba(23,21,15,.28); } 30%,65%{ box-shadow:0 16px 44px rgba(23,21,15,.28), 0 0 0 4px rgba(199,91,57,.5); } }
207
+ #sp-panel.sp-attn{ animation:sp-attn 1.5s ease-in-out; }
208
+
209
+ @media (max-width:560px){ .sp-w-foot{ flex-direction:column; align-items:stretch; } .sp-w-point{ text-align:center; } }
210
+
211
+ @media (max-width:720px){
212
+ #sp-panel{ right:8px; left:8px; bottom:8px; width:auto; max-height:72vh; }
213
+ #sp-thread{ max-height:52vh; }
214
+ }
215
+ @media (prefers-reduced-motion:reduce){
216
+ #sp-chip.sp-busy #sp-led{ animation:none; }
217
+ .sp-flash{ animation:none; outline:2px solid #C75B39; }
218
+ #sp-welcome, .sp-w-card{ transition:none; }
219
+ #sp-panel.sp-attn{ animation:none; }
220
+ }