@xenide-io/the-old-ui-theme 0.2.9 → 0.3.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 (61) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-SHF57J7U.mjs → chunk-FDMD3IIN.mjs} +1573 -652
  3. package/dist/index-D1RTT2Ap.d.mts +1044 -0
  4. package/dist/index-D1RTT2Ap.d.ts +1044 -0
  5. package/dist/index.d.mts +10 -7
  6. package/dist/index.d.ts +10 -7
  7. package/dist/index.js +1705 -744
  8. package/dist/index.mjs +61 -1
  9. package/dist/tailwind-preset.js +7 -0
  10. package/dist/tailwind-preset.mjs +7 -0
  11. package/dist/ui.d.mts +3 -2
  12. package/dist/ui.d.ts +3 -2
  13. package/dist/ui.js +1584 -666
  14. package/dist/ui.mjs +31 -1
  15. package/package.json +18 -4
  16. package/src/app/globals.css +1005 -227
  17. package/src/components/icons/IconBase.tsx +20 -12
  18. package/src/components/icons/createIconBase.tsx +12 -7
  19. package/src/components/icons/icons.tsx +208 -18
  20. package/src/components/sections/AlertShowcase.tsx +2 -1
  21. package/src/components/sections/BadgeShowcase.tsx +1 -1
  22. package/src/components/sections/ButtonShowcase.tsx +6 -10
  23. package/src/components/sections/CardShowcase.tsx +22 -6
  24. package/src/components/sections/DropdownShowcase.tsx +4 -6
  25. package/src/components/sections/FilterChipsShowcase.tsx +74 -26
  26. package/src/components/sections/FormShowcase.tsx +2 -1
  27. package/src/components/sections/IconShowcase.tsx +86 -206
  28. package/src/components/sections/KbdShowcase.tsx +47 -21
  29. package/src/components/sections/ModalShowcase.tsx +7 -6
  30. package/src/components/sections/ProductLayoutsShowcase.tsx +138 -0
  31. package/src/components/sections/ProgressShowcase.tsx +50 -53
  32. package/src/components/sections/SwapShowcase.tsx +13 -5
  33. package/src/components/ui/Alert.tsx +28 -19
  34. package/src/components/ui/AuthLayout.tsx +58 -0
  35. package/src/components/ui/Badge.tsx +10 -5
  36. package/src/components/ui/Button.tsx +22 -12
  37. package/src/components/ui/ButtonChrome.tsx +1 -1
  38. package/src/components/ui/Calendar.tsx +6 -7
  39. package/src/components/ui/Card.tsx +21 -11
  40. package/src/components/ui/CollapsibleSection.tsx +11 -11
  41. package/src/components/ui/DropdownMenu.tsx +189 -65
  42. package/src/components/ui/FilterBar.tsx +165 -0
  43. package/src/components/ui/FilterChips.tsx +65 -35
  44. package/src/components/ui/FilterControls.tsx +30 -0
  45. package/src/components/ui/FormField.tsx +69 -0
  46. package/src/components/ui/Input.tsx +166 -140
  47. package/src/components/ui/Kbd.tsx +88 -13
  48. package/src/components/ui/Loader.tsx +96 -0
  49. package/src/components/ui/Modal.tsx +66 -36
  50. package/src/components/ui/SettingsLayout.tsx +94 -0
  51. package/src/components/ui/ShowcaseWrapper.tsx +4 -16
  52. package/src/components/ui/Stepper.tsx +5 -6
  53. package/src/components/ui/first-slice.test.tsx +98 -0
  54. package/src/components/ui/index.ts +62 -3
  55. package/src/components/ui/interaction-primitives.test.tsx +77 -0
  56. package/src/components/ui/kbd-icons.test.tsx +90 -0
  57. package/src/components/ui/product-patterns.test.tsx +77 -0
  58. package/src/styles/themes.css +411 -1
  59. package/tailwind-preset.ts +7 -0
  60. package/dist/index-CmS6hcUk.d.mts +0 -753
  61. package/dist/index-CmS6hcUk.d.ts +0 -753
