├── .babelrc
├── .eslintrc.json
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── archive.zip
├── config.json
├── gulp-tasks
├── assets.js
├── boilerplate.js
├── browser-sync.js
├── clean.js
├── css.js
├── default.js
├── dist.js
├── fetch-google.js
├── html.js
├── js.js
├── smoosh.js
└── style-guide.js
├── gulpfile.js
├── package.json
├── report-error.js
├── src
├── assets
│ ├── bg.jpg
│ ├── fonts
│ │ ├── atlas
│ │ │ ├── AtlasGrotesk-Bold-Web.woff2
│ │ │ ├── AtlasGrotesk-Light-Web.woff2
│ │ │ ├── AtlasGrotesk-Medium-Web.woff2
│ │ │ ├── AtlasGrotesk-Regular-Web.woff2
│ │ │ └── AtlasGrotesk-Thin-Web.woff2
│ │ ├── canela
│ │ │ ├── Canela-Bold-Web.woff2
│ │ │ └── Canela-Light-Web.woff2
│ │ └── publico
│ │ │ ├── PublicoText-Bold-Web.woff2
│ │ │ ├── PublicoText-Italic-Web.woff2
│ │ │ └── PublicoText-Roman-Web.woff2
│ ├── prism
│ │ ├── code.css
│ │ ├── code.html
│ │ └── code.js
│ ├── scripts
│ │ ├── d3.v4.12.0+jetpack.min.js
│ │ ├── d3.v5.0.0.min.js
│ │ └── prism.js
│ └── social
│ │ ├── .gitkeep
│ │ ├── social-facebook.jpg
│ │ └── social-twitter.jpg
├── css
│ ├── config.styl
│ ├── story
│ │ ├── header.styl
│ │ ├── intro.styl
│ │ ├── prism.styl
│ │ ├── scrolly-overlay.styl
│ │ ├── scrolly-side.styl
│ │ └── story.styl
│ └── utils
│ │ ├── font.styl
│ │ ├── helpers.styl
│ │ ├── layout.styl
│ │ ├── no-ui-slider.styl
│ │ ├── presets.styl
│ │ ├── reset.styl
│ │ ├── unicode.styl
│ │ └── variables.styl
├── html
│ ├── helpers
│ │ ├── greaterThan.js
│ │ ├── ifEquals.js
│ │ ├── lessThan.js
│ │ └── slugify.js
│ ├── index.hbs
│ └── partials
│ │ ├── base
│ │ ├── analytics.hbs
│ │ ├── font.hbs
│ │ ├── header.hbs
│ │ └── meta.hbs
│ │ └── story
│ │ ├── content.hbs
│ │ ├── intro.hbs
│ │ ├── scrolly-overlay.hbs
│ │ └── scrolly-side.hbs
└── js
│ ├── critical.js
│ ├── entry.js
│ ├── graphic-overlay.js
│ ├── graphic-side.js
│ ├── polyfills
│ ├── endsWith.js
│ ├── find.js
│ ├── findIndex.js
│ ├── includes.js
│ └── startsWith.js
│ ├── pudding-chart
│ └── base.js
│ └── utils
│ ├── dom.js
│ ├── is-mobile.js
│ ├── load-css.js
│ ├── load-font.js
│ ├── load-image.js
│ ├── locate-test.js
│ ├── locate.js
│ ├── lookup-state-abbr.js
│ ├── lookup-state-name.js
│ ├── tracker.js
│ ├── truncate.js
│ ├── url-parameter.js
│ └── us-state-data.js
├── svg
├── activity.svg
├── airplay.svg
├── alert-circle.svg
├── alert-octagon.svg
├── alert-triangle.svg
├── align-center.svg
├── align-justify.svg
├── align-left.svg
├── align-right.svg
├── anchor.svg
├── aperture.svg
├── archive.svg
├── arrow-down-circle.svg
├── arrow-down-left.svg
├── arrow-down-right.svg
├── arrow-down.svg
├── arrow-left-circle.svg
├── arrow-left.svg
├── arrow-right-circle.svg
├── arrow-right.svg
├── arrow-up-circle.svg
├── arrow-up-left.svg
├── arrow-up-right.svg
├── arrow-up.svg
├── at-sign.svg
├── award.svg
├── bar-chart-2.svg
├── bar-chart.svg
├── battery-charging.svg
├── battery.svg
├── bell-off.svg
├── bell.svg
├── bluetooth.svg
├── bold.svg
├── book-open.svg
├── book.svg
├── bookmark.svg
├── box.svg
├── briefcase.svg
├── calendar.svg
├── camera-off.svg
├── camera.svg
├── cast.svg
├── check-circle.svg
├── check-square.svg
├── check.svg
├── chevron-down.svg
├── chevron-left.svg
├── chevron-right.svg
├── chevron-up.svg
├── chevrons-down.svg
├── chevrons-left.svg
├── chevrons-right.svg
├── chevrons-up.svg
├── chrome.svg
├── circle.svg
├── clipboard.svg
├── clock.svg
├── cloud-drizzle.svg
├── cloud-lightning.svg
├── cloud-off.svg
├── cloud-rain.svg
├── cloud-snow.svg
├── cloud.svg
├── code.svg
├── codepen.svg
├── command.svg
├── compass.svg
├── copy.svg
├── corner-down-left.svg
├── corner-down-right.svg
├── corner-left-down.svg
├── corner-left-up.svg
├── corner-right-down.svg
├── corner-right-up.svg
├── corner-up-left.svg
├── corner-up-right.svg
├── cpu.svg
├── credit-card.svg
├── crop.svg
├── crosshair.svg
├── database.svg
├── delete.svg
├── disc.svg
├── dollar-sign.svg
├── download-cloud.svg
├── download.svg
├── droplet.svg
├── edit-2.svg
├── edit-3.svg
├── edit.svg
├── external-link.svg
├── eye-off.svg
├── eye.svg
├── facebook.svg
├── fast-forward.svg
├── feather.svg
├── file-minus.svg
├── file-plus.svg
├── file-text.svg
├── file.svg
├── film.svg
├── filter.svg
├── flag.svg
├── folder-minus.svg
├── folder-plus.svg
├── folder.svg
├── gift.svg
├── git-branch.svg
├── git-commit.svg
├── git-merge.svg
├── git-pull-request.svg
├── github.svg
├── gitlab.svg
├── globe.svg
├── grid.svg
├── hard-drive.svg
├── hash.svg
├── headphones.svg
├── heart.svg
├── help-circle.svg
├── home.svg
├── image.svg
├── inbox.svg
├── info.svg
├── instagram.svg
├── italic.svg
├── layers.svg
├── layout.svg
├── life-buoy.svg
├── link-2.svg
├── link.svg
├── linkedin.svg
├── list.svg
├── loader.svg
├── lock.svg
├── log-in.svg
├── log-out.svg
├── logo-small.svg
├── logo.svg
├── mail.svg
├── map-pin.svg
├── map.svg
├── maximize-2.svg
├── maximize.svg
├── menu.svg
├── message-circle.svg
├── message-square.svg
├── mic-off.svg
├── mic.svg
├── minimize-2.svg
├── minimize.svg
├── minus-circle.svg
├── minus-square.svg
├── minus.svg
├── monitor.svg
├── moon.svg
├── more-horizontal.svg
├── more-vertical.svg
├── move.svg
├── music.svg
├── navigation-2.svg
├── navigation.svg
├── octagon.svg
├── package.svg
├── paperclip.svg
├── pause-circle.svg
├── pause.svg
├── percent.svg
├── phone-call.svg
├── phone-forwarded.svg
├── phone-incoming.svg
├── phone-missed.svg
├── phone-off.svg
├── phone-outgoing.svg
├── phone.svg
├── pie-chart.svg
├── play-circle.svg
├── play.svg
├── plus-circle.svg
├── plus-square.svg
├── plus.svg
├── pocket.svg
├── power.svg
├── printer.svg
├── radio.svg
├── refresh-ccw.svg
├── refresh-cw.svg
├── repeat.svg
├── rewind.svg
├── rotate-ccw.svg
├── rotate-cw.svg
├── rss.svg
├── save.svg
├── scissors.svg
├── search.svg
├── send.svg
├── server.svg
├── settings.svg
├── share-2.svg
├── share.svg
├── shield-off.svg
├── shield.svg
├── shopping-bag.svg
├── shopping-cart.svg
├── shuffle.svg
├── sidebar.svg
├── skip-back.svg
├── skip-forward.svg
├── slack.svg
├── slash.svg
├── sliders.svg
├── smartphone.svg
├── speaker.svg
├── square.svg
├── star.svg
├── stop-circle.svg
├── sun.svg
├── sunrise.svg
├── sunset.svg
├── tablet.svg
├── tag.svg
├── target.svg
├── terminal.svg
├── thermometer.svg
├── thumbs-down.svg
├── thumbs-up.svg
├── toggle-left.svg
├── toggle-right.svg
├── trash-2.svg
├── trash.svg
├── trending-down.svg
├── trending-up.svg
├── triangle.svg
├── truck.svg
├── tv.svg
├── twitter.svg
├── type.svg
├── umbrella.svg
├── underline.svg
├── unlock.svg
├── upload-cloud.svg
├── upload.svg
├── user-check.svg
├── user-minus.svg
├── user-plus.svg
├── user-x.svg
├── user.svg
├── users.svg
├── video-off.svg
├── video.svg
├── voicemail.svg
├── volume-1.svg
├── volume-2.svg
├── volume-x.svg
├── volume.svg
├── watch.svg
├── wifi-off.svg
├── wifi.svg
├── wind.svg
├── x-circle.svg
├── x-square.svg
├── x.svg
├── youtube.svg
├── zap-off.svg
├── zap.svg
├── zoom-in.svg
└── zoom-out.svg
├── template-data
├── copy.json
└── meta.json
├── webpack.config.dev.js
└── webpack.config.dist.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-1"]
3 | }
4 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["airbnb-base", "prettier"],
3 | "plugins": ["prettier"],
4 | "rules": {
5 | "quotes": [1, "single"],
6 | "no-tabs": 0,
7 | "indent": ["error", "tab"]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | npm-debug.log
3 | node_modules
4 | dev
5 | dist
6 | .tmp
7 | package-lock.json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Russell Goldenberg
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PHONY: github aws-assets aws-htmljs aws-cache live
2 |
3 | github:
4 | rm -rf docs
5 | cp -r dist/ docs
6 | git add -A
7 | git commit -m "update dev version"
8 | git push
9 |
10 | archive:
11 | zip -r archive.zip dev
12 |
13 | aws-assets:
14 | aws s3 sync dist s3://pudding.cool/process/scrollytelling-sticky --delete --cache-control 'max-age=31536000' --exclude 'index.html' --exclude 'bundle.js'
15 |
16 | aws-htmljs:
17 | aws s3 cp dist/index.html s3://pudding.cool/process/scrollytelling-sticky/index.html
18 | aws s3 cp dist/bundle.js s3://pudding.cool/process/scrollytelling-sticky/bundle.js
19 |
20 | aws-cache:
21 | aws cloudfront create-invalidation --distribution-id E13X38CRR4E04D --paths '/process/scrollytelling-sticky*'
22 |
23 | live: aws-assets aws-htmljs aws-cache archive
24 |
--------------------------------------------------------------------------------
/archive.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/archive.zip
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "google": {
3 | "id": "1e2SzXVgKZ0FyxVParOksqWbdABwZUHY4IECEK3IMkWs"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/gulp-tasks/assets.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const browserSync = require('browser-sync')
3 | const src = 'src/assets/**/*'
4 |
5 | gulp.task('assets-dev', () => {
6 | return gulp.src(src)
7 | .pipe(gulp.dest('dev/assets'))
8 | .pipe(browserSync.reload({ stream: true }))
9 | })
10 |
11 | gulp.task('assets-dist', () => {
12 | return gulp.src(src)
13 | .pipe(gulp.dest('dist/assets'))
14 | })
15 |
16 |
17 | gulp.task('assets-boilerplate', () => {
18 | return gulp.src(src)
19 | .pipe(gulp.dest('boilerplate/assets'))
20 | })
21 |
22 | gulp.task('assets-style-guide', () => {
23 | return gulp.src(src)
24 | .pipe(gulp.dest('docs/assets'))
25 | })
26 |
--------------------------------------------------------------------------------
/gulp-tasks/boilerplate.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const runSequence = require('run-sequence')
3 |
4 | // run all dist tasks to deploy
5 | gulp.task('boilerplate', (cb) => {
6 | runSequence(
7 | 'clean-boilerplate',
8 | 'css-boilerplate-base',
9 | 'css-boilerplate-story',
10 | 'js-boilerplate',
11 | 'html-boilerplate',
12 | 'assets-boilerplate',
13 | cb
14 | )
15 | })
16 |
--------------------------------------------------------------------------------
/gulp-tasks/browser-sync.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const browserSync = require('browser-sync')
3 |
4 | // browser-sync task for starting the server.
5 | gulp.task('browser-sync', () => {
6 | browserSync.init({
7 | server: {
8 | baseDir: 'dev/',
9 | index: 'index.html',
10 | },
11 | port: 4000,
12 | notify: false,
13 | ghostMode: false,
14 | online: false,
15 | })
16 | })
17 |
18 | gulp.task('browser-sync-reload', browserSync.reload)
19 |
--------------------------------------------------------------------------------
/gulp-tasks/clean.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const del = require('del')
3 |
4 | gulp.task('clean-dev', (cb) => {
5 | del(['dev/**']).then(() => cb())
6 | })
7 |
8 | gulp.task('clean-dist', (cb) => {
9 | del(['.tmp/**', 'dist/**']).then(() => cb())
10 | })
11 |
12 | gulp.task('clean-boilerplate', (cb) => {
13 | del(['boilerplate/**/!(bundle.js)']).then(() => cb())
14 | })
15 |
16 | gulp.task('clean-style-guide', (cb) => {
17 | del(['style-guide/**/!(*.js)']).then(() => cb())
18 | })
19 |
--------------------------------------------------------------------------------
/gulp-tasks/css.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp');
2 | const stylus = require('gulp-stylus');
3 | const autoprefixer = require('gulp-autoprefixer');
4 | const rename = require('gulp-rename');
5 | const browserSync = require('browser-sync');
6 | const plumber = require('gulp-plumber');
7 | const sourcemaps = require('gulp-sourcemaps');
8 | const combineMq = require('gulp-combine-mq');
9 | const cleanCSS = require('gulp-clean-css');
10 | const report = require('../report-error.js');
11 |
12 | const src = 'src/css/config.styl';
13 |
14 | // compile styl to css and autoprefix
15 | gulp.task('css-dev', () => {
16 | gulp
17 | .src(src)
18 | .pipe(plumber({ errorHandler: report }))
19 | // .pipe(sourcemaps.init())
20 | .pipe(stylus())
21 | .pipe(
22 | autoprefixer({
23 | browsers: ['last 4 versions']
24 | })
25 | )
26 | .pipe(combineMq())
27 | .pipe(rename('bundle.css'))
28 | // .pipe(sourcemaps.write('.'))
29 | .pipe(gulp.dest('dev'))
30 | .pipe(browserSync.stream({ match: '**/*.css' }));
31 | });
32 |
33 | // compile all styl and autoprefix, and minify
34 | gulp.task('css-dist', () => {
35 | gulp
36 | .src(src)
37 | .pipe(stylus())
38 | .pipe(
39 | autoprefixer({
40 | browsers: ['last 4 versions']
41 | })
42 | )
43 | .pipe(combineMq())
44 | .pipe(cleanCSS())
45 | .pipe(rename('bundle.css'))
46 | .pipe(gulp.dest('.tmp'));
47 | });
48 |
49 | // compile all styl and autoprefix, and minify
50 | gulp.task('css-boilerplate-base', () => {
51 | gulp
52 | .src('src/css/boilerplate-base.styl')
53 | .pipe(stylus())
54 | .pipe(
55 | autoprefixer({
56 | browsers: ['last 3 versions']
57 | })
58 | )
59 | .pipe(combineMq())
60 | .pipe(cleanCSS())
61 | .pipe(rename('critical.css'))
62 | .pipe(gulp.dest('boilerplate'));
63 | });
64 |
65 | gulp.task('css-boilerplate-story', () => {
66 | gulp
67 | .src('src/css/boilerplate-story.styl')
68 | .pipe(stylus())
69 | .pipe(
70 | autoprefixer({
71 | browsers: ['last 3 versions']
72 | })
73 | )
74 | .pipe(combineMq())
75 | .pipe(rename('bundle.css'))
76 | .pipe(gulp.dest('boilerplate'));
77 | });
78 |
79 | // compile styl to css and autoprefix
80 | gulp.task('css-style-guide', () => {
81 | gulp
82 | .src('src/css/style-guide.styl')
83 | .pipe(stylus())
84 | .pipe(
85 | autoprefixer({
86 | browsers: ['last 4 versions']
87 | })
88 | )
89 | .pipe(combineMq())
90 | .pipe(rename('bundle.css'))
91 | .pipe(gulp.dest('docs'));
92 | });
93 |
--------------------------------------------------------------------------------
/gulp-tasks/default.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const runSequence = require('run-sequence')
3 |
4 | // Default task to be run with `gulp`
5 | gulp.task('default', ['dev'], () => {
6 | gulp.watch('src/css/**/*.styl', ['css-dev'])
7 | gulp.watch('src/html/**/*.hbs', ['html-dev'])
8 | gulp.watch('src/js/**/*.js', ['js-dev'])
9 | gulp.watch('src/assets/**/*', ['assets-dev'])
10 | gulp.watch('template-data/*.json', ['html-dev'])
11 | })
12 |
13 | gulp.task('dev', () => {
14 | runSequence(
15 | 'clean-dev',
16 | 'css-dev',
17 | 'js-dev-critical',
18 | 'js-dev',
19 | 'assets-dev',
20 | 'html-dev',
21 | 'browser-sync'
22 | )
23 | })
24 |
--------------------------------------------------------------------------------
/gulp-tasks/dist.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const runSequence = require('run-sequence')
3 |
4 | // run all dist tasks to deploy
5 | gulp.task('dist', (cb) => {
6 | runSequence(
7 | 'clean-dist',
8 | 'css-dist',
9 | 'html-dist',
10 | 'js-dist-critical',
11 | 'js-dist',
12 | 'smoosh-dist',
13 | 'assets-dist',
14 | cb
15 | )
16 | })
17 |
--------------------------------------------------------------------------------
/gulp-tasks/fetch-google.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const archieml = require('archieml')
3 | const request = require('request')
4 | const fs = require('fs')
5 | const configPath = `${process.cwd()}/config.json`
6 | const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))
7 | const google = config.google
8 |
9 | const url = `https://docs.google.com/document/d/${google.id}/export?format=txt`
10 |
11 | const makeRequest = (cb) => {
12 | request(url, function(error, response, body) {
13 | const parsed = archieml.load(body)
14 | const str = JSON.stringify(parsed)
15 | const basePath = `${process.cwd()}/template-data`
16 | const file = `${basePath}/${(google.filename || 'copy')}.json`
17 |
18 | fs.writeFile(file, str, (err) => {
19 | if (err) console.error(err)
20 | cb()
21 | })
22 | })
23 | }
24 |
25 | gulp.task('fetch-google', (cb) => {
26 | if (google.id) makeRequest(cb)
27 | else {
28 | console.error('No google doc')
29 | cb()
30 | }
31 | })
32 |
--------------------------------------------------------------------------------
/gulp-tasks/html.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp');
2 | const hb = require('gulp-hb');
3 | const rename = require('gulp-rename');
4 | const include = require('gulp-file-include');
5 | const plumber = require('gulp-plumber');
6 | const replace = require('gulp-replace');
7 | const report = require('../report-error.js');
8 | const browserSync = require('browser-sync');
9 |
10 | const srcIndex = 'src/html/*.hbs';
11 | const svgPath = `${process.cwd()}/svg/`;
12 |
13 | gulp.task('html-dev', () => {
14 | const hbStream = hb()
15 | .partials('./src/html/partials/**/*.hbs')
16 | .helpers('./src/html/helpers/*.js')
17 | .data('./template-data/**/*.{js,json}')
18 | .data({ basepath: '', timestamp: Date.now() });
19 |
20 | return (
21 | gulp
22 | .src(srcIndex)
23 | .pipe(plumber({ errorHandler: report }))
24 | .pipe(hbStream)
25 | .pipe(include({ basepath: svgPath }))
26 | .pipe(
27 | rename(path => {
28 | path.extname = '.html';
29 | })
30 | )
31 | // .pipe(rename('index.html'))
32 | .pipe(gulp.dest('dev'))
33 | .pipe(browserSync.reload({ stream: true }))
34 | );
35 | });
36 |
37 | gulp.task('html-dist', () => {
38 | const hbStream = hb()
39 | .partials('./src/html/partials/**/*.hbs')
40 | .helpers('./src/html/helpers/*.js')
41 | .data('./template-data/**/*.{js,json}')
42 | .data({ basepath: 'https://pudding.cool/', timestamp: Date.now() });
43 |
44 | return gulp
45 | .src(srcIndex)
46 | .pipe(plumber({ errorHandler: report }))
47 | .pipe(hbStream)
48 | .pipe(include({ basepath: svgPath }))
49 | .pipe(
50 | rename(path => {
51 | path.extname = '.html';
52 | })
53 | )
54 | .pipe(gulp.dest('.tmp'));
55 | });
56 |
57 | gulp.task('html-boilerplate', () => {
58 | const hbStream = hb()
59 | .partials('./src/html/partials/**/*.hbs')
60 | // .helpers('./src/html/helpers/*.js')
61 | .data('./template-data/**/*.{js,json}')
62 | .data({ basepath: 'https://pudding.cool/', timestamp: Date.now() });
63 |
64 | return gulp
65 | .src(srcIndex)
66 | .pipe(plumber({ errorHandler: report }))
67 | .pipe(hbStream)
68 | .pipe(include({ basepath: svgPath }))
69 | .pipe(
70 | replace(
71 | '',
72 | `
73 |
74 |
75 | `
76 | )
77 | )
78 | .pipe(replace('', ''))
79 | .pipe(rename('index.html'))
80 | .pipe(gulp.dest('boilerplate'));
81 | });
82 |
83 | gulp.task('html-style-guide', () => {
84 | const hbStream = hb()
85 | .partials('./src/html/partials/**/*.hbs')
86 | // .helpers('./src/html/helpers/*.js')
87 | .data('./template-data/**/*.{js,json}')
88 | .data({ basepath: 'https://pudding.cool/', timestamp: Date.now() });
89 |
90 | return gulp
91 | .src('./src/html/style-guide.hbs')
92 | .pipe(plumber({ errorHandler: report }))
93 | .pipe(hbStream)
94 | .pipe(include({ basepath: svgPath }))
95 | .pipe(rename('index.html'))
96 | .pipe(gulp.dest('docs'));
97 | });
98 |
--------------------------------------------------------------------------------
/gulp-tasks/js.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const rename = require('gulp-rename')
3 | const browserSync = require('browser-sync')
4 | const plumber = require('gulp-plumber')
5 | const webpack = require('webpack')
6 | const webpackStream = require('webpack-stream')
7 | const configDev = require('../webpack.config.dev.js')
8 | const configDist = require('../webpack.config.dist.js')
9 | const report = require('../report-error.js')
10 |
11 | const srcEntry = 'src/js/entry.js'
12 | const srcCritical = 'src/js/critical.js'
13 |
14 | gulp.task('js-dev', () => {
15 | return gulp.src(srcEntry)
16 | .pipe(plumber({ errorHandler: report }))
17 | .pipe(webpackStream(configDev, webpack, (error, stats) => {
18 | const time = stats.toJson().time
19 | console.log(`Built in ${time} ms.`)
20 | }))
21 | .pipe(rename('bundle.js'))
22 | .pipe(gulp.dest('dev'))
23 | .pipe(browserSync.reload({ stream: true }))
24 | })
25 |
26 | gulp.task('js-dev-critical', () => {
27 | return gulp.src(srcCritical)
28 | .pipe(webpackStream(configDev, webpack, (error, stats) => {
29 | const time = stats.toJson().time
30 | console.log(`Built in ${time} ms.`)
31 | }))
32 | .pipe(rename('critical.js'))
33 | .pipe(gulp.dest('dev'))
34 | .pipe(browserSync.reload({ stream: true }))
35 | })
36 |
37 | gulp.task('js-dist', () => {
38 | return gulp.src(srcEntry)
39 | .pipe(webpackStream(configDist, webpack, (error, stats) => {
40 | const time = stats.toJson().time
41 | console.log(`Built in ${time} ms.`)
42 | }))
43 | .pipe(rename('bundle.js'))
44 | .pipe(gulp.dest('dist'))
45 | })
46 |
47 | gulp.task('js-dist-critical', () => {
48 | return gulp.src(srcCritical)
49 | .pipe(webpackStream(configDist, webpack, (error, stats) => {
50 | const time = stats.toJson().time
51 | console.log(`Built in ${time} ms.`)
52 | }))
53 | .pipe(rename('critical.js'))
54 | .pipe(gulp.dest('.tmp'))
55 | })
56 |
57 | gulp.task('js-boilerplate', () => {
58 | return gulp.src(srcCritical)
59 | .pipe(webpackStream(configDist, webpack, (error, stats) => {
60 | const time = stats.toJson().time
61 | console.log(`Built in ${time} ms.`)
62 | }))
63 | .pipe(rename('critical.js'))
64 | .pipe(gulp.dest('boilerplate'))
65 | })
66 |
67 |
68 | gulp.task('js-style-guide', () => {
69 | return gulp.src(srcCritical)
70 | .pipe(webpackStream(configDist, webpack, (error, stats) => {
71 | const time = stats.toJson().time
72 | console.log(`Built in ${time} ms.`)
73 | }))
74 | .pipe(rename('critical.js'))
75 | .pipe(gulp.dest('docs'))
76 | })
77 |
--------------------------------------------------------------------------------
/gulp-tasks/smoosh.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const smoosher = require('gulp-smoosher')
3 |
4 | // smoosh all the files! (insert code for references/links to resources)
5 | gulp.task('smoosh-dist', () => {
6 | return gulp.src('.tmp/*.html')
7 | .pipe(smoosher())
8 | .pipe(gulp.dest('dist'))
9 | })
10 |
--------------------------------------------------------------------------------
/gulp-tasks/style-guide.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const runSequence = require('run-sequence')
3 |
4 | // run all dist tasks to deploy
5 | gulp.task('style-guide', (cb) => {
6 | runSequence(
7 | 'clean-style-guide',
8 | 'css-style-guide',
9 | 'js-style-guide',
10 | 'html-style-guide',
11 | 'assets-style-guide',
12 | cb
13 | )
14 | })
15 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | process.env.PROJECT_ROOT = __dirname
2 |
3 | require ('babel-register')
4 |
5 | const requireDir = require('require-dir')
6 |
7 | requireDir('./gulp-tasks', { recurse: true })
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "starter",
3 | "version": "2.0.0",
4 | "description": "Starter template for Pudding stories",
5 | "author": "Russell Goldenberg",
6 | "license": "MIT",
7 | "engines": {
8 | "node": ">=8.0.0"
9 | },
10 | "dependencies": {
11 | "archieml": "^0.4.2",
12 | "babel-core": "^6.26.3",
13 | "babel-loader": "^7.1.4",
14 | "babel-plugin-transform-object-rest-spread": "^6.26.0",
15 | "babel-preset-env": "^1.7.0",
16 | "babel-preset-es2015": "^6.24.1",
17 | "babel-preset-stage-1": "^6.24.1",
18 | "babel-register": "^6.26.0",
19 | "browser-sync": "^2.24.4",
20 | "del": "^3.0.0",
21 | "enter-view": "1.0.0",
22 | "eslint": "^4.19.1",
23 | "eslint-config-airbnb-base": "^12.1.0",
24 | "eslint-config-prettier": "^2.9.0",
25 | "eslint-plugin-import": "^2.12.0",
26 | "eslint-plugin-prettier": "^2.6.0",
27 | "fontfaceobserver": "^2.0.13",
28 | "gulp": "^3.9.1",
29 | "gulp-autoprefixer": "^5.0.0",
30 | "gulp-clean-css": "^3.9.4",
31 | "gulp-combine-mq": "^0.4.0",
32 | "gulp-file-include": "^2.0.1",
33 | "gulp-hb": "^7.0.1",
34 | "gulp-htmlmin": "^4.0.0",
35 | "gulp-notify": "^3.2.0",
36 | "gulp-plumber": "^1.2.0",
37 | "gulp-rename": "^1.2.3",
38 | "gulp-replace": "^1.0.0",
39 | "gulp-smoosher": "^0.0.9",
40 | "gulp-sourcemaps": "^2.6.4",
41 | "gulp-stylus": "^2.7.0",
42 | "gulp-util": "^3.0.7",
43 | "lodash.debounce": "^4.0.8",
44 | "nouislider": "^11.1.0",
45 | "prettier": "^1.13.4",
46 | "promise-polyfill": "^8.0.0",
47 | "request": "^2.87.0",
48 | "require-dir": "^1.0.0",
49 | "run-sequence": "^2.2.0",
50 | "source-map": "^0.7.3",
51 | "stickyfilljs": "2.0.5",
52 | "superagent": "^3.8.3",
53 | "uglifyjs-webpack-plugin": "1.2.5",
54 | "webpack": "^4.10.2",
55 | "webpack-stream": "^4.0.3"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/report-error.js:
--------------------------------------------------------------------------------
1 | const notify = require('gulp-notify')
2 | const gutil = require('gulp-util')
3 |
4 | module.exports = function(error) {
5 | const lineNumber = (error.lineNumber) ? 'LINE ' + error.lineNumber + ' -- ' : '';
6 |
7 | notify({
8 | title: 'Task failed [' + error.plugin + ']',
9 | message: lineNumber + 'See terminal.',
10 | sound: 'Sosumi'
11 | }).write(error);
12 |
13 | gutil.beep();
14 |
15 | let report = '';
16 | let chalk = gutil.colors.white.bgRed;
17 |
18 | report += chalk('TASK:') + ' [' + error.plugin + ']\n';
19 | report += chalk('PROB:') + ' ' + error.message + '\n';
20 |
21 | if (error.lineNumber) { report += chalk('LINE:') + ' ' + error.lineNumber + '\n'; }
22 |
23 | if (error.fileName) { report += chalk('FILE:') + ' ' + error.fileName + '\n'; }
24 |
25 | console.error(report);
26 |
27 | this.emit('end');
28 | }
29 |
--------------------------------------------------------------------------------
/src/assets/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/bg.jpg
--------------------------------------------------------------------------------
/src/assets/fonts/atlas/AtlasGrotesk-Bold-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/atlas/AtlasGrotesk-Bold-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/atlas/AtlasGrotesk-Light-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/atlas/AtlasGrotesk-Light-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/atlas/AtlasGrotesk-Medium-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/atlas/AtlasGrotesk-Medium-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/atlas/AtlasGrotesk-Regular-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/atlas/AtlasGrotesk-Regular-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/atlas/AtlasGrotesk-Thin-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/atlas/AtlasGrotesk-Thin-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/canela/Canela-Bold-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/canela/Canela-Bold-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/canela/Canela-Light-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/canela/Canela-Light-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/publico/PublicoText-Bold-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/publico/PublicoText-Bold-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/publico/PublicoText-Italic-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/publico/PublicoText-Italic-Web.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/publico/PublicoText-Roman-Web.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/fonts/publico/PublicoText-Roman-Web.woff2
--------------------------------------------------------------------------------
/src/assets/prism/code.css:
--------------------------------------------------------------------------------
1 | article {
2 | position: relative;
3 | }
4 | figure.sticky {
5 | position: -webkit-sticky;
6 | position: sticky;
7 | top: 0;
8 | }
9 |
--------------------------------------------------------------------------------
/src/assets/prism/code.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/prism/code.js:
--------------------------------------------------------------------------------
1 | enterView({
2 | selector: stepSel.nodes(),
3 | offset: 0.5,
4 | enter: el => {
5 | const index = +d3.select(el).attr('data-index');
6 | updateChart(index);
7 | },
8 | exit: el => {
9 | let index = +d3.select(el).attr('data-index');
10 | index = Math.max(0, index - 1);
11 | updateChart(index);
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/src/assets/social/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/social/.gitkeep
--------------------------------------------------------------------------------
/src/assets/social/social-facebook.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/social/social-facebook.jpg
--------------------------------------------------------------------------------
/src/assets/social/social-twitter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-pudding/blog_scrollytelling-sticky/be94dd19bdfb12e9b439ee9dc398f8077f23790e/src/assets/social/social-twitter.jpg
--------------------------------------------------------------------------------
/src/css/config.styl:
--------------------------------------------------------------------------------
1 | @require 'utils/unicode'
2 | @require 'utils/variables'
3 | @require 'utils/helpers'
4 |
5 | @require 'utils/reset'
6 | @require 'utils/presets'
7 | @require 'utils/font'
8 | @require 'utils/layout'
9 | // @require 'utils/no-ui-slider'
10 | @require 'story/*'
11 |
--------------------------------------------------------------------------------
/src/css/story/header.styl:
--------------------------------------------------------------------------------
1 | header
2 | z-index set-index('overlay')
3 | position absolute
4 | top 0
5 | left 0
6 | width 100%
7 |
8 | a.logo
9 | display block
10 | border none
11 | max-width 9rem
12 | margin 1rem auto
13 |
14 | svg
15 | fill $off-black
16 | display block
17 | width 100%
--------------------------------------------------------------------------------
/src/css/story/intro.styl:
--------------------------------------------------------------------------------
1 | .intro
2 | margin 0 auto
3 | padding 3rem 1rem 1.5rem 1rem
4 | background-color $gray
5 | background-image url('assets/bg.jpg')
6 | bacgkround-repeat no-repeat
7 | background-position center center
8 | background-size cover
9 | margin-bottom 3rem
10 | text-shadow 0 0 3px $bg
11 | .intro-inner
12 | padding 0 1rem
13 | max-width $column-width
14 | margin 3rem auto 1.5rem auto
15 | background-color rgba($bg, 0.4)
16 |
17 | &__hed
18 | padding-top 5rem
19 | font-weight bold
20 | margin 0
21 | set-type-size('xx-large', true)
22 | +mq('bp-2')
23 | set-type-size('xxx-large', true)
24 | &__byline
25 | set-type-size('small', true)
26 | &__date
27 | set-type-size('small', true)
28 |
29 | &__dek
30 | margin 0
31 | padding-top 1.5rem
32 | text-align left
33 | set-type-size('medium', true)
34 |
35 | &__info
36 | margin 0
37 | display flex
38 | justify-content space-between
--------------------------------------------------------------------------------
/src/css/story/prism.styl:
--------------------------------------------------------------------------------
1 | @css {
2 | /* http://prismjs.com/download.html?themes=prism-okaidia&languages=clike+javascript */
3 | /**
4 | * okaidia theme for JavaScript, CSS and HTML
5 | * Loosely based on Monokai textmate theme by http://www.monokai.nl/
6 | * @author ocodia
7 | */
8 |
9 | code[class*="language-"],
10 | pre[class*="language-"] {
11 | color: #f8f8f2;
12 | background: none;
13 | text-shadow: 0 1px rgba(0, 0, 0, 0.3);
14 | font-family: Menlo, Consolas, Monaco, 'Courier New', monospace;
15 | text-align: left;
16 | white-space: pre;
17 | word-spacing: normal;
18 | word-break: normal;
19 | word-wrap: normal;
20 | line-height: 1.5;
21 |
22 | -moz-tab-size: 2;
23 | -o-tab-size: 2;
24 | tab-size: 2;
25 |
26 | -webkit-hyphens: none;
27 | -moz-hyphens: none;
28 | -ms-hyphens: none;
29 | hyphens: none;
30 | }
31 |
32 | /* Code blocks */
33 | pre[class*="language-"] {
34 | padding: 1em;
35 | margin: .5em 0;
36 | overflow: auto;
37 | border-radius: 0.3em;
38 | }
39 |
40 | :not(pre) > code[class*="language-"],
41 | pre[class*="language-"] {
42 | background: #272822;
43 | }
44 |
45 | /* Inline code */
46 | :not(pre) > code[class*="language-"] {
47 | padding: .1em;
48 | border-radius: .3em;
49 | white-space: normal;
50 | }
51 |
52 | .token.comment,
53 | .token.prolog,
54 | .token.doctype,
55 | .token.cdata {
56 | color: slategray;
57 | }
58 |
59 | .token.punctuation {
60 | color: #f8f8f2;
61 | }
62 |
63 | .namespace {
64 | opacity: .7;
65 | }
66 |
67 | .token.property,
68 | .token.tag,
69 | .token.constant,
70 | .token.symbol,
71 | .token.deleted {
72 | color: #f92672;
73 | }
74 |
75 | .token.boolean,
76 | .token.number {
77 | color: #ae81ff;
78 | }
79 |
80 | .token.selector,
81 | .token.attr-name,
82 | .token.string,
83 | .token.char,
84 | .token.builtin,
85 | .token.inserted {
86 | color: #a6e22e;
87 | }
88 |
89 | .token.operator,
90 | .token.entity,
91 | .token.url,
92 | .language-css .token.string,
93 | .style .token.string,
94 | .token.variable {
95 | color: #f8f8f2;
96 | }
97 |
98 | .token.atrule,
99 | .token.attr-value,
100 | .token.function {
101 | color: #e6db74;
102 | }
103 |
104 | .token.keyword {
105 | color: #66d9ef;
106 | }
107 |
108 | .token.regex,
109 | .token.important {
110 | color: #fd971f;
111 | }
112 |
113 | .token.important,
114 | .token.bold {
115 | font-weight: bold;
116 | }
117 | .token.italic {
118 | font-style: italic;
119 | }
120 |
121 | .token.entity {
122 | cursor: help;
123 | }
124 |
125 | }
--------------------------------------------------------------------------------
/src/css/story/scrolly-overlay.styl:
--------------------------------------------------------------------------------
1 | #scrolly-overlay .scrolly
2 | max-width 60rem
3 | margin 3rem auto
4 | background-color $off-white
5 | padding 1rem
6 |
7 | article
8 | padding 0
9 | max-width 30rem
10 | margin 0 auto
11 | position relative
12 |
13 | .step
14 | min-height 67vh
15 | margin-bottom 1rem
16 | &:last-of-type
17 | margin-bottom 0
18 | &.is-active
19 | p
20 | background-color $secondary
21 | p
22 | margin 0
23 | padding 1rem
24 | text-align center
25 | font-weight 400
26 | background-color $gray-dark
27 | transition background-color 250ms ease-in-out
28 | color $off-white
29 | set-type-size(large)
30 |
31 |
32 | figure.sticky
33 | position sticky
34 | width 100%
35 | background $gray
36 | margin 0
37 | top 25vh
38 | height 50vh
39 | left 0
40 |
41 | .bar-outer
42 | position absolute
43 | top 50%
44 | left 5%
45 | transform translateY(-50%)
46 | width 90%
47 | height 4rem
48 | background-color $bg
49 |
50 | .bar-inner
51 | width 10%
52 | height 100%
53 | transition width 1s ease-in-out
54 | background-color $primary
--------------------------------------------------------------------------------
/src/css/story/scrolly-side.styl:
--------------------------------------------------------------------------------
1 | #scrolly-side .scrolly
2 | display flex
3 | max-width 60rem
4 | margin 3rem auto
5 | background-color $off-white
6 | padding 1rem
7 |
8 | & > *
9 | flex 1
10 |
11 | article
12 | padding-right 1rem
13 | max-width 30rem
14 |
15 | .step
16 | min-height 67vh
17 | margin-bottom 1rem
18 | background-color $gray-dark
19 | transition background-color 250ms ease-in-out
20 | &:last-of-type
21 | margin-bottom 0
22 | &.is-active
23 | background-color $secondary
24 | p
25 | margin 0
26 | padding 1rem
27 | text-align center
28 | font-weight 400
29 | color $off-white
30 | set-type-size(large)
31 |
32 |
33 | figure.sticky
34 | position sticky
35 | width 100%
36 | height 50vh
37 | background $gray
38 | margin 0
39 | top 25vh
40 | left 0
41 |
42 | .bar-outer
43 | position absolute
44 | top 50%
45 | left 5%
46 | transform translateY(-50%)
47 | width 90%
48 | height 4rem
49 | background-color $bg
50 |
51 | .bar-inner
52 | width 10%
53 | height 100%
54 | transition width 1s ease-in-out
55 | background-color $primary
--------------------------------------------------------------------------------
/src/css/story/story.styl:
--------------------------------------------------------------------------------
1 | /* CUSTOM STORY STYLE */
2 | section
3 | margin 1.5rem auto
4 |
5 | .prose
6 | code
7 | background-color $secondary
8 | color $bg
9 | font-family $mono
10 | padding 0.25em 0.5em
11 | font-size 0.8em
12 | font-weight 600
13 | border-radius 2px
14 |
15 | #content
16 | padding-bottom 3rem
17 |
18 | pre
19 | display block
20 | margin 1.5rem auto
21 | max-width 38rem
22 | width 90%
23 | set-type-size(small)
24 |
--------------------------------------------------------------------------------
/src/css/utils/font.styl:
--------------------------------------------------------------------------------
1 | // -------------------
2 | // font loading
3 | // -------------------
4 |
5 | fontify($publico, $publico-hash, $serif-fb)
6 | fontify($atlas, $atlas-hash, $sans-fb)
7 |
8 | set-type-class(all, true)
9 |
--------------------------------------------------------------------------------
/src/css/utils/layout.styl:
--------------------------------------------------------------------------------
1 | // -------------------
2 | // Layouts
3 | // -------------------
4 |
5 | body
6 | font-feature-settings 'kern' 1, 'onum' 0, 'liga' 0, 'tnum' 1
7 | -webkit-font-smoothing antialiased
8 | -moz-osx-font-smoothing grayscale
9 | -webkit-tap-highlight-color rgba(0,0,0,0)
10 | background-color $bg
11 | color $fg
12 | set-type-size(root, false)
13 | +mq('bp-3')
14 | set-type-size(medium, false)
15 |
16 | h1
17 | set-type-size(xx-large, true)
18 | margin-top 1.5rem
19 | h2
20 | set-type-size(x-large, true)
21 | margin-top 1.5rem
22 | h3
23 | set-type-size(large, true)
24 | margin-top 3rem
25 | h4
26 | set-type-size(medium, true)
27 | margin-top 1.5rem
28 | h5
29 | set-type-size(root, true)
30 | margin-top 1.5rem
31 | h6
32 | set-type-size(small, true)
33 | margin-top 1.5rem
34 | p
35 | margin 1.5rem 0
36 | set-type-size(root, true)
37 | +mq('bp-3')
38 | set-type-size(medium, true)
39 |
40 | a
41 | text-decoration none
42 | border-bottom 1px solid $off-black
43 | color $off-black
44 | &:visited, &:hover
45 | color $off-black
46 |
47 | strong, b
48 | font-weight bold
49 |
50 | em, i
51 | font-style italic
52 |
53 | ul
54 | list-style-type none
55 |
56 | li
57 | set-type-size(root, false)
58 | +mq('bp-3')
59 | set-type-size(medium, false)
60 |
61 | img, video
62 | display block
63 | width 100%
64 |
65 | button
66 | cursor pointer
67 | border none
68 | outline none
69 | margin 0
70 | padding 0
71 | font-size 1rem
72 | set-type-size(root, false)
73 | +mq('bp-3')
74 | set-type-size(medium, false)
75 |
76 | sub, sup
77 | font-size 0.75rem
78 | line-height 0
79 | position relative
80 | vertical-align baseline
81 |
82 | sup
83 | top -0.5em
84 |
85 | sub
86 | bottom -0.25em
87 |
--------------------------------------------------------------------------------
/src/css/utils/presets.styl:
--------------------------------------------------------------------------------
1 | // Various hides
2 | .hide-accessible
3 | hidden(accessible)
4 | .hide-invisible
5 | hidden(invisible)
6 | .hide-display
7 | hidden()
8 |
9 | // Skip to main for accessibility
10 | .skip-to-main
11 | border none
12 | hidden(accessible)
13 | &:focus
14 | width auto
15 | height auto
16 | background-color $off-white
17 | padding 0.5em
18 | z-index 1
19 |
20 | .prose
21 | max-width $column-width
22 | margin 0 auto
23 | padding 0 1rem
24 | &__hed
25 | font-weight bold
26 |
27 | .media-overlay
28 | position absolute
29 | top 0
30 | left 0
31 | width 100%
32 | height 100%
33 | background url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkRDMDBGQ0Y5NEI4NjExRTM5RTg2QTY1RTUyQjIxNEQyIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkRDMDBGQ0ZBNEI4NjExRTM5RTg2QTY1RTUyQjIxNEQyIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6REMwMEZDRjc0Qjg2MTFFMzlFODZBNjVFNTJCMjE0RDIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6REMwMEZDRjg0Qjg2MTFFMzlFODZBNjVFNTJCMjE0RDIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6C0EmkAAAAGElEQVR42mJiYGD4DwQMTECCEchhAAgwAEcGBv9dngKPAAAAAElFTkSuQmCC')
34 |
35 | .graphic
36 | &__hed
37 | font-weight 500
38 | &__dek
39 | margin 0
40 | margin-bottom 1.5rem
41 | &__chart
42 | width 100%
43 | &__key
44 | display flex
45 | flex-wrap wrap
46 | margin-bottom 0.5rem
47 | justify-content flex-end
48 | li
49 | padding 0
50 | margin-left 0.75em
51 | letter-spacing 0.05em
52 | text-transform uppercase
53 | font-weight bold
54 | line-height 1
55 | &:before
56 | content ''
57 | display inline-block
58 | width 0.8em
59 | height 0.8em
60 | background-color $off-black
61 | margin-right 0.25em
--------------------------------------------------------------------------------
/src/css/utils/reset.styl:
--------------------------------------------------------------------------------
1 | // -------------------
2 | // Reset
3 | // -------------------
4 | *
5 | -moz-box-sizing border-box
6 | box-sizing border-box
7 |
8 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video
9 | margin 0
10 | padding 0
11 | border 0
12 | font-size 100%
13 | font inherit
14 | vertical-align baseline
15 |
16 | article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section
17 | display block
18 |
19 | a img
20 | border none
21 |
22 | blockquote
23 | quotes none
24 |
25 | blockquote:before, blockquote:after
26 | content ''
27 | content none
28 |
29 | table
30 | border-collapse collapse
31 | border-spacing 0
32 |
33 | caption, th, td
34 | text-align left
35 | font-weight normal
36 | vertical-align middle
--------------------------------------------------------------------------------
/src/css/utils/unicode.styl:
--------------------------------------------------------------------------------
1 | // -------------------
2 | // Unicode characters
3 | // -------------------
4 |
5 | //space
6 | $u-space = '\0020'
7 | //non-breaking space
8 | $u-nbsp = '\00A0'
9 |
10 | // quotation mark
11 | $u-quote = '\0022'
12 | // left single smart quote
13 | $u-lsquo = '\2018'
14 | // right single smart quote
15 | $u-rsquo = '\2019'
16 | // left double smart quote
17 | $u-ldquo = '\201C'
18 | // right double smart quote
19 | $u-rdquo = '\201D'
20 | // left single angle quote (guillemet)
21 | $u-lsaquo = '\2039'
22 | // right single angle quote (guillemet)
23 | $u-lsaquo = '\203A'
24 | // left double angle quote (guillemet)
25 | $u-lsaquo = '\00ab'
26 | // right double angle quote (guillemet)
27 | $u-lsaquo = '\00bb'
28 |
29 | // em dash (mutton)
30 | $u-mdash = '\2014'
31 | // en dash (nut)
32 | $u-ndash = '\2013'
33 | // hyphen
34 | $u-hyphen = '\2010'
35 |
36 | // ampersand
37 | $u-amp = '\0026'
38 | // greater than
39 | $u-greater = '\003E'
40 | // less than
41 | $u-less = '\003C'
42 | // multiply/times
43 | $u-multiply = '\003C'
44 | // big multiply/times
45 | $u-bigmultiply = '\2715'
46 | // plus
47 | $u-plus = '\2795'
48 | // minus
49 | $u-plus = '\2796'
50 | // checkmark
51 | $u-check = '\2714'
52 |
53 | // left arrow
54 | $u-larrow = '\2190'
55 | // right arrow
56 | $u-rarrow = '\2192'
57 | // up arrow
58 | $u-rarrow = '\2191'
59 | // down arrow
60 | $u-rarrow = '\2193'
61 | // heavy right arrow
62 | $u-heavyarrow = '\279C'
63 | // right swoop arrow
64 | $u-swooparrow = '\2935'
65 | // refresh arrow
66 | $u-refresh = '\21BA'
67 |
68 | // right triangle
69 | $u-rtri = '\25B8'
70 | // down triangle
71 | $u-dtri = '\25BE'
--------------------------------------------------------------------------------
/src/css/utils/variables.styl:
--------------------------------------------------------------------------------
1 | // -------------------
2 | // Breakpoints
3 | // -------------------
4 | $mq_vars = {
5 | bp-2: '(min-width: 20em)' // 320px
6 | bp-3: '(min-width: 30em)' // 480px
7 | bp-4: '(min-width: 40em)' // 640px
8 | bp-5: '(min-width: 50em)' // 800px
9 | bp-6: '(min-width: 60em)' // 960px
10 | }
11 |
12 | // -------------------
13 | // Typefaces
14 | // -------------------
15 | $canela = 'Canela Web'
16 | $canela-hash = 'canela'
17 | $publico = 'Publico Text Web'
18 | $publico-hash = 'publico'
19 | $atlas = 'Atlas Grotesk Web'
20 | $atlas-hash = 'atlas'
21 |
22 | $sans-fb = Helvetica, Arial, sans-serif
23 | $sans = $atlas, $sans-fb
24 | $serif-fb = Georgia, Times, serif
25 | $serif = $publico, $serif-fb
26 | $serif-hed-fb = 'Times New Roman', serif
27 | $mono = Menlo, Consolas, Monaco, 'Courier New', monospace
28 |
29 | // z-index
30 | $z-index = {
31 | bottom: -100
32 | middle: 0
33 | top: 100
34 | overlay: 1000
35 | }
36 |
37 | // Color
38 | $off-black = #282828
39 | $gray-dark = #5b5b5b
40 | $gray = #969696
41 | $gray-light = #c9c9c9
42 | $off-white = #f4f4f4
43 |
44 | $bg = #fff
45 | $fg = $off-black
46 | $primary= goldenrod
47 | $secondary = teal
48 |
49 | $column-width = 40rem
50 |
51 | $type-size = {
52 | xxx-small: {
53 | size: 10px,
54 | line-height: 1.5,
55 | }
56 | xx-small: {
57 | size: 11px,
58 | line-height: 1.5,
59 | }
60 | x-small: {
61 | size: 12px,
62 | line-height: 1.5
63 | }
64 | small: {
65 | size: 14px,
66 | line-height: 1.5
67 | }
68 | root: {
69 | size: 16px,
70 | line-height: 1.7
71 | }
72 | medium: {
73 | size: 17px,
74 | line-height: 1.7
75 | }
76 | large: {
77 | size: 24px,
78 | line-height: 1.5
79 | }
80 | x-large: {
81 | size: 32px,
82 | line-height: 1.5
83 | }
84 | xx-large: {
85 | size: 40px,
86 | line-height: 1.2
87 | }
88 | xxx-large: {
89 | size: 48px,
90 | line-height: 1.2
91 | }
92 | xxxx-large: {
93 | size: 64px,
94 | line-height: 1.2
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/html/helpers/greaterThan.js:
--------------------------------------------------------------------------------
1 | module.exports = function(a, b, opts) {
2 | if (a > b) return opts.fn(this)
3 | else return opts.inverse(this)
4 | }
--------------------------------------------------------------------------------
/src/html/helpers/ifEquals.js:
--------------------------------------------------------------------------------
1 | module.exports = function(a, b, opts) {
2 | if (a === b) return opts.fn(this)
3 | else return opts.inverse(this)
4 | }
--------------------------------------------------------------------------------
/src/html/helpers/lessThan.js:
--------------------------------------------------------------------------------
1 | module.exports = function(a, b, opts) {
2 | if (a < b) return opts.fn(this)
3 | else return opts.inverse(this)
4 | }
--------------------------------------------------------------------------------
/src/html/helpers/slugify.js:
--------------------------------------------------------------------------------
1 | // Changes a string to lowercase and replaces spaces with hyphens
2 | module.exports = function(text) {
3 | return String(text).replace(/\s+/g, '-').toLowerCase()
4 | }
5 |
--------------------------------------------------------------------------------
/src/html/index.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{> base/meta}}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | {{> base/font}}
15 |
16 |
17 |
18 |
19 |
20 | {{> base/analytics }}
21 |
22 |
23 |
24 |
25 |
26 | {{> base/header }}
27 |
28 |
29 |
30 | {{> story/intro }}
31 |
32 | {{> story/content }}
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/html/partials/base/analytics.hbs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/html/partials/base/font.hbs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/html/partials/base/header.hbs:
--------------------------------------------------------------------------------
1 | Skip to main content
2 |
--------------------------------------------------------------------------------
/src/html/partials/base/meta.hbs:
--------------------------------------------------------------------------------
1 | {{! See variable definitions in template-data/meta.json }}
2 | {{copy.hed}}
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/html/partials/story/content.hbs:
--------------------------------------------------------------------------------
1 | {{#each copy.sections}}
2 |
3 | {{#ifEquals id 'scrolly-side'}} {{> story/scrolly-side}} {{/ifEquals}}
4 | {{#ifEquals id 'scrolly-overlay'}} {{> story/scrolly-overlay}} {{/ifEquals}}
5 |
6 | {{#if hed}}
7 |
8 | {{{hed}}}
9 |
10 | {{/if}}
11 | {{#each text}}
12 |
{{{value}}}
13 | {{/each}}
14 |
15 | {{#ifEquals id 'code-html'}} {{/ifEquals}}
16 | {{#ifEquals id 'code-css'}} {{/ifEquals}}
17 | {{#ifEquals id 'code-js'}} {{/ifEquals}}
18 |
19 | {{/each}}
20 |
--------------------------------------------------------------------------------
/src/html/partials/story/intro.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{copy.hed}}
4 |
{{copy.dek}}
5 |
16 |
17 |
--------------------------------------------------------------------------------
/src/html/partials/story/scrolly-overlay.hbs:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/src/html/partials/story/scrolly-side.hbs:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/src/js/critical.js:
--------------------------------------------------------------------------------
1 | import Promise from 'promise-polyfill';
2 | import './polyfills/startsWith';
3 | import './polyfills/endsWith';
4 | import './polyfills/findIndex';
5 | import './polyfills/find';
6 | import './polyfills/includes';
7 | import { loadFontGroup } from './utils/load-font';
8 |
9 | const canela = [
10 | { family: 'Canela Web', weight: 300 },
11 | { family: 'Canela Web', weight: 700 }
12 | ];
13 |
14 | const publico = [
15 | { family: 'Publico Text Web', weight: 400 },
16 | { family: 'Publico Text Web', weight: 700 }
17 | ];
18 |
19 | const atlas = [
20 | { family: 'Atlas Grotesk Web', weight: 400 },
21 | { family: 'Atlas Grotesk Web', weight: 500 },
22 | { family: 'Atlas Grotesk Web', weight: 600 }
23 | ];
24 |
25 | // polyfill promise
26 | if (!window.Promise) window.Promise = Promise;
27 |
28 | // load fonts
29 | // loadFontGroup(canela);
30 | loadFontGroup(publico);
31 | loadFontGroup(atlas);
32 |
--------------------------------------------------------------------------------
/src/js/entry.js:
--------------------------------------------------------------------------------
1 | // D3 is included by globally by default
2 | import graphicSide from './graphic-side';
3 | import graphicOverlay from './graphic-overlay';
4 |
5 | function init() {
6 | // kick off graphic code
7 | graphicSide.init();
8 | graphicOverlay.init();
9 | }
10 |
11 | init();
12 |
--------------------------------------------------------------------------------
/src/js/graphic-overlay.js:
--------------------------------------------------------------------------------
1 | // D3 is included by globally by default
2 | import enterView from 'enter-view';
3 | import Stickyfill from 'stickyfilljs';
4 |
5 | const container = d3.select('#scrolly-overlay');
6 | const stepSel = container.selectAll('.step');
7 |
8 | function updateChart(index) {
9 | const sel = container.select(`[data-index='${index}']`);
10 | const width = sel.attr('data-width');
11 | stepSel.classed('is-active', (d, i) => i === index);
12 | container.select('.bar-inner').style('width', width);
13 | }
14 |
15 | function init() {
16 | Stickyfill.add(d3.select('.sticky').node());
17 |
18 | enterView({
19 | selector: stepSel.nodes(),
20 | offset: 0.5,
21 | enter: el => {
22 | const index = +d3.select(el).attr('data-index');
23 | updateChart(index);
24 | },
25 | exit: el => {
26 | let index = +d3.select(el).attr('data-index');
27 | index = Math.max(0, index - 1);
28 | updateChart(index);
29 | }
30 | });
31 | }
32 |
33 | export default { init };
34 |
--------------------------------------------------------------------------------
/src/js/graphic-side.js:
--------------------------------------------------------------------------------
1 | // D3 is included by globally by default
2 | import enterView from 'enter-view';
3 | import Stickyfill from 'stickyfilljs';
4 |
5 | const container = d3.select('#scrolly-side');
6 | const stepSel = container.selectAll('.step');
7 |
8 | function updateChart(index) {
9 | const sel = container.select(`[data-index='${index}']`);
10 | const width = sel.attr('data-width');
11 | stepSel.classed('is-active', (d, i) => i === index);
12 | container.select('.bar-inner').style('width', width);
13 | }
14 |
15 | function init() {
16 | Stickyfill.add(d3.select('.sticky').node());
17 |
18 | enterView({
19 | selector: stepSel.nodes(),
20 | offset: 0.5,
21 | enter: el => {
22 | const index = +d3.select(el).attr('data-index');
23 | updateChart(index);
24 | },
25 | exit: el => {
26 | let index = +d3.select(el).attr('data-index');
27 | index = Math.max(0, index - 1);
28 | updateChart(index);
29 | }
30 | });
31 | }
32 |
33 | export default { init };
34 |
--------------------------------------------------------------------------------
/src/js/polyfills/endsWith.js:
--------------------------------------------------------------------------------
1 | if (!String.prototype.endsWith) {
2 | String.prototype.endsWith = function(searchString, position) {
3 | var subjectString = this.toString();
4 | if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
5 | position = subjectString.length;
6 | }
7 | position -= searchString.length;
8 | var lastIndex = subjectString.lastIndexOf(searchString, position);
9 | return lastIndex !== -1 && lastIndex === position;
10 | };
11 | }
--------------------------------------------------------------------------------
/src/js/polyfills/find.js:
--------------------------------------------------------------------------------
1 | if (!Array.prototype.find) {
2 | Object.defineProperty(Array.prototype, 'find', {
3 | value: function(predicate) {
4 | 'use strict';
5 | if (this == null) {
6 | throw new TypeError('Array.prototype.find called on null or undefined');
7 | }
8 | if (typeof predicate !== 'function') {
9 | throw new TypeError('predicate must be a function');
10 | }
11 | var list = Object(this);
12 | var length = list.length >>> 0;
13 | var thisArg = arguments[1];
14 | var value;
15 |
16 | for (var i = 0; i < length; i++) {
17 | value = list[i];
18 | if (predicate.call(thisArg, value, i, list)) {
19 | return value;
20 | }
21 | }
22 | return undefined;
23 | }
24 | });
25 | }
--------------------------------------------------------------------------------
/src/js/polyfills/findIndex.js:
--------------------------------------------------------------------------------
1 | if (!Array.prototype.findIndex) {
2 | Object.defineProperty(Array.prototype, 'findIndex', {
3 | value: function(predicate) {
4 | 'use strict';
5 | if (this == null) {
6 | throw new TypeError('Array.prototype.findIndex called on null or undefined');
7 | }
8 | if (typeof predicate !== 'function') {
9 | throw new TypeError('predicate must be a function');
10 | }
11 | var list = Object(this);
12 | var length = list.length >>> 0;
13 | var thisArg = arguments[1];
14 | var value;
15 |
16 | for (var i = 0; i < length; i++) {
17 | value = list[i];
18 | if (predicate.call(thisArg, value, i, list)) {
19 | return i;
20 | }
21 | }
22 | return -1;
23 | },
24 | enumerable: false,
25 | configurable: false,
26 | writable: false
27 | });
28 | }
--------------------------------------------------------------------------------
/src/js/polyfills/includes.js:
--------------------------------------------------------------------------------
1 | // https://tc39.github.io/ecma262/#sec-array.prototype.includes
2 | if (!Array.prototype.includes) {
3 | Object.defineProperty(Array.prototype, 'includes', {
4 | value: function(searchElement, fromIndex) {
5 |
6 | // 1. Let O be ? ToObject(this value).
7 | if (this == null) {
8 | throw new TypeError('"this" is null or not defined');
9 | }
10 |
11 | var o = Object(this);
12 |
13 | // 2. Let len be ? ToLength(? Get(O, "length")).
14 | var len = o.length >>> 0;
15 |
16 | // 3. If len is 0, return false.
17 | if (len === 0) {
18 | return false;
19 | }
20 |
21 | // 4. Let n be ? ToInteger(fromIndex).
22 | // (If fromIndex is undefined, this step produces the value 0.)
23 | var n = fromIndex | 0;
24 |
25 | // 5. If n ≥ 0, then
26 | // a. Let k be n.
27 | // 6. Else n < 0,
28 | // a. Let k be len + n.
29 | // b. If k < 0, let k be 0.
30 | var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
31 |
32 | // 7. Repeat, while k < len
33 | while (k < len) {
34 | // a. Let elementK be the result of ? Get(O, ! ToString(k)).
35 | // b. If SameValueZero(searchElement, elementK) is true, return true.
36 | // c. Increase k by 1.
37 | // NOTE: === provides the correct "SameValueZero" comparison needed here.
38 | if (o[k] === searchElement) {
39 | return true;
40 | }
41 | k++;
42 | }
43 |
44 | // 8. Return false
45 | return false;
46 | }
47 | });
48 | }
--------------------------------------------------------------------------------
/src/js/polyfills/startsWith.js:
--------------------------------------------------------------------------------
1 | if (!String.prototype.startsWith) {
2 | String.prototype.startsWith = function(searchString, position) {
3 | return this.substr(position || 0, searchString.length) === searchString;
4 | };
5 | }
6 |
--------------------------------------------------------------------------------
/src/js/pudding-chart/base.js:
--------------------------------------------------------------------------------
1 | /*
2 | USAGE (example: line chart)
3 | 1. c+p this template to a new file (line.js)
4 | 2. change puddingChartName to puddingChartLine
5 | 3. in graphic file: import './pudding-chart/line'
6 | 4a. const charts = d3.selectAll('.thing').data(data).puddingChartLine();
7 | 4b. const chart = d3.select('.thing').datum(datum).puddingChartLine();
8 | */
9 |
10 | d3.selection.prototype.puddingChartName = function init(options) {
11 | function createChart(el) {
12 | const $sel = d3.select(el);
13 | let data = $sel.datum();
14 | // dimension stuff
15 | let width = 0;
16 | let height = 0;
17 | const marginTop = 0;
18 | const marginBottom = 0;
19 | const marginLeft = 0;
20 | const marginRight = 0;
21 |
22 | // scales
23 | const scaleX = null;
24 | const scaleY = null;
25 |
26 | // dom elements
27 | let $svg = null;
28 | let $axis = null;
29 | let $vis = null;
30 |
31 | // helper functions
32 |
33 | const Chart = {
34 | // called once at start
35 | init() {
36 | $svg = $sel.append('svg.pudding-chart');
37 | const $g = $svg.append('g');
38 |
39 | // offset chart for margins
40 | $g.at('transform', `translate(${marginLeft}, ${marginTop})`);
41 |
42 | // create axis
43 | $axis = $svg.append('g.g-axis');
44 |
45 | // setup viz group
46 | $vis = $g.append('g.g-vis');
47 |
48 | Chart.resize();
49 | Chart.render();
50 | },
51 | // on resize, update new dimensions
52 | resize() {
53 | // defaults to grabbing dimensions from container element
54 | width = $sel.node().offsetWidth - marginLeft - marginRight;
55 | height = $sel.node().offsetHeight - marginTop - marginBottom;
56 | $svg.at({
57 | width: width + marginLeft + marginRight,
58 | height: height + marginTop + marginBottom
59 | });
60 | return Chart;
61 | },
62 | // update scales and render chart
63 | render() {
64 | return Chart;
65 | },
66 | // get / set data
67 | data(val) {
68 | if (!arguments.length) return data;
69 | data = val;
70 | $sel.datum(data);
71 | Chart.render();
72 | return Chart;
73 | }
74 | };
75 | Chart.init();
76 |
77 | return Chart;
78 | }
79 |
80 | // create charts
81 | const charts = this.nodes().map(createChart);
82 | return charts.length > 1 ? charts : charts.pop();
83 | };
84 |
--------------------------------------------------------------------------------
/src/js/utils/dom.js:
--------------------------------------------------------------------------------
1 | // DOM helper functions
2 |
3 | // public
4 | function select(selector) {
5 | return document.querySelector(selector);
6 | }
7 |
8 | function selectAll(selector, parent = document) {
9 | return [...parent.querySelectorAll(selector)];
10 | }
11 |
12 | function find(el, selector) {
13 | return [...el.querySelectorAll(selector)];
14 | }
15 |
16 | function removeClass(el, className) {
17 | if (el.classList) el.classList.remove(className);
18 | else
19 | el.className = el.className.replace(
20 | new RegExp(`(^|\\b)${className.split(' ').join('|')}(\\b|$)`, 'gi'),
21 | ' ',
22 | );
23 | }
24 |
25 | function addClass(el, className) {
26 | if (el.classList) el.classList.add(className);
27 | else el.className = `${el.className} ${className}`;
28 | }
29 |
30 | function hasClass(el, className) {
31 | if (el.classList) return el.classList.contains(className);
32 | return new RegExp(`(^| )${className}( |$)`, 'gi').test(el.className);
33 | }
34 |
35 | function jumpTo(el, offset) {
36 | offset = offset || 0;
37 | const top = el.getBoundingClientRect().top + offset;
38 | const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
39 | const destY = scrollTop + top;
40 | window.scrollTo(0, destY);
41 | }
42 |
43 | export { select, selectAll, find, removeClass, addClass, hasClass, jumpTo };
44 |
--------------------------------------------------------------------------------
/src/js/utils/is-mobile.js:
--------------------------------------------------------------------------------
1 | // device sniffing for mobile
2 |
3 | const isMobile = {
4 | android: () => navigator.userAgent.match(/Android/i),
5 |
6 | blackberry: () => navigator.userAgent.match(/BlackBerry/i),
7 |
8 | ios: () => navigator.userAgent.match(/iPhone|iPad|iPod/i),
9 |
10 | opera: () => navigator.userAgent.match(/Opera Mini/i),
11 |
12 | windows: () => navigator.userAgent.match(/IEMobile/i),
13 |
14 | any: () => (
15 | isMobile.android() ||
16 | isMobile.blackberry() ||
17 | isMobile.ios() ||
18 | isMobile.opera() ||
19 | isMobile.windows()
20 | ),
21 | }
22 |
23 | export default isMobile
24 |
--------------------------------------------------------------------------------
/src/js/utils/load-css.js:
--------------------------------------------------------------------------------
1 | /*! loadCSS: load a CSS file asynchronously. [c]2016 @scottjehl, Filament Group, Inc. Licensed MIT */
2 | export default function( href, before, media ){
3 | // Arguments explained:
4 | // `href` [REQUIRED] is the URL for your CSS file.
5 | // `before` [OPTIONAL] is the element the script should use as a reference for injecting our stylesheet before
6 | // By default, loadCSS attempts to inject the link after the last stylesheet or script in the DOM. However, you might desire a more specific location in your document.
7 | // `media` [OPTIONAL] is the media type or query of the stylesheet. By default it will be 'all'
8 | var doc = document;
9 | var ss = doc.createElement( "link" );
10 | var ref;
11 | if( before ){
12 | ref = before;
13 | }
14 | else {
15 | var refs = ( doc.body || doc.getElementsByTagName( "head" )[ 0 ] ).childNodes;
16 | ref = refs[ refs.length - 1];
17 | }
18 |
19 | var sheets = doc.styleSheets;
20 | ss.rel = "stylesheet";
21 | ss.href = href;
22 | // temporarily set media to something inapplicable to ensure it'll fetch without blocking render
23 | ss.media = "only x";
24 |
25 | // wait until body is defined before injecting link. This ensures a non-blocking load in IE11.
26 | function ready( cb ){
27 | if( doc.body ){
28 | return cb();
29 | }
30 | setTimeout(function(){
31 | ready( cb );
32 | });
33 | }
34 | // Inject link
35 | // Note: the ternary preserves the existing behavior of "before" argument, but we could choose to change the argument to "after" in a later release and standardize on ref.nextSibling for all refs
36 | // Note: `insertBefore` is used instead of `appendChild`, for safety re: http://www.paulirish.com/2011/surefire-dom-element-insertion/
37 | ready( function(){
38 | ref.parentNode.insertBefore( ss, ( before ? ref : ref.nextSibling ) );
39 | });
40 | // A method (exposed on return object for external use) that mimics onload by polling document.styleSheets until it includes the new sheet.
41 | var onloadcssdefined = function( cb ){
42 | var resolvedHref = ss.href;
43 | var i = sheets.length;
44 | while( i-- ){
45 | if( sheets[ i ].href === resolvedHref ){
46 | return cb();
47 | }
48 | }
49 | setTimeout(function() {
50 | onloadcssdefined( cb );
51 | });
52 | };
53 |
54 | function loadCB(){
55 | if( ss.addEventListener ){
56 | ss.removeEventListener( "load", loadCB );
57 | }
58 | ss.media = media || "all";
59 | }
60 |
61 | // once loaded, set link's media back to `all` so that the stylesheet applies once it loads
62 | if( ss.addEventListener ){
63 | ss.addEventListener( "load", loadCB);
64 | }
65 | ss.onloadcssdefined = onloadcssdefined;
66 | onloadcssdefined( loadCB );
67 | return ss;
68 | }
--------------------------------------------------------------------------------
/src/js/utils/load-font.js:
--------------------------------------------------------------------------------
1 | import FontFaceObserver from 'fontfaceobserver'
2 | import { addClass } from './dom'
3 |
4 | const htmlEl = document.documentElement
5 | const TIMEOUT = 5000
6 |
7 | function addFont(family) {
8 | const first = family.split(' ')[0]
9 | const name = first.toLowerCase().replace(/ /g, '-')
10 | const className = `loaded-${name}`
11 | addClass(htmlEl, className)
12 | }
13 |
14 | function handleError(err) {
15 | console.error(err)
16 | }
17 |
18 | function loadFont(font) {
19 | const { family, weight = 'normal' } = font
20 | const fontObserver = new FontFaceObserver(family, { weight })
21 | fontObserver
22 | .load(null, TIMEOUT)
23 | .then(() => addFont(font))
24 | .catch(handleError)
25 | }
26 |
27 | function loadFontGroup(group) {
28 | const promises = group.map(font =>
29 | new Promise((resolve, reject) => {
30 | const { family, weight, style = 'normal' } = font
31 |
32 | const fontObserver = new FontFaceObserver(family, { weight, style })
33 | return fontObserver
34 | .load(null, TIMEOUT)
35 | .then(() => resolve(family))
36 | .catch(err => reject(err))
37 | })
38 | )
39 |
40 | Promise.all(promises)
41 | .then(result => addFont(result[0]))
42 | .catch(handleError)
43 | }
44 |
45 | export { loadFont, loadFontGroup }
46 |
--------------------------------------------------------------------------------
/src/js/utils/load-image.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Load an image and callback when it is loaded
3 | * @param {string} url path to image
4 | * @param {function} cb callback function
5 | */
6 |
7 | function loadImage(url, cb) {
8 | const img = new Image();
9 | img.onload = () => cb(null, img);
10 | img.onerror = () => cb(`error loading image: ${url}`);
11 | img.src = url;
12 | }
13 |
14 | export default loadImage;
15 |
--------------------------------------------------------------------------------
/src/js/utils/locate-test.js:
--------------------------------------------------------------------------------
1 | export default {
2 | ip: '72.228.10.129',
3 | hostname: 'cpe-72-228-10-129.nycap.res.rr.com',
4 | type: 'ipv4',
5 | continent_code: 'NA',
6 | continent_name: 'North America',
7 | country_code: 'US',
8 | country_name: 'United States',
9 | region_code: 'MA',
10 | region_name: 'Massachusetts',
11 | city: 'Great Barrington',
12 | zip: '01230',
13 | latitude: 42.1617,
14 | longitude: -73.3277,
15 | location: {
16 | geoname_id: 4938157,
17 | capital: 'Washington D.C.',
18 | languages: [
19 | {
20 | code: 'en',
21 | name: 'English',
22 | native: 'English'
23 | }
24 | ],
25 | country_flag: 'http://assets.ipstack.com/flags/us.svg',
26 | country_flag_emoji: '🇺🇸',
27 | country_flag_emoji_unicode: 'U+1F1FA U+1F1F8',
28 | calling_code: '1',
29 | is_eu: false
30 | },
31 | time_zone: {
32 | id: 'America/New_York',
33 | current_time: '2018-04-17T15:29:13-04:00',
34 | gmt_offset: -14400,
35 | code: 'EDT',
36 | is_daylight_saving: true
37 | },
38 | currency: {
39 | code: 'USD',
40 | name: 'US Dollar',
41 | plural: 'US dollars',
42 | symbol: '$',
43 | symbol_native: '$'
44 | },
45 | connection: {
46 | asn: 11351,
47 | isp: 'Time Warner Cable Internet LLC'
48 | },
49 | security: {
50 | is_proxy: false,
51 | proxy_type: null,
52 | is_crawler: false,
53 | crawler_name: null,
54 | crawler_type: null,
55 | is_tor: false,
56 | threat_level: 'low',
57 | threat_types: null
58 | }
59 | };
60 |
--------------------------------------------------------------------------------
/src/js/utils/locate.js:
--------------------------------------------------------------------------------
1 | /* USAGE:
2 | locate(key, (err, result) => {
3 | ...
4 | })
5 | */
6 |
7 | import request from 'superagent';
8 | import testData from './locate-test';
9 |
10 | const debug = false;
11 | const MAX_TIME = 4000;
12 | let key = null;
13 |
14 | function getIP() {
15 | if (debug) return Promise.resolve(testData);
16 | const url = 'https://api.ipify.org?format=json';
17 | return new Promise((resolve, reject) => {
18 | request.get(url).end((err, res) => {
19 | if (err) reject(err);
20 | else if (res && res.status >= 200 && res.status < 400)
21 | resolve(JSON.parse(res.text));
22 | else reject(err);
23 | });
24 | });
25 | }
26 |
27 | function getGeocode({ ip }) {
28 | if (debug) return Promise.resolve(testData);
29 | const url = `https://api.ipstack.com/${ip}?access_key=${key}`;
30 | return new Promise((resolve, reject) => {
31 | request.get(url).end((err, res) => {
32 | if (err) reject(err);
33 | else if (res && res.status >= 200 && res.status < 400) {
34 | const j = JSON.parse(res.text);
35 | if (j.error) reject(j.error);
36 | else resolve(j);
37 | } else reject(err);
38 | });
39 | });
40 | }
41 |
42 | /**
43 | * Get users approx. location according to IP address
44 | * @param {function} cb callback funtion
45 | */
46 |
47 | function init(k, cb) {
48 | if (k) {
49 | key = k;
50 | const timeout = setTimeout(() => cb('timeout'), MAX_TIME);
51 |
52 | getIP()
53 | .then(getGeocode)
54 | .then(response => {
55 | clearTimeout(timeout);
56 | cb(null, response);
57 | })
58 | .catch(err => cb(err));
59 | } else cb('error: must pass ipstack key');
60 | }
61 |
62 | export default init;
63 |
--------------------------------------------------------------------------------
/src/js/utils/lookup-state-abbr.js:
--------------------------------------------------------------------------------
1 | import data from './us-state-data';
2 |
3 | /**
4 | * Return state abbrevation from name
5 | * @param {string} state to use to lookup abbreviation
6 |
7 | * @returns {string} abbreviation
8 | */
9 |
10 | export default lookupStateAbbr(state) {
11 | const match = data.find(d => d.state.toLowerCase() === state.toLowerCase());
12 | return match ? match.abbr : null;
13 | }
14 |
15 | export default lookupStateAbbr
16 |
--------------------------------------------------------------------------------
/src/js/utils/lookup-state-name.js:
--------------------------------------------------------------------------------
1 | import data from './us-state-data';
2 |
3 | /**
4 | * Return state name from abbreviation
5 | * @param {string} abbr to use to lookup state name
6 |
7 | * @returns {string} state name
8 | */
9 |
10 | function lookupStateName(abbr) {
11 | const match = data.find(d => d.abbr.toLowerCase() === abbr.toLowerCase());
12 | return match ? match.state : null;
13 | }
14 |
15 | export default lookupStateName;
16 |
--------------------------------------------------------------------------------
/src/js/utils/tracker.js:
--------------------------------------------------------------------------------
1 | const DEV_MODE = window.location.hostname.indexOf('localhost') > -1
2 |
3 | // keeps track to not resend
4 | const fired = {}
5 |
6 | function check({ category, action, once }) {
7 | if (once) {
8 | const cat = category.toString().replace(/\W+/g, '')
9 | const act = action.toString().replace(/\W+/g, '')
10 | const key = `${cat}${act}`
11 | if (fired[key]) return false
12 |
13 | fired[key] = true
14 | return true
15 | }
16 | return true
17 | }
18 |
19 | function send({ category, action, once }) {
20 | const add = check({ category, action, once })
21 |
22 | if (add) {
23 | if (DEV_MODE) console.log({ category, action, once })
24 | else if (window.ga) {
25 | ga('send', {
26 | hitType: 'event',
27 | eventCategory: category.toString(),
28 | eventAction: action.toString(),
29 | })
30 | }
31 | }
32 | }
33 |
34 | export default { send }
35 |
--------------------------------------------------------------------------------
/src/js/utils/truncate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Truncate string with options for clean break and ellipses
3 | * @param {string} text to trim
4 | * @param {number} [chars=100] number of characters to cut at
5 | * @param {boolean} [clean=true] break on space?
6 | * @param {boolean} [ellipses=false] add ...
7 |
8 | * @returns {string} truncated text
9 | */
10 | function truncate({ text, chars = 100, clean = true, ellipses = false }) {
11 | const a = text.substring(0, chars);
12 | const end = clean ? sub.lastIndexOf(' ') : a.length;
13 | const b = sub.substring(0, end);
14 | const e = ellipses ? '...' : '';
15 | return `${b}${e}`;
16 | }
17 |
18 | export default truncate;
19 |
--------------------------------------------------------------------------------
/src/js/utils/url-parameter.js:
--------------------------------------------------------------------------------
1 | function get(key) {
2 | const name = key.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
3 | const regex = new RegExp(`[\\?&]${name}=([^]*)`);
4 | const results = regex.exec(window.location.search);
5 | return results === null
6 | ? ''
7 | : decodeURIComponent(results[1].replace(/\+/g, ' '));
8 | }
9 |
10 | function set(key, value) {
11 | const baseUrl = [
12 | window.location.protocol,
13 | '//',
14 | window.location.host,
15 | window.location.pathname,
16 | ].join('');
17 | const urlQueryString = document.location.search;
18 | const newParam = `${key}=${value}`;
19 | let params = `?${newParam}`;
20 |
21 | // If the "search" string exists, then build params from it
22 | if (urlQueryString) {
23 | const updateRegex = new RegExp(`([\?&])${key}[^&]*`);
24 | const removeRegex = new RegExp(`([\?&])${key}=[^&;]+[&;]?`);
25 |
26 | // Remove param if value is empty
27 | if (typeof value === 'undefined' || value === null || value === '') {
28 | params = urlQueryString.replace(removeRegex, '$1');
29 | params = params.replace(/[&;]$/, '');
30 | } else if (urlQueryString.match(updateRegex) !== null) {
31 | // If param exists already, update it
32 | params = urlQueryString.replace(updateRegex, `$1${newParam}`);
33 | } else {
34 | // Otherwise, add it to end of query string
35 | params = `${urlQueryString}&${newParam}`;
36 | }
37 | }
38 |
39 | // no parameter was set so we don't need the question mark
40 | params = params === '?' ? '' : params;
41 |
42 | window.history.replaceState({}, '', `${baseUrl}${params}`);
43 | }
44 |
45 | export default { get, set };
46 |
--------------------------------------------------------------------------------
/src/js/utils/us-state-data.js:
--------------------------------------------------------------------------------
1 | export default [
2 | { state: 'Alabama', abbr: 'AL' },
3 | { state: 'Alaska', abbr: 'AK' },
4 | { state: 'Arizona', abbr: 'AZ' },
5 | { state: 'Arkansas', abbr: 'AR' },
6 | { state: 'California', abbr: 'CA' },
7 | { state: 'Colorado', abbr: 'CO' },
8 | { state: 'Connecticut', abbr: 'CT' },
9 | { state: 'Delaware', abbr: 'DE' },
10 | { state: 'District of Columbia', abbr: 'DC' },
11 | { state: 'Florida', abbr: 'FL' },
12 | { state: 'Georgia', abbr: 'GA' },
13 | { state: 'Hawaii', abbr: 'HI' },
14 | { state: 'Idaho', abbr: 'ID' },
15 | { state: 'Illinois', abbr: 'IL' },
16 | { state: 'Indiana', abbr: 'IN' },
17 | { state: 'Iowa', abbr: 'IA' },
18 | { state: 'Kansas', abbr: 'KS' },
19 | { state: 'Kentucky', abbr: 'KY' },
20 | { state: 'Louisiana', abbr: 'LA' },
21 | { state: 'Maine', abbr: 'ME' },
22 | { state: 'Montana', abbr: 'MT' },
23 | { state: 'Nebraska', abbr: 'NE' },
24 | { state: 'Nevada', abbr: 'NV' },
25 | { state: 'New Hampshire', abbr: 'NH' },
26 | { state: 'New Jersey', abbr: 'NJ' },
27 | { state: 'New Mexico', abbr: 'NM' },
28 | { state: 'New York', abbr: 'NY' },
29 | { state: 'North Carolina', abbr: 'NC' },
30 | { state: 'North Dakota', abbr: 'ND' },
31 | { state: 'Ohio', abbr: 'OH' },
32 | { state: 'Oklahoma', abbr: 'OK' },
33 | { state: 'Oregon', abbr: 'OR' },
34 | { state: 'Maryland', abbr: 'MD' },
35 | { state: 'Massachusetts', abbr: 'MA' },
36 | { state: 'Michigan', abbr: 'MI' },
37 | { state: 'Minnesota', abbr: 'MN' },
38 | { state: 'Mississippi', abbr: 'MS' },
39 | { state: 'Missouri', abbr: 'MO' },
40 | { state: 'Pennsylvania', abbr: 'PA' },
41 | { state: 'Rhode Island', abbr: 'RI' },
42 | { state: 'South Carolina', abbr: 'SC' },
43 | { state: 'South Dakota', abbr: 'SD' },
44 | { state: 'Tennessee', abbr: 'TN' },
45 | { state: 'Texas', abbr: 'TX' },
46 | { state: 'Utah', abbr: 'UT' },
47 | { state: 'Vermont', abbr: 'VT' },
48 | { state: 'Virginia', abbr: 'VA' },
49 | { state: 'Washington', abbr: 'WA' },
50 | { state: 'West Virginia', abbr: 'WV' },
51 | { state: 'Wisconsin', abbr: 'WI' },
52 | { state: 'Wyoming', abbr: 'WY' },
53 | { state: 'Washington DC', abbr: 'DC' }
54 | ];
55 |
--------------------------------------------------------------------------------
/svg/activity.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/airplay.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/alert-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/alert-octagon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/alert-triangle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/align-center.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/align-justify.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/align-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/align-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/anchor.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/aperture.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/archive.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-down-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-down-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-down-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-left-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-right-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-up-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-up-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-up-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/arrow-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/at-sign.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/award.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/bar-chart-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/bar-chart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/battery-charging.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/battery.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/bell-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/bell.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/bluetooth.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/bold.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/book-open.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/book.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/bookmark.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/box.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/briefcase.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/calendar.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/camera-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/camera.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/cast.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/check-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/check-square.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/check.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chevron-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chevron-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chevron-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chevron-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chevrons-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chevrons-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chevrons-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chevrons-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/chrome.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/clipboard.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/clock.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/cloud-drizzle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/cloud-lightning.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/cloud-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/cloud-rain.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/cloud-snow.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/cloud.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/code.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/codepen.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/command.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/compass.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/copy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/corner-down-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/corner-down-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/corner-left-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/corner-left-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/corner-right-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/corner-right-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/corner-up-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/corner-up-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/cpu.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/credit-card.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/crop.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/crosshair.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/database.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/delete.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/disc.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/dollar-sign.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/download-cloud.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/download.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/droplet.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/edit-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/edit-3.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/edit.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/external-link.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/eye-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/eye.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/facebook.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/fast-forward.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/feather.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/file-minus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/file-plus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/file-text.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/film.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/filter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/flag.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/folder-minus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/folder-plus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/folder.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/gift.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/git-branch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/git-commit.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/git-merge.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/git-pull-request.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/gitlab.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/globe.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/grid.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/hard-drive.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/hash.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/headphones.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/heart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/help-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/home.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/image.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/inbox.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/info.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/instagram.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/italic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/layers.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/layout.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/life-buoy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/link-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/link.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/linkedin.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/list.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/loader.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/lock.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/log-in.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/log-out.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/logo-small.svg:
--------------------------------------------------------------------------------
1 |
46 |
--------------------------------------------------------------------------------
/svg/mail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/map-pin.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/map.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/maximize-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/maximize.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/menu.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/message-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/message-square.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/mic-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/mic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/minimize-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/minimize.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/minus-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/minus-square.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/minus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/monitor.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/moon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/more-horizontal.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/more-vertical.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/move.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/music.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/navigation-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/navigation.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/octagon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/package.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/paperclip.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/pause-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/pause.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/percent.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/phone-call.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/phone-forwarded.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/phone-incoming.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/phone-missed.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/phone-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/phone-outgoing.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/phone.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/pie-chart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/play-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/play.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/plus-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/plus-square.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/plus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/pocket.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/power.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/printer.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/radio.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/refresh-ccw.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/refresh-cw.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/repeat.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/rewind.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/rotate-ccw.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/rotate-cw.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/rss.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/save.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/scissors.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/search.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/send.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/server.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/settings.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/share-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/share.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/shield-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/shield.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/shopping-bag.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/shopping-cart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/shuffle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/sidebar.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/skip-back.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/skip-forward.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/slack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/slash.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/sliders.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/smartphone.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/speaker.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/square.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/star.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/stop-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/sun.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/sunrise.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/sunset.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/tablet.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/tag.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/target.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/terminal.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/thermometer.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/thumbs-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/thumbs-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/toggle-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/toggle-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/trash-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/trash.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/trending-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/trending-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/triangle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/truck.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/tv.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/twitter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/type.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/umbrella.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/underline.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/unlock.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/upload-cloud.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/upload.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/user-check.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/user-minus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/user-plus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/user-x.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/user.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/users.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/video-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/video.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/voicemail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/volume-1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/volume-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/volume-x.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/volume.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/watch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/wifi-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/wifi.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/wind.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/x-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/x-square.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/x.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/youtube.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/zap-off.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/zap.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/zoom-in.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/zoom-out.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/template-data/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Title Case Headline Goes Here",
3 | "description":
4 | "Your dek goes here. It is probably one or two sentences that succinctly describe more explicitly what the story will be about.",
5 | "url": "https://pudding.cool/process/scrollytelling-sticky/",
6 | "keywords":
7 | "scrollytelling, position, sticky, css, graphic, interactive, data",
8 | "imgFacebook":
9 | "https://pudding.cool/process/scrollytelling-sticky/assets/social/social-facebook.jpg",
10 | "imgTwitter":
11 | "https://pudding.cool/process/scrollytelling-sticky/assets/social/social-twitter.jpg",
12 | "author": {
13 | "name": "Russell Goldenberg",
14 | "url": "https://pudding.cool/author/russell-goldenberg",
15 | "twitterHandle": "@codenberg"
16 | },
17 | "author2": {
18 | "name": "Elaina Natario",
19 | "url": "https://pudding.cool/author/elaina-natario",
20 | "twitterHandle": "@elainanatario"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/webpack.config.dev.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | module: {
3 | rules: [
4 | {
5 | test: /\.js$/,
6 | exclude: /(node_modules|bower_components)/,
7 | use: {
8 | loader: 'babel-loader',
9 | options: {
10 | presets: [
11 | require.resolve('babel-preset-env'),
12 | ],
13 | plugins: [
14 | require.resolve('babel-plugin-transform-object-rest-spread'),
15 | ],
16 | },
17 | },
18 | },
19 | ],
20 | },
21 | devtool: 'cheap-module-eval-source-map',
22 | }
23 |
--------------------------------------------------------------------------------
/webpack.config.dist.js:
--------------------------------------------------------------------------------
1 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
2 |
3 | module.exports = {
4 | module: {
5 | rules: [
6 | {
7 | test: /\.js$/,
8 | exclude: /(node_modules|bower_components)/,
9 | use: {
10 | loader: 'babel-loader',
11 | options: {
12 | presets: [require.resolve('babel-preset-env')],
13 | plugins: [
14 | require.resolve('babel-plugin-transform-object-rest-spread')
15 | ]
16 | }
17 | }
18 | }
19 | ]
20 | },
21 | plugins: [new UglifyJsPlugin()]
22 | };
23 |
--------------------------------------------------------------------------------