@openwarelabs/ui 0.3.1 → 0.5.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.
Files changed (71) hide show
  1. package/README.md +8 -7
  2. package/dist/components/Calendar/Calendar.d.cts +58 -0
  3. package/dist/components/Calendar/Calendar.d.ts +58 -0
  4. package/dist/components/Calendar/DateRangePicker.d.cts +39 -0
  5. package/dist/components/Calendar/DateRangePicker.d.ts +39 -0
  6. package/dist/components/Calendar/RangeCalendar.d.cts +38 -0
  7. package/dist/components/Calendar/RangeCalendar.d.ts +38 -0
  8. package/dist/components/Calendar/dates.d.cts +13 -0
  9. package/dist/components/Calendar/dates.d.ts +13 -0
  10. package/dist/components/ChainOfThought/ChainOfThought.d.cts +44 -0
  11. package/dist/components/ChainOfThought/ChainOfThought.d.ts +44 -0
  12. package/dist/components/Chat/ChatConversation.d.cts +48 -0
  13. package/dist/components/Chat/ChatConversation.d.ts +48 -0
  14. package/dist/components/Chat/ChatLoader.d.cts +21 -0
  15. package/dist/components/Chat/ChatLoader.d.ts +21 -0
  16. package/dist/components/Chat/ChatMessage.d.cts +93 -0
  17. package/dist/components/Chat/ChatMessage.d.ts +93 -0
  18. package/dist/components/ChatSource/ChatSource.d.cts +58 -0
  19. package/dist/components/ChatSource/ChatSource.d.ts +58 -0
  20. package/dist/components/ChatTool/ChatTool.d.cts +89 -0
  21. package/dist/components/ChatTool/ChatTool.d.ts +89 -0
  22. package/dist/components/ColorPicker/ColorArea.d.cts +44 -0
  23. package/dist/components/ColorPicker/ColorArea.d.ts +44 -0
  24. package/dist/components/ColorPicker/ColorSlider.d.cts +53 -0
  25. package/dist/components/ColorPicker/ColorSlider.d.ts +53 -0
  26. package/dist/components/ColorPicker/ColorSwatchPicker.d.cts +43 -0
  27. package/dist/components/ColorPicker/ColorSwatchPicker.d.ts +43 -0
  28. package/dist/components/ColorPicker/color.d.cts +91 -0
  29. package/dist/components/ColorPicker/color.d.ts +91 -0
  30. package/dist/components/DateField/DateField.d.cts +47 -0
  31. package/dist/components/DateField/DateField.d.ts +47 -0
  32. package/dist/components/DateField/SegmentedField.d.cts +63 -0
  33. package/dist/components/DateField/SegmentedField.d.ts +63 -0
  34. package/dist/components/DateField/TimeField.d.cts +52 -0
  35. package/dist/components/DateField/TimeField.d.ts +52 -0
  36. package/dist/components/Field/Field.d.cts +17 -5
  37. package/dist/components/Field/Field.d.ts +17 -5
  38. package/dist/components/FileDropZone/FileDropZone.d.cts +1 -1
  39. package/dist/components/FileDropZone/FileDropZone.d.ts +1 -1
  40. package/dist/components/Form/Form.d.cts +63 -0
  41. package/dist/components/Form/Form.d.ts +63 -0
  42. package/dist/components/InputOTP/InputOTP.d.cts +7 -1
  43. package/dist/components/InputOTP/InputOTP.d.ts +7 -1
  44. package/dist/components/ListBox/ListBox.d.cts +65 -0
  45. package/dist/components/ListBox/ListBox.d.ts +65 -0
  46. package/dist/components/Meter/Meter.d.cts +62 -0
  47. package/dist/components/Meter/Meter.d.ts +62 -0
  48. package/dist/components/PromptInput/PromptInput.d.cts +95 -0
  49. package/dist/components/PromptInput/PromptInput.d.ts +95 -0
  50. package/dist/components/PromptInput/PromptSuggestion.d.cts +36 -0
  51. package/dist/components/PromptInput/PromptSuggestion.d.ts +36 -0
  52. package/dist/components/Prose/Prose.d.cts +22 -0
  53. package/dist/components/Prose/Prose.d.ts +22 -0
  54. package/dist/components/Slider/Slider.d.cts +7 -1
  55. package/dist/components/Slider/Slider.d.ts +7 -1
  56. package/dist/components/TextShimmer/TextShimmer.d.cts +20 -0
  57. package/dist/components/TextShimmer/TextShimmer.d.ts +20 -0
  58. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.cts +74 -0
  59. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.ts +74 -0
  60. package/dist/components/Toolbar/Toolbar.d.cts +36 -0
  61. package/dist/components/Toolbar/Toolbar.d.ts +36 -0
  62. package/dist/components.css +3557 -38
  63. package/dist/index.cjs +7391 -3179
  64. package/dist/index.cjs.map +4 -4
  65. package/dist/index.d.cts +45 -0
  66. package/dist/index.d.ts +45 -0
  67. package/dist/index.js +7478 -3214
  68. package/dist/index.js.map +4 -4
  69. package/dist/openware-ui.iife.js +7 -6
  70. package/dist/styles.css +3557 -38
  71. package/package.json +1 -1
package/dist/styles.css CHANGED
@@ -744,9 +744,8 @@
744
744
  padding: 0;
745
745
  }
746
746
  .ow-button--icon-only.ow-button--sm {
747
- width: 28px;
748
- height: 28px;
749
- min-height: 28px;
747
+ width: 32px;
748
+ height: 32px;
750
749
  }
751
750
  .ow-button--icon-only.ow-button--md {
752
751
  width: 40px;
@@ -954,29 +953,38 @@
954
953
  flex-wrap: nowrap;
955
954
  gap: 0;
956
955
  }
