diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4c218a0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[{*.json,*.yml}] +indent_size = 2 +indent_style = space diff --git a/.gitattributes b/.gitattributes new file mode 100755 index 0000000..2125666 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..c353790 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +.sass-cache +bower_components diff --git a/.jshintrc b/.jshintrc new file mode 100755 index 0000000..eeafae8 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,22 @@ +{ + "boss": true, + "browser": true, + "curly": true, + "debug": true, + "devel": true, + "eqeqeq": true, + "expr": true, + "forin": true, + "immed": true, + "noarg": true, + "node": true, + "noempty": true, + "nonew": true, + "strict": true, + "trailing": true, + "undef": true, + "unused": true, + "predef": [ + "Prism" + ] +} \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100755 index 0000000..1dd5ba7 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,7 @@ +Copyright (c) 2014 Resource LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100755 index 0000000..434dee4 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +

+ +

+ +This is the [Fabricator](https://github.com/fbrctr/fabricator) instance used to build [http://fbrctr.github.io](http://fbrctr.github.io). + +## Development + +Checkout the `fabricator` branch: + +``` +$ git checkout fabricator +``` + +Start local dev server: + +``` +$ npm start +``` + +Build for release: + +``` +$ npm run build +``` + +Publish: + +``` +$ git subtree push --prefix dist origin master +``` diff --git a/assets/toolkit/styles/toolkit.css b/assets/toolkit/styles/toolkit.css deleted file mode 100755 index 5b3ae4b..0000000 --- a/assets/toolkit/styles/toolkit.css +++ /dev/null @@ -1 +0,0 @@ -code,pre{color:#333;text-align:left;white-space:pre;word-spacing:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;line-height:1.4;direction:ltr;cursor:text}pre{margin:1em 0;padding:1.2em;border-radius:3px}p code,li code,table code{margin:0;border-radius:3px;padding:.2em 0;font-size:85%}p code:before,p code:after,li code:before,li code:after,table code:before,table code:after{letter-spacing:-.2em;content:'\00a0'}code,:not(pre)>code,pre{background:#f7f7f7}:not(pre)>code{padding:.1em;border-radius:.3em}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#969896}.token.punctuation,.token.string,.token.atrule,.token.attr-value{color:#183691}.token.property,.token.tag{color:#63a35c}.token.boolean,.token.number{color:#0086b3}.token.selector,.token.attr-name,.token.attr-value .punctuation:first-child,.token.keyword,.token.regex,.token.important{color:#a71d5d}.token.operator,.token.entity,.token.url,.language-css .token.string{color:#a71d5d}.token.entity{cursor:help}.namespace{opacity:.7}html{box-sizing:border-box}*,*::after,*::before{box-sizing:inherit}.d-b{display:block!important}.d-i{display:inline!important}.d-ib{display:inline-block!important;max-width:100%}.d-tb{display:table!important}.d-tbc{display:table-cell!important}.d-tbr{display:table-row!important}.vh{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.fl-l{float:left!important}.fl-r{float:right!important}.fl-n{float:none!important}.cl-b{clear:both!important}.cl-n{clear:none!important}.cl-l{clear:left!important}.cl-r{clear:right!important}.cf:before,.cf:after{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.rwd-img{max-width:100%;height:auto}.rwd-img-st{width:100%;height:auto}.instrinsic{position:relative;padding-bottom:56.25%;height:0;text-align:center}.instrinsic div,.instrinsic embed,.instrinsic object,.instrinsic iframe{position:absolute!important;top:0;left:0;width:100%!important;height:100%!important}.pos-r{position:relative!important}.pos-s{position:static!important}.pos-a{position:absolute!important}.pos-f{position:fixed!important;-webkit-backface-visibility:hidden;backface-visibility:hidden}.mt-0{margin-top:0!important}.mt-xxs{margin-top:.14591em!important}.mt-xs{margin-top:.23608em!important}.mt-s{margin-top:.61805em!important}.mt{margin-top:1em!important}.mt-l{margin-top:1.618em!important}.mt-xl{margin-top:2.61792em!important}.mt-xxl{margin-top:4.2358em!important}.pt-0{padding-top:0!important}.pt-xxs{padding-top:.14591em!important}.pt-xs{padding-top:.23608em!important}.pt-s{padding-top:.61805em!important}.pt{padding-top:1em!important}.pt-l{padding-top:1.618em!important}.pt-xl{padding-top:2.61792em!important}.pt-xxl{padding-top:4.2358em!important}.mr-0{margin-right:0!important}.mr-xxs{margin-right:.14591em!important}.mr-xs{margin-right:.23608em!important}.mr-s{margin-right:.61805em!important}.mr{margin-right:1em!important}.mr-l{margin-right:1.618em!important}.mr-xl{margin-right:2.61792em!important}.mr-xxl{margin-right:4.2358em!important}.pr-0{padding-right:0!important}.pr-xxs{padding-right:.14591em!important}.pr-xs{padding-right:.23608em!important}.pr-s{padding-right:.61805em!important}.pr{padding-right:1em!important}.pr-l{padding-right:1.618em!important}.pr-xl{padding-right:2.61792em!important}.pr-xxl{padding-right:4.2358em!important}.mb-0{margin-bottom:0!important}.mb-xxs{margin-bottom:.14591em!important}.mb-xs{margin-bottom:.23608em!important}.mb-s{margin-bottom:.61805em!important}.mb{margin-bottom:1em!important}.mb-l{margin-bottom:1.618em!important}.mb-xl{margin-bottom:2.61792em!important}.mb-xxl{margin-bottom:4.2358em!important}.pb-0{padding-bottom:0!important}.pb-xxs{padding-bottom:.14591em!important}.pb-xs{padding-bottom:.23608em!important}.pb-s{padding-bottom:.61805em!important}.pb{padding-bottom:1em!important}.pb-l{padding-bottom:1.618em!important}.pb-xl{padding-bottom:2.61792em!important}.pb-xxl{padding-bottom:4.2358em!important}.ml-0{margin-left:0!important}.ml-xxs{margin-left:.14591em!important}.ml-xs{margin-left:.23608em!important}.ml-s{margin-left:.61805em!important}.ml{margin-left:1em!important}.ml-l{margin-left:1.618em!important}.ml-xl{margin-left:2.61792em!important}.ml-xxl{margin-left:4.2358em!important}.pl-0{padding-left:0!important}.pl-xxs{padding-left:.14591em!important}.pl-xs{padding-left:.23608em!important}.pl-s{padding-left:.61805em!important}.pl{padding-left:1em!important}.pl-l{padding-left:1.618em!important}.pl-xl{padding-left:2.61792em!important}.pl-xxl{padding-left:4.2358em!important}.ml-a{margin-left:auto}.mr-a{margin-right:auto}.ta-l{text-align:left!important}.ta-c{text-align:center!important}.ta-r{text-align:right!important}.ta-j{text-align:justify!important}.c-i{color:inherit!important}.kern{text-rendering:optimizeLegibility;-webkit-font-feature-settings:"kern" 1;-moz-font-feature-settings:"kern" 1;font-feature-settings:"kern" 1;-webkit-font-kerning:normal;-moz-font-kerning:normal;font-kerning:normal}.whs-nw,.truncate{white-space:nowrap!important}.truncate{max-width:100%;overflow:hidden!important;text-overflow:ellipsis!important;word-wrap:normal!important}.fw-l{font-weight:200!important}.fw-n{font-weight:400!important}.fw-b{font-weight:700!important}.fs-i{font-style:italic!important}.tt-u{text-transform:uppercase!important}.wfsm{-webkit-font-smoothing:antialiased}.va-t{vertical-align:top!important}.va-m{vertical-align:middle!important}.va-b{vertical-align:bottom!important}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.row{max-width:60rem;margin-left:auto;margin-right:auto;position:relative;padding-right:1em;padding-left:1em}.row::after{clear:both;content:"";display:table}.row--fluid{max-width:100%}.row--no-gutter{padding-left:0;padding-right:0}[class*=col-]{position:relative;float:left}.col-1{float:left;display:block;margin-right:4.34783%;width:100%}.col-1:last-child{margin-right:0}@media screen and (min-width:48rem){.col-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-1:last-child{margin-right:0}}.col-2{float:left;display:block;margin-right:4.34783%;width:100%}.col-2:last-child{margin-right:0}@media screen and (min-width:48rem){.col-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-2:last-child{margin-right:0}}.col-3{float:left;display:block;margin-right:4.34783%;width:100%}.col-3:last-child{margin-right:0}@media screen and (min-width:48rem){.col-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-3:last-child{margin-right:0}}.col-4{float:left;display:block;margin-right:4.34783%;width:100%}.col-4:last-child{margin-right:0}@media screen and (min-width:48rem){.col-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-4:last-child{margin-right:0}}.col-5{float:left;display:block;margin-right:4.34783%;width:100%}.col-5:last-child{margin-right:0}@media screen and (min-width:48rem){.col-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-5:last-child{margin-right:0}}.col-6{float:left;display:block;margin-right:4.34783%;width:100%}.col-6:last-child{margin-right:0}@media screen and (min-width:48rem){.col-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-6:last-child{margin-right:0}}.col-7{float:left;display:block;margin-right:4.34783%;width:100%}.col-7:last-child{margin-right:0}@media screen and (min-width:48rem){.col-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-7:last-child{margin-right:0}}.col-8{float:left;display:block;margin-right:4.34783%;width:100%}.col-8:last-child{margin-right:0}@media screen and (min-width:48rem){.col-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-8:last-child{margin-right:0}}.col-9{float:left;display:block;margin-right:4.34783%;width:100%}.col-9:last-child{margin-right:0}@media screen and (min-width:48rem){.col-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-9:last-child{margin-right:0}}.col-10{float:left;display:block;margin-right:4.34783%;width:100%}.col-10:last-child{margin-right:0}@media screen and (min-width:48rem){.col-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-10:last-child{margin-right:0}}.col-11{float:left;display:block;margin-right:4.34783%;width:100%}.col-11:last-child{margin-right:0}@media screen and (min-width:48rem){.col-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-11:last-child{margin-right:0}}.col-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-12:last-child{margin-right:0}@media screen and (min-width:48rem){.col-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-12:last-child{margin-right:0}}.col-s-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-s-1:last-child{margin-right:0}.col-s-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-s-2:last-child{margin-right:0}.col-s-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-s-3:last-child{margin-right:0}.col-s-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-s-4:last-child{margin-right:0}.col-s-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-s-5:last-child{margin-right:0}.col-s-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-s-6:last-child{margin-right:0}.col-s-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-s-7:last-child{margin-right:0}.col-s-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-s-8:last-child{margin-right:0}.col-s-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-s-9:last-child{margin-right:0}.col-s-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-s-10:last-child{margin-right:0}.col-s-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-s-11:last-child{margin-right:0}.col-s-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-s-12:last-child{margin-right:0}@media screen and (min-width:48rem){.col-m-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-m-1:last-child{margin-right:0}.col-m-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-m-2:last-child{margin-right:0}.col-m-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-m-3:last-child{margin-right:0}.col-m-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-m-4:last-child{margin-right:0}.col-m-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-m-5:last-child{margin-right:0}.col-m-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-m-6:last-child{margin-right:0}.col-m-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-m-7:last-child{margin-right:0}.col-m-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-m-8:last-child{margin-right:0}.col-m-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-m-9:last-child{margin-right:0}.col-m-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-m-10:last-child{margin-right:0}.col-m-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-m-11:last-child{margin-right:0}.col-m-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-m-12:last-child{margin-right:0}}@media screen and (min-width:66rem){.col-l-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-l-1:last-child{margin-right:0}.col-l-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-l-2:last-child{margin-right:0}.col-l-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-l-3:last-child{margin-right:0}.col-l-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-l-4:last-child{margin-right:0}.col-l-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-l-5:last-child{margin-right:0}.col-l-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-l-6:last-child{margin-right:0}.col-l-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-l-7:last-child{margin-right:0}.col-l-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-l-8:last-child{margin-right:0}.col-l-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-l-9:last-child{margin-right:0}.col-l-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-l-10:last-child{margin-right:0}.col-l-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-l-11:last-child{margin-right:0}.col-l-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-l-12:last-child{margin-right:0}}@media screen and (min-width:76rem){.col-xl-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-xl-1:last-child{margin-right:0}.col-xl-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-xl-2:last-child{margin-right:0}.col-xl-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-xl-3:last-child{margin-right:0}.col-xl-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-xl-4:last-child{margin-right:0}.col-xl-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-xl-5:last-child{margin-right:0}.col-xl-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-xl-6:last-child{margin-right:0}.col-xl-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-xl-7:last-child{margin-right:0}.col-xl-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-xl-8:last-child{margin-right:0}.col-xl-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-xl-9:last-child{margin-right:0}.col-xl-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-xl-10:last-child{margin-right:0}.col-xl-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-xl-11:last-child{margin-right:0}.col-xl-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-xl-12:last-child{margin-right:0}}.f-grid-preview [class^="col-"]{margin-bottom:ms(0);color:#1a1a1a;background-color:#d1d1dd;padding:ms(1)}.f-grid-preview [class^="col-"]+[class^="col-"]{border-left:0}img{max-width:100%}.side-menu{text-align:center}@media screen and (min-width:48rem){.side-menu{text-align:right}}html{font-size:16px;line-height:1.2}body{font-size:1rem;font-family:'Montserrat',sans-serif;color:#181830}a{color:inherit;text-decoration:none}a:hover{text-decoration:underline}a.nav-link:hover{color:#b72906}h1,h2{margin-top:3.5rem}h1,h2,h3,h4{color:#b72906;margin-bottom:1rem}h1>a,h2>a,h3>a,h4>a{display:block;cursor:pointer}h1,h3{letter-spacing:.13em;text-transform:uppercase}h3,h4{margin-top:2.5rem}p{line-height:1.6;margin-top:1.5em;margin-bottom:1.5em}p a{color:#b72906;text-decoration:underline}.section-title{letter-spacing:.13em;text-transform:uppercase;padding:.5rem 0}blockquote{box-shadow:inset .25rem 0 0 0 #9696b2;margin-left:0;padding-left:2rem;font-style:italic;color:#9696b2}.button{letter-spacing:.13em;background-color:#181830;border:0;color:#fff;padding:1em 3em;text-transform:uppercase;text-decoration:none;display:inline-block;font-size:1.3rem}.button:hover{text-decoration:underline}figure{width:100%;margin:0}figure>img{max-width:100%}.form-group{padding:1rem 0}.form-group label{color:#9696b2;display:block;font-size:.875rem}.form-control{padding:.75rem 0;display:block;margin-top:.5rem;width:100%;border:0;box-shadow:0 2px 0 0 #d1d1dd;color:#181830}.form-control:focus{box-shadow:0 3px 0 0 #e7ad00;outline:none}.footer{background-color:#7eede2;padding:2rem 1rem;text-align:center}.footer a{color:#181830}.footer p{margin:1rem 0}.stamp{height:4rem;max-width:10rem}.stamp use{fill:#181830}.header-bar{background-color:#181830;text-align:center;padding-top:.75rem;padding-bottom:.75rem}.header-bar__divider{margin:0 1rem;display:inline-block;vertical-align:middle}.header-bar__divider svg{width:2rem;height:2rem}.header-bar a{letter-spacing:.13em;color:#fff;text-decoration:none;text-transform:uppercase;vertical-align:middle}.header-bar a:hover{text-decoration:underline}.hero{background-color:#7eede2;text-align:center;padding:2rem 1rem 3rem}.hero>img{max-width:30rem;display:inline-block}.hero__byline{letter-spacing:.13em;text-transform:uppercase;position:relative;color:#181830;font-weight:700;margin:0}@media screen and (min-width:28rem){.hero__byline{top:-2rem;font-size:1.3rem}}.hero .button{margin-top:1.3rem}@media screen and (min-width:28rem){.hero .button{margin-top:0}}ul,ol{margin:1.2em 0}ul li,ol li{margin-bottom:1em}ul li:last-child,ol li:last-child{margin-bottom:0}.list-heading{letter-spacing:.13em;text-transform:uppercase;color:#b72906;font-weight:700;list-style-type:none;padding-bottom:.5em;display:block}.link-list{padding-left:0;list-style-type:none}.link-list li{margin-bottom:0}.link-list a{padding:.5em 0;text-decoration:none;display:block}.link-list a:hover{text-decoration:underline;color:#b72906}.piped-list{list-style-type:none;padding-left:0;margin:0}.piped-list li{display:inline-block;vertical-align:middle;margin-bottom:0}.piped-list li.pipe{margin:0 .5em}.piped-list li .bolt{width:1.5em;height:1.5em;display:inline-block;vertical-align:middle}.piped-list li .bolt use{fill:#e78100}.page-header{text-align:center;background-color:#7eede2;padding:1rem 0}.page-header>a{display:inline-block;max-width:5rem}.page-header>a img{width:100%}.bolt use{fill:#e7ad00}.bg-orange2{background-color:#e54600}.bg-orange2 a,.white{color:#fff} \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..fa4a22b --- /dev/null +++ b/bower.json @@ -0,0 +1,21 @@ +{ + "name": "fbrctr.github.io", + "version": "0.0.0", + "homepage": "https://github.com/fbrctr/fbrctr.github.io", + "authors": [ + "Luke Askew " + ], + "license": "MIT", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "devDependencies": { + "neat": "~1.7.2", + "css-utils": "~0.1.4" + } +} diff --git a/advanced/customization.html b/dist/advanced/customization.html similarity index 100% rename from advanced/customization.html rename to dist/advanced/customization.html diff --git a/advanced/error-handling.html b/dist/advanced/error-handling.html similarity index 100% rename from advanced/error-handling.html rename to dist/advanced/error-handling.html diff --git a/advanced/helpers.html b/dist/advanced/helpers.html similarity index 100% rename from advanced/helpers.html rename to dist/advanced/helpers.html diff --git a/advanced/preprocessors.html b/dist/advanced/preprocessors.html similarity index 100% rename from advanced/preprocessors.html rename to dist/advanced/preprocessors.html diff --git a/advanced/third-party.html b/dist/advanced/third-party.html similarity index 100% rename from advanced/third-party.html rename to dist/advanced/third-party.html diff --git a/assets/fabricator/scripts/f.js b/dist/assets/fabricator/scripts/f.js similarity index 57% rename from assets/fabricator/scripts/f.js rename to dist/assets/fabricator/scripts/f.js index 92eebaa..204a94b 100644 --- a/assets/fabricator/scripts/f.js +++ b/dist/assets/fabricator/scripts/f.js @@ -1 +1 @@ -self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof a?new a(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(p instanceof r)){c.lastIndex=0;var h=c.exec(p);if(h){g&&(f=h[1].length);var b=h.index-1+f,h=h[0].slice(f),v=h.length,y=b+v,w=p.slice(0,b+1),k=p.slice(y+1),S=[m,1];w&&S.push(w);var P=new r(o,u?t.tokenize(h,u):h,d);S.push(P),k&&S.push(k),Array.prototype.splice.apply(n,S)}}}}}return n},hooks:{all:{},add:function(e,a){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(a)},run:function(e,a){var r=t.hooks.all[e];if(r&&r.length)for(var n,i=0;n=r[i++];)n(a)}}},a=t.Token=function(e,t,a){this.type=e,this.content=t,this.alias=a};if(a.stringify=function(e,r,n){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return a.stringify(t,r,e)}).join("");var i={type:e.type,content:a.stringify(e.content,r,n),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:n};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var o="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,o)}t.hooks.run("wrap",i);var s="";for(var l in i.attributes)s+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var a=JSON.parse(e.data),r=a.language,n=a.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(n,t.languages[r])))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),Prism.languages.markup={comment://,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/i,inside:{tag:{pattern:/|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.+/,lookbehind:!0}],string:/("|')(\\\n|\\?.)*?\1/,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":{pattern:/[a-z0-9_]+\(/i,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,ignore:/&(lt|gt|amp);/i,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}}),Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/,lookbehind:!0},atrule:/@[\w-]+(?=\s+(\(|\{|;))/i,url:/([-a-z]+-)*url(?=\()/i,selector:/([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m}),Prism.languages.insertBefore("scss","atrule",{keyword:/@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i}),Prism.languages.insertBefore("scss","property",{variable:/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i}),Prism.languages.insertBefore("scss","function",{placeholder:/%[-_\w]+/i,statement:/\B!(default|optional)\b/i,"boolean":/\b(true|false)\b/,"null":/\b(null)\b/,operator:/\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/});var fabricator=window.fabricator={};fabricator.options={toggles:{labels:!0,notes:!0,code:!1},menu:!1,mq:"(min-width: 60em)"},fabricator.options.menu=window.matchMedia(fabricator.options.mq).matches,fabricator.test={},fabricator.test.sessionStorage=function(){var e="_f";try{return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(t){return!1}}(),fabricator.test.sessionStorage&&(sessionStorage.fabricator=sessionStorage.fabricator||JSON.stringify(fabricator.options)),fabricator.dom={root:document.querySelector("html"),primaryMenu:document.querySelector(".f-menu"),menuItems:document.querySelectorAll(".f-menu li a"),menuToggle:document.querySelector(".f-menu-toggle")},fabricator.getOptions=function(){return fabricator.test.sessionStorage?JSON.parse(sessionStorage.fabricator):fabricator.options},fabricator.buildColorChips=function(){for(var e,t=document.querySelectorAll(".f-color-chip"),a=t.length-1;a>=0;a--)e=t[a].querySelector(".f-color-chip__color").innerHTML,t[a].style.borderTopColor=e,t[a].style.borderBottomColor=e;return this},fabricator.setActiveItem=function(){var e=function(){for(var e,t,a=[],r=fabricator.dom.menuItems.length-1;r>=0;r--)fabricator.dom.menuItems[r].classList.remove("f-active"),t=fabricator.dom.menuItems[r].getAttribute("href"),e=t.indexOf("#")>-1?t.split("#").pop():t.split("/").pop().replace(/\.[^/.]+$/,""),a.push(e);return a.reverse()},t=function(){var t,a,r=window.location.href,n=e();t=r.indexOf("#")>-1?window.location.hash.replace("#",""):window.location.pathname.split("/").pop().replace(/\.[^/.]+$/,""),""===t&&(t="index"),a=n.indexOf(t)>-1?n.indexOf(t):0,fabricator.dom.menuItems[a].classList.add("f-active")};return window.addEventListener("hashchange",t),t(),this},fabricator.menuToggle=function(){var e=fabricator.dom.menuToggle,t=fabricator.getOptions(),a=function(){t.menu=!fabricator.dom.root.classList.contains("f-menu-active"),fabricator.dom.root.classList.toggle("f-menu-active"),fabricator.test.sessionStorage&&sessionStorage.setItem("fabricator",JSON.stringify(t))};e.addEventListener("click",function(){a()});for(var r=function(){window.matchMedia(fabricator.options.mq).matches||a()},n=0;n=0;a--)e[a].addEventListener("click",t.bind(this,e[a]))},fabricator.setInitialMenuState=function(){var e=document.querySelector("html"),t=window.matchMedia(fabricator.options.mq),a=function(t){t.matches&&fabricator.getOptions().menu?e.classList.add("f-menu-active"):e.classList.remove("f-menu-active")};return t.addListener(a),a(t),this},function(){fabricator.setInitialMenuState().menuToggle().allItemsToggles().singleItemToggle().buildColorChips().setActiveItem().bindCodeAutoSelect(),Prism.highlightAll()}(); \ No newline at end of file +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof a?new a(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(p instanceof r)){c.lastIndex=0;var h=c.exec(p);if(h){g&&(f=h[1].length);var b=h.index-1+f,h=h[0].slice(f),v=h.length,y=b+v,w=p.slice(0,b+1),k=p.slice(y+1),S=[m,1];w&&S.push(w);var P=new r(o,u?t.tokenize(h,u):h,d);S.push(P),k&&S.push(k),Array.prototype.splice.apply(n,S)}}}}}return n},hooks:{all:{},add:function(e,a){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(a)},run:function(e,a){var r=t.hooks.all[e];if(r&&r.length)for(var n,i=0;n=r[i++];)n(a)}}},a=t.Token=function(e,t,a){this.type=e,this.content=t,this.alias=a};if(a.stringify=function(e,r,n){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return a.stringify(t,r,e)}).join("");var i={type:e.type,content:a.stringify(e.content,r,n),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:n};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var o="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,o)}t.hooks.run("wrap",i);var s="";for(var l in i.attributes)s+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var a=JSON.parse(e.data),r=a.language,n=a.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(n,t.languages[r])))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),Prism.languages.markup={comment://,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/i,inside:{tag:{pattern:/|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.+/,lookbehind:!0}],string:/("|')(\\\n|\\?.)*?\1/,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":{pattern:/[a-z0-9_]+\(/i,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,ignore:/&(lt|gt|amp);/i,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}}),Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/,lookbehind:!0},atrule:/@[\w-]+(?=\s+(\(|\{|;))/i,url:/([-a-z]+-)*url(?=\()/i,selector:/([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m}),Prism.languages.insertBefore("scss","atrule",{keyword:/@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i}),Prism.languages.insertBefore("scss","property",{variable:/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i}),Prism.languages.insertBefore("scss","function",{placeholder:/%[-_\w]+/i,statement:/\B!(default|optional)\b/i,"boolean":/\b(true|false)\b/,"null":/\b(null)\b/,operator:/\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/});var fabricator=window.fabricator={};fabricator.options={toggles:{labels:!0,notes:!0,code:!1},menu:!1,mq:"(min-width: 60em)"},fabricator.options.menu=window.matchMedia(fabricator.options.mq).matches,fabricator.test={},fabricator.test.sessionStorage=function(){var e="_f";try{return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(t){return!1}}(),fabricator.test.sessionStorage&&(sessionStorage.fabricator=sessionStorage.fabricator||JSON.stringify(fabricator.options)),fabricator.dom={root:document.querySelector("html"),primaryMenu:document.querySelector(".f-menu"),menuItems:document.querySelectorAll(".f-menu li a"),menuToggle:document.querySelector(".f-menu-toggle")},fabricator.getOptions=function(){return fabricator.test.sessionStorage?JSON.parse(sessionStorage.fabricator):fabricator.options},fabricator.buildColorChips=function(){for(var e,t=document.querySelectorAll(".f-color-chip"),a=t.length-1;a>=0;a--)e=t[a].querySelector(".f-color-chip__color").innerHTML,t[a].style.borderTopColor=e,t[a].style.borderBottomColor=e;return this},fabricator.setActiveItem=function(){var e=function(){for(var e,t,a=[],r=fabricator.dom.menuItems.length-1;r>=0;r--)fabricator.dom.menuItems[r].classList.remove("f-active"),t=fabricator.dom.menuItems[r].getAttribute("href"),e=t.indexOf("#")>-1?t.split("#").pop():t.split("/").pop().replace(/\.[^\/.]+$/,""),a.push(e);return a.reverse()},t=function(){var t,a,r=window.location.href,n=e();t=r.indexOf("#")>-1?window.location.hash.replace("#",""):window.location.pathname.split("/").pop().replace(/\.[^\/.]+$/,""),""===t&&(t="index"),a=n.indexOf(t)>-1?n.indexOf(t):0,fabricator.dom.menuItems[a].classList.add("f-active")};return window.addEventListener("hashchange",t),t(),this},fabricator.menuToggle=function(){var e=fabricator.dom.menuToggle,t=fabricator.getOptions(),a=function(){t.menu=!fabricator.dom.root.classList.contains("f-menu-active"),fabricator.dom.root.classList.toggle("f-menu-active"),fabricator.test.sessionStorage&&sessionStorage.setItem("fabricator",JSON.stringify(t))};e.addEventListener("click",function(){a()});for(var r=function(){window.matchMedia(fabricator.options.mq).matches||a()},n=0;n=0;a--)e[a].addEventListener("click",t.bind(this,e[a]))},fabricator.setInitialMenuState=function(){var e=document.querySelector("html"),t=window.matchMedia(fabricator.options.mq),a=function(t){t.matches&&fabricator.getOptions().menu?e.classList.add("f-menu-active"):e.classList.remove("f-menu-active")};return t.addListener(a),a(t),this},function(){fabricator.setInitialMenuState().menuToggle().allItemsToggles().singleItemToggle().buildColorChips().setActiveItem().bindCodeAutoSelect(),Prism.highlightAll()}(); \ No newline at end of file diff --git a/assets/fabricator/styles/f.css b/dist/assets/fabricator/styles/f.css similarity index 100% rename from assets/fabricator/styles/f.css rename to dist/assets/fabricator/styles/f.css diff --git a/dist/assets/toolkit/images/alistapart.png b/dist/assets/toolkit/images/alistapart.png new file mode 100644 index 0000000..dcdcbdb Binary files /dev/null and b/dist/assets/toolkit/images/alistapart.png differ diff --git a/assets/toolkit/images/bolt.svg b/dist/assets/toolkit/images/bolt.svg similarity index 100% rename from assets/toolkit/images/bolt.svg rename to dist/assets/toolkit/images/bolt.svg diff --git a/assets/toolkit/images/fabricating-architecture.png b/dist/assets/toolkit/images/fabricating-architecture.png similarity index 100% rename from assets/toolkit/images/fabricating-architecture.png rename to dist/assets/toolkit/images/fabricating-architecture.png diff --git a/assets/toolkit/images/head-outline.svg b/dist/assets/toolkit/images/head-outline.svg similarity index 100% rename from assets/toolkit/images/head-outline.svg rename to dist/assets/toolkit/images/head-outline.svg diff --git a/assets/toolkit/images/head.svg b/dist/assets/toolkit/images/head.svg similarity index 100% rename from assets/toolkit/images/head.svg rename to dist/assets/toolkit/images/head.svg diff --git a/assets/toolkit/images/logo.svg b/dist/assets/toolkit/images/logo.svg similarity index 100% rename from assets/toolkit/images/logo.svg rename to dist/assets/toolkit/images/logo.svg diff --git a/assets/toolkit/images/masthead.png b/dist/assets/toolkit/images/masthead.png similarity index 100% rename from assets/toolkit/images/masthead.png rename to dist/assets/toolkit/images/masthead.png diff --git a/dist/assets/toolkit/images/net-magazine.png b/dist/assets/toolkit/images/net-magazine.png new file mode 100644 index 0000000..e5c356d Binary files /dev/null and b/dist/assets/toolkit/images/net-magazine.png differ diff --git a/dist/assets/toolkit/images/smashing-magazine.png b/dist/assets/toolkit/images/smashing-magazine.png new file mode 100644 index 0000000..61c719a Binary files /dev/null and b/dist/assets/toolkit/images/smashing-magazine.png differ diff --git a/assets/toolkit/images/social.png b/dist/assets/toolkit/images/social.png similarity index 100% rename from assets/toolkit/images/social.png rename to dist/assets/toolkit/images/social.png diff --git a/assets/toolkit/images/toggle-all.png b/dist/assets/toolkit/images/toggle-all.png similarity index 100% rename from assets/toolkit/images/toggle-all.png rename to dist/assets/toolkit/images/toggle-all.png diff --git a/assets/toolkit/images/toggle-single.png b/dist/assets/toolkit/images/toggle-single.png similarity index 100% rename from assets/toolkit/images/toggle-single.png rename to dist/assets/toolkit/images/toggle-single.png diff --git a/assets/toolkit/images/word-mark-outline.svg b/dist/assets/toolkit/images/word-mark-outline.svg similarity index 100% rename from assets/toolkit/images/word-mark-outline.svg rename to dist/assets/toolkit/images/word-mark-outline.svg diff --git a/assets/toolkit/scripts/toolkit.js b/dist/assets/toolkit/scripts/toolkit.js similarity index 81% rename from assets/toolkit/scripts/toolkit.js rename to dist/assets/toolkit/scripts/toolkit.js index 903204d..90692b7 100644 --- a/assets/toolkit/scripts/toolkit.js +++ b/dist/assets/toolkit/scripts/toolkit.js @@ -1 +1 @@ -self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(m instanceof a)){u.lastIndex=0;var h=u.exec(m);if(h){g&&(p=h[1].length);var y=h.index-1+p,h=h[0].slice(p),w=h.length,v=y+w,b=m.slice(0,y+1),k=m.slice(v+1),P=[d,1];b&&P.push(b);var x=new a(s,c?t.tokenize(h,c):h,f);P.push(x),k&&P.push(k),Array.prototype.splice.apply(r,P)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var s="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,s)}t.hooks.run("wrap",i);var l="";for(var o in i.attributes)l+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+l+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),Prism.languages.markup={comment://,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/i,inside:{tag:{pattern:/|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.+/,lookbehind:!0}],string:/("|')(\\\n|\\?.)*?\1/,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":{pattern:/[a-z0-9_]+\(/i,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,ignore:/&(lt|gt|amp);/i,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}}),Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/,lookbehind:!0},atrule:/@[\w-]+(?=\s+(\(|\{|;))/i,url:/([-a-z]+-)*url(?=\()/i,selector:/([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m}),Prism.languages.insertBefore("scss","atrule",{keyword:/@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i}),Prism.languages.insertBefore("scss","property",{variable:/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i}),Prism.languages.insertBefore("scss","function",{placeholder:/%[-_\w]+/i,statement:/\B!(default|optional)\b/i,"boolean":/\b(true|false)\b/,"null":/\b(null)\b/,operator:/\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/}),function e(t,n,a){function r(s,l){if(!n[s]){if(!t[s]){var o="function"==typeof require&&require;if(!l&&o)return o(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[s]={exports:{}};t[s][0].call(c.exports,function(e){var n=t[s][1][e];return r(n?n:e)},c,c.exports,e,t,n,a)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;se.length)break e;if(!(m instanceof a)){u.lastIndex=0;var h=u.exec(m);if(h){g&&(p=h[1].length);var y=h.index-1+p,h=h[0].slice(p),w=h.length,v=y+w,b=m.slice(0,y+1),k=m.slice(v+1),P=[d,1];b&&P.push(b);var x=new a(s,c?t.tokenize(h,c):h,f);P.push(x),k&&P.push(k),Array.prototype.splice.apply(r,P)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var s="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,s)}t.hooks.run("wrap",i);var l="";for(var o in i.attributes)l+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+l+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),Prism.languages.markup={comment://,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/i,inside:{tag:{pattern:/|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.+/,lookbehind:!0}],string:/("|')(\\\n|\\?.)*?\1/,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":{pattern:/[a-z0-9_]+\(/i,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,ignore:/&(lt|gt|amp);/i,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}}),Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/,lookbehind:!0},atrule:/@[\w-]+(?=\s+(\(|\{|;))/i,url:/([-a-z]+-)*url(?=\()/i,selector:/([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m}),Prism.languages.insertBefore("scss","atrule",{keyword:/@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i}),Prism.languages.insertBefore("scss","property",{variable:/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i}),Prism.languages.insertBefore("scss","function",{placeholder:/%[-_\w]+/i,statement:/\B!(default|optional)\b/i,"boolean":/\b(true|false)\b/,"null":/\b(null)\b/,operator:/\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/}),function e(t,n,a){function r(s,l){if(!n[s]){if(!t[s]){var o="function"==typeof require&&require;if(!l&&o)return o(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[s]={exports:{}};t[s][0].call(c.exports,function(e){var n=t[s][1][e];return r(n?n:e)},c,c.exports,e,t,n,a)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;scode,pre{background:#f7f7f7}:not(pre)>code{padding:.1em;border-radius:.3em}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#969896}.token.punctuation,.token.string,.token.atrule,.token.attr-value{color:#183691}.token.property,.token.tag{color:#63a35c}.token.boolean,.token.number{color:#0086b3}.token.selector,.token.attr-name,.token.attr-value .punctuation:first-child,.token.keyword,.token.regex,.token.important{color:#a71d5d}.token.operator,.token.entity,.token.url,.language-css .token.string{color:#a71d5d}.token.entity{cursor:help}.namespace{opacity:.7}html{box-sizing:border-box}*,*::after,*::before{box-sizing:inherit}.d-b{display:block!important}.d-i{display:inline!important}.d-ib{display:inline-block!important;max-width:100%}.d-tb{display:table!important}.d-tbc{display:table-cell!important}.d-tbr{display:table-row!important}.vh{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.fl-l{float:left!important}.fl-r{float:right!important}.fl-n{float:none!important}.cl-b{clear:both!important}.cl-n{clear:none!important}.cl-l{clear:left!important}.cl-r{clear:right!important}.cf:before,.cf:after{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.rwd-img{max-width:100%;height:auto}.rwd-img-st{width:100%;height:auto}.instrinsic{position:relative;padding-bottom:56.25%;height:0;text-align:center}.instrinsic div,.instrinsic embed,.instrinsic object,.instrinsic iframe{position:absolute!important;top:0;left:0;width:100%!important;height:100%!important}.pos-r{position:relative!important}.pos-s{position:static!important}.pos-a{position:absolute!important}.pos-f{position:fixed!important;-webkit-backface-visibility:hidden;backface-visibility:hidden}.mt-0{margin-top:0!important}.mt-xxs{margin-top:.14591em!important}.mt-xs{margin-top:.23608em!important}.mt-s{margin-top:.61805em!important}.mt{margin-top:1em!important}.mt-l{margin-top:1.618em!important}.mt-xl{margin-top:2.61792em!important}.mt-xxl{margin-top:4.2358em!important}.pt-0{padding-top:0!important}.pt-xxs{padding-top:.14591em!important}.pt-xs{padding-top:.23608em!important}.pt-s{padding-top:.61805em!important}.pt{padding-top:1em!important}.pt-l{padding-top:1.618em!important}.pt-xl{padding-top:2.61792em!important}.pt-xxl{padding-top:4.2358em!important}.mr-0{margin-right:0!important}.mr-xxs{margin-right:.14591em!important}.mr-xs{margin-right:.23608em!important}.mr-s{margin-right:.61805em!important}.mr{margin-right:1em!important}.mr-l{margin-right:1.618em!important}.mr-xl{margin-right:2.61792em!important}.mr-xxl{margin-right:4.2358em!important}.pr-0{padding-right:0!important}.pr-xxs{padding-right:.14591em!important}.pr-xs{padding-right:.23608em!important}.pr-s{padding-right:.61805em!important}.pr{padding-right:1em!important}.pr-l{padding-right:1.618em!important}.pr-xl{padding-right:2.61792em!important}.pr-xxl{padding-right:4.2358em!important}.mb-0{margin-bottom:0!important}.mb-xxs{margin-bottom:.14591em!important}.mb-xs{margin-bottom:.23608em!important}.mb-s{margin-bottom:.61805em!important}.mb{margin-bottom:1em!important}.mb-l{margin-bottom:1.618em!important}.mb-xl{margin-bottom:2.61792em!important}.mb-xxl{margin-bottom:4.2358em!important}.pb-0{padding-bottom:0!important}.pb-xxs{padding-bottom:.14591em!important}.pb-xs{padding-bottom:.23608em!important}.pb-s{padding-bottom:.61805em!important}.pb{padding-bottom:1em!important}.pb-l{padding-bottom:1.618em!important}.pb-xl{padding-bottom:2.61792em!important}.pb-xxl{padding-bottom:4.2358em!important}.ml-0{margin-left:0!important}.ml-xxs{margin-left:.14591em!important}.ml-xs{margin-left:.23608em!important}.ml-s{margin-left:.61805em!important}.ml{margin-left:1em!important}.ml-l{margin-left:1.618em!important}.ml-xl{margin-left:2.61792em!important}.ml-xxl{margin-left:4.2358em!important}.pl-0{padding-left:0!important}.pl-xxs{padding-left:.14591em!important}.pl-xs{padding-left:.23608em!important}.pl-s{padding-left:.61805em!important}.pl{padding-left:1em!important}.pl-l{padding-left:1.618em!important}.pl-xl{padding-left:2.61792em!important}.pl-xxl{padding-left:4.2358em!important}.ml-a{margin-left:auto}.mr-a{margin-right:auto}.ta-l{text-align:left!important}.ta-c{text-align:center!important}.ta-r{text-align:right!important}.ta-j{text-align:justify!important}.c-i{color:inherit!important}.kern{text-rendering:optimizeLegibility;-webkit-font-feature-settings:"kern" 1;-moz-font-feature-settings:"kern" 1;font-feature-settings:"kern" 1;-webkit-font-kerning:normal;-moz-font-kerning:normal;font-kerning:normal}.whs-nw,.truncate{white-space:nowrap!important}.truncate{max-width:100%;overflow:hidden!important;text-overflow:ellipsis!important;word-wrap:normal!important}.fw-l{font-weight:200!important}.fw-n{font-weight:400!important}.fw-b{font-weight:700!important}.fs-i{font-style:italic!important}.tt-u{text-transform:uppercase!important}.wfsm{-webkit-font-smoothing:antialiased}.va-t{vertical-align:top!important}.va-m{vertical-align:middle!important}.va-b{vertical-align:bottom!important}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.row{max-width:60rem;margin-left:auto;margin-right:auto;position:relative;padding-right:1em;padding-left:1em}.row::after{clear:both;content:"";display:table}.row--fluid{max-width:100%}.row--no-gutter{padding-left:0;padding-right:0}[class*=col-]{position:relative;float:left}.col-1{float:left;display:block;margin-right:4.34783%;width:100%}.col-1:last-child{margin-right:0}@media screen and (min-width:48rem){.col-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-1:last-child{margin-right:0}}.col-2{float:left;display:block;margin-right:4.34783%;width:100%}.col-2:last-child{margin-right:0}@media screen and (min-width:48rem){.col-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-2:last-child{margin-right:0}}.col-3{float:left;display:block;margin-right:4.34783%;width:100%}.col-3:last-child{margin-right:0}@media screen and (min-width:48rem){.col-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-3:last-child{margin-right:0}}.col-4{float:left;display:block;margin-right:4.34783%;width:100%}.col-4:last-child{margin-right:0}@media screen and (min-width:48rem){.col-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-4:last-child{margin-right:0}}.col-5{float:left;display:block;margin-right:4.34783%;width:100%}.col-5:last-child{margin-right:0}@media screen and (min-width:48rem){.col-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-5:last-child{margin-right:0}}.col-6{float:left;display:block;margin-right:4.34783%;width:100%}.col-6:last-child{margin-right:0}@media screen and (min-width:48rem){.col-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-6:last-child{margin-right:0}}.col-7{float:left;display:block;margin-right:4.34783%;width:100%}.col-7:last-child{margin-right:0}@media screen and (min-width:48rem){.col-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-7:last-child{margin-right:0}}.col-8{float:left;display:block;margin-right:4.34783%;width:100%}.col-8:last-child{margin-right:0}@media screen and (min-width:48rem){.col-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-8:last-child{margin-right:0}}.col-9{float:left;display:block;margin-right:4.34783%;width:100%}.col-9:last-child{margin-right:0}@media screen and (min-width:48rem){.col-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-9:last-child{margin-right:0}}.col-10{float:left;display:block;margin-right:4.34783%;width:100%}.col-10:last-child{margin-right:0}@media screen and (min-width:48rem){.col-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-10:last-child{margin-right:0}}.col-11{float:left;display:block;margin-right:4.34783%;width:100%}.col-11:last-child{margin-right:0}@media screen and (min-width:48rem){.col-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-11:last-child{margin-right:0}}.col-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-12:last-child{margin-right:0}@media screen and (min-width:48rem){.col-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-12:last-child{margin-right:0}}.col-s-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-s-1:last-child{margin-right:0}.col-s-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-s-2:last-child{margin-right:0}.col-s-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-s-3:last-child{margin-right:0}.col-s-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-s-4:last-child{margin-right:0}.col-s-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-s-5:last-child{margin-right:0}.col-s-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-s-6:last-child{margin-right:0}.col-s-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-s-7:last-child{margin-right:0}.col-s-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-s-8:last-child{margin-right:0}.col-s-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-s-9:last-child{margin-right:0}.col-s-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-s-10:last-child{margin-right:0}.col-s-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-s-11:last-child{margin-right:0}.col-s-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-s-12:last-child{margin-right:0}@media screen and (min-width:48rem){.col-m-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-m-1:last-child{margin-right:0}.col-m-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-m-2:last-child{margin-right:0}.col-m-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-m-3:last-child{margin-right:0}.col-m-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-m-4:last-child{margin-right:0}.col-m-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-m-5:last-child{margin-right:0}.col-m-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-m-6:last-child{margin-right:0}.col-m-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-m-7:last-child{margin-right:0}.col-m-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-m-8:last-child{margin-right:0}.col-m-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-m-9:last-child{margin-right:0}.col-m-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-m-10:last-child{margin-right:0}.col-m-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-m-11:last-child{margin-right:0}.col-m-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-m-12:last-child{margin-right:0}}@media screen and (min-width:66rem){.col-l-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-l-1:last-child{margin-right:0}.col-l-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-l-2:last-child{margin-right:0}.col-l-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-l-3:last-child{margin-right:0}.col-l-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-l-4:last-child{margin-right:0}.col-l-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-l-5:last-child{margin-right:0}.col-l-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-l-6:last-child{margin-right:0}.col-l-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-l-7:last-child{margin-right:0}.col-l-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-l-8:last-child{margin-right:0}.col-l-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-l-9:last-child{margin-right:0}.col-l-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-l-10:last-child{margin-right:0}.col-l-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-l-11:last-child{margin-right:0}.col-l-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-l-12:last-child{margin-right:0}}@media screen and (min-width:76rem){.col-xl-1{float:left;display:block;margin-right:4.34783%;width:4.34783%}.col-xl-1:last-child{margin-right:0}.col-xl-2{float:left;display:block;margin-right:4.34783%;width:13.04348%}.col-xl-2:last-child{margin-right:0}.col-xl-3{float:left;display:block;margin-right:4.34783%;width:21.73913%}.col-xl-3:last-child{margin-right:0}.col-xl-4{float:left;display:block;margin-right:4.34783%;width:30.43478%}.col-xl-4:last-child{margin-right:0}.col-xl-5{float:left;display:block;margin-right:4.34783%;width:39.13043%}.col-xl-5:last-child{margin-right:0}.col-xl-6{float:left;display:block;margin-right:4.34783%;width:47.82609%}.col-xl-6:last-child{margin-right:0}.col-xl-7{float:left;display:block;margin-right:4.34783%;width:56.52174%}.col-xl-7:last-child{margin-right:0}.col-xl-8{float:left;display:block;margin-right:4.34783%;width:65.21739%}.col-xl-8:last-child{margin-right:0}.col-xl-9{float:left;display:block;margin-right:4.34783%;width:73.91304%}.col-xl-9:last-child{margin-right:0}.col-xl-10{float:left;display:block;margin-right:4.34783%;width:82.6087%}.col-xl-10:last-child{margin-right:0}.col-xl-11{float:left;display:block;margin-right:4.34783%;width:91.30435%}.col-xl-11:last-child{margin-right:0}.col-xl-12{float:left;display:block;margin-right:4.34783%;width:100%}.col-xl-12:last-child{margin-right:0}}.f-grid-preview [class^="col-"]{margin-bottom:ms(0);color:#1a1a1a;background-color:#d1d1dd;padding:ms(1)}.f-grid-preview [class^="col-"]+[class^="col-"]{border-left:0}img{max-width:100%}.side-menu{text-align:center}@media screen and (min-width:48rem){.side-menu{text-align:right}}@media screen and (min-width:48rem){.feature-row{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}}.feature-row a{display:block;margin-left:auto;margin-right:auto;margin-bottom:2em;max-width:10em;opacity:.4}@media screen and (min-width:48rem){.feature-row a{width:33.33333%;max-width:100%;padding:0 5%;margin-bottom:0;margin-left:0;margin-right:0}}.feature-row a:last-child{margin-bottom:0}.feature-row a:not(:last-child){margin-top:1em}.feature-row a img{width:100%}html{font-size:16px;line-height:1.2}body{font-size:1rem;font-family:'Montserrat',sans-serif;color:#181830}a{color:inherit;text-decoration:none}a:hover{text-decoration:underline}a.nav-link:hover{color:#b72906}h1,h2{margin-top:3.5rem}h1,h2,h3,h4{color:#b72906;margin-bottom:1rem}h1>a,h2>a,h3>a,h4>a{display:block;cursor:pointer}h1,h3{letter-spacing:.13em;text-transform:uppercase}h3,h4{margin-top:2.5rem}p{line-height:1.6;margin-top:1.5em;margin-bottom:1.5em}p a{color:#b72906;text-decoration:underline}.section-title{letter-spacing:.13em;text-transform:uppercase;padding:.5rem 0}blockquote{box-shadow:inset .25rem 0 0 0 #9696b2;margin-left:0;padding-left:2rem;font-style:italic;color:#9696b2}.button{letter-spacing:.13em;background-color:#181830;border:0;color:#fff;padding:1em 3em;text-transform:uppercase;text-decoration:none;display:inline-block;font-size:1.3rem}.button:hover{text-decoration:underline}figure{width:100%;margin:0}figure>img{max-width:100%}.form-group{padding:1rem 0}.form-group label{color:#9696b2;display:block;font-size:.875rem}.form-control{padding:.75rem 0;display:block;margin-top:.5rem;width:100%;border:0;box-shadow:0 2px 0 0 #d1d1dd;color:#181830}.form-control:focus{box-shadow:0 3px 0 0 #e7ad00;outline:none}.footer{background-color:#7eede2;padding:2rem 1rem;text-align:center}.footer a{color:#181830}.footer p{margin:1rem 0}.stamp{height:4rem;max-width:10rem}.stamp use{fill:#181830}.header-bar{background-color:#181830;text-align:center;padding-top:.75rem;padding-bottom:.75rem}.header-bar__divider{margin:0 1rem;display:inline-block;vertical-align:middle}.header-bar__divider svg{width:2rem;height:2rem}.header-bar a{letter-spacing:.13em;color:#fff;text-decoration:none;text-transform:uppercase;vertical-align:middle}.header-bar a:hover{text-decoration:underline}.hero{background-color:#7eede2;text-align:center;padding:2rem 1rem 3rem}.hero>img{max-width:30rem;display:inline-block}.hero__byline{letter-spacing:.13em;text-transform:uppercase;position:relative;color:#181830;font-weight:700;margin:0}@media screen and (min-width:28rem){.hero__byline{top:-2rem;font-size:1.3rem}}.hero .button{margin-top:1.3rem}@media screen and (min-width:28rem){.hero .button{margin-top:0}}ul,ol{margin:1.2em 0}ul li,ol li{margin-bottom:1em}ul li:last-child,ol li:last-child{margin-bottom:0}.list-heading{letter-spacing:.13em;text-transform:uppercase;color:#b72906;font-weight:700;list-style-type:none;padding-bottom:.5em;display:block}.link-list{padding-left:0;list-style-type:none}.link-list li{margin-bottom:0}.link-list a{padding:.5em 0;text-decoration:none;display:block}.link-list a:hover{text-decoration:underline;color:#b72906}.piped-list{list-style-type:none;padding-left:0;margin:0}.piped-list li{display:inline-block;vertical-align:middle;margin-bottom:0}.piped-list li.pipe{margin:0 .5em}.piped-list li .bolt{width:1.5em;height:1.5em;display:inline-block;vertical-align:middle}.piped-list li .bolt use{fill:#e78100}.page-header{text-align:center;background-color:#7eede2;padding:1rem 0}.page-header>a{display:inline-block;max-width:5rem}.page-header>a img{width:100%}.bolt use{fill:#e7ad00}.bg-orange2{background-color:#e54600}.bg-orange2 a{color:#fff}.bg-grey1{background-color:#d1d1dd}.bg-grey1 a{color:#1a1a1a}.white{color:#fff} \ No newline at end of file diff --git a/building-a-toolkit/assets.html b/dist/building-a-toolkit/assets.html similarity index 98% rename from building-a-toolkit/assets.html rename to dist/building-a-toolkit/assets.html index 846658e..0768bfe 100644 --- a/building-a-toolkit/assets.html +++ b/dist/building-a-toolkit/assets.html @@ -104,7 +104,7 @@

Style guide vs toolkit

Website style guides have evolved over the years, first starting as an outreach of the tradition (print) branding style guides, and eventually maturing into interactive examples of how a brand should be look and feel on the web. See Starbucks, Yelp, Salesforce, Code For America, and Google's Material Design.

-

A toolkit is more focused on code - specifically the modularity of website interfaces. Toolkits break down websites into small, repeatable chunks, then use those chunks to build an infinite number of layouts. Twitter Bootstrap, Topcoat, and Zurb's Foundation are popular toolkits.

+

A toolkit is more focused on code - specifically the modularity of website interfaces. Toolkits break down websites into small, repeatable chunks, then use those chunks to build an infinite number of layouts. Bootstrap, Topcoat, and Zurb's Foundation are popular toolkits.

Both are great and can be extremely useful. Fabricator gives you a way to combine both concepts into one deliverable.

When you work with Fabricator, you develop a brand's look and feel on the web while also producing a code toolkit.

Next, learn how to use Fabricator.

diff --git a/getting-started/working-with-fabricator.html b/dist/getting-started/working-with-fabricator.html similarity index 100% rename from getting-started/working-with-fabricator.html rename to dist/getting-started/working-with-fabricator.html diff --git a/index.html b/dist/index.html similarity index 96% rename from index.html rename to dist/index.html index b807034..e562d0d 100644 --- a/index.html +++ b/dist/index.html @@ -87,6 +87,23 @@

Rapid Prototyping

+
+
+

Featured In

+
+ +
+

Quick Start

diff --git a/gulpfile.js b/gulpfile.js new file mode 100755 index 0000000..3aa150f --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,204 @@ +'use strict'; + +// modules +var assemble = require('fabricator-assemble'); +var browserify = require('browserify'); +var browserSync = require('browser-sync'); +var concat = require('gulp-concat'); +var csso = require('gulp-csso'); +var del = require('del'); +var gulp = require('gulp'); +var gutil = require('gulp-util'); +var gulpif = require('gulp-if'); +var imagemin = require('gulp-imagemin'); +var prefix = require('gulp-autoprefixer'); +var rename = require('gulp-rename'); +var reload = browserSync.reload; +var runSequence = require('run-sequence'); +var sass = require('gulp-sass'); +var source = require('vinyl-source-stream'); +var streamqueue = require('streamqueue'); +var streamify = require('gulp-streamify'); +var uglify = require('gulp-uglify'); + + +// configuration +var config = { + dev: gutil.env.dev, + src: { + scripts: { + fabricator: [ + 'src/assets/fabricator/scripts/prism.js', + 'src/assets/fabricator/scripts/fabricator.js' + ], + vendor: [ + 'src/assets/fabricator/scripts/prism.js' + ], + toolkit: './src/assets/toolkit/scripts/toolkit.js' + }, + styles: { + fabricator: 'src/assets/fabricator/styles/fabricator.scss', + toolkit: 'src/assets/toolkit/styles/toolkit.scss' + }, + images: 'src/assets/toolkit/images/**/*', + views: 'src/toolkit/views/*.html' + }, + dest: 'dist' +}; + + +// clean +gulp.task('clean', function (cb) { + del(['**'], { ignore: 'demo/**', cwd: config.dest }, cb); +}); + + +// styles +gulp.task('styles:fabricator', function () { + return gulp.src(config.src.styles.fabricator) + .pipe(sass({ + errLogToConsole: true + })) + .pipe(prefix('last 1 version')) + .pipe(gulpif(!config.dev, csso())) + .pipe(rename('f.css')) + .pipe(gulp.dest(config.dest + '/assets/fabricator/styles')) + .pipe(gulpif(config.dev, reload({stream:true}))); +}); + +gulp.task('styles:toolkit', function () { + return gulp.src(config.src.styles.toolkit) + .pipe(sass({ + errLogToConsole: true + })) + .pipe(prefix('last 1 version')) + .pipe(gulpif(!config.dev, csso())) + .pipe(gulp.dest(config.dest + '/assets/toolkit/styles')) + .pipe(gulpif(config.dev, reload({stream:true}))); +}); + +gulp.task('styles', ['styles:fabricator', 'styles:toolkit']); + + +// scripts +gulp.task('scripts:fabricator', function () { + return gulp.src(config.src.scripts.fabricator) + .pipe(concat('f.js')) + .pipe(gulpif(!config.dev, uglify())) + .pipe(gulp.dest(config.dest + '/assets/fabricator/scripts')); +}); + +gulp.task('scripts:toolkit', function() { + + var toolkit = function() { + return browserify(config.src.scripts.toolkit).bundle() + .on('error', function(error) { + gutil.log(gutil.colors.red(error)); + this.emit('end'); + }) + .pipe(source('toolkit.js')); + }; + + var vendor = function() { + return gulp.src(config.src.scripts.vendor) + .pipe(concat('vendor.js')); + }; + + return streamqueue({ + objectMode: true + }, vendor(), toolkit()) + .pipe(streamify(concat('toolkit.js'))) + .pipe(gulpif(!config.dev, streamify(uglify()))) + .pipe(gulp.dest(config.dest + '/assets/toolkit/scripts')); + +}); + +gulp.task('scripts', ['scripts:fabricator', 'scripts:toolkit']); + + +// images +gulp.task('images', ['favicon'], function () { + return gulp.src(config.src.images) + .pipe(imagemin()) + .pipe(gulp.dest(config.dest + '/assets/toolkit/images')); +}); + +gulp.task('favicon', function () { + return gulp.src('./src/favicon.ico') + .pipe(gulp.dest(config.dest)); +}); + + +// assemble +gulp.task('assemble', function(done) { + assemble({ + helpers: { + markdown: function (str, opts) { + if (typeof str === 'object') { + opts = str; + str = null; + } + str = str || opts.fn(this); + return require('markdown-it')() + .use(require('markdown-it-headinganchor'), { + linkify: true, + anchorClass: '', + slugify: function(str) { + return require('string')(str).slugify().s; + } + }) + .render(str); + }, + decode: function (val) { + return decodeURIComponent(val); + }, + raw: function (options) { + return options.fn(); + } + } + }); + done(); +}); + + +// server +gulp.task('serve', function () { + + var reload = browserSync.reload; + + browserSync({ + server: { + baseDir: config.dest + }, + notify: false, + logPrefix: 'FABRICATOR' + }); + + gulp.watch('src/**/*.{html,md,json,yml}', ['assemble']).on('change', reload); + gulp.watch('src/assets/fabricator/styles/**/*.scss', ['styles:fabricator']); + gulp.watch('src/assets/toolkit/styles/**/*.scss', ['styles:toolkit']); + gulp.watch('src/assets/fabricator/scripts/**/*.js', ['scripts:fabricator']).on('change', reload); + gulp.watch('src/assets/toolkit/scripts/**/*.js', ['scripts:toolkit']).on('change', reload); + gulp.watch(config.src.images, ['images']).on('change', reload); +}); + + +// default build task +gulp.task('default', ['clean'], function () { + + // define build tasks + var tasks = [ + 'styles', + 'scripts', + 'images', + 'assemble' + ]; + + // run build + runSequence(tasks, function () { + if (config.dev) { + gulp.start('serve'); + } + }); + +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..d86bb6b --- /dev/null +++ b/package.json @@ -0,0 +1,47 @@ +{ + "name": "fabricator", + "version": "1.0.0", + "description": "A tool for building website UI toolkits", + "homepage": "http://fbrctr.github.io/", + "main": "README.md", + "scripts": { + "gulp": "gulp", + "bower": "bower", + "prestart": "npm install", + "build": "npm install && gulp", + "start": "gulp --dev", + "postinstall": "bower install", + "test": "npm run build" + }, + "repository": { + "type": "git", + "url": "https://github.com/fbrctr/fbrctr.github.io.git" + }, + "engines": { + "node": ">=0.10.0", + "npm": ">=2.0.0" + }, + "devDependencies": { + "browser-sync": "^2.5.3", + "browserify": "^9.0.7", + "del": "^1.1.1", + "fabricator-assemble": "^1.0.0", + "gulp": "^3.8.11", + "gulp-autoprefixer": "^2.1.0", + "gulp-concat": "^2.5.2", + "gulp-csso": "^1.0.0", + "gulp-if": "^1.2.5", + "gulp-imagemin": "^2.2.1", + "gulp-rename": "^1.2.2", + "gulp-sass": "^2.1.0", + "gulp-streamify": "0.0.5", + "gulp-uglify": "^1.1.0", + "gulp-util": "^3.0.4", + "markdown-it": "^4.1.0", + "markdown-it-headinganchor": "lukeaskew/markdown-it-headinganchor", + "run-sequence": "^1.0.2", + "streamqueue": "^0.1.3", + "string": "^3.3.0", + "vinyl-source-stream": "^1.1.0" + } +} diff --git a/recipes/bower.md b/recipes/bower.md new file mode 100755 index 0000000..9be2651 --- /dev/null +++ b/recipes/bower.md @@ -0,0 +1,28 @@ +# Using Bower for dependency managment + +[Bower](http://bower.io) is a great tool for managing third party client side dependencies. Here's how to leverage Bower on a Fabricator instance: + +1. Install bower `$ npm install bower --save-dev` +2. Add a `.bowerrc` config file (see below). +3. Update `package.json` `scripts` object to hook into Bower install task. +4. Refer to the [vendor script recipe](https://github.com/resource/fabricator/blob/master/recipes/vendor-scripts.md) for steps on including these scripts into your `toolkit.js` file. + +**.bowerrc** +```json +{ + "directory": "src/toolkit/assets/vendor" +} +``` + +**package.json** + +```json +"scripts": { + "gulp": "gulp", + "bower": "bower", + "prestart": "npm install", + "build": "npm install && gulp", + "postinstall": "bower install", + "start": "gulp --dev" +}, +``` diff --git a/recipes/vendor-scripts.md b/recipes/vendor-scripts.md new file mode 100755 index 0000000..ea3ff0d --- /dev/null +++ b/recipes/vendor-scripts.md @@ -0,0 +1,62 @@ +# Including vendor scripts + +Third party scripts like [jQuery](http://jquery.com) can be a helpful part of your toolkit. Here's how to modify the `gulpfile.js` to include these files: + +1. Install the [streamqueue](https://www.npmjs.com/package/streamqueue) package: `$ npm install streamqueue --save-dev` +2. Create a `config.src.vendor` array and include vendor file paths. +3. Break the `scripts:toolkit` task into two streams - `toolkit()` and `vendor()` - then merge streams using `streamqueue()`. + +```javascript +var browserify = require('browserify'); +var concat = require('gulp-concat'); +var gulp = require('gulp'); +var gulpif = require('gulp-if'); +var gutil = require('gulp-util'); +var source = require('vinyl-source-stream'); +var streamqueue = require('streamqueue'); +var streamify = require('gulp-streamify'); +var uglify = require('gulp-uglify'); + +var config = { + dev: gutil.env.dev, + src: { + scripts: { + fabricator: [ + 'src/fabricator/scripts/prism.js', + 'src/fabricator/scripts/fabricator.js' + ], + vendor: [ + 'src/toolkit/assets/vendor/jquery/dist/jquery.js' + ], + toolkit: './src/toolkit/assets/scripts/toolkit.js' + } + }, + dest: 'dist' +}; + +gulp.task('scripts:toolkit', function () { + + var toolkit = function () { + return browserify(config.src.scripts.toolkit).bundle() + .on('error', function (error) { + gutil.log(gutil.colors.red(error)); + this.emit('end'); + }) + .pipe(source('toolkit.js')); + }; + + var vendor = function () { + return gulp.src(config.src.scripts.vendor) + .pipe(concat('vendor.js')); + }; + + return streamqueue({ objectMode: true }, vendor(), toolkit()) + .pipe(streamify(concat('toolkit.js'))) + .pipe(gulpif(!config.dev, streamify(uglify()))) + .pipe(gulp.dest(config.dest + '/toolkit/scripts')); + +}); + +``` + +**Optional:** Check out the [Bower recipe](https://github.com/resource/fabricator/blob/master/recipes/bower.md) for info on using Bower as your client-side dependecny manager. diff --git a/src/assets/fabricator/scripts/fabricator.js b/src/assets/fabricator/scripts/fabricator.js new file mode 100644 index 0000000..b09c544 --- /dev/null +++ b/src/assets/fabricator/scripts/fabricator.js @@ -0,0 +1,378 @@ +'use strict'; + +/** + * Global `fabricator` object + * @namespace + */ +var fabricator = window.fabricator = {}; + + +/** + * Default options + * @type {Object} + */ +fabricator.options = { + toggles: { + labels: true, + notes: true, + code: false + }, + menu: false, + mq: '(min-width: 60em)' +}; + +// open menu by default if large screen +fabricator.options.menu = window.matchMedia(fabricator.options.mq).matches; + +/** + * Feature detection + * @type {Object} + */ +fabricator.test = {}; + +// test for sessionStorage +fabricator.test.sessionStorage = (function () { + var test = '_f'; + try { + sessionStorage.setItem(test, test); + sessionStorage.removeItem(test); + return true; + } catch(e) { + return false; + } +}()); + +// create storage object if it doesn't exist; store options +if (fabricator.test.sessionStorage) { + sessionStorage.fabricator = sessionStorage.fabricator || JSON.stringify(fabricator.options); +} + + +/** + * Cache DOM + * @type {Object} + */ +fabricator.dom = { + root: document.querySelector('html'), + primaryMenu: document.querySelector('.f-menu'), + menuItems: document.querySelectorAll('.f-menu li a'), + menuToggle: document.querySelector('.f-menu-toggle') +}; + + +/** + * Get current option values from session storage + * @return {Object} + */ +fabricator.getOptions = function () { + return (fabricator.test.sessionStorage) ? JSON.parse(sessionStorage.fabricator) : fabricator.options; +}; + + +/** + * Build color chips + */ +fabricator.buildColorChips = function () { + + var chips = document.querySelectorAll('.f-color-chip'), + color; + + for (var i = chips.length - 1; i >= 0; i--) { + color = chips[i].querySelector('.f-color-chip__color').innerHTML; + chips[i].style.borderTopColor = color; + chips[i].style.borderBottomColor = color; + } + + return this; + +}; + + +/** + * Add `f-active` class to active menu item + */ +fabricator.setActiveItem = function () { + + /** + * @return {Array} Sorted array of menu item 'ids' + */ + var parsedItems = function () { + + var items = [], + id, href; + + for (var i = fabricator.dom.menuItems.length - 1; i >= 0; i--) { + + // remove active class from items + fabricator.dom.menuItems[i].classList.remove('f-active'); + + // get item href + href = fabricator.dom.menuItems[i].getAttribute('href'); + + // get id + if (href.indexOf('#') > -1) { + id = href.split('#').pop(); + } else { + id = href.split('/').pop().replace(/\.[^/.]+$/, ''); + } + + items.push(id); + + } + + return items.reverse(); + + }; + + + /** + * Match the 'id' in the window location with the menu item, set menu item as active + */ + var setActive = function () { + + var href = window.location.href, + items = parsedItems(), + id, index; + + // get window 'id' + if (href.indexOf('#') > -1) { + id = window.location.hash.replace('#', ''); + } else { + id = window.location.pathname.split('/').pop().replace(/\.[^/.]+$/, ''); + } + + // In case the first menu item isn't the index page. + if (id === '') { + id = 'index'; + } + + // find the window id in the items array + index = (items.indexOf(id) > -1) ? items.indexOf(id) : 0; + + // set the matched item as active + fabricator.dom.menuItems[index].classList.add('f-active'); + + }; + + window.addEventListener('hashchange', setActive); + + setActive(); + + return this; + +}; + + +/** + * Click handler to primary menu toggle + * @return {Object} fabricator + */ +fabricator.menuToggle = function () { + + // shortcut menu DOM + var toggle = fabricator.dom.menuToggle; + + var options = fabricator.getOptions(); + + // toggle classes on certain elements + var toggleClasses = function () { + options.menu = !fabricator.dom.root.classList.contains('f-menu-active'); + fabricator.dom.root.classList.toggle('f-menu-active'); + + if (fabricator.test.sessionStorage) { + sessionStorage.setItem('fabricator', JSON.stringify(options)); + } + }; + + // toggle classes on click + toggle.addEventListener('click', function () { + toggleClasses(); + }); + + // close menu when clicking on item (for collapsed menu view) + var closeMenu = function () { + if (!window.matchMedia(fabricator.options.mq).matches) { + toggleClasses(); + } + }; + + for (var i = 0; i < fabricator.dom.menuItems.length; i++) { + fabricator.dom.menuItems[i].addEventListener('click', closeMenu); + } + + return this; + +}; + + +/** + * Handler for preview and code toggles + * @return {Object} fabricator + */ +fabricator.allItemsToggles = function () { + + var items = { + labels: document.querySelectorAll('[data-f-toggle="labels"]'), + notes: document.querySelectorAll('[data-f-toggle="notes"]'), + code: document.querySelectorAll('[data-f-toggle="code"]') + }; + + var toggleAllControls = document.querySelectorAll('.f-controls [data-f-toggle-control]'); + + var options = fabricator.getOptions(); + + // toggle all + var toggleAllItems = function (type, value) { + + var button = document.querySelector('.f-controls [data-f-toggle-control=' + type + ']'), + _items = items[type]; + + for (var i = 0; i < _items.length; i++) { + if (value) { + _items[i].classList.remove('f-item-hidden'); + } else { + _items[i].classList.add('f-item-hidden'); + } + } + + // toggle styles + if (value) { + button.classList.add('f-active'); + } else { + button.classList.remove('f-active'); + } + + // update options + options.toggles[type] = value; + + if (fabricator.test.sessionStorage) { + sessionStorage.setItem('fabricator', JSON.stringify(options)); + } + + }; + + for (var i = 0; i < toggleAllControls.length; i++) { + + toggleAllControls[i].addEventListener('click', function (e) { + + // extract info from target node + var type = e.currentTarget.getAttribute('data-f-toggle-control'), + value = e.currentTarget.className.indexOf('f-active') < 0; + + // toggle the items + toggleAllItems(type, value); + + }); + + } + + // persist toggle options from page to page + for (var toggle in options.toggles) { + if (options.toggles.hasOwnProperty(toggle)) { + toggleAllItems(toggle, options.toggles[toggle]); + } + } + + return this; + +}; + + +/** + * Handler for single item code toggling + */ +fabricator.singleItemToggle = function () { + + var itemToggleSingle = document.querySelectorAll('.f-item-group [data-f-toggle-control]'); + + // toggle single + var toggleSingleItemCode = function (e) { + var group = this.parentNode.parentNode.parentNode, + type = e.currentTarget.getAttribute('data-f-toggle-control'); + + group.querySelector('[data-f-toggle=' + type + ']').classList.toggle('f-item-hidden'); + }; + + for (var i = 0; i < itemToggleSingle.length; i++) { + itemToggleSingle[i].addEventListener('click', toggleSingleItemCode); + } + + return this; + +}; + + +/** + * Automatically select code when code block is clicked + */ +fabricator.bindCodeAutoSelect = function () { + + var codeBlocks = document.querySelectorAll('.f-item-code'); + + var select = function (block) { + var selection = window.getSelection(); + var range = document.createRange(); + range.selectNodeContents(block.querySelector('code')); + selection.removeAllRanges(); + selection.addRange(range); + }; + + for (var i = codeBlocks.length - 1; i >= 0; i--) { + codeBlocks[i].addEventListener('click', select.bind(this, codeBlocks[i])); + } + +}; + + +/** + * Open/Close menu based on session var. + * Also attach a media query listener to close the menu when resizing to smaller screen. + */ +fabricator.setInitialMenuState = function () { + + // root element + var root = document.querySelector('html'); + + var mq = window.matchMedia(fabricator.options.mq); + + // if small screen + var mediaChangeHandler = function (list) { + if (!list.matches) { + root.classList.remove('f-menu-active'); + } else { + if (fabricator.getOptions().menu) { + root.classList.add('f-menu-active'); + } else { + root.classList.remove('f-menu-active'); + } + } + }; + + mq.addListener(mediaChangeHandler); + mediaChangeHandler(mq); + + return this; + +}; + + +/** + * Initialization + */ +(function () { + + // invoke + fabricator + .setInitialMenuState() + .menuToggle() + .allItemsToggles() + .singleItemToggle() + .buildColorChips() + .setActiveItem() + .bindCodeAutoSelect(); + + + // syntax highlighting + Prism.highlightAll(); + +}()); diff --git a/src/assets/fabricator/scripts/prism.js b/src/assets/fabricator/scripts/prism.js new file mode 100644 index 0000000..06e6d0d --- /dev/null +++ b/src/assets/fabricator/scripts/prism.js @@ -0,0 +1,619 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+scss */ +self = (typeof window !== 'undefined') + ? window // if in browser + : ( + (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + ? self // if in worker + : {} // if in node js + ); + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * MIT license http://www.opensource.org/licenses/mit-license.php/ + * @author Lea Verou http://lea.verou.me + */ + +var Prism = (function(){ + +// Private helper vars +var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; + +var _ = self.Prism = { + util: { + encode: function (tokens) { + if (tokens instanceof Token) { + return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); + } else if (_.util.type(tokens) === 'Array') { + return tokens.map(_.util.encode); + } else { + return tokens.replace(/&/g, '&').replace(/ text.length) { + // Something went terribly wrong, ABORT, ABORT! + break tokenloop; + } + + if (str instanceof Token) { + continue; + } + + pattern.lastIndex = 0; + + var match = pattern.exec(str); + + if (match) { + if(lookbehind) { + lookbehindLength = match[1].length; + } + + var from = match.index - 1 + lookbehindLength, + match = match[0].slice(lookbehindLength), + len = match.length, + to = from + len, + before = str.slice(0, from + 1), + after = str.slice(to + 1); + + var args = [i, 1]; + + if (before) { + args.push(before); + } + + var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias); + + args.push(wrapped); + + if (after) { + args.push(after); + } + + Array.prototype.splice.apply(strarr, args); + } + } + } + } + + return strarr; + }, + + hooks: { + all: {}, + + add: function (name, callback) { + var hooks = _.hooks.all; + + hooks[name] = hooks[name] || []; + + hooks[name].push(callback); + }, + + run: function (name, env) { + var callbacks = _.hooks.all[name]; + + if (!callbacks || !callbacks.length) { + return; + } + + for (var i=0, callback; callback = callbacks[i++];) { + callback(env); + } + } + } +}; + +var Token = _.Token = function(type, content, alias) { + this.type = type; + this.content = content; + this.alias = alias; +}; + +Token.stringify = function(o, language, parent) { + if (typeof o == 'string') { + return o; + } + + if (_.util.type(o) === 'Array') { + return o.map(function(element) { + return Token.stringify(element, language, o); + }).join(''); + } + + var env = { + type: o.type, + content: Token.stringify(o.content, language, parent), + tag: 'span', + classes: ['token', o.type], + attributes: {}, + language: language, + parent: parent + }; + + if (env.type == 'comment') { + env.attributes['spellcheck'] = 'true'; + } + + if (o.alias) { + var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; + Array.prototype.push.apply(env.classes, aliases); + } + + _.hooks.run('wrap', env); + + var attributes = ''; + + for (var name in env.attributes) { + attributes += name + '="' + (env.attributes[name] || '') + '"'; + } + + return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + ''; + +}; + +if (!self.document) { + if (!self.addEventListener) { + // in Node.js + return self.Prism; + } + // In worker + self.addEventListener('message', function(evt) { + var message = JSON.parse(evt.data), + lang = message.language, + code = message.code; + + self.postMessage(JSON.stringify(_.util.encode(_.tokenize(code, _.languages[lang])))); + self.close(); + }, false); + + return self.Prism; +} + +// Get current script and highlight +var script = document.getElementsByTagName('script'); + +script = script[script.length - 1]; + +if (script) { + _.filename = script.src; + + if (document.addEventListener && !script.hasAttribute('data-manual')) { + document.addEventListener('DOMContentLoaded', _.highlightAll); + } +} + +return self.Prism; + +})(); + +if (typeof module !== 'undefined' && module.exports) { + module.exports = Prism; +} +; +Prism.languages.markup = { + 'comment': //, + 'prolog': /<\?.+?\?>/, + 'doctype': //, + 'cdata': //i, + 'tag': { + pattern: /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i, + inside: { + 'tag': { + pattern: /^<\/?[\w:-]+/i, + inside: { + 'punctuation': /^<\/?/, + 'namespace': /^[\w-]+?:/ + } + }, + 'attr-value': { + pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i, + inside: { + 'punctuation': /=|>|"/ + } + }, + 'punctuation': /\/?>/, + 'attr-name': { + pattern: /[\w:-]+/, + inside: { + 'namespace': /^[\w-]+?:/ + } + } + + } + }, + 'entity': /&#?[\da-z]{1,8};/i +}; + +// Plugin to make entity title show the real entity, idea by Roman Komarov +Prism.hooks.add('wrap', function(env) { + + if (env.type === 'entity') { + env.attributes['title'] = env.content.replace(/&/, '&'); + } +}); +; +Prism.languages.css = { + 'comment': /\/\*[\w\W]*?\*\//, + 'atrule': { + pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, + inside: { + 'punctuation': /[;:]/ + } + }, + 'url': /url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i, + 'selector': /[^\{\}\s][^\{\};]*(?=\s*\{)/, + 'string': /("|')(\\\n|\\?.)*?\1/, + 'property': /(\b|\B)[\w-]+(?=\s*:)/i, + 'important': /\B!important\b/i, + 'punctuation': /[\{\};:]/, + 'function': /[-a-z0-9]+(?=\()/i +}; + +if (Prism.languages.markup) { + Prism.languages.insertBefore('markup', 'tag', { + 'style': { + pattern: /[\w\W]*?<\/style>/i, + inside: { + 'tag': { + pattern: /|<\/style>/i, + inside: Prism.languages.markup.tag.inside + }, + rest: Prism.languages.css + }, + alias: 'language-css' + } + }); + + Prism.languages.insertBefore('inside', 'attr-value', { + 'style-attr': { + pattern: /\s*style=("|').*?\1/i, + inside: { + 'attr-name': { + pattern: /^\s*style/i, + inside: Prism.languages.markup.tag.inside + }, + 'punctuation': /^\s*=\s*['"]|['"]\s*$/, + 'attr-value': { + pattern: /.+/i, + inside: Prism.languages.css + } + }, + alias: 'language-css' + } + }, Prism.languages.markup.tag); +}; +Prism.languages.clike = { + 'comment': [ + { + pattern: /(^|[^\\])\/\*[\w\W]*?\*\//, + lookbehind: true + }, + { + pattern: /(^|[^\\:])\/\/.+/, + lookbehind: true + } + ], + 'string': /("|')(\\\n|\\?.)*?\1/, + 'class-name': { + pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, + lookbehind: true, + inside: { + punctuation: /(\.|\\)/ + } + }, + 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, + 'boolean': /\b(true|false)\b/, + 'function': { + pattern: /[a-z0-9_]+\(/i, + inside: { + punctuation: /\(/ + } + }, + 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/, + 'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/, + 'ignore': /&(lt|gt|amp);/i, + 'punctuation': /[{}[\];(),.:]/ +}; +; +Prism.languages.javascript = Prism.languages.extend('clike', { + 'keyword': /\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/, + 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/, + 'function': /(?!\d)[a-z0-9_$]+(?=\()/i +}); + +Prism.languages.insertBefore('javascript', 'keyword', { + 'regex': { + pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/, + lookbehind: true + } +}); + +if (Prism.languages.markup) { + Prism.languages.insertBefore('markup', 'tag', { + 'script': { + pattern: /[\w\W]*?<\/script>/i, + inside: { + 'tag': { + pattern: /|<\/script>/i, + inside: Prism.languages.markup.tag.inside + }, + rest: Prism.languages.javascript + }, + alias: 'language-javascript' + } + }); +} +; +Prism.languages.scss = Prism.languages.extend('css', { + 'comment': { + pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/, + lookbehind: true + }, + // aturle is just the @***, not the entire rule (to highlight var & stuffs) + // + add ability to highlight number & unit for media queries + 'atrule': /@[\w-]+(?=\s+(\(|\{|;))/i, + // url, compassified + 'url': /([-a-z]+-)*url(?=\()/i, + // CSS selector regex is not appropriate for Sass + // since there can be lot more things (var, @ directive, nesting..) + // a selector must start at the end of a property or after a brace (end of other rules or nesting) + // it can contain some caracters that aren't used for defining rules or end of selector, & (parent selector), or interpolated variable + // the end of a selector is found when there is no rules in it ( {} or {\s}) or if there is a property (because an interpolated var + // can "pass" as a selector- e.g: proper#{$erty}) + // this one was ard to do, so please be careful if you edit this one :) + 'selector': /([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m +}); + +Prism.languages.insertBefore('scss', 'atrule', { + 'keyword': /@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i +}); + +Prism.languages.insertBefore('scss', 'property', { + // var and interpolated vars + 'variable': /((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i +}); + +Prism.languages.insertBefore('scss', 'function', { + 'placeholder': /%[-_\w]+/i, + 'statement': /\B!(default|optional)\b/i, + 'boolean': /\b(true|false)\b/, + 'null': /\b(null)\b/, + 'operator': /\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/ +}); +; diff --git a/src/assets/fabricator/styles/fabricator.scss b/src/assets/fabricator/styles/fabricator.scss new file mode 100644 index 0000000..1e94675 --- /dev/null +++ b/src/assets/fabricator/styles/fabricator.scss @@ -0,0 +1,13 @@ +/** + * Fabricator styles + * @author Luke Askew + * Class selectors are namespaced with "f-" + */ + +@import 'partials/variables'; +@import 'partials/code'; +@import 'partials/color-chips'; +@import 'partials/controls'; +@import 'partials/item'; +@import 'partials/layout'; +@import 'partials/menu'; diff --git a/src/assets/fabricator/styles/partials/_code.scss b/src/assets/fabricator/styles/partials/_code.scss new file mode 100755 index 0000000..1032276 --- /dev/null +++ b/src/assets/fabricator/styles/partials/_code.scss @@ -0,0 +1,123 @@ +/** + * Github-like theme for Prism.js + * @author Luke Askew http://github.com/lukeaskew + */ + +// color vars +$code-colors: ( + blue: #183691, + teal: #0086b3, + black: #333, + purple: #a71d5d, + maroon: #a71d5d, + green: #63a35c, + light-gray: #f7f7f7, + dark-gray: #969896 +); + + +// base +code, +pre { + color: map-get($code-colors, black); + text-align: left; + white-space: pre; + word-spacing: normal; + tab-size: 4; + hyphens: none; + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + line-height: 1.4; + direction: ltr; + cursor: text; +} + +// code blocks +pre { + overflow: auto; + margin: 1em 0; + padding: 1.2em; + border-radius: 3px; + font-size: 85%; +} + +p code, +li code, +table code { + margin: 0; + border-radius: 3px; + padding: 0.2em 0; + font-size: 85%; + + &:before, + &:after { + letter-spacing: -0.2em; + content: '\00a0'; + } +} + +code, +:not(pre) > code, +pre { + background: map-get($code-colors, light-gray); +} + +// inline code +:not(pre) > code { + padding: 0.1em; + border-radius: 0.3em; +} + + +// token colors +.token { + + &.comment, + &.prolog, + &.doctype, + &.cdata { + color: map-get($code-colors, dark-gray); + } + + &.punctuation, + &.string, + &.atrule, + &.attr-value { + color: map-get($code-colors, blue); + } + + &.property, + &.tag { + color: map-get($code-colors, green); + } + + &.boolean, + &.number { + color: map-get($code-colors, teal); + } + + &.selector, + &.attr-name, + &.attr-value .punctuation:first-child, + &.keyword, + &.regex, + &.important { + color: map-get($code-colors, maroon); + } + + + &.operator, + &.entity, + &.url, + .language-css &.string { + color: map-get($code-colors, purple); + } + + &.entity { + cursor: help; + } + +} + +.namespace { + opacity: 0.7; +} diff --git a/src/assets/fabricator/styles/partials/_color-chips.scss b/src/assets/fabricator/styles/partials/_color-chips.scss new file mode 100644 index 0000000..06fff60 --- /dev/null +++ b/src/assets/fabricator/styles/partials/_color-chips.scss @@ -0,0 +1,29 @@ +.f-color-chips { + display: flex; + flex-wrap: wrap; +} + +.f-color-chip { + flex-grow: 1; + flex-shrink: 0; + flex-basis: 100%; + border-top-width: 8em; + border-top-style: solid; + border-bottom-width: 0; + border-bottom-style: solid; + background-color: #fff; + font-weight: 700; + font-size: 0.75em; + padding: 1em; + margin-bottom: 2em; + + @media (min-width: 60em) { + flex-basis: 13em; + } + + .f-color-chip__color { + background-color: #fff; + content: attr(data-color); + font-weight: 400; + } +} diff --git a/src/assets/fabricator/styles/partials/_controls.scss b/src/assets/fabricator/styles/partials/_controls.scss new file mode 100644 index 0000000..f95f75b --- /dev/null +++ b/src/assets/fabricator/styles/partials/_controls.scss @@ -0,0 +1,61 @@ +.f-controls { + @include clearfix; + @include border-box; + + .f-control { + display: block; + float: left; + text-align: center; + width: percentage(1/3); + margin: 0; + padding: 1rem 0; + + &.f-active { + box-shadow: inset 0 3px 0 0 map-get($colors, accent); + + use { + fill: map-get($colors, normal); + } + } + + svg { + vertical-align: middle; + } + } +} + +.f-control { + @include border-box; + display: inline-block; + cursor: pointer; + margin-left: 0.618rem; + + &:first-child { + margin-left: 0; + } + + svg { + width: 14px; + height: 14px; + + use { + fill: map-get($colors, light); + } + } +} + +.f-control-bar { + @include clearfix; + padding: 1rem 0; +} + +.f-menu-toggle { + cursor: pointer; + vertical-align: middle; + + svg { + display: block; + float: left; + margin-bottom: -1px; + } +} diff --git a/src/assets/fabricator/styles/partials/_item.scss b/src/assets/fabricator/styles/partials/_item.scss new file mode 100644 index 0000000..1d52b63 --- /dev/null +++ b/src/assets/fabricator/styles/partials/_item.scss @@ -0,0 +1,89 @@ +.f-item-group { + @include clearfix; + margin-top: 3rem; + margin-bottom: 3rem; + padding-bottom: 3rem; + border-bottom: 1px solid map-get($colors, light); + + &:last-child { + border-bottom: 0; + margin-bottom: 0; + } + + & ~ & { + margin-top: 0; + } + + & > & { + padding-bottom: 1.5rem; + margin-bottom: 1.5rem; + border-bottom: 0; + + &:first-of-type { + margin-top: 0; + } + + &:last-child { + margin-bottom: 0; + padding-bottom: 0; + } + } +} + +.f-item-code { + margin-top: 2rem; +} + +.f-item-preview { + @include clearfix; +} + +.f-item-border-bottom { + border-bottom: 1px solid map-get($colors, light); +} + +.f-item-heading-group { + @include clearfix; + margin-bottom: 2rem; + vertical-align: middle; +} + +.f-item-heading { + margin-top: 0; + margin-bottom: 0; + display: inline-block; + vertical-align: middle; + line-height: 1; +} + + +.f-item-controls { + display: inline-block; + vertical-align: middle; + margin-left: 0.5rem; + + .f-control { + width: 14px; + height: 14px; + display: block; + float: left; + + &:hover { + use { + fill: map-get($colors, normal); + } + } + + use { + fill: map-get($colors, light); + } + } +} + +.f-item-hidden { + display: none; +} + +.f-item-notes { + font-size: 0.875rem; +} diff --git a/src/assets/fabricator/styles/partials/_layout.scss b/src/assets/fabricator/styles/partials/_layout.scss new file mode 100644 index 0000000..2eb1edf --- /dev/null +++ b/src/assets/fabricator/styles/partials/_layout.scss @@ -0,0 +1,45 @@ +html { + height: 100%; + + &.f-menu-active { + overflow: hidden; + + @media (min-width: 60em) { + overflow: auto; + } + } +} + +body { + margin: 0; + position: relative; + + .f-menu-active & { + width:100%; + height: 100%; + overflow: hidden; + + @media (min-width: 60em) { + overflow: auto; + } + } +} + +.f-container { + @include clearfix; + @include border-box; + position: relative; + padding: 0 1em; + z-index: 0; + min-height: 100vh; + + .f-menu-active & { + transform: translate($menu-width, 0); + + @media (min-width: 60em) { + margin-left: $menu-width; + transform: translate(0, 0); + } + } + +} diff --git a/src/assets/fabricator/styles/partials/_menu.scss b/src/assets/fabricator/styles/partials/_menu.scss new file mode 100644 index 0000000..5f7fe70 --- /dev/null +++ b/src/assets/fabricator/styles/partials/_menu.scss @@ -0,0 +1,70 @@ +// menu +.f-menu { + @include border-box; + position: fixed; + top: 0; + left: 0; + transform: translate(-$menu-width, 0); + width: $menu-width; + height: 100%; + z-index: 1; + background-color: map-get($colors, menu-background); + overflow-x: hidden; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + + .f-menu-active & { + transform: translate(0, 0); + + } + + ul { + margin-top: 0; + margin-bottom: 0; + padding-left: 0; + } + + > ul { + margin-top: 0; + margin-bottom: 1rem; + + > li { + margin-top: 1rem; + } + } + + li { + list-style-type: none; + margin-top: 0; + margin-bottom: 0; + } + + a { + display: block; + padding: 0.5rem 2rem; + color: map-get($colors, normal) !important; + text-decoration: none; + font-size: 0.75rem; + line-height: 1; + + &:hover { + color: map-get($colors, normal) !important; + text-decoration: underline; + } + + &.f-active { + box-shadow: inset 3px 0 0 0 map-get($colors, accent); + } + } + + .f-menu__heading { + padding-left: 1.5rem; + font-weight: 700; + font-size: .6875rem; + text-transform: uppercase; + + &:hover { + color: map-get($colors, normal); + } + } +} diff --git a/src/assets/fabricator/styles/partials/_variables.scss b/src/assets/fabricator/styles/partials/_variables.scss new file mode 100644 index 0000000..e0859d5 --- /dev/null +++ b/src/assets/fabricator/styles/partials/_variables.scss @@ -0,0 +1,40 @@ +$base-colors: ( + dark: hsl(0, 0%, 12%), + medium: hsl(0, 0%, 46%), + light: hsl(0, 0%, 80%), + accent: hsl(0, 0%, 46%) +); + +$theme-dark: ( + menu-background: lighten(map-get($base-colors, dark), 4%), + normal: map-get($base-colors, medium) +); + +$theme-light: ( + menu-background: rgb(255, 255, 255), + normal: map-get($base-colors, medium) +); + +$theme: $theme-light; + +$colors: map-merge($base-colors, $theme); + +$menu-width: 14rem; + + +// mixins +@mixin clearfix { + &:after { + clear: both; + } + + &:before, + &:after { + display: table; + content: ' '; + } +} + +@mixin border-box { + box-sizing: border-box; +} diff --git a/src/assets/toolkit/images/alistapart.png b/src/assets/toolkit/images/alistapart.png new file mode 100644 index 0000000..d63993f Binary files /dev/null and b/src/assets/toolkit/images/alistapart.png differ diff --git a/src/assets/toolkit/images/bolt.svg b/src/assets/toolkit/images/bolt.svg new file mode 100644 index 0000000..f098c60 --- /dev/null +++ b/src/assets/toolkit/images/bolt.svg @@ -0,0 +1,10 @@ + + + + Shape + Created with Sketch. + + + + + \ No newline at end of file diff --git a/src/assets/toolkit/images/fabricating-architecture.png b/src/assets/toolkit/images/fabricating-architecture.png new file mode 100644 index 0000000..821708b Binary files /dev/null and b/src/assets/toolkit/images/fabricating-architecture.png differ diff --git a/src/assets/toolkit/images/head-outline.svg b/src/assets/toolkit/images/head-outline.svg new file mode 100644 index 0000000..eff87e9 --- /dev/null +++ b/src/assets/toolkit/images/head-outline.svg @@ -0,0 +1,84 @@ + + + + + + + + + diff --git a/src/assets/toolkit/images/head.svg b/src/assets/toolkit/images/head.svg new file mode 100644 index 0000000..a3707cd --- /dev/null +++ b/src/assets/toolkit/images/head.svg @@ -0,0 +1,588 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/toolkit/images/logo.svg b/src/assets/toolkit/images/logo.svg new file mode 100644 index 0000000..e4cb0af --- /dev/null +++ b/src/assets/toolkit/images/logo.svg @@ -0,0 +1 @@ + diff --git a/src/assets/toolkit/images/masthead.png b/src/assets/toolkit/images/masthead.png new file mode 100644 index 0000000..0311ac5 Binary files /dev/null and b/src/assets/toolkit/images/masthead.png differ diff --git a/src/assets/toolkit/images/net-magazine.png b/src/assets/toolkit/images/net-magazine.png new file mode 100644 index 0000000..910670d Binary files /dev/null and b/src/assets/toolkit/images/net-magazine.png differ diff --git a/src/assets/toolkit/images/smashing-magazine.png b/src/assets/toolkit/images/smashing-magazine.png new file mode 100644 index 0000000..39f902f Binary files /dev/null and b/src/assets/toolkit/images/smashing-magazine.png differ diff --git a/src/assets/toolkit/images/social.png b/src/assets/toolkit/images/social.png new file mode 100644 index 0000000..6f8251c Binary files /dev/null and b/src/assets/toolkit/images/social.png differ diff --git a/src/assets/toolkit/images/toggle-all.png b/src/assets/toolkit/images/toggle-all.png new file mode 100644 index 0000000..27bc1a1 Binary files /dev/null and b/src/assets/toolkit/images/toggle-all.png differ diff --git a/src/assets/toolkit/images/toggle-single.png b/src/assets/toolkit/images/toggle-single.png new file mode 100644 index 0000000..74432d5 Binary files /dev/null and b/src/assets/toolkit/images/toggle-single.png differ diff --git a/src/assets/toolkit/images/word-mark-outline.svg b/src/assets/toolkit/images/word-mark-outline.svg new file mode 100644 index 0000000..bad48fd --- /dev/null +++ b/src/assets/toolkit/images/word-mark-outline.svg @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + diff --git a/src/assets/toolkit/scripts/toolkit.js b/src/assets/toolkit/scripts/toolkit.js new file mode 100755 index 0000000..d097f06 --- /dev/null +++ b/src/assets/toolkit/scripts/toolkit.js @@ -0,0 +1,5 @@ +/** + * Toolkit JavaScript + */ + +'use strict'; diff --git a/src/assets/toolkit/styles/base/_grid.scss b/src/assets/toolkit/styles/base/_grid.scss new file mode 100644 index 0000000..d3233f8 --- /dev/null +++ b/src/assets/toolkit/styles/base/_grid.scss @@ -0,0 +1,68 @@ +.row { + @include outer-container; + position: relative; + padding-right: 1em; + padding-left: 1em; + + &--fluid { + max-width: 100%; + } + + &--no-gutter { + padding-left: 0; + padding-right: 0; + } +} + +[class*=col-] { + position: relative; + float: left; +} + +// standard grid +@for $i from 1 through $grid-columns { + .col-#{$i} { + @include span-columns($grid-columns); + + @include breakpoint($bp-m) { + @include span-columns($i); + } + } +} + + +// dynamic grid +@mixin col-classes($size) { + @for $i from 1 through $grid-columns { + .col-#{$size}-#{$i} { + @include span-columns($i); + } + } +} + +@include col-classes($size:s); + +@include breakpoint($bp-m) { + @include col-classes($size:m); +} + +@include breakpoint($bp-l) { + @include col-classes($size:l); +} + +@include breakpoint($bp-xl) { + @include col-classes($size:xl); +} + + +// for documentation site +.f-grid-preview [class^="col-"] { + margin-bottom: ms(0); + color: color(black); + background-color: color(gray, 1); + padding: ms(1); + + + [class^="col-"] { + border-left: 0; + } +} diff --git a/src/assets/toolkit/styles/base/_layout.scss b/src/assets/toolkit/styles/base/_layout.scss new file mode 100644 index 0000000..566f369 --- /dev/null +++ b/src/assets/toolkit/styles/base/_layout.scss @@ -0,0 +1,50 @@ +img { + max-width: 100%; +} + +.side-menu { + text-align: center; + + @include breakpoint($bp-m) { + text-align: right; + } +} + +.feature-row { + + @include breakpoint ($bp-m) { + display: flex; + align-items: center; + } + + + a { + display: block; + margin-left: auto; + margin-right: auto; + margin-bottom: 2em; + max-width: 10em; + opacity: 0.4; + + @include breakpoint($bp-m) { + width: percentage(1/3); + max-width: 100%; + padding: 0 5%; + margin-bottom: 0; + margin-left: 0; + margin-right: 0; + } + + &:last-child { + margin-bottom: 0; + } + + &:not(:last-child) { + margin-top: 1em; + } + + img { + width: 100%; + } + } +} diff --git a/src/assets/toolkit/styles/base/_normalize.scss b/src/assets/toolkit/styles/base/_normalize.scss new file mode 100644 index 0000000..23d8449 --- /dev/null +++ b/src/assets/toolkit/styles/base/_normalize.scss @@ -0,0 +1,424 @@ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + box-sizing: content-box; /* 2 */ +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} diff --git a/src/assets/toolkit/styles/base/_typography.scss b/src/assets/toolkit/styles/base/_typography.scss new file mode 100644 index 0000000..cde3871 --- /dev/null +++ b/src/assets/toolkit/styles/base/_typography.scss @@ -0,0 +1,67 @@ +html { + font-size: 16px; + line-height: 1.2; +} + +body { + font-size: 1rem; + font-family: 'Montserrat', sans-serif; + color: color(blue); +} + +a { + color: inherit; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + &.nav-link { + &:hover { + color: color(red); + } + } +} + +h1, +h2, +h3, +h4 { + color: color(red); + margin-top: 3.5rem; + margin-bottom: 1rem; + + > a { + display: block; + cursor: pointer; + } +} + +h1, +h3 { + @include wide-kerning; + text-transform: uppercase; +} + +h3, +h4 { + margin-top: 2.5rem; +} + +p { + line-height: 1.6; + margin-top: 1.5em; + margin-bottom: 1.5em; + + a { + color: color(red); + text-decoration: underline; + } +} + +.section-title { + @include wide-kerning; + text-transform: uppercase; + padding: 0.5rem 0; +} diff --git a/src/assets/toolkit/styles/components/_blockquote.scss b/src/assets/toolkit/styles/components/_blockquote.scss new file mode 100644 index 0000000..b7aa5dc --- /dev/null +++ b/src/assets/toolkit/styles/components/_blockquote.scss @@ -0,0 +1,7 @@ +blockquote { + box-shadow: inset 0.25rem 0 0 0 color(grey); + margin-left: 0; + padding-left: 2rem; + font-style: italic; + color: color(grey); +} diff --git a/src/assets/toolkit/styles/components/_button.scss b/src/assets/toolkit/styles/components/_button.scss new file mode 100644 index 0000000..043acc8 --- /dev/null +++ b/src/assets/toolkit/styles/components/_button.scss @@ -0,0 +1,15 @@ +.button { + @include wide-kerning; + background-color: color(blue); + border: 0; + color: color(white); + padding: 1em 3em; + text-transform: uppercase; + text-decoration: none; + display: inline-block; + font-size: 1.3rem; + + &:hover { + text-decoration: underline; + } +} diff --git a/src/assets/toolkit/styles/components/_figure.scss b/src/assets/toolkit/styles/components/_figure.scss new file mode 100644 index 0000000..5171180 --- /dev/null +++ b/src/assets/toolkit/styles/components/_figure.scss @@ -0,0 +1,8 @@ +figure { + width: 100%; + margin: 0; + + > img { + max-width: 100%; + } +} diff --git a/src/assets/toolkit/styles/components/_footer.scss b/src/assets/toolkit/styles/components/_footer.scss new file mode 100644 index 0000000..df16047 --- /dev/null +++ b/src/assets/toolkit/styles/components/_footer.scss @@ -0,0 +1,23 @@ +.footer { + background-color: color(aqua); + // color: color(white); + padding: 2rem 1rem; + text-align: center; + + a { + color: color(blue); + } + + p { + margin: 1rem 0; + } +} + +.stamp { + height: 4rem; + max-width: 10rem; + + use { + fill: color(blue); + } +} diff --git a/src/assets/toolkit/styles/components/_form-controls.scss b/src/assets/toolkit/styles/components/_form-controls.scss new file mode 100644 index 0000000..62fd507 --- /dev/null +++ b/src/assets/toolkit/styles/components/_form-controls.scss @@ -0,0 +1,24 @@ +.form-group { + padding: 1rem 0; + + label { + color: color(grey); + display: block; + font-size: 0.875rem; + } +} + +.form-control { + padding: 0.75rem 0; + display: block; + margin-top: 0.5rem; + width: 100%; + border: 0; + box-shadow: 0 2px 0 0 color(grey, 1); + color: color(blue); + + &:focus { + box-shadow: 0 3px 0 0 color(orange); + outline: none; + } +} diff --git a/src/assets/toolkit/styles/components/_header-bar.scss b/src/assets/toolkit/styles/components/_header-bar.scss new file mode 100644 index 0000000..cef9796 --- /dev/null +++ b/src/assets/toolkit/styles/components/_header-bar.scss @@ -0,0 +1,29 @@ +.header-bar { + background-color: color(blue); + text-align: center; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + + &__divider { + margin: 0 1rem; + display: inline-block; + vertical-align: middle; + + svg { + width: 2rem; + height: 2rem; + } + } + + a { + @include wide-kerning; + color: color(white); + text-decoration: none; + text-transform: uppercase; + vertical-align: middle; + + &:hover { + text-decoration: underline; + } + } +} diff --git a/src/assets/toolkit/styles/components/_hero.scss b/src/assets/toolkit/styles/components/_hero.scss new file mode 100644 index 0000000..132dd17 --- /dev/null +++ b/src/assets/toolkit/styles/components/_hero.scss @@ -0,0 +1,32 @@ +.hero { + background-color: color(aqua); + text-align: center; + padding: 2rem 1rem 3rem; + + > img { + max-width: 30rem; + display: inline-block; + } + + &__byline { + @include wide-kerning; + text-transform: uppercase; + position: relative; + color: color(blue); + font-weight: bold; + margin: 0; + + @include breakpoint($bp-xs) { + top: -2rem; + font-size: 1.3rem; + } + } + + .button { + margin-top: 1.3rem; + + @include breakpoint($bp-xs) { + margin-top: 0; + } + } +} diff --git a/src/assets/toolkit/styles/components/_lists.scss b/src/assets/toolkit/styles/components/_lists.scss new file mode 100644 index 0000000..1cf2d3b --- /dev/null +++ b/src/assets/toolkit/styles/components/_lists.scss @@ -0,0 +1,70 @@ +ul, +ol { + margin: 1.2em 0; + + li { + margin-bottom: 1em; + + &:last-child { + margin-bottom: 0; + } + } +} + +.list-heading { + @include wide-kerning; + text-transform: uppercase; + color: color(red); + font-weight: 700; + list-style-type: none; + padding-bottom: 0.5em; + display: block; +} + +.link-list { + padding-left: 0; + list-style-type: none; + + li { + margin-bottom: 0; + } + + a { + padding: 0.5em 0; + text-decoration: none; + display: block; + + &:hover { + text-decoration: underline; + color: color(red); + } + } +} + + +.piped-list { + list-style-type: none; + padding-left: 0; + margin: 0; + + li { + display: inline-block; + vertical-align: middle; + margin-bottom: 0; + + &.pipe { + margin: 0 0.5em; + } + + .bolt { + width: 1.5em; + height: 1.5em; + display: inline-block; + vertical-align: middle; + + use { + fill: color(orange, 1); + } + } + } +} diff --git a/src/assets/toolkit/styles/components/_page-header.scss b/src/assets/toolkit/styles/components/_page-header.scss new file mode 100644 index 0000000..4a17a49 --- /dev/null +++ b/src/assets/toolkit/styles/components/_page-header.scss @@ -0,0 +1,14 @@ +.page-header { + text-align: center; + background-color: color(aqua); + padding: 1rem 0; + + > a { + display: inline-block; + max-width: 5rem; + + img { + width: 100%; + } + } +} diff --git a/src/assets/toolkit/styles/components/_symbols.scss b/src/assets/toolkit/styles/components/_symbols.scss new file mode 100644 index 0000000..88b8736 --- /dev/null +++ b/src/assets/toolkit/styles/components/_symbols.scss @@ -0,0 +1,5 @@ +.bolt { + use { + fill: color(orange); + } +} diff --git a/src/assets/toolkit/styles/mixins/_breakpoint.scss b/src/assets/toolkit/styles/mixins/_breakpoint.scss new file mode 100644 index 0000000..f92f0a8 --- /dev/null +++ b/src/assets/toolkit/styles/mixins/_breakpoint.scss @@ -0,0 +1,9 @@ +/** + * Include a responsive breakpoint + * @example @include breakpoint(32em) { ... } + */ +@mixin breakpoint($width) { + @media screen and (min-width: $width) { + @content; + } +} diff --git a/src/assets/toolkit/styles/mixins/_type.scss b/src/assets/toolkit/styles/mixins/_type.scss new file mode 100644 index 0000000..5985c0c --- /dev/null +++ b/src/assets/toolkit/styles/mixins/_type.scss @@ -0,0 +1,3 @@ +@mixin wide-kerning { + letter-spacing: 0.13em; +} diff --git a/src/assets/toolkit/styles/toolkit.scss b/src/assets/toolkit/styles/toolkit.scss new file mode 100755 index 0000000..3812435 --- /dev/null +++ b/src/assets/toolkit/styles/toolkit.scss @@ -0,0 +1,30 @@ +@import 'variables/breakpoints'; +@import 'variables/colors'; +@import 'variables/utils'; + +@import '../../fabricator/styles/partials/code'; +@import '../../../../bower_components/bourbon/app/assets/stylesheets/bourbon'; +@import '../../../../bower_components/neat/app/assets/stylesheets/neat'; +@import '../../../../bower_components/css-utils/utils.scss'; +@import 'base/normalize'; + +@import 'mixins/breakpoint'; +@import 'mixins/type'; + +@import 'base/grid'; +@import 'base/layout'; +@import 'base/typography'; + +@import 'components/blockquote'; +@import 'components/button'; +@import 'components/figure'; +@import 'components/form-controls'; +@import 'components/footer'; +@import 'components/header-bar'; +@import 'components/hero'; +@import 'components/lists'; +@import 'components/page-header'; +@import 'components/symbols'; + +@import 'utils/bg'; +@import 'utils/text'; diff --git a/src/assets/toolkit/styles/utils/_bg.scss b/src/assets/toolkit/styles/utils/_bg.scss new file mode 100644 index 0000000..4648f53 --- /dev/null +++ b/src/assets/toolkit/styles/utils/_bg.scss @@ -0,0 +1,15 @@ +.bg-orange2 { + background-color: color(orange, 2); + + a { + color: color(white); + } +} + +.bg-grey1 { + background-color: color(grey, 1); + + a { + color: color(black); + } +} diff --git a/src/assets/toolkit/styles/utils/_text.scss b/src/assets/toolkit/styles/utils/_text.scss new file mode 100644 index 0000000..fcc8372 --- /dev/null +++ b/src/assets/toolkit/styles/utils/_text.scss @@ -0,0 +1,4 @@ + +.white { + color: color(white); +} diff --git a/src/assets/toolkit/styles/variables/_breakpoints.scss b/src/assets/toolkit/styles/variables/_breakpoints.scss new file mode 100644 index 0000000..99bc3b8 --- /dev/null +++ b/src/assets/toolkit/styles/variables/_breakpoints.scss @@ -0,0 +1,10 @@ +$max-width: 60rem; // (target / context) + +$bp-xs: 28rem; +$bp-s: 32rem; +$bp-m: 48rem; +$bp-l: 66rem; +$bp-xl: 76rem; + +$column: 4rem; +$gutter: 4rem; diff --git a/src/assets/toolkit/styles/variables/_colors.scss b/src/assets/toolkit/styles/variables/_colors.scss new file mode 100644 index 0000000..d456864 --- /dev/null +++ b/src/assets/toolkit/styles/variables/_colors.scss @@ -0,0 +1,42 @@ +/** + * Color variable map + */ +$colors: ( + orange: ( + 0: rgb(231, 173, 0), + 1: rgb(231, 129, 0), + 2: rgb(229, 70, 0) + ), + red: ( + 0: rgb(183, 41, 6) + ), + blue: ( + 0: rgb(24, 24, 48) + ), + grey: ( + 0: rgb(150, 150, 178), + 1: lighten(rgb(150, 150, 178), 20%) + ), + aqua: ( + 0: rgb(126, 237, 226) + ), + white: ( + 0: hsl(0, 0%, 100%) + ), + black: ( + 0: hsl(0, 0%, 10%) + ) +); + + +@function color($color, $tone: 0) { + @return map-get(map-get($colors, $color), $tone); +} + +.blue { + color: color(blue); +} + +.black { + color: color(black); +} diff --git a/src/assets/toolkit/styles/variables/_utils.scss b/src/assets/toolkit/styles/variables/_utils.scss new file mode 100644 index 0000000..7cb9fbf --- /dev/null +++ b/src/assets/toolkit/styles/variables/_utils.scss @@ -0,0 +1,2 @@ +$scale: 1.618; // golden ratio +$steps: -4, -3, -1, 0, 1, 2, 3; // xxs - xxl diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000..b3c1dd5 Binary files /dev/null and b/src/favicon.ico differ diff --git a/src/materials/components/_blockquote.html b/src/materials/components/_blockquote.html new file mode 100644 index 0000000..d250897 --- /dev/null +++ b/src/materials/components/_blockquote.html @@ -0,0 +1,3 @@ +
+

Introduction to toolkit-driven development

+
diff --git a/src/materials/components/button.html b/src/materials/components/button.html new file mode 100755 index 0000000..9a65ad4 --- /dev/null +++ b/src/materials/components/button.html @@ -0,0 +1 @@ + diff --git a/src/materials/components/footer.html b/src/materials/components/footer.html new file mode 100644 index 0000000..275d1ea --- /dev/null +++ b/src/materials/components/footer.html @@ -0,0 +1,11 @@ + diff --git a/src/materials/components/header-bar.html b/src/materials/components/header-bar.html new file mode 100644 index 0000000..b3dc457 --- /dev/null +++ b/src/materials/components/header-bar.html @@ -0,0 +1,9 @@ +
+ Docs + + + + + + Source +
diff --git a/src/materials/components/hero.html b/src/materials/components/hero.html new file mode 100644 index 0000000..97d1e5d --- /dev/null +++ b/src/materials/components/hero.html @@ -0,0 +1,8 @@ +
+ Fabricator +

+ Build your UI toolkit +

+ Start Building + View demo +
diff --git a/src/materials/components/lists/link.html b/src/materials/components/lists/link.html new file mode 100644 index 0000000..21edba8 --- /dev/null +++ b/src/materials/components/lists/link.html @@ -0,0 +1,15 @@ + diff --git a/src/materials/components/lists/ordered.html b/src/materials/components/lists/ordered.html new file mode 100755 index 0000000..6f0c8e9 --- /dev/null +++ b/src/materials/components/lists/ordered.html @@ -0,0 +1,5 @@ +
    +
  1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  2. +
  3. Aliquam tincidunt mauris eu risus.
  4. +
  5. Vestibulum auctor dapibus neque.
  6. +
\ No newline at end of file diff --git a/src/materials/components/lists/piped.html b/src/materials/components/lists/piped.html new file mode 100644 index 0000000..f082538 --- /dev/null +++ b/src/materials/components/lists/piped.html @@ -0,0 +1,21 @@ + diff --git a/src/materials/components/lists/unordered.html b/src/materials/components/lists/unordered.html new file mode 100755 index 0000000..115af04 --- /dev/null +++ b/src/materials/components/lists/unordered.html @@ -0,0 +1,5 @@ +
    +
  • Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  • +
  • Aliquam tincidunt mauris eu risus.
  • +
  • Vestibulum auctor dapibus neque.
  • +
\ No newline at end of file diff --git a/src/materials/components/page-header.html b/src/materials/components/page-header.html new file mode 100644 index 0000000..25435ee --- /dev/null +++ b/src/materials/components/page-header.html @@ -0,0 +1,6 @@ + diff --git a/src/materials/components/paragraph.html b/src/materials/components/paragraph.html new file mode 100755 index 0000000..e20feca --- /dev/null +++ b/src/materials/components/paragraph.html @@ -0,0 +1 @@ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ullamcorper nulla non metus auctor fringilla. Donec id elit non mi porta gravida at eget metus.

diff --git a/src/materials/components/symbols.html b/src/materials/components/symbols.html new file mode 100644 index 0000000..21f1f77 --- /dev/null +++ b/src/materials/components/symbols.html @@ -0,0 +1,27 @@ +--- +notes: | + Symbols are SVG and the `` method described here - [CSS-Tricks - SVG symbol a Good Choice for Icons](https://css-tricks.com/svg-symbol-good-choice-icons/) + + This element is a hidden `` element that persists on every page. + + Include a symbol using the following syntax: + + ```markup + + + + ``` +--- + + + + + + + + + + + + + diff --git a/src/materials/components/text-input.html b/src/materials/components/text-input.html new file mode 100755 index 0000000..bea7589 --- /dev/null +++ b/src/materials/components/text-input.html @@ -0,0 +1,7 @@ +
+ +
+ diff --git a/src/views/components.html b/src/views/components.html new file mode 100755 index 0000000..efffd11 --- /dev/null +++ b/src/views/components.html @@ -0,0 +1,11 @@ +--- +fabricator: true +--- + +

Components

+ +{{#each materials.components.items}} + +{{> f-item this}} + +{{/each}} diff --git a/src/views/docs/advanced/customization.html b/src/views/docs/advanced/customization.html new file mode 100644 index 0000000..f0cefbe --- /dev/null +++ b/src/views/docs/advanced/customization.html @@ -0,0 +1,33 @@ +--- +title: Customization - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Customization + +> Make Fabricator look and feel like you want + +## Themes + +Fabricator comes with two themes: light (default) and dark. + +Set the theme in the `src/assets/fabricator/styles/partials/_variables.scss` file: + +```scss +$theme: $theme-dark; +``` + +### Colors + +The colors for each theme can also be set in the `_variables.scss` file. The most important color is `$accent`. This is the color that used to highlight active menu items and **should be a color from your toolkit's palette**. + +## Menu + +The order of items is the side menu can be changed to fit your needs. The `f-menu.html` partial is templated using data scraped from your toolkit files. By default, it iterates through a hash of materials and views. + +See [data](/building-a-toolkit/data.html) for an example of data model scheme used to template the menu. + +{{/markdown}} diff --git a/src/views/docs/advanced/error-handling.html b/src/views/docs/advanced/error-handling.html new file mode 100644 index 0000000..7bf716b --- /dev/null +++ b/src/views/docs/advanced/error-handling.html @@ -0,0 +1,40 @@ +--- +title: Error Handling - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Error Handling + +There are a couple of options for capturing errors encountered during the assembly of Fabricator view and partials. + +## options.logErrors + +Type: `Boolean` + +Whether or not to log errors to console. If set to false, the app will exit on error. + +By default, this value is set to `true` in dev mode and `false` in build mode. Generally, you should tolerate errors in development, but not when building for release. + +```javascript +assemble({ + logErrors: true +}); +``` + +## options.onError + +Type: `Function` + +Error handler function. Receives an error object param. Helpful if you want to customize your error handling. + +```javascript +assemble({ + onError: function (err) { + notify(err.message); + } +}); + +{{/markdown}} diff --git a/src/views/docs/advanced/helpers.html b/src/views/docs/advanced/helpers.html new file mode 100644 index 0000000..d4120a0 --- /dev/null +++ b/src/views/docs/advanced/helpers.html @@ -0,0 +1,55 @@ +--- +title: Helpers - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Helpers + +> How to add your own Handlebars helpers + +Add your own helpers to the Fabricator assembly engine by defining them in the `assemble` task in `gulpfile.js`: + +```javascript +// assemble +gulp.task('assemble', function(done) { + assemble({ + helpers: { + markdown: require('helper-markdown') + } + }); + done(); +}); +``` + +This adds the [helper-markdown](https://www.npmjs.com/package/helper-markdown) helper, which can be used like: + +``` +{{{{raw}}}}{{#markdown}} + # Markdown! +{{/markdown}}{{{{/raw}}}} +``` + +Learn more about [Handlebars helpers](http://handlebarsjs.com/block_helpers.html). + +## Built-in helpers + +There are some useful helpers already built into Fabricator. + +### iterate + +``` +{{{{raw}}}}{{#iterate 20}} +
  • List Item {{@index}}
  • +{{/iterate}}{{{{/raw}}}} +``` + +### material + +``` +{{{{raw}}}}{{material name context}}{{{{/raw}}}} +``` + +{{/markdown}} diff --git a/src/views/docs/advanced/preprocessors.html b/src/views/docs/advanced/preprocessors.html new file mode 100644 index 0000000..03ef01e --- /dev/null +++ b/src/views/docs/advanced/preprocessors.html @@ -0,0 +1,59 @@ +--- +title: Preprocessors - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Preprocessors + +> How to use Ruby Sass and other Preprocessors + +Fabricator uses the `libsass` compiler because it is much faster than the Ruby compiler. However, you may want to use edge features that only exist in the Ruby compiler. Switching out the compilers is easy. + +0. Install the Sass gem: + +``` +$ gem install sass +``` + +1. Update dependencies ([gulp-ruby-sass](https://github.com/sindresorhus/gulp-ruby-sass)) + +``` +$ npm install --save-dev gulp-ruby-sass && npm uninstall --save-dev gulp-sass +``` + +2. Update the `styles:toolkit` and `styles:fabricator` tasks to use `gulp-ruby-sass`: + +```javascript +var sass = require('gulp-ruby-sass'); + +... + +// styles +gulp.task('styles:fabricator', function () { + return sass(config.src.styles.fabricator, { container: 'gulp-ruby-sass-fabricator' }) + .on('error', function (err) { + console.error('Error!', err.message); + }) + .pipe(prefix('last 1 version')) + .pipe(gulpif(!config.dev, csso())) + .pipe(rename('f.css')) + .pipe(gulp.dest(config.dest + '/assets/fabricator/styles')) + .pipe(gulpif(config.dev, reload({stream:true}))); +}); + +gulp.task('styles:toolkit', function () { + return sass(config.src.styles.toolkit, { container: 'gulp-ruby-sass-toolkit' }) + .on('error', function (err) { + console.error('Error!', err.message); + }) + .pipe(prefix('last 1 version')) + .pipe(gulpif(!config.dev, csso())) + .pipe(gulp.dest(config.dest + '/assets/toolkit/styles')) + .pipe(gulpif(config.dev, reload({stream:true}))); +}); +``` + +{{/markdown}} diff --git a/src/views/docs/advanced/third-party.html b/src/views/docs/advanced/third-party.html new file mode 100644 index 0000000..60ee012 --- /dev/null +++ b/src/views/docs/advanced/third-party.html @@ -0,0 +1,169 @@ +--- +title: Third-party Dependencies - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Third-party Dependencies + +> Including third-party dependencies in your toolkit + +Fabricator makes it easy to include a third-party library like [jQuery](http://jquery.com) +in your toolkit. + +## Using Webpack to bundle dependencies + +Fabricator uses [Webpack](http://webpack.github.io) to bundle modules using the +[CommonJS](http://webpack.github.io/docs/commonjs.html) module syntax: + +```javascript +/* src/assets/toolkit/scripts/my-module.js */ +module.exports = { + foo: function() { + return 'bar'; + } +}; +```` + +```javascript +/* src/assets/toolkit/scripts/toolkit.js */ +var myModule = require('./my-module'); +myModule.foo(); // 'bar' +``` + +In the above example, webpack will find all the dependencies and +output a single file that contains both `my-module.js` and `toolkit.js`. + +## Dependency Management + +It's recommended that you leverage either [NPM](https://www.npmjs.com/) or [Bower](http://bower.io/search/) to manage dependencies. + +### Option 1: NPM + +[NPM](http://npmjs.com) is the recommended way to add third-party dependencies. + +```bash +$ npm install --save-dev jquery +``` + +#### Including NPM dependencies + +By default, if a `require()` call is not prefixed with a path, webpack will +recursively search the `node_modules` directories for the specified module. + +```javascript +// "./" tells webpack to search the current +// directory for "my-module" +var myModule = require('./my-module'); + +// no path was specified, so recursively search +// "node_modules" directories for "jquery" +var $ = require('jquery'); +$('#my-button').hide(); +``` + +### Option 2: Bower + +[Bower](http://bower.io) is a great tool for managing third party client side +dependencies. Here's how to leverage Bower on a Fabricator instance: + +1. Install Bower globally for access to the CLI `$ npm install -g bower` +2. Install Bower local to project `$ npm install bower --save-dev` +3. Run `$ bower init` to initialize Bower for your project. +4. Add a `.bowerrc` config file to your project root. + +**.bowerrc** + +```javascript +{ + "directory": "bower_components" +} +``` + +5. Update `package.json` `scripts` object to hook into Bower install task. + +**package.json** + +```javascript +"scripts": { + "gulp": "gulp", + "bower": "bower", + "prestart": "npm install", + "build": "npm install && gulp", + "start": "gulp --dev", + "postinstall": "bower install", + "test": "npm run build" +}, +``` + +6. Add `bower_components` to `.gitignore`. + +7. Install dependencies with Bower. + +```bash +$ bower install --save-dev jquery +``` + + +#### Including Bower dependencies + +1. Tell webpack to search "bower_components" + +**webpack.config.js** + +```javascript +// add the "resolve" property to the config +var config = { + /* other config properties */ + resolve: { + modulesDirectories: ['node_modules', 'bower_components'] + } +}; +``` + +2. Require the module + +Unlike including NPM dependencies, Bower has no rules for how a module +is structured. As a result, you will often have to specify a more specific path: + +```javascript +var myLibrary = require('myLibrary/dist/library'); +``` + +## Handling modules that do not use CommonJS + +Many Bower modules are just plain JavaScript files that don't use the CommonJS +module syntax; an example might be a jQuery plugin. + +Fabricator includes both the [Imports Loader](https://github.com/webpack/imports-loader) +and the [Script Loader](https://github.com/webpack/script-loader) to handle these cases. + +### Imports Loader + +```javascript +// installed via NPM +var $ = require('jquery'); + +// installed via Bower +require('imports?$=jquery!somePlugin/dist/plugin'); + +$('#my-button').somePlugin(); +``` + +### Script Loader + +> This loader evaluates code in the global context, just like you would add +the code into a script tag. In this mode every normal library should work. +require, module, etc. are undefined. + +> Note: The file is added as string to the bundle. It is not minimized by webpack, +so use a minimized version. There is also no dev tool support for +libraries added by this loader. + +```javascript +require('script!anotherLib/lib/another-lib'); +``` + +{{/markdown}} diff --git a/src/views/docs/building-a-toolkit/assets.html b/src/views/docs/building-a-toolkit/assets.html new file mode 100644 index 0000000..a493c1b --- /dev/null +++ b/src/views/docs/building-a-toolkit/assets.html @@ -0,0 +1,17 @@ +--- +title: Stylesheets and JavaScript - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Stylesheets and JavaScript + +> How to work with CSS and JS within Fabricator + +Fabricator comes with little opinion about how you should architect your Stylesheets and JavaScript. Each use case is different, so it's up to you to define what works best. + +Out of the box, you'll find a single `.scss` and `.js` file. These are the entry points for Sass compilation and Webpack respectively. It is recommended that you leverage the module importing features of each preprocessor to compile your toolkit down to a single `.css` and `.js` file. Practically speaking, you should be able to drop these two files into any application and have full access to your entire toolkit. + +{{/markdown}} diff --git a/src/views/docs/building-a-toolkit/data.html b/src/views/docs/building-a-toolkit/data.html new file mode 100644 index 0000000..5300c46 --- /dev/null +++ b/src/views/docs/building-a-toolkit/data.html @@ -0,0 +1,164 @@ +--- +title: Data - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Data + +> How to feed data into your toolkit materials and prototypes + +Sometimes it is helpful to decouple page data from materials and layouts. + +## src/data + +Data can be stored in JSON or YML files in the `src/data` directory. + +Data within these files is accessed using dot notation. For example, given `home.yml`: + +```yml +links: + About Us: + - About Us + - Careers + - Media Center + - Legal +``` + +Data could be used in a view as: + +```markup +{{{{raw}}}}{{#each home.links}} + {{#each this}} + {{this}} + {{/each}} +{{/each}}{{{{/raw}}}} +``` + +And would output: + +```markup +About Us +Careers +Media Center +Legal +``` + +## Material Front-matter + +Data can also be stored as front-matter in a view or material. + +Example material `src/materials/components/welcome.html`: + +```markup +--- +greeting: Hello +--- +
    {{{{raw}}}}{{greeting}}{{{{/raw}}}}, World!
    +``` + +Output: + +```markup +
    Hello, World!
    +``` + +## Context + +Each view is templated with a unique context (data model) assembled from material data, front-matter, and `src/data`. Fabricator scrapes the files in your toolkit and builds theses data models on the fly. They only exist within the `fabricator-assemble` task; views are templated using these data models, but the data is never written to disk. + +Here's an example scheme: + +```javascript +{ + // page front-matter + "title": "Home", + // built-in props + "baseurl": "..", + // src/data + "home": { + "greeting": "Hello", + "action": "Click" + }, + "user": { + "user": { + "name": "Luke" + } + }, + // material data + "materials": { + "components": { + "name": "Components", + "items": { + "alerts": { + "name": "Alerts", + "items": { + "alerts.primary": { + "name": "Primary", + "notes": "" + } + } + }, + "button": { + "name": "Button", + "notes": "

    foo bar

    \n" + }, + "toggles": { + "name": "Toggles", + "items": { + "toggles.primary": { + "name": "Primary", + "notes": "" + } + } + } + } + }, + "structures": { + "name": "Structures", + "items": { + "form": { + "name": "Form", + "notes": "" + } + } + } + }, + // user-defined views + "views": { + "pages": { + "name": "Pages", + "items": { + "home": { + "name": "Home" + } + } + } + }, + // documentation + "docs": { + "javascript": { + "name": "Javascript", + "content": "

    This is a markdown document.

    \n

    var foo = 'bar';

    \n" + } + } +} +``` + +You can iterate over the properties in this data model when [customizing](/advanced/customization.html) your Fabricator pages. + +## Reserved words + +There are a handful of predefined context properties. You should avoid over-riding these properties. + +### {{{{raw}}}}{{baseurl}}{{{{/raw}}}} + +Used when building links in nested views: + +```markup + +``` + +{{/markdown}} diff --git a/src/views/docs/building-a-toolkit/materials.html b/src/views/docs/building-a-toolkit/materials.html new file mode 100644 index 0000000..69b3e23 --- /dev/null +++ b/src/views/docs/building-a-toolkit/materials.html @@ -0,0 +1,115 @@ +--- +title: Materials - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Materials + +> Defining the "materials" that make up your toolkit + +"Material" is a generic term for the individual components/modules/chunks that make up an interface. By default, Fabricator defines a material taxonomy of "component" and "structure", but is flexible and allows you to define your own taxonomy. + +## Defining your taxonomy + +A successful taxonomy takes into account a number of different factors such as established brand terminology, personal preference, the size and scale of the end applications, etc. Here are some sample taxonomies that might work for you: + +``` +└── materials + ├── components + └── structures +``` + +``` +└── materials + ├── atoms + ├── molecules + └── organism +``` + +``` +└── materials + ├── typography + ├── elements + └── components +``` + +``` +└── materials + ├── content + ├── forms + ├── lists + └── navigation +``` + +Within the `src/materials` directory, you can define your taxonomy by organizing your materials into sub-directories. + +## Adding materials + +A material is a `.html` file that can contain [YAML](http://nodeca.github.io/js-yaml/) front-matter and handlebars markup. + +To add a material, create a new `.html` file in the desired directory. The material should show up on the listing page automatically. + +Every material is accessible as a handlebars partial using the `{{{decode "%7B%7B> partial-name%7D%7D"}}}` syntax where `partial-name` is the name of the file. + +Sometimes it is useful to group materials, like instances where you want to show alternate versions. You can group materials by placing them in a subdirectory: + +``` +└── materials + └── components + └── lists + ├── ordered.html + └── unordered.html +``` + +Grouped materials are accessed as a partial using dot notation: `{{{decode "%7B%7B> lists.ordered%7D%7D"}}}` + +## Documenting a material + +You can directly associate documentation with a material by adding `notes` in the front-matter of the file: + +```markup +--- +notes: | + These are notes written in `markdown` +--- +
    My Component
    +``` + +Notes will appear adjacent to a material on the listing page and can be toggled on/off. + +## Ordering materials + +Sometimes you want to have control over the order in which materials are listed. By default, materials are sorted alphabetically, but you can manually sort materials by prefixing their filename with a number. + +For example: + +``` +01-foo.html +02-bar.html +``` + +will list as: + +``` +Foo +Bar +``` + +Number prefixes are ignored in partial keywords, so in the example above, the materials are still accessed as: + +``` +{{{{raw}}}}{{> foo}} +{{> bar}}{{{{/raw}}}} +``` + +Ordering works with any quantity of dot-delimited number prefixes. You can get pretty granular: + +``` +01.00-foo.html +01.01-bar.html +``` + +{{/markdown}} diff --git a/src/views/docs/building-a-toolkit/rapid-prototyping.html b/src/views/docs/building-a-toolkit/rapid-prototyping.html new file mode 100644 index 0000000..3f9f8d6 --- /dev/null +++ b/src/views/docs/building-a-toolkit/rapid-prototyping.html @@ -0,0 +1,89 @@ +--- +title: Rapid Prototyping - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Rapid Prototyping + +> How to use Fabricator to quickly build new views + +Fabricator's [assembly engine](https://github.com/fbrctr/fabricator-assemble) is a powerful templating engine built on top of [Handlebars.js](http://handlebarsjs.com). It helps you compose new materials and prototypical pages with very little friction. + +## Layouts + +Layouts are wrappers for pages. You can define as many layouts as you want by creating `.html` files in your layouts directory. + +Example layout: + +```markup + + + + {{{decode "%7B%7Btitle%7D%7D"}}} + + + + {{{decode "%7B%25%20body%20%25%7D"}}} + + + +``` + +View content is inserted in the `{{{decode "%7B%25%20body%20%25%7D"}}}` placeholder. + +Context can be passed from a view to the layout via front-matter. + +The layout that a view uses is also defined in front-matter: + +```yml +--- +layout: custom-layout +title: My Custom Layout +--- +``` + +This would use `src/views/layouts/custom-layout.html`. + +When no `layout` property is defined, the view uses the `default` layout. + +## Views + +Views are unique pages templated using Handlebars. These are both Fabricator pages and user-created pages. + +Example view: + +```markup +--- +title: Document Name +name: World +--- + +

    {{{decode "%7B%7Bhome.greeting%7D%7D%2C%20%7B%7Bname%7D%7D"}}}!

    + +{{{decode "%7B%7B%3E%20button%7D%7D"}}} + +``` + +This outputs a page that uses the default layout (since no layout was defined). + +The front-matter block at the top provides context to both the layout and the view itself. + +Context is also piped in from [data files](/building-a-toolkit/data.html). In this example, `{{{decode "%7B%7Bhome.greeting%7D%7D"}}}` refers to the `greeting` property in `home.json`. + +Fabricator pages are typically stored at the root level of the `views` directory and user-created views (e.g. "templates", "pages", "interfaces") should be stored in subdirectories: + +``` +└── views + ├── templates + │ ├── about.html + │ └── home.html + ├── components.html + ├── docs.html + ├── index.html + └── structures.html +``` + +{{/markdown}} diff --git a/src/views/docs/getting-started/what-is-a-toolkit.html b/src/views/docs/getting-started/what-is-a-toolkit.html new file mode 100644 index 0000000..2355e1f --- /dev/null +++ b/src/views/docs/getting-started/what-is-a-toolkit.html @@ -0,0 +1,48 @@ +--- +title: What's a "toolkit"? - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# What is a "toolkit"? + +> An introduction to toolkit-driven development + +## Fabricating Websites + +Modern day web interfaces are large, complex systems of interoperable parts. If not planned thoughtfully, UI code can become overly complex and difficult to scale. It can be helpful [take some queues from other industries](http://us5.campaign-archive1.com/?u=7e093c5cf4&id=ead8a72012&e=ecb25a3f93) that have solved this problem of scale already. + +A UI "toolkit" addresses the issue of complexity by breaking down an interface into smaller chunks. It is the digital equivalent of the auto industry's sub-assemblies and modules. It is a collection of independent pieces that are assembled to form larger pieces. A toolkit is not a website, rather it is the pieces that make up a website. These pieces can be used in any type of end-application, whether it is .NET, Ruby on Rails, Node.js, or just plain HTML. + +Fabricator is a tool for building toolkits. It provides an efficient, optimized working environment to help you build your toolkit. + +## Toolkit-driven Development + +Thinking of a website as a system of materials can be a powerful shift in thinking. Each piece must work both independently and in concert with an unknown combination of other pieces. The UI must be backend-agnostic so it can work in as many places as possible. + +To achieve this, developers must design their code to be modular and scalable. Further, toolkits should be a single `.js` and `.css` file that contains a site's entire design system. A developer should be able to drop these two files on any page an have access to the entire design system. + +When done well, a mature toolkit can be used to build a large number of unique pages and layouts. Once a baseline of materials has been built, designers can compose new pages by selecting existing materials, then design to fill the gaps. The need to produce a layout artifact for each new page is eliminated. The time it takes to layout new pages dramatically decreases as the toolkit matures. + +## Style guide vs toolkit + +Website style guides have evolved over the years, first starting as an outreach of the tradition (print) branding style guides, and eventually maturing into interactive examples of how a brand should be look and feel on the web. See [Starbucks](http://www.starbucks.com/static/reference/styleguide/), [Yelp](http://www.yelp.com/styleguide), [Salesforce](http://sfdc-styleguide.herokuapp.com/), [Code For America](http://style.codeforamerica.org), and [Google's Material Design](http://www.google.com/design/spec/material-design/). + +A toolkit is more focused on code - specifically the modularity of website interfaces. Toolkits break down websites into small, repeatable chunks, then use those chunks to build an infinite number of layouts. [Bootstrap](http://getbootstrap.com/), [Topcoat](http://topcoat.io/topcoat/), and [Zurb's Foundation](http://foundation.zurb.com/) are popular toolkits. + +Both are great and can be extremely useful. Fabricator gives you a way to combine both concepts into one deliverable. + +When you work with Fabricator, you develop a brand's look and feel on the web while also producing a code toolkit. + +Next, [learn how to use Fabricator](/getting-started/working-with-fabricator.html). + +## Helpful Resources + +- [Architecting a Pattern Library](http://us5.campaign-archive1.com/?u=7e093c5cf4&id=ead8a72012&e=ecb25a3f93) +- [Responsive Deliverables](http://daverupert.com/2013/04/responsive-deliverables/) +- [Design Systems: Building for the Future](https://css-tricks.com/design-systems-building-future/) +- [styleguides.io](http://styleguides.io/) + +{{/markdown}} diff --git a/src/views/docs/getting-started/working-with-fabricator.html b/src/views/docs/getting-started/working-with-fabricator.html new file mode 100644 index 0000000..9994f5b --- /dev/null +++ b/src/views/docs/getting-started/working-with-fabricator.html @@ -0,0 +1,128 @@ +--- +title: Working with Fabricator - Fabricator +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Working with Fabricator + +> A look at how Fabricator is setup and an explanation of some of it's features. + +## Running and Building + +Fabricator is built on [node.js](http://nodejs.org). You'll need Node installed before you can start building. + +Once you have a Fabricator instance setup, run the following command to start the development environment: + +``` +$ npm start +``` + +This installs dependencies, compiles the site, and watches for changes to re-compile. + +Once you're ready to deploy your toolkit, run the following command to run an optimized build: + +``` +$ npm run build +``` + +## Directories + +All work is done in`src` directory. Inside you'll find the following directories: + +``` +└── src + ├── assets + ├── data + ├── docs + ├── materials + └── views +``` + +`assets` - static assets (stylesheets, javascript, images) for both Fabricator and your toolkit. + +`data` - yml or json files that can be fed into materials and views + +`docs` - markdown files with toolkit-wide documentation (e.g. usage guidelines, branding, tone) + +`materials` - individual pieces of UI that make up your toolkit. Each file within is registered as a Handlebars partial for rapid prototyping. + +`views` - pages of the style guide + documentation site that Fabricator generates. Also where any prototyping pages are placed. + +### Materials + +By default, Fabricator defines a simple UI taxonomy of "components" and "structures" - components are the smallest unit of UI, and structures are two or more components combined. This is a simple, reasonable taxonomy will work in many cases, however, you are free to define your own taxonomy. To do so, rename/create new directories in the `materials` directory as needed. For example, toolkit that follows [Atomic Design](http://bradfrost.com/blog/post/atomic-web-design/) might look like: + +``` +└── materials + ├── atoms + ├── molecules + └── organism +``` + +Learn more about [materials](/building-a-toolkit/materials.html) + +### Views + +Views are the actual static `.html` pages Fabricator generates. By default, the root contains the skeleton of a Fabricator style guide + documentation site. It has a main landing page, a listing page for each material type, and a page for documentation. These pages are highly customizable. Change them to fit your needs. + +Learn more about the view [data model](/building-a-toolkit/data.html) and [customization](/advanced/customization.html) + +## Assets + +Fabricator uses [Gulp.js](http://gulpjs.com) as a super-fast build system. Gulp handles all static asset processing and view/material assembly. + +Tasks are defined in `gulpfile.js`. **Customization of this file is encouraged**. Hack on it to fit your needs. + +### toolkit + +By default, Fabricator defines almost no architecture. Those decisions are best made by you, the developer. Inside of `src/assets/toolkit` you'll find a single `.scss` and `.js` file. Both are entry points for Sass and Browserify, respectively. It is recommended that you compile your toolkit to a single `.js` and `.css` file to increase portability. The Gulp tasks for both stylesheets and scripts is setup to give you all the power of Sass and Browserify to help achieve this. + +### f.js and f.css + +`f.js` and `f.css` - or before compilation, `fabricator.js` and `fabricator.scss` - are the two files that provide basic functionality and styling for the Fabricator site. They are intentionally minimal as to not conflict with anything in your toolkit. All Fabricator CSS classes and data-attributes are name-spaced with `f-`. + +You shouldn't need to modify these files, but if you find the need to, don't sweat - they are included in the compilation tasks just like your toolkit files. Changes are automatically recompiled. + +## Controls + +**Toggling** + +You can toggle visibility on elements such as **notes**, **code snippets**, and **labels**. + +The controls in the menu allow you to toggle each type globally: + +![Toggle all](http://fbrctr.github.io/assets/toolkit/images/toggle-all.png) + +You can toggle an individual item's code snippet by pressing the code toggle for that item: + +![Toggle single](http://fbrctr.github.io/assets/toolkit/images/toggle-single.png) + + +**Adding toggles to elements** + +You can make an element toggleable by adding a `data-toggle` attribute to that element. + +e.g. + +```markup +
    Some item label
    +
    Some item code
    +``` + +## .dotfiles + +Fabricator comes with a handful of useful dotfiles to help with code management. + +`.editorconfig` - editor configuration rule via [EditorConfig](http://editorconfig.org/) + +`.gitattributes` and `.gitignore` - source control configuration + +`.jshintrc` - JavaScript static analysis via [JSHint](http://jshint.com/) + +Customize these files to fit your needs/opinions. + + +{{/markdown}} diff --git a/src/views/docs/index.html b/src/views/docs/index.html new file mode 100644 index 0000000..080bf61 --- /dev/null +++ b/src/views/docs/index.html @@ -0,0 +1,42 @@ +--- +title: Fabricator Documentation +layout: 2-column +section: Documentation +--- + +{{#markdown}} + +# Quick Start + +## 0. Install Node.js + +Fabricator is built on Node.js, a platform for building fast, scalable network applications. There are pre-built [installers for each platform](http://nodejs.org/download/). You can also install with [Homebrew](http://brew.sh/) via `brew install node` + +## 1. Download Fabricator Instance + +Each toolkit starts with a new, unique instance of Fabricator. You can grab the latest with this one-liner: + +```shell +$ curl -L https://github.com/fbrctr/fabricator/archive/master.tar.gz | tar zx --strip 1 +``` + +Alternatively, you can use the [Yeoman generator](https://github.com/fbrctr/generator-fabricator) to scaffold a new project for you: + +```shell +$ npm install -g generator-fabricator +$ yo fabricator +``` + +## 2. Start Building + +Once your instance is setup, you're ready to start building. Start the development environment by running: + +```shell +$ npm start +``` + +## 3. Next Steps... + +Learn about [toolkit-driven development](/getting-started/what-is-a-toolkit.html) or dig right into [using materials](/building-a-toolkit/materials.html), [rapid prototyping](/building-a-toolkit/rapid-prototyping.html), and [data](/building-a-toolkit/data.html). + +{{/markdown}} diff --git a/src/views/index.html b/src/views/index.html new file mode 100755 index 0000000..ca4e6e3 --- /dev/null +++ b/src/views/index.html @@ -0,0 +1,60 @@ +--- +title: Fabricator - Build your UI toolkit +--- + +{{> header-bar}} + +{{> hero}} + +
    +
    +
    +

    Design System

    +

    Organize your design system the way you want. Components, Structures, Elements, Atoms, Molecules, whatever - the taxonomy is up to you!

    +
    +
    +

    Style Guide + Documentation

    +

    Generate a style guide from your toolkit code. Write documentation in markdown to make your toolkit easy for other developers to use.

    +
    +
    +
    +
    +

    Optimized Builds

    +

    Uses gulp.js as a super-fast, highly-optimized build system to compress images, CSS, and JavaScript.

    +
    +
    +

    Rapid Prototyping

    +

    Highly-portable local development environment with Handlebars and BrowserSync built-in for a fast, efficient workflow.

    +
    +
    +
    + +
    +
    +

    Featured In

    +
    + +
    + +
    +
    +

    Quick Start

    +
    +
    $ curl -L https://github.com/fbrctr/fabricator/archive/master.tar.gz | tar zx --strip 1
    +$ npm start
    + +
    + +{{> footer}} diff --git a/src/views/layouts/2-column.html b/src/views/layouts/2-column.html new file mode 100755 index 0000000..aa26854 --- /dev/null +++ b/src/views/layouts/2-column.html @@ -0,0 +1,86 @@ + + + + + + + + {{> social-meta}} + + {{title}} + + + + + + + + + + {{> symbols}} + + {{> page-header}} + +
    +
    + + + +
    +
    + {% body %} +
    +
    + + {{> footer}} + + + + + + {{> analytics}} + + + diff --git a/src/views/layouts/default.html b/src/views/layouts/default.html new file mode 100755 index 0000000..0d3536d --- /dev/null +++ b/src/views/layouts/default.html @@ -0,0 +1,46 @@ + + + + + + + + {{> social-meta}} + + {{title}} + + {{#if fabricator}}{{/if}} + + + + + + + + + + {{#if fabricator}} + {{> f-icons}} + {{> f-menu}} +
    + {{> f-control-bar}} + {{/if}} + + {{> symbols}} + + {% body %} + + + {{#if fabricator}} +
    + + {{/if}} + + + + + + {{> analytics}} + + + diff --git a/src/views/layouts/includes/analytics.html b/src/views/layouts/includes/analytics.html new file mode 100644 index 0000000..4429f2b --- /dev/null +++ b/src/views/layouts/includes/analytics.html @@ -0,0 +1,10 @@ + diff --git a/src/views/layouts/includes/f-control-bar.html b/src/views/layouts/includes/f-control-bar.html new file mode 100644 index 0000000..8daaaab --- /dev/null +++ b/src/views/layouts/includes/f-control-bar.html @@ -0,0 +1,7 @@ +
    +
    + + + +
    +
    diff --git a/src/views/layouts/includes/f-controls.html b/src/views/layouts/includes/f-controls.html new file mode 100644 index 0000000..e911717 --- /dev/null +++ b/src/views/layouts/includes/f-controls.html @@ -0,0 +1,17 @@ +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    diff --git a/src/views/layouts/includes/f-icons.html b/src/views/layouts/includes/f-icons.html new file mode 100755 index 0000000..cffbdf0 --- /dev/null +++ b/src/views/layouts/includes/f-icons.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/views/layouts/includes/f-item-content.html b/src/views/layouts/includes/f-item-content.html new file mode 100755 index 0000000..e241c24 --- /dev/null +++ b/src/views/layouts/includes/f-item-content.html @@ -0,0 +1,9 @@ +{{#if notes}}
    + {{{notes}}} +
    {{/if}} +
    + {{{material @key @root}}} +
    +
    +
    {{material @key @root}}
    +
    diff --git a/src/views/layouts/includes/f-item-controls.html b/src/views/layouts/includes/f-item-controls.html new file mode 100755 index 0000000..1e0b171 --- /dev/null +++ b/src/views/layouts/includes/f-item-controls.html @@ -0,0 +1,12 @@ +
    + {{#if notes}} + + + + {{/if}} + + + + + +
    diff --git a/src/views/layouts/includes/f-item.html b/src/views/layouts/includes/f-item.html new file mode 100755 index 0000000..e600c0a --- /dev/null +++ b/src/views/layouts/includes/f-item.html @@ -0,0 +1,22 @@ +
    + +{{#if items}} +
    +

    {{name}}

    +
    + {{#each items}} +
    +
    +

    {{name}}

    + {{> f-item-controls}} +
    {{> f-item-content this}} +
    + {{/each}} +{{else}} +
    +

    {{name}}

    + {{> f-item-controls}} +
    {{> f-item-content this}} +{{/if}} + +
    diff --git a/src/views/layouts/includes/f-menu.html b/src/views/layouts/includes/f-menu.html new file mode 100755 index 0000000..b6f8d43 --- /dev/null +++ b/src/views/layouts/includes/f-menu.html @@ -0,0 +1,24 @@ + +
    + + {{> f-controls}} + +
      + + {{#each materials}} +
    • + {{name}} +
        + {{#each items}} +
      • + {{name}} +
      • + {{/each}} +
      +
    • + {{/each}} + +
    + +
    + diff --git a/src/views/layouts/includes/social-meta.html b/src/views/layouts/includes/social-meta.html new file mode 100644 index 0000000..22aa979 --- /dev/null +++ b/src/views/layouts/includes/social-meta.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + +