privateboard 0.1.19 → 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.
@@ -652,6 +663,14 @@
652
663
  html.is-electron-mac .body-grid {
653
664
  border-radius: 10px;
654
665
  }
666
+ /* Fullscreen · the OS window is edge-to-edge, so the 10px outer
667
+ padding ring and 10px rounded corners on the body-grid become
668
+ wasted margins / a floating-card look. Both flatten to zero in
669
+ fullscreen so the content reaches the screen edges. The
670
+ `is-fullscreen` class is toggled by electron/main.ts on
671
+ `enter-full-screen` / `leave-full-screen` events. */
672
+ html.is-fullscreen .control { padding: 0; }
673
+ html.is-fullscreen .body-grid { border-radius: 0; }
655
674
  /* macOS Electron · let the BrowserWindow's `vibrancy: "under-window"`
656
675
  layer show through. The vibrancy lives behind the renderer, so
657
676
  anything painted with a fully opaque background covers it. We
@@ -724,30 +743,27 @@
724
743
  pinned to the top-left of the body-grid area. Frosted black
725
744
  glass with hairline border, lime on hover. z-index sits above
726
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. */
727
751
  .sidebar-expand-btn {
728
752
  display: none;
729
753
  position: absolute;
730
754
  top: 12px;
731
755
  left: 12px;
732
- width: 34px;
733
- height: 34px;
756
+ width: 28px;
757
+ height: 28px;
734
758
  align-items: center;
735
759
  justify-content: center;
736
- /* Theme-adaptive frosted backdrop · uses `--bg` (the page bg
737
- token, which flips dark ↔ light with the active appearance)
738
- at ~55 % opacity. The earlier hardcoded `rgba(8,8,8,.55)` was
739
- fine in dark mode but left a dark blob on light surfaces in
740
- the atrium / light appearance — making the hamburger icon
741
- (currentColor stroke) read against its own background tint
742
- instead of the page. */
743
- background: color-mix(in srgb, var(--bg) 55%, transparent);
744
- -webkit-backdrop-filter: blur(12px) saturate(1.05);
745
- backdrop-filter: blur(12px) saturate(1.05);
746
- border: 0.5px solid var(--line-strong);
760
+ background: var(--bg);
761
+ border: 1px solid var(--lime-dim);
762
+ border-radius: 50%;
747
763
  color: var(--text-soft);
748
764
  cursor: pointer;
749
765
  z-index: 200;
750
- transition: color 0.12s, border-color 0.12s, background 0.12s;
766
+ transition: color 0.12s, border-color 0.12s;
751
767
  appearance: none;
752
768
  padding: 0;
753
769
  }
@@ -760,8 +776,7 @@
760
776
  }
761
777
  .sidebar-expand-btn:hover {
762
778
  color: var(--lime);
763
- border-color: var(--lime-dim);
764
- background: color-mix(in srgb, var(--bg) 72%, transparent);
779
+ border-color: var(--lime);
765
780
  }
766
781
  /* Hit-area expander · the visible button is 34×34, but ::after
767
782
  stretches 18px past every edge so the click target is 70×70 even
@@ -1793,26 +1808,25 @@
1793
1808
  overflow: hidden;
1794
1809
  text-overflow: ellipsis;
1795
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. */
1796
1815
  .icon-btn {
1797
- width: 32px; height: 32px;
1816
+ width: 16px; height: 16px;
1798
1817
  background: transparent;
1799
- border: 0.5px solid var(--line-bright);
1818
+ border: 0;
1800
1819
  display: flex;
1801
1820
  align-items: center;
1802
1821
  justify-content: center;
1803
1822
  cursor: pointer;
1804
1823
  color: var(--text-soft);
1805
1824
  text-decoration: none;
1806
- font-size: 16px;
1807
1825
  line-height: 1;
1808
1826
  flex-shrink: 0;
1809
- transition: all 0.12s;
1810
- }
1811
- .icon-btn:hover {
1812
- background: var(--panel-3);
1813
- color: var(--lime);
1814
- border-color: var(--lime);
1827
+ transition: color 0.12s;
1815
1828
  }
1829
+ .icon-btn:hover { color: var(--lime); }
1816
1830
  /* Settings trigger · Lucide Settings (gear) glyph in the same
1817
1831
  mask-image vocabulary as the .new-btn.nav-* sidebar icons.
1818
1832
  Keeps the bottom row visually paired with the search /
@@ -2595,7 +2609,7 @@
2595
2609
  background: color-mix(in srgb, color-mix(in srgb, var(--panel-3) 78%, var(--bg) 22%) 88%, transparent);
2596
2610
  backdrop-filter: blur(24px) saturate(180%);
2597
2611
  -webkit-backdrop-filter: blur(24px) saturate(180%);
2598
- border: 0.5px solid var(--line-strong);
2612
+ border: 0.5px solid var(--accent-line);
2599
2613
  border-radius: 14px;
2600
2614
  /* No drop shadow · mirrors cmp-input-frame after the lifted
2601
2615
  card shadow was removed there. The frosted surface + hairline
@@ -2608,11 +2622,9 @@
2608
2622
  padding 0.22s ease;
2609
2623
  }
2610
2624
  .search-card:focus-within {
2611
- /* Match cmp-input-frame's focus register · softer lime ring (the
2612
- `--lime-dim` rim) instead of a hard lime border, so the
2613
- focused state reads as "warmed" rather than "selected
2614
- outline". */
2615
- 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);
2616
2628
  }
