@aparte/core 0.10.0 → 0.12.0
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/client/aparte-client.d.ts +54 -33
- package/dist/client/aparte-client.d.ts.map +1 -1
- package/dist/client/stream-adapter.d.ts +6 -1
- package/dist/client/stream-adapter.d.ts.map +1 -1
- package/dist/components/bubble/aparte-chat-bubble.d.ts +25 -4
- package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
- package/dist/components/chat/aparte-chat.d.ts +8 -4
- package/dist/components/chat/aparte-chat.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-action.d.ts +15 -6
- package/dist/components/composer/aparte-composer-action.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-add-attachment.d.ts +5 -4
- package/dist/components/composer/aparte-composer-add-attachment.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-attachments.d.ts +5 -3
- package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-cancel.d.ts +2 -2
- package/dist/components/composer/aparte-composer-input.d.ts +8 -5
- package/dist/components/composer/aparte-composer-input.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-send.d.ts +2 -2
- package/dist/components/composer/aparte-composer-toolbar.d.ts +3 -3
- package/dist/components/composer/aparte-composer.d.ts +81 -10
- package/dist/components/composer/aparte-composer.d.ts.map +1 -1
- package/dist/components/conversation-list/aparte-conversation-list.d.ts +19 -12
- package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
- package/dist/components/elicitation/aparte-elicitation.d.ts +14 -2
- package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
- package/dist/components/status/aparte-chat-status.d.ts +9 -0
- package/dist/components/status/aparte-chat-status.d.ts.map +1 -1
- package/dist/components/viewport/aparte-chat-viewport.d.ts +15 -4
- package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
- package/dist/config/aparte-config.d.ts +72 -15
- package/dist/config/aparte-config.d.ts.map +1 -1
- package/dist/config/locale.d.ts +43 -0
- package/dist/config/locale.d.ts.map +1 -1
- package/dist/custom-elements.json +2824 -1801
- package/dist/elicitation/approval-panel.d.ts +42 -0
- package/dist/elicitation/approval-panel.d.ts.map +1 -0
- package/dist/elicitation/index.d.ts +4 -1
- package/dist/elicitation/index.d.ts.map +1 -1
- package/dist/elicitation/panel.d.ts +1 -1
- package/dist/elicitation/panel.d.ts.map +1 -1
- package/dist/elicitation/types.d.ts +116 -9
- package/dist/elicitation/types.d.ts.map +1 -1
- package/dist/generated/element-attributes.d.ts +177 -0
- package/dist/generated/element-attributes.d.ts.map +1 -0
- package/dist/index.css +621 -92
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +368 -255
- package/dist/index.js.map +1 -1
- package/dist/index.node.d.ts +4 -3
- package/dist/index.node.d.ts.map +1 -1
- package/dist/index.node.js +46 -44
- package/dist/index.node.js.map +1 -1
- package/dist/interop/element-props.d.ts +40 -2
- package/dist/interop/element-props.d.ts.map +1 -1
- package/dist/{index-BnKBciDG.js → is-awaiting-reply-CxWRISBC.js} +949 -957
- package/dist/is-awaiting-reply-CxWRISBC.js.map +1 -0
- package/dist/primitives/select/aparte-optgroup.d.ts +3 -0
- package/dist/primitives/select/aparte-optgroup.d.ts.map +1 -1
- package/dist/primitives/select/aparte-option.d.ts +1 -0
- package/dist/primitives/select/aparte-option.d.ts.map +1 -1
- package/dist/primitives/select/aparte-select.d.ts +22 -18
- package/dist/primitives/select/aparte-select.d.ts.map +1 -1
- package/dist/renderers/segment-renderers.d.ts.map +1 -1
- package/dist/renderers/segments/artifact/card.d.ts.map +1 -1
- package/dist/renderers/segments/pipeline-waiting.d.ts.map +1 -1
- package/dist/renderers/segments/tool-call.d.ts.map +1 -1
- package/dist/types/element-attributes.d.ts +42 -0
- package/dist/types/element-attributes.d.ts.map +1 -0
- package/dist/types/event-map.d.ts +1 -2
- package/dist/types/event-map.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/segments.d.ts +1 -8
- package/dist/types/segments.d.ts.map +1 -1
- package/dist/types/tools.d.ts +26 -23
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/chat-boundary.d.ts +22 -0
- package/dist/utils/chat-boundary.d.ts.map +1 -0
- package/dist/utils/segments.d.ts +8 -0
- package/dist/utils/segments.d.ts.map +1 -1
- package/package.json +3 -2
- package/dist/index-BnKBciDG.js.map +0 -1
- package/dist/renderers/segments/progress.d.ts +0 -3
- package/dist/renderers/segments/progress.d.ts.map +0 -1
package/dist/index.css
CHANGED
|
@@ -192,6 +192,11 @@
|
|
|
192
192
|
--aparte-elic-option-desc-size: 0.78rem;
|
|
193
193
|
--aparte-elic-control-size: 15px;
|
|
194
194
|
--aparte-elic-input-radius: 6px;
|
|
195
|
+
/* The tool-call row's corner. Declared here rather than left as an inline
|
|
196
|
+
fallback in the renderer: an undeclared custom property still WORKS, which is
|
|
197
|
+
what makes it dangerous — it is absent from the generated CSS reference, so a
|
|
198
|
+
consumer has no way to discover the knob exists. */
|
|
199
|
+
--aparte-tool-row-radius: 6px;
|
|
195
200
|
--aparte-elic-textarea-min-height: 64px;
|
|
196
201
|
--aparte-elic-skip-size: 0.8rem;
|
|
197
202
|
--aparte-elic-step-size: 0.78rem;
|
|
@@ -229,7 +234,7 @@
|
|
|
229
234
|
--aparte-error-icon-size: 20px;
|
|
230
235
|
--aparte-error-rail-width: 4px;
|
|
231
236
|
|
|
232
|
-
/* Prose (segment-content) */
|
|
237
|
+
/* Prose (aparte-segment-content) */
|
|
233
238
|
--aparte-prose-p-margin: 0.4em 0;
|
|
234
239
|
--aparte-prose-h1-size: 1.4em;
|
|
235
240
|
--aparte-prose-h2-size: 1.25em;
|
|
@@ -412,10 +417,6 @@ aparte-chat {
|
|
|
412
417
|
--aparte-code-border: var(--aparte-border);
|
|
413
418
|
--aparte-code-header-text: var(--aparte-text-muted);
|
|
414
419
|
|
|
415
|
-
/* Progress */
|
|
416
|
-
--aparte-progress-bar-bg: var(--aparte-surface-3);
|
|
417
|
-
--aparte-progress-bar-fill: var(--aparte-primary);
|
|
418
|
-
--aparte-progress-label: var(--aparte-text);
|
|
419
420
|
|
|
420
421
|
/* Scroll-to-bottom button */
|
|
421
422
|
--aparte-scroll-btn-bg: var(--aparte-surface-1);
|
|
@@ -423,7 +424,7 @@ aparte-chat {
|
|
|
423
424
|
--aparte-scroll-btn-border: var(--aparte-border);
|
|
424
425
|
--aparte-scroll-btn-hover-bg: var(--aparte-surface-2);
|
|
425
426
|
|
|
426
|
-
/* Prose (segment-content) */
|
|
427
|
+
/* Prose (aparte-segment-content) */
|
|
427
428
|
--aparte-prose-blockquote-border: var(--aparte-border);
|
|
428
429
|
--aparte-prose-code-bg: var(--aparte-surface-2);
|
|
429
430
|
|
|
@@ -670,6 +671,91 @@ textarea.aparte-elic-text {
|
|
|
670
671
|
z-index: 1;
|
|
671
672
|
}
|
|
672
673
|
|
|
674
|
+
/* ── An approval: a decision, not a value ───────────────────────────────────
|
|
675
|
+
The options are buttons, not radios, because a decision has two primary actions
|
|
676
|
+
of opposite polarity and the composer's one button cannot carry both. So they
|
|
677
|
+
settle on the first click, and approving costs one gesture rather than two.
|
|
678
|
+
|
|
679
|
+
The colours are the ones the inline Approve / Reject pair used, moved here from
|
|
680
|
+
the runtime-injected `getStyles()` string in the tool_call renderer. That move is
|
|
681
|
+
the point: injected CSS is invisible to a consumer's own rules, absent from the
|
|
682
|
+
generated CSS reference, and unreachable by `check:derived-vars`. The elicitation
|
|
683
|
+
panel made the same move for the same reason. */
|
|
684
|
+
/* A COLUMN, not a row of pills.
|
|
685
|
+
The panel lives in a composer, which is narrow — two or three labels side by side
|
|
686
|
+
either wrap into an unreadable jumble or get squeezed. And the labels are not short:
|
|
687
|
+
a scope option reads "Approve, and always for this tool". A stacked list is also what
|
|
688
|
+
every reference implementation of this shows, for the same reason: one target per
|
|
689
|
+
line, full width, so the choice is read rather than aimed at. */
|
|
690
|
+
.aparte-approval-options {
|
|
691
|
+
display: flex;
|
|
692
|
+
flex-direction: column;
|
|
693
|
+
gap: var(--aparte-approval-gap, 4px);
|
|
694
|
+
margin: 0 6px;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
.aparte-approval-option {
|
|
698
|
+
font: inherit;
|
|
699
|
+
font-size: var(--aparte-approval-option-size, 0.85rem);
|
|
700
|
+
font-weight: var(--aparte-font-weight-medium, 500);
|
|
701
|
+
line-height: 1.35;
|
|
702
|
+
/* Left-aligned and full width: the eye reads down a list, and a centred label in a
|
|
703
|
+
wide target is harder to scan than a flush one. */
|
|
704
|
+
text-align: start;
|
|
705
|
+
width: 100%;
|
|
706
|
+
padding: var(--aparte-approval-option-padding, 8px 10px);
|
|
707
|
+
border-radius: var(--aparte-approval-option-radius, 8px);
|
|
708
|
+
cursor: pointer;
|
|
709
|
+
border: 1px solid var(--aparte-border, rgba(128, 128, 128, 0.3));
|
|
710
|
+
background: transparent;
|
|
711
|
+
color: var(--aparte-text);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.aparte-approval-option:hover {
|
|
715
|
+
background: var(--aparte-surface-2, rgba(128, 128, 128, 0.08));
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/* Tone is carried by a leading rule, not by colouring the label or ringing the whole
|
|
719
|
+
button. Both of those were tried: a green word on a dark panel reads as a link, and a
|
|
720
|
+
coloured border on every option turns the list into a traffic light. A 2px edge says
|
|
721
|
+
which way an option goes while leaving the text plain. */
|
|
722
|
+
/* The SOLID colours, not the `-border` pair. Those carry ~40% alpha because they were
|
|
723
|
+
made for a 1px box outline over a surface; on a 2px rule against a light background
|
|
724
|
+
the deny edge came out a pale pink that read as decoration. A rule wants a colour. */
|
|
725
|
+
.aparte-approval-option--affirm {
|
|
726
|
+
border-inline-start: 2px solid var(--aparte-success, rgb(21, 128, 61));
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
.aparte-approval-option--deny {
|
|
730
|
+
border-inline-start: 2px solid var(--aparte-error, rgb(185, 28, 28));
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/* The refusal's reason, in the user's words. Quiet by default and one line tall: it is
|
|
734
|
+
the exception, not the expected act, and a box sized for a paragraph invites one. */
|
|
735
|
+
.aparte-approval-instruction {
|
|
736
|
+
font: inherit;
|
|
737
|
+
font-size: var(--aparte-elic-input-size, 0.85rem);
|
|
738
|
+
color: var(--aparte-text);
|
|
739
|
+
background: transparent;
|
|
740
|
+
border: none;
|
|
741
|
+
border-top: 1px solid var(--aparte-border, rgba(128, 128, 128, 0.3));
|
|
742
|
+
border-radius: 0;
|
|
743
|
+
padding: 8px 10px 2px;
|
|
744
|
+
margin: 4px 6px 0;
|
|
745
|
+
resize: none;
|
|
746
|
+
overflow: hidden;
|
|
747
|
+
min-height: 1.6em;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
.aparte-approval-instruction:focus {
|
|
751
|
+
outline: none;
|
|
752
|
+
border-top-color: var(--aparte-accent, rgba(128, 128, 128, 0.6));
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
.aparte-approval-instruction::placeholder {
|
|
756
|
+
color: var(--aparte-text-muted, rgba(128, 128, 128, 0.75));
|
|
757
|
+
}
|
|
758
|
+
|
|
673
759
|
.aparte-elic-skip {
|
|
674
760
|
border: none;
|
|
675
761
|
background: transparent;
|
|
@@ -1474,7 +1560,7 @@ aparte-chat-bubble:last-of-type .aparte-message[data-role="assistant"]:not(.apar
|
|
|
1474
1560
|
font-size: var(--aparte-font-size-md, 13px);
|
|
1475
1561
|
}
|
|
1476
1562
|
|
|
1477
|
-
.aparte-input-upper.has-content {
|
|
1563
|
+
.aparte-input-upper.aparte-has-content {
|
|
1478
1564
|
display: flex;
|
|
1479
1565
|
}
|
|
1480
1566
|
|
|
@@ -1701,7 +1787,7 @@ aparte-chat-status:not([visible]) {
|
|
|
1701
1787
|
========================================= */
|
|
1702
1788
|
|
|
1703
1789
|
/* Text */
|
|
1704
|
-
.segment-text {
|
|
1790
|
+
.aparte-segment-text {
|
|
1705
1791
|
word-wrap: break-word;
|
|
1706
1792
|
}
|
|
1707
1793
|
|
|
@@ -1712,60 +1798,60 @@ aparte-chat-status:not([visible]) {
|
|
|
1712
1798
|
========================================= */
|
|
1713
1799
|
|
|
1714
1800
|
.aparte-content,
|
|
1715
|
-
.segment-content {
|
|
1801
|
+
.aparte-segment-content {
|
|
1716
1802
|
white-space: normal;
|
|
1717
1803
|
}
|
|
1718
1804
|
|
|
1719
1805
|
.aparte-content p,
|
|
1720
|
-
.segment-content p,
|
|
1721
|
-
.thinking-content p {
|
|
1806
|
+
.aparte-segment-content p,
|
|
1807
|
+
.aparte-thinking-content p {
|
|
1722
1808
|
margin: var(--aparte-prose-p-margin, 0.4em 0);
|
|
1723
1809
|
}
|
|
1724
1810
|
|
|
1725
1811
|
.aparte-content p:first-child,
|
|
1726
|
-
.segment-content p:first-child,
|
|
1727
|
-
.thinking-content p:first-child {
|
|
1812
|
+
.aparte-segment-content p:first-child,
|
|
1813
|
+
.aparte-thinking-content p:first-child {
|
|
1728
1814
|
margin-top: 0;
|
|
1729
1815
|
}
|
|
1730
1816
|
|
|
1731
1817
|
.aparte-content p:last-child,
|
|
1732
|
-
.segment-content p:last-child,
|
|
1733
|
-
.thinking-content p:last-child {
|
|
1818
|
+
.aparte-segment-content p:last-child,
|
|
1819
|
+
.aparte-thinking-content p:last-child {
|
|
1734
1820
|
margin-bottom: 0;
|
|
1735
1821
|
}
|
|
1736
1822
|
|
|
1737
|
-
.aparte-content h1, .segment-content h1, .thinking-content h1 { font-size: var(--aparte-prose-h1-size, 1.4em); font-weight: var(--aparte-font-weight-semibold, 600); margin: 0.6em 0 0.2em; }
|
|
1738
|
-
.aparte-content h2, .segment-content h2, .thinking-content h2 { font-size: var(--aparte-prose-h2-size, 1.25em); font-weight: var(--aparte-font-weight-semibold, 600); margin: 0.5em 0 0.2em; }
|
|
1739
|
-
.aparte-content h3, .segment-content h3, .thinking-content h3 { font-size: var(--aparte-prose-h3-size, 1.1em); font-weight: var(--aparte-font-weight-semibold, 600); margin: 0.4em 0 0.15em; }
|
|
1740
|
-
.aparte-content h4, .segment-content h4, .thinking-content h4,
|
|
1741
|
-
.aparte-content h5, .segment-content h5, .thinking-content h5,
|
|
1742
|
-
.aparte-content h6, .segment-content h6, .thinking-content h6 { font-size: 1em; font-weight: var(--aparte-font-weight-semibold, 600); margin: 0.3em 0 0.1em; }
|
|
1823
|
+
.aparte-content h1, .aparte-segment-content h1, .aparte-thinking-content h1 { font-size: var(--aparte-prose-h1-size, 1.4em); font-weight: var(--aparte-font-weight-semibold, 600); margin: 0.6em 0 0.2em; }
|
|
1824
|
+
.aparte-content h2, .aparte-segment-content h2, .aparte-thinking-content h2 { font-size: var(--aparte-prose-h2-size, 1.25em); font-weight: var(--aparte-font-weight-semibold, 600); margin: 0.5em 0 0.2em; }
|
|
1825
|
+
.aparte-content h3, .aparte-segment-content h3, .aparte-thinking-content h3 { font-size: var(--aparte-prose-h3-size, 1.1em); font-weight: var(--aparte-font-weight-semibold, 600); margin: 0.4em 0 0.15em; }
|
|
1826
|
+
.aparte-content h4, .aparte-segment-content h4, .aparte-thinking-content h4,
|
|
1827
|
+
.aparte-content h5, .aparte-segment-content h5, .aparte-thinking-content h5,
|
|
1828
|
+
.aparte-content h6, .aparte-segment-content h6, .aparte-thinking-content h6 { font-size: 1em; font-weight: var(--aparte-font-weight-semibold, 600); margin: 0.3em 0 0.1em; }
|
|
1743
1829
|
|
|
1744
1830
|
.aparte-content ul,
|
|
1745
|
-
.segment-content ul,
|
|
1746
|
-
.thinking-content ul {
|
|
1831
|
+
.aparte-segment-content ul,
|
|
1832
|
+
.aparte-thinking-content ul {
|
|
1747
1833
|
list-style: disc;
|
|
1748
1834
|
padding-left: var(--aparte-prose-list-indent, 1.5em);
|
|
1749
1835
|
margin: var(--aparte-prose-list-margin, 0.4em 0);
|
|
1750
1836
|
}
|
|
1751
1837
|
|
|
1752
1838
|
.aparte-content ol,
|
|
1753
|
-
.segment-content ol,
|
|
1754
|
-
.thinking-content ol {
|
|
1839
|
+
.aparte-segment-content ol,
|
|
1840
|
+
.aparte-thinking-content ol {
|
|
1755
1841
|
list-style: decimal;
|
|
1756
1842
|
padding-left: var(--aparte-prose-list-indent, 1.5em);
|
|
1757
1843
|
margin: var(--aparte-prose-list-margin, 0.4em 0);
|
|
1758
1844
|
}
|
|
1759
1845
|
|
|
1760
1846
|
.aparte-content li,
|
|
1761
|
-
.segment-content li,
|
|
1762
|
-
.thinking-content li {
|
|
1847
|
+
.aparte-segment-content li,
|
|
1848
|
+
.aparte-thinking-content li {
|
|
1763
1849
|
margin: var(--aparte-prose-li-margin, 0.15em 0);
|
|
1764
1850
|
}
|
|
1765
1851
|
|
|
1766
1852
|
.aparte-content blockquote,
|
|
1767
|
-
.segment-content blockquote,
|
|
1768
|
-
.thinking-content blockquote {
|
|
1853
|
+
.aparte-segment-content blockquote,
|
|
1854
|
+
.aparte-thinking-content blockquote {
|
|
1769
1855
|
border-left: var(--aparte-prose-blockquote-border-width, 3px) solid var(--aparte-prose-blockquote-border, var(--aparte-border, #e5e7eb));
|
|
1770
1856
|
padding-left: 1em;
|
|
1771
1857
|
margin: 0.4em 0;
|
|
@@ -1774,20 +1860,20 @@ aparte-chat-status:not([visible]) {
|
|
|
1774
1860
|
}
|
|
1775
1861
|
|
|
1776
1862
|
.aparte-content strong,
|
|
1777
|
-
.segment-content strong,
|
|
1778
|
-
.thinking-content strong {
|
|
1863
|
+
.aparte-segment-content strong,
|
|
1864
|
+
.aparte-thinking-content strong {
|
|
1779
1865
|
font-weight: var(--aparte-font-weight-semibold, 600);
|
|
1780
1866
|
}
|
|
1781
1867
|
|
|
1782
1868
|
.aparte-content em,
|
|
1783
|
-
.segment-content em,
|
|
1784
|
-
.thinking-content em {
|
|
1869
|
+
.aparte-segment-content em,
|
|
1870
|
+
.aparte-thinking-content em {
|
|
1785
1871
|
font-style: italic;
|
|
1786
1872
|
}
|
|
1787
1873
|
|
|
1788
1874
|
.aparte-content code,
|
|
1789
|
-
.segment-content code,
|
|
1790
|
-
.thinking-content code {
|
|
1875
|
+
.aparte-segment-content code,
|
|
1876
|
+
.aparte-thinking-content code {
|
|
1791
1877
|
font-family: var(--aparte-code-font-family, ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, monospace);
|
|
1792
1878
|
font-size: var(--aparte-code-inline-font-size, 0.875em);
|
|
1793
1879
|
background: var(--aparte-prose-code-bg, var(--aparte-code-bg, #f3f4f6));
|
|
@@ -1796,29 +1882,29 @@ aparte-chat-status:not([visible]) {
|
|
|
1796
1882
|
}
|
|
1797
1883
|
|
|
1798
1884
|
.aparte-content a,
|
|
1799
|
-
.segment-content a,
|
|
1800
|
-
.thinking-content a {
|
|
1885
|
+
.aparte-segment-content a,
|
|
1886
|
+
.aparte-thinking-content a {
|
|
1801
1887
|
color: var(--aparte-primary, #6366f1);
|
|
1802
1888
|
text-decoration: underline;
|
|
1803
1889
|
}
|
|
1804
1890
|
|
|
1805
1891
|
.aparte-content hr,
|
|
1806
|
-
.segment-content hr,
|
|
1807
|
-
.thinking-content hr {
|
|
1892
|
+
.aparte-segment-content hr,
|
|
1893
|
+
.aparte-thinking-content hr {
|
|
1808
1894
|
border: none;
|
|
1809
1895
|
border-top: var(--aparte-border-width, 1px) solid var(--aparte-border, #e5e7eb);
|
|
1810
1896
|
margin: 0.75em 0;
|
|
1811
1897
|
}
|
|
1812
1898
|
|
|
1813
1899
|
/* Thinking */
|
|
1814
|
-
.segment-thinking {
|
|
1900
|
+
.aparte-segment-thinking {
|
|
1815
1901
|
/* Understated disclosure: a muted left rail, not a filled card. */
|
|
1816
1902
|
border-left: var(--aparte-thinking-rail-width, 2px) solid var(--aparte-thinking-border, #e5e7eb);
|
|
1817
1903
|
margin: var(--aparte-space-5, 10px) 0;
|
|
1818
1904
|
background: transparent;
|
|
1819
1905
|
}
|
|
1820
1906
|
|
|
1821
|
-
.thinking-header {
|
|
1907
|
+
.aparte-thinking-header {
|
|
1822
1908
|
display: flex;
|
|
1823
1909
|
align-items: center;
|
|
1824
1910
|
gap: var(--aparte-space-3, 6px);
|
|
@@ -1830,27 +1916,27 @@ aparte-chat-status:not([visible]) {
|
|
|
1830
1916
|
list-style: none;
|
|
1831
1917
|
}
|
|
1832
1918
|
|
|
1833
|
-
.thinking-header::-webkit-details-marker {
|
|
1919
|
+
.aparte-thinking-header::-webkit-details-marker {
|
|
1834
1920
|
display: none;
|
|
1835
1921
|
}
|
|
1836
1922
|
|
|
1837
|
-
.thinking-toggle {
|
|
1923
|
+
.aparte-thinking-toggle {
|
|
1838
1924
|
margin-inline-start: auto;
|
|
1839
1925
|
/* Logical property */
|
|
1840
1926
|
transition: transform 0.2s;
|
|
1841
1927
|
opacity: 0.55;
|
|
1842
1928
|
}
|
|
1843
1929
|
|
|
1844
|
-
details[open] .thinking-toggle {
|
|
1930
|
+
details[open] .aparte-thinking-toggle {
|
|
1845
1931
|
transform: rotate(180deg);
|
|
1846
1932
|
}
|
|
1847
1933
|
|
|
1848
|
-
.thinking-toggle::after {
|
|
1934
|
+
.aparte-thinking-toggle::after {
|
|
1849
1935
|
content: '▼';
|
|
1850
1936
|
font-size: var(--aparte-thinking-toggle-size, 9px);
|
|
1851
1937
|
}
|
|
1852
1938
|
|
|
1853
|
-
.thinking-content {
|
|
1939
|
+
.aparte-thinking-content {
|
|
1854
1940
|
padding: var(--aparte-space-2, 4px) 0 var(--aparte-space-1, 2px) var(--aparte-space-5, 10px);
|
|
1855
1941
|
font-size: var(--aparte-font-size-md, 13px);
|
|
1856
1942
|
line-height: var(--aparte-thinking-content-line-height, 1.55);
|
|
@@ -1861,14 +1947,14 @@ details[open] .thinking-toggle {
|
|
|
1861
1947
|
}
|
|
1862
1948
|
|
|
1863
1949
|
/* Code */
|
|
1864
|
-
.segment-code {
|
|
1950
|
+
.aparte-segment-code {
|
|
1865
1951
|
margin: var(--aparte-space-6, 12px) 0;
|
|
1866
1952
|
border-radius: var(--aparte-radius-code);
|
|
1867
1953
|
overflow: hidden;
|
|
1868
1954
|
border: var(--aparte-border-width, 1px) solid var(--aparte-code-border, #e5e7eb);
|
|
1869
1955
|
}
|
|
1870
1956
|
|
|
1871
|
-
.code-header {
|
|
1957
|
+
.aparte-code-header {
|
|
1872
1958
|
display: flex;
|
|
1873
1959
|
align-items: center;
|
|
1874
1960
|
padding: var(--aparte-space-4, 8px) var(--aparte-space-6, 12px);
|
|
@@ -1878,25 +1964,25 @@ details[open] .thinking-toggle {
|
|
|
1878
1964
|
color: var(--aparte-code-header-text, #4b5563);
|
|
1879
1965
|
}
|
|
1880
1966
|
|
|
1881
|
-
.code-filename {
|
|
1967
|
+
.aparte-code-filename {
|
|
1882
1968
|
font-weight: var(--aparte-font-weight-semibold, 600);
|
|
1883
1969
|
margin-inline-end: auto;
|
|
1884
1970
|
/* Logical property: pushes language + copy to the right when filename is present */
|
|
1885
1971
|
}
|
|
1886
1972
|
|
|
1887
|
-
.code-header-filler {
|
|
1973
|
+
.aparte-code-header-filler {
|
|
1888
1974
|
flex: 1;
|
|
1889
1975
|
/* No-filename placeholder — keeps language + copy right-aligned */
|
|
1890
1976
|
}
|
|
1891
1977
|
|
|
1892
|
-
.code-language {
|
|
1978
|
+
.aparte-code-language {
|
|
1893
1979
|
margin-inline-end: var(--aparte-space-4, 8px);
|
|
1894
1980
|
/* Logical property */
|
|
1895
1981
|
text-transform: uppercase;
|
|
1896
1982
|
opacity: 0.7;
|
|
1897
1983
|
}
|
|
1898
1984
|
|
|
1899
|
-
.code-copy {
|
|
1985
|
+
.aparte-code-copy {
|
|
1900
1986
|
background: transparent;
|
|
1901
1987
|
border: none;
|
|
1902
1988
|
cursor: pointer;
|
|
@@ -1908,23 +1994,23 @@ details[open] .thinking-toggle {
|
|
|
1908
1994
|
justify-content: center;
|
|
1909
1995
|
}
|
|
1910
1996
|
|
|
1911
|
-
.code-copy:hover {
|
|
1997
|
+
.aparte-code-copy:hover {
|
|
1912
1998
|
background: var(--aparte-code-copy-hover-bg, rgba(0, 0, 0, 0.05));
|
|
1913
1999
|
}
|
|
1914
2000
|
|
|
1915
|
-
.code-copy svg {
|
|
2001
|
+
.aparte-code-copy svg {
|
|
1916
2002
|
width: var(--aparte-code-copy-icon-size, 14px);
|
|
1917
2003
|
height: var(--aparte-code-copy-icon-size, 14px);
|
|
1918
2004
|
}
|
|
1919
2005
|
|
|
1920
|
-
.code-content-wrapper pre {
|
|
2006
|
+
.aparte-code-content-wrapper pre {
|
|
1921
2007
|
margin: 0;
|
|
1922
2008
|
padding: var(--aparte-space-6, 12px);
|
|
1923
2009
|
/* Wrap long lines instead of a horizontal scrollbar. `pre-wrap` honours
|
|
1924
2010
|
newlines + indentation but soft-wraps overflowing lines; `overflow-wrap:
|
|
1925
2011
|
anywhere` breaks unbreakable tokens (long URLs, hashes). Applies to both
|
|
1926
2012
|
the plain <pre><code> initial render and the shiki <pre class="shiki">
|
|
1927
|
-
replacement, since both sit inside .code-content-wrapper. */
|
|
2013
|
+
replacement, since both sit inside .aparte-code-content-wrapper. */
|
|
1928
2014
|
white-space: pre-wrap;
|
|
1929
2015
|
overflow-wrap: anywhere;
|
|
1930
2016
|
overflow-x: hidden;
|
|
@@ -1940,7 +2026,7 @@ details[open] .thinking-toggle {
|
|
|
1940
2026
|
}
|
|
1941
2027
|
|
|
1942
2028
|
/* Error */
|
|
1943
|
-
.segment-error {
|
|
2029
|
+
.aparte-segment-error {
|
|
1944
2030
|
display: flex;
|
|
1945
2031
|
gap: var(--aparte-space-6, 12px);
|
|
1946
2032
|
padding: var(--aparte-space-6, 12px) var(--aparte-space-8, 16px);
|
|
@@ -1953,7 +2039,7 @@ details[open] .thinking-toggle {
|
|
|
1953
2039
|
font-family: var(--aparte-font-family, system-ui, sans-serif);
|
|
1954
2040
|
}
|
|
1955
2041
|
|
|
1956
|
-
.error-icon-wrapper {
|
|
2042
|
+
.aparte-error-icon-wrapper {
|
|
1957
2043
|
flex-shrink: 0;
|
|
1958
2044
|
color: var(--aparte-error-solid, #dc2626);
|
|
1959
2045
|
display: flex;
|
|
@@ -1961,29 +2047,29 @@ details[open] .thinking-toggle {
|
|
|
1961
2047
|
padding-top: var(--aparte-space-1, 2px);
|
|
1962
2048
|
}
|
|
1963
2049
|
|
|
1964
|
-
.error-icon-wrapper svg {
|
|
2050
|
+
.aparte-error-icon-wrapper svg {
|
|
1965
2051
|
width: var(--aparte-error-icon-size, 20px);
|
|
1966
2052
|
height: var(--aparte-error-icon-size, 20px);
|
|
1967
2053
|
}
|
|
1968
2054
|
|
|
1969
|
-
.error-content {
|
|
2055
|
+
.aparte-error-content {
|
|
1970
2056
|
flex: 1;
|
|
1971
2057
|
min-width: 0;
|
|
1972
2058
|
}
|
|
1973
2059
|
|
|
1974
|
-
.error-title {
|
|
2060
|
+
.aparte-error-title {
|
|
1975
2061
|
font-weight: var(--aparte-font-weight-semibold, 600);
|
|
1976
2062
|
font-size: var(--aparte-font-size-lg, 14px);
|
|
1977
2063
|
margin-bottom: var(--aparte-space-2, 4px);
|
|
1978
2064
|
color: var(--aparte-error-title, #7f1d1d);
|
|
1979
2065
|
}
|
|
1980
2066
|
|
|
1981
|
-
.error-message {
|
|
2067
|
+
.aparte-error-message {
|
|
1982
2068
|
font-size: var(--aparte-font-size-lg, 14px);
|
|
1983
2069
|
line-height: var(--aparte-line-height-normal, 1.5);
|
|
1984
2070
|
}
|
|
1985
2071
|
|
|
1986
|
-
.error-details {
|
|
2072
|
+
.aparte-error-details {
|
|
1987
2073
|
margin-top: var(--aparte-space-4, 8px);
|
|
1988
2074
|
padding-top: var(--aparte-space-4, 8px);
|
|
1989
2075
|
border-top: var(--aparte-border-width, 1px) solid var(--aparte-error-border, #fecaca);
|
|
@@ -1993,35 +2079,461 @@ details[open] .thinking-toggle {
|
|
|
1993
2079
|
white-space: pre-wrap;
|
|
1994
2080
|
}
|
|
1995
2081
|
|
|
1996
|
-
/* Progress */
|
|
1997
|
-
.segment-progress {
|
|
1998
|
-
margin: var(--aparte-space-6, 12px) 0;
|
|
1999
|
-
}
|
|
2000
2082
|
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2083
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
2084
|
+
Segment renderers — tool call · artifact card · pipeline waiting
|
|
2085
|
+
|
|
2086
|
+
These three shipped their CSS from `getStyles()` until now: a template literal
|
|
2087
|
+
in the renderer's own .ts file, injected into <head> at runtime. That seam is
|
|
2088
|
+
for a CONSUMER's renderer — something registered through registerSegmentRenderer
|
|
2089
|
+
or registerToolRenderer cannot edit this file, so `getStyles()` is its only way
|
|
2090
|
+
onto the page. A BUILT-IN has this file, and two reasons to use it:
|
|
2091
|
+
|
|
2092
|
+
- check:derived-vars reads this path and nothing else. A declaration whose
|
|
2093
|
+
value reads another variable has to sit on the 5-anchor layer or it cannot
|
|
2094
|
+
follow a palette a subtree overrides, and one hidden in a renderer was
|
|
2095
|
+
never checked at all.
|
|
2096
|
+
- it is read as CSS, by tools and by people. A backtick closes a template
|
|
2097
|
+
literal, and one did — the artifact card's own comment recorded it
|
|
2098
|
+
happening — then it happened three more times in one sitting, the worst of
|
|
2099
|
+
them rendering a `safe-text` source marker into an assistant's bubble as
|
|
2100
|
+
prose, because inside a template literal a `//` comment is just text.
|
|
2101
|
+
|
|
2102
|
+
NOT a reason, though it was the first one I wrote here: reaching the public CSS
|
|
2103
|
+
reference. `gen-css-vars.mjs` walks all of core's source for `var(--aparte-*)`
|
|
2104
|
+
reads, so a knob a renderer read was already listed with its fallback as the
|
|
2105
|
+
default — the move changed that file by zero lines. Worth recording, because the
|
|
2106
|
+
plausible version of this argument is the one that gets repeated.
|
|
2107
|
+
|
|
2108
|
+
Moving them changes no contract either: core's entry imports this file and
|
|
2109
|
+
package.json marks every .css a side effect, so importing @aparte/core has
|
|
2110
|
+
always brought this sheet along.
|
|
2111
|
+
───────────────────────────────────────────────────────────────────────────── */
|
|
2009
2112
|
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2113
|
+
/* Tool call */
|
|
2114
|
+
.aparte-segment-tool-call { display: block; padding: 2px 0; }
|
|
2115
|
+
/* The row is the summary. list-style:none plus the ::-webkit- pseudo is the
|
|
2116
|
+
pair that actually removes the native marker across engines. */
|
|
2117
|
+
/* A ROW, not a badge.
|
|
2118
|
+
It was a rounded chip, which is what a tag looks like — and a tool call is not
|
|
2119
|
+
a tag, it is a step of the turn. Every current implementation draws it as a
|
|
2120
|
+
line: the disclosure control, the call's identity, and its state at the far
|
|
2121
|
+
end. The chip also had to carry a border and a fill, so it competed with the
|
|
2122
|
+
reply text beside it for attention it did not deserve. */
|
|
2123
|
+
.aparte-tool-summary {
|
|
2124
|
+
display: flex; align-items: center; gap: 7px;
|
|
2125
|
+
padding: 3px 6px; margin-inline-start: -6px;
|
|
2126
|
+
border-radius: var(--aparte-tool-row-radius, 6px);
|
|
2127
|
+
cursor: pointer; list-style: none;
|
|
2128
|
+
}
|
|
2129
|
+
.aparte-tool-summary:hover { background: var(--aparte-surface-2, rgba(128,128,128,0.07)); }
|
|
2130
|
+
.aparte-tool-summary::-webkit-details-marker { display: none; }
|
|
2131
|
+
.aparte-tool-toggle {
|
|
2132
|
+
width: 0; height: 0; flex: none; margin-inline-start: -1px;
|
|
2133
|
+
border-inline-start: 5px solid currentColor;
|
|
2134
|
+
border-block: 4px solid transparent;
|
|
2135
|
+
opacity: 0.5; transition: transform 0.15s;
|
|
2136
|
+
}
|
|
2137
|
+
.aparte-tool-summary:hover .aparte-tool-toggle { opacity: 0.9; }
|
|
2138
|
+
details[open] > .aparte-tool-summary .aparte-tool-toggle { transform: rotate(90deg); }
|
|
2139
|
+
/* A rule down the leading edge, so the disclosure reads as belonging to the
|
|
2140
|
+
pill above it rather than continuing the message text below. Without it
|
|
2141
|
+
"Output" and the assistant's next sentence sat in one undifferentiated
|
|
2142
|
+
column. */
|
|
2143
|
+
.aparte-tool-detail {
|
|
2144
|
+
display: flex; flex-direction: column; gap: 8px;
|
|
2145
|
+
/* Aligned under the row's icon, so the rule reads as descending from the
|
|
2146
|
+
call rather than floating beside it. */
|
|
2147
|
+
margin: 4px 0 6px 3px; padding: 2px 0 2px 12px;
|
|
2148
|
+
border-inline-start: 1px solid var(--aparte-border, rgba(128,128,128,0.25));
|
|
2149
|
+
}
|
|
2150
|
+
.aparte-tool-part-label {
|
|
2151
|
+
display: block; font-size: 0.68rem; text-transform: uppercase;
|
|
2152
|
+
letter-spacing: 0.04em; opacity: 0.55; margin-bottom: 2px;
|
|
2153
|
+
}
|
|
2154
|
+
.aparte-tool-part-body pre { margin: 0; }
|
|
2155
|
+
/* Always in the DOM so update can leave the node alone and toggle hidden
|
|
2156
|
+
instead — an attribute a test can read, where a CSS-only rule is invisible
|
|
2157
|
+
to jsdom. */
|
|
2158
|
+
.aparte-tool-spinner[hidden] { display: none; }
|
|
2159
|
+
/* The call's identity: its icon and its name, and no decoration of its own.
|
|
2160
|
+
No border, no fill, no tint at any status — the row is the container now, and
|
|
2161
|
+
the colour lives on the state badge alone. A resolved call used to be filled
|
|
2162
|
+
green, which made a finished step shout louder than the reply it belongs to. */
|
|
2163
|
+
.aparte-tool-label {
|
|
2164
|
+
display: inline-flex;
|
|
2165
|
+
align-items: center;
|
|
2166
|
+
gap: 6px;
|
|
2167
|
+
min-width: 0;
|
|
2168
|
+
font-size: 0.8rem;
|
|
2169
|
+
font-weight: 500;
|
|
2170
|
+
color: var(--aparte-text, inherit);
|
|
2171
|
+
user-select: none;
|
|
2172
|
+
}
|
|
2173
|
+
/* A fixed square, and the glyph centred in it. The icon was baseline-aligned
|
|
2174
|
+
inside an inline box, so it sat low against the name and moved with whatever
|
|
2175
|
+
glyph the icon provider returned. */
|
|
2176
|
+
.aparte-tool-icon {
|
|
2177
|
+
display: grid;
|
|
2178
|
+
place-items: center;
|
|
2179
|
+
width: 1em; height: 1em;
|
|
2180
|
+
flex: none;
|
|
2181
|
+
opacity: 0.7;
|
|
2182
|
+
}
|
|
2183
|
+
.aparte-tool-icon svg { width: 1em; height: 1em; display: block; }
|
|
2184
|
+
.aparte-tool-name { font-family: var(--aparte-code-font-family, ui-monospace, monospace); }
|
|
2185
|
+
/* The state, as a word with its glyph. Colour lives HERE and nowhere else.
|
|
2186
|
+
Pushed to the far end by DOM order plus an auto inline-start margin, which is
|
|
2187
|
+
the placement rule this repo already settled on: no left/right in a name, so
|
|
2188
|
+
a right-to-left locale mirrors it for free. */
|
|
2189
|
+
.aparte-tool-state {
|
|
2190
|
+
display: inline-flex; align-items: center; gap: 4px;
|
|
2191
|
+
margin-inline-start: auto;
|
|
2192
|
+
font-size: 0.72rem; font-weight: 500;
|
|
2193
|
+
color: var(--aparte-text-muted, rgba(128,128,128,0.75));
|
|
2194
|
+
user-select: none;
|
|
2195
|
+
}
|
|
2196
|
+
.aparte-tool-state svg { width: 0.9em; height: 0.9em; display: block; }
|
|
2197
|
+
/* Scoped to the segment, not to a bare [data-status].
|
|
2198
|
+
These three were the only rules in this file whose leftmost compound is an unprefixed
|
|
2199
|
+
non-element selector, which means they reached OUT of core: a host wrapping the chat in
|
|
2200
|
+
<div data-status="rejected"> re-tinted every completed tool call's word red, because
|
|
2201
|
+
0,2,0 beats the base rule's 0,1,0 and source order puts rejected/aborted last. Core
|
|
2202
|
+
itself documents data-status as a free-form host attribute on <aparte-option>. */
|
|
2203
|
+
.aparte-segment-tool-call[data-status="resolved"] .aparte-tool-state { color: var(--aparte-success, rgb(21,128,61)); }
|
|
2204
|
+
.aparte-segment-tool-call[data-status="rejected"] .aparte-tool-state,
|
|
2205
|
+
.aparte-segment-tool-call[data-status="aborted"] .aparte-tool-state { color: var(--aparte-error, rgb(185,28,28)); }
|
|
2206
|
+
/* The Approve / Reject button rules were here. They moved with the buttons, to
|
|
2207
|
+
.aparte-approval-option in this same file - and what stayed behind was a
|
|
2208
|
+
leftover: a rule tinting .aparte-tool-label's border while a decision was pending,
|
|
2209
|
+
which stopped painting anything the moment the row redesign took that border
|
|
2210
|
+
off .aparte-tool-label. It reached for a variable that was never declared, and it
|
|
2211
|
+
survived because a template literal is not a stylesheet anyone greps. The
|
|
2212
|
+
state is named in words by .aparte-tool-state now, and the decision is at the
|
|
2213
|
+
composer. */
|
|
2214
|
+
.aparte-tool-spinner {
|
|
2215
|
+
width: 10px; height: 10px;
|
|
2216
|
+
border: 1.5px solid currentColor;
|
|
2217
|
+
border-top-color: transparent;
|
|
2218
|
+
border-radius: 50%;
|
|
2219
|
+
display: inline-block;
|
|
2220
|
+
animation: tool-spin 0.7s linear infinite;
|
|
2221
|
+
}
|
|
2222
|
+
.aparte-tool-state { font-size: 0.75rem; }
|
|
2223
|
+
@keyframes tool-spin { to { transform: rotate(360deg); } }
|
|
2224
|
+
|
|
2225
|
+
/* Artifact card */
|
|
2226
|
+
.aparte-segment-artifact-card {
|
|
2227
|
+
display: flex; flex-direction: column;
|
|
2228
|
+
margin: 8px 0;
|
|
2229
|
+
border: 1px solid var(--aparte-border, rgba(0,0,0,0.12));
|
|
2230
|
+
border-radius: 12px;
|
|
2231
|
+
background: var(--aparte-surface, #fff);
|
|
2232
|
+
overflow: hidden;
|
|
2233
|
+
font: inherit;
|
|
2234
|
+
color: var(--aparte-text, inherit);
|
|
2235
|
+
}
|
|
2236
|
+
.aparte-art-card__header {
|
|
2237
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
2238
|
+
padding: 8px 10px;
|
|
2239
|
+
border-bottom: 1px solid var(--aparte-border, rgba(0,0,0,0.08));
|
|
2240
|
+
background: var(--aparte-surface-2, rgba(0,0,0,0.02));
|
|
2241
|
+
min-height: 36px;
|
|
2242
|
+
}
|
|
2243
|
+
.aparte-art-card__title-block { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
2244
|
+
.aparte-art-card__kind {
|
|
2245
|
+
font-size: 0.7rem; font-weight: 600;
|
|
2246
|
+
text-transform: uppercase; letter-spacing: 0.04em;
|
|
2247
|
+
padding: 2px 6px; border-radius: 4px;
|
|
2248
|
+
background: var(--aparte-surface, #fff);
|
|
2249
|
+
border: 1px solid var(--aparte-border, rgba(0,0,0,0.1));
|
|
2250
|
+
color: var(--aparte-text-muted, rgba(0,0,0,0.6));
|
|
2251
|
+
}
|
|
2252
|
+
.aparte-art-card__title {
|
|
2253
|
+
font-size: 0.85rem; font-weight: 500;
|
|
2254
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
2255
|
+
}
|
|
2256
|
+
.aparte-art-card__pulse {
|
|
2257
|
+
width: 8px; height: 8px; border-radius: 50%;
|
|
2258
|
+
background: var(--aparte-accent, #3b82f6);
|
|
2259
|
+
animation: aparte-art-card-pulse 1.2s ease-in-out infinite;
|
|
2260
|
+
}
|
|
2261
|
+
@keyframes aparte-art-card-pulse {
|
|
2262
|
+
0%, 100% { opacity: 0.35; transform: scale(0.85); }
|
|
2263
|
+
50% { opacity: 1; transform: scale(1.1); }
|
|
2264
|
+
}
|
|
2265
|
+
.aparte-art-card__actions { display: flex; gap: 4px; }
|
|
2266
|
+
.aparte-art-card__btn {
|
|
2267
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
2268
|
+
width: 28px; height: 28px;
|
|
2269
|
+
background: transparent;
|
|
2270
|
+
border: 1px solid transparent;
|
|
2271
|
+
border-radius: 6px;
|
|
2272
|
+
color: var(--aparte-text-muted, rgba(0,0,0,0.55));
|
|
2273
|
+
cursor: pointer;
|
|
2274
|
+
transition: background 0.12s, border-color 0.12s, color 0.12s;
|
|
2275
|
+
}
|
|
2276
|
+
.aparte-art-card__btn:hover:not(:disabled) {
|
|
2277
|
+
background: var(--aparte-surface-hover, rgba(0,0,0,0.04));
|
|
2278
|
+
border-color: var(--aparte-border, rgba(0,0,0,0.1));
|
|
2279
|
+
color: var(--aparte-text, inherit);
|
|
2280
|
+
}
|
|
2281
|
+
.aparte-art-card__btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
2282
|
+
.aparte-art-card__tabs {
|
|
2283
|
+
/* justify-content and the padding are DECLARED, not left to a default.
|
|
2284
|
+
Core is light DOM on purpose - no shadow root, no ::part(), any selector
|
|
2285
|
+
reaches in - and the corollary is that a component must state what its
|
|
2286
|
+
layout depends on, because an undeclared property has nothing to override
|
|
2287
|
+
a host rule with. A consuming page with a bare nav selector setting
|
|
2288
|
+
justify-content: space-between and padding-top (this library's own docs
|
|
2289
|
+
site had exactly that) otherwise pushes these two tabs to opposite ends of
|
|
2290
|
+
the card and pads the row out.
|
|
2291
|
+
|
|
2292
|
+
flex-end, and Code first in the DOM. The card OPENS on Code - mounting the
|
|
2293
|
+
preview would execute model-authored code with no gesture (ratified
|
|
2294
|
+
decision #8) - and a selected tab sitting second reads backwards. Right,
|
|
2295
|
+
because the header above puts the artifact's identity on the left and its
|
|
2296
|
+
copy/download buttons on the right, so this keeps every control in one
|
|
2297
|
+
column. DOM order is also keyboard order, so the tab a reader lands on
|
|
2298
|
+
first is the one already showing. */
|
|
2299
|
+
display: flex; justify-content: flex-end; align-items: stretch; gap: 2px;
|
|
2300
|
+
padding: 4px 8px 0;
|
|
2301
|
+
border-bottom: 1px solid var(--aparte-border, rgba(0,0,0,0.08));
|
|
2302
|
+
background: var(--aparte-surface-2, rgba(0,0,0,0.02));
|
|
2303
|
+
}
|
|
2304
|
+
.aparte-art-card__tabs button {
|
|
2305
|
+
padding: 6px 12px;
|
|
2306
|
+
font-size: 0.78rem;
|
|
2307
|
+
background: transparent;
|
|
2308
|
+
border: 1px solid transparent;
|
|
2309
|
+
border-bottom: none;
|
|
2310
|
+
border-radius: 6px 6px 0 0;
|
|
2311
|
+
color: var(--aparte-text-muted, rgba(0,0,0,0.6));
|
|
2312
|
+
cursor: pointer;
|
|
2313
|
+
transition: background 0.12s, color 0.12s;
|
|
2314
|
+
}
|
|
2315
|
+
.aparte-art-card__tabs button[aria-selected="true"] {
|
|
2316
|
+
background: var(--aparte-surface, #fff);
|
|
2317
|
+
border-color: var(--aparte-border, rgba(0,0,0,0.08));
|
|
2318
|
+
color: var(--aparte-text, inherit);
|
|
2319
|
+
font-weight: 500;
|
|
2320
|
+
}
|
|
2321
|
+
.aparte-art-card__tabs button:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
2322
|
+
/* The card's heights, as variables with ONE owner each.
|
|
2323
|
+
They were four hardcoded numbers in the only part of this card that did not
|
|
2324
|
+
use a variable - everything else here already reads var(--aparte-code-bg) and
|
|
2325
|
+
friends - and two of them had to agree while a third contradicted a fourth:
|
|
2326
|
+
the code pane repeated the body's 600px, and the "press Preview" placeholder
|
|
2327
|
+
was 120px tall inside a body whose min-height said 80, so that minimum applied
|
|
2328
|
+
to nothing.
|
|
2329
|
+
The frame stays a FIXED height rather than an aspect ratio, which is what
|
|
2330
|
+
embeds of arbitrary HTML actually do - CodeSandbox documents 500px, StackBlitz
|
|
2331
|
+
takes a height parameter - because a frame with an opaque origin cannot be
|
|
2332
|
+
measured and a 16/10 ratio on a wide card is enormous. The vh cap is the part
|
|
2333
|
+
that was missing: a fixed 480px should not own a phone screen.
|
|
2334
|
+
Each default lives in its read, as var(--x, literal), the way every other
|
|
2335
|
+
value in this file already does - not in a declaration block on top of the
|
|
2336
|
+
fallbacks, which would be two owners of one number again. It also means the
|
|
2337
|
+
docs' CSS-variable generator finds them: its sweep looks for reads that
|
|
2338
|
+
carry a fallback, so a read without one is a public knob nobody documents. */
|
|
2339
|
+
.aparte-art-card__body {
|
|
2340
|
+
position: relative;
|
|
2341
|
+
/* The placeholder is the tallest thing this box can hold while empty, so it
|
|
2342
|
+
IS the minimum - one number instead of two that disagreed. */
|
|
2343
|
+
min-height: var(--aparte-artifact-pending-height, 120px);
|
|
2344
|
+
max-height: var(--aparte-artifact-body-max, 600px);
|
|
2345
|
+
overflow: hidden;
|
|
2016
2346
|
}
|
|
2017
|
-
|
|
2018
|
-
.
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2347
|
+
.aparte-art-card__pane { display: none; height: 100%; }
|
|
2348
|
+
.aparte-segment-artifact-card[data-tab="code"] .aparte-art-card__pane[data-pane="code"] { display: block; }
|
|
2349
|
+
.aparte-segment-artifact-card[data-tab="preview"] .aparte-art-card__pane[data-pane="preview"] { display: block; }
|
|
2350
|
+
.aparte-art-card__pane[data-pane="code"] {
|
|
2351
|
+
/* The body already caps this; repeating the number was the second owner. */
|
|
2352
|
+
max-height: var(--aparte-artifact-body-max, 600px); overflow: auto;
|
|
2353
|
+
}
|
|
2354
|
+
.aparte-art-card__pane[data-pane="code"] pre {
|
|
2355
|
+
margin: 0; padding: 12px;
|
|
2356
|
+
font-size: 0.82rem;
|
|
2357
|
+
background: var(--aparte-code-bg, #fafafa);
|
|
2358
|
+
}
|
|
2359
|
+
.aparte-art-card__frame {
|
|
2360
|
+
display: block;
|
|
2361
|
+
width: 100%;
|
|
2362
|
+
height: min(var(--aparte-artifact-frame-height, 480px), var(--aparte-artifact-frame-max, 70vh));
|
|
2363
|
+
border: 0;
|
|
2364
|
+
background: #fff;
|
|
2365
|
+
}
|
|
2366
|
+
.aparte-art-card__pending {
|
|
2367
|
+
display: flex; align-items: center; justify-content: center;
|
|
2368
|
+
height: var(--aparte-artifact-pending-height, 120px);
|
|
2369
|
+
color: var(--aparte-text-muted, rgba(0,0,0,0.5));
|
|
2370
|
+
font-size: 0.85rem;
|
|
2371
|
+
font-style: italic;
|
|
2372
|
+
}
|
|
2373
|
+
/* ── Binary file artifact (xlsx/pdf/docx) ──────────────────── */
|
|
2374
|
+
.aparte-segment-artifact-file {
|
|
2375
|
+
display: flex; flex-direction: column;
|
|
2376
|
+
margin: 8px 0;
|
|
2377
|
+
border: 1px solid var(--aparte-border, rgba(0,0,0,0.12));
|
|
2378
|
+
border-radius: 12px;
|
|
2379
|
+
background: var(--aparte-surface, #fff);
|
|
2380
|
+
overflow: hidden;
|
|
2381
|
+
color: var(--aparte-text, inherit);
|
|
2382
|
+
font: inherit;
|
|
2383
|
+
}
|
|
2384
|
+
.aparte-art-file__card {
|
|
2385
|
+
display: flex; align-items: center; gap: 12px;
|
|
2386
|
+
padding: 12px 14px;
|
|
2387
|
+
background: var(--aparte-surface-2, rgba(0,0,0,0.02));
|
|
2388
|
+
border-bottom: 1px solid var(--aparte-border, rgba(0,0,0,0.08));
|
|
2389
|
+
}
|
|
2390
|
+
.aparte-art-file__body {
|
|
2391
|
+
position: relative;
|
|
2392
|
+
}
|
|
2393
|
+
.aparte-art-file__code-pane {
|
|
2394
|
+
max-height: var(--aparte-artifact-file-code-max, 360px); overflow: auto;
|
|
2395
|
+
background: var(--aparte-code-bg, #fafafa);
|
|
2396
|
+
}
|
|
2397
|
+
.aparte-art-file__code-pane pre {
|
|
2398
|
+
margin: 0; padding: 12px;
|
|
2399
|
+
font-size: 0.82rem;
|
|
2400
|
+
font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
|
|
2401
|
+
}
|
|
2402
|
+
.aparte-art-file__preview-pane {
|
|
2403
|
+
max-height: var(--aparte-artifact-file-preview-max, 460px);
|
|
2404
|
+
overflow: auto;
|
|
2405
|
+
background: #fff;
|
|
2406
|
+
/* Preview is a document view — force light scheme regardless of
|
|
2407
|
+
the app theme, with a dark text colour so cells stay readable. */
|
|
2408
|
+
color: #1f2937;
|
|
2409
|
+
}
|
|
2410
|
+
.aparte-art-file__icon {
|
|
2411
|
+
width: 40px; height: 40px;
|
|
2412
|
+
border-radius: 8px;
|
|
2413
|
+
display: flex; align-items: center; justify-content: center;
|
|
2414
|
+
background: linear-gradient(135deg, #1d6f42, #0f5132);
|
|
2415
|
+
color: #fff;
|
|
2416
|
+
font-weight: 700;
|
|
2417
|
+
font-size: 0.78rem;
|
|
2418
|
+
letter-spacing: 0.04em;
|
|
2419
|
+
flex-shrink: 0;
|
|
2420
|
+
}
|
|
2421
|
+
.aparte-art-file__icon[data-kind="pdf"] { background: linear-gradient(135deg, #c0392b, #7d1f17); }
|
|
2422
|
+
.aparte-art-file__icon[data-kind="docx"] { background: linear-gradient(135deg, #1e5288, #0f3060); }
|
|
2423
|
+
.aparte-art-file__meta { flex: 1 1 auto; min-width: 0; }
|
|
2424
|
+
.aparte-art-file__meta-name {
|
|
2425
|
+
font-weight: 600; font-size: 0.92rem;
|
|
2426
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
2427
|
+
}
|
|
2428
|
+
.aparte-art-file__meta-sub {
|
|
2429
|
+
font-size: 0.78rem;
|
|
2430
|
+
color: var(--aparte-text-muted, rgba(0,0,0,0.55));
|
|
2431
|
+
}
|
|
2432
|
+
.aparte-art-file__actions { display: flex; gap: 6px; flex-shrink: 0; }
|
|
2433
|
+
.aparte-art-file__btn {
|
|
2434
|
+
border: 1px solid var(--aparte-border, rgba(0,0,0,0.12));
|
|
2435
|
+
background: var(--aparte-surface, #fff);
|
|
2436
|
+
color: var(--aparte-text, inherit);
|
|
2437
|
+
padding: 6px 10px;
|
|
2438
|
+
border-radius: 6px;
|
|
2439
|
+
font-size: 0.8rem;
|
|
2440
|
+
cursor: pointer;
|
|
2441
|
+
transition: background 0.12s ease;
|
|
2442
|
+
}
|
|
2443
|
+
.aparte-art-file__btn:hover { background: var(--aparte-surface-2, rgba(0,0,0,0.05)); }
|
|
2444
|
+
.aparte-art-file__btn--primary {
|
|
2445
|
+
background: var(--aparte-primary, #6366f1);
|
|
2446
|
+
color: #fff;
|
|
2447
|
+
border-color: var(--aparte-primary, #6366f1);
|
|
2448
|
+
}
|
|
2449
|
+
.aparte-art-file__btn--primary:hover { filter: brightness(1.07); }
|
|
2450
|
+
/* Hide the download button until the sandbox has produced the buffer.
|
|
2451
|
+
Avoids confusing the user with a disabled-but-styled-primary button
|
|
2452
|
+
during streaming / compiling. */
|
|
2453
|
+
.aparte-segment-artifact-file:not([data-state="ready"]) .aparte-art-file__btn[data-action="download"] {
|
|
2454
|
+
display: none;
|
|
2455
|
+
}
|
|
2456
|
+
.aparte-art-file__preview-pane table {
|
|
2457
|
+
border-collapse: collapse;
|
|
2458
|
+
width: 100%;
|
|
2459
|
+
font-size: 0.82rem;
|
|
2460
|
+
font-family: inherit;
|
|
2461
|
+
}
|
|
2462
|
+
.aparte-art-file__preview-pane th,
|
|
2463
|
+
.aparte-art-file__preview-pane td {
|
|
2464
|
+
border: 1px solid rgba(0,0,0,0.10);
|
|
2465
|
+
padding: 6px 10px;
|
|
2466
|
+
text-align: left;
|
|
2467
|
+
white-space: nowrap;
|
|
2468
|
+
color: #1f2937;
|
|
2469
|
+
background: #fff;
|
|
2470
|
+
}
|
|
2471
|
+
.aparte-art-file__preview-pane tr:nth-child(odd) td { background: #f9fafb; }
|
|
2472
|
+
.aparte-art-file__preview-pane tr:first-child td {
|
|
2473
|
+
background: #f3f4f6;
|
|
2474
|
+
font-weight: 600;
|
|
2475
|
+
position: sticky; top: 0;
|
|
2476
|
+
color: #111827;
|
|
2477
|
+
}
|
|
2478
|
+
.aparte-art-file__preview-empty {
|
|
2479
|
+
padding: 20px; text-align: center;
|
|
2480
|
+
color: var(--aparte-text-muted, rgba(0,0,0,0.5));
|
|
2481
|
+
font-size: 0.85rem; font-style: italic;
|
|
2482
|
+
}
|
|
2483
|
+
.aparte-segment-artifact-file[data-state="error"] .aparte-art-file__icon {
|
|
2484
|
+
background: linear-gradient(135deg, #c0392b, #7d1f17);
|
|
2485
|
+
}
|
|
2486
|
+
.aparte-art-file__error {
|
|
2487
|
+
padding: 16px 18px;
|
|
2488
|
+
background: rgba(239, 68, 68, 0.05);
|
|
2489
|
+
border-top: 1px solid rgba(239, 68, 68, 0.2);
|
|
2490
|
+
color: var(--aparte-text, inherit);
|
|
2491
|
+
}
|
|
2492
|
+
.aparte-art-file__error-title {
|
|
2493
|
+
font-weight: 600;
|
|
2494
|
+
font-size: 0.9rem;
|
|
2495
|
+
margin-bottom: 6px;
|
|
2496
|
+
color: #b91c1c;
|
|
2497
|
+
}
|
|
2498
|
+
.aparte-art-file__error-msg {
|
|
2499
|
+
font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
|
|
2500
|
+
font-size: 0.78rem;
|
|
2501
|
+
padding: 6px 10px;
|
|
2502
|
+
background: rgba(0,0,0,0.04);
|
|
2503
|
+
border-radius: 4px;
|
|
2504
|
+
margin-bottom: 8px;
|
|
2505
|
+
color: #7f1d1d;
|
|
2506
|
+
word-break: break-word;
|
|
2507
|
+
}
|
|
2508
|
+
.aparte-art-file__error-hint {
|
|
2509
|
+
font-size: 0.78rem;
|
|
2510
|
+
color: var(--aparte-text-muted, rgba(0,0,0,0.55));
|
|
2511
|
+
font-style: italic;
|
|
2023
2512
|
}
|
|
2024
2513
|
|
|
2514
|
+
/* Pipeline waiting */
|
|
2515
|
+
.aparte-segment-pipeline-waiting {
|
|
2516
|
+
display: flex;
|
|
2517
|
+
align-items: center;
|
|
2518
|
+
gap: 5px;
|
|
2519
|
+
padding: 6px 2px;
|
|
2520
|
+
min-height: 28px;
|
|
2521
|
+
}
|
|
2522
|
+
.aparte-pw-dot {
|
|
2523
|
+
display: inline-block;
|
|
2524
|
+
width: 8px;
|
|
2525
|
+
height: 8px;
|
|
2526
|
+
border-radius: 50%;
|
|
2527
|
+
background: var(--aparte-text-muted, #6b7280);
|
|
2528
|
+
opacity: 0.3;
|
|
2529
|
+
animation: pw-pulse 1.2s ease-in-out infinite;
|
|
2530
|
+
}
|
|
2531
|
+
.aparte-pw-dot:nth-child(2) { animation-delay: 0.2s; }
|
|
2532
|
+
.aparte-pw-dot:nth-child(3) { animation-delay: 0.4s; }
|
|
2533
|
+
@keyframes pw-pulse {
|
|
2534
|
+
0%, 80%, 100% { opacity: 0.3; transform: scale(0.85); }
|
|
2535
|
+
40% { opacity: 1; transform: scale(1.1); }
|
|
2536
|
+
}
|
|
2025
2537
|
|
|
2026
2538
|
/* ─────────────────────────────────────────────────────────────────────────────
|
|
2027
2539
|
Composer Primitives
|
|
@@ -2118,13 +2630,13 @@ aparte-composer-action {
|
|
|
2118
2630
|
}
|
|
2119
2631
|
|
|
2120
2632
|
/* ── Drag-over state on root ── */
|
|
2121
|
-
aparte-composer.is-dragover .aparte-composer-shell {
|
|
2633
|
+
aparte-composer.aparte-is-dragover .aparte-composer-shell {
|
|
2122
2634
|
outline: var(--aparte-focus-outline-width, 2px) dashed var(--aparte-primary);
|
|
2123
2635
|
outline-offset: -2px;
|
|
2124
2636
|
border-radius: var(--aparte-radius-input, 12px);
|
|
2125
2637
|
}
|
|
2126
2638
|
/* fallback: no shell */
|
|
2127
|
-
aparte-composer.is-dragover:not(:has(.aparte-composer-shell)) {
|
|
2639
|
+
aparte-composer.aparte-is-dragover:not(:has(.aparte-composer-shell)) {
|
|
2128
2640
|
outline: var(--aparte-focus-outline-width, 2px) dashed var(--aparte-primary);
|
|
2129
2641
|
outline-offset: -2px;
|
|
2130
2642
|
border-radius: var(--aparte-radius-input, 12px);
|
|
@@ -2186,6 +2698,23 @@ aparte-composer.is-dragover:not(:has(.aparte-composer-shell)) {
|
|
|
2186
2698
|
justify-content: center;
|
|
2187
2699
|
}
|
|
2188
2700
|
|
|
2701
|
+
/* A panel is mounted INSIDE that row, so its own buttons inherited the 44x44 sizing
|
|
2702
|
+
above and rendered as circles with their labels spilling out. The rule above means
|
|
2703
|
+
"the composer's own controls"; anything inside a panel is CONTENT, and a panel is
|
|
2704
|
+
free to contain a button — the approval options are the first that do, and they will
|
|
2705
|
+
not be the last. */
|
|
2706
|
+
[data-aparte-panel] button {
|
|
2707
|
+
width: auto;
|
|
2708
|
+
height: auto;
|
|
2709
|
+
flex-shrink: 1;
|
|
2710
|
+
/* The row also makes its controls centred flex boxes, which beats `text-align` — so a
|
|
2711
|
+
left-aligned label in a panel came out centred until this line existed. Undo the
|
|
2712
|
+
whole treatment, not the half of it that was visible. */
|
|
2713
|
+
display: block;
|
|
2714
|
+
justify-content: initial;
|
|
2715
|
+
align-items: initial;
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2189
2718
|
/* The composer's bottom row (mode picker, model selector, token counter…).
|
|
2190
2719
|
`aparte-composer-toolbar` is the element consumers write — one name for vanilla and
|
|
2191
2720
|
every wrapper. `.aparte-composer-footer` is the class the same row used to be built
|
|
@@ -2422,15 +2951,15 @@ aparte-conversation-list {
|
|
|
2422
2951
|
Provider-HTML overflow guards
|
|
2423
2952
|
========================================= */
|
|
2424
2953
|
|
|
2425
|
-
/* Markdown providers inject arbitrary HTML into .segment-text, and the bubble
|
|
2954
|
+
/* Markdown providers inject arbitrary HTML into .aparte-segment-text, and the bubble
|
|
2426
2955
|
clips overflow (`aparte-chat-bubble { overflow: hidden }`) — without these
|
|
2427
2956
|
guards a wide image or table is silently cut at the bubble edge. */
|
|
2428
|
-
.segment-text img {
|
|
2957
|
+
.aparte-segment-text img {
|
|
2429
2958
|
max-width: 100%;
|
|
2430
2959
|
height: auto;
|
|
2431
2960
|
}
|
|
2432
2961
|
|
|
2433
|
-
.segment-text table {
|
|
2962
|
+
.aparte-segment-text table {
|
|
2434
2963
|
display: block;
|
|
2435
2964
|
max-width: 100%;
|
|
2436
2965
|
overflow-x: auto;
|