~wuz/wuz.sh

c87e15be2671dbedf0acdc3b9a3ebdc70dc741b2 — Conlin Durbin 6 months ago c94543a
Update writing and styles
M .eleventy.js => .eleventy.js +115 -124
@@ 1,129 1,120 @@
const markdownIt = require("markdown-it");
const mdAttrs = require("markdown-it-attrs");
const mdContainer = require("markdown-it-container");
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const moment = require("moment");
const pluginRss = require("@11ty/eleventy-plugin-rss");
const markdownIt = require('markdown-it');
const mdAttrs = require('markdown-it-attrs');
const mdContainer = require('markdown-it-container');
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight');
const moment = require('moment');
const pluginRss = require('@11ty/eleventy-plugin-rss');

const { codepen } = require('./shortcode-templates');

module.exports = (config) => {
  let env = process.env.ELEVENTY_ENV;
  config.addLayoutAlias("post", "layouts/post.njk");
  config.addPassthroughCopy("fonts");
  config.addPassthroughCopy("js");
  config.addPassthroughCopy("sw.js");
  config.addPassthroughCopy("assets");
  config.addPlugin(pluginRss);
  config.addPlugin(syntaxHighlight);
  config.addFilter("prettyDate", function (value) {
    const date = moment(value);
    return date.format("MMM Do YYYY");
  });

  config.addFilter("log", function (value) {
    console.log(value);
  });

  config.addShortcode("github", function(repo) {
    return `[${repo.replace("https://github.com/", '')}](${repo})`;
  });

  config.addFilter("garden_stage", function(stage = 0) {
    const stages = [
      `This post is still in the early stages. Beware - here be mental dragon!`,
      `This post is growing. The basic thoughts are here, but they haven't been fully fleshed out.`,
      `This post is in bloom. It's fleshed out and unlikely to change.`,
      `This post is wilting. The ideas here don't represent my current thought process.`,
    ];
    return stages[Number(stage)];
  });

  config.addFilter("garden_stage_icon", function(stage = 0) {
    const stagesIcon = [
      `🌧` ,
      `🌱`,
      `💐`,
      `🥀 `,
    ];
    return stagesIcon[Number(stage)];
  });

  config.addShortcode("codepen", function(pen, options, height) {
    const html = codepen(pen, options, height);
    console.log(html);
    return html;
  });

  config.addShortcode("twitter", function(id) {
    return `${id}`;
  });

  config.addShortcode("tweet", function(id) {
    return `${id}`;
  });

  config.addShortcode("medium", function(id) {
    return `https://medium.com/${id}`;
  });

  config.addShortcode("youtube", function(id) {
    return `https://medium.com/${id}`;
  });

  config.addShortcode("devto", function(link) {
    return `https://dev.to/${link}`;
  });

  config.addShortcode("devcomment", function(link) {
    return `https://dev.to/${link}`;
  });

  config.addShortcode("glitch", function(app, screen = "app") {
    return `https://glitch.com/embed/#!/${app}`;
  });

  const now = new Date();

  const livePosts = post => post.date <= now && !post.data.draft;
  config.addCollection('posts', collection => {
    return [
      ...collection.getFilteredByGlob('./writing/*.md').filter(livePosts)
    ].reverse();
  });

  config.addCollection('postFeed', collection => {
    return [...collection.getFilteredByGlob('./writing/*.md').filter(livePosts)]
      .reverse()
      .slice(0, 5);
  });

  let options = {
    html: true,
    breaks: true,
    linkify: true,
    typographer: true,
  };

  const md = markdownIt(options);

  // md.use(mdContainer, "aspect", {
  //   validate: function(params) {
  //     return params.trim().match(/^aspect\s+(.*)$/);
  //   },

  //   render: function(tokens, idx) {
  //     var m = tokens[idx].info.trim().match(/^aspect\s+(.*)$/);

  //     if (tokens[idx].nesting === 1) {
  //       // opening tag
  //       return `<figure style="--aspect-ratio:${md.utils.escapeHtml(m[1])}">`;
  //     } else {
  //       // closing tag
  //       return "</figure>\n";
  //     }
  //   }
  // });
  md.use(mdAttrs);
  config.setLibrary("md", md);
	let env = process.env.ELEVENTY_ENV;
	config.addLayoutAlias('post', 'layouts/post.njk');
	config.addPassthroughCopy('fonts');
	config.addPassthroughCopy('js');
	config.addPassthroughCopy('sw.js');
	config.addPassthroughCopy('assets');
	config.addPlugin(pluginRss);
	config.addPlugin(syntaxHighlight);
	config.addFilter('prettyDate', function (value) {
		const date = moment(value);
		return date.format('MMM Do YYYY');
	});

	config.addFilter('log', function (value) {
		console.log(value);
	});

	config.addShortcode('github', function (repo) {
		return `[${repo.replace('https://github.com/', '')}](${repo})`;
	});

	config.addFilter('garden_stage', function (stage = 0) {
		const stages = [
			`This post is still in the early stages. Beware - here be mental dragons!`,
			`This post is growing. The basic thoughts are here, but they haven't been fully fleshed out.`,
			`This post is in bloom. It's fleshed out and unlikely to change.`,
			`This post is wilting. The ideas here don't represent my current thought process.`,
		];
		return stages[Number(stage)];
	});

	config.addFilter('garden_stage_icon', function (stage = 0) {
		const stagesIcon = [`🌧`, `🌱`, `💐`, `🥀 `];
		return stagesIcon[Number(stage)];
	});

	config.addShortcode('codepen', function (pen, options, height) {
		const html = codepen(pen, options, height);
		console.log(html);
		return html;
	});

	config.addShortcode('twitter', function (id) {
		return `${id}`;
	});

	config.addShortcode('tweet', function (id) {
		return `${id}`;
	});

	config.addShortcode('medium', function (id) {
		return `https://medium.com/${id}`;
	});

	config.addShortcode('youtube', function (id) {
		return `https://medium.com/${id}`;
	});

	config.addShortcode('devto', function (link) {
		return `https://dev.to/${link}`;
	});

	config.addShortcode('devcomment', function (link) {
		return `https://dev.to/${link}`;
	});

	config.addShortcode('glitch', function (app, screen = 'app') {
		return `https://glitch.com/embed/#!/${app}`;
	});

	const now = new Date();

	const livePosts = (post) => post.date <= now && !post.data.draft;
	config.addCollection('posts', (collection) => {
		return [...collection.getFilteredByGlob('./writing/*.md').filter(livePosts)].reverse();
	});

	config.addCollection('postFeed', (collection) => {
		return [...collection.getFilteredByGlob('./writing/*.md').filter(livePosts)].reverse().slice(0, 5);
	});

	let options = {
		html: true,
		breaks: true,
		linkify: true,
		typographer: true,
	};

	const md = markdownIt(options);

	// md.use(mdContainer, "aspect", {
	//   validate: function(params) {
	//     return params.trim().match(/^aspect\s+(.*)$/);
	//   },

	//   render: function(tokens, idx) {
	//     var m = tokens[idx].info.trim().match(/^aspect\s+(.*)$/);

	//     if (tokens[idx].nesting === 1) {
	//       // opening tag
	//       return `<figure style="--aspect-ratio:${md.utils.escapeHtml(m[1])}">`;
	//     } else {
	//       // closing tag
	//       return "</figure>\n";
	//     }
	//   }
	// });
	md.use(mdAttrs);
	config.setLibrary('md', md);
};

