privateboard 0.1.8 → 0.1.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "privateboard",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "PrivateBoard · your private board meeting, on call. Local-first, multi-agent thinking amplifier.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -246,11 +246,12 @@
246
246
  grid-template-columns: 1fr 1fr;
247
247
  }
248
248
  /* At desktop width the primary tile (Report · the long-form
249
- markdown mode) takes 1.5× the width of the other three so it
249
+ markdown mode) takes 1.5× the width of the other tiles so it
250
250
  reads as the default / recommended choice. The implementation
251
251
  piggybacks on grid auto-placement: the primary is always the
252
252
  first child, so giving column 1 a 1.5fr track is enough. */
253
253
  @media (min-width: 800px) {
254
+ .adjourn-mode-options-3 { grid-template-columns: 1.5fr 1fr 1fr; }
254
255
  .adjourn-mode-options-4 { grid-template-columns: 1.5fr 1fr 1fr 1fr; }
255
256
  }
256
257
  @media (max-width: 720px) {
@@ -909,6 +909,531 @@
909
909
  color: var(--text);
910
910
  background: var(--panel);
911
911
  }
912
+
913
+ /* Multiple actions in one section header (e.g. chair Memory's
914
+ "⊘ run consolidation" + "+ add note"). Sits flush right with a
915
+ tight gap so the buttons read as a paired toolbar. */
916
+ .ap-block-h-actions {
917
+ display: inline-flex;
918
+ align-items: center;
919
+ gap: 6px;
920
+ }
921
+
922
+ /* Run consolidation pill · accent-leaning border on hover so it
923
+ reads as the slightly-heavier action vs the neutral "add note". */
924
+ .ap-dream-trigger:hover {
925
+ border-color: var(--lime, #6FB572);
926
+ color: var(--lime, #6FB572);
927
+ }
928
+ .ap-dream-trigger:disabled {
929
+ opacity: 0.5;
930
+ cursor: progress;
931
+ pointer-events: none;
932
+ }
933
+
934
+ /* ─── Dream-cycle overlay · centered modal "memory sleep" stage ──
935
+ Replaces the prior inline ap-dream-status. The whole consolidation
936
+ flow (running animation + result tiles) lives inside a focused
937
+ centered modal so the widget gets the visual real estate it
938
+ needs and the user's attention is correctly directed at "the
939
+ agent is sleeping now."
940
+ Dark backdrop with light blur · click backdrop, ✕ button, or
941
+ ESC to close. State transitions (running → done / error) flip
942
+ classes on the overlay root so border + kicker tint follow. */
943
+ .dream-overlay {
944
+ position: fixed;
945
+ inset: 0;
946
+ z-index: 9500;
947
+ display: flex;
948
+ align-items: center;
949
+ justify-content: center;
950
+ padding: 24px;
951
+ font-family: var(--mono);
952
+ animation: dream-overlay-in 0.16s ease-out;
953
+ }
954
+ @keyframes dream-overlay-in {
955
+ from { opacity: 0; }
956
+ to { opacity: 1; }
957
+ }
958
+ .dream-backdrop {
959
+ position: absolute;
960
+ inset: 0;
961
+ background: rgba(0, 0, 0, 0.62);
962
+ -webkit-backdrop-filter: blur(2px);
963
+ backdrop-filter: blur(2px);
964
+ cursor: pointer;
965
+ }
966
+ .dream-modal {
967
+ position: relative;
968
+ z-index: 1;
969
+ width: 100%;
970
+ max-width: 540px;
971
+ background: var(--panel, #131312);
972
+ border: 0.5px solid var(--lime-dim, #2D5532);
973
+ color: var(--text);
974
+ display: flex;
975
+ flex-direction: column;
976
+ /* Subtle "breathing" glow during the sleep cycle so the modal
977
+ itself feels alive · 5s slow pulse to match a calm respiratory
978
+ rhythm. Removed when the dream resolves. */
979
+ animation: dream-modal-rise 0.24s ease-out, dream-breathe 5s ease-in-out 0.24s infinite;
980
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.5);
981
+ }
982
+ .dream-overlay.is-done .dream-modal,
983
+ .dream-overlay.is-error .dream-modal {
984
+ /* Stop the breathing once we land on a result · keep the
985
+ entrance rise but drop the infinite pulse. */
986
+ animation: dream-modal-rise 0.24s ease-out;
987
+ }
988
+ .dream-overlay.is-done .dream-modal {
989
+ border-color: var(--lime, #6FB572);
990
+ }
991
+ .dream-overlay.is-error .dream-modal {
992
+ border-color: var(--red, #B5706A);
993
+ }
994
+ @keyframes dream-modal-rise {
995
+ from { opacity: 0; transform: translateY(8px); }
996
+ to { opacity: 1; transform: translateY(0); }
997
+ }
998
+ @keyframes dream-breathe {
999
+ 0%, 100% { box-shadow: 0 18px 60px rgba(0, 0, 0, 0.5), inset 0 0 0 0 rgba(111, 181, 114, 0); }
1000
+ 50% { box-shadow: 0 18px 60px rgba(0, 0, 0, 0.5), inset 0 0 22px 0 rgba(111, 181, 114, 0.10); }
1001
+ }
1002
+
1003
+ /* Modal head · classification-style strip with the moon glyph
1004
+ kicker on the left + ✕ close on the right. Same vocabulary as
1005
+ the adjourn / supplement modals so they all read as one family. */
1006
+ .dream-modal-head {
1007
+ display: flex;
1008
+ align-items: center;
1009
+ justify-content: space-between;
1010
+ padding: 10px 14px;
1011
+ border-bottom: 0.5px solid var(--line);
1012
+ background: var(--panel-2);
1013
+ }
1014
+ .dream-modal-kicker {
1015
+ display: inline-flex;
1016
+ align-items: center;
1017
+ gap: 8px;
1018
+ font-family: var(--mono);
1019
+ font-size: 10px;
1020
+ font-weight: 700;
1021
+ letter-spacing: 0.18em;
1022
+ text-transform: uppercase;
1023
+ color: var(--lime, #6FB572);
1024
+ }
1025
+ .dream-modal-glyph {
1026
+ font-family: var(--font-human);
1027
+ font-size: 14px;
1028
+ line-height: 1;
1029
+ letter-spacing: 0;
1030
+ }
1031
+ .dream-modal-close {
1032
+ width: 22px; height: 22px;
1033
+ background: transparent;
1034
+ border: 0.5px solid var(--line-bright);
1035
+ color: var(--text-dim);
1036
+ font-size: 11px;
1037
+ line-height: 1;
1038
+ cursor: pointer;
1039
+ display: inline-flex;
1040
+ align-items: center;
1041
+ justify-content: center;
1042
+ transition: border-color 0.12s, color 0.12s;
1043
+ }
1044
+ .dream-modal-close:hover {
1045
+ border-color: var(--lime, #6FB572);
1046
+ color: var(--lime, #6FB572);
1047
+ }
1048
+ /* Body · pinned min-height so the modal doesn't visibly resize
1049
+ between running ↔ done states. Both states use `.dream-stage-pad`
1050
+ as their root grid which fills the body cleanly. */
1051
+ .dream-modal-body {
1052
+ position: relative;
1053
+ overflow: hidden;
1054
+ min-height: 320px;
1055
+ display: flex;
1056
+ flex-direction: column;
1057
+ }
1058
+
1059
+ /* Shared stage layout · 4 stacked zones with explicit gaps so
1060
+ running and done both occupy the same visual real estate:
1061
+ 1. section kicker (24px · top label + step / delta chip)
1062
+ 2. hero / sky (flex 1 · primary visualization area)
1063
+ 3. divider hairline
1064
+ 4. caption / tiles (auto · footer / breakdown row)
1065
+ Quiet variants (`.is-quiet`) drop the divider — there's no
1066
+ tile row to introduce, so the dashed hairline + the modal's
1067
+ own bottom border were reading as two stacked lines below the
1068
+ short footnote caption. */
1069
+ .dream-stage-pad {
1070
+ display: grid;
1071
+ grid-template-rows: auto 1fr auto auto;
1072
+ gap: 14px;
1073
+ padding: 18px 22px 20px;
1074
+ flex: 1;
1075
+ min-height: 0;
1076
+ }
1077
+ .dream-stage-pad.is-quiet {
1078
+ grid-template-rows: auto 1fr auto;
1079
+ }
1080
+
1081
+ .dream-section-kicker {
1082
+ display: flex;
1083
+ align-items: center;
1084
+ justify-content: space-between;
1085
+ gap: 12px;
1086
+ }
1087
+ .dream-kicker-text {
1088
+ font-family: var(--mono);
1089
+ font-size: 9px;
1090
+ font-weight: 700;
1091
+ letter-spacing: 0.18em;
1092
+ text-transform: uppercase;
1093
+ color: var(--text-faint);
1094
+ }
1095
+ .dream-step {
1096
+ font-family: var(--mono);
1097
+ font-size: 9px;
1098
+ font-weight: 700;
1099
+ letter-spacing: 0.14em;
1100
+ text-transform: uppercase;
1101
+ color: var(--text-soft);
1102
+ padding: 2px 8px;
1103
+ border: 0.5px solid var(--line-bright);
1104
+ background: var(--panel-2);
1105
+ }
1106
+ .dream-step.is-quiet { color: var(--text-dim); border-color: var(--line); }
1107
+ .dream-step.is-shrink { color: var(--lime, #6FB572); border-color: var(--lime, #6FB572); }
1108
+ .dream-step.is-grow { color: var(--cyan, #6A9B97); border-color: var(--cyan, #6A9B97); }
1109
+ .dream-step.is-flat { color: var(--text-soft); border-color: var(--line-bright); }
1110
+ .dream-step.is-error { color: var(--red, #B5706A); border-color: var(--red, #B5706A); }
1111
+
1112
+ /* Hairline divider between hero and footer. Mirrors the dotted
1113
+ separator style the chair Memory section uses in the agent
1114
+ profile panes. */
1115
+ .dream-divider {
1116
+ height: 0;
1117
+ border-top: 0.5px dashed var(--line-bright);
1118
+ }
1119
+
1120
+ /* Caption row · used by running (rotating phase) and quiet result
1121
+ variants (no-op / error footnotes). */
1122
+ .dream-caption {
1123
+ display: flex;
1124
+ align-items: center;
1125
+ min-height: 28px;
1126
+ }
1127
+ .dream-caption-foot {
1128
+ font-family: var(--font-human);
1129
+ font-size: 11.5px;
1130
+ color: var(--text-soft);
1131
+ letter-spacing: -0.003em;
1132
+ font-style: italic;
1133
+ }
1134
+
1135
+ /* Frame · the running-state's visualization · sky (Z characters)
1136
+ on top, lanes (sweeping bars) on the bottom. Slots into the
1137
+ `.dream-stage-pad` 1fr zone, so it grows to fill whatever
1138
+ vertical room the modal allocates between kicker and divider. */
1139
+ .dream-frame {
1140
+ display: flex;
1141
+ flex-direction: column;
1142
+ gap: 14px;
1143
+ position: relative;
1144
+ min-height: 0;
1145
+ }
1146
+
1147
+ /* Sky · 60px band where Z characters drift. Each Z is absolutely
1148
+ positioned and animates `translateY` from bottom to top with a
1149
+ fade, then loops with a stagger so the animation doesn't look
1150
+ mechanical. Drift stays inside the band so the Z never bleeds
1151
+ into the lanes below. */
1152
+ .dream-sky {
1153
+ position: relative;
1154
+ height: 60px;
1155
+ overflow: hidden;
1156
+ }
1157
+ .dream-z {
1158
+ position: absolute;
1159
+ bottom: 0;
1160
+ font-family: var(--font-human);
1161
+ font-weight: 700;
1162
+ color: var(--lime, #6FB572);
1163
+ opacity: 0;
1164
+ animation: dream-z-float 3.4s ease-out infinite;
1165
+ text-shadow: 0 0 6px rgba(111, 181, 114, 0.3);
1166
+ pointer-events: none;
1167
+ line-height: 1;
1168
+ }
1169
+ .dream-z.z1 { left: 14%; font-size: 18px; animation-delay: 0s; }
1170
+ .dream-z.z2 { left: 30%; font-size: 13px; animation-delay: 0.6s; }
1171
+ .dream-z.z3 { left: 50%; font-size: 11px; animation-delay: 1.2s; }
1172
+ .dream-z.z4 { left: 70%; font-size: 16px; animation-delay: 1.7s; }
1173
+ .dream-z.z5 { left: 86%; font-size: 12px; animation-delay: 2.4s; }
1174
+
1175
+ @keyframes dream-z-float {
1176
+ 0% { transform: translateY(10px) rotate(-4deg); opacity: 0; }
1177
+ 25% { transform: translateY(0) rotate(-2deg); opacity: 1; }
1178
+ 100% { transform: translateY(-44px) rotate(8deg); opacity: 0; }
1179
+ }
1180
+
1181
+ /* Lanes · 3 rows, one per pipeline operation. Each lane has:
1182
+ · a 64px mono label on the left
1183
+ · a thin track that contains a moving "head" bar that sweeps
1184
+ left→right and loops with a stagger across the three lanes
1185
+ so they read as a moving processing pipeline rather than
1186
+ three independent loaders. */
1187
+ .dream-lanes {
1188
+ display: grid;
1189
+ grid-template-rows: 1fr 1fr 1fr;
1190
+ height: 56px;
1191
+ gap: 6px;
1192
+ }
1193
+ .dream-lane {
1194
+ display: grid;
1195
+ grid-template-columns: 64px 1fr;
1196
+ align-items: center;
1197
+ gap: 10px;
1198
+ font-size: 8.5px;
1199
+ font-weight: 700;
1200
+ letter-spacing: 0.18em;
1201
+ text-transform: uppercase;
1202
+ min-width: 0;
1203
+ }
1204
+ .dream-lane-label {
1205
+ color: var(--text-faint);
1206
+ text-align: right;
1207
+ white-space: nowrap;
1208
+ }
1209
+ .dream-lane-bar {
1210
+ position: relative;
1211
+ height: 2px;
1212
+ background: var(--line);
1213
+ overflow: hidden;
1214
+ }
1215
+ .dream-lane-bar i {
1216
+ position: absolute;
1217
+ top: 0;
1218
+ left: -30%;
1219
+ width: 30%;
1220
+ height: 100%;
1221
+ background: linear-gradient(
1222
+ to right,
1223
+ transparent,
1224
+ var(--lime, #6FB572) 50%,
1225
+ transparent
1226
+ );
1227
+ animation: dream-sweep 1.8s ease-in-out infinite;
1228
+ }
1229
+ .dream-lane.lane-decay .dream-lane-bar i { animation-delay: 0s; }
1230
+ .dream-lane.lane-merge .dream-lane-bar i { animation-delay: 0.3s; }
1231
+ .dream-lane.lane-promote .dream-lane-bar i { animation-delay: 0.6s; }
1232
+
1233
+ @keyframes dream-sweep {
1234
+ 0% { left: -30%; }
1235
+ 100% { left: 100%; }
1236
+ }
1237
+
1238
+ /* Caption · kicker + rotating phase text. Sits below the lanes
1239
+ with explicit padding-top so the phase line has visual room to
1240
+ breathe (earlier this collided into the bottom lane bar when
1241
+ long phrases like "merging clusters into canonical notes…"
1242
+ wrapped). `min-height` reserves 2 lines of phase room without
1243
+ forcing the height when the text is short. */
1244
+ .dream-caption {
1245
+ display: flex;
1246
+ flex-direction: column;
1247
+ gap: 4px;
1248
+ padding-top: 4px;
1249
+ border-top: 0.5px dashed var(--line);
1250
+ min-height: 38px;
1251
+ }
1252
+ .dream-caption-kicker {
1253
+ font-size: 9px;
1254
+ font-weight: 700;
1255
+ letter-spacing: 0.18em;
1256
+ text-transform: uppercase;
1257
+ color: var(--text-faint);
1258
+ }
1259
+ .dream-phase {
1260
+ font-size: 11px;
1261
+ letter-spacing: 0.02em;
1262
+ color: var(--lime, #6FB572);
1263
+ line-height: 1.4;
1264
+ /* Subtle flicker so the static word doesn't feel dead between
1265
+ the 1.6s text rotations. Low amplitude · doesn't compete with
1266
+ the lane sweeps. */
1267
+ animation: dream-phase-flicker 2.4s ease-in-out infinite;
1268
+ }
1269
+ @keyframes dream-phase-flicker {
1270
+ 0%, 100% { opacity: 0.9; }
1271
+ 50% { opacity: 1; }
1272
+ }
1273
+
1274
+ /* ─── Hero · primary visualization in the done state ────────────
1275
+ Two layouts share this class:
1276
+ · `.dream-hero` (default) · big numerals · the
1277
+ "consolidated" celebration when something actually changed.
1278
+ · `.dream-hero.is-quiet` · text-forward variant for
1279
+ no-op / error states · glyph + headline + sub-line stacked
1280
+ to the right of the moon glyph, reads more like a settled
1281
+ statement than a stat display.
1282
+ Both are flex-centered inside the `.dream-stage-pad` 1fr zone
1283
+ so the running and done states occupy the same visual height. */
1284
+ .dream-hero {
1285
+ display: flex;
1286
+ flex-direction: column;
1287
+ align-items: center;
1288
+ justify-content: center;
1289
+ gap: 10px;
1290
+ padding: 16px 8px;
1291
+ animation: dream-settle 0.42s cubic-bezier(0.2, 0.8, 0.2, 1);
1292
+ }
1293
+ @keyframes dream-settle {
1294
+ from { opacity: 0; transform: translateY(8px) scale(0.96); }
1295
+ to { opacity: 1; transform: translateY(0) scale(1); }
1296
+ }
1297
+ .dream-hero.is-quiet {
1298
+ flex-direction: row;
1299
+ align-items: center;
1300
+ justify-content: flex-start;
1301
+ gap: 16px;
1302
+ padding: 8px 4px;
1303
+ }
1304
+
1305
+ /* Quiet variant · moon / failure glyph sits in a 40px box on the
1306
+ left, paired with stacked title + sub on the right. */
1307
+ .dream-hero-glyph {
1308
+ display: inline-flex;
1309
+ align-items: center;
1310
+ justify-content: center;
1311
+ width: 44px; height: 44px;
1312
+ font-size: 22px;
1313
+ line-height: 1;
1314
+ border: 0.5px solid var(--lime, #6FB572);
1315
+ color: var(--lime, #6FB572);
1316
+ background: var(--panel-2);
1317
+ flex-shrink: 0;
1318
+ }
1319
+ .dream-overlay.is-error .dream-hero-glyph {
1320
+ border-color: var(--red, #B5706A);
1321
+ color: var(--red, #B5706A);
1322
+ }
1323
+ .dream-hero-text {
1324
+ display: flex;
1325
+ flex-direction: column;
1326
+ gap: 4px;
1327
+ min-width: 0;
1328
+ }
1329
+ .dream-hero-title {
1330
+ font-family: var(--font-human);
1331
+ font-size: 15px;
1332
+ font-weight: 700;
1333
+ letter-spacing: -0.005em;
1334
+ color: var(--text);
1335
+ }
1336
+ .dream-hero-sub {
1337
+ font-family: var(--font-human);
1338
+ font-size: 11.5px;
1339
+ color: var(--text-soft);
1340
+ letter-spacing: -0.003em;
1341
+ }
1342
+
1343
+ /* Default hero · big numerals row centered above the unit caption.
1344
+ `was → frame[now]` · the framed numeral is what catches the
1345
+ eye, the bare "before" sits one weight quieter to its left. */
1346
+ .dream-hero-numerals {
1347
+ display: flex;
1348
+ align-items: center;
1349
+ gap: 16px;
1350
+ }
1351
+ .dream-num {
1352
+ font-family: var(--mono);
1353
+ font-weight: 700;
1354
+ letter-spacing: -0.02em;
1355
+ line-height: 1;
1356
+ }
1357
+ .dream-num.was {
1358
+ font-size: 32px;
1359
+ color: var(--text-dim);
1360
+ text-decoration: line-through;
1361
+ text-decoration-color: var(--line-bright);
1362
+ text-decoration-thickness: 1px;
1363
+ }
1364
+ .dream-num-arrow {
1365
+ font-family: var(--mono);
1366
+ font-size: 18px;
1367
+ font-weight: 400;
1368
+ color: var(--text-faint);
1369
+ letter-spacing: 0;
1370
+ }
1371
+ .dream-num-frame {
1372
+ display: inline-flex;
1373
+ align-items: center;
1374
+ justify-content: center;
1375
+ padding: 8px 18px;
1376
+ border: 1px solid var(--lime, #6FB572);
1377
+ background: var(--panel-2);
1378
+ box-shadow: 0 0 24px rgba(111, 181, 114, 0.12);
1379
+ }
1380
+ .dream-num.now {
1381
+ font-size: 38px;
1382
+ color: var(--lime, #6FB572);
1383
+ }
1384
+ .dream-hero-unit {
1385
+ font-family: var(--mono);
1386
+ font-size: 10px;
1387
+ font-weight: 700;
1388
+ letter-spacing: 0.22em;
1389
+ text-transform: uppercase;
1390
+ color: var(--text-soft);
1391
+ }
1392
+
1393
+ /* Tile row · one block per operation. Empty operations render
1394
+ `.is-empty` (count 0) so the row stays a stable 4-up grid
1395
+ instead of jumping width when only some ops fired. */
1396
+ .dream-tiles {
1397
+ display: grid;
1398
+ grid-template-columns: repeat(4, minmax(0, 1fr));
1399
+ gap: 8px;
1400
+ }
1401
+ .dream-tile {
1402
+ display: flex;
1403
+ flex-direction: column;
1404
+ align-items: flex-start;
1405
+ justify-content: center;
1406
+ gap: 6px;
1407
+ padding: 10px 12px;
1408
+ border: 0.5px solid var(--line-bright);
1409
+ background: var(--panel-2);
1410
+ min-height: 56px;
1411
+ }
1412
+ .dream-tile.is-empty {
1413
+ opacity: 0.35;
1414
+ }
1415
+ .dream-tile-n {
1416
+ font-family: var(--mono);
1417
+ font-size: 22px;
1418
+ font-weight: 700;
1419
+ line-height: 1;
1420
+ letter-spacing: -0.01em;
1421
+ }
1422
+ .dream-tile-l {
1423
+ font-size: 8.5px;
1424
+ font-weight: 700;
1425
+ letter-spacing: 0.18em;
1426
+ text-transform: uppercase;
1427
+ color: var(--text-faint);
1428
+ }
1429
+ .dream-tile.is-decay { border-color: var(--text-faint, #3A382F); }
1430
+ .dream-tile.is-decay .dream-tile-n { color: var(--text-soft); }
1431
+ .dream-tile.is-merge { border-color: var(--cyan, #6A9B97); }
1432
+ .dream-tile.is-merge .dream-tile-n { color: var(--cyan, #6A9B97); }
1433
+ .dream-tile.is-supersede { border-color: var(--amber, #B59560); }
1434
+ .dream-tile.is-supersede .dream-tile-n { color: var(--amber, #B59560); }
1435
+ .dream-tile.is-promote { border-color: var(--lime, #6FB572); }
1436
+ .dream-tile.is-promote .dream-tile-n { color: var(--lime, #6FB572); }
912
1437
  .ap-sec-hint {
913
1438
  font-family: var(--mono);
914
1439
  font-size: 9px;