@expressivecss/expressive 0.1.0-alpha.3 → 0.2.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 (154) hide show
  1. package/LICENSE +82 -2
  2. package/README.md +153 -43
  3. package/dist/css/expressive.css +7121 -9658
  4. package/dist/css/expressive.css.map +1 -0
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -0
  7. package/dist/js/expressive.cjs +7521 -0
  8. package/dist/js/expressive.cjs.map +7 -0
  9. package/dist/js/expressive.js +7383 -8099
  10. package/dist/js/expressive.js.map +7 -1
  11. package/dist/js/expressive.min.js +75 -1
  12. package/dist/js/expressive.min.js.map +7 -1
  13. package/dist/js/expressive.mjs +7292 -7998
  14. package/dist/js/expressive.mjs.map +7 -1
  15. package/dist/types/behaviors/dialogs.d.ts +25 -0
  16. package/dist/{js → types}/components/autocomplete.d.ts +10 -1
  17. package/dist/{js → types}/components/buttons.d.ts +11 -1
  18. package/dist/{js → types}/components/cards.d.ts +10 -1
  19. package/dist/{js → types}/components/carousel.d.ts +4 -5
  20. package/dist/{js/forms/character-counter.d.ts → types/components/characterCounter.d.ts} +1 -1
  21. package/dist/{js → types}/components/chips.d.ts +1 -1
  22. package/dist/{js → types}/components/collapsible.d.ts +1 -1
  23. package/dist/{js → types}/components/datepicker.d.ts +63 -2
  24. package/dist/{js → types}/components/dropdown.d.ts +3 -3
  25. package/dist/types/components/index.d.ts +23 -0
  26. package/dist/{js/components/materialbox.d.ts → types/components/lightbox.d.ts} +21 -21
  27. package/dist/{js → types}/components/modal.d.ts +1 -1
  28. package/dist/{js → types}/components/parallax.d.ts +11 -5
  29. package/dist/{js → types}/components/pushpin.d.ts +1 -1
  30. package/dist/{js/forms → types/components}/range.d.ts +3 -3
  31. package/dist/types/components/registry.d.ts +107 -0
  32. package/dist/{js → types}/components/scrollspy.d.ts +6 -9
  33. package/dist/{js/forms → types/components}/select.d.ts +11 -2
  34. package/dist/{js → types}/components/sidenav.d.ts +1 -1
  35. package/dist/{js → types}/components/slider.d.ts +3 -2
  36. package/dist/{js → types}/components/tabs.d.ts +3 -2
  37. package/dist/{js/components/tap-target.d.ts → types/components/tapTarget.d.ts} +2 -2
  38. package/dist/{js → types}/components/timepicker.d.ts +13 -5
  39. package/dist/{js/components/toast.d.ts → types/components/toasts.d.ts} +28 -4
  40. package/dist/{js → types}/components/tooltip.d.ts +2 -2
  41. package/dist/types/core/bounding.d.ts +6 -0
  42. package/dist/{js/foundation → types/core}/component.d.ts +1 -1
  43. package/dist/types/core/edges.d.ts +6 -0
  44. package/dist/{js/foundation → types/core}/utils.d.ts +21 -14
  45. package/dist/types/index.d.ts +7 -0
  46. package/dist/{js/plugins/docked-display.d.ts → types/plugins/dockedDisplayPlugin.d.ts} +7 -0
  47. package/package.json +60 -36
  48. package/src/sass/README.md +200 -0
  49. package/src/sass/abstracts/_breakpoints.scss +69 -0
  50. package/src/sass/abstracts/_elevation.scss +34 -0
  51. package/src/sass/abstracts/_index.scss +7 -0
  52. package/src/sass/abstracts/_mixins.scss +171 -0
  53. package/src/sass/abstracts/_variables.scss +57 -0
  54. package/src/{scss/layout/_table.scss → sass/base/_global.scss} +64 -2
  55. package/src/{scss/layout → sass/base}/_grid.scss +6 -6
  56. package/src/sass/base/_index.scss +6 -0
  57. package/src/{scss/foundation → sass/base}/_normalize.scss +51 -139
  58. package/src/sass/base/_typography.scss +90 -0
  59. package/src/sass/components/_badges.scss +77 -0
  60. package/src/{scss → sass}/components/_breadcrumb.scss +2 -0
  61. package/src/sass/components/_buttons.scss +407 -0
  62. package/src/sass/components/_cards.scss +328 -0
  63. package/src/{scss → sass}/components/_carousel.scss +5 -3
  64. package/src/sass/components/_chips.scss +140 -0
  65. package/src/sass/components/_collapsible.scss +81 -0
  66. package/src/{scss → sass}/components/_collection.scss +2 -2
  67. package/src/{scss/components/_date-picker.scss → sass/components/_datepicker.scss} +51 -44
  68. package/src/sass/components/_docked-display.scss +11 -0
  69. package/src/sass/components/_dropdown.scss +129 -0
  70. package/src/{scss/components/_material-icons.scss → sass/components/_icons-material-design.scss} +2 -0
  71. package/src/sass/components/_index.scss +35 -0
  72. package/src/{scss/components/_material-box.scss → sass/components/_lightbox.scss} +6 -4
  73. package/src/sass/components/_modal.scss +208 -0
  74. package/src/sass/components/_navbar.scss +345 -0
  75. package/src/{scss/layout/_footer.scss → sass/components/_page-footer.scss} +7 -6
  76. package/src/{scss → sass}/components/_pagination.scss +4 -3
  77. package/src/{scss → sass}/components/_parallax.scss +4 -1
  78. package/src/{scss → sass}/components/_preloader.scss +19 -97
  79. package/src/{scss → sass}/components/_pulse.scss +2 -0
  80. package/src/sass/components/_pushpin.scss +11 -0
  81. package/src/{scss → sass}/components/_sidenav.scss +99 -82
  82. package/src/{scss → sass}/components/_slider.scss +3 -1
  83. package/src/{scss/components/_table-of-contents.scss → sass/components/_table_of_contents.scss} +2 -0
  84. package/src/sass/components/_tabs.scss +232 -0
  85. package/src/{scss/components/_tap-target.scss → sass/components/_tapTarget.scss} +24 -22
  86. package/src/{scss/components/_time-picker.scss → sass/components/_timepicker.scss} +56 -56
  87. package/src/sass/components/_toast.scss +260 -0
  88. package/src/sass/components/_toolbar.scss +192 -0
  89. package/src/sass/components/_tooltip.scss +166 -0
  90. package/src/{scss → sass}/components/_transitions.scss +4 -4
  91. package/src/sass/components/forms/_checkboxes.scss +288 -0
  92. package/src/sass/components/forms/_fieldset.scss +128 -0
  93. package/src/{scss → sass/components}/forms/_file-input.scss +11 -9
  94. package/src/{scss → sass/components}/forms/_index.scss +2 -0
  95. package/src/sass/components/forms/_input-fields.scss +326 -0
  96. package/src/sass/components/forms/_radio-buttons.scss +190 -0
  97. package/src/sass/components/forms/_range.scss +310 -0
  98. package/src/sass/components/forms/_select.scss +103 -0
  99. package/src/sass/components/forms/_switches.scss +239 -0
  100. package/src/sass/expressive.scss +60 -0
  101. package/src/sass/tokens/_index.scss +4 -0
  102. package/src/sass/tokens/_reference.scss +265 -0
  103. package/src/sass/tokens/_theme.scss +49 -0
  104. package/src/sass/utilities/_helpers.scss +63 -0
  105. package/src/sass/utilities/_index.scss +8 -0
  106. package/src/{scss → sass}/utilities/_spacing.scss +4 -3
  107. package/src/sass/utilities/_typescale.scss +45 -0
  108. package/src/sass/utilities/_visibility.scss +63 -0
  109. package/src/sass/utilities/_z-depth.scss +18 -0
  110. package/dist/js/components/index.d.ts +0 -21
  111. package/dist/js/forms/index.d.ts +0 -4
  112. package/dist/js/foundation/index.d.ts +0 -2
  113. package/dist/js/index.d.ts +0 -52
  114. package/dist/js/plugins/index.d.ts +0 -1
  115. package/src/scss/components/_appbar.scss +0 -454
  116. package/src/scss/components/_badges.scss +0 -77
  117. package/src/scss/components/_buttons.scss +0 -412
  118. package/src/scss/components/_cards.scss +0 -267
  119. package/src/scss/components/_chips.scss +0 -147
  120. package/src/scss/components/_collapsible.scss +0 -84
  121. package/src/scss/components/_dropdown.scss +0 -98
  122. package/src/scss/components/_index.scss +0 -28
  123. package/src/scss/components/_modal.scss +0 -84
  124. package/src/scss/components/_tabs.scss +0 -176
  125. package/src/scss/components/_toast.scss +0 -70
  126. package/src/scss/components/_tooltip.scss +0 -49
  127. package/src/scss/components/_video.scss +0 -15
  128. package/src/scss/expressive.scss +0 -7
  129. package/src/scss/forms/_checkboxes.scss +0 -199
  130. package/src/scss/forms/_input-fields.scss +0 -360
  131. package/src/scss/forms/_radio-buttons.scss +0 -114
  132. package/src/scss/forms/_range.scss +0 -148
  133. package/src/scss/forms/_select.scss +0 -108
  134. package/src/scss/forms/_switches.scss +0 -127
  135. package/src/scss/foundation/_base.scss +0 -71
  136. package/src/scss/foundation/_color-palette.scss +0 -402
  137. package/src/scss/foundation/_index.scss +0 -10
  138. package/src/scss/foundation/_mixins.scss +0 -198
  139. package/src/scss/foundation/_motion.scss +0 -70
  140. package/src/scss/foundation/_shape.scss +0 -30
  141. package/src/scss/foundation/_state-layers.scss +0 -68
  142. package/src/scss/foundation/_theme.scss +0 -238
  143. package/src/scss/foundation/_tokens.scss +0 -511
  144. package/src/scss/foundation/_variables.scss +0 -57
  145. package/src/scss/layout/_index.scss +0 -3
  146. package/src/scss/utilities/_a11y.scss +0 -77
  147. package/src/scss/utilities/_elevation.scss +0 -63
  148. package/src/scss/utilities/_helpers.scss +0 -50
  149. package/src/scss/utilities/_index.scss +0 -7
  150. package/src/scss/utilities/_responsive.scss +0 -62
  151. package/src/scss/utilities/_typography.scss +0 -115
  152. /package/dist/{js/forms → types/behaviors}/forms.d.ts +0 -0
  153. /package/dist/{js/components → types/behaviors}/waves.d.ts +0 -0
  154. /package/src/{scss → sass}/utilities/_colors.scss +0 -0
