privateboard 0.1.20 → 0.1.21

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/public/index.html CHANGED
@@ -362,6 +362,10 @@
362
362
 
363
363
  .sidebar-head {
364
364
  padding: 8px 12px;
365
+ /* Anchor the topbar height explicitly. Was previously driven by
366
+ the 22px collapse-button's box; after the button was shrunk to a
367
+ 16px icon, the row would collapse 6px shorter without this lock. */
368
+ min-height: 38px;
365
369
  border-bottom: 0.5px solid var(--line-bright);
366
370
  display: flex;
367
371
  justify-content: space-between;
@@ -396,51 +400,58 @@
396
400
  Sits at the right edge of sidebar-head. Pure CSS glyph (no svg)
397
401
  so we can flip the direction via class without re-rendering DOM.
398
402
  Hover lime per the new-btn vocabulary. */
403
+ /* Icon-only: no border, no fill — matches `.new-btn` (Search, All
404
+ Reports, All Notes) vocabulary. The chevron is a Lucide line icon
405
+ painted via mask-image + currentColor, so hover -> lime cascades
406
+ naturally without per-state chrome to repaint. */
399
407
  .sidebar-collapse-btn {
400
408
  appearance: none;
401
- background: var(--panel-3);
402
- border: 0.5px solid var(--line-strong);
409
+ background: transparent;
410
+ border: 0;
403
411
  color: var(--text-soft);
404
412
  cursor: pointer;
405
- width: 24px;
406
- height: 22px;
413
+ width: 16px;
414
+ height: 16px;
407
415
  padding: 0;
408
- line-height: 1;
409
- font-family: var(--mono);
410
- font-size: 16px;
411
- font-weight: 700;
412
- display: inline-flex;
413
- align-items: center;
414
- justify-content: center;
415
- transition: color 0.12s, background 0.12s, border-color 0.12s;
416
416
  flex-shrink: 0;
417
- /* position:relative anchors the ::after hit-area expander below.
418
- The visual chrome stays 24×22, but the click region is enlarged
419
- to 40×38 so the cursor doesn't have to land precisely on the
420
- small button — a frequent miss with a 16px chevron in a 24×22
421
- hit box. */
417
+ transition: color 0.12s;
418
+ /* position:relative anchors the ::after hit-area expander below
419
+ so the cursor doesn't have to land precisely on the 16px icon. */
422
420
  position: relative;
423
421
  }
424
- .sidebar-collapse-btn::before { content: "‹"; }
425
- body.sidebar-collapsed .sidebar-collapse-btn::before { content: "›"; }
426
- /* Invisible hit-area expander · ::before is taken by the chevron
427
- glyph, so ::after provides the larger click rectangle. `inset:-16px`
428
- extends 16px beyond every edge (24+32=56 wide, 22+32=54 tall) so
429
- the cursor doesn't have to land precisely on a 16px chevron — a
430
- frequent miss the user has flagged twice. The pseudo-element is
431
- part of the button's render box, so hover and click in this
432
- enlarged area still fire on the button itself and trigger
433
- `:hover` styles normally — no extra JS needed. */
422
+ /* Lucide PanelLeft with 3 row-marks · matches public/icons/fold.png
423
+ (rounded panel · vertical divider · 3 short lines suggesting the
424
+ sidebar's contents on the left). One single glyph for both states;
425
+ collapsed mirrors horizontally so the "fold lines" flip to the
426
+ right edge, telegraphing "the panel will come out from that side". */
427
+ .sidebar-collapse-btn::before {
428
+ content: "";
429
+ display: block;
430
+ width: 16px;
431
+ height: 16px;
432
+ background-color: currentColor;
433
+ -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>");
434
+ 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>");
435
+ -webkit-mask-repeat: no-repeat;
436
+ mask-repeat: no-repeat;
437
+ -webkit-mask-position: center;
438
+ mask-position: center;
439
+ -webkit-mask-size: 16px 16px;
440
+ mask-size: 16px 16px;
441
+ transition: transform 0.18s;
442
+ }
443
+ body.sidebar-collapsed .sidebar-collapse-btn::before {
444
+ transform: scaleX(-1);
445
+ }
446
+ /* Invisible hit-area expander · the icon is only 16px, so this
447
+ pseudo-element grows the click rectangle by 16px on every edge
448
+ (= 48×48 hit zone) without changing the visible chrome. */
434
449
  .sidebar-collapse-btn::after {
435
450
  content: "";
436
451
  position: absolute;
437
452
  inset: -16px;
438
453
  }
439
- .sidebar-collapse-btn:hover {
440
- color: var(--lime);
441
- border-color: var(--lime-dim);
442
- background: var(--panel-2);
443
- }
454
+ .sidebar-collapse-btn:hover { color: var(--lime); }
444
455
 
445
456
  /* ─── Electron (macOS) · cede the sidebar-head logo slot to the native
446
457
  traffic lights and turn the strip into a window-drag handle.
@@ -732,30 +743,27 @@
732
743
  pinned to the top-left of the body-grid area. Frosted black
733
744
  glass with hairline border, lime on hover. z-index sits above
734
745
  chat content but below modal overlays (which use 1500+). */
746
+ /* Round chip · fold glyph centred in a 28px circle. `--bg` fill
747
+ (white on light, near-black on dark) masks the cmp-bg-deco
748
+ constellation behind it; `--lime-dim` ring anchors it to the
749
+ product's accent. Hover intensifies both ring + icon to full
750
+ `--lime` for an obvious interactive state. */
735
751
  .sidebar-expand-btn {
736
752
  display: none;
737
753
  position: absolute;
738
754
  top: 12px;
739
755
  left: 12px;
740
- width: 34px;
741
- height: 34px;
756
+ width: 28px;
757
+ height: 28px;
742
758
  align-items: center;
743
759
  justify-content: center;
744
- /* Theme-adaptive frosted backdrop · uses `--bg` (the page bg
745
- token, which flips dark ↔ light with the active appearance)
746
- at ~55 % opacity. The earlier hardcoded `rgba(8,8,8,.55)` was
747
- fine in dark mode but left a dark blob on light surfaces in
748
- the atrium / light appearance — making the hamburger icon
749
- (currentColor stroke) read against its own background tint
750
- instead of the page. */
751
- background: color-mix(in srgb, var(--bg) 55%, transparent);
752
- -webkit-backdrop-filter: blur(12px) saturate(1.05);
753
- backdrop-filter: blur(12px) saturate(1.05);
754
- border: 0.5px solid var(--line-strong);
760
+ background: var(--bg);
761
+ border: 1px solid var(--lime-dim);
762
+ border-radius: 50%;
755
763
  color: var(--text-soft);
756
764
  cursor: pointer;
757
765
  z-index: 200;
758
- transition: color 0.12s, border-color 0.12s, background 0.12s;
766
+ transition: color 0.12s, border-color 0.12s;
759
767
  appearance: none;
760
768
  padding: 0;
761
769
  }
@@ -768,8 +776,7 @@
768
776
  }