2617
2629
  .search-page.has-results .search-card {
2618
2630
  display: flex;
@@ -9465,6 +9477,46 @@
9465
9477
  animation: rt-sub-in 0.18s ease-out;
9466
9478
  }
9467
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; }
9468
9520
  @keyframes rt-sub-in {
9469
9521
  from { opacity: 0; transform: translate(-50%, 6px); }
9470
9522
  to { opacity: 1; transform: translate(-50%, 0); }
@@ -11367,8 +11419,12 @@
11367
11419
  z-index: -1;
11368
11420
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
11369
11421
  mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
11370
- 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;
11371
11426
  }
11427
+ :root[data-theme="light"] .cmp-bg-deco { opacity: 0.4; }
11372
11428
  .cmp-bg-deco svg { display: block; width: 100%; height: 100%; }
11373
11429
  /* 8-bit deco animations · keep subtle so the field reads as
11374
11430
  "alive" rather than "demanding attention". All animations are
@@ -11496,32 +11552,24 @@
11496
11552
  max-width: 620px;
11497
11553
  }
11498
11554
 
11499
- /* Input frame · the focal point. Mirrors the in-room `.input-bar`
11500
- register (frosted glass · hairline border · 14px radius · soft
11501
- elevation) so the new-room / new-agent composer reads as the same
11502
- control surface family as the in-room textarea. Background recipe
11503
- (layered color-mix backdrop-filter) is borrowed verbatim from
11504
- `.input-bar` (~line 14612). `overflow: hidden` keeps the toolbar
11505
- flush with the rounded corners; focus lifts to a brighter lime
11506
- border + slightly deeper shadow, matching input-bar's focus
11507
- 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. */
11508
11563
  .cmp-input-frame {
11509
11564
  position: relative;
11510
- background: color-mix(in srgb, var(--panel-3) 78%, var(--bg) 22%);
11511
- background: color-mix(in srgb, color-mix(in srgb, var(--panel-3) 78%, var(--bg) 22%) 88%, transparent);
11512
- backdrop-filter: blur(24px) saturate(180%);
11513
- -webkit-backdrop-filter: blur(24px) saturate(180%);
11514
- border: 0.5px solid var(--line-strong);
11565
+ background: var(--bg);
11566
+ border: 0.5px solid var(--accent-line);
11515
11567
  border-radius: 14px;
11516
- /* No drop shadow · the frosted-glass surface + hairline border
11517
- already feel like a discrete card. The earlier lifted shadow
11518
- (`0 14px 32px -20px rgba(0,0,0,.55)`) made the composer look
11519
- like a floating modal, which fought with the deco backdrop. */
11520
11568
  transition: border-color 0.18s;
11521
11569
  overflow: hidden;
11522
11570
  }
11523
11571
  .cmp-input-frame:focus-within {
11524
- border-color: var(--lime-dim, var(--lime));
11572
+ border-color: var(--lime);
11525
11573
  }
11526
11574
  .cmp-input {
11527
11575
  display: block;
@@ -11578,8 +11626,11 @@
11578
11626
  flex-wrap: wrap;
11579
11627
  gap: 4px;
11580
11628
  padding: 6px 8px;
11581
- background: var(--panel-2);
11582
- 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);
11583
11634
  min-height: 44px;
11584
11635
  }
11585
11636
  /* Topbar buttons adopt the in-room input-bar's
@@ -11722,11 +11773,11 @@
11722
11773
  align-items: center;
11723
11774
  gap: 8px;
11724
11775
  padding: 6px 10px;
11725
- /* No hairline divider between textarea and bottombar · the
11726
- `--panel-2` toolbar tray plus the textarea's own focused-border
11727
- already telegraph the boundary; the extra rule read as visual
11728
- noise pinning the bottom of the card. */
11729
- 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);
11730
11781
  min-height: 48px;
11731
11782
  /* Establish a size container · child elements (notably the
11732
11783
  voice-mode toggle's text) can respond to the toolbar's width
@@ -14963,6 +15014,49 @@
14963
15014
  stable when the slot empties. */
14964
15015
  .ib-controls-right [hidden] { display: none !important; }
14965
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
+
14966
15060
  /* ─── Inline-tool register inside the input / paused bar ───
14967
15061
  The reference design (icons/bar.png) places ALL controls
14968
15062
  below the textarea as borderless, fill-less inline tools ·
@@ -16105,6 +16199,11 @@
16105
16199
  <!-- populated by app.renderQueue() · summary follows
16106
16200
  the real queue: speaking, pending, or idle. -->
16107
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>
16108
16207
  <button type="button" class="queue-toggle" data-i18n-title="queue_toggle" aria-expanded="true">
16109
16208
  <!-- Expanded state · chevron-up = "fold the queue".
16110
16209
  Collapsed state · list-rows = "open the queue".
@@ -16266,10 +16365,15 @@
16266
16365
  sat before collapse. Frosted black glass with a 3-line
16267
16366
  hamburger glyph. -->
16268
16367
  <button type="button" class="sidebar-expand-btn" data-sidebar-expand data-i18n-title="sidebar_expand" data-i18n-tip="sidebar_expand">
16269
- <svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true">
16270
- <line x1="2.5" y1="4.25" x2="13.5" y2="4.25"/>
16271
- <line x1="2.5" y1="8" x2="13.5" y2="8"/>
16272
- <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"/>
16273
16377
  </svg>
16274
16378
  </button>
16275
16379