@anydigital/bricks 0.21.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/.prettierrc.json +3 -0
- package/LICENSE +20 -0
- package/README.md +303 -0
- package/bricks/__html-begin.liquid +40 -0
- package/bricks/__html-end.liquid +2 -0
- package/bricks/__html.css +28 -0
- package/bricks/_gtm.liquid +23 -0
- package/bricks/_nav.liquid +9 -0
- package/bricks/_prism.css +14 -0
- package/bricks/_prose.css +110 -0
- package/bricks/_util.css +6 -0
- package/bricks/bricks.css +10 -0
- package/dist/bricks.css +323 -0
- package/package.json +33 -0
- package/postcss.config.js +8 -0
package/.prettierrc.json
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013 Anton Staroverov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# *Any*bricks
|
|
2
|
+
|
|
3
|
+
Framework-agnostic CSS utilities and single-file Liquid 'bricks' for modern web development.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Via CDN
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@anydigital/bricks@1/dist/bricks.css" />
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Via npm
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install @anydigital/bricks
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then import in your CSS:
|
|
20
|
+
|
|
21
|
+
```css
|
|
22
|
+
@import "@anydigital/bricks";
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
### Overflow Control
|
|
28
|
+
|
|
29
|
+
Prevents horizontal overflow and scrolling on the entire page:
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
html,
|
|
33
|
+
body {
|
|
34
|
+
overflow-x: clip;
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This is automatically applied when you include the stylesheet.
|
|
39
|
+
|
|
40
|
+
### Full Viewport Height
|
|
41
|
+
|
|
42
|
+
Ensures the body element takes at least the full height of the viewport using dynamic viewport height for better mobile support:
|
|
43
|
+
|
|
44
|
+
```css
|
|
45
|
+
body {
|
|
46
|
+
min-height: 100dvh;
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This is automatically applied when you include the stylesheet.
|
|
51
|
+
|
|
52
|
+
### Typography Enhancements
|
|
53
|
+
|
|
54
|
+
Improves text rendering and readability:
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
body {
|
|
58
|
+
hyphens: auto;
|
|
59
|
+
-webkit-font-smoothing: antialiased;
|
|
60
|
+
-moz-osx-font-smoothing: grayscale;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- Automatic hyphenation for better text flow
|
|
65
|
+
- Font smoothing for cleaner text rendering across browsers
|
|
66
|
+
- Hyphenation is disabled for links and tables to prevent awkward breaks
|
|
67
|
+
|
|
68
|
+
This is automatically applied when you include the stylesheet.
|
|
69
|
+
|
|
70
|
+
### Prose Styling
|
|
71
|
+
|
|
72
|
+
The `.prose` class provides enhanced typography for article content and long-form text with container-like behavior:
|
|
73
|
+
|
|
74
|
+
**Container:**
|
|
75
|
+
|
|
76
|
+
- Full width with `1rem` padding
|
|
77
|
+
- Centered with automatic inline margins
|
|
78
|
+
|
|
79
|
+
**Typography Helpers:**
|
|
80
|
+
|
|
81
|
+
- `small` elements: styled for multi-line subtitles with top vertical alignment, `0.1em` top margin, `1.1` line height, lighter weight (`300`), and displayed as `inline-block` with `100%` width to prevent underline decoration inside links
|
|
82
|
+
|
|
83
|
+
**Links:**
|
|
84
|
+
|
|
85
|
+
- Custom underline offset (`0.1em`) and thickness (`1px` default, `2px` on hover)
|
|
86
|
+
- Anchor links (starting with `#`) have no text decoration
|
|
87
|
+
- Icon helper: `i` elements inside links are displayed as `inline-block` with normal font style to prevent underline decoration, with `1em` height and `0.25em` right margin. Nested `img` elements are styled with `100%` height, no margin, and positioned `0.15em` from the bottom for proper alignment
|
|
88
|
+
|
|
89
|
+
**Headings:**
|
|
90
|
+
|
|
91
|
+
- `h1` elements have a `0.5em` bottom margin
|
|
92
|
+
- `h1 small` elements get reduced font size (`50%`)
|
|
93
|
+
|
|
94
|
+
**Tables:**
|
|
95
|
+
|
|
96
|
+
- Tables within `.breakout` containers are automatically styled for full-bleed display and horizontal scrolling
|
|
97
|
+
- Table cells (`th` and `td`) have padding of `1rem 2rem 1rem 0` (extra space on the right for better horizontal scroll on mobile) and `top` vertical alignment
|
|
98
|
+
- Table headers (`th`) have `bottom` vertical alignment
|
|
99
|
+
- Workaround for widening columns using hidden `hr` elements (width: `12ch`, with zero margin and hidden visibility)
|
|
100
|
+
- Support for headings in Markdown tables using `big` elements (styled as bold)
|
|
101
|
+
- Images in table cells have no top margin and `1em` bottom margin
|
|
102
|
+
|
|
103
|
+
**Blockquotes:**
|
|
104
|
+
|
|
105
|
+
- Lighter font weight (`300`)
|
|
106
|
+
- Adjacent `figcaption` elements (using `+ figcaption` selector) are styled with italic text, right alignment, lighter weight (`300`), negative top margin (`-1em`), and an em dash prefix (`—`) with `0.25em` right margin
|
|
107
|
+
|
|
108
|
+
**Code Blocks:**
|
|
109
|
+
|
|
110
|
+
- Code blocks with `data-caption` attribute display the caption above the code block (styled with 50% opacity, italic, and `1.5em` bottom margin)
|
|
111
|
+
|
|
112
|
+
### Code Highlighting
|
|
113
|
+
|
|
114
|
+
Includes specialized styling for Prism.js, specifically focusing on treeview components:
|
|
115
|
+
|
|
116
|
+
- Custom styling for `.token.treeview-part`
|
|
117
|
+
- Reduced opacity for entry lines (25%) and names (50%) to create a hierarchical visual effect
|
|
118
|
+
- Entry lines have a fixed width of `2.5em`
|
|
119
|
+
- Last-child entry names have no `::before` pseudo-element
|
|
120
|
+
- Supports complex file tree visualizations out of the box
|
|
121
|
+
|
|
122
|
+
### Utilities
|
|
123
|
+
|
|
124
|
+
#### Scrollbar Inversion
|
|
125
|
+
|
|
126
|
+
The `.invert` class can be used to invert the scrollbar colors, which is particularly useful for dark themes or specific UI components:
|
|
127
|
+
|
|
128
|
+
```css
|
|
129
|
+
.invert {
|
|
130
|
+
::-webkit-scrollbar {
|
|
131
|
+
filter: invert(1) !important;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Usage:**
|
|
137
|
+
|
|
138
|
+
```html
|
|
139
|
+
<article class="prose">
|
|
140
|
+
<h1>Article Title</h1>
|
|
141
|
+
<p>Your content here...</p>
|
|
142
|
+
</article>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This is automatically included when you import the stylesheet.
|
|
146
|
+
|
|
147
|
+
### Flexbox Layout
|
|
148
|
+
|
|
149
|
+
Sets up a flexible column layout structure:
|
|
150
|
+
|
|
151
|
+
```css
|
|
152
|
+
body {
|
|
153
|
+
display: flex;
|
|
154
|
+
flex-direction: column;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
body > main {
|
|
158
|
+
flex-grow: 1;
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The body becomes a flex container with column direction, and `main` elements automatically grow to fill available space. This is useful for creating sticky footers and full-height layouts.
|
|
163
|
+
|
|
164
|
+
This is automatically applied when you include the stylesheet.
|
|
165
|
+
|
|
166
|
+
### Breakout CSS
|
|
167
|
+
|
|
168
|
+
Includes [breakout-css](https://github.com/anydigital/breakout-css) utilities for breaking out images and figures beyond their container width. Use the `.breakout` class to allow elements to extend beyond their parent container:
|
|
169
|
+
|
|
170
|
+
```html
|
|
171
|
+
<div class="breakout">
|
|
172
|
+
<img src="image.jpg" alt="Description" />
|
|
173
|
+
</div>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The breakout container has `10%` inline padding and a max-width of `calc(10% + 65ch + 10%)`. The breakout utilities support images, pictures, figures, canvas, audio, video, tables, pre, iframe, and other media elements. Tables inside `.breakout` are specifically enhanced for horizontal scrolling and full-bleed mobile display. This is automatically included when you import the stylesheet.
|
|
177
|
+
|
|
178
|
+
## Bricks (Template Components)
|
|
179
|
+
|
|
180
|
+
The package includes reusable Liquid templates in the `bricks/` directory. These are useful for common web development patterns.
|
|
181
|
+
|
|
182
|
+
### Base HTML Template (`__html-begin.liquid` and `__html-end.liquid`)
|
|
183
|
+
|
|
184
|
+
Base HTML templates that provide the essential document structure with built-in support for modern web best practices. Split into begin and end files to wrap around your content.
|
|
185
|
+
|
|
186
|
+
**Features:**
|
|
187
|
+
|
|
188
|
+
- HTML5 DOCTYPE with language attribute (defaults to `en`, configurable via `site.lang`)
|
|
189
|
+
- UTF-8 charset and comprehensive viewport meta tag with `viewport-fit=cover` for notched devices
|
|
190
|
+
- Dynamic title generation with site title suffix (title is stripped of HTML tags and separated with `|`)
|
|
191
|
+
- Favicon link (to `/favicon.ico`)
|
|
192
|
+
- Automatic stylesheet linking from `site.styles` array
|
|
193
|
+
- Inline styles from `site.inline_styles` array (joined with newlines in a `<style>` tag)
|
|
194
|
+
- Automatic script loading from `site.scripts` array (with `defer` attribute)
|
|
195
|
+
- Inline module scripts from `site.inline_scripts` array (joined with newlines in a `<script type="module">` tag)
|
|
196
|
+
- Custom header content via `content_for_header`
|
|
197
|
+
- Google Tag Manager integration (automatically rendered via `_gtm.liquid` template for both `<head>` and `<body>`)
|
|
198
|
+
|
|
199
|
+
**Usage:**
|
|
200
|
+
|
|
201
|
+
```liquid
|
|
202
|
+
{% render 'bricks/__html-begin', site: site, title: title, content_for_header: content_for_header %}
|
|
203
|
+
|
|
204
|
+
<!-- Your page content -->
|
|
205
|
+
|
|
206
|
+
{% render 'bricks/__html-end' %}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Note: Google Tag Manager is automatically included in both `<head>` and `<body>` (via the `_gtm.liquid` template) when `site.prod` and `site.gtm_id` are set.
|
|
210
|
+
|
|
211
|
+
**Variables:**
|
|
212
|
+
|
|
213
|
+
- `title` - Page title (optional, will be stripped of HTML tags)
|
|
214
|
+
- `site.title` - Site title for the title suffix
|
|
215
|
+
- `site.lang` - Language code (optional, defaults to `'en'`)
|
|
216
|
+
- `site.styles` - Array of stylesheet URLs (optional)
|
|
217
|
+
- `site.inline_styles` - Array of inline CSS strings (optional)
|
|
218
|
+
- `site.scripts` - Array of script URLs (optional)
|
|
219
|
+
- `site.inline_scripts` - Array of inline JavaScript strings (optional)
|
|
220
|
+
- `content_for_header` - Custom HTML for the head section (optional)
|
|
221
|
+
- `site.gtm_id` - Google Tag Manager ID (optional)
|
|
222
|
+
- `site.prod` - Boolean flag for production environment (optional)
|
|
223
|
+
|
|
224
|
+
### Navigation (`_nav.liquid`)
|
|
225
|
+
|
|
226
|
+
A navigation template that renders a list of navigation links with proper accessibility attributes.
|
|
227
|
+
|
|
228
|
+
**Parameters:**
|
|
229
|
+
|
|
230
|
+
- `nav_pages` - Array of navigation page objects with `url` and `title` properties
|
|
231
|
+
- `current_url` - The URL of the current page (used to set `aria-current="page"`)
|
|
232
|
+
|
|
233
|
+
**Usage:**
|
|
234
|
+
|
|
235
|
+
```liquid
|
|
236
|
+
{% render 'bricks/_nav', nav_pages: navPages, current_url: page.url %}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Example:**
|
|
240
|
+
|
|
241
|
+
```liquid
|
|
242
|
+
{% assign navPages = site.pages | where: "nav", true %}
|
|
243
|
+
{% render 'bricks/_nav', nav_pages: navPages, current_url: page.url %}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Output:**
|
|
247
|
+
|
|
248
|
+
```html
|
|
249
|
+
<nav>
|
|
250
|
+
<a href="/">Home</a>
|
|
251
|
+
<a href="/about" aria-current="page">About</a>
|
|
252
|
+
<a href="/contact">Contact</a>
|
|
253
|
+
</nav>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Compatibility:** Compatible with [Eleventy Navigation plugin](https://www.11ty.dev/docs/plugins/navigation/#bring-your-own-html-render-the-menu-items-manually).
|
|
257
|
+
|
|
258
|
+
### Google Tag Manager (`_gtm.liquid`)
|
|
259
|
+
|
|
260
|
+
A template for embedding Google Tag Manager scripts in your pages.
|
|
261
|
+
|
|
262
|
+
**Parameters:**
|
|
263
|
+
|
|
264
|
+
- `site.gtm_id` - Your Google Tag Manager container ID (e.g., `GTM-XXXXXXX`)
|
|
265
|
+
- `site.prod` - Boolean flag to enable GTM only in production
|
|
266
|
+
- `for_body` - Boolean flag (default: `false`). When `false`, renders the script tag for the `<head>`. When `true`, renders the noscript fallback for the `<body>`.
|
|
267
|
+
|
|
268
|
+
**Note:** This template is automatically included when using `__html-begin.liquid` and `__html-end.liquid`. You only need to manually render it if you're not using those base templates.
|
|
269
|
+
|
|
270
|
+
**Manual Usage:**
|
|
271
|
+
|
|
272
|
+
In your base template's `<head>`:
|
|
273
|
+
|
|
274
|
+
```liquid
|
|
275
|
+
{% render 'bricks/_gtm', site: site %}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
In your base template's `<body>` (right after the opening tag):
|
|
279
|
+
|
|
280
|
+
```liquid
|
|
281
|
+
{% render 'bricks/_gtm', site: site, for_body: true %}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Example (Manual Integration):**
|
|
285
|
+
|
|
286
|
+
```liquid
|
|
287
|
+
<!DOCTYPE html>
|
|
288
|
+
<html>
|
|
289
|
+
<head>
|
|
290
|
+
{% render 'bricks/_gtm', site: site %}
|
|
291
|
+
</head>
|
|
292
|
+
<body>
|
|
293
|
+
{% render 'bricks/_gtm', site: site, for_body: true %}
|
|
294
|
+
<!-- Your content -->
|
|
295
|
+
</body>
|
|
296
|
+
</html>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Rendering Logic:** The GTM script is only rendered when both `site.prod` is `true` and `site.gtm_id` is set. The template uses a capture block to strip whitespace from the output.
|
|
300
|
+
|
|
301
|
+
## License
|
|
302
|
+
|
|
303
|
+
MIT
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
{% # if-true trick not to break auto-formatting %}
|
|
3
|
+
{% if true %}<html lang="{{ site.lang | default: 'en' }}">{% endif %}
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<meta charset="utf-8">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover">
|
|
8
|
+
<title>
|
|
9
|
+
{{- title | strip_html | append: ' | ' | if: title -}}
|
|
10
|
+
{{- site.title -}}
|
|
11
|
+
</title>
|
|
12
|
+
<link rel="icon" href="/favicon.ico">
|
|
13
|
+
|
|
14
|
+
{% # styles %}
|
|
15
|
+
{%- for href in site.styles %}
|
|
16
|
+
<link rel="stylesheet" href="{{ href }}">
|
|
17
|
+
{%- endfor %}
|
|
18
|
+
<style>
|
|
19
|
+
{{ site.inline_styles | join: '\n' }}
|
|
20
|
+
</style>
|
|
21
|
+
|
|
22
|
+
{% # scripts %}
|
|
23
|
+
{%- for src in site.scripts %}
|
|
24
|
+
<script src="{{ src }}" defer></script>
|
|
25
|
+
{%- endfor %}
|
|
26
|
+
<script type="module">
|
|
27
|
+
{{ site.inline_scripts | join: '\n' }}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
{% # custom %}
|
|
31
|
+
{{ content_for_header }}
|
|
32
|
+
|
|
33
|
+
{% render './_gtm', site: site %}
|
|
34
|
+
</head>
|
|
35
|
+
|
|
36
|
+
{% # if-true trick not to break auto-formatting %}
|
|
37
|
+
{% if true %}
|
|
38
|
+
<body>
|
|
39
|
+
{% render './_gtm', site: site, for_body: true %}
|
|
40
|
+
{% endif %}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* Prevent horizontal overflow and scrolling, modern way */
|
|
2
|
+
html,
|
|
3
|
+
body {
|
|
4
|
+
overflow-x: clip;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
/* Ensures body takes at least the full height of the viewport (using dynamic viewport height for better mobile support) */
|
|
9
|
+
min-height: 100dvh;
|
|
10
|
+
|
|
11
|
+
/* Enable hyphenation and font smoothing for better typography */
|
|
12
|
+
hyphens: auto;
|
|
13
|
+
-webkit-font-smoothing: antialiased;
|
|
14
|
+
-moz-osx-font-smoothing: grayscale;
|
|
15
|
+
|
|
16
|
+
/* Make the body a flex container with column layout; main fills space */
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
> main {
|
|
20
|
+
flex-grow: 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Disable hyphenation for links and tables */
|
|
24
|
+
a,
|
|
25
|
+
table {
|
|
26
|
+
hyphens: none;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{% if site.prod and site.gtm_id %}
|
|
2
|
+
{% capture _ %}
|
|
3
|
+
{% unless for_body %}
|
|
4
|
+
|
|
5
|
+
<!-- Google Tag Manager -->
|
|
6
|
+
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
7
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
8
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
9
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
10
|
+
})(window,document,'script','dataLayer','{{ site.gtm_id }}');</script>
|
|
11
|
+
<!-- End Google Tag Manager -->
|
|
12
|
+
|
|
13
|
+
{% else %}
|
|
14
|
+
|
|
15
|
+
<!-- Google Tag Manager (noscript) -->
|
|
16
|
+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ site.gtm_id }}"
|
|
17
|
+
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
|
18
|
+
<!-- End Google Tag Manager (noscript) -->
|
|
19
|
+
|
|
20
|
+
{% endunless %}
|
|
21
|
+
{% endcapture %}
|
|
22
|
+
{{ _ | strip }}
|
|
23
|
+
{% endif %}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<nav>
|
|
2
|
+
{%- for entry in nav_pages %}
|
|
3
|
+
{% # prettier-ignore %}
|
|
4
|
+
<a href="{{ entry.url }}" {% if entry.url == current_url %}aria-current="page"{% endif %}>
|
|
5
|
+
{{- entry.title -}}
|
|
6
|
+
</a>
|
|
7
|
+
{%- endfor %}
|
|
8
|
+
</nav>
|
|
9
|
+
{% # Compatible with https://www.11ty.dev/docs/plugins/navigation/#bring-your-own-html-render-the-menu-items-manually %}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
.prose {
|
|
2
|
+
/* Container-like behavior with padding and auto margins */
|
|
3
|
+
width: 100%;
|
|
4
|
+
padding: 1rem;
|
|
5
|
+
margin-inline: auto;
|
|
6
|
+
|
|
7
|
+
/* Helper for multi-line subtitles */
|
|
8
|
+
small {
|
|
9
|
+
vertical-align: top;
|
|
10
|
+
margin-top: 0.1em;
|
|
11
|
+
line-height: 1.1;
|
|
12
|
+
font-weight: 300;
|
|
13
|
+
/* Workaround to prevent underline inside links */
|
|
14
|
+
display: inline-block;
|
|
15
|
+
width: 100%;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
a {
|
|
19
|
+
text-underline-offset: 0.1em;
|
|
20
|
+
text-decoration-thickness: 1px;
|
|
21
|
+
/* Don't underline links that point to anchors */
|
|
22
|
+
&[href^="#"] {
|
|
23
|
+
text-decoration: none;
|
|
24
|
+
}
|
|
25
|
+
&:hover {
|
|
26
|
+
text-decoration-thickness: 2px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Helper to insert icons in links */
|
|
30
|
+
i {
|
|
31
|
+
height: 1em;
|
|
32
|
+
margin-right: 0.25em;
|
|
33
|
+
font-style: normal;
|
|
34
|
+
/* Workaround to prevent underline */
|
|
35
|
+
display: inline-block;
|
|
36
|
+
|
|
37
|
+
img {
|
|
38
|
+
height: 100%;
|
|
39
|
+
margin: 0;
|
|
40
|
+
position: relative;
|
|
41
|
+
bottom: -0.15em;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
img {
|
|
47
|
+
&:not(:where(.prose > img, .prose > p > img)) {
|
|
48
|
+
margin-top: 0;
|
|
49
|
+
margin-bottom: 1em;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
h1 {
|
|
54
|
+
margin-bottom: 0.5em !important;
|
|
55
|
+
|
|
56
|
+
small {
|
|
57
|
+
font-size: 50%;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
th,
|
|
62
|
+
td {
|
|
63
|
+
/* Keep extra space on the right for better horizontal scroll on mobile */
|
|
64
|
+
padding: 1rem 2rem 1rem 0;
|
|
65
|
+
vertical-align: top;
|
|
66
|
+
/* Workaround to widen particular columns */
|
|
67
|
+
hr {
|
|
68
|
+
width: 12ch;
|
|
69
|
+
height: 0;
|
|
70
|
+
margin: 0;
|
|
71
|
+
visibility: hidden;
|
|
72
|
+
/* &.ch16 {
|
|
73
|
+
width: 16ch;
|
|
74
|
+
} */
|
|
75
|
+
}
|
|
76
|
+
/* Workaround for headings in Markdown tables */
|
|
77
|
+
big {
|
|
78
|
+
font-weight: bold;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
th {
|
|
82
|
+
vertical-align: bottom;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
blockquote {
|
|
86
|
+
font-weight: 300;
|
|
87
|
+
|
|
88
|
+
+ figcaption {
|
|
89
|
+
margin-top: -1em;
|
|
90
|
+
text-align: right;
|
|
91
|
+
font-style: italic;
|
|
92
|
+
font-weight: 300;
|
|
93
|
+
|
|
94
|
+
&::before {
|
|
95
|
+
content: "—";
|
|
96
|
+
margin-right: 0.25em;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
code[data-caption] {
|
|
102
|
+
&::before {
|
|
103
|
+
content: attr(data-caption);
|
|
104
|
+
display: block;
|
|
105
|
+
margin-bottom: 1.5em;
|
|
106
|
+
opacity: 0.5;
|
|
107
|
+
font-style: italic;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
package/bricks/_util.css
ADDED
package/dist/bricks.css
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @anydigital/bricks
|
|
3
|
+
* Framework-agnostic CSS utility helpers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Prevent horizontal overflow and scrolling, modern way */
|
|
7
|
+
|
|
8
|
+
html,
|
|
9
|
+
body {
|
|
10
|
+
overflow-x: clip;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
body {
|
|
14
|
+
/* Ensures body takes at least the full height of the viewport (using dynamic viewport height for better mobile support) */
|
|
15
|
+
min-height: 100dvh;
|
|
16
|
+
|
|
17
|
+
/* Enable hyphenation and font smoothing for better typography */
|
|
18
|
+
hyphens: auto;
|
|
19
|
+
-webkit-font-smoothing: antialiased;
|
|
20
|
+
-moz-osx-font-smoothing: grayscale;
|
|
21
|
+
|
|
22
|
+
/* Make the body a flex container with column layout; main fills space */
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body > main {
|
|
28
|
+
flex-grow: 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Disable hyphenation for links and tables */
|
|
32
|
+
|
|
33
|
+
body a,body table {
|
|
34
|
+
hyphens: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.prose {
|
|
38
|
+
/* Container-like behavior with padding and auto margins */
|
|
39
|
+
width: 100%;
|
|
40
|
+
padding: 1rem;
|
|
41
|
+
margin-inline: auto;
|
|
42
|
+
|
|
43
|
+
/* Helper for multi-line subtitles */
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.prose small {
|
|
47
|
+
vertical-align: top;
|
|
48
|
+
margin-top: 0.1em;
|
|
49
|
+
line-height: 1.1;
|
|
50
|
+
font-weight: 300;
|
|
51
|
+
/* Workaround to prevent underline inside links */
|
|
52
|
+
display: inline-block;
|
|
53
|
+
width: 100%;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.prose a {
|
|
57
|
+
text-underline-offset: 0.1em;
|
|
58
|
+
text-decoration-thickness: 1px;
|
|
59
|
+
/* Don't underline links that point to anchors */
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.prose a[href^="#"] {
|
|
63
|
+
text-decoration: none;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.prose a:hover {
|
|
67
|
+
text-decoration-thickness: 2px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* Helper to insert icons in links */
|
|
71
|
+
|
|
72
|
+
.prose a i {
|
|
73
|
+
height: 1em;
|
|
74
|
+
margin-right: 0.25em;
|
|
75
|
+
font-style: normal;
|
|
76
|
+
/* Workaround to prevent underline */
|
|
77
|
+
display: inline-block;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.prose a i img {
|
|
81
|
+
height: 100%;
|
|
82
|
+
margin: 0;
|
|
83
|
+
position: relative;
|
|
84
|
+
bottom: -0.15em;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.prose img:not(:where(.prose > img,.prose > p > img)) {
|
|
88
|
+
margin-top: 0;
|
|
89
|
+
margin-bottom: 1em;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.prose h1 {
|
|
93
|
+
margin-bottom: 0.5em !important;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.prose h1 small {
|
|
97
|
+
font-size: 50%;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.prose th,.prose td {
|
|
101
|
+
/* Keep extra space on the right for better horizontal scroll on mobile */
|
|
102
|
+
padding: 1rem 2rem 1rem 0;
|
|
103
|
+
vertical-align: top;
|
|
104
|
+
/* Workaround to widen particular columns */
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.prose th hr,.prose td hr {
|
|
108
|
+
width: 12ch;
|
|
109
|
+
height: 0;
|
|
110
|
+
margin: 0;
|
|
111
|
+
visibility: hidden;
|
|
112
|
+
/* &.ch16 {
|
|
113
|
+
width: 16ch;
|
|
114
|
+
} */
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Workaround for headings in Markdown tables */
|
|
118
|
+
|
|
119
|
+
.prose th big,.prose td big {
|
|
120
|
+
font-weight: bold;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.prose th {
|
|
124
|
+
vertical-align: bottom;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.prose blockquote {
|
|
128
|
+
font-weight: 300;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.prose blockquote + figcaption {
|
|
132
|
+
margin-top: -1em;
|
|
133
|
+
text-align: right;
|
|
134
|
+
font-style: italic;
|
|
135
|
+
font-weight: 300;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.prose blockquote + figcaption::before {
|
|
139
|
+
content: "—";
|
|
140
|
+
margin-right: 0.25em;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.prose code[data-caption]::before {
|
|
144
|
+
content: attr(data-caption);
|
|
145
|
+
display: block;
|
|
146
|
+
margin-bottom: 1.5em;
|
|
147
|
+
opacity: 0.5;
|
|
148
|
+
font-style: italic;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Breakout CSS - Framework-agnostic utilities for breaking out images and figures */
|
|
152
|
+
|
|
153
|
+
.breakout {
|
|
154
|
+
/* Prepare the container for breakout elements */
|
|
155
|
+
padding-inline: 10%;
|
|
156
|
+
max-width: calc(10% + 65ch + 10%);
|
|
157
|
+
|
|
158
|
+
/* Direct children, or wrapped in <p> for Markdown support */
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.breakout > img:not(does-not-exist):not(.does-not-exist),.breakout > picture:not(does-not-exist):not(.does-not-exist),.breakout > figure:not(does-not-exist):not(.does-not-exist),.breakout > canvas:not(does-not-exist):not(.does-not-exist),.breakout > audio:not(does-not-exist):not(.does-not-exist),.breakout > table:not(does-not-exist):not(.does-not-exist),.breakout > pre:not(does-not-exist):not(.does-not-exist),.breakout > iframe:not(does-not-exist):not(.does-not-exist),.breakout > object:not(does-not-exist):not(.does-not-exist),.breakout > embed:not(does-not-exist):not(.does-not-exist),.breakout > video:not(does-not-exist):not(.does-not-exist),.breakout > .breakout-item:not(does-not-exist),.breakout > .breakout-item-max:not(does-not-exist),.breakout > p > img:not(.does-not-exist),.breakout > p > picture:not(.does-not-exist),.breakout > p > figure:not(.does-not-exist),.breakout > p > canvas:not(.does-not-exist),.breakout > p > audio:not(.does-not-exist),.breakout > p > table:not(.does-not-exist),.breakout > p > pre:not(.does-not-exist),.breakout > p > iframe:not(.does-not-exist),.breakout > p > object:not(.does-not-exist),.breakout > p > embed:not(.does-not-exist),.breakout > p > video:not(.does-not-exist),.breakout > p > .breakout-item,.breakout > p > .breakout-item-max {
|
|
162
|
+
width: -moz-fit-content;
|
|
163
|
+
width: fit-content;
|
|
164
|
+
min-width: 100%;
|
|
165
|
+
max-width: 125%;
|
|
166
|
+
margin-left: 50%;
|
|
167
|
+
transform: translateX(-50%);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Respect inline blocks' min-width */
|
|
171
|
+
|
|
172
|
+
.breakout > img:not(does-not-exist),.breakout > picture:not(does-not-exist),.breakout > figure:not(does-not-exist),.breakout > canvas:not(does-not-exist),.breakout > audio:not(does-not-exist),.breakout > p > img,.breakout > p > picture,.breakout > p > figure,.breakout > p > canvas,.breakout > p > audio {
|
|
173
|
+
min-width: auto;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Tables are so special :( */
|
|
177
|
+
|
|
178
|
+
.breakout > table:not(does-not-exist):not(.does-not-exist),.breakout > p > table:not(.does-not-exist) {
|
|
179
|
+
/* .does-not-exist is here to avoid !important below @TODO */
|
|
180
|
+
|
|
181
|
+
/* Let them full-bleed */
|
|
182
|
+
width: -moz-max-content;
|
|
183
|
+
width: max-content;
|
|
184
|
+
min-width: auto;
|
|
185
|
+
max-width: 100vw;
|
|
186
|
+
padding-inline: 7.5%;
|
|
187
|
+
|
|
188
|
+
/* Let them scroll */
|
|
189
|
+
display: block;
|
|
190
|
+
overflow-x: auto;
|
|
191
|
+
-webkit-overflow-scrolling: touch; /* Smooth scroll for iOS */
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* Max out the width of the element */
|
|
195
|
+
|
|
196
|
+
.breakout > .breakout-item-max:not(does-not-exist),.breakout > p > .breakout-item-max {
|
|
197
|
+
width: 125% !important; /* !important is for cases like figure.breakout-item-max @TODO */
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.breakout-headings h2:not([class]),.breakout-headings h3:not([class]),.breakout-headings h4:not([class]),.breakout-headings hr {
|
|
201
|
+
position: relative;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.breakout-headings h2:not([class])::before {
|
|
205
|
+
content: "";
|
|
206
|
+
display: block;
|
|
207
|
+
position: absolute;
|
|
208
|
+
background-color: rgba(0, 0, 0, 5%);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.breakout-headings h3:not([class])::before {
|
|
212
|
+
content: "";
|
|
213
|
+
display: block;
|
|
214
|
+
position: absolute;
|
|
215
|
+
background-color: rgba(0, 0, 0, 5%);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.breakout-headings h4:not([class])::before {
|
|
219
|
+
content: "";
|
|
220
|
+
display: block;
|
|
221
|
+
position: absolute;
|
|
222
|
+
background-color: rgba(0, 0, 0, 5%);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.breakout-headings hr:not(.does-not-exist)::before {
|
|
226
|
+
content: "";
|
|
227
|
+
display: block;
|
|
228
|
+
position: absolute;
|
|
229
|
+
background-color: rgba(0, 0, 0, 5%);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.breakout-headings h2:not([class])::before {
|
|
233
|
+
width: 10em;
|
|
234
|
+
right: 100%;
|
|
235
|
+
margin-right: 1rem;
|
|
236
|
+
height: 0.3em;
|
|
237
|
+
top: 50%;
|
|
238
|
+
transform: translateY(-50%);
|
|
239
|
+
background: linear-gradient(
|
|
240
|
+
to left,
|
|
241
|
+
rgba(0, 0, 0, 10%),
|
|
242
|
+
rgba(0, 0, 0, 5%) 10%,
|
|
243
|
+
transparent
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.breakout-headings h3:not([class])::before {
|
|
248
|
+
width: 10em;
|
|
249
|
+
right: 100%;
|
|
250
|
+
margin-right: 1rem;
|
|
251
|
+
height: 0.3em;
|
|
252
|
+
top: 50%;
|
|
253
|
+
transform: translateY(-50%);
|
|
254
|
+
background: linear-gradient(
|
|
255
|
+
to left,
|
|
256
|
+
rgba(0, 0, 0, 10%),
|
|
257
|
+
rgba(0, 0, 0, 5%) 10%,
|
|
258
|
+
transparent
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.breakout-headings h4:not([class])::before {
|
|
263
|
+
width: 10em;
|
|
264
|
+
right: 100%;
|
|
265
|
+
margin-right: 1rem;
|
|
266
|
+
height: 0.3em;
|
|
267
|
+
top: 50%;
|
|
268
|
+
transform: translateY(-50%);
|
|
269
|
+
background: linear-gradient(
|
|
270
|
+
to left,
|
|
271
|
+
rgba(0, 0, 0, 10%),
|
|
272
|
+
rgba(0, 0, 0, 5%) 10%,
|
|
273
|
+
transparent
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.breakout-headings hr {
|
|
278
|
+
height: 0.75rem;
|
|
279
|
+
border: none;
|
|
280
|
+
overflow: visible;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.breakout-headings hr::before {
|
|
284
|
+
width: 100vw;
|
|
285
|
+
left: 50%;
|
|
286
|
+
height: 100%;
|
|
287
|
+
transform: translateX(-50%);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.breakout-headings hr + h2::before {
|
|
291
|
+
display: none !important;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.breakout-headings hr + h3::before {
|
|
295
|
+
display: none !important;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.breakout-headings hr + h4::before {
|
|
299
|
+
display: none !important;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* after prose to override it */
|
|
303
|
+
|
|
304
|
+
/* Prism.js */
|
|
305
|
+
|
|
306
|
+
.token.treeview-part .entry-line {
|
|
307
|
+
width: 2.5em !important;
|
|
308
|
+
opacity: 25%;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.token.treeview-part .entry-name:last-child {
|
|
312
|
+
opacity: 50%;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.token.treeview-part .entry-name:last-child::before {
|
|
316
|
+
display: none !important;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* Utility classes */
|
|
320
|
+
|
|
321
|
+
.invert ::-webkit-scrollbar {
|
|
322
|
+
filter: invert(1) !important;
|
|
323
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@anydigital/bricks",
|
|
3
|
+
"version": "0.21.0",
|
|
4
|
+
"description": "Framework-agnostic CSS utilities and single-file Liquid 'bricks' for modern web development.",
|
|
5
|
+
"main": "dist/bricks.css",
|
|
6
|
+
"style": "dist/bricks.css",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"postcss": "postcss bricks/bricks.css -o dist/bricks.css",
|
|
9
|
+
"build": "npm run postcss -- --no-map",
|
|
10
|
+
"start": "npm run postcss -- --watch",
|
|
11
|
+
"prepublishOnly": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/anydigital/bricks.git"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"css",
|
|
19
|
+
"utilities",
|
|
20
|
+
"helpers",
|
|
21
|
+
"atomic",
|
|
22
|
+
"cdn"
|
|
23
|
+
],
|
|
24
|
+
"author": "Anton Staroverov",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@anydigital/breakout-css": "^0.11.0",
|
|
28
|
+
"postcss": "^8.4.33",
|
|
29
|
+
"postcss-cli": "^11.0.0",
|
|
30
|
+
"postcss-import": "^16.1.1",
|
|
31
|
+
"postcss-preset-env": "^10.6.0"
|
|
32
|
+
}
|
|
33
|
+
}
|