M _includes/layouts/footer.njk => _includes/layouts/footer.njk +2 -0
@@ 1,3 1,5 @@
<black-lives></black-lives>

<script>
if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {

M _includes/layouts/head.njk => _includes/layouts/head.njk +1 -2
@@ 9,7 9,6 @@
    <script src="/js/main.js" async></script>
  </head>
  <body
    class="font:recursive bg:parchment"
    class="font:recursive bg:black text:cream"
  >
<black-lives></black-lives>


D _includes/layouts/nav-logo.njk => _includes/layouts/nav-logo.njk +0 -22
@@ 1,22 0,0 @@
<header class="grid grid:col-10 maxw:large padding:3 container:wide">
  <div class="grid:span-7 flex ai:center jc:center">
    <a href="/" class="no-decoration">
      <h1 class="typescale:4 wght:600">wuz</h1>
    </a>
  </div>
  <nav class="grid:span-1 flex ai:center jc:center wght:600">
    <a href="/writing" class="margin:1:right">Writing</a>
    <!-- <a href="/kit" class="margin:1:right">Kit</a>
    <div class="color-switch-container">
      <button class="color-switch" aria-label="Toggle Dark Mode">
        <span role="img" aria-label="dark mode">
          🌝
        </span>
        <span role="img" aria-label="light mode">
          🌞
        </span>
      </button>
    </div>
    -->
  </nav>
</header>

M _includes/layouts/nav.njk => _includes/layouts/nav.njk +6 -5
@@ 1,12 1,13 @@
<header class="grid grid:col-10 maxw:large padding:3 container:wide margin:4:top">
<header class="grid grid:col-10 maxw:large padding:3 container:wide">
  <div class="grid:span-7 flex ai:center wght:600">
    {% if page.url !== '/' %}
      <a href="/">wuz.sh</a>
    {% endif %}
      
  </div>
  <nav class="grid:span-3 flex ai:center jc:flex-end wght:600">
    <a href="/writing" class="margin:1:right">Writing</a>
    <!-- <a href="/kit" class="margin:1:right">Kit</a>
    <a href="/writing" class="margin:1:right">writing</a>
    &mdash;&nbsp;
    <a href="/kit" class="margin:1:right">kit</a>
    <!-- 
    <div class="color-switch-container">
      <button class="color-switch" aria-label="Toggle Dark Mode">
        <span role="img" aria-label="dark mode">

M _includes/layouts/post.njk => _includes/layouts/post.njk +4 -4
@@ 1,16 1,16 @@
{% include "./head.njk" %}
{% include "./nav.njk" %}
<div class="typescale:2 text:night">
<div class="typescale:2 bg:black text:white">
  <section class="container padding:2">
    <main class="content">
      {% if cover_image != "" %}
      <img data-responsive src="{{ cover_image }}" />
      {% endif %}
      <h1 class="typescale:12 wght:800 bdr:rainbow:bottom">{{ title | safe  }}</h1>
      <h2 class="typescale:9 text:stone wght:500 margin:2:top">
      <h1 class="typescale:6 wght:800 bdr:rainbow:bottom hack">{{ title | safe  }}</h1>
      <h2 class="typescale:5 text:stone wght:500 margin:2:top">
        {{ description | safe }}
      </h2>
      <h3 class="alert alert:info wght:600">
      <h3 class="alert alert:info wght:600 bg:purple-ping text:black">
        <section class="alert:icon">{{stage | garden_stage_icon }}</section>
        {{ stage | garden_stage }}
      </h3>

M _includes/styles/atoms/color.scss => _includes/styles/atoms/color.scss +53 -112
@@ 1,129 1,70 @@
@each $color
  in (
    brand,
    brand-secondary,
    pastel-red,
    pastel-orange,
    pastel-yellow,
    pastel-lime,
    pastel-green,
    pastel-blue,
    pastel-purple,
  )
{
  .text\:$color {
    color: var(--c-$color);
  }
$colors: (black, cream, brand, brand-secondary, hacker-pink, electric-blue, purple-ping, relay-red);
@each $color in $colors {
	.text\:$color {
		color: var(--c-$color);
	}

  .text-shadow\:$color {
    text-shadow: 0.05em 0.05em 0.1em var(--c-$color);
  }
	.text\:$color\:dark {
		color: darken(var(--c-$color), 10);
	}

  .text\:$color\:hov:hover {
    color: var(--c-$color);
  }
	.text-shadow\:$color {
		text-shadow: 0.02em 0.02em 0.1em var(--c-$color);
	}

  .bg\:$color {
    background-color: var(--c-$color);
  }
	.text\:$color\:hov:hover {
		color: var(--c-$color);
	}

  .fill\:$color {
    fill: var(--c-$color);
  }
	.bg\:$color {
		background-color: var(--c-$color);
	}

  .fill\:$color\:hover:hover {
    color: var(--c-$color);
  }
	.fill\:$color {
		fill: var(--c-$color);
	}

  .stroke\:$color {
    stroke: var(--c-$color);
  }
	.fill\:$color\:hover:hover {
		color: var(--c-$color);
	}

  .dark-mode.d\:bg\:$color {
    background-color: var(--c-$color);
  }
	.stroke\:$color {
		stroke: var(--c-$color);
	}

  .dark-mode.d\:text\:$color {
    color: var(--c-$color);
  }
	.dark-mode.d\:bg\:$color {
		background-color: var(--c-$color);
	}

  .dark-mode .d\:text\:$color {
    color: var(--c-$color);
  }
	.dark-mode.d\:text\:$color {
		color: var(--c-$color);
	}

  .dark-mode .d\:bg\:$color {
    background-color: var(--c-$color);
  }
	.dark-mode .d\:text\:$color {
		color: var(--c-$color);
	}

  .dark-mode .d\:fill\:$color {
    fill: var(--c-$color);
  }
	.dark-mode .d\:bg\:$color {
		background-color: var(--c-$color);
	}

  .dark-mode .d\:stroke\:$color {
    stroke: var(--c-$color);
  }
}
	.dark-mode .d\:fill\:$color {
		fill: var(--c-$color);
	}

.bg\:rainbow {
  background: linear-gradient(
    45deg,
    var(--c-pastel-red),
    var(--c-pastel-orange),
    var(--c-pastel-yellow),
    var(--c-pastel-lime),
    var(--c-pastel-green),
    var(--c-pastel-blue),
    var(--c-pastel-purple),
    var(--c-pastel-red),
    var(--c-pastel-orange),
    var(--c-pastel-yellow),
    var(--c-pastel-lime),
    var(--c-pastel-green),
    var(--c-pastel-blue)
  );
	.dark-mode .d\:stroke\:$color {
		stroke: var(--c-$color);
	}
}

.bdr\:rainbow {
  border: 5px solid;
  border-image: linear-gradient(
      45deg,
      var(--c-pastel-red),
      var(--c-pastel-orange),
      var(--c-pastel-yellow),
      var(--c-pastel-lime),
      var(--c-pastel-green),
      var(--c-pastel-blue),
      var(--c-pastel-purple),
      var(--c-pastel-red),
      var(--c-pastel-orange),
      var(--c-pastel-yellow),
      var(--c-pastel-lime),
      var(--c-pastel-green),
      var(--c-pastel-blue)
    )
    30;
}
.text-gradient\:hacker {
	background: linear-gradient(45deg, var(--c-brand), var(--c-brand-secondary));
	background-size: 100% 100%;

@each $dir in (left, right, top, bottom) {
  .bdr\:rainbow\:$dir {
    border-$(dir): 8px solid;
    padding-bottom: 1rem;
    border-image: linear-gradient(
        45deg,
        var(--c-pastel-red),
        var(--c-pastel-orange),
        var(--c-pastel-yellow),
        var(--c-pastel-lime),
        var(--c-pastel-green),
        var(--c-pastel-blue),
        var(--c-pastel-purple),
        var(--c-pastel-red),
        var(--c-pastel-orange),
        var(--c-pastel-yellow),
        var(--c-pastel-lime),
        var(--c-pastel-green),
        var(--c-pastel-blue)
      )
      30;
  }
	/* Use the text as a mask for the background. */
	/* This will show the gradient as a text color rather than element bg. */
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	-moz-background-clip: text;
	-moz-text-fill-color: transparent;
}

M _includes/styles/atoms/general.scss => _includes/styles/atoms/general.scss +16 -26
@@ 1,47 1,37 @@
.content {
  max-width: 45em;
	max-width: 45em;
}

.container {
  margin: 0 auto;
  width: 100%;
  max-width: 60em;
	margin: 0 auto;
	width: 100%;
	max-width: 60em;
}

.container\:wide {
  margin: 0 auto;
  width: 100%;
  max-width: 72em;
	margin: 0 auto;
	width: 100%;
	max-width: 72em;
}

.no-decoration {
  text-decoration: none;
	text-decoration: none;
}

.maxw\:large {
  max-width: var(--large-width);
	max-width: var(--large-width);
}

.heading-wrapper {
  position: relative;
  height: 100%;
	position: relative;
	height: 100%;

  h1 {
    position: relative;
    z-index: 2;
  }
	h1 {
		position: relative;
		z-index: 2;
	}
}

.pos\:rel {
  position: relative;
}

.alert-animation {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  height: 100%;
  width: 100%;
	position: relative;
}

M _includes/styles/components/alert.scss => _includes/styles/components/alert.scss +4 -13
@@ 1,18 1,9 @@
.alert {
  padding: em(spacing(1));
  display: flex;
	padding: em(spacing(3));
	display: flex;
}

.alert\:icon {
  font-size: 40px;
  margin-right: 10px;
}

.alert\:danger {
  background: var(--c-strawberry);
}

.alert\:info {
  background: var(--c-tonic);
  color: var(--c-cream);
	font-size: 40px;
	margin-right: 10px;
}

M _includes/styles/components/markdown.scss => _includes/styles/components/markdown.scss +17 -0
@@ 15,4 15,21 @@
  pre {
    border-radius: 4px;
  }

  blockquote {
    border-left: 5px solid var(--c-brand);
    padding: 10px;
    margin-left: 10px;
    background: var(--c-grayed-out);
  }

  em {
    font-style: italic;
  }

  strong {
    font-weight: 500;
    font-variation-settings: var(--mono), var(--casl), "wght" 600, var(--slnt),
      var(--ital);
  }
}

M _includes/styles/generics/html.scss => _includes/styles/generics/html.scss +37 -22
@@ 4,39 4,54 @@ h3,
h4,
h5,
h6 {
  font-size: var(--base-font-size);
  line-height: 1.1;
	font-size: var(--base-font-size);
	line-height: 1.1;
}

h1.hack {
	position: relative;
	overflow: hidden;
	padding-bottom: 40px;
	&:after {
		content: '================================================================================================================';
		position: absolute;
		bottom: 10px;
		left: 0;
	}
}

body {
  min-height: 100vh;
  font-size: var(--base-font-size);

  @media screen and (max-width: 468px) {
    & {
      font-size: var(--mobile-font-size);
    }
  }
	min-height: 100vh;
	font-size: var(--base-font-size);

	@media screen and (max-width: 468px) {
		& {
			font-size: var(--mobile-font-size);
		}
	}
}

strong {
	font-variation-settings: var(--mono), var(--casl), 'wght' 800, var(--slnt), var(--ital);
}

[data-responsive] {
  object-fit: cover;
  width: 100%;
  height: auto;
	object-fit: cover;
	width: 100%;
	height: auto;
}

a {
  --link-color: var(--c-brand);
  color: var(--link-color);
  text-decoration: none;
  position: relative;

	--link-color: var(--c-brand);
	color: var(--link-color);
	text-decoration: none;
	position: relative;

  &:hover {
    text-decoration: underline var(--link-color) solid 2px;
  }
	&:hover {
		text-decoration: underline var(--link-color) solid 2px;
	}
}

svg {
  fill: currentColor;
	fill: currentColor;
}

M _includes/styles/token.scss => _includes/styles/token.scss +12 -15
@@ 1,23 1,20 @@
:root {
  --c-pastel-red: #ff9aa2;
  --c-pastel-orange: #ffb7b2;
  --c-pastel-yellow: #ffdac1;
  --c-pastel-lime: #e2f0cb;
  --c-pastel-green: #b5ead7;
  --c-pastel-blue: #c7ceea;
  --c-pastel-purple: #eab2f3;
  --c-black: #052229;
	--c-grayed-out: #d1e2e8;
	--c-black: #052229;
	--c-cream: #f1f1f1;

  --c-electric-blue: #73ffff;
  --c-hacker-pink: #ff2c75;
	--c-purple-ping: #be73ff;
	--c-relay-red: #ff5f5c;
	--c-electric-blue: #73ffff;
	--c-hacker-pink: #ff2c75;

  --c-brand: var(--c-hacker-pink);
  --c-brand-secondary: var(--c-electric-blue);
	--c-brand: var(--c-hacker-pink);
	--c-brand-secondary: var(--c-electric-blue);

  --base-font-size: em(typescale(4));
  --mobile-font-size: em(typescale(3));
	--base-font-size: em(typescale(4));
	--mobile-font-size: em(typescale(3));

  --large-width: 1280px;
	--large-width: 1280px;
}

/* --c-strawberry: #da667b; */

M index.html => index.html +52 -78
@@ 4,82 4,56 @@ pageTitle: Howdy, I'm Wuz!
---

<main class="content">
  <header class="pos:rel">
    <canvas class="alert-animation"></canvas>
    <h1 class="typescale:17 wght:900 text:brand text-shadow:brand-secondary hacker">
      Howdy, I'm Wuz.
    </h1>
  </header>
  <h2 class="typescale:8 margin:1:bottom bdr:rainbow:bottom">
    Software engineer working to help other engineers learn and grow.
  </h2>
  <div>
    <h1 class="typescale:6">Current Focuses</h1>
    <ul>
      <li>
        <a href="https://indyhackers.org">IndyHackers</a> - A community for tech
        folks in Indiana
      </li>
      <li>
        <a href="https://serialfork.com">SerialFork</a> - A new idea for the new
        year
      </li>
    </ul>
  </div>
  <div>
    <h1 class="typescale:6">Recent Writing</h1>
    <ul>
      {%- for post in collections.writing -%}
      {% if post.data.stage >= 2 %}
          <li>
            <a href="{{post.url}}">{{ post.data.title }}</a> |
            <time datetime="{{page.date}}">
              {{ post.date | prettyDate }}
            </time>
          </li>
        {% endif %}
      {%- endfor -%}
    </ul>
  </div>
  <div>
    <h1 class="typescale:6">Find me on the web</h1>
    <ul>
      <li>
        <a rel="me" href="https://sunbeam.city/@wuz">
          Mastodon
        </a>
      </li>
      <li>
        <a rel="me" href="https://twitter.com/CallMeWuz">
          Twitter
        </a>
      </li>
      <li>
        <a rel="me" href="https://sr.ht/~wuz">
          SourceHut
        </a>
      </li>
      <li>
        <a rel="me" href="https://github.com/wuz">
          Github
        </a>
      </li>
      <li>
        <a rel="me" href="https://keybase.io/wuz">
          Keybase
        </a>
      </li>
    </ul>
  </div>
  <div>
    <h1 class="typescale:6">Projects</h1>
    <p>
      built <a href="https://dankneon.com">Dank Neon</a>,
      <a href="https://botsin.space/@ajjbot">AJJ Bot</a>,
      <a href="https://picdance.party">Picdance</a>, and
      <a href="https://github.com/wuz/all_google_fonts">
        all google fonts
      </a>
    </p>
  </div>
	<header class="pos:rel">
		<h1 class="typescale:17 wght:900 text-gradient:hacker">Howdy, I'm Wuz.</h1>
	</header>
	<h2 class="typescale:8 margin:1:bottom bdr:rainbow:bottom">
		Software engineer working to help other engineers learn and grow.
	</h2>
	<div>
		<h1 class="typescale:6">Current Focuses</h1>
		<ul>
			<li><a href="https://indyhackers.org">IndyHackers</a> - A community for tech folks in Indiana</li>
			<li><a href="https://serialfork.com">SerialFork</a> - A new idea for the new year</li>
		</ul>
	</div>
	<div>
		<h1 class="typescale:6">Recent Writing</h1>
		<ul>
			{%- for post in collections.writing -%} {% if post.data.stage >= 2 %}
			<li>
				<a href="{{post.url}}">{{ post.data.title }}</a> |
				<time datetime="{{page.date}}"> {{ post.date | prettyDate }} </time>
			</li>
			{% endif %} {%- endfor -%}
		</ul>
	</div>
	<div>
		<h1 class="typescale:6">Find me on the web</h1>
		<ul>
			<li>
				<a rel="me" href="https://sunbeam.city/@wuz"> Mastodon </a>
			</li>
			<li>
				<a rel="me" href="https://twitter.com/CallMeWuz"> Twitter </a>
			</li>
			<li>
				<a rel="me" href="https://sr.ht/~wuz"> SourceHut </a>
			</li>
			<li>
				<a rel="me" href="https://github.com/wuz"> Github </a>
			</li>
			<li>
				<a rel="me" href="https://keybase.io/wuz"> Keybase </a>
			</li>
		</ul>
	</div>
	<div>
		<h1 class="typescale:6">Projects</h1>
		<p>
			built <a href="https://dankneon.com">Dank Neon</a>, <a href="https://botsin.space/@ajjbot">AJJ Bot</a>,
			<a href="https://picdance.party">Picdance</a>, and
			<a href="https://github.com/wuz/all_google_fonts"> all google fonts </a>
		</p>
	</div>
</main>

M js/main.js => js/main.js +0 -9
@@ 1,10 1,1 @@



document.addEventListener("DOMContentLoaded", () => {
  const canvas = document.querySelector(".alert-animation");
  const ctx = canvas.getContext("2d");
  const drawTriangle = () => {

  }
});

M writing.html => writing.html +16 -20
@@ 4,29 4,25 @@ layout: layouts/index
---

<h1 class="typescale:9 wght:800 margin:2:bottom">A Digital Garden</h1>
<p>
  This is a space for half-finished thoughts and notes to take the time they
  need to bloom into something fully formed.
<p class="margin:2:bottom">
	This is a space for half-finished thoughts and notes to take the time they need to bloom into something fully
	formed.
</p>
<strong>Legend</strong>
<ul>
  <li>🌧  - This post is still in the early stages. Beware - here be mental dragons!</li>
  <li>🌱 - This post is growing. The basic thoughts are here, but they haven't been fully fleshed out.</li>
  <li>💐 - This post is in bloom. It's fleshed out and unlikely to change.</li>
  <li>🥀 - This post is wilting. The ideas here don't represent my current thought process.</li>
	<li>🌧 - This post is still in the early stages. Beware - here be mental dragons!</li>
	<li>🌱 - This post is growing. The basic thoughts are here, but they haven't been fully fleshed out.</li>
	<li>💐 - This post is in bloom. It's fleshed out and unlikely to change.</li>
	<li>🥀 - This post is wilting. The ideas here don't represent my current thought process.</li>
</ul>
<ul class="grid grid:auto-fit">
  {%- for post in collections.writing -%}
  <li class="o:post">
    <section>{{ post.data.stage | garden_stage_icon }}</section>
    <time class="typescale:3" datetime="{{page.date}}">
      {{ page.date | prettyDate }}
    </time>
    <h1 class="typescale:7 wght:700 bdr:rainbow:bottom">
      {{ post.data.title }}
    </h1>
    <h2 class="typescale:5">{{ post.data.description }}</h2>
    <a href="{{post.url}}">Read</a>
  </li>
  {%- endfor -%}
	{%- for post in collections.writing -%} {% if post.data.draft %} {% else %}
	<li class="o:post">
		<section>{{ post.data.stage | garden_stage_icon }}</section>
		<time class="typescale:3" datetime="{{page.date}}"> {{ page.date | prettyDate }} </time>
		<h1 class="typescale:7 wght:700 bdr:rainbow:bottom">{{ post.data.title }}</h1>
		<h2 class="typescale:5">{{ post.data.description }}</h2>
		<a href="{{post.url}}">Read</a>
	</li>
	{% endif %} {%- endfor -%}
</ul>

D writing/5_tips_for_your_first_5_days_as_a_new_dev.md => writing/5_tips_for_your_first_5_days_as_a_new_dev.md +0 -6
@@ 1,6 0,0 @@
---
title: "5 tips for your first 5 days as a new dev"
date: 2019-07-29T21:32:14.982Z
cover_image: https://thepracticaldev.s3.amazonaws.com/i/tz0ybd0j4fgalpipqxx8.jpg
---
Hopefully these tips help! I'd love to hear your thoughts in the comments or on [Twitter](https://twitter.com/CallMeWuz).
\ No newline at end of file

M writing/announcing_stdio__a_community_for_human_engineers.md => writing/announcing_stdio__a_community_for_human_engineers.md +4 -2
@@ 2,15 2,17 @@
title: "Announcing stdio - A community for human engineers"
date: 2019-03-23T02:20:04.270Z
cover_image: https://res.cloudinary.com/practicaldev/image/fetch/s--deJFwAsv--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://thepracticaldev.s3.amazonaws.com/i/qiqh0dgkxh1x8ioluvwp.png
stage: 3
---

Hey friends! It's been a little over a week since I've posted and I feel like I am loosing some of my drive. To get it kickstarted back up, I'd love to announce a new side project I am working on! So without further ado, check out **stdio**.

# What is it?

[stdio](https://stdio.app) (standard io) is a community/name under which a few projects are being released, all centered around helping everyone become more human engineers. 
[stdio](https://stdio.app) (standard io) is a community/name under which a few projects are being released, all centered around helping everyone become more human engineers.

The first project is up - it's a discord server for engineers of all skill levels to come hang out, get help with programming problems, connect with other engineers and learn new things. We'll be having weekly community nights every Tuesday at 6:15PM PST (subject to change by popular demand) where we will just hang out, discuss engineering things, and (hopefully) have some special guests!

More projects are in the works, but I really want this to be a collaborative, community-driven group. I have lots of ideas where this could go, but I want to know what the community wants!

Come join us in Discord, accept the Code of Conduct and join us _this_ Tuesday at 6:15PM EST! We'll be hanging out, chatting, and getting to know everyone!
\ No newline at end of file
Come join us in Discord, accept the Code of Conduct and join us _this_ Tuesday at 6:15PM EST! We'll be hanging out, chatting, and getting to know everyone!

D writing/become_an_accessibility_rockstar_%F0%9F%A4%98.md => writing/become_an_accessibility_rockstar_%F0%9F%A4%98.md +0 -6
@@ 1,6 0,0 @@
---
title: "Become an accessibility rock-star! 🤘"
date: 2019-04-09T12:14:33.735Z

---
Come chat with me on [Twitter](https://twitter.com/CallMeWuz) for more like this!
\ No newline at end of file

M writing/build_something_that_makes_a_difference.md => writing/build_something_that_makes_a_difference.md +4 -2
@@ 2,7 2,9 @@
title: "Build Something That Makes a Difference "
date: 2020-05-13T19:36:50.591Z
cover_image: https://i.imgur.com/85LiQLt.jpg
stage: 2
---

> This was a post I wrote almost a year ago. I just now am getting around to sharing it.
> If you didn't know, Codeland is online this year! [Check it out!](https://codelandconf.com/)



@@ 32,5 34,5 @@ We had a break here, where we met with the conference sponsors. I met some inspi

Finally, we all came back into the theatre to hear a talk from Scott Hanselman about building an artificial pancreas. There were some incredible technical pieces to this talk - from Bluetooth and radio communications to building applications to help monitor glucose levels. However, to me, the most critical part of the talk was how it inspired developers to find something that seems set or unchangeable and use technology to change it. The proprietary technology that powers glucose monitors doesn’t speak to the technology that powers insulin pumps, so some intrepid hackers made a device that bridges that gap. There are so many problems out there that could be improved with technology.

I think my favorite takeaway from the conference was a joke line from Michael Winslow’s talk on building cross-fade technology. In talking about being a DJ and channeling a bit of Uncle Ben, he said, **“With great volume, comes great responsibility.”** 
I know what was meant by this line at the time, but I think it sums up the conference better than I ever could. In the world of tech, we tend to forget just how much volume we have. When Facebook “moves fast and breaks things,” they do so at the expense of those unable to be broken. When we limit our intake of immigrants through draconian immigration law, we miss out on the incredible people that want to make our country better. We exist in a noisy industry, and we have a responsibility to use that volume in the right way.
\ No newline at end of file
I think my favorite takeaway from the conference was a joke line from Michael Winslow’s talk on building cross-fade technology. In talking about being a DJ and channeling a bit of Uncle Ben, he said, **“With great volume, comes great responsibility.”**
I know what was meant by this line at the time, but I think it sums up the conference better than I ever could. In the world of tech, we tend to forget just how much volume we have. When Facebook “moves fast and breaks things,” they do so at the expense of those unable to be broken. When we limit our intake of immigrants through draconian immigration law, we miss out on the incredible people that want to make our country better. We exist in a noisy industry, and we have a responsibility to use that volume in the right way.

M writing/building_a_country_highlighting_tool_with_mapbox.md => writing/building_a_country_highlighting_tool_with_mapbox.md +48 -48
@@ 2,6 2,7 @@
title: "Building a Country Highlighting Tool With Mapbox"
date: 2017-07-27T12:47:00.000Z
cover_image: https://i.imgur.com/vINLBHg.png
stage: 2
---

For a recent project, we needed to create a dynamic map that highlighted the areas in which our client had done work. After evaluating the requirements and looking into our options, we decided to build this using [Mapbox](http://mapbox.com/). Their integration with [OpenStreetMap](https://www.openstreetmap.org/) and ability to easily customize the tilesets and style on our map was an instant hook.


@@ 22,7 23,7 @@ Go ahead and copy then paste it into a new Javascript file named `main.js` like 

```js
mapboxgl.accessToken =
  'pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ'; // Replace with your token
  "pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ"; // Replace with your token
```

Now we just need some basic HTML boilerplate. Create a file called index.html and add the following:


@@ 76,11 77,11 @@ If you load up your page, you probably won’t see anything yet. Our next step i

```js
mapboxgl.accessToken =
  'pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ'; // Replace with your token
  "pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ"; // Replace with your token

var map = new mapboxgl.Map({
  container: 'map', //this is the id of the container you want your map in
  style: 'mapbox://styles/mapbox/light-v9', // this controls the style of the map. Want to see more? Try changing 'light' to 'simple'.
  container: "map", //this is the id of the container you want your map in
  style: "mapbox://styles/mapbox/light-v9", // this controls the style of the map. Want to see more? Try changing 'light' to 'simple'.
  minZoom: 2, // We want our map to start out pretty zoomed in to start.
});
```


@@ 121,28 122,28 @@ You’ll also need the source layer name, which is that bit starting with `ne_`.

```js
mapboxgl.accessToken =
  'pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ'; // Replace with your token
  "pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ"; // Replace with your token

var map = new mapboxgl.Map({
  container: 'map', //this is the id of the container you want your map in
  style: 'mapbox://styles/mapbox/light-v9', // this controls the style of the map. Want to see more? Try changing 'light' to 'simple'.
  container: "map", //this is the id of the container you want your map in
  style: "mapbox://styles/mapbox/light-v9", // this controls the style of the map. Want to see more? Try changing 'light' to 'simple'.
  minZoom: 2, // We want our map to start out pretty zoomed in to start.
});

map.on('load', function() {
map.on("load", function () {
  //On map load, we want to do some stuff
  map.addLayer({
    //here we are adding a layer containing the tileset we just uploaded
    id: 'countries', //this is the name of our layer, which we will need later
    id: "countries", //this is the name of our layer, which we will need later
    source: {
      type: 'vector',
      url: 'mapbox://', // <--- Add the Map ID you copied here
      type: "vector",
      url: "mapbox://", // <--- Add the Map ID you copied here
    },
    'source-layer': '', // <--- Add the source layer name you copied here
    type: 'fill',
    "source-layer": "", // <--- Add the source layer name you copied here
    type: "fill",
    paint: {
      'fill-color': '#52489C', //this is the color you want your tileset to have (I used a nice purple color)
      'fill-outline-color': '#F2F2F2', //this helps us distinguish individual countries a bit better by giving them an outline
      "fill-color": "#52489C", //this is the color you want your tileset to have (I used a nice purple color)
      "fill-outline-color": "#F2F2F2", //this helps us distinguish individual countries a bit better by giving them an outline
    },
  });
});


@@ 154,40 155,40 @@ We should now have loaded the tileset and your map should look something like th

Right now this isn’t super helpful. All of the countries are showing, which makes it hard to distinguish anything. Let’s filter the data a bit.

For this, we want to filter by [ISO Alpha3 Codes](http://www.nationsonline.org/oneworld/country_code_list.htm), which exist in our tileset under the ID “ADM0\_A3\_IS”.
For this, we want to filter by [ISO Alpha3 Codes](http://www.nationsonline.org/oneworld/country_code_list.htm), which exist in our tileset under the ID “ADM0_A3_IS”.

We add a line to the load function to start filtering:

```js
mapboxgl.accessToken =
  'pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ'; // Replace with your token
  "pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ"; // Replace with your token

var map = new mapboxgl.Map({
  container: 'map', //this is the id of the container you want your map in
  style: 'mapbox://styles/mapbox/light-v9', // this controls the style of the map. Want to see more? Try changing 'light' to 'simple'.
  container: "map", //this is the id of the container you want your map in
  style: "mapbox://styles/mapbox/light-v9", // this controls the style of the map. Want to see more? Try changing 'light' to 'simple'.
  minZoom: 2, // We want our map to start out pretty zoomed in to start.
});

map.on('load', function() {
map.on("load", function () {
  //On map load, we want to do some stuff
  map.addLayer({
    //here we are adding a layer containing the tileset we just uploaded
    id: 'countries', //this is the name of our layer, which we will need later
    id: "countries", //this is the name of our layer, which we will need later
    source: {
      type: 'vector',
      url: 'mapbox://', // <--- Add the Map ID you copied here
      type: "vector",
      url: "mapbox://", // <--- Add the Map ID you copied here
    },
    'source-layer': '', // <--- Add the source layer name you copied here
    type: 'fill',
    "source-layer": "", // <--- Add the source layer name you copied here
    type: "fill",
    paint: {
      'fill-color': '#52489C', //this is the color you want your tileset to have (I used a nice purple color)
      'fill-outline-color': '#F2F2F2', //this helps us distinguish individual countries a bit better by giving them an outline
      "fill-color": "#52489C", //this is the color you want your tileset to have (I used a nice purple color)
      "fill-outline-color": "#F2F2F2", //this helps us distinguish individual countries a bit better by giving them an outline
    },
  });

  map.setFilter(
    'countries',
    ['in', 'ADM0_A3_IS'].concat(['USA', 'AUS', 'NGA']),
    "countries",
    ["in", "ADM0_A3_IS"].concat(["USA", "AUS", "NGA"])
  ); // This line lets us filter by country codes.
});
```


@@ 200,42 201,42 @@ Finally, let’s make the map interactive. For this, we are going to use the API

```js
mapboxgl.accessToken =
  'pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ'; // Replace with your token
  "pk.eyJ1IjoiYnlmcm9zdC1hcnRpY2xlcyIsImEiOiJjajVsZ3NwZGczMWNtMnFyeTR2cHRnajZ4In0.HOjYrueiLWlhLfhsDCa7wQ"; // Replace with your token

var map = new mapboxgl.Map({
  container: 'map', //this is the id of the container you want your map in
  style: 'mapbox://styles/mapbox/light-v9', // this controls the style of the map. Want to see more? Try changing 'light' to 'simple'.
  container: "map", //this is the id of the container you want your map in
  style: "mapbox://styles/mapbox/light-v9", // this controls the style of the map. Want to see more? Try changing 'light' to 'simple'.
  minZoom: 2, // We want our map to start out pretty zoomed in to start.
});

map.on('load', function() {
map.on("load", function () {
  //On map load, we want to do some stuff
  map.addLayer({
    //here we are adding a layer containing the tileset we just uploaded
    id: 'countries', //this is the name of our layer, which we will need later
    id: "countries", //this is the name of our layer, which we will need later
    source: {
      type: 'vector',
      url: 'mapbox://byfrost-articles.74qv0xp0', // <--- Add the Map ID you copied here
      type: "vector",
      url: "mapbox://byfrost-articles.74qv0xp0", // <--- Add the Map ID you copied here
    },
    'source-layer': 'ne_10m_admin_0_countries-76t9ly', // <--- Add the source layer name you copied here
    type: 'fill',
    "source-layer": "ne_10m_admin_0_countries-76t9ly", // <--- Add the source layer name you copied here
    type: "fill",
    paint: {
      'fill-color': '#52489C', //this is the color you want your tileset to have (I used a nice purple color)
      'fill-outline-color': '#F2F2F2', //this helps us distinguish individual countries a bit better by giving them an outline
      "fill-color": "#52489C", //this is the color you want your tileset to have (I used a nice purple color)
      "fill-outline-color": "#F2F2F2", //this helps us distinguish individual countries a bit better by giving them an outline
    },
  });

  map.setFilter(
    'countries',
    ['in', 'ADM0_A3_IS'].concat(['USA', 'AUS', 'NGA']),
    "countries",
    ["in", "ADM0_A3_IS"].concat(["USA", "AUS", "NGA"])
  ); // This line lets us filter by country codes.

  map.on('click', 'countries', function(mapElement) {
  map.on("click", "countries", function (mapElement) {
    const countryCode = mapElement.features[0].properties.ADM0_A3_IS; // Grab the country code from the map properties.

    fetch(`https://restcountries.eu/rest/v2/alpha/${countryCode}`) // Using tempalate tags to create the API request
      .then(data => data.json()) //fetch returns an object with a .json() method, which returns a promise
      .then(country => {
      .then((data) => data.json()) //fetch returns an object with a .json() method, which returns a promise
      .then((country) => {
        //country contains the data from the API request
        // Let's build our HTML in a template tag
        const html = ` 


@@ 243,8 244,8 @@ map.on('load', function() {
        <ul>
          <li><h3>${country.name}</h3></li>
          <li><strong>Currencies:</strong> ${country.currencies
            .map(c => c.code)
            .join(', ')}</li>
            .map((c) => c.code)
            .join(", ")}</li>
          <li><strong>Capital:</strong> ${country.capital}</li>
          <li><strong>Population:</strong> ${country.population}</li>
          <li><strong>Demonym:</strong> ${country.demonym}</li>


@@ 262,4 263,3 @@ map.on('load', function() {
Now we have an interactive map with highlighted countries!

{% codepen "https://codepen.io/wuz/pen/ayOwjY/" "default-tab=js,result" %}


M writing/building_a_simple_alfred_workflow_to_grab_gifs_from_my_website.md => writing/building_a_simple_alfred_workflow_to_grab_gifs_from_my_website.md +14 -10
@@ 1,16 1,20 @@
---
title: "Building a simple Alfred workflow to grab gifs from my website"
date: 2019-01-15T03:50:00.991Z
cover_image: https://thepracticaldev.s3.amazonaws.com/i/d0gq1cwl3uvduvn1l6kr.png
---
I save a lot of gifs. 
---
title: "Building a simple Alfred workflow to grab gifs from my website"
date: 2019-01-15T03:50:00.991Z
cover_image: https://thepracticaldev.s3.amazonaws.com/i/d0gq1cwl3uvduvn1l6kr.png
stage: 2
---

I save a lot of gifs.

![](https://thepracticaldev.s3.amazonaws.com/i/wyzsfhh30j2e9ujvh1cw.png)

<figcaption>I've got 169 as of this article</figcaption>

I used to store them in Dropbox and share them with a link, but Dropbox has changed the way they handle Public folders and links, so it was a hassle to drop a gif in. Plus, I'm trying to migrate my stuff away from big services in 2019 (more coming this in a future post!) With this in mind, a week or two ago I setup a nice little [Alfred workflow](https://www.alfredapp.com) for to grab the links to my gifs and share them.  
I used to store them in Dropbox and share them with a link, but Dropbox has changed the way they handle Public folders and links, so it was a hassle to drop a gif in. Plus, I'm trying to migrate my stuff away from big services in 2019 (more coming this in a future post!) With this in mind, a week or two ago I setup a nice little [Alfred workflow](https://www.alfredapp.com) for to grab the links to my gifs and share them.

![](https://wuz.fyi/gifs/typing.gif)

<figcaption>Actual footage of me searching and sharing gifs (not actual footage)</figcaption>

First things first, I had to set up my gif hosting. I use [NearlyFreeSpeech](https://nearlyfreespeech.net) to host [my personal site](https://wuz.fyi). I store the gifs in a folder in there and sync them back and forth using [rsync](https://www.samba.org/rsync/). Basically all you need for this step is a publicly hosted base url for your gifs - i.e. https://wuz.fyi/gifs for my site.


@@ 44,7 48,7 @@ urlencode() {
    # urlencode <string>
    old_lc_collate=$LC_COLLATE
    LC_COLLATE=C
    

    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
        local c="${1:i:1}"


@@ 53,7 57,7 @@ urlencode() {
            *) printf '%%%02X' "'$c" ;;
        esac
    done
    

    LC_COLLATE=$old_lc_collate
}
URL="https://wuz.fyi/gifs/"


@@ 73,4 77,4 @@ Way to go! I hope you get as much enjoyment and usage out of this as I have!

![](https://wuz.fyi/gifs/thats-our-show.gif)

Help me spend too much money on hosting! What is your favorite gif? Share below!
\ No newline at end of file
Help me spend too much money on hosting! What is your favorite gif? Share below!

M writing/cantrip.md => writing/cantrip.md +1 -1
@@ 1,4 1,4 @@
---
title: "Cantrip - "
title: "Cantrip"
draft: true
---

M writing/deno.md => writing/deno.md +3 -0
@@ 5,6 5,9 @@ description: A new runtime for Javascript and Typescript from the founder of Nod
stage: 2
---

> **Edit:** Deno has hit 1.0 and with it, there has been some major discussion around whether the project needs an explicit CoC. The original maintainer seems to think it doesn't and I can't recommend that you use Deno until they do.
> **A Code of Conduct is a necessary part of any open source project.**

![People in dino suits dancing](https://media.giphy.com/media/3rgXBvnbXtxwaWmhr2/giphy.gif) {style="--aspect-ratio:16/9"}

In case you missed it, the new Javascript and Typescript runtime from Ryan Dahl,

D writing/design_for_developers_by_sarah_drasner_starts_soon.md => writing/design_for_developers_by_sarah_drasner_starts_soon.md +0 -10
@@ 1,10 0,0 @@
---
title: "Design for Developers by Sarah Drasner starts soon!"
date: 2018-11-28T15:30:51.290Z

---
{% twitter 1067796979470819328 %}

Sarah Drasner is hosting a workshop on FrontendMasters about design for developers! [Check it out](https://frontendmasters.com) then check out this #discuss by Jaime Rios:

{% devto "papaponmx/flipping-the-coin-should-developers-design-26ie" %}

M writing/design_systems_101.md => writing/design_systems_101.md +15 -14
@@ 2,7 2,9 @@
title: "Design Systems 101"
date: 2020-04-01T14:12:55.044Z
cover_image: https://imgur.com/mkcG5lz.png
stage: 2
---

# Benefits of a design system:

- **Design systems bring order to chaos.** Everyone is kept on the same page, so the entire product remains consistent and polished throughout.


@@ 25,7 27,7 @@ cover_image: https://imgur.com/mkcG5lz.png

### 1. Don't start from scratch

"Steal like an artist", where you can. There are lots of open design systems out there that we can borrow from. Additionally, there are lots of good tools that we can use. 
"Steal like an artist", where you can. There are lots of open design systems out there that we can borrow from. Additionally, there are lots of good tools that we can use.

Even things like Bootstrap can be useful to steal from - we can find common patterns that many web-apps use and build reusable components to build them out for our companies.



@@ 46,24 48,24 @@ Some ideas of sections:

### 4. Build a component library and document it

Once the audit is done, begin to build out a component library. For each component, include documentation and standards. Remember that when *not* to use a component is just as important as when you should use it.
Once the audit is done, begin to build out a component library. For each component, include documentation and standards. Remember that when _not_ to use a component is just as important as when you should use it.

## Quick Activity for getting started

> Our design system offers _______[kit scope]_______
> released as _______[kit outputs]_____
> and documented at _______[kit doc site]_____
> produced by _______[people]_________
> in order to serve _______[products]_______
> Our design system offers **\_\_\_**[kit scope]**\_\_\_**
> released as **\_\_\_**[kit outputs]**\_**
> and documented at **\_\_\_**[kit doc site]**\_**
> produced by **\_\_\_**[people]\***\*\_\*\***
> in order to serve **\_\_\_**[products]**\_\_\_**
> products and experiences.

# To infinity and beyond

As the design system grows and evolves it enables us to work in interesting and new ways. 
As the design system grows and evolves it enables us to work in interesting and new ways.

## Giving Back

One great thing about a design system is that it can live out in the open. It's a great way to represent your Product/Engineering brand and give back to the community. 
One great thing about a design system is that it can live out in the open. It's a great way to represent your Product/Engineering brand and give back to the community.

## DesignOps



@@ 73,8 75,7 @@ DesignOps (also called div-ops!), much like DevOps, is a fast-growing field. A d

## Full Stack Design systems

> When you’re creating a bespoke Design System for a specific product, you have the opportunity to not just group common UI elements together, but to actually represent your core product concepts at many levels. I call this a **Full Stack Design System.**
[[Link]](https://www.intercom.com/blog/the-full-stack-design-system/)
> When you’re creating a bespoke Design System for a specific product, you have the opportunity to not just group common UI elements together, but to actually represent your core product concepts at many levels. I call this a **Full Stack Design System.** > [[Link]](https://www.intercom.com/blog/the-full-stack-design-system/)

# Tips



@@ 83,7 84,7 @@ DesignOps (also called div-ops!), much like DevOps, is a fast-growing field. A d
Get something built sooner, rather than later.

> GitHub’s design system, Primer, was being revamped internally and privately. Doing so, Diana said, was in part because her team faced Imposter Syndrome comparing Primer to the systems of matured and larger organizations like AirBnb’s DLS, Shopify’s Polaris, and the US Web Design System. Primer felt unpolished in comparison. Many components were deprecated.
**[[Link]](https://medium.com/tradecraft-traction/eight-things-you-need-to-know-about-design-systems-bae8bd884b3b)**
> **[[Link]](https://medium.com/tradecraft-traction/eight-things-you-need-to-know-about-design-systems-bae8bd884b3b)**

### Build systems, not pages



@@ 93,7 94,7 @@ The web is massive and diverse - it is no longer enough to build webpages. Inste

### Pay attention to the team's limits

We can't build a design system in a day, a sprint, or a quarter. Even starting with just a sketch file that makes the creation of new features and pages consistent is a good base. 
We can't build a design system in a day, a sprint, or a quarter. Even starting with just a sketch file that makes the creation of new features and pages consistent is a good base.

### Organization is key



@@ 112,4 113,4 @@ Have a sharable Sketch library and component library that everyone uses while wo
- [Getting executive buy-in for your design system | Inside Design Blog](https://www.invisionapp.com/inside-design/getting-executive-ok-design-system/)
- [Picking Parts, Products & People - EightShapes - Medium](https://medium.com/eightshapes-llc/picking-parts-products-people-a06721e81742)
- [Accessible Brand Colors](https://abc.useallfive.com/?ref=producthunt)
- [Sketch version control & design workflow management - Abstract](https://www.goabstract.com/)
\ No newline at end of file
- [Sketch version control & design workflow management - Abstract](https://www.goabstract.com/)