diff --git a/.eleventy.js b/.eleventy.js index 305e89cc..d7088d0b 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,10 +1,12 @@ -const { DateTime } = require('luxon'); const fs = require('fs'); const pluginRss = require('@11ty/eleventy-plugin-rss'); const pluginNavigation = require('@11ty/eleventy-navigation'); const markdownIt = require('markdown-it'); +const markdownItAttrs = require('markdown-it-attrs'); const markdownItAnchor = require('markdown-it-anchor'); +const { readableDate, htmlDateString, head, min, filterTagList } = require("./config/filters"); const { headingLinks } = require("./config/headingLinks"); +const { contrastRatio, humanReadableContrastRatio } = require("./config/wcagColorContrast"); const yaml = require("js-yaml"); const svgSprite = require("eleventy-plugin-svg-sprite"); const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); @@ -23,10 +25,14 @@ module.exports = function (config) { // Specific scripts to guides config.addPassthroughCopy("./assets/_common/js/*"); - // + config.addPassthroughCopy({'./assets/_common/_img/favicons/favicon.ico': './favicon.ico' }); config.addPassthroughCopy({'./assets/_common/_img/favicons': './img/favicons' }); + // Set download paths + // Place files for download in assets/{guide}/dist/{filename.ext} + config.addPassthroughCopy("./assets/**/dist/*"); + // Add plugins config.addPlugin(pluginRss); config.addPlugin(pluginNavigation); @@ -51,41 +57,18 @@ module.exports = function (config) { // Allow yaml to be used in the _data dir config.addDataExtension("yaml", contents => yaml.load(contents)); - config.addFilter('readableDate', (dateObj) => { - return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat( - 'dd LLL yyyy' - ); - }); - + // Filters + // Add filter function defintions to config/filters.js, then add the functions + // to the import statement above and define like the other filters. + config.addFilter('readableDate', readableDate); // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string - config.addFilter('htmlDateString', (dateObj) => { - return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat('yyyy-LL-dd'); - }); - - // Get the first `n` elements of a collection. - config.addFilter('head', (array, n) => { - if (!Array.isArray(array) || array.length === 0) { - return []; - } - if (n < 0) { - return array.slice(n); - } - - return array.slice(0, n); - }); - - // Return the smallest number argument - config.addFilter('min', (...numbers) => { - return Math.min.apply(null, numbers); - }); - - function filterTagList(tags) { - return (tags || []).filter( - (tag) => ['all', 'nav', 'post', 'posts'].indexOf(tag) === -1 - ); - } - + config.addFilter('htmlDateString', htmlDateString); + config.addFilter('head', head); // Get the first `n` elements of a collection. + config.addFilter('min', min); // Return the smallest number argument config.addFilter('filterTagList', filterTagList); + // Color contrast checkers for the color matrix in the Brand guide + config.addFilter('contrastRatio', contrastRatio); + config.addFilter('humanReadableContrastRatio', humanReadableContrastRatio); // Create an array of all tags config.addCollection('tagList', function (collection) { @@ -97,7 +80,7 @@ module.exports = function (config) { return filterTagList([...tagSet]); }); - // Customize Markdown library and settings: + // Customize Markdown library and settings let markdownLibrary = markdownIt({ html: true, breaks: false, @@ -105,7 +88,7 @@ module.exports = function (config) { }).use(markdownItAnchor, { permalink: headingLinks, slugify: config.getFilter('slug'), - }); + }).use(markdownItAttrs); config.setLibrary('md', markdownLibrary); // Override Browsersync defaults (used only with --serve) diff --git a/_data/navigation.yaml b/_data/navigation.yaml index cf337d5e..3ecc9216 100644 --- a/_data/navigation.yaml +++ b/_data/navigation.yaml @@ -13,6 +13,34 @@ agile: - name: More 18F guides url: https://18f.gsa.gov/guides/ +brand: + - name: Introduction + url: /brand/ + - name: Logo + url: /brand/logo/ + - name: Color palette + url: /brand/color-palette/ + - name: Typography + url: /brand/typography/ + - name: Icons + url: /brand/icons/ + - name: Templates + url: /brand/templates/ + - name: Images + url: /brand/images/ + - name: Principles + url: /brand/principles/ + - name: More 18F guides + url: https://18f.gsa.gov/guides/ + +content-guide: + - name: About this guide + url: /content-guide/ + - name: Our approach + url: /content-guide/our-approach/ + - name: Our style + url: /content-guide/our-style/ + engineering: - name: Home url: /engineering/ @@ -27,14 +55,6 @@ engineering: - name: Security url: /engineering/security/ -content-guide: - - name: About this guide - url: /content-guide/ - - name: Our approach - url: /content-guide/our-approach/ - - name: Our style - url: /content-guide/our-style/ - eng-hiring: - name: Overview url: /eng-hiring/ @@ -72,4 +92,3 @@ product: url: /product/deliver/ - name: Enable partners url: /product/partners/ - diff --git a/_data/titles_roots.yaml b/_data/titles_roots.yaml index a32dd1f5..c9ac8f95 100644 --- a/_data/titles_roots.yaml +++ b/_data/titles_roots.yaml @@ -1,17 +1,20 @@ # Title for each guide that will appear in the header, as well as the root subdirectory for the guide -default: +default: title: 18F Approaches root: / -accessibility: +accessibility: title: Accessibility root: /accessibility/ -agile: +agile: title: Agile root: /agile/ -content-guide: +brand: + title: Visual identity + root: /brand/ +content-guide: title: Content Guide root: /content-guide/ -derisking: +derisking: title: De-risking Guide root: /derisking/ eng-hiring: diff --git a/_includes/brand/color-matrix.html b/_includes/brand/color-matrix.html new file mode 100644 index 00000000..ef3d39b6 --- /dev/null +++ b/_includes/brand/color-matrix.html @@ -0,0 +1,112 @@ + + + + + + + + +
+ + +
+ +
+ + +
+ +
+ + + +
+ + + + + + {% for foreground in palette %} + + {% endfor %} + + + + + {% assign reversed_palette = palette | reverse %} + {% for background in reversed_palette %} + + + {% for foreground in palette %} + {% assign ratio = foreground.hex | contrastRatio: background.hex %} + {% if ratio >= 3.1 %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + +
+
+ {{ foreground.name | capitalize }} text
+ #{{ foreground.hex }}
+
+ +
+
+
+
+ {{ background.name | capitalize }} background
+ #{{ background.hex }} +
+
+
+ {% if ratio >= 4.5 %} + +
+

{{ foreground.name | capitalize }} elements on {{ background.name }} background

+ is 508-compliant, with a contrast ratio of {{ ratio | humanReadableContrastRatio }}. +
+ {% else %} + +
+

{{ foreground.name | capitalize }} elements on {{ background.name }} background

+ is 508-compliant, with a contrast ratio of {{ ratio | humanReadableContrastRatio }}. We recommend using this combination only for non-text elements. +
+ {% endif %} +
+ +
+ Do not use {{ foreground.name }} text on {{ background.name }} background; it is not 508-compliant, with a contrast ratio of {{ ratio | humanReadableContrastRatio }}. +
+
diff --git a/_includes/guidelist.html b/_includes/guidelist.html index 7d1d29c6..60a1cc83 100644 --- a/_includes/guidelist.html +++ b/_includes/guidelist.html @@ -1,39 +1,46 @@ -
+

Some approaches and stuff

-
-
- +
+ -
- + -
- + + + -
- + diff --git a/assets/_common/_img/guide_icons/brand.svg b/assets/_common/_img/guide_icons/brand.svg new file mode 100644 index 00000000..8979a0d0 --- /dev/null +++ b/assets/_common/_img/guide_icons/brand.svg @@ -0,0 +1,9 @@ + + + eye + + + + + + \ No newline at end of file diff --git a/assets/_common/styles/_uswds-theme-settings.scss b/assets/_common/styles/_uswds-theme-settings.scss index 48560f54..528c0e9d 100644 --- a/assets/_common/styles/_uswds-theme-settings.scss +++ b/assets/_common/styles/_uswds-theme-settings.scss @@ -15,7 +15,7 @@ $brand-color-dark: #1C304A; $theme-font-path: '../../../node_modules/@uswds/uswds/dist/fonts', $theme-image-path: '../../../node_modules/@uswds/uswds/dist/img', - // TODO: remove + // TODO: remove $theme-hero-image: '../_img/hero.png', @@ -39,7 +39,7 @@ $brand-color-dark: #1C304A; /*------------------------------------------------ ## Primary color - -------------------------------------------------*/ + -------------------------------------------------*/ $theme-color-primary-darkest: 'blue-90', $theme-color-primary-darker: $brand-color-dark, $theme-color-primary-dark: 'blue-70v', @@ -50,14 +50,14 @@ $brand-color-dark: #1C304A; /*------------------------------------------------ ## Accent color - -------------------------------------------------*/ + -------------------------------------------------*/ $theme-color-accent-cool-dark: 'cyan-50v', $theme-color-accent-cool: $brand-color-bright, $theme-color-accent-cool-light: 'cyan-20v', /*------------------------------------------------ ## Error color - -------------------------------------------------*/ + -------------------------------------------------*/ $theme-color-error-lighter: 'red-warm-5v', /*------------------------------------------------ @@ -66,4 +66,3 @@ $brand-color-dark: #1C304A; $theme-header-logo-text-width: 70%, ); - diff --git a/assets/_common/styles/styles.scss b/assets/_common/styles/styles.scss index c4f10012..8e998b9c 100644 --- a/assets/_common/styles/styles.scss +++ b/assets/_common/styles/styles.scss @@ -14,7 +14,6 @@ Custom styling @forward "custom-styles.scss"; // TODO: Delete +// @forward "overrides/_hero.scss"; -@forward "overrides/_hero.scss"; - -@forward "overrides/code_highlight.scss"; \ No newline at end of file +@forward "overrides/code_highlight.scss"; diff --git a/assets/brand/dist/18F-Feather-Icons--all.pdf b/assets/brand/dist/18F-Feather-Icons--all.pdf new file mode 100644 index 00000000..011fca12 Binary files /dev/null and b/assets/brand/dist/18F-Feather-Icons--all.pdf differ diff --git a/assets/brand/dist/18F-Feather-Icons--top-hits.pdf b/assets/brand/dist/18F-Feather-Icons--top-hits.pdf new file mode 100644 index 00000000..737f574a Binary files /dev/null and b/assets/brand/dist/18F-Feather-Icons--top-hits.pdf differ diff --git a/assets/brand/dist/18F_Color_Palette.zip b/assets/brand/dist/18F_Color_Palette.zip new file mode 100644 index 00000000..52fb0af1 Binary files /dev/null and b/assets/brand/dist/18F_Color_Palette.zip differ diff --git a/assets/brand/dist/18F_Desktop_Art.zip b/assets/brand/dist/18F_Desktop_Art.zip new file mode 100644 index 00000000..b5642e51 Binary files /dev/null and b/assets/brand/dist/18F_Desktop_Art.zip differ diff --git a/assets/brand/dist/18F_Logo.zip b/assets/brand/dist/18F_Logo.zip new file mode 100644 index 00000000..1ebdffd8 Binary files /dev/null and b/assets/brand/dist/18F_Logo.zip differ diff --git a/assets/brand/dist/18F_VideoBackgrounds.zip b/assets/brand/dist/18F_VideoBackgrounds.zip new file mode 100644 index 00000000..ee7c36ae Binary files /dev/null and b/assets/brand/dist/18F_VideoBackgrounds.zip differ diff --git a/assets/brand/dist/18F_feather.zip b/assets/brand/dist/18F_feather.zip new file mode 100644 index 00000000..1bf51964 Binary files /dev/null and b/assets/brand/dist/18F_feather.zip differ diff --git a/assets/brand/dist/Using_18Fs_Templates.pdf b/assets/brand/dist/Using_18Fs_Templates.pdf new file mode 100644 index 00000000..f4ba0755 Binary files /dev/null and b/assets/brand/dist/Using_18Fs_Templates.pdf differ diff --git a/assets/brand/favicon.ico b/assets/brand/favicon.ico new file mode 100644 index 00000000..c81a0226 Binary files /dev/null and b/assets/brand/favicon.ico differ diff --git a/assets/brand/img/18F-Logo-L.png b/assets/brand/img/18F-Logo-L.png new file mode 100644 index 00000000..67e0a092 Binary files /dev/null and b/assets/brand/img/18F-Logo-L.png differ diff --git a/assets/brand/img/18F-Logo-M.png b/assets/brand/img/18F-Logo-M.png new file mode 100644 index 00000000..a20fe880 Binary files /dev/null and b/assets/brand/img/18F-Logo-M.png differ diff --git a/assets/brand/img/18F-Logo-S.png b/assets/brand/img/18F-Logo-S.png new file mode 100644 index 00000000..ca56d7ca Binary files /dev/null and b/assets/brand/img/18F-Logo-S.png differ diff --git a/assets/brand/img/18F-Logo.svg b/assets/brand/img/18F-Logo.svg new file mode 100644 index 00000000..d9f648f6 --- /dev/null +++ b/assets/brand/img/18F-Logo.svg @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/assets/brand/img/18F-color-palette.png b/assets/brand/img/18F-color-palette.png new file mode 100644 index 00000000..5748b03e Binary files /dev/null and b/assets/brand/img/18F-color-palette.png differ diff --git a/assets/brand/img/18F-slide-theme-cover.svg b/assets/brand/img/18F-slide-theme-cover.svg new file mode 100644 index 00000000..5d8f420d --- /dev/null +++ b/assets/brand/img/18F-slide-theme-cover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/brand/img/18FDesktop-Preview.png b/assets/brand/img/18FDesktop-Preview.png new file mode 100644 index 00000000..245e7584 Binary files /dev/null and b/assets/brand/img/18FDesktop-Preview.png differ diff --git a/assets/brand/img/18F_VideoBG_6Illo.png b/assets/brand/img/18F_VideoBG_6Illo.png new file mode 100644 index 00000000..f19c972b Binary files /dev/null and b/assets/brand/img/18F_VideoBG_6Illo.png differ diff --git a/assets/brand/img/18f-logo-blue.svg b/assets/brand/img/18f-logo-blue.svg new file mode 100644 index 00000000..c2725f3f --- /dev/null +++ b/assets/brand/img/18f-logo-blue.svg @@ -0,0 +1,14 @@ + + + + 18F-Logo-2016-Blue + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/assets/brand/img/Apply-18F-styles-existing-doc.png b/assets/brand/img/Apply-18F-styles-existing-doc.png new file mode 100644 index 00000000..a8d7bad3 Binary files /dev/null and b/assets/brand/img/Apply-18F-styles-existing-doc.png differ diff --git a/assets/brand/img/Instructions_Preview.png b/assets/brand/img/Instructions_Preview.png new file mode 100644 index 00000000..b789c7ba Binary files /dev/null and b/assets/brand/img/Instructions_Preview.png differ diff --git a/assets/brand/img/Save-18F-styles-as-default.png b/assets/brand/img/Save-18F-styles-as-default.png new file mode 100644 index 00000000..b70bc0db Binary files /dev/null and b/assets/brand/img/Save-18F-styles-as-default.png differ diff --git a/assets/brand/img/Slack_Mark.svg b/assets/brand/img/Slack_Mark.svg new file mode 100644 index 00000000..c37dc5eb --- /dev/null +++ b/assets/brand/img/Slack_Mark.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/brand/img/Template_Preview.png b/assets/brand/img/Template_Preview.png new file mode 100644 index 00000000..0e9907ab Binary files /dev/null and b/assets/brand/img/Template_Preview.png differ diff --git a/assets/brand/img/angle-arrow-down-white.svg b/assets/brand/img/angle-arrow-down-white.svg new file mode 100644 index 00000000..b59fd759 --- /dev/null +++ b/assets/brand/img/angle-arrow-down-white.svg @@ -0,0 +1 @@ +angle-arrow-down-white \ No newline at end of file diff --git a/assets/brand/img/angle-arrow-up-white.svg b/assets/brand/img/angle-arrow-up-white.svg new file mode 100644 index 00000000..0eb91312 --- /dev/null +++ b/assets/brand/img/angle-arrow-up-white.svg @@ -0,0 +1 @@ +angle-arrow-up-white \ No newline at end of file diff --git a/assets/brand/img/favicon-16x16.png b/assets/brand/img/favicon-16x16.png new file mode 100644 index 00000000..24f0cb4c Binary files /dev/null and b/assets/brand/img/favicon-16x16.png differ diff --git a/assets/brand/img/favicon-32x32.png b/assets/brand/img/favicon-32x32.png new file mode 100644 index 00000000..d7887873 Binary files /dev/null and b/assets/brand/img/favicon-32x32.png differ diff --git a/assets/brand/img/gsa-logo-blue.svg b/assets/brand/img/gsa-logo-blue.svg new file mode 100644 index 00000000..b05af73a --- /dev/null +++ b/assets/brand/img/gsa-logo-blue.svg @@ -0,0 +1,10 @@ + + + gsa-logo-blue + + + + + + + \ No newline at end of file diff --git a/assets/brand/img/placeholder.png b/assets/brand/img/placeholder.png new file mode 100644 index 00000000..79b009bb Binary files /dev/null and b/assets/brand/img/placeholder.png differ diff --git a/assets/brand/styles/_color-matrix.scss b/assets/brand/styles/_color-matrix.scss new file mode 100644 index 00000000..dce3d20e --- /dev/null +++ b/assets/brand/styles/_color-matrix.scss @@ -0,0 +1,270 @@ +//// background color helpers +.usa-color-white { + background-color: $color-white; + box-shadow: inset 0 0 0 1px $color-gray-divider; +} + +.usa-color-light { + background-color: $color-light; +} + +.usa-color-bright { + background-color: $color-bright; +} + +.usa-color-medium { + background-color: $color-medium; +} + +.usa-color-dark { + background-color: $color-dark; +} + +.usa-color-black { + background-color: $color-black; +} + +.usa-color-short { + height: 7rem; + margin-bottom: 1rem; +} + +//// color palette display + +.usa-color-name { + font-weight: bold; + margin-bottom: 0; + margin-top: 1rem; + text-transform: capitalize; +} + +.usa-color-hex { + margin-bottom: 1em; + margin-top: 0; + + @include at-media(tablet) { + margin: 0; + } +} + +.usa-color-row { + margin-bottom: 3rem; + margin-top: 1.5rem; +} + +#color-guidance { + margin-top: 5rem; +} + +.usa-primary-color-section { + @include at-media(tablet) { + margin-bottom: 8rem; + } + margin-bottom: 0; + + .usa-color-square { + margin-bottom: 7rem; + padding-bottom: 50%; + width: 48%; + float: left; + margin-right: 2%; + position: relative; + + @include at-media(tablet) { + width: 14.66%; + margin-bottom: 0; + padding-bottom: 14.66%; + } + } +} + +.usa-color-inner-content { + position: absolute; + top: 100%; +} + +//// color matrix + +.usa-sr-invisible[aria-hidden="true"] { + display: block !important; +} + +.usa-matrix-foreground-white { + color: $color-white; + + // https://css-tricks.com/adding-stroke-to-web-text/ + text-shadow: + -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000; +} + +.usa-matrix-foreground-light { + color: $color-light; +} + +.usa-matrix-foreground-bright { + color: $color-bright; +} + +.usa-matrix-foreground-medium { + color: $color-medium; +} + +.usa-matrix-foreground-dark { + color: $color-dark; +} + +.usa-matrix-foreground-black { + color: $color-black; +} + +.usa-matrix td { + vertical-align: top; +} + +.usa-matrix-square { + width: 3.5em; + height: 3.5em; + display: flex; + justify-content: center; + align-items: center; + margin-right: units(1); + + strong { + text-shadow: none; + } +} + +.usa-matrix-symbol-definitions { + display: none; +} + +.usa-prose .usa-matrix-legend { + display: flex; + margin-top: 0.5em; + justify-content: flex-start; + align-items: top; + + svg, p { + margin-top: 0.5em; + margin-bottom: 0.5em; + } + + svg{ + flex: 0 0 auto; + width: 35px; + height: 35px; + } + + p { + flex-grow: 1; + flex-shrink: 1; + max-width: measure(6); + margin-left: 1em; + font-size: .85em; + } +} + +.usa-matrix-legend.legend-bad-contrast { + display: none; +} + + +td[scope="row"] > div { + display: flex; +} + +.usa-matrix td.usa-matrix-valid-color-combo, +.usa-matrix td.usa-matrix-invalid-color-combo { + padding: .5em .25em; +} + +.usa-matrix-desc { + font-size: .85em; + flex: 1; + line-height: lh('body', 3); +} + +.usa-matrix p { + font-size: .85em; + line-height: lh('body', 3); +} + + +table.usa-matrix { + display: block; + + thead { + display: none; + } + + tbody { + display: block; + + tr { + display: block; + + td.usa-matrix-valid-color-combo, + td.usa-matrix-invalid-color-combo, { + display: flex; + align-items: center; + + .usa-matrix-color-combo-description { + flex: 1; + padding-left: 1em; + } + } + + td.usa-matrix-invalid-color-combo { + display: none; + } + + td[scope="row"] { + display: none; + } + } + } +} + +@include at-media('tablet-lg') { +.usa-prose .usa-matrix-legend { + align-items: center; +} + +.usa-matrix-legend.legend-bad-contrast { + display: flex; + } + + table.usa-matrix { + display: table; + + thead { + display: table-header-group; + } + + tbody { + display: table-row-group; + + tr { + display: table-row; + + + td.usa-matrix-valid-color-combo, + td.usa-matrix-invalid-color-combo, { + display: table-cell; + + .usa-matrix-color-combo-description { + flex: 1; + padding-left: 0; + } + } + + td[scope="row"] { + display: table-cell; + } + } + } + } +} diff --git a/assets/brand/styles/_styleguide.scss b/assets/brand/styles/_styleguide.scss new file mode 100644 index 00000000..0898831d --- /dev/null +++ b/assets/brand/styles/_styleguide.scss @@ -0,0 +1,520 @@ +// Variables -------------- // + +$width-nav-sidebar: 250px; +$site-top: 98px; + +//fix these Variables +$color-white: #fff; +$color-gray-light: #000; +$color-gray-dark: #000; +$medium-screen: 1200px; +$site-margins: 10px; +$h3-font-size: inherit; +$h5-font-size: inherit; +//// @media screen and ($medium-screen + $width-nav-sidebar) + +// Navigation ------------- // + +.usa-site-header { + background-color: $color-white; + border-bottom: 1px solid $color-gray-light; + position: fixed; + left: 0; + top: 0; + width: 100%; + z-index: 1; + + a { + border-bottom: none; + } + + .usa-site-navbar { + @media screen and ($medium-screen + $width-nav-sidebar) { + height: 6rem; + margin: { + bottom: 1rem; + top: 2.7rem; + } + } + margin-top: 4px; + + .logo { + @media screen and ($medium-screen + $width-nav-sidebar) { + padding-left: $site-margins; + text-align: left; + padding-top: 0; + width: auto; + } + float: left; + text-align: center; + padding-top: 1.3rem; + width: 70%; + + a { + color: $color-dark; + + &:hover { + color: $color-gray-dark; + text-decoration: none; + } + + &:visited { + color: $color-dark; + } + } + + img { + max-width: 48px; + } + } + + h1 { + @media screen and ($medium-screen + $width-nav-sidebar) { + display: block; + font-size: $h3-font-size; + float: right; + margin-top: 1.2rem; + padding-left: 1.2rem; + } + margin: 0; + font-size: $h5-font-size; + } + } +} + +.menu-btn { + @media screen and ($medium-screen + $width-nav-sidebar) { + display: none; + } + display: inline; + float: left; + margin-top: -4px; + padding-top: 1.5rem; + padding-bottom: 1.5rem; + color: $color-black; + background-color: $color-bright; + font-size: 1.5rem; + width: 15%; + text-align: center; + + &:visited { + color: $color-black; + } + + &:hover { + text-decoration: none; + color: $color-white; + background-color: $color-medium; + } +} + +// #menu-content { +// @media (max-width: $medium-screen + $width-nav-sidebar) { +// $sliding-panel-width: 220px; +// +// @include position(fixed, 0 auto 0 0); +// @include size($sliding-panel-width 100%); +// @include transform(translateX(- $sliding-panel-width)); +// background: #fff; +// -webkit-overflow-scrolling: touch; +// overflow-y: auto; +// z-index: 999999; +// display: block; +// &.is-visible { +// @include transition(all 0.25s linear); +// @include transform(translateX(0)); +// } +// } +// } + +.overlay { + @include position(fixed, 0 0 0 0); + @include transition; + background: #000; + opacity: 0; + visibility: hidden; + z-index: 9999; + + &.is-visible { + visibility: visible; + } +} + +// Main Content --------- // + +.main-content { + display: flex; + flex-direction: column; + + @include media($medium-screen) { + min-height: calc(100vh - #{$site-top}); + top: $site-top; + } + position: absolute; + top: 4rem; + min-height: calc(100vh - 4rem); + bottom: 0; + right: 0; + width: 100%; + padding: { + bottom: 0; + top: 1em; + } + z-index: -1; + + .lt-ie9 & { + width: 75%; + } + + @media screen and ($medium-screen + $width-nav-sidebar) { + width: calc(100% - #{$width-nav-sidebar}); + + .lt-ie9 & { + width: 75%; + } + } +} + +h2.styleguide-header { + border-bottom: 1px solid $color-gray-light; + padding-bottom: .5em; +} + +.styleguide-header { + font-weight: $font-normal; +} + +.download_link { + display: inline-block; + margin-bottom: 1em; +} + +// Sidebar Nav --------- // + +.sidenav { + background-color: $color-white; + position: fixed; + top: $site-top; + bottom: 0; + left: 0; + width: $width-nav-sidebar; + border-right: 1px solid $color-gray-light; + padding: 5rem 3rem 3rem 3rem; + overflow: auto; + display: none; + z-index: -1; + + .lt-ie9 & { + width: 25%; + } + + .usa-sidenav-sub_list { + display: none; + } + + a { + color: $color-medium; + text-decoration: none; + + &:hover { + color: $color-medium; + } + } + + @media screen and ($medium-screen + $width-nav-sidebar) { + display: block; + } +} + +.sidenav .usa-current ~ .usa-sidenav-sub_list { + display: block; +} + +// Styleguide Content -------- // + +.styleguide-content { + // https://github.com/philipwalton/flexbugs#1-minimum-content-sizing-of-flex-items-not-honored + flex: 1 0 auto; + + margin-bottom: 5em; + max-width: $site-max-width; + padding: { + left: 2em; + right: 2em; + } + position: relative; + + > h1 { + margin-top: 3.4rem; + &:not(:first-child) { + margin-top: 1.5em; + } + } + @media (min-width: $medium-screen + $width-nav-sidebar) { + padding: { + left: 3em; + right: 3em; + } + } +} + +// Footer --------------- // + +.usa-styleguide-footer { + background-color: $color-dark;; + + // https://github.com/philipwalton/flexbugs#1-minimum-content-sizing-of-flex-items-not-honored + flex-shrink: 0; + flex-basis: auto; + + padding: { + bottom: 3rem; + top: 3rem; + } + +// This is a styleguide-only rule and is not needed in the main library code for +// the footer component which uses different styles + p, a { + @include media($medium-screen) { + margin-bottom: 0; + } + color: $color-white; + font-size: $h5-font-size; + margin: { + bottom: 1.5rem; + top: 0; + } + } + + a:hover { + color: $color-bright; + } +} + +.type-example { + margin-top: .5em; +} + +// Colors -------------- // + +.usa-color-short { + height: 7rem; + margin-bottom: 1rem; +} + +.usa-color-name { + font-weight: $font-bold; + margin-bottom: 0; + margin-top: 1rem; + text-transform: capitalize; +} + +.usa-color-hex { + margin-bottom: 1em; + margin-top: 0; + + @include media($medium-screen) { + margin: 0; + } +} + +.usa-color-row { + margin-bottom: 3rem; + margin-top: 1.5rem; + + .color-big { + @include media($medium-screen) { + float: left; + padding-right: 4%; + width: 32%; + } + } + + .color-small { + float: left; + width: 50%; + + @include media($medium-screen) { + width: 17%; + } + margin-right: 0; + } +} + +.usa-primary-color-section { + @include media($medium-screen) { + margin-bottom: 8rem; + } + margin-bottom: 0; + + .usa-color-square { + @include span-columns(6); + margin-bottom: 7rem; + padding-bottom: 50%; + position: relative; + + @include media($medium-screen) { + @include span-columns(2); + margin-bottom: 0; + padding-bottom: 14.70196%; + } + } + + .usa-mobile-end-row { + @include media($medium-screen) { + margin-right: 2.35765%; + } + margin-right: 0; + } +} + +.usa-color-inner-content { + position: absolute; + top: 100%; +} + +.usa-color-text { + font-weight: $font-bold; + margin-bottom: .4rem; + padding: { + bottom: 1rem; + left: 2rem; + right: 2rem; + top: 1rem; + } +} + +.usa-color-outline { + .usa-color-text { + box-shadow: inset 0 0 0 1px $color-gray; + } +} + +// Color background helpers + +.usa-color-bright { + background-color: $color-bright; +} + +.usa-color-dark { + background-color: $color-dark; +} + +.usa-color-medium { + background-color: $color-medium; +} + +.usa-color-light { + background-color: $color-light; +} + +.usa-color-black { + background-color: $color-black; +} + +.usa-color-gray-dark { + background-color: $color-gray-dark; +} + +.usa-color-gray-light { + background-color: $color-gray-light; +} + +.usa-color-white { + background-color: $color-white; + box-shadow: inset 0 0 0 1px $color-gray-light; +} + +.usa-color-primary-alt { + background-color: $color-primary-alt; +} + +.usa-color-primary-alt-dark { + background-color: $color-primary-alt-dark; +} + +.usa-color-primary-alt-darkest { + background-color: $color-primary-alt-darkest; +} + +.usa-color-text-white { + color: $color-white; +} + +.usa-color-text-black { + color: $color-black; +} + +.color-col-tall .usa-color-text { + margin-bottom: 0; + padding-top: 3rem; + padding-bottom: 3rem; +} + + +// Custom CSS --------------- // + +h1, h2, h3, h4, h5, h6 { + font-family: $font-sans; +} + +// rewrote this to prevent overlapping margins + +h4 { + margin-top: 0; + padding-top: 1.5em; +} + +a { + color: $color-medium; + text-decoration: underline; + + &:hover { + text-decoration: none; + } + + &:visited { + color: $color-medium; + } +} + +.usa-sidenav-list { + a { + color: $color-black; + + &.usa-current { + border-left-color: $color-medium; + color: $color-medium; + } + } + + > li { + border-top: 1px solid $color-gray-light; + } +} + +.display-logo { + max-width: 162px; +} + +// added from USWDS for typography section + +.text-tiny { + @include margin(5px null 0); + &:first-child { + margin-top: 0; + } +} +.typography-specimen { + .text-huge { + font-size: 140px; + line-height: 1.05; + } + .text-tiny { + font-size: 15px; + } +} + +.bold { + font-weight: bold; +} diff --git a/assets/brand/styles/_usa_anchor.scss b/assets/brand/styles/_usa_anchor.scss new file mode 100644 index 00000000..672c3d57 --- /dev/null +++ b/assets/brand/styles/_usa_anchor.scss @@ -0,0 +1,208 @@ +// Anchor component - - - - - - - - - - - - - - - +// Using the USWDS Design Tokens +.anchor{ + display: flex; + flex-direction: column; + justify-content: flex-end; + flex: 1; +} + + +.component-anchor{ + background-color: $color-dark; + @include u-text('white'); + + h3{ + @include u-font('sans', 'md'); + } + + .org-short{ + @include u-padding-y(3); + @include u-display('block'); + @include at-media('tablet') { + @include u-display('flex'); + @include u-flex('align-center'); + @include u-flex('justify'); + } + .org-copy{ + @include u-display('flex'); + @include u-flex('align-start'); + @include at-media('tablet'){ + @include u-flex('align-center'); + } + p{ + @include u-margin(0); + @include at-media('tablet'){ + @include u-measure(5); + } + } + .org-img{ + @include u-margin-right(2); + @include u-maxw(7); + @include u-minw(7); + @include at-media('tablet') { + @include u-maxw(6); + @include u-minw(6); + } + } + } + } + + .org-copy{ + @include u-font('sans', 'xs'); + @include u-line-height('sans', 3); + @include u-text('white'); + @include at-media('tablet') { + @include u-font('sans', 'sm'); + } + p{ + a{ + @include u-text('white'); + } + .more{ + @include u-text('underline'); + } + } + + } + + .org-expanded{ + .org-copy{ + @include u-margin-bottom(2); + } + .org-links{ + @include u-margin-bottom(2); + @include u-padding-x(2); + @include u-padding-right(1); + @include u-padding-top('105'); + @include u-padding-bottom(2); + @include u-bg('primary-dark'); + @include u-font('sans', '2xs'); + @include u-text('base-lightest'); + ul{ + @include u-padding-left('205'); + li{ + @include u-margin-bottom('05'); + a{ + @include u-text('no-underline'); + @include u-border-bottom('1px', 'solid', 'white'); + &:hover{ + @include u-text('white'); + @include u-border-bottom('2px', 'solid', 'white'); + } + } + } + } + a{ + @include u-text('base-lightest'); + &:hover{ + @include u-text('white'); + @include u-border-bottom('2px', 'solid', 'white'); + } + } + } + } + + button.btn-learn-more{ + @include u-text('white'); + @include u-border('1px', 'solid', 'white'); + @include u-radius('md'); + background: none; + box-shadow: none; + @include u-width('auto'); + + @include u-margin(0); + @include u-margin-top(1); + @include u-padding-y('05'); + @include u-padding-left('105'); + @include u-padding-right(4); + @include u-font('sans', '2xs'); + @include at-media('tablet') { + @include u-margin-top(0); + @include u-margin-left(2); + @include u-padding-y(1); + @include u-float('right'); + @include u-font('sans', 'xs'); + } + @include at-media('desktop') { + @include u-font('sans', 'sm'); + } + &:hover{ + box-shadow: none; + } + } + .usa-accordion__button[aria-expanded=false]{ + background-image: url('../../assets/img/angle-arrow-down-white.svg'),-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)); + background-size: .85rem; + background-repeat: no-repeat; + background-position: 6.65em center; + } + .usa-accordion__button[aria-expanded=true]{ + background-image: url('../../assets/img/angle-arrow-up-white.svg'),-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)); + background-size: .85rem; + background-repeat: no-repeat; + background-position: 6.65em center; + } +} + +.component-anchor-support{ + @include u-bg('black'); + @include u-text('white'); + .usagov{ + @include u-padding-y(1); + @include u-display('block'); + @include at-media('tablet') { + @include u-display('flex'); + @include u-font('sans', 'sm'); + @include u-flex('align-center'); + @include u-flex('justify-start'); + } + p{ + @include u-margin-y('05'); + @include u-flex('align-center'); + @include u-line-height('sans', 2); + @include u-font('sans', 'xs'); + @include at-media('tablet') { + @include u-font('sans', 'sm'); + } + i{ + @include u-margin-right('105'); + font-size:1.25rem; + @include u-maxw(3); + @include u-minw(3); + @include at-media('tablet') { + @include u-maxw(3); + @include u-minw(3); + } + } + } + .usagov__link{ + @include u-margin(0); + @include u-margin-top(1); + @include u-margin-bottom(2); + @include u-padding-y(1); + @include u-text('white'); + white-space: nowrap; + @include u-font('sans', 'sm'); + @include at-media('tablet') { + @include u-margin(0); + @include u-margin-left('105'); + @include u-font('sans', 'xs'); + } + @include at-media('tablet-lg') { + @include u-font('sans', 'sm'); + } + } + } +} + + +.usa-button-sm{ + @include u-margin-x('05'); + @include u-padding-y('05'); + @include u-padding-x('105'); +} +.arrow-down{ + @include u-margin-left('105'); + @include u-width('105'); +} diff --git a/assets/brand/styles/_uswds-theme-custom-styles.scss b/assets/brand/styles/_uswds-theme-custom-styles.scss new file mode 100644 index 00000000..44ef68ef --- /dev/null +++ b/assets/brand/styles/_uswds-theme-custom-styles.scss @@ -0,0 +1,255 @@ + +//// 18F styles + +// Color +$color-light: #b3efff; // $color-light / $color-secondary-light +$color-bright: #00cfff; // $color-bright / $color-secondary +$color-medium: #046b99; // $color-medium / $theme-color-primary +$color-dark: #1C304A; // $color-dark / $theme-color-primary-dark +$color-base: #1F2E4A; +$color-white: color("white"); +$color-black: color("black"); +$color-inverse: color("white"); + +//// originals +// $color-light: color("cyan-10v"); +// $color-bright: color("cyan-30v"); +// $color-medium: color("primary"); +// $color-dark: color("primary-dark"); +// $color-base: color("primary-dark"); +// $color-black: color("black"); +// $color-inverse: color("white"); + +$color-bright-hover: color("accent-cool-dark"); +$color-medium-hover: color("blue-60"); + +$color-gray-lightest: color("base-lightest"); // Adding bc used in our $border-light in this file. +$color-gray-hover: color("gray-2"); +$color-gray-divider: color("gray-20"); + +$color-gray-border: color("base-dark"); + +$logo-size-lg: 3rem; +$logo-size-md: 2rem; + +// Typography +.usa-prose{ + h1,h2,h3,h4,h5,h6 { + color: $color-dark; + } + + p, li { + color: $color-base; + } +} +.usa-list li, +.usa-prose>ul li, +.usa-prose>ol li { + margin-bottom: units(0.5); +} +.usa-prose>ul li>ul, +.usa-prose>ul li>ol, +.usa-prose>ol li>ul, +.usa-prose>ol li>ol { + margin-top: units(1.5); +} + +// Links + +a { + color: $color-medium; +} + +a:hover { + color: $color-medium-hover; +} + +// Header +.usa-nav .usa-current::after, +.usa-header--extended .usa-current:hover::after, +.usa-nav__primary>.usa-nav__primary-item > .usa-current:hover::after { + background-color: $color-bright; +} + +.usa-nav__primary>.usa-nav__primary-item > .usa-current, +.usa-nav__primary>.usa-nav__primary-item > a:hover { + color: $color-black; +} + +.usa-nav__primary>.usa-nav__primary-item > a:hover { + background-color: $color-gray-lightest; +} + +.usa-nav__secondary-links { + display: none; +} + +// icon +.usa-header.usa-header--extended .usa-logo-img { + height: $logo-size-md; +} + +.usa-logo__text { + line-height: $logo-size-md; +} + + +@include at-media('tablet') { + .usa-header.usa-header--extended .usa-logo-img { + height: $logo-size-lg; + } + + .usa-logo__text { + line-height: $logo-size-lg; + } + +} + +// usa-sidenav + +.usa-sidenav a { + color: $color-base; +} + +.usa-sidenav > .usa-sidenav__item { + padding-left: 0; +} + +.usa-sidenav .usa-current { + color: $color-dark; +} + +.usa-sidenav .usa-current::after { + background-color: $color-bright; + border-radius: 0; + width: units(1); + top: 0; + bottom: 0; +} + +.usa-sidenav a:hover { + color: inherit; + background-color: $color-gray-lightest; +} + +//// Customization + +// Set max-width on container to contain lines +.usa-layout-docs__main { + max-width: units("tablet"); +} + +// Set line-height to specify distance between lines of text +.usa-prose > h1, +.usa-prose > h2, +.usa-prose > h3, +.usa-prose > h4, +.usa-prose > h5, +.usa-prose > h6 { + @include u-line-height("heading", 3); +} + +// Set property values for code block +pre { + white-space: pre-wrap; +} + +// Show Slack icon before Slack Links +a[href^="https://gsa-tts.slack.com"]::before { + content: ""; + $size: units(4); + width: $size; + height: $size; + display: inline-block; + vertical-align: middle; + margin: units(-2px) units(-0.5) 0; + background-size: 100%; + background-repeat: no-repeat; + background-image: url("../img/Slack_Mark.svg"); +} +.usa-prose>ul.list-item--margin-bottom-extra>li, +.usa-prose>ol.list-item--margin-bottom-extra>li { + @include u-margin-bottom(1.5); +} + +@include at-media("desktop") { + .usa-header--extended .usa-logo { + max-width: none; + } + + .usa-nav__primary>.usa-nav__primary-item { + @include u-font("ui", "xs"); + } + + .usa-header--extended .usa-nav__primary-item>.usa-current::after { + background-color: $color-bright; + } + + .usa-header--extended .usa-nav__primary-item>.usa-nav__link:not(.usa-current):hover::after { + display: none; + } +} + +.usa-layout-docs__sidenav { + overflow: visible; + order: 0; + margin-bottom: units(3); + padding-top: 0; + position: relative; +} + +.usa-header .usa-logo a { + display: inline-block; +} + +@include at-media("desktop") { + .usa-layout-docs__sidenav { + @include grid-col(3); + position: sticky; + } + + .usa-layout-docs__main { + @include u-flex("fill"); + } +} + +// Typography Page +.typography-specimen { + color: $color-dark; +} + .text-huge { + font-size: 140px !important; + line-height: 1.05; + } + .text-tiny { + font-size: 15px; + letter-spacing:letter-spacing(2); + } + +// Color palette +@include at-media("tablet") { + .color-palette .usa-layout-docs__main { + max-width: 55rem; + p { + max-width: measure(5); + } + } +} + +.color-palette .usa-matrix { + min-width: 100%; +} + +//// Footer (usa-anchor styles) + +// Fixing footer anchor to bottom +@include at-media("desktop") { + body { + display: flex; + flex-direction: column; + min-height: 100vh; + } +} + +@import '_usa_anchor'; +@import '_color-matrix'; diff --git a/assets/brand/styles/_uswds-theme-settings.scss b/assets/brand/styles/_uswds-theme-settings.scss new file mode 100644 index 00000000..fcabf9c0 --- /dev/null +++ b/assets/brand/styles/_uswds-theme-settings.scss @@ -0,0 +1,10 @@ +// Just put any changed settings in here! + +$theme-show-notifications: false; +$theme-font-type-sans: "helvetica"; +$theme-font-role-heading: "sans"; + +$theme-color-primary-dark: "blue-80v"; +$theme-color-primary-darker: "blue-90"; +$theme-type-scale-sm: 6; +$theme-type-scale-md: 7; diff --git a/assets/brand/styles/_variables_old.scss b/assets/brand/styles/_variables_old.scss new file mode 100644 index 00000000..29da65bb --- /dev/null +++ b/assets/brand/styles/_variables_old.scss @@ -0,0 +1,12 @@ +// Typography + +$font-sans: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; +$font-path: 'fonts'; + +// Color + +$color-light: #b3efff; +$color-bright: #00cfff; +$color-medium: #046b99; +$color-dark: #1C304A; +$color-black: #000000; diff --git a/config/filters.js b/config/filters.js new file mode 100644 index 00000000..27ab6c7c --- /dev/null +++ b/config/filters.js @@ -0,0 +1,45 @@ +// Keep filter source code here. + +const { DateTime } = require('luxon'); + +const readableDate = (dateObj) => { + return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat( + 'dd LLL yyyy' + ); +}; + +// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string +const htmlDateString = (dateObj) => { + return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat('yyyy-LL-dd'); +}; + +// Get the first `n` elements of a collection. +const head = (array, n) => { + if (!Array.isArray(array) || array.length === 0) { + return []; + } + if (n < 0) { + return array.slice(n); + } + return array.slice(0, n); +}; + +// Return the smallest number argument +const min = (...numbers) => { + return Math.min.apply(null, numbers); +}; + +const filterTagList = (tags) => { + return (tags || []).filter( + (tag) => ['all', 'nav', 'post', 'posts'].indexOf(tag) === -1 + ); +} + + +module.exports = { + readableDate, + htmlDateString, + head, + min, + filterTagList +}; diff --git a/config/wcagColorContrast.js b/config/wcagColorContrast.js new file mode 100644 index 00000000..80e5b18e --- /dev/null +++ b/config/wcagColorContrast.js @@ -0,0 +1,51 @@ +// WCAG Color Contrast functions +// Implements the WCAG color contrast procedure: https://www.w3.org/TR/WCAG20-TECHS/G18.html#G18-tests +// With gratitude to: +// https://github.com/mkdynamic/wcag_color_contrast +// https://blog.cristiana.tech/calculating-color-contrast-in-typescript-using-web-content-accessibility-guidelines-wcag + +const humanReadableContrastRatio = (ratio) => { + // SMELL: This is less readable than ideal. + if (ratio < 4) { + digits = 1 + } else if (ratio < 5) { + digits = 2 + } else { + digits = 0 + } + return `${ratio.toFixed(digits)}:1` +} + +const contrastRatio = (hex1, hex2) => { + lum1 = luminance(hex1) + lum2 = luminance(hex2) + if (lum1 >= lum2) { + lighter = lum1; + darker = lum2; + } else { + darker = lum1; + lighter = lum2; + } + return (lighter + 0.05) / (darker + 0.05) +} + +const luminance = (hex) => { + const [r8, g8, b8] = hexToRgb(hex) + const [r, g, b] = [r8, g8, b8].map((component) => { + const value = component / 255; + return value <= 0.03928 ? value / 12.92 : Math.pow((value + 0.055) / 1.055, 2.4); + }); + return r * 0.2126 + g * 0.7152 + b * 0.0722; +}; + +const hexToRgb = (hex) => { + hex = hex.slice(1); + const value = parseInt(hex, 16); + const r = (value >> 16) & 255; + const g = (value >> 8) & 255; + const b = value & 255; + + return [r, g, b]; +}; + +module.exports = { contrastRatio, humanReadableContrastRatio }; diff --git a/content/brand/_brand.md b/content/brand/_brand.md new file mode 100644 index 00000000..016a70c9 --- /dev/null +++ b/content/brand/_brand.md @@ -0,0 +1,9 @@ +--- +permalink: false +eleventyNavigation: + key: brand +--- + +{% comment %} +This is a meta page for the Brand guide which helps establish a parent for the navigation. It will not be rendered. +{% endcomment %} diff --git a/content/brand/color-palette.md b/content/brand/color-palette.md new file mode 100644 index 00000000..56263379 --- /dev/null +++ b/content/brand/color-palette.md @@ -0,0 +1,68 @@ +--- +title: Color palette +permalink: /brand/color-palette/ +layout: layouts/page +sidenav: false +tags: brand +eleventyNavigation: + parent: brand + key: color-palette + order: 3 + title: Color palette + +palette: + - name: white + hex: 'FFFFFF' + - name: light + hex: 'B3EFFF' + - name: bright + hex: '00CFFF' + - name: medium + hex: '046B99' + - name: dark + hex: '1C304A' + - name: black + hex: '000000' +--- + +For Adobe, Sketch, and Mac applications + +[Download color palettes]({{ "/assets/brand/dist/18F_Color_Palette.zip" | url }}){.usa-button} + +
+ {% for color in palette %} +
+
+

{{ color.name }}

+

#{{ color.hex }}

+
+
+ {% endfor %} +
+ +
+ + +## Color guidance +Color choices impact the accessibility of our content. Here's how to use color in line with [18F's accessibility practices](https://pages.18f.gov/accessibility/). + +### Don't use color exclusively to convey meaning +People see colors differently, and color is not seen by everyone. If color is the only signal, that signal won’t get through as intended to everyone. + +When communicating, use color as an enhancement to other elements like text, icons, or patterns. For example, to visualize data in a line chart, use different line styles (solid, dashed, dotted) in addition to different line colors. + +One helpful test is to imagine your design in black and white. Is it still understandable? + +### Use accessible color combinations +Colors need to contrast with one another to be identifiable. WCAG provides guidance on what contrast ratios are accessible in certain situations: +* Large text (bolded 18px text, regular 24px text, or larger) [should have a contrast ratio of 3:1 or more with its background](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html). +* Small text (18px text or smaller) [should have a contrast ratio of 4.5:1 or more with its background](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html). +* Non-text elements (aka, icons or diagrams) [should have a contrast ratio of 3:1 or more with its background color](https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast.html). + +We recommend using a higher standard when using the 18F palette: +* Large **and** small text should have a contrast ratio of 4.5:1 or more with its background. +* Non-text elements should have a contrast ratio of 3:1 or more with its background color. + +Below is an outline of accessible 18F color combinations. + +{% include 'brand/color-matrix.html' %} diff --git a/content/brand/icons.md b/content/brand/icons.md new file mode 100644 index 00000000..83601a1c --- /dev/null +++ b/content/brand/icons.md @@ -0,0 +1,38 @@ +--- +title: Icons +permalink: /brand/icons/ +layout: layouts/page +sidenav: false +tags: brand +eleventyNavigation: + parent: brand + key: icons + order: 5 + title: Icons + +--- + +18F uses a customized version of [Feather Icons](https://feathericons.com/) for its iconography. Feather Icons is [licensed under an MIT License](https://github.com/feathericons/feather/blob/master/LICENSE), with copyright belonging to Cole Bemis. + +## Design Specs +Most of the icons retain the base styling of Feather icons. The 18F version includes a few adjustments. +* Icons are drawn on a 48x48 grid, with some custom detailed icons drawn on a 64x64 grid. +* Strokes of 2px, centered, with capped ends. +* For square icons, a min width or height of 28px. +* For circular icons, a min width or height of 34px. +* Minimum of 2px between elements. + +## Get the icons +You can access a set of common icons in the [18F Google Slides template]({{ "/brand/templates/" | url }}) (only available to GSA staff), or [download the full set]({{ "/assets/brand/dist/18F_feather.zip" | url }}). + +The download includes: +* Searchable PDF sticker sheets of [all 300+ icons]({{ "/assets/brand/img/18F-Feather-Icons--all.pdf" | url }}) and [top requested icons]({{ "/assets/brand/img/18F-Feather-Icons--top-hits.pdf" | url }}). Icons with a "--c" name are customized. +* SVG and PNG exports of all icons, by color. +* A sketch file of all icons for designers. + +## Representing humans +In order to offer more diverse and expressive ways to represent humans, we created a custom set of 18F Avataaars based on [the work of Pablo Stanley](https://getavataaars.com/). These are great stand-ins for showing emotion and to represent anonymous user groups. + +These are available to GSA staff in two formats: +* Via the [starter deck](https://docs.google.com/presentation/d/1CXXvxBbVjO3LjIUwRYEbk8WHpsG0AJdUc6SI_jAZDNQ/edit#slide=id.g5fdac3c814_0_209), which includes 10 characters and a range of emotions as well as guidance on different ways to represent humans. You can also get to this starter from the [18F Google Slides template]({{ "/brand/templates/" | url }}). +* Via the [full sketch library](https://drive.google.com/drive/folders/1MFGWlJ6Z1ZzIVXK0h0Xh8RsUiBZzYdbg) for designers. diff --git a/content/brand/images.md b/content/brand/images.md new file mode 100644 index 00000000..2a5843d3 --- /dev/null +++ b/content/brand/images.md @@ -0,0 +1,37 @@ +--- +title: Images +permalink: /brand/images/ +layout: layouts/page +sidenav: false +tags: brand +eleventyNavigation: + parent: brand + key: images + order: 7 + title: Images +--- +## Virtual backgrounds +A collection of images containing the 18F logo that can be used as virtual backgrounds for video calls. + +{% image_with_class "assets/brand/img/18F_VideoBG_6Illo.png" "" "" %} + +[Download virtual backgrounds]({{ "/assets/brand/dist/18F_VideoBackgrounds.zip" | url }}){.usa-button} + +## Desktop Art +A variety of wallpaper images for MacBooks and Apple Displays. + +{% image_with_class "assets/brand/img/18FDesktop-Preview.png" "" "" %} + +[Download desktop art]({{ "/assets/brand/dist/18F_Desktop_Art.zip" | url }}){.usa-button} + +### Instructions +1. In **System Preferences**, open **Desktop & Screensaver**. +2. On the **Desktop** tab, click the **+** button. +3. Find the **18F_Desktop_Art** folder and click **Choose**. +4. Choose your desktop wallpaper on the right. + +#### Image credits +* Flag, [Eric Duvauchelle](https://unsplash.com/photos/xn4Lc-87_fM) +* Sky, [Tumprins](http://tumblr.unsplash.com/post/54230079634/download-tumprins) +* Statue of Liberty, [Anthony Delanoix](https://unsplash.com/photos/ciJJ57qsQLs) +* Highway, [Israel Sundseth](https://unsplash.com/photos/BYu8ITUWMfc/) diff --git a/content/brand/introduction.md b/content/brand/introduction.md new file mode 100644 index 00000000..2dd602eb --- /dev/null +++ b/content/brand/introduction.md @@ -0,0 +1,37 @@ +--- +title: Introduction +permalink: /brand/ +layout: layouts/page +sidenav: false +tags: brand +eleventyNavigation: + parent: brand + key: Introduction + order: 1 + title: Introduction +--- + +This toolkit was developed for 18F employees, but we hope it’s a useful reference for anyone, whether you’re on another design team or a member of the press. + +## If you work at 18F +Our visual identity is a flexible system that helps you communicate clearly while building visual consistency across our work. It features a growing set of templates and guides you can use to meet common design needs — and save time in the process. + +This identity is integral to our ability to communicate our goals and deliver high-quality products. We recognize that having a strong brand is as important for government agencies as it is for private companies, and our users expect nothing less. + +Because a brand communicates [our core values](https://handbook.tts.gsa.gov/about-us/tts-history/#our-values), it helps us build trust with our partners, increase engagement, foster input and open-source contributions, and improve the public’s perception of government, all of which are central to [our mission](https://18f.gsa.gov/about/#our-mission). + +## If you work at another organization +As a work of the federal government, this project is in the public domain within the United States. Additionally, we waive copyright and related rights in the work worldwide through the CC0 1.0 Universal public domain dedication. + +Feel free to use the format of this guide with your own branding and identity. Please don’t use our visual styles as your own, though. These templates, color palettes, and styles are reflective of our core values, and won’t necessarily translate well for your organization and your communication goals. + +## Feedback or questions +This is not a complete brand style guide, and it’s still an early draft. We’ll continue adding to this as we can, but there is no dedicated team at the moment. + +We welcome your feedback and contributions so that we can continue to chip away at the highest priority needs for the 18F team. If you have any suggestions or are interested in getting involved, please chat us in [#18f-branding](https://18f.slack.com/archives/18f-branding) or [create an issue in GitHub](https://github.com/18F/brand/issues/new). + +### Related links +* [18F Content Guide](https://pages.18f.gov/content-guide/) +* [U.S. Web Design System](https://designsystem.digital.gov/) +* [Getting Started with Google Slides](https://support.google.com/docs/topic/19431) +* [Apple Keynote Support](https://www.apple.com/support/mac-apps/keynote/) diff --git a/content/brand/logo.md b/content/brand/logo.md new file mode 100644 index 00000000..d06372bf --- /dev/null +++ b/content/brand/logo.md @@ -0,0 +1,34 @@ +--- +title: Logo +permalink: /brand/logo/ +layout: layouts/page +sidenav: false +tags: brand +eleventyNavigation: + parent: brand + key: logo + order: 2 + title: Logo +--- + +Logo variations (PNG, SVG) + +{% image_with_class "assets/brand/img/18F-Logo-M.png" ".display-logo" "" %} + +[Download logo]({{"/assets/brand/dist/18F_Logo.zip" | url }}){.usa-button} + +## Guidelines + +* **Do** use the black version of the logo over a white background as your default. Bright blue (#00cfff) and white do not have enough contrast to meet accessibility requirements for low-vision users. Even though logos can be an exception to this rule, we prefer to follow best practices, and use black as our primary logo color. The bright blue version of the logo should only be used if you are using a dark page background. You can see an example of this in our [presentation templates]({{ "/brand/templates/" | url }}). + +* **Do** keep adequate white space around the logo. At any size, there should be half a logo’s-width of white space between the logo and any other object or border. + +* **Do** use the SVG logo whenever possible. It has a small file size and renders well at any scale. PNG is an acceptable fallback if the format of your document doesn’t support SVG. + +* **Do** ask in [#18f-branding](https://gsa-tts.slack.com/archives/C04B8KGCZ) when you have questions. + +* **Don't** change the color of the logo. + +* **Don't** place the logo over images. + +* **Don't** stretch or skew the logo. diff --git a/content/brand/principles.md b/content/brand/principles.md new file mode 100644 index 00000000..36dd74da --- /dev/null +++ b/content/brand/principles.md @@ -0,0 +1,56 @@ +--- +title: Visual design principles +permalink: /brand/principles/ +layout: layouts/page +sidenav: false +tags: brand +eleventyNavigation: + parent: brand + key: visual-design-principles + order: 8 + title: Visual design principles +--- + +These visual design principles provide guidance for applying and extending the 18F identity into other communication assets. They serve as a framework for evaluating potential design solutions against our core values and priorities. + +18F's visual design principles are intended to be applied to projects that should reflect the 18F brand, not work we do for our partners. + +## Lead by example +You’re a role model. Don’t do anything you wouldn’t encourage others to copy. +* Is this design an example of best practices? If not, is it a modification you believe others should consider a best practice? +* How would you feel if this design was repeated across 18F or government? + +## Let the content be the voice +Bring clarity to content through design choices that support meaning and intent. Design a fair, inclusive, and open platform for the many voices that make up 18F. +* Do the visuals overpower the content? +* Do the design choices promote clarity of meaning? +* What message does the design convey before you read the words? +* How does typographic hierarchy contribute to understanding? +* Does the content design allow for multiple levels of engagement? + +## Start with the expected +Meet expectations before you raise them. Favor solutions from standards. Use common design patterns that establish confidence and trust. Don’t reinvent the wheel, incrementally improve it. +* Are you using a commonly used pattern? +* Has someone else solved this problem already? +* What is the potential benefit of an unconventional solution? +* Could your modifications be applied back to a standard? +* Are the unique elements of the design necessary? Could an existing element be used instead? +* Is the reason for design choices apparent? +* Does your design feel part of a considered visual system? + +## Convince with soundness not loudness +Design with confidence and calmness by being honest and direct. Practice visual design with solid fundamentals, attention to detail, flexibility, and resilience. +* Is the layout of elements intuitive? +* Does the design guide the viewer? +* Are you leveraging typographic styles? +* Are there elements that get in the way of understanding? +* Have you run spell check lately? +* Is the tone honest, respectful, and inviting? +* Does it exceed expectations for government? + +## Keep questioning +Have opinions, express them, and be open to change. Question the principles — acknowledge their dynamic, iterative nature. Evolve alongside 18F’s people, culture, and core values. Push forward. +* Is something missing? Is this an opportunity for the principles to grow? +* Are these principles consistent with 18F’s organizational principles? +* Do the decisions encouraged by these principles result in the desired outcomes for the folks using what we design? +* Have you discussed any dissatisfaction with the principles with anyone? Why not? diff --git a/content/brand/templates.md b/content/brand/templates.md new file mode 100644 index 00000000..e12bb884 --- /dev/null +++ b/content/brand/templates.md @@ -0,0 +1,53 @@ +--- +title: Templates +permalink: /brand/templates/ +layout: layouts/page +sidenav: false +tags: brand +eleventyNavigation: + parent: brand + key: templates + order: 6 + title: Templates +--- +## Google Docs templates +We have three Google Docs templates: a [basic outline](https://docs.google.com/a/gsa.gov/document/d/1lJBCZwgQzKsX5ggr7ykUaeuAUNqKsthENYCXMTA5Tbs/edit?usp=sharing), a [detailed example](https://docs.google.com/a/gsa.gov/document/d/1BovRM6thz0YWCyd32zwbh-6TYy4ON6GEc8ILDd3RLl8/edit?usp=sharing) with a table of contents, tables, typographic elements, and an appendix, and a [letterhead](https://docs.google.com/document/d/16rQOcP9XYu4qlPwrswTXKO7XBKegxejvXocxo98rW5c/edit?usp=sharing). + +### Instructions +#### To save 18F styles as your default Google styles: +1. Open the [basic outline](https://docs.google.com/a/gsa.gov/document/d/1lJBCZwgQzKsX5ggr7ykUaeuAUNqKsthENYCXMTA5Tbs/edit?usp=sharing). +2. In the Styles drop-down menu, choose **Options > Save as my default styles**. Any new Google document you create will use the 18F styles by default. +{% image_with_class "assets/brand/img/Save-18F-styles-as-default.png" "" "Screenshot showing how to save 18F styles as default styles in Google Docs" %} + +#### To apply 18F styles to an existing Google document: +1. Follow the instructions above to save 18F styles as your default Google styles. +2. Open an existing document you want to apply the 18F styles to. +3. In the Styles drop-down menu, choose **Options > Use my default styles**. This will apply the 18F styles and override any existing styles in the document. +{% image_with_class "assets/brand/img/Apply-18F-styles-existing-doc.png" "" "Screenshot showing how to apply default styles to an existing Google Doc" %} + +#### To reuse specific tables or typographic elements in a Google Doc: +1. Open the [detailed example](https://docs.google.com/a/gsa.gov/document/d/1BovRM6thz0YWCyd32zwbh-6TYy4ON6GEc8ILDd3RLl8/edit?usp=sharing). +2. Click **File > Make a copy…** (This will ensure you don’t accidentally edit the original master file.) +3. Highlight and delete any sections you don’t need, and make changes as needed. + +*** + +## Google Slides presentation templates +{% image_with_class "assets/brand/img/18F-slide-theme-cover.svg" "" "18F slide template cover" %} + +[GSA slide template gallery](https://docs.google.com/presentation/u/0/?ftv=1&folder=0BwWYNZcEDfwabE13dnZpbFN5QmM&tgif=d){.usa-button} + +### Instructions +#### To make a new Google Slides presentation +1. In Google Drive, click **New > Google Slides > From a template**. +2. Once the GSA Template Gallery opens, choose the **18F Slide Theme** presentation from the list. +3. This will create a copy of the template. Rename your presentation so that the team doesn't confuse it with the original. + +#### To import the theme into an existing Google Slides presentation +1. Open your existing presentation. +2. Choose the **Theme** button in the toolbar. +3. Click **Import theme** at the bottom of the theme menu. +4. Search for **18F Slide Theme**. +5. Select and import the theme. + +You can choose different layouts by selecting and inserting master pages from the template. For more details, learn about [custom layouts and themes](https://support.google.com/docs/answer/1694986?hl=en). diff --git a/content/brand/typography.md b/content/brand/typography.md new file mode 100644 index 00000000..4956af29 --- /dev/null +++ b/content/brand/typography.md @@ -0,0 +1,56 @@ +--- +title: Typography +permalink: /brand/typography/ +layout: layouts/page +sidenav: false +tags: brand +eleventyNavigation: + parent: brand + key: typography + order: 4 + title: Typography + +--- + +The primary font is **Helvetica Neue**, in bold and regular weights. +We use one typeface to keep things simple, and use different font sizes and weights to create hierarchy. + +Helvetica Neue is a system font on all Apple devices, so you don't need to download or install anything. On Windows devices, if Helvetica Neue is not available, use Arial as a replacement. + +
+
+

Helvetica Neue, Regular

+ Aa +
+ + A B C D E F G H I J K L M
+ + N O P Q R S T U V W X Y Z
+ + a b c d e f g h i j k l m
+ + n o p q r s t u v w x y z
+ + 0 1 2 3 4 5 6 7 8 9 + +
+
+ +
+

Helvetica Neue, Bold

+ Aa +
+ + A B C D E F G H I J K L M
+ + N O P Q R S T U V W X Y Z
+ + a b c d e f g h i j k l m
+ + n o p q r s t u v w x y z
+ + 0 1 2 3 4 5 6 7 8 9 + +
+
+
diff --git a/docs/replatforming.md b/docs/replatforming.md index 0f28f45f..9d393461 100644 --- a/docs/replatforming.md +++ b/docs/replatforming.md @@ -89,25 +89,40 @@ If that doesn't work, type in `git update-index --assume-unchanged _data/assetPa ## Content migration process -The general steps for migrating a guide: +The general steps for migrating a guide: 1. Add the guide to the `_data/titles_roots.yaml` file with the guide’s tag, name, and root (See [Guide titles and subdirectories](#guide-titles-and-subdirectories) for an example). 2. Add the primary navigation for the guide to `_data/navigation.yaml`. -4. Add a link to the new guide in `_includes/guidelist.html` so it will be easier to find. -5. Copy over the markdown file for the guide into the appropriate subfolder. -6. Open up the markdown file to edit the front matter: +3. Add a link to the new guide in `_includes/guidelist.html` so it will be easier to find. +4. Copy over the markdown file for the guide into the appropriate subfolder. +5. Open up the markdown file to edit the front matter: 1. Change the layout to `layout/page` or whatever layout is most appropriate. 2. Add `tags: ` where is the guide’s tag. - 2. Update the `permalink` to the link that should be displayed. Generally this will be `///`. Try to match the permalink of the original markdown file. - 3. Add the `eleventyNavigation` front matter (See [Sidenavs](#sidenavs) for more details) : + 3. Update the `permalink` to the link that should be displayed. Generally this will be `///`. Try to match the permalink of the original markdown file. + 4. Add the `eleventyNavigation` front matter (See [Sidenavs](#sidenavs) for more details) : ``` - eleventyNavigation: + eleventyNavigation: parent: key: order: <#> title: ``` +6. If your guide offers any downloads, add the files for download to `/assets/{guide}/dist/{filename}`, and set the download links to point to the same path. 7. Celebrate! Or edit this documentation to update any steps that may be missing. +## Adding new node modules + +It may turn out that you need to install an npm package to replicate functionality in the old guides. Here's how to do it! + +First, before your write any code or configuration that relies on the package, install the package via Docker Compose while the services are running: + +```sh +# If you haven't already +$ docker compose up + +# In another tab +$ docker compose exec guides npm install {your options here} +``` + ## Running pa11y We use `pa11y-ci` is used to scan for accessibility issues. The scan runs as part of our CI setup (see the [pull-request.yml workflow](.github/workflows/pull-request.yml)) @@ -125,6 +140,6 @@ In certain cases we may need `pa11y-ci` to ignore an element. For example, in th _Example:_ -``` -This text fails. +```html +This text fails. ``` diff --git a/package-lock.json b/package-lock.json index 10ed6c51..849f42fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "luxon": "^2.3.1", "markdown-it": "^12.3.2", "markdown-it-anchor": "^8.6.7", + "markdown-it-attrs": "^4.1.6", "netlify-cms-proxy-server": "^1.3.23", "npm-run-all": "^4.1.5", "pa11y-ci": "^3.0.1", @@ -7345,6 +7346,18 @@ "markdown-it": "*" } }, + "node_modules/markdown-it-attrs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.1.6.tgz", + "integrity": "sha512-O7PDKZlN8RFMyDX13JnctQompwrrILuz2y43pW2GagcwpIIElkAdfeek+erHfxUOlXWPsjFeWmZ8ch1xtRLWpA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "markdown-it": ">= 9.0.0" + } + }, "node_modules/markdown-table": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", diff --git a/package.json b/package.json index 63a16d80..0a1a213b 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "luxon": "^2.3.1", "markdown-it": "^12.3.2", "markdown-it-anchor": "^8.6.7", + "markdown-it-attrs": "^4.1.6", "netlify-cms-proxy-server": "^1.3.23", "npm-run-all": "^4.1.5", "pa11y-ci": "^3.0.1",