composeai 0.1.3 → 0.1.5
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/index.cjs +179 -265
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +179 -265
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/composer.css +1163 -9
package/src/composer.css
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
/* ComposeAI — component styles.
|
|
2
2
|
*
|
|
3
|
-
* Plain CSS
|
|
4
|
-
*
|
|
3
|
+
* Plain CSS, NO Tailwind required. Every element the package renders (editor
|
|
4
|
+
* content AND chrome — card, buttons, menus, chips, …) is styled here off a
|
|
5
|
+
* single set of design tokens:
|
|
5
6
|
* --background, --foreground, --primary, --primary-foreground,
|
|
6
7
|
* --muted, --muted-foreground, --border, --card, --card-foreground,
|
|
7
8
|
* --popover, --popover-foreground, --accent, --accent-foreground,
|
|
8
9
|
* --destructive, --success, --warning
|
|
9
|
-
* Values are HSL components (e.g. `258 90% 62%`) so
|
|
10
|
-
*
|
|
10
|
+
* Values are HSL components (e.g. `258 90% 62%`) so they compose with
|
|
11
|
+
* opacities via `hsl(var(--primary) / 0.1)`.
|
|
12
|
+
*
|
|
13
|
+
* The package ships a complete DEFAULT value for every token (see the
|
|
14
|
+
* `[data-composer-scope]` block in the CHROME section below), scoped to the
|
|
15
|
+
* composer subtree + its portaled popovers — so a consumer who configures
|
|
16
|
+
* nothing still gets a correct, opaque, themed composer. The `color` /
|
|
17
|
+
* `tokens` / `sx` props override per-token (they apply inline on the same
|
|
18
|
+
* scope element, which always beats this stylesheet).
|
|
11
19
|
*/
|
|
12
20
|
|
|
13
21
|
/* ----------------------------------------------------------------------------
|
|
14
22
|
* Composer-wide custom properties.
|
|
15
23
|
*
|
|
16
|
-
* These are READ by
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* never the consumer app's global theme.
|
|
24
|
+
* These are READ by the package CSS below (`var(--composer-radius)`, etc.).
|
|
25
|
+
* They are SET inline on the composer root by `<Composer />` itself when the
|
|
26
|
+
* consumer passes `tokens={...}`, so they only affect that one composer
|
|
27
|
+
* instance — never the consumer app's global theme.
|
|
21
28
|
*
|
|
22
29
|
* --composer-radius outer card corner radius (default 28px)
|
|
23
30
|
* --composer-font-size editor base font size (default 15px)
|
|
@@ -386,6 +393,10 @@
|
|
|
386
393
|
* ------------------------------------------------------------------------- */
|
|
387
394
|
|
|
388
395
|
.composer-ghost-overlay {
|
|
396
|
+
position: absolute;
|
|
397
|
+
inset: 0;
|
|
398
|
+
pointer-events: none;
|
|
399
|
+
user-select: none;
|
|
389
400
|
font-size: var(--composer-font-size, 15px);
|
|
390
401
|
font-family: var(--composer-font-family, inherit);
|
|
391
402
|
line-height: 1.6;
|
|
@@ -418,6 +429,17 @@
|
|
|
418
429
|
font-style: italic;
|
|
419
430
|
}
|
|
420
431
|
|
|
432
|
+
/* Padding mirrors EditorShell's editor padding so the ghost text lines up
|
|
433
|
+
* with the caret. `--multiline` matches `.composer-editor--multiline`
|
|
434
|
+
* (0.875rem 1.25rem); `--inline` matches `.composer-editor--inline`
|
|
435
|
+
* (0.5rem inline). Keep these in lock-step with those rules. */
|
|
436
|
+
.composer-ghost-overlay--multiline {
|
|
437
|
+
padding: 0.875rem 1.25rem;
|
|
438
|
+
}
|
|
439
|
+
.composer-ghost-overlay--inline {
|
|
440
|
+
padding-inline: 0.5rem;
|
|
441
|
+
}
|
|
442
|
+
|
|
421
443
|
/* Inline-layout overrides: mirror the editor's 36px row line-height so
|
|
422
444
|
* the suggestion sits on the same baseline as the typed text. */
|
|
423
445
|
.composer-ghost-overlay.composer-ghost-overlay--inline {
|
|
@@ -451,7 +473,12 @@
|
|
|
451
473
|
* order, with the line-height matching the 36px row height so a single
|
|
452
474
|
* line of text is perfectly centered. */
|
|
453
475
|
.composer-editor.composer-editor--inline {
|
|
476
|
+
height: 2.25rem; /* h-9 (36px) */
|
|
454
477
|
line-height: 2.25rem; /* matches h-9 / leading-9 (36px) */
|
|
478
|
+
padding-inline: 0.5rem;
|
|
479
|
+
overflow-x: auto;
|
|
480
|
+
overflow-y: hidden;
|
|
481
|
+
white-space: nowrap;
|
|
455
482
|
scrollbar-width: none;
|
|
456
483
|
}
|
|
457
484
|
.composer-editor.composer-editor--inline::-webkit-scrollbar {
|
|
@@ -478,4 +505,1131 @@
|
|
|
478
505
|
* showing if a consumer renders one manually inside an inline composer. */
|
|
479
506
|
[data-composer-root][data-composer-inline] [data-mermaid-tile] {
|
|
480
507
|
display: none;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/* ============================================================================
|
|
511
|
+
* CHROME — self-contained component styles.
|
|
512
|
+
*
|
|
513
|
+
* Everything below styles the composer's *chrome* (card, toolbar, buttons,
|
|
514
|
+
* menus, attachment chips, tooltips, …) in plain CSS, so the package renders
|
|
515
|
+
* correctly with NO Tailwind in the consumer app and NO assumptions about the
|
|
516
|
+
* consumer's design-token names. Each element carries a semantic
|
|
517
|
+
* `composer-*` class (set by the components) that these rules target.
|
|
518
|
+
*
|
|
519
|
+
* Colors are keyed off the same `hsl(var(--token))` design tokens the editor
|
|
520
|
+
* content above uses. The package now ships a complete DEFAULT value for every
|
|
521
|
+
* token (below), scoped to the composer subtree + its portaled popovers, so a
|
|
522
|
+
* consumer who defines nothing still gets a correct, opaque, rounded composer.
|
|
523
|
+
* The `color` / `tokens` / `sx` props still win — they are applied inline on
|
|
524
|
+
* the same scope element, and inline always beats this stylesheet.
|
|
525
|
+
* ========================================================================= */
|
|
526
|
+
|
|
527
|
+
/* ----------------------------------------------------------------------------
|
|
528
|
+
* Built-in default theme.
|
|
529
|
+
*
|
|
530
|
+
* Set DIRECTLY on the scope elements (not on the consumer's `:root`) so they
|
|
531
|
+
* shadow whatever the host app defines globally — even when the host uses an
|
|
532
|
+
* incompatible format (hex, rgb, oklch) for the same variable name. Because
|
|
533
|
+
* they sit on the same element the `color`/`tokens` props target inline, the
|
|
534
|
+
* consumer's theming still overrides them per-token. `--composer-shadow-*` are
|
|
535
|
+
* package-private so they can't clash with a host's shadow tokens.
|
|
536
|
+
* ------------------------------------------------------------------------- */
|
|
537
|
+
.composer-root,
|
|
538
|
+
[data-composer-scope] {
|
|
539
|
+
--background: 0 0% 100%;
|
|
540
|
+
--foreground: 222 18% 18%;
|
|
541
|
+
--card: 0 0% 100%;
|
|
542
|
+
--card-foreground: 222 18% 18%;
|
|
543
|
+
--popover: 0 0% 100%;
|
|
544
|
+
--popover-foreground: 222 18% 18%;
|
|
545
|
+
--muted: 220 14% 96%;
|
|
546
|
+
--muted-foreground: 220 9% 46%;
|
|
547
|
+
--border: 220 13% 90%;
|
|
548
|
+
--input: 220 13% 90%;
|
|
549
|
+
--primary: 222 47% 11%;
|
|
550
|
+
--primary-foreground: 210 20% 98%;
|
|
551
|
+
--accent: 220 14% 95%;
|
|
552
|
+
--accent-foreground: 222 47% 11%;
|
|
553
|
+
--ring: 222 47% 11%;
|
|
554
|
+
--destructive: 0 72% 51%;
|
|
555
|
+
--destructive-foreground: 0 0% 100%;
|
|
556
|
+
--success: 142 71% 45%;
|
|
557
|
+
--success-foreground: 0 0% 100%;
|
|
558
|
+
--warning: 38 92% 50%;
|
|
559
|
+
--warning-foreground: 24 10% 10%;
|
|
560
|
+
|
|
561
|
+
--composer-shadow-soft: 0 1px 2px hsl(220 13% 10% / 0.05),
|
|
562
|
+
0 12px 32px -16px hsl(220 13% 10% / 0.24);
|
|
563
|
+
--composer-shadow-pop: 0 4px 12px hsl(220 13% 10% / 0.08),
|
|
564
|
+
0 20px 48px -20px hsl(220 13% 10% / 0.4);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/* Auto dark theme for hosts whose users prefer dark — keeps the composer
|
|
568
|
+
* readable out of the box on a dark canvas. A consumer who wants an explicit
|
|
569
|
+
* theme regardless of OS setting passes `tokens` (which wins inline). */
|
|
570
|
+
@media (prefers-color-scheme: dark) {
|
|
571
|
+
.composer-root,
|
|
572
|
+
[data-composer-scope] {
|
|
573
|
+
--background: 222 16% 11%;
|
|
574
|
+
--foreground: 210 20% 92%;
|
|
575
|
+
--card: 222 16% 13%;
|
|
576
|
+
--card-foreground: 210 20% 92%;
|
|
577
|
+
--popover: 222 16% 15%;
|
|
578
|
+
--popover-foreground: 210 20% 92%;
|
|
579
|
+
--muted: 220 14% 20%;
|
|
580
|
+
--muted-foreground: 220 9% 64%;
|
|
581
|
+
--border: 220 13% 26%;
|
|
582
|
+
--input: 220 13% 26%;
|
|
583
|
+
--primary: 210 20% 96%;
|
|
584
|
+
--primary-foreground: 222 47% 11%;
|
|
585
|
+
--accent: 220 13% 24%;
|
|
586
|
+
--accent-foreground: 210 20% 96%;
|
|
587
|
+
--ring: 210 20% 80%;
|
|
588
|
+
--destructive: 0 72% 55%;
|
|
589
|
+
--destructive-foreground: 0 0% 100%;
|
|
590
|
+
--success: 142 64% 47%;
|
|
591
|
+
--success-foreground: 0 0% 100%;
|
|
592
|
+
--warning: 38 92% 55%;
|
|
593
|
+
--warning-foreground: 24 10% 10%;
|
|
594
|
+
|
|
595
|
+
--composer-shadow-soft: 0 1px 2px hsl(0 0% 0% / 0.4),
|
|
596
|
+
0 12px 32px -16px hsl(0 0% 0% / 0.6);
|
|
597
|
+
--composer-shadow-pop: 0 4px 12px hsl(0 0% 0% / 0.5),
|
|
598
|
+
0 20px 48px -20px hsl(0 0% 0% / 0.7);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/* Shared keyframes / animation helpers. `composer-popover-in` already exists
|
|
603
|
+
* above for the small attachment popover; these cover the typeahead menus,
|
|
604
|
+
* spinners and pulsing recording indicators. */
|
|
605
|
+
@keyframes composer-slide-up {
|
|
606
|
+
from {
|
|
607
|
+
opacity: 0;
|
|
608
|
+
transform: translateY(-4px) scale(0.985);
|
|
609
|
+
}
|
|
610
|
+
to {
|
|
611
|
+
opacity: 1;
|
|
612
|
+
transform: none;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
@keyframes composer-spin {
|
|
616
|
+
to {
|
|
617
|
+
transform: rotate(360deg);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
@keyframes composer-pulse {
|
|
621
|
+
50% {
|
|
622
|
+
opacity: 0.45;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
.composer-spin {
|
|
626
|
+
animation: composer-spin 0.9s linear infinite;
|
|
627
|
+
}
|
|
628
|
+
.composer-pulse {
|
|
629
|
+
animation: composer-pulse 1.4s ease-in-out infinite;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/* Shared thin scrollbar (matches the editor's own, defined above). */
|
|
633
|
+
.composer-scroll-y {
|
|
634
|
+
overflow-y: auto;
|
|
635
|
+
scrollbar-width: thin;
|
|
636
|
+
scrollbar-color: hsl(var(--border)) transparent;
|
|
637
|
+
}
|
|
638
|
+
.composer-scroll-x {
|
|
639
|
+
overflow-x: auto;
|
|
640
|
+
scrollbar-width: thin;
|
|
641
|
+
scrollbar-color: hsl(var(--border)) transparent;
|
|
642
|
+
}
|
|
643
|
+
.composer-scroll-y::-webkit-scrollbar,
|
|
644
|
+
.composer-scroll-x::-webkit-scrollbar {
|
|
645
|
+
width: 6px;
|
|
646
|
+
height: 6px;
|
|
647
|
+
}
|
|
648
|
+
.composer-scroll-y::-webkit-scrollbar-thumb,
|
|
649
|
+
.composer-scroll-x::-webkit-scrollbar-thumb {
|
|
650
|
+
background: hsl(var(--border));
|
|
651
|
+
border-radius: 9999px;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/* All package SVGs inherit the current text color and never shrink in a flex
|
|
655
|
+
* row. Concrete sizes are set per-context below. Mermaid-rendered SVGs live
|
|
656
|
+
* inside `.composer-mermaid-svg` and are sized there, never by this rule. */
|
|
657
|
+
.composer-icon {
|
|
658
|
+
flex: none;
|
|
659
|
+
color: currentColor;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/* Visually-hidden but screen-reader-accessible (replaces Tailwind `sr-only`). */
|
|
663
|
+
.composer-sr-only {
|
|
664
|
+
position: absolute;
|
|
665
|
+
width: 1px;
|
|
666
|
+
height: 1px;
|
|
667
|
+
padding: 0;
|
|
668
|
+
margin: -1px;
|
|
669
|
+
overflow: hidden;
|
|
670
|
+
clip: rect(0, 0, 0, 0);
|
|
671
|
+
white-space: nowrap;
|
|
672
|
+
border: 0;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/* ----------------------------------------------------------------------------
|
|
676
|
+
* Root + card + focus/drag overlays.
|
|
677
|
+
* ------------------------------------------------------------------------- */
|
|
678
|
+
.composer-root {
|
|
679
|
+
display: flex;
|
|
680
|
+
flex-direction: column;
|
|
681
|
+
gap: 0.5rem;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
[data-composer-root] {
|
|
685
|
+
position: relative;
|
|
686
|
+
border: 1px solid hsl(var(--border));
|
|
687
|
+
background: hsl(var(--card));
|
|
688
|
+
color: hsl(var(--card-foreground));
|
|
689
|
+
box-shadow: var(--composer-shadow-soft);
|
|
690
|
+
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
|
691
|
+
}
|
|
692
|
+
[data-composer-root]:focus-within {
|
|
693
|
+
border-color: hsl(var(--primary) / 0.4);
|
|
694
|
+
box-shadow: 0 0 0 1px hsl(var(--primary) / 0.15),
|
|
695
|
+
0 10px 34px -14px hsl(var(--primary) / 0.35);
|
|
696
|
+
}
|
|
697
|
+
[data-composer-root][data-composer-web] {
|
|
698
|
+
box-shadow: 0 0 0 1px hsl(var(--primary) / 0.2), var(--composer-shadow-soft);
|
|
699
|
+
}
|
|
700
|
+
[data-composer-root][data-composer-dragging] {
|
|
701
|
+
border-color: hsl(var(--primary) / 0.6);
|
|
702
|
+
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.6), var(--composer-shadow-soft);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
.composer-overlay-glow {
|
|
706
|
+
pointer-events: none;
|
|
707
|
+
position: absolute;
|
|
708
|
+
inset: 0;
|
|
709
|
+
opacity: 0;
|
|
710
|
+
transition: opacity 0.25s ease;
|
|
711
|
+
}
|
|
712
|
+
[data-composer-root]:focus-within .composer-overlay-glow {
|
|
713
|
+
opacity: 1;
|
|
714
|
+
}
|
|
715
|
+
.composer-overlay-drop {
|
|
716
|
+
pointer-events: none;
|
|
717
|
+
position: absolute;
|
|
718
|
+
inset: 0;
|
|
719
|
+
z-index: 10;
|
|
720
|
+
display: flex;
|
|
721
|
+
align-items: center;
|
|
722
|
+
justify-content: center;
|
|
723
|
+
background: hsl(var(--primary) / 0.05);
|
|
724
|
+
font-size: 0.875rem;
|
|
725
|
+
font-weight: 500;
|
|
726
|
+
color: hsl(var(--primary));
|
|
727
|
+
backdrop-filter: blur(1px);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/* ----------------------------------------------------------------------------
|
|
731
|
+
* Editor shell layout (multiline + inline).
|
|
732
|
+
* ------------------------------------------------------------------------- */
|
|
733
|
+
.composer-editor--multiline {
|
|
734
|
+
min-height: 44px;
|
|
735
|
+
max-height: 14rem;
|
|
736
|
+
overflow-y: auto;
|
|
737
|
+
scrollbar-width: thin;
|
|
738
|
+
scrollbar-color: hsl(var(--border)) transparent;
|
|
739
|
+
padding: 0.875rem 1.25rem;
|
|
740
|
+
}
|
|
741
|
+
.composer-editor--multiline::-webkit-scrollbar {
|
|
742
|
+
width: 6px;
|
|
743
|
+
}
|
|
744
|
+
.composer-editor--multiline::-webkit-scrollbar-thumb {
|
|
745
|
+
background: hsl(var(--border));
|
|
746
|
+
border-radius: 9999px;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
.composer-editor-block {
|
|
750
|
+
position: relative;
|
|
751
|
+
min-width: 0;
|
|
752
|
+
}
|
|
753
|
+
.composer-editor-block--inline {
|
|
754
|
+
flex: 1 1 0%;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.composer-placeholder {
|
|
758
|
+
pointer-events: none;
|
|
759
|
+
position: absolute;
|
|
760
|
+
user-select: none;
|
|
761
|
+
color: hsl(var(--muted-foreground));
|
|
762
|
+
font-size: 15px;
|
|
763
|
+
}
|
|
764
|
+
.composer-placeholder--multiline {
|
|
765
|
+
inset-inline: 0;
|
|
766
|
+
top: 0;
|
|
767
|
+
padding: 0.875rem 1.25rem;
|
|
768
|
+
line-height: 1.625;
|
|
769
|
+
}
|
|
770
|
+
.composer-placeholder--inline {
|
|
771
|
+
inset: 0;
|
|
772
|
+
padding-inline: 0.5rem;
|
|
773
|
+
line-height: 2.25rem;
|
|
774
|
+
white-space: nowrap;
|
|
775
|
+
overflow: hidden;
|
|
776
|
+
text-overflow: ellipsis;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
.composer-inline-row {
|
|
780
|
+
display: flex;
|
|
781
|
+
align-items: center;
|
|
782
|
+
gap: 0.25rem;
|
|
783
|
+
padding: 0.375rem 0.5rem;
|
|
784
|
+
}
|
|
785
|
+
.composer-inline-toolbar,
|
|
786
|
+
.composer-inline-send {
|
|
787
|
+
display: flex;
|
|
788
|
+
flex: none;
|
|
789
|
+
align-items: center;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
.composer-toolbar-row {
|
|
793
|
+
display: flex;
|
|
794
|
+
align-items: center;
|
|
795
|
+
justify-content: space-between;
|
|
796
|
+
padding: 0 0.75rem 0.625rem;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/* ----------------------------------------------------------------------------
|
|
800
|
+
* Toolbar + buttons.
|
|
801
|
+
* ------------------------------------------------------------------------- */
|
|
802
|
+
.composer-toolbar {
|
|
803
|
+
display: flex;
|
|
804
|
+
align-items: center;
|
|
805
|
+
gap: 0.25rem;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
.composer-toolbar-btn {
|
|
809
|
+
display: inline-flex;
|
|
810
|
+
align-items: center;
|
|
811
|
+
justify-content: center;
|
|
812
|
+
height: 2rem;
|
|
813
|
+
width: 2rem;
|
|
814
|
+
border-radius: 9999px;
|
|
815
|
+
color: hsl(var(--muted-foreground));
|
|
816
|
+
background: transparent;
|
|
817
|
+
border: none;
|
|
818
|
+
cursor: pointer;
|
|
819
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
820
|
+
}
|
|
821
|
+
.composer-toolbar-btn:hover {
|
|
822
|
+
background: hsl(var(--accent));
|
|
823
|
+
color: hsl(var(--foreground));
|
|
824
|
+
}
|
|
825
|
+
.composer-toolbar-btn svg {
|
|
826
|
+
height: 1rem;
|
|
827
|
+
width: 1rem;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/* Web-search pill — wider, pressed state lights up in the brand color. */
|
|
831
|
+
.composer-web-btn {
|
|
832
|
+
margin-inline-start: 0.125rem;
|
|
833
|
+
display: inline-flex;
|
|
834
|
+
align-items: center;
|
|
835
|
+
gap: 0.375rem;
|
|
836
|
+
height: 2rem;
|
|
837
|
+
padding-inline: 0.625rem;
|
|
838
|
+
border-radius: 9999px;
|
|
839
|
+
border: none;
|
|
840
|
+
background: transparent;
|
|
841
|
+
font-size: 0.75rem;
|
|
842
|
+
font-weight: 500;
|
|
843
|
+
color: hsl(var(--muted-foreground));
|
|
844
|
+
cursor: pointer;
|
|
845
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
846
|
+
}
|
|
847
|
+
.composer-web-btn:hover {
|
|
848
|
+
background: hsl(var(--accent));
|
|
849
|
+
color: hsl(var(--foreground));
|
|
850
|
+
}
|
|
851
|
+
.composer-web-btn[aria-pressed="true"] {
|
|
852
|
+
background: hsl(var(--primary) / 0.1);
|
|
853
|
+
color: hsl(var(--primary));
|
|
854
|
+
}
|
|
855
|
+
.composer-web-btn svg {
|
|
856
|
+
height: 0.875rem;
|
|
857
|
+
width: 0.875rem;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/* Voice button + live recording timer. */
|
|
861
|
+
.composer-voice {
|
|
862
|
+
display: flex;
|
|
863
|
+
align-items: center;
|
|
864
|
+
gap: 0.375rem;
|
|
865
|
+
}
|
|
866
|
+
.composer-voice-btn[aria-pressed="true"] {
|
|
867
|
+
background: hsl(var(--destructive) / 0.1);
|
|
868
|
+
color: hsl(var(--destructive));
|
|
869
|
+
box-shadow: 0 0 0 1px hsl(var(--destructive) / 0.4);
|
|
870
|
+
}
|
|
871
|
+
.composer-voice-btn[aria-pressed="true"]:hover {
|
|
872
|
+
background: hsl(var(--destructive) / 0.15);
|
|
873
|
+
color: hsl(var(--destructive));
|
|
874
|
+
}
|
|
875
|
+
.composer-voice-timer {
|
|
876
|
+
display: flex;
|
|
877
|
+
align-items: center;
|
|
878
|
+
gap: 0.25rem;
|
|
879
|
+
border-radius: 9999px;
|
|
880
|
+
background: hsl(var(--destructive) / 0.1);
|
|
881
|
+
padding: 0.125rem 0.5rem;
|
|
882
|
+
font-size: 11px;
|
|
883
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
884
|
+
font-weight: 500;
|
|
885
|
+
font-variant-numeric: tabular-nums;
|
|
886
|
+
color: hsl(var(--destructive));
|
|
887
|
+
}
|
|
888
|
+
.composer-voice-dot {
|
|
889
|
+
height: 0.375rem;
|
|
890
|
+
width: 0.375rem;
|
|
891
|
+
border-radius: 9999px;
|
|
892
|
+
background: hsl(var(--destructive));
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/* Send / stop button. Filled, circular, lifts on hover. The disabled send
|
|
896
|
+
* state drops to a muted fill so it reads as inert. */
|
|
897
|
+
.composer-send-btn {
|
|
898
|
+
display: inline-flex;
|
|
899
|
+
align-items: center;
|
|
900
|
+
justify-content: center;
|
|
901
|
+
height: 2.25rem;
|
|
902
|
+
width: 2.25rem;
|
|
903
|
+
border-radius: 9999px;
|
|
904
|
+
border: none;
|
|
905
|
+
background: hsl(var(--foreground));
|
|
906
|
+
color: hsl(var(--background));
|
|
907
|
+
box-shadow: 0 1px 2px hsl(220 13% 10% / 0.12);
|
|
908
|
+
cursor: pointer;
|
|
909
|
+
transition: transform 0.15s ease, background-color 0.15s ease,
|
|
910
|
+
color 0.15s ease;
|
|
911
|
+
}
|
|
912
|
+
.composer-send-btn:hover:not(:disabled) {
|
|
913
|
+
transform: scale(1.05);
|
|
914
|
+
}
|
|
915
|
+
.composer-send-btn:disabled {
|
|
916
|
+
background: hsl(var(--muted));
|
|
917
|
+
color: hsl(var(--muted-foreground) / 0.6);
|
|
918
|
+
box-shadow: none;
|
|
919
|
+
cursor: default;
|
|
920
|
+
}
|
|
921
|
+
.composer-send-btn svg {
|
|
922
|
+
height: 1rem;
|
|
923
|
+
width: 1rem;
|
|
924
|
+
}
|
|
925
|
+
.composer-send-btn--stop svg {
|
|
926
|
+
height: 0.875rem;
|
|
927
|
+
width: 0.875rem;
|
|
928
|
+
fill: currentColor;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/* ----------------------------------------------------------------------------
|
|
932
|
+
* Typeahead menus (mentions / slash) + attachment-type popover.
|
|
933
|
+
*
|
|
934
|
+
* The mention/slash menus are portaled and positioned by SmartPopover (fixed,
|
|
935
|
+
* via inline styles), so the class only owns the surface + animation. The
|
|
936
|
+
* attachment-type picker positions itself (absolute, opens upward).
|
|
937
|
+
* ------------------------------------------------------------------------- */
|
|
938
|
+
.composer-menu {
|
|
939
|
+
z-index: 50;
|
|
940
|
+
width: 16rem;
|
|
941
|
+
overflow: hidden;
|
|
942
|
+
border-radius: 0.75rem;
|
|
943
|
+
border: 1px solid hsl(var(--border));
|
|
944
|
+
background: hsl(var(--popover));
|
|
945
|
+
color: hsl(var(--popover-foreground));
|
|
946
|
+
box-shadow: var(--composer-shadow-pop);
|
|
947
|
+
transform-origin: top;
|
|
948
|
+
animation: composer-slide-up 0.16s ease-out;
|
|
949
|
+
}
|
|
950
|
+
.composer-menu--slash {
|
|
951
|
+
width: 18rem;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
.composer-menu-list {
|
|
955
|
+
max-height: 18rem;
|
|
956
|
+
overflow-y: auto;
|
|
957
|
+
scrollbar-width: thin;
|
|
958
|
+
scrollbar-color: hsl(var(--border)) transparent;
|
|
959
|
+
padding-block: 0.25rem;
|
|
960
|
+
}
|
|
961
|
+
.composer-menu-list::-webkit-scrollbar {
|
|
962
|
+
width: 6px;
|
|
963
|
+
}
|
|
964
|
+
.composer-menu-list::-webkit-scrollbar-thumb {
|
|
965
|
+
background: hsl(var(--border));
|
|
966
|
+
border-radius: 9999px;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
.composer-menu-group {
|
|
970
|
+
padding: 0.5rem 0.75rem 0.25rem;
|
|
971
|
+
font-size: 10px;
|
|
972
|
+
font-weight: 500;
|
|
973
|
+
text-transform: uppercase;
|
|
974
|
+
letter-spacing: 0.05em;
|
|
975
|
+
color: hsl(var(--muted-foreground));
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
.composer-menu-item {
|
|
979
|
+
display: flex;
|
|
980
|
+
cursor: pointer;
|
|
981
|
+
align-items: center;
|
|
982
|
+
gap: 0.625rem;
|
|
983
|
+
padding: 0.375rem 0.625rem;
|
|
984
|
+
font-size: 0.875rem;
|
|
985
|
+
color: hsl(var(--foreground));
|
|
986
|
+
}
|
|
987
|
+
.composer-menu-item[aria-selected="true"],
|
|
988
|
+
.composer-menu-item[data-active] {
|
|
989
|
+
background: hsl(var(--accent));
|
|
990
|
+
color: hsl(var(--accent-foreground));
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
.composer-menu-text {
|
|
994
|
+
display: flex;
|
|
995
|
+
min-width: 0;
|
|
996
|
+
flex-direction: column;
|
|
997
|
+
line-height: 1.2;
|
|
998
|
+
}
|
|
999
|
+
.composer-menu-label {
|
|
1000
|
+
overflow: hidden;
|
|
1001
|
+
text-overflow: ellipsis;
|
|
1002
|
+
white-space: nowrap;
|
|
1003
|
+
font-weight: 500;
|
|
1004
|
+
}
|
|
1005
|
+
.composer-menu-desc {
|
|
1006
|
+
overflow: hidden;
|
|
1007
|
+
text-overflow: ellipsis;
|
|
1008
|
+
white-space: nowrap;
|
|
1009
|
+
font-size: 11px;
|
|
1010
|
+
color: hsl(var(--muted-foreground));
|
|
1011
|
+
}
|
|
1012
|
+
.composer-menu-shortcut {
|
|
1013
|
+
margin-inline-start: auto;
|
|
1014
|
+
border-radius: 0.25rem;
|
|
1015
|
+
border: 1px solid hsl(var(--border));
|
|
1016
|
+
background: hsl(var(--muted));
|
|
1017
|
+
padding: 0.125rem 0.375rem;
|
|
1018
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
1019
|
+
font-size: 10px;
|
|
1020
|
+
color: hsl(var(--muted-foreground));
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
/* Round avatar bubble for mention rows (icon / initial fallback). */
|
|
1024
|
+
.composer-menu-avatar {
|
|
1025
|
+
display: flex;
|
|
1026
|
+
height: 1.75rem;
|
|
1027
|
+
width: 1.75rem;
|
|
1028
|
+
flex: none;
|
|
1029
|
+
align-items: center;
|
|
1030
|
+
justify-content: center;
|
|
1031
|
+
border-radius: 9999px;
|
|
1032
|
+
background: hsl(var(--primary) / 0.1);
|
|
1033
|
+
color: hsl(var(--primary));
|
|
1034
|
+
font-size: 0.75rem;
|
|
1035
|
+
font-weight: 600;
|
|
1036
|
+
}
|
|
1037
|
+
/* Square-ish badge for slash-command icons. */
|
|
1038
|
+
.composer-menu-icon {
|
|
1039
|
+
display: flex;
|
|
1040
|
+
height: 1.75rem;
|
|
1041
|
+
width: 1.75rem;
|
|
1042
|
+
flex: none;
|
|
1043
|
+
align-items: center;
|
|
1044
|
+
justify-content: center;
|
|
1045
|
+
border-radius: 0.5rem;
|
|
1046
|
+
background: hsl(var(--muted));
|
|
1047
|
+
color: hsl(var(--muted-foreground));
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
/* Skeleton shimmer rows shown while async items load. */
|
|
1051
|
+
.composer-skel-row {
|
|
1052
|
+
padding: 0.375rem 0.625rem;
|
|
1053
|
+
}
|
|
1054
|
+
.composer-skel-line {
|
|
1055
|
+
display: flex;
|
|
1056
|
+
align-items: center;
|
|
1057
|
+
gap: 0.625rem;
|
|
1058
|
+
padding: 0.375rem 0;
|
|
1059
|
+
}
|
|
1060
|
+
.composer-skel-avatar {
|
|
1061
|
+
height: 1.75rem;
|
|
1062
|
+
width: 1.75rem;
|
|
1063
|
+
flex: none;
|
|
1064
|
+
border-radius: 9999px;
|
|
1065
|
+
background: hsl(var(--muted));
|
|
1066
|
+
}
|
|
1067
|
+
.composer-skel-avatar--square {
|
|
1068
|
+
border-radius: 0.5rem;
|
|
1069
|
+
}
|
|
1070
|
+
.composer-skel-text {
|
|
1071
|
+
display: flex;
|
|
1072
|
+
min-width: 0;
|
|
1073
|
+
flex: 1;
|
|
1074
|
+
flex-direction: column;
|
|
1075
|
+
gap: 0.375rem;
|
|
1076
|
+
}
|
|
1077
|
+
.composer-skel-bar {
|
|
1078
|
+
height: 0.625rem;
|
|
1079
|
+
border-radius: 0.25rem;
|
|
1080
|
+
background: hsl(var(--muted));
|
|
1081
|
+
}
|
|
1082
|
+
.composer-skel-bar--sm {
|
|
1083
|
+
height: 0.5rem;
|
|
1084
|
+
background: hsl(var(--muted) / 0.7);
|
|
1085
|
+
}
|
|
1086
|
+
.composer-skel-group {
|
|
1087
|
+
display: flex;
|
|
1088
|
+
flex-direction: column;
|
|
1089
|
+
gap: 0.25rem;
|
|
1090
|
+
}
|
|
1091
|
+
.composer-skel-grouplabel {
|
|
1092
|
+
display: block;
|
|
1093
|
+
height: 0.5rem;
|
|
1094
|
+
width: 4rem;
|
|
1095
|
+
border-radius: 0.25rem;
|
|
1096
|
+
background: hsl(var(--muted) / 0.7);
|
|
1097
|
+
margin-block: 0.125rem 0.375rem;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/* Internal Avatar (image with initials fallback) used in mention rows. */
|
|
1101
|
+
.composer-avatar {
|
|
1102
|
+
display: inline-flex;
|
|
1103
|
+
flex: none;
|
|
1104
|
+
user-select: none;
|
|
1105
|
+
align-items: center;
|
|
1106
|
+
justify-content: center;
|
|
1107
|
+
overflow: hidden;
|
|
1108
|
+
border-radius: 9999px;
|
|
1109
|
+
background: hsl(var(--primary) / 0.1);
|
|
1110
|
+
color: hsl(var(--primary));
|
|
1111
|
+
font-size: 0.75rem;
|
|
1112
|
+
font-weight: 600;
|
|
1113
|
+
}
|
|
1114
|
+
.composer-avatar-img {
|
|
1115
|
+
height: 100%;
|
|
1116
|
+
width: 100%;
|
|
1117
|
+
object-fit: cover;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/* Attachment-type picker popover — anchored above the paperclip. */
|
|
1121
|
+
.composer-attach-picker {
|
|
1122
|
+
position: relative;
|
|
1123
|
+
}
|
|
1124
|
+
.composer-attach-menu {
|
|
1125
|
+
position: absolute;
|
|
1126
|
+
bottom: 100%;
|
|
1127
|
+
inset-inline-start: 0;
|
|
1128
|
+
z-index: 30;
|
|
1129
|
+
margin-bottom: 0.5rem;
|
|
1130
|
+
min-width: 200px;
|
|
1131
|
+
overflow: hidden;
|
|
1132
|
+
border-radius: 0.75rem;
|
|
1133
|
+
border: 1px solid hsl(var(--border));
|
|
1134
|
+
background: hsl(var(--popover));
|
|
1135
|
+
color: hsl(var(--popover-foreground));
|
|
1136
|
+
padding: 0.25rem;
|
|
1137
|
+
box-shadow: var(--composer-shadow-pop);
|
|
1138
|
+
}
|
|
1139
|
+
.composer-attach-item {
|
|
1140
|
+
display: flex;
|
|
1141
|
+
width: 100%;
|
|
1142
|
+
align-items: center;
|
|
1143
|
+
gap: 0.625rem;
|
|
1144
|
+
border-radius: 0.5rem;
|
|
1145
|
+
border: none;
|
|
1146
|
+
background: transparent;
|
|
1147
|
+
padding: 0.375rem 0.625rem;
|
|
1148
|
+
text-align: start;
|
|
1149
|
+
font-size: 0.875rem;
|
|
1150
|
+
color: hsl(var(--foreground));
|
|
1151
|
+
cursor: pointer;
|
|
1152
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
1153
|
+
}
|
|
1154
|
+
.composer-attach-item:hover {
|
|
1155
|
+
background: hsl(var(--accent) / 0.6);
|
|
1156
|
+
}
|
|
1157
|
+
.composer-attach-item[data-active] {
|
|
1158
|
+
background: hsl(var(--accent));
|
|
1159
|
+
color: hsl(var(--accent-foreground));
|
|
1160
|
+
}
|
|
1161
|
+
.composer-attach-item-icon {
|
|
1162
|
+
display: flex;
|
|
1163
|
+
height: 1.25rem;
|
|
1164
|
+
width: 1.25rem;
|
|
1165
|
+
flex: none;
|
|
1166
|
+
align-items: center;
|
|
1167
|
+
justify-content: center;
|
|
1168
|
+
color: hsl(var(--muted-foreground));
|
|
1169
|
+
}
|
|
1170
|
+
.composer-attach-item-label {
|
|
1171
|
+
min-width: 0;
|
|
1172
|
+
flex: 1;
|
|
1173
|
+
overflow: hidden;
|
|
1174
|
+
text-overflow: ellipsis;
|
|
1175
|
+
white-space: nowrap;
|
|
1176
|
+
font-weight: 500;
|
|
1177
|
+
}
|
|
1178
|
+
.composer-attach-item-desc {
|
|
1179
|
+
flex: none;
|
|
1180
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
1181
|
+
font-size: 11px;
|
|
1182
|
+
color: hsl(var(--muted-foreground));
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
/* ----------------------------------------------------------------------------
|
|
1186
|
+
* Attachment tray + chips.
|
|
1187
|
+
* ------------------------------------------------------------------------- */
|
|
1188
|
+
.composer-attachment-tray {
|
|
1189
|
+
display: flex;
|
|
1190
|
+
flex-wrap: wrap;
|
|
1191
|
+
gap: 0.5rem;
|
|
1192
|
+
padding: 0.75rem 1rem 0;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
.composer-chip {
|
|
1196
|
+
position: relative;
|
|
1197
|
+
}
|
|
1198
|
+
.composer-chip--image {
|
|
1199
|
+
height: 4rem;
|
|
1200
|
+
width: 4rem;
|
|
1201
|
+
overflow: hidden;
|
|
1202
|
+
border-radius: 0.75rem;
|
|
1203
|
+
border: 1px solid hsl(var(--border));
|
|
1204
|
+
background: hsl(var(--muted));
|
|
1205
|
+
}
|
|
1206
|
+
.composer-chip-img {
|
|
1207
|
+
height: 100%;
|
|
1208
|
+
width: 100%;
|
|
1209
|
+
object-fit: cover;
|
|
1210
|
+
}
|
|
1211
|
+
.composer-chip-overlay {
|
|
1212
|
+
position: absolute;
|
|
1213
|
+
inset: 0;
|
|
1214
|
+
display: grid;
|
|
1215
|
+
place-items: center;
|
|
1216
|
+
}
|
|
1217
|
+
.composer-chip-overlay--uploading {
|
|
1218
|
+
background: hsl(var(--foreground) / 0.5);
|
|
1219
|
+
color: hsl(var(--background));
|
|
1220
|
+
}
|
|
1221
|
+
.composer-chip-overlay--failed {
|
|
1222
|
+
background: hsl(var(--destructive) / 0.55);
|
|
1223
|
+
color: hsl(var(--destructive-foreground));
|
|
1224
|
+
}
|
|
1225
|
+
.composer-chip-overlay svg {
|
|
1226
|
+
height: 1.25rem;
|
|
1227
|
+
width: 1.25rem;
|
|
1228
|
+
}
|
|
1229
|
+
.composer-chip-zoom {
|
|
1230
|
+
position: absolute;
|
|
1231
|
+
inset: 0;
|
|
1232
|
+
display: flex;
|
|
1233
|
+
align-items: center;
|
|
1234
|
+
justify-content: center;
|
|
1235
|
+
border: none;
|
|
1236
|
+
background: hsl(var(--foreground) / 0.4);
|
|
1237
|
+
color: hsl(var(--background));
|
|
1238
|
+
opacity: 0;
|
|
1239
|
+
cursor: pointer;
|
|
1240
|
+
transition: opacity 0.15s ease;
|
|
1241
|
+
}
|
|
1242
|
+
.composer-chip--image:hover .composer-chip-zoom {
|
|
1243
|
+
opacity: 1;
|
|
1244
|
+
}
|
|
1245
|
+
.composer-chip-zoom svg {
|
|
1246
|
+
height: 1rem;
|
|
1247
|
+
width: 1rem;
|
|
1248
|
+
}
|
|
1249
|
+
.composer-chip-remove {
|
|
1250
|
+
position: absolute;
|
|
1251
|
+
inset-inline-end: 0.25rem;
|
|
1252
|
+
top: 0.25rem;
|
|
1253
|
+
z-index: 10;
|
|
1254
|
+
display: flex;
|
|
1255
|
+
height: 1.25rem;
|
|
1256
|
+
width: 1.25rem;
|
|
1257
|
+
align-items: center;
|
|
1258
|
+
justify-content: center;
|
|
1259
|
+
border: none;
|
|
1260
|
+
border-radius: 9999px;
|
|
1261
|
+
background: hsl(var(--foreground));
|
|
1262
|
+
color: hsl(var(--background));
|
|
1263
|
+
cursor: pointer;
|
|
1264
|
+
opacity: 0;
|
|
1265
|
+
transition: opacity 0.15s ease;
|
|
1266
|
+
}
|
|
1267
|
+
.composer-chip--image:hover .composer-chip-remove,
|
|
1268
|
+
.composer-chip-remove[data-visible] {
|
|
1269
|
+
opacity: 1;
|
|
1270
|
+
}
|
|
1271
|
+
.composer-chip-remove svg {
|
|
1272
|
+
height: 0.75rem;
|
|
1273
|
+
width: 0.75rem;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
.composer-chip--file {
|
|
1277
|
+
display: flex;
|
|
1278
|
+
align-items: center;
|
|
1279
|
+
gap: 0.5rem;
|
|
1280
|
+
border-radius: 0.75rem;
|
|
1281
|
+
border: 1px solid hsl(var(--border));
|
|
1282
|
+
background: hsl(var(--card));
|
|
1283
|
+
padding: 0.375rem 0.25rem 0.375rem 0.5rem;
|
|
1284
|
+
}
|
|
1285
|
+
.composer-chip--file[data-failed] {
|
|
1286
|
+
border-color: hsl(var(--destructive) / 0.6);
|
|
1287
|
+
}
|
|
1288
|
+
.composer-chip-icon {
|
|
1289
|
+
display: flex;
|
|
1290
|
+
height: 2rem;
|
|
1291
|
+
width: 2rem;
|
|
1292
|
+
flex: none;
|
|
1293
|
+
align-items: center;
|
|
1294
|
+
justify-content: center;
|
|
1295
|
+
border-radius: 0.5rem;
|
|
1296
|
+
background: hsl(var(--muted));
|
|
1297
|
+
color: hsl(var(--muted-foreground));
|
|
1298
|
+
}
|
|
1299
|
+
.composer-chip-icon[data-failed] {
|
|
1300
|
+
background: hsl(var(--destructive) / 0.15);
|
|
1301
|
+
color: hsl(var(--destructive));
|
|
1302
|
+
}
|
|
1303
|
+
.composer-chip-icon svg {
|
|
1304
|
+
height: 1rem;
|
|
1305
|
+
width: 1rem;
|
|
1306
|
+
}
|
|
1307
|
+
.composer-chip-text {
|
|
1308
|
+
display: flex;
|
|
1309
|
+
min-width: 0;
|
|
1310
|
+
flex-direction: column;
|
|
1311
|
+
}
|
|
1312
|
+
.composer-chip-name {
|
|
1313
|
+
max-width: 160px;
|
|
1314
|
+
overflow: hidden;
|
|
1315
|
+
text-overflow: ellipsis;
|
|
1316
|
+
white-space: nowrap;
|
|
1317
|
+
font-size: 0.75rem;
|
|
1318
|
+
font-weight: 500;
|
|
1319
|
+
line-height: 1.2;
|
|
1320
|
+
}
|
|
1321
|
+
.composer-chip-meta {
|
|
1322
|
+
font-size: 10px;
|
|
1323
|
+
color: hsl(var(--muted-foreground));
|
|
1324
|
+
}
|
|
1325
|
+
.composer-chip-meta[data-failed] {
|
|
1326
|
+
color: hsl(var(--destructive));
|
|
1327
|
+
}
|
|
1328
|
+
.composer-chip-remove-inline {
|
|
1329
|
+
display: flex;
|
|
1330
|
+
height: 1.5rem;
|
|
1331
|
+
width: 1.5rem;
|
|
1332
|
+
flex: none;
|
|
1333
|
+
align-items: center;
|
|
1334
|
+
justify-content: center;
|
|
1335
|
+
border: none;
|
|
1336
|
+
border-radius: 9999px;
|
|
1337
|
+
background: transparent;
|
|
1338
|
+
color: hsl(var(--muted-foreground));
|
|
1339
|
+
cursor: pointer;
|
|
1340
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
1341
|
+
}
|
|
1342
|
+
.composer-chip-remove-inline:hover {
|
|
1343
|
+
background: hsl(var(--accent));
|
|
1344
|
+
color: hsl(var(--foreground));
|
|
1345
|
+
}
|
|
1346
|
+
.composer-chip-remove-inline svg {
|
|
1347
|
+
height: 0.875rem;
|
|
1348
|
+
width: 0.875rem;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
/* ----------------------------------------------------------------------------
|
|
1352
|
+
* Image lightbox (portaled, full-viewport).
|
|
1353
|
+
* ------------------------------------------------------------------------- */
|
|
1354
|
+
.composer-lightbox {
|
|
1355
|
+
position: fixed;
|
|
1356
|
+
inset: 0;
|
|
1357
|
+
z-index: 50;
|
|
1358
|
+
display: flex;
|
|
1359
|
+
align-items: center;
|
|
1360
|
+
justify-content: center;
|
|
1361
|
+
padding: 1.5rem;
|
|
1362
|
+
}
|
|
1363
|
+
.composer-lightbox-backdrop {
|
|
1364
|
+
position: absolute;
|
|
1365
|
+
inset: 0;
|
|
1366
|
+
background: hsl(var(--foreground) / 0.7);
|
|
1367
|
+
backdrop-filter: blur(4px);
|
|
1368
|
+
}
|
|
1369
|
+
.composer-lightbox-close {
|
|
1370
|
+
position: absolute;
|
|
1371
|
+
inset-inline-end: 1.25rem;
|
|
1372
|
+
top: 1.25rem;
|
|
1373
|
+
display: flex;
|
|
1374
|
+
height: 2.25rem;
|
|
1375
|
+
width: 2.25rem;
|
|
1376
|
+
align-items: center;
|
|
1377
|
+
justify-content: center;
|
|
1378
|
+
border: none;
|
|
1379
|
+
border-radius: 9999px;
|
|
1380
|
+
background: hsl(var(--card));
|
|
1381
|
+
color: hsl(var(--foreground));
|
|
1382
|
+
box-shadow: var(--composer-shadow-soft);
|
|
1383
|
+
cursor: pointer;
|
|
1384
|
+
transition: background-color 0.15s ease;
|
|
1385
|
+
}
|
|
1386
|
+
.composer-lightbox-close:hover {
|
|
1387
|
+
background: hsl(var(--accent));
|
|
1388
|
+
}
|
|
1389
|
+
.composer-lightbox-close svg {
|
|
1390
|
+
height: 1rem;
|
|
1391
|
+
width: 1rem;
|
|
1392
|
+
}
|
|
1393
|
+
.composer-lightbox-img {
|
|
1394
|
+
position: relative;
|
|
1395
|
+
max-height: 85vh;
|
|
1396
|
+
max-width: 85vw;
|
|
1397
|
+
border-radius: 0.5rem;
|
|
1398
|
+
object-fit: contain;
|
|
1399
|
+
box-shadow: 0 25px 50px -12px hsl(0 0% 0% / 0.5);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
/* ----------------------------------------------------------------------------
|
|
1403
|
+
* Mermaid diagram preview.
|
|
1404
|
+
* ------------------------------------------------------------------------- */
|
|
1405
|
+
.composer-mermaid {
|
|
1406
|
+
border-top: 1px solid hsl(var(--border) / 0.6);
|
|
1407
|
+
background: hsl(var(--muted) / 0.3);
|
|
1408
|
+
padding: 0.75rem 1rem;
|
|
1409
|
+
}
|
|
1410
|
+
.composer-mermaid-head {
|
|
1411
|
+
display: flex;
|
|
1412
|
+
align-items: center;
|
|
1413
|
+
gap: 0.375rem;
|
|
1414
|
+
margin-bottom: 0.375rem;
|
|
1415
|
+
font-size: 10px;
|
|
1416
|
+
font-weight: 500;
|
|
1417
|
+
text-transform: uppercase;
|
|
1418
|
+
letter-spacing: 0.05em;
|
|
1419
|
+
color: hsl(var(--muted-foreground));
|
|
1420
|
+
}
|
|
1421
|
+
.composer-mermaid-head svg {
|
|
1422
|
+
height: 0.75rem;
|
|
1423
|
+
width: 0.75rem;
|
|
1424
|
+
}
|
|
1425
|
+
.composer-mermaid-row {
|
|
1426
|
+
display: flex;
|
|
1427
|
+
gap: 0.5rem;
|
|
1428
|
+
overflow-x: auto;
|
|
1429
|
+
scrollbar-width: thin;
|
|
1430
|
+
scrollbar-color: hsl(var(--border)) transparent;
|
|
1431
|
+
}
|
|
1432
|
+
.composer-mermaid-tile {
|
|
1433
|
+
position: relative;
|
|
1434
|
+
flex: none;
|
|
1435
|
+
overflow: hidden;
|
|
1436
|
+
border-radius: 0.5rem;
|
|
1437
|
+
border: 1px solid hsl(var(--border));
|
|
1438
|
+
background: hsl(var(--card));
|
|
1439
|
+
padding: 0;
|
|
1440
|
+
cursor: pointer;
|
|
1441
|
+
transition: border-color 0.15s ease;
|
|
1442
|
+
}
|
|
1443
|
+
.composer-mermaid-tile:hover {
|
|
1444
|
+
border-color: hsl(var(--primary) / 0.4);
|
|
1445
|
+
}
|
|
1446
|
+
.composer-mermaid-svg {
|
|
1447
|
+
height: 6rem;
|
|
1448
|
+
width: 10rem;
|
|
1449
|
+
}
|
|
1450
|
+
.composer-mermaid-svg svg {
|
|
1451
|
+
height: 100%;
|
|
1452
|
+
width: 100%;
|
|
1453
|
+
}
|
|
1454
|
+
.composer-mermaid-zoom {
|
|
1455
|
+
position: absolute;
|
|
1456
|
+
inset-inline-end: 0.25rem;
|
|
1457
|
+
top: 0.25rem;
|
|
1458
|
+
display: flex;
|
|
1459
|
+
height: 1.25rem;
|
|
1460
|
+
width: 1.25rem;
|
|
1461
|
+
align-items: center;
|
|
1462
|
+
justify-content: center;
|
|
1463
|
+
border-radius: 9999px;
|
|
1464
|
+
background: hsl(var(--foreground) / 0.7);
|
|
1465
|
+
color: hsl(var(--background));
|
|
1466
|
+
opacity: 0;
|
|
1467
|
+
transition: opacity 0.15s ease;
|
|
1468
|
+
}
|
|
1469
|
+
.composer-mermaid-tile:hover .composer-mermaid-zoom {
|
|
1470
|
+
opacity: 1;
|
|
1471
|
+
}
|
|
1472
|
+
.composer-mermaid-zoom svg {
|
|
1473
|
+
height: 0.75rem;
|
|
1474
|
+
width: 0.75rem;
|
|
1475
|
+
}
|
|
1476
|
+
.composer-mermaid-msg {
|
|
1477
|
+
display: grid;
|
|
1478
|
+
height: 6rem;
|
|
1479
|
+
width: 10rem;
|
|
1480
|
+
place-items: center;
|
|
1481
|
+
padding: 0 0.75rem;
|
|
1482
|
+
text-align: center;
|
|
1483
|
+
font-size: 11px;
|
|
1484
|
+
line-height: 1.35;
|
|
1485
|
+
color: hsl(var(--muted-foreground));
|
|
1486
|
+
}
|
|
1487
|
+
.composer-mermaid-msg--error {
|
|
1488
|
+
font-size: 10px;
|
|
1489
|
+
color: hsl(var(--destructive));
|
|
1490
|
+
}
|
|
1491
|
+
.composer-mermaid-code {
|
|
1492
|
+
border-radius: 0.25rem;
|
|
1493
|
+
background: hsl(var(--muted));
|
|
1494
|
+
padding-inline: 0.25rem;
|
|
1495
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
/* ----------------------------------------------------------------------------
|
|
1499
|
+
* Hint bar + keyboard chips.
|
|
1500
|
+
* ------------------------------------------------------------------------- */
|
|
1501
|
+
.composer-hint {
|
|
1502
|
+
text-align: center;
|
|
1503
|
+
font-size: 11px;
|
|
1504
|
+
color: hsl(var(--muted-foreground));
|
|
1505
|
+
}
|
|
1506
|
+
.composer-kbd {
|
|
1507
|
+
border-radius: 0.25rem;
|
|
1508
|
+
border: 1px solid hsl(var(--border));
|
|
1509
|
+
background: hsl(var(--card));
|
|
1510
|
+
padding: 0.0625rem 0.25rem;
|
|
1511
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
1512
|
+
font-size: 10px;
|
|
1513
|
+
}
|
|
1514
|
+
.composer-hint-sm,
|
|
1515
|
+
.composer-hint-md {
|
|
1516
|
+
display: none;
|
|
1517
|
+
}
|
|
1518
|
+
@media (min-width: 640px) {
|
|
1519
|
+
.composer-hint-sm {
|
|
1520
|
+
display: inline;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
@media (min-width: 768px) {
|
|
1524
|
+
.composer-hint-md {
|
|
1525
|
+
display: inline;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
/* ----------------------------------------------------------------------------
|
|
1530
|
+
* Quick-prompt + suggestion chip rows.
|
|
1531
|
+
* ------------------------------------------------------------------------- */
|
|
1532
|
+
.composer-prompts {
|
|
1533
|
+
display: flex;
|
|
1534
|
+
flex-wrap: wrap;
|
|
1535
|
+
align-items: center;
|
|
1536
|
+
gap: 0.5rem;
|
|
1537
|
+
padding: 0 0.25rem 0.25rem;
|
|
1538
|
+
}
|
|
1539
|
+
.composer-suggestions {
|
|
1540
|
+
display: flex;
|
|
1541
|
+
flex-wrap: wrap;
|
|
1542
|
+
justify-content: center;
|
|
1543
|
+
gap: 0.5rem;
|
|
1544
|
+
}
|
|
1545
|
+
.composer-prompt,
|
|
1546
|
+
.composer-suggestion {
|
|
1547
|
+
display: inline-flex;
|
|
1548
|
+
max-width: 100%;
|
|
1549
|
+
align-items: center;
|
|
1550
|
+
gap: 0.375rem;
|
|
1551
|
+
border-radius: 9999px;
|
|
1552
|
+
border: 1px solid hsl(var(--border));
|
|
1553
|
+
background: hsl(var(--card) / 0.6);
|
|
1554
|
+
padding: 0.375rem 0.875rem;
|
|
1555
|
+
font-size: 0.75rem;
|
|
1556
|
+
color: hsl(var(--muted-foreground));
|
|
1557
|
+
backdrop-filter: blur(4px);
|
|
1558
|
+
cursor: pointer;
|
|
1559
|
+
transition: transform 0.15s ease, border-color 0.15s ease,
|
|
1560
|
+
background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
|
|
1561
|
+
}
|
|
1562
|
+
.composer-prompt:hover,
|
|
1563
|
+
.composer-suggestion:hover {
|
|
1564
|
+
transform: translateY(-1px);
|
|
1565
|
+
border-color: hsl(var(--primary) / 0.4);
|
|
1566
|
+
background: hsl(var(--card));
|
|
1567
|
+
color: hsl(var(--foreground));
|
|
1568
|
+
box-shadow: 0 1px 2px hsl(220 13% 10% / 0.1);
|
|
1569
|
+
}
|
|
1570
|
+
.composer-prompt:focus-visible,
|
|
1571
|
+
.composer-suggestion:focus-visible {
|
|
1572
|
+
outline: none;
|
|
1573
|
+
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.4);
|
|
1574
|
+
}
|
|
1575
|
+
.composer-prompt svg,
|
|
1576
|
+
.composer-suggestion svg {
|
|
1577
|
+
height: 0.75rem;
|
|
1578
|
+
width: 0.75rem;
|
|
1579
|
+
flex: none;
|
|
1580
|
+
color: hsl(var(--primary));
|
|
1581
|
+
opacity: 0.7;
|
|
1582
|
+
transition: opacity 0.15s ease;
|
|
1583
|
+
}
|
|
1584
|
+
.composer-prompt:hover svg,
|
|
1585
|
+
.composer-suggestion:hover svg {
|
|
1586
|
+
opacity: 1;
|
|
1587
|
+
}
|
|
1588
|
+
.composer-prompt-text {
|
|
1589
|
+
overflow: hidden;
|
|
1590
|
+
text-overflow: ellipsis;
|
|
1591
|
+
white-space: nowrap;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
/* ----------------------------------------------------------------------------
|
|
1595
|
+
* Tooltip.
|
|
1596
|
+
* ------------------------------------------------------------------------- */
|
|
1597
|
+
.composer-tooltip-wrap {
|
|
1598
|
+
position: relative;
|
|
1599
|
+
display: inline-flex;
|
|
1600
|
+
}
|
|
1601
|
+
.composer-tooltip {
|
|
1602
|
+
position: absolute;
|
|
1603
|
+
z-index: 50;
|
|
1604
|
+
white-space: nowrap;
|
|
1605
|
+
border-radius: 0.375rem;
|
|
1606
|
+
background: hsl(var(--foreground));
|
|
1607
|
+
padding: 0.25rem 0.5rem;
|
|
1608
|
+
font-size: 0.75rem;
|
|
1609
|
+
color: hsl(var(--background));
|
|
1610
|
+
box-shadow: var(--composer-shadow-soft);
|
|
1611
|
+
}
|
|
1612
|
+
.composer-tooltip--top {
|
|
1613
|
+
bottom: 100%;
|
|
1614
|
+
left: 50%;
|
|
1615
|
+
margin-bottom: 0.5rem;
|
|
1616
|
+
transform: translateX(-50%);
|
|
1617
|
+
}
|
|
1618
|
+
.composer-tooltip--bottom {
|
|
1619
|
+
top: 100%;
|
|
1620
|
+
left: 50%;
|
|
1621
|
+
margin-top: 0.5rem;
|
|
1622
|
+
transform: translateX(-50%);
|
|
1623
|
+
}
|
|
1624
|
+
.composer-tooltip--left {
|
|
1625
|
+
inset-inline-end: 100%;
|
|
1626
|
+
top: 50%;
|
|
1627
|
+
margin-inline-end: 0.5rem;
|
|
1628
|
+
transform: translateY(-50%);
|
|
1629
|
+
}
|
|
1630
|
+
.composer-tooltip--right {
|
|
1631
|
+
inset-inline-start: 100%;
|
|
1632
|
+
top: 50%;
|
|
1633
|
+
margin-inline-start: 0.5rem;
|
|
1634
|
+
transform: translateY(-50%);
|
|
481
1635
|
}
|