769
777
  .sidebar-expand-btn:hover {
770
778
  color: var(--lime);
771
- border-color: var(--lime-dim);
772
- background: color-mix(in srgb, var(--bg) 72%, transparent);
779
+ border-color: var(--lime);
773
780
  }
774
781
  /* Hit-area expander · the visible button is 34×34, but ::after
775
782
  stretches 18px past every edge so the click target is 70×70 even
@@ -1801,26 +1808,25 @@
1801
1808
  overflow: hidden;
1802
1809
  text-overflow: ellipsis;
1803
1810
  }
1811
+ /* Icon-only chrome — same vocabulary as the sidebar's `.new-btn`
1812
+ nav icons (Search / All Reports / All Notes). No box, no border:
1813
+ just the icon glyph painted via currentColor + mask-image, with
1814
+ a hover-to-lime color transition. */
1804
1815
  .icon-btn {
1805
- width: 32px; height: 32px;
1816
+ width: 16px; height: 16px;
1806
1817
  background: transparent;
1807
- border: 0.5px solid var(--line-bright);
1818
+ border: 0;
1808
1819
  display: flex;
1809
1820
  align-items: center;
1810
1821
  justify-content: center;
1811
1822
  cursor: pointer;
1812
1823
  color: var(--text-soft);
1813
1824
  text-decoration: none;
1814
- font-size: 16px;
1815
1825
  line-height: 1;
1816
1826
  flex-shrink: 0;
1817
- transition: all 0.12s;
1818
- }
1819
- .icon-btn:hover {
1820
- background: var(--panel-3);
1821
- color: var(--lime);
1822
- border-color: var(--lime);
1827
+ transition: color 0.12s;
1823
1828
  }
