@grantcodes/ui 2.12.1 → 2.15.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +5 -1
  3. package/custom-elements.json +295 -176
  4. package/package.json +11 -3
  5. package/src/components/accordion/accordion-item.css +14 -14
  6. package/src/components/accordion/accordion.css +1 -1
  7. package/src/components/app-bar/app-bar.component.js +2 -2
  8. package/src/components/app-bar/app-bar.css +68 -22
  9. package/src/components/app-bar/app-bar.stories.js +37 -0
  10. package/src/components/app-bar/app-bar.test.js +19 -0
  11. package/src/components/app-bar/nav-link.css +10 -11
  12. package/src/components/avatar/avatar.css +5 -6
  13. package/src/components/badge/badge.css +16 -15
  14. package/src/components/breadcrumb/breadcrumb.css +10 -11
  15. package/src/components/button/button.css +112 -24
  16. package/src/components/button/button.stories.js +37 -0
  17. package/src/components/button-group/button-group.css +4 -4
  18. package/src/components/card/card.css +25 -25
  19. package/src/components/code-preview/code-preview.css +6 -6
  20. package/src/components/container/container.css +2 -1
  21. package/src/components/container/container.stories.js +1 -1
  22. package/src/components/countdown/countdown.css +13 -13
  23. package/src/components/cta/cta.component.js +6 -5
  24. package/src/components/cta/cta.css +15 -23
  25. package/src/components/dialog/dialog.css +14 -14
  26. package/src/components/dropdown/dropdown.css +14 -14
  27. package/src/components/dropzone/dropzone.css +11 -12
  28. package/src/components/feature-list/feature-list.component.js +3 -2
  29. package/src/components/feature-list/feature-list.css +14 -20
  30. package/src/components/footer/footer-column.css +9 -10
  31. package/src/components/footer/footer.component.js +3 -2
  32. package/src/components/footer/footer.css +12 -18
  33. package/src/components/footer/footer.test.js +1 -1
  34. package/src/components/form-field/form-field.css +6 -6
  35. package/src/components/hero/hero.css +9 -9
  36. package/src/components/loading/loading.css +3 -3
  37. package/src/components/logo-cloud/logo-cloud.component.js +3 -2
  38. package/src/components/logo-cloud/logo-cloud.css +8 -16
  39. package/src/components/map/map.css +8 -8
  40. package/src/components/media-text/media-text.css +9 -9
  41. package/src/components/newsletter/newsletter.css +21 -21
  42. package/src/components/notice/notice.css +17 -17
  43. package/src/components/person/index.js +1 -0
  44. package/src/components/person/person.component.js +51 -0
  45. package/src/components/person/person.css +39 -0
  46. package/src/components/person/person.js +8 -0
  47. package/src/components/person/person.react.js +9 -0
  48. package/src/components/person/person.stories.js +59 -0
  49. package/src/components/person/person.test.js +69 -0
  50. package/src/components/pricing/pricing.component.js +3 -2
  51. package/src/components/pricing/pricing.css +33 -41
  52. package/src/components/sidebar/sidebar.css +21 -21
  53. package/src/components/stats/stats.component.js +3 -2
  54. package/src/components/stats/stats.css +13 -21
  55. package/src/components/tabs/internal/tabs-item.component.js +5 -0
  56. package/src/components/tabs/tabs.component.js +4 -2
  57. package/src/components/tabs/tabs.css +15 -15
  58. package/src/components/testimonials/testimonials.component.js +11 -24
  59. package/src/components/testimonials/testimonials.css +11 -36
  60. package/src/components/toast/toast.css +23 -24
  61. package/src/components/tooltip/tooltip.css +6 -6
  62. package/src/css/colors.stories.js +6 -6
  63. package/src/css/elements/a.css +4 -4
  64. package/src/css/elements/forms/input.css +27 -27
  65. package/src/css/elements/forms/label.css +1 -1
  66. package/src/css/elements/media/image.css +1 -0
  67. package/src/css/layers.stories.js +3 -3
  68. package/src/css/reset.css +3 -3
  69. package/src/css/themes/todomap.css +1 -1
  70. package/src/css/tokens.stories.js +16 -16
  71. package/src/css/typography.css +7 -7
  72. package/src/css/util/focus-ring.css +9 -9
  73. package/src/lib/styles/focus-ring.css +9 -9
  74. package/src/main.js +1 -0
  75. package/src/pages/agency.stories.js +5 -4
  76. package/src/pages/blog-post.stories.js +33 -50
  77. package/src/pages/saas-landing.stories.js +8 -7
  78. package/src/react.js +1 -0
