diff --git a/README.md b/README.md index aa1233e..16ec1c7 100644 --- a/README.md +++ b/README.md @@ -13,5 +13,7 @@ See `deno.jsonc` for documentation on available commands. ## TODO + * [ ] portfolio page including descriptions of big projects + * [ ] - * [ ] Fix "Quirks Mode" issue with slides styling * [ ] Unit test public/js/slides.js diff --git a/admin/build.sh b/admin/build.sh index a77ffe5..e0fc498 100755 --- a/admin/build.sh +++ b/admin/build.sh @@ -11,13 +11,7 @@ deno run --allow-env --allow-read=./ --allow-write=$PUB_DIR ./sanguine/index.ts # copy public content cp -r ./public/* $PUB_DIR -# compile css file if running locally and not in a CI environment -if [ -z $CI ];then - npx sass --style=compressed ./styles/kalisjoshua.scss $PUB_DIR/css/kalisjoshua.css -fi - # create cname file echo kalisjoshua.me > $PUB_DIR/CNAME - echo "Build complete." diff --git a/admin/dev-server.ts b/admin/dev-server.ts index a0d9791..36a17fe 100644 --- a/admin/dev-server.ts +++ b/admin/dev-server.ts @@ -1,4 +1,4 @@ -import { loadSync } from "deno/dotenv/mod.ts"; +import { loadSync } from "../deno.deps.ts"; const PUB_DIR = loadSync()["PUB_DIR"]; const server = Deno.listen({ port: 8080 }); @@ -52,7 +52,7 @@ async function serveHttp(conn: Deno.Conn) { new Response(decoder.decode(data), { headers: { ...mime }, status: 200, - }), + }) ); } catch (error) { if (error.name === Deno.errors.NotFound.name) { @@ -60,7 +60,7 @@ async function serveHttp(conn: Deno.Conn) { req.respondWith(new Response("Not found.", { status: 404 })); } else { req.respondWith( - new Response("Sorry, something went wrong.", { status: 500 }), + new Response("Sorry, something went wrong.", { status: 500 }) ); throw error; } diff --git a/admin/watchDev.ts b/admin/watchDev.ts index ec7d47e..47a752c 100644 --- a/admin/watchDev.ts +++ b/admin/watchDev.ts @@ -1,13 +1,23 @@ const DELAY = 300; let taskRunning = false; -const watched = ["admin", "content", "public", "sanguine", "styles"]; +const watched = ["admin", "content", "public", "sanguine"]; for await (const { paths } of Deno.watchFs(watched)) { if (!taskRunning) { taskRunning = true; - console.log("Change detected.", paths); + console.log("Change detected.", ...paths); - await Deno.run({ cmd: ["deno", "task", "build"] }).status(); + const command = new Deno.Command(Deno.execPath(), { + args: ["task", "build"], + stdin: "piped", + }); + + const child = command.spawn(); + + // manually close stdin + child.stdin.close(); + + await child.status; setTimeout(() => { taskRunning = false; diff --git a/content/contact.md b/content/contact.md index 83e4c10..c0092e7 100644 --- a/content/contact.md +++ b/content/contact.md @@ -3,4 +3,4 @@ * kalisjoshua@gmail.com * github.com/[kalisjoshua](https://github.com/kalisjoshua) * linkedin.com/in/[kalisjoshua](https://linkedin.com/in/kalisjoshua) - * twitter.com/[kalisjoshua](https://twitter.com/kalisjoshua) + diff --git a/content/template.html b/content/template.html index 0be25c3..2a9d0bb 100644 --- a/content/template.html +++ b/content/template.html @@ -1,4 +1,4 @@ - + @@ -12,14 +12,25 @@ - +

Skip navigation

-
+
+ {{?isResume}} +
+ Google Document +
+ {{?/}} +

${header}

I build great teams and excellent software.

@@ -33,20 +44,13 @@

${header}

@@ -130,5 +136,22 @@

${header}

