├── app ├── .gitignore ├── components │ ├── layout.js │ └── head.js ├── package.json ├── config.js └── pages │ └── index.js ├── partials ├── _styles.css.js ├── _images.css.js ├── _lists.css.js ├── _font-style.css.js ├── _code.css.js ├── _background-size.css.js ├── _floats.css.js ├── _white-space.css.js ├── _line-height.css.js ├── _module-template.css.js ├── _outlines.css.js ├── _word-break.css.js ├── _text-align.css.js ├── _debug-children.css.js ├── _letter-spacing.css.js ├── _position.css.js ├── _text-decoration.css.js ├── _text-transform.css.js ├── _border-style.css.js ├── _media-queries.css.js ├── _visibility.css.js ├── _vertical-align.css.js ├── _forms.css.js ├── _utilities.css.js ├── _clears.css.js ├── _rotations.css.js ├── _box-shadow.css.js ├── _borders.css.js ├── _font-weight.css.js ├── _z-index.css.js ├── _links.css.js ├── _background-position.css.js ├── _overflow.css.js ├── _box-sizing.css.js ├── _display.css.js ├── _coordinates.css.js ├── _debug-grid.css.js ├── _aspect-ratios.css.js ├── _font-family.css.js ├── _flexbox.css.js ├── _hovers.css.js ├── tachyons.css.js ├── _normalize.css.js └── _debug.css.js ├── .gitignore ├── .travis.yml ├── test ├── snapshots │ ├── border-test.js.snap │ ├── nested-test.js.snap │ ├── palette-test.js.snap │ ├── integration-test.js.snap │ ├── line-height-test.js.snap │ ├── media-query-test.js.snap │ ├── line-height-test.js.md │ ├── nested-test.js.md │ ├── media-query-test.js.md │ ├── palette-test.js.md │ └── border-test.js.md ├── palette-test.js ├── config-utils-test.js ├── line-height-test.js ├── nested-test.js ├── border-test.js ├── media-query-test.js ├── integration-test.js └── fixtures │ ├── type-scale.css │ └── display.css ├── lib ├── directions.js ├── units.js ├── declarations.js ├── hash-config.js ├── config-utils.js ├── opacity.js ├── line-height.js ├── type-scale.js ├── max-widths.js ├── border-widths.js ├── docs-helper.js ├── tables.js ├── typography.js ├── assemble-css.js ├── border-radius.js ├── spacing.js ├── heights.js ├── manifest.js ├── nested.js ├── widths.js ├── generate.js └── color.js ├── .editorconfig ├── api ├── lib │ ├── aws-client.js │ ├── hash-config.js │ └── token.js ├── readme.md ├── package.json └── index.js ├── docs ├── components │ ├── HtmlSection.js │ ├── Layout.js │ ├── Section.js │ ├── CodeSection.js │ ├── Hero.js │ ├── TypeScale.js │ ├── Styleguide.js │ ├── Measure.js │ ├── GettingStarted.js │ └── Colors.js ├── generate.js ├── index.js └── style.js ├── now.json ├── index.js ├── license ├── package.json ├── config.js └── readme.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | .next 2 | -------------------------------------------------------------------------------- /partials/_styles.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | 3 | ` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | out.css 3 | out.html 4 | *.swp 5 | .env 6 | -------------------------------------------------------------------------------- /partials/_images.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | img { max-width: 100%; } 3 | ` -------------------------------------------------------------------------------- /partials/_lists.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .list { list-style-type: none; } 3 | ` 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | dist: trusty 4 | node_js: 5 | - '8' 6 | -------------------------------------------------------------------------------- /test/snapshots/border-test.js.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyons-css/generator/HEAD/test/snapshots/border-test.js.snap -------------------------------------------------------------------------------- /test/snapshots/nested-test.js.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyons-css/generator/HEAD/test/snapshots/nested-test.js.snap -------------------------------------------------------------------------------- /test/snapshots/palette-test.js.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyons-css/generator/HEAD/test/snapshots/palette-test.js.snap -------------------------------------------------------------------------------- /partials/_font-style.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .i { font-style: italic; } 3 | .fs-normal { font-style: normal; } 4 | ` -------------------------------------------------------------------------------- /partials/_code.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .pre { 3 | overflow-x: auto; 4 | overflow-y: hidden; 5 | overflow: scroll; 6 | } 7 | ` -------------------------------------------------------------------------------- /test/snapshots/integration-test.js.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyons-css/generator/HEAD/test/snapshots/integration-test.js.snap -------------------------------------------------------------------------------- /test/snapshots/line-height-test.js.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyons-css/generator/HEAD/test/snapshots/line-height-test.js.snap -------------------------------------------------------------------------------- /test/snapshots/media-query-test.js.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyons-css/generator/HEAD/test/snapshots/media-query-test.js.snap -------------------------------------------------------------------------------- /partials/_background-size.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .cover { background-size: cover!important; } 3 | .contain { background-size: contain!important; } 4 | ` 5 | -------------------------------------------------------------------------------- /partials/_floats.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .fl { float: left; _display: inline; } 3 | .fr { float: right; _display: inline; } 4 | .fn { float: none; } 5 | ` -------------------------------------------------------------------------------- /partials/_white-space.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .ws-normal { white-space: normal; } 3 | .nowrap { white-space: nowrap; } 4 | .pre { white-space: pre; } 5 | ` -------------------------------------------------------------------------------- /partials/_line-height.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .lh-solid { line-height: 1; } 3 | .lh-title { line-height: 1.25; } 4 | .lh-copy { line-height: 1.5; } 5 | ` 6 | -------------------------------------------------------------------------------- /partials/_module-template.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | @media (--breakpoint-medium) { 3 | 4 | } 5 | 6 | @media (--breakpoint-large) { 7 | 8 | } 9 | ` 10 | -------------------------------------------------------------------------------- /lib/directions.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | all: 'a', 3 | left: 'l', 4 | right: 'r', 5 | top: 't', 6 | bottom: 'b', 7 | vert: 'v', 8 | horiz: 'h' 9 | } 10 | -------------------------------------------------------------------------------- /partials/_outlines.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .outline { outline: 1px solid; } 3 | .outline-transparent { outline: 1px solid transparent; } 4 | .outline-0 { outline: 0; } 5 | ` -------------------------------------------------------------------------------- /partials/_word-break.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .word-normal { word-break: normal; } 3 | .word-wrap { word-break: break-all; } 4 | .word-nowrap { word-break: keep-all; } 5 | ` -------------------------------------------------------------------------------- /partials/_text-align.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .tl { text-align: left; } 3 | .tr { text-align: right; } 4 | .tc { text-align: center; } 5 | .tj { text-align: justify; } 6 | ` -------------------------------------------------------------------------------- /partials/_debug-children.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .debug * { outline: 1px solid gold; } 3 | .debug-white * { outline: 1px solid white; } 4 | .debug-black * { outline: 1px solid black; } 5 | ` -------------------------------------------------------------------------------- /partials/_letter-spacing.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .tracked { letter-spacing: .1em; } 3 | .tracked-tight { letter-spacing: -.05em; } 4 | .tracked-mega { letter-spacing: .25em; } 5 | ` -------------------------------------------------------------------------------- /partials/_position.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .static { position: static; } 3 | .relative { position: relative; } 4 | .absolute { position: absolute; } 5 | .fixed { position: fixed; } 6 | ` -------------------------------------------------------------------------------- /partials/_text-decoration.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .strike { text-decoration: line-through; } 3 | .underline { text-decoration: underline; } 4 | .no-underline { text-decoration: none; } 5 | ` -------------------------------------------------------------------------------- /partials/_text-transform.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .ttc { text-transform: capitalize; } 3 | .ttl { text-transform: lowercase; } 4 | .ttu { text-transform: uppercase; } 5 | .ttn { text-transform: none; } 6 | ` -------------------------------------------------------------------------------- /lib/units.js: -------------------------------------------------------------------------------- 1 | const hasUnits = str => /(px|em|rem)$/.test(str) 2 | 3 | const withUnits = (str, unit = 'em') => hasUnits(str) ? str : `${str}${unit}` 4 | 5 | module.exports = { 6 | withUnits, 7 | hasUnits 8 | } 9 | -------------------------------------------------------------------------------- /partials/_border-style.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .b--dotted { border-style: dotted; } 3 | .b--dashed { border-style: dashed; } 4 | .b--solid { border-style: solid; } 5 | .b--none { border-style: none; } 6 | ` -------------------------------------------------------------------------------- /partials/_media-queries.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | @custom-media --breakpoint-medium screen and (min-width: 30em) and (max-width: 60em); 3 | @custom-media --breakpoint-large screen and (min-width: 60em); 4 | ` 5 | -------------------------------------------------------------------------------- /partials/_visibility.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .clip { 3 | position: fixed !important; 4 | _position: absolute !important; 5 | clip: rect(1px 1px 1px 1px); 6 | clip: rect(1px, 1px, 1px, 1px); 7 | } 8 | ` -------------------------------------------------------------------------------- /partials/_vertical-align.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .v-base { vertical-align: baseline; } 3 | .v-mid { vertical-align: middle; } 4 | .v-top { vertical-align: top; } 5 | .v-btm { vertical-align: bottom; } 6 | ` -------------------------------------------------------------------------------- /lib/declarations.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | all: [''], 3 | left: ['-left'], 4 | right: ['-right'], 5 | top: ['-top'], 6 | bottom: ['-bottom'], 7 | vert: ['-top', '-bottom'], 8 | horiz: ['-left', '-right'] 9 | } 10 | -------------------------------------------------------------------------------- /app/components/layout.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Head from './head' 3 | 4 | export default ({ config, children }) => ( 5 |
6 | 7 | {children} 8 |
9 | ) 10 | -------------------------------------------------------------------------------- /partials/_forms.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .input-reset { 3 | -webkit-appearance: none; 4 | -moz-appearance: none; 5 | } 6 | 7 | .button-reset::-moz-focus-inner, 8 | .input-reset::-moz-focus-inner { 9 | border: 0; 10 | padding: 0; 11 | } 12 | ` -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /partials/_utilities.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .overflow-container { 3 | overflow-y: scroll; 4 | } 5 | 6 | .center { 7 | margin-right: auto; 8 | margin-left: auto; 9 | } 10 | 11 | .mr-auto { margin-right: auto; } 12 | .ml-auto { margin-left: auto; } 13 | ` -------------------------------------------------------------------------------- /api/lib/aws-client.js: -------------------------------------------------------------------------------- 1 | const AWS = require('aws-sdk') 2 | 3 | AWS.config.update({ 4 | region: 'us-west-2', 5 | accessKeyId: process.env.TACHYONS_AWS_ACCESS_KEY_ID, 6 | secretAccessKey: process.env.TACHYONS_AWS_SECRET_ACCESS_KEY 7 | }) 8 | 9 | module.exports = AWS 10 | -------------------------------------------------------------------------------- /lib/hash-config.js: -------------------------------------------------------------------------------- 1 | const crypto = require('crypto') 2 | 3 | module.exports = (obj, sha = '256') => { 4 | const str = JSON.stringify(obj) 5 | 6 | return crypto 7 | .createHash(`sha${sha}`) 8 | .update(str) 9 | .digest('hex') 10 | .slice(0, 32) 11 | } 12 | -------------------------------------------------------------------------------- /partials/_clears.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .cf:before, 3 | .cf:after { content: " "; display: table; } 4 | .cf:after { clear: both; } 5 | .cf { *zoom: 1; } 6 | 7 | .cl { clear: left; } 8 | .cr { clear: right; } 9 | .cb { clear: both; } 10 | .cn { clear: none; } 11 | ` -------------------------------------------------------------------------------- /api/lib/hash-config.js: -------------------------------------------------------------------------------- 1 | const crypto = require('crypto') 2 | 3 | module.exports = (obj, sha = '256') => { 4 | const str = JSON.stringify(obj) 5 | 6 | return crypto 7 | .createHash(`sha${sha}`) 8 | .update(str) 9 | .digest('hex') 10 | .slice(0, 32) 11 | } 12 | -------------------------------------------------------------------------------- /docs/components/HtmlSection.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const e = React.createElement 3 | 4 | const { 5 | HtmlSectionCx: { 6 | wrap 7 | } 8 | } = require('../style') 9 | 10 | module.exports = children => e('div', { className: wrap, key: 'html' }, children) 11 | -------------------------------------------------------------------------------- /docs/components/Layout.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const e = React.createElement 3 | 4 | const { 5 | BodyCx: { 6 | body 7 | } 8 | } = require('../style') 9 | 10 | const className = `${body} sans-serif` 11 | 12 | module.exports = children => 13 | e('body', { className }, children) 14 | -------------------------------------------------------------------------------- /api/readme.md: -------------------------------------------------------------------------------- 1 | # tachyons.pub api 2 | 3 | Returns a token with 15 minute access to a directory in the tachyons-pub styleguide hosting bucket. 4 | 5 | ```sh 6 | curl -X POST \ 7 | -H "Content-Type: application/json" \ 8 | -d '{"typeScale": [5,4,3,2,1,0.5] }' \ 9 | https://tachyons.pub 10 | ``` 11 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias": ["publish.tachyons.pub"], 3 | "builds": [ 4 | { 5 | "src": "api/index.js", 6 | "use": "@now/node" 7 | } 8 | ], 9 | "env": { 10 | "TACHYONS_AWS_ACCESS_KEY_ID": "@tachyons-aws-access-key-id", 11 | "TACHYONS_AWS_SECRET_ACCESS_KEY": "@tachyons-aws-secret-access-key" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /partials/_rotations.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .rotate-45 { transform: rotate(45deg); } 3 | .rotate-90 { transform: rotate(90deg); } 4 | .rotate-135 { transform: rotate(135deg); } 5 | .rotate-180 { transform: rotate(180deg); } 6 | .rotate-225 { transform: rotate(225deg); } 7 | .rotate-270 { transform: rotate(270deg); } 8 | .rotate-315 { transform: rotate(315deg); } 9 | ` -------------------------------------------------------------------------------- /partials/_box-shadow.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .shadow-1 { box-shadow: 0px 0px 4px 2px rgba( 0, 0, 0, 0.2 ); } 3 | .shadow-2 { box-shadow: 0px 0px 8px 2px rgba( 0, 0, 0, 0.2 ); } 4 | .shadow-3 { box-shadow: 2px 2px 4px 2px rgba( 0, 0, 0, 0.2 ); } 5 | .shadow-4 { box-shadow: 2px 2px 8px 0px rgba( 0, 0, 0, 0.2 ); } 6 | .shadow-5 { box-shadow: 4px 4px 8px 0px rgba( 0, 0, 0, 0.2 ); } 7 | ` -------------------------------------------------------------------------------- /docs/components/Section.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const e = React.createElement 3 | 4 | const { 5 | SectionCx: { 6 | wrap, 7 | h3 8 | } 9 | } = require('../style') 10 | 11 | module.exports = ({ title, children }) => 12 | e('article', { className: 'center' }, 13 | e('h3', { className: h3 }, title), 14 | e('div', { className: wrap }, children) 15 | ) 16 | -------------------------------------------------------------------------------- /test/palette-test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import tachyonsGenerator from '../' 3 | 4 | test.only('palette is generated for colors array when included in config', async t => { 5 | const tachy = tachyonsGenerator({ palette: '#07cccc' }) 6 | const { 7 | modules: { 8 | variables 9 | } 10 | } = await tachy.generate() 11 | 12 | t.snapshot(variables.trim()) 13 | }) 14 | -------------------------------------------------------------------------------- /partials/_borders.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .ba { border-style: solid; border-width: 1px; } 3 | .bt { border-top-style: solid; border-top-width: 1px; } 4 | .br { border-right-style: solid; border-right-width: 1px; } 5 | .bb { border-bottom-style: solid; border-bottom-width: 1px; } 6 | .bl { border-left-style: solid; border-left-width: 1px; } 7 | .bn { border-style: none; border-width: 0; } 8 | ` 9 | -------------------------------------------------------------------------------- /api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tachyons-publish-api", 3 | "version": "0.0.1", 4 | "description": "Microservice to get a temporary token to write to a subdir of the tachyons bucket", 5 | "scripts": { 6 | "start": "micro" 7 | }, 8 | "repository": "tachyons/generate/api", 9 | "dependencies": { 10 | "aws-sdk": "^2.559.0", 11 | "tachyons-generator": "^0.23.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /docs/components/CodeSection.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const e = React.createElement 3 | 4 | const stripMedia = require('strip-css-media-queries') 5 | 6 | const { 7 | CodeSectionCx: { 8 | pre, 9 | code 10 | } 11 | } = require('../style') 12 | 13 | module.exports = css => 14 | e('pre', { className: pre, key: 'code' }, 15 | e('code', { className: code }, stripMedia(css)) 16 | ) 17 | -------------------------------------------------------------------------------- /partials/_font-weight.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .normal { font-weight: normal; } 3 | .b { font-weight: bold; } 4 | .fw1 { font-weight: 100; } 5 | .fw2 { font-weight: 200; } 6 | .fw3 { font-weight: 300; } 7 | .fw4 { font-weight: 400; } 8 | .fw5 { font-weight: 500; } 9 | .fw6 { font-weight: 600; } 10 | .fw7 { font-weight: 700; } 11 | .fw8 { font-weight: 800; } 12 | .fw9 { font-weight: 900; } 13 | ` -------------------------------------------------------------------------------- /partials/_z-index.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .z-0 { z-index: 0; } 3 | .z-1 { z-index: 1; } 4 | .z-2 { z-index: 2; } 5 | .z-3 { z-index: 3; } 6 | .z-4 { z-index: 4; } 7 | .z-5 { z-index: 5; } 8 | 9 | .z-999 { z-index: 999; } 10 | .z-9999 { z-index: 9999; } 11 | 12 | .z-max { 13 | z-index: 2147483647; 14 | } 15 | 16 | .z-inherit { z-index: inherit; } 17 | .z-initial { z-index: initial; } 18 | .z-unset { z-index: unset; } 19 | ` -------------------------------------------------------------------------------- /lib/config-utils.js: -------------------------------------------------------------------------------- 1 | const defaultConfig = require('../config') 2 | 3 | function getColor(customConfig, name, fallback) { 4 | if (name && customConfig.colors[name]) { 5 | return customConfig.colors[name] 6 | } 7 | 8 | if (name) { 9 | console.warn(`Color "${name}" not found. Using Tachyons default color.`) 10 | } 11 | 12 | return defaultConfig.colors[fallback] 13 | } 14 | 15 | module.exports = { 16 | getColor 17 | } 18 | -------------------------------------------------------------------------------- /partials/_links.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .link { 3 | text-decoration: none; 4 | transition: color .15s ease-in; 5 | } 6 | 7 | .link:link, 8 | .link:visited { 9 | transition: color .15s ease-in; 10 | } 11 | .link:hover { 12 | transition: color .15s ease-in; 13 | } 14 | .link:active { 15 | transition: color .15s ease-in; 16 | } 17 | .link:focus { 18 | transition: color .15s ease-in; 19 | outline: 1px dotted currentColor; 20 | } 21 | ` -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "main": "index.js", 4 | "scripts": { 5 | "dev": "next", 6 | "build": "next build", 7 | "start": "next" 8 | }, 9 | "dependencies": { 10 | "comma-split": "^1.0.0", 11 | "is-color": "^0.2.0", 12 | "is-present": "^1.0.0", 13 | "json-loader": "^0.5.7", 14 | "next": "^5.0.0", 15 | "react": "^16.2.0", 16 | "react-dom": "^16.2.0", 17 | "tachyons-generator": "0.20.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /docs/generate.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const tachyonsGenerator = require('../index') 5 | const config = require('../config.js') 6 | 7 | const generate = async () => { 8 | const tachy = tachyonsGenerator(config) 9 | 10 | const out = await tachy.generate() 11 | 12 | fs.writeFileSync(path.join(__dirname, '..', 'out.html'), out.docs) 13 | fs.writeFileSync(path.join(__dirname, '..', 'out.css'), out.css) 14 | } 15 | 16 | generate() 17 | -------------------------------------------------------------------------------- /test/config-utils-test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import { getColor } from '../lib/config-utils' 3 | 4 | test('should get the custom color if it exists', t => { 5 | const customConfig = { 6 | colors: { 7 | customBlue: '#f1f8ff' 8 | } 9 | } 10 | 11 | const color = getColor(customConfig, 'customBlue', 'blue') 12 | 13 | t.is(color, '#f1f8ff') 14 | }) 15 | 16 | test('should use the fallback color if the color is not defined', t => { 17 | const color = getColor({ colors: {} }, 'customRed', 'red') 18 | 19 | t.is(color, '#ff3223') 20 | }) 21 | -------------------------------------------------------------------------------- /app/components/head.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Head from 'next/head' 3 | 4 | import generator from 'tachyons-generator' 5 | 6 | export default ({ config }) => { 7 | const gen = generator(config) 8 | const css = `${gen.assembleCss(gen.generate())} ${gen.typeScale()} ${gen.spacing()}` 9 | 10 | return ( 11 | 12 | Tachyons Generator 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | ${ReactDOMServer.renderToStaticMarkup(docs)} 24 | 25 | ` 26 | } 27 | -------------------------------------------------------------------------------- /test/nested-test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import path from 'path' 4 | 5 | import config from '../config' 6 | import tachyonsGenerator from '../' 7 | 8 | test('nested links colors fall back to default values when not defined', async t => { 9 | const tachy = tachyonsGenerator() 10 | const { modules: { nested } } = await tachy.generate() 11 | 12 | t.snapshot(nested) 13 | }) 14 | 15 | test('nested links colors are generated when defined', async t => { 16 | const tachy = tachyonsGenerator({ 17 | nested: { 18 | links: ['blue', 'lightest-blue'], 19 | }, 20 | }) 21 | const { modules: { nested } } = await tachy.generate() 22 | 23 | t.snapshot(nested) 24 | }) 25 | -------------------------------------------------------------------------------- /lib/type-scale.js: -------------------------------------------------------------------------------- 1 | const { step, mqSteps } = require('./docs-helper') 2 | 3 | const docs = (steps, mqs) => ` 4 | /* 5 | TYPE SCALE 6 | Docs: http://tachyons.io/docs/typography/scale/ 7 | 8 | Base: 9 | f = font-size 10 | 11 | Modifiers: 12 | ${ steps.map((_, idx) => step({ nth: 'size scale' }, idx + 1)).join('\n ') } 13 | 14 | Media Query Extensions: 15 | ${mqSteps(mqs)} 16 | */` 17 | 18 | const css = typeScale => { 19 | const steps = [] 20 | 21 | for (let i = 0; i < typeScale.length; i++) { 22 | steps.push(decl(i + 1, typeScale[i])) 23 | } 24 | 25 | return steps.join('\n') 26 | } 27 | 28 | const decl = (step, size) => `.f${step} { font-size: ${size}rem; }` 29 | 30 | module.exports = { 31 | css, 32 | docs 33 | } 34 | -------------------------------------------------------------------------------- /docs/components/Styleguide.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const e = React.createElement 3 | 4 | const Hero = require('./Hero') 5 | const GettingStarted = require('./GettingStarted') 6 | const TypeScale = require('./TypeScale') 7 | const Measure = require('./Measure') 8 | const Colors = require('./Colors') 9 | 10 | const hashConfig = require('../../lib/hash-config') 11 | const { version } = require('../../package') 12 | 13 | module.exports = (config, modules) => { 14 | const hash = hashConfig(config) 15 | 16 | return e('div', null, 17 | Hero(), 18 | GettingStarted(hash, version), 19 | TypeScale(config, modules.typeScale), 20 | Measure(modules.typography), 21 | Colors(config, [ 22 | modules.colors, 23 | modules.backgroundColors 24 | ].join('\n')) 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /lib/max-widths.js: -------------------------------------------------------------------------------- 1 | const { step, mqSteps } = require('./docs-helper') 2 | 3 | const docs = (widths, mqs) => ` 4 | /* 5 | MAX WIDTHS 6 | Docs: http://tachyons.io/docs/layout/max-widths/ 7 | 8 | Base: 9 | mw = max-width 10 | 11 | Modifiers: 12 | ${ widths.map((_, idx) => step({ nth: 'width scale' }, idx + 1)).join('\n ') } 13 | 14 | -100 = literal value 100% 15 | 16 | -none = string value none 17 | 18 | Media Query Extensions: 19 | ${mqSteps(mqs)} 20 | */ 21 | ` 22 | 23 | const css = widths => 24 | widths 25 | .map((width, idx) => `.mw${idx+1} { max-width: ${width}rem; }`) 26 | .concat([ 27 | '.mw-none { max-width: none; }', 28 | '.mw-100 { max-width: 100%; }' 29 | ]) 30 | .join('\n') 31 | 32 | module.exports = { 33 | css, 34 | docs 35 | } 36 | -------------------------------------------------------------------------------- /test/border-test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import path from 'path' 4 | 5 | import config from '../config' 6 | import tachyonsGenerator from '../' 7 | 8 | test('border widths are generated for widths array when included in config', async t => { 9 | const tachy = tachyonsGenerator({ borderWidths: [0, .125, .25, .5, 1, 2] }) 10 | const { 11 | modules: { 12 | borderWidths 13 | } 14 | } = await tachy.generate() 15 | 16 | t.snapshot(borderWidths) 17 | }) 18 | 19 | test('border radii are generated for radii array when included in config', async t => { 20 | const tachy = tachyonsGenerator({ borderRadius: [0, .125, .25, .5, 1] }) 21 | const { 22 | modules: { 23 | borderRadius 24 | } 25 | } = await tachy.generate() 26 | 27 | t.snapshot(borderRadius) 28 | }) 29 | -------------------------------------------------------------------------------- /partials/_coordinates.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .top-0 { top: 0; } 3 | .right-0 { right: 0; } 4 | .bottom-0 { bottom: 0; } 5 | .left-0 { left: 0; } 6 | 7 | .top-1 { top: 1rem; } 8 | .right-1 { right: 1rem; } 9 | .bottom-1 { bottom: 1rem; } 10 | .left-1 { left: 1rem; } 11 | 12 | .top-2 { top: 2rem; } 13 | .right-2 { right: 2rem; } 14 | .bottom-2 { bottom: 2rem; } 15 | .left-2 { left: 2rem; } 16 | 17 | .top--1 { top: -1rem; } 18 | .right--1 { right: -1rem; } 19 | .bottom--1 { bottom: -1rem; } 20 | .left--1 { left: -1rem; } 21 | 22 | .top--2 { top: -2rem; } 23 | .right--2 { right: -2rem; } 24 | .bottom--2 { bottom: -2rem; } 25 | .left--2 { left: -2rem; } 26 | 27 | 28 | .absolute--fill { 29 | top: 0; 30 | right: 0; 31 | bottom: 0; 32 | left: 0; 33 | } 34 | ` -------------------------------------------------------------------------------- /partials/_debug-grid.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .debug-grid { 3 | background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAFElEQVR4AWPAC97/9x0eCsAEPgwAVLshdpENIxcAAAAASUVORK5CYII=) repeat top left; 4 | } 5 | 6 | .debug-grid-16 { 7 | background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMklEQVR4AWOgCLz/b0epAa6UGuBOqQHOQHLUgFEDnAbcBZ4UGwDOkiCnkIhdgNgNxAYAiYlD+8sEuo8AAAAASUVORK5CYII=) repeat top left; 8 | } 9 | 10 | .debug-grid-8-solid { 11 | background:white url(data:image/gif;base64,R0lGODdhCAAIAPEAAADw/wDx/////wAAACwAAAAACAAIAAACDZQvgaeb/lxbAIKA8y0AOw==) repeat top left; 12 | } 13 | 14 | .debug-grid-16-solid { 15 | background:white url(data:image/gif;base64,R0lGODdhEAAQAPEAAADw/wDx/xXy/////ywAAAAAEAAQAAACIZyPKckYDQFsb6ZqD85jZ2+BkwiRFKehhqQCQgDHcgwEBQA7) repeat top left; 16 | } 17 | ` -------------------------------------------------------------------------------- /partials/_aspect-ratios.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .aspect-ratio { 3 | height: 0; 4 | position: relative; 5 | } 6 | 7 | .aspect-ratio--16x9 { padding-bottom: 56.25%; } 8 | .aspect-ratio--9x16 { padding-bottom: 177.77%; } 9 | 10 | .aspect-ratio--4x3 { padding-bottom: 75%; } 11 | .aspect-ratio--3x4 { padding-bottom: 133.33%; } 12 | 13 | .aspect-ratio--6x4 { padding-bottom: 66.6%; } 14 | .aspect-ratio--4x6 { padding-bottom: 150%; } 15 | 16 | .aspect-ratio--8x5 { padding-bottom: 62.5%; } 17 | .aspect-ratio--5x8 { padding-bottom: 160%; } 18 | 19 | .aspect-ratio--7x5 { padding-bottom: 71.42%; } 20 | .aspect-ratio--5x7 { padding-bottom: 140%; } 21 | 22 | .aspect-ratio--1x1 { padding-bottom: 100%; } 23 | 24 | .aspect-ratio--object { 25 | position: absolute; 26 | top: 0; 27 | right: 0; 28 | bottom: 0; 29 | left: 0; 30 | width: 100%; 31 | height: 100%; 32 | z-index: 100; 33 | } 34 | ` -------------------------------------------------------------------------------- /lib/border-widths.js: -------------------------------------------------------------------------------- 1 | const { step, mqSteps } = require('./docs-helper') 2 | 3 | const docs = (widths, mqs) => ` 4 | /* 5 | 6 | BORDER WIDTHS 7 | Docs: http://tachyons.io/docs/themes/borders/ 8 | 9 | Base: 10 | bw = border-width 11 | 12 | Modifiers: 13 | ${ widths.map((_, idx) => 14 | step({ zeroth: ' width border', nth: 'border-width scale' }, idx)).join('\n ') 15 | } 16 | 17 | Media Query Extensions: 18 | ${mqSteps(mqs)} 19 | 20 | */` 21 | 22 | const css = widths => { 23 | let borderWidths = [] 24 | 25 | for (let i = 0; i < widths.length; i++) { 26 | borderWidths.push(`.bw${i} { border-width: ${ widths[i] }rem; }`) 27 | } 28 | 29 | borderWidths.push(` 30 | .bt-0 { border-top-width: 0; } 31 | .br-0 { border-right-width: 0; } 32 | .bb-0 { border-bottom-width: 0; } 33 | .bl-0 { border-left-width: 0; } 34 | `) 35 | 36 | return borderWidths.join('\n') 37 | } 38 | 39 | module.exports = { 40 | css, 41 | docs 42 | } 43 | -------------------------------------------------------------------------------- /test/media-query-test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import path from 'path' 4 | 5 | import config from '../config' 6 | import tachyonsGenerator from '../' 7 | 8 | test('handle greater than queries', async t => { 9 | const tachy = tachyonsGenerator({ 10 | customMedia: [ 11 | { m: '32' }, 12 | { 13 | l: { 14 | value: '64' 15 | } 16 | }, 17 | { 18 | med: { 19 | value: 64, 20 | minWidth: true, 21 | prefix: true, 22 | delimiter: '@' 23 | } 24 | }, 25 | { 26 | xl: { 27 | value: 123, 28 | minWidth: true 29 | } 30 | }, 31 | { 32 | ns: { 33 | value: 1234, 34 | maxWidth: true 35 | } 36 | } 37 | ] 38 | }) 39 | 40 | const { 41 | modules: { 42 | borderWidths 43 | } 44 | } = await tachy.generate() 45 | 46 | t.snapshot(borderWidths) 47 | }) 48 | -------------------------------------------------------------------------------- /lib/docs-helper.js: -------------------------------------------------------------------------------- 1 | const isObject = require('isobject') 2 | 3 | const suffix = (idx) => { 4 | if (idx == 1) { 5 | return 'st' 6 | } else if(idx == 2) { 7 | return 'nd' 8 | } else if(idx == 3) { 9 | return 'rd' 10 | } else { 11 | return 'th' 12 | } 13 | } 14 | 15 | function step({ zeroth = '', nth = '' }, idx) { 16 | if (idx === 0) { return `0 = 0${zeroth}` } 17 | const last = Math.abs(idx).toString().split('').reverse()[0] 18 | 19 | return `${idx} = ${idx}${suffix(last)} step in ${nth}` 20 | } 21 | 22 | function mqSteps(mediaQueries, delimiter = '\n ') { 23 | return mediaQueries.map((mq) => { 24 | const key = Object.keys(mq)[0]; 25 | const maybeObj = isObject(mq[key]) && mq[key] 26 | const delimiter = maybeObj && maybeObj.delimiter || '-' 27 | const value = maybeObj ? maybeObj.value : mq[key] 28 | 29 | return `${delimiter}${key} = ${value}em` 30 | }) 31 | .join(delimiter) 32 | } 33 | 34 | module.exports = { 35 | step, 36 | mqSteps 37 | } 38 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const camelcase = require('camelcase') 4 | const buildCss = require('tachyons-build-css') 5 | 6 | const DEFAULT_CONFIG = require('./config') 7 | 8 | const generateDocs = require('./docs') 9 | const generate = require('./lib/generate') 10 | const assembleCss = require('./lib/assemble-css') 11 | 12 | module.exports = config => { 13 | const _config = Object.assign({}, DEFAULT_CONFIG, config) 14 | const mediaQueries = _config.customMedia 15 | 16 | generator.generate = async () => { 17 | const modules = await generate(_config, mediaQueries) 18 | 19 | const post = await assembleCss(modules, _config) 20 | 21 | const min = await buildCss(post, { minify: true }) 22 | const css = await buildCss(post) 23 | 24 | const docs = generateDocs(_config, { modules, min: min.css }) 25 | 26 | return { 27 | post, 28 | modules, 29 | css: css.css, 30 | min: min.css, 31 | docs 32 | } 33 | } 34 | 35 | function generator () {} 36 | return generator 37 | } 38 | -------------------------------------------------------------------------------- /lib/tables.js: -------------------------------------------------------------------------------- 1 | const { getColor } = require('./config-utils') 2 | 3 | const docs = () => 4 | ` 5 | /* 6 | 7 | TABLES 8 | Docs: http://tachyons.io/docs/elements/tables/ 9 | 10 | */ 11 | ` 12 | 13 | const css = (tables, fullConfig) => { 14 | return ` 15 | .collapse { 16 | border-collapse: collapse; 17 | border-spacing: 0; 18 | } 19 | 20 | ${striped(tables.striped, fullConfig)} 21 | ${stripe(tables.stripe, fullConfig)} 22 | ` 23 | } 24 | 25 | const striped = (stripedColors, fullConfig) => 26 | stripedColors.map(color => ` 27 | .striped--${color}:nth-child(odd) { 28 | background-color: ${getColor(fullConfig, color, color)}; 29 | } 30 | ` 31 | ) 32 | 33 | const stripe = (stripeColors, fullConfig) => 34 | stripeColors.map(color => ` 35 | .stripe-${color}:nth-child(odd) { 36 | background-color: ${fullConfig.colors[color] || 37 | (color === 'light' ? 'rgba(255, 255, 255, .1)' : 'rgba(0, 0, 0, .1)')}; 38 | } 39 | ` 40 | ) 41 | 42 | 43 | module.exports = { 44 | css, 45 | docs, 46 | } 47 | -------------------------------------------------------------------------------- /api/lib/token.js: -------------------------------------------------------------------------------- 1 | const AWS = require('./aws-client') 2 | 3 | const sts = new AWS.STS() 4 | 5 | module.exports = (hash, version) => { 6 | return new Promise((resolve, reject) => { 7 | sts.getFederationToken({ 8 | Name: hash, 9 | DurationSeconds: 900, 10 | Policy: JSON.stringify({ 11 | Version: '2012-10-17', 12 | Statement: [{ 13 | Effect: 'Allow', 14 | Action: ['s3:ListBucket'], 15 | Resource: [`arn:aws:s3:::tachyons-pub/${version}/${hash}`] 16 | }, { 17 | Effect: 'Allow', 18 | Action: ['s3:PutObject', 's3:PutObjectACL'], 19 | Resource: [`arn:aws:s3:::tachyons-pub/${version}/${hash}/*`] 20 | }] 21 | }) 22 | }, (err, data) => { 23 | if (err) { 24 | return reject(err) 25 | } 26 | 27 | resolve({ 28 | accessKeyId: data.Credentials.AccessKeyId, 29 | secretAccessKey: data.Credentials.SecretAccessKey, 30 | sessionToken: data.Credentials.SessionToken 31 | }) 32 | }) 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /lib/typography.js: -------------------------------------------------------------------------------- 1 | const { step, mqSteps } = require('./docs-helper') 2 | 3 | const docs = (typography, mqs) => ` 4 | /* 5 | 6 | TYPOGRAPHY 7 | http://tachyons.io/docs/typography/measure/ 8 | 9 | Measures: 10 | measure = literal value ${typography.measure[0]}em (base line length) 11 | measure-narrow = literal value ${typography.measure[1]}em (narrow line length) 12 | measure-wide = literal value ${typography.measure[2]}em (wide line length) 13 | 14 | Media Query Extensions: 15 | ${mqSteps(mqs)} 16 | 17 | */` 18 | 19 | const css = typography => ` 20 | .measure { 21 | max-width: ${typography.measure[0]}em; 22 | } 23 | .measure-wide { 24 | max-width: ${typography.measure[1]}em; 25 | } 26 | .measure-narrow { 27 | max-width: ${typography.measure[2]}em; 28 | } 29 | .small-caps { font-variant: small-caps; } 30 | .indent { 31 | text-indent: 1em; 32 | margin-top: 0; 33 | margin-bottom: 0; 34 | } 35 | .truncate { 36 | white-space: nowrap; 37 | overflow: hidden; 38 | text-overflow: ellipsis; 39 | }`; 40 | 41 | module.exports = { 42 | css, 43 | docs 44 | } 45 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 John Otander 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/components/Measure.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const e = React.createElement 3 | 4 | const Section = require('./Section') 5 | const HtmlSection = require('./HtmlSection') 6 | const CodeSection = require('./CodeSection') 7 | 8 | const LOREM = ` 9 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, 10 | sed diam nonumy eirmod tempor invidunt ut labore et dolore 11 | magna aliquyam erat, sed diam voluptua. At vero eos et 12 | accusam et justo duo dolores et ea rebum. Stet clita kasd 13 | gubergren, no sea takimata sanctus est Lorem ipsum dolor 14 | sit amet 15 | ` 16 | 17 | const generateMeasure = (title, className) => 18 | e('div', { className, key: className }, 19 | e('h3', { className: 'mt4 fw6 f6' }, title), 20 | e('p', { className: 'lh-copy' }, LOREM), 21 | ) 22 | 23 | const Measures = () => [ 24 | generateMeasure('Wide Measure', 'measure-wide'), 25 | generateMeasure('Measure', 'measure'), 26 | generateMeasure('Narrow Measure', 'measure-narrow'), 27 | ] 28 | 29 | module.exports = measure => 30 | Section({ 31 | title: 'Measure', 32 | children: [ 33 | HtmlSection(Measures()), 34 | CodeSection(measure) 35 | ] 36 | }) 37 | -------------------------------------------------------------------------------- /lib/assemble-css.js: -------------------------------------------------------------------------------- 1 | module.exports = (cssObj, config) => ` 2 | /* TACHYONS v${config.version || '0.0.1'} | https://github.com/tachyons-css/tachyons */ 3 | 4 | /* 5 | * 6 | * ________ ______ 7 | * ___ __/_____ _________ /______ ______________________ 8 | * __ / _ __ / ___/_ __ \_ / / / __ \_ __ \_ ___/ 9 | * _ / / /_/ // /__ _ / / / /_/ // /_/ / / / /(__ ) 10 | * /_/ \__,_/ \___/ /_/ /_/_\__, / \____//_/ /_//____/ 11 | * /____/ 12 | * 13 | * TABLE OF CONTENTS 14 | * 15 | * 1. External Library Includes 16 | * - Normalize.css | http://normalize.css.github.io 17 | * 2. Tachyons Modules 18 | * 3. Variables 19 | * - Media Queries 20 | * - Colors 21 | * 4. Debugging 22 | * - Debug all 23 | * - Debug children 24 | * 25 | */ 26 | 27 | /* External Library Includes */ 28 | ${cssObj.normalize || ''} 29 | 30 | ${importModules(cssObj)} 31 | ` 32 | 33 | const importModules = cssObj => { 34 | const SKIP = [ 35 | 'normalize', 36 | ] 37 | 38 | return Object 39 | .keys(cssObj) 40 | .filter(key => !SKIP.includes(key)) 41 | .map(key => cssObj[key]) 42 | .join('\n') 43 | } 44 | -------------------------------------------------------------------------------- /test/integration-test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import globby from 'globby' 3 | import camel from 'camelcase' 4 | import fs from 'fs' 5 | import path from 'path' 6 | 7 | import config from '../config' 8 | import tachyonsGenerator from '../' 9 | 10 | test('media-queries are handled correctly', async t => { 11 | const tachy = tachyonsGenerator(config) 12 | const { 13 | modules: { 14 | display 15 | } 16 | } = await tachy.generate() 17 | 18 | t.snapshot(display) 19 | }) 20 | 21 | test('type-scale', async t => { 22 | const tachy = tachyonsGenerator(config) 23 | const { 24 | modules: { 25 | typeScale 26 | } 27 | } = await tachy.generate() 28 | 29 | t.snapshot(typeScale) 30 | }) 31 | 32 | test('module skipping', async t => { 33 | const tachy = tachyonsGenerator({ skipModules: ['aspect-ratios'] }) 34 | const { 35 | modules: { 36 | aspectRatios 37 | } 38 | } = await tachy.generate() 39 | 40 | t.is(aspectRatios, undefined) 41 | }) 42 | 43 | test('css', async t => { 44 | const tachy = tachyonsGenerator(config) 45 | 46 | const { css, docs } = await tachy.generate() 47 | 48 | fs.writeFileSync('out.css', css) 49 | fs.writeFileSync('out.html', docs) 50 | 51 | t.snapshot(css) 52 | }) 53 | -------------------------------------------------------------------------------- /test/fixtures/type-scale.css: -------------------------------------------------------------------------------- 1 | /* 2 | TYPE SCALE 3 | Docs: http://tachyons.io/docs/typography/scale/ 4 | 5 | Base: 6 | f = font-size 7 | 8 | Modifiers: 9 | 1 = 1st step in size scale 10 | 2 = 2nd step in size scale 11 | 3 = 3rd step in size scale 12 | 4 = 4th step in size scale 13 | 5 = 5th step in size scale 14 | 6 = 6th step in size scale 15 | 7 = 7th step in size scale 16 | 17 | Media Query Extensions: 18 | -m = 48em 19 | -l = 64em 20 | */ 21 | .f1 { font-size: 3rem; } 22 | .f2 { font-size: 2.25rem; } 23 | .f3 { font-size: 1.5rem; } 24 | .f4 { font-size: 1.25rem; } 25 | .f5 { font-size: 1rem; } 26 | .f6 { font-size: 0.875rem; } 27 | .f7 { font-size: 0.75rem; } 28 | @media screen and (min-width: 48) and (max-width: 64) { 29 | .f1-m { font-size: 3rem; } 30 | .f2-m { font-size: 2.25rem; } 31 | .f3-m { font-size: 1.5rem; } 32 | .f4-m { font-size: 1.25rem; } 33 | .f5-m { font-size: 1rem; } 34 | .f6-m { font-size: 0.875rem; } 35 | .f7-m { font-size: 0.75rem; } 36 | } 37 | @media screen and (min-width: 64) { 38 | .f1-l { font-size: 3rem; } 39 | .f2-l { font-size: 2.25rem; } 40 | .f3-l { font-size: 1.5rem; } 41 | .f4-l { font-size: 1.25rem; } 42 | .f5-l { font-size: 1rem; } 43 | .f6-l { font-size: 0.875rem; } 44 | .f7-l { font-size: 0.75rem; } 45 | } 46 | -------------------------------------------------------------------------------- /lib/border-radius.js: -------------------------------------------------------------------------------- 1 | const { step, mqSteps } = require('./docs-helper') 2 | 3 | const docs = (radii, mqs) => ` 4 | /* 5 | 6 | BORDER RADIUS 7 | Docs: http://tachyons.io/docs/themes/border-radius/ 8 | 9 | Base: 10 | br = border-radius 11 | 12 | Modifiers: 13 | ${ radii.map((_, idx) => step({ zeroth: '/none', nth: 'scale' }, idx)).join('\n ') } 14 | 15 | Literal values: 16 | -100 = 100% 17 | -pill = 9999px 18 | 19 | Media Query Extensions: 20 | ${mqSteps(mqs)} 21 | 22 | */` 23 | 24 | const css = radii => 25 | radii 26 | .map((radius, idx) => `.br${idx} { border-radius: ${radius}rem; }`) 27 | .concat([ 28 | '.br-100 { border-radius: 100%; }', 29 | '.br-pill { border-radius: 9999px; }', 30 | `.br--bottom { 31 | border-top-left-radius: 0; 32 | border-top-right-radius: 0; 33 | }`, 34 | `.br--top { 35 | border-bottom-left-radius: 0; 36 | border-bottom-right-radius: 0; 37 | }`, 38 | `.br--right { 39 | border-top-left-radius: 0; 40 | border-bottom-left-radius: 0; 41 | }`, 42 | `.br--left { 43 | border-top-right-radius: 0; 44 | border-bottom-right-radius: 0; 45 | }` 46 | ]) 47 | .join('\n') 48 | 49 | module.exports = { 50 | css, 51 | docs 52 | } 53 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tachyons-generator", 3 | "description": "Generate a custom Tachyons build with a json configuration", 4 | "author": "John Otander", 5 | "version": "0.23.0", 6 | "main": "index.js", 7 | "files": [ 8 | "index.js", 9 | "config.js", 10 | "lib", 11 | "docs", 12 | "partials" 13 | ], 14 | "workspaces": [ 15 | "api" 16 | ], 17 | "scripts": { 18 | "test": "ava -v --timeout=20s", 19 | "docs": "node docs/generate" 20 | }, 21 | "repository": "tachyons-css/tachyons-generator", 22 | "keywords": [ 23 | "tachyons", 24 | "css", 25 | "oocss", 26 | "generator" 27 | ], 28 | "license": "MIT", 29 | "dependencies": { 30 | "camelcase": "^4.1.0", 31 | "colorable": "^1.0.5", 32 | "cxs": "^6.0.0", 33 | "is-blank": "^2.1.0", 34 | "isobject": "^3.0.1", 35 | "kebab-case": "^1.0.0", 36 | "mqify": "^0.1.1", 37 | "palx": "^1.0.2", 38 | "perfectionist": "^2.4.0", 39 | "postcss": "^6.0.11", 40 | "postcss-class-postfix": "^1.0.0", 41 | "postcss-class-prefix": "^0.3.0", 42 | "react": "^15.6.1", 43 | "react-dom": "^15.6.1", 44 | "strip-css-comments": "^3.0.0", 45 | "strip-css-media-queries": "^1.0.0", 46 | "tachyons-build-css": "^1.5.1" 47 | }, 48 | "devDependencies": { 49 | "ava": "^0.22.0", 50 | "globby": "^6.1.0", 51 | "tachyons": "latest" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/spacing.js: -------------------------------------------------------------------------------- 1 | const directions = require('./directions') 2 | const decls = require('./declarations') 3 | const { step, mqSteps } = require('./docs-helper') 4 | const withUnits = require('./units').withUnits 5 | 6 | const docs = (spacing, mqs) => ` 7 | /* 8 | 9 | SPACING 10 | Docs: http://tachyons.io/docs/layout/spacing/ 11 | 12 | An eight step powers of two scale ranging from 0 to 16rem. 13 | 14 | Base: 15 | p = padding 16 | m = margin 17 | 18 | Modifiers: 19 | a = all 20 | h = horizontal 21 | v = vertical 22 | t = top 23 | r = right 24 | b = bottom 25 | l = left 26 | 27 | ${ [].concat(0, spacing).map((_, idx) => step({ zeroth: '/none', nth: 'spacing scale' }, idx )).join('\n ') } 28 | 29 | Media Query Extensions: 30 | ${mqSteps(mqs)} 31 | 32 | */` 33 | 34 | const css = spacing => 35 | [].concat(0, spacing).map((spacing, idx) => 36 | Object.keys(directions).map(d => 37 | [ 38 | `.p${directions[d]}${idx} { ${fullDecl(d, spacing, 'padding')} }`, 39 | `.m${directions[d]}${idx} { ${fullDecl(d, spacing, 'margin')} }`, 40 | `.n${directions[d]}${idx} { ${fullDecl(d, `-${spacing}`, 'margin')} }` 41 | ].join('\n') 42 | ).join('\n') 43 | ) 44 | 45 | 46 | const fullDecl = (d, size, prop) => decls[d].map(dir => `${prop}${dir}: ${withUnits(size, 'rem')};`).join('\n') 47 | 48 | module.exports = { 49 | css, 50 | docs 51 | } 52 | -------------------------------------------------------------------------------- /lib/heights.js: -------------------------------------------------------------------------------- 1 | const { step, mqSteps } = require('./docs-helper') 2 | 3 | const docs = (heights, mqs) => ` 4 | /* 5 | 6 | HEIGHTS 7 | Docs: http://tachyons.io/docs/layout/heights/ 8 | 9 | Base: 10 | h = height 11 | min-h = min-height 12 | min-vh = min-height vertical screen height 13 | vh = vertical screen height 14 | 15 | Modifiers 16 | ${ heights.map((_, idx) => step({ nth: 'height scale' }, idx + 1)).join('\n ') } 17 | 18 | -25 = literal value 25% 19 | -50 = literal value 50% 20 | -75 = literal value 75% 21 | -100 = literal value 100% 22 | 23 | -auto = string value of auto 24 | -inherit = string value of inherit 25 | 26 | Media Query Extensions: 27 | ${mqSteps(mqs)} 28 | 29 | */` 30 | 31 | const css = heights => 32 | heights 33 | .map((height, idx) => `.h${idx+1} { height: ${height}rem; }`) 34 | .concat([ 35 | '.h-25 { height: 25%; }', 36 | '.h-50 { height: 50%; }', 37 | '.h-75 { height: 75%; }', 38 | '.h-100 { height: 100%; }', 39 | '.min-h-100 { min-height: 100%; }', 40 | '.vh-25 { height: 25vh; }', 41 | '.vh-50 { height: 50vh; }', 42 | '.vh-75 { height: 75vh; }', 43 | '.vh-100 { height: 100vh; }', 44 | '.min-vh-100 { min-height: 100vh; }', 45 | '.h-auto { height: auto; }', 46 | '.h-inherit { height: inherit; }' 47 | ]) 48 | .join('\n') 49 | 50 | module.exports = { 51 | css, 52 | docs 53 | } 54 | -------------------------------------------------------------------------------- /app/config.js: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | "typeScale": [ 3 | 3, 2.25, 1.5, 1.25, 1, 0.875 4 | ], 5 | "spacing": { 6 | "root": 8, 7 | "ratio": 2, 8 | "steps": 6 9 | }, 10 | "customMedia": [ 11 | { "m": 48 }, 12 | { "l": 64 } 13 | ], 14 | "colors": [ 15 | { "black": "#000" }, 16 | { "near-black": "#111" }, 17 | { "dark-gray": "#333" }, 18 | { "mid-gray": "#555" }, 19 | { "gray": "#777" }, 20 | { "silver": "#999" }, 21 | { "light-silver": "#aaa" }, 22 | { "moon-gray": "#ccc" }, 23 | { "light-gray": "#eee" }, 24 | { "near-white": "#f4f4f4" }, 25 | { "white": "#fff" }, 26 | { "dark-red": "#f00008" }, 27 | { "red": "#ff3223" }, 28 | { "orange": "#f3a801" }, 29 | { "gold": "#f2c800" }, 30 | { "yellow": "#ffde37" }, 31 | { "purple": "#7d5da9" }, 32 | { "light-purple": "#8d4f92" }, 33 | { "hot-pink": "#d62288" }, 34 | { "dark-pink": "#c64774" }, 35 | { "pink": "#f49cc8" }, 36 | { "dark-green": "#006C71" }, 37 | { "green": "#41D69F" }, 38 | { "navy": "#001b44" }, 39 | { "dark-blue": "#00449e" }, 40 | { "blue": "#357edd" }, 41 | { "light-blue": "#96ccff" }, 42 | { "lightest-blue": "#cdecff" }, 43 | { "washed-blue": "#f6fffe" }, 44 | { "washed-green": "#e8fdf5" }, 45 | { "washed-yellow": "#fff8d5" }, 46 | { "light-pink": "#efa4b8" }, 47 | { "light-yellow": "#f3dd70" }, 48 | { "light-red": "#ffd3c0" } 49 | ] 50 | }) 51 | -------------------------------------------------------------------------------- /lib/manifest.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | variables: { colors: true }, 3 | aspectRatios: { mq: true }, 4 | backgroundSize: { mq: true }, 5 | backgroundPosition: { mq: true }, 6 | borders: { mq: true }, 7 | borderColors: { colors: true }, 8 | borderRadius: { mq: true }, 9 | borderStyle: { mq: true }, 10 | borderWidths: { mq: true }, 11 | boxShadow: { mq: true }, 12 | boxSizing: {}, 13 | code: {}, 14 | spacing: { mq: true }, 15 | coordinates: { mq: true }, 16 | clears: { mq: true }, 17 | display: { mq: true }, 18 | flexbox: { mq: true }, 19 | floats: { mq: true }, 20 | fontFamily: {}, 21 | fontStyle: { mq: true }, 22 | fontWeight: { mq: true }, 23 | forms: {}, 24 | debugChildren: {}, 25 | debugGrid: {}, 26 | links: {}, 27 | lists: {}, 28 | heights: { mq: true }, 29 | skins: { colors: true }, 30 | skinsPseudo: { colors: true }, 31 | images: {}, 32 | letterSpacing: { mq: true }, 33 | lineHeight: { mq: true }, 34 | maxWidths: { mq: true }, 35 | normalize: {}, 36 | nested: {}, 37 | hovers: {}, 38 | opacity: { mq: true }, 39 | rotations: { mq: true }, 40 | outlines: { mq: true }, 41 | overflow: { mq: true }, 42 | position: { mq: true }, 43 | tables: {}, 44 | textDecoration: { mq: true }, 45 | textAlign: { mq: true }, 46 | textTransform: { mq: true }, 47 | verticalAlign: {}, 48 | typeScale: { mq: true }, 49 | typography: { mq: true }, 50 | utilities: {}, 51 | visibility: { mq: true }, 52 | whiteSpace: { mq: true }, 53 | widths: { mq: true }, 54 | zIndex: {} 55 | } 56 | -------------------------------------------------------------------------------- /docs/components/GettingStarted.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const e = React.createElement 3 | 4 | const { 5 | GettingStartedCx: { 6 | wrap, 7 | pre 8 | }, 9 | ButtonCx: { 10 | button 11 | } 12 | } = require('../style') 13 | 14 | const DESCRIPTION = ` 15 | Copy the link style tag and paste it 16 | it in the head of the html file(s) you 17 | want to include this custom tachyons 18 | build in 19 | ` 20 | 21 | const html = (hash, version) => ` 22 | 23 | 24 | ${link(hash, version)} 25 | 26 | 27 | 28 | ` 29 | 30 | const link = (hash, version) => `` 31 | 32 | module.exports = (hash, version) => 33 | e('article', { className: wrap }, 34 | e('h3', { className: 'f3' }, 'Getting Started'), 35 | e('p', { className: 'lh-copy measure' }, DESCRIPTION), 36 | e('pre', { className: pre }, html(hash, version)), 37 | e('div', { className: 'tc mv4' }, 38 | e('h4', { className: 'mb2 ttu' }, 'Start Using'), 39 | e('a', { className: button, href: 'http://tachyons.io' }, 'Tachyons'), 40 | e('a', { className: button, href: 'https://github.com/tachyons-css/tachyons-generator' }, 'GitHub'), 41 | e('a', { className: button, href: 'css/tachyons.css' }, 'Download Css'), 42 | e('a', { className: button, href: 'config.json' }, 'Config'), 43 | e('a', { className: button, href: 'modules.json' }, 'Modules') 44 | ) 45 | ) 46 | -------------------------------------------------------------------------------- /partials/_font-family.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .sans-serif { 3 | font-family: -apple-system, BlinkMacSystemFont, 4 | 'avenir next', avenir, 5 | 'helvetica neue', helvetica, 6 | ubuntu, 7 | roboto, noto, 8 | 'segoe ui', arial, 9 | sans-serif; 10 | } 11 | 12 | .serif { 13 | font-family: georgia, 14 | times, 15 | serif; 16 | } 17 | 18 | .system-sans-serif { 19 | font-family: sans-serif; 20 | } 21 | 22 | .system-serif { 23 | font-family: serif; 24 | } 25 | 26 | 27 | 28 | 29 | 30 | code, .code { 31 | font-family: Consolas, 32 | monaco, 33 | monospace; 34 | } 35 | 36 | .courier { 37 | font-family: 'Courier Next', 38 | courier, 39 | monospace; 40 | } 41 | 42 | 43 | 44 | 45 | .helvetica { 46 | font-family: 'helvetica neue', helvetica, 47 | sans-serif; 48 | } 49 | 50 | .avenir { 51 | font-family: 'avenir next', avenir, 52 | sans-serif; 53 | } 54 | 55 | 56 | 57 | 58 | .athelas { 59 | font-family: athelas, 60 | georgia, 61 | serif; 62 | } 63 | 64 | .georgia { 65 | font-family: georgia, 66 | serif; 67 | } 68 | 69 | .times { 70 | font-family: times, 71 | serif; 72 | } 73 | 74 | .bodoni { 75 | font-family: "Bodoni MT", 76 | serif; 77 | } 78 | 79 | .calisto { 80 | font-family: "Calisto MT", 81 | serif; 82 | } 83 | 84 | .garamond { 85 | font-family: garamond, 86 | serif; 87 | } 88 | 89 | .baskerville { 90 | font-family: baskerville, 91 | serif; 92 | } 93 | ` -------------------------------------------------------------------------------- /lib/nested.js: -------------------------------------------------------------------------------- 1 | const { getColor } = require('./config-utils') 2 | const { step, mqSteps } = require('./docs-helper') 3 | 4 | const docs = () => 5 | ` 6 | /* 7 | 8 | NESTED 9 | Tachyons module for styling nested elements 10 | that are generated by a cms. 11 | 12 | */ 13 | ` 14 | 15 | const css = (nested, fullConfig) => { 16 | return ` 17 | .nested-copy-line-height p, 18 | .nested-copy-line-height ul, 19 | .nested-copy-line-height ol { 20 | line-height: 1.5; 21 | } 22 | 23 | .nested-headline-line-height h1, 24 | .nested-headline-line-height h2, 25 | .nested-headline-line-height h3, 26 | .nested-headline-line-height h4, 27 | .nested-headline-line-height h5, 28 | .nested-headline-line-height h6 { 29 | line-height: 1.25; 30 | } 31 | 32 | .nested-list-reset ul, 33 | .nested-list-reset ol { 34 | padding-left: 0; 35 | margin-left: 0; 36 | list-style-type: none; 37 | } 38 | 39 | .nested-copy-indent p+p { 40 | text-indent: 1em; 41 | margin-top: 0; 42 | margin-bottom: 0; 43 | } 44 | 45 | .nested-copy-separator p+p { 46 | margin-top: 1.5em; 47 | } 48 | 49 | .nested-img img { 50 | width: 100%; 51 | max-width: 100%; 52 | display: block; 53 | } 54 | 55 | .nested-links a { 56 | color: ${getColor( 57 | fullConfig, 58 | nested && nested.links && nested.links.length > 0 && nested.links[0], 59 | 'blue' 60 | )}; 61 | transition: color .15s ease-in; 62 | } 63 | 64 | .nested-links a:hover, 65 | .nested-links a:focus { 66 | color: ${getColor( 67 | fullConfig, 68 | nested && nested.links && nested.links.length > 0 && nested.links[1], 69 | 'light-blue' 70 | )}; 71 | transition: color .15s ease-in; 72 | } 73 | ` 74 | } 75 | 76 | module.exports = { 77 | css, 78 | docs, 79 | } 80 | -------------------------------------------------------------------------------- /api/index.js: -------------------------------------------------------------------------------- 1 | const tachyonsGenerator = require('tachyons-generator') 2 | 3 | const { version } = require('tachyons-generator/package') 4 | const hashConfig = require('./lib/hash-config') 5 | const AWS = require('./lib/aws-client') 6 | 7 | const upload = ({ bucket, name, contentType, dir, body }) => { 8 | return new Promise((resolve, reject) => { 9 | bucket.putObject({ 10 | Bucket: 'tachyons-pub', 11 | Key: `${dir}/${name}`, 12 | ContentType: contentType, 13 | Body: body, 14 | ACL: 'public-read' 15 | }, err => err ? reject(err) : resolve()) 16 | }) 17 | } 18 | 19 | module.exports = async (req, res) => { 20 | try { 21 | const config = req.body 22 | const hash = hashConfig(config) 23 | const dir = `${version}/${hash}` 24 | 25 | const bucket = new AWS.S3() 26 | 27 | const tGenerate = await tachyonsGenerator(config) 28 | const tachy = await tGenerate.generate() 29 | 30 | const px = [ 31 | upload({ bucket, name: 'css/tachyons.css', contentType: 'text/css', dir, body: tachy.css }), 32 | upload({ bucket, name: 'css/tachyons.min.css', contentType: 'text/css', dir, body: tachy.min }), 33 | upload({ bucket, name: 'config.json', contentType: 'application/json', dir, body: JSON.stringify(config, null, 2) }), 34 | upload({ bucket, name: 'modules.json', contentType: 'application/json', dir, body: JSON.stringify(tachy.modules, null, 2) }), 35 | upload({ bucket, name: 'index.html', contentType: 'text/html', dir, body: tachy.docs }) 36 | ] 37 | 38 | await Promise.all(px) 39 | 40 | res.json({ url: `https://s3-us-west-1.amazonaws.com/tachyons-pub/${dir}/index.html` }) 41 | } catch (error) { 42 | console.log(error) 43 | res.json({ error }) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/fixtures/display.css: -------------------------------------------------------------------------------- 1 | .dn { display: none; } 2 | .di { display: inline; } 3 | .db { display: block; } 4 | .dib { display: inline-block; } 5 | .dit { display: inline-table; } 6 | .dt { display: table; } 7 | .dtc { display: table-cell; } 8 | .dt-row { display: table-row; } 9 | .dt-row-group { display: table-row-group; } 10 | .dt-column { display: table-column; } 11 | .dt-column-group { display: table-column-group; } 12 | 13 | 14 | .dt--fixed { 15 | table-layout: fixed; 16 | width: 100%; 17 | } 18 | 19 | @media screen and (min-width: 48) and (max-width: 64) { 20 | .dn-m { display: none; } 21 | .di-m { display: inline; } 22 | .db-m { display: block; } 23 | .dib-m { display: inline-block; } 24 | .dit-m { display: inline-table; } 25 | .dt-m { display: table; } 26 | .dtc-m { display: table-cell; } 27 | .dt-row-m { display: table-row; } 28 | .dt-row-group-m { display: table-row-group; } 29 | .dt-column-m { display: table-column; } 30 | .dt-column-group-m { display: table-column-group; } 31 | 32 | 33 | .dt--fixed-m { 34 | table-layout: fixed; 35 | width: 100%; 36 | } 37 | } 38 | @media screen and (min-width: 64) { 39 | .dn-l { display: none; } 40 | .di-l { display: inline; } 41 | .db-l { display: block; } 42 | .dib-l { display: inline-block; } 43 | .dit-l { display: inline-table; } 44 | .dt-l { display: table; } 45 | .dtc-l { display: table-cell; } 46 | .dt-row-l { display: table-row; } 47 | .dt-row-group-l { display: table-row-group; } 48 | .dt-column-l { display: table-column; } 49 | .dt-column-group-l { display: table-column-group; } 50 | 51 | 52 | .dt--fixed-l { 53 | table-layout: fixed; 54 | width: 100%; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/widths.js: -------------------------------------------------------------------------------- 1 | const { step, mqSteps } = require('./docs-helper') 2 | 3 | const docs = (widths, mqs) => ` 4 | /* 5 | 6 | WIDTHS 7 | Docs: http://tachyons.io/docs/layout/widths/ 8 | 9 | Base: 10 | w = width 11 | 12 | Modifiers 13 | ${ widths.map((_, idx) => step({ nth: 'width scale' }, idx + 1)).join('\n ') } 14 | 15 | -10 = literal value 10% 16 | -20 = literal value 20% 17 | -25 = literal value 25% 18 | -30 = literal value 30% 19 | -33 = literal value 33% 20 | -34 = literal value 34% 21 | -40 = literal value 40% 22 | -50 = literal value 50% 23 | -60 = literal value 60% 24 | -70 = literal value 70% 25 | -75 = literal value 75% 26 | -80 = literal value 80% 27 | -90 = literal value 90% 28 | -100 = literal value 100% 29 | 30 | -third = 100% / 3 (Not supported in opera mini or IE8) 31 | -two-thirds = 100% / 1.5 (Not supported in opera mini or IE8) 32 | 33 | -auto = string value auto 34 | 35 | Media Query Extensions: 36 | ${mqSteps(mqs)} 37 | 38 | */` 39 | 40 | const css = widths => 41 | widths 42 | .map((width, idx) => `.w${idx+1} { width: ${width}rem; }`) 43 | .concat([ 44 | '.w-10 { width: 10%; }', 45 | '.w-20 { width: 20%; }', 46 | '.w-25 { width: 25%; }', 47 | '.w-30 { width: 30%; }', 48 | '.w-33 { width: 33%; }', 49 | '.w-34 { width: 34%; }', 50 | '.w-40 { width: 40%; }', 51 | '.w-50 { width: 50%; }', 52 | '.w-60 { width: 60%; }', 53 | '.w-70 { width: 70%; }', 54 | '.w-75 { width: 75%; }', 55 | '.w-80 { width: 80%; }', 56 | '.w-90 { width: 90%; }', 57 | '.w-100 { width: 100%; }', 58 | '.w-third { width: calc(100% / 3); }', 59 | '.w-two-thirds { width: calc(100% / 1.5); }', 60 | '.w-auto { width: auto; }' 61 | ]) 62 | .join('\n') 63 | 64 | module.exports = { 65 | css, 66 | docs 67 | } 68 | -------------------------------------------------------------------------------- /partials/_flexbox.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .flex { display: flex; } 3 | .inline-flex { display: inline-flex; } 4 | 5 | .flex-auto { 6 | flex: 1 1 auto; 7 | min-width: 0; 8 | min-height: 0; 9 | } 10 | 11 | .flex-none { flex: none; } 12 | 13 | .flex-column { flex-direction: column; } 14 | .flex-row { flex-direction: row; } 15 | .flex-wrap { flex-wrap: wrap; } 16 | .flex-nowrap { flex-wrap: nowrap; } 17 | .flex-wrap-reverse { flex-wrap: wrap-reverse; } 18 | .flex-column-reverse { flex-direction: column-reverse; } 19 | .flex-row-reverse { flex-direction: row-reverse; } 20 | 21 | .items-start { align-items: flex-start; } 22 | .items-end { align-items: flex-end; } 23 | .items-center { align-items: center; } 24 | .items-baseline { align-items: baseline; } 25 | .items-stretch { align-items: stretch; } 26 | 27 | .self-start { align-self: flex-start; } 28 | .self-end { align-self: flex-end; } 29 | .self-center { align-self: center; } 30 | .self-baseline { align-self: baseline; } 31 | .self-stretch { align-self: stretch; } 32 | 33 | .justify-start { justify-content: flex-start; } 34 | .justify-end { justify-content: flex-end; } 35 | .justify-center { justify-content: center; } 36 | .justify-between { justify-content: space-between; } 37 | .justify-around { justify-content: space-around; } 38 | 39 | .content-start { align-content: flex-start; } 40 | .content-end { align-content: flex-end; } 41 | .content-center { align-content: center; } 42 | .content-between { align-content: space-between; } 43 | .content-around { align-content: space-around; } 44 | .content-stretch { align-content: stretch; } 45 | 46 | .order-0 { order: 0; } 47 | .order-1 { order: 1; } 48 | .order-2 { order: 2; } 49 | .order-3 { order: 3; } 50 | .order-4 { order: 4; } 51 | .order-5 { order: 5; } 52 | .order-6 { order: 6; } 53 | .order-7 { order: 7; } 54 | .order-8 { order: 8; } 55 | .order-last { order: 99999; } 56 | 57 | .flex-grow-0 { flex-grow: 0; } 58 | .flex-grow-1 { flex-grow: 1; } 59 | 60 | .flex-shrink-0 { flex-shrink: 0; } 61 | .flex-shrink-1 { flex-shrink: 1; } 62 | ` 63 | -------------------------------------------------------------------------------- /test/snapshots/line-height-test.js.md: -------------------------------------------------------------------------------- 1 | # Snapshot report for `test/line-height-test.js` 2 | 3 | The actual snapshot is saved in `line-height-test.js.snap`. 4 | 5 | Generated by [AVA](https://ava.li). 6 | 7 | ## Line heights are generated when included in config. 8 | 9 | > Snapshot 1 10 | 11 | `␊ 12 | /*␊ 13 | LINE HEIGHT / Leading␊ 14 | Docs: http://tachyons.io/docs/typography/line-height/␊ 15 | ␊ 16 | Base:␊ 17 | lh = line-height␊ 18 | ␊ 19 | Media Query Extensions:␊ 20 | -m = 48em␊ 21 | -l = 64em␊ 22 | */␊ 23 | ␊ 24 | .lh-solid { line-height: 1.3 }␊ 25 | .lh-title { line-height: 1.5 }␊ 26 | .lh-copy { line-height: 1.7 }␊ 27 | ␊ 28 | @media screen and (min-width: 48em) and (max-width: 64em) {␊ 29 | .lh-solid-m { line-height: 1.3 }␊ 30 | .lh-title-m { line-height: 1.5 }␊ 31 | .lh-copy-m { line-height: 1.7 }␊ 32 | }␊ 33 | ␊ 34 | ␊ 35 | @media screen and (min-width: 64em) {␊ 36 | .lh-solid-l { line-height: 1.3 }␊ 37 | .lh-title-l { line-height: 1.5 }␊ 38 | .lh-copy-l { line-height: 1.7 }␊ 39 | }␊ 40 | ` 41 | 42 | ## Line heights fall back to default values when not included. 43 | 44 | > Snapshot 1 45 | 46 | `␊ 47 | /*␊ 48 | LINE HEIGHT / Leading␊ 49 | Docs: http://tachyons.io/docs/typography/line-height/␊ 50 | ␊ 51 | Base:␊ 52 | lh = line-height␊ 53 | ␊ 54 | Media Query Extensions:␊ 55 | -m = 48em␊ 56 | -l = 64em␊ 57 | */␊ 58 | ␊ 59 | .lh-solid { line-height: 1 }␊ 60 | .lh-title { line-height: 1.25 }␊ 61 | .lh-copy { line-height: 1.5 }␊ 62 | ␊ 63 | @media screen and (min-width: 48em) and (max-width: 64em) {␊ 64 | .lh-solid-m { line-height: 1 }␊ 65 | .lh-title-m { line-height: 1.25 }␊ 66 | .lh-copy-m { line-height: 1.5 }␊ 67 | }␊ 68 | ␊ 69 | ␊ 70 | @media screen and (min-width: 64em) {␊ 71 | .lh-solid-l { line-height: 1 }␊ 72 | .lh-title-l { line-height: 1.25 }␊ 73 | .lh-copy-l { line-height: 1.5 }␊ 74 | }␊ 75 | ` 76 | -------------------------------------------------------------------------------- /partials/_hovers.css.js: -------------------------------------------------------------------------------- 1 | module.exports = ` 2 | .dim { 3 | opacity: 1; 4 | transition: opacity .15s ease-in; 5 | } 6 | .dim:hover, 7 | .dim:focus { 8 | opacity: .5; 9 | transition: opacity .15s ease-in; 10 | } 11 | .dim:active { 12 | opacity: .8; transition: opacity .15s ease-out; 13 | } 14 | 15 | .glow { 16 | transition: opacity .15s ease-in; 17 | } 18 | .glow:hover, 19 | .glow:focus { 20 | opacity: 1; 21 | transition: opacity .15s ease-in; 22 | } 23 | 24 | .hide-child .child { 25 | opacity: 0; 26 | transition: opacity .15s ease-in; 27 | } 28 | .hide-child:hover .child, 29 | .hide-child:focus .child, 30 | .hide-child:active .child { 31 | opacity: 1; 32 | transition: opacity .15s ease-in; 33 | } 34 | 35 | .underline-hover:hover, 36 | .underline-hover:focus { 37 | text-decoration: underline; 38 | } 39 | 40 | .grow { 41 | -moz-osx-font-smoothing: grayscale; 42 | backface-visibility: hidden; 43 | transform: translateZ(0); 44 | transition: transform 0.25s ease-out; 45 | } 46 | .grow:hover, 47 | .grow:focus { 48 | transform: scale(1.05); 49 | } 50 | .grow:active { 51 | transform: scale(.90); 52 | } 53 | 54 | .grow-large { 55 | -moz-osx-font-smoothing: grayscale; 56 | backface-visibility: hidden; 57 | transform: translateZ(0); 58 | transition: transform .25s ease-in-out; 59 | } 60 | .grow-large:hover, 61 | .grow-large:focus { 62 | transform: scale(1.2); 63 | } 64 | .grow-large:active { 65 | transform: scale(.95); 66 | } 67 | 68 | .pointer:hover { 69 | cursor: pointer; 70 | } 71 | 72 | .shadow-hover { 73 | cursor: pointer; 74 | position: relative; 75 | transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); 76 | } 77 | .shadow-hover::after { 78 | content: ''; 79 | box-shadow: 0px 0px 16px 2px rgba( 0, 0, 0, .2 ); 80 | border-radius: inherit; 81 | opacity: 0; 82 | position: absolute; 83 | top: 0; 84 | left: 0; 85 | width: 100%; 86 | height: 100%; 87 | z-index: -1; 88 | transition: opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); 89 | } 90 | .shadow-hover:hover::after, 91 | .shadow-hover:focus::after { 92 | opacity: 1; 93 | } 94 | 95 | .bg-animate, 96 | .bg-animate:hover, 97 | .bg-animate:focus { 98 | transition: background-color .15s ease-in-out; 99 | } 100 | ` 101 | -------------------------------------------------------------------------------- /lib/generate.js: -------------------------------------------------------------------------------- 1 | const camel = require('camelcase') 2 | const kebab = require('kebab-case') 3 | const isBlank = require('is-blank') 4 | 5 | const manifest = require('./manifest') 6 | const color = require('./color') 7 | const mqify = require('mqify') 8 | 9 | const generators = { 10 | borderWidths: require('./border-widths'), 11 | borderRadius: require('./border-radius'), 12 | typeScale: require('./type-scale'), 13 | spacing: require('./spacing'), 14 | widths: require('./widths'), 15 | maxWidths: require('./max-widths'), 16 | heights: require('./heights'), 17 | typography: require('./typography'), 18 | opacity: require('./opacity'), 19 | lineHeight: require('./line-height'), 20 | tables: require('./tables'), 21 | nested: require('./nested'), 22 | } 23 | 24 | const cssWithDocs = (generator, config, mqs, fullConfig) => `${generator.docs(config, mqs)} 25 | ${generator.css(config, fullConfig)}` 26 | 27 | module.exports = (config, mediaQueries) => { 28 | const colors = color(config.palette || config.colors) 29 | 30 | const skipModules = (config.skipModules || []).map(n => camel(n)) 31 | 32 | const px = Object.keys(manifest) 33 | .filter(filterSkipped.bind(null, skipModules)) 34 | .map(name => { 35 | const module = manifest[name] 36 | 37 | let raw = null 38 | 39 | if (module.colors) { 40 | raw = colors[name]() 41 | } else if (generators.hasOwnProperty(name)) { 42 | const generator = generators[name] 43 | raw = cssWithDocs(generator, config[name], config.customMedia, config) 44 | } else { 45 | raw = requireify(name) 46 | } 47 | 48 | if (!module.mq) { 49 | return { name, css: raw } 50 | } 51 | 52 | return mqify(raw, mediaQueries).then(css => ({ name, css })) 53 | }) 54 | 55 | return Promise.all(px).then(reduceModules) 56 | } 57 | 58 | const reduceModules = modules => { 59 | return modules.reduce((prev, curr) => { 60 | prev[camel(curr.name)] = curr.css 61 | return prev 62 | }, {}) 63 | } 64 | 65 | const filterSkipped = (skipModules, name) => { 66 | if (isBlank(skipModules)) { 67 | return true 68 | } else { 69 | return !skipModules.includes(camel(name)) 70 | } 71 | } 72 | 73 | const requireify = name => { 74 | const kebabed = kebab(name) 75 | return require(`../partials/_${kebabed}.css`) 76 | } 77 | -------------------------------------------------------------------------------- /docs/components/Colors.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const e = React.createElement 3 | 4 | const colorable = require('colorable') 5 | 6 | const { 7 | ColorsCx: { 8 | td, 9 | bg, 10 | color, 11 | colorTile 12 | } 13 | } = require('../style') 14 | 15 | const COLORABLE_DESCRIPTION = ` 16 | In visual perception a color is almost never seen as 17 | it really is – as it physically is. This fact makes color 18 | the most relative medium in art. - Josef Albers 19 | ` 20 | 21 | // Need to use this for palx handling 22 | const colorify = require('../../lib/color') 23 | 24 | const Section = require('./Section') 25 | const HtmlSection = require('./HtmlSection') 26 | const CodeSection = require('./CodeSection') 27 | 28 | const Colors = config => { 29 | const colorMap = colorify(config.colors).colorMap 30 | 31 | return Object.keys(colorMap).map(name => { 32 | const colorCx = `${td} ${color} ${name}` 33 | const bgCx = `${td} ${bg} bg-${name}` 34 | const varCx = td 35 | 36 | return e('tr', { key: name }, 37 | e('td', { className: bgCx }, null), 38 | e('td', { className: colorCx }, 'Aa'), 39 | e('td', { className: varCx }, `--${name}: ${colorMap[name]}`) 40 | ) 41 | }) 42 | } 43 | 44 | const ColorsTable = config => 45 | e('table', { className: 'border-collapse w-100' }, 46 | e('tbody', { className: 'f6', cellspacing: 0, cellpadding: 0 }, Colors(config)) 47 | ) 48 | 49 | const Colorable = colors => 50 | e('div', { className: 'cf w-100 flex flex-wrap' }, 51 | colorable(colors, { threshold: 3 }).map(combo => 52 | e('div', { key: combo.name, className: `${colorTile} bg-${combo.name}` }, 53 | combo.combinations.map(color => 54 | e('div', { key: `${color.name}${combo.name}`, className: color.name }, 55 | e('h1', null, 'Aa', 56 | e('span', { className: 'pl1 f5' }, color.contrast.toFixed(2)) 57 | ), 58 | e('p', { className: 'f6 lh-copy code' }, `.bg-${combo.name} + .${color.name}`), 59 | e('p', { className: 'f6 lh-copy' }, COLORABLE_DESCRIPTION) 60 | ) 61 | ) 62 | ) 63 | ) 64 | ) 65 | 66 | module.exports = (config, typeScale) => 67 | e('div', null, 68 | Section({ 69 | title: 'Colors', 70 | children: [ 71 | HtmlSection(ColorsTable(config)), 72 | CodeSection(typeScale), 73 | ] 74 | }), 75 | Section({ 76 | title: 'Color Combinations', 77 | children: Colorable(config.colors) 78 | }) 79 | ) 80 | -------------------------------------------------------------------------------- /lib/color.js: -------------------------------------------------------------------------------- 1 | const palx = require('palx') 2 | 3 | module.exports = colors => { 4 | if (typeof colors === 'string') { 5 | colors = listToMap(palxToColors(colors)) 6 | } 7 | 8 | const colorsWithTransparency = Object.assign( 9 | {}, colors, { transparent: 'transparent' } 10 | ) 11 | 12 | colorGenerator.variables = () => variables(colorsWithTransparency) 13 | colorGenerator.borderColors = () => border(colorsWithTransparency) 14 | colorGenerator.skins = () => skins(colors, colorsWithTransparency) 15 | colorGenerator.skinsPseudo = () => skinsPseudo(colors, colorsWithTransparency) 16 | 17 | colorGenerator.colorMap = colors 18 | 19 | function colorGenerator () {} 20 | return colorGenerator 21 | } 22 | 23 | const skins = (colors, colorsWithTransparency) => ` 24 | ${text(colors)} 25 | ${bg(colorsWithTransparency)} 26 | ` 27 | 28 | const skinsPseudo = (colors, colorsWithTransparency) => ` 29 | ${hover(colors)} 30 | ${hoverBg(colorsWithTransparency)} 31 | ` 32 | 33 | const colorToCss = fn => obj => Object.keys(obj).map(key => fn(key, obj[key])).join('\n') 34 | 35 | const bg = colorToCss(key => `.bg-${key} { background-color: ${asVar(key)} }`) 36 | 37 | const text = colorToCss(key => `.${key} { color: ${asVar(key)} }`) 38 | 39 | const hover = colorToCss(key => ([ 40 | `.hover-${key}:focus, .hover-${key}:hover { color: ${asVar(key)} }`, 41 | ])) 42 | 43 | const hoverBg = colorToCss(key => ([ 44 | `.hover-bg-${key}:focus, .hover-bg-${key}:hover { background-color: ${asVar(key)} }`, 45 | ])) 46 | 47 | const border = colorToCss(key => `.b--${key} { border-color: ${asVar(key)} }`) 48 | 49 | const variables = colors => { 50 | const _variables = [] 51 | _variables.push(`:root {`) 52 | 53 | Object.keys(colors).forEach(key => { 54 | const val = colors[key] 55 | 56 | _variables.push(` --${key}: ${val};`) 57 | }) 58 | 59 | _variables.push(`}`) 60 | return _variables.join('\n') 61 | } 62 | 63 | const palxToColors = color => { 64 | const colorMap = palx(color) 65 | 66 | const black = colorMap.black 67 | 68 | delete colorMap.base 69 | delete colorMap.black 70 | 71 | const colors = [{ black: black }] 72 | 73 | Object.keys(colorMap).forEach(name => { 74 | for (let i = 0; i < colorMap[name].length; i++) { 75 | const obj = {} 76 | obj[`${name}-${i + 1}`] = colorMap[name][i] 77 | 78 | colors.push(obj) 79 | } 80 | }) 81 | 82 | return colors 83 | } 84 | 85 | const asVar = color => `var(--${color})` 86 | 87 | const listToMap = list => list.reduce((acc, obj) => Object.assign(acc, obj), {}) 88 | -------------------------------------------------------------------------------- /partials/tachyons.css.js: -------------------------------------------------------------------------------- 1 | module.exports = `/* TACHYONS (customized) | https://github.com/tachyons-css/tachyons */ 2 | 3 | /* 4 | * 5 | * ________ ______ 6 | * ___ __/_____ _________ /______ ______________________ 7 | * __ / _ __ `/ ___/_ __ \_ / / / __ \_ __ \_ ___/ 8 | * _ / / /_/ // /__ _ / / / /_/ // /_/ / / / /(__ ) 9 | * /_/ \__,_/ \___/ /_/ /_/_\__, / \____//_/ /_//____/ 10 | * /____/ 11 | * 12 | * TABLE OF CONTENTS 13 | * 14 | * 1. External Library Includes 15 | * - Normalize.css | http://normalize.css.github.io 16 | * 2. Tachyons Modules 17 | * 3. Variables 18 | * - Media Queries 19 | * - Colors 20 | * 4. Debugging 21 | * - Debug all 22 | * - Debug children 23 | * 24 | */ 25 | 26 | 27 | /* External Library Includes */ 28 | @import './_normalize'; 29 | 30 | 31 | /* Modules */ 32 | @import './_box-sizing'; 33 | @import './_aspect-ratios'; 34 | @import './_images'; 35 | @import './_background-size'; 36 | @import './_background-position'; 37 | @import './_outlines'; 38 | @import './_borders'; 39 | @import './_border-colors'; 40 | @import './_border-radius'; 41 | @import './_border-style'; 42 | @import './_border-widths'; 43 | @import './_box-shadow'; 44 | @import './_code'; 45 | @import './_coordinates'; 46 | @import './_clears'; 47 | @import './_display'; 48 | @import './_flexbox'; 49 | @import './_floats'; 50 | @import './_font-family'; 51 | @import './_font-style'; 52 | @import './_font-weight'; 53 | @import './_forms'; 54 | @import './_heights'; 55 | @import './_letter-spacing'; 56 | @import './_line-height'; 57 | @import './_links'; 58 | @import './_lists'; 59 | @import './_max-widths'; 60 | @import './_widths'; 61 | @import './_overflow'; 62 | @import './_rotations'; 63 | @import './_position'; 64 | @import './_opacity'; 65 | @import './_skins'; 66 | @import './_skins-pseudo'; 67 | @import './_spacing'; 68 | @import './_negative-margins'; 69 | @import './_tables'; 70 | @import './_text-decoration'; 71 | @import './_text-align'; 72 | @import './_text-transform'; 73 | @import './_type-scale'; 74 | @import './_typography'; 75 | @import './_utilities'; 76 | @import './_visibility'; 77 | @import './_white-space'; 78 | @import './_vertical-align'; 79 | @import './_hovers'; 80 | @import './_z-index'; 81 | @import './_styles'; 82 | 83 | /* Variables */ 84 | /* Importing here will allow you to override any variables in the modules */ 85 | @import './_colors'; 86 | @import './_media-queries'; 87 | 88 | /* Debugging */ 89 | @import './_debug-children'; 90 | @import './_debug-grid'; 91 | 92 | /* Uncomment out the line below to help debug layout issues */ 93 | /* @import './_debug'; */` 94 | -------------------------------------------------------------------------------- /docs/style.js: -------------------------------------------------------------------------------- 1 | 2 | const cxs = require('cxs') 3 | 4 | // This ensures that basic styling for 5 | // the styleguide are consistent amongst 6 | // all configurations 7 | module.exports.BodyCx = { 8 | body: cxs({ 9 | width: '100%', 10 | overflowX: 'hidden', 11 | maxWidth: '96rem', 12 | paddingLeft: '2rem', 13 | paddingRight: '2rem', 14 | marginLeft: 'auto', 15 | marginRight: 'auto' 16 | }) 17 | } 18 | 19 | module.exports.GettingStartedCx = { 20 | wrap: cxs({ 21 | borderTop: 'thin solid #fafafa', 22 | color: 'rgba(0, 0, 0, .7)', 23 | paddingTop: '4rem', 24 | paddingBottom: '4rem' 25 | }), 26 | pre: cxs({ 27 | backgroundColor: 'rgba(0, 0, 0, .7)', 28 | color: '#e8fdf5', 29 | padding: '1rem', 30 | overflow: 'auto', 31 | whiteSpace: 'pre' 32 | }) 33 | } 34 | 35 | module.exports.SectionCx = { 36 | wrap: cxs({ 37 | marginLeft: 'auto', 38 | marginRight: 'auto', 39 | marginTop: '4rem', 40 | marginBottom: '4rem', 41 | maxWidth: '96rem', 42 | overflow: 'auto', 43 | '@media screen and (min-width: 40em)': { 44 | display: 'flex', 45 | alignItems: 'center' 46 | } 47 | }), 48 | h3: cxs({ 49 | textTransform: 'uppercase', 50 | borderBottom: 'thin solid #444', 51 | fontSize: '.875rem' 52 | }) 53 | } 54 | 55 | module.exports.CodeSectionCx = { 56 | pre: cxs({ 57 | '@media screen and (min-width: 40em)': { 58 | width: '50%' 59 | }, 60 | border: 'thin solid #fafafa', 61 | padding: '1rem', 62 | overflow: 'auto' 63 | }), 64 | code: cxs({ 65 | display: 'block', 66 | fontSize: '.875rem', 67 | padding: '1rem', 68 | lineHeight: '1.4' 69 | }) 70 | } 71 | 72 | module.exports.HtmlSectionCx = { 73 | wrap: cxs({ 74 | overflow: 'auto', 75 | '@media screen and (min-width: 40em)': { 76 | width: '50%' 77 | } 78 | }) 79 | } 80 | 81 | module.exports.ColorsCx = { 82 | td: cxs({ borderBottom: 'thin solid #fafafa' }), 83 | bg: cxs({ padding: '2rem' }), 84 | color: cxs({ 85 | fontSize: '1.25rem', 86 | fontWeight: 'bold', 87 | paddingLeft: '2rem', 88 | paddingRight: '2rem' 89 | }), 90 | colorTile: cxs({ 91 | width: '100%', 92 | padding: '2rem', 93 | '@media screen and (min-width: 40em)': { 94 | width: '50%' 95 | }, 96 | '@media screen and (min-width: 60em)': { 97 | width: '25%' 98 | }, 99 | }) 100 | } 101 | 102 | module.exports.ButtonCx = { 103 | button: cxs({ 104 | color: '#444', 105 | backgroundColor: '#fff', 106 | padding: '1rem', 107 | border: 'thin solid #444', 108 | transition: 'background-color .15s ease-in-out', 109 | margin: '1rem', 110 | textDecoration: 'none', 111 | ':hover': { 112 | color: '#fff', 113 | backgroundColor: '#444' 114 | } 115 | }) 116 | } 117 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "typeScale": [ 3 | 3, 2.25, 1.5, 1.25, 1, 0.875, 0.75 4 | ], 5 | "lineHeight": [1, 1.25, 1.5], 6 | "spacing": [.25, .5, 1, 2, 4, 8, 16], 7 | "customMedia": [ 8 | { "m": 48 }, 9 | { "l": 64 } 10 | ], 11 | "colors": { 12 | "black": "#000", 13 | "near-black": "#111", 14 | "dark-gray": "#333", 15 | "mid-gray": "#555", 16 | "gray": "#777", 17 | "silver": "#999", 18 | "light-silver": "#aaa", 19 | "moon-gray": "#ccc", 20 | "light-gray": "#eee", 21 | "near-white": "#f4f4f4", 22 | "white": "#fff", 23 | 24 | "black-90": "rgba(0,0,0,.9)", 25 | "black-80": "rgba(0,0,0,.8)", 26 | "black-70": "rgba(0,0,0,.7)", 27 | "black-60": "rgba(0,0,0,.6)", 28 | "black-50": "rgba(0,0,0,.5)", 29 | "black-40": "rgba(0,0,0,.4)", 30 | "black-30": "rgba(0,0,0,.3)", 31 | "black-20": "rgba(0,0,0,.2)", 32 | "black-10": "rgba(0,0,0,.1)", 33 | "black-05": "rgba(0,0,0,.05)", 34 | "black-025": "rgba(0,0,0,.025)", 35 | "black-0125": "rgba(0,0,0,.0125)", 36 | 37 | "white-90": "rgba(255,255,255,.9)", 38 | "white-80": "rgba(255,255,255,.8)", 39 | "white-70": "rgba(255,255,255,.7)", 40 | "white-60": "rgba(255,255,255,.6)", 41 | "white-50": "rgba(255,255,255,.5)", 42 | "white-40": "rgba(255,255,255,.4)", 43 | "white-30": "rgba(255,255,255,.3)", 44 | "white-20": "rgba(255,255,255,.2)", 45 | "white-10": "rgba(255,255,255,.1)", 46 | "white-05": "rgba(255,255,255,.05)", 47 | "white-025": "rgba(255,255,255,.025)", 48 | "white-0125": "rgba(255,255,255,.0125)", 49 | 50 | "dark-red": "#f00008", 51 | "red": "#ff3223", 52 | "light-red": "#ffd3c0", 53 | "orange": "#f3a801", 54 | "gold": "#f2c800", 55 | "yellow": "#ffde37", 56 | "light-yellow": "#f3dd70", 57 | "purple": "#7d5da9", 58 | "light-purple": "#8d4f92", 59 | "dark-pink": "#c64774", 60 | "hot-pink": "#d62288", 61 | "pink": "#f49cc8", 62 | "light-pink": "#efa4b8", 63 | "dark-green": "#006C71", 64 | "green": "#41D69F", 65 | "light-green": "#9eebcf", 66 | "navy": "#001b44", 67 | "dark-blue": "#00449e", 68 | "blue": "#357edd", 69 | "light-blue": "#96ccff", 70 | "lightest-blue": "#cdecff", 71 | "washed-blue": "#f6fffe", 72 | "washed-green": "#e8fdf5", 73 | "washed-yellow": "#fff8d5", 74 | "washed-red": "#ffdfdf", 75 | }, 76 | "nested": { 77 | "links": ["blue", "light-blue"] 78 | }, 79 | "borderWidths": [0, .125, .25, .5, 1, 2], 80 | "borderRadius": [0, .125, .25, .5, 1], 81 | "widths": [1, 2, 4, 8, 16], 82 | "maxWidths": [1, 2, 4, 8, 16, 32, 48, 64, 96], 83 | "heights": [1, 2, 4, 8, 16], 84 | "tables": { 85 | "striped": ["light-silver", "moon-gray", "light-gray", "near-white"], 86 | "stripe": ["light", "dark"] 87 | }, 88 | "typography":{ 89 | "measure": [30, 34, 20] 90 | }, 91 | "opacity": [1, .9, .8, .7, .6, .5, .4, .3, .2, .1, .05, .025, 0] 92 | } 93 | -------------------------------------------------------------------------------- /app/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import isPresent from 'is-present' 4 | import commaSplit from 'comma-split' 5 | 6 | import conf from '../config' 7 | const config = conf() 8 | 9 | import Layout from '../components/layout' 10 | 11 | export default class extends React.Component { 12 | constructor () { 13 | super() 14 | this.state = { 15 | config 16 | } 17 | } 18 | 19 | handleTypeScale (e, i) { 20 | const { config } = this.state 21 | const { typeScale } = config 22 | typeScale[i] = e.target.value 23 | 24 | const newConfig = Object.assign({}, config, { typeScale }) 25 | this.setState({ config: newConfig }) 26 | } 27 | 28 | handleColorRemove (name, val) { 29 | const { config } = this.state 30 | const { colors } = config 31 | 32 | const newColors = colors.filter(color => { 33 | const n = Object.keys(color)[0] 34 | 35 | return n !== name 36 | }) 37 | 38 | const newConfig = Object.assign({}, config, { colors: newColors }) 39 | this.setState({ config: newConfig }) 40 | } 41 | 42 | handleColorAdd (name, val) { 43 | const { config } = this.state 44 | const { colors } = config 45 | 46 | const color = {} 47 | color[name] = val 48 | colors.push(color) 49 | 50 | const newConfig = Object.assign({}, config, { colors }) 51 | this.setState({ config: newConfig }) 52 | } 53 | 54 | render () { 55 | const { config } = this.state 56 | 57 | return ( 58 | 59 |