957
- .ow-button-group--attached > .ow-button {
956
+ /* A button joins its neighbours whether it's a direct child or wrapped one level down, by a Tooltip or a Menu's trigger. */
957
+ .ow-button-group--attached > .ow-button,
958
+ .ow-button-group--attached > * > .ow-button {
958
959
  position: relative;
959
960
  }
960
961
  .ow-button-group--attached > .ow-button:hover,
961
962
  .ow-button-group--attached > .ow-button:focus-visible,
962
- .ow-button-group--attached > .ow-button--pressed {
963
+ .ow-button-group--attached > .ow-button--pressed,
964
+ .ow-button-group--attached > * > .ow-button:hover,
965
+ .ow-button-group--attached > * > .ow-button:focus-visible,
966
+ .ow-button-group--attached > * > .ow-button--pressed {
963
967
  z-index: 1;
964
968
  }
965
- .ow-button-group--attached:not(.ow-button-group--vertical) > .ow-button:not(:first-child) {
969
+ .ow-button-group--attached:not(.ow-button-group--vertical) > .ow-button:not(:first-child),
970
+ .ow-button-group--attached:not(.ow-button-group--vertical) > :not(:first-child) > .ow-button {
966
971
  margin-left: -1px;
967
972
  border-top-left-radius: 0;
968
973
  border-bottom-left-radius: 0;
969
974
  }
970
- .ow-button-group--attached:not(.ow-button-group--vertical) > .ow-button:not(:last-child) {
975
+ .ow-button-group--attached:not(.ow-button-group--vertical) > .ow-button:not(:last-child),
976
+ .ow-button-group--attached:not(.ow-button-group--vertical) > :not(:last-child) > .ow-button {
971
977
  border-top-right-radius: 0;
972
978
  border-bottom-right-radius: 0;
973
979
  }
974
- .ow-button-group--attached.ow-button-group--vertical > .ow-button:not(:first-child) {
980
+ .ow-button-group--attached.ow-button-group--vertical > .ow-button:not(:first-child),
981
+ .ow-button-group--attached.ow-button-group--vertical > :not(:first-child) > .ow-button {
975
982
  margin-top: -1px;
976
983
  border-top-left-radius: 0;
977
984
  border-top-right-radius: 0;
978
985
  }
979
- .ow-button-group--attached.ow-button-group--vertical > .ow-button:not(:last-child) {
986
+ .ow-button-group--attached.ow-button-group--vertical > .ow-button:not(:last-child),
987
+ .ow-button-group--attached.ow-button-group--vertical > :not(:last-child) > .ow-button {
980
988
  border-bottom-left-radius: 0;
981
989
  border-bottom-right-radius: 0;
982
990
  }
@@ -1020,6 +1028,139 @@
1020
1028
  opacity: 0.5;
1021
1029
  }
1022
1030
 
1031
+ /* components/ToggleButtonGroup/ToggleButtonGroup.css */
1032
+ /* ToggleButtonGroup: toggles joined like an attached ButtonGroup, sharing borders, each pressed in while it's on.
1033
+ An item is the button itself, or the Tooltip around an icon-only one. */
1034
+ .ow-toggle-group {
1035
+ display: inline-flex;
1036
+ flex-wrap: nowrap;
1037
+ align-items: stretch;
1038
+ vertical-align: middle;
1039
+ }
1040
+
1041
+ .ow-toggle-group--vertical {
1042
+ flex-direction: column;
1043
+ }
1044
+
1045
+ .ow-toggle-group > * {
1046
+ position: relative;
1047
+ }
1048
+
1049
+ .ow-toggle-group > .ow-tooltip > .ow-button {
1050
+ flex: 1;
1051
+ }
1052
+
1053
+ /* Hovered and pressed buttons sit above their neighbours so their whole border shows; a focused one above all,
1054
+ so nothing covers its ring. */
1055
+ .ow-toggle-group > :hover,
1056
+ .ow-toggle-group > .ow-button--pressed,
1057
+ .ow-toggle-group > :has(> .ow-button--pressed) {
1058
+ z-index: 1;
1059
+ }
1060
+
1061
+ .ow-toggle-group > :focus-visible,
1062
+ .ow-toggle-group > :has(> :focus-visible) {
1063
+ z-index: 2;
1064
+ }
1065
+
1066
+ /* Shared borders: each item overlaps the one before by a border's width, and only the ends keep their corners. */
1067
+ .ow-toggle-group:not(.ow-toggle-group--vertical) > :not(:first-child) {
1068
+ margin-inline-start: -1px;
1069
+ }
1070
+
1071
+ .ow-toggle-group:not(.ow-toggle-group--vertical) > .ow-button:not(:first-child),
1072
+ .ow-toggle-group:not(.ow-toggle-group--vertical) > :not(:first-child) > .ow-button {
1073
+ border-start-start-radius: 0;
1074
+ border-end-start-radius: 0;
1075
+ }
1076
+
1077
+ .ow-toggle-group:not(.ow-toggle-group--vertical) > .ow-button:not(:last-child),
1078
+ .ow-toggle-group:not(.ow-toggle-group--vertical) > :not(:last-child) > .ow-button {
1079
+ border-start-end-radius: 0;
1080
+ border-end-end-radius: 0;
1081
+ }
1082
+
1083
+ .ow-toggle-group--vertical > :not(:first-child) {
1084
+ margin-block-start: -1px;
1085
+ }
1086
+
1087
+ .ow-toggle-group--vertical > .ow-button:not(:first-child),
1088
+ .ow-toggle-group--vertical > :not(:first-child) > .ow-button {
1089
+ border-start-start-radius: 0;
1090
+ border-start-end-radius: 0;
1091
+ }
1092
+
1093
+ .ow-toggle-group--vertical > .ow-button:not(:last-child),
1094
+ .ow-toggle-group--vertical > :not(:last-child) > .ow-button {
1095
+ border-end-start-radius: 0;
1096
+ border-end-end-radius: 0;
1097
+ }
1098
+
1099
+ /* An icon-only option among labelled ones matches their height. */
1100
+ .ow-toggle-group--sm:not(.ow-toggle-group--icon-only) .ow-button--icon-only {
1101
+ width: 32px;
1102
+ height: 32px;
1103
+ min-height: 32px;
1104
+ }
1105
+
1106
+ /* components/Toolbar/Toolbar.css */
1107
+ /* Toolbar: a row (or column) of controls for one context, raised on its own surface or plain. */
1108
+ .ow-toolbar {
1109
+ display: flex;
1110
+ flex-wrap: wrap;
1111
+ align-items: center;
1112
+ gap: var(--ow-space-xs);
1113
+ min-width: 0;
1114
+ }
1115
+
1116
+ .ow-toolbar--sm {
1117
+ gap: var(--ow-space-2xs);
1118
+ }
1119
+
1120
+ .ow-toolbar--raised {
1121
+ border: 1px solid var(--ow-border);
1122
+ border-radius: var(--ow-radius-container);
1123
+ background: var(--ow-surface);
1124
+ padding: var(--ow-space-xs);
1125
+ box-shadow: var(--ow-shadow-control);
1126
+ }
1127
+
1128
+ /* 4px inside a 12px corner keeps the buttons' 8px corners concentric with the bar's. */
1129
+ .ow-toolbar--raised.ow-toolbar--sm {
1130
+ padding: var(--ow-space-2xs);
1131
+ }
1132
+
1133
+ .ow-toolbar--vertical {
1134
+ display: inline-flex;
1135
+ flex-direction: column;
1136
+ flex-wrap: nowrap;
1137
+ align-items: stretch;
1138
+ }
1139
+
1140
+ /* The separator stops short of the bar's edges, so it divides groups without boxing them in. */
1141
+ .ow-toolbar__separator {
1142
+ flex-shrink: 0;
1143
+ align-self: center;
1144
+ width: 1px;
1145
+ height: 20px;
1146
+ margin: 0 var(--ow-space-2xs);
1147
+ background: var(--ow-border);
1148
+ }
1149
+
1150
+ .ow-toolbar--sm .ow-toolbar__separator {
1151
+ height: 16px;
1152
+ }
1153
+
1154
+ .ow-toolbar--vertical .ow-toolbar__separator {
1155
+ width: 20px;
1156
+ height: 1px;
1157
+ margin: var(--ow-space-2xs) 0;
1158
+ }
1159
+
1160
+ .ow-toolbar--vertical.ow-toolbar--sm .ow-toolbar__separator {
1161
+ width: 16px;
1162
+ }
1163
+
1023
1164
  /* components/SegmentedControl/SegmentedControl.css */
1024
1165
  /* SegmentedControl and segmented Tabs: a well with the chosen segment raised. */
1025
1166
  .ow-segmented,
@@ -1425,6 +1566,153 @@
1425
1566
  white-space: nowrap;
1426
1567
  }
1427
1568
 
1569
+ /* components/DateField/DateField.css */
1570
+ /* DateField and TimeField: typed segments in a field drawn like Input. The whole field shows focus while a segment
1571
+ has it; the focused segment is tinted. */
1572
+ .ow-date-field {
1573
+ display: flex;
1574
+ width: 100%;
1575
+ /* Shrink in a narrow grid or flex column instead of pushing past it. */
1576
+ min-width: 0;
1577
+ height: 40px;
1578
+ align-items: center;
1579
+ gap: var(--ow-space-xs);
1580
+ border: 1px solid var(--ow-border-strong);
1581
+ border-radius: var(--ow-radius-form);
1582
+ background: var(--ow-surface);
1583
+ /* With the segments' own 2px, the digits start where Input's text does. */
1584
+ padding: 0 var(--ow-space-md);
1585
+ color: var(--ow-text);
1586
+ font-size: 14px;
1587
+ font-weight: var(--ow-weight-regular);
1588
+ line-height: 1.45;
1589
+ font-variant-numeric: tabular-nums;
1590
+ cursor: text;
1591
+ transition-property: border-color, background-color, box-shadow, opacity;
1592
+ transition-duration: var(--ow-duration-base);
1593
+ transition-timing-function: var(--ow-ease-standard);
1594
+ }
1595
+
1596
+ .ow-date-field--sm {
1597
+ height: 32px;
1598
+ gap: var(--ow-space-2xs);
1599
+ padding: 0 var(--ow-space-sm);
1600
+ font-size: 13px;
1601
+ }
1602
+
1603
+ .ow-date-field--with-start {
1604
+ padding-left: var(--ow-space-lg);
1605
+ }
1606
+
1607
+ .ow-date-field--sm.ow-date-field--with-start {
1608
+ padding-left: var(--ow-space-md);
1609
+ }
1610
+
1611
+ .ow-date-field:focus-within {
1612
+ border-color: var(--ow-focus-border);
1613
+ box-shadow: var(--ow-shadow-focus);
1614
+ }
1615
+
1616
+ .ow-date-field:has(.ow-date-field__segment:focus-visible) {
1617
+ outline: 2px solid var(--ow-focus-ring);
1618
+ outline-offset: 2px;
1619
+ }
1620
+
1621
+ .ow-date-field--invalid {
1622
+ border-color: var(--ow-danger-line);
1623
+ }
1624
+
1625
+ .ow-date-field--invalid:focus-within {
1626
+ border-color: var(--ow-danger-solid);
1627
+ box-shadow: var(--ow-shadow-focus-danger);
1628
+ }
1629
+
1630
+ .ow-date-field--readonly {
1631
+ cursor: default;
1632
+ }
1633
+
1634
+ .ow-date-field--disabled {
1635
+ cursor: not-allowed;
1636
+ opacity: 0.62;
1637
+ }
1638
+
1639
+ .ow-date-field__addon {
1640
+ display: inline-flex;
1641
+ flex-shrink: 0;
1642
+ align-items: center;
1643
+ color: var(--ow-text-muted);
1644
+ cursor: default;
1645
+ }
1646
+
1647
+ .ow-date-field__segments {
1648
+ display: flex;
1649
+ min-width: 0;
1650
+ align-items: center;
1651
+ white-space: pre;
1652
+ }
1653
+
1654
+ .ow-date-field__segment {
1655
+ flex-shrink: 0;
1656
+ border-radius: var(--ow-radius-sm);
1657
+ padding: 2px;
1658
+ color: var(--ow-text);
1659
+ text-align: center;
1660
+ caret-color: transparent;
1661
+ outline: 0;
1662
+ transition-property: color, background-color, box-shadow;
1663
+ transition-duration: var(--ow-duration-fast);
1664
+ transition-timing-function: var(--ow-ease-standard);
1665
+ }
1666
+
1667
+ .ow-date-field__segment::selection {
1668
+ background: transparent;
1669
+ }
1670
+
1671
+ /* Tabular digits are 1ch wide, so a segment keeps its width while a value is half typed ("1" on the way to "12").
1672
+ Placeholders keep their own width, so the letters sit evenly. */
1673
+ .ow-date-field__segment--digits-2:not(.ow-date-field__segment--placeholder) {
1674
+ min-width: calc(2ch + 4px);
1675
+ }
1676
+
1677
+ .ow-date-field__segment--digits-4:not(.ow-date-field__segment--placeholder) {
1678
+ min-width: calc(4ch + 4px);
1679
+ }
1680
+
1681
+ .ow-date-field__segment--placeholder {
1682
+ color: var(--ow-text-muted);
1683
+ }
1684
+
1685
+ /* The tint and edge of selected things, as on Pagination's current page. */
1686
+ .ow-date-field__segment:focus {
1687
+ background: var(--ow-primary-subtle);
1688
+ box-shadow: inset 0 0 0 1px var(--ow-primary-border);
1689
+ color: var(--ow-primary-text);
1690
+ }
1691
+
1692
+ .ow-date-field__segment--placeholder:focus {
1693
+ color: var(--ow-text-muted);
1694
+ }
1695
+
1696
+ .ow-date-field--disabled .ow-date-field__segment {
1697
+ cursor: not-allowed;
1698
+ }
1699
+
1700
+ .ow-date-field--readonly .ow-date-field__segment {
1701
+ cursor: default;
1702
+ }
1703
+
1704
+ .ow-date-field__literal {
1705
+ color: var(--ow-text-muted);
1706
+ user-select: none;
1707
+ }
1708
+
1709
+ @media (prefers-reduced-motion: reduce) {
1710
+ .ow-date-field,
1711
+ .ow-date-field__segment {
1712
+ transition: none;
1713
+ }
1714
+ }
1715
+
1428
1716
  /* components/Textarea/Textarea.css */
1429
1717
  /* Textarea: the field look from Input.css, taller and resizable. */
1430
1718
  .ow-textarea {
@@ -1638,6 +1926,87 @@
1638
1926
  font-weight: var(--ow-weight-control);
1639
1927
  }
1640
1928
 
1929
+ /* components/ListBox/ListBox.css */
1930
+ /* ListBox: Select's list on the page. It wears Select.css's .ow-listbox and .ow-option (rows, checkmarks, group
1931
+ labels, sizes), so the two stay in step; this file only undoes the floating and adds the field states. */
1932
+ .ow-listbox.ow-listbox--standalone {
1933
+ position: relative;
1934
+ z-index: auto;
1935
+ min-width: 0;
1936
+ box-shadow: none;
1937
+ overscroll-behavior: auto;
1938
+ outline: 0;
1939
+ transition-property: border-color, box-shadow, opacity;
1940
+ transition-duration: var(--ow-duration-base);
1941
+ transition-timing-function: var(--ow-ease-standard);
1942
+ }
1943
+
1944
+ .ow-listbox--standalone .ow-option {
1945
+ user-select: none;
1946
+ transition: background-color var(--ow-duration-fast) var(--ow-ease-standard);
1947
+ }
1948
+
1949
+ /* In a floating list the pointer moves the highlight; here hover is its own state, apart from the keyboard's. */
1950
+ .ow-listbox--standalone:not(.ow-listbox--disabled, .ow-listbox--readonly) .ow-option:not(.ow-option--disabled):hover {
1951
+ background: var(--ow-hover);
1952
+ }
1953
+
1954
+ .ow-listbox--readonly .ow-option {
1955
+ cursor: default;
1956
+ }
1957
+
1958
+ .ow-listbox--standalone.ow-listbox--focus-visible {
1959
+ border-color: var(--ow-focus-border);
1960
+ box-shadow: var(--ow-shadow-focus);
1961
+ }
1962
+
1963
+ .ow-listbox--standalone.ow-listbox--invalid {
1964
+ border-color: var(--ow-danger-line);
1965
+ }
1966
+
1967
+ .ow-listbox--standalone.ow-listbox--invalid.ow-listbox--focus-visible {
1968
+ border-color: var(--ow-danger-solid);
1969
+ box-shadow: var(--ow-shadow-focus-danger);
1970
+ }
1971
+
1972
+ .ow-listbox--standalone.ow-listbox--disabled {
1973
+ cursor: not-allowed;
1974
+ opacity: 0.62;
1975
+ }
1976
+
1977
+ .ow-listbox--disabled .ow-option {
1978
+ cursor: not-allowed;
1979
+ }
1980
+
1981
+ /* An empty list is one option row tall. */
1982
+ .ow-listbox--standalone .ow-listbox__empty {
1983
+ padding: var(--ow-space-md);
1984
+ font-size: 14px;
1985
+ line-height: 16px;
1986
+ }
1987
+
1988
+ .ow-listbox--standalone.ow-listbox--sm .ow-listbox__empty {
1989
+ padding-block: var(--ow-space-sm);
1990
+ font-size: 12px;
1991
+ }
1992
+
1993
+ .ow-option__icon {
1994
+ display: flex;
1995
+ width: 16px;
1996
+ height: 16px;
1997
+ flex-shrink: 0;
1998
+ align-items: center;
1999
+ justify-content: center;
2000
+ color: var(--ow-text-muted);
2001
+ }
2002
+
2003
+ @media (prefers-reduced-motion: reduce) {
2004
+ .ow-listbox.ow-listbox--standalone,
2005
+ .ow-listbox--standalone .ow-option {
2006
+ transition: none;
2007
+ }
2008
+ }
2009
+
1641
2010
  /* components/Combobox/Combobox.css */
1642
2011
  /* Combobox: a grouped field (Input.css) with a chevron, over Select's listbox. */
1643
2012
  .ow-combobox {
@@ -2444,9 +2813,32 @@
2444
2813
  line-height: 1.4;
2445
2814
  }
2446
2815
 
2447
- /* components/Badge/Badge.css */
2448
- /* Badge (the app's Pill): status in a bordered pill. */
2449
- .ow-badge {
2816
+ /* A checkbox in a Field with an error (the terms, say) takes the invalid field's border until it's ticked. */
2817
+ .ow-field .ow-checkbox__input[aria-invalid="true"]:not(:checked, :disabled) {
2818
+ border-color: var(--ow-danger-line);
2819
+ }
2820
+
2821
+ /* components/Form/Form.css */
2822
+ /* Form: its rows sit ow-space-xl apart, as the README asks. */
2823
+ .ow-form {
2824
+ display: grid;
2825
+ grid-template-columns: minmax(0, 1fr);
2826
+ align-content: start;
2827
+ gap: var(--ow-space-xl);
2828
+ }
2829
+
2830
+ /* A button on a row of its own keeps its width, unless it's fullWidth. */
2831
+ .ow-form > .ow-button {
2832
+ justify-self: start;
2833
+ }
2834
+
2835
+ .ow-form > .ow-button--full {
2836
+ justify-self: stretch;
2837
+ }
2838
+
2839
+ /* components/Badge/Badge.css */
2840
+ /* Badge (the app's Pill): status in a bordered pill. */
2841
+ .ow-badge {
2450
2842
  display: inline-flex;
2451
2843
  width: fit-content;
2452
2844
  align-items: center;
@@ -2734,6 +3126,96 @@
2734
3126
  }
2735
3127
  }
2736
3128
 
3129
+ /* components/Meter/Meter.css */
3130
+ /* Meter: ProgressBar's header and track (Progress.css), for an amount within a range. Tones swap in a status colour. */
3131
+ .ow-meter {
3132
+ display: grid;
3133
+ min-width: 0;
3134
+ gap: var(--ow-space-sm);
3135
+ }
3136
+
3137
+ .ow-meter--primary {
3138
+ --ow-meter-fill: var(--ow-progress);
3139
+ }
3140
+
3141
+ /* Status fills use the status text colours, which keep 3:1 against the track in both themes. */
3142
+ .ow-meter--success {
3143
+ --ow-meter-fill: var(--ow-success-text);
3144
+ }
3145
+
3146
+ .ow-meter--warning {
3147
+ --ow-meter-fill: var(--ow-warning-text);
3148
+ }
3149
+
3150
+ .ow-meter--danger {
3151
+ --ow-meter-fill: var(--ow-danger-text);
3152
+ }
3153
+
3154
+ .ow-meter__header {
3155
+ display: flex;
3156
+ align-items: baseline;
3157
+ justify-content: space-between;
3158
+ gap: var(--ow-space-md);
3159
+ }
3160
+
3161
+ .ow-meter__label {
3162
+ min-width: 0;
3163
+ color: var(--ow-text);
3164
+ font-size: 14px;
3165
+ font-weight: var(--ow-weight-emphasis);
3166
+ }
3167
+
3168
+ .ow-meter__value {
3169
+ flex-shrink: 0;
3170
+ color: var(--ow-text-muted);
3171
+ font-size: 13px;
3172
+ font-variant-numeric: tabular-nums;
3173
+ }
3174
+
3175
+ .ow-meter__track {
3176
+ display: flex;
3177
+ height: 4px;
3178
+ overflow: hidden;
3179
+ border-radius: var(--ow-radius-pill);
3180
+ background: var(--ow-meter-track);
3181
+ }
3182
+
3183
+ .ow-meter--md .ow-meter__track {
3184
+ height: 8px;
3185
+ }
3186
+
3187
+ .ow-meter__fill {
3188
+ display: block;
3189
+ height: 100%;
3190
+ border-radius: inherit;
3191
+ background: var(--ow-meter-fill);
3192
+ transition:
3193
+ width var(--ow-duration-slow) var(--ow-ease-standard),
3194
+ background-color var(--ow-duration-base) var(--ow-ease-standard);
3195
+ }
3196
+
3197
+ /* Segments: the track splits into blocks, each with its own track and a share of the fill. */
3198
+ .ow-meter__track--segmented {
3199
+ gap: var(--ow-space-2xs);
3200
+ overflow: visible;
3201
+ border-radius: 0;
3202
+ background: none;
3203
+ }
3204
+
3205
+ .ow-meter__segment {
3206
+ min-width: 0;
3207
+ flex: 1;
3208
+ overflow: hidden;
3209
+ border-radius: var(--ow-radius-pill);
3210
+ background: var(--ow-meter-track);
3211
+ }
3212
+
3213
+ @media (prefers-reduced-motion: reduce) {
3214
+ .ow-meter__fill {
3215
+ transition: none;
3216
+ }
3217
+ }
3218
+
2737
3219
  /* components/Tooltip/Tooltip.css */
2738
3220
  /* Tooltip: a small dark label in the top layer, on the side of the child it prefers (or the other side when there's no room). */
2739
3221
  .ow-tooltip {
@@ -3338,6 +3820,13 @@
3338
3820
  cursor: not-allowed;
3339
3821
  }
3340
3822
 
3823
+ /* Holds a missing button's place, so a month's name stays centred (RangeCalendar's months side by side). */
3824
+ .ow-calendar__nav-space {
3825
+ width: 32px;
3826
+ height: 32px;
3827
+ flex-shrink: 0;
3828
+ }
3829
+
3341
3830
  .ow-calendar__grid {
3342
3831
  border-collapse: separate;
3343
3832
  border-spacing: 2px;
@@ -3471,6 +3960,200 @@
3471
3960
  padding: var(--ow-space-md);
3472
3961
  }
3473
3962
 
3963
+ /* components/Calendar/RangeCalendar.css */
3964
+ /* RangeCalendar: Calendar's month grid, with the range's ends as solid caps and a primary-subtle band between them. */
3965
+ .ow-range-calendar {
3966
+ display: inline-flex;
3967
+ max-width: 100%;
3968
+ flex-wrap: wrap;
3969
+ align-items: flex-start;
3970
+ gap: var(--ow-space-2xl) var(--ow-space-4xl);
3971
+ color: var(--ow-text);
3972
+ font-family: var(--ow-font-sans);
3973
+ }
3974
+
3975
+ .ow-range-calendar .ow-calendar__cell {
3976
+ position: relative;
3977
+ }
3978
+
3979
+ /* The band sits behind the day buttons and reaches 1px into the 2px gaps either side, so the days join up. */
3980
+ .ow-range-calendar__cell--in-range::before {
3981
+ content: "";
3982
+ position: absolute;
3983
+ top: 0;
3984
+ right: -1px;
3985
+ bottom: 0;
3986
+ left: -1px;
3987
+ background: var(--ow-primary-subtle);
3988
+ }
3989
+
3990
+ /* It rounds off at the ends of each week, and side by side at the ends of each month. */
3991
+ .ow-range-calendar__cell--row-start::before {
3992
+ left: 0;
3993
+ border-top-left-radius: var(--ow-radius-form);
3994
+ border-bottom-left-radius: var(--ow-radius-form);
3995
+ }
3996
+
3997
+ .ow-range-calendar__cell--row-end::before {
3998
+ right: 0;
3999
+ border-top-right-radius: var(--ow-radius-form);
4000
+ border-bottom-right-radius: var(--ow-radius-form);
4001
+ }
4002
+
4003
+ /* At the caps it starts and stops halfway, so it fills in behind their inner corners. */
4004
+ .ow-range-calendar__cell--start::before {
4005
+ left: 50%;
4006
+ }
4007
+
4008
+ .ow-range-calendar__cell--end::before {
4009
+ right: 50%;
4010
+ }
4011
+
4012
+ .ow-range-calendar__day--in-range:not(.ow-calendar__day--disabled):hover {
4013
+ border-color: var(--ow-primary-border);
4014
+ background: var(--ow-primary-soft);
4015
+ }
4016
+
4017
+ /* components/Calendar/DateRangePicker.css */
4018
+ /* DateRangePicker: Select's trigger with a calendar icon and a clear button, opening a RangeCalendar and presets. */
4019
+ .ow-date-range-picker {
4020
+ position: relative;
4021
+ display: inline-flex;
4022
+ min-width: 0;
4023
+ vertical-align: middle;
4024
+ }
4025
+
4026
+ .ow-date-range-picker--md {
4027
+ min-width: 240px;
4028
+ }
4029
+
4030
+ .ow-date-range-picker--sm {
4031
+ min-width: 210px;
4032
+ }
4033
+
4034
+ .ow-date-range-picker__trigger {
4035
+ width: 100%;
4036
+ }
4037
+
4038
+ .ow-date-range-picker__icon {
4039
+ flex-shrink: 0;
4040
+ color: var(--ow-text-muted);
4041
+ }
4042
+
4043
+ /* The clear button sits over the trigger's right end (a button can't hold another), which leaves it room. */
4044
+ .ow-date-range-picker--clearable.ow-date-range-picker--md .ow-date-range-picker__trigger {
4045
+ padding-right: 38px;
4046
+ }
4047
+
4048
+ .ow-date-range-picker--clearable.ow-date-range-picker--sm .ow-date-range-picker__trigger {
4049
+ padding-right: 30px;
4050
+ }
4051
+
4052
+ .ow-date-range-picker__clear {
4053
+ position: absolute;
4054
+ top: 50%;
4055
+ right: var(--ow-space-sm);
4056
+ transform: translateY(-50%);
4057
+ }
4058
+
4059
+ .ow-date-range-picker--sm .ow-date-range-picker__clear {
4060
+ right: var(--ow-space-2xs);
4061
+ }
4062
+
4063
+ /* Hovering the clear button still shows the field's hover edge. */
4064
+ .ow-date-range-picker:hover .ow-date-range-picker__trigger:not(:disabled):not(.ow-select--open):not(.ow-select--invalid):not(:focus-visible) {
4065
+ border-color: var(--ow-border-hover);
4066
+ }
4067
+
4068
+ .ow-date-range-picker__panel {
4069
+ display: flex;
4070
+ width: auto;
4071
+ max-width: calc(100vw - 16px);
4072
+ align-items: flex-start;
4073
+ gap: var(--ow-space-lg);
4074
+ padding: var(--ow-space-md);
4075
+ }
4076
+
4077
+ .ow-date-range-picker__presets {
4078
+ display: grid;
4079
+ width: 148px;
4080
+ flex-shrink: 0;
4081
+ align-self: stretch;
4082
+ align-content: start;
4083
+ gap: var(--ow-space-2xs);
4084
+ border-right: 1px solid var(--ow-border);
4085
+ padding-right: var(--ow-space-md);
4086
+ }
4087
+
4088
+ .ow-date-range-picker__preset {
4089
+ display: flex;
4090
+ min-height: 32px;
4091
+ align-items: center;
4092
+ gap: var(--ow-space-sm);
4093
+ margin: 0;
4094
+ border: 0;
4095
+ border-radius: var(--ow-radius-lg);
4096
+ background: transparent;
4097
+ padding: var(--ow-space-xs) var(--ow-space-sm);
4098
+ color: var(--ow-text);
4099
+ font: inherit;
4100
+ font-size: 14px;
4101
+ font-weight: var(--ow-weight-control);
4102
+ line-height: 1.1;
4103
+ text-align: left;
4104
+ cursor: pointer;
4105
+ transition-property: color, background-color;
4106
+ transition-duration: var(--ow-duration-base);
4107
+ transition-timing-function: var(--ow-ease-standard);
4108
+ }
4109
+
4110
+ .ow-date-range-picker__preset:hover {
4111
+ background: var(--ow-hover);
4112
+ }
4113
+
4114
+ .ow-date-range-picker__preset:focus-visible {
4115
+ outline: 2px solid var(--ow-focus-ring);
4116
+ outline-offset: -2px;
4117
+ }
4118
+
4119
+ .ow-date-range-picker__preset--current,
4120
+ .ow-date-range-picker__preset--current:hover {
4121
+ background: var(--ow-primary-subtle);
4122
+ color: var(--ow-primary-text);
4123
+ font-weight: var(--ow-weight-emphasis);
4124
+ }
4125
+
4126
+ .ow-date-range-picker__preset-label {
4127
+ min-width: 0;
4128
+ flex: 1;
4129
+ }
4130
+
4131
+ .ow-date-range-picker__preset-check {
4132
+ flex-shrink: 0;
4133
+ }
4134
+
4135
+ /* On a phone the presets wrap in rows above the month, no wider than it. */
4136
+ @media (max-width: 479px) {
4137
+ .ow-date-range-picker__panel {
4138
+ width: min-content;
4139
+ flex-direction: column;
4140
+ align-items: stretch;
4141
+ }
4142
+
4143
+ .ow-date-range-picker__presets {
4144
+ display: flex;
4145
+ width: auto;
4146
+ flex-wrap: wrap;
4147
+ border-right: 0;
4148
+ border-bottom: 1px solid var(--ow-border);
4149
+ padding: 0 0 var(--ow-space-md);
4150
+ }
4151
+
4152
+ .ow-date-range-picker__preset {
4153
+ border: 1px solid var(--ow-border);
4154
+ }
4155
+ }
4156
+
3474
4157
  /* components/ColorPicker/ColorPicker.css */
3475
4158
  /* ColorPicker: react-colorful's saturation area and hue slider in Openware's look, with a hex field,
3476
4159
  an eyedropper and swatches. react-colorful injects its own styles after this sheet, so these
@@ -3669,38 +4352,350 @@
3669
4352
  padding: var(--ow-space-lg);
3670
4353
  }
3671
4354
 
3672
- /* components/CommandPalette/CommandPalette.css */
3673
- /* CommandPalette: a dialog 12vh from the top, 560px wide, with a search row and a results list. */
3674
- .ow-palette {
3675
- top: 12vh;
3676
- bottom: auto;
3677
- width: min(560px, calc(100% - 32px));
3678
- margin: 0 auto;
3679
- overflow: hidden;
3680
- padding: 0;
4355
+ /* components/ColorPicker/ColorArea.css */
4356
+ /* ColorArea: one hue's square, white to the hue across and down to black, in ColorPicker's look (its corners,
4357
+ hairline and thumb), so the two can sit side by side. */
4358
+ .ow-color-area {
4359
+ --ow-color-area-direction: to right;
4360
+ position: relative;
4361
+ width: var(--ow-color-area-width, 232px);
4362
+ max-width: 100%;
4363
+ height: var(--ow-color-area-height, 152px);
4364
+ flex-shrink: 0;
4365
+ border-radius: var(--ow-radius-form);
4366
+ background: linear-gradient(to top, #000000, transparent), linear-gradient(var(--ow-color-area-direction), #ffffff, var(--ow-color-area-hue));
4367
+ box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.1);
4368
+ cursor: pointer;
4369
+ touch-action: none;
4370
+ user-select: none;
4371
+ -webkit-tap-highlight-color: transparent;
3681
4372
  }
3682
4373
 
3683
- .ow-palette__search {
3684
- display: flex;
3685
- align-items: center;
3686
- gap: var(--ow-space-sm);
3687
- border-bottom: 1px solid var(--ow-border);
3688
- padding: var(--ow-space-md) var(--ow-space-lg);
4374
+ .ow-color-area:dir(rtl) {
4375
+ --ow-color-area-direction: to left;
3689
4376
  }
3690
4377
 
3691
- .ow-palette__search-icon {
3692
- flex-shrink: 0;
3693
- color: var(--ow-text-muted);
4378
+ .ow-color-area__thumb {
4379
+ position: absolute;
4380
+ top: var(--ow-color-area-y);
4381
+ inset-inline-start: var(--ow-color-area-x);
4382
+ width: 18px;
4383
+ height: 18px;
4384
+ border: 2px solid #ffffff;
4385
+ border-radius: 50%;
4386
+ background: var(--ow-color-area-color);
4387
+ box-shadow:
4388
+ 0 0 0 1px rgba(15, 23, 42, 0.18),
4389
+ 0 2px 6px rgba(15, 23, 42, 0.28);
4390
+ pointer-events: none;
4391
+ translate: -50% -50%;
4392
+ transition: scale var(--ow-duration-fast) var(--ow-ease-standard);
3694
4393
  }
3695
4394
 
3696
- .ow-palette__input {
3697
- min-width: 0;
3698
- flex: 1;
3699
- margin: 0;
3700
- border: 0;
3701
- background: transparent;
3702
- padding: 0;
3703
- color: var(--ow-text);
4395
+ .ow-color-area:dir(rtl) .ow-color-area__thumb {
4396
+ translate: 50% -50%;
4397
+ }
4398
+
4399
+ .ow-color-area--dragging .ow-color-area__thumb {
4400
+ scale: 1.15;
4401
+ }
4402
+
4403
+ /* Focused by a press, it shows no ring until a key is used (useDrag's pointerFocus). */
4404
+ .ow-color-area:not(.ow-color-area--pointer) .ow-color-area__thumb:has(:focus-visible) {
4405
+ outline: 2px solid var(--ow-focus-ring);
4406
+ outline-offset: 2px;
4407
+ }
4408
+
4409
+ .ow-color-area--disabled {
4410
+ cursor: not-allowed;
4411
+ opacity: 0.55;
4412
+ }
4413
+
4414
+ @media (prefers-reduced-motion: reduce) {
4415
+ .ow-color-area__thumb {
4416
+ transition: none;
4417
+ }
4418
+ }
4419
+
4420
+ /* components/ColorPicker/ColorSlider.css */
4421
+ /* ColorSlider: a 12px pill track painted with the channel's range, and ColorPicker's thumb, which shows the colour.
4422
+ The input is visually hidden inside the thumb, so a screen reader's focus box sits where the thumb is. */
4423
+ .ow-color-slider {
4424
+ --ow-color-slider-direction: to right;
4425
+ display: grid;
4426
+ min-width: 0;
4427
+ gap: var(--ow-space-md);
4428
+ }
4429
+
4430
+ .ow-color-slider--horizontal:dir(rtl) {
4431
+ --ow-color-slider-direction: to left;
4432
+ }
4433
+
4434
+ .ow-color-slider--vertical {
4435
+ --ow-color-slider-direction: to top;
4436
+ display: inline-flex;
4437
+ height: 152px;
4438
+ flex-direction: column;
4439
+ align-items: center;
4440
+ }
4441
+
4442
+ .ow-color-slider__header {
4443
+ display: flex;
4444
+ align-items: baseline;
4445
+ justify-content: space-between;
4446
+ gap: var(--ow-space-md);
4447
+ }
4448
+
4449
+ .ow-color-slider--vertical .ow-color-slider__header {
4450
+ flex-direction: column;
4451
+ align-items: center;
4452
+ gap: 0;
4453
+ }
4454
+
4455
+ .ow-color-slider__label {
4456
+ color: var(--ow-text);
4457
+ font-size: 14px;
4458
+ font-weight: var(--ow-weight-emphasis);
4459
+ }
4460
+
4461
+ .ow-color-slider__value {
4462
+ color: var(--ow-text-muted);
4463
+ font-size: 13px;
4464
+ font-variant-numeric: tabular-nums;
4465
+ }
4466
+
4467
+ .ow-color-slider__track {
4468
+ position: relative;
4469
+ border-radius: var(--ow-radius-pill);
4470
+ background: var(--ow-color-slider-gradient);
4471
+ box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.1);
4472
+ cursor: pointer;
4473
+ touch-action: none;
4474
+ user-select: none;
4475
+ -webkit-tap-highlight-color: transparent;
4476
+ }
4477
+
4478
+ /* A taller target than the 12px track, the thumb's full height. */
4479
+ .ow-color-slider__track::before {
4480
+ position: absolute;
4481
+ content: "";
4482
+ }
4483
+
4484
+ .ow-color-slider--horizontal .ow-color-slider__track {
4485
+ height: 12px;
4486
+ }
4487
+
4488
+ .ow-color-slider--horizontal .ow-color-slider__track::before {
4489
+ inset: -4px 0;
4490
+ }
4491
+
4492
+ .ow-color-slider--vertical .ow-color-slider__track {
4493
+ width: 12px;
4494
+ min-height: 0;
4495
+ flex: 1;
4496
+ }
4497
+
4498
+ .ow-color-slider--vertical .ow-color-slider__track::before {
4499
+ inset: 0 -4px;
4500
+ }
4501
+
4502
+ .ow-color-slider--alpha .ow-color-slider__track {
4503
+ background:
4504
+ var(--ow-color-slider-gradient),
4505
+ repeating-conic-gradient(var(--ow-gray-200) 0 25%, #ffffff 0 50%) 0 0 / 12px 12px;
4506
+ }
4507
+
4508
+ .ow-color-slider__thumb {
4509
+ position: absolute;
4510
+ width: 16px;
4511
+ height: 16px;
4512
+ border: 2px solid #ffffff;
4513
+ border-radius: 50%;
4514
+ background:
4515
+ linear-gradient(var(--ow-color-slider-thumb), var(--ow-color-slider-thumb)),
4516
+ repeating-conic-gradient(var(--ow-gray-200) 0 25%, #ffffff 0 50%) 0 0 / 8px 8px;
4517
+ box-shadow:
4518
+ 0 0 0 1px rgba(15, 23, 42, 0.18),
4519
+ 0 2px 6px rgba(15, 23, 42, 0.28);
4520
+ pointer-events: none;
4521
+ transition: scale var(--ow-duration-fast) var(--ow-ease-standard);
4522
+ }
4523
+
4524
+ .ow-color-slider--horizontal .ow-color-slider__thumb {
4525
+ top: 50%;
4526
+ inset-inline-start: var(--ow-color-slider-position);
4527
+ translate: -50% -50%;
4528
+ }
4529
+
4530
+ .ow-color-slider--horizontal:dir(rtl) .ow-color-slider__thumb {
4531
+ translate: 50% -50%;
4532
+ }
4533
+
4534
+ .ow-color-slider--vertical .ow-color-slider__thumb {
4535
+ bottom: var(--ow-color-slider-position);
4536
+ left: 50%;
4537
+ translate: -50% 50%;
4538
+ }
4539
+
4540
+ .ow-color-slider--dragging .ow-color-slider__thumb {
4541
+ scale: 1.15;
4542
+ }
4543
+
4544
+ /* Focused by a press, it shows no ring until a key is used (useDrag's pointerFocus). */
4545
+ .ow-color-slider:not(.ow-color-slider--pointer) .ow-color-slider__thumb:has(:focus-visible) {
4546
+ outline: 2px solid var(--ow-focus-ring);
4547
+ outline-offset: 2px;
4548
+ }
4549
+
4550
+ .ow-color-slider--disabled {
4551
+ opacity: 0.55;
4552
+ }
4553
+
4554
+ .ow-color-slider--disabled .ow-color-slider__track {
4555
+ cursor: not-allowed;
4556
+ }
4557
+
4558
+ @media (prefers-reduced-motion: reduce) {
4559
+ .ow-color-slider__thumb {
4560
+ transition: none;
4561
+ }
4562
+ }
4563
+
4564
+ /* components/ColorPicker/ColorSwatchPicker.css */
4565
+ /* ColorSwatchPicker: swatches in wrapping rows, like ColorPicker's. The chosen one gets ColorPicker's ring (a gap in
4566
+ the surface colour, then a 2px ring in the text colour) and a check in white or slate, whichever reads on it.
4567
+ The focus outline lands exactly on the ring, so a focused swatch's ring turns the focus colour. */
4568
+ .ow-color-swatch-picker {
4569
+ display: flex;
4570
+ flex-wrap: wrap;
4571
+ align-items: center;
4572
+ gap: var(--ow-space-sm);
4573
+ }
4574
+
4575
+ .ow-color-swatch-picker--sm {
4576
+ gap: var(--ow-space-xs);
4577
+ }
4578
+
4579
+ .ow-color-swatch-picker__swatch {
4580
+ display: inline-flex;
4581
+ width: 32px;
4582
+ height: 32px;
4583
+ flex-shrink: 0;
4584
+ align-items: center;
4585
+ justify-content: center;
4586
+ border-radius: var(--ow-radius-form);
4587
+ background:
4588
+ linear-gradient(var(--ow-color-swatch-picker-value), var(--ow-color-swatch-picker-value)),
4589
+ repeating-conic-gradient(var(--ow-gray-200) 0 25%, #ffffff 0 50%) 0 0 / 8px 8px;
4590
+ box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.14);
4591
+ cursor: pointer;
4592
+ outline: none;
4593
+ -webkit-tap-highlight-color: transparent;
4594
+ transition:
4595
+ transform var(--ow-duration-base) var(--ow-ease-spring),
4596
+ box-shadow var(--ow-duration-base) var(--ow-ease-standard);
4597
+ }
4598
+
4599
+ .ow-color-swatch-picker--sm .ow-color-swatch-picker__swatch {
4600
+ width: 24px;
4601
+ height: 24px;
4602
+ border-radius: var(--ow-radius-md);
4603
+ }
4604
+
4605
+ .ow-color-swatch-picker--circle .ow-color-swatch-picker__swatch {
4606
+ border-radius: 50%;
4607
+ }
4608
+
4609
+ .ow-color-swatch-picker__swatch:hover:not([aria-disabled="true"]) {
4610
+ transform: scale(1.1);
4611
+ }
4612
+
4613
+ .ow-color-swatch-picker__swatch[aria-checked="true"] {
4614
+ box-shadow:
4615
+ inset 0 0 0 1px rgba(15, 23, 42, 0.14),
4616
+ 0 0 0 2px var(--ow-surface),
4617
+ 0 0 0 4px var(--ow-text);
4618
+ }
4619
+
4620
+ .ow-color-swatch-picker__swatch:focus-visible {
4621
+ outline: 2px solid var(--ow-focus-ring);
4622
+ outline-offset: 2px;
4623
+ }
4624
+
4625
+ .ow-color-swatch-picker__check {
4626
+ opacity: 0;
4627
+ scale: 0.5;
4628
+ transition:
4629
+ opacity var(--ow-duration-fast) var(--ow-ease-standard),
4630
+ scale var(--ow-duration-base) var(--ow-ease-spring);
4631
+ }
4632
+
4633
+ .ow-color-swatch-picker__swatch[data-ink="light"] .ow-color-swatch-picker__check {
4634
+ color: #ffffff;
4635
+ }
4636
+
4637
+ .ow-color-swatch-picker__swatch[data-ink="dark"] .ow-color-swatch-picker__check {
4638
+ color: var(--ow-gray-900);
4639
+ }
4640
+
4641
+ .ow-color-swatch-picker__swatch[aria-checked="true"] .ow-color-swatch-picker__check {
4642
+ opacity: 1;
4643
+ scale: 1;
4644
+ }
4645
+
4646
+ .ow-color-swatch-picker__swatch[aria-disabled="true"] {
4647
+ cursor: not-allowed;
4648
+ opacity: 0.4;
4649
+ }
4650
+
4651
+ .ow-color-swatch-picker--disabled {
4652
+ opacity: 0.55;
4653
+ }
4654
+
4655
+ /* The group fades as a whole; its swatches don't fade again. */
4656
+ .ow-color-swatch-picker--disabled .ow-color-swatch-picker__swatch[aria-disabled="true"] {
4657
+ opacity: 1;
4658
+ }
4659
+
4660
+ @media (prefers-reduced-motion: reduce) {
4661
+ .ow-color-swatch-picker__swatch,
4662
+ .ow-color-swatch-picker__check {
4663
+ transition: none;
4664
+ }
4665
+ }
4666
+
4667
+ /* components/CommandPalette/CommandPalette.css */
4668
+ /* CommandPalette: a dialog 12vh from the top, 560px wide, with a search row and a results list. */
4669
+ .ow-palette {
4670
+ top: 12vh;
4671
+ bottom: auto;
4672
+ width: min(560px, calc(100% - 32px));
4673
+ margin: 0 auto;
4674
+ overflow: hidden;
4675
+ padding: 0;
4676
+ }
4677
+
4678
+ .ow-palette__search {
4679
+ display: flex;
4680
+ align-items: center;
4681
+ gap: var(--ow-space-sm);
4682
+ border-bottom: 1px solid var(--ow-border);
4683
+ padding: var(--ow-space-md) var(--ow-space-lg);
4684
+ }
4685
+
4686
+ .ow-palette__search-icon {
4687
+ flex-shrink: 0;
4688
+ color: var(--ow-text-muted);
4689
+ }
4690
+
4691
+ .ow-palette__input {
4692
+ min-width: 0;
4693
+ flex: 1;
4694
+ margin: 0;
4695
+ border: 0;
4696
+ background: transparent;
4697
+ padding: 0;
4698
+ color: var(--ow-text);
3704
4699
  font: inherit;
3705
4700
  font-size: 14px;
3706
4701
  outline: 0;
@@ -5809,3 +6804,2527 @@
5809
6804
  .ow-dot-grid__content {
5810
6805
  position: relative;
5811
6806
  }
6807
+
6808
+ /* components/Prose/Prose.css */
6809
+ /* Prose: the plain elements of rendered Markdown, a CMS body or an agent's answer, in Openware's type and colours.
6810
+ Every element rule ends in the same :not(): it skips Openware components and everything inside them, so a CodeBlock,
6811
+ a Table or a Code in the text keeps its own look. That :not() also gives the rules enough weight that a page's own
6812
+ element styles (a reset, `article p`) don't leak in. */
6813
+ .ow-prose {
6814
+ min-width: 0;
6815
+ color: var(--ow-text);
6816
+ overflow-wrap: break-word;
6817
+ }
6818
+
6819
+ /* md: articles and docs, on the prose style (16.5px, 1.7), about 68 characters a line. */
6820
+ .ow-prose--md {
6821
+ --ow-prose-flow: var(--ow-space-4xl);
6822
+ --ow-prose-block: var(--ow-space-7xl);
6823
+ --ow-prose-heading: 40px;
6824
+ --ow-prose-heading-gap: var(--ow-space-xl);
6825
+ --ow-prose-subheading: var(--ow-space-7xl);
6826
+ --ow-prose-subheading-gap: var(--ow-space-sm);
6827
+ --ow-prose-rule: 40px;
6828
+ --ow-prose-item: var(--ow-space-xs);
6829
+ --ow-prose-indent: var(--ow-space-6xl);
6830
+ --ow-prose-marker-gap: var(--ow-space-2xs);
6831
+ --ow-prose-quote: var(--ow-space-3xl);
6832
+ --ow-prose-code: 14px;
6833
+ --ow-prose-key: 13px;
6834
+ --ow-prose-pre-y: var(--ow-space-2xl);
6835
+ --ow-prose-pre-x: var(--ow-space-3xl);
6836
+ --ow-prose-cell-y: var(--ow-space-md);
6837
+ --ow-prose-cell-x: var(--ow-space-xl);
6838
+ --ow-prose-caption: 14px;
6839
+ --ow-prose-caption-gap: var(--ow-space-md);
6840
+ --ow-prose-check: 16px;
6841
+ --ow-prose-check-gap: var(--ow-space-sm);
6842
+ --ow-prose-details-x: var(--ow-space-2xl);
6843
+ --ow-prose-details-y: var(--ow-space-lg);
6844
+ --ow-prose-details-end: var(--ow-space-2xl);
6845
+ max-width: 68ch;
6846
+ color: var(--ow-text-soft);
6847
+ }
6848
+
6849
+ /* sm: chat answers and comments, on 14px interface text with a tight rhythm. */
6850
+ .ow-prose--sm {
6851
+ --ow-prose-flow: var(--ow-space-lg);
6852
+ --ow-prose-block: var(--ow-space-xl);
6853
+ --ow-prose-heading: var(--ow-space-4xl);
6854
+ --ow-prose-heading-gap: var(--ow-space-xs);
6855
+ --ow-prose-subheading: var(--ow-space-2xl);
6856
+ --ow-prose-subheading-gap: var(--ow-space-2xs);
6857
+ --ow-prose-rule: var(--ow-space-3xl);
6858
+ --ow-prose-item: var(--ow-space-2xs);
6859
+ --ow-prose-indent: var(--ow-space-5xl);
6860
+ --ow-prose-marker-gap: 2px;
6861
+ --ow-prose-quote: var(--ow-space-lg);
6862
+ --ow-prose-code: 13px;
6863
+ --ow-prose-key: 12px;
6864
+ --ow-prose-pre-y: var(--ow-space-xl);
6865
+ --ow-prose-pre-x: var(--ow-space-lg);
6866
+ --ow-prose-cell-y: var(--ow-space-sm);
6867
+ --ow-prose-cell-x: var(--ow-space-lg);
6868
+ --ow-prose-caption: 12px;
6869
+ --ow-prose-caption-gap: var(--ow-space-sm);
6870
+ --ow-prose-check: 14px;
6871
+ --ow-prose-check-gap: var(--ow-space-xs);
6872
+ --ow-prose-details-x: var(--ow-space-lg);
6873
+ --ow-prose-details-y: var(--ow-space-md);
6874
+ --ow-prose-details-end: var(--ow-space-lg);
6875
+ }
6876
+
6877
+ .ow-prose--full {
6878
+ max-width: none;
6879
+ }
6880
+
6881
+ /* Vertical rhythm: paragraphs and lists, then the larger blocks, with more room above a heading than below it. */
6882
+ .ow-prose :where(p):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6883
+ max-width: none;
6884
+ margin-block: var(--ow-prose-flow);
6885
+ color: inherit;
6886
+ font-size: inherit;
6887
+ line-height: inherit;
6888
+ text-wrap: pretty;
6889
+ }
6890
+
6891
+ .ow-prose :where(h1, h2, h3, h4, h5, h6):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6892
+ color: var(--ow-text);
6893
+ text-wrap: balance;
6894
+ }
6895
+
6896
+ .ow-prose :where(h1, h2):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6897
+ margin-block: var(--ow-prose-heading) var(--ow-prose-heading-gap);
6898
+ }
6899
+
6900
+ .ow-prose :where(h3, h4, h5, h6):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6901
+ margin-block: var(--ow-prose-subheading) var(--ow-prose-subheading-gap);
6902
+ }
6903
+
6904
+ /* md headings come from the type scale: h1 is the section title as phones set it, light and tight; h2 is heading. */
6905
+ .ow-prose--md :where(h1):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6906
+ font-size: 32px;
6907
+ font-weight: 500;
6908
+ line-height: 1.12;
6909
+ letter-spacing: -0.03em;
6910
+ }
6911
+
6912
+ .ow-prose--md :where(h2):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6913
+ font-size: 24px;
6914
+ font-weight: var(--ow-weight-emphasis);
6915
+ line-height: 1.25;
6916
+ letter-spacing: -0.02em;
6917
+ }
6918
+
6919
+ .ow-prose--md :where(h3):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6920
+ font-size: 18px;
6921
+ font-weight: var(--ow-weight-emphasis);
6922
+ line-height: 1.4;
6923
+ letter-spacing: -0.01em;
6924
+ }
6925
+
6926
+ .ow-prose--md :where(h4, h5, h6):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6927
+ font-size: 1em;
6928
+ font-weight: var(--ow-weight-emphasis);
6929
+ line-height: 1.5;
6930
+ }
6931
+
6932
+ /* sm headings stay modest, in the app's heavy weights: a dialog title, then smaller and lighter. */
6933
+ .ow-prose--sm :where(h1):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6934
+ font-size: 16px;
6935
+ font-weight: var(--ow-weight-display);
6936
+ line-height: 1.3;
6937
+ }
6938
+
6939
+ .ow-prose--sm :where(h2):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6940
+ font-size: 15px;
6941
+ font-weight: var(--ow-weight-title);
6942
+ line-height: 1.35;
6943
+ }
6944
+
6945
+ .ow-prose--sm :where(h3):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6946
+ font-size: 14px;
6947
+ font-weight: var(--ow-weight-label);
6948
+ line-height: 1.45;
6949
+ }
6950
+
6951
+ .ow-prose--sm :where(h4, h5, h6):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6952
+ font-size: 14px;
6953
+ font-weight: var(--ow-weight-emphasis);
6954
+ line-height: 1.45;
6955
+ }
6956
+
6957
+ /* Inline text. */
6958
+ .ow-prose :where(a):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6959
+ border-radius: 2px;
6960
+ color: var(--ow-text);
6961
+ text-decoration-line: underline;
6962
+ text-decoration-color: var(--ow-border-strong);
6963
+ text-decoration-thickness: 1px;
6964
+ text-underline-offset: 3px;
6965
+ transition-property: color, text-decoration-color;
6966
+ transition-duration: var(--ow-duration-base);
6967
+ transition-timing-function: var(--ow-ease-standard);
6968
+ }
6969
+
6970
+ .ow-prose :where(a):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *):hover {
6971
+ color: var(--ow-brass-deep);
6972
+ text-decoration-color: var(--ow-brass-deep);
6973
+ }
6974
+
6975
+ .ow-prose :where(a):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *):focus-visible {
6976
+ outline: 2px solid var(--ow-focus-ring);
6977
+ outline-offset: 2px;
6978
+ }
6979
+
6980
+ .ow-prose :where(strong, b):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6981
+ color: var(--ow-text);
6982
+ font-weight: var(--ow-weight-emphasis);
6983
+ }
6984
+
6985
+ /* Inter ships upright only here, so emphasis lets the browser slant it. */
6986
+ .ow-prose :where(em, i, cite):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6987
+ font-style: italic;
6988
+ font-synthesis: style;
6989
+ }
6990
+
6991
+ .ow-prose :where(code):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
6992
+ border-radius: var(--ow-radius-code);
6993
+ background: var(--ow-code-ground);
6994
+ padding: 2px 4px;
6995
+ color: var(--ow-text);
6996
+ font-family: var(--ow-font-mono);
6997
+ font-size: 0.88em;
6998
+ font-variant-ligatures: none;
6999
+ -webkit-box-decoration-break: clone;
7000
+ box-decoration-break: clone;
7001
+ }
7002
+
7003
+ .ow-prose :where(kbd):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7004
+ box-sizing: border-box;
7005
+ display: inline-block;
7006
+ min-width: 1.85em;
7007
+ border: 1px solid var(--ow-border-strong);
7008
+ border-bottom-width: 2px;
7009
+ border-radius: var(--ow-radius-md);
7010
+ background: var(--ow-key-ground);
7011
+ padding: 0 var(--ow-space-xs);
7012
+ color: var(--ow-text-soft);
7013
+ font-family: var(--ow-font-mono);
7014
+ font-size: var(--ow-prose-key);
7015
+ font-weight: var(--ow-weight-control);
7016
+ line-height: 1.6;
7017
+ text-align: center;
7018
+ white-space: nowrap;
7019
+ }
7020
+
7021
+ /* <kbd><kbd>⌘</kbd><kbd>K</kbd></kbd> is one shortcut: only the inner keys are drawn. */
7022
+ .ow-prose :where(kbd:has(kbd)):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7023
+ min-width: 0;
7024
+ border: 0;
7025
+ background: none;
7026
+ padding: 0;
7027
+ color: inherit;
7028
+ font: inherit;
7029
+ }
7030
+
7031
+ .ow-prose :where(mark):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7032
+ border-radius: var(--ow-radius-sm);
7033
+ background: var(--ow-brass-soft);
7034
+ padding: 0 2px;
7035
+ color: var(--ow-text);
7036
+ -webkit-box-decoration-break: clone;
7037
+ box-decoration-break: clone;
7038
+ }
7039
+
7040
+ /* Raised and lowered text that doesn't open up the line it sits in. */
7041
+ .ow-prose :where(sub, sup):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7042
+ position: relative;
7043
+ font-size: 0.75em;
7044
+ line-height: 0;
7045
+ vertical-align: baseline;
7046
+ }
7047
+
7048
+ .ow-prose :where(sup):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7049
+ top: -0.5em;
7050
+ }
7051
+
7052
+ .ow-prose :where(sub):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7053
+ bottom: -0.25em;
7054
+ }
7055
+
7056
+ /* Lists: muted markers hanging in the indent; nested lists sit as close as their items. */
7057
+ .ow-prose :where(ul, ol):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7058
+ margin-block: var(--ow-prose-flow);
7059
+ padding-inline-start: var(--ow-prose-indent);
7060
+ }
7061
+
7062
+ .ow-prose :where(ul):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7063
+ list-style-type: disc;
7064
+ }
7065
+
7066
+ .ow-prose :where(ol):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7067
+ list-style-type: decimal;
7068
+ }
7069
+
7070
+ .ow-prose :where(ul ul):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7071
+ list-style-type: circle;
7072
+ }
7073
+
7074
+ .ow-prose :where(ul ul ul):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7075
+ list-style-type: square;
7076
+ }
7077
+
7078
+ .ow-prose :where(li ul, li ol):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7079
+ margin-block: var(--ow-prose-item);
7080
+ }
7081
+
7082
+ .ow-prose :where(li):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7083
+ margin-block: var(--ow-prose-item);
7084
+ padding-inline-start: var(--ow-prose-marker-gap);
7085
+ }
7086
+
7087
+ .ow-prose :where(li):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *)::marker {
7088
+ color: var(--ow-text-muted);
7089
+ }
7090
+
7091
+ .ow-prose :where(ol > li):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *)::marker {
7092
+ font-variant-numeric: tabular-nums;
7093
+ }
7094
+
7095
+ /* Task lists (GitHub Markdown's - [ ] and - [x]): the checkbox takes the bullet's place and the text lines up with
7096
+ the other items'. */
7097
+ .ow-prose
7098
+ :where(li:has(> input[type="checkbox"]:first-child, > p:first-child > input[type="checkbox"]:first-child)):not(
7099
+ [class^="ow-"],
7100
+ [class*=" ow-"],
7101
+ .ow-prose [class^="ow-"] *,
7102
+ .ow-prose [class*=" ow-"] *
7103
+ ) {
7104
+ list-style-type: none;
7105
+ }
7106
+
7107
+ .ow-prose :where(input[type="checkbox"]):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7108
+ box-sizing: border-box;
7109
+ width: var(--ow-prose-check);
7110
+ height: var(--ow-prose-check);
7111
+ margin: 0 var(--ow-prose-check-gap) 0 0;
7112
+ appearance: none;
7113
+ border: 1px solid var(--ow-border-strong);
7114
+ border-radius: var(--ow-radius-sm);
7115
+ background: var(--ow-surface);
7116
+ box-shadow: var(--ow-shadow-control);
7117
+ vertical-align: -0.15em;
7118
+ cursor: pointer;
7119
+ transition-property: border-color, background-color;
7120
+ transition-duration: var(--ow-duration-base);
7121
+ transition-timing-function: var(--ow-ease-standard);
7122
+ }
7123
+
7124
+ /* Markdown puts a space after the box; the gap allows for it (a space is 0.28em in Inter), so a wrapped line lines up
7125
+ with the first. */
7126
+ .ow-prose
7127
+ :where(li > input[type="checkbox"]:first-child, li > p:first-child > input[type="checkbox"]:first-child):not(
7128
+ [class^="ow-"],
7129
+ [class*=" ow-"],
7130
+ .ow-prose [class^="ow-"] *,
7131
+ .ow-prose [class*=" ow-"] *
7132
+ ) {
7133
+ margin-inline: calc(-1 * (var(--ow-prose-check) + var(--ow-prose-check-gap))) calc(var(--ow-prose-check-gap) - 0.28em);
7134
+ }
7135
+
7136
+ /* The tick is white, like Checkbox's, on the primary fill in both themes. */
7137
+ .ow-prose :where(input[type="checkbox"]:checked):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7138
+ border-color: var(--ow-primary-active);
7139
+ background-color: var(--ow-primary);
7140
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' \
7141
+ stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
7142
+ background-position: center;
7143
+ background-repeat: no-repeat;
7144
+ background-size: calc(var(--ow-prose-check) - 4px);
7145
+ }
7146
+
7147
+ .ow-prose
7148
+ :where(input[type="checkbox"]:hover:not(:disabled, :checked)):not(
7149
+ [class^="ow-"],
7150
+ [class*=" ow-"],
7151
+ .ow-prose [class^="ow-"] *,
7152
+ .ow-prose [class*=" ow-"] *
7153
+ ) {
7154
+ border-color: var(--ow-border-hover);
7155
+ }
7156
+
7157
+ .ow-prose :where(input[type="checkbox"]):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *):focus-visible {
7158
+ outline: 2px solid var(--ow-focus-ring);
7159
+ outline-offset: 2px;
7160
+ }
7161
+
7162
+ /* Rendered Markdown disables its checkboxes: they report a state rather than wait for a click, so they keep their
7163
+ colours and only lose the pointer. */
7164
+ .ow-prose :where(input[type="checkbox"]:disabled):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7165
+ cursor: default;
7166
+ }
7167
+
7168
+ .ow-prose :where(blockquote):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7169
+ margin-block: var(--ow-prose-block);
7170
+ margin-inline: 0;
7171
+ border-inline-start: 2px solid var(--ow-border-strong);
7172
+ padding-inline-start: var(--ow-prose-quote);
7173
+ color: var(--ow-text-muted);
7174
+ }
7175
+
7176
+ /* Code blocks: the CodeBlock's dark ground in both themes, scrolling sideways rather than wrapping. */
7177
+ .ow-prose :where(pre):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7178
+ box-sizing: border-box;
7179
+ margin-block: var(--ow-prose-block);
7180
+ overflow-x: auto;
7181
+ border: 1px solid var(--ow-code-block-border);
7182
+ border-radius: var(--ow-radius-container);
7183
+ background: var(--ow-code-block);
7184
+ padding: var(--ow-prose-pre-y) var(--ow-prose-pre-x);
7185
+ color: var(--ow-on-code-block);
7186
+ font-family: var(--ow-font-mono);
7187
+ font-size: var(--ow-prose-code);
7188
+ font-variant-ligatures: none;
7189
+ line-height: 1.7;
7190
+ tab-size: 4;
7191
+ white-space: pre;
7192
+ overflow-wrap: normal;
7193
+ color-scheme: dark;
7194
+ }
7195
+
7196
+ .ow-prose :where(pre):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *):focus-visible {
7197
+ outline: 2px solid var(--ow-focus-ring);
7198
+ outline-offset: 2px;
7199
+ }
7200
+
7201
+ .ow-prose :where(pre code):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7202
+ border-radius: 0;
7203
+ background: none;
7204
+ padding: 0;
7205
+ color: inherit;
7206
+ font-size: inherit;
7207
+ }
7208
+
7209
+ .ow-prose :where(hr):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7210
+ height: 0;
7211
+ margin-block: var(--ow-prose-rule);
7212
+ border: 0;
7213
+ border-top: 1px solid var(--ow-border);
7214
+ }
7215
+
7216
+ /* Tables: Table's look, a bordered card with a quiet header and hairlines between rows. As a block it scrolls
7217
+ sideways when it's wider than the text, and is as wide as its content otherwise. */
7218
+ .ow-prose :where(table):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7219
+ box-sizing: border-box;
7220
+ display: block;
7221
+ width: max-content;
7222
+ max-width: 100%;
7223
+ margin-block: var(--ow-prose-block);
7224
+ overflow-x: auto;
7225
+ border: 1px solid var(--ow-border);
7226
+ border-radius: var(--ow-radius-container);
7227
+ border-collapse: separate;
7228
+ border-spacing: 0;
7229
+ background: var(--ow-surface);
7230
+ color: var(--ow-text);
7231
+ font-size: 14px;
7232
+ font-variant-numeric: tabular-nums;
7233
+ line-height: 1.45;
7234
+ }
7235
+
7236
+ .ow-prose :where(table):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *):focus-visible {
7237
+ outline: 2px solid var(--ow-focus-ring);
7238
+ outline-offset: 2px;
7239
+ }
7240
+
7241
+ .ow-prose :where(caption):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7242
+ padding: var(--ow-space-lg) var(--ow-prose-cell-x) var(--ow-space-sm);
7243
+ color: var(--ow-text);
7244
+ font-weight: var(--ow-weight-emphasis);
7245
+ text-align: start;
7246
+ }
7247
+
7248
+ .ow-prose :where(th, td):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7249
+ border-bottom: 1px solid var(--ow-border);
7250
+ padding: var(--ow-prose-cell-y) var(--ow-prose-cell-x);
7251
+ text-align: start;
7252
+ vertical-align: top;
7253
+ }
7254
+
7255
+ .ow-prose :where(thead th):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7256
+ background: var(--ow-surface-muted);
7257
+ color: var(--ow-text-muted);
7258
+ font-size: 12px;
7259
+ font-weight: var(--ow-weight-emphasis);
7260
+ line-height: 1.35;
7261
+ white-space: nowrap;
7262
+ vertical-align: bottom;
7263
+ }
7264
+
7265
+ .ow-prose :where(tbody th):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7266
+ font-weight: var(--ow-weight-emphasis);
7267
+ }
7268
+
7269
+ .ow-prose :where(tbody tr:last-child > *):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7270
+ border-bottom: 0;
7271
+ }
7272
+
7273
+ /* Markdown sets column alignment with align="…"; the start alignment above would otherwise win over it. */
7274
+ .ow-prose :where(th[align="center"], td[align="center"]):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7275
+ text-align: center;
7276
+ }
7277
+
7278
+ .ow-prose :where(th[align="right"], td[align="right"]):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7279
+ text-align: right;
7280
+ }
7281
+
7282
+ .ow-prose :where(img, video):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7283
+ max-width: 100%;
7284
+ height: auto;
7285
+ }
7286
+
7287
+ .ow-prose > :where(img, video):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *),
7288
+ .ow-prose :where(figure > img, figure > video):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7289
+ display: block;
7290
+ border-radius: var(--ow-radius-container);
7291
+ }
7292
+
7293
+ .ow-prose > :where(img, video):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7294
+ margin-block: var(--ow-prose-block);
7295
+ }
7296
+
7297
+ .ow-prose :where(figure):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7298
+ margin-block: var(--ow-prose-block);
7299
+ margin-inline: 0;
7300
+ }
7301
+
7302
+ .ow-prose :where(figure > *):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7303
+ margin-block: 0;
7304
+ }
7305
+
7306
+ .ow-prose :where(figcaption):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7307
+ margin-top: var(--ow-prose-caption-gap);
7308
+ color: var(--ow-text-muted);
7309
+ font-size: var(--ow-prose-caption);
7310
+ line-height: 1.5;
7311
+ text-wrap: pretty;
7312
+ }
7313
+
7314
+ /* details: Disclosure's look, a bordered card with a chevron that turns as it opens. The content lines up with the
7315
+ summary's text. */
7316
+ .ow-prose :where(details):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7317
+ --ow-prose-details-indent: calc(var(--ow-prose-details-x) + 16px + var(--ow-space-sm));
7318
+ box-sizing: border-box;
7319
+ margin-block: var(--ow-prose-block);
7320
+ border: 1px solid var(--ow-border);
7321
+ border-radius: var(--ow-radius-container);
7322
+ background: var(--ow-surface);
7323
+ padding-inline: var(--ow-prose-details-indent) var(--ow-prose-details-x);
7324
+ }
7325
+
7326
+ .ow-prose :where(details[open]):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7327
+ padding-bottom: var(--ow-prose-details-end);
7328
+ }
7329
+
7330
+ .ow-prose :where(summary):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7331
+ display: block;
7332
+ margin-inline: calc(-1 * var(--ow-prose-details-indent)) calc(-1 * var(--ow-prose-details-x));
7333
+ padding-block: var(--ow-prose-details-y);
7334
+ padding-inline: var(--ow-prose-details-indent) var(--ow-prose-details-x);
7335
+ color: var(--ow-text);
7336
+ font-weight: var(--ow-weight-emphasis);
7337
+ list-style: none;
7338
+ cursor: pointer;
7339
+ }
7340
+
7341
+ .ow-prose :where(summary):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *)::-webkit-details-marker {
7342
+ display: none;
7343
+ }
7344
+
7345
+ /* The chevron hangs in the indent on the first line, so a summary that wraps keeps its text aligned. */
7346
+ .ow-prose :where(summary):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *)::before {
7347
+ content: "";
7348
+ display: inline-block;
7349
+ width: 16px;
7350
+ height: 16px;
7351
+ margin-inline: calc(-16px - var(--ow-space-sm)) var(--ow-space-sm);
7352
+ --ow-prose-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' \
7353
+ stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
7354
+ background: var(--ow-text-muted);
7355
+ vertical-align: -0.2em;
7356
+ -webkit-mask: var(--ow-prose-chevron) center / 16px no-repeat;
7357
+ mask: var(--ow-prose-chevron) center / 16px no-repeat;
7358
+ transition: transform var(--ow-duration-slow) var(--ow-ease-emphasized);
7359
+ }
7360
+
7361
+ .ow-prose :where(summary):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *):hover::before {
7362
+ background: var(--ow-text);
7363
+ }
7364
+
7365
+ .ow-prose :where(summary:dir(rtl)):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *)::before {
7366
+ transform: scaleX(-1);
7367
+ }
7368
+
7369
+ .ow-prose :where(details[open] > summary):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *)::before {
7370
+ transform: rotate(90deg);
7371
+ }
7372
+
7373
+ .ow-prose :where(summary):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *):focus-visible {
7374
+ border-radius: var(--ow-radius-form);
7375
+ outline: 2px solid var(--ow-focus-ring);
7376
+ outline-offset: -4px;
7377
+ }
7378
+
7379
+ /* While an answer streams in (aria-busy on it or around it), lines break as they fill rather than evening out, so words
7380
+ already shown don't hop to another line as more arrive. */
7381
+ .ow-prose:is([aria-busy="true"], [aria-busy="true"] *)
7382
+ :where(p, h1, h2, h3, h4, h5, h6, figcaption):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7383
+ text-wrap: wrap;
7384
+ }
7385
+
7386
+ /* Openware components placed straight in the text get the block spacing; Text gets a paragraph's. */
7387
+ .ow-prose > :where([class^="ow-"], [class*=" ow-"]) {
7388
+ margin-block: var(--ow-prose-block);
7389
+ }
7390
+
7391
+ .ow-prose > :where(.ow-text) {
7392
+ margin-block: var(--ow-prose-flow);
7393
+ }
7394
+
7395
+ /* Nothing adds space at the edges, so the text sits flush in a message bubble or a card; the same goes inside quotes,
7396
+ list items, cells, figures and details. */
7397
+ .ow-prose > :where([class^="ow-"], [class*=" ow-"]):first-child,
7398
+ .ow-prose > :first-child:not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *),
7399
+ .ow-prose :where(blockquote, li, th, td, figure) > :first-child:not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *),
7400
+ .ow-prose :where(details > summary) + *:not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7401
+ margin-top: 0;
7402
+ }
7403
+
7404
+ .ow-prose > :where([class^="ow-"], [class*=" ow-"]):last-child,
7405
+ .ow-prose > :last-child:not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *),
7406
+ .ow-prose
7407
+ :where(blockquote, li, th, td, figure, details)
7408
+ > :last-child:not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7409
+ margin-bottom: 0;
7410
+ }
7411
+
7412
+ /* The heading size on phones, as Text sets it. */
7413
+ @media (max-width: 760px) {
7414
+ .ow-prose--md :where(h2):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7415
+ font-size: 21px;
7416
+ }
7417
+ }
7418
+
7419
+ @media (prefers-reduced-motion: reduce) {
7420
+ .ow-prose :where(a, input):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *),
7421
+ .ow-prose :where(summary):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *)::before {
7422
+ transition: none;
7423
+ }
7424
+ }
7425
+
7426
+ /* High contrast: the system draws the checkboxes, and the chevron takes the text colour. */
7427
+ @media (forced-colors: active) {
7428
+ .ow-prose :where(input[type="checkbox"]):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *) {
7429
+ appearance: auto;
7430
+ }
7431
+ .ow-prose :where(summary):not([class^="ow-"], [class*=" ow-"], .ow-prose [class^="ow-"] *, .ow-prose [class*=" ow-"] *)::before {
7432
+ background: CanvasText;
7433
+ forced-color-adjust: none;
7434
+ }
7435
+ }
7436
+
7437
+ /* components/TextShimmer/TextShimmer.css */
7438
+ /* TextShimmer: muted text with a band of full-strength text sweeping across it. */
7439
+ .ow-shimmer {
7440
+ color: var(--ow-text-muted);
7441
+ }
7442
+
7443
+ .ow-shimmer--active {
7444
+ /* The band is the text colour; either side is the muted colour, so the words stay readable throughout. */
7445
+ background-image: linear-gradient(
7446
+ 90deg,
7447
+ var(--ow-text-muted) 0%,
7448
+ var(--ow-text-muted) 40%,
7449
+ var(--ow-text) 50%,
7450
+ var(--ow-text-muted) 60%,
7451
+ var(--ow-text-muted) 100%
7452
+ );
7453
+ background-size: 250% 100%;
7454
+ background-position: 100% 0;
7455
+ background-clip: text;
7456
+ -webkit-background-clip: text;
7457
+ color: transparent;
7458
+ animation: ow-shimmer var(--ow-shimmer-duration, 2s) linear infinite;
7459
+ }
7460
+
7461
+ @keyframes ow-shimmer {
7462
+ from {
7463
+ background-position: 100% 0;
7464
+ }
7465
+ to {
7466
+ background-position: 0 0;
7467
+ }
7468
+ }
7469
+
7470
+ @media (prefers-reduced-motion: reduce) {
7471
+ .ow-shimmer--active {
7472
+ background: none;
7473
+ color: var(--ow-text-muted);
7474
+ animation: none;
7475
+ }
7476
+ }
7477
+
7478
+ /* Windows high-contrast and forced colours: plain text. */
7479
+ @media (forced-colors: active) {
7480
+ .ow-shimmer--active {
7481
+ background: none;
7482
+ color: CanvasText;
7483
+ animation: none;
7484
+ }
7485
+ }
7486
+
7487
+ /* components/PromptInput/PromptInput.css */
7488
+ /* PromptInput: a surface card holding the attachments, the text and a toolbar; the field's border and halo show focus. */
7489
+ .ow-prompt-input {
7490
+ --ow-prompt-line: 24px;
7491
+ --ow-prompt-pad: 0px;
7492
+ display: grid;
7493
+ width: 100%;
7494
+ min-width: 0;
7495
+ gap: var(--ow-space-sm);
7496
+ color: var(--ow-text);
7497
+ font-family: var(--ow-font-sans);
7498
+ font-size: 14px;
7499
+ }
7500
+
7501
+ .ow-prompt-input--sm {
7502
+ --ow-prompt-line: 20px;
7503
+ gap: var(--ow-space-xs);
7504
+ }
7505
+
7506
+ .ow-prompt-input__box {
7507
+ position: relative;
7508
+ display: grid;
7509
+ min-width: 0;
7510
+ min-inline-size: 0;
7511
+ gap: var(--ow-space-md);
7512
+ margin: 0;
7513
+ border: 1px solid var(--ow-border);
7514
+ border-radius: var(--ow-radius-container);
7515
+ background: var(--ow-surface);
7516
+ padding: var(--ow-space-lg) var(--ow-space-md) var(--ow-space-md);
7517
+ box-shadow: var(--ow-shadow-control);
7518
+ cursor: text;
7519
+ transition-property: border-color, box-shadow, opacity;
7520
+ transition-duration: var(--ow-duration-base);
7521
+ transition-timing-function: var(--ow-ease-standard);
7522
+ }
7523
+
7524
+ .ow-prompt-input--sm .ow-prompt-input__box {
7525
+ gap: var(--ow-space-sm);
7526
+ padding: var(--ow-space-sm) var(--ow-space-xs) var(--ow-space-xs);
7527
+ }
7528
+
7529
+ .ow-prompt-input__box:hover {
7530
+ border-color: var(--ow-border-strong);
7531
+ }
7532
+
7533
+ .ow-prompt-input__box:focus-within {
7534
+ border-color: var(--ow-focus-border);
7535
+ box-shadow: var(--ow-shadow-focus);
7536
+ }
7537
+
7538
+ .ow-prompt-input--invalid .ow-prompt-input__box {
7539
+ border-color: var(--ow-danger-line);
7540
+ }
7541
+
7542
+ .ow-prompt-input--invalid .ow-prompt-input__box:focus-within {
7543
+ border-color: var(--ow-danger-solid);
7544
+ box-shadow: var(--ow-shadow-focus-danger);
7545
+ }
7546
+
7547
+ .ow-prompt-input--disabled .ow-prompt-input__box {
7548
+ border-color: var(--ow-border);
7549
+ box-shadow: none;
7550
+ cursor: not-allowed;
7551
+ opacity: 0.62;
7552
+ }
7553
+
7554
+ /* Inline: with nothing in the toolbar but the send button, the button sits at the end of the text. */
7555
+ .ow-prompt-input--inline .ow-prompt-input__box {
7556
+ grid-template-columns: minmax(0, 1fr) auto;
7557
+ align-items: end;
7558
+ column-gap: var(--ow-space-sm);
7559
+ padding: var(--ow-space-sm) var(--ow-space-sm) var(--ow-space-sm) var(--ow-space-md);
7560
+ }
7561
+
7562
+ .ow-prompt-input--inline .ow-prompt-input__attachments {
7563
+ grid-column: 1 / -1;
7564
+ }
7565
+
7566
+ /* The count stands above the send button, so the text keeps its width. */
7567
+ .ow-prompt-input--inline .ow-prompt-input__end {
7568
+ flex-direction: column;
7569
+ align-items: flex-end;
7570
+ gap: var(--ow-space-2xs);
7571
+ }
7572
+
7573
+ /* The text, centred on the 32px button while it's one line. */
7574
+ .ow-prompt-input--inline {
7575
+ --ow-prompt-pad: var(--ow-space-2xs);
7576
+ }
7577
+
7578
+ .ow-prompt-input--sm.ow-prompt-input--inline {
7579
+ --ow-prompt-pad: var(--ow-space-xs);
7580
+ }
7581
+
7582
+ .ow-prompt-input--sm.ow-prompt-input--inline .ow-prompt-input__box {
7583
+ padding: var(--ow-space-xs) var(--ow-space-xs) var(--ow-space-xs) var(--ow-space-sm);
7584
+ }
7585
+
7586
+ /* The text: borderless, with its own line height so the rows are exact. */
7587
+ .ow-prompt-input__textarea.ow-textarea {
7588
+ min-height: calc(var(--ow-prompt-line) * var(--ow-prompt-min-rows, 1) + 2 * var(--ow-prompt-pad));
7589
+ padding: var(--ow-prompt-pad) var(--ow-space-sm);
7590
+ color: var(--ow-text);
7591
+ font-size: 15px;
7592
+ line-height: var(--ow-prompt-line);
7593
+ cursor: text;
7594
+ }
7595
+
7596
+ .ow-prompt-input--sm .ow-prompt-input__textarea.ow-textarea {
7597
+ padding-inline: var(--ow-space-xs);
7598
+ font-size: 14px;
7599
+ }
7600
+
7601
+ .ow-prompt-input__textarea.ow-textarea:disabled {
7602
+ cursor: not-allowed;
7603
+ opacity: 1;
7604
+ }
7605
+
7606
+ /* Attachments: chips with a thumbnail or an icon, the name and size, and a remove button. */
7607
+ .ow-prompt-input__attachments {
7608
+ display: flex;
7609
+ min-width: 0;
7610
+ flex-wrap: wrap;
7611
+ gap: var(--ow-space-sm);
7612
+ margin: 0;
7613
+ padding: 0;
7614
+ list-style: none;
7615
+ cursor: default;
7616
+ }
7617
+
7618
+ .ow-prompt-input__attachment {
7619
+ display: flex;
7620
+ min-width: 0;
7621
+ max-width: min(100%, 240px);
7622
+ align-items: center;
7623
+ gap: var(--ow-space-sm);
7624
+ border: 1px solid var(--ow-border);
7625
+ border-radius: var(--ow-radius-lg);
7626
+ background: var(--ow-surface-muted);
7627
+ padding: var(--ow-space-2xs);
7628
+ }
7629
+
7630
+ .ow-prompt-input__thumb {
7631
+ position: relative;
7632
+ display: inline-flex;
7633
+ width: 36px;
7634
+ height: 36px;
7635
+ flex: none;
7636
+ align-items: center;
7637
+ justify-content: center;
7638
+ overflow: hidden;
7639
+ border: 1px solid var(--ow-border);
7640
+ border-radius: var(--ow-radius-md);
7641
+ background: var(--ow-surface);
7642
+ color: var(--ow-text-muted);
7643
+ }
7644
+
7645
+ .ow-prompt-input__thumb img {
7646
+ position: absolute;
7647
+ inset: 0;
7648
+ width: 100%;
7649
+ height: 100%;
7650
+ object-fit: cover;
7651
+ }
7652
+
7653
+ .ow-prompt-input__file {
7654
+ display: grid;
7655
+ min-width: 0;
7656
+ gap: 2px;
7657
+ padding-right: var(--ow-space-2xs);
7658
+ }
7659
+
7660
+ .ow-prompt-input__file-name {
7661
+ display: flex;
7662
+ min-width: 0;
7663
+ color: var(--ow-text);
7664
+ font-size: 13px;
7665
+ font-weight: var(--ow-weight-control);
7666
+ line-height: 16px;
7667
+ white-space: nowrap;
7668
+ }
7669
+
7670
+ .ow-prompt-input__file-base {
7671
+ min-width: 0;
7672
+ overflow: hidden;
7673
+ text-overflow: ellipsis;
7674
+ }
7675
+
7676
+ .ow-prompt-input__file-size {
7677
+ color: var(--ow-text-muted);
7678
+ font-size: 12px;
7679
+ line-height: 16px;
7680
+ font-variant-numeric: tabular-nums;
7681
+ white-space: nowrap;
7682
+ }
7683
+
7684
+ .ow-prompt-input__remove {
7685
+ display: inline-flex;
7686
+ width: 24px;
7687
+ height: 24px;
7688
+ flex: none;
7689
+ align-self: flex-start;
7690
+ align-items: center;
7691
+ justify-content: center;
7692
+ margin: 0;
7693
+ border: 0;
7694
+ border-radius: var(--ow-radius-md);
7695
+ background: transparent;
7696
+ padding: 0;
7697
+ color: var(--ow-text-muted);
7698
+ cursor: pointer;
7699
+ transition-property: color, background-color;
7700
+ transition-duration: var(--ow-duration-fast);
7701
+ transition-timing-function: var(--ow-ease-standard);
7702
+ }
7703
+
7704
+ .ow-prompt-input__remove:hover:not(:disabled) {
7705
+ background: color-mix(in srgb, var(--ow-text) 8%, transparent);
7706
+ color: var(--ow-text);
7707
+ }
7708
+
7709
+ .ow-prompt-input__remove:focus-visible {
7710
+ outline: 2px solid var(--ow-focus-ring);
7711
+ outline-offset: 0;
7712
+ }
7713
+
7714
+ .ow-prompt-input__remove:disabled {
7715
+ cursor: not-allowed;
7716
+ }
7717
+
7718
+ .ow-prompt-input--sm .ow-prompt-input__thumb {
7719
+ width: 28px;
7720
+ height: 28px;
7721
+ }
7722
+
7723
+ .ow-prompt-input--sm .ow-prompt-input__file-name {
7724
+ font-size: 12px;
7725
+ }
7726
+
7727
+ .ow-prompt-input--sm .ow-prompt-input__file-size {
7728
+ font-size: 11px;
7729
+ line-height: 14px;
7730
+ }
7731
+
7732
+ .ow-prompt-input--sm .ow-prompt-input__remove {
7733
+ width: 20px;
7734
+ height: 20px;
7735
+ }
7736
+
7737
+ /* The toolbar: the paperclip and start actions on the left; the count, end actions and send on the right. When the start
7738
+ actions wrap in a narrow box, send stays on the last row, under the end of the text. */
7739
+ .ow-prompt-input__toolbar {
7740
+ display: flex;
7741
+ min-width: 0;
7742
+ align-items: flex-end;
7743
+ gap: var(--ow-space-sm);
7744
+ cursor: default;
7745
+ }
7746
+
7747
+ .ow-prompt-input__start,
7748
+ .ow-prompt-input__end {
7749
+ display: flex;
7750
+ min-width: 0;
7751
+ align-items: center;
7752
+ gap: var(--ow-space-2xs);
7753
+ }
7754
+
7755
+ .ow-prompt-input__start {
7756
+ flex: 1;
7757
+ flex-wrap: wrap;
7758
+ }
7759
+
7760
+ .ow-prompt-input__end {
7761
+ flex: none;
7762
+ margin-left: auto;
7763
+ gap: var(--ow-space-sm);
7764
+ }
7765
+
7766
+ .ow-prompt-input__counter {
7767
+ padding: 0 var(--ow-space-2xs);
7768
+ color: var(--ow-text-muted);
7769
+ font-size: 12px;
7770
+ font-variant-numeric: tabular-nums;
7771
+ white-space: nowrap;
7772
+ }
7773
+
7774
+ .ow-prompt-input__counter--full {
7775
+ color: var(--ow-warning-text);
7776
+ font-weight: var(--ow-weight-emphasis);
7777
+ }
7778
+
7779
+ /* The send and Stop button keeps its square while the icon inside changes. */
7780
+ .ow-prompt-input__action.ow-button {
7781
+ flex: none;
7782
+ }
7783
+
7784
+ /* While files are dragged over it, the box turns primary and says what a drop does. */
7785
+ .ow-prompt-input__drop {
7786
+ position: absolute;
7787
+ z-index: 1;
7788
+ inset: -1px;
7789
+ display: flex;
7790
+ align-items: center;
7791
+ justify-content: center;
7792
+ gap: var(--ow-space-sm);
7793
+ border: 1.5px dashed var(--ow-primary-text);
7794
+ border-radius: inherit;
7795
+ /* The tint over the surface, since primary-subtle is see-through in dark. */
7796
+ background-color: var(--ow-surface);
7797
+ background-image: linear-gradient(var(--ow-primary-subtle), var(--ow-primary-subtle));
7798
+ color: var(--ow-primary-text);
7799
+ font-size: 14px;
7800
+ font-weight: var(--ow-weight-emphasis);
7801
+ pointer-events: none;
7802
+ animation: ow-prompt-input-drop-in var(--ow-duration-fast) var(--ow-ease-standard);
7803
+ }
7804
+
7805
+ @keyframes ow-prompt-input-drop-in {
7806
+ from {
7807
+ opacity: 0;
7808
+ }
7809
+ }
7810
+
7811
+ /* The line under the box: a hint, or a message about a file that couldn't be attached. */
7812
+ .ow-prompt-input__hint {
7813
+ padding: 0 var(--ow-space-md);
7814
+ color: var(--ow-text-muted);
7815
+ font-size: 12px;
7816
+ line-height: 18px;
7817
+ text-wrap: pretty;
7818
+ }
7819
+
7820
+ .ow-prompt-input--sm .ow-prompt-input__hint {
7821
+ padding: 0 var(--ow-space-sm);
7822
+ }
7823
+
7824
+ .ow-prompt-input__hint--notice {
7825
+ color: var(--ow-danger-text);
7826
+ }
7827
+
7828
+ @media (prefers-reduced-motion: reduce) {
7829
+ .ow-prompt-input__box,
7830
+ .ow-prompt-input__remove {
7831
+ transition: none;
7832
+ }
7833
+
7834
+ .ow-prompt-input__drop {
7835
+ animation: none;
7836
+ }
7837
+ }
7838
+
7839
+ /* components/PromptInput/PromptSuggestion.css */
7840
+ /* PromptSuggestion: a secondary pill at regular weight, or a card with a muted second line. */
7841
+ .ow-prompt-suggestion--pill.ow-button {
7842
+ max-width: 100%;
7843
+ gap: var(--ow-space-sm);
7844
+ font-weight: var(--ow-weight-regular);
7845
+ }
7846
+
7847
+ .ow-prompt-suggestion__label {
7848
+ min-width: 0;
7849
+ overflow: hidden;
7850
+ text-overflow: ellipsis;
7851
+ }
7852
+
7853
+ .ow-prompt-suggestion__icon {
7854
+ display: inline-flex;
7855
+ flex: none;
7856
+ color: var(--ow-icon);
7857
+ transition: color var(--ow-duration-base) var(--ow-ease-standard);
7858
+ }
7859
+
7860
+ .ow-prompt-suggestion:hover:not(:disabled) .ow-prompt-suggestion__icon {
7861
+ color: var(--ow-primary-text);
7862
+ }
7863
+
7864
+ .ow-prompt-suggestion:disabled .ow-prompt-suggestion__icon {
7865
+ color: var(--ow-text-disabled);
7866
+ }
7867
+
7868
+ /* Card: the secondary button's material, left-aligned, with the icon beside the title. */
7869
+ .ow-prompt-suggestion--card {
7870
+ display: flex;
7871
+ width: 100%;
7872
+ min-width: 0;
7873
+ align-items: flex-start;
7874
+ gap: var(--ow-space-md);
7875
+ margin: 0;
7876
+ border: 1px solid var(--ow-border-strong);
7877
+ border-radius: var(--ow-radius-container);
7878
+ background-color: var(--ow-control);
7879
+ background-image: linear-gradient(to bottom, var(--ow-control), var(--ow-control-shade));
7880
+ padding: var(--ow-space-lg) var(--ow-space-xl);
7881
+ color: var(--ow-text);
7882
+ font: inherit;
7883
+ text-align: left;
7884
+ cursor: pointer;
7885
+ box-shadow: var(--ow-shadow-button-secondary);
7886
+ transition-property: transform, border-color, background-color, box-shadow;
7887
+ transition-duration: var(--ow-duration-base);
7888
+ transition-timing-function: var(--ow-ease-standard);
7889
+ }
7890
+
7891
+ .ow-prompt-suggestion--card:hover:not(:disabled) {
7892
+ border-color: var(--ow-border-hover);
7893
+ background-image: linear-gradient(to bottom, var(--ow-control), var(--ow-control-shade-hover));
7894
+ }
7895
+
7896
+ .ow-prompt-suggestion--card:active:not(:disabled) {
7897
+ box-shadow: var(--ow-shadow-pressed-secondary);
7898
+ transform: translateY(1px);
7899
+ }
7900
+
7901
+ .ow-prompt-suggestion--card:focus-visible {
7902
+ outline: 2px solid var(--ow-focus-ring);
7903
+ outline-offset: 2px;
7904
+ }
7905
+
7906
+ .ow-prompt-suggestion--card:disabled {
7907
+ border-style: dashed;
7908
+ background: transparent;
7909
+ box-shadow: none;
7910
+ color: var(--ow-text-disabled);
7911
+ cursor: not-allowed;
7912
+ }
7913
+
7914
+ /* The icon sits on the title's first line (20px). */
7915
+ .ow-prompt-suggestion--card .ow-prompt-suggestion__icon {
7916
+ height: 20px;
7917
+ align-items: center;
7918
+ }
7919
+
7920
+ .ow-prompt-suggestion__text {
7921
+ display: grid;
7922
+ min-width: 0;
7923
+ gap: 2px;
7924
+ }
7925
+
7926
+ .ow-prompt-suggestion__title {
7927
+ font-size: 14px;
7928
+ font-weight: var(--ow-weight-emphasis);
7929
+ line-height: 20px;
7930
+ text-wrap: pretty;
7931
+ }
7932
+
7933
+ .ow-prompt-suggestion__description {
7934
+ color: var(--ow-text-muted);
7935
+ font-size: 13px;
7936
+ line-height: 18px;
7937
+ text-wrap: pretty;
7938
+ }
7939
+
7940
+ .ow-prompt-suggestion--card:disabled .ow-prompt-suggestion__description {
7941
+ color: var(--ow-text-disabled);
7942
+ }
7943
+
7944
+ /* PromptSuggestions: pills that wrap, or cards in columns of at least 200px, up to --ow-suggestion-columns. */
7945
+ .ow-prompt-suggestions--wrap {
7946
+ display: flex;
7947
+ min-width: 0;
7948
+ flex-wrap: wrap;
7949
+ gap: var(--ow-space-sm);
7950
+ }
7951
+
7952
+ .ow-prompt-suggestions--center {
7953
+ justify-content: center;
7954
+ }
7955
+
7956
+ .ow-prompt-suggestions--grid {
7957
+ display: grid;
7958
+ min-width: 0;
7959
+ grid-template-columns: repeat(
7960
+ auto-fill,
7961
+ minmax(min(100%, max(200px, calc((100% - (var(--ow-suggestion-columns, 2) - 1) * var(--ow-space-md)) / var(--ow-suggestion-columns, 2)))), 1fr)
7962
+ );
7963
+ gap: var(--ow-space-md);
7964
+ }
7965
+
7966
+ @media (prefers-reduced-motion: reduce) {
7967
+ .ow-prompt-suggestion--card,
7968
+ .ow-prompt-suggestion__icon {
7969
+ transition: none;
7970
+ }
7971
+
7972
+ .ow-prompt-suggestion--card:active:not(:disabled) {
7973
+ transform: none;
7974
+ }
7975
+ }
7976
+
7977
+ /* components/Chat/Chat.css */
7978
+ /* Chat: the conversation's scrolling column, its messages and the loader. */
7979
+
7980
+ /* ChatConversation: fills its parent and scrolls; the messages sit in a reading column in the middle, with the footer
7981
+ (a prompt box) docked under them in the same column. */
7982
+ .ow-chat-conversation {
7983
+ --ow-chat-gutter: var(--ow-space-4xl);
7984
+ --ow-chat-column: 720px;
7985
+ display: flex;
7986
+ height: 100%;
7987
+ min-width: 0;
7988
+ min-height: 0;
7989
+ flex: 1 1 auto;
7990
+ flex-direction: column;
7991
+ }
7992
+
7993
+ /* The scrolling part, which the empty state and Jump to latest sit over. */
7994
+ .ow-chat-conversation__viewport {
7995
+ position: relative;
7996
+ display: flex;
7997
+ min-height: 0;
7998
+ flex: 1;
7999
+ flex-direction: column;
8000
+ }
8001
+
8002
+ .ow-chat-conversation__scroll {
8003
+ min-height: 0;
8004
+ flex: 1;
8005
+ overflow-y: auto;
8006
+ overscroll-behavior: contain;
8007
+ outline: 0;
8008
+ }
8009
+
8010
+ .ow-chat-conversation__scroll:focus-visible {
8011
+ outline: 2px solid var(--ow-focus-ring);
8012
+ outline-offset: -2px;
8013
+ }
8014
+
8015
+ .ow-chat-conversation__content {
8016
+ display: flex;
8017
+ max-width: calc(var(--ow-chat-column) + 2 * var(--ow-chat-gutter));
8018
+ flex-direction: column;
8019
+ gap: var(--ow-space-6xl);
8020
+ margin: 0 auto;
8021
+ padding: var(--ow-space-6xl) var(--ow-chat-gutter) var(--ow-space-7xl);
8022
+ }
8023
+
8024
+ /* What shows while there are no messages, over the (empty) log so the log is there for the first one. */
8025
+ .ow-chat-conversation__empty {
8026
+ position: absolute;
8027
+ inset: 0;
8028
+ display: grid;
8029
+ overflow-y: auto;
8030
+ place-items: center;
8031
+ padding: var(--ow-space-6xl) var(--ow-chat-gutter);
8032
+ }
8033
+
8034
+ .ow-chat-conversation__empty-inner {
8035
+ width: 100%;
8036
+ max-width: var(--ow-chat-column);
8037
+ }
8038
+
8039
+ /* The footer: lined up with the messages, with the gutter below it. */
8040
+ .ow-chat-conversation__footer {
8041
+ flex-shrink: 0;
8042
+ padding: 0 var(--ow-chat-gutter) var(--ow-chat-gutter);
8043
+ }
8044
+
8045
+ .ow-chat-conversation__footer-inner {
8046
+ max-width: var(--ow-chat-column);
8047
+ margin: 0 auto;
8048
+ }
8049
+
8050
+ .ow-chat-conversation--full {
8051
+ --ow-chat-column: none;
8052
+ }
8053
+
8054
+ .ow-chat-conversation--full .ow-chat-conversation__content {
8055
+ max-width: none;
8056
+ }
8057
+
8058
+ /* "Jump to latest": floats at the bottom in the middle once the reader scrolls up. */
8059
+ .ow-chat-conversation__jump {
8060
+ position: absolute;
8061
+ right: 0;
8062
+ bottom: var(--ow-space-2xl);
8063
+ left: 0;
8064
+ z-index: 2;
8065
+ display: flex;
8066
+ justify-content: center;
8067
+ pointer-events: none;
8068
+ animation: ow-chat-rise var(--ow-duration-base) var(--ow-ease-emphasized);
8069
+ }
8070
+
8071
+ .ow-chat-conversation__jump[data-state="closed"] {
8072
+ animation: ow-chat-sink var(--ow-duration-exit) var(--ow-ease-exit) forwards;
8073
+ }
8074
+
8075
+ .ow-chat-conversation__jump > .ow-button {
8076
+ pointer-events: auto;
8077
+ box-shadow: var(--ow-shadow-button-secondary), var(--ow-shadow-menu);
8078
+ }
8079
+
8080
+ .ow-chat-conversation__count {
8081
+ display: inline-flex;
8082
+ height: 20px;
8083
+ align-items: center;
8084
+ margin-right: calc(-1 * var(--ow-space-xs));
8085
+ border: 1px solid var(--ow-primary-border);
8086
+ border-radius: var(--ow-radius-pill);
8087
+ background: var(--ow-primary-subtle);
8088
+ padding: 0 var(--ow-space-xs);
8089
+ color: var(--ow-primary-text);
8090
+ font-size: 12px;
8091
+ font-weight: var(--ow-weight-strong);
8092
+ font-variant-numeric: tabular-nums;
8093
+ }
8094
+
8095
+ /* ChatMessage. */
8096
+ .ow-chat-message {
8097
+ min-width: 0;
8098
+ color: var(--ow-text);
8099
+ font-family: var(--ow-font-sans);
8100
+ font-size: 14px;
8101
+ line-height: 1.55;
8102
+ }
8103
+
8104
+ .ow-chat-message--user,
8105
+ .ow-chat-message--assistant {
8106
+ display: flex;
8107
+ align-items: flex-start;
8108
+ gap: var(--ow-space-lg);
8109
+ }
8110
+
8111
+ /* The person's message sits on the right: its avatar, when there is one, on the far side. */
8112
+ .ow-chat-message--user {
8113
+ flex-direction: row-reverse;
8114
+ }
8115
+
8116
+ .ow-chat-message__avatar {
8117
+ display: flex;
8118
+ flex-shrink: 0;
8119
+ }
8120
+
8121
+ /* ChatAgentAvatar: the bot on a tinted circle, at Avatar's sizes. */
8122
+ .ow-chat-avatar {
8123
+ display: inline-flex;
8124
+ width: 28px;
8125
+ height: 28px;
8126
+ flex-shrink: 0;
8127
+ align-items: center;
8128
+ justify-content: center;
8129
+ border: 1px solid var(--ow-primary-border);
8130
+ border-radius: 50%;
8131
+ background: var(--ow-primary-subtle);
8132
+ color: var(--ow-primary-text);
8133
+ }
8134
+
8135
+ .ow-chat-avatar--sm {
8136
+ width: 24px;
8137
+ height: 24px;
8138
+ }
8139
+
8140
+ .ow-chat-avatar--lg {
8141
+ width: 36px;
8142
+ height: 36px;
8143
+ }
8144
+
8145
+ .ow-chat-message__main {
8146
+ display: grid;
8147
+ min-width: 0;
8148
+ flex: 1;
8149
+ align-content: start;
8150
+ gap: var(--ow-space-xs);
8151
+ }
8152
+
8153
+ /* Beside a 28px avatar, the header (or the first line) sits level with its middle. */
8154
+ .ow-chat-message__avatar + .ow-chat-message__main {
8155
+ padding-top: var(--ow-space-2xs);
8156
+ }
8157
+
8158
+ .ow-chat-message--user .ow-chat-message__main {
8159
+ max-width: 80%;
8160
+ flex: 0 1 auto;
8161
+ justify-items: end;
8162
+ }
8163
+
8164
+ .ow-chat-message__header {
8165
+ display: flex;
8166
+ min-width: 0;
8167
+ align-items: baseline;
8168
+ gap: var(--ow-space-sm);
8169
+ line-height: 1.4;
8170
+ }
8171
+
8172
+ .ow-chat-message__name {
8173
+ min-width: 0;
8174
+ overflow: hidden;
8175
+ font-weight: var(--ow-weight-emphasis);
8176
+ text-overflow: ellipsis;
8177
+ white-space: nowrap;
8178
+ }
8179
+
8180
+ .ow-chat-message__time {
8181
+ flex-shrink: 0;
8182
+ color: var(--ow-text-muted);
8183
+ font-size: 12px;
8184
+ font-variant-numeric: tabular-nums;
8185
+ }
8186
+
8187
+ /* The body holds the content and, while it streams, the caret placed after its last character. */
8188
+ .ow-chat-message__body {
8189
+ position: relative;
8190
+ min-width: 0;
8191
+ }
8192
+
8193
+ .ow-chat-message--streaming .ow-chat-message__body {
8194
+ min-height: 1.55em;
8195
+ }
8196
+
8197
+ .ow-chat-message__content {
8198
+ min-width: 0;
8199
+ overflow-wrap: break-word;
8200
+ }
8201
+
8202
+ /* Blocks in a message (paragraphs, code, a card) sit 12px apart; text, Code and Kbd flow inline as written. */
8203
+ .ow-chat-message__content > :is(p, div, pre, ul, ol, dl, blockquote, table, figure, details, section, h1, h2, h3, h4, h5, h6, hr, a):not(:first-child) {
8204
+ margin-top: var(--ow-space-lg);
8205
+ }
8206
+
8207
+ /* The person's own words in a bubble, kept as typed: line breaks stay, and a long link breaks rather than overflowing. */
8208
+ .ow-chat-message--user .ow-chat-message__content {
8209
+ border: 1px solid var(--ow-border);
8210
+ border-radius: var(--ow-radius-panel) var(--ow-radius-sm) var(--ow-radius-panel) var(--ow-radius-panel);
8211
+ background: var(--ow-surface-muted);
8212
+ padding: var(--ow-space-md) var(--ow-space-xl);
8213
+ white-space: pre-wrap;
8214
+ overflow-wrap: anywhere;
8215
+ }
8216
+
8217
+ .ow-chat-message__caret {
8218
+ position: absolute;
8219
+ top: 0;
8220
+ left: 0;
8221
+ width: 2px;
8222
+ height: 1.2em;
8223
+ border-radius: 1px;
8224
+ background: currentColor;
8225
+ pointer-events: none;
8226
+ transform: translateY(0.18em);
8227
+ animation: ow-chat-caret 1s var(--ow-ease-standard) infinite;
8228
+ }
8229
+
8230
+ /* A system line: muted, in the middle, between hairlines. */
8231
+ .ow-chat-message--system {
8232
+ display: flex;
8233
+ align-items: center;
8234
+ gap: var(--ow-space-lg);
8235
+ color: var(--ow-text-muted);
8236
+ font-size: 12px;
8237
+ line-height: 1.35;
8238
+ text-align: center;
8239
+ }
8240
+
8241
+ .ow-chat-message--system::before,
8242
+ .ow-chat-message--system::after {
8243
+ content: "";
8244
+ height: 1px;
8245
+ min-width: var(--ow-space-2xl);
8246
+ flex: 1;
8247
+ background: var(--ow-border);
8248
+ }
8249
+
8250
+ .ow-chat-message__system-text {
8251
+ max-width: 80%;
8252
+ text-wrap: balance;
8253
+ }
8254
+
8255
+ /* What went wrong, with Retry beside it. */
8256
+ .ow-chat-message__error {
8257
+ display: flex;
8258
+ max-width: 100%;
8259
+ align-items: center;
8260
+ justify-self: start;
8261
+ gap: var(--ow-space-sm);
8262
+ border: 1px solid var(--ow-danger-border);
8263
+ border-radius: var(--ow-radius-form);
8264
+ background: var(--ow-danger-surface);
8265
+ padding: var(--ow-space-xs) var(--ow-space-lg);
8266
+ color: var(--ow-danger-text);
8267
+ line-height: 1.4;
8268
+ }
8269
+
8270
+ .ow-chat-message__error--retry {
8271
+ padding: var(--ow-space-2xs) var(--ow-space-2xs) var(--ow-space-2xs) var(--ow-space-lg);
8272
+ }
8273
+
8274
+ .ow-chat-message--user .ow-chat-message__error {
8275
+ justify-self: end;
8276
+ }
8277
+
8278
+ .ow-chat-message__error-icon {
8279
+ flex-shrink: 0;
8280
+ color: var(--ow-danger-solid);
8281
+ }
8282
+
8283
+ .ow-chat-message__error-text {
8284
+ min-width: 0;
8285
+ flex: 1;
8286
+ }
8287
+
8288
+ .ow-chat-message__error > .ow-button {
8289
+ margin-left: var(--ow-space-xs);
8290
+ }
8291
+
8292
+ /* Actions: under the message, the first icon level with the text's edge. Hidden (but reachable) until the message
8293
+ is hovered or holds focus; always shown where there's no hover. The buttons' padding hangs into the space around
8294
+ them, so the row adds its icons' height to the message rather than a whole 32px button. */
8295
+ .ow-chat-message__actions {
8296
+ justify-self: start;
8297
+ margin: calc(-1 * var(--ow-space-2xs)) 0 calc(-1 * var(--ow-space-lg)) calc(-1 * var(--ow-space-sm));
8298
+ opacity: 0;
8299
+ transition: opacity var(--ow-duration-fast) var(--ow-ease-standard);
8300
+ }
8301
+
8302
+ .ow-chat-message--user .ow-chat-message__actions {
8303
+ justify-self: end;
8304
+ margin-right: calc(-1 * var(--ow-space-sm));
8305
+ margin-left: 0;
8306
+ }
8307
+
8308
+ .ow-chat-message:hover .ow-chat-message__actions,
8309
+ .ow-chat-message:focus-within .ow-chat-message__actions,
8310
+ .ow-chat-message--actions-always .ow-chat-message__actions {
8311
+ opacity: 1;
8312
+ }
8313
+
8314
+ @media (hover: none) {
8315
+ .ow-chat-message__actions {
8316
+ opacity: 1;
8317
+ }
8318
+ }
8319
+
8320
+ /* ChatMessageActions. */
8321
+ .ow-chat-actions__copy-icon {
8322
+ display: inline-grid;
8323
+ }
8324
+
8325
+ .ow-chat-actions__copy-icon > svg {
8326
+ grid-area: 1 / 1;
8327
+ transition:
8328
+ opacity var(--ow-duration-base) var(--ow-ease-standard),
8329
+ transform var(--ow-duration-slow) var(--ow-ease-spring);
8330
+ }
8331
+
8332
+ .ow-chat-actions__copy-icon > svg:last-child,
8333
+ .ow-chat-actions__copy--copied .ow-chat-actions__copy-icon > svg:first-child {
8334
+ opacity: 0;
8335
+ transform: scale(0.5);
8336
+ }
8337
+
8338
+ .ow-chat-actions__copy--copied .ow-chat-actions__copy-icon > svg:last-child {
8339
+ color: var(--ow-success-text);
8340
+ opacity: 1;
8341
+ transform: none;
8342
+ }
8343
+
8344
+ /* A pressed rating fills its thumb lightly, as well as taking the pressed tint. */
8345
+ .ow-chat-actions__rate[aria-pressed="true"] svg {
8346
+ fill: currentColor;
8347
+ fill-opacity: 0.22;
8348
+ }
8349
+
8350
+ /* ChatLoader. */
8351
+ .ow-chat-loader__line {
8352
+ display: flex;
8353
+ min-height: 1.55em;
8354
+ align-items: center;
8355
+ }
8356
+
8357
+ .ow-chat-loader--inline {
8358
+ display: inline-flex;
8359
+ align-items: center;
8360
+ vertical-align: middle;
8361
+ }
8362
+
8363
+ .ow-chat-loader__dots {
8364
+ display: inline-flex;
8365
+ align-items: center;
8366
+ gap: var(--ow-space-2xs);
8367
+ }
8368
+
8369
+ .ow-chat-loader__dot {
8370
+ width: 6px;
8371
+ height: 6px;
8372
+ border-radius: 50%;
8373
+ background: var(--ow-text-muted);
8374
+ opacity: 0.35;
8375
+ animation: ow-chat-dot 1.2s var(--ow-ease-standard) infinite;
8376
+ }
8377
+
8378
+ .ow-chat-loader__dot:nth-child(2) {
8379
+ animation-delay: 160ms;
8380
+ }
8381
+
8382
+ .ow-chat-loader__dot:nth-child(3) {
8383
+ animation-delay: 320ms;
8384
+ }
8385
+
8386
+ /* Arrivals: once a conversation is showing, a person's message and a system line rise in; the agent's answer fades in
8387
+ beside an avatar that stays put, so a loader turning into the answer doesn't blink. */
8388
+ .ow-chat-message--enter.ow-chat-message--user,
8389
+ .ow-chat-message--enter.ow-chat-message--system,
8390
+ .ow-chat-loader--enter {
8391
+ animation: ow-chat-rise var(--ow-duration-slow) var(--ow-ease-emphasized);
8392
+ }
8393
+
8394
+ .ow-chat-message--enter.ow-chat-message--assistant > .ow-chat-message__main {
8395
+ animation: ow-chat-fade var(--ow-duration-slow) var(--ow-ease-emphasized);
8396
+ }
8397
+
8398
+ @keyframes ow-chat-rise {
8399
+ from {
8400
+ opacity: 0;
8401
+ transform: translateY(6px);
8402
+ }
8403
+ }
8404
+
8405
+ @keyframes ow-chat-sink {
8406
+ to {
8407
+ opacity: 0;
8408
+ transform: translateY(6px);
8409
+ }
8410
+ }
8411
+
8412
+ @keyframes ow-chat-fade {
8413
+ from {
8414
+ opacity: 0;
8415
+ }
8416
+ }
8417
+
8418
+ @keyframes ow-chat-caret {
8419
+ 0%,
8420
+ 100% {
8421
+ opacity: 0.9;
8422
+ }
8423
+ 50% {
8424
+ opacity: 0.15;
8425
+ }
8426
+ }
8427
+
8428
+ @keyframes ow-chat-dot {
8429
+ 0%,
8430
+ 60%,
8431
+ 100% {
8432
+ opacity: 0.35;
8433
+ transform: scale(0.8);
8434
+ }
8435
+ 30% {
8436
+ opacity: 1;
8437
+ transform: none;
8438
+ }
8439
+ }
8440
+
8441
+ @media (max-width: 760px) {
8442
+ .ow-chat-conversation {
8443
+ --ow-chat-gutter: var(--ow-space-2xl);
8444
+ }
8445
+ .ow-chat-conversation__content {
8446
+ gap: var(--ow-space-5xl);
8447
+ }
8448
+ .ow-chat-message--user,
8449
+ .ow-chat-message--assistant {
8450
+ gap: var(--ow-space-md);
8451
+ }
8452
+ .ow-chat-message--user .ow-chat-message__main {
8453
+ max-width: 88%;
8454
+ }
8455
+ }
8456
+
8457
+ @media (prefers-reduced-motion: reduce) {
8458
+ .ow-chat-conversation__jump,
8459
+ .ow-chat-message--enter.ow-chat-message--user,
8460
+ .ow-chat-message--enter.ow-chat-message--system,
8461
+ .ow-chat-message--enter.ow-chat-message--assistant > .ow-chat-message__main,
8462
+ .ow-chat-loader--enter,
8463
+ .ow-chat-message__caret {
8464
+ animation: none;
8465
+ }
8466
+ .ow-chat-loader__dot {
8467
+ opacity: 0.6;
8468
+ animation: none;
8469
+ }
8470
+ .ow-chat-message__actions,
8471
+ .ow-chat-actions__copy-icon > svg {
8472
+ transition: none;
8473
+ }
8474
+ }
8475
+
8476
+ /* Forced colours drop backgrounds: draw the caret and the dots in the text colour. */
8477
+ @media (forced-colors: active) {
8478
+ .ow-chat-message__caret,
8479
+ .ow-chat-loader__dot {
8480
+ forced-color-adjust: none;
8481
+ background: CanvasText;
8482
+ }
8483
+ }
8484
+
8485
+ /* components/ChatTool/ChatTool.css */
8486
+ /* ChatTool: one tool call on a row that opens to its input and output. Also the pieces ChainOfThought and ChatSources
8487
+ share: the status mark, the plain disclosure toggle and the collapsing panel. */
8488
+
8489
+ /* The status mark: a 20px circle, tinted by status. */
8490
+ .ow-chat-status {
8491
+ position: relative;
8492
+ display: inline-flex;
8493
+ width: 20px;
8494
+ height: 20px;
8495
+ flex-shrink: 0;
8496
+ align-items: center;
8497
+ justify-content: center;
8498
+ border-radius: 50%;
8499
+ color: var(--ow-text-muted);
8500
+ }
8501
+
8502
+ .ow-chat-status__glyph {
8503
+ display: inline-flex;
8504
+ }
8505
+
8506
+ .ow-chat-status--success {
8507
+ background: var(--ow-success-surface);
8508
+ color: var(--ow-success-text);
8509
+ box-shadow: inset 0 0 0 1px var(--ow-success-border);
8510
+ }
8511
+
8512
+ .ow-chat-status--error {
8513
+ background: var(--ow-danger-surface);
8514
+ color: var(--ow-danger-text);
8515
+ box-shadow: inset 0 0 0 1px var(--ow-danger-border);
8516
+ }
8517
+
8518
+ .ow-chat-status--approval {
8519
+ background: var(--ow-warning-surface);
8520
+ color: var(--ow-warning-text);
8521
+ box-shadow: inset 0 0 0 1px var(--ow-warning-border);
8522
+ }
8523
+
8524
+ /* Not started: a hollow ring. Called off: the ring with a slash across it. */
8525
+ .ow-chat-status--pending,
8526
+ .ow-chat-status--cancelled {
8527
+ box-shadow: inset 0 0 0 1.5px var(--ow-border-strong);
8528
+ }
8529
+
8530
+ /* A step's own icon, at the size of the check it stands in for. */
8531
+ .ow-chat-status--icon .ow-chat-status__glyph > svg {
8532
+ width: 12px;
8533
+ height: 12px;
8534
+ }
8535
+
8536
+ /* The mark settles in when a status lands. */
8537
+ .ow-chat-status--success .ow-chat-status__glyph,
8538
+ .ow-chat-status--error .ow-chat-status__glyph,
8539
+ .ow-chat-status--approval .ow-chat-status__glyph,
8540
+ .ow-chat-status--cancelled .ow-chat-status__glyph {
8541
+ animation: ow-chat-status-in var(--ow-duration-slow) var(--ow-ease-spring);
8542
+ }
8543
+
8544
+ @keyframes ow-chat-status-in {
8545
+ from {
8546
+ opacity: 0;
8547
+ transform: scale(0.5);
8548
+ }
8549
+ }
8550
+
8551
+ /* A plain disclosure toggle ("Thought for 12 s", "3 sources"): a chevron in a 20px column, so whatever opens below
8552
+ lines up with the label. */
8553
+ .ow-chat-toggle {
8554
+ display: inline-flex;
8555
+ max-width: 100%;
8556
+ min-height: 28px;
8557
+ align-items: center;
8558
+ gap: var(--ow-space-md);
8559
+ margin: 0;
8560
+ border: 0;
8561
+ border-radius: var(--ow-radius-md);
8562
+ background: transparent;
8563
+ padding: var(--ow-space-2xs) var(--ow-space-xs) var(--ow-space-2xs) 0;
8564
+ color: var(--ow-text-soft);
8565
+ font: inherit;
8566
+ font-family: var(--ow-font-sans);
8567
+ font-size: 14px;
8568
+ font-weight: var(--ow-weight-control);
8569
+ line-height: 20px;
8570
+ text-align: left;
8571
+ cursor: pointer;
8572
+ transition: color var(--ow-duration-base) var(--ow-ease-standard);
8573
+ }
8574
+
8575
+ .ow-chat-toggle:hover {
8576
+ color: var(--ow-text);
8577
+ }
8578
+
8579
+ .ow-chat-toggle:focus-visible {
8580
+ outline: 2px solid var(--ow-focus-ring);
8581
+ outline-offset: 2px;
8582
+ }
8583
+
8584
+ .ow-chat-toggle__chevron {
8585
+ display: inline-flex;
8586
+ width: 20px;
8587
+ flex-shrink: 0;
8588
+ justify-content: center;
8589
+ color: var(--ow-icon);
8590
+ transition:
8591
+ transform var(--ow-duration-slow) var(--ow-ease-emphasized),
8592
+ color var(--ow-duration-base) var(--ow-ease-standard);
8593
+ }
8594
+
8595
+ .ow-chat-toggle:hover .ow-chat-toggle__chevron {
8596
+ color: var(--ow-text-muted);
8597
+ }
8598
+
8599
+ .ow-chat-toggle[aria-expanded="true"] .ow-chat-toggle__chevron {
8600
+ transform: rotate(90deg);
8601
+ }
8602
+
8603
+ .ow-chat-toggle__text {
8604
+ display: flex;
8605
+ min-width: 0;
8606
+ flex-wrap: wrap;
8607
+ align-items: baseline;
8608
+ column-gap: var(--ow-space-xs);
8609
+ }
8610
+
8611
+ .ow-chat-toggle__meta {
8612
+ color: var(--ow-text-muted);
8613
+ font-weight: var(--ow-weight-regular);
8614
+ font-variant-numeric: tabular-nums;
8615
+ }
8616
+
8617
+ /* A panel that animates its height with a 0fr → 1fr grid row. Its content's height can change while it's open
8618
+ (streaming text) without animating. */
8619
+ .ow-chat-collapse {
8620
+ display: grid;
8621
+ min-width: 0;
8622
+ grid-template-rows: 0fr;
8623
+ visibility: hidden;
8624
+ transition:
8625
+ grid-template-rows var(--ow-duration-base) var(--ow-ease-standard),
8626
+ visibility 0s linear var(--ow-duration-base);
8627
+ }
8628
+
8629
+ .ow-chat-collapse[data-open="true"] {
8630
+ grid-template-rows: 1fr;
8631
+ visibility: visible;
8632
+ transition:
8633
+ grid-template-rows var(--ow-duration-panel) var(--ow-ease-emphasized),
8634
+ visibility 0s;
8635
+ }
8636
+
8637
+ .ow-chat-collapse__clip {
8638
+ min-width: 0;
8639
+ min-height: 0;
8640
+ overflow: hidden;
8641
+ }
8642
+
8643
+ .ow-chat-collapse__clip > * {
8644
+ opacity: 0;
8645
+ transition: opacity var(--ow-duration-fast) var(--ow-ease-standard);
8646
+ }
8647
+
8648
+ .ow-chat-collapse[data-open="true"] > .ow-chat-collapse__clip > * {
8649
+ opacity: 1;
8650
+ transition: opacity var(--ow-duration-slow) var(--ow-ease-standard) 60ms;
8651
+ }
8652
+
8653
+ /* Room past the edges for the focus rings of links and cards inside. */
8654
+ .ow-chat-collapse--bleed {
8655
+ margin-inline: calc(-1 * var(--ow-space-2xs));
8656
+ }
8657
+
8658
+ .ow-chat-collapse--bleed > .ow-chat-collapse__clip {
8659
+ padding-inline: var(--ow-space-2xs);
8660
+ }
8661
+
8662
+ /* The tool call: a bordered card whose header row is the disclosure button. */
8663
+ .ow-chat-tool {
8664
+ min-width: 0;
8665
+ overflow: hidden;
8666
+ border: 1px solid var(--ow-border);
8667
+ border-radius: var(--ow-radius-container);
8668
+ background: var(--ow-surface);
8669
+ color: var(--ow-text);
8670
+ font-family: var(--ow-font-sans);
8671
+ font-size: 14px;
8672
+ line-height: 1.45;
8673
+ transition: border-color var(--ow-duration-base) var(--ow-ease-standard);
8674
+ }
8675
+
8676
+ .ow-chat-tool:focus-visible {
8677
+ outline: 2px solid var(--ow-focus-ring);
8678
+ outline-offset: 2px;
8679
+ }
8680
+
8681
+ .ow-chat-tool[data-status="approval"] {
8682
+ border-color: var(--ow-warning-border);
8683
+ }
8684
+
8685
+ .ow-chat-tool[data-status="error"] {
8686
+ border-color: var(--ow-danger-border);
8687
+ }
8688
+
8689
+ .ow-chat-tool__header {
8690
+ display: flex;
8691
+ width: 100%;
8692
+ align-items: flex-start;
8693
+ gap: var(--ow-space-md);
8694
+ margin: 0;
8695
+ border: 0;
8696
+ background: transparent;
8697
+ padding: var(--ow-space-md) var(--ow-space-lg);
8698
+ color: inherit;
8699
+ font: inherit;
8700
+ text-align: left;
8701
+ }
8702
+
8703
+ .ow-chat-tool__header--button {
8704
+ cursor: pointer;
8705
+ transition: background-color var(--ow-duration-base) var(--ow-ease-standard);
8706
+ }
8707
+
8708
+ .ow-chat-tool__header--button:hover {
8709
+ background: var(--ow-surface-muted);
8710
+ }
8711
+
8712
+ .ow-chat-tool__header--button:focus-visible {
8713
+ border-radius: calc(var(--ow-radius-container) - 1px);
8714
+ outline: 2px solid var(--ow-focus-ring);
8715
+ outline-offset: -2px;
8716
+ }
8717
+
8718
+ .ow-chat-tool__icon {
8719
+ display: inline-flex;
8720
+ height: 20px;
8721
+ flex-shrink: 0;
8722
+ align-items: center;
8723
+ color: var(--ow-text-muted);
8724
+ }
8725
+
8726
+ .ow-chat-tool__icon > svg {
8727
+ width: 15px;
8728
+ height: 15px;
8729
+ }
8730
+
8731
+ /* The title and tool name, then the result; the result drops to a second line when there's no room beside them. */
8732
+ .ow-chat-tool__main {
8733
+ display: flex;
8734
+ min-width: 0;
8735
+ flex: 1;
8736
+ flex-wrap: wrap;
8737
+ align-items: baseline;
8738
+ gap: 0 var(--ow-space-lg);
8739
+ }
8740
+
8741
+ .ow-chat-tool__heading {
8742
+ display: flex;
8743
+ min-width: 0;
8744
+ flex: 1 1 auto;
8745
+ flex-wrap: wrap;
8746
+ align-items: baseline;
8747
+ gap: 0 var(--ow-space-sm);
8748
+ }
8749
+
8750
+ .ow-chat-tool__title {
8751
+ min-width: 0;
8752
+ font-weight: var(--ow-weight-emphasis);
8753
+ line-height: 20px;
8754
+ overflow-wrap: anywhere;
8755
+ }
8756
+
8757
+ .ow-chat-tool[data-status="pending"] .ow-chat-tool__title,
8758
+ .ow-chat-tool[data-status="cancelled"] .ow-chat-tool__title {
8759
+ color: var(--ow-text-muted);
8760
+ }
8761
+
8762
+ .ow-chat-tool__name.ow-code {
8763
+ font-size: 12px;
8764
+ line-height: 18px;
8765
+ }
8766
+
8767
+ .ow-chat-tool__meta {
8768
+ display: inline-flex;
8769
+ min-width: 0;
8770
+ flex-wrap: wrap;
8771
+ align-items: baseline;
8772
+ gap: 0 var(--ow-space-xs);
8773
+ color: var(--ow-text-muted);
8774
+ font-size: 12px;
8775
+ line-height: 20px;
8776
+ font-variant-numeric: tabular-nums;
8777
+ }
8778
+
8779
+ .ow-chat-tool[data-status="error"] .ow-chat-tool__summary {
8780
+ color: var(--ow-danger-text);
8781
+ }
8782
+
8783
+ .ow-chat-tool[data-status="approval"] .ow-chat-tool__summary {
8784
+ color: var(--ow-warning-text);
8785
+ }
8786
+
8787
+ .ow-chat-tool__duration {
8788
+ white-space: nowrap;
8789
+ }
8790
+
8791
+ .ow-chat-tool__chevron {
8792
+ display: inline-flex;
8793
+ height: 20px;
8794
+ flex-shrink: 0;
8795
+ align-items: center;
8796
+ color: var(--ow-icon);
8797
+ transition: transform var(--ow-duration-slow) var(--ow-ease-emphasized);
8798
+ }
8799
+
8800
+ .ow-chat-tool[data-open="true"] .ow-chat-tool__chevron {
8801
+ transform: rotate(90deg);
8802
+ }
8803
+
8804
+ /* Input, output and error, lined up with the title (12px padding + the 20px mark + a 10px gap). */
8805
+ .ow-chat-tool__details {
8806
+ display: grid;
8807
+ gap: var(--ow-space-lg);
8808
+ padding: var(--ow-space-2xs) var(--ow-space-lg) var(--ow-space-lg) 42px;
8809
+ }
8810
+
8811
+ .ow-chat-tool__section {
8812
+ display: grid;
8813
+ min-width: 0;
8814
+ gap: var(--ow-space-xs);
8815
+ }
8816
+
8817
+ .ow-chat-tool__label {
8818
+ color: var(--ow-text-muted);
8819
+ font-size: 12px;
8820
+ font-weight: var(--ow-weight-emphasis);
8821
+ line-height: 1.35;
8822
+ }
8823
+
8824
+ .ow-chat-tool__output {
8825
+ min-width: 0;
8826
+ color: var(--ow-text-soft);
8827
+ }
8828
+
8829
+ .ow-chat-tool__error {
8830
+ min-width: 0;
8831
+ border: 1px solid var(--ow-danger-border);
8832
+ border-radius: var(--ow-radius-form);
8833
+ background: var(--ow-danger-surface);
8834
+ padding: var(--ow-space-sm) var(--ow-space-lg);
8835
+ color: var(--ow-danger-text);
8836
+ font-family: var(--ow-font-mono);
8837
+ font-size: 12px;
8838
+ line-height: 1.6;
8839
+ white-space: pre-wrap;
8840
+ overflow-wrap: anywhere;
8841
+ }
8842
+
8843
+ /* Waiting for the person: what it wants to do, and Approve and Deny. */
8844
+ .ow-chat-tool__approval {
8845
+ display: flex;
8846
+ flex-wrap: wrap;
8847
+ align-items: center;
8848
+ gap: var(--ow-space-md) var(--ow-space-lg);
8849
+ border-top: 1px solid var(--ow-warning-border);
8850
+ background: var(--ow-warning-surface);
8851
+ padding: var(--ow-space-md) var(--ow-space-lg) var(--ow-space-md) 42px;
8852
+ animation: ow-fade-up var(--ow-duration-slow) var(--ow-ease-emphasized);
8853
+ }
8854
+
8855
+ .ow-chat-tool__request {
8856
+ min-width: 0;
8857
+ flex: 1 1 220px;
8858
+ margin: 0;
8859
+ color: var(--ow-text);
8860
+ font-size: 14px;
8861
+ font-weight: var(--ow-weight-control);
8862
+ line-height: 1.45;
8863
+ }
8864
+
8865
+ .ow-chat-tool__request .ow-code {
8866
+ font-size: 12px;
8867
+ }
8868
+
8869
+ .ow-chat-tool__actions {
8870
+ display: flex;
8871
+ flex-wrap: wrap;
8872
+ gap: var(--ow-space-sm);
8873
+ }
8874
+
8875
+ @media (max-width: 480px) {
8876
+ .ow-chat-tool__details,
8877
+ .ow-chat-tool__approval {
8878
+ padding-left: var(--ow-space-lg);
8879
+ }
8880
+ }
8881
+
8882
+ /* Forced colours drop the tints and inset rings, so the marks get a plain outline. */
8883
+ @media (forced-colors: active) {
8884
+ .ow-chat-status:not(.ow-chat-status--running) {
8885
+ border: 1px solid CanvasText;
8886
+ }
8887
+ }
8888
+
8889
+ @media (prefers-reduced-motion: reduce) {
8890
+ .ow-chat-status__glyph,
8891
+ .ow-chat-tool__approval {
8892
+ animation: none !important;
8893
+ }
8894
+ .ow-chat-collapse,
8895
+ .ow-chat-collapse[data-open="true"],
8896
+ .ow-chat-collapse__clip > *,
8897
+ .ow-chat-toggle__chevron,
8898
+ .ow-chat-tool__chevron {
8899
+ transition: none !important;
8900
+ }
8901
+ }
8902
+
8903
+ /* components/ChainOfThought/ChainOfThought.css */
8904
+ /* ChainOfThought: a "Thinking…" toggle over the agent's reasoning and its steps on a thin line. The toggle, the status
8905
+ marks and the collapsing panel come from ChatTool.css. */
8906
+ .ow-chain-of-thought {
8907
+ display: grid;
8908
+ min-width: 0;
8909
+ justify-items: start;
8910
+ color: var(--ow-text);
8911
+ font-family: var(--ow-font-sans);
8912
+ font-size: 14px;
8913
+ line-height: 1.45;
8914
+ }
8915
+
8916
+ .ow-chain-of-thought > .ow-chat-collapse {
8917
+ justify-self: stretch;
8918
+ }
8919
+
8920
+ .ow-chain-of-thought__static,
8921
+ .ow-chain-of-thought__static:hover {
8922
+ color: var(--ow-text-soft);
8923
+ cursor: default;
8924
+ }
8925
+
8926
+ .ow-chain-of-thought__failed {
8927
+ color: var(--ow-danger-text);
8928
+ }
8929
+
8930
+ .ow-chain-of-thought__body {
8931
+ display: grid;
8932
+ gap: var(--ow-space-md);
8933
+ padding: var(--ow-space-xs) 0 var(--ow-space-2xs);
8934
+ }
8935
+
8936
+ /* The reasoning, lined up with the toggle's words, with a line down from its chevron. */
8937
+ .ow-chain-of-thought__reasoning {
8938
+ position: relative;
8939
+ min-width: 0;
8940
+ padding-left: 30px;
8941
+ color: var(--ow-text-muted);
8942
+ line-height: 1.55;
8943
+ white-space: pre-line;
8944
+ overflow-wrap: anywhere;
8945
+ text-wrap: pretty;
8946
+ }
8947
+
8948
+ .ow-chain-of-thought__reasoning::before {
8949
+ content: "";
8950
+ position: absolute;
8951
+ top: var(--ow-space-2xs);
8952
+ bottom: var(--ow-space-2xs);
8953
+ left: 9.5px;
8954
+ width: 1px;
8955
+ background: var(--ow-border);
8956
+ }
8957
+
8958
+ .ow-chain-of-thought__reasoning p {
8959
+ margin: 0 0 var(--ow-space-sm);
8960
+ }
8961
+
8962
+ .ow-chain-of-thought__reasoning > :last-child {
8963
+ margin-bottom: 0;
8964
+ }
8965
+
8966
+ .ow-chain-of-thought__steps {
8967
+ display: grid;
8968
+ margin: 0;
8969
+ padding: 0;
8970
+ list-style: none;
8971
+ }
8972
+
8973
+ .ow-chain-of-thought__step {
8974
+ position: relative;
8975
+ display: grid;
8976
+ grid-template-columns: 20px minmax(0, 1fr);
8977
+ column-gap: var(--ow-space-md);
8978
+ padding-bottom: var(--ow-space-lg);
8979
+ }
8980
+
8981
+ .ow-chain-of-thought__step:last-child {
8982
+ padding-bottom: 0;
8983
+ }
8984
+
8985
+ /* The line from each mark down to the next, with a little air at both ends; green behind the steps that are done. */
8986
+ .ow-chain-of-thought__step:not(:last-child)::before {
8987
+ content: "";
8988
+ position: absolute;
8989
+ top: 22px;
8990
+ bottom: 2px;
8991
+ left: 9.5px;
8992
+ width: 1px;
8993
+ background: var(--ow-border);
8994
+ }
8995
+
8996
+ .ow-chain-of-thought__step[data-status="success"]:not(:last-child)::before {
8997
+ background: color-mix(in srgb, var(--ow-success-solid) 40%, var(--ow-border));
8998
+ }
8999
+
9000
+ .ow-chain-of-thought__step-body {
9001
+ display: grid;
9002
+ min-width: 0;
9003
+ align-content: start;
9004
+ gap: var(--ow-space-2xs);
9005
+ }
9006
+
9007
+ .ow-chain-of-thought__step-title {
9008
+ min-width: 0;
9009
+ font-weight: var(--ow-weight-control);
9010
+ line-height: 20px;
9011
+ overflow-wrap: anywhere;
9012
+ }
9013
+
9014
+ .ow-chain-of-thought__step[data-status="pending"] .ow-chain-of-thought__step-title {
9015
+ color: var(--ow-text-muted);
9016
+ }
9017
+
9018
+ .ow-chain-of-thought__detail {
9019
+ min-width: 0;
9020
+ color: var(--ow-text-muted);
9021
+ line-height: 1.55;
9022
+ overflow-wrap: anywhere;
9023
+ }
9024
+
9025
+ .ow-chain-of-thought__detail .ow-code {
9026
+ font-size: 12px;
9027
+ }
9028
+
9029
+ /* components/ChatSource/ChatSource.css */
9030
+ /* ChatSource: a citation chip in running text with a preview card in the top layer. ChatSources: the list of sources
9031
+ under an answer, behind a toggle (from ChatTool.css). */
9032
+ .ow-chat-source {
9033
+ display: inline;
9034
+ }
9035
+
9036
+ /* The chip: a small numbered pill that sits on the line without changing its height. */
9037
+ .ow-chat-source__chip,
9038
+ .ow-chat-sources__index {
9039
+ border: 1px solid var(--ow-border);
9040
+ border-radius: var(--ow-radius-pill);
9041
+ background: var(--ow-surface-muted);
9042
+ color: var(--ow-text-soft);
9043
+ font-family: var(--ow-font-sans);
9044
+ font-size: 11px;
9045
+ font-style: normal;
9046
+ font-weight: var(--ow-weight-emphasis);
9047
+ font-variant-numeric: tabular-nums;
9048
+ line-height: 1;
9049
+ letter-spacing: 0;
9050
+ text-decoration: none;
9051
+ white-space: nowrap;
9052
+ }
9053
+
9054
+ /* In the text it's a plain inline, not an inline-flex box: the line can break after a box, so the full stop after a
9055
+ citation could otherwise wrap onto a line of its own. */
9056
+ .ow-chat-source__chip {
9057
+ position: relative;
9058
+ top: -1px;
9059
+ display: inline;
9060
+ margin-left: 2px;
9061
+ padding: 2px var(--ow-space-xs);
9062
+ vertical-align: baseline;
9063
+ cursor: pointer;
9064
+ transition-property: color, background-color, border-color;
9065
+ transition-duration: var(--ow-duration-base);
9066
+ transition-timing-function: var(--ow-ease-standard);
9067
+ }
9068
+
9069
+ .ow-chat-sources__index {
9070
+ display: inline-flex;
9071
+ height: 18px;
9072
+ min-width: 18px;
9073
+ align-items: center;
9074
+ justify-content: center;
9075
+ padding: 0 var(--ow-space-2xs);
9076
+ }
9077
+
9078
+ /* A label can be cut short, which takes a box. */
9079
+ .ow-chat-source__chip--label {
9080
+ display: inline-flex;
9081
+ height: 18px;
9082
+ max-width: 180px;
9083
+ align-items: center;
9084
+ padding: 0 var(--ow-space-xs);
9085
+ }
9086
+
9087
+ .ow-chat-source__chip-text {
9088
+ min-width: 0;
9089
+ overflow: hidden;
9090
+ text-overflow: ellipsis;
9091
+ }
9092
+
9093
+ .ow-chat-source__chip:hover,
9094
+ .ow-chat-source__chip--open {
9095
+ border-color: var(--ow-primary-border);
9096
+ background: var(--ow-primary-subtle);
9097
+ color: var(--ow-primary-text);
9098
+ }
9099
+
9100
+ .ow-chat-source__chip:focus-visible {
9101
+ outline: 2px solid var(--ow-focus-ring);
9102
+ outline-offset: 2px;
9103
+ }
9104
+
9105
+ /* The preview. It sits in the top layer but inherits from the sentence around the chip, so it sets its own type. */
9106
+ .ow-chat-source-card {
9107
+ z-index: 60;
9108
+ display: grid;
9109
+ width: min(320px, calc(100vw - 16px));
9110
+ gap: var(--ow-space-sm);
9111
+ overflow: hidden;
9112
+ border: 1px solid var(--ow-border);
9113
+ border-radius: var(--ow-radius-container);
9114
+ background: var(--ow-surface);
9115
+ padding: var(--ow-space-lg) var(--ow-space-xl);
9116
+ color: var(--ow-text);
9117
+ font-family: var(--ow-font-sans);
9118
+ font-size: 14px;
9119
+ font-style: normal;
9120
+ font-weight: var(--ow-weight-regular);
9121
+ line-height: 1.45;
9122
+ letter-spacing: normal;
9123
+ text-align: left;
9124
+ text-transform: none;
9125
+ white-space: normal;
9126
+ box-shadow: var(--ow-shadow-menu);
9127
+ }
9128
+
9129
+ .ow-chat-source-card[hidden] {
9130
+ display: none;
9131
+ }
9132
+
9133
+ .ow-chat-source-card__header {
9134
+ display: flex;
9135
+ min-width: 0;
9136
+ align-items: flex-start;
9137
+ gap: var(--ow-space-sm);
9138
+ }
9139
+
9140
+ .ow-chat-source-card__icon {
9141
+ display: inline-flex;
9142
+ height: 20px;
9143
+ flex-shrink: 0;
9144
+ align-items: center;
9145
+ color: var(--ow-text-muted);
9146
+ }
9147
+
9148
+ .ow-chat-source-card__icon > svg {
9149
+ width: 15px;
9150
+ height: 15px;
9151
+ }
9152
+
9153
+ .ow-chat-source-card__title {
9154
+ display: -webkit-box;
9155
+ min-width: 0;
9156
+ overflow: hidden;
9157
+ font-weight: var(--ow-weight-emphasis);
9158
+ line-height: 20px;
9159
+ overflow-wrap: anywhere;
9160
+ -webkit-box-orient: vertical;
9161
+ -webkit-line-clamp: 2;
9162
+ }
9163
+
9164
+ .ow-chat-source-card__source {
9165
+ display: block;
9166
+ min-width: 0;
9167
+ color: var(--ow-text-muted);
9168
+ font-size: 12px;
9169
+ line-height: 1.35;
9170
+ overflow-wrap: anywhere;
9171
+ }
9172
+
9173
+ .ow-chat-source-card__source .ow-code,
9174
+ .ow-chat-sources__source .ow-code {
9175
+ font-size: 11px;
9176
+ }
9177
+
9178
+ /* A few lines from the source, cut off rather than scrolling: there's nothing to scroll with in a preview. */
9179
+ .ow-chat-source-card__snippet {
9180
+ display: -webkit-box;
9181
+ min-width: 0;
9182
+ overflow: hidden;
9183
+ -webkit-box-orient: vertical;
9184
+ }
9185
+
9186
+ .ow-chat-source-card__snippet--text {
9187
+ border-left: 2px solid var(--ow-border-strong);
9188
+ padding-left: var(--ow-space-md);
9189
+ color: var(--ow-text-soft);
9190
+ font-size: 13px;
9191
+ line-height: 1.5;
9192
+ white-space: pre-line;
9193
+ -webkit-line-clamp: 4;
9194
+ }
9195
+
9196
+ .ow-chat-source-card__snippet--code {
9197
+ border: 1px solid var(--ow-border);
9198
+ border-radius: var(--ow-radius-form);
9199
+ background: var(--ow-code-ground);
9200
+ padding: var(--ow-space-sm) var(--ow-space-md);
9201
+ font-family: var(--ow-font-mono);
9202
+ font-size: 12px;
9203
+ line-height: 1.6;
9204
+ white-space: pre;
9205
+ -webkit-line-clamp: 6;
9206
+ }
9207
+
9208
+ .ow-chat-source-card__open.ow-link {
9209
+ display: inline-flex;
9210
+ justify-self: start;
9211
+ align-items: center;
9212
+ gap: var(--ow-space-2xs);
9213
+ font-size: 12px;
9214
+ font-weight: var(--ow-weight-emphasis);
9215
+ }
9216
+
9217
+ /* ChatSources: a toggle, then a card per source in as many columns as fit. */
9218
+ .ow-chat-sources {
9219
+ display: grid;
9220
+ min-width: 0;
9221
+ justify-items: start;
9222
+ color: var(--ow-text);
9223
+ font-family: var(--ow-font-sans);
9224
+ font-size: 14px;
9225
+ line-height: 1.45;
9226
+ }
9227
+
9228
+ .ow-chat-sources > .ow-chat-collapse {
9229
+ justify-self: stretch;
9230
+ }
9231
+
9232
+ .ow-chat-sources__body {
9233
+ padding: var(--ow-space-xs) 0 var(--ow-space-2xs);
9234
+ }
9235
+
9236
+ .ow-chat-sources__list {
9237
+ display: grid;
9238
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
9239
+ gap: var(--ow-space-sm);
9240
+ margin: 0;
9241
+ padding: 0;
9242
+ list-style: none;
9243
+ }
9244
+
9245
+ .ow-chat-sources__list > li {
9246
+ display: grid;
9247
+ min-width: 0;
9248
+ }
9249
+
9250
+ .ow-chat-sources__card {
9251
+ display: flex;
9252
+ min-width: 0;
9253
+ align-items: flex-start;
9254
+ gap: var(--ow-space-md);
9255
+ border: 1px solid var(--ow-border);
9256
+ border-radius: var(--ow-radius-container);
9257
+ background: var(--ow-surface);
9258
+ padding: var(--ow-space-md) var(--ow-space-lg);
9259
+ color: inherit;
9260
+ text-decoration: none;
9261
+ }
9262
+
9263
+ .ow-chat-sources__card--link {
9264
+ cursor: pointer;
9265
+ transition-property: border-color, background-color;
9266
+ transition-duration: var(--ow-duration-base);
9267
+ transition-timing-function: var(--ow-ease-standard);
9268
+ }
9269
+
9270
+ .ow-chat-sources__card--link:hover {
9271
+ border-color: var(--ow-border-strong);
9272
+ background: var(--ow-surface-muted);
9273
+ }
9274
+
9275
+ .ow-chat-sources__card--link:focus-visible {
9276
+ outline: 2px solid var(--ow-focus-ring);
9277
+ outline-offset: 2px;
9278
+ }
9279
+
9280
+ .ow-chat-sources__lead {
9281
+ display: inline-flex;
9282
+ height: 20px;
9283
+ flex-shrink: 0;
9284
+ align-items: center;
9285
+ gap: var(--ow-space-xs);
9286
+ }
9287
+
9288
+ .ow-chat-sources__icon {
9289
+ display: inline-flex;
9290
+ color: var(--ow-text-muted);
9291
+ }
9292
+
9293
+ .ow-chat-sources__icon > svg {
9294
+ width: 15px;
9295
+ height: 15px;
9296
+ }
9297
+
9298
+ .ow-chat-sources__text {
9299
+ display: grid;
9300
+ min-width: 0;
9301
+ flex: 1;
9302
+ gap: 2px;
9303
+ }
9304
+
9305
+ .ow-chat-sources__title {
9306
+ display: -webkit-box;
9307
+ overflow: hidden;
9308
+ font-weight: var(--ow-weight-emphasis);
9309
+ line-height: 20px;
9310
+ overflow-wrap: anywhere;
9311
+ -webkit-box-orient: vertical;
9312
+ -webkit-line-clamp: 2;
9313
+ }
9314
+
9315
+ .ow-chat-sources__source {
9316
+ overflow: hidden;
9317
+ color: var(--ow-text-muted);
9318
+ text-overflow: ellipsis;
9319
+ white-space: nowrap;
9320
+ font-size: 12px;
9321
+ line-height: 1.35;
9322
+ }
9323
+
9324
+ .ow-chat-sources__external {
9325
+ display: inline-flex;
9326
+ height: 20px;
9327
+ flex-shrink: 0;
9328
+ align-items: center;
9329
+ color: var(--ow-icon);
9330
+ }