package/LICENSE CHANGED
@@ -1,6 +1,7 @@
1
- MIT License
1
+ The MIT License (MIT)
2
2
 
3
- Copyright (c) 2026 Javier Baez
3
+ Copyright (c) 2026 BaezFJ
4
+ Copyright (c) 2014-2026 Materialize
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +20,82 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
20
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
21
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
22
  SOFTWARE.
23
+
24
+
25
+ ================================================================================
26
+ THIRD-PARTY NOTICES
27
+ ================================================================================
28
+
29
+ ExpressiveCSS is derived from MaterializeCSS v2.2.2
30
+ (https://github.com/materializecss/materialize), which is distributed under the
31
+ MIT license reproduced above. Portions of `src/ts` and `src/sass` remain
32
+ substantially that work.
33
+
34
+ The following components carry their own licenses, reproduced in full below.
35
+
36
+ --------------------------------------------------------------------------------
37
+ normalize.css v8.0.1 - MIT License
38
+ https://github.com/necolas/normalize.css
39
+
40
+ Used in: src/sass/base/_normalize.scss (trimmed to this project's browser
41
+ support baseline; see that file's header for the list of removed rules).
42
+
43
+ Copyright © Nicolas Gallagher and Jonathan Neal
44
+
45
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
46
+ this software and associated documentation files (the "Software"), to deal in
47
+ the Software without restriction, including without limitation the rights to
48
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
49
+ of the Software, and to permit persons to whom the Software is furnished to do
50
+ so, subject to the following conditions:
51
+
52
+ The above copyright notice and this permission notice shall be included in all
53
+ copies or substantial portions of the Software.
54
+
55
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
60
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
61
+ SOFTWARE.
62
+
63
+ --------------------------------------------------------------------------------
64
+ The Polymer Project - BSD 3-Clause License
65
+ https://polymer.github.io/LICENSE.txt
66
+
67
+ Used in: src/sass/components/_preloader.scss (spinner animation).
68
+
69
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
70
+ The complete set of contributors may be found at
71
+ http://polymer.github.io/CONTRIBUTORS.txt
72
+ Code distributed by Google as part of the polymer project is also subject to an
73
+ additional IP rights grant found at http://polymer.github.io/PATENTS.txt
74
+
75
+ Copyright (c) 2014 The Polymer Authors. All rights reserved.
76
+
77
+ Redistribution and use in source and binary forms, with or without
78
+ modification, are permitted provided that the following conditions are
79
+ met:
80
+
81
+ * Redistributions of source code must retain the above copyright
82
+ notice, this list of conditions and the following disclaimer.
83
+ * Redistributions in binary form must reproduce the above
84
+ copyright notice, this list of conditions and the following disclaimer
85
+ in the documentation and/or other materials provided with the
86
+ distribution.
87
+ * Neither the name of Google Inc. nor the names of its
88
+ contributors may be used to endorse or promote products derived from
89
+ this software without specific prior written permission.
90
+
91
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
92
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
93
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
94
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
95
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
97
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
101
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md CHANGED
@@ -1,82 +1,192 @@
1
1
  # ExpressiveCSS
2
2
 
3
- A CSS framework inspired by Google's [Material Design 3 Expressive](https://material.io/) design language. Built on top of [MaterializeCSS v2.2.2](https://materializecss.github.io/materialize/), ExpressiveCSS aims to bring the expressive, dynamic, and personality-rich aesthetics of M3 Expressive to the web.
3
+ ExpressiveCSS is a Material Design 3 front-end framework built with Sass and
4
+ TypeScript. It provides theme tokens, layout and utility classes, styled form
5
+ controls, and JavaScript components in browser, ES module, and CommonJS builds.
4
6
 
5
- > **Status: Early Alpha** — Actively under development. APIs and class names may change. Not yet recommended for production use.
7
+ > ExpressiveCSS is currently at version `0.2.0` and under active development.
6
8
 
7
- ## Vision
9
+ ## Features
8
10
 
9
- Google's M3 Expressive introduces a more vibrant, playful, and emotionally resonant layer to Material Design — prioritizing personality, motion, and visual richness. ExpressiveCSS brings that vision to a CSS framework you can drop into any project.
11
+ - Material Design 3 color and typography tokens
12
+ - Light and dark themes using CSS custom properties
13
+ - Responsive grid and utility classes
14
+ - Buttons, cards, forms, navigation, and other styled components
15
+ - Interactive components including carousels, collapsibles, date pickers,
16
+ dropdowns, side navigation, tabs, tooltips, and more
17
+ - ES module, CommonJS, browser IIFE, CSS, and TypeScript declaration outputs
18
+ - Automatic component initialization with an opt-out mechanism
10
19
 
11
- The framework uses MaterializeCSS v2.2.2 as its foundation, which will be progressively updated and reshaped to match the M3 Expressive design language.
20
+ ## Requirements
12
21
 
13
- ## Project Structure
22
+ - [Node.js](https://nodejs.org/) 20 or newer
23
+ - npm
24
+ - Python 3.14 or newer and [uv](https://docs.astral.sh/uv/) to run the local
25
+ documentation site
14
26
 
27
+ Python is not required to build or use the framework itself.
28
+
29
+ ## Getting started
30
+
31
+ Clone the repository and install the JavaScript dependencies:
32
+
33
+ ```sh
34
+ npm install
35
+ npm run build
15
36
  ```
16
- src/scss/
17
- ├── materialize.scss # Entry point
18
- ├── foundation/ # Design tokens, theme, variables, color palette, mixins, normalize, base
19
- ├── utilities/ # Colors, typography, elevation, spacing, responsive, helpers
20
- ├── layout/ # Grid, footer, table
21
- ├── components/ # 28 UI components (buttons, cards, appbar, modal, etc.)
22
- └── forms/ # Input fields, radio buttons, checkboxes, switches, select, file input, range
37
+
38
+ The compiled assets are written to `dist/`:
39
+
40
+ ```text
41
+ dist/
42
+ ├── css/
43
+ │ ├── expressive.css
44
+ │ └── expressive.min.css
45
+ ├── js/
46
+ │ ├── expressive.cjs
47
+ │ ├── expressive.js
48
+ │ ├── expressive.min.js
49
+ │ └── expressive.mjs
50
+ └── types/
23
51
  ```
24
52
 
25
- The framework loads in a layered dependency order: **foundation → utilities → layout → components → forms**, ensuring design tokens and variables are available before any component uses them.
53
+ Source maps are produced alongside the CSS and JavaScript bundles.
26
54
 
27
- ## Getting Started
55
+ ## Usage
28
56
 
29
- ### Prerequisites
57
+ ### Browser bundle
30
58
 
31
- - [Sass](https://sass-lang.com/) (Dart Sass recommended — uses the modern `@use`/`@forward` module system)
59
+ Include the compiled stylesheet and browser bundle, then initialize components
60
+ after the page has loaded:
32
61
 
33
- ### Installation
62
+ ```html
63
+ <link rel="stylesheet" href="dist/css/expressive.min.css">
34
64
 
35
- Clone the repository:
65
+ <ul class="collapsible">
66
+ <li>
67
+ <div class="collapsible-header">Details</div>
68
+ <div class="collapsible-body">ExpressiveCSS is ready.</div>
69
+ </li>
70
+ </ul>
36
71
 
37
- ```bash
38
- git clone https://github.com/BaezFJ/ExpressiveCSS.git
39
- cd ExpressiveCSS
72
+ <script src="dist/js/expressive.min.js"></script>
73
+ <script>
74
+ document.addEventListener('DOMContentLoaded', () => {
75
+ Expressive.AutoInit();
76
+ });
77
+ </script>
40
78
  ```
41
79
 
42
- ### Usage
80
+ The browser bundle exposes the framework as the global `Expressive` object.
43
81
 
44
- Import the full framework in your Sass file:
82
+ ### ES modules
45
83
 
46
- ```scss
47
- @use 'path/to/src/scss/materialize';
84
+ Import the framework or individual components from the module build:
85
+
86
+ ```js
87
+ import { AutoInit, Tooltip } from './dist/js/expressive.mjs';
88
+
89
+ AutoInit();
90
+
91
+ const element = document.querySelector('.custom-tooltip');
92
+ Tooltip.init(element, { position: 'top' });
93
+ ```
94
+
95
+ `AutoInit()` scans `document.body` by default. Pass a container to limit the
96
+ scan, or add the `no-autoinit` class to an element that should be initialized
97
+ manually:
98
+
99
+ ```js
100
+ AutoInit(document.querySelector('#app'), {
101
+ Tooltip: { position: 'top' }
102
+ });
48
103
  ```
49
104
 
50
- Or import only the layers you need:
105
+ Importing the JavaScript bundle installs the framework's shared document
106
+ behaviors, but it does not call `AutoInit()` automatically.
107
+
108
+ ### Sass
109
+
110
+ Use the framework's Sass entry point in another Sass project:
51
111
 
52
112
  ```scss
53
- @use 'path/to/src/scss/foundation';
54
- @use 'path/to/src/scss/utilities';
55
- @use 'path/to/src/scss/components';
113
+ @use "expressivecss/src/sass/expressive";
56
114
  ```
57
115
 
58
- ### Compile
116
+ When working directly in this repository, the entry point is
117
+ `src/sass/expressive.scss`.
59
118
 
60
- ```bash
61
- sass src/scss/materialize.scss dist/css/materialize.css
119
+ ### Themes
120
+
121
+ ExpressiveCSS uses the `theme` attribute on the root element:
122
+
123
+ ```html
124
+ <html lang="en" theme="light">
62
125
  ```
63
126
 
64
- ## Components
127
+ Switch themes at runtime by updating the attribute:
128
+
129
+ ```js
130
+ document.documentElement.setAttribute('theme', 'dark');
131
+ ```
65
132
 
66
- ExpressiveCSS includes a wide range of UI components:
133
+ ## Development
67
134
 
68
- **Layout** — Grid, Footer, Table
135
+ Available npm commands include:
69
136
 
70
- **Components** — Buttons, Cards, Navbar, Tabs, Modal, Dropdown, Sidenav, Collapsible, Carousel, Slider, Tooltip, Toast, Chips, Badges, Collection, Breadcrumb, Pagination, Parallax, Preloader, Pulse, Tap Target, Date Picker, Time Picker, Table of Contents, Material Box, Material Icons, Video
137
+ | Command | Purpose |
138
+ | --- | --- |
139
+ | `npm run build` | Build all CSS, JavaScript, and declaration files |
140
+ | `npm run build:css` | Build expanded and minified CSS |
141
+ | `npm run build:js` | Build ESM, CommonJS, and browser bundles |
142
+ | `npm run build:types` | Generate TypeScript declarations |
143
+ | `npm run watch` | Watch Sass and TypeScript sources |
144
+ | `npm run typecheck` | Check the TypeScript source without emitting files |
145
+ | `npm test` | Build the ESM bundle and run the test suite |
146
+ | `npm run clean` | Remove generated build output |
147
+
148
+ Run the local documentation and smoke-test site in a second terminal:
149
+
150
+ ```sh
151
+ uv sync
152
+ uv run python docs/app.py
153
+ ```
71
154
 
72
- **Forms** — Input Fields, Radio Buttons, Checkboxes, Switches, Select, File Input, Range
155
+ Then open `http://127.0.0.1:5000`. The Flask app serves assets directly from
156
+ `dist/`, so changes made by `npm run watch` appear after a browser refresh.
73
157
 
74
- ## Acknowledgments
158
+ ## Project structure
75
159
 
76
- ExpressiveCSS is built on top of **[MaterializeCSS v2.2.2](https://materializecss.github.io/materialize/)**, a modern responsive front-end framework based on Material Design. We are grateful to the MaterializeCSS team and its contributors for providing the solid foundation that this project builds upon.
160
+ ```text
161
+ src/
162
+ ├── sass/ Design tokens, utilities, base styles, and component styles
163
+ └── ts/ Core APIs, behaviors, plugins, and interactive components
164
+ docs/ Local Flask documentation and build smoke test
165
+ tests/ Node test runner and jsdom tests
166
+ dist/ Generated distributable files
167
+ ```
168
+
169
+ See [`src/sass/README.md`](src/sass/README.md) for Sass architecture and
170
+ [`src/ts/README.md`](src/ts/README.md) for component conventions and testing
171
+ guidance.
172
+
173
+ ## Testing
174
+
175
+ Run the complete automated suite with:
176
+
177
+ ```sh
178
+ npm test
179
+ npm run typecheck
180
+ ```
77
181
 
78
- MaterializeCSS is licensed under the [MIT License](https://github.com/nicholasgasior/materialize/blob/v2-dev/LICENSE).
182
+ Tests use Node's built-in test runner and jsdom. Because jsdom does not perform
183
+ layout, component tests focus on DOM structure, classes, content, and lifecycle
184
+ behavior rather than geometry or visual transitions.
79
185
 
80
- ## License
186
+ ## Contributing
81
187
 
82
- This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
188
+ Keep generated files out of commits, add tests for behavior changes, and run
189
+ both the test suite and type checker before submitting a change. New JavaScript
190
+ components must be exported from `src/ts/components/index.ts`; components that
191
+ support automatic initialization must also be registered in
192
+ `src/ts/components/registry.ts`.