├── .eleventy.js ├── .eleventyignore ├── .gitignore ├── .prettierrc ├── gulp-tasks ├── fonts.js ├── images.js └── sass.js ├── gulpfile.js ├── netlify.toml ├── package-lock.json ├── package.json ├── readme.md └── src ├── _data ├── global.js ├── helpers.js ├── navigation.json ├── patterns.js ├── site.json └── tokens.json ├── _includes ├── layouts │ ├── base.njk │ ├── home.njk │ └── page.njk ├── partials │ ├── meta-info.njk │ ├── pagination.njk │ └── site-head.njk └── prototype.js ├── about.md ├── colors.njk ├── filters └── markdown-filter.js ├── images └── .gitkeep ├── index.md ├── pattern.njk ├── patterns ├── button │ ├── button.json │ ├── button.njk │ ├── docs.md │ └── variants │ │ ├── button-secondary.json │ │ └── button-secondary.njk ├── patterns.json └── toggle-switch │ ├── docs.md │ ├── toggle-switch.json │ └── toggle-switch.njk ├── preview.njk ├── scss ├── _config.scss ├── _reset.scss ├── blocks │ ├── .gitkeep │ ├── _code-sample.scss │ ├── _side-nav.scss │ └── _swatch.scss ├── critical.scss └── utilities │ ├── _auto-grid.scss │ ├── _flow.scss │ ├── _sidebar.scss │ ├── _visually-hidden.scss │ └── _wrapper.scss └── typography.njk /.eleventy.js: -------------------------------------------------------------------------------- 1 | // Create a global base directory variable for easier includes 2 | global.__basedir = __dirname; 3 | 4 | const markdownFilter = require('./src/filters/markdown-filter.js'); 5 | 6 | module.exports = config => { 7 | // Tell 11ty to use the .eleventyignore and ignore our .gitignore file 8 | config.setUseGitIgnore(false); 9 | 10 | config.addCollection('patterns', collection => { 11 | return collection.getFilteredByGlob('./src/patterns/**/*.njk'); 12 | }); 13 | 14 | config.addFilter('markdownFilter', markdownFilter); 15 | 16 | return { 17 | markdownTemplateEngine: 'njk', 18 | dataTemplateEngine: 'njk', 19 | htmlTemplateEngine: 'njk', 20 | dir: { 21 | input: 'src', 22 | output: 'dist' 23 | } 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /.eleventyignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Misc 2 | *.log 3 | npm-debug.* 4 | *.scssc 5 | *.log 6 | *.swp 7 | .DS_Store 8 | Thumbs.db 9 | .sass-cache 10 | .env 11 | .cache 12 | 13 | # Node modules and output 14 | node_modules 15 | dist 16 | src/_includes/css 17 | .vscode 18 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 90, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "bracketSpacing": false, 6 | "quoteProps": "consistent", 7 | "trailingComma": "none", 8 | "arrowParens": "avoid" 9 | } 10 | -------------------------------------------------------------------------------- /gulp-tasks/fonts.js: -------------------------------------------------------------------------------- 1 | const {dest, src} = require('gulp'); 2 | const GetGoogleFonts = require('get-google-fonts'); 3 | 4 | const fonts = async () => { 5 | // Setup of the library instance by setting where we want 6 | // the output to go. CSS is relative to output font directory 7 | const instance = new GetGoogleFonts({ 8 | outputDir: './dist/fonts', 9 | cssFile: './fonts.css' 10 | }); 11 | 12 | // Grabs fonts and CSS from google and puts in the dist folder 13 | const result = await instance.download( 14 | 'https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap' 15 | ); 16 | 17 | return result; 18 | }; 19 | 20 | module.exports = fonts; 21 | -------------------------------------------------------------------------------- /gulp-tasks/images.js: -------------------------------------------------------------------------------- 1 | const {dest, src} = require('gulp'); 2 | const imagemin = require('gulp-imagemin'); 3 | 4 | // Grabs all images, runs them through imagemin 5 | // and plops them in the dist folder 6 | const images = cb => { 7 | // We have specific configs for jpeg and png files to try 8 | // to really pull down asset sizes 9 | return src('./src/images/**/*') 10 | .pipe( 11 | imagemin( 12 | [ 13 | imagemin.mozjpeg({quality: 60, progressive: true}), 14 | imagemin.optipng({optimizationLevel: 5, interlaced: null}) 15 | ], 16 | { 17 | silent: true 18 | } 19 | ) 20 | ) 21 | .pipe(dest('./dist/images')) 22 | .on('done', cb); 23 | }; 24 | 25 | module.exports = images; 26 | -------------------------------------------------------------------------------- /gulp-tasks/sass.js: -------------------------------------------------------------------------------- 1 | const {dest, src} = require('gulp'); 2 | const cleanCSS = require('gulp-clean-css'); 3 | const sassProcessor = require('gulp-sass'); 4 | 5 | // We want to be using canonical Sass, rather than node-sass 6 | sassProcessor.compiler = require('sass'); 7 | 8 | // Flags wether we compress the output etc 9 | const isProduction = process.env.NODE_ENV === 'production'; 10 | 11 | // An array of outputs that should be sent over to includes 12 | const criticalStyles = ['critical.scss']; 13 | 14 | // Takes the arguments passed by `dest` and determines where the output file goes 15 | const calculateOutput = ({history}) => { 16 | // By default, we want a CSS file in our dist directory, so the 17 | // HTML can grab it with a 18 | let response = './dist/css'; 19 | 20 | // Get everything after the last slash 21 | const sourceFileName = /[^/]*$/.exec(history[0])[0]; 22 | 23 | // If this is critical CSS though, we want it to go 24 | // to the _includes directory, so nunjucks can include it 25 | // directly in a 12 | 13 | {# Add facility for pages to delare an array of critical styles #} 14 | {% if pageCriticalStyles %} 15 | {% for item in pageCriticalStyles %} 16 | 17 | {% endfor %} 18 | {% endif %} 19 | 20 | 21 | 22 | {# Add facility for pages to declare an array of stylesheet paths #} 23 | {% if pageStylesheets %} 24 | {% for item in pageStylesheets %} 25 | 26 | {% endfor %} 27 | {% endif %} 28 | 29 | 30 | {% include "partials/site-head.njk" %} 31 | 32 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/_includes/layouts/home.njk: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base.njk" %} 2 | 3 | {% block content %} 4 |
5 |