@@ -0,0 +1,90 @@
1
+ import { createRef } from "react";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { describe, expect, it } from "vitest";
4
+ import {
5
+ CANONICAL_ICONS,
6
+ OLD_UI_ICONS,
7
+ PH_ICONS,
8
+ PH_ICON_ALIASES,
9
+ IconByName,
10
+ IconInfo,
11
+ IconOldWindow,
12
+ IconTerminal,
13
+ } from "@/components/icons";
14
+ import { Kbd } from "@/components/ui/Kbd";
15
+
16
+ describe("Kbd", () => {
17
+ it("renders shortcuts as separate, spoken keycaps", () => {
18
+ render(<Kbd keys={["Command", "K"]} platform="mac" />);
19
+ const shortcut = screen.getByLabelText("Command + K");
20
+
21
+ expect(shortcut).toHaveClass("ph-keycap");
22
+ expect(shortcut.querySelectorAll(".ph-shortcut-key")).toHaveLength(2);
23
+ expect(shortcut).toHaveTextContent("⌘K");
24
+ });
25
+
26
+ it("keeps platform conversion explicit and preserves React nodes", () => {
27
+ const { rerender } = render(<Kbd keys={["Control", "K"]} />);
28
+ expect(screen.getByLabelText("Control + K")).toHaveTextContent("ControlK");
29
+
30
+ rerender(<Kbd keys={[<span key="mod">Fn</span>, "K"]} aria-label="Function + K" />);
31
+ expect(screen.getByLabelText("Function + K")).toHaveTextContent("FnK");
32
+ expect(screen.getByLabelText("Function + K")).not.toHaveTextContent("[object Object]");
33
+ });
34
+
35
+ it("distinguishes a physical key from a code token", () => {
36
+ render(
37
+ <>
38
+ <Kbd variant="key">Escape</Kbd>
39
+ <Kbd variant="token">HogQL</Kbd>
40
+ </>,
41
+ );
42
+
43
+ expect(screen.getByText("Escape")).toHaveClass("ph-keycap");
44
+ expect(screen.getByText("HogQL")).toHaveClass("ph-code-token");
45
+ });
46
+ });
47
+
48
+ describe("icons", () => {
49
+ it("hides decorative icons but exposes labeled icons", () => {
50
+ const { rerender } = render(<IconInfo data-testid="icon" />);
51
+ expect(screen.getByTestId("icon")).toHaveAttribute("aria-hidden", "true");
52
+
53
+ rerender(<IconInfo data-testid="icon" aria-label="Information" />);
54
+ expect(screen.getByRole("img", { name: "Information" })).not.toHaveAttribute("aria-hidden");
55
+ });
56
+
57
+ it("honors size, forwards refs, and renders original glyphs", () => {
58
+ const ref = createRef<SVGSVGElement>();
59
+ render(
60
+ <>
61
+ <IconTerminal ref={ref} size={16} data-testid="terminal" />
62
+ <IconOldWindow aria-label="Old window" />
63
+ </>,
64
+ );
65
+
66
+ expect(ref.current).toBe(screen.getByTestId("terminal"));
67
+ expect(screen.getByTestId("terminal")).toHaveStyle({ width: "16px", height: "16px" });
68
+ expect(screen.getByRole("img", { name: "Old window" })).toBeInTheDocument();
69
+ });
70
+
71
+ it("keeps aliases runtime-identical while originals stay canonical", () => {
72
+ expect(PH_ICONS.grid).toBe(CANONICAL_ICONS.gridView);
73
+ expect(PH_ICONS.play).toBe(CANONICAL_ICONS.playCircle);
74
+ expect(PH_ICONS.warning).toBe(CANONICAL_ICONS.exclamation);
75
+ expect(Object.keys(PH_ICON_ALIASES)).toEqual(expect.arrayContaining(["grid", "play", "warning"]));
76
+
77
+ for (const name of Object.keys(OLD_UI_ICONS)) {
78
+ expect(name in CANONICAL_ICONS).toBe(true);
79
+ }
80
+ });
81
+
82
+ it("gives generated icons useful identities and forwards dynamic refs", () => {
83
+ const ref = createRef<SVGSVGElement>();
84
+ render(<IconByName ref={ref} name="grid" data-testid="dynamic-icon" />);
85
+
86
+ expect(CANONICAL_ICONS.areaChart.displayName).toBe("IconAreaChart");
87
+ expect(ref.current).toBe(screen.getByTestId("dynamic-icon"));
88
+ expect(ref.current).toHaveAttribute("aria-hidden", "true");
89
+ });
90
+ });
@@ -0,0 +1,77 @@
1
+ import { render, screen } from "@testing-library/react";
2
+ import { describe, expect, it } from "vitest";
3
+ import { AuthCard, AuthLayout } from "@/components/ui/AuthLayout";
4
+ import { FilterControls } from "@/components/ui/FilterControls";
5
+ import { Loader, LoadingState, Skeleton } from "@/components/ui/Loader";
6
+ import { SettingsLayout, SettingsNav } from "@/components/ui/SettingsLayout";
7
+ import { getTheme, isThemeId, THEMES } from "@/themes/registry";
8
+
9
+ describe("loading patterns", () => {
10
+ it("announces one useful loading status and keeps skeleton geometry decorative", () => {
11
+ render(
12
+ <>
13
+ <Loader variant="dots" label="Loading events" />
14
+ <LoadingState label="Preparing workspace" title="Almost ready" />
15
+ <Skeleton shape="block" data-testid="skeleton" />
16
+ </>,
17
+ );
18
+
19
+ expect(screen.getByRole("status", { name: "Loading events" })).toBeInTheDocument();
20
+ expect(screen.getByRole("status", { name: "Preparing workspace" })).toHaveTextContent("Almost ready");
21
+ expect(screen.getByTestId("skeleton")).toHaveAttribute("aria-hidden", "true");
22
+ });
23
+ });
24
+
25
+ describe("product layouts", () => {
26
+ it("labels auth and settings regions without owning their application state", () => {
27
+ render(
28
+ <>
29
+ <AuthLayout brand="Acme">
30
+ <AuthCard title="Welcome back"><input aria-label="Email" /></AuthCard>
31
+ </AuthLayout>
32
+ <SettingsLayout
33
+ title="Workspace settings"
34
+ navigation={
35
+ <SettingsNav groups={[{
36
+ label: "Workspace",
37
+ items: [{ id: "general", label: "General", href: "/settings", active: true }],
38
+ }]} />
39
+ }
40
+ >
41
+ Settings content
42
+ </SettingsLayout>
43
+ </>,
44
+ );
45
+
46
+ expect(screen.getByRole("heading", { name: "Welcome back" })).toBeInTheDocument();
47
+ expect(screen.getAllByRole("navigation", { name: "Settings" })).toHaveLength(2);
48
+ for (const link of screen.getAllByRole("link", { name: "General" })) {
49
+ expect(link).toHaveAttribute("aria-current", "page");
50
+ }
51
+ });
52
+
53
+ it("composes filter controls and applied chips in one explicit pattern", () => {
54
+ render(
55
+ <FilterControls
56
+ barProps={{ resultCount: "12 results" }}
57
+ chipsProps={{ chips: [{ id: "status", label: "Status", value: "Active", active: true }] }}
58
+ >
59
+ <button type="button">Add filter</button>
60
+ </FilterControls>,
61
+ );
62
+
63
+ expect(screen.getByRole("button", { name: "Add filter" })).toBeInTheDocument();
64
+ expect(screen.getByText("12 results")).toBeInTheDocument();
65
+ expect(screen.getByRole("group", { name: "Applied filters" })).toHaveTextContent("StatusActive");
66
+ });
67
+ });
68
+
69
+ describe("Kraken themes", () => {
70
+ it("registers a complete light and dark pair", () => {
71
+ expect(isThemeId("kraken-light")).toBe(true);
72
+ expect(isThemeId("kraken-dark")).toBe(true);
73
+ expect(getTheme("kraken-light")).toMatchObject({ colorScheme: "light", group: "Kraken" });
74
+ expect(getTheme("kraken-dark")).toMatchObject({ colorScheme: "dark", group: "Kraken" });
75
+ expect(THEMES.filter((theme) => theme.group === "Kraken")).toHaveLength(2);
76
+ });
77
+ });
@@ -63,6 +63,24 @@
63
63
  --ph-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%236b6b6b' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
