privateboard 0.1.0 → 0.1.2
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/dist/cli.js +2060 -183
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/public/agent-overlay.js +3 -3
- package/public/agent-profile.css +5 -4
- package/public/agent-profile.js +18 -2
- package/public/app.js +513 -26
- package/public/avatar-skill.js +6 -9
- package/public/home.html +1750 -0
- package/public/{prototype-dashboard.html → index.html} +129 -116
- package/public/onboarding.js +4 -4
- package/public/quote-cta.css +225 -0
- package/public/quote-cta.js +355 -0
- package/public/report/spines/a16z-thesis.css +33 -1
- package/public/report/spines/anthropic-essay.css +54 -1
- package/public/report/spines/boardroom-dark.css +18 -2
- package/public/report/spines/gartner-note.css +47 -0
- package/public/report/spines/mckinsey-deck.css +38 -1
- package/public/report/spines/openai-paper.css +37 -1
- package/public/report.html +361 -6
- package/public/room-settings.css +6 -4
- package/public/room-settings.js +8 -5
- package/public/user-settings.css +18 -0
- package/public/user-settings.js +31 -2
|
@@ -63,16 +63,71 @@
|
|
|
63
63
|
height: 100vh;
|
|
64
64
|
overflow: hidden;
|
|
65
65
|
}
|
|
66
|
+
/* Body becomes a flex column so the optional system-notice banner
|
|
67
|
+
can sit above the .control shell without forcing total height to
|
|
68
|
+
exceed the viewport. .control keeps its existing internal grid;
|
|
69
|
+
it just lives inside this outer flex now. */
|
|
70
|
+
body {
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-direction: column;
|
|
73
|
+
min-height: 0;
|
|
74
|
+
}
|
|
66
75
|
|
|
67
76
|
::-webkit-scrollbar { width: 5px; height: 5px; }
|
|
68
77
|
::-webkit-scrollbar-track { background: var(--bg); }
|
|
69
78
|
::-webkit-scrollbar-thumb { background: var(--line-bright); }
|
|
70
79
|
|
|
80
|
+
/* ─────────── SYSTEM NOTICE BANNER ───────────
|
|
81
|
+
Dismissible single-line notice that appears above the app shell
|
|
82
|
+
when storage migrations have been applied. Mono micro-type, lime
|
|
83
|
+
left chevron, hairline border under so it reads as system chrome
|
|
84
|
+
not chat content. Only shown when app.js sets data-sys-notice
|
|
85
|
+
visible. */
|
|
86
|
+
.sys-notice {
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
gap: 10px;
|
|
90
|
+
padding: 8px 14px;
|
|
91
|
+
background: var(--panel-2, #1A1A18);
|
|
92
|
+
border-bottom: 0.5px solid var(--lime-dim, #2D5532);
|
|
93
|
+
font-family: var(--mono, "Inter", system-ui, sans-serif);
|
|
94
|
+
font-size: 11.5px;
|
|
95
|
+
color: var(--text-soft, #8E8B83);
|
|
96
|
+
flex-shrink: 0;
|
|
97
|
+
}
|
|
98
|
+
.sys-notice[hidden] { display: none; }
|
|
99
|
+
.sys-notice-mark {
|
|
100
|
+
color: var(--lime, #6FB572);
|
|
101
|
+
font-weight: 700;
|
|
102
|
+
}
|
|
103
|
+
.sys-notice-text {
|
|
104
|
+
flex: 1 1 auto;
|
|
105
|
+
min-width: 0;
|
|
106
|
+
line-height: 1.4;
|
|
107
|
+
}
|
|
108
|
+
.sys-notice-text .sys-notice-strong {
|
|
109
|
+
color: var(--text, #C8C5BE);
|
|
110
|
+
font-weight: 600;
|
|
111
|
+
}
|
|
112
|
+
.sys-notice-close {
|
|
113
|
+
appearance: none;
|
|
114
|
+
background: none;
|
|
115
|
+
border: 0;
|
|
116
|
+
color: var(--text-faint, #5C5A4D);
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
font-size: 13px;
|
|
119
|
+
line-height: 1;
|
|
120
|
+
padding: 4px 6px;
|
|
121
|
+
transition: color 0.12s;
|
|
122
|
+
}
|
|
123
|
+
.sys-notice-close:hover { color: var(--lime, #6FB572); }
|
|
124
|
+
|
|
71
125
|
/* ─────────── ROOT ─────────── */
|
|
72
126
|
.control {
|
|
73
127
|
display: grid;
|
|
74
128
|
grid-template-rows: auto 1fr;
|
|
75
|
-
|
|
129
|
+
flex: 1 1 auto;
|
|
130
|
+
min-height: 0;
|
|
76
131
|
gap: 8px;
|
|
77
132
|
padding: 8px;
|
|
78
133
|
}
|
|
@@ -141,98 +196,6 @@
|
|
|
141
196
|
.topbar-right .val { color: var(--text-soft); }
|
|
142
197
|
@keyframes pulse { 0%, 60% { opacity: 1; } 80% { opacity: 0.4; } }
|
|
143
198
|
|
|
144
|
-
.user-menu-wrap { position: relative; flex: 1; min-width: 0; }
|
|
145
|
-
.user-menu {
|
|
146
|
-
position: absolute;
|
|
147
|
-
/* Default opens DOWNWARD; sidebar-foot variant flips upward below */
|
|
148
|
-
top: calc(100% + 6px);
|
|
149
|
-
right: 0;
|
|
150
|
-
min-width: 200px;
|
|
151
|
-
background: var(--panel);
|
|
152
|
-
border: 0.5px solid var(--line-bright);
|
|
153
|
-
z-index: 100;
|
|
154
|
-
opacity: 0;
|
|
155
|
-
visibility: hidden;
|
|
156
|
-
transform: translateY(-2px);
|
|
157
|
-
transition: opacity 0.12s, transform 0.12s, visibility 0s linear 0.12s;
|
|
158
|
-
}
|
|
159
|
-
.user-menu-wrap:hover .user-menu,
|
|
160
|
-
.user-menu-wrap:focus-within .user-menu {
|
|
161
|
-
opacity: 1;
|
|
162
|
-
visibility: visible;
|
|
163
|
-
transform: translateY(0);
|
|
164
|
-
transition: opacity 0.12s, transform 0.12s, visibility 0s;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/* Sidebar-foot variant: menu pops UPWARD from the bottom user-block,
|
|
168
|
-
anchored to the left edge so it sits inside the sidebar column. */
|
|
169
|
-
.sidebar-foot .user-menu-wrap { display: flex; }
|
|
170
|
-
.sidebar-foot .user-block { flex: 1; min-width: 0; }
|
|
171
|
-
.sidebar-foot .user-menu {
|
|
172
|
-
top: auto;
|
|
173
|
-
bottom: calc(100% + 6px);
|
|
174
|
-
right: auto;
|
|
175
|
-
left: 0;
|
|
176
|
-
transform: translateY(2px);
|
|
177
|
-
}
|
|
178
|
-
.sidebar-foot .user-menu-wrap:hover .user-menu,
|
|
179
|
-
.sidebar-foot .user-menu-wrap:focus-within .user-menu {
|
|
180
|
-
transform: translateY(0);
|
|
181
|
-
}
|
|
182
|
-
.sidebar-foot .user-block .chev {
|
|
183
|
-
margin-left: auto;
|
|
184
|
-
color: var(--text-dim);
|
|
185
|
-
font-size: 9px;
|
|
186
|
-
transition: color 0.1s;
|
|
187
|
-
}
|
|
188
|
-
.sidebar-foot .user-menu-wrap:hover .user-block .chev,
|
|
189
|
-
.sidebar-foot .user-menu-wrap:focus-within .user-block .chev {
|
|
190
|
-
color: var(--lime);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.user-menu-section {
|
|
194
|
-
padding: 8px 12px;
|
|
195
|
-
border-bottom: 0.5px solid var(--line);
|
|
196
|
-
background: var(--panel-2);
|
|
197
|
-
}
|
|
198
|
-
.user-menu-section .name {
|
|
199
|
-
font-size: 11px;
|
|
200
|
-
color: var(--text);
|
|
201
|
-
font-weight: 700;
|
|
202
|
-
margin-bottom: 1px;
|
|
203
|
-
}
|
|
204
|
-
.user-menu-section .meta {
|
|
205
|
-
font-size: 9.5px;
|
|
206
|
-
color: var(--text-dim);
|
|
207
|
-
letter-spacing: 0.04em;
|
|
208
|
-
}
|
|
209
|
-
.user-menu-section .meta .lime { color: var(--lime); }
|
|
210
|
-
|
|
211
|
-
.user-menu-item {
|
|
212
|
-
display: flex;
|
|
213
|
-
align-items: center;
|
|
214
|
-
gap: 10px;
|
|
215
|
-
padding: 8px 12px;
|
|
216
|
-
font-size: 11.5px;
|
|
217
|
-
color: var(--text-soft);
|
|
218
|
-
text-decoration: none;
|
|
219
|
-
border-bottom: 0.5px solid var(--line);
|
|
220
|
-
transition: all 0.08s;
|
|
221
|
-
}
|
|
222
|
-
.user-menu-item:last-child { border-bottom: none; }
|
|
223
|
-
.user-menu-item:hover {
|
|
224
|
-
background: var(--panel-2);
|
|
225
|
-
color: var(--lime);
|
|
226
|
-
}
|
|
227
|
-
.user-menu-item .menu-icon {
|
|
228
|
-
width: 14px;
|
|
229
|
-
color: var(--text-dim);
|
|
230
|
-
text-align: center;
|
|
231
|
-
}
|
|
232
|
-
.user-menu-item:hover .menu-icon { color: var(--lime); }
|
|
233
|
-
.user-menu-item.danger:hover { color: var(--red); }
|
|
234
|
-
.user-menu-item.danger:hover .menu-icon { color: var(--red); }
|
|
235
|
-
|
|
236
199
|
/* ═══════════════════════════════════════════
|
|
237
200
|
MAIN GRID — sidebar + content
|
|
238
201
|
═══════════════════════════════════════════ */
|
|
@@ -661,9 +624,10 @@
|
|
|
661
624
|
}
|
|
662
625
|
.new-btn:hover {
|
|
663
626
|
background: var(--panel-2);
|
|
664
|
-
color: var(--
|
|
627
|
+
color: var(--lime);
|
|
665
628
|
}
|
|
666
|
-
|
|
629
|
+
/* The ::before icon inherits via currentColor — no explicit
|
|
630
|
+
hover override needed; setting the parent's color cascades. */
|
|
667
631
|
/* Active state · matches session-row-shell.active treatment so the
|
|
668
632
|
sidebar reads consistently when the composer is the current view. */
|
|
669
633
|
.new-btn.active {
|
|
@@ -1838,8 +1802,10 @@
|
|
|
1838
1802
|
.paused-bar-text { font-size: 10.5px; color: var(--text-dim); }
|
|
1839
1803
|
.paused-bar-text strong { color: var(--text); font-weight: 700; }
|
|
1840
1804
|
.paused-bar-text .lime { color: var(--lime); }
|
|
1841
|
-
.paused-bar-actions { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
1805
|
+
.paused-bar-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
1842
1806
|
.resume-btn-lg {
|
|
1807
|
+
display: inline-flex;
|
|
1808
|
+
align-items: center;
|
|
1843
1809
|
padding: 6px 12px;
|
|
1844
1810
|
background: var(--lime);
|
|
1845
1811
|
color: var(--bg);
|
|
@@ -1847,6 +1813,7 @@
|
|
|
1847
1813
|
font-family: var(--mono);
|
|
1848
1814
|
font-size: 10px;
|
|
1849
1815
|
font-weight: 700;
|
|
1816
|
+
line-height: 1.2;
|
|
1850
1817
|
cursor: pointer;
|
|
1851
1818
|
text-decoration: none;
|
|
1852
1819
|
text-transform: uppercase;
|
|
@@ -1935,17 +1902,26 @@
|
|
|
1935
1902
|
}
|
|
1936
1903
|
.followup-btn:hover { background: var(--bg); color: var(--lime); }
|
|
1937
1904
|
.ghost-btn {
|
|
1938
|
-
|
|
1905
|
+
/* inline-flex + align-items:center so text always centers vertically
|
|
1906
|
+
inside the box even when a flex parent stretches us to match the
|
|
1907
|
+
resume-btn-lg sibling's height. Padding / font-size / weight are
|
|
1908
|
+
lined up with .resume-btn-lg so the buttons read as the same
|
|
1909
|
+
size class — only the fill / border treatment distinguishes the
|
|
1910
|
+
primary lime CTA from a quieter ghost. */
|
|
1911
|
+
display: inline-flex;
|
|
1912
|
+
align-items: center;
|
|
1913
|
+
padding: 6px 12px;
|
|
1939
1914
|
background: var(--bg);
|
|
1940
1915
|
border: 0.5px solid var(--line-strong);
|
|
1941
1916
|
font-family: var(--mono);
|
|
1942
|
-
font-size:
|
|
1943
|
-
font-weight:
|
|
1917
|
+
font-size: 10px;
|
|
1918
|
+
font-weight: 700;
|
|
1919
|
+
line-height: 1.2;
|
|
1944
1920
|
color: var(--text);
|
|
1945
1921
|
cursor: pointer;
|
|
1946
1922
|
text-decoration: none;
|
|
1947
1923
|
text-transform: uppercase;
|
|
1948
|
-
letter-spacing: 0.
|
|
1924
|
+
letter-spacing: 0.1em;
|
|
1949
1925
|
}
|
|
1950
1926
|
.ghost-btn:hover { border-color: var(--lime); color: var(--lime); }
|
|
1951
1927
|
|
|
@@ -3850,6 +3826,37 @@
|
|
|
3850
3826
|
.msg-bubble p:last-child { margin-bottom: 0; }
|
|
3851
3827
|
.msg-bubble strong { color: var(--text); font-weight: 600; }
|
|
3852
3828
|
.msg-bubble em { font-style: normal; color: var(--lime); font-weight: 500; }
|
|
3829
|
+
/* Markdown blockquote · designed inset card, not a raw `>` line.
|
|
3830
|
+
Per the no-coloured-left-borders rule, the callout treatment
|
|
3831
|
+
uses a top mono kicker + panel-2 surface + indent (NOT a left
|
|
3832
|
+
border). Italic body sets it apart from the surrounding agent
|
|
3833
|
+
prose; the inline @director attribution at the end (rendered
|
|
3834
|
+
by inline()'s @-mention pass) gets its usual lime treatment.
|
|
3835
|
+
Used by quote-cta probe / second messages and any plain
|
|
3836
|
+
markdown blockquote a director / chair might emit. */
|
|
3837
|
+
.msg-bubble .msg-quote {
|
|
3838
|
+
margin: 0 0 12px;
|
|
3839
|
+
padding: 10px 14px;
|
|
3840
|
+
background: var(--panel-2);
|
|
3841
|
+
font-family: var(--font-agent);
|
|
3842
|
+
font-style: italic;
|
|
3843
|
+
font-size: 13px;
|
|
3844
|
+
line-height: 1.55;
|
|
3845
|
+
color: var(--text-soft);
|
|
3846
|
+
}
|
|
3847
|
+
.msg-bubble .msg-quote::before {
|
|
3848
|
+
content: "// quoted";
|
|
3849
|
+
display: block;
|
|
3850
|
+
font-family: var(--mono);
|
|
3851
|
+
font-size: 9px;
|
|
3852
|
+
font-weight: 700;
|
|
3853
|
+
letter-spacing: 0.18em;
|
|
3854
|
+
text-transform: uppercase;
|
|
3855
|
+
color: var(--text-faint);
|
|
3856
|
+
font-style: normal;
|
|
3857
|
+
margin-bottom: 6px;
|
|
3858
|
+
}
|
|
3859
|
+
.msg-bubble .msg-quote:last-child { margin-bottom: 0; }
|
|
3853
3860
|
/* Markdown tables · editorial style. No outer box, no zebra, no
|
|
3854
3861
|
uppercase data-grid headers — those read as "spreadsheet pasted
|
|
3855
3862
|
into a conversation" and broke the bubble's literary register.
|
|
@@ -6991,6 +6998,8 @@
|
|
|
6991
6998
|
<script src="auto-hide-scroll.js" defer></script>
|
|
6992
6999
|
<link rel="stylesheet" href="onboarding.css">
|
|
6993
7000
|
<script src="onboarding.js" defer></script>
|
|
7001
|
+
<link rel="stylesheet" href="quote-cta.css">
|
|
7002
|
+
<script src="quote-cta.js" defer></script>
|
|
6994
7003
|
<script src="app.js" defer></script>
|
|
6995
7004
|
<script>
|
|
6996
7005
|
/* FOUC-prevention: apply saved theme synchronously before paint */
|
|
@@ -7007,6 +7016,19 @@
|
|
|
7007
7016
|
</head>
|
|
7008
7017
|
<body>
|
|
7009
7018
|
|
|
7019
|
+
<!-- ═══════════════ SYSTEM NOTICE BANNER ═══════════════
|
|
7020
|
+
Surfaces "storage upgraded" notices when the user opens a build
|
|
7021
|
+
that ran new schema migrations against their existing DB. Hidden
|
|
7022
|
+
by default; populated + un-hidden by app.js after the boot fetch
|
|
7023
|
+
to /api/system/migrations resolves. Dismiss writes the latest
|
|
7024
|
+
migration name to localStorage so it doesn't re-show until the
|
|
7025
|
+
next time fresh migrations actually apply. -->
|
|
7026
|
+
<div class="sys-notice" data-sys-notice hidden>
|
|
7027
|
+
<span class="sys-notice-mark">▸</span>
|
|
7028
|
+
<span class="sys-notice-text" data-sys-notice-text></span>
|
|
7029
|
+
<button type="button" class="sys-notice-close" data-sys-notice-close aria-label="Dismiss">✕</button>
|
|
7030
|
+
</div>
|
|
7031
|
+
|
|
7010
7032
|
<div class="control">
|
|
7011
7033
|
|
|
7012
7034
|
<!-- ═══════════════ TOP BAR (classification banner) ═══════════════ -->
|
|
@@ -7089,21 +7111,13 @@
|
|
|
7089
7111
|
</div><!-- /agents panel -->
|
|
7090
7112
|
|
|
7091
7113
|
<div class="sidebar-foot">
|
|
7092
|
-
<
|
|
7093
|
-
<
|
|
7094
|
-
|
|
7095
|
-
<div class="user-
|
|
7096
|
-
|
|
7097
|
-
<div class="user-meta" data-user-meta>// host</div>
|
|
7098
|
-
</div>
|
|
7099
|
-
<span class="chev">▴</span>
|
|
7100
|
-
</a>
|
|
7101
|
-
<div class="user-menu">
|
|
7102
|
-
<div class="user-menu-section">
|
|
7103
|
-
<div class="name" data-user-menu-name>—</div>
|
|
7104
|
-
</div>
|
|
7114
|
+
<a href="#" class="user-block">
|
|
7115
|
+
<div class="user-av" data-user-avatar>K</div>
|
|
7116
|
+
<div class="user-info">
|
|
7117
|
+
<div class="user-name" data-user-name>—</div>
|
|
7118
|
+
<div class="user-meta" data-user-meta>// host</div>
|
|
7105
7119
|
</div>
|
|
7106
|
-
</
|
|
7120
|
+
</a>
|
|
7107
7121
|
<a href="#" class="icon-btn" title="Settings" data-user-settings-trigger>⚙</a>
|
|
7108
7122
|
</div>
|
|
7109
7123
|
|
|
@@ -7171,8 +7185,7 @@
|
|
|
7171
7185
|
<strong>// room adjourned.</strong> the brief is filed above.
|
|
7172
7186
|
</div>
|
|
7173
7187
|
<div class="adjourned-bar-actions">
|
|
7174
|
-
<a href="#" class="ghost-btn">[↓] Export</a>
|
|
7175
|
-
<a href="#" class="ghost-btn">[↗] Share</a>
|
|
7188
|
+
<a href="#" class="ghost-btn" data-room-export>[↓] Export</a>
|
|
7176
7189
|
</div>
|
|
7177
7190
|
</footer>
|
|
7178
7191
|
</div>
|
package/public/onboarding.js
CHANGED
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
{
|
|
85
85
|
tag: "// pivot",
|
|
86
86
|
text: "Six months of runway, real users but flat MRR — pivot the product, hold the line, or shut it down?",
|
|
87
|
-
hint: "
|
|
88
|
-
tone: "
|
|
89
|
-
intensity: "
|
|
87
|
+
hint: "critique room: each director audits the plan — blocker / major / minor",
|
|
88
|
+
tone: "critique",
|
|
89
|
+
intensity: "sharp",
|
|
90
90
|
briefStyle: "auto",
|
|
91
91
|
agents: ["socrates", "first-principles", "long-horizon"],
|
|
92
92
|
},
|
|
@@ -729,7 +729,7 @@
|
|
|
729
729
|
|
|
730
730
|
function show() {
|
|
731
731
|
if (document.getElementById("onb-overlay")) return;
|
|
732
|
-
// Claim the dashboard sub-state ·
|
|
732
|
+
// Claim the dashboard sub-state · the dashboard page runs a
|
|
733
733
|
// restore tick (~2.5s of 250ms retries) that re-opens whatever
|
|
734
734
|
// agent profile the user last viewed once refreshAgents mounts the
|
|
735
735
|
// sidebar rows. Onboarding always lands the user on a fresh room
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════
|
|
2
|
+
QUOTE CTA · selection-driven follow-up
|
|
3
|
+
═══════════════════════════════════════════
|
|
4
|
+
When the user selects text inside a director's message bubble,
|
|
5
|
+
a small floating bar appears above the selection with two
|
|
6
|
+
actions: ask a follow-up (opens an overlay), or react with
|
|
7
|
+
"love it" (one-click, no typing). Both produce a user message
|
|
8
|
+
that quotes the selected snippet via markdown blockquote.
|
|
9
|
+
|
|
10
|
+
Visual vocabulary mirrors the rest of the app: panel-2 surface,
|
|
11
|
+
lime accent, mono micro-type for the action labels. Per the
|
|
12
|
+
no-coloured-left-borders rule, callouts use top tags + indent
|
|
13
|
+
instead of border-left treatments. */
|
|
14
|
+
|
|
15
|
+
/* Floating action bar · two segmented buttons above the selection.
|
|
16
|
+
Restrained surface · panel-2 base, neutral hairline border, soft
|
|
17
|
+
shadow for elevation. No lime border, no notch · the bar is just
|
|
18
|
+
text-and-icon, not a feature. Inter-button divider is structural
|
|
19
|
+
border-right between adjacent items, not a callout treatment. */
|
|
20
|
+
.qcta {
|
|
21
|
+
position: absolute;
|
|
22
|
+
z-index: 1400;
|
|
23
|
+
display: none;
|
|
24
|
+
background: var(--panel-2, #1A1A18);
|
|
25
|
+
border: 0.5px solid var(--line-strong, #3A3A35);
|
|
26
|
+
font-family: var(--mono, "Inter", system-ui, sans-serif);
|
|
27
|
+
box-shadow: 0 4px 14px -6px rgba(0, 0, 0, 0.55);
|
|
28
|
+
white-space: nowrap;
|
|
29
|
+
user-select: none;
|
|
30
|
+
}
|
|
31
|
+
.qcta.open { display: inline-flex; align-items: stretch; }
|
|
32
|
+
|
|
33
|
+
.qcta-btn {
|
|
34
|
+
appearance: none;
|
|
35
|
+
background: transparent;
|
|
36
|
+
border: 0;
|
|
37
|
+
color: var(--text, #C8C5BE);
|
|
38
|
+
font-family: inherit;
|
|
39
|
+
font-size: 12px;
|
|
40
|
+
font-weight: 500;
|
|
41
|
+
letter-spacing: 0;
|
|
42
|
+
padding: 7px 13px;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
display: inline-flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
gap: 6px;
|
|
47
|
+
transition: color 0.12s;
|
|
48
|
+
}
|
|
49
|
+
/* Tighten the inner edge of each button so the two CTAs sit close
|
|
50
|
+
together. Outer edges keep their 13px breathing room against the
|
|
51
|
+
bar border. */
|
|
52
|
+
.qcta-btn:not(:last-child) { padding-right: 6px; }
|
|
53
|
+
.qcta-btn:not(:first-child) { padding-left: 6px; }
|
|
54
|
+
.qcta-btn:hover { color: var(--lime, #6FB572); }
|
|
55
|
+
.qcta-btn:hover .ico { color: var(--lime, #6FB572); }
|
|
56
|
+
.qcta-btn .ico {
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
font-size: 12.5px;
|
|
60
|
+
font-weight: 500;
|
|
61
|
+
line-height: 1;
|
|
62
|
+
color: var(--text-soft, #8E8B83);
|
|
63
|
+
transition: color 0.12s;
|
|
64
|
+
}
|
|
65
|
+
.qcta-btn .ico svg { display: block; }
|
|
66
|
+
|
|
67
|
+
/* Read-only hint · shown only when the bar is in `qcta-readonly`
|
|
68
|
+
state (adjourned room). The buttons collapse out of the row and
|
|
69
|
+
the hint takes their place — the bar still pops up to acknowledge
|
|
70
|
+
the user's selection, but explains why probe / second can't fire. */
|
|
71
|
+
.qcta-hint {
|
|
72
|
+
display: none;
|
|
73
|
+
font-family: var(--mono, "Inter", system-ui, sans-serif);
|
|
74
|
+
font-size: 11px;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
letter-spacing: 0.04em;
|
|
77
|
+
color: var(--text-soft, #8E8B83);
|
|
78
|
+
padding: 8px 13px;
|
|
79
|
+
white-space: nowrap;
|
|
80
|
+
}
|
|
81
|
+
.qcta.qcta-readonly .qcta-btn { display: none; }
|
|
82
|
+
.qcta.qcta-readonly .qcta-hint { display: inline-flex; align-items: center; }
|
|
83
|
+
|
|
84
|
+
/* Ask-follow-up overlay · backdrop + modal. Same chrome family
|
|
85
|
+
as openSendChoiceModal (.pc-overlay) so the family stays coherent. */
|
|
86
|
+
.qask-overlay {
|
|
87
|
+
position: fixed;
|
|
88
|
+
inset: 0;
|
|
89
|
+
background: rgba(8, 8, 8, 0.5);
|
|
90
|
+
-webkit-backdrop-filter: blur(8px) saturate(1.05);
|
|
91
|
+
backdrop-filter: blur(8px) saturate(1.05);
|
|
92
|
+
z-index: 1500;
|
|
93
|
+
display: flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: center;
|
|
96
|
+
padding: 24px;
|
|
97
|
+
animation: qask-fade 0.16s ease-out;
|
|
98
|
+
}
|
|
99
|
+
@keyframes qask-fade { from { opacity: 0; } to { opacity: 1; } }
|
|
100
|
+
|
|
101
|
+
.qask-modal {
|
|
102
|
+
width: 100%;
|
|
103
|
+
max-width: 560px;
|
|
104
|
+
background: var(--panel, #131312);
|
|
105
|
+
border: 0.5px solid var(--lime, #6FB572);
|
|
106
|
+
color: var(--text, #C8C5BE);
|
|
107
|
+
display: flex;
|
|
108
|
+
flex-direction: column;
|
|
109
|
+
box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.65);
|
|
110
|
+
animation: qask-rise 0.2s ease-out;
|
|
111
|
+
}
|
|
112
|
+
@keyframes qask-rise {
|
|
113
|
+
from { transform: translateY(8px); opacity: 0; }
|
|
114
|
+
to { transform: translateY(0); opacity: 1; }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.qask-classification {
|
|
118
|
+
padding: 8px 14px;
|
|
119
|
+
border-bottom: 0.5px solid var(--line-bright, #2A2A26);
|
|
120
|
+
font-family: var(--mono, "Inter", system-ui, sans-serif);
|
|
121
|
+
font-size: 9px;
|
|
122
|
+
letter-spacing: 0.18em;
|
|
123
|
+
text-transform: uppercase;
|
|
124
|
+
color: var(--text-faint, #3A382F);
|
|
125
|
+
display: flex;
|
|
126
|
+
justify-content: space-between;
|
|
127
|
+
align-items: center;
|
|
128
|
+
background: var(--panel-2, #1A1A18);
|
|
129
|
+
}
|
|
130
|
+
.qask-classification .dot { color: var(--lime, #6FB572); }
|
|
131
|
+
.qask-classification .right { color: var(--text-faint, #3A382F); }
|
|
132
|
+
|
|
133
|
+
.qask-body { padding: 18px 18px 14px; display: flex; flex-direction: column; gap: 12px; }
|
|
134
|
+
|
|
135
|
+
/* Quote callout · top tag + indented italic body. NO left-border
|
|
136
|
+
treatment per the project-wide rule. */
|
|
137
|
+
.qask-quote {
|
|
138
|
+
background: var(--panel-2, #1A1A18);
|
|
139
|
+
padding: 12px 14px;
|
|
140
|
+
display: flex;
|
|
141
|
+
flex-direction: column;
|
|
142
|
+
gap: 6px;
|
|
143
|
+
max-height: 180px;
|
|
144
|
+
overflow-y: auto;
|
|
145
|
+
}
|
|
146
|
+
.qask-quote-tag {
|
|
147
|
+
font-family: var(--mono, "Inter", system-ui, sans-serif);
|
|
148
|
+
font-size: 9px;
|
|
149
|
+
letter-spacing: 0.18em;
|
|
150
|
+
text-transform: uppercase;
|
|
151
|
+
color: var(--text-faint, #3A382F);
|
|
152
|
+
font-weight: 700;
|
|
153
|
+
}
|
|
154
|
+
.qask-quote-body {
|
|
155
|
+
font-size: 12.5px;
|
|
156
|
+
line-height: 1.55;
|
|
157
|
+
color: var(--text-soft, #8E8B83);
|
|
158
|
+
font-style: italic;
|
|
159
|
+
white-space: pre-wrap;
|
|
160
|
+
word-break: break-word;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.qask-input-wrap {
|
|
164
|
+
border: 0.5px solid var(--line-strong, #3A3A35);
|
|
165
|
+
background: var(--bg, #0A0A0A);
|
|
166
|
+
display: flex;
|
|
167
|
+
align-items: stretch;
|
|
168
|
+
transition: border-color 0.12s;
|
|
169
|
+
}
|
|
170
|
+
.qask-input-wrap:focus-within { border-color: var(--lime, #6FB572); }
|
|
171
|
+
.qask-input-wrap::before {
|
|
172
|
+
content: ">";
|
|
173
|
+
color: var(--lime, #6FB572);
|
|
174
|
+
font-weight: 700;
|
|
175
|
+
font-size: 13px;
|
|
176
|
+
font-family: var(--mono, "Inter", system-ui, sans-serif);
|
|
177
|
+
padding: 9px 0 0 11px;
|
|
178
|
+
align-self: flex-start;
|
|
179
|
+
}
|
|
180
|
+
.qask-input {
|
|
181
|
+
flex: 1;
|
|
182
|
+
border: none;
|
|
183
|
+
background: transparent;
|
|
184
|
+
font-family: var(--font-human, var(--mono));
|
|
185
|
+
font-size: 13.5px;
|
|
186
|
+
color: var(--text, #C8C5BE);
|
|
187
|
+
outline: none;
|
|
188
|
+
padding: 9px 12px;
|
|
189
|
+
letter-spacing: -0.003em;
|
|
190
|
+
width: 100%;
|
|
191
|
+
resize: none;
|
|
192
|
+
min-height: 72px;
|
|
193
|
+
line-height: 1.5;
|
|
194
|
+
}
|
|
195
|
+
.qask-input::placeholder { color: var(--text-faint, #3A382F); }
|
|
196
|
+
|
|
197
|
+
.qask-foot {
|
|
198
|
+
padding: 10px 14px;
|
|
199
|
+
border-top: 0.5px solid var(--line-bright, #2A2A26);
|
|
200
|
+
background: var(--panel-2, #1A1A18);
|
|
201
|
+
display: flex;
|
|
202
|
+
justify-content: flex-end;
|
|
203
|
+
align-items: center;
|
|
204
|
+
gap: 8px;
|
|
205
|
+
}
|
|
206
|
+
.qask-btn {
|
|
207
|
+
font-family: var(--mono, "Inter", system-ui, sans-serif);
|
|
208
|
+
font-size: 10px;
|
|
209
|
+
font-weight: 700;
|
|
210
|
+
text-transform: uppercase;
|
|
211
|
+
letter-spacing: 0.1em;
|
|
212
|
+
padding: 7px 14px;
|
|
213
|
+
border: 0.5px solid var(--line-strong, #3A3A35);
|
|
214
|
+
background: transparent;
|
|
215
|
+
color: var(--text-soft, #8E8B83);
|
|
216
|
+
cursor: pointer;
|
|
217
|
+
transition: border-color 0.12s, color 0.12s, background 0.12s;
|
|
218
|
+
}
|
|
219
|
+
.qask-btn:hover { border-color: var(--lime, #6FB572); color: var(--lime, #6FB572); }
|
|
220
|
+
.qask-btn.primary {
|
|
221
|
+
border-color: var(--lime, #6FB572);
|
|
222
|
+
color: var(--lime, #6FB572);
|
|
223
|
+
}
|
|
224
|
+
.qask-btn.primary:hover { background: var(--lime, #6FB572); color: var(--bg, #0A0A0A); }
|
|
225
|
+
.qask-btn[disabled] { opacity: 0.4; cursor: not-allowed; }
|