Extract CV build pipeline from madr/19 project
This commit is contained in:
commit
0959c17c95
8 changed files with 1922 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
pub
|
||||||
BIN
assets/cv-anders-englof-ytterstrom.pdf
Normal file
BIN
assets/cv-anders-englof-ytterstrom.pdf
Normal file
Binary file not shown.
246
assets/cv.css
Normal file
246
assets/cv.css
Normal file
|
|
@ -0,0 +1,246 @@
|
||||||
|
html {
|
||||||
|
font: normal small/1.5 apple-system, system-ui, BlinkMacSystemFont, Segoe UI,
|
||||||
|
Roboto, Helvetica Neue, Arial, sans-serif;
|
||||||
|
background-color: var(--bg-color, #fff);
|
||||||
|
color: var(--bg-color, #444);
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
font-size: clamp(0.9em, 1.5vw, 1.4em);
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-size: 3em;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
border-bottom: 0.3em solid #e3e3e3;
|
||||||
|
padding-bottom: 0.25em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
figure {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: var(--bg-color, #444);
|
||||||
|
transition: background-color 0.3s ease-out, border-bottom-color 0.3s ease-out;
|
||||||
|
}
|
||||||
|
p:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
a:link,
|
||||||
|
a:visited {
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid #bbb;
|
||||||
|
}
|
||||||
|
a:hover,
|
||||||
|
a:focus {
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-bottom-color: #000;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
a:active {
|
||||||
|
transform: translate(3px, 3px);
|
||||||
|
}
|
||||||
|
[href^="tel"]::before {
|
||||||
|
content: "📞 ";
|
||||||
|
}
|
||||||
|
[href^="mailto"]::before {
|
||||||
|
content: "✉️ ";
|
||||||
|
}
|
||||||
|
[href^="https://github.com"]::before
|
||||||
|
{
|
||||||
|
content: "🐙 ";
|
||||||
|
}
|
||||||
|
[href^="https://madr"]::before
|
||||||
|
{
|
||||||
|
content: "🏠 ";
|
||||||
|
}
|
||||||
|
[href$="pdf"] {
|
||||||
|
font-size: 1.1em;
|
||||||
|
padding: 0.3em;
|
||||||
|
}
|
||||||
|
[href$="pdf"]::before {
|
||||||
|
content: "📑 ";
|
||||||
|
}
|
||||||
|
[href$="pdf"]:hover::before,
|
||||||
|
[href$="pdf"]:focus::before {
|
||||||
|
background-color: rgba(0, 255, 0, 0.2);
|
||||||
|
}
|
||||||
|
[role="doc-subtitle"] {
|
||||||
|
font-size: 1.25em;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
@media (min-width: 40em) {
|
||||||
|
.h-aside {
|
||||||
|
border-bottom: 0;
|
||||||
|
font-size: 1.4em;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 1.95em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contact {
|
||||||
|
margin: 1em 0;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
|
@media (min-width: 40em) {
|
||||||
|
.contact {
|
||||||
|
margin: 0.5em 0 0;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contact > dd {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.contact > dt {
|
||||||
|
position: absolute;
|
||||||
|
left: -9999em;
|
||||||
|
}
|
||||||
|
.skillset {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5em 1em;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
}
|
||||||
|
.skillset > dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.skillset > dd {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Left for good measure, could have been gold if
|
||||||
|
the upcoming Container queries was a thing.
|
||||||
|
|
||||||
|
@media (min-width: 80em) {
|
||||||
|
.skillset {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.skillset > dt {
|
||||||
|
transform: translateY(0.2em);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
.resume {
|
||||||
|
max-width: 70em;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"name"
|
||||||
|
"about"
|
||||||
|
"skills"
|
||||||
|
"work"
|
||||||
|
"education"
|
||||||
|
"projects"
|
||||||
|
"courses"
|
||||||
|
"personal";
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
@media (min-width: 40em) {
|
||||||
|
.resume {
|
||||||
|
grid-template-columns: 2fr 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"name name"
|
||||||
|
"skills about"
|
||||||
|
"work work"
|
||||||
|
"education courses"
|
||||||
|
"projects personal";
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
grid-area: name;
|
||||||
|
display: flex;
|
||||||
|
gap: 1em;
|
||||||
|
place-items: center;
|
||||||
|
text-align: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.photo {
|
||||||
|
grid-area: photo;
|
||||||
|
}
|
||||||
|
.work {
|
||||||
|
grid-area: work;
|
||||||
|
}
|
||||||
|
.courses {
|
||||||
|
grid-area: courses;
|
||||||
|
}
|
||||||
|
.personal {
|
||||||
|
grid-area: personal;
|
||||||
|
}
|
||||||
|
.about {
|
||||||
|
grid-area: about;
|
||||||
|
background: #f1f1f1;
|
||||||
|
border-radius: 0.2em;
|
||||||
|
padding: 1em;
|
||||||
|
color: #111;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.education {
|
||||||
|
grid-area: education;
|
||||||
|
}
|
||||||
|
.projects {
|
||||||
|
grid-area: projects;
|
||||||
|
}
|
||||||
|
.skills {
|
||||||
|
grid-area: skills;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5em 0.5em;
|
||||||
|
margin: 2em 0;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event--aside {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event__title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.event__position {
|
||||||
|
font-variant: small-caps;
|
||||||
|
}
|
||||||
|
.event__content {
|
||||||
|
line-height: 1.5;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
grid-column: 1 / 3;
|
||||||
|
}
|
||||||
|
.event__aside {
|
||||||
|
text-align: right;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@page {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
size: A4 portrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
body {
|
||||||
|
padding: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
[href$="pdf"] {
|
||||||
|
display: none;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
index.js
Normal file
34
index.js
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
var Metalsmith = require("metalsmith");
|
||||||
|
var htmlMinifier = require("metalsmith-html-minifier");
|
||||||
|
var layouts = require("metalsmith-layouts");
|
||||||
|
var markdown = require("metalsmith-markdown-remarkable");
|
||||||
|
var permalinks = require("@metalsmith/permalinks");
|
||||||
|
var static = require("metalsmith-static");
|
||||||
|
|
||||||
|
Metalsmith(__dirname)
|
||||||
|
.source("./src")
|
||||||
|
.destination("./pub")
|
||||||
|
.use(
|
||||||
|
markdown({
|
||||||
|
html: true,
|
||||||
|
typographer: false,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.use(permalinks())
|
||||||
|
.use(
|
||||||
|
layouts({
|
||||||
|
engine: "handlebars",
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.use(htmlMinifier())
|
||||||
|
.use(
|
||||||
|
static({
|
||||||
|
src: "./assets",
|
||||||
|
dest: "./",
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.build(function (err, _files) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
});
|
||||||
156
layouts/cv.hbs
Normal file
156
layouts/cv.hbs
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
<html lang="en">
|
||||||
|
<!--
|
||||||
|
Welcome to the source code of the resume of Anders Ytterström!
|
||||||
|
|
||||||
|
I apologize for the ending slash (/) in the void elements, this
|
||||||
|
is due to an opinion that won't be added as an option to skip in
|
||||||
|
Prettier: https://github.com/prettier/prettier/issues/5246
|
||||||
|
|
||||||
|
Anyways, hope you fint my code entertaining to read! The _content_ is
|
||||||
|
best viewed in a web browser, though. :)
|
||||||
|
|
||||||
|
Colophon:
|
||||||
|
- Metalsmith, the pluggable static site generator.
|
||||||
|
- Prettier, for code formatting.
|
||||||
|
- Handlebars, not my favorite template engine but it does the job.
|
||||||
|
- Markdown.
|
||||||
|
- Plain old CSS, for a change.
|
||||||
|
|
||||||
|
Internet Explorer support was not considered when
|
||||||
|
creating this page. I apologize if this is an issue for you.
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>{{title}} | {{name}}</title>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta
|
||||||
|
property="og:title"
|
||||||
|
content="{{ogdesk}}"
|
||||||
|
/>
|
||||||
|
<meta property="og:description" content="CV" />
|
||||||
|
<meta property="og:image" content="fixme.jpg" />
|
||||||
|
<link rel="stylesheet" href="./cv.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<main class="resume">
|
||||||
|
<div class="name">
|
||||||
|
<header>
|
||||||
|
<hgroup>
|
||||||
|
<h1>{{name}}</h1>
|
||||||
|
<div role="doc-subtitle">{{subtitle}}</div>
|
||||||
|
</hgroup>
|
||||||
|
</header>
|
||||||
|
<footer class="vcard">
|
||||||
|
<address>{{address}}</address>
|
||||||
|
<dl class="contact">
|
||||||
|
<dt>Phone:</dt>
|
||||||
|
<dd><a href="tel:+46702169645">+46 70 216 96 45</a></dd>
|
||||||
|
<dt>Email:</dt>
|
||||||
|
<dd><a href="mailto:{{email}}">{{email}}</a></dd>
|
||||||
|
<dt>Github:</dt>
|
||||||
|
<dd><a href="https://github.com/{{github}}" rel="external" title="Github">{{github}}</a></dd>
|
||||||
|
<dt>Website:</dt>
|
||||||
|
<dd><a href="https://{{website}}" rel="external" title="Website">{{website}}</a></dd>
|
||||||
|
</dl>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
<section class="about">
|
||||||
|
<div>
|
||||||
|
{{{contents}}}
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
<a href="./cv-anders-englof-ytterstrom.pdf">Download as PDF</a>
|
||||||
|
</span>
|
||||||
|
</section>
|
||||||
|
<section class="skills">
|
||||||
|
<h2>Skills</h2>
|
||||||
|
<dl class="skillset">
|
||||||
|
{{#each skills}}
|
||||||
|
<dt>{{@key}}</dt>
|
||||||
|
<dd>{{.}}</dd>
|
||||||
|
{{/each}}
|
||||||
|
</dl>
|
||||||
|
</section>
|
||||||
|
<section class="work">
|
||||||
|
<h2>Experience</h2>
|
||||||
|
<div class="timeline">
|
||||||
|
{{#each work}}
|
||||||
|
<article class="event">
|
||||||
|
<h3 class="event__title">{{employer}}, {{type}}</h3>
|
||||||
|
<div class="event__location event__aside">{{location}}</div>
|
||||||
|
<div class="event__position">{{position}}</div>
|
||||||
|
<div class="event__date event__aside">{{date}}</div>
|
||||||
|
<div class="event__content">
|
||||||
|
<ul>
|
||||||
|
{{#each responsibilies}}
|
||||||
|
<li>{{.}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="education">
|
||||||
|
<h2>Education</h2>
|
||||||
|
<div class="timeline">
|
||||||
|
{{#each education}}
|
||||||
|
<article class="event">
|
||||||
|
<h3 class="event__title">{{institution}}</h3>
|
||||||
|
<div class="event__location event__aside">{{location}}</div>
|
||||||
|
<div class="event__position">{{graduation}}</div>
|
||||||
|
<div class="event__date event__aside">{{date}}</div>
|
||||||
|
<div class="event__content">
|
||||||
|
{{fields}}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="projects">
|
||||||
|
<h2>Projects</h2>
|
||||||
|
<div class="timeline">
|
||||||
|
{{#each projects}}
|
||||||
|
<article class="event">
|
||||||
|
<h3 class="event__title">{{name}}</h3>
|
||||||
|
<i></i>
|
||||||
|
<div class="event__position">{{context}}</div>
|
||||||
|
<div class="event__aside">{{date}}</div>
|
||||||
|
<div class="event__content">
|
||||||
|
<ul>
|
||||||
|
{{#each responsibilies}}
|
||||||
|
<li>{{.}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="courses">
|
||||||
|
<h2 class="h-aside">Courses, Conferences & Certifications</h2>
|
||||||
|
<ul>
|
||||||
|
{{#each courses}}
|
||||||
|
<li>{{.}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="personal">
|
||||||
|
<h2 class="h-aside">Personal Projects</h2>
|
||||||
|
<div class="timeline">
|
||||||
|
{{#each personal}}
|
||||||
|
<article class="event event--aside">
|
||||||
|
<h3 class="event__title">{{@key}}</h3>
|
||||||
|
<i></i>
|
||||||
|
<div class="event__content">
|
||||||
|
<p>{{.}}</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
1230
package-lock.json
generated
Normal file
1230
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
17
package.json
Normal file
17
package.json
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "madr-se-19",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "node index.js",
|
||||||
|
"start": "node dev.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@metalsmith/permalinks": "^2.2.0",
|
||||||
|
"handlebars": "^4.7.7",
|
||||||
|
"metalsmith": "^2.1.0",
|
||||||
|
"metalsmith-html-minifier": "^3.0.3",
|
||||||
|
"metalsmith-layouts": "^1.4.1",
|
||||||
|
"metalsmith-markdown-remarkable": "^1.0.2",
|
||||||
|
"metalsmith-static": "0.0.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
237
src/index.md
Normal file
237
src/index.md
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
---
|
||||||
|
skip: true
|
||||||
|
title: cv
|
||||||
|
layout: cv.hbs
|
||||||
|
name: Anders Englöf Ytterström
|
||||||
|
ogdesc: Anders Englöf Ytterström - Frontend Engineer, Full Stack Developer, Web standardista
|
||||||
|
titles: Frontend Engineer, Full Stack Developer, Web standardista
|
||||||
|
address: Balladvägen 3, 784 43 Borlänge, Sweden
|
||||||
|
email: yttan@fastmail.se
|
||||||
|
github: madr
|
||||||
|
website: madr.se
|
||||||
|
work:
|
||||||
|
- employer: PlaymakerAI
|
||||||
|
type: Data analytics SaaS
|
||||||
|
date: Nov 2023–now
|
||||||
|
location: Remote position
|
||||||
|
position: Full Stack Engineer
|
||||||
|
responsibilies:
|
||||||
|
- Part of a team consisting of Data scientists and Machine learning experts.
|
||||||
|
- DevOps, Backend programming, Frontend engineering.
|
||||||
|
- Python, NumPy, Pandas, Scikit-learn, React, MaterialUI
|
||||||
|
|
||||||
|
- employer: Stratsys
|
||||||
|
type: Process management platform (SaaS)
|
||||||
|
date: Mar 2022–Oct 2023
|
||||||
|
location: Remote position
|
||||||
|
position: Senior Frontend Architect
|
||||||
|
responsibilies:
|
||||||
|
- Part of a team consisting of Frontend architects and UX designers.
|
||||||
|
- Responsible for the design system, frontend DX and Microfrontend toolchain and architecture.
|
||||||
|
- Writing Web components with full ARIA compability, according to the spec.
|
||||||
|
- QA and manual testing with screen readers (NVDA, VoiceOver).
|
||||||
|
|
||||||
|
- employer: Iteam
|
||||||
|
type: Technical Innovation agency
|
||||||
|
date: Sep 2021–Mar 2022
|
||||||
|
location: Remote position
|
||||||
|
position: Full Stack Developer
|
||||||
|
responsibilies:
|
||||||
|
- All source code are released by a FOSS license.
|
||||||
|
- Backend programming in Node.js, TypeScript, Express and Next.js.
|
||||||
|
- Frontend development in React, Jotai, Formik, Styleguidist and Figma.
|
||||||
|
- Code labs and skill sharing.
|
||||||
|
|
||||||
|
- employer: Kundo
|
||||||
|
type: Customer service company (SaaS)
|
||||||
|
date: Mar 2017–Sep 2021
|
||||||
|
location: Stockholm, Sweden
|
||||||
|
position: Full Stack Developer
|
||||||
|
responsibilies:
|
||||||
|
- T-shaped frontend developer focusing on WCAG 2.0 AA, design and mentoring.
|
||||||
|
- "Roles besides development: Team Lead, Tech Lead and Security administrator (briefly)."
|
||||||
|
- Backend programming in Django and Phoenix, with RabbitMQ as broker/RPC and Celery as job queue.
|
||||||
|
|
||||||
|
- employer: Adeprimo
|
||||||
|
type: Digital Fullservice agency
|
||||||
|
date: Oct 2007–Feb 2017
|
||||||
|
location: Östersund, Sweden
|
||||||
|
position: Systems developer
|
||||||
|
responsibilies:
|
||||||
|
- "T-shaped Systems developer focusing on frontend and backend web development. Fields: Media, Destination, Tourism."
|
||||||
|
- High demand on customer experience and context switching.
|
||||||
|
- Distributed, remote-first teams with members located in Vaasa (Finland), Örebro (Sweden) and Östersund (Sweden).
|
||||||
|
- Consulting for startups based in Östersund and Åre, Sweden.
|
||||||
|
- Polopoly, Python, PHP, Sass, jQuery, Wordpress, SilverStripe, .NET.
|
||||||
|
|
||||||
|
- employer: Pierce
|
||||||
|
type: Ecommerce (Motocross, MC and Snowmobile accessories)
|
||||||
|
date: Mar–Jul 2015
|
||||||
|
location: Åre, Sweden
|
||||||
|
position: Web developer
|
||||||
|
responsibilies:
|
||||||
|
- Development and maintainence for 24mx.se, XLMoto.se och sledstore.se.
|
||||||
|
- .NET, C#, Azure.
|
||||||
|
|
||||||
|
- employer: Västsvensk tidningsdistribution (VTD)
|
||||||
|
type: Distribution
|
||||||
|
date: Jul–Aug 2007
|
||||||
|
location: Alingsås, Sweden
|
||||||
|
position: Newspaper carrier
|
||||||
|
responsibilies:
|
||||||
|
- Temporary summer position. Delivering Göteborgs-Posten to 300 households by foot. It rained every night.
|
||||||
|
|
||||||
|
- employer: Moment Marketing
|
||||||
|
type: Startup
|
||||||
|
date: Sep 2006–Apr 2007
|
||||||
|
location: Stockholm, Sweden
|
||||||
|
position: Web designer
|
||||||
|
responsibilies:
|
||||||
|
- Frontend development assistance. Employment by the hour.
|
||||||
|
education:
|
||||||
|
- institution: Media and Communication Science, Mid Sweden University
|
||||||
|
date: 2004–2007
|
||||||
|
location: Sundsvall, Sweden
|
||||||
|
graduation: Degree of Bachelor of Arts (incomplete)
|
||||||
|
fields: Web design, Computer science, Computer engineering, Programming (Java, C)
|
||||||
|
|
||||||
|
- institution: Staffanskolan secondary school
|
||||||
|
date: 2001–2004
|
||||||
|
location: Söderhamn, Sweden
|
||||||
|
graduation: Student degree
|
||||||
|
fields: Media programme, vocational, media production, graphical communication
|
||||||
|
|
||||||
|
skills:
|
||||||
|
Programming languages: HTML, CSS (Sass), Python, JavaScript (TypeScript), Elixir, Rust, PHP
|
||||||
|
Development process: CI/CD, Automated testing, Mentoring, Mob programming, Pair programming
|
||||||
|
Web Backend Frameworks: Django, Flask, Phoenix (LiveView), Express
|
||||||
|
Web Frontend: React, Redux, Vue, Svelte, Lit, OOCSS, BEM, Living styleguides
|
||||||
|
Build systems: Webpack, Parcel, esbuild
|
||||||
|
Content management: Wordpress, Joomla
|
||||||
|
Testing: pytest, Jest, Lighthouse, Axe, VoiceOver, Voice Assistant, NVDA, Cypress, WebDriverIO, Web Test Runner
|
||||||
|
Deployment: AWS, Docker (Podman), Kubernetes, Ansible, Terraform, Azure DevOps
|
||||||
|
"Services & Infrastructure": Nameko, RabbitMQ, Celery, Kibana, Prometheus
|
||||||
|
Databases: MySQL, Postgres, Elasticsearch, GraphQL, Influx, Timescale
|
||||||
|
Version control: Git, Subversion
|
||||||
|
Operating systems: Linux, Mac OS, Windows
|
||||||
|
Other skills: Inclusive communication, Accessibility compliance, Technical writing
|
||||||
|
Languages: Swedish (native), English (fluent)
|
||||||
|
|
||||||
|
projects:
|
||||||
|
- name: OneUX Component library
|
||||||
|
context: Senior Frontend Architect, Stratsys
|
||||||
|
date: "2022-2023"
|
||||||
|
responsibilies:
|
||||||
|
- Implement a reusable set of components as Web components (Custom element with Shadow DOM).
|
||||||
|
- Data-driven state over DOM State.
|
||||||
|
- Deployed by the MicroFrontend concept and practices.
|
||||||
|
- Fully accessible, with keyboard navigation and mouse gestures, according to the ARIA Authoring Practices guide.
|
||||||
|
- E2E/Integration tests in a set of real, headless browsers.
|
||||||
|
- Packaged as part of a NPM package and a Design system for internal frontend developers.
|
||||||
|
- Atomic Design, Microfrontends, Storybook, Custom Elements, Design Systems, Style Guides, Web Components, Lit, Vue.js, ARIA Authoring Practices guides (APG).
|
||||||
|
|
||||||
|
- name: Slussen FastAPI data adapter, Sveriges Almännytta
|
||||||
|
context: Full Stack Developer, Iteam
|
||||||
|
date: "Okt–Dec 2021"
|
||||||
|
responsibilies:
|
||||||
|
- "Turn Allmännyttan FastAPI from blob XML to compact JSON."
|
||||||
|
- The adapter was used to create a POC to joyfully report a fault of an rental object.
|
||||||
|
- Design sprint together with the stake holders.
|
||||||
|
- All code was open sourced.
|
||||||
|
- TypeScript, FastAPI, Express, React, MIT.
|
||||||
|
|
||||||
|
- name: SEO-friendly embed of knowledgebase
|
||||||
|
context: Full Stack Developer, Kundo
|
||||||
|
date: "Mar 2020–Mar 2021"
|
||||||
|
responsibilies:
|
||||||
|
- Embedded a knowledgebase on any site using a simple embed snippet, whereas the knowledgebase is embedded using fetch().
|
||||||
|
- Navigation between guides and text search included, all crawlable by googlebot.
|
||||||
|
- SPA-compliance.
|
||||||
|
- TypeScript, Jest, Google Search Console.
|
||||||
|
|
||||||
|
- name: Accessibility Statement
|
||||||
|
context: Full Stack Developer, Kundo
|
||||||
|
date: "Sep–Dec 2019"
|
||||||
|
responsibilies:
|
||||||
|
- Compliance of the EU Directive on the Accessibility of Public Sector Websites.
|
||||||
|
- Axe, W3C validators, Lighthouse, manual accessibility testing.
|
||||||
|
|
||||||
|
- name: Kubernetes migration
|
||||||
|
context: Full Stack Developer, Kundo
|
||||||
|
date: "Jan 2019–Dec 2020"
|
||||||
|
responsibilies:
|
||||||
|
- Migrating an AWS production environment (several service-modules in different programming languages, message queues and micro services) to Kubernetes, along with all in-house DevOps tooling.
|
||||||
|
- "Goals: keep one command deploys to production, keep Kibana logging, supervision of all services."
|
||||||
|
- Terraform, Ansible, Docker, Helm, Prometheus, Kubectl, Minikube.
|
||||||
|
|
||||||
|
- name: Facebook Opengraph client
|
||||||
|
context: Full Stack Developer, Kundo
|
||||||
|
date: "Sep 2017–Mar 2019"
|
||||||
|
responsibilies:
|
||||||
|
- "Integrating customer support questions posted on Facebook Pages and Messenger into the Dashboard."
|
||||||
|
- "Needed to be done asyncronously to not tamper with API credibility."
|
||||||
|
- "Python, Django, MyPy, Protobuf, RabbitMQ, Phoenix Presence+Channels, React + Redux"
|
||||||
|
|
||||||
|
- name: Security & GDPR accountable
|
||||||
|
context: Full Stack Developer, Kundo
|
||||||
|
date: "Sep 2017–Feb 2019"
|
||||||
|
responsibilies:
|
||||||
|
- Accountable for several projects to fulfil the GDPR directive up to May 25th, 2018 and onwards.
|
||||||
|
- Accountable for security processes and planning for the technical platform.
|
||||||
|
|
||||||
|
- name: Engcon pricelist
|
||||||
|
context: Interface Developer, Consultant
|
||||||
|
date: Nov 2016–Feb 2017
|
||||||
|
responsibilies:
|
||||||
|
- Prototyp-driven development of a digital version of a printed pricelist, focusing on effiency and MVP.
|
||||||
|
- Vue, Django, Twitter Bootstrap
|
||||||
|
|
||||||
|
- name: Wide Ideas
|
||||||
|
context: Full stack Developer, Consultant
|
||||||
|
date: "Aug 2011–Feb 2017"
|
||||||
|
responsibilies:
|
||||||
|
- Development of an idea management platform.
|
||||||
|
- Handled DevOps, automation of workflows, development of web interface, and backend programming.
|
||||||
|
- PHP, Pligg, Python, Flask, MongoDB, Elastic Search
|
||||||
|
|
||||||
|
- name: Östersundstidningar redesign
|
||||||
|
context: Interface Developer
|
||||||
|
date: "Mar–May 2011"
|
||||||
|
responsibilies:
|
||||||
|
- Complete redesign of 3 sites with the same locked (and oldfashioned) HTML.
|
||||||
|
- An Object-oriented CSS architecture (OOCSS) was used to create a design system and KSS-powered styleguide utilizing Sass mixins.
|
||||||
|
|
||||||
|
- name: Mktwebb
|
||||||
|
context: Interface Developer
|
||||||
|
date: "Oct 2007–Aug 2009"
|
||||||
|
responsibilies:
|
||||||
|
- Shared technical solution for a publication platform for 40 newspapers across Sweden, with Polopoly as CMS.
|
||||||
|
- Technological ownership and mentoring others to write JavaScript.
|
||||||
|
- All HTML and CSS written in collaboration with backend programmers, UX researchers and designers.
|
||||||
|
|
||||||
|
personal:
|
||||||
|
Advent of code: Every December since 2016, I challenge myself (and sometimes other collegues) to solve AOC puzzles in a programming language of my choice.
|
||||||
|
Tajm.me: As a consultant, time tracking is a crucial part of every day work, and using bad time tracking software sucks. For 5 years, I scratched my own itch. Django, DRF and Web standards at its core. Several experimental client side solutions built with D3, React, Vue, Android, iOS and GTK+. (Archived, 2012–2017)
|
||||||
|
"Baslyft, bärs & burgare": "My first Progressive Web App, with support to work fully offline once installed on a device. It's a simple app for logging reps, sets and PB's in the gym, with some nice tools built-in: 1RM calculator and KG-LBS converter. Touch-oriented design patterns, React, Redux, localStorage, ServiceWorker and other nifty Web API:s. (On hold, Sep 2019–)"
|
||||||
|
Brütal Legend: A site to track progress of owning vinyl copies os songs licensed in an epic video game. Occasionally used as a real-world example to teach TypeScript, React and Redux concepts to collegues. (On hold)
|
||||||
|
Utsökt: A simple bookmarking and read list service, with integration to RSS feeds, Pocket and Slack. Inspired by the old, more minimal version of Instapaper. Elixir, Phoenix LiveViews. (In progress)
|
||||||
|
Smed: "A pluggable static site generator, inspired by Metalsmith. The goal is to replace my own sites in Metalsmith, and to learn Rust. (In progress)"
|
||||||
|
courses:
|
||||||
|
- ElixirConf EU, Warshawa (2020, postponed due to the Coronavirus pandemic)
|
||||||
|
- Att leda utan att vara chef, Företagsakademin (2019)
|
||||||
|
- Modern React with Redux, Udemy (2017)
|
||||||
|
- Ethical Programming from Scratch, Udemy (2018)
|
||||||
|
- Android Developer Nanodegree, Udacity (2017)
|
||||||
|
- PyConf, Stockholm (2017)
|
||||||
|
- Nordic.JS, Stockholm (2014)
|
||||||
|
- TiConf, Amsterdam (2014)
|
||||||
|
- FFConf, Brighton (2012)
|
||||||
|
- DevSum, Stockholm (2012)
|
||||||
|
- Certificed Scrum Master Course, Crisp AB (2010)
|
||||||
|
---
|
||||||
|
|
||||||
|
**Anders Englöf Ytterström**, Web Developer with 16 years of passion. I strive to constantly come up with new ways of improving both products and processes for all participants in projects I am part of.
|
||||||
|
|
||||||
|
I prefer my coffee black, just like my metal, and preferably drip brewed by hand.
|
||||||
|
|
||||||
|
I also aim to be a [roadie, not a rockstar](https://www.linkedin.com/pulse/20140816105034-167544180-you-don-t-want-a-rock-star), as well as defending [boring tech](https://mcfunley.com/choose-boring-technology).
|
||||||
Loading…
Add table
Reference in a new issue