64
64
  }
65
65
 
66
+ :root:not([data-theme]),
67
+ [data-theme="hedgehog-light"] {
68
+ --ph-surface-inset: hsl(70 16% 93%);
69
+ --ph-surface-raised: #ffffff;
70
+ --ph-surface-overlay: #ffffff;
71
+ --ph-border-subtle: hsl(75 14% 90%);
72
+ --ph-on-accent: #211108;
73
+ --ph-on-violet: #ffffff;
74
+ --ph-on-success: #071b10;
75
+ --ph-on-warning: #1c1504;
76
+ --ph-on-danger: #ffffff;
77
+ --ph-on-info: #ffffff;
78
+ --ph-focus-ring: hsl(217deg 90% 52%);
79
+ --ph-selected-bg: hsl(19deg 100% 95%);
80
+ --ph-selected-text: hsl(19deg 88% 30%);
81
+ --ph-selected-border: hsl(19deg 90% 58%);
82
+ }
83
+
66
84
  [data-theme="hedgehog-dark"] {
67
85
  color-scheme: dark;
68
86
 
@@ -70,7 +88,11 @@
70
88
  --ph-surface: hsl(220 10% 13%);
71
89
  --ph-muted: hsl(220 9% 16%);
72
90
  --ph-toolbar: hsl(220 8% 19%);
91
+ --ph-surface-inset: hsl(220 12% 10%);
92
+ --ph-surface-raised: hsl(220 9% 16%);
93
+ --ph-surface-overlay: hsl(220 8% 18%);
73
94
  --ph-border: hsl(220 7% 24%);
95
+ --ph-border-subtle: hsl(220 8% 19%);
74
96
  --ph-border-strong: hsl(220 6% 38%);
75
97
 
76
98
  --ph-text-primary: hsl(0 0% 96%);
@@ -87,6 +109,16 @@
87
109
  --ph-warning: hsl(43deg 85% 52%);
88
110
  --ph-danger: hsl(9deg 65% 55%);
89
111
  --ph-info: hsl(217deg 85% 58%);
112
+ --ph-on-accent: hsl(220 14% 8%);
113
+ --ph-on-violet: hsl(220 14% 8%);
114
+ --ph-on-success: hsl(220 14% 8%);
115
+ --ph-on-warning: hsl(220 14% 8%);
116
+ --ph-on-danger: hsl(220 14% 8%);
117
+ --ph-on-info: hsl(220 14% 8%);
118
+ --ph-focus-ring: hsl(217deg 95% 72%);
119
+ --ph-selected-bg: hsl(19deg 70% 18%);
120
+ --ph-selected-text: hsl(19deg 100% 72%);
121
+ --ph-selected-border: hsl(19deg 90% 55%);
90
122
 
91
123
  --ph-text-3000: hsl(0 0% 96%);
92
124
  --ph-primary-button-face: hsl(220 10% 15%);
@@ -1417,7 +1449,7 @@
1417
1449
  --ph-danger: #f15e5e;
1418
1450
  --ph-info: #4a9eff;
1419
1451
 
1420
- --ph-text-3000: #ffffff;
1452
+ --ph-text-3000: #191919;
1421
1453
  --ph-primary-button-face: #ffffff;
1422
1454
  --ph-primary-button-border: #3381e6;
1423
1455
  --ph-primary-button-border-hover: #2663b8;
@@ -1450,3 +1482,381 @@
1450
1482
 
1451
1483
  --ph-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%236b6b6b' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
1452
1484
  }