Homepage

6 |

This could be a lander with info on how to get started working in the pattern library etc.

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /src/_includes/layouts/page.njk: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base.njk" %} 2 | 3 | {% block content %} 4 |
5 |

{{ title }}

6 | {{ content | safe }} 7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /src/_includes/partials/meta-info.njk: -------------------------------------------------------------------------------- 1 | {% set pageTitle = title + ' - ' + site.name %} 2 | 3 | {# We don't want any duplication. This is likely for the homepage #} 4 | {% if site.name === title %} 5 | {% set pageTitle = title %} 6 | {% endif %} 7 | 8 | {% set siteTitle = site.name %} 9 | {% set currentUrl = site.url + page.url %} 10 | 11 | {# If the page’s frontmatter has specific metaTitle and/or metaDesc items, switch 12 | them into the mix #} 13 | {% if metaTitle %} 14 | {% set pageTitle = metaTitle %} 15 | {% endif %} 16 | 17 | {% if not metaDesc %} 18 | {% set metaDesc = summary %} 19 | {% endif %} 20 | 21 | 22 | {{ pageTitle }} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% if socialImage %} 31 | 32 | 33 | 34 | 35 | 36 | {% endif %} 37 | 38 | {% if metaDesc %} 39 | 40 | 41 | 42 | {% endif %} 43 | -------------------------------------------------------------------------------- /src/_includes/partials/pagination.njk: -------------------------------------------------------------------------------- 1 | {# Only renders this section if there are links to render #} 2 | {% if pagination.href.next or pagination.href.previous %} 3 | 19 | {% endif %} 20 | -------------------------------------------------------------------------------- /src/_includes/partials/site-head.njk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-set-studio/11ty-pattern-library/cc4cb787cae4f3177610da3ed5eb8af71388ab2f/src/_includes/partials/site-head.njk -------------------------------------------------------------------------------- /src/_includes/prototype.js: -------------------------------------------------------------------------------- 1 | const frameContext = location.pathname.replace(/\//g, '-'); 2 | 3 | const frameKeys = { 4 | width: `${frameContext}:frame-width`, 5 | height: `${frameContext}:frame-height` 6 | }; 7 | 8 | const frameWidth = localStorage.getItem(frameKeys.width); 9 | const frameHeight = localStorage.getItem(frameKeys.height); 10 | 11 | if (frameWidth) { 12 | document.documentElement.style.setProperty('--frame-width', frameWidth); 13 | } 14 | 15 | if (frameHeight) { 16 | document.documentElement.style.setProperty('--frame-height', frameHeight); 17 | } 18 | 19 | document.querySelectorAll('iframe').forEach(item => 20 | item.contentWindow.addEventListener('resize', evt => { 21 | const rects = item.getClientRects()[0]; 22 | const itemWidth = rects.width; 23 | const itemHeight = rects.height; 24 | 25 | document.documentElement.style.setProperty('--frame-width', `${itemWidth}px`); 26 | document.documentElement.style.setProperty('--frame-height', `${itemHeight}px`); 27 | localStorage.setItem(frameKeys.width, `${itemWidth}px`); 28 | localStorage.setItem(frameKeys.height, `${itemHeight}px`); 29 | }) 30 | ); 31 | -------------------------------------------------------------------------------- /src/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'About' 3 | layout: 'layouts/page.njk' 4 | --- 5 | 6 | Maecenas sed diam eget risus varius blandit sit amet non magna. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam id dolor id nibh ultricies vehicula ut id elit. Curabitur blandit tempus porttitor. Vestibulum id ligula porta felis euismod semper. 7 | -------------------------------------------------------------------------------- /src/colors.njk: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base.njk" %} 2 | {% set title = 'Colors' %} 3 | 4 | {% block content %} 5 | 6 |
7 |

{{ title }}

8 | 26 |
27 | 28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /src/filters/markdown-filter.js: -------------------------------------------------------------------------------- 1 | const markdown = require('markdown-it'); 2 | const stripIndent = require('strip-indent'); 3 | const renderer = new markdown(); 4 | 5 | module.exports = (content = '') => { 6 | const trimmedContent = stripIndent(content); 7 | 8 | return content.split('\n').length > 1 9 | ? renderer.render(trimmedContent) 10 | : renderer.renderInline(trimmedContent); 11 | }; 12 | -------------------------------------------------------------------------------- /src/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-set-studio/11ty-pattern-library/cc4cb787cae4f3177610da3ed5eb8af71388ab2f/src/images/.gitkeep -------------------------------------------------------------------------------- /src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Base Project' 3 | metaDesc: 'Don’t forget the meta desc Maecenas sed diam eget risus varius blandit sit amet non magna. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.' 4 | layout: 'layouts/home.njk' 5 | --- 6 | -------------------------------------------------------------------------------- /src/pattern.njk: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Preview' 3 | pagination: 4 | data: collections.patterns 5 | size: 1 6 | addAllPagesToCollections: true 7 | alias: item 8 | permalink: '{{ item.filePathStem }}/index.html' 9 | --- 10 | 11 | {% extends "layouts/base.njk" %} 12 | 13 | {% set variants = patterns.getVariants(item, collections.patterns) %} 14 | {% set docs = patterns.getDocs(item) %} 15 | 16 | {% block content %} 17 |
18 |

{{ item.data.title }}

19 | {% set frameId = global.random() %} 20 | 21 |
22 | 23 | View full screen 24 |
25 | 33 |

Source (Nunjucks)

34 |
{{ patterns.renderSource(item) }}
35 |

Output

36 |
{{ patterns.render(item) }}
37 | 38 | {% if docs %} 39 |
40 |

Docs

41 | {{ docs | markdownFilter | safe }} 42 |
43 | {% endif %} 44 | 45 | {% if variants | length %} 46 |

Variants

47 | {% for variant in variants %} 48 |
49 | 50 |
51 | View full screen 52 |
53 |

Source (Nunjucks)

54 |
{{ patterns.renderSource(variant) }}
55 |

Output

56 |
{{ patterns.render(variant) }}
57 |
58 | {% endfor %} 59 | {% endif %} 60 | 61 |
62 | {% endblock %} 63 | -------------------------------------------------------------------------------- /src/patterns/button/button.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Button", 3 | "text": "A button" 4 | } 5 | -------------------------------------------------------------------------------- /src/patterns/button/button.njk: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/patterns/button/docs.md: -------------------------------------------------------------------------------- 1 | Nulla vitae elit libero, a pharetra augue. Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. 2 | 3 | Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Vestibulum id ligula porta felis euismod semper. Nulla vitae elit libero, a pharetra augue. Donec sed odio dui. 4 | -------------------------------------------------------------------------------- /src/patterns/button/variants/button-secondary.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Button Secondary", 3 | "text": "A secondary button" 4 | } 5 | -------------------------------------------------------------------------------- /src/patterns/button/variants/button-secondary.njk: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/patterns/patterns.json: -------------------------------------------------------------------------------- 1 | { 2 | "permalink": false 3 | } 4 | -------------------------------------------------------------------------------- /src/patterns/toggle-switch/docs.md: -------------------------------------------------------------------------------- 1 | Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla sed consectetur. Curabitur blandit tempus porttitor. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas sed diam eget risus varius blandit sit amet non magna. 2 | 3 | Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Sed posuere consectetur est at lobortis. Nullam quis risus eget urna mollis ornare vel eu leo. 4 | 5 | Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Maecenas faucibus mollis interdum. Vestibulum id ligula porta felis euismod semper. Maecenas sed diam eget risus varius blandit sit amet non magna. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. 6 | -------------------------------------------------------------------------------- /src/patterns/toggle-switch/toggle-switch.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Toggle", 3 | "label": "A label for a toggle", 4 | "id": "toggle_element", 5 | "checked": false 6 | } 7 | -------------------------------------------------------------------------------- /src/patterns/toggle-switch/toggle-switch.njk: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/preview.njk: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Preview' 3 | pagination: 4 | data: collections.patterns 5 | size: 1 6 | addAllPagesToCollections: true 7 | alias: item 8 | permalink: '/preview/{{ item.fileSlug | slug }}/index.html' 9 | --- 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {{ item.data.title }} - Preview 19 | 60 | 61 | 62 |
63 | {{ patterns.render(item) | safe }} 64 |
65 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /src/scss/_config.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * BASE SIZE 3 | * All calculations are based on this. It’s recommended that 4 | * you keep it at 1rem because that is the root font size. You 5 | * can set it to whatever you like and whatever unit you like. 6 | */ 7 | $gorko-base-size: 1rem; 8 | 9 | /** 10 | * SIZE SCALE 11 | * This is a Perfect Fourth scale that powers all the utilities that 12 | * it is relevant for (font-size, margin, padding). All items are 13 | * calcuated off the base size, so change that and cascade across 14 | * your whole project. 15 | */ 16 | $gorko-size-scale: ( 17 | '300': $gorko-base-size * 0.75, 18 | '400': $gorko-base-size, 19 | '500': $gorko-base-size * 1.33, 20 | '600': $gorko-base-size * 1.77, 21 | '700': $gorko-base-size * 2.36, 22 | '800': $gorko-base-size * 3.15, 23 | '900': $gorko-base-size * 4.2, 24 | 'major': $gorko-base-size * 5.6 25 | ); 26 | 27 | /** 28 | * COLORS 29 | * Colors are shared between backgrounds and text by default. 30 | * You can also use them to power borders, fills or shadows, for example. 31 | */ 32 | $gorko-colors: ( 33 | 'dark': #38445b, 34 | 'dark-shade': #263147, 35 | 'dark-glare': #505c73, 36 | 'light': #efefef, 37 | 'light-shade': #fdfdfd, 38 | 'light-glare': #fdfbf3, 39 | 'primary': #513aa6 40 | ); 41 | 42 | /** 43 | * CORE CONFIG 44 | * This powers everything from utility class generation to breakpoints 45 | * to enabling/disabling pre-built components/utilities. 46 | */ 47 | $gorko-config: ( 48 | 'bg': ( 49 | 'items': $gorko-colors, 50 | 'output': 'standard', 51 | 'property': 'background' 52 | ), 53 | 'color': ( 54 | 'items': $gorko-colors, 55 | 'output': 'standard', 56 | 'property': 'color' 57 | ), 58 | 'flow-space': ( 59 | 'items': $gorko-size-scale, 60 | 'output': 'responsive', 61 | 'property': '--flow-space' 62 | ), 63 | 'font': ( 64 | 'items': ( 65 | 'base': 'sans-serif', 66 | 'sans': '"Inter", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif' 67 | ), 68 | 'output': 'standard', 69 | 'property': 'font-family' 70 | ), 71 | 'gap-top': ( 72 | 'items': $gorko-size-scale, 73 | 'output': 'responsive', 74 | 'property': 'margin-top' 75 | ), 76 | 'leading': ( 77 | 'items': ( 78 | 'loose': 1.7, 79 | 'tight': 1.3, 80 | 'flat': '1.1' 81 | ), 82 | 'output': 'standard', 83 | 'property': 'line-height' 84 | ), 85 | 'measure': ( 86 | 'items': ( 87 | 'micro': '10ch', 88 | 'compact': '30ch', 89 | 'short': '40ch', 90 | 'long': '65ch' 91 | ), 92 | 'output': 'responsive', 93 | 'property': 'max-width' 94 | ), 95 | 'text': ( 96 | 'items': $gorko-size-scale, 97 | 'output': 'responsive', 98 | 'property': 'font-size' 99 | ), 100 | 'weight': ( 101 | 'items': ( 102 | 'normal': 400, 103 | 'bold': 900 104 | ), 105 | 'output': 'standard', 106 | 'property': 'font-weight' 107 | ), 108 | 'breakpoints': ( 109 | 'md': '(min-width: 37em)', 110 | 'lg': '(min-width: 62em)' 111 | ) 112 | ); 113 | -------------------------------------------------------------------------------- /src/scss/_reset.scss: -------------------------------------------------------------------------------- 1 | /* Box sizing rules */ 2 | *, 3 | *::before, 4 | *::after { 5 | box-sizing: border-box; 6 | } 7 | 8 | /* Remove default margin */ 9 | body, 10 | h1, 11 | h2, 12 | h3, 13 | h4, 14 | p, 15 | figure, 16 | blockquote, 17 | dl, 18 | dd { 19 | margin: 0; 20 | } 21 | 22 | /* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */ 23 | ul[role='list'], 24 | ol[role='list'] { 25 | list-style: none; 26 | } 27 | 28 | /* Set core root defaults */ 29 | html:focus-within { 30 | scroll-behavior: smooth; 31 | } 32 | 33 | /* Set core body defaults */ 34 | body { 35 | min-height: 100vh; 36 | text-rendering: optimizeSpeed; 37 | line-height: 1.5; 38 | } 39 | 40 | /* A elements that don't have a class get default styles */ 41 | a:not([class]) { 42 | text-decoration-skip-ink: auto; 43 | } 44 | 45 | /* Make images easier to work with */ 46 | img, 47 | picture { 48 | max-width: 100%; 49 | display: block; 50 | } 51 | 52 | /* Inherit fonts for inputs and buttons */ 53 | input, 54 | button, 55 | textarea, 56 | select { 57 | font: inherit; 58 | } 59 | 60 | @media (prefers-reduced-motion: reduce) { 61 | html:focus-within { 62 | scroll-behavior: auto; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/scss/blocks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-set-studio/11ty-pattern-library/cc4cb787cae4f3177610da3ed5eb8af71388ab2f/src/scss/blocks/.gitkeep -------------------------------------------------------------------------------- /src/scss/blocks/_code-sample.scss: -------------------------------------------------------------------------------- 1 | .code-sample { 2 | border: 1px solid; 3 | background: white; 4 | padding: 1em; 5 | 6 | code { 7 | font-size: 1.2em; 8 | text-align: left; 9 | word-spacing: normal; 10 | word-break: normal; 11 | word-wrap: normal; 12 | tab-size: 2; 13 | hyphens: none; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/scss/blocks/_side-nav.scss: -------------------------------------------------------------------------------- 1 | .side-nav { 2 | border-top: 1px solid; 3 | padding: 0; 4 | 5 | a { 6 | display: block; 7 | padding: get-size('300') get-size('500'); 8 | background: white; 9 | text-decoration: none; 10 | font-weight: bold; 11 | } 12 | 13 | li { 14 | border-bottom: 1px solid; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/scss/blocks/_swatch.scss: -------------------------------------------------------------------------------- 1 | .swatch { 2 | background: white; 3 | border: 1px solid; 4 | 5 | > * { 6 | padding: 1rem; 7 | } 8 | 9 | &__sample { 10 | aspect-ratio: 16/9; 11 | } 12 | 13 | h2, 14 | h3 { 15 | text-transform: capitalize; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/scss/critical.scss: -------------------------------------------------------------------------------- 1 | // First up: config and functions 2 | @import 'config'; 3 | 4 | // Next: pull in gorko for design tokens 5 | @import '../../node_modules/gorko/gorko.scss'; 6 | 7 | @import 'reset'; 8 | 9 | // Global styles start 10 | :root { 11 | --flow-space: #{get-size('600')}; 12 | } 13 | 14 | body { 15 | background: get-color('light'); 16 | color: get-color('dark-shade'); 17 | line-height: 1.5; 18 | 19 | @include apply-utility('font', 'base'); 20 | } 21 | 22 | a:not([class]) { 23 | color: currentColor; 24 | } 25 | 26 | :focus { 27 | outline: 2px dashed get-color('primary'); 28 | outline-offset: 0.25rem; 29 | } 30 | 31 | main:focus { 32 | outline: none; 33 | } 34 | 35 | h1, 36 | h2, 37 | h3, 38 | h4 { 39 | font-weight: 900; 40 | 41 | @include apply-utility('font', 'sans'); 42 | @include apply-utility('leading', 'flat'); 43 | } 44 | 45 | dl { 46 | display: grid; 47 | grid-template-columns: minmax(0, max-content) 1fr; 48 | grid-gap: 0.5rem 1.5rem; 49 | } 50 | 51 | iframe { 52 | border: 1px solid; 53 | resize: both; 54 | width: var(--frame-width, auto); 55 | height: var(--frame-height, auto); 56 | min-width: 300px; 57 | min-height: 150px; 58 | } 59 | 60 | // High contrast selection because it can help visually-impaired 61 | // folks read the text easier 62 | ::selection { 63 | color: get-color('light'); 64 | 65 | // We set this as an RGBA because that's how you get a solid color, by using 0.99 66 | // alpha value. Browsers are wild. 67 | background: rgba(get-color('dark-shade'), 0.99); 68 | } 69 | 70 | // Import blocks 71 | @import 'blocks/code-sample'; 72 | @import 'blocks/side-nav'; 73 | @import 'blocks/swatch'; 74 | 75 | // Import utilities 76 | @import 'utilities/auto-grid'; 77 | @import 'utilities/flow'; 78 | @import 'utilities/sidebar'; 79 | @import 'utilities/visually-hidden'; 80 | @import 'utilities/wrapper'; 81 | -------------------------------------------------------------------------------- /src/scss/utilities/_auto-grid.scss: -------------------------------------------------------------------------------- 1 | .auto-grid { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(var(--auto-grid-min-size, 16rem), 1fr)); 4 | gap: 1rem; 5 | padding: 0; 6 | } 7 | -------------------------------------------------------------------------------- /src/scss/utilities/_flow.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * FLOW 3 | * Applies a margin to sibling elements based on a --flow-space custom property. 4 | */ 5 | .flow > * + * { 6 | margin-top: var(--flow-space, get-size('600')); 7 | } 8 | -------------------------------------------------------------------------------- /src/scss/utilities/_sidebar.scss: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | display: flex; 3 | flex-wrap: wrap; 4 | gap: get-size('500'); 5 | min-height: 100vh; 6 | } 7 | 8 | .sidebar > * { 9 | flex-basis: 14rem; 10 | flex-grow: 1; 11 | padding: get-size('700') 0; 12 | } 13 | 14 | .sidebar > :last-child { 15 | flex-basis: 0; 16 | flex-grow: 999; 17 | min-width: calc(50% - #{get-size('500')}); 18 | } 19 | 20 | .sidebar > :first-child { 21 | outline: 1px solid get-color('dark'); 22 | max-width: 20rem; 23 | } 24 | 25 | .sidebar > :first-child h2 { 26 | --flow-space: 2rem; 27 | padding-inline-start: get-size('500'); 28 | } 29 | 30 | .sidebar > :first-child h2 + * { 31 | --flow-space: 0.5rem; 32 | } 33 | -------------------------------------------------------------------------------- /src/scss/utilities/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | .visually-hidden { 2 | border: 0; 3 | clip: rect(0 0 0 0); 4 | height: auto; 5 | margin: 0; 6 | overflow: hidden; 7 | padding: 0; 8 | position: absolute; 9 | width: 1px; 10 | white-space: nowrap; 11 | } 12 | -------------------------------------------------------------------------------- /src/scss/utilities/_wrapper.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WRAPPER 3 | * Sets a max width, adds a consisten gutter and horizontally 4 | * centers the contents 5 | */ 6 | .wrapper { 7 | max-width: 60rem; 8 | padding: 0 get-size('500'); 9 | margin-left: auto; 10 | margin-right: auto; 11 | position: relative; 12 | } 13 | -------------------------------------------------------------------------------- /src/typography.njk: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base.njk" %} 2 | {% set title = 'Typography' %} 3 | 4 | {% block content %} 5 | 6 |
7 |

{{ title }}

8 |

Font sizes

9 | {% for item in tokens.sizes %} 10 |

Size item: {{ item.value }}

11 | {% endfor %} 12 |
13 | 14 | {% endblock %} 15 | --------------------------------------------------------------------------------