+ + diff --git a/deno.jsonc b/deno.jsonc index 3164f63..09b3e6c 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -2,9 +2,7 @@ "fmt": { "files": { "include": [], - "exclude": [ - "." - ] + "exclude": ["."] } }, "tasks": { @@ -13,7 +11,7 @@ // run test coverage report "cover": "./admin/cover.sh", // watch files for changes and run build after files have been changed - "dev": "deno run --allow-read=./ --allow-run ./admin/watchDev.ts", + "dev": "deno run --allow-read --allow-run ./admin/watchDev.ts", // host published files at http://localhost:8080 "serve": "deno run --allow-env --allow-net --allow-read ./admin/dev-server.ts", // run unit tests diff --git a/package.json b/package.json index 6a374ae..17fbfe9 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ }, "name": "kalisjoshua.me", "description": "Personal website and resume for Joshua Kalis.", - "version": "11.2.1", + "version": "11.2.2", "homepage": "https://kalisjoshua.me", "repository": { "type": "git", diff --git a/public/styles/cicada.css b/public/styles/cicada.css new file mode 100644 index 0000000..f411231 --- /dev/null +++ b/public/styles/cicada.css @@ -0,0 +1,53 @@ +.cicada { + position: absolute; + z-index: -1; + + &:after { + --grad: linear-gradient( + 90deg, + var(--teal) 0%, + var(--teal) 10%, + transparent 10%, + transparent 20%, + var(--magenta) 20%, + var(--magenta) 30%, + transparent 30%, + transparent 40%, + var(--gold) 40%, + var(--gold) 50%, + transparent 50%, + transparent 60%, + var(--green) 60%, + var(--green) 70%, + var(--pink) 70%, + var(--pink) 80%, + var(--purple) 80%, + var(--purple) 90%, + transparent 90% + ); + + background-color: var(--bg); + background-image: var(--grad), var(--grad), var(--grad), var(--grad); + background-blend-mode: darken, color-burn, multiply; + background-size: 17%, 19%, 33%, 33%; + content: ""; + height: 100%; + left: 0; + position: fixed; + top: 0; + width: 100%; + z-index: 0; + } + + &:before { + background-image: linear-gradient(180deg, transparent, var(--bg) 30%); + box-shadow: inset 0 3em 3em 0 rgba(0, 0, 0, 0.2); + content: ""; + height: 100%; + left: 0; + position: fixed; + top: 0; + width: 100%; + z-index: 1; + } +} diff --git a/public/styles/kalisjoshua.css b/public/styles/kalisjoshua.css new file mode 100644 index 0000000..c02364d --- /dev/null +++ b/public/styles/kalisjoshua.css @@ -0,0 +1,283 @@ +@import "./lib/normalize.css"; +@import "./lib/h5bp.css"; + +@import "./cicada.css"; +@import "./slides.css"; + +:root { + --bg: rgb(224, 223, 209); + --bg-dark: #2a363b; + --bg-dark: #18453b; + --gold: rgba(200, 200, 50, 0.5); + --green: rgba(0, 170, 70, 0.5); + --magenta: rgba(140, 35, 70, 0.5); + --pink: rgba(163, 44, 120, 0.5); + --purple: rgba(119, 64, 152, 0.5); + --teal: rgba(50, 100, 100, 0.5); +} + +*, +*:before, +*:after { + box-sizing: border-box; +} + +html { + font-family: sans-serif; + background: var(--bg); + padding-top: 2em; + + & a { + color: var(--bg-dark); + } + + & a.anchor[aria-hidden="true"] { + display: none; + } + + & h1 { + color: var(--bg-dark); + font-weight: 100; + margin: 1ex 0 0; + + & a { + text-decoration: none; + } + } + + & pre { + & code { + background: gainsboro; + display: block; + overflow: auto; + + &[class*="language-"] { + border-radius: 1ex; + padding: 1ex; + } + } + } + + & ul { + padding-left: 2ex; + } +} + +aside { + background: #18453b; + color: #e5e5e5; + overflow: hidden; + padding: 2ex; + + & a { + color: inherit; + } + + & .dev-icons { + background: #612e3f; + border: 8px solid gainsboro; + border-left: 0; + border-right: 0; + box-shadow: inset 0 100px 100px 0px rgba(0, 0, 0, 0.2), + 0 0 100px 10px rgba(0, 0, 0, 0.5); + box-sizing: unset; + margin: 0 -2ex; + padding: 4ex 2ex; + text-align: center; + + & img { + background: white; + border-radius: 5px; + box-sizing: unset; + height: 30px; + margin: 5px; + padding: 6px; + } + } + + & #jk-logo img { + background: white; + display: table !important; + height: 150px; + margin: 10ex auto; + padding: 6px; + } + + & #pride-ally { + margin: 8ex 0; + text-align: center; + } +} + +main { + padding: 1px 1em 0; + + & h2 { + border-bottom: 1px solid; + } + + & h3 { + font-size: 100%; + font-weight: 400; + margin: 1em 0 0; + } + + & h4 { + margin: 0; + } + + & header { + & h1 { + margin-bottom: 0; + + & + p { + margin-top: 0; + } + } + } +} + +nav { + &, + & ul, + & ul li { + margin: 0 -2ex; + padding: 0 2ex; + } + + & ul li { + list-style-type: none; + margin: 0 -2ex 3px; + overflow: hidden; + padding: 0 2ex; + transition: background 300ms; + + &:hover { + background: rgba(0, 0, 0, 0.4); + } + + &.active { + background: white; + background: rgba(255, 255, 255, 0.2); + } + + & a { + cursor: pointer; + display: block; + padding: 1ex 0; + position: relative; + text-decoration: none; + + &:after { + border-top: 3ex solid transparent; + border-bottom: 3ex solid transparent; + border-right: 1.5ex solid transparent; + content: ""; + height: 0; + right: -2ex; + margin-top: -3ex; + position: absolute; + top: 50%; + transition: border 300ms; + width: 0; + z-index: 99999; + } + } + + &:hover a:after, + &.active a:after { + border-right-color: white; + } + } +} + +.layout { + background: white; +} + +@media screen and (min-width: 900px) { + .layout { + box-shadow: 2rem 6rem 3rem 2rem rgba(0, 0, 0, 0.2); + display: grid; + grid-template-areas: + "aside header" + "aside content"; + grid-template-columns: 1fr minmax(400px, 2fr); + grid-template-rows: auto; + margin: 0 auto 12em; + max-width: 120ex; + min-height: 80%; + position: relative; + z-index: 99; + + & aside { + grid-area: aside; + } + + & header { + grid-area: header; + } + } +} /* @media screen and (min-width: 900px) */ + +@media print { + @page { + margin: 0 0.5in !important; + } + + * { + color: black !important; + } + + p, + li { + font-size: 11pt; + } + + a[href]:after { + content: ""; + } + + a[href*="docs.google.com"] { + display: none; + } + + h1 { + font-size: 16pt !important; + font-weight: 900 !important; + text-align: center; + + & small { + display: block; + font-size: 11pt !important; + font-weight: 200; + + & :before { + content: "517.803.9806 - kalisjoshua@gmail.com - https://linkedin.com/in/kalisjoshua - "; + } + } + } + + h2 { + border: 0 !important; + font-size: 14pt !important; + } + + h3 { + font-size: 12pt !important; + line-height: 0 !important; + } + + aside, + header p, + .cicada, + .sr-only { + display: none; + } + + .layout { + box-shadow: unset; + display: block !important; + max-width: unset; + } +} diff --git a/styles/lib/h5bp.css b/public/styles/lib/h5bp.css similarity index 100% rename from styles/lib/h5bp.css rename to public/styles/lib/h5bp.css diff --git a/styles/lib/normalize.css b/public/styles/lib/normalize.css similarity index 100% rename from styles/lib/normalize.css rename to public/styles/lib/normalize.css diff --git a/styles/slides.css b/public/styles/slides.css similarity index 100% rename from styles/slides.css rename to public/styles/slides.css diff --git a/sanguine/collectMeta.ts b/sanguine/collectMeta.ts index 8465edb..c7dafe3 100644 --- a/sanguine/collectMeta.ts +++ b/sanguine/collectMeta.ts @@ -5,7 +5,7 @@ import { organizeContent } from "./organizeContent.ts"; type SiteContent = ReturnType; -import pkg from "../package.json" assert { type: "json" }; +import pkg from "../package.json" with { type: "json" }; type SemVer = `${number}.${number}.${number}`; diff --git a/sanguine/createRenderFn.ts b/sanguine/createRenderFn.ts index 1f3dedc..1a87baf 100644 --- a/sanguine/createRenderFn.ts +++ b/sanguine/createRenderFn.ts @@ -4,6 +4,7 @@ import { createNavigation } from "./createNavigation.ts"; interface PageContext { isActive?: (h: string) => string; isArticle?: boolean; + isResume?: boolean; main: string; navigation: Array; path?: string; @@ -33,7 +34,7 @@ function createRenderFn({ }: ReturnType) { const fill = new Function( "context", - `with(context){return \`${template.raw}\`}`, + `with(context){return \`${template.raw}\`}` ); return { diff --git a/sanguine/renderPages.ts b/sanguine/renderPages.ts index 67d8c78..8e92ed4 100644 --- a/sanguine/renderPages.ts +++ b/sanguine/renderPages.ts @@ -16,6 +16,7 @@ function genPage(siteContent: SiteContent, page: FileNodeContent) { ? "active" : "", isArticle: page.section === "articles" && page.name !== "index", + isResume: page.name === "index" && !page.section, main: marked.parse(page.raw), navigation, path, diff --git a/styles/cicada.css b/styles/cicada.css deleted file mode 100644 index a263c72..0000000 --- a/styles/cicada.css +++ /dev/null @@ -1,46 +0,0 @@ -.cicada:after { - --grad: linear-gradient(90deg, - var(--teal) 0%, - var(--teal) 10%, - transparent 10%, - transparent 20%, - var(--magenta) 20%, - var(--magenta) 30%, - transparent 30%, - transparent 40%, - var(--gold) 40%, - var(--gold) 50%, - transparent 50%, - transparent 60%, - var(--green) 60%, - var(--green) 70%, - var(--pink) 70%, - var(--pink) 80%, - var(--purple) 80%, - var(--purple) 90%, - transparent 90%); - - background-color: var(--bg); - background-image: var(--grad), var(--grad), var(--grad), var(--grad); - background-blend-mode: darken, color-burn, multiply; - background-size: 17%, 19%, 33%, 33%; - content: ""; - height: 100%; - left: 0; - position: fixed; - top: 0; - width: 100%; - z-index: 0; -} - -.cicada:before { - background-image: linear-gradient(180deg, transparent, var(--bg) 30%); - box-shadow: inset 0 3em 3em 0 rgba(0, 0, 0, 0.2); - content: ""; - height: 100%; - left: 0; - position: fixed; - top: 0; - width: 100%; - z-index: 1; -} \ No newline at end of file diff --git a/styles/colors.css b/styles/colors.css deleted file mode 100644 index bb87563..0000000 --- a/styles/colors.css +++ /dev/null @@ -1,10 +0,0 @@ -:root { - --bg: rgb(224, 223, 209); - --bg-dark: #2A363B; - --gold: rgba(200, 200, 50, 0.5); - --green: rgba(0, 170, 70, 0.5); - --magenta: rgba(140, 35, 70, 0.5); - --pink: rgba(163, 44, 120, 0.5); - --purple: rgba(119, 64, 152, 0.5); - --teal: rgba(50, 100, 100, 0.5); -} diff --git a/styles/highlight.scss b/styles/highlight.scss deleted file mode 100644 index b4ea738..0000000 --- a/styles/highlight.scss +++ /dev/null @@ -1,97 +0,0 @@ -// .gfm-highlight, -.highlight { - --ink: #FFFFFF; - --mint: #99B898; - --pink: #FECEA8; - --salmon: #FF847C; - --salmon-dark: #E84A5F; - --unset: #555; - - --comment: #999999; - --constant: var(--salmon-dark); - --entity: var(--salmon); - --entity-tag: var(--unset); - --keyword: var(--mint); - --markup-deleted-bg: var(--unset); - --markup-deleted-text: var(--unset); - --markup-inserted-bg: var(--unset); - --markup-inserted-text: var(--unset); - --storage-modifier-import: var(--unset); - --string: var(--pink); - --variable: var(--salmon); - - border-radius: 1ex; - color: var(--ink); - line-height: 1.3em; - overflow: auto; - - > pre { - background: var(--bg-dark); - counter-increment: line-number; - float: left; - padding: 1ex; - white-space: pre; - } - - .token { - &.keyword { - color: var(--keyword); - } - - &.tag .token.class-name, - &.tag .token.script .token.punctuation { - color: var(--storage-modifier-import); - } - - &.operator { - color: var(--comment); - } - - &.number, - &.boolean, - &.tag .token.punctuation, - &.tag .token.script .token.script-punctuation, - &.tag .token.attr-name { - color: var(--constant); - } - - &.function { - color: var(--entity); - } - - &.string { - color: var(--string); - } - - &.comment { - color: var(--comment); - } - - &.class-name { - color: var(--variable); - } - - &.regex { - color: var(--string); - } - - &.regex .regex-delimiter { - color: var(--constant); - } - - &.tag .token.tag, - &.property { - color: var(--entity-tag); - } - - &.deleted { - color: var(--markup-deleted-text); - background-color: var(--markup-deleted-bg); - } - - &.inserted { - color: var(--markup-inserted-text); - background-color: var(--markup-inserted-bg); - } - } -} \ No newline at end of file diff --git a/styles/kalisjoshua.scss b/styles/kalisjoshua.scss deleted file mode 100644 index 7797112..0000000 --- a/styles/kalisjoshua.scss +++ /dev/null @@ -1,97 +0,0 @@ -@use "./lib/normalize.css"; -@use "./lib/h5bp.css"; - -@use "./cicada.css"; -@use "./colors.css"; -@use "./highlight.scss"; -@use "./navigation.css"; -@use "./resume.css"; -@use "./sidebar.css"; -@use "./slides.css"; - -@use "./print.scss"; - -*, *:before, *:after { - box-sizing: border-box; -} - -a { - color: #18453b; -} - -a.anchor[aria-hidden="true"] { - display: none; -} - -body { - height: 100%; -} - -h1 { - color: #18453b; - font-weight: 100; - margin: 1ex 0 0; -} - -h1 a { - text-decoration: none; -} - -header { - grid-area: header; -} - -html { - background: rgb(224, 223, 209); -} - -pre code { - background: gainsboro; - display: block; - overflow: auto; -} - -pre code[class*="language-"] { - border-radius: 1ex; - padding: 1ex; -} - -.contentinfo p > a { - margin-right: .5ex; -} - -.layout { - background: white; - box-shadow: 2rem 6rem 3rem 2rem rgba(0, 0, 0, 0.2); - font-family: sans-serif; - margin: 4ex auto 12em; - max-width: 120ex; - min-height: 80%; - position: relative; - z-index: 99; -} - -.main { - padding: 2ex; -} - -.main h3 { - font-size: 100%; - margin: 0; - padding: 0; -} - -.main h4 { - margin: 0; -} - -@media screen and (min-width: 900px) { - .layout { - display: grid; - grid-template-areas: - "aside header" - "aside content"; - grid-template-columns: 1fr minmax(400px, 2fr); - grid-template-rows: auto; - } -} /* @media screen and (min-width: 900px) */ diff --git a/styles/navigation.css b/styles/navigation.css deleted file mode 100644 index 54c813a..0000000 --- a/styles/navigation.css +++ /dev/null @@ -1,51 +0,0 @@ -.navigation, -.navigation ul, -.navigation ul li { - margin: 0 -2ex; - padding: 0 2ex; -} - -.navigation ul li { - list-style-type: none; - margin: 0 -2ex 3px; - overflow: hidden; - padding: 0 2ex; - transition: background 300ms; -} - -.navigation ul li:hover { - background: rgba(0, 0, 0, 0.4); -} - -.navigation ul li.active { - background: white; - background: rgba(255, 255, 255, 0.2); -} - -.navigation ul li a { - cursor: pointer; - display: block; - padding: 1ex 0; - position: relative; - text-decoration: none; -} - -.navigation ul li a:after { - border-top: 3ex solid transparent; - border-bottom: 3ex solid transparent; - border-right: 1.5ex solid transparent; - content: ""; - height: 0; - right: -2ex; - margin-top: -3ex; - position: absolute; - top: 50%; - transition: border 300ms; - width: 0; - z-index: 99999; -} - -.navigation ul li:hover a:after, -.navigation ul li.active a:after { - border-right-color: white; -} diff --git a/styles/print.scss b/styles/print.scss deleted file mode 100644 index ae1e631..0000000 --- a/styles/print.scss +++ /dev/null @@ -1,56 +0,0 @@ -@media print { - @page { - margin: 0 .5in !important; - } - - * { - color: black !important; - } - - p, li { - font-size: 11pt; - } - - a[href]:after { - content: ""; - } - - h1 { - font-size: 16pt !important; - font-weight: 900 !important; - text-align: center; - - small { - display: block; - font-size: 11pt !important; - font-weight: 200; - - :before { - content: "517.803.9806 - kalisjoshua@gmail.com - https://linkedin.com/in/kalisjoshua - "; - } - } - } - - h2 { - border: 0 !important; - font-size: 14pt !important; - } - - h3 { - font-size: 12pt !important; - line-height: 0 !important; - } - - aside, - header p, - .cicada, - .sr-only { - display: none; - } - - .layout { - box-shadow: unset; - display: block !important; - max-width: unset; - } -} diff --git a/styles/resume.css b/styles/resume.css deleted file mode 100644 index efce17a..0000000 --- a/styles/resume.css +++ /dev/null @@ -1,8 +0,0 @@ -.section-index .main h2 { - border-bottom: 1px solid; -} - -.section-index .main h3 { - font-weight: 400; - margin: 1em 0 0; -} diff --git a/styles/sidebar.css b/styles/sidebar.css deleted file mode 100644 index 569fae4..0000000 --- a/styles/sidebar.css +++ /dev/null @@ -1,54 +0,0 @@ -aside { - background: #18453b; - color: #e5e5e5; - grid-area: aside; - overflow: hidden; - padding: 2ex; -} - -aside a { - color: inherit; -} - -aside ul { - padding-left: 2ex; -} - -.dev-icons { - background: #612e3f; - border: 8px solid gainsboro; - border-left: 0; - border-right: 0; - box-shadow: - inset 0 100px 100px 0px rgba(0, 0, 0, 0.2), - 0 0 100px 10px rgba(0, 0, 0, 0.5); - box-sizing: unset; - margin: 0 -2ex; - padding: 4ex 2ex; - text-align: center; -} - -.dev-icons img { - background: white; - border-radius: 5px; - box-sizing: unset; - height: 30px; - margin: 5px; - padding: 6px; -} - -#jk-logo { - display: table !important; - margin: 10ex auto; -} - -#jk-logo img { - background: white; - height: 150px; - padding: 6px; -} - -#pride-ally { - margin-top: 8ex; - text-align: center; -}