@@ -8,40 +8,40 @@
8
8
  display: flex;
9
9
  flex-direction: row;
10
10
  align-items: flex-start;
11
- gap: var(--g-theme-spacing-md);
12
- padding: var(--g-theme-spacing-md);
13
- border-radius: var(--g-theme-border-radius-sm, 0.25rem);
11
+ gap: var(--g-spacing-md);
12
+ padding: var(--g-spacing-md);
13
+ border-radius: var(--g-border-radius-sm, 0.25rem);
14
14
  view-transition-name: notice;
15
15
  transition: opacity 0.5s;
16
16
  }
17
17
 
18
18
  .notice--info {
19
- color: var(--g-color-utility-blue-900);
20
- background-color: var(--g-color-utility-blue-100);
19
+ color: var(--g-color-content-utility-info);
20
+ background-color: var(--g-color-background-utility-info);
21
21
  }
22
22
 
23
23
  .notice--success {
24
- color: var(--g-color-utility-green-900);
25
- background-color: var(--g-color-utility-green-100);
24
+ color: var(--g-color-content-utility-success);
25
+ background-color: var(--g-color-background-utility-success);
26
26
  }
27
27
 
28
28
  .notice--warning {
29
- color: var(--g-color-utility-yellow-900);
30
- background-color: var(--g-color-utility-yellow-100);
29
+ color: var(--g-color-content-utility-warning);
30
+ background-color: var(--g-color-background-utility-warning);
31
31
  }
32
32
 
33
33
  .notice--error {
34
- color: var(--g-color-utility-red-900);
35
- background-color: var(--g-color-utility-red-100);
34
+ color: var(--g-color-content-utility-error);
35
+ background-color: var(--g-color-background-utility-error);
36
36
  }
37
37
 
38
38
  .notice__title {
39
- font-size: var(--g-theme-typography-body-default-font-size);
39
+ font-size: var(--g-typography-body-default-font-size);
40
40
  margin: 0;
41
41
  }
42
42
 
43
43
  .notice__icon {
44
- font-size: calc(var(--g-theme-typography-body-default-line-height) * 1em);
44
+ font-size: calc(var(--g-typography-body-default-line-height) * 1em);
45
45
  }
46
46
 