1829
+ .icon-btn:hover { color: var(--lime); }
1824
1830
  /* Settings trigger · Lucide Settings (gear) glyph in the same
1825
1831
  mask-image vocabulary as the .new-btn.nav-* sidebar icons.
1826
1832
  Keeps the bottom row visually paired with the search /
@@ -2603,7 +2609,7 @@
2603
2609
  background: color-mix(in srgb, color-mix(in srgb, var(--panel-3) 78%, var(--bg) 22%) 88%, transparent);
2604
2610
  backdrop-filter: blur(24px) saturate(180%);
2605
2611
  -webkit-backdrop-filter: blur(24px) saturate(180%);
2606
- border: 0.5px solid var(--line-strong);
2612
+ border: 0.5px solid var(--accent-line);
2607
2613
  border-radius: 14px;
2608
2614
  /* No drop shadow · mirrors cmp-input-frame after the lifted
2609
2615
  card shadow was removed there. The frosted surface + hairline
@@ -2616,11 +2622,9 @@
2616
2622
  padding 0.22s ease;
2617
2623
  }
2618
2624
  .search-card:focus-within {
2619
- /* Match cmp-input-frame's focus register · softer lime ring (the
2620
- `--lime-dim` rim) instead of a hard lime border, so the
2621
- focused state reads as "warmed" rather than "selected
2622
- outline". */
2623
- border-color: var(--lime-dim, var(--lime));
2625
+ /* Default border is `--lime-dim` (subtle brand tint); focus lifts
2626
+ to full `--lime` for a clear "active" register. */
2627
+ border-color: var(--lime);
2624
2628
  }
2625
2629
  .search-page.has-results .search-card {
2626
2630
  display: flex;
@@ -9473,6 +9477,46 @@
9473
9477
  animation: rt-sub-in 0.18s ease-out;
9474
9478
  }
9475
9479
  .rt-subtitle[hidden] { display: none; }
9480
+ /* Minimize affordance · top-right corner of the subtitle panel.
9481
+ Pure icon · no frame, no background. Lucide-style "minimize-2"
9482
+ pictogram (two corner arrows pulling inward) rendered as SVG
9483
+ via mask-image so it follows currentColor. Clicking sets
9484
+ `body.is-subtitle-min` which hides the panel and reveals the
9485
+ restore CC button on the speaking-queue head. */
9486
+ .rt-sub-min {
9487
+ position: absolute;
9488
+ top: 6px;
9489
+ right: 8px;
9490
+ width: 18px;
9491
+ height: 18px;
9492
+ padding: 0;
9493
+ background: transparent;
9494
+ border: 0;
9495
+ color: rgba(244, 239, 223, 0.78);
9496
+ cursor: pointer;
9497
+ display: inline-flex;
9498
+ align-items: center;
9499
+ justify-content: center;
9500
+ pointer-events: auto;
9501
+ transition: color 0.12s;
9502
+ }
9503
+ .rt-sub-min::before {
9504
+ content: "";
9505
+ display: block;
9506
+ width: 16px;
9507
+ height: 16px;
9508
+ background-color: currentColor;
9509
+ -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'><polyline points='4 14 10 14 10 20'/><polyline points='20 10 14 10 14 4'/><line x1='14' y1='10' x2='21' y2='3'/><line x1='3' y1='21' x2='10' y2='14'/></svg>");
9510
+ 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'><polyline points='4 14 10 14 10 20'/><polyline points='20 10 14 10 14 4'/><line x1='14' y1='10' x2='21' y2='3'/><line x1='3' y1='21' x2='10' y2='14'/></svg>");
9511
+ -webkit-mask-repeat: no-repeat;
9512
+ mask-repeat: no-repeat;
9513
+ -webkit-mask-position: center;
9514
+ mask-position: center;
9515
+ -webkit-mask-size: 16px 16px;
9516
+ mask-size: 16px 16px;
9517
+ }
9518
+ .rt-sub-min:hover { color: var(--lime); }
9519
+ body.is-subtitle-min .rt-subtitle { display: none !important; }
9476
9520
  @keyframes rt-sub-in {
9477
9521
  from { opacity: 0; transform: translate(-50%, 6px); }
9478
9522
  to { opacity: 1; transform: translate(-50%, 0); }
@@ -11375,8 +11419,12 @@
11375
11419
  z-index: -1;
11376
11420
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
11377
11421
  mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
11378
- opacity: 0.85;
11422
+ /* Opacity tuned down from 0.85 — the field of small pixel motifs
11423
+ read as "fragmented dirt" especially in light, where white bg
11424
+ amplifies every dot's contrast. Light gets an extra step down. */
11425
+ opacity: 0.6;
11379
11426
  }
11427
+ :root[data-theme="light"] .cmp-bg-deco { opacity: 0.4; }
11380
11428
  .cmp-bg-deco svg { display: block; width: 100%; height: 100%; }
