diff --git a/.yo-rc.json b/.yo-rc.json
index 6dba385..a2a5576 100644
--- a/.yo-rc.json
+++ b/.yo-rc.json
@@ -10,6 +10,386 @@
"husky": true,
"longName": "style-guider-demo",
"yarn": false,
- "npm": true
+ "npm": true,
+ "components": {
+ "accessibility": {
+ "name": "accessibility",
+ "mixin": false,
+ "scss": true,
+ "js": false,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "accessibility"
+ },
+ "alert": {
+ "name": "alert",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "alert"
+ },
+ "blockquote": {
+ "name": "blockquote",
+ "mixin": false,
+ "scss": false,
+ "js": false,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "blockquote"
+ },
+ "bold-header": {
+ "name": "bold-header",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "bold-header"
+ },
+ "breadcrumbs": {
+ "name": "breadcrumbs",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "breadcrumbs"
+ },
+ "button": {
+ "name": "button",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "button"
+ },
+ "callout": {
+ "name": "callout",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "callout"
+ },
+ "card": {
+ "name": "card",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "card"
+ },
+ "checkbox": {
+ "name": "checkbox",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "checkbox"
+ },
+ "closeable": {
+ "name": "closeable",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "closeable"
+ },
+ "colour": {
+ "name": "colour",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "colour"
+ },
+ "definition-list": {
+ "name": "definition-list",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "definition-list"
+ },
+ "disabled": {
+ "name": "disabled",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "disabled"
+ },
+ "divider": {
+ "name": "divider",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "divider"
+ },
+ "errors": {
+ "name": "errors",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "errors"
+ },
+ "footer": {
+ "name": "footer",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "footer"
+ },
+ "form": {
+ "name": "form",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "form"
+ },
+ "header": {
+ "name": "header",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "header"
+ },
+ "hero": {
+ "name": "hero",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "hero"
+ },
+ "hidden": {
+ "name": "hidden",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "hidden"
+ },
+ "input": {
+ "name": "input",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "input"
+ },
+ "layout": {
+ "name": "layout",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "layout"
+ },
+ "link": {
+ "name": "link",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "link"
+ },
+ "list": {
+ "name": "list",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "list"
+ },
+ "login": {
+ "name": "login",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "login"
+ },
+ "pagination": {
+ "name": "pagination",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "pagination"
+ },
+ "progress": {
+ "name": "progress",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "progress"
+ },
+ "quick-links": {
+ "name": "quick-links",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "quick-links"
+ },
+ "radio": {
+ "name": "radio",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "radio"
+ },
+ "required": {
+ "name": "required",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "required"
+ },
+ "select": {
+ "name": "select",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "select"
+ },
+ "sub-header": {
+ "name": "sub-header",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "sub-header"
+ },
+ "sub-menu": {
+ "name": "sub-menu",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "sub-menu"
+ },
+ "submit": {
+ "name": "submit",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "submit"
+ },
+ "tab-list": {
+ "name": "tab-list",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "tab-list"
+ },
+ "tab": {
+ "name": "tab",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "tab"
+ },
+ "table": {
+ "name": "table",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "table"
+ },
+ "textarea": {
+ "name": "textarea",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "textarea"
+ },
+ "top-menu": {
+ "name": "top-menu",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "top-menu"
+ },
+ "typography": {
+ "name": "typography",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "typography"
+ },
+ "ui-elements": {
+ "name": "ui-elements",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "ui-elements"
+ },
+ "upload": {
+ "name": "upload",
+ "mixin": true,
+ "scss": true,
+ "js": true,
+ "docs": true,
+ "projectName": "style-guider-demo",
+ "longName": "upload"
+ }
+ }
}
}
\ No newline at end of file
diff --git a/README.md b/README.md
index a90c4bb..f784e38 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# style-guider-demo
+# Style Guider Demo
A web framework and style guide built with [Style Guider](https://www.npmjs.com/package/generator-style-guider)
@@ -45,3 +45,6 @@ yo style-guider:component
There are pre-commit and pre-push hooks for linting, and building the minified files in `dist/`
+## Incorporating this framework in other projects
+
+This project also acts as a web framework, with re-usable SCSS mixins, pug mixins and front-end javascript that can be included in other projects. Just add it as an npm dependency so it is stored in `node_modules` then the mixin endpoints (or minified dist files) will be available to your project code.
diff --git a/dist/style-guider-demo.min.css b/dist/style-guider-demo.min.css
index 0051ed1..edb5529 100644
--- a/dist/style-guider-demo.min.css
+++ b/dist/style-guider-demo.min.css
@@ -1 +1 @@
-main,.contain,.row{max-width:75rem;margin-right:auto;margin-left:auto;clear:both}main::before,main::after,.contain::before,.contain::after,.row::before,.row::after{display:table;content:' '}main::after,.contain::after,.row::after{clear:both}.nest{margin-right:-.625rem;margin-left:-.625rem;clear:both}@media print, screen and (min-width: 37.5em){.nest{margin-right:-.9375rem;margin-left:-.9375rem}}@media print, screen and (min-width: 56.25em){.nest{margin-right:-1.25rem;margin-left:-1.25rem}}/*! normalize-scss | MIT/GPLv2 License | bit.ly/normalize-scss */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:0.67em 0}figcaption,figure{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}main{display:block}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}input{overflow:visible}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{box-sizing:border-box;display:table;max-width:100%;padding:0;color:inherit;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}details{display:block}summary{display:list-item}menu{display:block}canvas{display:inline-block}template{display:none}[hidden]{display:none}.foundation-mq{font-family:"small=0em&medium=37.5em&large=56.25em&xlarge=75em&xxlarge=112.5em"}html{box-sizing:border-box;font-size:100%}*,*::before,*::after{box-sizing:inherit}body{margin:0;padding:0;background:#fefefe;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:normal;line-height:1.6;color:#474747;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle;max-width:100%;height:auto;-ms-interpolation-mode:bicubic}textarea{height:auto;min-height:50px;border-radius:0}select{box-sizing:border-box;width:100%;border-radius:0}.map_canvas img,.map_canvas embed,.map_canvas object,.mqa-display img,.mqa-display embed,.mqa-display object{max-width:none !important}button{padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;border-radius:0;background:transparent;line-height:1}[data-whatinput='mouse'] button{outline:0}pre{overflow:auto}.is-visible{display:block !important}.is-hidden{display:none !important}[type='text'],[type='password'],[type='date'],[type='datetime'],[type='datetime-local'],[type='month'],[type='week'],[type='email'],[type='number'],[type='search'],[type='tel'],[type='time'],[type='url'],[type='color'],textarea{display:block;box-sizing:border-box;width:100%;height:2.4375rem;margin:0 0 1rem;padding:.5rem;border:1px solid #bfbfbf;border-radius:0;background-color:#fbfbfb;box-shadow:inset 0 1px 2px rgba(53,54,47,0.1);font-family:inherit;font-size:1rem;font-weight:normal;color:#0a0a0a;transition:box-shadow 0.5s,border-color 0.25s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}[type='text']:focus,[type='password']:focus,[type='date']:focus,[type='datetime']:focus,[type='datetime-local']:focus,[type='month']:focus,[type='week']:focus,[type='email']:focus,[type='number']:focus,[type='search']:focus,[type='tel']:focus,[type='time']:focus,[type='url']:focus,[type='color']:focus,textarea:focus{outline:none;border:1px solid #7b7e84;background-color:#fefefe;box-shadow:0 0 5px rgba(102,102,102,0.3);transition:box-shadow 0.5s,border-color 0.25s ease-in-out}textarea{max-width:100%}textarea[rows]{height:auto}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#7b7e84}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#7b7e84}input::placeholder,textarea::placeholder{color:#7b7e84}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#c9c9c9;cursor:default}[type='submit'],[type='button']{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}input[type='search']{box-sizing:border-box}[type='file'],[type='checkbox'],[type='radio']{margin:0 0 1rem}[type='checkbox']+label,[type='radio']+label{display:inline-block;vertical-align:baseline;margin-left:.5rem;margin-right:1rem;margin-bottom:0}[type='checkbox']+label[for],[type='radio']+label[for]{cursor:pointer}label>[type='checkbox'],label>[type='radio']{margin-right:.5rem}[type='file']{width:100%}label{display:block;margin:0;font-size:1rem;font-weight:normal;line-height:1.8;color:#35362f}label.middle{margin:0 0 1rem;padding:.5625rem 0}.help-text{margin-top:-.5rem;font-size:.8125rem;font-style:italic;color:#0a0a0a}.input-group{display:table;width:100%;margin-bottom:1rem}.input-group>:first-child{border-radius:0 0 0 0}.input-group>:last-child>*{border-radius:0 0 0 0}.input-group-label,.input-group-field,.input-group-button,.input-group-button a,.input-group-button input,.input-group-button button,.input-group-button label{margin:0;white-space:nowrap;display:table-cell;vertical-align:middle}.input-group-label{padding:0 1rem;border:1px solid #666;background:#7b7e84;color:#0a0a0a;text-align:center;white-space:nowrap;width:1%;height:100%}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.input-group-field{border-radius:0;height:2.5rem}.input-group-button{padding-top:0;padding-bottom:0;text-align:center;width:1%;height:100%}.input-group-button a,.input-group-button input,.input-group-button button,.input-group-button label{height:2.5rem;padding-top:0;padding-bottom:0;font-size:1rem}.input-group .input-group-button{display:table-cell}fieldset{margin:0;padding:0;border:0}legend{max-width:100%;margin-bottom:.5rem}.fieldset{margin:1.125rem 0;padding:1.25rem;border:1px solid #666}.fieldset legend{margin:0;margin-left:-.1875rem;padding:0 .1875rem;background:#fefefe}select{height:2.4375rem;margin:0 0 1rem;padding:.5rem;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid #bfbfbf;border-radius:0;background-color:#fefefe;font-family:inherit;font-size:1rem;line-height:normal;color:#0a0a0a;background-image:url("data:image/svg+xml;utf8, ");background-origin:content-box;background-position:right -1rem center;background-repeat:no-repeat;background-size:9px 6px;padding-right:1.5rem;transition:box-shadow 0.5s,border-color 0.25s ease-in-out}@media screen and (min-width: 0\0){select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==")}}select:focus{outline:none;border:1px solid #7b7e84;background-color:#fefefe;box-shadow:0 0 5px rgba(102,102,102,0.3);transition:box-shadow 0.5s,border-color 0.25s ease-in-out}select:disabled{background-color:#c9c9c9;cursor:default}select::-ms-expand{display:none}select[multiple]{height:auto;background-image:none}.is-invalid-input:not(:focus){border-color:#e75113;background-color:#fcede7}.is-invalid-input:not(:focus)::-webkit-input-placeholder{color:#e75113}.is-invalid-input:not(:focus):-ms-input-placeholder{color:#e75113}.is-invalid-input:not(:focus)::placeholder{color:#e75113}.is-invalid-label{color:#e75113}.form-error{display:none;margin-top:-.5rem;margin-bottom:1rem;font-size:.75rem;font-weight:bold;color:#e75113}.form-error.is-visible{display:block}input+span,input+span+span,textarea+span,textarea+span+span,select+span,select+span+span,label+span,label+span+span,legend+span,legend+span+span,fieldset+span,fieldset+span+span{display:block;margin-top:-1.6rem;margin-bottom:1.6rem;color:#666;font-size:.75rem;font-style:italic}[for]{cursor:pointer}label+span,legend+span{margin-top:0;margin-bottom:0}.has-error input,.has-error textarea,.has-error select{border-color:#e75113}.has-error label,.has-error legend,.has-error .error-message{color:#e75113}.has-error [type=file]+label{color:#fefefe}.has-error [type='checkbox']+label,.has-error [type='radio']+label{color:#0a0a0a}.has-error .error-message{font-style:normal;font-weight:bold}[type='text'],[type='password'],[type='date'],[type='datetime'],[type='datetime-local'],[type='month'],[type='week'],[type='email'],[type='number'],[type='search'],[type='tel'],[type='time'],[type='url'],[type='color'],select,textarea,.input-group{max-width:43.75rem;margin-bottom:1.6rem}
+@import url("https://fonts.googleapis.com/css?family=Open+Sans|Varela+Round");.banner::after,footer::after,footer .top::after,menu::after,.tabs::after,.tabs>ul::after,.ui-datepicker::after{display:table;clear:both;content:''}a:focus{transition:text-shadow .2s ease-in;outline-offset:1px;text-shadow:rgba(123,126,132,0.5) 0 0 2px}[type='checkbox']:focus+label,[type='radio']:focus+label{text-decoration:underline}.skip-to-content a{position:absolute;top:-2.875rem;left:0;padding:.375rem .625rem;transition:top 1s ease-out;border-right:1px solid #fefefe;border-bottom:1px solid #fefefe;background:#992c0e;color:#fefefe;font-size:.75rem;z-index:100}.skip-to-content a:focus{top:0;transition:top .1s ease-in;outline:0;color:#fefefe;text-decoration:underline}/*! normalize-scss | MIT/GPLv2 License | bit.ly/normalize-scss */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:0.67em 0}figcaption,figure{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}main{display:block}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}input{overflow:visible}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{box-sizing:border-box;display:table;max-width:100%;padding:0;color:inherit;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}details{display:block}summary{display:list-item}menu{display:block}canvas{display:inline-block}template{display:none}[hidden]{display:none}.foundation-mq{font-family:"small=0em&medium=37.5em&large=56.25em&xlarge=75em&xxlarge=112.5em"}html{box-sizing:border-box;font-size:100%}*,*::before,*::after{box-sizing:inherit}body{margin:0;padding:0;background:#fefefe;font-family:"Open Sans",Helvetica,Arial,sans-serif;font-weight:normal;line-height:1.6;color:#474747;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle;max-width:100%;height:auto;-ms-interpolation-mode:bicubic}textarea{height:auto;min-height:50px;border-radius:0}select{box-sizing:border-box;width:100%;border-radius:0}.map_canvas img,.map_canvas embed,.map_canvas object,.mqa-display img,.mqa-display embed,.mqa-display object{max-width:none !important}button{padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;border-radius:0;background:transparent;line-height:1}[data-whatinput='mouse'] button{outline:0}pre{overflow:auto}.is-visible{display:block !important}.is-hidden{display:none !important}main,.contain,.row{max-width:75rem;margin-right:auto;margin-left:auto;clear:both}main::before,main::after,.contain::before,.contain::after,.row::before,.row::after{display:table;content:' '}main::after,.contain::after,.row::after{clear:both}.nest{margin-right:-.625rem;margin-left:-.625rem;clear:both}@media print, screen and (min-width: 37.5em){.nest{margin-right:-.9375rem;margin-left:-.9375rem}}@media print, screen and (min-width: 56.25em){.nest{margin-right:-1.25rem;margin-left:-1.25rem}}.full,.content,.sidebar{padding-top:1.5rem;padding-bottom:1.5rem}@media print, screen and (min-width: 37.5em){.full,.content,.sidebar{padding-top:2.25rem}}@media print, screen and (min-width: 56.25em){.full,.content,.sidebar{padding-top:3rem}}@media print, screen and (min-width: 37.5em){.full,.content,.sidebar{padding-bottom:2.25rem}}@media print, screen and (min-width: 56.25em){.full,.content,.sidebar{padding-bottom:3rem}}.full.no-pad,.content.no-pad,.sidebar.no-pad{padding-top:0;padding-bottom:0}.full.no-top-pad,.content.no-top-pad,.sidebar.no-top-pad{padding-top:0}.full.no-bottom-pad,.content.no-bottom-pad,.sidebar.no-bottom-pad{padding-bottom:0}.full{width:100%;float:left;padding-right:.625rem;padding-left:.625rem}@media print, screen and (min-width: 37.5em){.full{padding-right:.9375rem;padding-left:.9375rem}}@media print, screen and (min-width: 56.25em){.full{padding-right:1.25rem;padding-left:1.25rem}}.full:last-child:not(:first-child){float:right}.content{width:100%;float:left;padding-right:.625rem;padding-left:.625rem}@media print, screen and (min-width: 37.5em){.content{width:58.33333%;padding-right:.9375rem;padding-left:.9375rem}}@media print, screen and (min-width: 56.25em){.content{width:66.66667%;padding-right:1.25rem;padding-left:1.25rem}}@media print, screen and (min-width: 37.5em){.content{border-right:1px solid #eeeff0}.content.no-border{border:0}}.sidebar{width:100%;float:left;padding-right:.625rem;padding-left:.625rem}@media print, screen and (min-width: 37.5em){.sidebar{width:41.66667%;padding-right:.9375rem;padding-left:.9375rem}}@media print, screen and (min-width: 56.25em){.sidebar{width:33.33333%;padding-right:1.25rem;padding-left:1.25rem}}.breakout{margin-top:1.25rem;margin-right:calc(50% - 50vw);margin-bottom:1.25rem;margin-left:calc(50% - 50vw)}.half{width:100%;float:left;padding-right:.625rem;padding-left:.625rem}@media print, screen and (min-width: 37.5em){.half{width:50%;padding-right:.9375rem;padding-left:.9375rem}}@media screen and (min-width: 37.5em) and (max-width: 56.1875em){.half:nth-child(2n-1){clear:left}}@media print, screen and (min-width: 56.25em){.half{width:50%;padding-right:1.25rem;padding-left:1.25rem}}@media print, screen and (min-width: 56.25em){.half:nth-child(2n-1){clear:left}}.third{width:100%;float:left;padding-right:.625rem;padding-left:.625rem}@media print, screen and (min-width: 37.5em){.third{width:33.33333%;padding-right:.9375rem;padding-left:.9375rem}}@media screen and (min-width: 37.5em) and (max-width: 56.1875em){.third:nth-child(3n-2){clear:left}}@media print, screen and (min-width: 56.25em){.third{width:33.33333%;padding-right:1.25rem;padding-left:1.25rem}}@media print, screen and (min-width: 56.25em){.third:nth-child(3n-2){clear:left}}.quarter{width:50%;float:left;padding-right:.625rem;padding-left:.625rem}@media screen and (max-width: 37.4375em){.quarter:nth-child(2n-1){clear:left}}@media print, screen and (min-width: 37.5em){.quarter{width:25%;padding-right:.9375rem;padding-left:.9375rem}}@media screen and (min-width: 37.5em) and (max-width: 56.1875em){.quarter:nth-child(4n-3){clear:left}}@media print, screen and (min-width: 56.25em){.quarter{width:25%;padding-right:1.25rem;padding-left:1.25rem}}@media print, screen and (min-width: 56.25em){.quarter:nth-child(4n-3){clear:left}}.sixth{width:50%;float:left;padding-right:.625rem;padding-left:.625rem}@media screen and (max-width: 37.4375em){.sixth:nth-child(2n-1){clear:left}}@media print, screen and (min-width: 37.5em){.sixth{width:25%;padding-right:.9375rem;padding-left:.9375rem}}@media screen and (min-width: 37.5em) and (max-width: 56.1875em){.sixth:nth-child(4n-3){clear:left}}@media print, screen and (min-width: 56.25em){.sixth{width:16.66667%;padding-right:1.25rem;padding-left:1.25rem}}@media print, screen and (min-width: 56.25em){.sixth:nth-child(6n-5){clear:left}}:root{font-size:1.125rem}@media print, screen and (min-width: 37.5em){:root{font-size:1rem}}div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,dt,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}p{margin-bottom:1.6rem;font-size:inherit;line-height:1.6;text-rendering:optimizeLegibility}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:80%;line-height:inherit}h1,h2,h3,h4,h5,dt,h6{font-family:"Varela+Round",Arial,sans-serif;font-style:normal;font-weight:300;color:#2e7cac;text-rendering:optimizeLegibility}h1 small,h2 small,h3 small,h4 small,h5 small,dt small,h6 small{line-height:0;color:#666}h1{font-size:1.75rem;line-height:1.3;margin-top:0;margin-bottom:1.6rem}h2{font-size:1.5rem;line-height:1.3;margin-top:0;margin-bottom:1.6rem}h3{font-size:1.375rem;line-height:1.3;margin-top:0;margin-bottom:1.6rem}h4{font-size:1.25rem;line-height:1.3;margin-top:0;margin-bottom:1.6rem}h5,dt{font-size:1.1875rem;line-height:1.3;margin-top:0;margin-bottom:1.6rem}h6{font-size:1.125rem;line-height:1.3;margin-top:0;margin-bottom:1.6rem}@media print, screen and (min-width: 37.5em){h1{font-size:2.25rem}h2{font-size:1.875rem}h3{font-size:1.5rem}h4{font-size:1.25rem}h5,dt{font-size:1.125rem}h6{font-size:1rem}}a{line-height:inherit;color:#992c0e;text-decoration:none;cursor:pointer}a:hover,a:focus{color:#84260c}a img{border:0}hr{clear:both;max-width:75rem;height:0;margin:3.2rem auto 1.6rem;border-top:0;border-right:0;border-bottom:1px solid #eeeff0;border-left:0}ul,ol,dl{margin-bottom:1.6rem;list-style-position:outside;line-height:1.6}li{font-size:inherit}ul{margin-left:1.875rem;list-style-type:disc}ol{margin-left:1.875rem}ul ul,ol ul,ul ol,ol ol{margin-left:1.25rem;margin-bottom:0}dl{margin-bottom:1rem}dl dt{margin-bottom:.3rem;font-weight:300}blockquote{margin:0 0 1.6rem;padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #bfbfbf}blockquote,blockquote p{line-height:1.6;color:#666}cite{display:block;font-size:.8125rem;color:#666}cite:before{content:"— "}abbr{border-bottom:1px dotted #0a0a0a;color:#474747;cursor:help}figure{margin:0}code{padding:.0625rem .25rem .0625rem;border:1px solid #bfbfbf;background-color:#eeeff0;font-family:"Hack",Consolas,"Liberation Mono",Courier,monospace;font-weight:normal;color:#35362f}kbd{margin:0;padding:.125rem .25rem 0;background-color:#7b7e84;font-family:"Hack",Consolas,"Liberation Mono",Courier,monospace;color:#0a0a0a}.subheader{margin-top:.2rem;margin-bottom:.5rem;font-weight:normal;line-height:1.4;color:#35362f}.lead{font-size:125%;line-height:1.6}.stat{font-size:2.5rem;line-height:1}p+.stat{margin-top:-1rem}.no-bullet{margin-left:0;list-style:none}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}@media print, screen and (min-width: 37.5em){.medium-text-left{text-align:left}.medium-text-right{text-align:right}.medium-text-center{text-align:center}.medium-text-justify{text-align:justify}}@media print, screen and (min-width: 56.25em){.large-text-left{text-align:left}.large-text-right{text-align:right}.large-text-center{text-align:center}.large-text-justify{text-align:justify}}.show-for-print{display:none !important}@media print{*{background:transparent !important;box-shadow:none !important;color:black !important;text-shadow:none !important}.show-for-print{display:block !important}.hide-for-print{display:none !important}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}.ir a:after,a[href^='javascript:']:after,a[href^='#']:after{content:''}abbr[title]:after{content:" (" attr(title) ")"}pre,blockquote{border:1px solid #35362f;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}h1.heavy,h2.heavy,h3.heavy,h4.heavy,h5.heavy,dt.heavy,h6.heavy{font-weight:400}p{max-width:43.75rem}p:empty{display:none}main p+ul,main p+ol{margin-top:-1.3rem}main a:hover,main a:focus{text-decoration:underline}dd+dt{margin-top:1.6rem}blockquote{font-weight:400}.closeable{position:relative}.closeable .close{position:absolute;top:.25rem;right:.5rem;font-size:87.5%;text-decoration:none;cursor:pointer}.closeable .close::before{content:'× '}.show-for-sr,.show-on-focus{position:absolute !important;width:1px;height:1px;overflow:hidden;clip:rect(0, 0, 0, 0)}.message{display:block;position:relative;width:100%;padding:.5rem 1rem;border-bottom:1px solid #fefefe;background-color:#666;color:#fefefe}.message.alert{background-color:#992c0e}.message.warning{background-color:#ffd600;color:#0a0a0a}.message.warning a,.message.warning a:hover,.message.warning a:focus{color:#0a0a0a}.message>*:first-child{max-width:75rem;margin-right:auto;margin-left:auto;position:relative;margin-bottom:0;padding:0}.message>*:first-child::before,.message>*:first-child::after{display:table;content:' '}.message>*:first-child::after{clear:both}.message.has-close>*:first-child{padding-right:4.375rem}.message .close{position:absolute;top:50%;right:0;-ms-transform:translateY(-50%);transform:translateY(-50%);font-weight:bold;text-decoration:none;cursor:pointer}.message .close::before{content:'× '}.message a,.message a:hover,.message a:focus{color:#fefefe;font-weight:bold}.message a:hover,.message a:focus{text-decoration:underline}.callout{position:relative;margin:0 0 1.6rem 0;padding:1rem;border:1px solid rgba(10,10,10,0.25);border-radius:0;background-color:#fff;color:#474747}.callout>:first-child{margin-top:0}.callout>:last-child{margin-bottom:0}.callout.primary{background-color:#dcecf6;color:#474747}.callout.secondary{background-color:#fbd9d0;color:#474747}.callout.success{background-color:#c9fffd;color:#474747}.callout.warning{background-color:#fff9d9;color:#474747}.callout.alert{background-color:#fce5db;color:#474747}.callout.small{padding-top:.5rem;padding-right:.5rem;padding-bottom:.5rem;padding-left:.5rem}.callout.large{padding-top:3rem;padding-right:3rem;padding-bottom:3rem;padding-left:3rem}.callout{max-width:43.75rem}.callout.alert a,.callout.warning a{font-weight:bold}.callout.alert a{color:#82250c}.callout h5,.callout dt{color:#474747;font-weight:bold}noscript .alert{text-align:center}noscript .alert a{text-decoration:underline}.no-js .message .close{display:none}.banner{position:relative;width:100%;padding:0 1.5rem;border-top:2px solid #eeeff0;border-bottom:2px solid #eeeff0}.banner>div{position:relative;left:50%;padding:2.375rem 0;float:left;-ms-transform:translateX(-50%);transform:translateX(-50%)}.banner>div *{margin:0}.banner>div *:last-child{color:#992c0e;font-weight:normal}.banner.logo>div{padding-right:6.4375rem;background-image:url(node_modules/style-guider-demo/img/style-guider-demo-logo.png);background-repeat:no-repeat;background-position:right center;background-size:5.9375rem}.banner.center{text-align:center}.button,[type=submit],[type=file]+label,.login-go,button{display:inline-block;vertical-align:middle;margin:0 0 1.6rem 0;padding:0.85em 1em;-webkit-appearance:none;border:1px solid transparent;border-radius:0;transition:background-color 0.25s ease-out,color 0.25s ease-out;font-size:0.9rem;line-height:1;text-align:center;cursor:pointer;background-color:#2e7cac;color:#fefefe}[data-whatinput='mouse'] .button,[data-whatinput='mouse'] [type=submit],[data-whatinput='mouse'] [type=file]+label,[data-whatinput='mouse'] .login-go,[data-whatinput='mouse'] button{outline:0}.button:hover,[type=submit]:hover,[type=file]+label:hover,.login-go:hover,.button:focus,[type=submit]:focus,[type=file]+label:focus,.login-go:focus,button:hover,button:focus{background-color:#276992;color:#fefefe}.button:hover,[type=submit]:hover,[type=file]+label:hover,.login-go:hover,.button:focus,[type=submit]:focus,[type=file]+label:focus,.login-go:focus,button:hover,button:focus{text-decoration:none}.button.alert,.alert[type=submit],[type=file]+label.alert,.alert.login-go,button.alert{background-color:#992c0e;color:#fefefe}.button.alert:hover,.alert[type=submit]:hover,[type=file]+label.alert:hover,.alert.login-go:hover,.button.alert:focus,.alert[type=submit]:focus,[type=file]+label.alert:focus,.alert.login-go:focus,button.alert:hover,button.alert:focus{background-color:#82250c;color:#fefefe}.button.secondary,.secondary[type=submit],[type=file]+label,.secondary.login-go,button.secondary{background-color:#666;color:#fefefe}.button.secondary:hover,.secondary[type=submit]:hover,[type=file]+label:hover,.secondary.login-go:hover,.button.secondary:focus,.secondary[type=submit]:focus,[type=file]+label:focus,.secondary.login-go:focus,button.secondary:hover,button.secondary:focus{background-color:#575757;color:#fefefe}.button.large,.large[type=submit],[type=file]+label.large,.large.login-go,button.large{padding:1.0625rem 1.25rem;font-size:1.25rem}.button.expanded,.expanded[type=submit],[type=file]+label.expanded,.expanded.login-go,button.expanded{display:block;width:100%;margin-right:0;margin-left:0}.button.small,.small[type=submit],[type=file]+label.small,.small.login-go,button.small{padding:.4375rem .625rem}.button.tiny,.tiny[type=submit],[type=file]+label.tiny,.tiny.login-go,button.tiny{padding:.3125rem .375rem;font-size:.8125rem}.button:not(:last-child),[type=submit]:not(:last-child),[type=file]+label:not(:last-child),.login-go:not(:last-child),button:not(:last-child){margin-right:.75rem}.button[disabled],[disabled][type=submit],[type=file]+label[disabled],[disabled].login-go{background:#bfbfbf;cursor:not-allowed}.button[disabled]:hover,[disabled][type=submit]:hover,[type=file]+label[disabled]:hover,[disabled].login-go:hover{background:#bfbfbf}.card{display:block;padding:1.5rem}.card.flat{background-color:#eeeff0}.card.shadow{border:1px solid #eeeff0;background-color:#fefefe;box-shadow:0 0 6px 1px rgba(204,204,204,0.4)}.card>a{display:block;text-align:right}h1 a,h2 a,h3 a,h4 a,h5 a,dt a{color:#2e7cac}.meta,.meta a,time,time a{color:#666;font-size:.875rem;text-transform:uppercase}.banner{position:relative;width:100%;padding:0 1.5rem;border-top:2px solid #eeeff0;border-bottom:2px solid #eeeff0}.banner>div{position:relative;left:50%;padding:2.375rem 0;float:left;-ms-transform:translateX(-50%);transform:translateX(-50%)}.banner>div *{margin:0}.banner>div *:last-child{color:#992c0e;font-weight:normal}.banner.logo>div{padding-right:6.4375rem;background-image:url(node_modules/style-guider-demo/img/style-guider-demo-logo.png);background-repeat:no-repeat;background-position:right center;background-size:5.9375rem}.banner.center{text-align:center}footer{background-color:#184059;color:#fefefe;font-size:.875rem}footer ul{margin:0;list-style:none}footer a{color:#94caeb}footer a:hover,footer a:focus{color:#3999d4;text-decoration:underline}footer h1,footer h2,footer h3,footer h4{color:#fefefe}footer .top{padding:2.625rem 0;border-top:.9375rem solid #236085;background-color:#2e7cac}@media screen and (max-width: 56.1875em){footer .top nav:nth-of-type(3){float:right}}footer .top nav{width:50%;float:left;padding-right:.625rem;padding-left:.625rem}@media print, screen and (min-width: 37.5em){footer .top nav{width:25%;padding-right:.9375rem;padding-left:.9375rem}}@media print, screen and (min-width: 56.25em){footer .top nav{width:16.66667%;padding-right:1.25rem;padding-left:1.25rem}}@media screen and (max-width: 56.1875em){footer .top ul{margin-bottom:1.6rem}}footer aside{width:100%;float:left;padding-right:.625rem;padding-left:.625rem;border-right:3px solid #236085;border-left:3px solid #236085}@media print, screen and (min-width: 37.5em){footer aside{width:50%;padding-right:.9375rem;padding-left:.9375rem}}@media print, screen and (min-width: 56.25em){footer aside{width:33.33333%;padding-right:1.25rem;padding-left:1.25rem}}footer aside:first-child{border-left:0}footer aside:last-child{border-right:0}footer small{font-size:.625rem}footer nav h4{color:#94caeb;font-size:1.125rem;font-weight:bold;line-height:1}footer .middle{padding:1rem;background-color:#236085}footer .middle span{float:left}footer .middle nav{float:right}footer .middle li{display:inline;margin-right:1.3125rem}footer .bottom{padding:1rem 0;color:#3999d4;font-size:.6875rem;letter-spacing:.05px;text-align:center}footer .bottom p{max-width:none;margin-right:auto;margin-bottom:0;margin-left:auto}[type='text'],[type='password'],[type='date'],[type='datetime'],[type='datetime-local'],[type='month'],[type='week'],[type='email'],[type='number'],[type='search'],[type='tel'],[type='time'],[type='url'],[type='color'],textarea{display:block;box-sizing:border-box;width:100%;height:2.4375rem;margin:0 0 1rem;padding:.5rem;border:1px solid #bfbfbf;border-radius:0;background-color:#fbfbfb;box-shadow:inset 0 1px 2px rgba(53,54,47,0.1);font-family:inherit;font-size:1rem;font-weight:normal;color:#0a0a0a;transition:box-shadow 0.5s,border-color 0.25s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}[type='text']:focus,[type='password']:focus,[type='date']:focus,[type='datetime']:focus,[type='datetime-local']:focus,[type='month']:focus,[type='week']:focus,[type='email']:focus,[type='number']:focus,[type='search']:focus,[type='tel']:focus,[type='time']:focus,[type='url']:focus,[type='color']:focus,textarea:focus{outline:none;border:1px solid #7b7e84;background-color:#fefefe;box-shadow:0 0 5px rgba(102,102,102,0.3);transition:box-shadow 0.5s,border-color 0.25s ease-in-out}textarea{max-width:100%}textarea[rows]{height:auto}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#7b7e84}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#7b7e84}input::placeholder,textarea::placeholder{color:#7b7e84}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#c9c9c9;cursor:default}[type='submit'],[type='button']{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}input[type='search']{box-sizing:border-box}[type='file'],[type='checkbox'],[type='radio']{margin:0 0 1rem}[type='checkbox']+label,[type='radio']+label{display:inline-block;vertical-align:baseline;margin-left:.5rem;margin-right:1rem;margin-bottom:0}[type='checkbox']+label[for],[type='radio']+label[for]{cursor:pointer}label>[type='checkbox'],label>[type='radio']{margin-right:.5rem}[type='file']{width:100%}label{display:block;margin:0;font-size:1rem;font-weight:normal;line-height:1.8;color:#35362f}label.middle{margin:0 0 1rem;padding:.5625rem 0}.help-text{margin-top:-.5rem;font-size:.8125rem;font-style:italic;color:#0a0a0a}.input-group{display:table;width:100%;margin-bottom:1rem}.input-group>:first-child{border-radius:0 0 0 0}.input-group>:last-child>*{border-radius:0 0 0 0}.input-group-label,.input-group-field,.input-group-button,.input-group-button a,.input-group-button input,.input-group-button button,.input-group-button label{margin:0;white-space:nowrap;display:table-cell;vertical-align:middle}.input-group-label{padding:0 1rem;border:1px solid #666;background:#7b7e84;color:#0a0a0a;text-align:center;white-space:nowrap;width:1%;height:100%}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.input-group-field{border-radius:0;height:2.5rem}.input-group-button{padding-top:0;padding-bottom:0;text-align:center;width:1%;height:100%}.input-group-button a,.input-group-button input,.input-group-button button,.input-group-button label{height:2.5rem;padding-top:0;padding-bottom:0;font-size:1rem}.input-group .input-group-button{display:table-cell}fieldset{margin:0;padding:0;border:0}legend{max-width:100%;margin-bottom:.5rem}.fieldset{margin:1.125rem 0;padding:1.25rem;border:1px solid #666}.fieldset legend{margin:0;margin-left:-.1875rem;padding:0 .1875rem;background:#fefefe}select{height:2.4375rem;margin:0 0 1rem;padding:.5rem;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid #bfbfbf;border-radius:0;background-color:#fefefe;font-family:inherit;font-size:1rem;line-height:normal;color:#0a0a0a;background-image:url("data:image/svg+xml;utf8, ");background-origin:content-box;background-position:right -1rem center;background-repeat:no-repeat;background-size:9px 6px;padding-right:1.5rem;transition:box-shadow 0.5s,border-color 0.25s ease-in-out}@media screen and (min-width: 0\0){select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==")}}select:focus{outline:none;border:1px solid #7b7e84;background-color:#fefefe;box-shadow:0 0 5px rgba(102,102,102,0.3);transition:box-shadow 0.5s,border-color 0.25s ease-in-out}select:disabled{background-color:#c9c9c9;cursor:default}select::-ms-expand{display:none}select[multiple]{height:auto;background-image:none}.is-invalid-input:not(:focus){border-color:#e75113;background-color:#fcede7}.is-invalid-input:not(:focus)::-webkit-input-placeholder{color:#e75113}.is-invalid-input:not(:focus):-ms-input-placeholder{color:#e75113}.is-invalid-input:not(:focus)::placeholder{color:#e75113}.is-invalid-label{color:#e75113}.form-error{display:none;margin-top:-.5rem;margin-bottom:1rem;font-size:.75rem;font-weight:bold;color:#e75113}.form-error.is-visible{display:block}input+span,input+span+span,textarea+span,textarea+span+span,select+span,select+span+span,label+span,label+span+span,legend+span,legend+span+span,fieldset+span,fieldset+span+span{display:block;margin-top:-1.6rem;margin-bottom:1.6rem;color:#666;font-size:.75rem;font-style:italic}[for]{cursor:pointer}label+span,legend+span{margin-top:0;margin-bottom:0}legend{margin-bottom:0}fieldset{margin-bottom:1.6rem}fieldset label+span+.error-message{margin-top:0}fieldset>div{display:inline-block}fieldset.stack-list>div{display:block}[type=file]+label{position:relative;padding-left:2.25rem}[type=file]+label+span{margin-top:-1.6rem;margin-bottom:1.6rem}[type=file]+label::before{position:absolute;top:50%;left:1rem;width:0;height:0;-ms-transform:translateY(-50%);transform:translateY(-50%);border-width:0 5.5px 9px;border-style:solid;border-color:transparent transparent #fefefe;content:''}.has-error input,.has-error textarea,.has-error select{border-color:#992c0e}.has-error label,.has-error legend,.has-error .error-message{color:#992c0e}.has-error [type=file]+label{color:#fefefe}.has-error [type='checkbox']+label,.has-error [type='radio']+label{color:#0a0a0a}.has-error .error-message{font-style:normal;font-weight:bold}[type='text'],[type='password'],[type='date'],[type='datetime'],[type='datetime-local'],[type='month'],[type='week'],[type='email'],[type='number'],[type='search'],[type='tel'],[type='time'],[type='url'],[type='color'],select,textarea,.input-group{max-width:43.75rem;margin-bottom:1.6rem}[type='file'],[type='checkbox'],[type='radio']{margin-bottom:.6rem;cursor:pointer}[type='checkbox']+[for],[type='radio']+[for]{margin-left:0;padding-left:.5rem}.input-group input{margin-bottom:0}[type=file]{position:absolute !important;width:1px;height:1px;overflow:hidden;clip:rect(0, 0, 0, 0)}.hero{position:relative;width:100%;height:0;padding-bottom:66.67%;overflow:hidden}@media print, screen and (min-width: 37.5em){.hero{padding-bottom:45%}}@media print, screen and (min-width: 56.25em){.hero{padding-bottom:33%}}@media screen and (min-width: 75em){.hero{padding-bottom:30%}}@media screen and (min-width: 112.5em){.hero{padding-bottom:25%}}.hero>*{width:120%;max-width:120%}@media print, screen and (min-width: 37.5em){.hero>*{width:100%}}@media print, screen and (min-width: 37.5em){.hero>*{max-width:100%}}.hero.slim{padding-bottom:40%}@media print, screen and (min-width: 37.5em){.hero.slim{padding-bottom:30%}}@media print, screen and (min-width: 56.25em){.hero.slim{padding-bottom:25%}}.hero.outline::after{display:block;position:absolute;top:0;left:0;width:100%;height:100%;background-image:url(node_modules/style-guider-demo/img/hero-overlay.png);background-repeat:no-repeat;background-position:top center;content:''}@media screen and (max-width: 37.4375em){.hero.outline::after{background-size:auto 120%}}.hero.outline>*{display:block;width:75rem;margin-right:auto;margin-left:auto}menu+.hero{margin-top:-2.5rem}@media print, screen and (min-width: 37.5em){menu+.hero{margin-top:-1.25rem}}.quick{border-top:2px solid #eeeff0;border-bottom:2px solid #eeeff0}.quick ul{max-width:75rem;margin-right:auto;margin-left:auto;margin-bottom:1rem;padding-top:1rem;list-style:none}.quick ul::before,.quick ul::after{display:table;content:' '}.quick ul::after{clear:both}.quick ul>li{float:left;width:20%;padding-right:.625rem;padding-left:.625rem}@media print, screen and (min-width: 37.5em){.quick ul>li{padding-right:.9375rem;padding-left:.9375rem}}@media print, screen and (min-width: 56.25em){.quick ul>li{padding-right:1.25rem;padding-left:1.25rem}}.quick ul>li:nth-of-type(1n){clear:none}.quick ul>li:nth-of-type(5n+1){clear:both}.quick ul>li:last-child{float:left}.quick a:hover,.quick a:focus{outline-color:#992c0e;outline-offset:3px;outline-width:medium;color:#992c0e;text-decoration:none}.quick.six ul>li{float:left;width:16.66667%}.quick.six ul>li:nth-of-type(1n){clear:none}.quick.six ul>li:nth-of-type(6n+1){clear:both}.quick.six ul>li:last-child{float:left}.quick.four ul>li{float:left;width:25%}.quick.four ul>li:nth-of-type(1n){clear:none}.quick.four ul>li:nth-of-type(4n+1){clear:both}.quick.four ul>li:last-child{float:left}.quick li{padding-top:1rem;background-repeat:no-repeat;background-position:center bottom;background-size:5.9375rem}@media screen and (max-width: 37.4375em){.quick ul>li{float:left;width:33.33333%}.quick ul>li:nth-of-type(1n){clear:none}.quick ul>li:nth-of-type(3n+1){clear:both}.quick ul>li:last-child{float:left}.quick:not(.four):not(.six) li:nth-last-of-type(2){margin-left:16.66667%}.quick.six ul>li{float:left;width:33.33333%}.quick.six ul>li:nth-of-type(1n){clear:none}.quick.six ul>li:nth-of-type(3n+1){clear:both}.quick.six ul>li:last-child{float:left}.quick.four ul>li{float:left;width:50%}.quick.four ul>li:nth-of-type(1n){clear:none}.quick.four ul>li:nth-of-type(2n+1){clear:both}.quick.four ul>li:last-child{float:left}}.quick a{display:block;height:0;padding-bottom:8.125rem;color:#35362f;font-size:1.25rem;font-weight:300;line-height:1;text-align:center}@media print, screen and (min-width: 37.5em){.quick.vertical{border:0}.quick.vertical ul{margin-bottom:0;padding-top:0}.quick.vertical ul>li{float:left;width:100%}.quick.vertical ul>li:nth-of-type(1n){clear:none}.quick.vertical ul>li:nth-of-type(1n+1){clear:both}.quick.vertical ul>li:last-child{float:left}.quick.vertical li{padding:.25rem 0;background-position:left center;background-size:5rem}.quick.vertical a{height:auto;padding:2rem 1rem 2rem 6rem;text-align:left}}.tablet{background-image:url(node_modules/style-guider-demo/img/red-tablet.png)}.van{background-image:url(node_modules/style-guider-demo/img/red-van.png)}.map{background-image:url(node_modules/style-guider-demo/img/red-map.png)}.box{background-image:url(node_modules/style-guider-demo/img/red-box.png)}.laptop{background-image:url(node_modules/style-guider-demo/img/red-laptop.png)}.sub-menu{width:100%;border-top:1px solid #eeeff0;border-bottom:1px solid #eeeff0;background-color:#fefefe}.sub-menu ul{max-width:75rem;margin-right:auto;margin-left:auto;margin-bottom:0;list-style:none}.sub-menu ul::before,.sub-menu ul::after{display:table;content:' '}.sub-menu ul::after{clear:both}@media screen and (min-width: 75em){.sub-menu ul{border-left:1px solid #eeeff0}}.sub-menu li{float:left;border-right:1px solid #eeeff0}.sub-menu .active a{background-color:#eeeff0}.sub-menu a{display:block;padding:.5rem 1.75rem;background-color:#fefefe;color:#35362f}.sub-menu a:hover,.sub-menu a:focus{outline:none;background-color:#eeeff0;color:#35362f}table{width:100%;margin-bottom:1.6rem;border-radius:0}thead,tbody,tfoot{border:1px solid #f1f1f1;background-color:#fefefe}caption{padding:.5rem .625rem .625rem;font-weight:bold}thead{background:#f8f8f8;color:#474747}tfoot{background:#f1f1f1;color:#474747}thead tr,tfoot tr{background:transparent}thead th,thead td,tfoot th,tfoot td{padding:.5rem .625rem .625rem;font-weight:bold;text-align:left}tbody th,tbody td{padding:.5rem .625rem .625rem}tbody tr:nth-child(even){border-bottom:0;background-color:#f1f1f1}table.unstriped tbody{background-color:#fefefe}table.unstriped tbody tr{border-bottom:0;border-bottom:1px solid #f1f1f1;background-color:#fefefe}@media screen and (max-width: 56.1875em){table.stack thead{display:none}table.stack tfoot{display:none}table.stack tr,table.stack th,table.stack td{display:block}table.stack td{border-top:0}}table.scroll{display:block;width:100%;overflow-x:auto}table.hover thead tr:hover{background-color:#f3f3f3}table.hover tfoot tr:hover{background-color:#ececec}table.hover tbody tr:hover{background-color:#f9f9f9}table.hover:not(.unstriped) tr:nth-of-type(even):hover{background-color:#ececec}.table-scroll{overflow-x:auto}.table-scroll table{width:auto}@media screen and (max-width: 56.1875em){.stack tbody{border-bottom:0}.stack tr{padding:.375rem 0;border-bottom:1px solid #f1f1f1;background-color:#fefefe !important}.stack tr:nth-child(even){border-bottom:1px solid #f1f1f1}.stack [data-th]::before{display:block;font-size:.875rem;font-weight:bold;line-height:1;content:attr(data-th) ":"}.stack td .button,.stack td [type=submit],.stack td [type=file]+label,.stack td .login-go,.stack td button{margin-top:.5rem}.stack td:empty{display:none}}table .button,table [type=submit],table [type=file]+label,table .login-go,table button{margin-bottom:0}tr th{background-color:#f8f8f8}menu{position:relative;width:100%;min-height:2.625rem;margin:0 0 2.5rem;padding:0;background-color:#35362f;color:#fefefe}menu .logo-link{display:block;position:absolute;left:.5rem;width:6.25rem;height:6.25rem;padding:0;background-color:transparent;background-image:url("node_modules/style-guider-demo/img/style-guider-demo-logo.png");background-repeat:no-repeat;background-position:top left;background-size:100%;text-indent:-10000px;z-index:5}menu.safe-pad .logo-link{width:5rem;height:5rem}menu .toggle{display:none}menu .menu-link{display:block;position:relative;right:0;padding:.8125rem 2.375rem .8125rem .25rem;color:#fefefe;font-weight:bold;line-height:1;text-align:right;text-transform:uppercase;cursor:pointer}menu .menu-link:focus{outline:none;background:#4a4c42;text-decoration:underline}menu .menu-icon,menu .menu-icon::before,menu .menu-icon::after{display:block;position:absolute;width:1.5625rem;height:.25rem;border-radius:1px;background-color:#fefefe;content:'';cursor:pointer}menu .menu-icon{top:1.1875rem;right:.375rem}menu .menu-icon::before{top:-.5rem}menu .menu-icon::after{top:.5rem}menu a,menu a:hover,menu a:focus{color:#fefefe}menu a{display:block;padding:.8125rem 1.1875rem;transition:background .3s;background-color:#35362f;line-height:1}menu ul,menu ul ul{margin:0;list-style:none}menu.open .wrap>ul{display:block}@media screen and (max-width: 37.4375em){menu li{margin-top:-1px}menu li a:focus,menu .wrap>ul>li a:focus{outline:none;background-color:#7b7e84;text-decoration:underline;text-shadow:none}}menu ul ul li:not(:first-child){margin-top:-1px}menu .active ul .active a{color:#7b7e84}menu .wrap>ul{display:none}menu .wrap>ul li{text-align:right}@media screen and (max-width: 37.4375em){menu .wrap>ul>li.down a{background-color:#404139}}menu .wrap>ul>li ul{display:none;position:relative;top:-100%}menu .wrap>ul>li.down ul{display:block}@media screen and (max-width: 37.4375em){menu .wrap>ul>li.down ul a{padding:.5rem 2.25rem .5rem 1.3125rem;font-size:.875rem}}@media print, screen and (min-width: 37.5em){menu{margin:0 0 1.25rem}menu .logo-link{top:1rem;right:1rem;left:auto;width:7.5rem;height:7.5rem}menu.safe-pad .logo-link{top:.5rem;right:.5rem;width:5.625rem;height:5.625rem}menu li a{display:block;text-align:left}menu li a:hover,menu li a:focus{outline:none;background-color:#7b7e84;text-decoration:underline;text-shadow:none}menu .active ul .active a{color:#fefefe}menu .active>a,menu .active>a:hover,menu .active>a:focus{background-color:#2e7cac}menu .menu-link,menu .menu-icon{display:none}menu .wrap{max-width:75rem;margin-right:auto;margin-left:auto;position:relative;padding-right:7.25rem}menu .wrap::before,menu .wrap::after{display:table;content:' '}menu .wrap::after{clear:both}menu .wrap>ul{display:block}menu .wrap>ul>li{position:relative;float:left;border-right:1px solid #fefefe}menu .wrap>ul>li.down ul{display:block}menu .wrap>ul>li ul{display:none;position:absolute;top:100%;right:auto;left:0;margin-left:-1px;border:1px solid #fefefe;list-style:none;z-index:1}menu .has-dropdown>a{padding-right:1.5rem}menu .has-dropdown>a::after{display:block;position:absolute;top:50%;right:.625rem;width:0;height:0;margin-top:-.0625rem;border:inset .25rem;border-bottom-width:0;border-top-style:solid;border-color:#fefefe transparent transparent;content:''}}@media print, screen and (min-width: 56.25em){menu .wrap{padding-right:10rem}menu .logo-link{width:9rem;height:9rem}menu.safe-pad+*{margin-top:1.875rem}menu.safe-pad .logo-link{width:6.25rem;height:6.25rem}}@media screen and (min-width: 75em){menu .wrap>ul>li:first-child{border-left:1px solid #fefefe}}.no-js .has-dropdown>a:focus+ul,.no-js .has-dropdown:hover ul{display:block}@media screen and (max-width: 37.4375em){.no-js .menu-link:focus+ul,.no-js .menu-link:focus+ul ul,.no-js .menu-link:hover+ul,.no-js .menu-link:hover+ul ul{display:block}.no-js menu ul:hover,.no-js menu ul:hover ul{display:block}.no-js menu ul ul a{padding:.5rem 2.25rem .5rem 1.3125rem;background-color:#404139;font-size:.875rem}}.login-page{position:relative;min-height:100vh;background-color:#2e7cac}.login{max-width:90%;position:absolute;top:50%;left:50%;width:100%;padding:1.5rem;-ms-transform:translateY(-50%) translateX(-50%);transform:translateY(-50%) translateX(-50%);background-color:#fefefe}@media print, screen and (min-width: 37.5em){.login{max-width:25rem}}.login-go{width:100%}.login-signup{margin-top:1rem;padding-top:1rem;border-top:1px solid #eeeff0;text-align:center}.login-signup :last-child{margin-bottom:0}.pagination{margin-left:0;margin-bottom:1.6rem}.pagination::before,.pagination::after{display:table;content:' '}.pagination::after{clear:both}.pagination li{margin-right:.0625rem;border-radius:0;font-size:.9375rem;display:none}.pagination li:last-child,.pagination li:first-child{display:inline-block}.pagination li.current{display:inline-block}@media print, screen and (min-width: 37.5em){.pagination li{display:inline-block}}.pagination a,.pagination button{display:block;padding:.1875rem .625rem;border-radius:0;color:#35362f}.pagination a:hover,.pagination button:hover{background:none}.pagination .current{padding:.1875rem .625rem;background:#2b5582;color:#fefefe;cursor:default}.pagination .disabled{padding:.1875rem .625rem;color:#bfbfbf;cursor:not-allowed}.pagination .disabled:hover{background:transparent}.pagination .ellipsis::after{padding:.1875rem .625rem;content:'\2026';color:#0a0a0a}.pagination-previous a::before,.pagination-previous.disabled::before{display:inline-block;margin-right:0.5rem;content:'\00ab'}.pagination-next a::after,.pagination-next.disabled::after{display:inline-block;margin-left:0.5rem;content:'\00bb'}.pagination{text-align:center}.pagination a:hover,.pagination button:hover{color:#992c0e}.pagination a:focus{outline-offset:-3px}.breadcrumbs{margin:0 0 1.6rem 0;list-style:none}.breadcrumbs::before,.breadcrumbs::after{display:table;content:' '}.breadcrumbs::after{clear:both}.breadcrumbs li{float:left;font-size:.75rem;color:#35362f;cursor:default}.breadcrumbs li:not(:last-child)::after{position:relative;top:1px;margin:0 .75rem;opacity:1;content:"/";color:#666}.breadcrumbs a{color:#2e7cac}.breadcrumbs a:hover{text-decoration:underline}.breadcrumbs .disabled{color:#666;cursor:not-allowed}.tabs{margin-bottom:1.6rem}.tabs .active a:focus{outline:none}.tabs>ul{width:100%;margin:0;border-bottom:1px solid #bfbfbf;list-style:none}.tabs>ul a:focus{text-shadow:none}.tabs>ul li{padding:.1875rem .5rem;display:inline-block;position:relative;bottom:0;margin-top:.375rem;margin-right:-1px;float:left;border:1px solid #bfbfbf;border-bottom:0;background-color:#eeeff0}@media print, screen and (min-width: 37.5em){.tabs>ul li{padding:.25rem .625rem}}@media print, screen and (min-width: 56.25em){.tabs>ul li{padding:.3125rem .75rem}}.tabs>ul .active{padding:.375rem .875rem .25rem;position:relative;bottom:-3px;margin-top:0;border-bottom:1px solid #fefefe;background-color:#fefefe}@media print, screen and (min-width: 37.5em){.tabs>ul .active{padding:.4375rem 1rem .3125rem}}@media print, screen and (min-width: 56.25em){.tabs>ul .active{padding:.5625rem 1.125rem .3125rem}}.tabs>ul a{display:block;color:#2e7cac}.tabs .panel{width:100%;float:left;padding-right:.625rem;padding-left:.625rem;display:none;padding-top:1.25rem;padding-bottom:2.5rem;border:1px solid #bfbfbf;border-top-width:0}@media print, screen and (min-width: 37.5em){.tabs .panel{padding-right:.9375rem;padding-left:.9375rem}}@media print, screen and (min-width: 56.25em){.tabs .panel{padding-right:1.25rem;padding-left:1.25rem}}.tabs .panel:last-child:not(:first-child){float:right}.tabs .panel.active{display:block}.tabs .panel>:last-child{margin-bottom:0}.no-js .tabs>ul{margin-bottom:1rem;border-bottom-width:0}.no-js .tabs li{border:1px solid #bfbfbf}.no-js .panel{display:block;margin-bottom:1rem;border-top-width:1px}.hasDatepicker{padding-left:2rem;background-image:url(node_modules/style-guider-demo/img/calendar.png);background-repeat:no-repeat;background-position:left .5rem center;cursor:pointer}.hasDatepicker:focus{background-image:url(node_modules/style-guider-demo/img/calendar-focus.png)}.ui-datepicker{display:none;width:21.875rem;max-width:100%;padding-top:.5rem;padding-bottom:.5rem}.ui-datepicker table{margin-bottom:0}.ui-datepicker th{background-color:#fefefe;text-align:center}.ui-datepicker td{width:14.285%;text-align:center}.ui-datepicker td.ui-datepicker-current-day{border-width:3px;border-style:solid;border-color:#7b7e84;font-weight:bold}.ui-datepicker a{line-height:1.125rem}.ui-datepicker a:hover,.ui-datepicker a:focus{font-weight:bold}.ui-datepicker tr:nth-child(odd){background:#d8d8d8}.ui-datepicker-other-month{background-color:#fefefe}.ui-datepicker-header,.ui-datepicker-calendar{padding:.5rem .5rem;background-color:#fefefe;box-shadow:0 0 5px rgba(102,102,102,0.3)}.ui-datepicker-header{background-color:#c44927}.ui-datepicker-calendar{padding-top:0;border-width:1px;border-style:solid;border-color:#7b7e84;border-top-color:#bfbfbf}.ui-datepicker-prev,.ui-datepicker-next{width:50%;float:left;color:#fefefe;font-weight:normal}.ui-datepicker-prev:hover,.ui-datepicker-prev:focus,.ui-datepicker-next:hover,.ui-datepicker-next:focus{color:#fefefe;font-weight:normal;text-decoration:underline}.ui-datepicker-next{text-align:right}.ui-datepicker-title{width:100%;color:#fefefe;font-size:1.25rem;font-weight:bold;text-align:center}progress{display:block;width:100%;height:1.25rem;margin-bottom:1.6rem;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0;border:0;background:#bfbfbf}progress::-webkit-progress-bar{background:#bfbfbf;border-radius:0}progress::-webkit-progress-value{background:#2e7cac;border-radius:0}progress::-moz-progress-bar{background:#2e7cac;border-radius:0}progress.primary{color:#2e7cac}progress.primary::-webkit-progress-value{background:#2e7cac}progress.primary::-moz-progress-bar{background:#2e7cac}progress.secondary{color:#992c0e}progress.secondary::-webkit-progress-value{background:#992c0e}progress.secondary::-moz-progress-bar{background:#992c0e}progress.success{color:#009893}progress.success::-webkit-progress-value{background:#009893}progress.success::-moz-progress-bar{background:#009893}progress.warning{color:#ffd600}progress.warning::-webkit-progress-value{background:#ffd600}progress.warning::-moz-progress-bar{background:#ffd600}progress.alert{color:#e75113}progress.alert::-webkit-progress-value{background:#e75113}progress.alert::-moz-progress-bar{background:#e75113}progress::-ms-fill{border-radius:0;border:0}progress[value]{cursor:progress}.show-percent{position:relative;padding-right:3rem}.show-percent::after{display:block;position:absolute;top:0;right:0;width:3rem;height:1.25rem;padding-right:.5rem;padding-left:.5rem;background:#7b7e84;color:#fefefe;font-size:.75rem;font-weight:bold;text-align:center;content:attr(value) "%"}.loading{position:relative}.loading::before{display:block;position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(254,254,254,0.66);background-image:url(node_modules/style-guider-demo/img/loading.gif);background-repeat:no-repeat;background-position:center top 30%;content:'';z-index:10}.loading.blackout::before{background-color:#fefefe}
diff --git a/dist/style-guider-demo.min.js b/dist/style-guider-demo.min.js
index 306286d..1229031 100644
--- a/dist/style-guider-demo.min.js
+++ b/dist/style-guider-demo.min.js
@@ -1 +1 @@
-$(document).ready(function(){$(document).on("click",".message .close",function(e){e.preventDefault(),$(this).closest(".message").slideUp(),e.stopPropagation()})});
\ No newline at end of file
+$(document).ready(function(){$(document).on("click",".message .close",function(t){t.preventDefault(),$(this).closest(".message").slideUp(),t.stopPropagation()})}),$(document).ready(function(){$(document).on("click",".closeable .close",function(t){t.preventDefault(),$(this).closest(".closeable").slideUp(),t.stopPropagation()})}),$(document).ready(function(){$("input[data-datepicker]").each(function(){$(this).attr("type","text"),$(this).datepicker({dateFormat:"yy-mm-dd",firstDay:1})})}),$(document).ready(function(){$("html").removeClass("no-js"),$("html").addClass("js")}),$(document).ready(function(){$(document).on("click",".tabs a[data-tab]",function(t){t.preventDefault();var e=$(this).attr("data-tab"),s=$(this).closest(".tabs");s.find("li").removeClass("active"),s.find(".panel").removeClass("active"),$(this).closest("li").addClass("active"),s.find(".panel[data-tab="+e+"]").addClass("active")})}),$(document).ready(function(){$(document).find("table.stack").each(function(){var t=[];$(this).find("th").each(function(e){t.push($(this).text())}),$(this).find("tbody tr").each(function(){$(this).find("td").each(function(e){$(this).attr("data-th",t[e])})})})}),$(document).ready(function(){$(document).on("click",".menu-link",function(t){t.preventDefault(),$(this).closest("menu").toggleClass("open"),t.stopPropagation()}),$(document).on("click",".has-dropdown > a",function(t){t.preventDefault(),$(document).find("menu ul li").removeClass("down"),$(this).closest("li").addClass("down"),t.stopPropagation()}),$(document).on("focusin","menu > .wrap > ul > li > a",function(){$(this).on("keydown",function(t){40===t.keyCode||32===t.keyCode?(t.preventDefault(),$(this).closest("li").hasClass("has-dropdown")&&($(this).click(),$(this).closest("li").find("ul li:first-child a").focus())):37===t.keyCode?(t.preventDefault(),$(this).closest("li").prev().length&&$(this).closest("li").prev().find("a").focus()):39===t.keyCode&&(t.preventDefault(),$(this).closest("li").next().length&&$(this).closest("li").next().find("a").focus())})}),$(document).on("focusin","menu ul ul a",function(){$(this).on("keydown",function(t){27===t.keyCode||38===t.keyCode&&$(this).closest("li").is(":first-child")?(t.preventDefault(),$(document).find("menu ul li").removeClass("down"),$(this).closest(".has-dropdown").find("a").focus()):37===t.keyCode?(t.preventDefault(),$(document).find("menu ul li").removeClass("down"),$(this).closest(".has-dropdown").prev().hasClass("has-dropdown")?($(this).closest(".has-dropdown").prev().find("> a").click(),$(this).closest(".has-dropdown").prev().find("ul li:first-child a").focus()):$(this).closest(".has-dropdown").prev().length?$(this).closest(".has-dropdown").prev().find("> a").focus():$(this).closest(".has-dropdown").find("> a").focus()):39===t.keyCode||40===t.keyCode&&$(this).closest("li").is(":last-child")?(t.preventDefault(),$(document).find("menu ul li").removeClass("down"),$(this).closest(".has-dropdown").next().hasClass("has-dropdown")?($(this).closest(".has-dropdown").next().find("> a").click(),$(this).closest(".has-dropdown").next().find("ul li:first-child a").focus()):$(this).closest(".has-dropdown").next().length?$(this).closest(".has-dropdown").next().find("> a").focus():$(this).closest(".has-dropdown").find("> a").focus()):38===t.keyCode?(t.preventDefault(),$(this).closest("li").prev().find("a").focus()):40===t.keyCode&&(t.preventDefault(),$(this).closest("li").next().find("a").focus())})}),$(document).on("focusout","menu a",function(){$(this).off("keydown")}),$(document).on("click",function(){$(document).find("menu").removeClass("open"),$(document).find("menu ul li").removeClass("down")})});
\ No newline at end of file
diff --git a/docs/pug/docs.pug b/docs/pug/docs.pug
index 2669051..aaffb7f 100644
--- a/docs/pug/docs.pug
+++ b/docs/pug/docs.pug
@@ -23,24 +23,14 @@ html.no-js(lang='en')
body
if options && options.skipLink
+skip-link
- if options && options.noScript
- +noscript
+
+ //- Custom top menu component
+ +top-menu(menuLinks)
main#content
- h3 Menu
- ul(role='navigation')
- each item in menuLinks
- - var classes = ''
- - classes = classes + (item.children ? 'has-dropdown' : '')
- - classes = classes + (item.active ? ' active' : '')
- li(class=classes)
- a(href=item.link ? item.link : '#', tabindex=0)= item.label
- if item.children
- ul(role='menu')
- each child in item.children
- li(class=child.active ? 'active' : null)
- a(href=child.link, role='menuitem')= child.label
+ if options && options.noScript
+ +noscript
.full
h1#root #{meta.title} #[small= version]
diff --git a/docs/scss/_swatches.scss b/docs/scss/_swatches.scss
new file mode 100644
index 0000000..4139e0a
--- /dev/null
+++ b/docs/scss/_swatches.scss
@@ -0,0 +1,49 @@
+.swatches {
+ @extend %clearfix;
+ @include grid-layout(5, '*', rem-calc(15));
+ margin-bottom: 1.6rem;
+
+ > * {
+ @include rprop('font-size', .6rem, .9rem, 1rem);
+ display: block;
+ height: 0;
+ padding-top: calc(10% - 1em);
+ padding-bottom: calc(10% + 1em);
+ background-color: $black;
+ color: $white;
+ font-family: $font-family-monospace;
+ text-align: center;
+ text-transform: lowercase;
+
+ &::before {
+ content: '$';
+ }
+ }
+
+ &.big {
+ @include grid-layout(3, '*', rem-calc(15));
+
+ > * {
+ padding-top: calc(16.66% - 1em);
+ padding-bottom: calc(16.66% + 1em);
+ font-size: 1.2rem;
+
+ }
+ }
+
+
+ // sass-lint:disable one-declaration-per-line
+ .red { background-color: $red; }
+ .blue { background-color: $blue; }
+ .claret { background-color: $claret; }
+ .flame { background-color: $flame; }
+ .carrot { background-color: $carrot; }
+ .buttercup { background-color: $buttercup; }
+ .sunglow { background-color: $sunglow; color: $black;}
+ .malibu { background-color: $malibu; color: $black;}
+ .bermuda { background-color: $bermuda; color: $black; }
+ .java { background-color: $java; }
+ .verdun { background-color: $verdun; }
+ .grey { background-color: $grey; }
+
+}
diff --git a/docs/scss/docs.scss b/docs/scss/docs.scss
index 3407043..21108c7 100644
--- a/docs/scss/docs.scss
+++ b/docs/scss/docs.scss
@@ -22,4 +22,5 @@ $img-path: '../../img/';
// ------------------------
@import 'code';
+@import 'swatches';
@import 'gist';
diff --git a/js/components/_example.js b/js/components/alert.js
similarity index 83%
rename from js/components/_example.js
rename to js/components/alert.js
index 130e33b..955ced5 100644
--- a/js/components/_example.js
+++ b/js/components/alert.js
@@ -1,11 +1,12 @@
$(document).ready(function () {
- /**
- * Close an alert message when its close
- * link is clicked
- */
- $(document).on('click', '.message .close', function (e) {
- e.preventDefault()
- $(this).closest('.message').slideUp()
- e.stopPropagation()
- })
+ /**
+ * Close an alert message when its close
+ * link is clicked
+ * No JS Fallback: ✅ // Don't show close button
+ */
+ $(document).on('click', '.message .close', function (e) {
+ e.preventDefault()
+ $(this).closest('.message').slideUp()
+ e.stopPropagation()
+ })
})
diff --git a/js/components/closeable.js b/js/components/closeable.js
new file mode 100644
index 0000000..a8ec31c
--- /dev/null
+++ b/js/components/closeable.js
@@ -0,0 +1,12 @@
+$(document).ready(function () {
+ /**
+ * Close an element when its close button is clicked
+ * link is clicked
+ * No JS Fallback: ✅ // Don't show close button
+ */
+ $(document).on('click', '.closeable .close', function (e) {
+ e.preventDefault()
+ $(this).closest('.closeable').slideUp()
+ e.stopPropagation()
+ })
+})
diff --git a/js/components/datepicker.js b/js/components/datepicker.js
new file mode 100644
index 0000000..236cfb1
--- /dev/null
+++ b/js/components/datepicker.js
@@ -0,0 +1,12 @@
+$(document).ready(function () {
+ /**
+ * Convert date input fields to jQuery UI datepicker
+ */
+ $('input[data-datepicker]').each(function () {
+ $(this).attr('type', 'text')
+ $(this).datepicker({
+ dateFormat: 'yy-mm-dd',
+ firstDay: 1
+ })
+ })
+})
diff --git a/js/components/no-js.js b/js/components/no-js.js
new file mode 100644
index 0000000..b89c907
--- /dev/null
+++ b/js/components/no-js.js
@@ -0,0 +1,10 @@
+$(document).ready(function () {
+ /**
+ * Detect js and change class of HTML element so we can
+ * apply different styles for users with javascript disabled.
+ * This can also be done with some inline vanilla js in the
+ * for quicker resolution to stop FOUC.
+ */
+ $('html').removeClass('no-js')
+ $('html').addClass('js')
+})
diff --git a/js/components/tab.js b/js/components/tab.js
new file mode 100644
index 0000000..528aed2
--- /dev/null
+++ b/js/components/tab.js
@@ -0,0 +1,17 @@
+$(document).ready(function () {
+ /**
+ * Switch Tabs based on click
+ * No JS Fallback: ✅
+ */
+ $(document).on('click', '.tabs a[data-tab]', function (e) {
+ e.preventDefault()
+ var selected = $(this).attr('data-tab')
+ var $tabs = $(this).closest('.tabs')
+
+ $tabs.find('li').removeClass('active')
+ $tabs.find('.panel').removeClass('active')
+
+ $(this).closest('li').addClass('active')
+ $tabs.find('.panel[data-tab=' + selected + ']').addClass('active')
+ })
+})
diff --git a/js/components/table.js b/js/components/table.js
new file mode 100644
index 0000000..d2845a5
--- /dev/null
+++ b/js/components/table.js
@@ -0,0 +1,21 @@
+$(document).ready(function () {
+ /**
+ * Add th attributes to all stacked tables
+ * so that the css can make them display
+ * titles for each cell in stacked view
+ * No JS Fallback: ✅ // Remove function
+ */
+ $(document).find('table.stack').each(function () {
+ var titles = []
+
+ $(this).find('th').each(function (index) {
+ titles.push($(this).text())
+ })
+
+ $(this).find('tbody tr').each(function () {
+ $(this).find('td').each(function (index) {
+ $(this).attr('data-th', titles[index])
+ })
+ })
+ })
+})
diff --git a/js/components/top-menu.js b/js/components/top-menu.js
new file mode 100644
index 0000000..a7cb65e
--- /dev/null
+++ b/js/components/top-menu.js
@@ -0,0 +1,115 @@
+$(document).ready(function () {
+ /**
+ * Toggle the parent main menu open
+ * when a menu toggle link is clicked
+ * No JS Fallback: ✅
+ */
+ $(document).on('click', '.menu-link', function (e) {
+ e.preventDefault()
+ $(this).closest('menu').toggleClass('open')
+ e.stopPropagation()
+ })
+
+ /**
+ * When a main menu drop down is clicked,
+ * add class 'down' to show child menu
+ * No JS Fallback: ✅
+ */
+ $(document).on('click', '.has-dropdown > a', function (e) {
+ e.preventDefault()
+ $(document).find('menu ul li').removeClass('down')
+ $(this).closest('li').addClass('down')
+ e.stopPropagation()
+ })
+
+ /**
+ * Top menu keyboard controls. Use ⬆️⬇️⬅️➡️ space esc to navigate the menu
+ */
+
+ // Top Level keybindings
+ $(document).on('focusin', 'menu > .wrap > ul > li > a', function () {
+ $(this).on('keydown', function (e) {
+ // Down and space - open child menu and focus on first item
+ if (e.keyCode === 40 || e.keyCode === 32) {
+ e.preventDefault()
+ if ($(this).closest('li').hasClass('has-dropdown')) {
+ $(this).click()
+ $(this).closest('li').find('ul li:first-child a').focus()
+ }
+
+ // Left and right, focus on prev or next top level item
+ } else if (e.keyCode === 37) {
+ e.preventDefault()
+ if ($(this).closest('li').prev().length) {
+ $(this).closest('li').prev().find('a').focus()
+ }
+ } else if (e.keyCode === 39) {
+ e.preventDefault()
+ if ($(this).closest('li').next().length) {
+ $(this).closest('li').next().find('a').focus()
+ }
+ }
+ })
+ })
+
+ // Sub menu keybindings
+ $(document).on('focusin', 'menu ul ul a', function () {
+ $(this).on('keydown', function (e) {
+ // Esc and up (if top item)
+ if (e.keyCode === 27 || (e.keyCode === 38 && $(this).closest('li').is(':first-child'))) {
+ e.preventDefault()
+ $(document).find('menu ul li').removeClass('down')
+ $(this).closest('.has-dropdown').find('a').focus()
+
+ // Left and right, focus on prev or next top level item
+ } else if (e.keyCode === 37) {
+ e.preventDefault()
+ $(document).find('menu ul li').removeClass('down')
+ if ($(this).closest('.has-dropdown').prev().hasClass('has-dropdown')) {
+ $(this).closest('.has-dropdown').prev().find('> a').click()
+ $(this).closest('.has-dropdown').prev().find('ul li:first-child a').focus()
+ } else if ($(this).closest('.has-dropdown').prev().length) {
+ $(this).closest('.has-dropdown').prev().find('> a').focus()
+ } else {
+ $(this).closest('.has-dropdown').find('> a').focus()
+ }
+
+ // or down if last sub item
+ } else if (e.keyCode === 39 || (e.keyCode === 40 && $(this).closest('li').is(':last-child'))) {
+ e.preventDefault()
+ $(document).find('menu ul li').removeClass('down')
+ if ($(this).closest('.has-dropdown').next().hasClass('has-dropdown')) {
+ $(this).closest('.has-dropdown').next().find('> a').click()
+ $(this).closest('.has-dropdown').next().find('ul li:first-child a').focus()
+ } else if ($(this).closest('.has-dropdown').next().length) {
+ $(this).closest('.has-dropdown').next().find('> a').focus()
+ } else {
+ $(this).closest('.has-dropdown').find('> a').focus()
+ }
+
+ // Up and down for prev and next child item
+ } else if (e.keyCode === 38) {
+ e.preventDefault()
+ $(this).closest('li').prev().find('a').focus()
+ } else if (e.keyCode === 40) {
+ e.preventDefault()
+ $(this).closest('li').next().find('a').focus()
+ }
+ })
+ })
+
+ // Cancel all keybindings
+ $(document).on('focusout', 'menu a', function () {
+ $(this).off('keydown')
+ })
+
+ /**
+ * When anything other than the menu is
+ * clicked, close the menu
+ * No JS Fallback: ✅
+ */
+ $(document).on('click', function () {
+ $(document).find('menu').removeClass('open')
+ $(document).find('menu ul li').removeClass('down')
+ })
+})
diff --git a/pug/_mixins.pug b/pug/_mixins.pug
index 2d75c86..9f90442 100644
--- a/pug/_mixins.pug
+++ b/pug/_mixins.pug
@@ -4,6 +4,25 @@ include meta/_meta-social.pug
include meta/_no-script.pug
include meta/_skip-link.pug
-include components/_example.pug
+include components/_alert.pug
+include components/_banner.pug
+include components/_callout.pug
+include components/_breadcrumbs.pug
+include components/_card.pug
+include components/_checkbox.pug
+include components/_hero.pug
+include components/_hidden.pug
+include components/_input.pug
+include components/_pagination.pug
+include components/_quick-links.pug
+include components/_radio.pug
+include components/_select.pug
+include components/_sub-menu.pug
+include components/_submit.pug
+include components/_tab.pug
+include components/_textarea.pug
+include components/_top-menu.pug
+include components/_upload.pug
+
//------ yeoman hook ------ //
//- NB! The above line is required for our yeoman generator and should not be changed.
diff --git a/pug/components/_alert.pug b/pug/components/_alert.pug
new file mode 100644
index 0000000..2a4cdfd
--- /dev/null
+++ b/pug/components/_alert.pug
@@ -0,0 +1,8 @@
+mixin alert(type, close)
+ - var classes = type
+ - classes = classes + (close ? ' has-close' : '')
+ section.message(class=classes, role='status')&attributes(attributes)
+ p
+ block
+ if close
+ a.close(tabindex=0, href='#') Close
diff --git a/pug/components/_banner.pug b/pug/components/_banner.pug
new file mode 100644
index 0000000..da6446a
--- /dev/null
+++ b/pug/components/_banner.pug
@@ -0,0 +1,8 @@
+mixin banner(heading, subHeading, logo, center)
+ - var classes = ''
+ - classes = classes + (logo ? 'logo ' : '')
+ - classes = classes + (center ? 'center ' : '')
+ section.banner(class=classes)&attributes(attributes)
+ div
+ h2= heading
+ h3= subHeading
diff --git a/pug/components/_breadcrumbs.pug b/pug/components/_breadcrumbs.pug
new file mode 100644
index 0000000..df60362
--- /dev/null
+++ b/pug/components/_breadcrumbs.pug
@@ -0,0 +1,10 @@
+mixin breadcrumbs(items)
+ ul.breadcrumbs&attributes(attributes)
+ if items
+ each item in items
+ if item.link
+ li
+ a(href=item.link)= item.label
+
+ else
+ li= item.label
diff --git a/pug/components/_callout.pug b/pug/components/_callout.pug
new file mode 100644
index 0000000..ddb7d6c
--- /dev/null
+++ b/pug/components/_callout.pug
@@ -0,0 +1,8 @@
+mixin callout(type, header, errors)
+ .callout(class=type)&attributes(attributes)
+ if header
+ h5= header
+ block
+ if errors
+ each error in errors
+ p #[a(href='#' + error.id)= error.label] - #{error.message}
diff --git a/pug/components/_card.pug b/pug/components/_card.pug
new file mode 100644
index 0000000..24a00ce
--- /dev/null
+++ b/pug/components/_card.pug
@@ -0,0 +1,18 @@
+mixin card(type, title, subtitle, link, linkLabel)
+ article.card(class=type)&attributes(attributes)
+ if subtitle
+ span.meta
+ if link
+ span.meta
+ a(href=link, tabindex=-1)= subtitle
+ else
+ span.meta= title
+ if title
+ if link
+ h4
+ a(href=link)= title
+ else
+ h4= title
+ block
+ if link && linkLabel
+ a(href=link)= linkLabel
diff --git a/pug/components/_checkbox.pug b/pug/components/_checkbox.pug
new file mode 100644
index 0000000..7c0fdc3
--- /dev/null
+++ b/pug/components/_checkbox.pug
@@ -0,0 +1,15 @@
+mixin checkbox(name, id, legend, helperBelow, helperAbove, options, stack, error)
+ div(class=error ? 'has-error' : '')&attributes(attributes)
+ legend(for=id)= legend
+ if helperAbove
+ span= helperAbove
+ fieldset(class=stack ? 'stack-list' : null)
+ each option in options
+ div
+ input(type='checkbox', id=id + '-' + option.value, value=option.value, name=name, checked=option.checked)
+ label(for=id + '-' + option.value)= option.label
+ if helperBelow
+ span= helperBelow
+ block
+ if error
+ span.error-message= error
diff --git a/pug/components/_hero.pug b/pug/components/_hero.pug
new file mode 100644
index 0000000..568c019
--- /dev/null
+++ b/pug/components/_hero.pug
@@ -0,0 +1,6 @@
+mixin hero(src, alt, slim, outline)
+ - var classes = ''
+ - classes = classes + (slim ? 'slim ' : '')
+ - classes = classes + (outline ? 'outline' : '')
+ .hero(class=classes)&attributes(attributes)
+ img(src=src, alt=alt)
diff --git a/pug/components/_hidden.pug b/pug/components/_hidden.pug
new file mode 100644
index 0000000..5b22d64
--- /dev/null
+++ b/pug/components/_hidden.pug
@@ -0,0 +1,3 @@
+//- Shortcode for
+mixin hidden(name, value)
+ input(type='hidden', name=name, value=value)&attributes(attributes)
diff --git a/pug/components/_example.pug b/pug/components/_input.pug
similarity index 78%
rename from pug/components/_example.pug
rename to pug/components/_input.pug
index 9b91b48..2dfbe7b 100644
--- a/pug/components/_example.pug
+++ b/pug/components/_input.pug
@@ -1,4 +1,4 @@
-mixin example(type, name, value, id, label, helperBelow, helperAbove, error)
+mixin input(type, name, value, id, label, helperBelow, helperAbove, error)
div(class=error ? 'has-error' : '')
label(for=id)= label
if helperAbove
diff --git a/pug/components/_pagination.pug b/pug/components/_pagination.pug
new file mode 100644
index 0000000..d6b28ff
--- /dev/null
+++ b/pug/components/_pagination.pug
@@ -0,0 +1,86 @@
+mixin pagination(pages, current, relativeNumber, absoluteNumber)
+ if pages.length
+ - var current = current * 1
+ - var total = pages.length || 0
+ - var relativeNumber = relativeNumber ? relativeNumber * 1 : 1
+ - var absoluteNumber = absoluteNumber ? absoluteNumber * 1 : 2
+ - var previous = current > 1 ? true : false
+ - var previousLink = previous && pages[current - 2] ? pages[current - 2].link : null
+ - var next = current < total ? true : false
+ - var nextLink = next ? pages[current].link : null
+ div
+ ul.pagination(role='navigation', aria-label='Pagination')&attributes(attributes)
+
+ //- Do some clever stuff to choose which links to display in here and what dividers to show in between
+ //- No links should repeat themselves :/
+
+ //- Fetch the x pages before current and put them in a separate array
+ - var before = []
+ each page, index in pages
+ if index > (current - 2 - relativeNumber) && index < (current - 1)
+ - before.push(page)
+
+ //- Fetch the x pages after current and put them in a separate array
+ - var after = []
+ each page, index in pages
+ if index < (current + relativeNumber) && index > (current - 1)
+ - after.push(page)
+
+ //- Get the first x pages and check they are not already in the before array (by inversing the same if statement), and are below the current page
+ - var start = []
+ each page, index in pages
+ if index < (current - 1) && index < absoluteNumber && !(index > (current - 2 - relativeNumber) && index < (current - 1))
+ - start.push(page)
+
+ //- Get the last x pages and check they are not already in the after array (by inversing the same if statement), and are above the current page
+ - var end = []
+ each page, index in pages
+ if index > (current - 1) && (index > (total - absoluteNumber - 1)) && !(index < (current + relativeNumber) && index > (current - 1))
+ - end.push(page)
+
+ //- Previous
+ if previous
+ li.pagination-previous
+ a(href=previousLink) Previous #[span.show-for-sr page]
+ else
+ li.pagination-previous.disabled Previous #[span.show-for-sr page]
+
+ //-- Start
+ each page in start
+ li
+ a(href=page.link, aria-label='Page ' + page.page)= page.page
+
+ //- Divider (if there is a gap between start and before)
+ if start[start.length - 1] && before[0] && start[start.length - 1].page + 2 < before[0].page + 1
+ li.ellipsis(aria-hidden='true')
+
+ //- Before
+ each page in before
+ li
+ a(href=page.link, aria-label='Page ' + page.page)= page.page
+
+ //- Current
+ each page, index in pages
+ if current - 1 === index
+ li.current #[span.show-for-sr= 'You\'re on page'] #{current}
+
+ //- After
+ each page in after
+ li
+ a(href=page.link, aria-label='Page ' + page.page)= page.page
+
+ //- Divider (if there is a gap between after and end)
+ if after[after.length - 1] && end[0] && after[after.length - 1].page + 2 < end[0].page + 1
+ li.ellipsis(aria-hidden='true')
+
+ //- End
+ each page in end
+ li
+ a(href=page.link, aria-label='Page ' + page.page)= page.page
+
+ //- Next
+ if next
+ li.pagination-next
+ a(href=nextLink) Next #[span.show-for-sr page]
+ else
+ li.pagination-next.disabled Next #[span.show-for-sr page]
diff --git a/pug/components/_quick-links.pug b/pug/components/_quick-links.pug
new file mode 100644
index 0000000..a2cd7c9
--- /dev/null
+++ b/pug/components/_quick-links.pug
@@ -0,0 +1,10 @@
+mixin quick-links(items, vertical, four, six)
+ - var classes = ''
+ - classes = classes + (vertical ? 'vertical ' : '')
+ - classes = classes + ((items.length === 4) || four ? 'four ' : '')
+ - classes = classes + ((items.length === 6) || six ? 'six ' : '')
+ nav.quick(class=classes)&attributes(attributes)
+ ul
+ each item in items
+ li(class=item.icon)
+ a(href=item.link)= item.label
diff --git a/pug/components/_radio.pug b/pug/components/_radio.pug
new file mode 100644
index 0000000..62b118a
--- /dev/null
+++ b/pug/components/_radio.pug
@@ -0,0 +1,16 @@
+mixin radio(name, selectedValue, id, legend, helperBelow, helperAbove, options, stack, error)
+ div(class=error ? 'has-error' : '', role='radiogroup')&attributes(attributes)
+ legend(for=id)= legend
+ if helperAbove
+ span= helperAbove
+ fieldset(class=stack ? 'stack-list' : null)
+ each option in options
+ - var isChecked = ('' + option.value) === ('' + selectedValue) ? true : false
+ div
+ input(type='radio', id=id + '-' + option.value, value=option.value, name=name, checked=isChecked)
+ label(for=id + '-' + option.value)= option.label
+ if helperBelow
+ span= helperBelow
+ block
+ if error
+ span.error-message= error
diff --git a/pug/components/_select.pug b/pug/components/_select.pug
new file mode 100644
index 0000000..0c96f50
--- /dev/null
+++ b/pug/components/_select.pug
@@ -0,0 +1,21 @@
+mixin select(name, selectedValue, id, label, helperBelow, helperAbove, options, error)
+ div(class=error ? 'has-error' : '')
+ label(for=id)= label
+ if helperAbove
+ span= helperAbove
+ select(id=id, name=name)&attributes(attributes)
+ each option in options
+ //- Change to selectedValue, we don't want confusing matching variables
+ if option.children && option.children.length
+ optgroup(label=option.label)
+ each child in option.children
+ - var isSelected = ('' + child['value']) === ('' + selectedValue) ? true : false
+ option(value=child.value, selected=isSelected)= child.label
+ else
+ - var isSelected = ('' + option['value']) === ('' + selectedValue) ? true : false
+ option(value=option.value, selected=isSelected)= option.label
+ if helperBelow
+ span= helperBelow
+ block
+ if error
+ span.error-message= error
diff --git a/pug/components/_sub-menu.pug b/pug/components/_sub-menu.pug
new file mode 100644
index 0000000..52693a0
--- /dev/null
+++ b/pug/components/_sub-menu.pug
@@ -0,0 +1,6 @@
+mixin sub-menu(items)
+ nav.sub-menu&attributes(attributes)
+ ul
+ each item in items
+ li(class=item.active ? 'active' : null)
+ a(href=item.link)= item.label
diff --git a/pug/components/_submit.pug b/pug/components/_submit.pug
new file mode 100644
index 0000000..0acadf8
--- /dev/null
+++ b/pug/components/_submit.pug
@@ -0,0 +1,3 @@
+//- Shortcode for
+mixin submit(value)
+ input.button(type='submit', value=value)&attributes(attributes)
diff --git a/pug/components/_tab.pug b/pug/components/_tab.pug
new file mode 100644
index 0000000..be08ab3
--- /dev/null
+++ b/pug/components/_tab.pug
@@ -0,0 +1,15 @@
+mixin tab-list(tabs)
+ .tabs&attributes(attributes)
+ ul(role='tablist')
+ each tab, index in tabs
+ if tab.active
+ li.active
+ a(role='tab', href='#tab-' + tab.id || index, tabindex=0, data-tab=tab.id || index)= tab.label
+ else
+ li
+ a(role='tab', href='#tab-' + tab.id || index, tabindex=0, data-tab=tab.id || index)= tab.label
+ block
+
+mixin tab(id, active)
+ .panel(role='tabpanel', id='tab-' + id, data-tab=id, class=active ? 'active' : '')
+ block
diff --git a/pug/components/_textarea.pug b/pug/components/_textarea.pug
new file mode 100644
index 0000000..7f53897
--- /dev/null
+++ b/pug/components/_textarea.pug
@@ -0,0 +1,11 @@
+mixin textarea(name, id, label, rows, helperBelow, helperAbove, error)
+ div(class=error ? 'has-error' : '')
+ label(for=id)= label
+ if helperAbove
+ span= helperAbove
+ textarea(id=id, name=name, rows=rows)&attributes(attributes)
+ block
+ if helperBelow
+ span= helperBelow
+ if error
+ span.error-message= error
diff --git a/pug/components/_top-menu.pug b/pug/components/_top-menu.pug
new file mode 100644
index 0000000..09d9a18
--- /dev/null
+++ b/pug/components/_top-menu.pug
@@ -0,0 +1,21 @@
+mixin top-menu(items, logo, logoLink, icon, linkText)
+ menu(role='banner')&attributes(attributes)
+ .wrap
+ if logo
+ a.logo-link(href=logoLink, title='Home', tabindex=-1) Home
+ a.menu-link(href='#')= linkText
+ if icon
+ span.menu-icon
+ if items
+ ul(role='navigation')
+ each item in items
+ - var classes = ''
+ - classes = classes + (item.children ? 'has-dropdown' : '')
+ - classes = classes + (item.active ? ' active' : '')
+ li(class=classes)
+ a(href=item.link ? item.link : '#', tabindex=0)= item.label
+ if item.children
+ ul(role='menu')
+ each child in item.children
+ li(class=child.active ? 'active' : null)
+ a(href=child.link, role='menuitem')= child.label
diff --git a/pug/components/_upload.pug b/pug/components/_upload.pug
new file mode 100644
index 0000000..17c4cc9
--- /dev/null
+++ b/pug/components/_upload.pug
@@ -0,0 +1,13 @@
+mixin upload(name, id, label, buttonText, helperBelow, helperAbove, error)
+ div(class=error ? 'has-error' : '')
+ if label
+ label(for=id)= label
+ if helperAbove
+ span= buttonText
+ input(type='file', id=id, name=name, tabindex=-1)&attributes(attributes)
+ label(for=id, tabindex=0)= buttonText
+ if helperBelow
+ span= helperBelow
+ block
+ if error
+ span.error-message= error
diff --git a/pug/meta/_meta-social.pug b/pug/meta/_meta-social.pug
index 80f953e..3ece59c 100644
--- a/pug/meta/_meta-social.pug
+++ b/pug/meta/_meta-social.pug
@@ -12,12 +12,12 @@ mixin meta-social(url, title, image, description, siteName)
if image
meta(property='og:image', content=image)
meta(property='og:description', content=description)
- meta(property='og:site_name', content=siteName || 'APC Overnight')
+ meta(property='og:site_name', content=siteName)
meta(property='og:locale', content='en_GB')
//- Twitter
meta(property='twitter:url', content=url)
- meta(property='twitter:site', content='@APCOvernight')
+ meta(property='twitter:site', content='@twitter')
meta(property='twitter:card', content='summary')
meta(property='twitter:title', content=title)
meta(property='twitter:description', content=description)
diff --git a/schema/components/accessibility.js b/schema/components/accessibility.js
new file mode 100644
index 0000000..8fce131
--- /dev/null
+++ b/schema/components/accessibility.js
@@ -0,0 +1,31 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'accessibility',
+
+ // Component title - for docs/style guide
+ title: 'Accessibility',
+
+ // Paragraphs for docs
+ docs: [
+ `#[blockquote Accessibility is the degree to which anyone can access and use a website using any web browsing technology. #[cite Royal National Institute of Blind People]]`,
+ 'Our public-facing applications must be built to work on all devices, browsers and with assistive technologies. A lot of effort has been made to ensure that the components in this framework are accessible. Such as:'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`ul
+ li Text and backgrounds have sufficient contrast ratios so text is legible.
+ li Clickable elements are clear and uniform, so users know what they can click.
+ li ARIA landmark roles and html5 elements help browsers define types of content.
+ li Focus states on all elements so that interactions can be operated with a keyboard or screen reader.
+ li Javascript features have a fallback for when javascript is not enabled.
+
+p #[a(href='http://a11yproject.com/checklist.html', target='_blank') This checklist from the A11Y Project] is a good guide to all the core web accessibility principles.`
+}
diff --git a/schema/components/alert.js b/schema/components/alert.js
new file mode 100644
index 0000000..e8a5d19
--- /dev/null
+++ b/schema/components/alert.js
@@ -0,0 +1,58 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'alert',
+
+ // Component title - for docs/style guide
+ title: 'Alert Message',
+
+ // Paragraphs for docs
+ docs: [
+ 'Alert messages can be displayed above or below the menu & hero for urgent messages to catch the user\'s attention.',
+ 'Alert messages can be made dismissable by adding a #[code .close] span.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: true,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: "We’re recruiting! #[a(href='#') Click here] to discover our fantastic career opportunities and start your journey today",
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: null,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ params: {
+ type: {
+ enum: [ 'default', 'alert', 'warning' ],
+ default: 'alert',
+ description: 'The type of message, determines colour scheme'
+ },
+ close: {
+ type: 'boolean',
+ default: false,
+ description: 'Should a close button be shown'
+ }
+ }
+}
diff --git a/schema/components/banner.js b/schema/components/banner.js
new file mode 100644
index 0000000..caa40f1
--- /dev/null
+++ b/schema/components/banner.js
@@ -0,0 +1,67 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'banner',
+
+ // Component title - for docs/style guide
+ title: 'Banner Message',
+
+ // Paragraphs for docs
+ docs: [
+ 'Banner callouts can be useful for displaying a quick eye-catching message. A logo can be included with the #[code .logo] class or the text can be centred with a #[code .center] class.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: true,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: null,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ params: {
+ heading: {
+ type: 'string',
+ default: 'A fancy strapline',
+ description: 'The header of the banner'
+ },
+ subHeading: {
+ type: 'string',
+ default: 'Call us on 0800 00 00 00',
+ description: 'The sub-header of the banner'
+ },
+ logo: {
+ type: 'boolean',
+ default: true,
+ description: 'Should logo be included'
+ },
+ center: {
+ type: 'boolean',
+ default: false,
+ description: 'Should text be centered'
+ }
+ }
+}
diff --git a/schema/components/blockquote.js b/schema/components/blockquote.js
new file mode 100644
index 0000000..5bec105
--- /dev/null
+++ b/schema/components/blockquote.js
@@ -0,0 +1,24 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'blockquote',
+
+ // Component title - for docs/style guide
+ title: 'Blockquote',
+
+ // Paragraphs for docs
+ docs: [
+ 'Sometimes other people say nice things, and we may want to mention those things with a quote that clearly shows who said it. Use a #[code= \'\'] tag for the byline.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`blockquote I had a really good experience using this product.
+ cite A. Customer`
+}
diff --git a/schema/components/bold-header.js b/schema/components/bold-header.js
new file mode 100644
index 0000000..56e83bc
--- /dev/null
+++ b/schema/components/bold-header.js
@@ -0,0 +1,29 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'bold-header',
+
+ // Component title - for docs/style guide
+ title: 'Bold Headers',
+
+ // Paragraphs for docs
+ docs: [
+ 'Sometimes a bolder header might be required for more emphasis. This can be done by adding the #[code .heavy] class. If this option is used it should be done consistently throughout the application or website.',
+ 'By inserting a #[code small] element into a header Foundation will scale the header font size down for an inline element, allowing you to use this for subtitles or other secondary header text.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`h1.heavy h1. This is a very large header
+h2.heavy h2. This is a large header
+h3.heavy h3. This is a medium heade
+h4.heavy h4. This is a moderate header
+h5.heavy h5. This is a small header
+h6.heavy h6. This is a tiny header`
+}
diff --git a/schema/components/breadcrumbs.js b/schema/components/breadcrumbs.js
new file mode 100644
index 0000000..dcf491c
--- /dev/null
+++ b/schema/components/breadcrumbs.js
@@ -0,0 +1,70 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'breadcrumbs',
+
+ // Component title - for docs/style guide
+ title: 'Breadcrumbs',
+
+ // Paragraphs for docs
+ docs: [
+ 'On applications with multi-level navigation, breadcrumbs can be used to indicate which section the user is in, and help them navigate back up navigation.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: null,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'items': {
+ 'type': 'array',
+ 'description': 'Array of objects with label/link strings',
+ 'default': [
+ {
+ 'label': 'Home',
+ 'link': '#'
+ },
+ {
+ 'label': 'Category',
+ 'link': '#',
+ 'active': true
+ },
+ {
+ 'label': 'Sub-Category',
+ 'link': '#',
+ 'active': true
+ },
+ {
+ 'label': 'Current'
+ }
+ ]
+ }
+ }
+}
diff --git a/schema/components/button.js b/schema/components/button.js
new file mode 100644
index 0000000..b1749bb
--- /dev/null
+++ b/schema/components/button.js
@@ -0,0 +1,47 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'button',
+
+ // Component title - for docs/style guide
+ title: 'Buttons',
+
+ // Paragraphs for docs
+ docs: [
+ 'Buttons are for users to trigger an actions, the text on the button should make it clear what the action will do. The colour of the button can also denote whether an action is constructive, destructive etc.',
+ 'Buttons in a row are spaced apart so that a user won\'t press the wrong one by mistake.',
+ 'Links or submit inputs can be styled as buttons with the #[code .button] class.',
+ '#[h4 Create new order?]',
+ '#[a.button.small.secondary(href=\'#\') Cancel] #[a.button(href=\'#\') Create order]',
+ 'Button labels should be clear so that the user knows what action will happen when they click it. Constructive actions (Yes, Confirm, Save etc) should go on the right and be blue. Destructive actions (Delete etc) should be red. Back-tracking actions (Cancel, Undo, No) should be grey and on the left, and could be smaller.',
+ 'Colour of buttons can be modified by adding a #[code .alert] or #[code .secondary] class. The size of buttons can be modified with #[code .small], #[code .tiny], #[code .large] and #[code .expanded] classes.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`div
+ a.button(href='#') Basic Button
+ a.alert.button(href='#') Alert Btn
+ a.secondary.button(href='#') Secondary Btn
+div
+ a.secondary.small.button(href='#') A Small Btn
+ a.tiny.button.alert(href='#') An even smaller button
+ a.large.button(href='#') A large button
+div
+ a.small.expanded.button(href='#') An expanded button`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null
+}
diff --git a/schema/components/callout.js b/schema/components/callout.js
new file mode 100644
index 0000000..cc90162
--- /dev/null
+++ b/schema/components/callout.js
@@ -0,0 +1,73 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'callout',
+
+ // Component title - for docs/style guide
+ title: 'Error Callout',
+
+ // Paragraphs for docs
+ docs: [
+ 'A callout should be included at the top of the form to indicate that there are errors after form submission. It should indicate which fields have errors to help the user amend them'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: true,
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: null,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'type': {
+ 'enum': ['default', 'alert', 'warning'],
+ 'default': null,
+ 'description': 'Type of callout, defines colour scheme'
+ },
+ 'header': {
+ 'type': 'string',
+ 'default': 'There were some problems with your form',
+ 'description': 'The header of the callout'
+ },
+ 'errors': {
+ 'type': 'array',
+ 'default': [
+ {
+ 'label': 'Example Field',
+ 'id': 'example-text-error',
+ 'message': 'Must be less than 30 characters'
+ },
+ {
+ 'label': 'Another Field',
+ 'id': 'example-text-error',
+ 'message': 'Must be a specific type of data'
+ }
+ ],
+ 'description': 'Array of objects with label/id/message pairs'
+ }
+ }
+}
diff --git a/schema/components/card.js b/schema/components/card.js
new file mode 100644
index 0000000..e0808b5
--- /dev/null
+++ b/schema/components/card.js
@@ -0,0 +1,84 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'card',
+
+ // Component title - for docs/style guide
+ title: 'Floating Card',
+
+ // Paragraphs for docs
+ docs: [
+ 'Floating cards can be useful for displaying single or repeating modules on a page, such as tweets or news stories. Cards fill the horizontal space they are in and stretch vertically to contain the content.',
+ 'Cards can contain a #[code= ""] or a #[code= \'\'] element, a header, paragraphs and link. If the card has a link, the header and time should also be linked.',
+ 'Cards with a class of #[code .flat] will have a grey background. Cards with a class of #[code .shadow] will have a shadow effect.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: "Don't forget, you can stay updated with all our latest news by visiting our website!",
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+ `.nest
+ .sidebar
+ +card(null,'News Item Title','12th December 16','#','Read more...')
+ p Don't forget, you can stay updated with all our latest news by visiting our website!
+ .sidebar
+ +card('flat','Class 1 Driver','Job Title','#','Apply now...')
+ p We are currently looking to recruit a driver to join the existing well established team.
+ .sidebar
+ +card('shadow','News Item Title','12th December 16','#','Read more...')
+ p Don't forget, you can stay updated with all our latest news by visiting our website!`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'type': {
+ 'enum': [ 'default', 'flat', 'shadow' ],
+ 'default': 'default',
+ 'description': 'The style of the card'
+ },
+ 'title': {
+ 'type': 'string',
+ 'default': 'My Card Title',
+ 'description': 'Title of the card'
+ },
+ 'subtitle': {
+ 'type': 'string',
+ 'default': 'Sub-Title',
+ 'description': 'Subtitle of the card'
+ },
+ 'link': {
+ 'type': 'string',
+ 'default': '#',
+ 'description': 'Link when card is clicked'
+ },
+ 'linkLabel': {
+ 'type': 'string',
+ 'default': 'Read more...',
+ 'description': 'Text of link label'
+ }
+ }
+}
diff --git a/schema/components/checkbox.js b/schema/components/checkbox.js
new file mode 100644
index 0000000..318657c
--- /dev/null
+++ b/schema/components/checkbox.js
@@ -0,0 +1,102 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'checkbox',
+
+ // Component title - for docs/style guide
+ title: 'Checkboxes',
+
+ // Paragraphs for docs
+ docs: [
+ 'Use groups of checkboxes when the user may select multiple choices from a list'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+checkbox('example-checkbox', 'example-checkbox', 'Example Checkbox Group', null, 'Some helper text', [{"label":"An Option","value":"1"},{"label":"Another Option","value":"2", "checked":true},{"label":"A Third Option","value":"3"}])`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'name': {
+ 'type': 'string',
+ 'default': 'my-checkboxes',
+ 'description': 'The name attribute of the checkbox group'
+ },
+ 'id': {
+ 'type': 'string',
+ 'default': 'my-checkboxes',
+ 'description': 'The id of the checkbox-group'
+ },
+ 'legend': {
+ 'type': 'string',
+ 'default': 'My Checkbox Options',
+ 'description': 'The legend text'
+ },
+ 'helperBelow': {
+ 'type': 'string',
+ 'default': 'Some helpful advice for this field',
+ 'description': 'Helper that appears below the field'
+ },
+ 'helperAbove': {
+ 'type': 'string',
+ 'default': 'More helpful advice for this field',
+ 'description': 'Helper the appears above the field'
+ },
+ 'options': {
+ 'type': 'array',
+ 'default': [
+ {
+ 'label': 'An Option',
+ 'value': '1'
+ },
+ {
+ 'label': 'Another Option',
+ 'value': '2',
+ 'checked': true
+ },
+ {
+ 'label': 'A Third Option',
+ 'value': '3',
+ 'checked': true
+ }
+ ],
+ 'description': 'Array of objects with label/value/checked key/values'
+ },
+ 'stack': {
+ 'type': 'boolean',
+ 'default': false,
+ 'description': 'Display options in vertical stack?'
+ },
+ 'error': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'Error message string, marks whole field as errorneous'
+ }
+ }
+}
diff --git a/schema/components/closeable.js b/schema/components/closeable.js
new file mode 100644
index 0000000..3846497
--- /dev/null
+++ b/schema/components/closeable.js
@@ -0,0 +1,30 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'closeable',
+
+ // Component title - for docs/style guide
+ title: 'Closeable Elements',
+
+ // Paragraphs for docs
+ docs: [
+ 'Sometimes elements need to be closeable by the user. The helper class #[code .closeable] can be combined with a #[code= \'Close \'] element to add a close button to any element. The styles for this are an attempt at #[em one-size fits all] so they may need to be tweaked for each use case.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`.nest
+ .sidebar
+ +card('flat','News Item Title','12th December 16','#','Read more...').closeable
+ span.close Close
+ p Don't forget, you can stay updated with all our latest news by visiting our website!`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: './pug/components/_card.pug'
+}
diff --git a/schema/components/colour.js b/schema/components/colour.js
new file mode 100644
index 0000000..be6665b
--- /dev/null
+++ b/schema/components/colour.js
@@ -0,0 +1,42 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'colour',
+
+ // Component title - for docs/style guide
+ title: 'Colours',
+
+ // Paragraphs for docs
+ docs: [
+ 'There are a variety of colours to choose from for digital interfaces.',
+ 'There are not pre-defined CSS classes for each colour, but they are available as SASS variables to use in your own extended styles.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`h3 Primary Colours
+
+.swatches.big
+ span.red Red
+ span.blue Blue
+
+h3 Secondary Colours
+
+.swatches.small
+ span.claret Claret
+ span.flame Flame
+ span.carrot Carrot
+ span.buttercup Buttercup
+ span.sunglow Sunglow
+ span.malibu Malibu
+ span.bermuda Bermuda
+ span.java Java
+ span.verdun Verdun
+ span.grey Grey`
+}
diff --git a/schema/components/datepicker.js b/schema/components/datepicker.js
new file mode 100644
index 0000000..9e27d12
--- /dev/null
+++ b/schema/components/datepicker.js
@@ -0,0 +1,43 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'datepicker',
+
+ // Component title - for docs/style guide
+ title: 'Date Picker',
+
+ // Paragraphs for docs
+ docs: [
+ 'Inputs with an attribute of #[code data-datepicker] can be made more user friendly with the jQuery-ui datepicker widget. The datepicker input element is one case where a placeholder is useful, to indicate that the input must be clicked to open the calendar.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: true,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+input('date', 'example-date-picker', null, 'Example Date Picker')(data-datepicker, placeholder='Pick Date')`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: './pug/components/_input.pug',
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null
+}
diff --git a/schema/components/definition-list.js b/schema/components/definition-list.js
new file mode 100644
index 0000000..d912f50
--- /dev/null
+++ b/schema/components/definition-list.js
@@ -0,0 +1,28 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'definition-list',
+
+ // Component title - for docs/style guide
+ title: 'Definition Lists',
+
+ // Paragraphs for docs
+ docs: [
+ 'A definition list #[code= \'\'] is used to display name-value pairs, like FAQs. Each term #[code= \'\'] is paired with one or more definitions #[code= \' \'].'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`dl
+ dt A Definition Term
+ dd The definition, styled just like a paragraph, but with clever spacing between definitions.
+
+ dt Why should I use this style guide?
+ dd Because it looks good`
+}
diff --git a/schema/components/disabled.js b/schema/components/disabled.js
new file mode 100644
index 0000000..1aaf9a2
--- /dev/null
+++ b/schema/components/disabled.js
@@ -0,0 +1,31 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'disabled',
+
+ // Component title - for docs/style guide
+ title: 'Disabled Fields',
+
+ // Paragraphs for docs
+ docs: [
+ 'Some applications will need to show a field but not accept user input, or disable the submit button until all required fields are completed. The #[code disabled] attribute stops input and styles it to makes it clear that inputs can not be modified by the user.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+input('text', 'example-text-disabled', 'User cannot edit this text', 'example-text-disabled', 'An example disabled text field', 'You cannot edit this field')(disabled)`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: './pug/components/_input.pug',
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null
+}
diff --git a/schema/components/divider.js b/schema/components/divider.js
new file mode 100644
index 0000000..55aa8a9
--- /dev/null
+++ b/schema/components/divider.js
@@ -0,0 +1,19 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'divider',
+
+ // Component title - for docs/style guide
+ title: 'Dividers',
+
+ // Paragraphs for docs
+ docs: [
+ 'Use #[code= \' \'] dividers to define thematic breaks between paragraphs or other page elements'
+ ]
+}
diff --git a/schema/components/errors.js b/schema/components/errors.js
new file mode 100644
index 0000000..7feaab4
--- /dev/null
+++ b/schema/components/errors.js
@@ -0,0 +1,45 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'errors',
+
+ // Component title - for docs/style guide
+ title: 'Form Errors',
+
+ // Paragraphs for docs
+ docs: [
+ 'User input needs to be validated to check for erroneous or malicious data. To improve usability, human-friendly error messages should be shown on invalid fields.',
+ 'In-line validation (inline feedback as the user is filling out the form) is much more effective than post-submission feedback.',
+ 'Error messages can be added to the DOM by javascript or into the source html server-side. A wrapper with class #[code .has-error] around an input and label denotes an error. A span with class #[code .error-message] should show the specific error.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: true,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+input('text', 'example-text-error', 'Some erroneous text', 'example-text-error', 'Text field with an error', 'Helper text', null, 'This field is too long')`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: './pug/components/_input.pug',
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null
+}
diff --git a/schema/components/example.js b/schema/components/example.js
deleted file mode 100644
index 0ce8ce0..0000000
--- a/schema/components/example.js
+++ /dev/null
@@ -1,105 +0,0 @@
-'use strict'
-
-/**
- * Component configuration
- * The data in these component configuration files ties together the
- * SCSS, JS and Pug markup for each component and is used by the docs generator
- * (in gulp) to build up documentation, including live demos
- * @type {Object}
- */
-
-module.exports = {
- // Component name, should match schema, pug, scss and js filename
- name: 'example',
-
- // Component title - for docs/style guide
- title: 'My Example Component',
-
- // Paragraphs for docs. Array of strings. Each string will be a separate paragraph, inline pug will be rendered
- docs: [
- 'This is an example component, it includes some CSS (compiled from SCSS), some JS, and a pug mixin to make the markup easily re-usable',
- 'These paragraphs are generated from the example component schema, in #[code schema/components/example.js]'
- ],
-
- // Path to mixin (if not pug/components/.pug)
- // Set to false if there is no mixin for this component
- // mixinPath: null,
-
- // Path to scss (if not scss/components/.scss)
- // Set to false if there is no scss for this component
- // scssPath: null,
-
- // Path to js (if not js/components/.js)
- // Set to false if there is no js for this component
- // jsPath: null,
-
- // Does this component break out of the content wrapper in the docs
- // If so, the generator with wrap a .breakout div around the demo
- breakout: false,
-
- // Can the component live preview be shown inline or does it require full width
- inline: true,
-
- // Default mixin block content for live preview (Can contain pug)
- // Set to false if there is no block
- block: false,
-
- // Can attributes be passed to the pug mixin?
- attributes: false,
-
- // Demo output (Mixin can be called, if left empty default parameters and block content will be used)
- demo: `+example('text', 'example-text', null, 'example-text', 'An example text field', 'A helper or example for this field', false)(my-attribute='true')`,
-
- /**
- * Pug Mixin Parameters
- * Object with parameter documentation for the mixin. In the following format
- paramName: {
- type: 'string', // Can be string, boolean, number, array or object
- enum: [], // Array of possible strings (shows a select drop down in docs preview)
- default: true // Default value, for demonstration purposes / live preview
- description: '' // Description of field for documentation
- }
- */
- params: {
- type: {
- enum: [ 'text', 'date', 'datetime', 'datetime-local', 'email', 'month', 'number', 'password', 'search', 'tel', 'time', 'url', ' week' ],
- default: 'text',
- description: 'The input type attribute'
- },
- name: {
- type: 'string',
- default: 'my-input',
- description: 'The name attribute of the input'
- },
- value: {
- type: 'string',
- default: null,
- description: 'The default value of the field'
- },
- id: {
- type: 'string',
- default: 'my-input',
- description: 'The id of the input'
- },
- label: {
- type: 'string',
- default: 'My Input',
- description: 'The label text'
- },
- helperBelow: {
- type: 'string',
- default: 'Some helpful advice for this field',
- description: 'Helper that appears below the field'
- },
- helperAbove: {
- type: 'string',
- default: 'More helpful advice for this field',
- description: 'Helper the appears above the field'
- },
- error: {
- type: 'string',
- default: null,
- description: 'Error message string, marks whole field as errorneous'
- }
- }
-}
diff --git a/schema/components/footer.js b/schema/components/footer.js
new file mode 100644
index 0000000..162ef13
--- /dev/null
+++ b/schema/components/footer.js
@@ -0,0 +1,106 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'footer',
+
+ // Component title - for docs/style guide
+ title: 'Footer',
+
+ // Paragraphs for docs
+ docs: [
+ 'The footer sits at the bottom of the screen and can contain 3 horizontal sections. It can be used for re-iterating navigation or adding extra information and links.',
+ 'No mixin / sample code is provided for this element because there are too many variables. Check the #[code docs.pug] source code for this example.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`footer
+ .top
+ .contain
+ aside
+ h2 Style Guider - Generate style guides
+ p It's really good!
+ ul
+ li Call on: 0800 00 00 00 #[sup *]
+ li Email: #[a(href='') mail@style-guider-demo.com]
+ li #[small * Calls may be recorded]
+ nav
+ h4 Some Navigation
+ ul
+ li
+ a(href='#') History
+ li
+ a(href='#') Team
+ li
+ a(href='#') Awards
+ li
+ a(href='#') Corporate Social Responsibility
+ li
+ a(href='#') Careers
+ nav
+ h4 More Navigation
+ ul
+ li
+ a(href='#') History
+ li
+ a(href='#') Team
+ li
+ a(href='#') Awards
+ li
+ a(href='#') Corporate Social Responsibility
+ li
+ a(href='#') Careers
+ nav
+ h4 More Navigation
+ ul
+ li
+ a(href='#') History
+ li
+ a(href='#') Team
+ li
+ a(href='#') Awards
+ li
+ a(href='#') Corporate Social Responsibility
+ li
+ a(href='#') Careers
+ nav
+ h4 More Navigation
+ ul
+ li
+ a(href='#') History
+ li
+ a(href='#') Team
+ li
+ a(href='#') Awards
+ li
+ a(href='#') Corporate Social Responsibility
+ li
+ a(href='#') Careers
+ .middle
+ .contain
+ span.copyright © 2017 Ian Egner
+ nav
+ ul
+ li
+ a(href='#') A text link
+ li
+ a(href='#') A text link
+ li
+ a(href='#') A text link
+ li
+ a(href='#') A text link
+ li
+ a(href='#') A text link
+ .bottom
+ p Some Company Name, Some Address, Some Town, Some County, Some Postcode
+ p Registered in England and Wales No. Some Company Number - VAT Registration No. Some VAT number`
+}
diff --git a/schema/components/form.js b/schema/components/form.js
new file mode 100644
index 0000000..4d8bf53
--- /dev/null
+++ b/schema/components/form.js
@@ -0,0 +1,28 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'form',
+
+ // Component title - for docs/style guide
+ title: 'Forms',
+
+ // Paragraphs for docs
+ docs: [
+ 'Forms are key in interacting with users and gleaning information from them. Forms must be intuitive and accessible to stop users getting frustrated and leaving before finishing.'
+ ],
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null
+}
diff --git a/schema/components/header.js b/schema/components/header.js
new file mode 100644
index 0000000..513b08a
--- /dev/null
+++ b/schema/components/header.js
@@ -0,0 +1,28 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'header',
+
+ // Component title - for docs/style guide
+ title: 'Headers',
+
+ // Paragraphs for docs
+ docs: [
+ 'Headers use a lighter font-weight. They should be used in cascading order to denote the importance of a section\'s contents.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`h1 h1. This is a very large header
+h2 h2. This is a large header
+h3 h3. This is a medium header
+h4 h4. This is a moderate header
+h5 h5. This is a small header
+h6 h6. This is a tiny header`
+}
diff --git a/schema/components/hero.js b/schema/components/hero.js
new file mode 100644
index 0000000..4c2fba5
--- /dev/null
+++ b/schema/components/hero.js
@@ -0,0 +1,69 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'hero',
+
+ // Component title - for docs/style guide
+ title: 'Hero Image',
+
+ // Paragraphs for docs
+ docs: [
+ 'A hero image can sit beneath the menu and spans the full width of the screen.',
+ 'Using a class of #[code .slim] squeezes the image to take up less vertical space. This is more appropriate for non-home pages.',
+ 'Using a class of #[code .outline] adds an oval cutout overlay to the image. Be sure to test any images on all screen sizes to make sure important focal points are not cropped'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: true,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: null,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'src': {
+ 'type': 'string',
+ 'default': 'https://unsplash.it/1200/400/?random',
+ 'description': 'The URL of the image'
+ },
+ 'alt': {
+ 'type': 'string',
+ 'default': 'A hero image',
+ 'description': 'The alt text of the image'
+ },
+ 'slim': {
+ 'type': 'boolean',
+ 'default': false,
+ 'description': 'Make the hero image thinner'
+ },
+ 'outline': {
+ 'type': 'boolean',
+ 'default': false,
+ 'description': 'Put an oval outline over the image'
+ }
+ }
+}
diff --git a/schema/components/hidden.js b/schema/components/hidden.js
new file mode 100644
index 0000000..5ccaaa5
--- /dev/null
+++ b/schema/components/hidden.js
@@ -0,0 +1,57 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'hidden',
+
+ // Component title - for docs/style guide
+ title: 'Hidden Inputs',
+
+ // Paragraphs for docs
+ docs: [
+ 'A mixin for inputs with a type of #[code hidden] has been included'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: '// No demo',
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'name': {
+ 'type': 'string',
+ 'default': 'my-input',
+ 'description': 'The name attribute of the input'
+ },
+ 'value': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'The default value of the field'
+ }
+ }
+}
diff --git a/schema/components/input.js b/schema/components/input.js
new file mode 100644
index 0000000..38b0446
--- /dev/null
+++ b/schema/components/input.js
@@ -0,0 +1,90 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'input',
+
+ // Component title - for docs/style guide
+ title: 'Text Inputs',
+
+ // Paragraphs for docs
+ docs: [
+ 'These input types create a single line text field: #[code text], #[code date], #[code datetime], #[code datetime-local], #[code email], #[code month], #[code number], #[code password], #[code search], #[code tel], #[code time], #[code url], and #[code week]',
+ 'Using specific input types for different data formats can help improve usability. For example, using a #[code tel] input will open a numpad keyboard on mobile devices, making it easier for the user to input a phone number.',
+ 'All form inputs should have a clear label, that describes what you want the user to enter. Clicking a label should focus on the form field. This is achieved by linking label elements to input elements with a #[code for] attribute.',
+ 'Although popular in modern websites, inline placeholders should not be used because they disappear as soon as a user starts typing, and the user may think there is already text input. Instead an example or hint should be placed beneath the input.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: true,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+input('text', 'example-text', null, 'example-text', 'An example text field', 'A helper or example for this field', false)`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'type': {
+ 'enum': [ 'text', 'date', 'datetime', 'datetime-local', 'email', 'month', 'number', 'password', 'search', 'tel', 'time', 'url', ' week' ],
+ 'default': 'text',
+ 'description': 'The input type attribute'
+ },
+ 'name': {
+ 'type': 'string',
+ 'default': 'my-input',
+ 'description': 'The name attribute of the input'
+ },
+ 'value': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'The default value of the field'
+ },
+ 'id': {
+ 'type': 'string',
+ 'default': 'my-input',
+ 'description': 'The id of the input'
+ },
+ 'label': {
+ 'type': 'string',
+ 'default': 'My Input',
+ 'description': 'The label text'
+ },
+ 'helperBelow': {
+ 'type': 'string',
+ 'default': 'Some helpful advice for this field',
+ 'description': 'Helper that appears below the field'
+ },
+ 'helperAbove': {
+ 'type': 'string',
+ 'default': 'More helpful advice for this field',
+ 'description': 'Helper the appears above the field'
+ },
+ 'error': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'Error message string, marks whole field as errorneous'
+ }
+ }
+}
diff --git a/schema/components/layout.js b/schema/components/layout.js
new file mode 100644
index 0000000..0f0f327
--- /dev/null
+++ b/schema/components/layout.js
@@ -0,0 +1,37 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'layout',
+
+ // Component title - for docs/style guide
+ title: 'Layout',
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`.content
+
+ p There are 3 main layout components: Full-width, two-thirds and one-third. This #[code .content] column is two-thirds.
+
+ p A #[code .full] element stretches across the width of the screen.
+
+ p On small screens all three if of these components are full-width and stack on top of each other
+
+ h4 Helper layout classes
+
+ p #[code .half], #[code .third], #[code .quarter] and #[code .sixth] are available for quick column width setting.
+
+ h4 Custom column layouts
+
+ p Columns should be implemented using Foundation's sass mixins - #[a(href='http://foundation.zurb.com/sites/docs/grid.html#building-semantically', target='_blank') see more details here]. There is also a useful grid-columns mixin in \`scss/_mixins.scss\`, see the documentation on that for more info
+
+.sidebar
+ h3 Sidebar
+
+ p This #[code .sidebar] element is one third width.`
+}
diff --git a/schema/components/link.js b/schema/components/link.js
new file mode 100644
index 0000000..6ee2abd
--- /dev/null
+++ b/schema/components/link.js
@@ -0,0 +1,19 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'link',
+
+ // Component title - for docs/style guide
+ title: 'Links',
+
+ // Paragraphs for docs
+ docs: [
+ 'Text links should be intuitive, so that users know they can click or tap on them. Inline links are #[a(href=\'#\') displayed in red] with an underline on hover'
+ ]
+}
diff --git a/schema/components/list.js b/schema/components/list.js
new file mode 100644
index 0000000..533b7e1
--- /dev/null
+++ b/schema/components/list.js
@@ -0,0 +1,37 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'list',
+
+ // Component title - for docs/style guide
+ title: 'Lists',
+
+ // Paragraphs for docs
+ docs: [
+ 'Lists are useful for a collection of text items and can be numbered or nested too.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`p This is what an un-ordered list looks like:
+
+ul
+ li A list item
+ li Another list item
+ li Another one
+ li Ok, last one
+
+p A list following a paragraph has reduced spacing, so that a paragraph can give context to a list:
+
+ol
+ li A list item
+ li Another list item
+ li Another one
+ li Ok, last one`
+}
diff --git a/schema/components/login.js b/schema/components/login.js
new file mode 100644
index 0000000..4a5077a
--- /dev/null
+++ b/schema/components/login.js
@@ -0,0 +1,41 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'login',
+
+ // Component title - for docs/style guide
+ title: 'Login Screen',
+
+ // Paragraphs for docs
+ docs: [
+ 'The login screen can be used inline (within another page) or floated alone on a full page.',
+ 'Users should be allowed to log in with their email address. If this is not technically possible, a link to instructions on how to find their username/user id etc should be provided underneath the relevant field.',
+ 'No mixin / sample code is provided for this element because there are too many variables. Check the #[code docs.pug] source code for this example.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`.login-page
+ form.login(action='#', method='post')
+ h1 Login to My App
+ +input('email', 'email', null, 'email', 'Your email address:')
+ +input('text', 'password', null, 'password', 'Password:')
+ span
+ a(href='#') Forgotten your password?
+ div
+ a.login-go(href='#') Login
+ .login-signup
+ p Don't have an account? #[a(href='#') Sign Up]`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: './pug/components/_input.pug'
+}
diff --git a/schema/components/pagination.js b/schema/components/pagination.js
new file mode 100644
index 0000000..beaf134
--- /dev/null
+++ b/schema/components/pagination.js
@@ -0,0 +1,83 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'pagination',
+
+ // Component title - for docs/style guide
+ title: 'Pagination',
+
+ // Paragraphs for docs
+ docs: [
+ 'When there is too much content for one page, we should make it easy for users to browse, skim or skip between pages. On small screens only the next and previous buttons are shown.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+ `+pagination([{"page":1,"link":"#"},{"page":2,"link":"#10"},{"page":3,"link":"#20"},{"page":4,"link":"#30"},{"page":5,"link":"#40"},{"page":6,"link":"#50"},{"page":7,"link":"#60"},{"page":8,"link":"#70"},{"page":9,"link":"#80"},{"page":10,"link":"#90"},{"page":11,"link":"#100"},{"page":12,"link":"#110"},{"page":13,"link":"#120"},{"page":14,"link":"#130"}],3,1,2)`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'pages': {
+ 'type': 'array',
+ 'default': [
+ {'page': 1, 'link': '#'},
+ {'page': 2, 'link': '#10'},
+ {'page': 3, 'link': '#20'},
+ {'page': 4, 'link': '#30'},
+ {'page': 5, 'link': '#40'},
+ {'page': 6, 'link': '#50'},
+ {'page': 7, 'link': '#60'},
+ {'page': 8, 'link': '#70'},
+ {'page': 9, 'link': '#80'},
+ {'page': 10, 'link': '#90'},
+ {'page': 11, 'link': '#100'},
+ {'page': 12, 'link': '#110'},
+ {'page': 13, 'link': '#120'},
+ {'page': 14, 'link': '#130'}
+ ],
+ 'description': "Array of objects with page number and link. This should include ALL pages, the mixin will remove ones that aren't needed"
+ },
+ 'current': {
+ 'type': 'number',
+ 'default': '6',
+ 'description': 'The current page'
+ },
+ 'relativeNumber': {
+ 'type': 'number',
+ 'default': '1',
+ 'description': 'Number of pages to show each side of current page'
+ },
+ 'absoluteNumber': {
+ 'type': 'number',
+ 'default': '2',
+ 'description': 'Number of pages to show at start and end'
+ }
+ }
+}
diff --git a/schema/components/progress.js b/schema/components/progress.js
new file mode 100644
index 0000000..91faae7
--- /dev/null
+++ b/schema/components/progress.js
@@ -0,0 +1,25 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'progress',
+
+ // Component title - for docs/style guide
+ title: 'Progress Bar',
+
+ // Paragraphs for docs
+ docs: [
+ 'A progress bar can be used to give an indication to users of how far through their wait they are. The #[code= \'\'] element is used and the progress is set with the #[code value] and #[code max] attributes. The percentage can be shown in-line by adding the #[code .show-percent] class.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`progress(value=30, max=100)
+progress.show-percent(value=80, max=100)
+progress.show-percent(value=55, max=100)`
+}
diff --git a/schema/components/quick-links.js b/schema/components/quick-links.js
new file mode 100644
index 0000000..6179b78
--- /dev/null
+++ b/schema/components/quick-links.js
@@ -0,0 +1,113 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'quick-links',
+
+ // Component title - for docs/style guide
+ title: 'Quick Links',
+
+ // Paragraphs for docs
+ docs: [
+ 'An eye-catching navigation with big icons can be used for directing users to the most common pages and actions of a website or application.',
+ 'The links on the menu should be consistent throughout the application to help users learn the pattern.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: true,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`+quick-links([{"label":"Products","link":"#","icon":"tablet"},{"label":"Services","link":"#","icon":"van"},{"label":"Reviews","link":"#","icon":"map"},{"label":"Case Studies","link":"#","icon":"box"},{"label":"Login","link":"#","icon":"laptop"}])
+
+main
+ .content
+ h4 Varying number of links
+
+ p The default amount of links in the quick link bar should be 5. If you need to have 4 or 6 link the classes #[code .four] and #[code .six] should be used to neatly arrange the spacing.
+
+ h4 Icons
+
+ p Icons are added to links with a class, the 5 icons shown here are using #[code .tablet], #[code .van], #[code .map], #[code .box] and #[code .laptop]. To add new icons you will need to define the #[code background-image: url()] with your own class
+
+ .sidebar.no-bottom-pad
+ h4 Vertical quick links
+
+ p Quick links can be displayed vertically (for use in sidebars etc) by adding the #[code .vertical] class. On small devices, vertical quick links are dispayed the same as horizontal.
+
+ +quick-links([{"label":"Products","link":"#","icon":"tablet"},{"label":"Services","link":"#","icon":"van"},{"label":"Reviews","link":"#","icon":"map"},{"label":"Case Studies","link":"#","icon":"box"},{"label":"Login","link":"#","icon":"laptop"}],true)`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'items': {
+ 'type': 'array',
+ 'description': 'array of objects with label/link/icon strings. The length of the array is counted to apply .four or .six class if necessary',
+ 'default': [
+ {
+ 'label': 'Products',
+ 'link': '#',
+ 'icon': 'tablet'
+ },
+ {
+ 'label': 'Services',
+ 'link': '#',
+ 'icon': 'van'
+ },
+ {
+ 'label': 'Reviews',
+ 'link': '#',
+ 'icon': 'map'
+ },
+ {
+ 'label': 'Case Studies',
+ 'link': '#',
+ 'icon': 'box'
+ },
+ {
+ 'label': 'Log In',
+ 'link': '#',
+ 'icon': 'laptop'
+ }
+ ]
+ },
+ 'vertical': {
+ 'type': 'boolean',
+ 'description': 'Vertical mode',
+ 'default': false
+ },
+ 'four': {
+ 'type': 'boolean',
+ 'description': 'Add four class (Auto-detected in js)',
+ 'default': false
+ },
+ 'six': {
+ 'type': 'boolean',
+ 'description': 'Add six class (Auto-detected in js)',
+ 'default': false
+ }
+
+ }
+}
diff --git a/schema/components/radio.js b/schema/components/radio.js
new file mode 100644
index 0000000..66aa259
--- /dev/null
+++ b/schema/components/radio.js
@@ -0,0 +1,105 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'radio',
+
+ // Component title - for docs/style guide
+ title: 'Radio Buttons',
+
+ // Paragraphs for docs
+ docs: [
+ 'Use radio buttons when the user must select just one choice'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: null,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'name': {
+ 'type': 'string',
+ 'default': 'my-radios',
+ 'description': 'The name attribute of the radio group'
+ },
+ 'selectedValue': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'The selected value'
+ },
+ 'id': {
+ 'type': 'string',
+ 'default': 'my-radios',
+ 'description': 'The id of the radio-group'
+ },
+ 'legend': {
+ 'type': 'string',
+ 'default': 'My Radio options',
+ 'description': 'The legend text'
+ },
+ 'helperBelow': {
+ 'type': 'string',
+ 'default': 'Some helpful advice for this field',
+ 'description': 'Helper that appears below the field'
+ },
+ 'helperAbove': {
+ 'type': 'string',
+ 'default': 'More helpful advice for this field',
+ 'description': 'Helper the appears above the field'
+ },
+ 'options': {
+ 'type': 'array',
+ 'default': [
+ {
+ 'label': 'An Option',
+ 'value': '1'
+ },
+ {
+ 'label': 'Another Option',
+ 'value': '2'
+ },
+ {
+ 'label': 'A Third Option',
+ 'value': '3'
+ }
+ ],
+ 'description': 'Array of objects with label/value pairs'
+ },
+ 'stack': {
+ 'type': 'boolean',
+ 'default': false,
+ 'description': 'Display options in vertical stack?'
+ },
+ 'error': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'Error message string, marks whole field as errorneous'
+ }
+ }
+}
diff --git a/schema/components/required.js b/schema/components/required.js
new file mode 100644
index 0000000..5215130
--- /dev/null
+++ b/schema/components/required.js
@@ -0,0 +1,28 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'required',
+
+ // Component title - for docs/style guide
+ title: 'Required Fields',
+
+ // Paragraphs for docs
+ docs: [
+ 'In some applications different input fields will be required or optional. For best usability, optional fields should be marked as optional (in the helper text), and required fields should be the default.'
+ ],
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null
+}
diff --git a/schema/components/select.js b/schema/components/select.js
new file mode 100644
index 0000000..b53d0d5
--- /dev/null
+++ b/schema/components/select.js
@@ -0,0 +1,100 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'select',
+
+ // Component title - for docs/style guide
+ title: 'Select Menu',
+
+ // Paragraphs for docs
+ docs: [
+ 'Use select menus to combine many choices into one dropdown menu. This is useful for saving space, small screen devices have native UI patterns for dealing with these'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: true,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+select('my-input',2,'my-input','My Input','Some helpful advice for this field','More helpful advice for this field',[{"label":"An Option","value":"1"},{"label":"Another Option","value":"2"},{"label":"A Third Option","value":"3"}])`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'name': {
+ 'type': 'string',
+ 'default': 'my-select',
+ 'description': 'The name attribute of the input'
+ },
+ 'selectedValue': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'The default value of the field'
+ },
+ 'id': {
+ 'type': 'string',
+ 'default': 'my-select',
+ 'description': 'The id of the input'
+ },
+ 'label': {
+ 'type': 'string',
+ 'default': 'My Select',
+ 'description': 'The label text'
+ },
+ 'helperBelow': {
+ 'type': 'string',
+ 'default': 'Some helpful advice for this field',
+ 'description': 'Helper that appears below the field'
+ },
+ 'helperAbove': {
+ 'type': 'string',
+ 'default': 'More helpful advice for this field',
+ 'description': 'Helper the appears above the field'
+ },
+ 'options': {
+ 'type': 'array',
+ 'default': [
+ {
+ 'label': 'An Option',
+ 'value': '1'
+ },
+ {
+ 'label': 'Another Option',
+ 'value': '2'
+ },
+ {
+ 'label': 'A Third Option',
+ 'value': '3'
+ }
+ ],
+ 'description': 'Array of objects with label/value pairs'
+ },
+ 'error': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'Error message string, marks whole field as errorneous'
+ }
+ }
+}
diff --git a/schema/components/sub-header.js b/schema/components/sub-header.js
new file mode 100644
index 0000000..fc72b2f
--- /dev/null
+++ b/schema/components/sub-header.js
@@ -0,0 +1,22 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'sub-header',
+
+ // Component title - for docs/style guide
+ title: 'Sub Headers',
+
+ // Paragraphs for docs
+ docs: [
+ 'By inserting a #[code small] element into a header Foundation will scale the header font size down for an inline element, allowing you to use this for subtitles or other secondary header text.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `h4 This is a medium header #[small with a subheader]`
+}
diff --git a/schema/components/sub-menu.js b/schema/components/sub-menu.js
new file mode 100644
index 0000000..8215d8d
--- /dev/null
+++ b/schema/components/sub-menu.js
@@ -0,0 +1,67 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'sub-menu',
+
+ // Component title - for docs/style guide
+ title: 'Sub-menu',
+
+ // Paragraphs for docs
+ docs: [
+ 'The submenu component can be used to help users navigate between pages or screens within the current section.',
+ 'Active menu items (the page the user is currently on) should be given the #[code .active] class to highlight them'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: true,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+sub-menu([{"label":"Menu Item 1","link":"#"},{"label":"Active Menu Item","link":"#","active":true},{"label":"Menu Item 3","link":"#"}])`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'items': {
+ 'type': 'array',
+ 'description': 'Array of objects with label/link strings and active boolean',
+ 'default': [
+ {
+ 'label': 'Menu Item 1',
+ 'link': '#'
+ },
+ {
+ 'label': 'Active Menu Item',
+ 'link': '#',
+ 'active': true
+ },
+ {
+ 'label': 'Menu Item 3',
+ 'link': '#'
+ }
+ ]
+ }
+ }
+}
diff --git a/schema/components/submit.js b/schema/components/submit.js
new file mode 100644
index 0000000..f705eef
--- /dev/null
+++ b/schema/components/submit.js
@@ -0,0 +1,54 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'submit',
+
+ // Component title - for docs/style guide
+ title: 'Submit Button',
+
+ // Paragraphs for docs
+ docs: [
+ 'A mixin for inputs with a type of #[code hidden] has been included'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`+submit('Submit')
+br`,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'value': {
+ 'type': 'string',
+ 'default': 'Submit',
+ 'description': 'The label on the submit button'
+ }
+ }
+}
diff --git a/schema/components/tab-list.js b/schema/components/tab-list.js
new file mode 100644
index 0000000..1982c3f
--- /dev/null
+++ b/schema/components/tab-list.js
@@ -0,0 +1,82 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'tab-list',
+
+ // Component title - for docs/style guide
+ title: 'Tab List',
+
+ // Paragraphs for docs
+ docs: [
+ 'To save on-screen space we can use tabbed content to alternate between views within the same context, whilst staying on the same page.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block:
+`+tab(1)
+ h2 This is tab 1
+ p Some tab content
++tab(2, true)
+ h2 This is tab 2
+ p Some tab content
++tab(3)
+ h2 This is tab 3
+ p Some tab content
++tab(4)
+ h2 This is tab 4
+ p Some tab content`,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: null,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: './pug/components/_tab.pug',
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'tabs': {
+ 'type': 'array',
+ 'default': [
+ {
+ 'label': 'Tab 1',
+ 'id': 1
+ },
+ {
+ 'label': 'Tab 2',
+ 'id': 2,
+ 'active': true
+ },
+ {
+ 'label': 'Tab 3',
+ 'id': 3
+ },
+ {
+ 'label': 'Tab 4',
+ 'id': 4
+ }
+ ],
+ 'description': 'Array of links with label/id/active key/values'
+ }
+ }
+}
diff --git a/schema/components/tab.js b/schema/components/tab.js
new file mode 100644
index 0000000..c75e096
--- /dev/null
+++ b/schema/components/tab.js
@@ -0,0 +1,70 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'tab',
+
+ // Component title - for docs/style guide
+ title: 'Tabs',
+
+ // Paragraphs for docs
+ docs: [
+ 'To save on-screen space we can use tabbed content to alternate between views within the same context, whilst staying on the same page.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: `h3 This is a tab
+ p Some tab content`,
+
+ // Can attributes be passed to the mixin?
+ attributes: false,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+tab-list([{"label":"Tab 1","id":1},{"label":"Tab 2","id":2,"active":true},{"label":"Tab 3","id":3},{"label":"Tab 4","id":4}])
+ +tab(1)
+ h2 This is tab 1
+ p Some tab content
+ +tab(2, true)
+ h2 This is tab 2
+ p Some tab content
+ +tab(3)
+ h2 This is tab 3
+ p Some tab content
+ +tab(4)
+ h2 This is tab 4
+ p Some tab content`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'id': {
+ 'type': 'string',
+ 'default': '1',
+ 'description': 'The id of the tab, must correspond to tab-list id'
+ },
+ 'active': {
+ 'type': 'boolean',
+ 'default': false,
+ 'description': 'Is the tab active'
+ }
+ }
+}
diff --git a/schema/components/table.js b/schema/components/table.js
new file mode 100644
index 0000000..d32d0d3
--- /dev/null
+++ b/schema/components/table.js
@@ -0,0 +1,49 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'table',
+
+ // Component title - for docs/style guide
+ title: 'Tables',
+
+ // Paragraphs for docs
+ docs: [
+ 'Tables are used for showing tabular data. A few simple style tweaks make tables much easier to read. Adding a class of #[code .hover] makes rows highlight on hover.',
+ 'Adding a class of #[code .stack] to a table makes it stack up on small screens for a cleaner layout.'
+ ],
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo:
+`table.stack.hover
+ thead
+ tr
+ th(width='200') Table Header
+ th Another Table Header
+ th Table Header
+ th Table Header
+ tbody
+ tr
+ td Content Goes Here
+ td This is longer content Donec id elit non mi porta gravida at eget metus.
+ td Content Goes Here
+ td
+ a.button.small(href='') A Button
+ tr
+ td Content Goes Here
+ td
+ | This is longer Content Donec id elit non mi porta gravida at eget metus.
+ td
+ td Content Goes Here
+ tr
+ td Content Goes Here
+ td
+ | This is longer Content Donec id elit non mi porta gravida at eget metus.
+ td Content Goes Here
+ td Content Goes Here`
+}
diff --git a/schema/components/textarea.js b/schema/components/textarea.js
new file mode 100644
index 0000000..c1e0e0b
--- /dev/null
+++ b/schema/components/textarea.js
@@ -0,0 +1,82 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'textarea',
+
+ // Component title - for docs/style guide
+ title: 'Text Area',
+
+ // Paragraphs for docs
+ docs: [
+ 'Text areas are used for multi-line text input, for example on a comments form. A text area can also be given a helper label. The text area should be given an appropriate amount of rows (with the #[code rows] attribute) for the text that is expected to be entered.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: 'Default Value',
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+textarea('example-textarea', 'example-textarea', 'Example Text Area', 3, null, 'Some helper text')`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'name': {
+ 'type': 'string',
+ 'default': 'my-input',
+ 'description': 'The name attribute of the text area'
+ },
+ 'id': {
+ 'type': 'string',
+ 'default': 'my-input',
+ 'description': 'The id of the text area'
+ },
+ 'label': {
+ 'type': 'string',
+ 'default': 'My Input',
+ 'description': 'The label text'
+ },
+ 'rows': {
+ 'type': 'number',
+ 'default': 4,
+ 'description': 'The number of rows'
+ },
+ 'helperBelow': {
+ 'type': 'string',
+ 'default': 'Some helpful advice for this field',
+ 'description': 'Helper that appears below the text area'
+ },
+ 'helperAbove': {
+ 'type': 'string',
+ 'default': 'More helpful advice for this field',
+ 'description': 'Helper the appears above the text area'
+ },
+ 'error': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'Error message string, marks whole field as errorneous'
+ }
+ }
+}
diff --git a/schema/components/top-menu.js b/schema/components/top-menu.js
new file mode 100644
index 0000000..2311e63
--- /dev/null
+++ b/schema/components/top-menu.js
@@ -0,0 +1,130 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'top-menu',
+
+ // Component title - for docs/style guide
+ title: 'Main Menu',
+
+ // Paragraphs for docs
+ docs: [
+ 'On applications with multi-level navigation, breadcrumbs can be used to indicate which section the user is in, and help them navigate back up navigation.'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: true,
+
+ // Can the component be demo'd inline
+ inline: false,
+
+ // Default blocks content (false for no block)
+ block: false,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: null,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'items': {
+ 'type': 'array',
+ 'description': 'Multi-dimensional array of items, links and children',
+ 'default': [
+ {
+ 'label': 'Home',
+ 'link': '#'
+ },
+ {
+ 'label': 'A dropdown Menu',
+ 'children': [
+ {
+ 'label': 'Menu Item 1',
+ 'link': '#'
+ },
+ {
+ 'label': 'Menu Item 2',
+ 'link': '#'
+ },
+ {
+ 'label': 'Menu Item 3',
+ 'link': '#'
+ }
+ ]
+ },
+ {
+ 'label': 'Active dropdown Menu',
+ 'active': true,
+ 'children': [
+ {
+ 'label': 'Menu Item 1',
+ 'link': '#'
+ },
+ {
+ 'label': 'Menu Item 2',
+ 'link': '#',
+ 'active': true
+ },
+ {
+ 'label': 'Menu Item 3',
+ 'link': '#'
+ }
+ ]
+ },
+ {
+ 'label': 'A dropdown Menu',
+ 'children': [
+ {
+ 'label': 'Menu Item 1',
+ 'link': '#'
+ },
+ {
+ 'label': 'Menu Item 2',
+ 'link': '#'
+ },
+ {
+ 'label': 'Menu Item 3',
+ 'link': '#'
+ }
+ ]
+ }
+ ]
+ },
+ 'logo': {
+ 'type': 'boolean',
+ 'default': true,
+ 'description': 'Should the logo be included in the menu'
+ },
+ 'logoLink': {
+ 'type': 'string',
+ 'default': '#',
+ 'description': 'Link when clicking on logo'
+ },
+ 'icon': {
+ 'type': 'boolean',
+ 'default': true,
+ 'description': 'Should the hamburger menu icon be shown on mobile'
+ },
+ 'linkText': {
+ 'type': 'string',
+ 'default': 'Menu',
+ 'description': 'Text for mobile menu link'
+ }
+ }
+}
diff --git a/schema/components/typography.js b/schema/components/typography.js
new file mode 100644
index 0000000..6ce366c
--- /dev/null
+++ b/schema/components/typography.js
@@ -0,0 +1,20 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'typography',
+
+ // Component title - for docs/style guide
+ title: 'Typography',
+
+ // Paragraphs for docs
+ docs: [
+ 'All text uses Helvetica Neue with a fallback to Helvetica or Arial. Body text is legible with generous line-spacing and the font-size adapts to the screen size to ensure readability. Paragraphs have a bottom margin to match a vertical rhythm.',
+ 'Paragraphs also have a maximum width of about 700px, so that long lines don\'t become too difficult to read.'
+ ]
+}
diff --git a/schema/components/ui-elements.js b/schema/components/ui-elements.js
new file mode 100644
index 0000000..7b4417e
--- /dev/null
+++ b/schema/components/ui-elements.js
@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'ui-elements',
+
+ // Component title - for docs/style guide
+ title: 'Custom UI Elements'
+}
diff --git a/schema/components/upload.js b/schema/components/upload.js
new file mode 100644
index 0000000..fad7e95
--- /dev/null
+++ b/schema/components/upload.js
@@ -0,0 +1,82 @@
+'use strict'
+
+/**
+ * Component configuration
+ * @type {Object}
+ */
+
+module.exports = {
+ // Component name, must match schema, pug, scss and js filename
+ name: 'upload',
+
+ // Component title - for docs/style guide
+ title: 'File Upload',
+
+ // Paragraphs for docs
+ docs: [
+ 'File upload inputs are inconsistent across all browsers, so we use a label mask to display it like a button. When clicked it opens up the user\'s file browser'
+ ],
+
+ // Does this component break out of the content wrapper
+ breakout: false,
+
+ // Can the component be demo'd inline
+ inline: true,
+
+ // Default blocks content (false for no block)
+ block: true,
+
+ // Can attributes be passed to the mixin?
+ attributes: true,
+
+ // Demo output (Mixin can be called, if left empty default parameters and block will be used)
+ demo: `+upload('example-file-upload', 'example-file-upload', 'Upload your file', 'Upload')`,
+
+ // Path to mixin (if not pug/components/.pug)
+ mixinPath: null,
+
+ // Path to scss (if not scss/components/.scss)
+ scssPath: null,
+
+ // Path to js (if not js/components/.js)
+ jsPath: null,
+
+ // Mixin params (false for no mixin)
+ 'params': {
+ 'name': {
+ 'type': 'string',
+ 'default': 'my-upload',
+ 'description': 'The name attribute of the input'
+ },
+ 'id': {
+ 'type': 'string',
+ 'default': 'my-upload',
+ 'description': 'The id of the input'
+ },
+ 'label': {
+ 'type': 'string',
+ 'default': 'My Upload',
+ 'description': 'The label text'
+ },
+ 'buttonText': {
+ 'type': 'string',
+ 'default': 'An Upload Button',
+ 'description': 'The text on the upload button'
+ },
+ 'helperBelow': {
+ 'type': 'string',
+ 'default': 'Some helpful advice for this field',
+ 'description': 'Helper that appears below the field'
+ },
+ 'helperAbove': {
+ 'type': 'string',
+ 'default': 'More helpful advice for this field',
+ 'description': 'Helper the appears above the field'
+ },
+ 'error': {
+ 'type': 'string',
+ 'default': null,
+ 'description': 'Error message string, marks whole field as errorneous'
+ }
+ }
+}
diff --git a/schema/docs.js b/schema/docs.js
index 3d40932..613c0cd 100644
--- a/schema/docs.js
+++ b/schema/docs.js
@@ -11,17 +11,17 @@ module.exports = {
*/
meta: {
// Title tag
- title: 'style-guider-demo',
+ title: 'Style Guider Demo',
// Include meta-basic mixin?
basic: true,
// Include meta-social mixin?
social: {
// Meta values for the meta social mixin
- url: '',
- title: 'style-guider-demo',
+ url: 'https://style-guider-demo.github.io/',
+ title: 'Style Guider Demo',
image: '',
- description: '',
- siteName: 'style-guider-demo'
+ description: 'Demo site for generator-style-guider',
+ siteName: 'Style Guider'
}
},
@@ -41,7 +41,8 @@ module.exports = {
* Introdcution text. Array of paragraphs. Each string will be a separate paragraph, inline pug will be rendered
*/
introduction: [
- "This is the style-guider-demo CSS framework and style guide, built with #[a(href='https://www.npmjs.com/package/generator-style-guider', target='_blank') Style Guider]"
+ `This is the style-guider-demo CSS framework and style guide, built with #[a(href='https://www.npmjs.com/package/generator-style-guider', target='_blank') Style Guider]. The source code for this style guide can be found on #[a(href='https://github.com/webdevian/style-guider-demo', target='_blank') GitHub].`,
+ `This fictional style guide is designed to give a demonstration of the wide variety of components that Style Guider docs can display`
],
/**
@@ -59,7 +60,52 @@ module.exports = {
*/
menu: {
// NB! The below line is required for our yeoman generator and should not be changed.
- // ------ yeoman include hook ------ //
- 'example': []
- }
+ // ------ yeoman include hook ------ //
+ 'accessibility': [],
+ 'colour': [],
+ 'typography': [
+ 'header',
+ 'bold-header',
+ 'sub-header',
+ 'link',
+ 'list',
+ 'definition-list',
+ 'blockquote',
+ 'divider'
+ ],
+ form: [
+ 'input',
+ 'textarea',
+ 'select',
+ 'checkbox',
+ 'radio',
+ 'upload',
+ 'datepicker',
+ 'errors',
+ 'callout',
+ 'required',
+ 'disabled',
+ 'button',
+ 'submit',
+ 'hidden'
+ ],
+ 'ui-elements': [
+ 'layout',
+ 'table',
+ 'top-menu',
+ 'hero',
+ 'alert',
+ 'sub-menu',
+ 'quick-links',
+ 'card',
+ 'breadcrumbs',
+ 'pagination',
+ 'tab',
+ 'progress',
+ 'login',
+ 'closeable',
+ 'banner',
+ 'footer'
+ ]
+ }
}
diff --git a/scss/_settings.scss b/scss/_settings.scss
index ddcdac8..0813f32 100644
--- a/scss/_settings.scss
+++ b/scss/_settings.scss
@@ -46,7 +46,7 @@
// ------------------------------------
// Main brand red - medium candy apple
-$red: #d71a16;
+$red: #992c0e;
// Main brand blue - dark midnight
$blue: #2e7cac;
@@ -72,10 +72,10 @@ $dark-grey: #35362f;
// Fonts - Helvetica falls back to Arial
// -------------------------------------
-$helvetica: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+$opensans: 'Open Sans', Helvetica, Arial, sans-serif;
+$varela: 'Varela+Round', Arial, sans-serif;
-
-// APC Settings
+// DEMO Settings
// ------------
$img-path: 'node_modules/style-guider-demo/img/' !default;
@@ -88,10 +88,10 @@ $faint-border: 2px solid $faint-gray;
$shadow-gray: rgba(204, 204, 204, .4);
-$lighter-blue: #c9cfde;
-$light-blue: #94a1bd;
-$dark-blue: #0b265c;
-$darker-blue: #09204e;
+$lighter-blue: #94caeb;
+$light-blue: #3999d4;
+$dark-blue: #236085;
+$darker-blue: #184059;
@import 'util/util';
@@ -116,7 +116,7 @@ $black: #0a0a0a;
$white: #fefefe;
$body-background: $white;
$body-font-color: #474747;
-$body-font-family: $helvetica;
+$body-font-family: $opensans;
$body-antialiased: true;
$global-margin: 1.6rem;
$global-padding: 1rem;
@@ -160,7 +160,7 @@ $block-grid-max: 8;
// 4. Base Typography
// ------------------
-$header-font-family: $body-font-family;
+$header-font-family: $varela;
$header-font-weight: 300;
$header-font-style: normal;
$font-family-monospace: 'Hack', Consolas, 'Liberation Mono', Courier, monospace;
diff --git a/scss/components/_accessibility.scss b/scss/components/_accessibility.scss
new file mode 100644
index 0000000..d299090
--- /dev/null
+++ b/scss/components/_accessibility.scss
@@ -0,0 +1,42 @@
+@mixin style-guider-demo-accessibility {
+ // Elements that we want to be visible on screen-readers only
+ .show-for-sr,
+ .show-on-focus {
+ @include element-invisible;
+ }
+}
+
+a:focus {
+ transition: text-shadow .2s ease-in;
+ outline-offset: 1px;
+ text-shadow: $gray-shadow 0 0 2px;
+}
+
+[type='checkbox']:focus,
+[type='radio']:focus {
+ + label {
+ text-decoration: underline;
+ }
+}
+
+.skip-to-content a {
+ position: absolute;
+ top: rem-calc(-46);
+ left: 0;
+ padding: rem-calc(6 10);
+ transition: top 1s ease-out;
+ border-right: 1px solid $white;
+ border-bottom: 1px solid $white;
+ background: $red;
+ color: $white;
+ font-size: rem-calc(12);
+ z-index: 100;
+}
+
+.skip-to-content a:focus {
+ top: 0;
+ transition: top .1s ease-in;
+ outline: 0;
+ color: $white;
+ text-decoration: underline;
+}
diff --git a/scss/components/_alert.scss b/scss/components/_alert.scss
new file mode 100644
index 0000000..188b0aa
--- /dev/null
+++ b/scss/components/_alert.scss
@@ -0,0 +1,107 @@
+@mixin style-guider-demo-alert {
+
+ .message {
+ display: block;
+ position: relative;
+ width: 100%;
+ padding: rem-calc(8 16);
+ border-bottom: 1px solid $white;
+ background-color: $medium-gray;
+ color: $white;
+
+
+ &.alert {
+ background-color: $red;
+ }
+
+ &.warning {
+ background-color: $warning-color;
+ color: $black;
+
+ a,
+ a:hover,
+ a:focus {
+ color: $black;
+ }
+ }
+
+ > *:first-child {
+ @include grid-row();
+ position: relative;
+ margin-bottom: 0;
+ padding: 0;
+ }
+
+ // Padding for the close link
+ &.has-close > *:first-child {
+ padding-right: rem-calc(70);
+ }
+
+ .close {
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+ font-weight: bold;
+ text-decoration: none;
+ cursor: pointer;
+
+ &::before {
+ content: '× ';
+ }
+ }
+
+ a,
+ a:hover,
+ a:focus {
+ color: $white;
+ font-weight: bold;
+ }
+
+ a:hover,
+ a:focus {
+ text-decoration: underline;
+ }
+ }
+
+ @include foundation-callout;
+
+ .callout {
+ max-width: rem-calc(700);
+
+ &.alert,
+ &.warning {
+ a {
+ font-weight: bold;
+ }
+ }
+
+ &.alert a {
+ color: scale-color($red, $lightness: -15%);
+ }
+
+ h5 {
+ color: $body-font-color;
+ font-weight: bold;
+ }
+ }
+
+ // No JS specific alert
+
+ noscript .alert {
+ text-align: center;
+
+ a {
+ text-decoration: underline;
+ }
+ }
+
+ // No JS support
+ // No point showing a close button if it won't work
+
+ .no-js {
+ .message .close {
+ display: none;
+ }
+ }
+}
diff --git a/scss/components/_animation.scss b/scss/components/_animation.scss
new file mode 100644
index 0000000..de8751e
--- /dev/null
+++ b/scss/components/_animation.scss
@@ -0,0 +1,25 @@
+@mixin style-guider-demo-animation {
+ .loading {
+
+ position: relative;
+
+ &::before {
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: $trans-white;
+ background-image: url(#{$img-path}loading.gif);
+ background-repeat: no-repeat;
+ background-position: center top 30%;
+ content: '';
+ z-index: 10;
+ }
+
+ &.blackout::before {
+ background-color: $white;
+ }
+ }
+}
diff --git a/scss/components/_banners.scss b/scss/components/_banners.scss
new file mode 100644
index 0000000..4a8c518
--- /dev/null
+++ b/scss/components/_banners.scss
@@ -0,0 +1,39 @@
+@mixin style-guider-demo-banners {
+ .banner {
+ @extend %clearfix;
+ position: relative;
+ width: 100%;
+ padding: rem-calc(0 24);
+ border-top: $faint-border;
+ border-bottom: $faint-border;
+
+ > div {
+ position: relative;
+ left: 50%;
+ padding: rem-calc(38 0);
+ float: left;
+ transform: translateX(-50%);
+
+ * {
+ margin: 0;
+ }
+
+ *:last-child {
+ color: $red;
+ font-weight: normal;
+ }
+ }
+
+ &.logo > div {
+ padding-right: rem-calc(95 + 8);
+ background-image: url(#{$img-path}style-guider-demo-logo.png);
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-size: rem-calc(95);
+ }
+
+ &.center {
+ text-align: center;
+ }
+ }
+}
diff --git a/scss/components/_breadcrumbs.scss b/scss/components/_breadcrumbs.scss
new file mode 100644
index 0000000..9026211
--- /dev/null
+++ b/scss/components/_breadcrumbs.scss
@@ -0,0 +1,3 @@
+@mixin style-guider-demo-breadcrumbs {
+ @include foundation-breadcrumbs;
+}
diff --git a/scss/components/_buttons.scss b/scss/components/_buttons.scss
new file mode 100644
index 0000000..380bfdc
--- /dev/null
+++ b/scss/components/_buttons.scss
@@ -0,0 +1,57 @@
+@mixin style-guider-demo-buttons {
+ .button,
+ button {
+ @include button();
+
+ &:hover,
+ &:focus {
+ text-decoration: none;
+ }
+
+ &.alert {
+ @include button-style($red, scale-color($red, $lightness: -15%), $white);
+ }
+
+ &.secondary {
+ @include button-style($medium-gray, scale-color($medium-gray, $lightness: -15%), $white);
+ }
+
+ &.large {
+ padding: rem-calc(17 20);
+ font-size: rem-calc(20);
+ }
+
+ &.expanded {
+ display: block;
+ width: 100%;
+ margin-right: 0;
+ margin-left: 0;
+ }
+
+ &.small {
+ padding: rem-calc(7 10);
+ }
+
+ &.tiny {
+ padding: rem-calc(5 6);
+ font-size: rem-calc(13);
+ }
+
+ &:not(:last-child) {
+ margin-right: rem-calc(12);
+ }
+ }
+
+ [type=submit] {
+ @extend .button;
+ }
+
+ .button[disabled] {
+ background: $lighter-gray;
+ cursor: not-allowed;
+
+ &:hover {
+ background: $lighter-gray;
+ }
+ }
+}
diff --git a/scss/components/_cards.scss b/scss/components/_cards.scss
new file mode 100644
index 0000000..ff78aba
--- /dev/null
+++ b/scss/components/_cards.scss
@@ -0,0 +1,40 @@
+@mixin style-guider-demo-cards {
+ .card {
+ display: block;
+ padding: rem-calc(24);
+
+ &.flat {
+ background-color: $faint-gray;
+ }
+
+ &.shadow {
+ border: 1px solid $faint-gray;
+ background-color: $white;
+ box-shadow: 0 0 6px 1px $shadow-gray;
+ }
+
+ > a {
+ display: block;
+ text-align: right;
+ }
+ }
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5 {
+ a {
+ color: $blue;
+ }
+ }
+
+ .meta,
+ .meta a,
+ time,
+ time a {
+ color: $medium-gray;
+ font-size: rem-calc(14);
+ text-transform: uppercase;
+ }
+}
diff --git a/scss/components/_datepicker.scss b/scss/components/_datepicker.scss
new file mode 100644
index 0000000..b16943e
--- /dev/null
+++ b/scss/components/_datepicker.scss
@@ -0,0 +1,108 @@
+@mixin style-guider-demo-datepicker {
+
+ .hasDatepicker { // sass-lint:disable-line class-name-format
+ padding-left: rem-calc(32);
+ background-image: url(#{$img-path}calendar.png);
+ background-repeat: no-repeat;
+ background-position: left rem-calc(8) center;
+ cursor: pointer;
+
+ &:focus {
+ background-image: url(#{$img-path}calendar-focus.png);
+ }
+ }
+
+ .ui-datepicker {
+ @extend %clearfix;
+ display: none;
+ width: rem-calc(350);
+ max-width: 100%;
+ padding-top: rem-calc(8);
+ padding-bottom: rem-calc(8);
+
+ table {
+ margin-bottom: 0;
+ }
+
+ th {
+ background-color: $white;
+ text-align: center;
+ }
+
+ td {
+ width: 14.285%; // 100 / 7
+ text-align: center;
+
+ &.ui-datepicker-current-day {
+ border-width: 3px;
+ border-style: solid;
+ border-color: $light-gray;
+ font-weight: bold;
+ }
+ }
+
+ a {
+ line-height: rem-calc(18);
+ }
+
+ a:hover,
+ a:focus {
+ font-weight: bold;
+ }
+
+ tr:nth-child(odd) {
+ background: smart-scale($table-background, 15%);
+ }
+ }
+
+ .ui-datepicker-other-month {
+ background-color: $white;
+ }
+
+ .ui-datepicker-header,
+ .ui-datepicker-calendar {
+ padding: rem-calc(8 8);
+ background-color: $white;
+ box-shadow: $input-shadow-focus;
+
+ }
+
+ .ui-datepicker-header {
+ background-color: scale-color($red, $saturation: -20%, $lightness: 20%);
+ }
+
+ .ui-datepicker-calendar {
+ padding-top: 0;
+ border-width: 1px;
+ border-style: solid;
+ border-color: $light-gray;
+ border-top-color: $lighter-gray;
+ }
+
+ .ui-datepicker-prev,
+ .ui-datepicker-next {
+ width: 50%;
+ float: left;
+ color: $white;
+ font-weight: normal;
+
+ &:hover,
+ &:focus {
+ color: $white;
+ font-weight: normal;
+ text-decoration: underline;
+ }
+ }
+
+ .ui-datepicker-next {
+ text-align: right;
+ }
+
+ .ui-datepicker-title {
+ width: 100%;
+ color: $white;
+ font-size: rem-calc(20);
+ font-weight: bold;
+ text-align: center;
+ }
+}
diff --git a/scss/components/_example.scss b/scss/components/_example.scss
deleted file mode 100644
index 108d56f..0000000
--- a/scss/components/_example.scss
+++ /dev/null
@@ -1,102 +0,0 @@
-@mixin style-guider-demo-example {
-
- main,
- .contain,
- .row {
- @include grid-row();
- clear: both;
- }
-
- .nest {
- @include grid-row-nest();
- clear: both;
- }
-
- @include foundation-global-styles;
-
- @include foundation-forms;
-
- %helper-text {
- // Input hint or example
- display: block;
- margin-top: -1.6rem;
- margin-bottom: 1.6rem;
- color: $medium-gray;
- font-size: rem-calc(12);
- font-style: italic;
- }
-
- input,
- textarea,
- select,
- label,
- legend,
- fieldset {
- + span,
- + span + span {
- @extend %helper-text;
- }
- }
-
- [for] {
- cursor: pointer;
- }
-
- label + span,
- legend + span {
- margin-top: 0;
- margin-bottom: 0;
- }
-
-
- .has-error {
- input,
- textarea,
- select {
- border-color: $alert-color;
- }
-
- label,
- legend,
- .error-message {
- color: $alert-color;
- }
-
- [type=file] + label {
- color: $white;
- }
-
- [type='checkbox'],
- [type='radio'] {
- + label {
- color: $black;
- }
- }
-
- .error-message {
- font-style: normal;
- font-weight: bold;
- }
- }
-
- [type='text'],
- [type='password'],
- [type='date'],
- [type='datetime'],
- [type='datetime-local'],
- [type='month'],
- [type='week'],
- [type='email'],
- [type='number'],
- [type='search'],
- [type='tel'],
- [type='time'],
- [type='url'],
- [type='color'],
- select,
- textarea,
- .input-group {
- max-width: rem-calc(700);
- margin-bottom: 1.6rem;
- }
-}
diff --git a/scss/components/_footer.scss b/scss/components/_footer.scss
new file mode 100644
index 0000000..3ee93f8
--- /dev/null
+++ b/scss/components/_footer.scss
@@ -0,0 +1,120 @@
+@mixin style-guider-demo-footer {
+ footer {
+ @extend %clearfix;
+ background-color: $darker-blue;
+ color: $white;
+ font-size: rem-calc(14);
+
+ ul {
+ margin: 0;
+ list-style: none;
+ }
+
+ a {
+ color: $lighter-blue;
+
+ &:hover,
+ &:focus {
+ color: $light-blue;
+ text-decoration: underline;
+ }
+ }
+
+ h1,
+ h2,
+ h3,
+ h4 {
+ color: $white;
+ }
+
+ .top {
+ @extend %clearfix;
+ padding: rem-calc(42 0);
+ border-top: rem-calc(15) solid $dark-blue;
+ background-color: $blue;
+
+ @include breakpoint(medium down) {
+ nav:nth-of-type(3) {
+ float: right;
+ }
+ }
+
+ nav {
+ @include grid-columns(6, 3, 2);
+ }
+
+ ul {
+ @include breakpoint(medium down) {
+ margin-bottom: 1.6rem;
+ }
+ }
+ }
+
+ aside {
+ @include grid-columns(12, 6, 4);
+
+ // Could do with adding extra margin here
+ // but it's tricky as the widths are already
+ // balanced. Would need to set margin then
+ // deduct it from width, for each size, and
+ // first / last variants
+
+ border-right: 3px solid $dark-blue;
+ border-left: 3px solid $dark-blue;
+
+ &:first-child {
+ border-left: 0;
+ }
+
+ &:last-child {
+ border-right: 0;
+ }
+ }
+
+ small {
+ font-size: rem-calc(10);
+ }
+
+ nav {
+ h4 {
+ color: $lighter-blue;
+ font-size: rem-calc(18);
+ font-weight: bold;
+ line-height: 1;
+ }
+ }
+
+ .middle {
+ padding: rem-calc(16);
+ background-color: $dark-blue;
+
+ span {
+ float: left;
+ }
+
+ nav {
+ float: right;
+ }
+
+ li {
+ display: inline;
+ margin-right: rem-calc(21);
+ }
+ }
+
+ .bottom {
+ padding: rem-calc(16 0);
+ color: $light-blue;
+ font-size: rem-calc(11);
+ letter-spacing: .05px; // Makes text more legible
+ text-align: center;
+
+ p {
+ max-width: none;
+ margin-right: auto;
+ margin-bottom: 0;
+ margin-left: auto;
+ }
+ }
+ }
+}
diff --git a/scss/components/_forms.scss b/scss/components/_forms.scss
new file mode 100644
index 0000000..c8075f4
--- /dev/null
+++ b/scss/components/_forms.scss
@@ -0,0 +1,156 @@
+@mixin style-guider-demo-forms {
+ @include foundation-forms;
+
+ %helper-text {
+ // Input hint or example
+ display: block;
+ margin-top: -1.6rem;
+ margin-bottom: 1.6rem;
+ color: $medium-gray;
+ font-size: rem-calc(12);
+ font-style: italic;
+ }
+
+ input,
+ textarea,
+ select,
+ label,
+ legend,
+ fieldset {
+ + span,
+ + span + span {
+ @extend %helper-text;
+ }
+ }
+
+ [for] {
+ cursor: pointer;
+ }
+
+ label + span,
+ legend + span {
+ margin-top: 0;
+ margin-bottom: 0;
+ }
+
+ legend {
+ margin-bottom: 0;
+ }
+
+ fieldset {
+ margin-bottom: 1.6rem;
+
+ label + span + .error-message {
+ margin-top: 0;
+ }
+
+ > div {
+ display: inline-block;
+ }
+
+ &.stack-list > div {
+ display: block;
+ }
+ }
+
+ [type=file] + label {
+ @extend .button, .button.secondary;
+
+ position: relative;
+ padding-left: rem-calc(36);
+
+ + span {
+ margin-top: -1.6rem;
+ margin-bottom: 1.6rem;
+ }
+
+ &::before {
+ position: absolute;
+ top: 50%;
+ left: 1rem;
+ width: 0;
+ height: 0;
+ transform: translateY(-50%);
+ border-width: 0 5.5px 9px;
+ border-style: solid;
+ border-color: transparent transparent $white;
+ content: '';
+ }
+ }
+
+ .has-error {
+ input,
+ textarea,
+ select {
+ border-color: $red;
+ }
+
+ label,
+ legend,
+ .error-message {
+ color: $red;
+ }
+
+ [type=file] + label {
+ color: $white;
+ }
+
+ [type='checkbox'],
+ [type='radio'] {
+ + label {
+ color: $black;
+ }
+ }
+
+ .error-message {
+ font-style: normal;
+ font-weight: bold;
+ }
+ }
+
+ [type='text'],
+ [type='password'],
+ [type='date'],
+ [type='datetime'],
+ [type='datetime-local'],
+ [type='month'],
+ [type='week'],
+ [type='email'],
+ [type='number'],
+ [type='search'],
+ [type='tel'],
+ [type='time'],
+ [type='url'],
+ [type='color'],
+ select,
+ textarea,
+ .input-group {
+ max-width: rem-calc(700);
+ margin-bottom: 1.6rem;
+ }
+
+ [type='file'],
+ [type='checkbox'],
+ [type='radio'] {
+ // Makes vertical lists of radios a bit tighter
+ margin-bottom: .6rem;
+ cursor: pointer;
+ }
+
+ [type='checkbox'],
+ [type='radio'] {
+ +[for] {
+ // Remove non-click space between box and label
+ margin-left: 0;
+ padding-left: .5rem;
+ }
+ }
+
+ .input-group input {
+ margin-bottom: 0;
+ }
+
+ [type=file] {
+ @include element-invisible;
+ }
+}
diff --git a/scss/components/_hero.scss b/scss/components/_hero.scss
new file mode 100644
index 0000000..1ed4fca
--- /dev/null
+++ b/scss/components/_hero.scss
@@ -0,0 +1,73 @@
+@mixin style-guider-demo-hero {
+ .hero {
+ position: relative;
+ width: 100%;
+ height: 0;
+ padding-bottom: 66.67%;
+ overflow: hidden;
+
+ @include breakpoint(medium) {
+ padding-bottom: 45%;
+ };
+
+ @include breakpoint(large) {
+ padding-bottom: 33%;
+ };
+
+ @include breakpoint(xlarge) {
+ padding-bottom: 30%;
+ };
+
+ @include breakpoint(xxlarge) {
+ padding-bottom: 25%;
+ };
+
+ > * {
+ @include rprop('width', 120%, 100%);
+ @include rprop('max-width', 120%, 100%);
+ }
+
+ &.slim {
+ padding-bottom: 40%;
+
+ @include breakpoint(medium) {
+ padding-bottom: 30%;
+ };
+
+ @include breakpoint(large) {
+ padding-bottom: 25%;
+ };
+
+ }
+
+ &.outline {
+ &::after {
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-image: url(#{$img-path}hero-overlay.png);
+ background-repeat: no-repeat;
+ background-position: top center;
+ content: '';
+
+ @include breakpoint(small only) {
+ background-size: auto 120%;
+ };
+ }
+
+ > * {
+ display: block;
+ width: $global-width;
+ margin-right: auto;
+ margin-left: auto;
+ }
+ }
+ }
+
+ menu + .hero {
+ @include rprop('margin-top', rem-calc(-40), rem-calc(-20));
+ }
+}
diff --git a/scss/components/_layout.scss b/scss/components/_layout.scss
new file mode 100644
index 0000000..ba47d9c
--- /dev/null
+++ b/scss/components/_layout.scss
@@ -0,0 +1,77 @@
+@mixin style-guider-demo-layout {
+ main,
+ .contain,
+ .row {
+ @include grid-row();
+ clear: both;
+ }
+
+ .nest {
+ @include grid-row-nest();
+ clear: both;
+ }
+
+ .full,
+ .content,
+ .sidebar {
+ @include rprop(padding-top, rem-calc(24), rem-calc(36), rem-calc(48));
+ @include rprop(padding-bottom, rem-calc(24), rem-calc(36), rem-calc(48));
+
+ &.no-pad {
+ // For use in docs where we keep breaking out of
+ // containers to remove the extra whitespace
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+
+ &.no-top-pad {
+ padding-top: 0;
+ }
+
+ &.no-bottom-pad {
+ padding-bottom: 0;
+ }
+ }
+
+ .full {
+ @include grid-column(12);
+ }
+
+ .content {
+ @include grid-columns(12, 7, 8);
+ @include breakpoint(medium) {
+ border-right: 1px solid $faint-gray;
+
+ &.no-border {
+ border: 0;
+ }
+ }
+ }
+
+ .sidebar {
+ @include grid-columns(12, 5, 4);
+ }
+
+ .breakout {
+ margin-top: rem-calc(20);
+ margin-right: calc(50% - 50vw);
+ margin-bottom: rem-calc(20);
+ margin-left: calc(50% - 50vw);
+ }
+
+ .half {
+ @include grid-columns(12, 6, 6, true)
+ }
+
+ .third {
+ @include grid-columns(12, 4, 4, true)
+ }
+
+ .quarter {
+ @include grid-columns(6, 3, 3, true)
+ }
+
+ .sixth {
+ @include grid-columns(6, 3, 2, true)
+ }
+}
diff --git a/scss/components/_login.scss b/scss/components/_login.scss
new file mode 100644
index 0000000..07b91eb
--- /dev/null
+++ b/scss/components/_login.scss
@@ -0,0 +1,34 @@
+@mixin style-guider-demo-login {
+ .login-page {
+ position: relative;
+ min-height: 100vh;
+ background-color: $blue;
+ }
+
+ .login {
+ @include rprop('max-width', 90%, rem-calc(400));
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 100%;
+ padding: rem-calc(24);
+ transform: translateY(-50%) translateX(-50%);
+ background-color: $white;
+ }
+
+ .login-go {
+ @extend .button;
+ width: 100%;
+ }
+
+ .login-signup {
+ margin-top: rem-calc(16);
+ padding-top: rem-calc(16);
+ border-top: 1px solid $faint-gray;
+ text-align: center;
+
+ :last-child {
+ margin-bottom: 0;
+ }
+ }
+}
diff --git a/scss/components/_pagination.scss b/scss/components/_pagination.scss
new file mode 100644
index 0000000..b175c6c
--- /dev/null
+++ b/scss/components/_pagination.scss
@@ -0,0 +1,16 @@
+@mixin style-guider-demo-pagination {
+ @include foundation-pagination;
+
+ .pagination {
+ text-align: center;
+
+ a:hover,
+ button:hover {
+ color: $anchor-color;
+ }
+
+ a:focus {
+ outline-offset: -3px;
+ }
+ }
+}
diff --git a/scss/components/_progress.scss b/scss/components/_progress.scss
new file mode 100644
index 0000000..a1ac400
--- /dev/null
+++ b/scss/components/_progress.scss
@@ -0,0 +1,29 @@
+@mixin style-guider-demo-progress {
+ @include foundation-progress-element;
+
+ progress[value] { // sass-lint:disable-line no-qualifying-elements
+ cursor: progress;
+ }
+
+ .show-percent {
+ position: relative;
+ padding-right: rem-calc(48);
+
+ &::after {
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: rem-calc(48);
+ height: $progress-height;
+ padding-right: rem-calc(8);
+ padding-left: rem-calc(8);
+ background: $light-gray;
+ color: $white;
+ font-size: rem-calc(12);
+ font-weight: bold;
+ text-align: center;
+ content: attr(value) '%';
+ }
+ }
+}
diff --git a/scss/components/_quick-links.scss b/scss/components/_quick-links.scss
new file mode 100644
index 0000000..430709b
--- /dev/null
+++ b/scss/components/_quick-links.scss
@@ -0,0 +1,123 @@
+@mixin style-guider-demo-quick-links {
+ .quick {
+
+ border-top: $faint-border;
+ border-bottom: $faint-border;
+
+ ul {
+ @include grid-row();
+ @include grid-layout(5, 'li', $grid-column-gutter);
+ margin-bottom: rem-calc(16);
+ padding-top: rem-calc(16);
+ list-style: none;
+
+ }
+
+ a:hover,
+ a:focus {
+ outline-color: $red;
+ outline-offset: 3px;
+ outline-width: medium;
+ color: $red;
+ text-decoration: none;
+ }
+
+ // Different layouts depending on how many children
+ // Currently done with a class, but could
+ // be done more cleverly with css selectors
+ // http://stackoverflow.com/a/12198561/1868365
+
+ &.six ul {
+ @include grid-layout(6, 'li');
+ }
+
+ &.four ul {
+ @include grid-layout(4, 'li');
+ }
+
+ li {
+ padding-top: rem-calc(16);
+ background-repeat: no-repeat;
+ background-position: center bottom;
+ background-size: rem-calc(95);
+
+
+ }
+
+ @include breakpoint(small only) {
+ ul {
+ @include grid-layout(3, 'li');
+ }
+
+ &:not(.four, .six) li:nth-last-of-type(2) {
+ margin-left: percentage(1 / 6);
+ }
+
+ &.six ul {
+ @include grid-layout(3, 'li');
+ }
+
+ &.four ul {
+ @include grid-layout(2, 'li');
+ }
+ }
+
+ a {
+ display: block;
+ height: 0;
+ // Padding added to link to make icon clickable too
+ padding-bottom: rem-calc(130);
+ color: $dark-gray;
+ font-size: rem-calc(20);
+ font-weight: 300;
+ line-height: 1;
+ text-align: center;
+ }
+
+ @include breakpoint(medium) {
+ &.vertical {
+ border: 0;
+
+ ul {
+ @include grid-layout(1, 'li');
+ margin-bottom: 0;
+ padding-top: 0;
+ }
+
+ li {
+ padding: rem-calc(4 0);
+ background-position: left center;
+ background-size: rem-calc(80);
+ }
+
+ a {
+ height: auto;
+ padding: rem-calc(32 16 32 96);
+ text-align: left;
+ }
+
+ }
+ }
+
+ }
+
+ .tablet {
+ background-image: url(#{$img-path}red-tablet.png);
+ }
+
+ .van {
+ background-image: url(#{$img-path}red-van.png);
+ }
+
+ .map {
+ background-image: url(#{$img-path}red-map.png);
+ }
+
+ .box {
+ background-image: url(#{$img-path}red-box.png);
+ }
+
+ .laptop {
+ background-image: url(#{$img-path}red-laptop.png);
+ }
+}
diff --git a/scss/components/_reset.scss b/scss/components/_reset.scss
new file mode 100644
index 0000000..c9313b2
--- /dev/null
+++ b/scss/components/_reset.scss
@@ -0,0 +1,3 @@
+@mixin style-guider-demo-reset {
+ @include foundation-global-styles;
+}
diff --git a/scss/components/_sub-menu.scss b/scss/components/_sub-menu.scss
new file mode 100644
index 0000000..acfc57e
--- /dev/null
+++ b/scss/components/_sub-menu.scss
@@ -0,0 +1,41 @@
+@mixin style-guider-demo-sub-menu {
+ .sub-menu {
+ width: 100%;
+ border-top: 1px solid $faint-gray;
+ border-bottom: 1px solid $faint-gray;
+ background-color: $white;
+
+ ul {
+ @include grid-row();
+ margin-bottom: 0;
+ list-style: none;
+
+ @include breakpoint(xlarge) {
+ border-left: 1px solid $faint-gray;
+ }
+ }
+
+ li {
+ float: left;
+ border-right: 1px solid $faint-gray;
+ }
+
+ .active a {
+ background-color: $faint-gray;
+ }
+
+ a {
+ display: block;
+ padding: rem-calc(8 28);
+ background-color: $white;
+ color: $dark-gray;
+
+ &:hover,
+ &:focus {
+ outline: none;
+ background-color: $faint-gray;
+ color: $dark-gray;
+ }
+ }
+ }
+}
diff --git a/scss/components/_tables.scss b/scss/components/_tables.scss
new file mode 100644
index 0000000..ded445c
--- /dev/null
+++ b/scss/components/_tables.scss
@@ -0,0 +1,52 @@
+@mixin style-guider-demo-tables {
+ @include foundation-table;
+
+ @include breakpoint(medium down) {
+ .stack {
+
+ tbody {
+ border-bottom: 0;
+ }
+
+ tr {
+ padding: rem-calc(6 0);
+ border-bottom: $table-border;
+ background-color: $table-background !important; // sass-lint:disable-line no-important
+ // Important required to override hover etc
+ }
+
+ tr:nth-child(even) {
+ // Override rule caused by odd/even colours
+ border-bottom: $table-border;
+ }
+
+ // Javascript passes the table headers for each td cell to
+ // the data-th attribute, so we can display it again
+ [data-th]::before {
+ display: block;
+ font-size: rem-calc(14);
+ font-weight: bold;
+ line-height: 1;
+ content: attr(data-th) ':';
+ }
+
+ td .button,
+ td button {
+ margin-top: rem-calc(8);
+ }
+
+ td:empty {
+ display: none;
+ }
+ }
+ }
+
+ table .button,
+ table button {
+ margin-bottom: 0;
+ }
+
+ tr th {
+ background-color: $table-head-background;
+ }
+}
diff --git a/scss/components/_tabs.scss b/scss/components/_tabs.scss
new file mode 100644
index 0000000..d64ba35
--- /dev/null
+++ b/scss/components/_tabs.scss
@@ -0,0 +1,85 @@
+@mixin style-guider-demo-tabs {
+
+ .tabs {
+ @extend %clearfix;
+ margin-bottom: 1.6rem;
+
+ .active a:focus {
+ outline: none;
+ }
+
+ > ul {
+ @extend %clearfix;
+ width: 100%;
+ margin: 0;
+ border-bottom: 1px solid $lighter-gray;
+ list-style: none;
+
+ a:focus {
+ text-shadow: none;
+ }
+
+ li {
+ @include rprop('padding', rem-calc(3 8), rem-calc(4 10), rem-calc(5 12));
+ display: inline-block;
+ position: relative;
+ bottom: 0;
+ margin-top: rem-calc(6);
+ margin-right: -1px;
+ float: left;
+ border: 1px solid $lighter-gray;
+ border-bottom: 0;
+ background-color: $faint-gray;
+ }
+
+ .active {
+ @include rprop('padding', rem-calc(6 14 4), rem-calc(7 16 5), rem-calc(9 18 5));
+ position: relative;
+ bottom: -3px;
+ margin-top: 0;
+ border-bottom: 1px solid $white;
+ background-color: $white;
+ }
+
+ a {
+ display: block;
+ color: $blue;
+ }
+ }
+
+ .panel {
+ @include grid-column(12);
+ display: none;
+ padding-top: rem-calc(20);
+ padding-bottom: rem-calc(40);
+ border: 1px solid $lighter-gray;
+ border-top-width: 0;
+
+ &.active {
+ display: block;
+ }
+
+ > :last-child {
+ margin-bottom: 0;
+ }
+ }
+ }
+
+ .no-js {
+ .tabs > ul {
+ margin-bottom: rem-calc(16);
+ border-bottom-width: 0;
+ }
+
+ .tabs li {
+ border: 1px solid $lighter-gray;
+ }
+
+ .panel {
+ display: block;
+ margin-bottom: rem-calc(16);
+ border-top-width: 1px;
+ }
+ }
+
+}
diff --git a/scss/components/_top-menu.scss b/scss/components/_top-menu.scss
new file mode 100644
index 0000000..80cc425
--- /dev/null
+++ b/scss/components/_top-menu.scss
@@ -0,0 +1,335 @@
+@mixin style-guider-demo-top-menu {
+ // sass-lint:disable nesting-depth
+
+ menu {
+ @extend %clearfix;
+ position: relative;
+ width: 100%;
+ // In case there are no block children
+ min-height: rem-calc(42);
+ margin: rem-calc(0 0 40);
+ padding: 0;
+ background-color: $dark-gray;
+ color: $white;
+
+ .logo-link {
+ display: block;
+ position: absolute;
+ left: rem-calc(8);
+ width: rem-calc(100);
+ height: rem-calc(100);
+ padding: 0;
+ background-color: transparent;
+ background-image: url('#{$img-path}style-guider-demo-logo.png');
+ background-repeat: no-repeat;
+ background-position: top left;
+ background-size: 100%;
+ text-indent: -10000px;
+ z-index: 5;
+ }
+
+ // Helper class for when the logo is
+ // overhanging onto content
+ &.safe-pad .logo-link {
+ width: rem-calc(80);
+ height: rem-calc(80);
+ }
+
+ .toggle {
+ display: none;
+ }
+
+ .menu-link {
+ display: block;
+ position: relative;
+ right: 0;
+ padding: rem-calc(13 38 13 4);
+ color: $white;
+ font-weight: bold;
+ line-height: 1;
+ text-align: right;
+ text-transform: uppercase;
+ cursor: pointer;
+
+ &:focus {
+ outline: none;
+ background: scale-color($dark-gray, $lightness: 10%);
+ text-decoration: underline;
+ }
+ }
+
+ .menu-icon,
+ .menu-icon::before,
+ .menu-icon::after {
+ display: block;
+ position: absolute;
+ width: rem-calc(25);
+ height: rem-calc(4);
+ border-radius: 1px;
+ background-color: $white;
+ content: '';
+ cursor: pointer;
+ }
+
+ .menu-icon {
+ top: rem-calc(19);
+ right: rem-calc(6);
+ }
+
+ .menu-icon::before {
+ top: rem-calc(-8);
+ }
+
+ .menu-icon::after {
+ top: rem-calc(8);
+ }
+
+ // Top level and dropdown links
+ a,
+ a:hover,
+ a:focus {
+ color: $white;
+ }
+
+ a {
+ display: block;
+ //
+ padding: rem-calc(13 19);
+ transition: background .3s;
+ background-color: $dark-gray;
+ line-height: 1;
+ }
+
+ ul,
+ ul ul {
+ margin: 0;
+ list-style: none;
+ }
+
+ &.open .wrap > ul {
+ display: block;
+ }
+
+ // Negative margins for phantom borders
+ // appearing between menu items
+ @include breakpoint(small only) {
+ li {
+ margin-top: -1px;
+ }
+
+ li a,
+ .wrap > ul > li a {
+ &:focus {
+ outline: none;
+ background-color: $light-gray;
+ text-decoration: underline;
+ text-shadow: none;
+ }
+ }
+ }
+
+ ul ul li {
+ &:not(:first-child) {
+ margin-top: -1px;
+ }
+ }
+
+ .active ul .active a {
+ color: $light-gray;
+ }
+
+ .wrap > ul {
+ display: none;
+
+ li {
+ text-align: right;
+ }
+
+ > li {
+
+ &.down a {
+ @include breakpoint(small only) {
+ background-color: scale-color($dark-gray, $lightness: 5%);
+ }
+ }
+
+ ul {
+ display: none;
+ position: relative;
+ top: -100%;
+ }
+
+ &.down ul {
+ display: block;
+
+ @include breakpoint(small only) {
+ a {
+ padding: rem-calc(8 36 8 21);
+ font-size: rem-calc(14);
+ }
+ }
+ }
+ }
+ }
+
+ @include breakpoint(medium) {
+
+ margin: rem-calc(0 0 20);
+
+ .logo-link {
+ top: rem-calc(16);
+ right: rem-calc(16);
+ left: auto;
+ width: rem-calc(120);
+ height: rem-calc(120);
+ }
+
+ &.safe-pad .logo-link {
+ top: rem-calc(8);
+ right: rem-calc(8);
+ width: rem-calc(90);
+ height: rem-calc(90);
+ }
+
+ li a {
+ display: block;
+ text-align: left;
+
+ &:hover,
+ &:focus {
+ outline: none;
+ background-color: $light-gray;
+ text-decoration: underline;
+ text-shadow: none;
+ }
+ }
+
+ .active ul .active a {
+ color: $white;
+ }
+
+ .active > a,
+ .active > a:hover,
+ .active > a:focus {
+ background-color: $blue;
+ }
+
+ // Hide toggle checkbox desktop
+ .menu-link,
+ .menu-icon {
+ display: none;
+ }
+
+ .wrap {
+ @include grid-row();
+ position: relative;
+ padding-right: rem-calc(116);
+
+ > ul {
+ display: block;
+
+ > li {
+ position: relative;
+ float: left;
+ border-right: 1px solid $white;
+
+ // Use .down to "activate" a menu item
+ // on click and drop down contents
+ &.down {
+
+ ul {
+ display: block;
+ }
+ }
+
+ // Hidden by default
+ ul {
+ display: none;
+ position: absolute;
+ top: 100%;
+ right: auto;
+ left: 0;
+ margin-left: -1px; // Line up with border
+ border: 1px solid $white;
+ list-style: none;
+ z-index: 1;
+ }
+ }
+ }
+ }
+
+ .has-dropdown > a {
+ padding-right: rem-calc(24);
+
+ &::after {
+ display: block;
+ position: absolute;
+ top: 50%;
+ right: rem-calc(10);
+ width: 0;
+ height: 0;
+ margin-top: rem-calc(-1);
+ border: inset rem-calc(4);
+ border-bottom-width: 0;
+ border-top-style: solid;
+ border-color: $white transparent transparent;
+ content: '';
+ }
+ }
+ }
+
+ @include breakpoint(large) {
+ .wrap {
+ padding-right: rem-calc(160);
+ }
+
+ .logo-link {
+ width: rem-calc(144);
+ height: rem-calc(144);
+ }
+
+ &.safe-pad + * {
+ margin-top: rem-calc(30);
+ }
+
+ &.safe-pad .logo-link {
+ width: rem-calc(100);
+ height: rem-calc(100);
+ }
+ }
+
+ @include breakpoint($global-width) {
+ .wrap > ul > li:first-child {
+ border-left: 1px solid $white;
+ }
+ }
+ }
+
+ // No JS support
+
+ .no-js .has-dropdown > a:focus + ul,
+ .no-js .has-dropdown:hover ul {
+ display: block;
+ }
+
+ @include breakpoint(small only) {
+ .no-js .menu-link:focus,
+ .no-js .menu-link:hover {
+ + ul,
+ + ul ul {
+ display: block;
+ }
+ }
+
+ .no-js menu ul:hover,
+ .no-js menu ul:hover ul {
+ display: block;
+ }
+
+ .no-js menu ul ul a {
+ padding: rem-calc(8 36 8 21);
+ background-color: scale-color($dark-gray, $lightness: 5%);
+ font-size: rem-calc(14);
+ }
+ }
+}
diff --git a/scss/components/_typography.scss b/scss/components/_typography.scss
new file mode 100644
index 0000000..3a9f42f
--- /dev/null
+++ b/scss/components/_typography.scss
@@ -0,0 +1,74 @@
+@mixin style-guider-demo-typography {
+
+ @import url('https://fonts.googleapis.com/css?family=Open+Sans|Varela+Round'); // sass-lint:disable-line no-url-domains no-url-protocols
+
+
+ :root {
+ font-size: 1.125rem;
+
+ @include breakpoint(medium) {
+ font-size: 1rem;
+ }
+ }
+
+ @include foundation-typography;
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ &.heavy {
+ font-weight: 400;
+ }
+ }
+
+ p {
+ max-width: rem-calc(700);
+ }
+
+ // Stop CMS editors abusing p tags as line breaks
+ p:empty {
+ display: none;
+ }
+
+ main p + ul,
+ main p + ol {
+ margin-top: -1.3rem;
+ }
+
+ main a:hover,
+ main a:focus {
+ text-decoration: underline;
+ }
+
+ dt {
+ @extend h5;
+ }
+
+ dd + dt {
+ margin-top: 1.6rem;
+ }
+
+ blockquote {
+ font-weight: 400;
+ }
+
+ .closeable {
+ position: relative;
+
+ .close {
+ position: absolute;
+ top: rem-calc(4);
+ right: rem-calc(8);
+ font-size: 87.5%;
+ text-decoration: none;
+ cursor: pointer;
+
+ &::before {
+ content: '× ';
+ }
+ }
+ }
+}
diff --git a/scss/style-guider-demo.scss b/scss/style-guider-demo.scss
index 3c6bfaa..3511f34 100644
--- a/scss/style-guider-demo.scss
+++ b/scss/style-guider-demo.scss
@@ -12,8 +12,28 @@
// Components
// ---------------------
-@import 'components/example';
-
+@import 'components/reset';
+@import 'components/animation';
+@import 'components/buttons';
+@import 'components/forms';
+@import 'components/tables';
+@import 'components/top-menu';
+@import 'components/sub-menu';
+@import 'components/quick-links';
+@import 'components/cards';
+@import 'components/banners';
+@import 'components/alert';
+@import 'components/hero';
+@import 'components/footer';
+@import 'components/login';
+@import 'components/pagination';
+@import 'components/breadcrumbs';
+@import 'components/tabs';
+@import 'components/datepicker';
+@import 'components/progress';
+@import 'components/layout';
+@import 'components/typography';
+@import 'components/accessibility';
//------ yeoman import hook ------ //
//- NB! The above line is required for our yeoman generator and should not be changed.
@@ -25,7 +45,31 @@
@mixin style-guider-demo-everything {
// Components - Optional
- @include style-guider-demo-example;
+
+ @include style-guider-demo-reset;
+ @include style-guider-demo-layout;
+ @include style-guider-demo-typography;
+ @include style-guider-demo-accessibility;
+ @include style-guider-demo-alert;
+ @include style-guider-demo-banners;
+ @include style-guider-demo-buttons;
+ @include style-guider-demo-cards;
+ @include style-guider-demo-banners;
+ @include style-guider-demo-footer;
+ @include style-guider-demo-forms;
+ @include style-guider-demo-hero;
+ @include style-guider-demo-quick-links;
+ @include style-guider-demo-sub-menu;
+ @include style-guider-demo-tables;
+ @include style-guider-demo-top-menu;
+ @include style-guider-demo-login;
+ @include style-guider-demo-pagination;
+ @include style-guider-demo-breadcrumbs;
+ @include style-guider-demo-tabs;
+ @include style-guider-demo-datepicker;
+ @include style-guider-demo-progress;
+
+ @include style-guider-demo-animation;
//------ yeoman include hook ------ //
//- NB! The above line is required for our yeoman generator and should not be changed.