diff --git a/flake.nix b/flake.nix
index 3ba17f4..cfbacb5 100644
--- a/flake.nix
+++ b/flake.nix
@@ -39,7 +39,9 @@
           typstSource = "src/main.typ";
           typstOutput = "out/main.pdf";
 
-          fontPaths = [ ];
+          fontPaths = [
+            "${pkgs.work-sans}/share/fonts/opentype"
+          ];
 
           virtualPaths = [ ];
         };
diff --git a/src/lib/main.typ b/src/lib/main.typ
index de6a915..1743285 100644
--- a/src/lib/main.typ
+++ b/src/lib/main.typ
@@ -1,22 +1,18 @@
-#import "@preview/scienceicons:0.0.6": orcid-icon
+#import "@preview/scienceicons:0.0.6": (
+  email-icon,
+  github-icon,
+  linkedin-icon,
+  orcid-icon,
+  website-icon,
+)
 
 // based on https://github.com/stuxf/basic-typst-resume-template
 
-#let resume(
+#let common-doc(
   author: "",
-  author-position: left,
-  personal-info-position: left,
-  pronouns: "",
-  location: "",
-  email: "",
-  github: "",
-  linkedin: "",
-  phone: "",
-  personal-site: "",
-  orcid: "",
-  accent-color: "#000000",
-  font: "New Computer Modern",
+  font: "Work Sans",
   paper: "a4",
+  accent-color: "#000000",
   body,
 ) = {
   // Sets document metadata
@@ -54,7 +50,7 @@
 
   // Name will be aligned left, bold and big
   show heading.where(level: 1): it => [
-    #set align(author-position)
+    #set align(left)
     #set text(
       weight: 700,
       size: 20pt,
@@ -62,43 +58,114 @@
     #pad(it.body)
   ]
 
-  // Level 1 Heading
-  [= #(author)]
+  body
+}
 
-  // Personal Info Helper
-  let contact-item(value, prefix: "", link-type: "") = {
-    if value != "" {
-      if link-type != "" {
-        link(link-type + value)[#(prefix + value)]
-      } else {
-        value
-      }
+// Personal Info Helper
+#let contact-item(value, icon: "", prefix: "", link-type: "") = {
+  if value != "" {
+    if icon != "" {
+      icon + " "
+    }
+    if link-type != "" {
+      link(link-type + value)[#(prefix + value)]
+    } else {
+      value
     }
   }
+}
 
-  // Personal Info
+// Personal Info
+#let personal-info(
+  position: left,
+  with-icons: false,
+  separator: " | ",
+  pronouns: "",
+  phone: "",
+  location: "",
+  email: "",
+  github: "",
+  linkedin: "",
+  personal-site: "",
+  orcid: "",
+) = {
   pad(
     top: 0.25em,
-    align(personal-info-position)[
+    align(position)[
       #{
         let items = (
           contact-item(pronouns),
           contact-item(phone),
           contact-item(location),
-          contact-item(email, link-type: "mailto:"),
-          contact-item(github, link-type: "https://"),
-          contact-item(linkedin, link-type: "https://"),
-          contact-item(personal-site, link-type: "https://"),
+          contact-item(
+            email,
+            icon: if with-icons { email-icon() } else { "" },
+            link-type: "mailto:",
+          ),
+          contact-item(
+            github,
+            icon: if with-icons { github-icon() } else { "" },
+            link-type: "https://",
+          ),
+          contact-item(
+            linkedin,
+            icon: if with-icons { linkedin-icon() } else { "" },
+            link-type: "https://",
+          ),
+          contact-item(
+            personal-site,
+            icon: if with-icons { website-icon() } else { "" },
+            link-type: "https://",
+          ),
           contact-item(
             orcid,
-            prefix: [#orcid-icon(color: rgb("#AECD54"))orcid.org/],
+            icon: orcid-icon(color: rgb("#AECD54")),
+            prefix: "orcid.org/",
             link-type: "https://orcid.org/",
           ),
         )
-        items.filter(x => x != none).join("  |  ")
+        items.filter(x => x != none).join(separator)
       }
     ],
   )
+}
+
+#let resume(
+  author: "",
+  pronouns: "",
+  location: "",
+  email: "",
+  github: "",
+  linkedin: "",
+  phone: "",
+  personal-site: "",
+  orcid: "",
+  accent-color: "#000000",
+  font: "Work Sans",
+  paper: "a4",
+  body,
+) = {
+  show: common-doc.with(
+    author: author,
+    font: font,
+    paper: paper,
+    accent-color: accent-color,
+  )
+
+  // Level 1 Heading
+  [= #(author)]
+
+  personal-info(
+    position: left,
+    pronouns: pronouns,
+    location: location,
+    email: email,
+    phone: phone,
+    github: github,
+    linkedin: linkedin,
+    personal-site: personal-site,
+    orcid: orcid,
+  )
 
   // Main body.
   set par(justify: true)
@@ -106,6 +173,55 @@
   body
 }
 
+#let cover-letter(
+  author: "",
+  title: "",
+  pronouns: "",
+  location: "",
+  email: "",
+  github: "",
+  linkedin: "",
+  phone: "",
+  personal-site: "",
+  orcid: "",
+  accent-color: "#000000",
+  font: "Work Sans",
+  paper: "a4",
+  body,
+) = {
+  show: common-doc.with(
+    author: author,
+    font: font,
+    paper: paper,
+    accent-color: accent-color,
+  )
+
+  grid(
+    columns: (70%, auto),
+    [
+      #[= #(author)]
+      #if (title != "") {
+        [#text(title, fill: rgb(accent-color), size: 12pt)]
+      } \
+      #location
+    ],
+    personal-info(
+      with-icons: true,
+      position: left,
+      separator: "\n",
+      pronouns: pronouns,
+      email: email,
+      phone: phone,
+      github: github,
+      linkedin: linkedin,
+      personal-site: personal-site,
+      orcid: orcid,
+    ),
+  )
+
+  body
+}
+
 // Generic two by two component for resume
 #let generic-two-by-two(
   top-left: "",
@@ -162,7 +278,7 @@
   generic-two-by-two(
     top-left: strong(title),
     top-right: dates,
-    bottom-left: company,
+    bottom-left: emph(company),
     bottom-right: emph(location),
   )
 }
diff --git a/src/main.typ b/src/main.typ
index de53bad..0a8dd0a 100644
--- a/src/main.typ
+++ b/src/main.typ
@@ -17,8 +17,6 @@
   accent-color: "#26428b",
   font: "New Computer Modern",
   paper: "a4",
-  author-position: left,
-  personal-info-position: left,
 )
 
 == Work Experience