Start bringing over a (curated) configuration for CSS and Eleventy
This commit is contained in:
commit
6c599aeaaf
24
.eleventy.js
Normal file
24
.eleventy.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
module.exports = function(eleventyConfig) {
|
||||||
|
// Configure passthrough copies, file ops
|
||||||
|
eleventyConfig.addPlugin(require('./config/files'));
|
||||||
|
// Setup plugins
|
||||||
|
eleventyConfig.addPlugin(require('./config/plugins'));
|
||||||
|
// Custom filters and shortcodes
|
||||||
|
eleventyConfig.addPlugin(require('./config/filters'));
|
||||||
|
// Custom collections
|
||||||
|
eleventyConfig.addPlugin(require('./config/collections'));
|
||||||
|
|
||||||
|
return {
|
||||||
|
passthroughFileCopy: true,
|
||||||
|
dataTemplateEngine: false,
|
||||||
|
markdownTemplateEngine: "njk",
|
||||||
|
|
||||||
|
htmlTemplateEngine: "njk",
|
||||||
|
dir: {
|
||||||
|
input: "src",
|
||||||
|
includes: "_includes",
|
||||||
|
data: "_data",
|
||||||
|
output: "_site"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
src/css/custom-props.css
|
||||||
|
_site
|
1
config/collections/index.js
Normal file
1
config/collections/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = function() {}
|
9
config/files/index.js
Normal file
9
config/files/index.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module.exports = function(eleventyConfig) {
|
||||||
|
if (process.env.NODE_ENV !== "development") {
|
||||||
|
eleventyConfig.ignores.add("src/posts/drafts/*");
|
||||||
|
}
|
||||||
|
|
||||||
|
eleventyConfig.addPassthroughCopy("src/assets");
|
||||||
|
eleventyConfig.setDataDeepMerge(true);
|
||||||
|
eleventyConfig.setFrontMatterParsingOptions({ excerpt: true });
|
||||||
|
}
|
1
config/filters/index.js
Normal file
1
config/filters/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = function() {}
|
54
config/plugins/image.js
Normal file
54
config/plugins/image.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
const Image = require('@11ty/eleventy-img');
|
||||||
|
|
||||||
|
const defaultSizes = `
|
||||||
|
(max-width: 300px) 300px,
|
||||||
|
(max-width: 600px) 600px,
|
||||||
|
(max-width: 1000px) 1000px,
|
||||||
|
(max-width: 1440px) 1440px,
|
||||||
|
(max-width: 2500px) 2500px,
|
||||||
|
(min-width: 2500px) 3840px
|
||||||
|
`;
|
||||||
|
|
||||||
|
const imageShortcode = (src, alt, cls, sizes = defaultSizes, widths = [300, 600, 1000, 1440, 2500, 3840]) => {
|
||||||
|
let options = {
|
||||||
|
widths: widths,
|
||||||
|
formats: ['webp', 'jpeg'],
|
||||||
|
outputDir: "./_site/img",
|
||||||
|
};
|
||||||
|
|
||||||
|
// generate images, while this is async we don’t wait
|
||||||
|
Image(src, options);
|
||||||
|
|
||||||
|
let imageAttributes = {
|
||||||
|
class: cls,
|
||||||
|
alt,
|
||||||
|
sizes,
|
||||||
|
decoding: "async",
|
||||||
|
};
|
||||||
|
// get metadata even the images are not fully generated
|
||||||
|
let metadata = Image.statsSync(src, options);
|
||||||
|
return Image.generateHTML(metadata, imageAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
const remoteImageShortcode = async (src, alt, cls, sizes = defaultSizes, widths = [300, 600, 1000, 1440, 2500, 3840]) => {
|
||||||
|
let metadata = await Image(src, {
|
||||||
|
widths,
|
||||||
|
formats: ["webp", "avif", "jpeg", "png"],
|
||||||
|
outputDir: "./_site/img",
|
||||||
|
});
|
||||||
|
|
||||||
|
let imageAttributes = {
|
||||||
|
alt,
|
||||||
|
class: cls,
|
||||||
|
sizes,
|
||||||
|
loading: "lazy",
|
||||||
|
decoding: "async",
|
||||||
|
};
|
||||||
|
|
||||||
|
// You bet we throw an error on missing alt in `imageAttributes` (alt="" works okay)
|
||||||
|
return Image.generateHTML(metadata, imageAttributes);
|
||||||
|
}
|
||||||
|
module.exports = function(eleventyConfig) {
|
||||||
|
eleventyConfig.addShortcode("image", imageShortcode);
|
||||||
|
eleventyConfig.addAsyncShortcode("remoteImage", remoteImageShortcode);
|
||||||
|
}
|
11
config/plugins/index.js
Normal file
11
config/plugins/index.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const markdownPlugin = require('./markdown');
|
||||||
|
const rss = require('@11ty/eleventy-plugin-rss');
|
||||||
|
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
|
||||||
|
const imagePlugin = require('./image');
|
||||||
|
|
||||||
|
module.exports = function(eleventyConfig) {
|
||||||
|
eleventyConfig.addPlugin(syntaxHighlight);
|
||||||
|
eleventyConfig.addPlugin(rss);
|
||||||
|
eleventyConfig.addPlugin(markdownPlugin);
|
||||||
|
eleventyConfig.addPlugin(imagePlugin);
|
||||||
|
}
|
69
config/plugins/markdown.js
Normal file
69
config/plugins/markdown.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const markdownIt = require('markdown-it');
|
||||||
|
const markdownItPrism = require('markdown-it-prism');
|
||||||
|
const markdownItAnchor = require('markdown-it-anchor');
|
||||||
|
const markdownItClass = require('@toycode/markdown-it-class');
|
||||||
|
const markdownItLinkAttributes = require('markdown-it-link-attributes');
|
||||||
|
const markdownItEmoji = require('markdown-it-emoji');
|
||||||
|
const markdownItFootnote = require('markdown-it-footnote');
|
||||||
|
const markdownitMark = require('markdown-it-mark');
|
||||||
|
const markdownitAbbr = require('markdown-it-abbr');
|
||||||
|
const markdownItEleventyImg = require('markdown-it-eleventy-img');
|
||||||
|
const { slugifyString } = require('../utils');
|
||||||
|
const markdownLib = markdownIt({
|
||||||
|
html: true,
|
||||||
|
breaks: true,
|
||||||
|
linkify: true,
|
||||||
|
typographer: true
|
||||||
|
})
|
||||||
|
.disable('code')
|
||||||
|
.use(markdownItPrism, {
|
||||||
|
defaultLanguage: 'plaintext'
|
||||||
|
})
|
||||||
|
.use(markdownItAnchor, {
|
||||||
|
slugify: slugifyString,
|
||||||
|
tabIndex: false,
|
||||||
|
permalink: markdownItAnchor.permalink.headerLink({
|
||||||
|
class: 'heading-anchor'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.use(markdownItClass, {
|
||||||
|
ol: 'list',
|
||||||
|
ul: 'list'
|
||||||
|
})
|
||||||
|
.use(markdownItLinkAttributes, [
|
||||||
|
{
|
||||||
|
// match external links
|
||||||
|
matcher(href) {
|
||||||
|
return href.match(/^https?:\/\//);
|
||||||
|
},
|
||||||
|
attrs: {
|
||||||
|
target: '_blank',
|
||||||
|
rel: 'noreferrer noopener'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.use(markdownItEmoji)
|
||||||
|
.use(markdownItFootnote)
|
||||||
|
.use(markdownitMark)
|
||||||
|
.use(markdownitAbbr)
|
||||||
|
.use(markdownItEleventyImg, {
|
||||||
|
imgOptions: {
|
||||||
|
widths: [300, 600, 1000, 1440],
|
||||||
|
urlPath: "/img/",
|
||||||
|
outputDir: path.join("_site", "img"),
|
||||||
|
formats: ["avif", "webp", "jpeg"]
|
||||||
|
},
|
||||||
|
globalAttributes: {
|
||||||
|
sizes: `(max-width: 300px) 300px,
|
||||||
|
(max-width: 600px) 600px,
|
||||||
|
(max-width: 1000px) 1000px,
|
||||||
|
(max-width: 1440px) 1440px,
|
||||||
|
100%`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = function(eleventyConfig) {
|
||||||
|
eleventyConfig.setLibrary('md', markdownLib);
|
||||||
|
};
|
14
config/utils.js
Normal file
14
config/utils.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
const slugify = require('slugify');
|
||||||
|
|
||||||
|
/** Converts string to a slug form. */
|
||||||
|
const slugifyString = str => {
|
||||||
|
return slugify(str, {
|
||||||
|
replacement: '-',
|
||||||
|
remove: /[#,&,+()$~%.'":*?<>{}]/g,
|
||||||
|
lower: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
slugifyString
|
||||||
|
}
|
9025
package-lock.json
generated
Normal file
9025
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
39
package.json
Normal file
39
package.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"name": "whimsy",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"serve": "run-p \"serve:*\"",
|
||||||
|
"serve:props": "node scripts/custom-props.js",
|
||||||
|
"serve:css": "postcss src/css/styles.css --base src --dir _site/assets -w",
|
||||||
|
"serve:eleventy": "eleventy --serve",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@11ty/eleventy": "^2.0.0-beta.3",
|
||||||
|
"@11ty/eleventy-fetch": "^3.0.0",
|
||||||
|
"@11ty/eleventy-img": "^3.0.0",
|
||||||
|
"@11ty/eleventy-plugin-rss": "^1.2.0",
|
||||||
|
"@11ty/eleventy-plugin-syntaxhighlight": "^4.2.0",
|
||||||
|
"@toycode/markdown-it-class": "^1.2.4",
|
||||||
|
"autoprefixer": "^10.4.13",
|
||||||
|
"markdown-it-abbr": "^1.0.4",
|
||||||
|
"markdown-it-anchor": "^8.6.6",
|
||||||
|
"markdown-it-eleventy-img": "^0.9.0",
|
||||||
|
"markdown-it-emoji": "^2.0.2",
|
||||||
|
"markdown-it-footnote": "^3.0.3",
|
||||||
|
"markdown-it-link-attributes": "^4.0.1",
|
||||||
|
"markdown-it-mark": "^3.0.1",
|
||||||
|
"markdown-it-prism": "^2.3.0",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"postcss": "^8.4.21",
|
||||||
|
"postcss-cli": "^10.1.0",
|
||||||
|
"postcss-import": "^15.1.0",
|
||||||
|
"postcss-import-ext-glob": "^2.1.1",
|
||||||
|
"prettier": "^2.8.3",
|
||||||
|
"tailwindcss": "^3.2.4"
|
||||||
|
}
|
||||||
|
}
|
9
postcss.config.js
Normal file
9
postcss.config.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
'postcss-import-ext-glob': {},
|
||||||
|
'postcss-import': {},
|
||||||
|
'tailwindcss/nesting': {},
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
67
scripts/custom-props.js
Normal file
67
scripts/custom-props.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
const fs = require('node:fs');
|
||||||
|
const prettier = require('prettier');
|
||||||
|
const config = require('../tailwind.config.js');
|
||||||
|
|
||||||
|
const groupToPrefix = (group, prefix) => {
|
||||||
|
return Object.entries(group).map(([key, value]) => {
|
||||||
|
if (value instanceof Object && !(value instanceof Array)) {
|
||||||
|
return groupToPrefix(value, `${prefix}-${key}`);
|
||||||
|
} else {
|
||||||
|
return `--${prefix}-${key}: ${value};`
|
||||||
|
}
|
||||||
|
}).join('');
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Converts the tailwind config elements into custom props.
|
||||||
|
*/
|
||||||
|
const generateCSSProps = () => {
|
||||||
|
let result = '';
|
||||||
|
|
||||||
|
const groups = [
|
||||||
|
{key: 'colors', prefix: 'color'},
|
||||||
|
{key: 'spacing', prefix: 'space'},
|
||||||
|
{key: 'fontSize', prefix: 'text'},
|
||||||
|
{key: 'fontFamily', prefix: 'font-family'},
|
||||||
|
{key: 'screens', prefix: 'screen'},
|
||||||
|
{key: 'gap', prefix: 'gap'},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Add a note that this is auto generated
|
||||||
|
result += `
|
||||||
|
/* VARIABLES GENERATED WITH TAILWIND CONFIG ON ${new Date().toLocaleDateString()}.
|
||||||
|
Tokens location: ./tailwind.config.js */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Loop each group's keys, use that and the associated
|
||||||
|
// property to define a :root custom prop
|
||||||
|
groups.forEach(({key, prefix}) => {
|
||||||
|
const group = config.theme[key];
|
||||||
|
|
||||||
|
if (!group) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Object.keys(group).forEach(key => {
|
||||||
|
// result += `--${prefix}-${key}: ${group[key]};`;
|
||||||
|
// });
|
||||||
|
|
||||||
|
result += groupToPrefix(group, prefix);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close the :root block
|
||||||
|
result += `
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Make the CSS readable to help people with auto-complete in their editors
|
||||||
|
result = prettier.format(result, {parser: 'scss'});
|
||||||
|
|
||||||
|
// Push this file into the CSS dir, ready to go
|
||||||
|
fs.writeFileSync('./src/css/custom-props.css', result);
|
||||||
|
};
|
||||||
|
|
||||||
|
generateCSSProps();
|
||||||
|
module.exports = generateCSSProps;
|
10
src/_data/metadata.json
Normal file
10
src/_data/metadata.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"author": {
|
||||||
|
"name": "Lewis Dale"
|
||||||
|
},
|
||||||
|
"site": {
|
||||||
|
"name": "LewisDale dot Dev",
|
||||||
|
"domain": "lewisdale.dev",
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
11
src/_includes/base.njk
Normal file
11
src/_includes/base.njk
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang={{data.page.lang}}>
|
||||||
|
<head>
|
||||||
|
<title>{{ title }} | {{ metadata.site.name }}</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="/assets/css/styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{ content | safe }}
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Bold.ttf
Normal file
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Bold.ttf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Bold.woff2
Normal file
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Bold.woff2
Normal file
Binary file not shown.
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Light.ttf
Normal file
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Light.ttf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Light.woff2
Normal file
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Light.woff2
Normal file
Binary file not shown.
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Medium.ttf
Normal file
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Medium.ttf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Medium.woff2
Normal file
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Medium.woff2
Normal file
Binary file not shown.
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Regular.ttf
Normal file
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Regular.ttf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Regular.woff2
Normal file
BIN
src/assets/fonts/Space_Grotesk/SpaceGrotesk-Regular.woff2
Normal file
Binary file not shown.
6
src/css/cube.css
Normal file
6
src/css/cube.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@import-glob "compositions/*";
|
||||||
|
@import-glob "utilities/*";
|
||||||
|
@import-glob "blocks/*";
|
||||||
|
@import-glob "exceptions/*";
|
||||||
|
|
||||||
|
@tailwind utilities;
|
72
src/css/fonts/space_grotesk.css
Normal file
72
src/css/fonts/space_grotesk.css
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
src: url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Bold.woff2') format('woff2'),
|
||||||
|
url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Bold.woff') format('woff');
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
src: url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Bold.woff2') format('woff2'),
|
||||||
|
url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Bold.woff') format('woff');
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
src: url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Medium.woff2') format('woff2'),
|
||||||
|
url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Medium.woff') format('woff');
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
src: url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Medium.woff2') format('woff2'),
|
||||||
|
url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Medium.woff') format('woff');
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
src: url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Light.woff2') format('woff2'),
|
||||||
|
url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Light.woff') format('woff');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
src: url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Regular.woff2') format('woff2'),
|
||||||
|
url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Regular.woff') format('woff');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
src: url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Regular.woff2') format('woff2'),
|
||||||
|
url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Regular.woff') format('woff');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Grotesk';
|
||||||
|
src: url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Light.woff2') format('woff2'),
|
||||||
|
url('/assets/fonts/Space_Grotesk/SpaceGrotesk-Light.woff') format('woff');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
4
src/css/globals.css
Normal file
4
src/css/globals.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
body {
|
||||||
|
font-family: var(--font-family-mono);
|
||||||
|
font-size: var(--font-size-s);
|
||||||
|
}
|
80
src/css/reset.css
Normal file
80
src/css/reset.css
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* Modern reset: https://piccalil.li/blog/a-modern-css-reset/ */
|
||||||
|
|
||||||
|
/* Box sizing rules */
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove default margin */
|
||||||
|
body,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
p,
|
||||||
|
figure,
|
||||||
|
blockquote,
|
||||||
|
dl,
|
||||||
|
dd {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
|
||||||
|
ul,
|
||||||
|
ol,
|
||||||
|
[role='list'] {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set core root defaults */
|
||||||
|
html:focus-within {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set core body defaults */
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
min-height: 100dvh; /* safari-specific */
|
||||||
|
text-rendering: optimizeSpeed;
|
||||||
|
line-height: 1.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A elements that don't have a class get default styles */
|
||||||
|
a:not([class]) {
|
||||||
|
text-decoration-skip-ink: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make images easier to work with */
|
||||||
|
img,
|
||||||
|
picture {
|
||||||
|
max-width: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inherit fonts for inputs and buttons */
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
html:focus-within {
|
||||||
|
scroll-behavior: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
}
|
||||||
|
}
|
11
src/css/styles.css
Normal file
11
src/css/styles.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
@import-glob "fonts/*";
|
||||||
|
@import "custom-props.css";
|
||||||
|
@import "reset.css";
|
||||||
|
@import "globals.css";
|
||||||
|
|
||||||
|
@import-glob "compositions/*";
|
||||||
|
@import-glob "utilities/*";
|
||||||
|
@import-glob "blocks/*";
|
||||||
|
@import-glob "exceptions/*";
|
||||||
|
|
||||||
|
@tailwind utilities;
|
6
src/index.html
Normal file
6
src/index.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: Home
|
||||||
|
layout: base.njk
|
||||||
|
---
|
||||||
|
|
||||||
|
<h1>{{ metadata.site.name }}</h1>
|
92
tailwind.config.js
Normal file
92
tailwind.config.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
const defaultTheme = require('tailwindcss/defaultTheme');
|
||||||
|
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
mode: 'jit',
|
||||||
|
content: ["./src/**/*.{md,njk,html}"],
|
||||||
|
theme: {
|
||||||
|
screens: {
|
||||||
|
'sm': '640px',
|
||||||
|
'md': '768px',
|
||||||
|
'lg': '1024px',
|
||||||
|
'xl': '1280px',
|
||||||
|
'2xl': '1536px',
|
||||||
|
'3xl': '1920px',
|
||||||
|
},
|
||||||
|
colors: defaultTheme.colors,
|
||||||
|
backgroundColor: ({theme}) => theme('colors'),
|
||||||
|
textColor: ({theme}) => theme('colors'),
|
||||||
|
spacing: {
|
||||||
|
'size-3xs': 'clamp(0.25rem, calc(0.24rem + 0.06vw), 0.31rem)',
|
||||||
|
'size-2xs': 'clamp(0.50rem, calc(0.48rem + 0.13vw), 0.63rem)',
|
||||||
|
'size-xs': 'clamp(0.75rem, calc(0.71rem + 0.19vw), 0.94rem)',
|
||||||
|
'size-s': 'clamp(1.00rem, calc(0.95rem + 0.25vw), 1.25rem)',
|
||||||
|
'size-m': 'clamp(1.50rem, calc(1.43rem + 0.38vw), 1.88rem)',
|
||||||
|
'size-l': 'clamp(2.00rem, calc(1.90rem + 0.50vw), 2.50rem)',
|
||||||
|
'size-xl': 'clamp(3.00rem, calc(2.85rem + 0.75vw), 3.75rem)',
|
||||||
|
'size-2xl': 'clamp(4.00rem, calc(3.80rem + 1.00vw), 5.00rem)',
|
||||||
|
'size-3xl': 'clamp(6.00rem, calc(5.70rem + 1.50vw), 7.50rem)',
|
||||||
|
},
|
||||||
|
fontSize: {
|
||||||
|
'size-2xs': 'clamp(0.56rem, calc(0.72rem + -0.14vw), 0.69rem)',
|
||||||
|
'size-xs': 'clamp(0.83rem, calc(0.83rem + 0.00vw), 0.83rem)',
|
||||||
|
'size-s': 'clamp(1.00rem, calc(0.95rem + 0.25vw), 1.25rem)',
|
||||||
|
'size-m': 'clamp(1.20rem, calc(1.07rem + 0.68vw), 1.88rem)',
|
||||||
|
'size-l': 'clamp(1.44rem, calc(1.17rem + 1.37vw), 2.81rem)',
|
||||||
|
'size-xl': 'clamp(1.73rem, calc(1.23rem + 2.49vw), 4.22rem)',
|
||||||
|
'size-2xl': 'clamp(2.07rem, calc(1.22rem + 4.25vw), 6.33rem)',
|
||||||
|
'size-3xl': 'clamp(2.49rem, calc(1.09rem + 7.00vw), 9.49rem)',
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans: defaultTheme.fontFamily.sans,
|
||||||
|
mono: ['"Space Grotesk"', ...defaultTheme.fontFamily.mono],
|
||||||
|
},
|
||||||
|
gap: ({theme}) => ({
|
||||||
|
none: '0px',
|
||||||
|
...theme('spacing'),
|
||||||
|
}),
|
||||||
|
margin: ({theme}) => ({
|
||||||
|
auto: 'auto',
|
||||||
|
none: '0',
|
||||||
|
...theme('spacing')
|
||||||
|
}),
|
||||||
|
padding: ({theme}) => ({
|
||||||
|
none: '0',
|
||||||
|
...theme('spacing')
|
||||||
|
}),
|
||||||
|
scrollMargin: ({theme}) => theme('spacing'),
|
||||||
|
textColor: ({theme}) => theme('colors'),
|
||||||
|
zIndex: {
|
||||||
|
auto: 'auto',
|
||||||
|
0: '0',
|
||||||
|
10: '10',
|
||||||
|
20: '20',
|
||||||
|
30: '30',
|
||||||
|
40: '40',
|
||||||
|
50: '50',
|
||||||
|
60: '60',
|
||||||
|
70: '70',
|
||||||
|
80: '80',
|
||||||
|
90: '90',
|
||||||
|
100: '100',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
variantOrder: [
|
||||||
|
'first',
|
||||||
|
'last',
|
||||||
|
'odd',
|
||||||
|
'even',
|
||||||
|
'visited',
|
||||||
|
'checked',
|
||||||
|
'empty',
|
||||||
|
'read-only',
|
||||||
|
'group-hover',
|
||||||
|
'group-focus',
|
||||||
|
'focus-within',
|
||||||
|
'hover',
|
||||||
|
'focus',
|
||||||
|
'focus-visible',
|
||||||
|
'active',
|
||||||
|
'disabled',
|
||||||
|
],
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user