@sekiui/elements 0.0.38 → 0.0.40

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 (88) hide show
  1. package/dist/cjs/{index-CQBxP9_b.js → index-DwgP2ssn.js} +26 -3
  2. package/dist/cjs/index.cjs.js +1 -1
  3. package/dist/cjs/loader.cjs.js +2 -2
  4. package/dist/cjs/seki-button.cjs.entry.js +1 -1
  5. package/dist/cjs/seki-field-description.cjs.entry.js +6 -6
  6. package/dist/cjs/seki-field-error.cjs.entry.js +6 -6
  7. package/dist/cjs/seki-field-group.cjs.entry.js +2 -2
  8. package/dist/cjs/seki-field-label.cjs.entry.js +3 -2
  9. package/dist/cjs/seki-field-legend.cjs.entry.js +2 -2
  10. package/dist/cjs/seki-field.cjs.entry.js +2 -2
  11. package/dist/cjs/seki-fieldset.cjs.entry.js +2 -2
  12. package/dist/cjs/seki-input.cjs.entry.js +2 -2
  13. package/dist/cjs/seki-skeleton.cjs.entry.js +2 -2
  14. package/dist/cjs/seki-switch.cjs.entry.js +1 -1
  15. package/dist/cjs/sekiui.cjs.js +2 -2
  16. package/dist/collection/components/field/seki-field.js +2 -2
  17. package/dist/collection/components/field-description/seki-field-description.js +7 -7
  18. package/dist/collection/components/field-error/seki-field-error.js +7 -7
  19. package/dist/collection/components/field-group/seki-field-group.js +1 -1
  20. package/dist/collection/components/field-label/seki-field-label.js +2 -1
  21. package/dist/collection/components/field-legend/seki-field-legend.js +1 -1
  22. package/dist/collection/components/fieldset/seki-fieldset.js +1 -1
  23. package/dist/collection/components/input/seki-input.js +1 -1
  24. package/dist/collection/components/skeleton/seki-skeleton.js +1 -1
  25. package/dist/collection/styles/tokens/typography-tokens.js +8 -0
  26. package/dist/collection/styles/tokens/typography-tokens.ts +9 -0
  27. package/dist/collection/styles/typography/base.css +137 -0
  28. package/dist/collection/styles/typography/index.css +9 -0
  29. package/dist/collection/styles/typography/prose.css +132 -0
  30. package/dist/collection/styles/typography/tokens.css +77 -0
  31. package/dist/collection/styles/typography/variants.css +25 -0
  32. package/dist/components/index.js +2 -2
  33. package/dist/components/{p-ag6agK1v.js → p-qBYH2h9w.js} +26 -3
  34. package/dist/components/seki-button.js +1 -1
  35. package/dist/components/seki-field-description.js +7 -7
  36. package/dist/components/seki-field-error.js +7 -7
  37. package/dist/components/seki-field-group.js +2 -2
  38. package/dist/components/seki-field-label.js +3 -2
  39. package/dist/components/seki-field-legend.js +2 -2
  40. package/dist/components/seki-field.js +2 -2
  41. package/dist/components/seki-fieldset.js +2 -2
  42. package/dist/components/seki-input.js +2 -2
  43. package/dist/components/seki-skeleton.js +2 -2
  44. package/dist/esm/{index-xoBNLQoq.js → index-DVaKDPWs.js} +26 -3
  45. package/dist/esm/index.js +1 -1
  46. package/dist/esm/loader.js +3 -3
  47. package/dist/esm/seki-button.entry.js +1 -1
  48. package/dist/esm/seki-field-description.entry.js +6 -6
  49. package/dist/esm/seki-field-error.entry.js +6 -6
  50. package/dist/esm/seki-field-group.entry.js +2 -2
  51. package/dist/esm/seki-field-label.entry.js +3 -2
  52. package/dist/esm/seki-field-legend.entry.js +2 -2
  53. package/dist/esm/seki-field.entry.js +2 -2
  54. package/dist/esm/seki-fieldset.entry.js +2 -2
  55. package/dist/esm/seki-input.entry.js +2 -2
  56. package/dist/esm/seki-skeleton.entry.js +2 -2
  57. package/dist/esm/seki-switch.entry.js +1 -1
  58. package/dist/esm/sekiui.js +3 -3
  59. package/dist/sekiui/index.esm.js +1 -1
  60. package/dist/sekiui/p-4471a11b.entry.js +1 -0
  61. package/dist/sekiui/{p-17cdd420.entry.js → p-6e145af3.entry.js} +1 -1
  62. package/dist/sekiui/p-90ac85ad.entry.js +1 -0
  63. package/dist/sekiui/{p-96f49bc5.entry.js → p-9798772a.entry.js} +1 -1
  64. package/dist/sekiui/{p-0226e4f7.entry.js → p-9b51119c.entry.js} +1 -1
  65. package/dist/sekiui/p-DVaKDPWs.js +2 -0
  66. package/dist/sekiui/{p-d25987f6.entry.js → p-b02ec16d.entry.js} +1 -1
  67. package/dist/sekiui/{p-d09b94a2.entry.js → p-b47f6624.entry.js} +1 -1
  68. package/dist/sekiui/p-bfb09d37.entry.js +1 -0
  69. package/dist/sekiui/p-cc81fc67.entry.js +1 -0
  70. package/dist/sekiui/{p-72741840.entry.js → p-e57f16b3.entry.js} +1 -1
  71. package/dist/sekiui/{p-03487f1f.entry.js → p-ea04d3b5.entry.js} +1 -1
  72. package/dist/sekiui/sekiui.esm.js +1 -1
  73. package/dist/sekiui/styles/tokens/typography-tokens.ts +9 -0
  74. package/dist/sekiui/styles/typography/base.css +137 -0
  75. package/dist/sekiui/styles/typography/index.css +9 -0
  76. package/dist/sekiui/styles/typography/prose.css +132 -0
  77. package/dist/sekiui/styles/typography/tokens.css +77 -0
  78. package/dist/sekiui/styles/typography/variants.css +25 -0
  79. package/dist/types/components/field-description/seki-field-description.d.ts +1 -1
  80. package/dist/types/components/field-error/seki-field-error.d.ts +1 -1
  81. package/dist/types/components.d.ts +10 -10
  82. package/dist/types/styles/tokens/typography-tokens.d.ts +6 -0
  83. package/package.json +7 -5
  84. package/dist/sekiui/p-0f6ca3b1.entry.js +0 -1
  85. package/dist/sekiui/p-3787d562.entry.js +0 -1
  86. package/dist/sekiui/p-4cf3ac27.entry.js +0 -1
  87. package/dist/sekiui/p-a9601821.entry.js +0 -1
  88. package/dist/sekiui/p-xoBNLQoq.js +0 -2