1485
+
1486
+ /* Tokyo Night Day — soft bluish greys with vivid blue and purple accents */
1487
+ [data-theme="deepsea-light"] {
1488
+ color-scheme: light;
1489
+
1490
+ --ph-canvas: #e1e2e7;
1491
+ --ph-surface: #f2f3f8;
1492
+ --ph-muted: #e9eaf1;
1493
+ --ph-toolbar: #d0d5e3;
1494
+ --ph-border: #c4c8da;
1495
+ --ph-border-strong: #a8aecb;
1496
+
1497
+ --ph-text-primary: #343b58;
1498
+ --ph-text-secondary: #6172b0;
1499
+ --ph-text-tertiary: #848cb5;
1500
+
1501
+ /* Tokyo Night blue */
1502
+ --ph-accent: #2e7de9;
1503
+ --ph-accent-hover: #2368c6;
1504
+ --ph-blue: #2e7de9;
1505
+ /* Day magenta */
1506
+ --ph-violet: #9854f1;
1507
+ /* Day purple */
1508
+ --ph-purple: #7847bd;
1509
+
1510
+ /* Day green */
1511
+ --ph-success: #587539;
1512
+ /* Day orange */
1513
+ --ph-warning: #b15c00;
1514
+ /* Day red */
1515
+ --ph-danger: #f52a65;
1516
+ /* Day cyan */
1517
+ --ph-info: #007197;
1518
+
1519
+ --ph-text-3000: #343b58;
1520
+ --ph-primary-button-face: #ffffff;
1521
+ --ph-primary-button-border: #2368c6;
1522
+ --ph-primary-button-border-hover: #1a52a3;
1523
+ --ph-primary-frame-bg: #2e7de9;
1524
+ --ph-secondary-button-bg: #f2f3f8;
1525
+ --ph-secondary-frame-bg: #d0d5e3;
1526
+ --ph-secondary-button-border: #c4c8da;
1527
+ --ph-secondary-button-border-hover: #2e7de9;
1528
+
1529
+ --ph-border-3000: #c4c8da;
1530
+ --ph-chrome-inset-face-top: inset 0 1px 0 hsl(0deg 0% 100% / 0.84);
1531
+ --ph-chrome-inset-face-bottom: inset 0 -1px 0 hsl(0deg 0% 0% / 0.06);
1532
+ --ph-accent-highlight-secondary: hsla(215deg 81% 55% / 12%);
1533
+
1534
+ --ph-data-1: #2e7de9;
1535
+ --ph-data-2: #9854f1;
1536
+ --ph-data-3: #007197;
1537
+ --ph-data-4: #b15c00;
1538
+ --ph-data-5: #587539;
1539
+ --ph-data-6: #f52a65;
1540
+ --ph-data-7: #8c6c3e;
1541
+
1542
+ --ph-product-session-replay: #b15c00;
1543
+ --ph-product-product-analytics: #2e7de9;
1544
+ --ph-product-data-pipeline: #007197;
1545
+ --ph-product-feature-flags: #9854f1;
1546
+ --ph-product-experiments: #f52a65;
1547
+ --ph-product-data-warehouse: #8c6c3e;
1548
+ --ph-product-surveys: #587539;
1549
+
1550
+ --ph-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%23848cb5' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
1551
+ }
1552
+
1553
+ /* Tokyo Night — #1a1b26 base with signature blue, cyan, and purple */
1554
+ [data-theme="deepsea-dark"] {
1555
+ color-scheme: dark;
1556
+
1557
+ --ph-canvas: #1a1b26;
1558
+ --ph-surface: #1f2335;
1559
+ --ph-muted: #24283b;
1560
+ --ph-toolbar: #292e42;
1561
+ --ph-border: #3b4261;
1562
+ --ph-border-strong: #565f89;
1563
+
1564
+ --ph-text-primary: #c0caf5;
1565
+ --ph-text-secondary: #a9b1d6;
1566
+ --ph-text-tertiary: #565f89;
1567
+
1568
+ /* Signature blue */
1569
+ --ph-accent: #7aa2f7;
1570
+ --ph-accent-hover: #97b4f9;
1571
+ --ph-blue: #7aa2f7;
1572
+ /* Purple */
1573
+ --ph-violet: #bb9af7;
1574
+ --ph-purple: #9d7cd8;
1575
+
1576
+ /* Green */
1577
+ --ph-success: #9ece6a;
1578
+ /* Yellow */
1579
+ --ph-warning: #e0af68;
1580
+ /* Red */
1581
+ --ph-danger: #f7768e;
1582
+ /* Cyan */
1583
+ --ph-info: #7dcfff;
1584
+
1585
+ --ph-text-3000: #c0caf5;
1586
+ --ph-primary-button-face: #1f2335;
1587
+ --ph-primary-button-border: #3d59a1;
1588
+ --ph-primary-button-border-hover: #7aa2f7;
1589
+ --ph-primary-frame-bg: #7aa2f7;
1590
+ --ph-secondary-button-bg: #24283b;
1591
+ --ph-secondary-frame-bg: #3b4261;
1592
+ --ph-secondary-button-border: #414868;
1593
+ --ph-secondary-button-border-hover: #565f89;
1594
+
1595
+ --ph-border-3000: #292e42;
1596
+ --ph-chrome-inset-face-top: inset 0 1px 0 hsl(0deg 0% 100% / 0.07);
1597
+ --ph-chrome-inset-face-bottom: inset 0 -1px 0 hsl(0deg 0% 0% / 0.4);
1598
+ --ph-accent-highlight-secondary: hsla(221deg 89% 72% / 16%);
1599
+
1600
+ --ph-data-1: #7aa2f7;
1601
+ --ph-data-2: #bb9af7;
1602
+ --ph-data-3: #7dcfff;
1603
+ --ph-data-4: #e0af68;
1604
+ --ph-data-5: #9ece6a;
1605
+ --ph-data-6: #f7768e;
1606
+ --ph-data-7: #ff9e64;
1607
+
1608
+ --ph-product-session-replay: #e0af68;
1609
+ --ph-product-product-analytics: #7aa2f7;
1610
+ --ph-product-data-pipeline: #7dcfff;
1611
+ --ph-product-feature-flags: #bb9af7;
1612
+ --ph-product-experiments: #f7768e;
1613
+ --ph-product-data-warehouse: #ff9e64;
1614
+ --ph-product-surveys: #9ece6a;
1615
+
1616
+ --ph-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%23565f89' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
1617
+ }
1618
+
1619
+ /* Kraken Light — Medium-inspired paper, editorial ink, and publication green. */
1620
+ [data-theme="kraken-light"] {
1621
+ color-scheme: light;
1622
+
1623
+ --ph-canvas: #f7f4ed;
1624
+ --ph-surface: #ffffff;
1625
+ --ph-muted: #f2f2f2;
1626
+ --ph-toolbar: #e8e8e6;
1627
+ --ph-surface-inset: #f2f2f2;
1628
+ --ph-surface-raised: #ffffff;
1629
+ --ph-surface-overlay: #ffffff;
1630
+ --ph-border: #e2e2df;
1631
+ --ph-border-subtle: #ededeb;
1632
+ --ph-border-strong: #a8a8a3;
1633
+
1634
+ --ph-text-primary: #242424;
1635
+ --ph-text-secondary: #4f4f4f;
1636
+ --ph-text-tertiary: #6b6b6b;
1637
+
1638
+ --ph-accent: #242424;
1639
+ --ph-accent-hover: #000000;
1640
+ --ph-blue: #437aff;
1641
+ --ph-violet: #ffc017;
1642
+ --ph-purple: #e6ad15;
1643
+
1644
+ --ph-success: #1a8917;
1645
+ --ph-warning: #b26a00;
1646
+ --ph-danger: #c7463a;
1647
+ --ph-info: #1769aa;
1648
+ --ph-on-accent: #ffffff;
1649
+ --ph-on-violet: #242424;
1650
+ --ph-on-success: #ffffff;
1651
+ --ph-on-warning: #050505;
1652
+ --ph-on-danger: #ffffff;
1653
+ --ph-on-info: #ffffff;
1654
+ --ph-focus-ring: #242424;
1655
+ --ph-selected-bg: #f2f2f2;
1656
+ --ph-selected-text: #242424;
1657
+ --ph-selected-border: #8b8b86;
1658
+
1659
+ --ph-text-3000: #ffffff;
1660
+ --ph-primary-button-face: #242424;
1661
+ --ph-primary-button-border: #171717;
1662
+ --ph-primary-button-border-hover: #000000;
1663
+ --ph-primary-frame-bg: #000000;
1664
+ --ph-secondary-button-bg: #ffffff;
1665
+ --ph-secondary-frame-bg: #d7d7d4;
1666
+ --ph-secondary-button-border: #b7b7b2;
1667
+ --ph-secondary-button-border-hover: #777772;
1668
+
1669
+ --ph-border-3000: #d7d7d4;
1670
+ --ph-chrome-inset-face-top: inset 0 1px 0 hsl(0deg 0% 100% / 0.9);
1671
+ --ph-chrome-inset-face-bottom: inset 0 -1px 0 hsl(0deg 0% 0% / 0.06);
1672
+ --ph-accent-highlight-secondary: rgb(36 36 36 / 8%);
1673
+
1674
+ --ph-data-1: #242424;
1675
+ --ph-data-2: #ffc017;
1676
+ --ph-data-3: #437aff;
1677
+ --ph-data-4: #00838f;
1678
+ --ph-data-5: #b26a00;
1679
+ --ph-data-6: #c7463a;
1680
+ --ph-data-7: #ad1457;
1681
+
1682
+ --ph-product-session-replay: #b26a00;
1683
+ --ph-product-product-analytics: #1769aa;
1684
+ --ph-product-data-pipeline: #00838f;
1685
+ --ph-product-feature-flags: #ffc017;
1686
+ --ph-product-experiments: #437aff;
1687
+ --ph-product-data-warehouse: #7b5e3b;
1688
+ --ph-product-surveys: #c7463a;
1689
+
1690
+ --ph-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%236b6b6b' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
1691
+ }
1692
+
1693
+ /* Kraken Dark — Medium-inspired night reading canvas and soft editorial contrast. */
1694
+ [data-theme="kraken-dark"] {
1695
+ color-scheme: dark;
1696
+
1697
+ --ph-canvas: #191919;
1698
+ --ph-surface: #222222;
1699
+ --ph-muted: #292929;
1700
+ --ph-toolbar: #323232;
1701
+ --ph-surface-inset: #1d1d1d;
1702
+ --ph-surface-raised: #262626;
1703
+ --ph-surface-overlay: #2b2b2b;
1704
+ --ph-border: #3a3a3a;
1705
+ --ph-border-subtle: #303030;
1706
+ --ph-border-strong: #686868;
1707
+
1708
+ --ph-text-primary: #f2f2f2;
1709
+ --ph-text-secondary: #c4c4c4;
1710
+ --ph-text-tertiary: #929292;
1711
+
1712
+ --ph-accent: #f2f2f2;
1713
+ --ph-accent-hover: #ffffff;
1714
+ --ph-blue: #7da3ff;
1715
+ --ph-violet: #ffc017;
1716
+ --ph-purple: #ffcd45;
1717
+
1718
+ --ph-success: #1a8917;
1719
+ --ph-warning: #e0a34a;
1720
+ --ph-danger: #c7463a;
1721
+ --ph-info: #1769aa;
1722
+ --ph-on-accent: #191919;
1723
+ --ph-on-violet: #242424;
1724
+ --ph-on-success: #ffffff;
1725
+ --ph-on-warning: #211606;
1726
+ --ph-on-danger: #ffffff;
1727
+ --ph-on-info: #ffffff;
1728
+ --ph-focus-ring: #f2f2f2;
1729
+ --ph-selected-bg: #333333;
1730
+ --ph-selected-text: #ffffff;
1731
+ --ph-selected-border: #858585;
1732
+
1733
+ --ph-text-3000: #191919;
1734
+ --ph-primary-button-face: #f2f2f2;
1735
+ --ph-primary-button-border: #d6d6d6;
1736
+ --ph-primary-button-border-hover: #ffffff;
1737
+ --ph-primary-frame-bg: #a9a9a9;
1738
+ --ph-secondary-button-bg: #2b2b2b;
1739
+ --ph-secondary-frame-bg: #414141;
1740
+ --ph-secondary-button-border: #505050;
1741
+ --ph-secondary-button-border-hover: #777777;
1742
+
1743
+ --ph-border-3000: #303030;
1744
+ --ph-chrome-inset-face-top: inset 0 1px 0 hsl(0deg 0% 100% / 0.08);
1745
+ --ph-chrome-inset-face-bottom: inset 0 -1px 0 hsl(0deg 0% 0% / 0.4);
1746
+ --ph-accent-highlight-secondary: rgb(242 242 242 / 10%);
1747
+
1748
+ --ph-data-1: #f2f2f2;
1749
+ --ph-data-2: #ffc017;
1750
+ --ph-data-3: #7da3ff;
1751
+ --ph-data-4: #58c4c7;
1752
+ --ph-data-5: #e0a34a;
1753
+ --ph-data-6: #e77b70;
1754
+ --ph-data-7: #e183ae;
1755
+
1756
+ --ph-product-session-replay: #e0a34a;
1757
+ --ph-product-product-analytics: #6ba7d6;
1758
+ --ph-product-data-pipeline: #58c4c7;
1759
+ --ph-product-feature-flags: #ffc017;
1760
+ --ph-product-experiments: #7da3ff;
1761
+ --ph-product-data-warehouse: #c59a6b;
1762
+ --ph-product-surveys: #e77b70;
1763
+
1764
+ --ph-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%23929292' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
1765
+ }
1766
+
1767
+ /* Semantic button contrast is scoped to buttons so other token consumers keep theme-native ink. */
1768
+ :is(
1769
+ [data-theme="hedgehog-dark"],
1770
+ [data-theme="catppuccin-dark"],
1771
+ [data-theme="sheets-dark"],
1772
+ [data-theme="note-dark"],
1773
+ [data-theme="presentation-dark"],
1774
+ [data-theme="socials-dark"],
1775
+ [data-theme="chats-dark"],
1776
+ [data-theme="xenide-dark"],
1777
+ [data-theme="bikini-bottom-dark"],
1778
+ [data-theme="turtletime-dark"],
1779
+ [data-theme="github-dark"],
1780
+ [data-theme="rosepine-dark"],
1781
+ [data-theme="notion-dark"],
1782
+ [data-theme="deepsea-dark"],
1783
+ [data-theme="kraken-dark"]
1784
+ ) {
1785
+ .ph-btn-signal {
1786
+ --ph-btn-face: color-mix(in oklab, var(--ph-accent) 62%, black);
1787
+ --ph-btn-ink: #ffffff;
1788
+ }
1789
+
1790
+ .ph-btn-accent {
1791
+ --ph-btn-face: color-mix(in oklab, var(--ph-violet) 62%, black);
1792
+ --ph-btn-ink: #ffffff;
1793
+ }
1794
+
1795
+ .ph-btn-info {
1796
+ --ph-btn-face: color-mix(in oklab, var(--ph-info) 62%, black);
1797
+ --ph-btn-ink: #ffffff;
1798
+ }
1799
+
1800
+ .ph-btn-success {
1801
+ --ph-btn-face: color-mix(in oklab, var(--ph-success) 62%, black);
1802
+ --ph-btn-ink: #ffffff;
1803
+ }
1804
+
1805
+ .ph-btn-warning {
1806
+ --ph-btn-face: color-mix(in oklab, var(--ph-warning) 62%, black);
1807
+ --ph-btn-ink: #ffffff;
1808
+ }
1809
+
1810
+ .ph-btn-danger {
1811
+ --ph-btn-face: color-mix(in oklab, var(--ph-danger) 62%, black);
1812
+ --ph-btn-ink: #ffffff;
1813
+ }
1814
+ }
1815
+
1816
+ :is(
1817
+ [data-theme="socials"],
1818
+ [data-theme="bikini-bottom"],
1819
+ [data-theme="rosepine-light"],
1820
+ [data-theme="notion"],
1821
+ [data-theme="deepsea-light"],
1822
+ [data-theme="presentation"]
1823
+ ) .ph-btn-signal,
1824
+ :is(
1825
+ [data-theme="socials"],
1826
+ [data-theme="bikini-bottom"],
1827
+ [data-theme="rosepine-light"],
1828
+ [data-theme="deepsea-light"]
1829
+ ) .ph-btn-accent,
1830
+ :is(
1831
+ [data-theme="catppuccin-light"],
1832
+ [data-theme="socials"],
1833
+ [data-theme="xenide-light"],
1834
+ [data-theme="bikini-bottom"],
1835
+ [data-theme="chats-light"]
1836
+ ) .ph-btn-success,
1837
+ :is(
1838
+ [data-theme="xenide-light"],
1839
+ [data-theme="bikini-bottom"],
1840
+ [data-theme="rosepine-light"],
1841
+ [data-theme="notion"],
1842
+ [data-theme="deepsea-light"]
1843
+ ) .ph-btn-danger,
1844
+ :is(
1845
+ [data-theme="socials"],
1846
+ [data-theme="bikini-bottom"],
1847
+ [data-theme="chats-light"],
1848
+ [data-theme="rosepine-light"],
1849
+ [data-theme="notion"]
1850
+ ) .ph-btn-info {
1851
+ --ph-btn-ink: #050505;
1852
+ }
1853
+
1854
+ :is(
1855
+ [data-theme="sheets"],
1856
+ [data-theme="note"],
1857
+ [data-theme="presentation"],
1858
+ [data-theme="github-light"],
1859
+ [data-theme="deepsea-light"]
1860
+ ) .ph-btn-warning {
1861
+ --ph-btn-ink: #ffffff;
1862
+ }
@@ -38,9 +38,13 @@ const posthogThemePreset: Partial<Config> = {
38
38
  ph: {
39
39
  canvas: "var(--ph-canvas)",
40
40
  surface: "var(--ph-surface)",
41
+ inset: "var(--ph-surface-inset)",
42
+ raised: "var(--ph-surface-raised)",
43
+ overlay: "var(--ph-surface-overlay)",
41
44
  muted: "var(--ph-muted)",
42
45
  toolbar: "var(--ph-toolbar)",
43
46
  border: "var(--ph-border)",
47
+ "border-subtle": "var(--ph-border-subtle)",
44
48
  strong: "var(--ph-border-strong)",
45
49
  ink: "var(--ph-text-primary)",
46
50
  subtle: "var(--ph-text-secondary)",
@@ -54,6 +58,9 @@ const posthogThemePreset: Partial<Config> = {
54
58
  warning: "var(--ph-warning)",
55
59
  danger: "var(--ph-danger)",
56
60
  info: "var(--ph-info)",
61
+ selected: "var(--ph-selected-bg)",
62
+ "selected-ink": "var(--ph-selected-text)",
63
+ focus: "var(--ph-focus-ring)",
57
64
  "btn-primary-face": "var(--ph-primary-button-face)",
58
65
  "btn-primary-border": "var(--ph-primary-button-border)",
59
66
  "btn-primary-frame": "var(--ph-primary-frame-bg)",