@ecomcx/ecomweb-content 0.0.0-stage → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/style.css ADDED
@@ -0,0 +1,161 @@
1
+ /*
2
+ * Giao diện nền cho nội dung (@ecomcx/ecomweb-content) — dùng chung cho website và trình soạn.
3
+ * Nằm trong @layer ecx-content + mọi selector trong :where() → CSS của theme (có layer hay không) luôn thắng.
4
+ * Nạp file này trước CSS của theme để layer ecx-content đứng thấp nhất.
5
+ * Theme đổi màu bằng biến: --ecx-border, --ecx-muted, --ecx-accent, --ecx-surface, --ecx-code-bg, --ecx-code-fg.
6
+ */
7
+ @layer ecx-content {
8
+ /* Preset của kiểu dáng khối (attrs.style): theme đổi bằng cách đặt lại biến (theme.json › styles) */
9
+ :where(:root) {
10
+ --ecx-spacing-xs: .25rem; --ecx-spacing-sm: .5rem; --ecx-spacing-md: 1rem; --ecx-spacing-lg: 1.5rem;
11
+ --ecx-spacing-xl: 2.5rem; --ecx-spacing-2xl: 4rem; --ecx-spacing-3xl: 6rem;
12
+ --ecx-font-size-xs: .75rem; --ecx-font-size-sm: .875rem; --ecx-font-size-md: 1rem; --ecx-font-size-lg: 1.25rem;
13
+ --ecx-font-size-xl: 1.5rem; --ecx-font-size-2xl: 2rem; --ecx-font-size-3xl: 2.75rem; --ecx-font-size-4xl: 3.5rem;
14
+ --ecx-color-primary: var(--primary, #2563eb); --ecx-color-muted: #6b7280; --ecx-color-surface: #f4f4f5;
15
+ --ecx-color-white: #fff; --ecx-color-black: #111;
16
+ --ecx-font-family-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
17
+ }
18
+
19
+ :where(.ecx-content) {
20
+ --_border: var(--ecx-border, color-mix(in srgb, currentColor 18%, transparent));
21
+ --_muted: var(--ecx-muted, color-mix(in srgb, currentColor 65%, transparent));
22
+ --_accent: var(--ecx-accent, var(--primary, currentColor));
23
+ --_surface: var(--ecx-surface, color-mix(in srgb, currentColor 5%, transparent));
24
+ overflow-wrap: break-word;
25
+ }
26
+
27
+ :where(.ecx-content) :where(ul, ol) { padding-left: 1.5em; }
28
+ :where(.ecx-content) :where(ul) { list-style: disc; }
29
+ :where(.ecx-content) :where(ol) { list-style: decimal; }
30
+ :where(.ecx-content) :where(li > p) { margin: 0; }
31
+ :where(.ecx-content) :where(.ecx-task-list) { list-style: none; padding-left: 0; }
32
+ :where(.ecx-content) :where(.ecx-task-item) { display: flex; gap: .5em; align-items: baseline; }
33
+
34
+ :where(.ecx-content) :where(blockquote) { margin: 1.5em 0; padding: .25em 0 .25em 1em; border-left: 3px solid var(--_accent); color: var(--_muted); }
35
+ :where(.ecx-content) :where(pre) { padding: 1em 1.25em; border-radius: 8px; overflow-x: auto; background: var(--ecx-code-bg, #18181b); color: var(--ecx-code-fg, #f4f4f5);
36
+ font: .875rem/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; }
37
+ :where(.ecx-content) :where(code) { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9em; }
38
+ :where(.ecx-content) :where(:not(pre) > code) { padding: .1em .35em; border-radius: 4px; background: var(--_surface); }
39
+ :where(.ecx-content) :where(hr) { margin: 2em 0; border: 0; border-top: 1px solid var(--_border); }
40
+ :where(.ecx-content) :where(a) { color: var(--_accent); text-underline-offset: 2px; }
41
+ :where(.ecx-content) :where(mark) { padding: 0 .1em; }
42
+
43
+ :where(.ecx-content) :where(img, video, iframe) { max-width: 100%; }
44
+ :where(.ecx-content) :where(img) { height: auto; }
45
+ :where(.ecx-content) :where(figure) { margin: 1.5em 0; }
46
+ :where(.ecx-content) :where(figcaption) { margin-top: .5em; font-size: .875em; color: var(--_muted); text-align: center; }
47
+ :where(.ecx-content) :where(.ecx-align-center) { margin-left: auto; margin-right: auto; text-align: center; }
48
+ :where(.ecx-content) :where(.ecx-align-left) { float: left; margin: .25em 1.5em 1em 0; max-width: 50%; }
49
+ :where(.ecx-content) :where(.ecx-align-right) { float: right; margin: .25em 0 1em 1.5em; max-width: 50%; }
50
+
51
+ :where(.ecx-content) :where(.ecx-table) { overflow-x: auto; margin: 1.5em 0; }
52
+ :where(.ecx-content) :where(table) { width: 100%; border-collapse: collapse; }
53
+ :where(.ecx-content) :where(th, td) { box-sizing: border-box; height: 2.5em; padding: .5em .75em; border: 1px solid var(--_border); vertical-align: top; text-align: start; }
54
+ :where(.ecx-content) :where(th) { background: var(--_surface); font-weight: 600; }
55
+ :where(.ecx-content) :where(th, td) > :where(p) { margin: 0; }
56
+ :where(.ecx-content) :where(tfoot td, tfoot th) { font-weight: 600; background: var(--_surface); }
57
+ :where(.ecx-content) :where(table.is-fixed) { table-layout: fixed; }
58
+
59
+ :where(.ecx-content) :where(.ecx-youtube) { position: relative; aspect-ratio: 16 / 9; margin: 1.5em 0; }
60
+ :where(.ecx-content) :where(.ecx-youtube iframe) { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 8px; }
61
+ :where(.ecx-content) :where(.ecx-file) { margin: 1.5em 0; }
62
+ :where(.ecx-content) :where(.ecx-file-link) { display: inline-block; padding: .5em .9em; border: 1px solid var(--_border); border-radius: 8px; text-decoration: none; }
63
+
64
+ :where(.ecx-content) :where(.ecx-columns, .ecx-group, .ecx-callout, .ecx-embed) { margin: 1.5em 0; }
65
+ :where(.ecx-content) :where(.ecx-column, .ecx-group, .ecx-callout) > :where(:first-child) { margin-top: 0; }
66
+ :where(.ecx-content) :where(.ecx-column, .ecx-group, .ecx-callout) > :where(:last-child) { margin-bottom: 0; }
67
+
68
+ /* Template trang "full-width": nội dung trải hết chiều ngang dù nằm trong khung giới hạn của theme */
69
+ :where(.ecx-full-width) { width: 100vw; margin-inline: calc(50% - 50vw); }
70
+
71
+ /* Bộ khối cơ bản (1.9) */
72
+ :where(.ecx-spacer) { display: block; }
73
+ :where(.ecx-buttons-group) { display: flex; flex-wrap: wrap; gap: .75em; margin: 1.5em 0; }
74
+ :where(.ecx-buttons-group.is-center) { justify-content: center; }
75
+ :where(.ecx-buttons-group.is-right) { justify-content: flex-end; }
76
+ :where(.ecx-buttons-group.is-space-between) { justify-content: space-between; }
77
+ :where(.ecx-cover) { position: relative; display: flex; align-items: center; overflow: hidden; margin: 1.5em 0; padding: 2rem 1.5rem; color: #fff; background-size: cover; background-position: center; }
78
+ :where(.ecx-cover.is-top) { align-items: flex-start; }
79
+ :where(.ecx-cover.is-bottom) { align-items: flex-end; }
80
+ :where(.ecx-cover.is-fixed) { background-attachment: fixed; }
81
+ :where(.ecx-cover-img) { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
82
+ :where(.ecx-cover-overlay) { position: absolute; inset: 0; }
83
+ :where(.ecx-cover-inner) { position: relative; width: 100%; max-width: 960px; margin-inline: auto; }
84
+ :where(.ecx-cover-inner) > :where(:first-child) { margin-top: 0; }
85
+ :where(.ecx-cover-inner) > :where(:last-child) { margin-bottom: 0; }
86
+ :where(.ecx-cover) :where(a:not(.ecx-button)) { color: inherit; }
87
+ :where(.ecx-media-text) { display: grid; gap: 2rem; align-items: center; margin: 1.5em 0; grid-template-columns: var(--ecx-media-width, 50%) 1fr; }
88
+ :where(.ecx-media-text.is-right) { grid-template-columns: 1fr var(--ecx-media-width, 50%); }
89
+ :where(.ecx-media-text.is-right) > :where(.ecx-media-text-media) { order: 2; }
90
+ :where(.ecx-media-text.is-top) { align-items: start; }
91
+ :where(.ecx-media-text.is-bottom) { align-items: end; }
92
+ :where(.ecx-media-text-media) :where(img) { display: block; width: 100%; height: auto; border-radius: 8px; }
93
+ :where(.ecx-media-text-content) > :where(:first-child) { margin-top: 0; }
94
+ @media (max-width: 640px) {
95
+ :where(.ecx-media-text.is-stack, .ecx-media-text.is-stack.is-right) { grid-template-columns: 1fr; }
96
+ :where(.ecx-media-text.is-stack.is-right) > :where(.ecx-media-text-media) { order: 0; }
97
+ }
98
+ :where(.ecx-pullquote) { margin: 2em 0; padding: 1.5em 0; border-block: 3px solid currentColor; text-align: center; }
99
+ :where(.ecx-pullquote) :where(blockquote) { margin: 0; padding: 0; border: 0; color: inherit; font-size: 1.5em; line-height: 1.4; }
100
+ :where(.ecx-pullquote) :where(figcaption) { margin-top: 1em; font-size: .875em; text-transform: uppercase; letter-spacing: .05em; }
101
+ :where(.ecx-details) { margin: 1em 0; padding: .75em 1em; border: 1px solid var(--_border, color-mix(in srgb, currentColor 18%, transparent)); border-radius: 8px; }
102
+ :where(.ecx-details) > :where(summary) { cursor: pointer; font-weight: 600; }
103
+ :where(.ecx-details[open]) > :where(summary) { margin-bottom: .5em; }
104
+ :where(.ecx-social) { display: flex; flex-wrap: wrap; gap: .5em; margin: 1em 0; padding: 0; list-style: none; }
105
+ :where(.ecx-social.is-center) { justify-content: center; }
106
+ :where(.ecx-social.is-right) { justify-content: flex-end; }
107
+ :where(.ecx-social) :where(a) { display: inline-flex; align-items: center; gap: .4em; padding: .5em; border-radius: 999px; background: var(--_surface, color-mix(in srgb, currentColor 6%, transparent)); color: inherit; text-decoration: none; font-size: 1.1em; font-weight: 600; line-height: 1; }
108
+ :where(.ecx-social.has-labels) :where(a) { padding: .5em .9em; font-size: .875em; }
109
+ :where(.ecx-social) :where(svg) { width: 1.1em; height: 1.1em; flex: none; }
110
+ :where(.ecx-social.is-small) :where(a) { font-size: .85em; }
111
+ :where(.ecx-social.is-large) :where(a) { font-size: 1.5em; }
112
+ :where(.ecx-toc) { margin: 1.5em 0; padding: 1em 1.25em; border: 1px solid var(--_border, color-mix(in srgb, currentColor 18%, transparent)); border-radius: 8px; }
113
+ :where(.ecx-toc-title) { margin: 0 0 .5em; font-weight: 700; }
114
+ :where(.ecx-toc) :where(ol) { margin: 0; padding-left: 1.25em; }
115
+ :where(.ecx-pre) { white-space: pre-wrap; font-family: var(--ecx-font-family-mono, ui-monospace, monospace); font-size: .9em; }
116
+
117
+ /* Biến thể kiểu có sẵn (attrs.blockStyle → .ecx-is-<tên>) */
118
+ :where(.ecx-is-stripes) :where(tbody tr:nth-child(odd) > td) { background: var(--_surface, color-mix(in srgb, currentColor 5%, transparent)); }
119
+ :where(.ecx-is-stripes) :where(th, td) { border-inline: 0; }
120
+ :where(.ecx-is-rounded img, img.ecx-is-rounded) { border-radius: 16px; }
121
+ :where(.ecx-is-circle img, img.ecx-is-circle) { border-radius: 50%; aspect-ratio: 1; object-fit: cover; }
122
+ :where(blockquote.ecx-is-plain) { border: 0; padding-left: 0; font-style: normal; }
123
+ :where(hr.ecx-is-dots) { border: 0; text-align: center; overflow: visible; }
124
+ :where(hr.ecx-is-dots)::before { content: "· · ·"; letter-spacing: 1em; font-size: 1.25em; color: var(--_muted, currentColor); }
125
+ :where(hr.ecx-is-wide) { border-top-width: 3px; }
126
+ :where(.ecx-is-pill .ecx-button, .ecx-button.ecx-is-pill) { border-radius: 999px !important; }
127
+ :where(.ecx-group.ecx-is-card) { padding: 1.5rem; border: 1px solid var(--_border, color-mix(in srgb, currentColor 15%, transparent)); border-radius: 12px; box-shadow: 0 4px 20px rgb(0 0 0 / .06); }
128
+
129
+ /* Khối động (template / Trình dựng) */
130
+ :where(.ecx-site-title) { margin: 0; font-weight: 700; }
131
+ :where(.ecx-site-title) :where(a) { color: inherit; text-decoration: none; }
132
+ :where(.ecx-site-tagline, .ecx-copyright, .ecx-post-date, .ecx-post-terms, .ecx-post-author) { color: var(--_muted, inherit); }
133
+ :where(.ecx-navigation-menu) :where(ul) { display: flex; flex-wrap: wrap; gap: .25em 1.25em; margin: 0; padding: 0; list-style: none; }
134
+ :where(.ecx-navigation-menu) :where(ul ul) { display: none; }
135
+ :where(.ecx-navigation-menu) :where(a) { color: inherit; text-decoration: none; }
136
+ :where(.ecx-navigation-vertical .ecx-navigation-menu) :where(ul) { flex-direction: column; }
137
+ :where(.ecx-navigation-toggle) { display: none; }
138
+ :where(.ecx-navigation-toggle) > :where(summary) { list-style: none; cursor: pointer; font-size: 1.4em; line-height: 1; }
139
+ :where(.ecx-navigation-toggle[open] .ecx-navigation-menu) :where(ul) { flex-direction: column; padding-top: .5em; }
140
+ @media (max-width: 640px) {
141
+ :where(.ecx-navigation.has-mobile) > :where(.ecx-navigation-items) { display: none; }
142
+ :where(.ecx-navigation.has-mobile) > :where(.ecx-navigation-toggle) { display: block; }
143
+ }
144
+ :where(.ecx-post-template) { margin: 0; padding: 0; list-style: none; }
145
+ :where(.ecx-post-template:not(.is-grid)) > :where(.ecx-post + .ecx-post) { margin-top: 2em; }
146
+ :where(.ecx-post) > :where(:first-child) { margin-top: 0; }
147
+
148
+ :where(.ecx-form) { display: grid; gap: 1em; max-width: 36rem; margin: 1.5em 0; }
149
+ :where(.ecx-form) :where(.ecx-form-field) { display: grid; gap: .35em; margin: 0; }
150
+ :where(.ecx-form) :where(.ecx-form-boolean) { display: block; }
151
+ :where(.ecx-form) :where(input:not([type="checkbox"], [type="radio"]), select, textarea) {
152
+ width: 100%; box-sizing: border-box; padding: .55em .75em; border: 1px solid var(--ecx-border, color-mix(in srgb, currentColor 25%, transparent));
153
+ border-radius: 8px; background: transparent; color: inherit; font: inherit; }
154
+ :where(.ecx-form) :where(input:focus-visible, select:focus-visible, textarea:focus-visible) { outline: 2px solid var(--ecx-accent, var(--primary, currentColor)); outline-offset: 1px; }
155
+ :where(.ecx-form) :where([aria-invalid="true"]) { border-color: #dc2626; }
156
+ :where(.ecx-form) :where(button[type="submit"]) { justify-self: start; padding: .6em 1.2em; border: 0; border-radius: 8px; cursor: pointer; font: inherit; font-weight: 600;
157
+ background: var(--ecx-button-bg, var(--primary, #18181b)); color: var(--ecx-button-fg, #fff); }
158
+ :where(.ecx-form) :where(button[type="submit"]:disabled) { opacity: .6; cursor: progress; }
159
+ :where(.ecx-form) :where(.ecx-form-error) { color: #dc2626; font-size: .875em; }
160
+ :where(.ecx-form-success) { padding: .75em 1em; border-radius: 8px; background: color-mix(in srgb, #16a34a 10%, transparent); }
161
+ }