@@ -13,12 +13,12 @@ export class SekiFieldDescription {
13
13
  this.componentId = '';
14
14
  }
15
15
  componentWillLoad() {
16
- this.componentId = this.id || generateId();
16
+ this.componentId = this.descriptorId || generateId();
17
17
  }
18
18
  componentWillUpdate() {
19
- // Update componentId if id prop changes
20
- if (this.id && this.id !== this.componentId) {
21
- this.componentId = this.id;
19
+ // Update componentId if descriptorId prop changes
20
+ if (this.descriptorId && this.descriptorId !== this.componentId) {
21
+ this.componentId = this.descriptorId;
22
22
  }
23
23
  }
24
24
  /**
@@ -29,7 +29,7 @@ export class SekiFieldDescription {
29
29
  return this.componentId;
30
30
  }
31
31
  render() {
32
- return (h("div", { key: 'ddd92769c6eed18b11eacd6005e1820a6abf1aa5', id: this.componentId, class: "description" }, h("slot", { key: '6da6a0a3300cf2bdfb20ae9c6cf972ab0f014726' })));
32
+ return (h("div", { key: '8dd37eb65e7c8c7608b070762681bb8586c53c9e', id: this.componentId, class: "description" }, h("slot", { key: '508d77bad3bf08741dc4c4e6e0f6167d7bf11688' })));
33
33
  }
34
34
  static get is() { return "seki-field-description"; }
35
35
  static get encapsulation() { return "shadow"; }
@@ -45,7 +45,7 @@ export class SekiFieldDescription {
45
45
  }
46
46
  static get properties() {
47
47
  return {
48
- "id": {
48
+ "descriptorId": {
49
49
  "type": "string",
50
50
  "mutable": false,
51
51
  "complexType": {
@@ -62,7 +62,7 @@ export class SekiFieldDescription {
62
62
  "getter": false,
63
63
  "setter": false,
64
64
  "reflect": false,
65
- "attribute": "id"
65
+ "attribute": "descriptor-id"
66
66
  }
67
67
  };
68
68
  }
@@ -22,13 +22,13 @@ export class SekiFieldError {
22
22
  this.previousVisible = true;
23
23
  }
24
24
  componentWillLoad() {
25
- this.componentId = this.id || generateId();
25
+ this.componentId = this.errorId || generateId();
26
26
  this.previousVisible = this.visible;
27
27
  }
28
28
  componentWillUpdate() {
29
- // Update componentId if id prop changes
30
- if (this.id && this.id !== this.componentId) {
31
- this.componentId = this.id;
29
+ // Update componentId if errorId prop changes
30
+ if (this.errorId && this.errorId !== this.componentId) {
31
+ this.componentId = this.errorId;
32
32
  }
33
33
  }
34
34
  handleVisibleChange(newValue) {
@@ -49,7 +49,7 @@ export class SekiFieldError {
49
49
  }
50
50
  render() {
51
51
  const style = this.visible ? {} : { display: 'none' };
52
- return (h("div", { key: 'ce75b19705fe6cfe21a9815f321a6e8fc95edcb5', id: this.componentId, class: "error", "aria-live": "polite", style: style }, h("slot", { key: '82f038546edafec2a383031941d928e8a6a623dd' })));
52
+ return (h("div", { key: 'aa140f9212c3f47d50113f77af0c33cf106177ed', id: this.componentId, class: "error", "aria-live": "polite", style: style }, h("slot", { key: '6fcdf53d218e817fa12792fadb3a946229b2dcf3' })));
53
53
  }
54
54
  static get is() { return "seki-field-error"; }
55
55
  static get encapsulation() { return "shadow"; }
@@ -65,7 +65,7 @@ export class SekiFieldError {
65
65
  }
66
66
  static get properties() {
67
67
  return {
68
- "id": {
68
+ "errorId": {
69
69
  "type": "string",
70
70
  "mutable": false,
71
71
  "complexType": {
@@ -82,7 +82,7 @@ export class SekiFieldError {
82
82
  "getter": false,
83
83
  "setter": false,
84
84
  "reflect": false,
85
- "attribute": "id"
85
+ "attribute": "error-id"
86
86
  },
87
87
  "visible": {
88
88
  "type": "boolean",
@@ -11,7 +11,7 @@ export class SekiFieldGroup {
11
11
  const style = {
12
12
  '--seki-field-group-gap': this.gap,
13
13
  };
14
- return (h("div", { key: '1ed413559e067c467933876185a446761c14a8fb', class: "field-group", style: style }, h("slot", { key: 'a8d7c2fd5bd89f89c76620ae6a6c4c9fbab5c36e' })));
14
+ return (h("div", { key: '479c3e657ce82b3ab5243b10ef5cccd26e17478b', class: "field-group", style: style }, h("slot", { key: '15d665a73e3d2d2eca773bdb216b4276feaf2071' })));
15
15
  }
16
16
  static get is() { return "seki-field-group"; }
17
17
  static get encapsulation() { return "shadow"; }
@@ -8,7 +8,8 @@ export class SekiFieldLabel {
8
8
  this.required = false;
9
9
  }
10
10
  render() {
11
- return (h("label", { key: '5a216d28d5324958cb9ba213c6ce4ec06b9262d6', htmlFor: this.htmlFor }, h("slot", { key: '7445f98ff6ba049e8f8a1d89d1f8c278a2a49047' }), this.required && h("span", { key: 'a42b90d3c61506b0d4659d7539f60f7eb318a12e', class: "required-indicator" }, " *")));
11
+ const labelProps = this.htmlFor ? { for: this.htmlFor } : {};
12
+ return (h("label", Object.assign({ key: 'f9f2b492f80fe46110f4f8766c88a1aec53342be' }, labelProps), h("slot", { key: '35564e4ea62df56807c7d2a90a4f9e66a7c09c4c' }), this.required && h("span", { key: '8f6f7a454790995b9d968fb1e0078fb9951fcba6', class: "required-indicator" }, " *")));
12
13
  }
13
14
  static get is() { return "seki-field-label"; }
14
15
  static get encapsulation() { return "shadow"; }
@@ -1,7 +1,7 @@
1
1
  import { h } from "@stencil/core";
2
2
  export class SekiFieldLegend {
3
3
  render() {
4
- return (h("legend", { key: 'd21cea8cee39d4c180c75b39271c0d027fddf70d' }, h("slot", { key: '1b50582352cbfb9836a0cb075ea1ffaa9908ec9a' })));
4
+ return (h("legend", { key: '34aa222c29443bbded4ba43c8592212e5328fb52' }, h("slot", { key: '59fddfd2160e0c3a512dc92f38465ed015b860ca' })));
5
5
  }
6
6
  static get is() { return "seki-field-legend"; }
7
7
  static get encapsulation() { return "shadow"; }
@@ -8,7 +8,7 @@ export class SekiFieldset {
8
8
  this.disabled = false;
9
9
  }
10
10
  render() {
11
- return (h("fieldset", { key: '4fd921680b8dcbb677eefaf4d29120e2901c7f51', disabled: this.disabled, class: "fieldset" }, h("slot", { key: '11b9e963faecd9fc6af387eb22689a91e482c183', name: "legend" }), h("div", { key: 'f1d6a247fc0615b1b734a89d2ab7cbac54e810e8', class: "fieldset-content" }, h("slot", { key: '93b1d28863b927d08921ebba2b694ec5bc242410' }))));
11
+ return (h("fieldset", { key: '8d7a47b3f837d34c11b905f64a35fe167fd9b16f', disabled: this.disabled, class: "fieldset" }, h("slot", { key: 'b620fe4fe86449d3cfb9e47db6837dbc5a8ad771', name: "legend" }), h("div", { key: 'd122e6eb636e8742cb8ac429c5879cb54bfce392', class: "fieldset-content" }, h("slot", { key: 'ea7f4dbea6e07c9b9cf68d7f3be5ea40500ed11f' }))));
12
12
  }
13
13
  static get is() { return "seki-fieldset"; }
14
14
  static get encapsulation() { return "shadow"; }
@@ -48,7 +48,7 @@ export class SekiInput {
48
48
  };
49
49
  }
50
50
  render() {
51
- return (h("input", { key: '6850324b28178a320ee55533501fec32dd2c97d7', type: this.type, value: this.value, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, required: this.required, name: this.name, autocomplete: this.autocomplete, min: this.min, max: this.max, step: this.step, pattern: this.pattern, minlength: this.minlength, maxlength: this.maxlength, class: `input input--${this.size}${this.invalid ? ' input--invalid' : ''}`, "aria-label": this.ariaLabel, "aria-describedby": this.ariaDescribedby, "aria-invalid": this.invalid ? 'true' : null, "aria-disabled": this.disabled ? 'true' : null, onInput: this.handleInput, onChange: this.handleChange, onFocus: this.handleFocus, onBlur: this.handleBlur }));
51
+ return (h("input", { key: '95dc9689258f013b3eeda42f2d0df353cc3d0edc', type: this.type, value: this.value, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, required: this.required, name: this.name, autocomplete: this.autocomplete, min: this.min, max: this.max, step: this.step, pattern: this.pattern, minlength: this.minlength, maxlength: this.maxlength, class: `input input--${this.size}${this.invalid ? ' input--invalid' : ''}`, "aria-label": this.ariaLabel, "aria-describedby": this.ariaDescribedby, "aria-invalid": this.invalid ? 'true' : null, "aria-disabled": this.disabled ? 'true' : null, onInput: this.handleInput, onChange: this.handleChange, onFocus: this.handleFocus, onBlur: this.handleBlur }));
52
52
  }
53
53
  static get is() { return "seki-input"; }
54
54
  static get encapsulation() { return "shadow"; }
@@ -15,7 +15,7 @@ export class SekiSkeleton {
15
15
  }
16
16
  }
17
17
  render() {
18
- return (h("div", { key: '12cf6b0b060e26aa0b991890e2667139fa43b507', class: "skeleton", part: "skeleton", role: "status", "aria-busy": "true", "aria-label": this.ariaLabel || undefined }));
18
+ return (h("div", { key: 'fb7e3abe8762cca61f0f950d6fb051c8ac30cec8', class: "skeleton", part: "skeleton", role: "status", "aria-busy": "true", "aria-label": this.ariaLabel || undefined }));
19
19
  }
20
20
  static get is() { return "seki-skeleton"; }
21
21
  static get encapsulation() { return "shadow"; }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Typography Design Tokens
3
+ * TypeScript exports for programmatic token access
4
+ * Reference: specs/012-time-to-do/research.md Section 7
5
+ */
6
+ export const typographyTokens = {
7
+ // Token definitions will be added in T028
8
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Typography Design Tokens
3
+ * TypeScript exports for programmatic token access
4
+ * Reference: specs/012-time-to-do/research.md Section 7
5
+ */
6
+
7
+ export const typographyTokens = {
8
+ // Token definitions will be added in T028
9
+ };
@@ -0,0 +1,137 @@
1
+ /* Typography Base Classes
2
+ * Heading classes (h1-h4), paragraph, blockquote, list, table, code
3
+ * Reference: specs/012-time-to-do/data-model.md
4
+ */
5
+
6
+ /* Heading Classes */
7
+ .seki-h1 {
8
+ scroll-margin-top: 5rem;
9
+ font-size: clamp(var(--seki-typography-h1-size-min), 5vw, var(--seki-typography-h1-size-max));
10
+ font-weight: var(--seki-typography-h1-weight);
11
+ font-family: var(--seki-typography-heading-font);
12
+ letter-spacing: var(--seki-typography-heading-spacing);
13
+ color: var(--seki-color-text);
14
+ text-wrap: balance;
15
+ }
16
+
17
+ .seki-h2 {
18
+ margin-top: 2.5rem;
19
+ scroll-margin-top: 5rem;
20
+ border-bottom: 1px solid var(--seki-color-border);
21
+ padding-bottom: 0.5rem;
22
+ font-size: clamp(var(--seki-typography-h2-size-min), 4vw, var(--seki-typography-h2-size-max));
23
+ font-weight: var(--seki-typography-h2-weight);
24
+ font-family: var(--seki-typography-heading-font);
25
+ letter-spacing: var(--seki-typography-heading-spacing);
26
+ color: var(--seki-color-text);
27
+ transition: color 200ms;
28
+ }
29
+
30
+ .seki-h2:first-child {
31
+ margin-top: 0;
32
+ }
33
+
34
+ .seki-h3 {
35
+ margin-top: 2rem;
36
+ scroll-margin-top: 5rem;
37
+ font-size: clamp(var(--seki-typography-h3-size-min), 3.5vw, var(--seki-typography-h3-size-max));
38
+ font-weight: var(--seki-typography-h3-weight);
39
+ font-family: var(--seki-typography-heading-font);
40
+ letter-spacing: var(--seki-typography-heading-spacing);
41
+ color: var(--seki-color-text);
42
+ }
43
+
44
+ .seki-h4 {
45
+ margin-top: 1.5rem;
46
+ scroll-margin-top: 5rem;
47
+ font-size: clamp(var(--seki-typography-h4-size-min), 3vw, var(--seki-typography-h4-size-max));
48
+ font-weight: var(--seki-typography-h4-weight);
49
+ font-family: var(--seki-typography-heading-font);
50
+ letter-spacing: var(--seki-typography-heading-spacing);
51
+ color: var(--seki-color-text);
52
+ }
53
+
54
+ /* Paragraph Classes */
55
+ .seki-p {
56
+ font-family: var(--seki-typography-body-font);
57
+ font-size: var(--seki-font-size-base);
58
+ font-weight: var(--seki-font-weight-normal);
59
+ line-height: var(--seki-typography-body-line-height);
60
+ color: var(--seki-color-text);
61
+ }
62
+
63
+ .seki-p:not(:first-child) {
64
+ margin-top: 1.5rem;
65
+ }
66
+
67
+ .seki-lead {
68
+ font-family: var(--seki-typography-body-font);
69
+ font-size: clamp(var(--seki-font-size-lg), 3vw, var(--seki-font-size-xl));
70
+ color: var(--seki-color-text-muted);
71
+ line-height: var(--seki-typography-body-line-height);
72
+ }
73
+
74
+ /* Blockquote Class */
75
+ .seki-blockquote {
76
+ margin-top: 1.5rem;
77
+ border-left: 2px solid var(--seki-color-border);
78
+ padding-left: 1.5rem;
79
+ font-style: italic;
80
+ color: var(--seki-color-text-muted);
81
+ font-family: var(--seki-typography-body-font);
82
+ }
83
+
84
+ /* List Class */
85
+ .seki-list {
86
+ margin: 1.5rem 0;
87
+ padding-left: 1.5rem;
88
+ font-family: var(--seki-typography-body-font);
89
+ color: var(--seki-color-text);
90
+ }
91
+
92
+ .seki-list > li {
93
+ margin-top: 0.5rem;
94
+ line-height: var(--seki-typography-body-line-height);
95
+ }
96
+
97
+ .seki-list > li::marker {
98
+ color: var(--seki-color-text-muted);
99
+ }
100
+
101
+ /* Table Class */
102
+ .seki-table {
103
+ width: 100%;
104
+ caption-side: bottom;
105
+ border-collapse: collapse;
106
+ margin: 1.5rem 0;
107
+ font-family: var(--seki-typography-body-font);
108
+ color: var(--seki-color-text);
109
+ }
110
+
111
+ .seki-table th {
112
+ border-bottom: 1px solid var(--seki-color-border);
113
+ padding: 0.75rem;
114
+ text-align: left;
115
+ font-weight: var(--seki-font-weight-semibold);
116
+ }
117
+
118
+ .seki-table td {
119
+ border-bottom: 1px solid var(--seki-color-border-subtle);
120
+ padding: 0.75rem;
121
+ text-align: left;
122
+ }
123
+
124
+ .seki-table tr:last-child td {
125
+ border-bottom: none;
126
+ }
127
+
128
+ /* Inline Code Class */
129
+ .seki-inline-code {
130
+ position: relative;
131
+ border-radius: 0.25rem;
132
+ background-color: var(--seki-color-muted);
133
+ padding: 0.125rem 0.375rem;
134
+ font-family: var(--seki-typography-code-font);
135
+ font-size: 0.875em; /* 87.5% of parent - inherits parent size then scales */
136
+ font-weight: var(--seki-font-weight-medium);
137
+ }
@@ -0,0 +1,9 @@
1
+ /* Typography System - Main Entry Point
2
+ * Import this file to get all typography styles
3
+ * Or import individual files for selective loading
4
+ */
5
+
6
+ @import './tokens.css';
7
+ @import './base.css';
8
+ @import './variants.css';
9
+ @import './prose.css';
@@ -0,0 +1,132 @@
1
+ /* Prose Wrapper
2
+ * Automatic typography styling for content areas
3
+ * Reference: specs/012-time-to-do/research.md Section 3
4
+ */
5
+
6
+ .seki-prose {
7
+ max-width: 65ch;
8
+ color: var(--seki-color-text);
9
+ }
10
+
11
+ /* Use :where() for low specificity - allows easy overrides */
12
+ .seki-prose :where(h1) {
13
+ scroll-margin-top: 5rem;
14
+ font-size: clamp(var(--seki-typography-h1-size-min), 5vw, var(--seki-typography-h1-size-max));
15
+ font-weight: var(--seki-typography-h1-weight);
16
+ font-family: var(--seki-typography-heading-font);
17
+ letter-spacing: var(--seki-typography-heading-spacing);
18
+ text-wrap: balance;
19
+ }
20
+
21
+ .seki-prose :where(h2) {
22
+ margin-top: 2.5rem;
23
+ scroll-margin-top: 5rem;
24
+ border-bottom: 1px solid var(--seki-color-border);
25
+ padding-bottom: 0.5rem;
26
+ font-size: clamp(var(--seki-typography-h2-size-min), 4vw, var(--seki-typography-h2-size-max));
27
+ font-weight: var(--seki-typography-h2-weight);
28
+ font-family: var(--seki-typography-heading-font);
29
+ letter-spacing: var(--seki-typography-heading-spacing);
30
+ }
31
+
32
+ .seki-prose :where(h2:first-child) {
33
+ margin-top: 0;
34
+ }
35
+
36
+ .seki-prose :where(h3) {
37
+ margin-top: 2rem;
38
+ scroll-margin-top: 5rem;
39
+ font-size: clamp(var(--seki-typography-h3-size-min), 3.5vw, var(--seki-typography-h3-size-max));
40
+ font-weight: var(--seki-typography-h3-weight);
41
+ font-family: var(--seki-typography-heading-font);
42
+ letter-spacing: var(--seki-typography-heading-spacing);
43
+ }
44
+
45
+ .seki-prose :where(h4) {
46
+ margin-top: 1.5rem;
47
+ scroll-margin-top: 5rem;
48
+ font-size: clamp(var(--seki-typography-h4-size-min), 3vw, var(--seki-typography-h4-size-max));
49
+ font-weight: var(--seki-typography-h4-weight);
50
+ font-family: var(--seki-typography-heading-font);
51
+ letter-spacing: var(--seki-typography-heading-spacing);
52
+ }
53
+
54
+ .seki-prose :where(p) {
55
+ font-family: var(--seki-typography-body-font);
56
+ font-size: var(--seki-font-size-base);
57
+ font-weight: var(--seki-font-weight-normal);
58
+ line-height: var(--seki-typography-body-line-height);
59
+ }
60
+
61
+ .seki-prose :where(p:not(:first-child)) {
62
+ margin-top: 1.5rem;
63
+ }
64
+
65
+ .seki-prose :where(blockquote) {
66
+ margin-top: 1.5rem;
67
+ border-left: 2px solid var(--seki-color-border);
68
+ padding-left: 1.5rem;
69
+ font-style: italic;
70
+ color: var(--seki-color-text-muted);
71
+ font-family: var(--seki-typography-body-font);
72
+ }
73
+
74
+ .seki-prose :where(ul, ol) {
75
+ margin: 1.5rem 0;
76
+ padding-left: 1.5rem;
77
+ font-family: var(--seki-typography-body-font);
78
+ }
79
+
80
+ .seki-prose :where(li) {
81
+ margin-top: 0.5rem;
82
+ line-height: var(--seki-typography-body-line-height);
83
+ }
84
+
85
+ .seki-prose :where(li::marker) {
86
+ color: var(--seki-color-text-muted);
87
+ }
88
+
89
+ .seki-prose :where(code) {
90
+ position: relative;
91
+ border-radius: 0.25rem;
92
+ background-color: var(--seki-color-muted);
93
+ padding: 0.125rem 0.375rem;
94
+ font-family: var(--seki-typography-code-font);
95
+ font-size: 0.875em;
96
+ font-weight: var(--seki-font-weight-medium);
97
+ }
98
+
99
+ .seki-prose :where(table) {
100
+ width: 100%;
101
+ caption-side: bottom;
102
+ border-collapse: collapse;
103
+ margin: 1.5rem 0;
104
+ font-family: var(--seki-typography-body-font);
105
+ }
106
+
107
+ .seki-prose :where(th) {
108
+ border-bottom: 1px solid var(--seki-color-border);
109
+ padding: 0.75rem;
110
+ text-align: left;
111
+ font-weight: var(--seki-font-weight-semibold);
112
+ }
113
+
114
+ .seki-prose :where(td) {
115
+ border-bottom: 1px solid var(--seki-color-border-subtle);
116
+ padding: 0.75rem;
117
+ text-align: left;
118
+ }
119
+
120
+ .seki-prose :where(tr:last-child td) {
121
+ border-bottom: none;
122
+ }
123
+
124
+ /* Flow spacing - space between sibling elements */
125
+ .seki-prose > * + * {
126
+ margin-top: 1.5rem;
127
+ }
128
+
129
+ /* Reduced spacing after headings */
130
+ .seki-prose > :is(h2, h3, h4) + * {
131
+ margin-top: 1rem;
132
+ }
@@ -0,0 +1,77 @@
1
+ /* Typography Design Tokens
2
+ * This file defines all CSS custom properties for the typography system
3
+ * Reference: specs/012-time-to-do/data-model.md
4
+ */
5
+
6
+ :root {
7
+ /* Font Family Tokens */
8
+ --seki-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
9
+ --seki-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
10
+
11
+ /* Font Size Tokens (Primitive Scale) */
12
+ --seki-font-size-xs: 0.75rem; /* 12px */
13
+ --seki-font-size-sm: 0.875rem; /* 14px */
14
+ --seki-font-size-base: 1rem; /* 16px */
15
+ --seki-font-size-lg: 1.125rem; /* 18px */
16
+ --seki-font-size-xl: 1.25rem; /* 20px */
17
+ --seki-font-size-2xl: 1.5rem; /* 24px */
18
+ --seki-font-size-3xl: 1.875rem; /* 30px */
19
+ --seki-font-size-4xl: 2.4rem; /* 38.4px */
20
+
21
+ /* Font Weight Tokens */
22
+ --seki-font-weight-normal: 400;
23
+ --seki-font-weight-medium: 500;
24
+ --seki-font-weight-semibold: 600;
25
+ --seki-font-weight-bold: 700;
26
+ --seki-font-weight-extrabold: 800;
27
+
28
+ /* Line Height Tokens */
29
+ --seki-line-height-tight: 1.25;
30
+ --seki-line-height-normal: 1.5;
31
+ --seki-line-height-relaxed: 1.75;
32
+
33
+ /* Letter Spacing Tokens */
34
+ --seki-letter-spacing-tight: -0.025em;
35
+ --seki-letter-spacing-normal: 0;
36
+ --seki-letter-spacing-wide: 0.025em;
37
+
38
+ /* Color Tokens - Light Mode */
39
+ --seki-color-text: hsl(0, 0%, 10%); /* #1a1a1a - 16.5:1 contrast on white */
40
+ --seki-color-text-muted: hsl(0, 0%, 45%); /* #737373 - 4.7:1 contrast (WCAG AA) */
41
+ --seki-color-border: hsl(0, 0%, 88%); /* #e0e0e0 */
42
+ --seki-color-border-subtle: hsl(0, 0%, 93%); /* #ededed */
43
+ --seki-color-muted: hsl(0, 0%, 96%); /* #f5f5f5 - for code backgrounds */
44
+
45
+ /* Component-Specific Tokens - Heading Sizes */
46
+ --seki-typography-h1-size-min: 2rem;
47
+ --seki-typography-h1-size-max: 2.4rem;
48
+ --seki-typography-h1-weight: var(--seki-font-weight-extrabold);
49
+
50
+ --seki-typography-h2-size-min: 1.5rem;
51
+ --seki-typography-h2-size-max: 1.875rem;
52
+ --seki-typography-h2-weight: var(--seki-font-weight-semibold);
53
+
54
+ --seki-typography-h3-size-min: 1.25rem;
55
+ --seki-typography-h3-size-max: 1.5rem;
56
+ --seki-typography-h3-weight: var(--seki-font-weight-semibold);
57
+
58
+ --seki-typography-h4-size-min: 1.125rem;
59
+ --seki-typography-h4-size-max: 1.25rem;
60
+ --seki-typography-h4-weight: var(--seki-font-weight-semibold);
61
+
62
+ /* Semantic Grouping Tokens */
63
+ --seki-typography-heading-font: var(--seki-font-sans);
64
+ --seki-typography-heading-spacing: var(--seki-letter-spacing-tight);
65
+ --seki-typography-body-font: var(--seki-font-sans);
66
+ --seki-typography-body-line-height: var(--seki-line-height-relaxed);
67
+ --seki-typography-code-font: var(--seki-font-mono);
68
+ }
69
+
70
+ /* Dark Mode Color Tokens (matching shadcn/ui) */
71
+ [data-theme="dark"] {
72
+ --seki-color-text: hsl(0, 0%, 98%); /* shadcn --foreground: oklch(0.985 0 0) ≈ 98.5% */
73
+ --seki-color-text-muted: hsl(0, 0%, 65%); /* shadcn --muted-foreground: oklch(0.708 0 0) ≈ 64.5% */
74
+ --seki-color-border: hsl(0, 0%, 27%); /* shadcn --border: oklch(0.269 0 0) */
75
+ --seki-color-border-subtle: hsl(0, 0%, 20%);/* slightly darker variant */
76
+ --seki-color-muted: hsl(0, 0%, 20%); /* shadcn --muted: oklch(0.269 0 0) */
77
+ }
@@ -0,0 +1,25 @@
1
+ /* Typography Variants
2
+ * Text emphasis classes: lead, large, small, muted
3
+ * Reference: specs/012-time-to-do/data-model.md
4
+ */
5
+
6
+ .seki-large {
7
+ font-size: clamp(var(--seki-font-size-lg), 3vw, var(--seki-font-size-xl));
8
+ font-weight: var(--seki-font-weight-semibold);
9
+ font-family: var(--seki-font-sans);
10
+ color: var(--seki-color-text);
11
+ }
12
+
13
+ .seki-small {
14
+ font-size: var(--seki-font-size-sm);
15
+ font-weight: var(--seki-font-weight-medium);
16
+ line-height: 1.25rem;
17
+ font-family: var(--seki-font-sans);
18
+ color: var(--seki-color-text);
19
+ }
20
+
21
+ .seki-muted {
22
+ font-size: var(--seki-font-size-sm);
23
+ color: var(--seki-color-text-muted);
24
+ font-family: var(--seki-font-sans);
25
+ }
@@ -1,5 +1,5 @@
1
- import { p as proxyCustomElement, H, c as createEvent, h, a as Host } from './p-ag6agK1v.js';
2
- export { g as getAssetPath, r as render, s as setAssetPath, b as setNonce, d as setPlatformOptions } from './p-ag6agK1v.js';
1
+ import { p as proxyCustomElement, H, c as createEvent, h, a as Host } from './p-qBYH2h9w.js';
2
+ export { g as getAssetPath, r as render, s as setAssetPath, b as setNonce, d as setPlatformOptions } from './p-qBYH2h9w.js';
3
3
 
4
4
  const sekiSwitchCss = ":host{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px}.switch{width:var(--seki-switch-width, 2.75rem);height:var(--seki-switch-height, 1.5rem);position:relative;display:inline-flex;align-items:center;flex-shrink:0;background-color:var(--seki-switch-bg-unchecked, hsl(var(--muted, 240 4.8% 95.9%)));border-radius:9999px;cursor:pointer;transition:background-color var(--seki-switch-transition-duration, 150ms) ease-out;outline:none}.switch:focus-visible{outline:2px solid var(--seki-switch-focus-ring, hsl(var(--ring, 240 5% 64.9%)));outline-offset:2px}:host([data-state=\"checked\"]) .switch{background-color:var(--seki-switch-bg-checked, hsl(var(--primary, 240 5.9% 10%)))}:host([data-disabled]) .switch{background-color:var(--seki-switch-bg-disabled, hsl(var(--muted, 240 4.8% 95.9%) / 0.5));cursor:not-allowed;opacity:0.5}.thumb{width:var(--seki-switch-thumb-size, 1.25rem);height:var(--seki-switch-thumb-size, 1.25rem);background-color:var(--seki-switch-thumb-bg, hsl(var(--background, 0 0% 100%)));position:absolute;left:0.125rem;border-radius:50%;box-shadow:0 1px 2px 0 rgb(0 0 0 / 0.05);transition:transform var(--seki-switch-transition-duration, 150ms) ease-out;pointer-events:none}:host([data-state=\"checked\"]) .thumb{transform:translateX(calc(var(--seki-switch-width, 2.75rem) - var(--seki-switch-thumb-size, 1.25rem) - 0.25rem))}@media (prefers-color-scheme: dark){.switch{--seki-switch-bg-unchecked:hsl(var(--muted, 240 3.7% 15.9%))}.thumb{--seki-switch-thumb-bg:hsl(var(--background, 240 10% 3.9%))}}";
5
5
 
@@ -40,6 +40,7 @@ var consoleError = (e, el) => (0, console.error)(e, el);
40
40
  // src/client/client-style.ts
41
41
  var styles = /* @__PURE__ */ new Map();
42
42
  var SLOT_FB_CSS = "slot-fb{display:contents}slot-fb[hidden]{display:none}";
43
+ var XLINK_NS = "http://www.w3.org/1999/xlink";
43
44
  var win = typeof window !== "undefined" ? window : {};
44
45
  var H = win.HTMLElement || class {
45
46
  };
@@ -467,7 +468,11 @@ var setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialRen
467
468
  }
468
469
  }