11381
11429
  /* 8-bit deco animations · keep subtle so the field reads as
11382
11430
  "alive" rather than "demanding attention". All animations are
@@ -11504,32 +11552,24 @@
11504
11552
  max-width: 620px;
11505
11553
  }
11506
11554
 
11507
- /* Input frame · the focal point. Mirrors the in-room `.input-bar`
11508
- register (frosted glass · hairline border · 14px radius · soft
11509
- elevation) so the new-room / new-agent composer reads as the same
11510
- control surface family as the in-room textarea. Background recipe
11511
- (layered color-mix backdrop-filter) is borrowed verbatim from
11512
- `.input-bar` (~line 14612). `overflow: hidden` keeps the toolbar
11513
- flush with the rounded corners; focus lifts to a brighter lime
11514
- border + slightly deeper shadow, matching input-bar's focus
11515
- vocabulary. */
11555
+ /* Input frame · the focal point. Previously rendered as frosted
11556
+ glass (color-mix(panel-3, bg) + backdrop-filter blur), which
11557
+ made the textarea zone end up at ~#EAEAEA / ~#1C1C19 — visually
11558
+ identical to `--strip-bg`, so the topbar disappeared into the
11559
+ input area. Switched to `var(--bg)` (clean white / clean black)
11560
+ so the textarea reads as a crisp input field and the strip-bg
11561
+ topbar above stays clearly delineated. The hairline border +
11562
+ 14px radius still carry the "discrete card" feel. */
11516
11563
  .cmp-input-frame {
11517
11564
  position: relative;
11518
- background: color-mix(in srgb, var(--panel-3) 78%, var(--bg) 22%);
11519
- background: color-mix(in srgb, color-mix(in srgb, var(--panel-3) 78%, var(--bg) 22%) 88%, transparent);
11520
- backdrop-filter: blur(24px) saturate(180%);
11521
- -webkit-backdrop-filter: blur(24px) saturate(180%);
11522
- border: 0.5px solid var(--line-strong);
11565
+ background: var(--bg);
11566
+ border: 0.5px solid var(--accent-line);
11523
11567
  border-radius: 14px;
11524
- /* No drop shadow · the frosted-glass surface + hairline border
11525
- already feel like a discrete card. The earlier lifted shadow
11526
- (`0 14px 32px -20px rgba(0,0,0,.55)`) made the composer look
11527
- like a floating modal, which fought with the deco backdrop. */
11528
11568
  transition: border-color 0.18s;
11529
11569
  overflow: hidden;
11530
11570
  }
11531
11571
  .cmp-input-frame:focus-within {
11532
- border-color: var(--lime-dim, var(--lime));
11572
+ border-color: var(--lime);
11533
11573
  }
11534
11574
  .cmp-input {
11535
11575
  display: block;
@@ -11586,8 +11626,11 @@
11586
11626
  flex-wrap: wrap;
11587
11627
  gap: 4px;
11588
11628
  padding: 6px 8px;
11589
- background: var(--panel-2);
11590
- border-bottom: 0.5px solid var(--line);
11629
+ background: var(--strip-bg);
11630
+ /* Hairline tinted with the brand colour (`--accent-line`) so the
11631
+ seam matches the strip-bg and frame border family — the whole
11632
+ composer card reads as one brand-tinted control surface. */
11633
+ border-bottom: 0.5px solid var(--accent-line);
11591
11634
  min-height: 44px;
11592
11635
  }
11593
11636
  /* Topbar buttons adopt the in-room input-bar's
@@ -11730,11 +11773,11 @@
11730
11773
  align-items: center;
11731
11774
  gap: 8px;
11732
11775
  padding: 6px 10px;
11733
- /* No hairline divider between textarea and bottombar · the
11734
- `--panel-2` toolbar tray plus the textarea's own focused-border
11735
- already telegraph the boundary; the extra rule read as visual
11736
- noise pinning the bottom of the card. */
11737
- background: var(--panel-2);
11776
+ /* Bottombar matches the topbar's brand-tinted treatment: `--strip-bg`
11777
+ fill + `--accent-line` hairline on top. The two strips bookend the
11778
+ textarea zone so the composer reads as one cohesive brand surface. */
11779
+ background: var(--strip-bg);
11780
+ border-top: 0.5px solid var(--accent-line);
11738
11781
  min-height: 48px;
11739
11782
  /* Establish a size container · child elements (notably the
11740
11783
  voice-mode toggle's text) can respond to the toolbar's width
@@ -14971,6 +15014,49 @@
14971
15014
  stable when the slot empties. */
14972
15015
  .ib-controls-right [hidden] { display: none !important; }
14973
15016
 