Tachyons Generator

60 |

Typography

61 | {config.typeScale.map((f, i) => ( 62 |
63 |

Heading {i + 1}

64 | this.handleTypeScale(e, i)} 67 | /> 68 |
69 | ))} 70 |

Colors

71 | 72 | 73 | {config.colors.map(color => { 74 | const name = Object.keys(color)[0] 75 | const value = color[name] 76 | 77 | return ( 78 | 79 | 84 | 90 | ) 91 | })} 92 | 93 |
80 | 81 | 82 | --{name}: {value}; 83 | this.handleColorRemove(name)} 88 | /> 89 |
94 |

Config

95 |
 96 |       
 97 |     )
 98 |   }
 99 | }
100 | 


--------------------------------------------------------------------------------
/test/snapshots/nested-test.js.md:
--------------------------------------------------------------------------------
  1 | # Snapshot report for `test/nested-test.js`
  2 | 
  3 | The actual snapshot is saved in `nested-test.js.snap`.
  4 | 
  5 | Generated by [AVA](https://ava.li).
  6 | 
  7 | ## nested links colors are generated when defined
  8 | 
  9 | > Snapshot 1
 10 | 
 11 |     `␊
 12 |     /*␊
 13 |     ␊
 14 |         NESTED␊
 15 |         Tachyons module for styling nested elements␊
 16 |         that are generated by a cms.␊
 17 |     ␊
 18 |     */␊
 19 |     ␊
 20 |     ␊
 21 |     .nested-copy-line-height p,␊
 22 |     .nested-copy-line-height ul,␊
 23 |     .nested-copy-line-height ol {␊
 24 |       line-height: 1.5;␊
 25 |     }␊
 26 |     ␊
 27 |     .nested-headline-line-height h1,␊
 28 |     .nested-headline-line-height h2,␊
 29 |     .nested-headline-line-height h3,␊
 30 |     .nested-headline-line-height h4,␊
 31 |     .nested-headline-line-height h5,␊
 32 |     .nested-headline-line-height h6 {␊
 33 |       line-height: 1.25;␊
 34 |     }␊
 35 |     ␊
 36 |     .nested-list-reset ul,␊
 37 |     .nested-list-reset ol {␊
 38 |       padding-left: 0;␊
 39 |       margin-left: 0;␊
 40 |       list-style-type: none;␊
 41 |     }␊
 42 |     ␊
 43 |     .nested-copy-indent p+p {␊
 44 |       text-indent: 1em;␊
 45 |       margin-top: 0;␊
 46 |       margin-bottom: 0;␊
 47 |     }␊
 48 |     ␊
 49 |     .nested-copy-separator p+p {␊
 50 |       margin-top: 1.5em;␊
 51 |     }␊
 52 |     ␊
 53 |     .nested-img img {␊
 54 |       width: 100%;␊
 55 |       max-width: 100%;␊
 56 |       display: block;␊
 57 |     }␊
 58 |     ␊
 59 |     .nested-links a {␊
 60 |       color: #357edd;␊
 61 |       transition: color .15s ease-in;␊
 62 |     }␊
 63 |     ␊
 64 |     .nested-links a:hover,␊
 65 |     .nested-links a:focus {␊
 66 |       color: #cdecff;␊
 67 |       transition: color .15s ease-in;␊
 68 |     }␊
 69 |     `
 70 | 
 71 | ## nested links colors fall back to default values when not defined
 72 | 
 73 | > Snapshot 1
 74 | 
 75 |     `␊
 76 |     /*␊
 77 |     ␊
 78 |         NESTED␊
 79 |         Tachyons module for styling nested elements␊
 80 |         that are generated by a cms.␊
 81 |     ␊
 82 |     */␊
 83 |     ␊
 84 |     ␊
 85 |     .nested-copy-line-height p,␊
 86 |     .nested-copy-line-height ul,␊
 87 |     .nested-copy-line-height ol {␊
 88 |       line-height: 1.5;␊
 89 |     }␊
 90 |     ␊
 91 |     .nested-headline-line-height h1,␊
 92 |     .nested-headline-line-height h2,␊
 93 |     .nested-headline-line-height h3,␊
 94 |     .nested-headline-line-height h4,␊
 95 |     .nested-headline-line-height h5,␊
 96 |     .nested-headline-line-height h6 {␊
 97 |       line-height: 1.25;␊
 98 |     }␊
 99 |     ␊
100 |     .nested-list-reset ul,␊
101 |     .nested-list-reset ol {␊
102 |       padding-left: 0;␊
103 |       margin-left: 0;␊
104 |       list-style-type: none;␊
105 |     }␊
106 |     ␊
107 |     .nested-copy-indent p+p {␊
108 |       text-indent: 1em;␊
109 |       margin-top: 0;␊
110 |       margin-bottom: 0;␊
111 |     }␊
112 |     ␊
113 |     .nested-copy-separator p+p {␊
114 |       margin-top: 1.5em;␊
115 |     }␊
116 |     ␊
117 |     .nested-img img {␊
118 |       width: 100%;␊
119 |       max-width: 100%;␊
120 |       display: block;␊
121 |     }␊
122 |     ␊
123 |     .nested-links a {␊
124 |       color: #357edd;␊
125 |       transition: color .15s ease-in;␊
126 |     }␊
127 |     ␊
128 |     .nested-links a:hover,␊
129 |     .nested-links a:focus {␊
130 |       color: #96ccff;␊
131 |       transition: color .15s ease-in;␊
132 |     }␊
133 |     `
134 | 


--------------------------------------------------------------------------------
/test/snapshots/media-query-test.js.md:
--------------------------------------------------------------------------------
  1 | # Snapshot report for `test/media-query-test.js`
  2 | 
  3 | The actual snapshot is saved in `media-query-test.js.snap`.
  4 | 
  5 | Generated by [AVA](https://ava.li).
  6 | 
  7 | ## handle greater than queries
  8 | 
  9 | > Snapshot 1
 10 | 
 11 |     `␊
 12 |     /*␊
 13 |     ␊
 14 |       BORDER WIDTHS␊
 15 |       Docs: http://tachyons.io/docs/themes/borders/␊
 16 |     ␊
 17 |       Base:␊
 18 |         bw = border-width␊
 19 |     ␊
 20 |       Modifiers:␊
 21 |         0 = 0 width border␊
 22 |         1 = 1st step in border-width scale␊
 23 |         2 = 2nd step in border-width scale␊
 24 |         3 = 3rd step in border-width scale␊
 25 |         4 = 4th step in border-width scale␊
 26 |         5 = 5th step in border-width scale␊
 27 |     ␊
 28 |      Media Query Extensions:␊
 29 |         -m  = 32em␊
 30 |         -l  = 64em␊
 31 |         @med  = 64em␊
 32 |         -xl  = 123em␊
 33 |         -ns  = 1234em␊
 34 |     ␊
 35 |     */␊
 36 |     .bw0 { border-width: 0rem; }␊
 37 |     .bw1 { border-width: 0.125rem; }␊
 38 |     .bw2 { border-width: 0.25rem; }␊
 39 |     .bw3 { border-width: 0.5rem; }␊
 40 |     .bw4 { border-width: 1rem; }␊
 41 |     .bw5 { border-width: 2rem; }␊
 42 |     ␊
 43 |         .bt-0 { border-top-width: 0; }␊
 44 |         .br-0 { border-right-width: 0; }␊
 45 |         .bb-0 { border-bottom-width: 0; }␊
 46 |         .bl-0 { border-left-width: 0; }␊
 47 |       ␊
 48 |     ␊
 49 |     					@media screen and (min-width: 32em) and (max-width: 64em) {␊
 50 |     						.bw0-m { border-width: 0rem; }␊
 51 |     .bw1-m { border-width: 0.125rem; }␊
 52 |     .bw2-m { border-width: 0.25rem; }␊
 53 |     .bw3-m { border-width: 0.5rem; }␊
 54 |     .bw4-m { border-width: 1rem; }␊
 55 |     .bw5-m { border-width: 2rem; }␊
 56 |     ␊
 57 |         .bt-0-m { border-top-width: 0; }␊
 58 |         .br-0-m { border-right-width: 0; }␊
 59 |         .bb-0-m { border-bottom-width: 0; }␊
 60 |         .bl-0-m { border-left-width: 0; }␊
 61 |     					}␊
 62 |     				␊
 63 |     ␊
 64 |     					@media screen and (min-width: 64em) {␊
 65 |     						.bw0-l { border-width: 0rem; }␊
 66 |     .bw1-l { border-width: 0.125rem; }␊
 67 |     .bw2-l { border-width: 0.25rem; }␊
 68 |     .bw3-l { border-width: 0.5rem; }␊
 69 |     .bw4-l { border-width: 1rem; }␊
 70 |     .bw5-l { border-width: 2rem; }␊
 71 |     ␊
 72 |         .bt-0-l { border-top-width: 0; }␊
 73 |         .br-0-l { border-right-width: 0; }␊
 74 |         .bb-0-l { border-bottom-width: 0; }␊
 75 |         .bl-0-l { border-left-width: 0; }␊
 76 |     					}␊
 77 |     				␊
 78 |     ␊
 79 |     					@media screen and (min-width: 64em) {␊
 80 |     						.med@bw0 { border-width: 0rem; }␊
 81 |     .med@bw1 { border-width: 0.125rem; }␊
 82 |     .med@bw2 { border-width: 0.25rem; }␊
 83 |     .med@bw3 { border-width: 0.5rem; }␊
 84 |     .med@bw4 { border-width: 1rem; }␊
 85 |     .med@bw5 { border-width: 2rem; }␊
 86 |     ␊
 87 |         .med@bt-0 { border-top-width: 0; }␊
 88 |         .med@br-0 { border-right-width: 0; }␊
 89 |         .med@bb-0 { border-bottom-width: 0; }␊
 90 |         .med@bl-0 { border-left-width: 0; }␊
 91 |     					}␊
 92 |     				␊
 93 |     ␊
 94 |     					@media screen and (min-width: 123em) {␊
 95 |     						.bw0-xl { border-width: 0rem; }␊
 96 |     .bw1-xl { border-width: 0.125rem; }␊
 97 |     .bw2-xl { border-width: 0.25rem; }␊
 98 |     .bw3-xl { border-width: 0.5rem; }␊
 99 |     .bw4-xl { border-width: 1rem; }␊
100 |     .bw5-xl { border-width: 2rem; }␊
101 |     ␊
102 |         .bt-0-xl { border-top-width: 0; }␊
103 |         .br-0-xl { border-right-width: 0; }␊
104 |         .bb-0-xl { border-bottom-width: 0; }␊
105 |         .bl-0-xl { border-left-width: 0; }␊
106 |     					}␊
107 |     				␊
108 |     ␊
109 |     					@media screen and (max-width: 1234em) {␊
110 |     						.bw0-ns { border-width: 0rem; }␊
111 |     .bw1-ns { border-width: 0.125rem; }␊
112 |     .bw2-ns { border-width: 0.25rem; }␊
113 |     .bw3-ns { border-width: 0.5rem; }␊
114 |     .bw4-ns { border-width: 1rem; }␊
115 |     .bw5-ns { border-width: 2rem; }␊
116 |     ␊
117 |         .bt-0-ns { border-top-width: 0; }␊
118 |         .br-0-ns { border-right-width: 0; }␊
119 |         .bb-0-ns { border-bottom-width: 0; }␊
120 |         .bl-0-ns { border-left-width: 0; }␊
121 |     					}␊
122 |     				`
123 | 


--------------------------------------------------------------------------------
/test/snapshots/palette-test.js.md:
--------------------------------------------------------------------------------
  1 | # Snapshot report for `test/palette-test.js`
  2 | 
  3 | The actual snapshot is saved in `palette-test.js.snap`.
  4 | 
  5 | Generated by [AVA](https://ava.li).
  6 | 
  7 | ## palette is generated for colors array when included in config
  8 | 
  9 | > Snapshot 1
 10 | 
 11 |     `:root {␊
 12 |       --black: #334242;␊
 13 |       --gray-1: #f8fafa;␊
 14 |       --gray-2: #ebeeee;␊
 15 |       --gray-3: #dce2e2;␊
 16 |       --gray-4: #ccd5d5;␊
 17 |       --gray-5: #bbc6c6;␊
 18 |       --gray-6: #a7b6b6;␊
 19 |       --gray-7: #91a3a3;␊
 20 |       --gray-8: #778d8d;␊
 21 |       --gray-9: #577171;␊
 22 |       --gray-10: #334242;␊
 23 |       --cyan-1: #e4f9f9;␊
 24 |       --cyan-2: #c5f3f3;␊
 25 |       --cyan-3: #a3ecec;␊
 26 |       --cyan-4: #7ae4e4;␊
 27 |       --cyan-5: #49dada;␊
 28 |       --cyan-6: #07cccc;␊
 29 |       --cyan-7: #06b9b9;␊
 30 |       --cyan-8: #06a2a2;␊
 31 |       --cyan-9: #058787;␊
 32 |       --cyan-10: #036161;␊
 33 |       --blue-1: #e6f0fa;␊
 34 |       --blue-2: #c9dff4;␊
 35 |       --blue-3: #a9cbed;␊
 36 |       --blue-4: #83b4e5;␊
 37 |       --blue-5: #5296db;␊
 38 |       --blue-6: #0769cc;␊
 39 |       --blue-7: #065fb8;␊
 40 |       --blue-8: #0653a0;␊
 41 |       --blue-9: #054484;␊
 42 |       --blue-10: #03305d;␊
 43 |       --indigo-1: #ebebfb;␊
 44 |       --indigo-2: #d5d5f6;␊
 45 |       --indigo-3: #bbbbf1;␊
 46 |       --indigo-4: #9b9bea;␊
 47 |       --indigo-5: #7070e2;␊
 48 |       --indigo-6: #0707cc;␊
 49 |       --indigo-7: #0606b8;␊
 50 |       --indigo-8: #0606a1;␊
 51 |       --indigo-9: #050585;␊
 52 |       --indigo-10: #03035f;␊
 53 |       --violet-1: #f2eafb;␊
 54 |       --violet-2: #e4d2f6;␊
 55 |       --violet-3: #d3b6f0;␊
 56 |       --violet-4: #bf95e9;␊
 57 |       --violet-5: #a367e0;␊
 58 |       --violet-6: #6907cc;␊
 59 |       --violet-7: #5f06b8;␊
 60 |       --violet-8: #5306a1;␊
 61 |       --violet-9: #440584;␊
 62 |       --violet-10: #30035e;␊
 63 |       --fuschia-1: #fbeafb;␊
 64 |       --fuschia-2: #f6d2f6;␊
 65 |       --fuschia-3: #f0b7f0;␊
 66 |       --fuschia-4: #e995e9;␊
 67 |       --fuschia-5: #e068e0;␊
 68 |       --fuschia-6: #cc07cc;␊
 69 |       --fuschia-7: #b906b9;␊
 70 |       --fuschia-8: #a206a2;␊
 71 |       --fuschia-9: #860586;␊
 72 |       --fuschia-10: #610361;␊
 73 |       --pink-1: #fbeaf2;␊
 74 |       --pink-2: #f6d2e4;␊
 75 |       --pink-3: #f0b7d4;␊
 76 |       --pink-4: #e995bf;␊
 77 |       --pink-5: #e068a4;␊
 78 |       --pink-6: #cc076a;␊
 79 |       --pink-7: #b80660;␊
 80 |       --pink-8: #a20654;␊
 81 |       --pink-9: #860546;␊
 82 |       --pink-10: #600332;␊
 83 |       --red-1: #fbeaea;␊
 84 |       --red-2: #f6d3d3;␊
 85 |       --red-3: #f0b8b8;␊
 86 |       --red-4: #ea9898;␊
 87 |       --red-5: #e16b6b;␊
 88 |       --red-6: #cc0707;␊
 89 |       --red-7: #b90606;␊
 90 |       --red-8: #a20606;␊
 91 |       --red-9: #860505;␊
 92 |       --red-10: #610303;␊
 93 |       --orange-1: #f9eee3;␊
 94 |       --orange-2: #f3dcc5;␊
 95 |       --orange-3: #ecc8a3;␊
 96 |       --orange-4: #e4b07b;␊
 97 |       --orange-5: #da924a;␊
 98 |       --orange-6: #cc6a07;␊
 99 |       --orange-7: #b86006;␊
100 |       --orange-8: #a15406;␊
101 |       --orange-9: #854505;␊
102 |       --orange-10: #5f3103;␊
103 |       --yellow-1: #f8f8df;␊
104 |       --yellow-2: #f1f1bc;␊
105 |       --yellow-3: #e9e996;␊
106 |       --yellow-4: #e1e16b;␊
107 |       --yellow-5: #d7d73c;␊
108 |       --yellow-6: #cccc07;␊
109 |       --yellow-7: #b9b906;␊
110 |       --yellow-8: #a2a206;␊
111 |       --yellow-9: #878705;␊
112 |       --yellow-10: #616103;␊
113 |       --lime-1: #edf9e1;␊
114 |       --lime-2: #d9f2c0;␊
115 |       --lime-3: #c3eb9b;␊
116 |       --lime-4: #aae272;␊
117 |       --lime-5: #8dd842;␊
118 |       --lime-6: #6acc07;␊
119 |       --lime-7: #60b906;␊
120 |       --lime-8: #54a206;␊
121 |       --lime-9: #468705;␊
122 |       --lime-10: #326103;␊
123 |       --green-1: #e5fae5;␊
124 |       --green-2: #c8f4c8;␊
125 |       --green-3: #a7eda7;␊
126 |       --green-4: #80e580;␊
127 |       --green-5: #4edb4e;␊
128 |       --green-6: #07cc07;␊
129 |       --green-7: #06b906;␊
130 |       --green-8: #06a206;␊
131 |       --green-9: #058705;␊
132 |       --green-10: #036103;␊
133 |       --teal-1: #e4f9ef;␊
134 |       --teal-2: #c6f3dd;␊
135 |       --teal-3: #a4ecc8;␊
136 |       --teal-4: #7ce4b0;␊
137 |       --teal-5: #4ada92;␊
138 |       --teal-6: #07cc6a;␊
139 |       --teal-7: #06b960;␊
140 |       --teal-8: #06a254;␊
141 |       --teal-9: #058746;␊
142 |       --teal-10: #036133;␊
143 |       --transparent: transparent;␊
144 |     }`
145 | 


--------------------------------------------------------------------------------
/partials/_normalize.css.js:
--------------------------------------------------------------------------------
  1 | module.exports = `
  2 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
  3 | 
  4 | 
  5 | 
  6 | 
  7 | 
  8 | html {
  9 |   line-height: 1.15; 
 10 |   -ms-text-size-adjust: 100%; 
 11 |   -webkit-text-size-adjust: 100%; 
 12 | }
 13 | 
 14 | 
 15 | 
 16 | 
 17 | 
 18 | body {
 19 |   margin: 0;
 20 | }
 21 | 
 22 | 
 23 | 
 24 | article,
 25 | aside,
 26 | footer,
 27 | header,
 28 | nav,
 29 | section {
 30 |   display: block;
 31 | }
 32 | 
 33 | 
 34 | 
 35 | h1 {
 36 |   font-size: 2em;
 37 |   margin: 0.67em 0;
 38 | }
 39 | 
 40 | 
 41 | 
 42 | 
 43 | 
 44 | figcaption,
 45 | figure,
 46 | main { 
 47 |   display: block;
 48 | }
 49 | 
 50 | 
 51 | 
 52 | figure {
 53 |   margin: 1em 40px;
 54 | }
 55 | 
 56 | 
 57 | 
 58 | hr {
 59 |   box-sizing: content-box; 
 60 |   height: 0; 
 61 |   overflow: visible; 
 62 | }
 63 | 
 64 | 
 65 | 
 66 | pre {
 67 |   font-family: monospace, monospace; 
 68 |   font-size: 1em; 
 69 | }
 70 | 
 71 | 
 72 | 
 73 | 
 74 | 
 75 | a {
 76 |   background-color: transparent; 
 77 |   -webkit-text-decoration-skip: objects; 
 78 | }
 79 | 
 80 | 
 81 | 
 82 | abbr[title] {
 83 |   border-bottom: none; 
 84 |   text-decoration: underline; 
 85 |   text-decoration: underline dotted; 
 86 | }
 87 | 
 88 | 
 89 | 
 90 | b,
 91 | strong {
 92 |   font-weight: inherit;
 93 | }
 94 | 
 95 | 
 96 | 
 97 | b,
 98 | strong {
 99 |   font-weight: bolder;
100 | }
101 | 
102 | 
103 | 
104 | code,
105 | kbd,
106 | samp {
107 |   font-family: monospace, monospace; 
108 |   font-size: 1em; 
109 | }
110 | 
111 | 
112 | 
113 | dfn {
114 |   font-style: italic;
115 | }
116 | 
117 | 
118 | 
119 | mark {
120 |   background-color: #ff0;
121 |   color: #000;
122 | }
123 | 
124 | 
125 | 
126 | small {
127 |   font-size: 80%;
128 | }
129 | 
130 | 
131 | 
132 | sub,
133 | sup {
134 |   font-size: 75%;
135 |   line-height: 0;
136 |   position: relative;
137 |   vertical-align: baseline;
138 | }
139 | 
140 | sub {
141 |   bottom: -0.25em;
142 | }
143 | 
144 | sup {
145 |   top: -0.5em;
146 | }
147 | 
148 | 
149 | 
150 | 
151 | 
152 | audio,
153 | video {
154 |   display: inline-block;
155 | }
156 | 
157 | 
158 | 
159 | audio:not([controls]) {
160 |   display: none;
161 |   height: 0;
162 | }
163 | 
164 | 
165 | 
166 | img {
167 |   border-style: none;
168 | }
169 | 
170 | 
171 | 
172 | svg:not(:root) {
173 |   overflow: hidden;
174 | }
175 | 
176 | 
177 | 
178 | 
179 | 
180 | button,
181 | input,
182 | optgroup,
183 | select,
184 | textarea {
185 |   font-family: sans-serif; 
186 |   font-size: 100%; 
187 |   line-height: 1.15; 
188 |   margin: 0; 
189 | }
190 | 
191 | 
192 | 
193 | button,
194 | input { 
195 |   overflow: visible;
196 | }
197 | 
198 | 
199 | 
200 | button,
201 | select { 
202 |   text-transform: none;
203 | }
204 | 
205 | 
206 | 
207 | button,
208 | html [type="button"], 
209 | [type="reset"],
210 | [type="submit"] {
211 |   -webkit-appearance: button; 
212 | }
213 | 
214 | 
215 | 
216 | button::-moz-focus-inner,
217 | [type="button"]::-moz-focus-inner,
218 | [type="reset"]::-moz-focus-inner,
219 | [type="submit"]::-moz-focus-inner {
220 |   border-style: none;
221 |   padding: 0;
222 | }
223 | 
224 | 
225 | 
226 | button:-moz-focusring,
227 | [type="button"]:-moz-focusring,
228 | [type="reset"]:-moz-focusring,
229 | [type="submit"]:-moz-focusring {
230 |   outline: 1px dotted ButtonText;
231 | }
232 | 
233 | 
234 | 
235 | fieldset {
236 |   padding: 0.35em 0.75em 0.625em;
237 | }
238 | 
239 | 
240 | 
241 | legend {
242 |   box-sizing: border-box; 
243 |   color: inherit; 
244 |   display: table; 
245 |   max-width: 100%; 
246 |   padding: 0; 
247 |   white-space: normal; 
248 | }
249 | 
250 | 
251 | 
252 | progress {
253 |   display: inline-block; 
254 |   vertical-align: baseline; 
255 | }
256 | 
257 | 
258 | 
259 | textarea {
260 |   overflow: auto;
261 | }
262 | 
263 | 
264 | 
265 | [type="checkbox"],
266 | [type="radio"] {
267 |   box-sizing: border-box; 
268 |   padding: 0; 
269 | }
270 | 
271 | 
272 | 
273 | [type="number"]::-webkit-inner-spin-button,
274 | [type="number"]::-webkit-outer-spin-button {
275 |   height: auto;
276 | }
277 | 
278 | 
279 | 
280 | [type="search"] {
281 |   -webkit-appearance: textfield; 
282 |   outline-offset: -2px; 
283 | }
284 | 
285 | 
286 | 
287 | [type="search"]::-webkit-search-cancel-button,
288 | [type="search"]::-webkit-search-decoration {
289 |   -webkit-appearance: none;
290 | }
291 | 
292 | 
293 | 
294 | ::-webkit-file-upload-button {
295 |   -webkit-appearance: button; 
296 |   font: inherit; 
297 | }
298 | 
299 | 
300 | 
301 | 
302 | 
303 | details, 
304 | menu {
305 |   display: block;
306 | }
307 | 
308 | 
309 | 
310 | summary {
311 |   display: list-item;
312 | }
313 | 
314 | 
315 | 
316 | 
317 | 
318 | canvas {
319 |   display: inline-block;
320 | }
321 | 
322 | 
323 | 
324 | template {
325 |   display: none;
326 | }
327 | 
328 | 
329 | 
330 | 
331 | 
332 | [hidden] {
333 |   display: none;
334 | }
335 | `


--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
  1 | # tachyons-generator [![Build Status](https://secure.travis-ci.org/tachyons-css/tachyons-generator.svg?branch=master)](https://travis-ci.org/tachyons-css/tachyons-generator) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard)
  2 | 
  3 | This repo is currently under active development.
  4 | It isn't currently ready for production, but we hope to have a beta out soon.
  5 | Pull requests and issues welcome!
  6 | If you'd like to lend a hand but don't know where to start please ping @johnotander :heart:.
  7 | 
  8 | Generate a custom Tachyons build with a json configuration.
  9 | Inspiration from [this tachyons issue](https://github.com/tachyons-css/tachyons/issues/224).
 10 | 
 11 | ## Installation
 12 | 
 13 | ```bash
 14 | npm i -S tachyons-generator
 15 | ```
 16 | 
 17 | Or, use a curl request to generate css and docs
 18 | 
 19 | ```sh
 20 | curl -X POST \
 21 |      -H "Content-Type: application/json" \
 22 |      -d '{"typeScale": [5,4,3,2,1,0.5] }' \
 23 |      https://tachyons.pub/api
 24 | ```
 25 | 
 26 | or post the config.json file
 27 | 
 28 | ```sh
 29 | curl -X POST \
 30 |      -H "Content-Type: application/json" \
 31 |      -d @config.json \
 32 |      https://tachyons.pub/api
 33 | ```
 34 | 
 35 | ## Usage
 36 | This will generate an index.html file with the generated style guide as well as a static css file.
 37 | 
 38 | ```javascript
 39 | const fs = require('fs')
 40 | 
 41 | const tachyonsGenerator = require('tachyons-generator')
 42 | const config = require('./config.json')
 43 | 
 44 | const generate = async () => {
 45 |   const tachy = tachyonsGenerator(config)
 46 | 
 47 |   const out = await tachy.generate()
 48 | 
 49 |   fs.writeFileSync('index.html', out.docs)
 50 |   fs.writeFileSync('tachyons.css', out.css)
 51 |   fs.writeFileSync('tachyons.min.css', out.min)
 52 | }
 53 | 
 54 | generate()
 55 | ```
 56 | 
 57 | #### Example config
 58 | 
 59 | ```js
 60 | {
 61 |   "typeScale": [
 62 |     3, 2.25, 1.5, 1.25, 1, 0.875
 63 |   ],
 64 |   "spacing": [.25, .5, 1, 2, 4, 8, 16],
 65 |   "lineHeight": [1, 1.25, 1.5],
 66 |   "customMedia": [
 67 |     { "m": 48 },
 68 |     { "l": 64 },
 69 |     { "xl": 128 }
 70 |   ],
 71 |   "colors": {
 72 |     "black": "#000",
 73 |     "near-black": "#111",
 74 |     "dark-gray": "#333",
 75 |     "mid-gray": "#555",
 76 |     "gray": "#777",
 77 |     "silver": "#999",
 78 |     "light-silver": "#aaa",
 79 |     "moon-gray": "#ccc",
 80 |     "light-gray": "#eee",
 81 |     "near-white": "#f4f4f4",
 82 |     "white": "#fff",
 83 |     "dark-red": "#f00008",
 84 |     "red": "#ff3223",
 85 |     "orange": "#f3a801",
 86 |     "gold": "#f2c800",
 87 |     "yellow": "#ffde37",
 88 |     "purple": "#7d5da9",
 89 |     "light-purple": "#8d4f92",
 90 |     "hot-pink": "#d62288",
 91 |     "dark-pink": "#c64774",
 92 |     "pink": "#f49cc8",
 93 |     "dark-green": "#006C71",
 94 |     "green": "#41D69F",
 95 |     "navy": "#001b44",
 96 |     "dark-blue": "#00449e",
 97 |     "blue": "#357edd",
 98 |     "light-blue": "#96ccff",
 99 |     "lightest-blue": "#cdecff",
100 |     "washed-blue": "#f6fffe",
101 |     "washed-green": "#e8fdf5",
102 |     "washed-yellow": "#fff8d5",
103 |     "light-pink": "#efa4b8",
104 |     "light-yellow": "#f3dd70",
105 |     "light-red": "#ffd3c0"
106 |   },
107 |   "nested": {
108 |     "links": ["blue", "light-blue"]
109 |   },
110 |   "borderWidths": [0, 0.125, 0.25, 0.5, 1, 2],
111 |   "borderRadius": [0, 0.125, 0.25, 0.5, 1],
112 |   "widths": [1, 2, 4, 8, 16],
113 |   "maxWidths": [1, 2, 4, 8, 16, 32, 48, 64, 96],
114 |   "heights": [1, 2, 4, 8, 16],
115 |   "tables": {
116 |     "striped": ["light-silver", "moon-gray", "light-gray", "near-white"],
117 |     "stripe": ["light", "dark"]
118 |   },
119 |   "typography":{
120 |     "measure": [30, 34, 20]
121 |   },
122 |   "opacity": [1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.05, 0.025, 0]
123 | }
124 | ```
125 | 
126 | You can also omit the partials you don't need with the key `skipModules`, for example if you don't want normalize.css in the bundle you can do:
127 | 
128 | ```js
129 | {
130 |   "skipModules": ["normalize"]
131 | }
132 | ```
133 | 
134 | #### Example npm commands
135 | You can automate the generation and publishing using something like this pattern
136 | ```
137 |   "start": "npm run build && npm run publish",
138 |   "build": "node index.js",
139 |   "publish": "curl -X POST -H 'Content-Type: application/json' -d @config.json  https://tachyons.pub/api"
140 | ```
141 | 
142 | 
143 | ## License
144 | 
145 | MIT
146 | 
147 | ## Contributing
148 | 
149 | 1. Fork it
150 | 2. Create your feature branch (`git checkout -b my-new-feature`)
151 | 3. Commit your changes (`git commit -am 'Add some feature'`)
152 | 4. Push to the branch (`git push origin my-new-feature`)
153 | 5. Create new Pull Request
154 | 
155 | ---
156 | 
157 | Crafted with <3 by John Otander ([@4lpine](https://twitter.com/4lpine)).
158 | 


--------------------------------------------------------------------------------
/partials/_debug.css.js:
--------------------------------------------------------------------------------
  1 | module.exports = `
  2 | body {        outline: 1px solid  #2980B9!important; }
  3 | article {     outline: 1px solid  #3498DB!important; }
  4 | nav {         outline: 1px solid  #0088C3!important; }
  5 | aside {       outline: 1px solid  #33A0CE!important; }
  6 | section {     outline: 1px solid  #66B8DA!important; }
  7 | header {      outline: 1px solid  #99CFE7!important; }
  8 | footer {      outline: 1px solid  #CCE7F3!important; }
  9 | h1 {          outline: 1px solid  #162544!important; }
 10 | h2 {          outline: 1px solid  #314E6E!important; }
 11 | h3 {          outline: 1px solid  #3E5E85!important; }
 12 | h4 {          outline: 1px solid  #449BAF!important; }
 13 | h5 {          outline: 1px solid  #C7D1CB!important; }
 14 | h6 {          outline: 1px solid  #4371D0!important; }
 15 | main {        outline: 1px solid  #2F4F90!important; }
 16 | address {     outline: 1px solid  #1A2C51!important; }
 17 | div {         outline: 1px solid  #036CDB!important; }
 18 | 
 19 | 
 20 | p {           outline: 1px solid  #AC050B!important; }
 21 | hr {          outline: 1px solid  #FF063F!important; }
 22 | pre {         outline: 1px solid  #850440!important; }
 23 | blockquote {  outline: 1px solid  #F1B8E7!important; }
 24 | ol {          outline: 1px solid  #FF050C!important; }
 25 | ul {          outline: 1px solid  #D90416!important; }
 26 | li {          outline: 1px solid  #D90416!important; }
 27 | dl {          outline: 1px solid  #FD3427!important; }
 28 | dt {          outline: 1px solid  #FF0043!important; }
 29 | dd {          outline: 1px solid  #E80174!important; }
 30 | figure {      outline: 1px solid  #FF00BB!important; }
 31 | figcaption {  outline: 1px solid  #BF0032!important; }
 32 | 
 33 | 
 34 | 
 35 | table {       outline: 1px solid  #00CC99!important; }
 36 | caption {     outline: 1px solid  #37FFC4!important; }
 37 | thead {       outline: 1px solid  #98DACA!important; }
 38 | tbody {       outline: 1px solid  #64A7A0!important; }
 39 | tfoot {       outline: 1px solid  #22746B!important; }
 40 | tr {          outline: 1px solid  #86C0B2!important; }
 41 | th {          outline: 1px solid  #A1E7D6!important; }
 42 | td {          outline: 1px solid  #3F5A54!important; }
 43 | col {         outline: 1px solid  #6C9A8F!important; }
 44 | colgroup {    outline: 1px solid  #6C9A9D!important; }
 45 | 
 46 | 
 47 | button {      outline: 1px solid  #DA8301!important; }
 48 | datalist {    outline: 1px solid  #C06000!important; }
 49 | fieldset {    outline: 1px solid  #D95100!important; }
 50 | form {        outline: 1px solid  #D23600!important; }
 51 | input {       outline: 1px solid  #FCA600!important; }
 52 | keygen {      outline: 1px solid  #B31E00!important; }
 53 | label {       outline: 1px solid  #EE8900!important; }
 54 | legend {      outline: 1px solid  #DE6D00!important; }
 55 | meter {       outline: 1px solid  #E8630C!important; }
 56 | optgroup {    outline: 1px solid  #B33600!important; }
 57 | option {      outline: 1px solid  #FF8A00!important; }
 58 | output {      outline: 1px solid  #FF9619!important; }
 59 | progress {    outline: 1px solid  #E57C00!important; }
 60 | select {      outline: 1px solid  #E26E0F!important; }
 61 | textarea {    outline: 1px solid  #CC5400!important; }
 62 | 
 63 | 
 64 | 
 65 | details {     outline: 1px solid  #33848F!important; }
 66 | summary {     outline: 1px solid  #60A1A6!important; }
 67 | command {     outline: 1px solid  #438DA1!important; }
 68 | menu {        outline: 1px solid  #449DA6!important; }
 69 | 
 70 | 
 71 | 
 72 | del {         outline: 1px solid  #BF0000!important; }
 73 | ins {         outline: 1px solid  #400000!important; }
 74 | 
 75 | 
 76 | 
 77 | img     {     outline: 1px solid #22746B!important; }
 78 | iframe  {     outline: 1px solid #64A7A0!important; }
 79 | embed   {     outline: 1px solid #98DACA!important; }
 80 | object  {     outline: 1px solid #00CC99!important; }
 81 | param   {     outline: 1px solid #37FFC4!important; }
 82 | video   {     outline: 1px solid #6EE866!important; }
 83 | audio   {     outline: 1px solid #027353!important; }
 84 | source  {     outline: 1px solid #012426!important; }
 85 | canvas  {     outline: 1px solid #A2F570!important; }
 86 | track   {     outline: 1px solid #59A600!important; }
 87 | map     {     outline: 1px solid #7BE500!important; }
 88 | area    {     outline: 1px solid #305900!important; }
 89 | 
 90 | 
 91 | 
 92 | a {           outline: 1px solid #FF62AB!important; }
 93 | em {          outline: 1px solid #800B41!important; }
 94 | strong {      outline: 1px solid #FF1583!important; }
 95 | i {           outline: 1px solid #803156!important; }
 96 | b {           outline: 1px solid #CC1169!important; }
 97 | u {           outline: 1px solid #FF0430!important; }
 98 | s {           outline: 1px solid #F805E3!important; }
 99 | small {       outline: 1px solid #D107B2!important; }
100 | abbr {        outline: 1px solid #4A0263!important; }
101 | q {           outline: 1px solid #240018!important; }
102 | cite {        outline: 1px solid #64003C!important; }
103 | dfn {         outline: 1px solid #B4005A!important; }
104 | sub {         outline: 1px solid #DBA0C8!important; }
105 | sup {         outline: 1px solid #CC0256!important; }
106 | time {        outline: 1px solid #D6606D!important; }
107 | code {        outline: 1px solid #E04251!important; }
108 | kbd {         outline: 1px solid #5E001F!important; }
109 | samp {        outline: 1px solid #9C0033!important; }
110 | var {         outline: 1px solid #D90047!important; }
111 | mark {        outline: 1px solid #FF0053!important; }
112 | bdi {         outline: 1px solid #BF3668!important; }
113 | bdo {         outline: 1px solid #6F1400!important; }
114 | ruby {        outline: 1px solid #FF7B93!important; }
115 | rt {          outline: 1px solid #FF2F54!important; }
116 | rp {          outline: 1px solid #803E49!important; }
117 | span {        outline: 1px solid #CC2643!important; }
118 | br {          outline: 1px solid #DB687D!important; }
119 | wbr {         outline: 1px solid #DB175B!important; }
120 | `


--------------------------------------------------------------------------------
/test/snapshots/border-test.js.md:
--------------------------------------------------------------------------------
  1 | # Snapshot report for `test/border-test.js`
  2 | 
  3 | The actual snapshot is saved in `border-test.js.snap`.
  4 | 
  5 | Generated by [AVA](https://ava.li).
  6 | 
  7 | ## border radii are generated for radii array when included in config
  8 | 
  9 | > Snapshot 1
 10 | 
 11 |     `␊
 12 |     /*␊
 13 |     ␊
 14 |       BORDER RADIUS␊
 15 |       Docs: http://tachyons.io/docs/themes/border-radius/␊
 16 |     ␊
 17 |       Base:␊
 18 |         br   = border-radius␊
 19 |     ␊
 20 |       Modifiers:␊
 21 |         0 = 0/none␊
 22 |         1 = 1st step in scale␊
 23 |         2 = 2nd step in scale␊
 24 |         3 = 3rd step in scale␊
 25 |         4 = 4th step in scale␊
 26 |     ␊
 27 |       Literal values:␊
 28 |         -100 = 100%␊
 29 |         -pill = 9999px␊
 30 |     ␊
 31 |       Media Query Extensions:␊
 32 |         -m  = 48em␊
 33 |         -l  = 64em␊
 34 |     ␊
 35 |     */␊
 36 |     .br0 { border-radius: 0rem; }␊
 37 |     .br1 { border-radius: 0.125rem; }␊
 38 |     .br2 { border-radius: 0.25rem; }␊
 39 |     .br3 { border-radius: 0.5rem; }␊
 40 |     .br4 { border-radius: 1rem; }␊
 41 |     .br-100 {     border-radius: 100%; }␊
 42 |     .br-pill {    border-radius: 9999px; }␊
 43 |     .br--bottom {␊
 44 |             border-top-left-radius: 0;␊
 45 |             border-top-right-radius: 0;␊
 46 |           }␊
 47 |     .br--top {␊
 48 |             border-bottom-left-radius: 0;␊
 49 |             border-bottom-right-radius: 0;␊
 50 |           }␊
 51 |     .br--right {␊
 52 |             border-top-left-radius: 0;␊
 53 |             border-bottom-left-radius: 0;␊
 54 |           }␊
 55 |     .br--left {␊
 56 |             border-top-right-radius: 0;␊
 57 |             border-bottom-right-radius: 0;␊
 58 |           }␊
 59 |     ␊
 60 |     					@media screen and (min-width: 48em) and (max-width: 64em) {␊
 61 |     						.br0-m { border-radius: 0rem; }␊
 62 |     .br1-m { border-radius: 0.125rem; }␊
 63 |     .br2-m { border-radius: 0.25rem; }␊
 64 |     .br3-m { border-radius: 0.5rem; }␊
 65 |     .br4-m { border-radius: 1rem; }␊
 66 |     .br-100-m {     border-radius: 100%; }␊
 67 |     .br-pill-m {    border-radius: 9999px; }␊
 68 |     .br--bottom-m {␊
 69 |             border-top-left-radius: 0;␊
 70 |             border-top-right-radius: 0;␊
 71 |           }␊
 72 |     .br--top-m {␊
 73 |             border-bottom-left-radius: 0;␊
 74 |             border-bottom-right-radius: 0;␊
 75 |           }␊
 76 |     .br--right-m {␊
 77 |             border-top-left-radius: 0;␊
 78 |             border-bottom-left-radius: 0;␊
 79 |           }␊
 80 |     .br--left-m {␊
 81 |             border-top-right-radius: 0;␊
 82 |             border-bottom-right-radius: 0;␊
 83 |           }␊
 84 |     					}␊
 85 |     				␊
 86 |     ␊
 87 |     					@media screen and (min-width: 64em) {␊
 88 |     						.br0-l { border-radius: 0rem; }␊
 89 |     .br1-l { border-radius: 0.125rem; }␊
 90 |     .br2-l { border-radius: 0.25rem; }␊
 91 |     .br3-l { border-radius: 0.5rem; }␊
 92 |     .br4-l { border-radius: 1rem; }␊
 93 |     .br-100-l {     border-radius: 100%; }␊
 94 |     .br-pill-l {    border-radius: 9999px; }␊
 95 |     .br--bottom-l {␊
 96 |             border-top-left-radius: 0;␊
 97 |             border-top-right-radius: 0;␊
 98 |           }␊
 99 |     .br--top-l {␊
100 |             border-bottom-left-radius: 0;␊
101 |             border-bottom-right-radius: 0;␊
102 |           }␊
103 |     .br--right-l {␊
104 |             border-top-left-radius: 0;␊
105 |             border-bottom-left-radius: 0;␊
106 |           }␊
107 |     .br--left-l {␊
108 |             border-top-right-radius: 0;␊
109 |             border-bottom-right-radius: 0;␊
110 |           }␊
111 |     					}␊
112 |     				`
113 | 
114 | ## border widths are generated for widths array when included in config
115 | 
116 | > Snapshot 1
117 | 
118 |     `␊
119 |     /*␊
120 |     ␊
121 |       BORDER WIDTHS␊
122 |       Docs: http://tachyons.io/docs/themes/borders/␊
123 |     ␊
124 |       Base:␊
125 |         bw = border-width␊
126 |     ␊
127 |       Modifiers:␊
128 |         0 = 0 width border␊
129 |         1 = 1st step in border-width scale␊
130 |         2 = 2nd step in border-width scale␊
131 |         3 = 3rd step in border-width scale␊
132 |         4 = 4th step in border-width scale␊
133 |         5 = 5th step in border-width scale␊
134 |     ␊
135 |      Media Query Extensions:␊
136 |         -m  = 48em␊
137 |         -l  = 64em␊
138 |     ␊
139 |     */␊
140 |     .bw0 { border-width: 0rem; }␊
141 |     .bw1 { border-width: 0.125rem; }␊
142 |     .bw2 { border-width: 0.25rem; }␊
143 |     .bw3 { border-width: 0.5rem; }␊
144 |     .bw4 { border-width: 1rem; }␊
145 |     .bw5 { border-width: 2rem; }␊
146 |     ␊
147 |         .bt-0 { border-top-width: 0; }␊
148 |         .br-0 { border-right-width: 0; }␊
149 |         .bb-0 { border-bottom-width: 0; }␊
150 |         .bl-0 { border-left-width: 0; }␊
151 |       ␊
152 |     ␊
153 |     					@media screen and (min-width: 48em) and (max-width: 64em) {␊
154 |     						.bw0-m { border-width: 0rem; }␊
155 |     .bw1-m { border-width: 0.125rem; }␊
156 |     .bw2-m { border-width: 0.25rem; }␊
157 |     .bw3-m { border-width: 0.5rem; }␊
158 |     .bw4-m { border-width: 1rem; }␊
159 |     .bw5-m { border-width: 2rem; }␊
160 |     ␊
161 |         .bt-0-m { border-top-width: 0; }␊
162 |         .br-0-m { border-right-width: 0; }␊
163 |         .bb-0-m { border-bottom-width: 0; }␊
164 |         .bl-0-m { border-left-width: 0; }␊
165 |     					}␊
166 |     				␊
167 |     ␊
168 |     					@media screen and (min-width: 64em) {␊
169 |     						.bw0-l { border-width: 0rem; }␊
170 |     .bw1-l { border-width: 0.125rem; }␊
171 |     .bw2-l { border-width: 0.25rem; }␊
172 |     .bw3-l { border-width: 0.5rem; }␊
173 |     .bw4-l { border-width: 1rem; }␊
174 |     .bw5-l { border-width: 2rem; }␊
175 |     ␊
176 |         .bt-0-l { border-top-width: 0; }␊
177 |         .br-0-l { border-right-width: 0; }␊
178 |         .bb-0-l { border-bottom-width: 0; }␊
179 |         .bl-0-l { border-left-width: 0; }␊
180 |     					}␊
181 |     				`
182 | 


--------------------------------------------------------------------------------