47
47
  .notice__content {
@@ -53,11 +53,11 @@
53
53
  color: inherit;
54
54
  opacity: 0.5;
55
55
  transition: 0.2s;
56
- font-size: calc(var(--g-theme-typography-body-default-line-height) * 1em);
56
+ font-size: calc(var(--g-typography-body-default-line-height) * 1em);
57
57
  line-height: 1;
58
- padding: var(--g-theme-spacing-sm);
59
- margin: calc(-1 * var(--g-theme-spacing-sm))
60
- calc(-1 * var(--g-theme-spacing-sm)) 0 0;
58
+ padding: var(--g-spacing-sm);
59
+ margin: calc(-1 * var(--g-spacing-sm))
60
+ calc(-1 * var(--g-spacing-sm)) 0 0;
61
61
  border: 0;
62
62
 
63
63
  &:hover,
@@ -0,0 +1 @@
1
+ export * from "./person.js";
@@ -0,0 +1,51 @@
1
+ import { LitElement, html } from "lit";
2
+ import { ifDefined } from "lit/directives/if-defined.js";
3
+ import personStyles from "./person.css" with { type: "css" };
4
+ import "../avatar/avatar.js";
5
+
6
+ export class GrantCodesPerson extends LitElement {
7
+ static properties = {
8
+ name: { type: String },
9
+ role: { type: String },
10
+ company: { type: String },
11
+ avatar: { type: String },
12
+ alt: { type: String },
13
+ size: { type: String },
14
+ };
15
+
16
+ static styles = [personStyles];
17
+
18
+ constructor() {
19
+ super();
20
+ this.name = "";
21
+ this.role = "";
22
+ this.company = "";
23
+ this.avatar = "";
24
+ this.alt = "";
25
+ this.size = "medium";
26
+ }
27
+
28
+ get meta() {
29
+ return [this.role, this.company].filter(Boolean).join(", ");
30
+ }
31
+
32
+ render() {
33
+ const meta = this.meta;
34
+
35
+ return html`
36
+ <div class="person">
37
+ <grantcodes-avatar
38
+ src=${ifDefined(this.avatar || undefined)}
39
+ name=${ifDefined(this.name || undefined)}
40
+ alt=${ifDefined(this.alt || undefined)}
41
+ size=${this.size}
42
+ ></grantcodes-avatar>
43
+ <div class="person__meta">
44
+ <cite class="person__name">${this.name}</cite>
45
+ ${meta ? html`<span class="person__details">${meta}</span>` : null}
46
+ <slot name="description" class="person__description"></slot>
47
+ </div>
48
+ </div>
49
+ `;
50
+ }
51
+ }
@@ -0,0 +1,39 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ :host {
8
+ display: block;
9
+ }
10
+
11
+ .person {
12
+ display: flex;
13
+ align-items: center;
14
+ gap: var(--g-spacing-sm);
15
+ }
16
+
17
+ .person__meta {
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: var(--g-spacing-xs);
21
+ min-inline-size: 0;
22
+ }
23
+
24
+ .person__name {
25
+ font: var(--g-typography-body-font);
26
+ font-style: normal;
27
+ color: var(--g-color-content-default);
28
+ }
29
+
30
+ .person__details {
31
+ font: var(--g-typography-body-sm-font);
32
+ color: var(--g-color-content-subtle);
33
+ }
34
+
35
+ ::slotted([slot="description"]) {
36
+ font: var(--g-typography-body-sm-font);
37
+ color: var(--g-color-content-subtle);
38
+ margin-block-start: var(--g-spacing-xs);
39
+ }
@@ -0,0 +1,8 @@
1
+ import { GrantCodesPerson } from "./person.component.js";
2
+
3
+ export * from "./person.component.js";
4
+ export default GrantCodesPerson;
5
+
6
+ if (!customElements.get("grantcodes-person")) {
7
+ customElements.define("grantcodes-person", GrantCodesPerson);
8
+ }
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { GrantCodesPerson } from "./person.js";
4
+
5
+ export const Person = createComponent({
6
+ tagName: "grantcodes-person",
7
+ elementClass: GrantCodesPerson,
8
+ react: React,
9
+ });
@@ -0,0 +1,59 @@
1
+ import { html } from "lit";
2
+ import { getStorybookHelpers } from "@wc-toolkit/storybook-helpers";
3
+ const { events, args, argTypes, template } =
4
+ getStorybookHelpers("grantcodes-person");
5
+ import "./person.js";
6
+
7
+ const meta = {
8
+ title: "Components/Person",
9
+ component: "grantcodes-person",
10
+ args: {
11
+ ...args,
12
+ name: "Tommy Tobasco",
13
+ role: "Designer",
14
+ company: "GrantCodes",
15
+ avatar: "https://placehold.co/160x160",
16
+ size: "small",
17
+ },
18
+ argTypes,
19
+ render: (storyArgs) => template(storyArgs),
20
+ parameters: {
21
+ actions: {
22
+ handles: events,
23
+ },
24
+ },
25
+ };
26
+
27
+ export default meta;
28
+
29
+ export const Default = {};
30
+
31
+ export const Initials = {
32
+ args: {
33
+ avatar: undefined,
34
+ },
35
+ };
36
+
37
+ export const WithDescription = {
38
+ args: {
39
+ name: "Sam Torres",
40
+ role: "CTO",
41
+ company: "Flowbase",
42
+ avatar: "https://i.pravatar.cc/80?img=12",
43
+ size: "medium",
44
+ },
45
+ render: (storyArgs) => html`
46
+ <grantcodes-person
47
+ name="${storyArgs.name}"
48
+ role="${storyArgs.role}"
49
+ company="${storyArgs.company}"
50
+ avatar="${storyArgs.avatar}"
51
+ size="${storyArgs.size}"
52
+ >
53
+ <span slot="description"
54
+ >Writes about engineering culture, distributed teams, and systems
55
+ thinking.</span
56
+ >
57
+ </grantcodes-person>
58
+ `,
59
+ };
@@ -0,0 +1,69 @@
1
+ import { afterEach, describe, it } from "node:test";
2
+ import { strict as assert } from "node:assert";
3
+ import { cleanup, fixture } from "../../test-utils/index.js";
4
+ import "./person.js";
5
+
6
+ describe("Person Component", () => {
7
+ let element;
8
+
9
+ afterEach(() => {
10
+ cleanup(element);
11
+ });
12
+
13
+ it("should render name and details", async () => {
14
+ element = await fixture("grantcodes-person", {
15
+ name: "Jane Doe",
16
+ role: "Designer",
17
+ company: "GrantCodes",
18
+ });
19
+
20
+ assert.strictEqual(
21
+ element.shadowRoot.querySelector(".person__name")?.textContent,
22
+ "Jane Doe",
23
+ );
24
+ assert.strictEqual(
25
+ element.shadowRoot.querySelector(".person__details")?.textContent,
26
+ "Designer, GrantCodes",
27
+ );
28
+ });
29
+
30
+ it("should omit details when role and company are missing", async () => {
31
+ element = await fixture("grantcodes-person", {
32
+ name: "Jane Doe",
33
+ });
34
+
35
+ assert.equal(
36
+ element.shadowRoot.querySelector(".person__details"),
37
+ null,
38
+ );
39
+ });
40
+
41
+ it("should render content in the description slot", async () => {
42
+ element = await fixture("grantcodes-person", {
43
+ name: "Jane Doe",
44
+ });
45
+
46
+ const description = document.createElement("span");
47
+ description.setAttribute("slot", "description");
48
+ description.textContent = "A short bio about Jane";
49
+ element.appendChild(description);
50
+
51
+ await element.updateComplete;
52
+
53
+ const slot = element.shadowRoot.querySelector(
54
+ 'slot[name="description"]',
55
+ );
56
+ assert.ok(slot, "description slot should exist");
57
+
58
+ const assignedNodes = slot.assignedNodes({ flatten: true });
59
+ const hasText = assignedNodes.some(
60
+ (node) =>
61
+ node.textContent &&
62
+ node.textContent.includes("A short bio about Jane"),
63
+ );
64
+ assert.ok(
65
+ hasText,
66
+ "description slot should contain the projected text",
67
+ );
68
+ });
69
+ });
@@ -1,6 +1,7 @@
1
1
  import { LitElement, html } from "lit";
2
2
  import pricingStyles from "./pricing.css" with { type: "css" };
3
3
  import "../button/button.js";
4
+ import "../container/container.js";
4
5
 
5
6
  export class GrantCodesPricing extends LitElement {
6
7
  static styles = [pricingStyles];
@@ -43,7 +44,7 @@ export class GrantCodesPricing extends LitElement {
43
44
  const tiers = this._tiers;
44
45
  return html`
45
46
  <section class="pricing">
46
- <div class="pricing__container">
47
+ <grantcodes-container>
47
48
  ${
48
49
  this.title
49
50
  ? html`<h2 class="pricing__title">${this.title}</h2>`
@@ -112,7 +113,7 @@ export class GrantCodesPricing extends LitElement {
112
113
  `,
113
114
  )}
114
115
  </ul>
115
- </div>
116
+ </grantcodes-container>
116
117
  </section>
117
118
  `;
118
119
  }
@@ -9,35 +9,28 @@
9
9
  }
10
10
 
11
11
  .pricing {
12
- padding-block: var(--g-theme-spacing-3xl);
13
- padding-inline: var(--g-theme-spacing-md);
14
- }
15
-
16
- .pricing__container {
17
- max-width: 1200px;
18
- margin: 0 auto;
12
+ padding-block: var(--g-spacing-3xl);
19
13
  }
20
14
 
21
15
  .pricing__title {
22
- margin: 0 0 var(--g-theme-spacing-sm);
23
- font-size: var(--g-theme-typography-h4-font-size);
24
- font-weight: var(--g-theme-typography-h4-font-weight);
16
+ margin: 0 0 var(--g-spacing-sm);
17
+ font: var(--g-typography-h3-font);
25
18
  text-align: center;
26
- color: var(--g-theme-color-content-default);
19
+ color: var(--g-color-content-default);
27
20
  }
28
21
 
29
22
  .pricing__subtitle {
30
- margin: 0 auto var(--g-theme-spacing-2xl);
31
- font-size: var(--g-theme-typography-body-lg-font-size);
23
+ margin: 0 auto var(--g-spacing-2xl);
24
+ font: var(--g-typography-body-lg-font);
32
25
  text-align: center;
33
- color: var(--g-theme-color-content-subtle);
26
+ color: var(--g-color-content-subtle);
34
27
  max-width: 55ch;
35
28
  }
36
29
 
37
30
  .pricing__grid {
38
31
  display: grid;
39
32
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
40
- gap: var(--g-theme-spacing-lg);
33
+ gap: var(--g-spacing-lg);
41
34
  align-items: start;
42
35
  padding: 0;
43
36
  margin: 0;
@@ -47,58 +40,57 @@
47
40
  .pricing__tier {
48
41
  display: flex;
49
42
  flex-direction: column;
50
- gap: var(--g-theme-spacing-lg);
51
- padding: var(--g-theme-spacing-xl);
52
- border: 1px solid var(--g-theme-color-border-default);
53
- border-radius: var(--g-theme-border-radius-md, 0.5rem);
54
- background: var(--g-theme-color-background-default);
43
+ gap: var(--g-spacing-lg);
44
+ padding: var(--g-spacing-xl);
45
+ border: 1px solid var(--g-color-border-default);
46
+ border-radius: var(--g-border-radius-md, 0.5rem);
47
+ background: var(--g-color-background-default);
55
48
  }
56
49
 
57
50
  .pricing__tier--highlighted {
58
- border-color: var(--g-theme-color-border-primary, #7c3aed);
59
- background: var(--g-theme-color-background-subtle);
60
- box-shadow: var(--g-theme-shadow-lg);
51
+ border-color: var(--g-color-border-primary);
52
+ background: var(--g-color-background-subtle);
53
+ box-shadow: var(--g-box-shadow-lg);
61
54
  }
62
55
 
63
56
  .pricing__tier-header {
64
57
  display: flex;
65
58
  flex-direction: column;
66
- gap: var(--g-theme-spacing-sm);
59
+ gap: var(--g-spacing-sm);
67
60
  }
68
61
 
69
62
  .pricing__tier-name {
70
63
  margin: 0;
71
- font-size: var(--g-theme-typography-body-lg-font-size);
72
- font-weight: var(--g-theme-typography-label-lg-font-weight);
73
- color: var(--g-theme-color-content-default);
64
+ font: var(--g-typography-body-lg-font);
65
+ color: var(--g-color-content-default);
74
66
  }
75
67
 
76
68
  .pricing__price-wrap {
77
69
  display: flex;
78
70
  align-items: baseline;
79
- gap: var(--g-theme-spacing-xs);
71
+ gap: var(--g-spacing-xs);
80
72
  }
81
73
 
82
74
  .pricing__price {
83
75
  font: var(--g-typography-h2-font);
84
- color: var(--g-theme-color-content-default);
76
+ color: var(--g-color-content-default);
85
77
  }
86
78
 
87
79
  .pricing__period {
88
- font-size: var(--g-theme-typography-body-default-font-size);
89
- color: var(--g-theme-color-content-subtle);
80
+ font-size: var(--g-typography-body-default-font-size);
81
+ color: var(--g-color-content-subtle);
90
82
  }
91
83
 
92
84
  .pricing__tier-desc {
93
85
  margin: 0;
94
- font: var(--g-theme-typography-body-sm);
95
- color: var(--g-theme-color-content-subtle);
86
+ font: var(--g-typography-body-sm);
87
+ color: var(--g-color-content-subtle);
96
88
  }
97
89
 
98
90
  .pricing__features {
99
91
  display: flex;
100
92
  flex-direction: column;
101
- gap: var(--g-theme-spacing-sm);
93
+ gap: var(--g-spacing-sm);
102
94
  padding: 0;
103
95
  margin: 0;
104
96
  list-style: none;
@@ -108,24 +100,24 @@
108
100
  .pricing__feature {
109
101
  display: flex;
110
102
  align-items: center;
111
- gap: var(--g-theme-spacing-sm);
112
- font-size: var(--g-theme-typography-body-default-font-size);
113
- color: var(--g-theme-color-content-default);
103
+ gap: var(--g-spacing-sm);
104
+ font-size: var(--g-typography-body-default-font-size);
105
+ color: var(--g-color-content-default);
114
106
  }
115
107
 
116
108
  .pricing__feature--excluded {
117
- color: var(--g-theme-color-content-subtle);
109
+ color: var(--g-color-content-subtle);
118
110
  text-decoration: line-through;
119
111
  }
120
112
 
121
113
  .pricing__feature-icon {
122
- font: var(--g-theme-typography-body-sm);
123
- color: var(--g-theme-color-content-primary, #7c3aed);
114
+ font: var(--g-typography-body-sm);
115
+ color: var(--g-color-content-primary);
124
116
  flex-shrink: 0;
125
117
  }
126
118
 
127
119
  .pricing__feature--excluded .pricing__feature-icon {
128
- color: var(--g-theme-color-content-subtle);
120
+ color: var(--g-color-content-subtle);
129
121
  }
130
122
 
131
123
  .pricing__cta {
@@ -12,8 +12,8 @@
12
12
  position: relative;
13
13
  inline-size: var(--sidebar-width, 280px);
14
14
  block-size: 100%;
15
- background-color: var(--g-theme-color-background-default);
16
- border-inline-end: 1px solid var(--g-theme-color-border-default);
15
+ background-color: var(--g-color-background-default);
16
+ border-inline-end: 1px solid var(--g-color-border-default);
17
17
  overflow-y: auto;
18
18
  transition: inline-size 0.3s ease;
19
19
  flex-shrink: 0;
@@ -21,7 +21,7 @@
21
21
 
22
22
  .sidebar--right {
23
23
  border-inline-end: none;
24
- border-inline-start: 1px solid var(--g-theme-color-border-default);
24
+ border-inline-start: 1px solid var(--g-color-border-default);
25
25
  }
26
26
 
27
27
  .sidebar--collapsed {
@@ -29,7 +29,7 @@
29
29
  }
30
30
 
31
31
  .sidebar--collapsed .sidebar__content {
32
- padding-inline: var(--g-theme-spacing-sm);
32
+ padding-inline: var(--g-spacing-sm);
33
33
  }
34
34
 
35
35
  .sidebar--collapsed
@@ -48,23 +48,23 @@
48
48
  all: unset;
49
49
  display: none;
50
50
  position: fixed;
51
- inset-block-start: var(--g-theme-spacing-md);
52
- inset-inline-start: var(--g-theme-spacing-md);
51
+ inset-block-start: var(--g-spacing-md);
52
+ inset-inline-start: var(--g-spacing-md);
53
53
  z-index: 1001;
54
54
  inline-size: 2.5rem;
55
55
  block-size: 2.5rem;
56
56
  align-items: center;
57
57
  justify-content: center;
58
- background-color: var(--g-theme-color-background-default);
59
- border: 1px solid var(--g-theme-color-border-default);
60
- border-radius: var(--g-theme-border-radius-md);
58
+ background-color: var(--g-color-background-default);
59
+ border: 1px solid var(--g-color-border-default);
60
+ border-radius: var(--g-border-radius-md);
61
61
  cursor: pointer;
62
- font-size: var(--g-theme-typography-h5-font-size);
62
+ font-size: var(--g-typography-h5-font-size);
63
63
  transition: all 0.2s ease;
64
64
  }
65
65
 
66
66
  .sidebar__mobile-toggle:hover {
67
- background-color: var(--g-theme-color-background-subtle-hover);
67
+ background-color: var(--g-color-background-subtle-hover);
68
68
  }
69
69
 
70
70
  /* Show mobile toggle on small screens */
@@ -127,29 +127,29 @@
127
127
  .sidebar__toggle {
128
128
  all: unset;
129
129
  position: absolute;
130
- inset-block-start: var(--g-theme-spacing-md);
131
- inset-inline-end: var(--g-theme-spacing-sm);
130
+ inset-block-start: var(--g-spacing-md);
131
+ inset-inline-end: var(--g-spacing-sm);
132
132
  inline-size: 1.5rem;
133
133
  block-size: 1.5rem;
134
134
  display: flex;
135
135
  align-items: center;
136
136
  justify-content: center;
137
- background-color: var(--g-theme-color-background-default);
138
- border: 1px solid var(--g-theme-color-border-default);
139
- border-radius: var(--g-theme-border-radius-md);
137
+ background-color: var(--g-color-background-default);
138
+ border: 1px solid var(--g-color-border-default);
139
+ border-radius: var(--g-border-radius-md);
140
140
  cursor: pointer;
141
- font-size: var(--g-typography-font-size-14);
141
+ font-size: var(--g-typography-body-sm-font-size);
142
142
  transition: all 0.2s ease;
143
143
  z-index: 10;
144
144
  }
145
145
 
146
146
  .sidebar__toggle:hover {
147
- background-color: var(--g-theme-color-background-subtle-hover);
147
+ background-color: var(--g-color-background-subtle-hover);
148
148
  }
149
149
 
150
150
  .sidebar--right .sidebar__toggle {
151
151
  inset-inline-end: auto;
152
- inset-inline-start: var(--g-theme-spacing-sm);
152
+ inset-inline-start: var(--g-spacing-sm);
153
153
  }
154
154
 
155
155
  .sidebar--right.sidebar--collapsed .sidebar__toggle {
@@ -166,8 +166,8 @@
166
166
 
167
167
  /* Content */
168
168
  .sidebar__content {
169
- padding-block: var(--g-theme-spacing-md);
170
- padding-inline: var(--g-theme-spacing-md);
169
+ padding-block: var(--g-spacing-md);
170
+ padding-inline: var(--g-spacing-md);
171
171
  }
172
172
 
173
173
  /* View transitions */
@@ -1,5 +1,6 @@
1
1
  import { LitElement, html } from "lit";
2
2
  import statsStyles from "./stats.css" with { type: "css" };
3
+ import "../container/container.js";
3
4
 
4
5
  export class GrantCodesStats extends LitElement {
5
6
  static styles = [statsStyles];
@@ -41,7 +42,7 @@ export class GrantCodesStats extends LitElement {
41
42
  const items = this._items;
42
43
  return html`
43
44
  <section class="stats">
44
- <div class="stats__container">
45
+ <grantcodes-container>
45
46
  ${
46
47
  this.title
47
48
  ? html`<h2 class="stats__title">${this.title}</h2>`
@@ -66,7 +67,7 @@ export class GrantCodesStats extends LitElement {
66
67
  `,
67
68
  )}
68
69
  </ul>
69
- </div>
70
+ </grantcodes-container>
70
71
  </section>
71
72
  `;
72
73
  }
@@ -9,28 +9,21 @@
9
9
  }
10
10
 
11
11
  .stats {
12
- padding-block: var(--g-theme-spacing-3xl);
13
- padding-inline: var(--g-theme-spacing-md);
14
- background: var(--g-theme-color-background-subtle);
15
- }
16
-
17
- .stats__container {
18
- max-width: 1200px;
19
- margin: 0 auto;
12
+ padding-block: var(--g-spacing-3xl);
13
+ background: var(--g-color-background-subtle);
20
14
  }
21
15
 
22
16
  .stats__title {
23
- margin: 0 0 var(--g-theme-spacing-xl);
24
- font-size: var(--g-theme-typography-h4-font-size);
25
- font-weight: var(--g-theme-typography-h4-font-weight);
17
+ margin: 0 0 var(--g-spacing-xl);
18
+ font: var(--g-typography-h3-font);
26
19
  text-align: center;
27
- color: var(--g-theme-color-content-default);
20
+ color: var(--g-color-content-default);
28
21
  }
29
22
 
30
23
  .stats__grid {
31
24
  display: grid;
32
25
  grid-template-columns: repeat(var(--columns, 4), 1fr);
33
- gap: var(--g-theme-spacing-xl);
26
+ gap: var(--g-spacing-xl);
34
27
  padding: 0;
35
28
  margin: 0;
36
29
  list-style: none;
@@ -46,23 +39,22 @@
46
39
  .stats__item {
47
40
  display: flex;
48
41
  flex-direction: column;
49
- gap: var(--g-theme-spacing-xs);
42
+ gap: var(--g-spacing-xs);
50
43
  }
51
44
 
52
45
  .stats__value {
53
- font: var(--g-theme-typography-h2);
46
+ font: var(--g-typography-h2);
54
47
  white-space: nowrap;
55
48
  line-height: 1;
56
- color: var(--g-theme-color-content-primary, #7c3aed);
49
+ color: var(--g-color-content-primary, #7c3aed);
57
50
  }
58
51
 
59
52
  .stats__label {
60
- font-size: var(--g-theme-typography-label-default-font-size);
61
- font-weight: var(--g-theme-typography-label-default-font-weight);
62
- color: var(--g-theme-color-content-default);
53
+ font: var(--g-typography-h5-font);
54
+ color: var(--g-color-content-default);
63
55
  }
64
56
 
65
57
  .stats__context {
66
- font-size: var(--g-theme-typography-body-sm-font-size);
67
- color: var(--g-theme-color-content-subtle);
58
+ font: var(--g-typography-body-sm-font);
59
+ color: var(--g-color-content-subtle);
68
60
  }