15017
+ /* Subtitle-restore CC button · sits inside the speaking-queue head,
15018
+ immediately to the LEFT of the queue expand/collapse toggle.
15019
+ Style register matches the sidebar's `.new-btn` icons (Lucide
15020
+ stroke pictogram + currentColor mask-image) so it reads as a
15021
+ peer affordance instead of a tinted action chip. Default hidden;
15022
+ visible only when body.is-subtitle-min. */
15023
+ .rt-sub-restore {
15024
+ display: none;
15025
+ align-items: center;
15026
+ justify-content: center;
15027
+ width: 22px;
15028
+ height: 22px;
15029
+ padding: 0;
15030
+ background: transparent;
15031
+ border: 0;
15032
+ color: var(--text-soft);
15033
+ cursor: pointer;
15034
+ flex-shrink: 0;
15035
+ transition: color 0.12s;
15036
+ }
15037
+ .rt-sub-restore::before {
15038
+ content: "";
15039
+ display: block;
15040
+ width: 16px;
15041
+ height: 16px;
15042
+ background-color: currentColor;
15043
+ -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='6' width='18' height='12' rx='2' ry='2'/><path d='M7 13h2'/><path d='M11 13h2'/><path d='M15 13h2'/><path d='M7 16h4'/><path d='M13 16h4'/></svg>");
15044
+ 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='6' width='18' height='12' rx='2' ry='2'/><path d='M7 13h2'/><path d='M11 13h2'/><path d='M15 13h2'/><path d='M7 16h4'/><path d='M13 16h4'/></svg>");
15045
+ -webkit-mask-repeat: no-repeat;
15046
+ mask-repeat: no-repeat;
15047
+ -webkit-mask-position: center;
15048
+ mask-position: center;
15049
+ -webkit-mask-size: 16px 16px;
15050
+ mask-size: 16px 16px;
15051
+ }
15052
+ body.is-subtitle-min .rt-sub-restore { display: inline-flex; }
15053
+ .rt-sub-restore:hover { color: var(--lime); }
15054
+ /* When the CC button is visible, the queue-head needs a third grid
15055
+ track to host it next to the toggle. Grid auto-collapses unused
15056
+ `auto` tracks when CC is display:none, so the default 2-col layout
15057
+ is preserved for the common case. */
15058
+ .queue-head { grid-template-columns: 1fr auto auto; }
15059
+
14974
15060
  /* ─── Inline-tool register inside the input / paused bar ───
14975
15061
  The reference design (icons/bar.png) places ALL controls
14976
15062
  below the textarea as borderless, fill-less inline tools ·
@@ -16113,6 +16199,11 @@
16113
16199
  <!-- populated by app.renderQueue() · summary follows
16114
16200
  the real queue: speaking, pending, or idle. -->
16115
16201
  </div>
16202
+ <!-- Subtitle restore · sits inside the queue head, to
16203
+ the LEFT of the expand/collapse toggle. Hidden
16204
+ unless body.is-subtitle-min. Click brings the
16205
+ minimized live-caption panel back. -->
16206
+ <button type="button" class="rt-sub-restore" data-rt-sub-restore title="Show subtitle" aria-label="Show subtitle"></button>
16116
16207
  <button type="button" class="queue-toggle" data-i18n-title="queue_toggle" aria-expanded="true">
16117
16208
  <!-- Expanded state · chevron-up = "fold the queue".
16118
16209
  Collapsed state · list-rows = "open the queue".
@@ -16274,10 +16365,15 @@
16274
16365
  sat before collapse. Frosted black glass with a 3-line
16275
16366
  hamburger glyph. -->
16276
16367
  <button type="button" class="sidebar-expand-btn" data-sidebar-expand data-i18n-title="sidebar_expand" data-i18n-tip="sidebar_expand">
16277
- <svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true">
16278
- <line x1="2.5" y1="4.25" x2="13.5" y2="4.25"/>
16279
- <line x1="2.5" y1="8" x2="13.5" y2="8"/>
16280
- <line x1="2.5" y1="11.75" x2="13.5" y2="11.75"/>
16368
+ <!-- Lucide PanelLeft + 3 row marks · same fold-style glyph as the
16369
+ in-sidebar collapse button. Unified icon vocabulary across
16370
+ both sidebar toggles. -->
16371
+ <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
16372
+ <rect x="3" y="3" width="18" height="18" rx="2"/>
16373
+ <path d="M9 3v18"/>
16374
+ <path d="M5 8h2"/>
16375
+ <path d="M5 12h2"/>
16376
+ <path d="M5 16h2"/>
16281
16377
  </svg>
16282
16378
  </button>
16283
16379