privateboard 0.1.38 → 0.1.41
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/boot.js +327 -50
- package/dist/boot.js.map +1 -1
- package/dist/cli.js +327 -50
- package/dist/cli.js.map +1 -1
- package/dist/server.js +201 -40
- package/dist/server.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/public/__avatar3d_test.html +156 -0
- package/public/agent-overlay.css +14 -6
- package/public/agent-overlay.js +6 -6
- package/public/agent-profile.css +9 -12
- package/public/agent-profile.js +91 -38
- package/public/app.js +471 -528
- package/public/avatar-3d-snap.js +205 -0
- package/public/avatar-3d.js +836 -0
- package/public/avatar-customizer.html +274 -0
- package/public/avatar3d-editor.css +240 -0
- package/public/avatar3d-editor.js +484 -0
- package/public/avatars/3d/chair.png +0 -0
- package/public/avatars/3d/first-principles.png +0 -0
- package/public/avatars/3d/historian.png +0 -0
- package/public/avatars/3d/long-horizon.png +0 -0
- package/public/avatars/3d/phenomenologist.png +0 -0
- package/public/avatars/3d/socrates.png +0 -0
- package/public/avatars/3d/user-empathy.png +0 -0
- package/public/avatars/3d/value-investor.png +0 -0
- package/public/core-avatars.js +86 -0
- package/public/home-3d-loader.js +15 -4
- package/public/home-3d-mock.js +25 -14
- package/public/home.html +78 -16
- package/public/i18n.js +8 -4
- package/public/icons/avatar_1779855104027.glb +0 -0
- package/public/icons/logo.png +0 -0
- package/public/icons/new-style.glb +0 -0
- package/public/icons/new-style2.glb +0 -0
- package/public/icons/new-style3.glb +0 -0
- package/public/icons/new-style4.glb +0 -0
- package/public/icons/new-style5.glb +0 -0
- package/public/icons/new-style6.glb +0 -0
- package/public/icons/office.glb +0 -0
- package/public/icons/stuff.glb +0 -0
- package/public/index.html +169 -141
- package/public/magazine.html +1 -1
- package/public/new-agent.js +46 -20
- package/public/newspaper.html +1 -1
- package/public/office-viewer.html +340 -0
- package/public/ppt.html +1 -1
- package/public/stuff-viewer.html +330 -0
- package/public/thread.css +16 -15
- package/public/user-settings.css +7 -31
- package/public/user-settings.js +75 -89
- package/public/vendor/BufferGeometryUtils.js +1434 -0
- package/public/vendor/DRACOLoader.js +739 -0
- package/public/vendor/GLTFLoader.js +4860 -0
- package/public/vendor/RoomEnvironment.js +185 -0
- package/public/vendor/SkeletonUtils.js +496 -0
- package/public/vendor/draco/draco_decoder.js +34 -0
- package/public/vendor/draco/draco_decoder.wasm +0 -0
- package/public/vendor/draco/draco_encoder.js +33 -0
- package/public/vendor/draco/draco_wasm_wrapper.js +117 -0
- package/public/vendor/meshopt_decoder.module.js +196 -0
- package/public/voice-3d-banner.js +19 -7
- package/public/voice-3d.js +1407 -432
- package/public/voice-replay.js +21 -0
- package/public/avatar-skill.js +0 -629
- package/public/avatars/chair-blink.svg +0 -1
- package/public/avatars/chair.svg +0 -1
- package/public/avatars/first-principles.svg +0 -1
- package/public/avatars/historian.svg +0 -1
- package/public/avatars/long-horizon.svg +0 -1
- package/public/avatars/phenomenologist.svg +0 -1
- package/public/avatars/socrates.svg +0 -1
- package/public/avatars/user-empathy.svg +0 -1
- package/public/avatars/value-investor.svg +0 -1
- package/public/icons/folded-sidebar.png +0 -0
package/public/index.html
CHANGED
|
@@ -1107,68 +1107,19 @@
|
|
|
1107
1107
|
mask here also overrides the generic .mini-btn::before, which —
|
|
1108
1108
|
lacking an --icon — would otherwise paint a solid square. */
|
|
1109
1109
|
.mini-logo { position: relative; }
|
|
1110
|
-
/*
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
position: relative;
|
|
1115
|
-
width: 26px;
|
|
1116
|
-
height: 26px;
|
|
1117
|
-
transition: opacity 0.12s;
|
|
1118
|
-
animation: chair-hop 7s ease-in-out infinite;
|
|
1119
|
-
}
|
|
1120
|
-
.mini-logo-av img {
|
|
1121
|
-
position: absolute;
|
|
1122
|
-
inset: 0;
|
|
1123
|
-
width: 100%;
|
|
1124
|
-
height: 100%;
|
|
1125
|
-
image-rendering: pixelated;
|
|
1126
|
-
image-rendering: crisp-edges;
|
|
1127
|
-
}
|
|
1128
|
-
/* Closed-eye frame · hidden at rest, briefly opaque on the blink
|
|
1129
|
-
keyframe. A different cycle length from the hop keeps the two from
|
|
1130
|
-
locking into a robotic sync. */
|
|
1131
|
-
.mini-logo-av .cl-blink {
|
|
1132
|
-
opacity: 0;
|
|
1133
|
-
animation: chair-blink 5.7s ease-in-out infinite;
|
|
1134
|
-
}
|
|
1135
|
-
.mini-logo:hover .mini-logo-av { opacity: 0; }
|
|
1136
|
-
/* Occasional double-bounce hop · still ~85% of the cycle, then a
|
|
1137
|
-
quick two-step hop so the chair reads as "alive" without being
|
|
1138
|
-
busy. */
|
|
1139
|
-
@keyframes chair-hop {
|
|
1140
|
-
0%, 60%, 100% { transform: translateY(0); }
|
|
1141
|
-
66% { transform: translateY(-4px); }
|
|
1142
|
-
72% { transform: translateY(0); }
|
|
1143
|
-
77% { transform: translateY(-2px); }
|
|
1144
|
-
82% { transform: translateY(0); }
|
|
1145
|
-
}
|
|
1146
|
-
/* Single crisp blink near the end of the cycle (~170ms closed). */
|
|
1147
|
-
@keyframes chair-blink {
|
|
1148
|
-
0%, 93.5%, 100% { opacity: 0; }
|
|
1149
|
-
94%, 96.5% { opacity: 1; }
|
|
1150
|
-
97% { opacity: 0; }
|
|
1151
|
-
}
|
|
1152
|
-
/* Respect reduced-motion · hold the open-eye frame, no hop / blink. */
|
|
1153
|
-
@media (prefers-reduced-motion: reduce) {
|
|
1154
|
-
.mini-logo-av,
|
|
1155
|
-
.mini-logo-av .cl-blink { animation: none; }
|
|
1156
|
-
}
|
|
1110
|
+
/* Fold glyph · same Lucide PanelLeft mark the in-sidebar collapse
|
|
1111
|
+
button uses. Always visible (no chair avatar / hover swap),
|
|
1112
|
+
mirrored on X so the rows flip to the right edge — telegraphs
|
|
1113
|
+
"the panel expands out from here". */
|
|
1157
1114
|
.mini-logo::before {
|
|
1158
1115
|
content: "";
|
|
1159
1116
|
position: absolute;
|
|
1160
1117
|
top: 50%;
|
|
1161
1118
|
left: 50%;
|
|
1162
|
-
/* scaleX(-1) mirrors the fold so the rows flip to the right edge —
|
|
1163
|
-
the same direction the in-sidebar collapse button uses in its
|
|
1164
|
-
collapsed state to telegraph "the panel expands out from here". */
|
|
1165
1119
|
transform: translate(-50%, -50%) scaleX(-1);
|
|
1166
1120
|
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='3' width='18' height='18' rx='2'/><path d='M9 3v18'/><path d='M5 8h2'/><path d='M5 12h2'/><path d='M5 16h2'/></svg>");
|
|
1167
1121
|
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='3' width='18' height='18' rx='2'/><path d='M9 3v18'/><path d='M5 8h2'/><path d='M5 12h2'/><path d='M5 16h2'/></svg>");
|
|
1168
|
-
opacity: 0;
|
|
1169
|
-
transition: opacity 0.12s;
|
|
1170
1122
|
}
|
|
1171
|
-
.mini-logo:hover::before { opacity: 1; }
|
|
1172
1123
|
/* Divider between the action group and the rooms/agents switchers. */
|
|
1173
1124
|
.mini-sep {
|
|
1174
1125
|
width: 20px;
|
|
@@ -1358,6 +1309,7 @@
|
|
|
1358
1309
|
.agent-row .agent-row-av {
|
|
1359
1310
|
width: 32px;
|
|
1360
1311
|
height: 32px;
|
|
1312
|
+
margin-top: -10px;
|
|
1361
1313
|
image-rendering: pixelated;
|
|
1362
1314
|
image-rendering: crisp-edges;
|
|
1363
1315
|
flex-shrink: 0;
|
|
@@ -2059,11 +2011,11 @@
|
|
|
2059
2011
|
position: relative;
|
|
2060
2012
|
overflow: hidden;
|
|
2061
2013
|
}
|
|
2062
|
-
/*
|
|
2063
|
-
swaps the initial-letter chip for
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2014
|
+
/* 3D portrait variant · when prefs.avatarSeed exists,
|
|
2015
|
+
app.renderUserBlock swaps the initial-letter chip for the
|
|
2016
|
+
Avatar3DSnap rendered PNG. The image fills the chip; we drop the
|
|
2017
|
+
filled background so the portrait reads cleanly against the
|
|
2018
|
+
surface behind it. */
|
|
2067
2019
|
.user-av.has-pixel-av {
|
|
2068
2020
|
background: transparent;
|
|
2069
2021
|
}
|
|
@@ -2229,6 +2181,17 @@
|
|
|
2229
2181
|
and leaving an empty band below. */
|
|
2230
2182
|
.main-view[hidden] { display: none !important; }
|
|
2231
2183
|
|
|
2184
|
+
/* Boot guard · on refresh, the sidebar restore tick has to wait for
|
|
2185
|
+
the agent rows to mount before openAgentProfile fires, but app.js's
|
|
2186
|
+
handleRoute paints the new-room composer into the room view straight
|
|
2187
|
+
away on an empty hash. Mask the room view while a saved agent profile
|
|
2188
|
+
is being restored so the composer doesn't flash under the profile.
|
|
2189
|
+
The guard class is set SYNCHRONOUSLY during parse (top of the sidebar
|
|
2190
|
+
IIFE, before app.js's deferred init runs) and cleared the moment the
|
|
2191
|
+
profile opens or the restore gives up. `!important` beats app.js's
|
|
2192
|
+
own removeAttribute("hidden") on the room view during that window. */
|
|
2193
|
+
html.bb-restoring-agent .main-view[data-main-view="room"] { display: none !important; }
|
|
2194
|
+
|
|
2232
2195
|
/* ─── All Reports · clean vertical reading list ──────────────────
|
|
2233
2196
|
Single-hierarchy archive view · header → filter chips → date-
|
|
2234
2197
|
grouped reading rows. Each row uses pure typography (kicker /
|
|
@@ -4202,6 +4165,34 @@
|
|
|
4202
4165
|
letter-spacing: 0.1em;
|
|
4203
4166
|
}
|
|
4204
4167
|
.resume-btn:hover { background: var(--bg); color: var(--lime); }
|
|
4168
|
+
/* Stop voice replay · same compact mono chrome as pause/resume, but in
|
|
4169
|
+
red so it reads as a distinct "terminate playback" action. Rendered
|
|
4170
|
+
by app.js only while a replay is active in this room, and it sits in
|
|
4171
|
+
the pause/resume slot (those are hidden on adjourned rooms, where
|
|
4172
|
+
replay runs) so it lands exactly where the eye looks for transport. */
|
|
4173
|
+
.replay-stop-btn {
|
|
4174
|
+
padding: 4px 10px;
|
|
4175
|
+
background: transparent;
|
|
4176
|
+
color: var(--text);
|
|
4177
|
+
border: 0.5px solid var(--red, #B5706A);
|
|
4178
|
+
font-family: var(--mono);
|
|
4179
|
+
font-size: 10px;
|
|
4180
|
+
font-weight: 700;
|
|
4181
|
+
cursor: pointer;
|
|
4182
|
+
text-decoration: none;
|
|
4183
|
+
text-transform: uppercase;
|
|
4184
|
+
letter-spacing: 0.1em;
|
|
4185
|
+
transition: all 0.12s;
|
|
4186
|
+
}
|
|
4187
|
+
.replay-stop-btn .replay-stop-icon {
|
|
4188
|
+
color: var(--red, #B5706A);
|
|
4189
|
+
margin: 0 1px;
|
|
4190
|
+
letter-spacing: -0.05em;
|
|
4191
|
+
}
|
|
4192
|
+
.replay-stop-btn:hover {
|
|
4193
|
+
background: rgba(181, 112, 106, 0.12);
|
|
4194
|
+
color: var(--red, #B5706A);
|
|
4195
|
+
}
|
|
4205
4196
|
/* ─── Empty state ───
|
|
4206
4197
|
No room loaded (zero-room first-run, or after a navigation). The
|
|
4207
4198
|
starter panel renders inside .chat; the input bar, speaking queue,
|
|
@@ -7357,11 +7348,10 @@
|
|
|
7357
7348
|
border: 0.5px solid var(--line-strong);
|
|
7358
7349
|
font-family: var(--mono);
|
|
7359
7350
|
}
|
|
7360
|
-
/*
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
the chip edge-to-edge. */
|
|
7351
|
+
/* Legacy pixel-av variant · the renderChat path no longer mounts
|
|
7352
|
+
`msg-av-pixel` (Avatar3DSnap PNG fills `<img class="msg-av">`
|
|
7353
|
+
directly), but the CSS is kept for any third-party plugins that
|
|
7354
|
+
still write into that node. */
|
|
7365
7355
|
.msg.user .msg-av.msg-av-pixel {
|
|
7366
7356
|
border: none;
|
|
7367
7357
|
background: var(--bg);
|
|
@@ -7547,7 +7537,10 @@
|
|
|
7547
7537
|
-webkit-box-orient: vertical;
|
|
7548
7538
|
overflow: hidden;
|
|
7549
7539
|
}
|
|
7550
|
-
|
|
7540
|
+
/* Flows inline right after the badges (no longer pinned far-right via
|
|
7541
|
+
margin-left:auto) so the far-right end of the meta line is free for
|
|
7542
|
+
the hover thread toolbar to sit at the row's end. */
|
|
7543
|
+
.msg-time { color: var(--text-faint); }
|
|
7551
7544
|
|
|
7552
7545
|
.msg-bubble {
|
|
7553
7546
|
padding: 0;
|
|
@@ -8480,23 +8473,16 @@
|
|
|
8480
8473
|
--rt-bottom-reserve: 130px;
|
|
8481
8474
|
}
|
|
8482
8475
|
|
|
8483
|
-
/* ─── brainstorm ·
|
|
8484
|
-
128×
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
fill; scattered 1×2 lighter pixels read as grass blades
|
|
8490
|
-
catching light; pebbles + dust spots inside the dirt patches
|
|
8491
|
-
add ground-texture detail. JRPG outdoor-tile vocabulary for
|
|
8492
|
-
the "yes-and" creative tone — open ground, room to grow.
|
|
8493
|
-
|
|
8494
|
-
Replaces the earlier muted-earth grid mosaic which still read
|
|
8495
|
-
as an indoor floor pattern even at the larger tile size. */
|
|
8476
|
+
/* ─── brainstorm · WARM-OAK PLANK floor ───────────────────────
|
|
8477
|
+
128×64 light warm-oak planks · alternating plank tones, darker
|
|
8478
|
+
seams, staggered plank-end joints, a soft catch-light under each
|
|
8479
|
+
seam, and a few faint grain dashes. Pairs with the 3D room's cozy
|
|
8480
|
+
modern interior (voice-3d.js · brainstorm = window / chest / sage
|
|
8481
|
+
sofa) so the directors sit on a warm wood floor. Bright + cozy. */
|
|
8496
8482
|
.roundtable-stage[data-floor="brainstorm"] {
|
|
8497
|
-
--floor-bg: #
|
|
8483
|
+
--floor-bg: #B0976E;
|
|
8498
8484
|
--rt-chair-name: var(--lime, #6FB572);
|
|
8499
|
-
--floor-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='128' height='
|
|
8485
|
+
--floor-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='128' height='64' shape-rendering='crispEdges'><rect width='128' height='64' fill='%23B0976E'/><rect y='16' width='128' height='16' fill='%23A68C62'/><rect y='48' width='128' height='16' fill='%23A68C62'/><rect y='0' width='128' height='1' fill='%23C2A87E'/><rect y='16' width='128' height='1' fill='%23C2A87E'/><rect y='32' width='128' height='1' fill='%23C2A87E'/><rect y='48' width='128' height='1' fill='%23C2A87E'/><rect y='15' width='128' height='1' fill='%23877045'/><rect y='31' width='128' height='1' fill='%23877045'/><rect y='47' width='128' height='1' fill='%23877045'/><rect y='63' width='128' height='1' fill='%23877045'/><rect x='40' y='0' width='1' height='16' fill='%23877045'/><rect x='96' y='16' width='1' height='16' fill='%23877045'/><rect x='20' y='32' width='1' height='16' fill='%23877045'/><rect x='72' y='48' width='1' height='16' fill='%23877045'/><rect x='10' y='6' width='14' height='1' fill='%23A38755'/><rect x='60' y='22' width='18' height='1' fill='%23A38755'/><rect x='100' y='40' width='14' height='1' fill='%23A38755'/><rect x='30' y='56' width='16' height='1' fill='%23A38755'/></svg>");
|
|
8500
8486
|
}
|
|
8501
8487
|
/* ─── constructive · BLACK-WALNUT STAGGERED PLANK ─────────────
|
|
8502
8488
|
192×192 tileable boardroom floor · 8 rows of horizontal black-
|
|
@@ -8555,10 +8541,16 @@
|
|
|
8555
8541
|
arms in antique brass, polished-gold corner dots. Smaller tile
|
|
8556
8542
|
than the burgundy carpet so the pattern reads as dense metallic
|
|
8557
8543
|
weave at room scale (executive boardroom polish). */
|
|
8544
|
+
/* ─── critique · DEEP-GREEN WOOL CARPET ───────────────────────
|
|
8545
|
+
64×64 near-solid deep forest-green carpet · only a whisper of
|
|
8546
|
+
low-contrast wool flecks (texture, not pattern). Replaced the
|
|
8547
|
+
busy brass-on-gunmetal grid, which read too loud. Deep green is
|
|
8548
|
+
the classic gentleman's-study pairing for the mahogany +
|
|
8549
|
+
brass executive panel walls — calm, grounding, high-end. */
|
|
8558
8550
|
.roundtable-stage[data-floor="critique"] {
|
|
8559
|
-
--floor-bg: #
|
|
8551
|
+
--floor-bg: #2F3A30;
|
|
8560
8552
|
--rt-chair-name: #E8C788;
|
|
8561
|
-
--floor-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='
|
|
8553
|
+
--floor-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='64' height='64' shape-rendering='crispEdges'><rect width='64' height='64' fill='%232F3A30'/><rect x='6' y='8' width='1' height='1' fill='%233C493C'/><rect x='24' y='5' width='1' height='1' fill='%233C493C'/><rect x='42' y='12' width='1' height='1' fill='%233C493C'/><rect x='58' y='7' width='1' height='1' fill='%233C493C'/><rect x='14' y='26' width='1' height='1' fill='%233C493C'/><rect x='34' y='22' width='1' height='1' fill='%233C493C'/><rect x='50' y='30' width='1' height='1' fill='%233C493C'/><rect x='9' y='44' width='1' height='1' fill='%233C493C'/><rect x='28' y='50' width='1' height='1' fill='%233C493C'/><rect x='46' y='46' width='1' height='1' fill='%233C493C'/><rect x='56' y='56' width='1' height='1' fill='%233C493C'/><rect x='18' y='60' width='1' height='1' fill='%233C493C'/><rect x='12' y='14' width='1' height='1' fill='%23283227'/><rect x='30' y='9' width='1' height='1' fill='%23283227'/><rect x='48' y='6' width='1' height='1' fill='%23283227'/><rect x='60' y='18' width='1' height='1' fill='%23283227'/><rect x='8' y='34' width='1' height='1' fill='%23283227'/><rect x='36' y='30' width='1' height='1' fill='%23283227'/><rect x='52' y='40' width='1' height='1' fill='%23283227'/><rect x='20' y='52' width='1' height='1' fill='%23283227'/><rect x='40' y='58' width='1' height='1' fill='%23283227'/><rect x='26' y='36' width='1' height='1' fill='%23283227'/><rect x='54' y='24' width='1' height='1' fill='%23283227'/><rect x='15' y='42' width='1' height='1' fill='%23283227'/></svg>");
|
|
8562
8554
|
}
|
|
8563
8555
|
|
|
8564
8556
|
/* 8-bit pixel-art conference table · sized to occupy the
|
|
@@ -9360,8 +9352,8 @@
|
|
|
9360
9352
|
|
|
9361
9353
|
/* Initial-letter avatar chip · fallback when the user has no
|
|
9362
9354
|
`prefs.avatarSeed` configured. Mirrors the sidebar foot's
|
|
9363
|
-
|
|
9364
|
-
|
|
9355
|
+
placeholder chip so the seat reads as "the user, no custom
|
|
9356
|
+
avatar" rather than empty space. */
|
|
9365
9357
|
.rt-avatar-user.rt-avatar-initial {
|
|
9366
9358
|
display: inline-flex;
|
|
9367
9359
|
align-items: center;
|
|
@@ -9374,14 +9366,14 @@
|
|
|
9374
9366
|
font-weight: 700;
|
|
9375
9367
|
text-transform: uppercase;
|
|
9376
9368
|
}
|
|
9377
|
-
/*
|
|
9378
|
-
|
|
9379
|
-
to the same box as a regular
|
|
9380
|
-
wrapper itself stays transparent
|
|
9381
|
-
its own surface, and the chair
|
|
9382
|
-
letterboxed area (the
|
|
9383
|
-
portrait 48×56, so without transparent
|
|
9384
|
-
above + below the
|
|
9369
|
+
/* Portrait avatar wrapper · when an avatar seed IS present, an
|
|
9370
|
+
Avatar3DSnap PNG is injected by app.renderRoundTable; this
|
|
9371
|
+
wrapper constrains it to the same box as a regular
|
|
9372
|
+
`<img class="rt-avatar">`. The wrapper itself stays transparent
|
|
9373
|
+
— the rendered PNG carries its own surface, and the chair
|
|
9374
|
+
sprite shows through any letterboxed area (the snap is square,
|
|
9375
|
+
the seat-avatar box is portrait 48×56, so without transparent
|
|
9376
|
+
bg a dark block paints above + below the image). */
|
|
9385
9377
|
.rt-avatar-user.has-pixel-av {
|
|
9386
9378
|
display: flex;
|
|
9387
9379
|
align-items: center;
|
|
@@ -11422,14 +11414,14 @@
|
|
|
11422
11414
|
display: grid !important;
|
|
11423
11415
|
align-content: center !important;
|
|
11424
11416
|
justify-items: stretch !important;
|
|
11425
|
-
/* `.chat`
|
|
11426
|
-
`.
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11430
|
-
|
|
11431
|
-
|
|
11432
|
-
padding
|
|
11417
|
+
/* `.chat` carries gutter padding meant for the room view (top
|
|
11418
|
+
clears the frosted `.room-head`, bottom reserves space for
|
|
11419
|
+
the floating `.ib-stack`). Neither applies to the new-room /
|
|
11420
|
+
new-agent composers — `.room-head:empty` and there's no
|
|
11421
|
+
`.ib-stack`, so the inherited padding just throws off centring
|
|
11422
|
+
and steals horizontal width from the cmp card. Zero it out;
|
|
11423
|
+
`.cmp` carries its own breathing room. */
|
|
11424
|
+
padding: 0 !important;
|
|
11433
11425
|
}
|
|
11434
11426
|
.chat.chat--composer > [data-chat-messages] {
|
|
11435
11427
|
width: 100% !important;
|
|
@@ -11450,8 +11442,11 @@
|
|
|
11450
11442
|
`50vh - 110px` puts the hero+input vertical midpoint at 50vh.
|
|
11451
11443
|
`max(32px, …)` keeps the original padding floor on tiny viewports
|
|
11452
11444
|
where the calc would go negative.
|
|
11453
|
-
Toggled by JS (updateComposerOverflow) on render + resize.
|
|
11454
|
-
|
|
11445
|
+
Toggled by JS (updateComposerOverflow) on render + resize.
|
|
11446
|
+
Scoped to NOT apply when the new-agent composer (`.ag-cmp`) is
|
|
11447
|
+
mounted — the agent composer keeps the default grid-centre
|
|
11448
|
+
layout regardless of natural height (per user spec). */
|
|
11449
|
+
.chat.chat--composer.chat--composer-overflow:not(:has(.ag-cmp)) {
|
|
11455
11450
|
display: block !important;
|
|
11456
11451
|
align-content: initial !important;
|
|
11457
11452
|
overflow-y: auto;
|
|
@@ -12322,7 +12317,7 @@
|
|
|
12322
12317
|
.cmp-celeb-card {
|
|
12323
12318
|
position: relative;
|
|
12324
12319
|
display: grid;
|
|
12325
|
-
grid-template-columns:
|
|
12320
|
+
grid-template-columns: 64px 1fr;
|
|
12326
12321
|
gap: 14px;
|
|
12327
12322
|
align-items: stretch;
|
|
12328
12323
|
width: 100%;
|
|
@@ -12343,12 +12338,8 @@
|
|
|
12343
12338
|
display: flex;
|
|
12344
12339
|
align-items: center;
|
|
12345
12340
|
justify-content: center;
|
|
12346
|
-
width:
|
|
12347
|
-
height:
|
|
12348
|
-
border-radius: 4px;
|
|
12349
|
-
overflow: hidden;
|
|
12350
|
-
background: var(--panel);
|
|
12351
|
-
border: 1px solid var(--line);
|
|
12341
|
+
width: 64px;
|
|
12342
|
+
height: 64px;
|
|
12352
12343
|
}
|
|
12353
12344
|
.cmp-celeb-img {
|
|
12354
12345
|
width: 100%;
|
|
@@ -15764,11 +15755,18 @@
|
|
|
15764
15755
|
<script src="room-settings.js" defer></script>
|
|
15765
15756
|
<link rel="stylesheet" href="adjourn-overlay.css">
|
|
15766
15757
|
<!-- Avatar skill must load before any UI that calls it (new-agent, user-settings). -->
|
|
15767
|
-
|
|
15758
|
+
<!-- avatar-3d-snap · shared head-and-shoulders 3D portrait helper
|
|
15759
|
+
(replaces the retired AvatarSkill 8-bit SVG generator). Loads as
|
|
15760
|
+
a classic script so window.Avatar3DSnap is available before app.js
|
|
15761
|
+
init(). Internally lazy-loads three.js + avatar-3d.js only when a
|
|
15762
|
+
portrait is actually requested. -->
|
|
15763
|
+
<script src="avatar-3d-snap.js" defer></script>
|
|
15768
15764
|
<link rel="stylesheet" href="agent-profile.css">
|
|
15769
15765
|
<script src="agent-profile.js" defer></script>
|
|
15770
15766
|
<link rel="stylesheet" href="new-agent.css">
|
|
15771
15767
|
<script src="new-agent.js" defer></script>
|
|
15768
|
+
<link rel="stylesheet" href="avatar3d-editor.css">
|
|
15769
|
+
<script type="module" src="avatar3d-editor.js"></script>
|
|
15772
15770
|
<link rel="stylesheet" href="user-settings.css">
|
|
15773
15771
|
<script type="module" src="keys-store.js"></script>
|
|
15774
15772
|
<script src="key-validators.js" defer></script>
|
|
@@ -15778,6 +15776,7 @@
|
|
|
15778
15776
|
<script src="mention-picker.js" defer></script>
|
|
15779
15777
|
<script src="auto-hide-scroll.js" defer></script>
|
|
15780
15778
|
<link rel="stylesheet" href="onboarding.css">
|
|
15779
|
+
<script src="core-avatars.js" defer></script>
|
|
15781
15780
|
<script src="voice-3d-banner.js" defer></script>
|
|
15782
15781
|
<script src="onboarding.js" defer></script>
|
|
15783
15782
|
<link rel="stylesheet" href="voice-onboarding.css">
|
|
@@ -15795,9 +15794,9 @@
|
|
|
15795
15794
|
<!-- voice-3d · voxel pixel-art 3D round-table renderer. ES module
|
|
15796
15795
|
(imports three.js from /vendor/three.module.min.js). Loads in
|
|
15797
15796
|
parallel with app.js · no ordering dependency, app.js feature-
|
|
15798
|
-
detects window.VoiceStage3D at render time.
|
|
15799
|
-
|
|
15800
|
-
|
|
15797
|
+
detects window.VoiceStage3D at render time. The voice room is
|
|
15798
|
+
3D-only as of 2026-05; the legacy 2D SVG stage + the user-
|
|
15799
|
+
settings toggle have been retired. -->
|
|
15801
15800
|
<script type="module" src="voice-3d.js"></script>
|
|
15802
15801
|
<!-- voice-recorder · meeting capture. Lazy module · only allocates
|
|
15803
15802
|
anything on first start(). Loaded BEFORE app.js so the global
|
|
@@ -16078,12 +16077,7 @@
|
|
|
16078
16077
|
sidebar uses); only the logo + rooms + agents expand. -->
|
|
16079
16078
|
<aside class="mini-sidebar" aria-label="Collapsed sidebar navigation">
|
|
16080
16079
|
<div class="mini-top">
|
|
16081
|
-
<button type="button" class="mini-btn mini-logo" data-sidebar-expand data-i18n-tip="sidebar_expand" data-tip="Expand sidebar" aria-label="Expand sidebar">
|
|
16082
|
-
<span class="mini-logo-av">
|
|
16083
|
-
<img class="cl-open" src="/avatars/chair.svg" alt="" aria-hidden="true">
|
|
16084
|
-
<img class="cl-blink" src="/avatars/chair-blink.svg" alt="" aria-hidden="true">
|
|
16085
|
-
</span>
|
|
16086
|
-
</button>
|
|
16080
|
+
<button type="button" class="mini-btn mini-logo" data-sidebar-expand data-i18n-tip="sidebar_expand" data-tip="Expand sidebar" aria-label="Expand sidebar"></button>
|
|
16087
16081
|
<button type="button" class="mini-btn mini-new-room" data-convene-trigger data-i18n-tip="sidebar_new_room" data-tip="New room" aria-label="New room"></button>
|
|
16088
16082
|
<button type="button" class="mini-btn mini-new-agent" data-agent-composer-trigger data-i18n-tip="sidebar_new_agent" data-tip="New agent" aria-label="New agent"></button>
|
|
16089
16083
|
<button type="button" class="mini-btn mini-search" data-search-trigger data-tip="Search" aria-label="Search"></button>
|
|
@@ -17018,6 +17012,22 @@
|
|
|
17018
17012
|
const lsGet = (k) => { try { return localStorage.getItem(k); } catch (_) { return null; } };
|
|
17019
17013
|
const lsSet = (k, v) => { try { localStorage.setItem(k, v); } catch (_) {} };
|
|
17020
17014
|
|
|
17015
|
+
/* Anti-flash boot guard · runs SYNCHRONOUSLY during parse, before
|
|
17016
|
+
app.js's deferred init paints the new-room composer. If this
|
|
17017
|
+
refresh will restore a saved agent profile, mask the room view
|
|
17018
|
+
now (see the `.bb-restoring-agent` CSS rule) so the composer never
|
|
17019
|
+
flashes under the profile. Cleared by clearAgentRestoreGuard once
|
|
17020
|
+
the profile opens or the restore gives up. */
|
|
17021
|
+
if (lsGet(TAB_KEY) === "agents") {
|
|
17022
|
+
const _savedAgent = lsGet(AGENTS_KEY);
|
|
17023
|
+
if (_savedAgent && _savedAgent !== "new") {
|
|
17024
|
+
document.documentElement.classList.add("bb-restoring-agent");
|
|
17025
|
+
}
|
|
17026
|
+
}
|
|
17027
|
+
function clearAgentRestoreGuard() {
|
|
17028
|
+
document.documentElement.classList.remove("bb-restoring-agent");
|
|
17029
|
+
}
|
|
17030
|
+
|
|
17021
17031
|
/* Truth source for "does this room exist?" is `window.app.rooms`,
|
|
17022
17032
|
not the DOM. The sidebar may not have rendered yet on first
|
|
17023
17033
|
restore (app.init's loadInitial is async and runs concurrently
|
|
@@ -17124,14 +17134,25 @@
|
|
|
17124
17134
|
|
|
17125
17135
|
function applyAgentsSubState(sub) {
|
|
17126
17136
|
if (!sub || sub === "new") {
|
|
17137
|
+
clearAgentRestoreGuard();
|
|
17127
17138
|
if (window.app && typeof window.app.setComposerMode === "function") {
|
|
17128
17139
|
window.app.setComposerMode("agent");
|
|
17129
17140
|
}
|
|
17130
17141
|
return;
|
|
17131
17142
|
}
|
|
17132
17143
|
if (typeof window.openAgentProfile === "function") {
|
|
17133
|
-
try {
|
|
17144
|
+
try {
|
|
17145
|
+
window.openAgentProfile(sub);
|
|
17146
|
+
// Drop the boot guard only once the profile view is actually
|
|
17147
|
+
// visible. open() early-returns (leaving the agent view
|
|
17148
|
+
// hidden) when the agent record hasn't loaded yet — in that
|
|
17149
|
+
// case the retry tick calls us again and the room view stays
|
|
17150
|
+
// masked until the profile genuinely opens.
|
|
17151
|
+
const agentView = document.querySelector('[data-main-view="agent"]');
|
|
17152
|
+
if (agentView && !agentView.hasAttribute("hidden")) clearAgentRestoreGuard();
|
|
17153
|
+
}
|
|
17134
17154
|
catch (_) {
|
|
17155
|
+
clearAgentRestoreGuard();
|
|
17135
17156
|
lsSet(AGENTS_KEY, "new");
|
|
17136
17157
|
if (window.app && typeof window.app.setComposerMode === "function") {
|
|
17137
17158
|
window.app.setComposerMode("agent");
|
|
@@ -17402,10 +17423,17 @@
|
|
|
17402
17423
|
const tick = () => {
|
|
17403
17424
|
attempts += 1;
|
|
17404
17425
|
const id = lsGet(AGENTS_KEY);
|
|
17405
|
-
if (!id || id === "new") return;
|
|
17426
|
+
if (!id || id === "new") { clearAgentRestoreGuard(); return; }
|
|
17406
17427
|
const haveAny = document.querySelector(".agents-scroll .agent-row[data-agent-profile]");
|
|
17407
|
-
if (haveAny) {
|
|
17428
|
+
if (haveAny) {
|
|
17429
|
+
applyAgentsSubState(id);
|
|
17430
|
+
// If the profile opened, the guard is already cleared and we
|
|
17431
|
+
// stop. If open() couldn't resolve the agent yet (guard still
|
|
17432
|
+
// set), keep retrying instead of leaving the room view masked.
|
|
17433
|
+
if (!document.documentElement.classList.contains("bb-restoring-agent")) return;
|
|
17434
|
+
}
|
|
17408
17435
|
if (attempts < 10) setTimeout(tick, 250);
|
|
17436
|
+
else clearAgentRestoreGuard(); // give up · reveal the composer
|
|
17409
17437
|
};
|
|
17410
17438
|
setTimeout(tick, 250);
|
|
17411
17439
|
}
|
|
@@ -17595,27 +17623,27 @@
|
|
|
17595
17623
|
<svg class="rt-plant rt-plant-2" viewBox="0 0 48 60"><use href="#vrp-plant-2"/></svg>
|
|
17596
17624
|
<div class="rt-seat rt-seat-chair" style="left:50%; top:82%;">
|
|
17597
17625
|
<svg class="rt-chair rt-chair--mod" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair-mod"/></svg>
|
|
17598
|
-
<img class="rt-avatar" src="avatars/chair.
|
|
17626
|
+
<img class="rt-avatar" src="avatars/3d/chair.png" alt="">
|
|
17599
17627
|
<div class="rt-name">CHAIR</div>
|
|
17600
17628
|
</div>
|
|
17601
17629
|
<div class="rt-seat" style="left:14.89%; top:43.11%;">
|
|
17602
17630
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17603
|
-
<img class="rt-avatar" src="avatars/socrates.
|
|
17631
|
+
<img class="rt-avatar" src="avatars/3d/socrates.png" alt="">
|
|
17604
17632
|
<div class="rt-name">SOCRATES</div>
|
|
17605
17633
|
</div>
|
|
17606
17634
|
<div class="rt-seat rt-seat-speaking" style="left:35.45%; top:33.37%;">
|
|
17607
17635
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17608
|
-
<img class="rt-avatar" src="avatars/first-principles.
|
|
17636
|
+
<img class="rt-avatar" src="avatars/3d/first-principles.png" alt="">
|
|
17609
17637
|
<div class="rt-bubble">Speaking</div>
|
|
17610
17638
|
</div>
|
|
17611
17639
|
<div class="rt-seat" style="left:64.55%; top:33.37%;">
|
|
17612
17640
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17613
|
-
<img class="rt-avatar" src="avatars/value-investor.
|
|
17641
|
+
<img class="rt-avatar" src="avatars/3d/value-investor.png" alt="">
|
|
17614
17642
|
<div class="rt-name">INVESTOR</div>
|
|
17615
17643
|
</div>
|
|
17616
17644
|
<div class="rt-seat" style="left:85.11%; top:43.11%;">
|
|
17617
17645
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17618
|
-
<img class="rt-avatar" src="avatars/historian.
|
|
17646
|
+
<img class="rt-avatar" src="avatars/3d/historian.png" alt="">
|
|
17619
17647
|
<div class="rt-name">HISTORIAN</div>
|
|
17620
17648
|
</div>
|
|
17621
17649
|
</div>
|
|
@@ -17633,32 +17661,32 @@
|
|
|
17633
17661
|
<svg class="rt-plant rt-plant-2" viewBox="0 0 48 60"><use href="#vrp-plant-2"/></svg>
|
|
17634
17662
|
<div class="rt-seat rt-seat-chair" style="left:50%; top:82%;">
|
|
17635
17663
|
<svg class="rt-chair rt-chair--mod" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair-mod"/></svg>
|
|
17636
|
-
<img class="rt-avatar" src="avatars/chair.
|
|
17664
|
+
<img class="rt-avatar" src="avatars/3d/chair.png" alt="">
|
|
17637
17665
|
<div class="rt-name">CHAIR</div>
|
|
17638
17666
|
</div>
|
|
17639
17667
|
<div class="rt-seat" style="left:13.86%; top:44.44%;">
|
|
17640
17668
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17641
|
-
<img class="rt-avatar" src="avatars/socrates.
|
|
17669
|
+
<img class="rt-avatar" src="avatars/3d/socrates.png" alt="">
|
|
17642
17670
|
<div class="rt-name">SOCRATES</div>
|
|
17643
17671
|
</div>
|
|
17644
17672
|
<div class="rt-seat" style="left:27.66%; top:35.44%;">
|
|
17645
17673
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17646
|
-
<img class="rt-avatar" src="avatars/first-principles.
|
|
17674
|
+
<img class="rt-avatar" src="avatars/3d/first-principles.png" alt="">
|
|
17647
17675
|
<div class="rt-name">PRINCIPLES</div>
|
|
17648
17676
|
</div>
|
|
17649
17677
|
<div class="rt-seat" style="left:50%; top:32%;">
|
|
17650
17678
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17651
|
-
<img class="rt-avatar" src="avatars/value-investor.
|
|
17679
|
+
<img class="rt-avatar" src="avatars/3d/value-investor.png" alt="">
|
|
17652
17680
|
<div class="rt-name">INVESTOR</div>
|
|
17653
17681
|
</div>
|
|
17654
17682
|
<div class="rt-seat rt-seat-speaking" style="left:72.34%; top:35.44%;">
|
|
17655
17683
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17656
|
-
<img class="rt-avatar" src="avatars/historian.
|
|
17684
|
+
<img class="rt-avatar" src="avatars/3d/historian.png" alt="">
|
|
17657
17685
|
<div class="rt-bubble">Speaking</div>
|
|
17658
17686
|
</div>
|
|
17659
17687
|
<div class="rt-seat" style="left:86.14%; top:44.44%;">
|
|
17660
17688
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17661
|
-
<img class="rt-avatar" src="avatars/long-horizon.
|
|
17689
|
+
<img class="rt-avatar" src="avatars/3d/long-horizon.png" alt="">
|
|
17662
17690
|
<div class="rt-name">HORIZON</div>
|
|
17663
17691
|
</div>
|
|
17664
17692
|
</div>
|
|
@@ -17676,22 +17704,22 @@
|
|
|
17676
17704
|
<svg class="rt-plant rt-plant-2" viewBox="0 0 48 60"><use href="#vrp-plant-2"/></svg>
|
|
17677
17705
|
<div class="rt-seat rt-seat-chair" style="left:50%; top:82%;">
|
|
17678
17706
|
<svg class="rt-chair rt-chair--mod" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair-mod"/></svg>
|
|
17679
|
-
<img class="rt-avatar" src="avatars/chair.
|
|
17707
|
+
<img class="rt-avatar" src="avatars/3d/chair.png" alt="">
|
|
17680
17708
|
<div class="rt-name">CHAIR</div>
|
|
17681
17709
|
</div>
|
|
17682
17710
|
<div class="rt-seat" style="left:17.09%; top:41%;">
|
|
17683
17711
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17684
|
-
<img class="rt-avatar" src="avatars/socrates.
|
|
17712
|
+
<img class="rt-avatar" src="avatars/3d/socrates.png" alt="">
|
|
17685
17713
|
<div class="rt-name">SOCRATES</div>
|
|
17686
17714
|
</div>
|
|
17687
17715
|
<div class="rt-seat rt-seat-speaking" style="left:50%; top:32%;">
|
|
17688
17716
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17689
|
-
<img class="rt-avatar" src="avatars/first-principles.
|
|
17717
|
+
<img class="rt-avatar" src="avatars/3d/first-principles.png" alt="">
|
|
17690
17718
|
<div class="rt-bubble">Speaking</div>
|
|
17691
17719
|
</div>
|
|
17692
17720
|
<div class="rt-seat" style="left:82.91%; top:41%;">
|
|
17693
17721
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17694
|
-
<img class="rt-avatar" src="avatars/value-investor.
|
|
17722
|
+
<img class="rt-avatar" src="avatars/3d/value-investor.png" alt="">
|
|
17695
17723
|
<div class="rt-name">INVESTOR</div>
|
|
17696
17724
|
</div>
|
|
17697
17725
|
</div>
|
|
@@ -17709,27 +17737,27 @@
|
|
|
17709
17737
|
<svg class="rt-plant rt-plant-2" viewBox="0 0 48 60"><use href="#vrp-plant-2"/></svg>
|
|
17710
17738
|
<div class="rt-seat rt-seat-chair" style="left:50%; top:82%;">
|
|
17711
17739
|
<svg class="rt-chair rt-chair--mod" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair-mod"/></svg>
|
|
17712
|
-
<img class="rt-avatar" src="avatars/chair.
|
|
17740
|
+
<img class="rt-avatar" src="avatars/3d/chair.png" alt="">
|
|
17713
17741
|
<div class="rt-name">CHAIR</div>
|
|
17714
17742
|
</div>
|
|
17715
17743
|
<div class="rt-seat rt-seat-speaking" style="left:14.89%; top:43.11%;">
|
|
17716
17744
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17717
|
-
<img class="rt-avatar" src="avatars/socrates.
|
|
17745
|
+
<img class="rt-avatar" src="avatars/3d/socrates.png" alt="">
|
|
17718
17746
|
<div class="rt-bubble">Speaking</div>
|
|
17719
17747
|
</div>
|
|
17720
17748
|
<div class="rt-seat" style="left:35.45%; top:33.37%;">
|
|
17721
17749
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17722
|
-
<img class="rt-avatar" src="avatars/first-principles.
|
|
17750
|
+
<img class="rt-avatar" src="avatars/3d/first-principles.png" alt="">
|
|
17723
17751
|
<div class="rt-name">PRINCIPLES</div>
|
|
17724
17752
|
</div>
|
|
17725
17753
|
<div class="rt-seat" style="left:64.55%; top:33.37%;">
|
|
17726
17754
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17727
|
-
<img class="rt-avatar" src="avatars/value-investor.
|
|
17755
|
+
<img class="rt-avatar" src="avatars/3d/value-investor.png" alt="">
|
|
17728
17756
|
<div class="rt-name">INVESTOR</div>
|
|
17729
17757
|
</div>
|
|
17730
17758
|
<div class="rt-seat" style="left:85.11%; top:43.11%;">
|
|
17731
17759
|
<svg class="rt-chair" viewBox="0 0 32 40" preserveAspectRatio="xMidYMid meet"><use href="#vrp-chair"/></svg>
|
|
17732
|
-
<img class="rt-avatar" src="avatars/phenomenologist.
|
|
17760
|
+
<img class="rt-avatar" src="avatars/3d/phenomenologist.png" alt="">
|
|
17733
17761
|
<div class="rt-name">PHENOM</div>
|
|
17734
17762
|
</div>
|
|
17735
17763
|
</div>
|
package/public/magazine.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=900, initial-scale=1">
|
|
6
6
|
<title>Magazine · PrivateBoard</title>
|
|
7
|
-
<link rel="icon" href="/avatars/chair.
|
|
7
|
+
<link rel="icon" href="/avatars/3d/chair.png" type="image/svg+xml">
|
|
8
8
|
<!-- Playfair Display for the Vogue-style high-contrast Didot
|
|
9
9
|
logotype + serif headlines. Free Google font · no fallback
|
|
10
10
|
drama since the system Tiempos / Bodoni stack picks up. -->
|