Rewrite site with 11ty
This commit is contained in:
		
							parent
							
								
									815d89ad49
								
							
						
					
					
						commit
						3da1f74f98
					
				
							
								
								
									
										9
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
root = true
 | 
			
		||||
 | 
			
		||||
[*]
 | 
			
		||||
end_of_line = lf
 | 
			
		||||
insert_final_newline = true
 | 
			
		||||
 | 
			
		||||
[*.{html,njk,js,scss,css}]
 | 
			
		||||
indent_style = tab
 | 
			
		||||
trim_trailing_whitespace = true
 | 
			
		||||
							
								
								
									
										61
									
								
								.eleventy.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								.eleventy.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
const eleventyNavigationPlugin = require("@11ty/eleventy-navigation");
 | 
			
		||||
const eleventySass = require("eleventy-sass");
 | 
			
		||||
const mdDefList = require("markdown-it-deflist");
 | 
			
		||||
 | 
			
		||||
module.exports = function (eleventyConfig) {
 | 
			
		||||
	eleventyConfig.setBrowserSyncConfig({
 | 
			
		||||
		files: "./_site/css/**/*.css",
 | 
			
		||||
	});
 | 
			
		||||
	eleventyConfig.addPassthroughCopy({
 | 
			
		||||
		"node_modules/bootstrap-icons/bootstrap-icons.svg":
 | 
			
		||||
			"images/bootstrap-icons.svg",
 | 
			
		||||
		"node_modules/@fortawesome/fontawesome-free/sprites":
 | 
			
		||||
			"images/fontawesome",
 | 
			
		||||
		"src/js/site.js": "js/site.js"
 | 
			
		||||
	});
 | 
			
		||||
	eleventyConfig.addPlugin(eleventyNavigationPlugin);
 | 
			
		||||
	eleventyConfig.addPlugin(eleventySass, {
 | 
			
		||||
		sass: {
 | 
			
		||||
			loadPaths: ["node_modules"],
 | 
			
		||||
		},
 | 
			
		||||
	});
 | 
			
		||||
	eleventyConfig.amendLibrary("md", mdLib => mdLib.use(mdDefList));
 | 
			
		||||
 | 
			
		||||
	eleventyConfig.addFilter("IsNotPage", (collection, url) =>
 | 
			
		||||
		collection.filter(item => item.url != url));
 | 
			
		||||
	eleventyConfig.addFilter("IsMainPageSection", (collection) => {
 | 
			
		||||
		return collection.filter(item => !item.url || item.url.startsWith("/_sections"));
 | 
			
		||||
	});
 | 
			
		||||
	eleventyConfig.addFilter("IsNotMainPageSection", (collection) => {
 | 
			
		||||
		return collection.filter(item => item.url != null && (item.data.tags == null || !item.data.tags.includes("MainPage")));
 | 
			
		||||
	});
 | 
			
		||||
	eleventyConfig.addFilter("orderBySectionOrder", (collection) =>
 | 
			
		||||
		collection.sort((a, b) => a.data.sectionOrder - b.data.sectionOrder)
 | 
			
		||||
	);
 | 
			
		||||
	eleventyConfig.addFilter("filterDrafts", collection => {
 | 
			
		||||
		if (process.env.BUILD_DRAFTS === true) {
 | 
			
		||||
			console.log("Skipping filtering drafts");
 | 
			
		||||
 | 
			
		||||
			return collection;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return collection.filter(item => {
 | 
			
		||||
			console.log(item);
 | 
			
		||||
 | 
			
		||||
			if (item.data.draft != null) {
 | 
			
		||||
				return !item.data.draft;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
	eleventyConfig.addFilter("log", (value) => console.log(value));
 | 
			
		||||
 | 
			
		||||
	console.log("BUILD_DRAFTS: " + process.env.BUILD_DRAFTS);
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		dir: {
 | 
			
		||||
			input: "src",
 | 
			
		||||
		},
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										33
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,4 +1,29 @@
 | 
			
		|||
static/lib/
 | 
			
		||||
static/info.php
 | 
			
		||||
.vscode/
 | 
			
		||||
public/
 | 
			
		||||
# Node.js files
 | 
			
		||||
node_modules/
 | 
			
		||||
 | 
			
		||||
# Built files
 | 
			
		||||
/_site/
 | 
			
		||||
 | 
			
		||||
# MacOS files
 | 
			
		||||
.DS_Store
 | 
			
		||||
.AppleDouble
 | 
			
		||||
.LSOverride
 | 
			
		||||
 | 
			
		||||
# Thumbnails
 | 
			
		||||
._*
 | 
			
		||||
 | 
			
		||||
# Files that might appear in the root of a volume
 | 
			
		||||
.DocumentRevisions-V100
 | 
			
		||||
.fseventsd
 | 
			
		||||
.Spotlight-V100
 | 
			
		||||
.TemporaryItems
 | 
			
		||||
.Trashes
 | 
			
		||||
.VolumeIcon.icns
 | 
			
		||||
.com.apple.timemachine.donotpresent
 | 
			
		||||
 | 
			
		||||
# Directories potentially created on remote AFP share
 | 
			
		||||
.AppleDB
 | 
			
		||||
.AppleDesktop
 | 
			
		||||
Network Trash Folder
 | 
			
		||||
Temporary Items
 | 
			
		||||
.apdisk
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								.nova/Configuration.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.nova/Configuration.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								.nova/Tasks/Eleventy.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.nova/Tasks/Eleventy.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
{
 | 
			
		||||
  "actions" : {
 | 
			
		||||
    "build" : {
 | 
			
		||||
      "enabled" : true,
 | 
			
		||||
      "script" : "npm install\nnpm run build"
 | 
			
		||||
    },
 | 
			
		||||
    "clean" : {
 | 
			
		||||
      "enabled" : true,
 | 
			
		||||
      "script" : "rm -r _site\nnpm clean-install"
 | 
			
		||||
    },
 | 
			
		||||
    "run" : {
 | 
			
		||||
      "enabled" : true,
 | 
			
		||||
      "script" : "npm install\nnpm start"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "environment" : {
 | 
			
		||||
    "BUILD_DRAFTS" : "false"
 | 
			
		||||
  },
 | 
			
		||||
  "openLogOnRun" : "fail",
 | 
			
		||||
  "persistent" : true
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
# Personal Website
 | 
			
		||||
# Personal Site
 | 
			
		||||
 | 
			
		||||
The files for my personal site at [neilbrommer.com](https://neilbrommer.com).
 | 
			
		||||
The source for my personal website at [neilbrommer.com](https://neilbrommer.com).
 | 
			
		||||
 | 
			
		||||
Built using [Hugo](https://gohugo.io/), [Bootstrap 4](https://getbootstrap.com/) and [FontAwesome 5](https://fontawesome.com/).
 | 
			
		||||
Built using [11ty](https://www.11ty.dev/).
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
+++
 | 
			
		||||
title = "{{ replace .Name '-' ' ' | title }}"
 | 
			
		||||
date = {{ .Date }}
 | 
			
		||||
draft = true
 | 
			
		||||
+++
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
languageCode = "en-us"
 | 
			
		||||
title = "Neil Brommer"
 | 
			
		||||
baseURL = "https://neilbrommer.com/"
 | 
			
		||||
enableGitInfo = true
 | 
			
		||||
enableRobotsTXT = true
 | 
			
		||||
googleAnalytics = "UA-105178749-1"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
+++
 | 
			
		||||
title = "Neil Brommer"
 | 
			
		||||
date = 2018-05-12T09:37:22-07:00
 | 
			
		||||
draft = false
 | 
			
		||||
[menu]
 | 
			
		||||
	[menu.main]
 | 
			
		||||
	title = "Home"
 | 
			
		||||
	weight = -100
 | 
			
		||||
+++
 | 
			
		||||
 | 
			
		||||
Recent graduate from <a href="https://www.ewu.edu/" target="_blank">Eastern Washington University</a> with a Bachelor of Science in Computer Science
 | 
			
		||||
| 
						 | 
				
			
			@ -1,44 +0,0 @@
 | 
			
		|||
+++
 | 
			
		||||
title = "Contact"
 | 
			
		||||
date = 2018-05-12T11:58:21-07:00
 | 
			
		||||
draft = false
 | 
			
		||||
[menu]
 | 
			
		||||
	[menu.main]
 | 
			
		||||
	weight = -70
 | 
			
		||||
+++
 | 
			
		||||
 | 
			
		||||
<div id="successAlert" class="alert alert-success" role="alert" style="display: none;">Message sent successfully!</div>
 | 
			
		||||
<div id="errorAlert" class="alert alert-danger" role="alert" style="display: none"></div>
 | 
			
		||||
 | 
			
		||||
<form id="contactForm" class="jumbotron border rounded p-1 p-sm-4">
 | 
			
		||||
	<div class="form-group">
 | 
			
		||||
		<label for="nameField">Name
 | 
			
		||||
			<span class="required">*</span>
 | 
			
		||||
		</label>
 | 
			
		||||
		<input id="nameField" type="text" required="required" class="form-control">
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="form-group">
 | 
			
		||||
		<label for="emailField">Email Address
 | 
			
		||||
			<span class="required">*</span>
 | 
			
		||||
		</label>
 | 
			
		||||
		<input id="emailField" type="email" required="required" class="form-control">
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="form-group">
 | 
			
		||||
		<label for="subjectField">Subject</label>
 | 
			
		||||
		<input id="subjectField" type="text" class="form-control">
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="form-group">
 | 
			
		||||
		<label for="messageField">Message
 | 
			
		||||
			<span class="required">*</span>
 | 
			
		||||
		</label>
 | 
			
		||||
		<textarea id="messageField" rows="5" required="required" class="form-control"></textarea>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="form-group captcha">
 | 
			
		||||
		<div class="g-recaptcha" data-sitekey="6LfFATcUAAAAAJ_YZ3qvYWqrtOUHmCItq-azzV3x"></div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<button id="contactSubmit" type="submit" class="btn btn-primary">Submit</button>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<script src='https://www.google.com/recaptcha/api.js'></script>
 | 
			
		||||
<script src="/js/contact.js"></script>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
+++
 | 
			
		||||
title = "Links"
 | 
			
		||||
date = 2018-05-12T14:28:21-07:00
 | 
			
		||||
draft = false
 | 
			
		||||
description = "A list of links (mostly to articles) that I find useful or interesting."
 | 
			
		||||
[menu]
 | 
			
		||||
	[menu.main]
 | 
			
		||||
	weight = -80
 | 
			
		||||
+++
 | 
			
		||||
 | 
			
		||||
{{< linkCardList >}}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,91 +0,0 @@
 | 
			
		|||
+++
 | 
			
		||||
title = "Resume"
 | 
			
		||||
date = 2018-05-12T11:48:46-07:00
 | 
			
		||||
draft = false
 | 
			
		||||
description = """
 | 
			
		||||
References and more contact information available on request via the [contact page](/contact).
 | 
			
		||||
 | 
			
		||||
PDF version available [here](/NeilBrommer-WebResume.pdf)"""
 | 
			
		||||
[menu]
 | 
			
		||||
	[menu.main]
 | 
			
		||||
	weight = -90
 | 
			
		||||
+++
 | 
			
		||||
 | 
			
		||||
## Education
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
	<div class="row">
 | 
			
		||||
		<div class="col-sm-8">
 | 
			
		||||
			<b>Eastern Washington University</b>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="col-sm-4">
 | 
			
		||||
			<b class="float-sm-right">Cheney, Washington</b>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="row">
 | 
			
		||||
		<div class="col-sm-8">
 | 
			
		||||
			<i>Bachelor of Science in Computer Science, 3.52 GPA</i>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="col-sm-4">
 | 
			
		||||
			<i class="float-sm-right">2014 – 2018</i>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
	<div class="row">
 | 
			
		||||
		<div class="col-sm-8">
 | 
			
		||||
			<b>Spokane Community College</b>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="col-sm-4">
 | 
			
		||||
			<b class="float-sm-right">Spokane, Washington</b>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="row">
 | 
			
		||||
		<div class="col-sm-8">
 | 
			
		||||
			<i>Associate of Applied Science in Network Design and Administration, 3.13 GPA</i>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="col-sm-4">
 | 
			
		||||
			<i class="float-sm-right">2011 – 2013</i>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	Networking with Cisco switches and routers, with basic Windows and Linux administration
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Relevant Coursework and Skills
 | 
			
		||||
 | 
			
		||||
<ul class="row">
 | 
			
		||||
	<li class="col-md-6">Object-Oriented Languages – Java, C#, C++</li>
 | 
			
		||||
	<li class="col-md-6">Object-Oriented design patterns</li>
 | 
			
		||||
	<li class="col-md-6">GUI Programming – JavaFX, WinForms, WPF</li>
 | 
			
		||||
	<li class="col-md-6">Databases – SQL, Database Design</li>
 | 
			
		||||
	<li class="col-md-6">Web Development – HTML, CSS, JavaScript, JQuery, PHP, REST APIs</li>
 | 
			
		||||
	<li class="col-md-6">Operating Systems – C, Unix, threads and processes, memory management</li>
 | 
			
		||||
	<li class="col-md-6">Software Engineering</li>
 | 
			
		||||
	<li class="col-md-6">Version Control Systems – Git</li>
 | 
			
		||||
	<li class="col-md-6">Network Programming – Network sockets, binary protocols</li>
 | 
			
		||||
	<li class="col-md-6">Data Mining</li>
 | 
			
		||||
	<li class="col-md-6">Linux Administration – Basic system maintenance, Email, DNS</li>
 | 
			
		||||
	<li class="col-md-6">Windows Administration – MS Exchange, Active Directory</li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Projects
 | 
			
		||||
 | 
			
		||||
See the [projects](/#projects) list
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Certifications
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
	<div style="font-weight: bold;">CCNA</div>
 | 
			
		||||
	<div class="row">
 | 
			
		||||
		<div class="col-sm-8">
 | 
			
		||||
			<i>Cisco Certified Network Administrator</i>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="col-sm-4">
 | 
			
		||||
			<i class="float-sm-right">September 2013 – 2016</i>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	Cisco’s second level of computer networking certifications. Focuses on designing and managing routed and switched networks.
 | 
			
		||||
</p>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
[[link]]
 | 
			
		||||
	title = "Ok→Cancel versus Cancel→Ok"
 | 
			
		||||
	description = "A look at button ordering in GUIs from the Factorio blog"
 | 
			
		||||
	URL = "https://www.factorio.com/blog/post/fff-246"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "Principles of Lighting and Rendering with John Carmack at QuakeCon 2013"
 | 
			
		||||
	description = "John Carmack talking about various 3D rendering concepts."
 | 
			
		||||
	URL = "https://www.youtube.com/watch?v=IyUgHPs86XM"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "Why the Flash Crash Really Matters"
 | 
			
		||||
	description = "An article on the flash crash of 2010 and the <a href=\"https://en.wikipedia.org/wiki/High-frequency_trading\" target=\"_blank\">high-frequency trading</a> programs that caused it."
 | 
			
		||||
	URL = "http://nautil.us/issue/23/dominoes/why-the-flash-crash-really-matters"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "Algorithms and Bias: Q. and A. With Cynthia Dwork"
 | 
			
		||||
	description = "An interview with Cynthia Dwork of Microsoft Research on how algorithms show bias and where those biases come from."
 | 
			
		||||
	URL = "https://www.nytimes.com/2015/08/11/upshot/algorithms-and-bias-q-and-a-with-cynthia-dwork.html?abt=0002&abg=1"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "Origin of Quake3’s Fast InvSqrt()"
 | 
			
		||||
	description = "An article on the inverse square root function in Quake 3 looking into how it works and its history."
 | 
			
		||||
	URL = "https://www.beyond3d.com/content/articles/8/"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "Real Time Rendering: An Overview for Artists"
 | 
			
		||||
	description = "A look at various aspects of real time 3D rendering, especially in video games."
 | 
			
		||||
	URL = "https://jesshiderue4.wordpress.com/real-time-rendering-an-overview-for-artists/"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "Entering the Quantum Era—How Firefox got fast again and where it’s going to get faster"
 | 
			
		||||
	description = "An article that looks at various architectural changes to Firefox in version 57 and changes planned for future versions."
 | 
			
		||||
	URL = "https://hacks.mozilla.org/2017/11/entering-the-quantum-era-how-firefox-got-fast-again-and-where-its-going-to-get-faster/"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "The whole web at maximum FPS: How WebRender gets rid of jank "
 | 
			
		||||
	description = " An article that gives a high level description how Firefox’s new rendering engine works."
 | 
			
		||||
	URL = "https://hacks.mozilla.org/2017/10/the-whole-web-at-maximum-fps-how-webrender-gets-rid-of-jank/"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "Inside a super fast CSS engine: Quantum CSS (aka Stylo)"
 | 
			
		||||
	description = "A high level overview of how Firefox’s new CSS engine Stylo works."
 | 
			
		||||
	URL = "https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-engine-quantum-css-aka-stylo/"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "The Judge’s Code"
 | 
			
		||||
	description = "An article on Judge William Alsup, who was the judge for the first <a href=\"https://en.wikipedia.org/wiki/Oracle_America,_Inc._v._Google,_Inc.\" target=\"_blank\"> Oracle v. Google</a> case over whether an API can be copywritten, and is now the judge for the <a href=\"http://www.businessinsider.com/google-waymo-v-uber-case-explained-2017-5\" target=\"_blank\">Waymo (Google) v. Uber</a>."
 | 
			
		||||
	URL = "https://www.theverge.com/2017/10/19/16503076/oracle-vs-google-judge-william-alsup-interview-waymo-uber"
 | 
			
		||||
 | 
			
		||||
[[link]]
 | 
			
		||||
	title = "LinkedIn Dark Patterns"
 | 
			
		||||
	description = "An in depth blog post detailing how LinkedIn used dark patterns to trick users."
 | 
			
		||||
	URL = "https://schlosser.io/writing/linkedin-dark-patterns/"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,78 +0,0 @@
 | 
			
		|||
[[project]]
 | 
			
		||||
	title = "Growing Neighbors"
 | 
			
		||||
	incomplete = false
 | 
			
		||||
	description = "The website for the Growing Neighbors organization in Spokane, WA. I worked as part of a team building this site."
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Site"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://growingneighbors.org/"
 | 
			
		||||
 | 
			
		||||
[[project]]
 | 
			
		||||
	title = "Snippets"
 | 
			
		||||
	incomplete = true
 | 
			
		||||
	description = "A web based tool for managing reusable pieces of code and useful programming resources"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Web Client"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://snippets.neilbrommer.com/"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Documentation"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://snippets.neilbrommer.com/documentation.html"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Source Code"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://github.com/NeilBrommer/SnippetManager"
 | 
			
		||||
 | 
			
		||||
[[project]]
 | 
			
		||||
	title = "Start"
 | 
			
		||||
	incomplete = false
 | 
			
		||||
	description = "A new tab page that displays lists of links using the browser's indexedDB to store all data"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Site"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://start.neilbrommer.com/"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Source Code"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://github.com/NeilBrommer/NewTabPage"
 | 
			
		||||
 | 
			
		||||
[[project]]
 | 
			
		||||
	title = "Picture Viewer"
 | 
			
		||||
	incomplete = false
 | 
			
		||||
	description = "A Windows program for viewing image files written using C# and WPF"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Source Code"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://github.com/NeilBrommer/PictureViewer"
 | 
			
		||||
 | 
			
		||||
[[project]]
 | 
			
		||||
	title = "Website"
 | 
			
		||||
	incomplete = false
 | 
			
		||||
	description = "The source code for this website"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Source Code"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://github.com/NeilBrommer/Personal-Site"
 | 
			
		||||
 | 
			
		||||
[[project]]
 | 
			
		||||
	title = "Resume"
 | 
			
		||||
	incomplete = false
 | 
			
		||||
	description = "My [Resume](resume)"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "PDF"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "/NeilBrommer-WebResume.pdf"
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Source Code"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://github.com/NeilBrommer/Resume"
 | 
			
		||||
 | 
			
		||||
[[project]]
 | 
			
		||||
	title = "Auto Dark"
 | 
			
		||||
	incomplete = false
 | 
			
		||||
	description = "A small utility for setting/toggling the Windows 10 dark theme. Useful in combination with the Windows Task Scheduler to automatically change the theme."
 | 
			
		||||
	[[project.links]]
 | 
			
		||||
		title = "Source Code"
 | 
			
		||||
		external = true
 | 
			
		||||
		URL = "https://github.com/NeilBrommer/WindowsAutoDark"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
github = "https://github.com/NeilBrommer"
 | 
			
		||||
linkedin = "https://www.linkedin.com/in/neilbrommer/"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
{{ partial "htmlhead" . }}
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
	{{ partial "navbar" .}}
 | 
			
		||||
 | 
			
		||||
	<div class="container">
 | 
			
		||||
		{{ if isset .Params "description" }}
 | 
			
		||||
			<div class="jumbotron">
 | 
			
		||||
				<h1 id="title" class="display-4 mb-4">{{ .Title }}</h1>
 | 
			
		||||
 | 
			
		||||
				{{ .Params.description | markdownify }}
 | 
			
		||||
			</div>
 | 
			
		||||
		{{ else }}
 | 
			
		||||
			<h1 class="display-4 mb-4">{{ .Title }}</h1>
 | 
			
		||||
		{{ end }}
 | 
			
		||||
 | 
			
		||||
		{{.Content}}
 | 
			
		||||
	</div>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,26 +0,0 @@
 | 
			
		|||
{{ partial "htmlhead" . }}
 | 
			
		||||
<link href="/css/index.css" rel="stylesheet">
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
	{{ partial "navbar" . }}
 | 
			
		||||
 | 
			
		||||
	<div id="header" class="text-center">
 | 
			
		||||
		<div id="headerContent" class="container">
 | 
			
		||||
			<h1 id="title" class="display-4 font-weight-normal">{{ .Title }}</h1>
 | 
			
		||||
			<div class="lead"> {{ .Content }} </div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div class="container">
 | 
			
		||||
		<h1 id="projects" class="mb-4">Projects</h1>
 | 
			
		||||
 | 
			
		||||
		<div class="card-columns">
 | 
			
		||||
			{{ range .Site.Data.projects.project }}
 | 
			
		||||
				{{ partial "projectCard" . }}
 | 
			
		||||
			{{ end }}
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,41 +0,0 @@
 | 
			
		|||
<!DOCTYPE HTML>
 | 
			
		||||
 | 
			
		||||
<html lang='{{ .Site.Language.Lang | default "en-us" }}'>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>{{ if eq (.Site.Title) (.Title) }}{{ .Site.Title }}{{ else }}{{ .Site.Title }} · {{ .Title }}{{ end }}</title>
 | 
			
		||||
		<meta charset="utf-8" />
 | 
			
		||||
		<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
 | 
			
		||||
 | 
			
		||||
		<meta name="author" content="Neil Brommer">
 | 
			
		||||
		<link rel="icon" href="/favicon.ico">
 | 
			
		||||
 | 
			
		||||
		<!-- theme colors -->
 | 
			
		||||
		<!-- Chrome, Firefox OS and Opera -->
 | 
			
		||||
		<meta name="theme-color" content="#3f51b5">
 | 
			
		||||
		<!-- Windows Phone -->
 | 
			
		||||
		<meta name="msapplication-navbutton-color" content="#3f51b5">
 | 
			
		||||
		<!-- iOS -->
 | 
			
		||||
		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
 | 
			
		||||
 | 
			
		||||
		<!-- Bootstrap -->
 | 
			
		||||
		<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		<!-- font awesome -->
 | 
			
		||||
		<script defer src="/lib/fontawesome/svg-with-js/js/fa-brands.js"></script>
 | 
			
		||||
		<script defer src="/lib/fontawesome/svg-with-js/js/fa-regular.js"></script>
 | 
			
		||||
		<script defer src="/lib/fontawesome/svg-with-js/js/fa-solid.js"></script>
 | 
			
		||||
		<script src="/lib/fontawesome/svg-with-js/js/fontawesome.js"></script>
 | 
			
		||||
 | 
			
		||||
		<!-- Custom styles for this site -->
 | 
			
		||||
		<link href="/css/main.css" rel="stylesheet">
 | 
			
		||||
 | 
			
		||||
		<!-- Bootstrap core JavaScript -->
 | 
			
		||||
		<script src="/lib/jquery/jquery-3.2.1.js"></script>
 | 
			
		||||
		<script src="/lib/popper/popper.js"></script>
 | 
			
		||||
		<script src="/lib/bootstrap/js/bootstrap.min.js"></script>
 | 
			
		||||
 | 
			
		||||
		<!-- Custom JS -->
 | 
			
		||||
		<script src="/js/main.js"></script>
 | 
			
		||||
 | 
			
		||||
		{{ template "_internal/google_analytics_async.html" . }}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
<div class="card">
 | 
			
		||||
	<h4 class="card-header">{{ .title }}</h4>
 | 
			
		||||
	<div class="card-body">
 | 
			
		||||
		<p><a class="card-link" href="{{ .URL }}" target="_blank">Link</a></p>
 | 
			
		||||
 | 
			
		||||
		{{ if isset . "description" }}
 | 
			
		||||
			<p>{{ .description | markdownify }}</p>
 | 
			
		||||
		{{ end }}
 | 
			
		||||
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,47 +0,0 @@
 | 
			
		|||
<nav id="topnav" class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
 | 
			
		||||
	<div class="container">
 | 
			
		||||
		<a class="navbar-brand" href="/">{{ .Site.Title }}</a>
 | 
			
		||||
		<button class="navbar-toggler mr-0 ml-auto" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse"
 | 
			
		||||
		 aria-expanded="false" aria-label="Toggle navigation">
 | 
			
		||||
			<span class="navbar-toggler-icon"></span>
 | 
			
		||||
		</button>
 | 
			
		||||
		<div class="collapse navbar-collapse" id="navbarCollapse">
 | 
			
		||||
			<ul class="navbar-nav mr-auto">
 | 
			
		||||
 | 
			
		||||
				{{ $currentPage := . }}
 | 
			
		||||
				{{ range .Site.Menus.main }}
 | 
			
		||||
				<li class="nav-item {{if or ($currentPage.IsMenuCurrent "main" .) ($currentPage.HasMenuCurrent "main" .) }} active{{end}}">
 | 
			
		||||
					<a class="nav-link" href="{{ .URL }}">{{.Title}}</a>
 | 
			
		||||
				</li>
 | 
			
		||||
				{{ end }}
 | 
			
		||||
 | 
			
		||||
			</ul>
 | 
			
		||||
 | 
			
		||||
			<ul id="social-menu" class="navbar-nav">
 | 
			
		||||
				{{ with .Site.Data.social }}
 | 
			
		||||
					{{ with .github }}
 | 
			
		||||
					<li class="nav-item">
 | 
			
		||||
						<a class="nav-link" href="{{ . }}" target="_blank" title="GitHub">
 | 
			
		||||
							<span class="fab fa-github-alt"></span>
 | 
			
		||||
						</a>
 | 
			
		||||
					</li>
 | 
			
		||||
					{{ end }}
 | 
			
		||||
					{{ with .linkedin }}
 | 
			
		||||
					<li class="nav-item">
 | 
			
		||||
						<a class="nav-link" href="{{ . }}" target="_blank" title="LinkedIn">
 | 
			
		||||
							<span class="fab fa-linkedin"></span>
 | 
			
		||||
						</a>
 | 
			
		||||
					</li>
 | 
			
		||||
					{{ end }}
 | 
			
		||||
				{{ end }}
 | 
			
		||||
 | 
			
		||||
				<li class="nav-item ml-auto">
 | 
			
		||||
					<button id="btnTheme" type="button" class="btn btn-dark" aria-pressed="false" autocomplete="off">
 | 
			
		||||
						<span id="themeText" class="fas fa-moon"></span>
 | 
			
		||||
					</button>
 | 
			
		||||
				</li>
 | 
			
		||||
			</ul>
 | 
			
		||||
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</nav>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,24 +0,0 @@
 | 
			
		|||
<div class="card">
 | 
			
		||||
	<h4 class="card-header">{{ .title }}</h4>
 | 
			
		||||
	<div class="card-body">
 | 
			
		||||
		{{ if .incomplete }}
 | 
			
		||||
			<p class="text-danger"><small>Incomplete</small></p>
 | 
			
		||||
		{{ end }}
 | 
			
		||||
 | 
			
		||||
		{{ if isset . "description" }}
 | 
			
		||||
			<p>{{ .description | markdownify }}</p>
 | 
			
		||||
		{{ end }}
 | 
			
		||||
 | 
			
		||||
		{{ if isset . "links" }}
 | 
			
		||||
			{{ range .links }}
 | 
			
		||||
				<a class="card-link" href="{{ .URL }}"
 | 
			
		||||
						{{ if and (isset . "external") (eq .external true) }}
 | 
			
		||||
						target="_blank"
 | 
			
		||||
						{{ end }}
 | 
			
		||||
						>
 | 
			
		||||
					{{ .title }}
 | 
			
		||||
				</a>
 | 
			
		||||
			{{ end }}
 | 
			
		||||
		{{ end }}
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +0,0 @@
 | 
			
		|||
{{ with $.Site.Data.links }}
 | 
			
		||||
 | 
			
		||||
<div class="card-columns">
 | 
			
		||||
	{{ range .link }}
 | 
			
		||||
		{{ partial "linkCard" . }}
 | 
			
		||||
	{{ end }}
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{{ end }}
 | 
			
		||||
							
								
								
									
										4232
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										4232
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										25
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
{
 | 
			
		||||
  "name": "websiterewrite",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "watch": "npx @11ty/eleventy --serve",
 | 
			
		||||
    "start": "open http://localhost:8080 & npm run watch",
 | 
			
		||||
    "build": "npx @11ty/eleventy"
 | 
			
		||||
  },
 | 
			
		||||
  "keywords": [],
 | 
			
		||||
  "author": "",
 | 
			
		||||
  "license": "ISC",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@11ty/eleventy": "^2.0.0",
 | 
			
		||||
    "@11ty/eleventy-navigation": "^0.3.5",
 | 
			
		||||
    "eleventy-sass": "^2.2.3",
 | 
			
		||||
    "markdown-it-deflist": "^2.1.0"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@fortawesome/fontawesome-free": "^6.4.0",
 | 
			
		||||
    "bootstrap-icons": "^1.10.5",
 | 
			
		||||
    "normalize.css": "^8.0.1"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								src/_data/layout.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/_data/layout.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
module.exports = "../_includes/layouts/layout.njk";
 | 
			
		||||
							
								
								
									
										46
									
								
								src/_data/projects.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/_data/projects.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
[
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Start",
 | 
			
		||||
    "description": "A new tab page that displays lists of links using the browser’s indexedDB to store all data",
 | 
			
		||||
    "links": [
 | 
			
		||||
      {
 | 
			
		||||
        "title": "Site",
 | 
			
		||||
        "url": "https://start.neilbrommer.com/"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "Source Code",
 | 
			
		||||
        "url": "https://github.com/NeilBrommer/NewTabPage"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Blazor Start",
 | 
			
		||||
    "description": "A work in progress rewrite of the Start project using Blazor WebAssembly",
 | 
			
		||||
    "links": [
 | 
			
		||||
      {
 | 
			
		||||
        "title": "Source Code",
 | 
			
		||||
        "url": "https://github.com/NeilBrommer/BlazorStart"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Website",
 | 
			
		||||
    "description": "The source code for this website",
 | 
			
		||||
    "links": [
 | 
			
		||||
      {
 | 
			
		||||
        "title": "Source Code",
 | 
			
		||||
        "url": "https://github.com/NeilBrommer/Personal-Site"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Auto Dark",
 | 
			
		||||
    "description": "A small utility for setting/toggling the Windows 10 dark theme. Useful in combination with the Windows Task Scheduler to automatically change the theme.",
 | 
			
		||||
    "links": [
 | 
			
		||||
      {
 | 
			
		||||
        "title": "Source Code",
 | 
			
		||||
        "url": "https://github.com/NeilBrommer/WindowsAutoDark"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										17
									
								
								src/_data/socialLinks.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/_data/socialLinks.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
[
 | 
			
		||||
	{
 | 
			
		||||
		"name": "GitHub",
 | 
			
		||||
		"icon": "github",
 | 
			
		||||
		"url": "https://github.com/NeilBrommer"
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		"name": "CodePen",
 | 
			
		||||
		"icon": "codepen",
 | 
			
		||||
		"url": "https://codepen.io/NeilBrommer"
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		"name": "LinkedIn",
 | 
			
		||||
		"icon": "linkedin",
 | 
			
		||||
		"url": "https://www.linkedin.com/in/neilbrommer/"
 | 
			
		||||
	}
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										87
									
								
								src/_includes/layouts/layout.njk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/_includes/layouts/layout.njk
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
<!doctype html>
 | 
			
		||||
<html lang="en-US">
 | 
			
		||||
<head>
 | 
			
		||||
	<meta charset="utf-8">
 | 
			
		||||
	<meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
	<meta name="author" content="Neil Brommer">
 | 
			
		||||
	<meta name="description" content="The personal website of Neil Brommer">
 | 
			
		||||
 | 
			
		||||
	<title>
 | 
			
		||||
		{% if (title is defined) and (page.url != "/") %}
 | 
			
		||||
			{{ title }} - Neil Brommer
 | 
			
		||||
		{% else %}
 | 
			
		||||
			Neil Brommer
 | 
			
		||||
		{% endif %}
 | 
			
		||||
	</title>
 | 
			
		||||
 | 
			
		||||
	<link rel="stylesheet" href="{{ '/css/site.css' | url }}">
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
	<header>
 | 
			
		||||
		<nav class="navbar" aria-label="Main Menu">
 | 
			
		||||
			<ul class="siteNav">
 | 
			
		||||
				{% for section in collections.MainPage | filterDrafts | eleventyNavigation %}
 | 
			
		||||
					<li {% if section.url == page.url %}class="active"{% endif %}>
 | 
			
		||||
						<a href="/#{{ section.title | slugify }}">
 | 
			
		||||
							{% if section.icon is defined %}
 | 
			
		||||
								<svg class="bi" fill="currentColor" role="img">
 | 
			
		||||
									<use xlink:href="/images/fontawesome/solid.svg#{{ section.icon }}" />
 | 
			
		||||
								</svg>
 | 
			
		||||
							{% endif %}
 | 
			
		||||
							{{ section.title }}
 | 
			
		||||
						</a>
 | 
			
		||||
					</li>
 | 
			
		||||
				{% endfor %}
 | 
			
		||||
 | 
			
		||||
				{% set standalonePages = collections.all | filterDrafts | IsNotMainPageSection | eleventyNavigation %}
 | 
			
		||||
 | 
			
		||||
				{% if standalonePages | length %}
 | 
			
		||||
					<li><hr /></li>
 | 
			
		||||
 | 
			
		||||
					{% for standalonePage in standalonePages %}
 | 
			
		||||
						<li {% if standalonePage.url == page.url %}class="active"{% endif %}>
 | 
			
		||||
							<a href="{{ standalonePage.url }}">
 | 
			
		||||
								{% if standalonePage.icon is defined %}
 | 
			
		||||
									<svg class="bi" fill="currentColor" role="img">
 | 
			
		||||
										<use xlink:href="/images/fontawesome/solid.svg#{{ standalonePage.icon }}" />
 | 
			
		||||
									</svg>
 | 
			
		||||
								{% endif %}
 | 
			
		||||
 | 
			
		||||
								{{ standalonePage.title }}
 | 
			
		||||
							</a>
 | 
			
		||||
						</li>
 | 
			
		||||
					{% endfor %}
 | 
			
		||||
				{% endif %}
 | 
			
		||||
			</ul>
 | 
			
		||||
 | 
			
		||||
			<ul class="externalNav">
 | 
			
		||||
				{% for externalLink in socialLinks %}
 | 
			
		||||
					<li>
 | 
			
		||||
						<a href="{{ externalLink.url }}" title="{{ externalLink.name }}">
 | 
			
		||||
							<svg class="bi" fill="currentColor" role="img">
 | 
			
		||||
								<use xlink:href="/images/fontawesome/brands.svg#{{ externalLink.icon }}" />
 | 
			
		||||
							</svg>
 | 
			
		||||
						</a>
 | 
			
		||||
					</li>
 | 
			
		||||
				{% endfor %}
 | 
			
		||||
			</ul>
 | 
			
		||||
		</nav>
 | 
			
		||||
	</header>
 | 
			
		||||
 | 
			
		||||
	<main>
 | 
			
		||||
		<h1 id="{{ title | slugify }}">
 | 
			
		||||
			{{ title }}
 | 
			
		||||
 | 
			
		||||
			<button class="sidebar-toggle" onclick="setSidebar()">
 | 
			
		||||
				<svg class="bi" fill="currentColor" role="img" aria-label="Toggle Main Menu">
 | 
			
		||||
					<use xlink:href="/images/bootstrap-icons.svg#layout-sidebar-inset" />
 | 
			
		||||
				</svg>
 | 
			
		||||
			</button>
 | 
			
		||||
		</h1>
 | 
			
		||||
 | 
			
		||||
		{{ content | safe }}
 | 
			
		||||
	</main>
 | 
			
		||||
 | 
			
		||||
	<script type="text/javascript" src="/js/site.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										30
									
								
								src/_sections/Colors.njk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/_sections/Colors.njk
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
---
 | 
			
		||||
title: Colors
 | 
			
		||||
eleventyNavigation:
 | 
			
		||||
  key: Colors
 | 
			
		||||
  icon: eye-dropper
 | 
			
		||||
  order: 3
 | 
			
		||||
tags: [ "MainPage" ]
 | 
			
		||||
sectionOrder: 3
 | 
			
		||||
draft: true
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<div class="color-blocks">
 | 
			
		||||
	<div class="color-block" style="background-color: var(--primary-dark-color); color: white;">
 | 
			
		||||
		Primary Dark
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="color-block" style="background-color: var(--primary-color); color: white;">
 | 
			
		||||
		Primary
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="color-block" style="background-color: var(--primary-light-color); color: black;">
 | 
			
		||||
		Primary Light
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="color-block" style="background-color: var(--complementary-color); color: black">
 | 
			
		||||
		Complementary
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
	<input type="checkbox" id="testCheckBox" name="testCheckBox" checked />
 | 
			
		||||
	<label for="testCheckBox">This checkbox has the accent color</label>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										11
									
								
								src/_sections/Contact.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/_sections/Contact.md
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
---
 | 
			
		||||
title: Contact
 | 
			
		||||
eleventyNavigation:
 | 
			
		||||
  key: Contact
 | 
			
		||||
  icon: envelope
 | 
			
		||||
  order: 2
 | 
			
		||||
tags: [ "MainPage" ]
 | 
			
		||||
sectionOrder: 2
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
Send an email to `contact @ this site`
 | 
			
		||||
							
								
								
									
										25
									
								
								src/_sections/Projects.njk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/_sections/Projects.njk
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
---
 | 
			
		||||
title: Projects
 | 
			
		||||
eleventyNavigation:
 | 
			
		||||
  key: Projects
 | 
			
		||||
  icon: screwdriver-wrench
 | 
			
		||||
  order: 1
 | 
			
		||||
tags: [ "MainPage" ]
 | 
			
		||||
sectionOrder: 1
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<div class="row-lg-3">
 | 
			
		||||
	{% for project in projects %}
 | 
			
		||||
		<section class="col card">
 | 
			
		||||
			<h3>{{ project.name }}</h3>
 | 
			
		||||
			<p>{{ project.description }}</p>
 | 
			
		||||
			<ul class="card-links">
 | 
			
		||||
				{% for link in project.links %}
 | 
			
		||||
					<li>
 | 
			
		||||
						<a href="{{ link.url }}" target="_blank">{{ link.title }}</a>
 | 
			
		||||
					</li>
 | 
			
		||||
				{% endfor %}
 | 
			
		||||
			</ul>
 | 
			
		||||
		</section>
 | 
			
		||||
	{% endfor %}
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										3
									
								
								src/_sections/_sections.11tydata.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/_sections/_sections.11tydata.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
{
 | 
			
		||||
	"permalink": false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								src/_sections/main.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/_sections/main.md
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
---
 | 
			
		||||
title: Neil Brommer
 | 
			
		||||
sectionOrder: 0
 | 
			
		||||
tags: [ "MainPage" ]
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
Full-stack web developer at [Washington State University](https://wsu.edu)
 | 
			
		||||
							
								
								
									
										71
									
								
								src/css/Components/_base.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/css/Components/_base.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
@use '_variables';
 | 
			
		||||
 | 
			
		||||
*,
 | 
			
		||||
::before,
 | 
			
		||||
::after {
 | 
			
		||||
	box-sizing: border-box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html {
 | 
			
		||||
	scroll-behavior: smooth;
 | 
			
		||||
 | 
			
		||||
	@media (prefers-reduced-motion: reduce) {
 | 
			
		||||
		scroll-behavior: auto;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
	font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto,
 | 
			
		||||
		"Helvetica Neue", sans-serif;
 | 
			
		||||
	line-height: 1.5;
 | 
			
		||||
	color: var(--text-color);
 | 
			
		||||
	background-color: var(--background-color);
 | 
			
		||||
	accent-color: var(--primary-color);
 | 
			
		||||
 | 
			
		||||
	@media (min-width: #{variables.$sidebar-breakpoint}) {
 | 
			
		||||
		display: flex;
 | 
			
		||||
		gap: 2rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
header {
 | 
			
		||||
	height: 100dvh;
 | 
			
		||||
	flex: 0 0 var(--sidebar-width);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main {
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	max-width: 70em;
 | 
			
		||||
	padding: 2rem;
 | 
			
		||||
	margin-left: auto;
 | 
			
		||||
	margin-right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a {
 | 
			
		||||
	color: var(--primary-color);
 | 
			
		||||
	text-decoration: underline;
 | 
			
		||||
	text-decoration-thickness: 2px;
 | 
			
		||||
	text-underline-offset: 0.25em;
 | 
			
		||||
	text-decoration-color: transparent;
 | 
			
		||||
	transition: text-decoration-color 200ms ease;
 | 
			
		||||
 | 
			
		||||
	&:hover,
 | 
			
		||||
	&:active {
 | 
			
		||||
		text-decoration-color: var(--primary-color);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@media (prefers-contrast: more) {
 | 
			
		||||
		color: var(--primary-color-dark);
 | 
			
		||||
		text-decoration-color: var(--primary-color);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@media (prefers-reduced-motion: reduce) {
 | 
			
		||||
		text-decoration-color: var(--primary-color);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
hr {
 | 
			
		||||
	border: none;
 | 
			
		||||
	height: 1px;
 | 
			
		||||
	background-color: var(--primary-border-color);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								src/css/Components/_bootstrap-icons.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/css/Components/_bootstrap-icons.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
// this allows changing the size using font-size
 | 
			
		||||
.bi {
 | 
			
		||||
	width: 1em;
 | 
			
		||||
	height: 1em;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								src/css/Components/_card.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/css/Components/_card.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
@use '_variables';
 | 
			
		||||
 | 
			
		||||
.card {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: column;
 | 
			
		||||
	padding: 1rem;
 | 
			
		||||
	margin-bottom: 1rem;
 | 
			
		||||
	border: solid 1px var(--primary-border-color);
 | 
			
		||||
	border-radius: var(--main-border-radius);
 | 
			
		||||
 | 
			
		||||
	h1, h2, h3, h4, h5, h6 {
 | 
			
		||||
		margin-bottom: 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	.card-links {
 | 
			
		||||
		display: flex;
 | 
			
		||||
		flex-direction: row;
 | 
			
		||||
		flex-wrap: wrap;
 | 
			
		||||
		gap: 0.5em;
 | 
			
		||||
		margin: auto -1rem -1rem -1rem;
 | 
			
		||||
		padding: 0.5rem;
 | 
			
		||||
		border-top: solid 1px var(--primary-border-color);
 | 
			
		||||
		list-style: none;
 | 
			
		||||
 | 
			
		||||
		li a {
 | 
			
		||||
			display: inline-block;
 | 
			
		||||
			padding: 0.5em 1em;
 | 
			
		||||
			text-decoration: none;
 | 
			
		||||
			border-radius: var(--main-border-radius);
 | 
			
		||||
			transition: background-color 200ms ease;
 | 
			
		||||
 | 
			
		||||
			&:hover, &:focus {
 | 
			
		||||
				background-color: var(--nav-hover-background);
 | 
			
		||||
 | 
			
		||||
				@media (prefers-reduced-motion: reduce) {
 | 
			
		||||
					background-color: transparent;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@media (prefers-contrast: more),
 | 
			
		||||
				(prefers-reduced-motion: reduce) {
 | 
			
		||||
				text-decoration: underline;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								src/css/Components/_code.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/css/Components/_code.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
@use 'variables';
 | 
			
		||||
 | 
			
		||||
$code-background-color: darken(variables.$background-color, 5%);
 | 
			
		||||
$code-background-color-dark: lighten(variables.$background-color-dark, 5%);
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
	--code-background: #{$code-background-color};
 | 
			
		||||
 | 
			
		||||
	@media (prefers-color-scheme: dark) {
 | 
			
		||||
		--code-background: #{$code-background-color-dark};
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code {
 | 
			
		||||
	background: var(--code-background);
 | 
			
		||||
	padding: 0.125em 0.25em;
 | 
			
		||||
	border: solid 1px var(--primary-border-color);
 | 
			
		||||
	border-radius: calc(var(--main-border-radius) / 2);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/css/Components/_color-block.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/css/Components/_color-block.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
@use '_variables';
 | 
			
		||||
 | 
			
		||||
.color-blocks {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: row;
 | 
			
		||||
	flex-wrap: wrap;
 | 
			
		||||
	justify-content: space-between;
 | 
			
		||||
	gap: 1rem;
 | 
			
		||||
	margin-bottom: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.color-block {
 | 
			
		||||
	flex: 1 1 0;
 | 
			
		||||
	height: 100px;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	justify-content: center;
 | 
			
		||||
	white-space: nowrap;
 | 
			
		||||
	border: solid 1px var(--primary-border-color);
 | 
			
		||||
	border-radius: var(--main-border-radius);
 | 
			
		||||
	padding: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/css/Components/_columns.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/css/Components/_columns.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
@use '_variables';
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
	--column-spacing: 1.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.row {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-wrap: wrap;
 | 
			
		||||
	gap: var(--column-spacing);
 | 
			
		||||
 | 
			
		||||
	.col {
 | 
			
		||||
		flex: 0 0 100%;
 | 
			
		||||
 | 
			
		||||
		// Default to md
 | 
			
		||||
		@media (min-width: #{variables.$size-md}) {
 | 
			
		||||
			flex: 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@mixin row($name, $breakpoint) {
 | 
			
		||||
	.row-#{$name} {
 | 
			
		||||
		display: flex;
 | 
			
		||||
		flex-wrap: wrap;
 | 
			
		||||
		align-items: flex-start;
 | 
			
		||||
		gap: var(--column-spacing);
 | 
			
		||||
 | 
			
		||||
		.col {
 | 
			
		||||
			flex: 0 0 100%;
 | 
			
		||||
 | 
			
		||||
			@media (min-width: #{$breakpoint}) {
 | 
			
		||||
				flex: 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@for $i from 1 through 12 {
 | 
			
		||||
		.row-#{$name}-#{$i} {
 | 
			
		||||
			display: flex;
 | 
			
		||||
			flex-wrap: wrap;
 | 
			
		||||
			gap: var(--column-spacing);
 | 
			
		||||
 | 
			
		||||
			.col {
 | 
			
		||||
				flex: 0 0 100%;
 | 
			
		||||
 | 
			
		||||
				@media (min-width: #{$breakpoint}) {
 | 
			
		||||
					// Even width filling the whole row accounting for gap
 | 
			
		||||
					flex: 0 0 calc((100% / #{$i}) - (var(--column-spacing) / #{$i} * (#{$i} - 1)));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@include row("xs", #{variables.$size-xs});
 | 
			
		||||
@include row("sm", #{variables.$size-sm});
 | 
			
		||||
@include row("md", #{variables.$size-md});
 | 
			
		||||
@include row("lg", #{variables.$size-lg});
 | 
			
		||||
@include row("xl", #{variables.$size-xl});
 | 
			
		||||
@include row("2x", #{variables.$size-2x});
 | 
			
		||||
							
								
								
									
										8
									
								
								src/css/Components/_headings.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/css/Components/_headings.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
h1, h2, h3, h4, h5, h6 {
 | 
			
		||||
	font-weight: 500;
 | 
			
		||||
	margin-top: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 {
 | 
			
		||||
	font-size: 3em;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								src/css/Components/_lists.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/css/Components/_lists.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
ul {
 | 
			
		||||
	padding-inline-start: 1.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
li {
 | 
			
		||||
	margin: 0.25em 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl {
 | 
			
		||||
	dt {
 | 
			
		||||
		font-weight: bold;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dd {
 | 
			
		||||
		padding: 0.25em 0;
 | 
			
		||||
		margin-inline-start: 1em;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								src/css/Components/_mobile-header.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/css/Components/_mobile-header.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
@use 'variables';
 | 
			
		||||
 | 
			
		||||
h1 {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: row;
 | 
			
		||||
	justify-content: space-between;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
 | 
			
		||||
	font-size: 2rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sidebar-toggle {
 | 
			
		||||
	font-size: 2rem;
 | 
			
		||||
 | 
			
		||||
	appearance: none;
 | 
			
		||||
	cursor: pointer;
 | 
			
		||||
	color: inherit;
 | 
			
		||||
	background-color: var(--background-color);
 | 
			
		||||
	border: solid 1px var(--primary-border-color);
 | 
			
		||||
	border-radius: var(--main-border-radius);
 | 
			
		||||
 | 
			
		||||
	display: flex;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	padding: 0.25em;
 | 
			
		||||
	margin: 0.25em;
 | 
			
		||||
 | 
			
		||||
	transition: background-color 200ms ease, color 200ms ease;
 | 
			
		||||
 | 
			
		||||
	&:hover, &focus {
 | 
			
		||||
		color: var(--primary-color);
 | 
			
		||||
		background-color: var(--nav-hover-background);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	&:active {
 | 
			
		||||
		background-color: var(--primary-light-color);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@media (min-width: #{variables.$sidebar-breakpoint}) {
 | 
			
		||||
		display: none;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										117
									
								
								src/css/Components/_navbar.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/css/Components/_navbar.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,117 @@
 | 
			
		|||
@use 'sass:color';
 | 
			
		||||
@use '_variables';
 | 
			
		||||
 | 
			
		||||
header {
 | 
			
		||||
	position: fixed;
 | 
			
		||||
	top: 0;
 | 
			
		||||
	left: calc((var(--sidebar-width) + 2rem) * -1);
 | 
			
		||||
	height: calc(100dvh - 2rem); // Account for margin
 | 
			
		||||
	margin: 1rem;
 | 
			
		||||
 | 
			
		||||
	border: solid 1px var(--primary-border-color);
 | 
			
		||||
	border-radius: var(--main-border-radius);
 | 
			
		||||
	background-color: rgba(var(--background-color-components), 0.5);
 | 
			
		||||
	backdrop-filter: blur(10px);
 | 
			
		||||
 | 
			
		||||
	// Goes slightly past the end, then bounces back to the final position
 | 
			
		||||
	transition: left 250ms cubic-bezier(.44,1.36,.74,.97);
 | 
			
		||||
 | 
			
		||||
	@media (prefers-reduced-motion: reduce) {
 | 
			
		||||
		transition: none;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@media (prefers-contrast: more) {
 | 
			
		||||
		backdrop-filter: none;
 | 
			
		||||
		background-color: var(--background-color);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	&[aria-hidden="false"] {
 | 
			
		||||
		left: 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@media (min-width: #{variables.$sidebar-breakpoint}) {
 | 
			
		||||
		// Always show the sidebar on larger screens
 | 
			
		||||
		position: sticky;
 | 
			
		||||
		left: unset;
 | 
			
		||||
		height: 100dvh;
 | 
			
		||||
		margin: 0;
 | 
			
		||||
 | 
			
		||||
		border: none;
 | 
			
		||||
		background-color: unset;
 | 
			
		||||
		backdrop-filter: none;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nav.navbar {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: column;
 | 
			
		||||
	justify-content: space-between;
 | 
			
		||||
 | 
			
		||||
	width: var(--sidebar-width);
 | 
			
		||||
	height: 100%;
 | 
			
		||||
	padding: 1rem;
 | 
			
		||||
	overflow: scroll;
 | 
			
		||||
 | 
			
		||||
	ul {
 | 
			
		||||
		display: flex;
 | 
			
		||||
		list-style: none;
 | 
			
		||||
		padding-left: 0;
 | 
			
		||||
 | 
			
		||||
		li {
 | 
			
		||||
			margin-bottom: 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		a {
 | 
			
		||||
			text-decoration: none;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ul.siteNav {
 | 
			
		||||
		flex-direction: column;
 | 
			
		||||
		justify-items: flex-start;
 | 
			
		||||
		gap: 0.5em;
 | 
			
		||||
 | 
			
		||||
		li {
 | 
			
		||||
			a {
 | 
			
		||||
				// Use flex to correct icon alignment
 | 
			
		||||
				display: flex;
 | 
			
		||||
				flex-direction: row;
 | 
			
		||||
				align-items: center;
 | 
			
		||||
				column-gap: 0.5em;
 | 
			
		||||
				width: 100%;
 | 
			
		||||
				padding: 0.75em;
 | 
			
		||||
				color: var(--nav-link-color);
 | 
			
		||||
				border-radius: var(--main-border-radius);
 | 
			
		||||
 | 
			
		||||
				transition: background-color 200ms ease;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			&.active a {
 | 
			
		||||
				background-color: var(--nav-active-background);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			&:not(.active) a:hover, &:not(.active) a:focus {
 | 
			
		||||
				background-color: var(--nav-hover-background);
 | 
			
		||||
 | 
			
		||||
				@media (prefers-reduced-motion: reduce) {
 | 
			
		||||
					background-color: transparent;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ul.externalNav {
 | 
			
		||||
		flex-direction: row;
 | 
			
		||||
		flex-wrap: wrap;
 | 
			
		||||
		justify-content: center;
 | 
			
		||||
		gap: 0.5em;
 | 
			
		||||
 | 
			
		||||
		li {
 | 
			
		||||
			a {
 | 
			
		||||
				display: inline-block;
 | 
			
		||||
				padding: 0 0.75em;
 | 
			
		||||
				color: var(--nav-link-color);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								src/css/Components/_variables.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/css/Components/_variables.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
@use 'sass:color';
 | 
			
		||||
 | 
			
		||||
@function select-foreground($backgroundColor, $lightColor: white, $darkColor: black) {
 | 
			
		||||
	@if (lightness($backgroundColor) > 60) {
 | 
			
		||||
		@return $darkColor;
 | 
			
		||||
	} @else {
 | 
			
		||||
		@return $lightColor;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$primary-r: 77;
 | 
			
		||||
$primary-g: 94;
 | 
			
		||||
$primary-b: 193;
 | 
			
		||||
$primary-color: rgb($primary-r, $primary-g, $primary-b);
 | 
			
		||||
$primary-light-color: lighten($primary-color, 35%);
 | 
			
		||||
$primary-dark-color: darken($primary-color, 10%);
 | 
			
		||||
$complementary-color: color.complement($primary-color);
 | 
			
		||||
 | 
			
		||||
$text-color: #3b4351;
 | 
			
		||||
$text-color-dark: white;
 | 
			
		||||
$background-color-components: 255, 255, 255;
 | 
			
		||||
$background-color: white;
 | 
			
		||||
$background-color-dark-components: 33, 33, 36;
 | 
			
		||||
$background-color-dark: rgb(33, 33, 36);
 | 
			
		||||
 | 
			
		||||
$main-border-radius: 8px;
 | 
			
		||||
 | 
			
		||||
$nav-active-background: rgba($primary-color, 0.15);
 | 
			
		||||
$nav-active-background-dark: rgba($primary-color, 0.35);
 | 
			
		||||
$nav-background-hover-color: rgba($primary-light-color, 0.2);
 | 
			
		||||
$nav-background-hover-color-dark: rgba($primary-color, 0.2);
 | 
			
		||||
$nav-link-color: $text-color;
 | 
			
		||||
$nav-link-color-dark: $text-color-dark;
 | 
			
		||||
 | 
			
		||||
$primary-border-color: darken($background-color, 15%);
 | 
			
		||||
$primary-border-color-dark: lighten($background-color-dark, 15%);
 | 
			
		||||
$primary-border-color-contrast: darken($background-color, 50%);
 | 
			
		||||
$primary-border-color-dark-contrast: lighten($background-color-dark, 50%);
 | 
			
		||||
 | 
			
		||||
$size-xs: 480px;
 | 
			
		||||
$size-sm: 600px;
 | 
			
		||||
$size-md: 840px;
 | 
			
		||||
$size-lg: 960px;
 | 
			
		||||
$size-xl: 1280px;
 | 
			
		||||
$size-2x: 1440px;
 | 
			
		||||
 | 
			
		||||
$sidebar-width: 15rem;
 | 
			
		||||
$sidebar-breakpoint: $size-md;
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
	--size-xs: 480px;
 | 
			
		||||
	--size-sm: 600px;
 | 
			
		||||
	--size-md: 840px;
 | 
			
		||||
	--size-lg: 960px;
 | 
			
		||||
	--size-xl: 1280px;
 | 
			
		||||
	--size-2x: 1440px;
 | 
			
		||||
 | 
			
		||||
	--sidebar-width: #{$sidebar-width};
 | 
			
		||||
	--sidebar-breakpoint: #{$sidebar-breakpoint};
 | 
			
		||||
	--main-border-radius: #{$main-border-radius};
 | 
			
		||||
 | 
			
		||||
	--primary-color: #{$primary-color};
 | 
			
		||||
	--primary-light-color: #{$primary-light-color};
 | 
			
		||||
	--primary-dark-color: #{$primary-dark-color};
 | 
			
		||||
	--complementary-color: #{$complementary-color};
 | 
			
		||||
 | 
			
		||||
	--primary-border-color: #{$primary-border-color};
 | 
			
		||||
 | 
			
		||||
	--text-color: #{$text-color};
 | 
			
		||||
	--background-color: #{$background-color};
 | 
			
		||||
	--background-color-components: #{$background-color-components};
 | 
			
		||||
 | 
			
		||||
	--nav-link-color: #{$nav-link-color};
 | 
			
		||||
	--nav-active-background: #{$nav-active-background};
 | 
			
		||||
	--nav-hover-background: #{$nav-background-hover-color};
 | 
			
		||||
 | 
			
		||||
	@media (prefers-color-scheme: dark) {
 | 
			
		||||
		--text-color: #{$text-color-dark};
 | 
			
		||||
		--background-color: #{$background-color-dark};
 | 
			
		||||
		--background-color-components: #{$background-color-dark-components};
 | 
			
		||||
		--primary-border-color: #{$primary-border-color-dark};
 | 
			
		||||
 | 
			
		||||
		--nav-link-color: #{$nav-link-color-dark};
 | 
			
		||||
		--nav-active-background: #{$nav-active-background-dark};
 | 
			
		||||
		--nav-hover-background: #{$nav-background-hover-color-dark};
 | 
			
		||||
 | 
			
		||||
		@media (prefers-contrast: more) {
 | 
			
		||||
			--primary-border-color: #{$primary-border-color-dark-contrast};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@media (prefers-contrast: more) {
 | 
			
		||||
		--primary-border-color: #{$primary-border-color-contrast};
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								src/css/site.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/css/site.scss
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
@use 'normalize.css/normalize';
 | 
			
		||||
 | 
			
		||||
@use 'Components/_variables';
 | 
			
		||||
@use 'Components/_base';
 | 
			
		||||
@use 'Components/_bootstrap-icons';
 | 
			
		||||
@use 'Components/_columns';
 | 
			
		||||
@use 'Components/_navbar';
 | 
			
		||||
@use 'Components/_headings';
 | 
			
		||||
@use 'Components/_card';
 | 
			
		||||
@use 'Components/_color-block';
 | 
			
		||||
@use 'Components/_mobile-header';
 | 
			
		||||
@use 'Components/_lists';
 | 
			
		||||
@use 'Components/_code';
 | 
			
		||||
							
								
								
									
										18
									
								
								src/index.njk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/index.njk
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
---
 | 
			
		||||
title: Neil Brommer
 | 
			
		||||
eleventyNavigation:
 | 
			
		||||
  key: Neil Brommer
 | 
			
		||||
  icon: house
 | 
			
		||||
  order: 0
 | 
			
		||||
tags: [ "MainPage" ]
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
{% for section in collections.MainPage | filterDrafts | IsNotPage(page.url) | IsMainPageSection | orderBySectionOrder %}
 | 
			
		||||
	{% if not loop.first %}
 | 
			
		||||
		<h2 id="{{ section.data.title | slugify }}">{{ section.data.title }}</h2>
 | 
			
		||||
	{% endif %}
 | 
			
		||||
 | 
			
		||||
	<section>
 | 
			
		||||
		{{ section.templateContent | safe }}
 | 
			
		||||
	</section>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
							
								
								
									
										48
									
								
								src/js/site.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/js/site.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
"use strict";
 | 
			
		||||
 | 
			
		||||
function dismissSidebarOnClick(event) {
 | 
			
		||||
	if (event.target.closest("header") == null && event.target.closest(".sidebar-toggle") == null) {
 | 
			
		||||
		event.stopPropagation();
 | 
			
		||||
		setSidebar(false);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setSidebar(isOpen) {
 | 
			
		||||
	let header = document.querySelector("header");
 | 
			
		||||
 | 
			
		||||
	// If isOpen isn't provided, then just toggle the sidebar
 | 
			
		||||
	if (isOpen == null) {
 | 
			
		||||
		let currentlyOpen = header.getAttribute("aria-hidden") == "false";
 | 
			
		||||
		isOpen = !currentlyOpen;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	header.setAttribute("aria-hidden", (!isOpen).toString());
 | 
			
		||||
 | 
			
		||||
	if (isOpen) {
 | 
			
		||||
		document.querySelector("body")
 | 
			
		||||
			.addEventListener("click", dismissSidebarOnClick);
 | 
			
		||||
	} else {
 | 
			
		||||
		document.querySelector("body")
 | 
			
		||||
			.removeEventListener("click", dismissSidebarOnClick);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Make main page sections active on scroll
 | 
			
		||||
 | 
			
		||||
document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
	const observer = new IntersectionObserver(entries => {
 | 
			
		||||
		entries.forEach(entry => {
 | 
			
		||||
			const id = entry.target.previousElementSibling.id;
 | 
			
		||||
			const menuListItem = document.querySelector(`nav li a[href="/#${id}"]`).parentElement;
 | 
			
		||||
 | 
			
		||||
			if (entry.intersectionRatio > 0) {
 | 
			
		||||
				menuListItem.classList.add("active");
 | 
			
		||||
			} else {
 | 
			
		||||
				menuListItem.classList.remove("active");
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	document.querySelectorAll("h1[id] + section, h2[id] + section, h3[id] + section, h4[id] + section, h5[id] + section, h6[id] + section")
 | 
			
		||||
		.forEach(section => observer.observe(section));
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										48
									
								
								src/resume.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/resume.md
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
---
 | 
			
		||||
title: Resume
 | 
			
		||||
eleventyNavigation:
 | 
			
		||||
  key: Resume
 | 
			
		||||
  icon: file-lines
 | 
			
		||||
  order: 2
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## Work History
 | 
			
		||||
 | 
			
		||||
[Washington State University](https://wsu.edu) [Division of Student Affairs](https://studentaffairs.wsu.edu/)
 | 
			
		||||
 | 
			
		||||
:	Application Developer, 2018 - present
 | 
			
		||||
:	Created and maintained custom web applications either as standalone software or integrating with
 | 
			
		||||
	third party backends
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Education
 | 
			
		||||
 | 
			
		||||
[Eastern Washington University](https://www.ewu.edu/)
 | 
			
		||||
 | 
			
		||||
:	Bachelor of Science in Computer Science
 | 
			
		||||
:	2014 - 2018
 | 
			
		||||
 | 
			
		||||
[Spokane Community College](https://scc.spokane.edu/)
 | 
			
		||||
 | 
			
		||||
:	Associate of Applied Science in Network Design and Administration
 | 
			
		||||
:	2011 - 2013
 | 
			
		||||
 | 
			
		||||
## Skills
 | 
			
		||||
 | 
			
		||||
* C# - .NET Framework and .NET 5+
 | 
			
		||||
	* [ASP.NET and ASP.NET Core](https://dotnet.microsoft.com/en-us/apps/aspnet) - [WebForms](https://learn.microsoft.com/en-us/aspnet/web-forms/what-is-web-forms), [MVC](https://dotnet.microsoft.com/en-us/apps/aspnet/mvc), [Razor Pages](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/?view=aspnetcore-7.0&tabs=visual-studio), and [WebAPI](https://learn.microsoft.com/en-us/aspnet/core/web-api/)
 | 
			
		||||
	* Entity Framework and [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/)
 | 
			
		||||
	* [Blazor WebAssembly](https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor)
 | 
			
		||||
	* WinForms and WPF
 | 
			
		||||
	* Xamarin native for MacOS
 | 
			
		||||
* Version control
 | 
			
		||||
	* Git
 | 
			
		||||
	* [Team Foundation Server/Azure DevOps Server](https://azure.microsoft.com/en-us/products/devops/server)
 | 
			
		||||
* Web development
 | 
			
		||||
	* HTML, CSS, JavaScript, [SASS](https://sass-lang.com/), [TypeScript](https://www.typescriptlang.org/)
 | 
			
		||||
	* [React](https://react.dev/)
 | 
			
		||||
	* Create and consume REST APIs with [OpenAPI](https://www.openapis.org/), [Swashbuckle](https://github.com/domaindrivendev/Swashbuckle.AspNetCore), and [NSwag](https://github.com/RicoSuter/NSwag)
 | 
			
		||||
	* [WCF](https://learn.microsoft.com/en-us/dotnet/framework/wcf/whats-wcf)/SOAP
 | 
			
		||||
* Web server administration
 | 
			
		||||
	* Linux (NGINX, Apache, Caddy) and Windows Server (IIS)
 | 
			
		||||
	* Continuous Integration and Continuous Deployment via [Azure DevOps Server](https://azure.microsoft.com/en-us/products/devops/server)
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -1,113 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
use PHPMailer\PHPMailer\PHPMailer;
 | 
			
		||||
use PHPMailer\PHPMailer\Exception;
 | 
			
		||||
 | 
			
		||||
require 'PHPMailer/src/Exception.php';
 | 
			
		||||
require 'PHPMailer/src/PHPMailer.php';
 | 
			
		||||
require 'PHPMailer/src/SMTP.php';
 | 
			
		||||
 | 
			
		||||
include_once "info.php";
 | 
			
		||||
 | 
			
		||||
if ($_SERVER["REQUEST_METHOD"] == 'POST') {
 | 
			
		||||
	if (isset($_POST["captcha"]) && !empty($_POST["captcha"])) {
 | 
			
		||||
 | 
			
		||||
		$captcha = $_POST["captcha"];
 | 
			
		||||
		$url = "https://www.google.com/recaptcha/api/siteverify";
 | 
			
		||||
		$data = array(
 | 
			
		||||
			"secret" => $recaptchaSecret,
 | 
			
		||||
			"response" => $captcha,
 | 
			
		||||
			"remoteip" => $_SERVER["REMOTE_ADDR"]
 | 
			
		||||
		);
 | 
			
		||||
		$options = array(
 | 
			
		||||
			"http" => array(
 | 
			
		||||
				"header" => "Content-Type: application/x-www-form-urlencoded\r\n",
 | 
			
		||||
				"method" => "POST",
 | 
			
		||||
				"content" => http_build_query($data)
 | 
			
		||||
			)
 | 
			
		||||
		);
 | 
			
		||||
		$context = stream_context_create($options);
 | 
			
		||||
		$result = file_get_contents($url, false, $context);
 | 
			
		||||
		if ($result === false) {
 | 
			
		||||
			http_response_code(500);
 | 
			
		||||
			die("Error verifying reCAPTCHA");
 | 
			
		||||
		}
 | 
			
		||||
		$result = json_decode($result, true);
 | 
			
		||||
 | 
			
		||||
		if ($result["success"] == false) {
 | 
			
		||||
			http_response_code(400);
 | 
			
		||||
			die("Could not verify reCAPTCHA");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		if (!isset($_POST["name"])) {
 | 
			
		||||
			http_response_code(400);
 | 
			
		||||
			die("A name is required");
 | 
			
		||||
		}
 | 
			
		||||
		$name = trim($_POST["name"]);
 | 
			
		||||
		if ($name == '') {
 | 
			
		||||
			http_response_code(400);
 | 
			
		||||
			die("The name cannot be empty");
 | 
			
		||||
		} else if (strtolower($name) == 'anon' || strToLower($name) == 'anonymous') {
 | 
			
		||||
			http_response_code(400);
 | 
			
		||||
			die("Enter a real name");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!isset($_POST["email"])) {
 | 
			
		||||
			http_response_code(400);
 | 
			
		||||
			die("An email address is required");
 | 
			
		||||
		}
 | 
			
		||||
		$email = trim($_POST["email"]);
 | 
			
		||||
		if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
 | 
			
		||||
			http_response_code(400);
 | 
			
		||||
			die("Invalid email address");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$subject = "Message from contact form";
 | 
			
		||||
		if (isset($_POST["subject"]) && trim($_POST["subject"]) != "") {
 | 
			
		||||
			$subject = $subject . ": " . $_POST["subject"];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!isset($_POST["message"])) {
 | 
			
		||||
			http_response_code(400);
 | 
			
		||||
			die("A message is required");
 | 
			
		||||
		}
 | 
			
		||||
		$message = trim($_POST["message"]);
 | 
			
		||||
		if ($message == '') {
 | 
			
		||||
			http_response_code(400);
 | 
			
		||||
			die("A message is required");
 | 
			
		||||
		}
 | 
			
		||||
		$message = $name . ' -- <' . $email . '><hr>' . $message;
 | 
			
		||||
 | 
			
		||||
		$mail = new PHPMailer(true); // true enables exceptions
 | 
			
		||||
		try {
 | 
			
		||||
			$mail->isSMTP();
 | 
			
		||||
			//$mail->SMTPDebug = 3;
 | 
			
		||||
			$mail->Host = $mailHost;
 | 
			
		||||
			$mail->SMTPAuth = true;
 | 
			
		||||
			$mail->Username = $mailUser;
 | 
			
		||||
			$mail->Password = $mailPass;
 | 
			
		||||
			$mail->SMTPSecure = 'ssl';
 | 
			
		||||
			$mail->Port = $mailPort;
 | 
			
		||||
 | 
			
		||||
			$mail->setFrom($mailFrom, 'Website Contact Form');
 | 
			
		||||
			$mail->addAddress($mailDest);
 | 
			
		||||
			$mail->addReplyTo($email);
 | 
			
		||||
 | 
			
		||||
			$mail->isHTML(true);
 | 
			
		||||
			$mail->Subject = $subject;
 | 
			
		||||
			$mail->Body = $message;
 | 
			
		||||
 | 
			
		||||
			$mail->Send();
 | 
			
		||||
		} catch (Exception $e) {
 | 
			
		||||
			http_response_code(500);
 | 
			
		||||
			echo 'Message could not be sent.';
 | 
			
		||||
			echo 'Mailer Error: ' . $mail->ErrorInfo;
 | 
			
		||||
		}
 | 
			
		||||
	} else { // no recaptcha
 | 
			
		||||
		http_response_code(400);
 | 
			
		||||
		echo "Bad reCAPTCHA";
 | 
			
		||||
	}
 | 
			
		||||
} else {
 | 
			
		||||
	http_response_code(404);
 | 
			
		||||
}
 | 
			
		||||
?>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,26 +0,0 @@
 | 
			
		|||
body {
 | 
			
		||||
	padding-top: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#header {
 | 
			
		||||
	padding: 10vw 2rem;
 | 
			
		||||
	margin-bottom: 2rem;
 | 
			
		||||
 | 
			
		||||
	color: white;
 | 
			
		||||
	text-shadow: 1px 1px 2px gray;
 | 
			
		||||
 | 
			
		||||
	box-shadow: 0 1px 3px rgba(0,0,0,0.16), 0 1px 3px rgba(0,0,0,0.23);
 | 
			
		||||
	background: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url('/img/trianglify.svg');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#headerContent {
 | 
			
		||||
	padding-top: 70px; /* account for nav bar */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#header a {
 | 
			
		||||
	color: #a10022 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#title {
 | 
			
		||||
	margin-bottom: 2rem;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,149 +0,0 @@
 | 
			
		|||
:root {
 | 
			
		||||
	--main-color: #3f51b5;       /* R:63,  G:82,  B:181 */
 | 
			
		||||
	--main-dark-color: #002984;  /* R:0,   G:41,  B:132 */
 | 
			
		||||
	--main-light-color: #757de8; /* R:117, G:125, B:232 */
 | 
			
		||||
	--accent-color: #FFC107;     /* R:255, G:193, B:7   */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
	padding-top: 70px;
 | 
			
		||||
	padding-bottom: 40px;
 | 
			
		||||
	cursor: default;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.navbar.fixed-top {
 | 
			
		||||
	padding-top: 0;
 | 
			
		||||
	padding-bottom: 0;
 | 
			
		||||
	background-color: #3f51b5 !important;
 | 
			
		||||
	box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
 | 
			
		||||
	border-bottom: #002984 1px solid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.nav-item {
 | 
			
		||||
	padding-top: 0.5rem;
 | 
			
		||||
	padding-bottom: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media screen and (min-width: 768px) {
 | 
			
		||||
	.navbar-nav .nav-item.active {
 | 
			
		||||
		padding-bottom: 0.25rem;
 | 
			
		||||
		border-bottom: white 0.25rem solid;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#btnTheme {
 | 
			
		||||
		margin-left: 0.5rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media screen and (max-width: 767px) {
 | 
			
		||||
	.navbar-nav .nav-item.active {
 | 
			
		||||
		padding-left: 0.75rem;
 | 
			
		||||
		border-left: white 0.25rem solid;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	.navbar-nav .nav-item {
 | 
			
		||||
		padding-left: 1rem;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#social-menu {
 | 
			
		||||
		flex-direction: row;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#social-menu .nav-item:not(:first-child) {
 | 
			
		||||
		padding-left: 2rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.navbar {
 | 
			
		||||
	padding-left: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.navbar .navbar-brand {
 | 
			
		||||
	margin-top: 0.5rem;
 | 
			
		||||
	margin-bottom: 0.5rem;
 | 
			
		||||
	padding-left: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.card, .jumbotron {
 | 
			
		||||
	box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1:not(.card-header):not(#title), h2:not(.card-header), h3:not(.card-header), h4:not(.card-header), h5:not(.card-header), h6:not(.card-header) {
 | 
			
		||||
	margin-top: 30px;
 | 
			
		||||
	margin-bottom: 15px;
 | 
			
		||||
	padding-bottom: 10px;
 | 
			
		||||
	border-bottom: 1px solid rgba(0, 0, 0, 0.1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a:not(.nav-link):not(.navbar-brand) {
 | 
			
		||||
	color: #3f51b5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a:hover:not(.nav-link):not(.navbar-brand) {
 | 
			
		||||
	color: #757de8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
li.col-md-6 {
 | 
			
		||||
	padding-left: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.cover {
 | 
			
		||||
	text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.required {
 | 
			
		||||
	color: red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.invalid-captcha {
 | 
			
		||||
	box-shadow: 0 0 1.5px 1px red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fa {
 | 
			
		||||
	font-size: 0.85rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.full-height {
 | 
			
		||||
	height: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Dark Mode */
 | 
			
		||||
 | 
			
		||||
.dark-mode {
 | 
			
		||||
	color: white;
 | 
			
		||||
	background-color: #343a40;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-mode .jumbotron {
 | 
			
		||||
	background-color: #2b3136;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-mode a:not(.navbar-brand):not(.nav-link) {
 | 
			
		||||
	color: #757de8 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-mode a:not(.navbar-brand):not(.nav-link):hover {
 | 
			
		||||
	color: #3f51b5 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-mode .card {
 | 
			
		||||
	background-color: #343a40;
 | 
			
		||||
	border-color: rgba(255, 255, 255, 0.125);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-mode .form-control {
 | 
			
		||||
	background-color: rgb(81, 89, 107);
 | 
			
		||||
	border-color: rgb(60, 66, 80);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-mode .form-control:focus {
 | 
			
		||||
	box-shadow: 0 0 0 .2rem rgba(255,255,255,.5);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* for transitioning to/from dark mode */
 | 
			
		||||
.transition {
 | 
			
		||||
	-webkit-transition: color 0.25s ease-in-out, background-color 0.25s ease-in-out, box-shadow 0.25s ease-in-out, border 0.25s ease-in-out;
 | 
			
		||||
	-moz-transition: color 0.25s ease-in-out, background-color 0.25s ease-in-out, box-shadow 0.25s ease-in-out, border 0.25s ease-in-out;
 | 
			
		||||
	-o-transition: color 0.25s ease-in-out, background-color 0.25s ease-in-out, box-shadow 0.25s ease-in-out, border 0.25s ease-in-out;
 | 
			
		||||
	transition: color 0.25s ease-in-out, background-color 0.25s ease-in-out, box-shadow 0.25s ease-in-out, border 0.25s ease-in-out;
 | 
			
		||||
}
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 5.4 KiB  | 
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 Before Width: | Height: | Size: 98 KiB  | 
| 
						 | 
				
			
			@ -1,65 +0,0 @@
 | 
			
		|||
$(document).ready(function() {
 | 
			
		||||
	$("#contactForm").on("submit", sendForm);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function sendForm(e) {
 | 
			
		||||
	e.preventDefault(); // prevent the page from refreshing
 | 
			
		||||
 | 
			
		||||
	$("#contactSubmit").prop("disabled", true);
 | 
			
		||||
 | 
			
		||||
	if ($("#successAlert")[0].style.display != 'none') {
 | 
			
		||||
		$("#successAlert").slideUp(250);
 | 
			
		||||
	}
 | 
			
		||||
	if ($("#errorAlert")[0].style.display != 'none') {
 | 
			
		||||
		$("#errorAlert").slideUp(250);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var captcha = grecaptcha.getResponse();
 | 
			
		||||
	if (captcha.length == 0) {
 | 
			
		||||
		$(".captcha").addClass("invalid-captcha");
 | 
			
		||||
	} else {
 | 
			
		||||
		$(".captcha").removeClass("invalid-captcha");
 | 
			
		||||
 | 
			
		||||
		var name = $("#nameField").val();
 | 
			
		||||
		var email = $("#emailField").val();
 | 
			
		||||
		var subject = $("#subjectField").val();
 | 
			
		||||
		var message = $("#messageField").val();
 | 
			
		||||
 | 
			
		||||
		$.ajax({
 | 
			
		||||
			url: "../contact.php",
 | 
			
		||||
			type: "POST",
 | 
			
		||||
			data: {
 | 
			
		||||
				"name": name,
 | 
			
		||||
				"email": email,
 | 
			
		||||
				"subject": subject,
 | 
			
		||||
				"message": message,
 | 
			
		||||
				"captcha": captcha
 | 
			
		||||
			},
 | 
			
		||||
			success: messageSuccess,
 | 
			
		||||
			error: messageError,
 | 
			
		||||
			complete: doneSending
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function messageSuccess(result) {
 | 
			
		||||
	$("#successAlert").slideDown(500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function messageError(result) {
 | 
			
		||||
	var alert = $("#errorAlert");
 | 
			
		||||
	alert.empty();
 | 
			
		||||
	$(document.createTextNode("Error: " + result.responseText)).appendTo(alert);
 | 
			
		||||
	alert.slideDown(500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function doneSending() {
 | 
			
		||||
	var html = $("html");
 | 
			
		||||
	var top = html.scrollTop() + $("body").scrollTop() // Get position of the body
 | 
			
		||||
 | 
			
		||||
	if(top != 0) {
 | 
			
		||||
		$("html,body").animate({scrollTop:0}, '500');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	$("#contactSubmit").prop("disabled", false);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,67 +0,0 @@
 | 
			
		|||
var theme = window.localStorage.getItem("theme");
 | 
			
		||||
if (theme != null && theme == "true")
 | 
			
		||||
	$("body").addClass("dark-mode");
 | 
			
		||||
 | 
			
		||||
$(document).ready(function () {
 | 
			
		||||
	$("#btnTheme").click(function () {
 | 
			
		||||
		if ($("#btnTheme").hasClass("btn-light")) {
 | 
			
		||||
			transitionLight();
 | 
			
		||||
		} else {
 | 
			
		||||
			transitionDark();
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	var theme = window.localStorage.getItem("theme");
 | 
			
		||||
	if (theme != null && theme == "true")
 | 
			
		||||
		setDark();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function checkTheme() {
 | 
			
		||||
	if (theme != null && theme == "true")
 | 
			
		||||
		setDark();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function transitionDark() {
 | 
			
		||||
	$(".card").addClass("transition");
 | 
			
		||||
	$(".jumbotron").addClass("transition");
 | 
			
		||||
	$(".form-control").addClass("transition");
 | 
			
		||||
	$("a:not(.navbar-brand):not(.nav-link)").addClass("transition");
 | 
			
		||||
	$("body").addClass("transition dark-mode");
 | 
			
		||||
 | 
			
		||||
	setTimeout(endTransition, 250);
 | 
			
		||||
 | 
			
		||||
	$("#btnTheme").removeClass("btn-dark").addClass("transition btn-light");
 | 
			
		||||
	$("#themeText").replaceWith($("<span>").attr("id", "themeText").addClass("fas fa-sun"));
 | 
			
		||||
 | 
			
		||||
	window.localStorage.setItem("theme", "true");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function transitionLight() {
 | 
			
		||||
	$(".card").addClass("transition");
 | 
			
		||||
	$(".jumbotron").addClass("transition");
 | 
			
		||||
	$(".form-control").addClass("transition");
 | 
			
		||||
	$("a:not(.navbar-brand):not(.nav-link)").addClass("transition");
 | 
			
		||||
	$("body").addClass("transition").removeClass("dark-mode");
 | 
			
		||||
 | 
			
		||||
	setTimeout(endTransition, 250);
 | 
			
		||||
 | 
			
		||||
	$("#btnTheme").removeClass("btn-light").addClass("transition btn-dark");
 | 
			
		||||
	$("#themeText").replaceWith($("<span>").attr("id", "themeText").addClass("fas fa-moon"));
 | 
			
		||||
 | 
			
		||||
	window.localStorage.setItem("theme", "false");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function endTransition() {
 | 
			
		||||
	$("body").removeClass("transition");
 | 
			
		||||
	$(".card").removeClass("transition");
 | 
			
		||||
	$(".jumbotron").removeClass("transition");
 | 
			
		||||
	$("a:not(.navbar-brand):not(.nav-link)").removeClass("transition");
 | 
			
		||||
	$(".form-control").removeClass("transition");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setDark() {
 | 
			
		||||
	$("body").addClass("dark-mode");
 | 
			
		||||
 | 
			
		||||
	$("#btnTheme").removeClass("btn-dark").addClass("btn-light");
 | 
			
		||||
	$("#themeText").replaceWith($("<span>").attr("id", "themeText").addClass("fas fa-sun"));
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in a new issue