469
470
  }
470
- } else if (memberName === "key") ; else if ((!elm.__lookupSetter__(memberName)) && memberName[0] === "o" && memberName[1] === "n") {
471
+ } else if (memberName === "key") ; else if (memberName === "ref") {
472
+ if (newValue) {
473
+ newValue(elm);
474
+ }
475
+ } else if ((!elm.__lookupSetter__(memberName)) && memberName[0] === "o" && memberName[1] === "n") {
471
476
  if (memberName[2] === "-") {
472
477
  memberName = memberName.slice(3);
473
478
  } else if (isMemberInElement(win, ln)) {
@@ -506,15 +511,26 @@ var setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialRen
506
511
  } catch (e) {
507
512
  }
508
513
  }
514
+ let xlink = false;
515
+ {
516
+ if (ln !== (ln = ln.replace(/^xlink\:?/, ""))) {
517
+ memberName = ln;
518
+ xlink = true;
519
+ }
520
+ }
509
521
  if (newValue == null || newValue === false) {
510
522
  if (newValue !== false || elm.getAttribute(memberName) === "") {
511
- {
523
+ if (xlink) {
524
+ elm.removeAttributeNS(XLINK_NS, memberName);
525
+ } else {
512
526
  elm.removeAttribute(memberName);
513
527
  }
514
528
  }
515
529
  } else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex && elm.nodeType === 1 /* ElementNode */) {
516
530
  newValue = newValue === true ? "" : newValue;
517
- {
531
+ if (xlink) {
532
+ elm.setAttributeNS(XLINK_NS, memberName, newValue);
533
+ } else {
518
534
  elm.setAttribute(memberName, newValue);
519
535
  }
520
536
  }
@@ -624,6 +640,7 @@ var removeVnodes = (vnodes, startIdx, endIdx) => {
624
640
  const vnode = vnodes[index];
625
641
  if (vnode) {
626
642
  const elm = vnode.$elm$;
643
+ nullifyVNodeRefs(vnode);
627
644
  if (elm) {
628
645
  elm.remove();
629
646
  }
@@ -752,6 +769,12 @@ var patch = (oldVNode, newVNode2, isInitialRender = false) => {
752
769
  elm.data = text;
753
770
  }
754
771
  };
772
+ var nullifyVNodeRefs = (vNode) => {
773
+ {
774
+ vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(null);
775
+ vNode.$children$ && vNode.$children$.map(nullifyVNodeRefs);
776
+ }
777
+ };
755
778
  var insertBefore = (parent, newNode, reference) => {
756
779
  {
757
780
  return parent == null ? void 0 : parent.insertBefore(newNode, reference);