- {{content}} +
+
+ {{#has tag="announcements,conferences-2,open-source-2,sponsorships,governance,newsletter-2,company-spotlight,community"}}

{{/has}} +

{{title}}

-

{{date published_at format="MMMM DD, YYYY"}}

-
+
+
+
+ {{content}} +
+
- {{/post}} - - {{#contentFor 'scripts'}} {{/contentFor}} diff --git a/rollup.config.js b/rollup.config.js index a87f429..3d6a20e 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -3,21 +3,6 @@ import { nodeResolve } from '@rollup/plugin-node-resolve'; import babel from '@rollup/plugin-babel'; import { terser } from 'rollup-plugin-terser'; import replace from 'rollup-plugin-replace'; -// CSS -import postcss from 'rollup-plugin-postcss'; -import atImport from 'postcss-import'; -import postcssPresetEnv from 'postcss-preset-env'; -import cssnano from 'cssnano'; - -const postcssConfig = postcss({ - extract: true, - sourceMap: true, - plugins: [ - atImport, - postcssPresetEnv({ features: { 'nesting-rules': true } }), - process.env.NODE_ENV === 'production' && cssnano({ preset: 'default' }), - ], -}); const plugins = [ commonjs(), @@ -37,7 +22,7 @@ export default [ format: 'iife', sourcemap: true, }, - plugins: [...plugins, postcssConfig], + plugins, }, { input: 'src/js/post/index.js', diff --git a/src/css/app.css b/src/css/app.css index 18d7dfe..6332215 100644 --- a/src/css/app.css +++ b/src/css/app.css @@ -1,33 +1,50 @@ -/* Base */ -@import './base/typography.css'; -@import './base/variables.css'; +@layer reset, dependencies, base, components, utilities, vendors; -/* Components */ -@import './components/button.css'; -@import './components/code.css'; -@import './components/get-involved.css'; -@import './components/sponsors.css'; -@import './components/profile-image.css'; -@import './components/static-content.css'; -@import './components/back.css'; -@import './components/divider.css'; +/* Resets */ +@import "resets/_normalize.css" layer(reset); -/* Layout */ -@import './layout/reset.css'; -@import './layout/dropdown.css'; -@import './layout/container.css'; -@import './layout/navigation-top.css'; -@import './layout/footer.css'; +/* Dependencies */ +@import "base/_variables.css" layer(dependencies); +@import "base/_fonts.css" layer(dependencies); -/* Pages */ -@import './pages/post.css'; -@import './pages/home.css'; -@import './pages/conferences.css'; -@import './pages/open-source.css'; -@import './pages/about.css'; +/* Base */ +@import "base/_animation.css" layer(base); +@import "base/_buttons.css" layer(base); +@import "base/_disclosures.css" layer(base); +@import "base/_forms.css" layer(base); +@import "base/_layout.css" layer(base); +@import "base/_lists.css" layer(base); +@import "base/_media.css" layer(base); +@import "base/_tables.css" layer(base); +@import "base/_typography.css" layer(base); + +/* Components */ +/* Import components from the component folder here in ABC order */ +@import "components/_cta.css" layer(components); +@import "components/_cta-buttons.css" layer(components); +@import "components/_global-footer.css" layer(components); +@import "components/_global-nav.css" layer(components); +@import "components/_hero.css" layer(components); +@import "components/_home-involvement.css" layer(components); +@import "components/_home-stats.css" layer(components); +@import "components/_image.css" layer(components); +@import "components/_info-block.css" layer(components); +@import "components/_info-block-feature.css" layer(components); +@import "components/_link-list.css" layer(components); +@import "components/_news.css" layer(components); +@import "components/_pagination.css" layer(components); +@import "components/_post.css" layer(components); +@import "components/_section.css" layer(components); +@import "components/_sponsor-group.css" layer(components); +@import "components/_sponsor-logo.css" layer(components); +@import "components/_team-member.css" layer(components); +@import "components/_timeline.css" layer(components); +@import "components/_video-tease.css" layer(components); -@import './modern.css'; +/* Utilities */ +@import "utilities/_container.css" layer(utilities); +@import "utilities/_grid.css" layer(utilities); +@import "utilities/_hide-visually.css" layer(utilities); /* Vendors */ -@import './vendors/ghost.css'; -@import '../../node_modules/tocbot/dist/tocbot.css'; +@import "vendors/ghost.css" layer(vendors); diff --git a/src/css/base/_animation.css b/src/css/base/_animation.css new file mode 100644 index 0000000..f4ae386 --- /dev/null +++ b/src/css/base/_animation.css @@ -0,0 +1,5 @@ +html { + @media screen and (prefers-reduced-motion: no-preference) { + scroll-behavior: smooth; + } +} diff --git a/src/css/base/_buttons.css b/src/css/base/_buttons.css new file mode 100644 index 0000000..cfcfd70 --- /dev/null +++ b/src/css/base/_buttons.css @@ -0,0 +1,76 @@ +.button, +.cta-buttons__button a { + align-items: center; + border: var(--border-width--base) solid transparent; + cursor: pointer; + display: flex; + font-family: var(--font-family--ui); + font-size: var(--font-size--ui); + font-weight: var(--font-weight--bold); + gap: var(--space--x-small); + justify-content: center; + line-height: 1; + padding-block: var(--space--base); + padding-inline: var(--space--medium); + text-align: center; + text-decoration: none; + transition-duration: var(--transition-duration--base); + transition-property: background-color, color; + transition-timing-function: var(--transition-timing--base); + + &:focus-visible { + outline: var(--border-width--thick) solid var(--color--focus); + outline-offset: 2px; + } +} + +.button--primary, +.cta-buttons__primary a { + --bg-color: var(--color--button-primary); + + background-color: var(--color--button-primary); + border-radius: var(--border-radius--medium) var(--border-radius--small) var(--border-radius--medium) var(--border-radius--small); + + &:hover, + &:focus-visible { + background-color: var(--color--button-primary-hover); + color: var(--color--text-inverse); + } +} + +.button--secondary, +.cta-buttons__secondary a { + + background-color: var(--color--background-base); + border-color: var(--color--button-secondary); + border-radius: var(--border-radius--small) var(--border-radius--medium) var(--border-radius--small) var(--border-radius--medium); + color: var(--color--text-base); + transition-property: border-color; + + &:hover, + &:focus-visible { + border-color: var(--color--button-primary); + } +} + +.button--inverted { + background-color: var(--color--background-base); + border-color: var(--color--button-secondary); + border-radius: var(--border-radius--small) var(--border-radius--medium) var(--border-radius--small) var(--border-radius--medium); + color: var(--color--text-base); + + &:hover, + &:focus-visible { + background-color: var(--color--button-primary); + } +} + +.button--icon { + border-radius: var(--border-radius--small); + padding-block: var(--space--small); + padding-inline: var(--space--small); +} + +.button:disabled { + cursor: not-allowed; +} diff --git a/src/css/base/_disclosures.css b/src/css/base/_disclosures.css new file mode 100644 index 0000000..0d2478f --- /dev/null +++ b/src/css/base/_disclosures.css @@ -0,0 +1,46 @@ +details { + display: flex; + flex-direction: column; + gap: var(--space--small); + + &[open] summary:after { + transform: rotate(90deg); + } + + p:not(:last-of-type) { + margin-block-end: var(--space--small); + } + + [dir="rtl"] &:not([open]) summary:after { + transform: rotate(180deg); + } +} + +summary { + align-items: center; + align-self: start; + cursor: pointer; + display: flex; + font-size: var(--font-size--body-large); + font-weight: var(--font-weight--bold); + gap: var(--space--x-small); + list-style: none; + + &::-webkit-details-marker { + display: none; + } + &:after { + --size: var(--space--small); + + background-image: url('data:image/svg+xml,'); + background-position: center; + background-repeat: no-repeat; + background-size: contain; + content: ""; + display: block; + height: var(--size); + transition: var(--transition-duration--base) transform + var(--transition-timing--base); + width: var(--size); + } +} diff --git a/src/css/base/_fonts.css b/src/css/base/_fonts.css new file mode 100644 index 0000000..da8cb1b --- /dev/null +++ b/src/css/base/_fonts.css @@ -0,0 +1,15 @@ +@font-face { + font-display: swap; + font-family: Rubik; + font-style: normal; + font-weight: 300 900; + src: url("../fonts/Rubik-Variable.woff2") format("woff2"); +} + +@font-face { + font-display: swap; + font-family: Inter; + font-style: normal; + font-weight: 100 900; + src: url("../fonts/Inter-Variable.woff2") format("woff2"); +} diff --git a/src/css/base/_forms.css b/src/css/base/_forms.css new file mode 100644 index 0000000..6222996 --- /dev/null +++ b/src/css/base/_forms.css @@ -0,0 +1,228 @@ +:is( + button, + input[type="checkbox"], + input[type="radio"], + input[type="range"], + select +) { + cursor: pointer; +} + +:where( + input, + label, + select +) { + display: block; +} + +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +form { + display: flex; + flex-direction: column; + gap: var(--space--large); +} + +:where(fieldset > *:not(:last-child)) { + margin-block-end: var(--space--base); +} + +:is( + input, + textarea, + select +) { + accent-color: var(--color--primary-base); + border: var(--border--light); + + &:focus { + outline: var(--border-width--base) solid var(--color--primary-base); + } + + &[readonly] { + border-color: transparent; + padding-inline-start: 0; + + &:focus { + padding-inline-start: var(--space--small); + } + } +} + +:where( + input:not([type]), + select, + textarea, + [type="color"], + [type="date"], + [type="datetime"], + [type="datetime-local"], + [type="email"], + [type="month"], + [type="number"], + [type="password"], + [type="search"], + [type="tel"], + [type="text"], + [type="time"], + [type="url"], + [type="week"] +) { + background-color: var(--color--background-base); + border-radius: var(--border-radius--small); + color: var(--color--text-base); + padding-block: var(--space--small); + padding-inline: var(--space--small); + + &:focus-visible { + outline: var(--border-width--thick) solid var(--color--focus); + outline-offset: 2px; + } +} + +label:has( + input:not([type]), + select, + textarea, + [type="color"], + [type="date"], + [type="datetime"], + [type="datetime-local"], + [type="email"], + [type="month"], + [type="number"], + [type="password"], + [type="search"], + [type="tel"], + [type="text"], + [type="time"], + [type="url"], + [type="week"] + ) { + display: flex; + flex-direction: column; + gap: var(--space--x-small); +} + +label:has([type="radio"], [type="checkbox"]) { + align-items: center; + cursor: pointer; + display: flex; + gap: var(--space--x-small); + justify-self: start; +} + +label:has( + input[required], + select[required], + textarea[required] +) > span::after, +.fieldset-required > legend::after { + content: "*"; + margin-inline-start: var(--space--xx-small); +} + +:is(input[type="checkbox"], input[type="radio"]) { + --input-size: 1.125rem; + + flex-shrink: 0; + height: var(--input-size); + width: var(--input-size); + + &:focus { + outline: none; + } + + &:focus-visible { + outline: var(--border-width--thick) solid var(--color--focus); + outline-offset: 2px; + } +} + +textarea { + resize: vertical; +} + +:where(select) { + appearance: none; + background-image: url('data:image/svg+xml,'); + background-position: right var(--space--small) center; + background-repeat: no-repeat; + background-size: var(--space--small); + + [dir="rtl"] & { + background-position: left var(--space--small) center; + } +} + +:where([type="search"])::-webkit-search-cancel-button { + appearance: none; + background-image: url('data:image/svg+xml,'); + background-position: center; + background-repeat: no-repeat; + cursor: pointer; + height: var(--space--small); + width: var(--space--small); +} + +:where(input[type="range"]) { + appearance: none; + background-color: var(--color--background-base); + border: 0; + border-radius: var(--border-radius--small); + height: var(--border-width--thick); + width: 100%; + + &:focus { + background-color: var(--color--primary-base); + outline: none; + } +} + +label:has(input[type="range"]) { + display: flex; + flex-direction: column; + gap: var(--space--medium); +} + +[type="range"]::-webkit-slider-thumb { + --size: var(--space--large); + + appearance: none; + background-color: var(--color--background-base); + background-image: url('data:image/svg+xml,'); + background-position: center; + background-repeat: no-repeat; + border: var(--border--base); + border-radius: var(--border-radius--circle); + height: var(--size); + width: var(--size); +} + +[type="range"]::-moz-range-thumb { + --size: var(--space--large); + + background-color: var(--color--background-base); + background-image: url('data:image/svg+xml,'); + background-position: center; + background-repeat: no-repeat; + border: var(--border--base); + border-radius: var(--border-radius--circle); + height: var(--size); + width: var(--size); +} + +[type="range"]:is(:active, :focus)::-webkit-slider-thumb { + background-color: var(--color--primary-base); + background-image: url('data:image/svg+xml,'); +} + +[type="range"]:is(:active, :focus)::-moz-range-thumb { + background-color: var(--color--primary-base); + background-image: url('data:image/svg+xml,'); +} diff --git a/src/css/base/_layout.css b/src/css/base/_layout.css new file mode 100644 index 0000000..2d58c08 --- /dev/null +++ b/src/css/base/_layout.css @@ -0,0 +1,54 @@ +html { + scroll-padding-block-start: 6rem; +} + +body { + --color--theme-background: var(--color--background-base); + + background-color: var(--color--background-base); + container: global-nav global-footer info-block / inline-size; +} + +main { + display: grid; + gap: var(--space--xxx-large); + grid-template-columns: minmax(0, 1fr); + margin-block-end: var(--space--xx-large); +} + +body:has(.hero--home) { + background-color: var(--color--background-secondary); +} + + +body.page-template { + --color--theme-background: var(--color--background-secondary); +} +body.page-about { + --color--theme-background: var(--color--accent-purple-background); +} + +body.page-community { + --color--theme-background: var(--color--accent-green-background); +} + +body.page-programs { + --color--theme-background: var(--color--accent-blue-background); +} + +body.page-events { + --color--theme-background: var(--color--accent-orange-background); +} + +body.page-sponsors { + --color--theme-background: var(--color--accent-yellow-background); +} + +body.page-news, +body.tag-template { + --color--theme-background: var(--color--accent-red-background); +} + +body.post-template { + --color--theme-background: var(--color--background-secondary); +} diff --git a/src/css/base/_lists.css b/src/css/base/_lists.css new file mode 100644 index 0000000..05b957b --- /dev/null +++ b/src/css/base/_lists.css @@ -0,0 +1,19 @@ +:where(ul, ol)[class] { + list-style: none; + margin: 0; + padding: 0; +} + +dl { + dt { + font-weight: var(--font-weight--bold); + } + + dd { + margin-inline-start: 0; + + &:not(:last-of-type) { + margin-bottom: var(--space--base); + } + } +} diff --git a/src/css/base/_media.css b/src/css/base/_media.css new file mode 100644 index 0000000..4f36685 --- /dev/null +++ b/src/css/base/_media.css @@ -0,0 +1,22 @@ +:where( + audio, + canvas, + iframe, + img, + figure, + picture, + video +) { + display: block; + height: auto; + margin: 0; + width: 100%; +} + +iframe { + border: 0; +} + +svg:not([fill]) { + fill: currentColor; +} diff --git a/src/css/base/_modal.css b/src/css/base/_modal.css new file mode 100644 index 0000000..3c337e3 --- /dev/null +++ b/src/css/base/_modal.css @@ -0,0 +1,70 @@ +dialog { + background-color: var(--color--background-base); + border: var(--border--base); + border-radius: var(--border-radius--base); + color: var(--color--text-base); + flex-direction: column; + gap: var(--space--base); + max-width: var(--container--base); + width: calc(100% - var(--space--base)); + + &[open] { + display: flex; + } + + &[open]::backdrop { + background-color: color-mix( + in srgb, + var(--color--primary-base), + transparent 10% + ); + } +} + +dialog button[data-dialogClose] { + align-self: flex-end; +} + +dialog.slide-in { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + margin-block-end: 0; + + @media (prefers-reduced-motion: no-preference) { + transform: translateY(100%); + transition: + calc(var(--transition-duration--base) * 2) var(--transition-timing--base) + transform, + display var(--transition-duration--base) var(--transition-timing--base) + allow-discrete, + overlay var(--transition-duration--base) var(--transition-timing--base) + allow-discrete; + } + + &::backdrop { + @media (prefers-reduced-motion: no-preference) { + transition: + overlay var(--transition-duration--base) allow-discrete, + display var(--transition-duration--base) allow-discrete, + var(--transition-duration--base) background-color + var(--transition-timing--base); + } + } + + &[open] { + transform: translateY(0); + + @media (prefers-reduced-motion: no-preference) { + transition: calc(var(--transition-duration--base) * 2) + var(--transition-timing--base) transform; + + @starting-style { + transform: translateY(100%); + + &::backdrop { + background-color: transparent; + } + } + } + } +} diff --git a/src/css/base/_tables.css b/src/css/base/_tables.css new file mode 100644 index 0000000..b07110a --- /dev/null +++ b/src/css/base/_tables.css @@ -0,0 +1,66 @@ +table { + border-collapse: separate; + border-spacing: 0; + width: 100%; + + p { + margin: 0; + } +} + +:where(thead, tbody) :where(th, td) { + border-bottom: var(--border--light); + border-inline-end: var(--border--light); + padding-block: var(--space--small); + padding-inline: var(--space--small); +} + +:where(tfoot) td, caption { + font-weight: var(--font-weight--bold); + padding-block: var(--space--xx-small); + padding-inline: var(--space--small); + text-align: start; +} + +:where(thead, tbody) :where(th, td):first-child { + border-inline-start: var(--border--light); +} + +th { + background-color: var(--color--background-secondary); + border-top: var(--border--light); + font-size: var(--font-size--body-small); + font-weight: var(--font-weight--bold); + text-align: start; +} + +tr:first-child th:first-child { + border-top-left-radius: var(--border-radius--base); +} + +tr:first-child th:last-child { + border-top-right-radius: var(--border-radius--base); +} + +tr:last-child td:first-child { + border-bottom-left-radius: var(--border-radius--base); +} + +tr:last-child td:last-child { + border-bottom-right-radius: var(--border-radius--base); +} + +.table--striped tbody tr:nth-child(even) { + background-color: var(--color--background-base); +} + +.table-outer-wrapper { + display: flex; +} + +.table-inner-wrapper { + flex: 1 1 0%; + margin-block-end: var(--space--base); + overflow-x: auto; + width: 1rem; +} diff --git a/src/css/base/_typography.css b/src/css/base/_typography.css new file mode 100644 index 0000000..c839a8f --- /dev/null +++ b/src/css/base/_typography.css @@ -0,0 +1,120 @@ +html { + font-size: 100%; + -webkit-font-smoothing: antialiased; +} + +body { + color: var(--color--text-base); + font-family: var(--font-family--body); + font-size: var(--font-size--body-base); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--base); +} + +:where( + h1, + h2, + h3, + h4, + strong +) { + font-weight: var(--font-weight--bold); +} + +h1, +h2 { + text-wrap: balance; + text-wrap: pretty; +} + +a { + color: var(--color--link); + text-decoration-color: var(--color--link-accent); + text-decoration-thickness: 10%; + transition: var(--transition-duration--base) text-decoration-color var(--transition-timing--base); + + &:hover { + text-decoration-color: var(--color--link); + } + + u { + text-decoration: none; + } +} + +label { + font-size: var(--font-size--ui); + font-weight: var(--font-weight--bold); + text-align: start; +} + +input { + font-size: var(--font-size--body-base); +} + +legend { + font-size: var(--font-size--body-base); + font-weight: var(--font-weight--bold); +} + +hr { + border: var(--border--light); + width: 100%; +} + +table { + font-variant-numeric: tabular-nums lining-nums slashed-zero; +} + +code { + font-variant-numeric: slashed-zero; +} + +small { + font-size: var(--font-size--body-small); +} + +::selection { + background-color: var(--color--accent-yellow); + color: var(--color--text-base); +} + +.heading-data { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-data); + font-weight: var(--font-weight--bold); +} + +.heading-overline { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-overline); + font-weight: var(--font-weight--bold); +} + +.heading-section { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-section); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--tight); +} + +.heading-subsection { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-subsection); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--tight); +} + +.heading-title-big { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-title-big); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--tight); +} + +.heading-title-small { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-title-small); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--tight); +} diff --git a/src/css/base/_variables.css b/src/css/base/_variables.css new file mode 100644 index 0000000..798e662 --- /dev/null +++ b/src/css/base/_variables.css @@ -0,0 +1,158 @@ +:root { + /* Color scheme settings */ + color-scheme: light dark; + + /* Primitive colors */ + --color--beige-base: #fffcfa; + --color--black-base: #292e37; + --color--blue-base: #4581d6; + --color--blue-light: #edf5ff; + --color--gray-base: #e4eaf5; + --color--gray-light: #eff4f8; + --color--green-base: #59c899; + --color--green-light: #f2fff9; + --color--navy-base: #36435e; + --color--navy-dark: #282e38; + --color--orange-base: #f87d25; + --color--orange-light: #fff5f1; + --color--purple-base: #755384; + --color--purple-light: #fcf4ff; + --color--red-base: #ff3b32; + --color--red-dark: #cf2821; + --color--red-light: #ffeeed; + --color--white-base: #ffffff; + --color--yellow-base: #fec233; + --color--yellow-light: #fff8ec; + + /* Semantic colors */ + --color--primary-base: var(--color--red-base); + --color--primary-dark: var(--color--red-dark); + --color--secondary-base: var(--color--yellow-base); + --color--primary-inverse: var(--color--navy-base); + --color--primary-inverse-dark: var(--color--navy-dark); + + --color--text-base: var(--color--black-base); + --color--text-inverse: var(--color--white-base); + --color--text-dark: var(--color--black-base); + + --color--accent-blue: var(--color--blue-base); + --color--accent-blue-background: var(--color--blue-light); + --color--accent-green: var(--color--green-base); + --color--accent-green-background: var(--color--green-light); + --color--accent-orange: var(--color--orange-base); + --color--accent-orange-background: var(--color--orange-light); + --color--accent-purple: var(--color--purple-base); + --color--accent-purple-background: var(--color--purple-light); + --color--accent-red: var(--color--red-base); + --color--accent-red-background: var(--color--red-light); + --color--accent-yellow: var(--color--yellow-base); + --color--accent-yellow-background: var(--color--yellow-light); + + --color--background-base: var(--color--white-base); + --color--background-secondary: var(--color--gray-light); + --color--background-dark: var(--color--navy-dark); + + --color--button-primary: var(--color--accent-yellow); + --color--button-primary-hover: var(--color--primary-inverse); + + --color--button-secondary: var(--color--primary-inverse); + + --color--focus: var(--color--primary-dark); + --color--link: var(--color--text-base); + --color--link-accent: var(--color--primary-base); + + /* Font & typography */ + --font-size--50: 0.875rem; + --font-size--100: 1rem; + --font-size--200: 1.15rem; + --font-size--300: 1.5rem; + --font-size--400: clamp(1.75rem, 1.375rem + 1vw, 2rem); + --font-size--500: clamp(2rem, 1.25rem + 2vw, 2.5rem); + --font-size--600: clamp(2.5rem, 1.75rem + 2vw, 3.25rem); + + --font-size--body-callout: var(--font-size--400); + --font-size--body-base: var(--font-size--100); + --font-size--body-large: var(--font-size--200); + --font-size--body-small: var(--font-size--50); + --font-size--heading-data: var(--font-size--200); + --font-size--heading-overline: var(--font-size--200); + --font-size--heading-section: var(--font-size--400); + --font-size--heading-subsection: var(--font-size--300); + --font-size--heading-title-big: var(--font-size--600); + --font-size--heading-title-small: var(--font-size--500); + --font-size--ui: var(--font-size--100); + + --font-weight--normal: 400; + --font-weight--bold: 600; + + --font-family--sans-fallback: system-ui, "Arial", "Helvetica", sans-serif; + --font-family--inter: "Inter", var(--font-family--sans-fallback); + --font-family--rubik: "Rubik", var(--font-family--sans-fallback); + + --font-family--body: var(--font-family--inter); + --font-family--heading: var(--font-family--rubik); + --font-family--ui: var(--font-family--rubik); + + --line-height--base: 1.5; + --line-height--tight: 1.2; + + /* Borders */ + --border-radius--small: 0.25rem; + --border-radius--base: 0.5rem; + --border-radius--medium: 1rem; + --border-radius--large: 6.25rem; + --border-radius--circle: 100%; + + --border-width--base: 1px; + --border-width--thick: 2px; + + --border--base: var(--border-width--base) solid var(--color--secondary-base); + --border--light: var(--border-width--base) solid var(--color--gray-base); + --border--dark: var(--border-width--base) solid var(--color--primary-inverse); + + /* Container sizing */ + --container--base: 85rem; + --container--narrow: 48rem; + + + /* Spacing */ + --space--xx-small: 0.25rem; + --space--x-small: 0.5rem; + --space--small: 0.75rem; + --space--base: 1rem; + --space--medium: 1.5rem; + --space--large: 2rem; + --space--x-large: 3rem; + --space--xx-large: 4rem; + --space--xxx-large: 7rem; + + + /* Spacing - Page margins */ + --space--page: var(--space--medium); + + /* Transitions */ + --transition-duration--base: 0.2s; + --transition-timing--base: ease-in-out; + + /* Z-index */ + --z-index--basement: -999999; + --z-index--base: 1; + --z-index--layout: 1000; + --z-index--modal: 4000; + --z-index--ceiling: 999999; + + /* High contrast settings */ + @media (prefers-contrast: more) { + --color--focus: Highlight; + --color--text-base: ButtonText; + --border--base: var(--border-width--base) solid ButtonText; + --border--light: var(--border-width--base) solid ButtonText; + --border--dark: var(--border-width--base) solid ButtonText; + } +} + +@media screen and (min-width: 1000px) { + :root { + --space--page-margin-inline: var(--space--x-large); + } +} diff --git a/src/css/base/typography.css b/src/css/base/typography.css deleted file mode 100644 index 19387df..0000000 --- a/src/css/base/typography.css +++ /dev/null @@ -1,79 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300..900;1,300..900&display=swap'); -@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); - -body { - color: var(--color-text); - font-family: 'Inter', sans-serif; - font-size: 1rem; - line-height: 1.5rem; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: 'Rubik', sans-serif; - line-height: normal; - margin: 0; - text-align: left; -} - -p { - margin-bottom: 16px; -} - -h2 { - font-size: 2rem; - font-weight: 700; - line-height: normal; -} - -h3 { - font-size: 1.125rem; - font-weight: 500; - line-height: 2.25rem; -} - -h6 { - font-size: 1.125rem; - font-weight: 300; - font-style: italic; -} - -a { - box-shadow: inset 0 -2px 0 var(--color-yellow); - color: inherit; - padding-bottom: 1px; - text-decoration: none; - transition: all 0.15s ease-in-out; -} - -a:hover { - box-shadow: inset 0 -2px 0 var(--color-red); -} - -@media (min-width: 834px) { - h1 { - font-size: 2.625rem; - } - - h2 { - font-size: 2rem; - } - - h3 { - font-size: 1.625rem; - } -} - -@media (min-width: 1440px) { - h1 { - font-size: 4.5rem; - } - - h2 { - font-size: 3rem; - } -} diff --git a/src/css/base/variables.css b/src/css/base/variables.css deleted file mode 100644 index f214460..0000000 --- a/src/css/base/variables.css +++ /dev/null @@ -1,16 +0,0 @@ -:root { - --color-blue: #6288bc; - --color-darkred: #cf2821; - --color-divider: #f6f3f0; - --color-green: #71c09e; - --color-lightblue: #eff4f8; - --color-mutednavy: #444d5c; - --color-navy: #292e37; - --color-offwhite: #f0f4fd; - --color-purple: #755384; - --color-red: #e14943; - --color-text: #3b3e44; - --color-white: #fffdf9; - --color-yellow: #ffd065; - --layout-inner-max-width: 1135px; -} diff --git a/src/css/components/.gitkeep b/src/css/components/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/css/components/_cta-buttons.css b/src/css/components/_cta-buttons.css new file mode 100644 index 0000000..2c5325a --- /dev/null +++ b/src/css/components/_cta-buttons.css @@ -0,0 +1,9 @@ +.cta-buttons { + display: flex; + flex-direction: column; + gap: var(--space--base); + + @media (min-width: 25em) { + flex-direction: row; + } +} diff --git a/src/css/components/_cta.css b/src/css/components/_cta.css new file mode 100644 index 0000000..09a9ed6 --- /dev/null +++ b/src/css/components/_cta.css @@ -0,0 +1,26 @@ +.cta { + background-color: var(--color--background-secondary); + border-radius: var(--border-radius--medium) var(--border-radius--large) var(--border-radius--medium) var(--border-radius--large); + display: flex; + justify-content: center; + padding: var(--space--xx-large); + + p { + font-family: var(--font-family--heading); + font-size: var(--font-size--body-callout); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--tight); + margin: 0; + } +} + +body:has(.hero--home) .cta { + background-color: var(--color--background-base); +} + +.cta__inner { + display: flex; + flex-direction: column; + gap: var(--space--medium); + max-width: 85ch; +} diff --git a/src/css/components/_global-footer.css b/src/css/components/_global-footer.css new file mode 100644 index 0000000..7a0266d --- /dev/null +++ b/src/css/components/_global-footer.css @@ -0,0 +1,134 @@ +.global-footer { + background-color: var(--color--background-dark); + color: var(--color--text-inverse); + padding-block: var(--space--base); +} + +.global-footer__inner { + grid-template-areas: + "logo" + "links" + "newsletter" + "legal"; + + @container global-footer (min-width: 65em) { + grid-template-areas: + "logo logo logo links links links links" + "newsletter newsletter newsletter newsletter newsletter newsletter newsletter" + "legal legal legal legal legal legal legal"; + } +} + +.global-footer__section h2 { + font-size: var(--font-size--body-base); +} + +.global-footer__nav a { + color: var(--color--text-inverse); + text-decoration-color: var(--color--text-inverse); + + &:hover { + text-decoration-color: var(--color--link-accent); + } +} + +.global-footer__logo { + color: var(--color--text-inverse); + grid-area: logo; + place-self: start; + + svg { + height: auto; + width: 20rem; + } +} + +.global-footer__links { + display: grid; + gap: var(--space--large); + grid-area: links; + grid-template-columns: 1fr; + + @container global-footer (min-width: 65em) { + grid-template-columns: subgrid; + } +} + +.global-footer__newsletter { + border-top: var(--border--dark); + grid-area: newsletter; + + @container global-footer (min-width: 65em) { + display: grid; + grid-template-columns: subgrid; + } +} + +.global-footer__newsletter-form { + display: flex; + flex-direction: column; + gap: var(--space--small); + margin-top: var(--space--small); + + @container global-footer (min-width: 65em) { + display: grid; + grid-column: 1 / -1; + grid-template-columns: subgrid; + } +} + +.global-footer__newsletter-form button { + @container global-footer (min-width: 65em) { + align-self: end; + } +} + +.global-footer__newsletter-form :where(input, button) { + block-size: 3.5rem; + box-sizing: border-box; +} + +.global-footer__section--bottom { + border-top: var(--border--dark); + display: grid; + font-size: var(--font-size--body-small); + gap: var(--space--medium); + grid-area: legal; + grid-template-areas: + "copyright" + "legal-links"; + grid-template-columns: subgrid; + padding-block-start: var(--space--base); + + @container global-footer (min-width: 65em) { + grid-template-areas: "copyright copyright copyright legal-links legal-links legal-links legal-links"; + } +} + +.global-footer__copyright { + grid-area: copyright; +} + +.global-footer__section--bottom .global-footer__nav { + grid-area: legal-links; + + @container global-footer (min-width: 65em) { + display: grid; + grid-template-columns: subgrid; + + ul { + display: grid; + grid-column: 1 / -1; + grid-template-columns: subgrid; + } + } +} + +.global-footer__nav ul { + display: flex; + flex-direction: column; + gap: var(--space--small); + list-style: none; + margin: 0; + padding: 0; +} diff --git a/src/css/components/_global-nav.css b/src/css/components/_global-nav.css new file mode 100644 index 0000000..c60c028 --- /dev/null +++ b/src/css/components/_global-nav.css @@ -0,0 +1,105 @@ +.global-nav { + background-color: var(--color--theme-background); + padding-block: var(--space--base); + position: sticky; + top: 0; + width: 100%; + z-index: var(--z-index--layout); +} + +.global-nav__inner { + align-items: center; + display: grid; + gap: var(--space--large); + grid-template-areas: + "logo menu" + "nav nav"; + grid-template-columns: 1fr min-content; +} + +.global-nav.is-closed .global-nav__inner { + grid-template-areas: "logo menu"; +} + +@container global-nav (min-width: 65em) { + .global-nav__inner, + .global-nav.is-closed .global-nav__inner { + grid-template-areas: "logo nav"; + grid-template-columns: min-content 1fr; + } +} + +.global-nav.is-closed .global-nav__links { + display: none; +} + +@container global-nav (min-width: 65em) { + .global-nav.is-closed .global-nav__links { + display: flex; + } +} + +.global-nav__logo { + color: var(--color--primary-base); + display: block; + grid-area: logo; + transition-property: color; + + &:hover { + color: var(--color--primary-dark); + } + + svg { + height: auto; + width: 12rem; + } +} + +.global-nav__menu-toggle { + grid-area: menu; + + @container global-nav (min-width: 65em) { + display: none; + } +} + +.global-nav__links { + display: flex; + grid-area: nav; + + @container global-nav (min-width: 65em) { + justify-content: flex-end; + } +} + +.global-nav__list { + align-items: baseline; + display: flex; + flex-direction: column; + gap: var(--space--large); + + @container global-nav (min-width: 65em) { + align-items: center; + flex-direction: row; + } +} + +.global-nav__link { + background-color: transparent; + border: 0; + border-bottom: var(--border-width--thick) solid transparent; + color: inherit; + cursor: pointer; + font-size: var(--font-size--body-small); + font-weight: var(--font-weight--bold); + line-height: 1; + padding-block-end: var(--space--xx-small); + padding-inline: var(--space--xx-small); + text-decoration: none; + transition-property: border-bottom-color; + + &[aria-current], + &:hover { + border-bottom-color: var(--color--primary-base); + } +} diff --git a/src/css/components/_hero.css b/src/css/components/_hero.css new file mode 100644 index 0000000..6cf1398 --- /dev/null +++ b/src/css/components/_hero.css @@ -0,0 +1,89 @@ +.hero { + background-color: var(--color--theme-background); + min-width: 0; + padding-block: var(--space--x-large); +} + +.hero__content { + display: flex; + flex-direction: column; + gap: var(--space--medium); + + h1, h2 { + margin: 0; + } + + h1 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-title-big); + font-weight: var(--font-weight--bold); + line-height: var(--line-height--tight); + } + + h2 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-overline); + font-weight: var(--font-weight--normal); + } +} + +.hero--home .hero__text { + align-content: start; + display: grid; + gap: var(--space--medium); +} + +.hero--home .hero__images { + display: grid; + gap: var(--space--small); + margin: 0; + + @media (min-width: 55em) { + aspect-ratio: 16 / 9; + grid-template-columns: repeat(7, 1fr); + grid-template-rows: repeat(7, 1fr); + } +} + +.hero__links { + @media (min-width: 55em) { + grid-column: 6 / 8; + } +} + +.hero--home .hero__images .image { + @media (min-width: 55em) { + &:nth-child(1) { + --animation-offset: 1s; + grid-column: 1 / 7; + grid-row: 2 / 7; + } + + &:nth-child(2) { + --animation-offset: 0.5s; + grid-column: 2 / 4; + grid-row: 5 / 8; + } + + &:nth-child(3) { + --animation-offset: 0; + grid-column: 5 / 8; + grid-row: 1 / 5; + } + + @media (prefers-reduced-motion: no-preference) { + animation: hero-image-bob 3.5s ease-in-out infinite; + animation-delay: var(--animation-offset); + } + } +} + +@keyframes hero-image-bob { + 0%, 100% { + transform: translate(0); + } + + 50% { + transform: translate(0.15rem, -0.25rem); + } +} diff --git a/src/css/components/_home-involvement.css b/src/css/components/_home-involvement.css new file mode 100644 index 0000000..1feab04 --- /dev/null +++ b/src/css/components/_home-involvement.css @@ -0,0 +1,9 @@ +.home-involvement { + display: grid; + gap: var(--space--large); +} + +.home-involvement__image { + justify-self: center; + max-width: 65rem; +} diff --git a/src/css/components/_home-stats.css b/src/css/components/_home-stats.css new file mode 100644 index 0000000..3c69112 --- /dev/null +++ b/src/css/components/_home-stats.css @@ -0,0 +1,98 @@ +.home-stats__row { + display: flex; + flex-direction: column; + gap: var(--space--medium); + margin-block-start: var(--space--x-large); + + @media (min-width: 65em) { + align-items: center; + flex-direction: row; + gap: var(--space--large); + } +} + +.home-stats__heading { + flex-shrink: 0; + + @media (min-width: 65em) { + max-width: 12rem; + } +} + +.home-stats__heading h2 { + font-family: var(--font-family--body); + font-size: var(--font-size--body-small); + font-weight: var(--font-weight--bold); + margin: 0; +} + +.home-stats__marquee { + mask-image: linear-gradient(to right, transparent, var(--color--black-base) var(--space--x-large), var(--color--black-base) calc(100% - var(--space--x-large)), transparent); + -webkit-mask-image: linear-gradient(to right, transparent, var(--color--black-base) var(--space--x-large), var(--color--black-base) calc(100% - var(--space--x-large)), transparent); + min-width: 0; + overflow: hidden; + + @media (min-width: 65em) { + flex: 1 1 0; + } +} + +.home-stats__track { + display: flex; +} + +.home-stats__list { + display: flex; + flex-wrap: wrap; + gap: var(--space--x-large); + padding-inline: var(--space--medium); +} + +.home-stats__list[aria-hidden="true"] { + display: none; +} + +.home-stats__item { + align-items: baseline; + display: flex; + flex-direction: row; + gap: var(--space--x-small); +} + +.home-stats__value { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-data); + font-weight: var(--font-weight--bold); + margin: 0; +} + +.home-stats__description { + font-size: var(--font-size--body-small); + margin: 0; +} + +@keyframes home-stats-marquee { + to { + transform: translateX(-50%); + } +} + +@media (prefers-reduced-motion: no-preference) { + .home-stats__list { + flex-shrink: 0; + flex-wrap: nowrap; + } + + .home-stats__list[aria-hidden="true"] { + display: flex; + } + + .home-stats__track { + animation: home-stats-marquee 60s linear infinite; + width: max-content; + } + + .home-stats__marquee:hover .home-stats__track { + animation-play-state: paused; + } +} diff --git a/src/css/components/_image.css b/src/css/components/_image.css new file mode 100644 index 0000000..7b1a69d --- /dev/null +++ b/src/css/components/_image.css @@ -0,0 +1,12 @@ +.image { + aspect-ratio: 16 / 9; + border-radius: var(--border-radius--base); + display: block; + height: 100%; + overflow: hidden; + + img { + height: 100%; + object-fit: cover; + } +} diff --git a/src/css/components/_info-block-feature.css b/src/css/components/_info-block-feature.css new file mode 100644 index 0000000..571fec6 --- /dev/null +++ b/src/css/components/_info-block-feature.css @@ -0,0 +1,42 @@ +.info-block-feature { + background-color: var(--color--background-dark); + border-radius: var(--border-radius--base); + color: var(--color--text-inverse); + display: flex; + flex-direction: column; + gap: var(--space--small); + padding: var(--space--base); +} + +.info-block-feature__image .image { + aspect-ratio: 16 / 9; +} + +.info-block-feature__content { + display: flex; + flex-direction: column; + gap: var(--space--xx-small); + + p { + margin: 0; + } + + .cta-buttons { + margin-block-start: var(--space--x-small); + } +} + +.info-block-feature__label { + font-family: var(--font-family--heading); + font-size: var(--font-size--body-small); + font-weight: var(--font-weight--bold); +} + +.info-block-feature__title { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-subsection); +} + +.info-block-feature__meta { + font-size: var(--font-size--body-small); +} diff --git a/src/css/components/_info-block.css b/src/css/components/_info-block.css new file mode 100644 index 0000000..27aa571 --- /dev/null +++ b/src/css/components/_info-block.css @@ -0,0 +1,96 @@ +.info-block { + display: flex; + flex-direction: column; + gap: var(--space--medium); + + @container info-block (min-width: 65em) { + &:has(.info-block__image) { + display: grid; + grid-template-columns: repeat(7, 1fr); + } + } +} + +@container info-block (min-width: 65em) { + .info-block:has(.info-block__image) > .info-block__content, + .info-block:has(.info-block__image) > .info-block__image { + grid-column: span 3; + min-width: 0; + } +} + +.info-block--border { + background-color: var(--color--background-base); + border: var(--border--dark); + border-radius: var(--border-radius--base); + padding: var(--space--base); + + .cta-buttons { + margin-block-start: auto; + } +} + +.info-block__image { + order: -1; + + .image { + height: 18rem; + } +} + +@container info-block (min-width: 65em) { + .info-block:not(.info-block--inverse) .info-block__image { + order: 1; + } +} + +.info-block__content { + display: flex; + flex-direction: column; + gap: var(--space--small); + height: 100%; + + h2, + h3, + h4 { + margin: 0; + } + + p, + ul, + ol { + margin-block-start: 0; + } + + h2 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-overline); + font-weight: var(--font-weight--bold); + } + + h3 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-subsection); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--tight); + } +} + +.info-block__content:not(:has(> h2)) h3 { + font-weight: var(--font-weight--bold); +} + +.info-block__content:has(> h4) { + h3 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-overline); + font-weight: var(--font-weight--bold); + } + + h4 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-subsection); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--tight); + } +} diff --git a/src/css/components/_link-list.css b/src/css/components/_link-list.css new file mode 100644 index 0000000..c93b57d --- /dev/null +++ b/src/css/components/_link-list.css @@ -0,0 +1,102 @@ +.link-list { + display: flex; + flex-direction: column; + font-family: var(--font-family--heading); + gap: var(--space--xx-small); + + p { + margin: 0; + } +} + +.link-list__label { + font-weight: var(--font-weight--bold); +} + +.link-list__items { + --gutter: var(--space--xx-small); + + display: flex; + flex-direction: column; + gap: var(--gutter); +} + +.link-list--feature .link-list__items { + --gutter: var(--space--base); +} + +.link-list__link { + align-items: center; + border-bottom: var(--border--dark); + display: flex; + justify-content: space-between; + padding-block-end: var(--gutter); + text-decoration: none; + transition-property: border-color; + + &:hover { + border-color: var(--color--secondary-base); + + .link-list__arrow { + background-color: var(--color--secondary-base); + color: var(--color--text-inverse); + transform: translateX(var(--space--xx-small)); + } + } +} + +.link-list--feature .link-list__link { + align-items: center; + display: grid; + gap: var(--space--xx-small) var(--space--base); + grid-template-areas: + "title arrow" + "description arrow"; + grid-template-columns: 1fr auto; + + @media (min-width: 65em) { + grid-template-areas: "title description arrow"; + grid-template-columns: 1fr 1fr auto; + } +} + +.link-list--feature .link-list__title { + font-size: var(--font-size--heading-subsection); + font-weight: var(--font-weight--bold); + grid-area: title; + line-height: var(--line-height--tight); +} + +.link-list--feature .link-list__description { + grid-area: description; +} + +.link-list__arrow { + --size: var(--space--medium); + + align-items: center; + border-radius: var(--border-radius--circle); + color: var(--color--primary-base); + display: flex; + height: var(--size); + justify-content: center; + transition-duration: var(--transition-duration--base); + transition-property: color, background-color, transform; + transition-timing-function: var(--transition-timing--base); + width: var(--size); + + svg { + width: var(--space--base); + } +} + +.link-list--feature .link-list__arrow { + --size: var(--space--large); + + grid-area: arrow; + + svg { + transform: rotate(-45deg); + width: var(--space--medium); + } +} diff --git a/src/css/components/_news.css b/src/css/components/_news.css new file mode 100644 index 0000000..379a981 --- /dev/null +++ b/src/css/components/_news.css @@ -0,0 +1,113 @@ +.news-list { + display: grid; + gap: var(--space--x-large); +} + +.news-teases { + --gutter: var(--space--large); + + display: grid; + gap: var(--gutter); +} + +.news-teases__item { + border-bottom: var(--border--light); + display: grid; + gap: var(--space--small); + padding-block-end: var(--gutter); + + h3, p { + margin: 0; + } +} + +.news-teases__date { + font-size: var(--font-size--body-small); +} + +.news-teases__title { + font-size: var(--font-size--heading-subsection); +} + + +.news-featured { + display: grid; + gap: var(--space--large); + grid-template-columns: minmax(0, 1fr); + padding-block-end: var(--space--large); + + @media (min-width: 55em) { + &:has(.news-featured__image) { + grid-template-columns: 1fr 1fr; + } + } +} + +.news-featured__image .image { + aspect-ratio: 3 / 2; + height: auto; + width: 100%; +} + +.news-featured__content { + align-content: start; + display: grid; + gap: var(--space--small); + + p { + margin: 0; + } +} + +.news-featured__date { + font-size: var(--font-size--body-small); +} + +.news-featured__title { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-section); + line-height: var(--line-height--tight); + margin: 0; +} + +.news-latest { + display: grid; + gap: var(--space--large); +} + +.news-latest__heading { + margin: 0; +} + +.news-tag-nav { + display: flex; + flex-wrap: wrap; + gap: var(--space--x-small); +} + +.news-tag-nav__link { + border: var(--border--dark); + border-radius: var(--border-radius--base); + color: var(--color--text-base); + font-size: var(--font-size--body-small); + font-weight: var(--font-weight--bold); + padding: var(--space--xx-small) var(--space--small); + text-decoration: none; + transition-property: background-color, border-color; + + &:hover { + background-color: var(--color--secondary-base); + border-color: transparent; + } +} + +.news-tag-nav__link[aria-current] { + background-color: var(--color--secondary-base); + border-color: transparent; +} + +.news-teases__tags { + display: flex; + font-size: var(--font-size--body-small); + gap: var(--space--small); +} diff --git a/src/css/components/_pagination.css b/src/css/components/_pagination.css new file mode 100644 index 0000000..1777101 --- /dev/null +++ b/src/css/components/_pagination.css @@ -0,0 +1,13 @@ +.pagination { + display: flex; + justify-content: space-between; +} + +.pagination__number { + font-size: var(--font-size--body-small); + margin: 0; +} + +.pagination__number-current { + font-weight: var(--font-weight--bold); +} diff --git a/src/css/components/_post.css b/src/css/components/_post.css new file mode 100644 index 0000000..b2e8cc7 --- /dev/null +++ b/src/css/components/_post.css @@ -0,0 +1,69 @@ +.post-header { + background-color: var(--color--theme-background); + padding-block: var(--space--x-large); +} + +.post-header__inner { + display: flex; + flex-direction: column; + gap: var(--space--small); +} + +.post-header__date { + font-size: var(--font-size--body-small); + font-weight: var(--font-weight--bold); + margin: 0; +} + +.post-header__title { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-title-small); + font-weight: var(--font-weight--bold); + line-height: var(--line-height--tight); + margin: 0; +} + +.post h2 { + border-bottom: var(--border--light); +} + +.post-toc { + align-self: start; + display: none; + position: sticky; + top: calc(var(--space--large) * 3); + + @media (min-width: 55em) { + display: block; + } +} + +[data-toc]:empty { + display: none; +} + +.post-toc__list { + border-left: var(--border--light); + display: flex; + flex-direction: column; + gap: var(--space--small); + padding-inline-start: var(--space--base); +} + +.post-toc__link { + background-color: transparent; + border: 0; + border-bottom: var(--border-width--thick) solid transparent; + color: var(--color--text-base); + font-size: var(--font-size--body-small); + font-weight: var(--font-weight--bold); + padding-block-end: var(--space--xx-small); + text-decoration: none; + transition-property: border-bottom-color; + + &:hover, + &[aria-current] { + border-bottom-color: var(--color--primary-base); + } +} + diff --git a/src/css/components/_section.css b/src/css/components/_section.css new file mode 100644 index 0000000..2772db6 --- /dev/null +++ b/src/css/components/_section.css @@ -0,0 +1,51 @@ +.section { + display: flex; + flex-direction: column; + gap: var(--space--medium); +} + +.section__heading { + display: flex; + flex-direction: column; + gap: var(--space--base); + + h2, + h3 { + margin: 0; + } + + > h2 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-overline); + font-weight: var(--font-weight--bold); + } + + > h3 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-section); + font-weight: var(--font-weight--normal); + line-height: var(--line-height--tight); + } +} + +.section__body { + max-width: 65ch; + + p { + margin: 0; + } +} + +.section--feature h2 { + align-items: center; + display: flex; + gap: var(--space--medium); + + &::after { + background-color: var(--color--secondary-base); + content: ""; + display: block; + height: var(--border-width--base); + width: 100%; + } +} diff --git a/src/css/components/_sponsor-group.css b/src/css/components/_sponsor-group.css new file mode 100644 index 0000000..3ec1743 --- /dev/null +++ b/src/css/components/_sponsor-group.css @@ -0,0 +1,16 @@ +.sponsor-group { + display: flex; + flex-direction: column; + gap: var(--space--small); +} + +.sponsor-group__heading { + font-family: var(--font-family--heading); + margin: 0; +} + +.section__content:has(.sponsor-group) { + display: flex; + flex-direction: column; + gap: var(--space--medium); +} diff --git a/src/css/components/_sponsor-logo.css b/src/css/components/_sponsor-logo.css new file mode 100644 index 0000000..e1968dd --- /dev/null +++ b/src/css/components/_sponsor-logo.css @@ -0,0 +1,29 @@ +.sponsor-logo { + align-items: center; + border: var(--border--light); + border-radius: var(--border-radius--base); + display: flex; + justify-content: center; + padding: var(--space--base); + + .image { + border-radius: 0; + + img { + object-fit: contain; + } + } +} + +a.sponsor-logo { + transition-property: border-color; + + &:hover { + border-color: var(--color--text-base); + } +} + +.sponsor-logo__name { + font-family: var(--font-family--heading); + font-weight: var(--font-weight--bold); +} diff --git a/src/css/components/_team-member.css b/src/css/components/_team-member.css new file mode 100644 index 0000000..e0a241c --- /dev/null +++ b/src/css/components/_team-member.css @@ -0,0 +1,17 @@ +.team-member { + display: flex; + flex-direction: column; + gap: var(--space--xx-small); + + .image { + aspect-ratio: 1; + } + + p { + margin: 0; + } +} + +.team-member__name { + font-weight: var(--font-weight--bold); +} diff --git a/src/css/components/_timeline.css b/src/css/components/_timeline.css new file mode 100644 index 0000000..24837b9 --- /dev/null +++ b/src/css/components/_timeline.css @@ -0,0 +1,138 @@ +.timeline { + display: flex; + flex-direction: column; + gap: var(--space--large); +} + +.timeline__heading { + h2, + h3 { + margin: 0; + } + + h2 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-overline); + font-weight: var(--font-weight--bold); + } + + h3 { + font-family: var(--font-family--heading); + font-size: var(--font-size--heading-section); + font-weight: var(--font-weight--bold); + line-height: var(--line-height--tight); + } +} + +.timeline__scroll { + overflow-x: auto; +} + +.timeline__track { + --_line-top: 2.375rem; + --_marker-size: 0.75rem; + + display: flex; + min-width: max-content; + padding-bottom: var(--space--base); + position: relative; + + &::before { + background-color: var(--color--primary-base); + content: ''; + height: var(--border-width--thick); + left: 0; + position: absolute; + right: 20ch; + top: var(--_line-top); + } +} + +.timeline__item { + align-items: flex-start; + background: none; + border: none; + cursor: pointer; + display: flex; + flex-direction: column; + font-family: var(--font-family--body); + font-size: var(--font-size--body-base); + min-width: 10rem; + padding: 0 var(--space--large) 0 0; + position: relative; + text-align: start; + z-index: 1; + + &:last-child { + padding-right: 0; + } + + &:hover { + .timeline__marker { + background-color: var(--color--primary-base); + } + } +} + +.timeline__year { + color: var(--color--text-base); + font-weight: var(--font-weight--bold); + line-height: var(--line-height--base); + margin-bottom: var(--space--x-small); +} + +.timeline__item[aria-pressed="true"] .timeline__year { + background-color: var(--color--primary-base); + color: var(--color--background-base); + padding-inline: var(--space--x-small); + border-radius: var(--border-radius--small); + font-weight: var(--font-weight--bold); +} + +.timeline__marker { + background-color: var(--color--background-base); + border: var(--border-width--thick) solid var(--color--primary-base); + border-radius: var(--border-radius--circle); + flex-shrink: 0; + height: var(--_marker-size, 0.75rem); + margin-bottom: var(--space--small); + width: var(--_marker-size, 0.75rem); +} + +.timeline__item[aria-pressed="true"] .timeline__marker { + background-color: var(--color--primary-base); +} + +.timeline__label { + color: var(--color--text-base); + line-height: var(--line-height--base); + width: 20ch; +} + +.timeline__detail { + background-color: var(--color--background-base); + border: var(--border--light); + border-radius: var(--border-radius--medium); + display: flex; + flex-direction: column; + gap: var(--space--x-small); + padding: var(--space--medium); + + &[hidden] { + display: none; + } +} + +.timeline__detail-year { + color: var(--color--text-base); + font-size: var(--font-size--body-small); + margin: 0; +} + +.timeline__detail-body { + color: var(--color--text-base); + + p { + margin: 0; + } +} diff --git a/src/css/components/_video-tease.css b/src/css/components/_video-tease.css new file mode 100644 index 0000000..62a8b60 --- /dev/null +++ b/src/css/components/_video-tease.css @@ -0,0 +1,74 @@ +.video-tease { + display: grid; + gap: var(--space--x-small); + + p { + margin: 0; + } +} + +.video-tease__image { + --play-button-size: 3rem; + align-items: center; + + border: var(--border--light); + border-radius: var(--border-radius--base); + display: grid; + justify-items: center; + + .image { + grid-area: 1 / 1; + + img { + transition: 0.45s transform var(--transition-timing--base); + } + } + + &::before { + aspect-ratio: cos(30deg); + background-color: var(--color--primary-base); + clip-path: polygon(100% 50%,0 100%,0 0); + content: ""; + display: block; + grid-area: 1 / 1; + height: calc(var(--play-button-size) / 2); + transform: translateX(2px); + transition: var(--transition-duration--base) background-color var(--transition-timing--base); + z-index: 2; + } + + &::after { + align-self: center; + background-color: var(--color--background-base); + border: var(--border--dark); + border-radius: var(--border-radius--circle); + content: ""; + display: block; + grid-area: 1 / 1; + height: var(--play-button-size); + justify-self: center; + transition: var(--transition-duration--base) background-color var(--transition-timing--base); + width: var(--play-button-size); + z-index: 1; + } + + &:hover { + + .image img { + transform: scale(1.05); + } + + &::before { + background-color: var(--color--background-base); + } + + &::after { + background-color: var(--color--secondary-base); + } + } +} + +.video-tease__title { + font-family: var(--font-family--heading); + font-weight: var(--font-weight--bold); +} diff --git a/src/css/components/back.css b/src/css/components/back.css deleted file mode 100644 index 236c34b..0000000 --- a/src/css/components/back.css +++ /dev/null @@ -1,5 +0,0 @@ -.back { - font-size: 16px; - display: inline-block; - margin: 0 0 20px 0; -} diff --git a/src/css/components/button.css b/src/css/components/button.css deleted file mode 100644 index 3a72194..0000000 --- a/src/css/components/button.css +++ /dev/null @@ -1,61 +0,0 @@ -.kg-button-card .kg-btn, -.kg-button-card .kg-btn-accent { - background: linear-gradient(0deg, #e14943 0%, #fa5d54 100%); - border: none; - border-radius: 12px; - box-shadow: 0px 4px 13px 0px rgba(250, 93, 84, 0.3); - color: white; - cursor: pointer; - display: flex; - font-family: 'Rubik', sans-serif; - font-size: 0.875rem; - font-weight: 700; - justify-content: center; - padding: 15px; - text-transform: uppercase; - width: 100%; -} - -.kg-button-card .kg-btn:hover, -.kg-button-card .kg-btn-accent:hover { - background: linear-gradient(0deg, #e14943 0%, #fa5d54 100%); - box-shadow: 0px 4px 13px 0px rgba(250, 93, 84, 0.4); -} - -.kg-button-card__group { - display: grid; - grid-template-columns: 1fr; - gap: 16px; -} - -.kg-button-card.kg-align-left, -.kg-button-card.kg-align-center { - display: flex; -} - -.kg-button-card.kg-align-left { - justify-content: flex-start; -} - -.kg-button-card.kg-align-center { - justify-content: center; -} - -@media (min-width: 768px) { - .kg-button-card__group { - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 24px; - } -} - -@media (min-width: 834px) { - .kg-button-card .kg-btn, - .kg-button-card .kg-btn-accent { - font-size: 1rem; - width: fit-content; - } - - .kg-button-card__group { - grid-template-columns: repeat(2, max-content); - } -} diff --git a/src/css/components/code.css b/src/css/components/code.css deleted file mode 100644 index 863b8ca..0000000 --- a/src/css/components/code.css +++ /dev/null @@ -1,119 +0,0 @@ -/* Inline code */ -:not(pre) > code { - background-color: var(--color-lightblue); - border: 1px solid color-mix(in srgb, var(--color-blue) 25%, transparent); - border-radius: 4px; - color: var(--color-mutednavy); - font-family: 'Menlo', 'Consolas', 'Monaco', monospace; - font-size: 0.875em; - padding: 0.15em 0.4em; -} - -/* Code block wrapper — Ghost wraps
 in a .kg-code-card */
-.kg-code-card {
-    margin: 1.75rem 0;
-}
-
-pre {
-    background-color: var(--color-navy);
-    border-radius: 6px;
-    color: #cdd9e5;
-    font-family: 'Menlo', 'Consolas', 'Monaco', monospace;
-    font-size: 0.875rem;
-    line-height: 1.6;
-    margin: 1.75rem 0;
-    overflow-x: auto;
-    padding: 1.25rem 1.5rem;
-    position: relative;
-}
-
-pre code {
-    background: none;
-    border: none;
-    color: inherit;
-    font-size: inherit;
-    padding: 0;
-}
-
-pre.wrap {
-    white-space: pre-wrap;
-    overflow-x: visible;
-}
-
-/* Language label — set via JS from Prism's language-* class */
-pre[data-language]::before {
-    background-color: var(--color-yellow);
-    border-radius: 0 0 4px 4px;
-    color: var(--color-navy);
-    content: attr(data-language);
-    font-family: 'Inter', sans-serif;
-    font-size: 0.7rem;
-    font-weight: 600;
-    letter-spacing: 0.05em;
-    padding: 2px 8px;
-    position: absolute;
-    right: 1rem;
-    text-transform: uppercase;
-    top: 0;
-}
-
-/* Syntax token colors — tuned for the navy background */
-.token.comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
-    color: #768390;
-    font-style: italic;
-}
-
-.token.punctuation {
-    color: #8dbbe8;
-}
-
-.token.namespace {
-    opacity: 0.7;
-}
-
-.token.property,
-.token.tag,
-.token.boolean,
-.token.number,
-.token.constant,
-.token.symbol,
-.token.deleted {
-    color: var(--color-red);
-}
-
-.token.selector,
-.token.attr-name,
-.token.string,
-.token.char,
-.token.builtin,
-.token.inserted {
-    color: var(--color-green);
-}
-
-.token.operator,
-.token.entity,
-.token.url,
-.language-css .token.string,
-.style .token.string {
-    color: #8dbbe8;
-}
-
-.token.atrule,
-.token.attr-value,
-.token.keyword {
-    color: var(--color-blue);
-}
-
-.token.function,
-.token.class-name {
-    color: var(--color-yellow);
-}
-
-.token.regex,
-.token.important,
-.token.variable {
-    color: #f69d50;
-}
diff --git a/src/css/components/divider.css b/src/css/components/divider.css
deleted file mode 100644
index d82124a..0000000
--- a/src/css/components/divider.css
+++ /dev/null
@@ -1,5 +0,0 @@
-hr {
-    border: 3px solid var(--color-yellow);
-    width: 70px;
-    margin: 0 0 30px;
-}
diff --git a/src/css/components/get-involved.css b/src/css/components/get-involved.css
deleted file mode 100644
index 57ae753..0000000
--- a/src/css/components/get-involved.css
+++ /dev/null
@@ -1,107 +0,0 @@
-.get-involved {
-    max-width: var(--layout-inner-max-width);
-    margin: auto;
-    padding: 70px 40px;
-
-    h2,
-    p,
-    a {
-        color: var(--color-navy);
-    }
-
-    hr {
-        margin: 0 auto 30px;
-    }
-
-    .get-involved__title {
-        font-size: 2rem;
-        font-weight: 500;
-        line-height: 3rem;
-        text-align: center;
-        margin-bottom: 16px;
-    }
-
-    .get-involved__row {
-        display: grid;
-        gap: 16px;
-        grid-template-columns: 1fr;
-    }
-
-    .get-involved__column--newsletter,
-    .get-involved__column--content {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        gap: 16px;
-
-        p {
-            margin: 0;
-            text-align: center;
-        }
-    }
-
-    .get-involved__column--newsletter {
-        p {
-            font-family: 'Rubik', sans-serif;
-            font-size: 1.5rem;
-            font-weight: 500;
-            line-height: 2.25rem;
-        }
-
-        input {
-            border: 1px solid rgba(220, 233, 250, 1);
-            border-radius: 8px;
-            box-shadow: 3px 3px 10px 0px rgba(0, 0, 0, 0.07);
-            color: var(--color-navy);
-            min-height: 50px;
-            font-size: 1rem;
-            padding: 12px 20px;
-            width: 100%;
-        }
-
-        input::placeholder {
-            color: rgba(160, 168, 184, 1);
-        }
-
-        .get-involved__form__row {
-            display: grid;
-            gap: 12px;
-            grid-template-columns: 1fr;
-            width: 100%;
-        }
-    }
-
-    @media (min-width: 834px) {
-        padding: 96px 56px 0;
-
-        .get-involved__title {
-            font-size: 2.625rem;
-        }
-
-        .get-involved__column--newsletter {
-            .get-involved__form__row {
-                grid-template-columns: 300px max-content;
-                justify-content: center;
-            }
-        }
-    }
-
-    @media (min-width: 1440px) {
-        padding: 96px 0;
-
-        .get-involved__row {
-            grid-template-columns: repeat(2, minmax(0, 1fr));
-        }
-
-        .get-involved__column--newsletter,
-        .get-involved__column--content {
-            gap: 48px;
-        }
-
-        .get-involved__column--content {
-            p {
-                text-align: left;
-            }
-        }
-    }
-}
diff --git a/src/css/components/profile-image.css b/src/css/components/profile-image.css
deleted file mode 100644
index 5579bcd..0000000
--- a/src/css/components/profile-image.css
+++ /dev/null
@@ -1,10 +0,0 @@
-.profile-image {
-    border: 2px solid var(--color-white);
-    border-radius: 100%;
-    box-shadow: 0 6px 14px rgb(39 41 45 / 26%);
-    display: block;
-    height: 200px;
-    margin: 0 auto 1rem;
-    width: 200px;
-    object-fit: cover;
-}
diff --git a/src/css/components/sponsors.css b/src/css/components/sponsors.css
deleted file mode 100644
index a59bc9d..0000000
--- a/src/css/components/sponsors.css
+++ /dev/null
@@ -1,58 +0,0 @@
-.sponsors {
-    background-color: white;
-    box-shadow: 0px 4px 13px 0px rgba(167, 167, 167, 0.3);
-    border-radius: 0 0 12px 12px;
-    padding: 0;
-    margin: 30px 0;
-
-    .sponsors__title {
-        background-color: var(--color-red);
-        border-radius: 12px 12px 0 0;
-        color: white;
-        margin: 0;
-        padding: 36px 20px;
-        text-align: center;
-    }
-}
-
-.sponsors__inner {
-    display: flex;
-    flex-direction: column;
-    column-gap: 60px;
-    row-gap: 20px;
-    padding: 60px 20px;
-    a {
-        text-decoration: none;
-        border-bottom: 0;
-        background-image: none;
-        box-shadow: none;
-    }
-    img {
-        height: 60px;
-        max-width: 100%;
-        object-fit: contain;
-    }
-}
-
-@media (min-width: 834px) {
-    .sponsors {
-        .sponsors__title {
-            font-size: 1.125rem;
-            line-height: 1.75rem;
-        }
-    }
-
-    .sponsors__inner {
-        flex-direction: row;
-        flex-wrap: wrap;
-        justify-content: center;
-    }
-}
-
-@media (min-width: 1440px) {
-    .sponsors {
-        .sponsors__title {
-            font-size: 1.5rem;
-        }
-    }
-}
diff --git a/src/css/components/static-content.css b/src/css/components/static-content.css
deleted file mode 100644
index 37bd1d8..0000000
--- a/src/css/components/static-content.css
+++ /dev/null
@@ -1,43 +0,0 @@
-.static-content {
-    width: 50%;
-    margin: 0 auto;
-    max-width: var(--layout-inner-max-width);
-}
-
-.static-content.upcoming-conference-container {
-    margin-top: -100px;
-}
-
-.static-content h3 {
-    color: var(--color-red);
-}
-
-.static-content ul {
-    margin: 0;
-    padding: 0;
-}
-
-.static-content ul li {
-    line-height: 27px;
-    margin: 0 0 15px 0;
-    padding: 0 0 0 20px;
-    background: url(/assets/images/bullet.svg) 0 8px no-repeat;
-    list-style-type: none;
-}
-
-.pagination {
-    display: flex;
-    justify-content: space-between;
-}
-
-@media screen and (max-width: 900px) and (orientation: portrait),
-    (max-width: 823px) and (orientation: landscape) {
-    .static-content {
-        width: auto;
-        padding: 0 20px;
-    }
-
-    .static-content.upcoming-conference-container {
-        margin-top: -5px;
-    }
-}
diff --git a/src/css/layout/container.css b/src/css/layout/container.css
deleted file mode 100644
index 1d1570f..0000000
--- a/src/css/layout/container.css
+++ /dev/null
@@ -1,26 +0,0 @@
-.container,
-.container--full-width {
-    margin: 0 auto;
-}
-
-.container {
-    max-width: var(--layout-inner-max-width);
-    padding: 0 20px;
-    width: 100%;
-}
-
-.container--full-width {
-    max-width: unset;
-}
-
-@media (min-width: 834px) {
-    .container {
-        padding: 0 40px;
-    }
-}
-
-@media (min-width: 1440px) {
-    .container {
-        padding: 0;
-    }
-}
diff --git a/src/css/layout/dropdown.css b/src/css/layout/dropdown.css
deleted file mode 100644
index 15b7b61..0000000
--- a/src/css/layout/dropdown.css
+++ /dev/null
@@ -1,99 +0,0 @@
-li.menu-item-has-children {
-  position: relative;
-  padding-right: 20px;
-  display: inline-block;
-}
-
-.menu-item-has-children svg {
-  position: absolute;
-  right: -6px;
-  top: 56%;
-  transform: translate(-0%, -50%) scale(1);
-}
-
-ul.ghost-submenu {
-  background: #fff;
-  color: #000;
-  padding: 10px 20px;
-  border-radius: 5px;
-  width: 140px;
-  max-width: 200px;
-  position: absolute;
-  visibility: hidden;
-  line-height: 3;
-  z-index: 1;
-  opacity: 0;
-  top: 30px;
-  transition: 0.3s;
-  box-shadow: 0 1px 5px 0 rgb(0 0 0 / 14%);
-  left: 0;
-  display: block;
-}
-
-li.menu-item-has-children:hover ul.ghost-submenu {
-  visibility: visible!important;
-  opacity: 1!important;
-  top: 45px!important;
-}
-
-ul.ghost-submenu li {
-  list-style: none;
-}
-
-nav > ul.ghost-dropdown-menu > li {
-  opacity: 0;
-}
-
-li.nav-item.menu-item-has-children.menu-item-has-megamenu ul.ghost-submenu {
-  width: 100vh;
-}
-
-@media screen and (max-width: 1100px) and (orientation: portrait),
-(max-width: 1005px) and (orientation: landscape) {
-
-  li.menu-item-has-children ul.ghost-submenu {
-    top: 0;
-    left: 0;
-    right: 0;
-    border: none;
-    box-shadow: none;
-    visibility: visible !important;
-    opacity: 1!important;
-    width: 100%;
-    min-width: initial;
-    max-width: none;
-  }
-
-  li.menu-item-has-children > a {
-    display: none;
-  }
-
-  li.menu-item-has-children {
-    position: relative;
-    width: 100%;
-    padding: 0 0;
-    display: block;
-    justify-content: flex-end;
-  }
-
-  li.menu-item-has-children ul.ghost-submenu {
-    position: absolute;
-    width: 100%;
-    right: 0;
-    padding: 0px 0px;
-    margin: 0px 0px;
-  }
-
-  li.menu-item-has-children ul.ghost-submenu::before {
-    content: none;
-  }
-
-  li.menu-item-has-children ul.ghost-submenu li {
-    text-align: right;
-    width: 100%;
-  }
-
-  li.menu-item-has-children:hover ul.ghost-submenu {
-    top: 0 !important;
-  }
-}
diff --git a/src/css/layout/footer.css b/src/css/layout/footer.css
deleted file mode 100644
index e486cd7..0000000
--- a/src/css/layout/footer.css
+++ /dev/null
@@ -1,194 +0,0 @@
-.footer {
-    background-color: var(--color-lightblue);
-    width: 100%;
-
-    .footer__inner {
-        display: flex;
-        flex-direction: column;
-        margin: auto;
-        max-width: var(--layout-inner-max-width);
-        padding: 40px;
-    }
-
-    .footer__top {
-        border-bottom: 2px solid #dce9fa;
-        display: grid;
-        grid-template-columns: 1fr;
-        margin-bottom: 25px;
-        padding-bottom: 36px;
-    }
-
-    .footer__logo {
-        justify-self: center;
-        max-width: 245px;
-        width: 100%;
-    }
-
-    .footer__links {
-        font-family: 'Rubik', sans-serif;
-        font-size: 1rem;
-        line-height: 1.125rem;
-        margin-bottom: 36px;
-
-        ul {
-            align-items: center;
-            display: flex;
-            flex-direction: column;
-            list-style: none;
-            margin: 0;
-            padding: 0;
-        }
-
-        li {
-            align-items: center;
-            display: flex;
-            min-height: 44px;
-        }
-
-        a {
-            box-shadow: none;
-        }
-
-        a:hover {
-            box-shadow: inset 0 -2px 0 var(--color-red);
-        }
-    }
-
-    .footer__bottom {
-        display: grid;
-        gap: 48px;
-        grid-template-columns: 1fr;
-    }
-
-    .footer__form {
-        align-items: center;
-        display: flex;
-        flex-direction: column;
-    }
-
-    .footer__form__row {
-        display: grid;
-        gap: 12px;
-        grid-template-columns: 1fr;
-        justify-content: center;
-        width: 100%;
-
-        input {
-            border: 1px solid #dce9fa;
-            border-radius: 8px;
-            color: var(--color-navy);
-            min-height: 50px;
-            font-size: 1rem;
-            padding: 12px 20px;
-            width: 100%;
-        }
-
-        input::placeholder {
-            color: rgba(160, 168, 184, 1);
-        }
-
-        .kg-button-card {
-            width: 100%;
-        }
-    }
-
-    .footer__bottom__socials {
-        align-items: center;
-        display: flex;
-        flex-direction: column;
-        gap: 16px;
-    }
-
-    .footer__bottom__socials__links {
-        align-items: center;
-        display: flex;
-        flex-wrap: wrap;
-        gap: 14px;
-        justify-content: center;
-
-        figcaption {
-            display: none;
-        }
-
-        a {
-            box-shadow: none;
-        }
-
-        figure.kg-image-card {
-            margin: 0;
-
-            a {
-                align-items: center;
-                display: flex;
-                height: 24px;
-                width: 24px;
-            }
-        }
-    }
-
-    @media (min-width: 834px) {
-        .footer__top {
-            align-items: center;
-            grid-template-columns: repeat(2, 1fr);
-            padding-bottom: 36px;
-
-            .kg-button-card {
-                justify-self: end;
-            }
-        }
-
-        .footer__logo {
-            justify-self: start;
-            margin: 0 0 -14px -10px;
-        }
-
-        .footer__bottom {
-            gap: 36px;
-            grid-template-columns: 1fr max-content;
-        }
-
-        .footer__form {
-            align-items: flex-start;
-        }
-
-        .footer__form__row {
-            grid-template-columns: 1fr max-content;
-        }
-
-        .footer__links {
-            ul {
-                column-gap: 24px;
-                flex-direction: row;
-                flex-wrap: wrap;
-                justify-content: center;
-                row-gap: 8px;
-            }
-        }
-    }
-
-    @media (min-width: 1440px) {
-        .footer__inner {
-            padding: 40px 0;
-        }
-
-        .footer__bottom {
-            gap: 0;
-            grid-template-columns: repeat(2, 1fr);
-        }
-
-        .footer__bottom__socials {
-            justify-self: end;
-        }
-
-        .footer__form__row {
-            grid-template-columns: 280px max-content;
-            justify-content: start;
-        }
-
-        .footer__links {
-            ul {
-                justify-content: end;
-            }
-        }
-    }
-}
diff --git a/src/css/layout/navigation-top.css b/src/css/layout/navigation-top.css
deleted file mode 100644
index 647c73f..0000000
--- a/src/css/layout/navigation-top.css
+++ /dev/null
@@ -1,154 +0,0 @@
-.navigation--top {
-    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
-
-    .navigation__inner {
-        align-items: center;
-        display: grid;
-        grid-template-areas: 'logo trigger membership';
-        grid-template-columns: 1fr repeat(2, max-content);
-        margin: auto;
-        max-width: var(--layout-inner-max-width);
-        padding: 8px 20px 8px 10px;
-    }
-
-    .navigation__logo {
-        box-shadow: none;
-        display: flex;
-        grid-area: logo;
-        max-width: fit-content;
-
-        img {
-            height: 75px;
-            width: 75px;
-        }
-    }
-
-    .navigation__mobile-menu-trigger {
-        background-color: white;
-        background-repeat: no-repeat;
-        background-size: contain;
-        border: none;
-        cursor: pointer;
-        height: 24px;
-        margin-right: 20px;
-        width: 24px;
-    }
-
-    .navigation__mobile-menu-trigger.closed {
-        background-image: url('/assets/images/icon__burger.svg');
-    }
-
-    .navigation__mobile-menu-trigger.opened {
-        background-image: url('/assets/images/icon__close.svg');
-    }
-
-    .navigation__list__wrapper {
-        grid-area: trigger;
-        position: relative;
-    }
-
-    .navigation__list {
-        background-color: white;
-        border-color: rgba(0, 0, 0, 0.1);
-        border-radius: 0 0 8px 8px;
-        border-style: solid;
-        border-width: 0 1px 1px 1px;
-        box-shadow: 0px 10px 30px 0 rgba(0, 0, 0, 0.04);
-        display: none;
-        flex-direction: column;
-        gap: 20px;
-        left: 25%;
-        list-style: none;
-        margin: 0;
-        min-width: 275px;
-        padding: 16px 30px;
-        position: absolute;
-        top: 61.5px;
-        transform: translateX(-50%);
-        z-index: 1;
-    }
-
-    .navigation__list--mobile-closed {
-        display: none;
-    }
-
-    .navigation__list--mobile-opened {
-        display: flex;
-    }
-
-    .navigation__list--mobile-opened::before {
-        border-top: 4px solid var(--color-yellow);
-        content: '';
-        display: block;
-        position: absolute;
-        right: calc(50% - 37.5px);
-        top: -3px;
-        width: 75px;
-    }
-
-    .navigation__item {
-        a {
-            align-items: center;
-            box-shadow: none;
-            color: var(--color-navy);
-            display: flex;
-            font-family: 'Rubik', sans-serif;
-            font-size: 1rem;
-            line-height: 1.125rem;
-            min-height: 30px;
-            padding: 12px;
-        }
-
-        a:hover {
-            background-color: var(--color-lightblue);
-        }
-    }
-
-    .navigation__membership {
-        grid-area: membership;
-    }
-
-    @media (min-width: 1080px) {
-        .navigation__mobile-menu-trigger {
-            display: none;
-        }
-
-        .navigation__inner {
-            grid-template-columns: max-content 1fr max-content;
-            padding: 0 20px 0 10px;
-        }
-
-        .navigation__logo {
-            margin-left: -8px;
-        }
-
-        .navigation__mobile-menu-trigger {
-            display: none;
-        }
-
-        .navigation__list {
-            border: none;
-            box-shadow: none;
-            display: flex;
-            flex-direction: row;
-            gap: 0;
-            justify-self: center;
-            left: auto;
-            min-width: unset;
-            padding: 0;
-            position: relative;
-            top: auto;
-            transform: unset;
-        }
-
-        .navigation__list::before {
-            display: none;
-        }
-    }
-
-    @media (min-width: 1440px) {
-        .navigation__inner {
-            padding: 0;
-        }
-    }
-}
diff --git a/src/css/layout/reset.css b/src/css/layout/reset.css
deleted file mode 100644
index 37aa7e0..0000000
--- a/src/css/layout/reset.css
+++ /dev/null
@@ -1,24 +0,0 @@
-* {
-    box-sizing: border-box;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-}
-
-html {
-    scroll-behavior: smooth;
-}
-
-body {
-    margin: 0;
-    padding: 0;
-}
-
-main {
-    padding: 20px 0;
-}
-
-@media (min-width: 834px) {
-    main {
-        padding: 48px 0;
-    }
-}
diff --git a/src/css/modern.css b/src/css/modern.css
deleted file mode 100644
index d519d5a..0000000
--- a/src/css/modern.css
+++ /dev/null
@@ -1,293 +0,0 @@
-#modern {
-    .post {
-        padding: 2.5rem;
-        padding-top: 0;
-    }
-    h1,
-    h2,
-    h3 {
-        margin-bottom: 1rem;
-        column-span: all !important;
-        > a {
-            text-decoration: none;
-        }
-    }
-    h1,
-    h2 {
-        position: relative;
-        padding-bottom: 0.75rem;
-
-        &::after {
-            content: '';
-            position: absolute;
-            left: 0;
-            right: 0;
-            bottom: 0;
-            height: 3px;
-            background-color: var(--color-yellow);
-            width: 70px;
-        }
-    }
-    h1 {
-        text-transform: uppercase;
-    }
-
-    .mission-and-vision {
-        display: grid;
-        grid-template-columns: 1fr;
-        gap: 2.5rem;
-        margin-bottom: 2.5rem;
-        margin-top: 2.5rem;
-    }
-
-    .post .column img {
-        max-width: 100%;
-        height: 100%;
-        object-fit: cover;
-        border-radius: 0.75rem;
-    }
-
-    .program-support {
-        background-color: var(--color-lightblue);
-        margin-bottom: 2.5rem;
-        margin-top: 2.5rem;
-        border-radius: 0.5rem;
-        padding: 20px;
-    }
-
-    .program-support span {
-        background-color: var(--color-yellow);
-        padding: 1rem;
-        margin: 0 1rem 1rem 0;
-        font-size: 1.25rem;
-        font-weight: bold;
-        min-width: 200px;
-        white-space: nowrap;
-        border-radius: 0.5rem;
-        padding: 1rem;
-        display: inline-block;
-    }
-    @media (min-width: 700px) {
-        .program-support span {
-            font-size: 1.5rem;
-            padding: 1rem 2.5rem;
-        }
-    }
-    .program-support span:nth-of-type(2) {
-        background-color: var(--color-red);
-        color: white;
-    }
-    .program-support span:nth-of-type(3) {
-        color: white;
-        background-color: var(--color-blue);
-    }
-    .program-support span:nth-of-type(4) {
-        background-color: var(--color-green);
-    }
-    .projects {
-        background-color: var(--color-darkred);
-        color: var(--color-white);
-        margin-bottom: 2.5rem;
-        margin-top: 2.5rem;
-        border-radius: 0.5rem;
-        padding: 20px;
-    }
-    .project {
-        width: 100%;
-        background-color: var(--color-navy);
-        color: var(--color-white);
-        border-radius: 0.5rem;
-        padding: 1.5rem;
-        padding-bottom: 2rem;
-    }
-    .projects .projects-list {
-        display: grid;
-        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
-        gap: 2.5rem;
-        width: 100%;
-        margin-bottom: 2.5rem;
-
-        h1 {
-            font-size: 20px;
-        }
-        @media (min-width: 700px) {
-            h1 {
-                font-size: 26px;
-            }
-        }
-        @media (min-width: 1024px) {
-            h1 {
-                font-size: 32px;
-            }
-        }
-    }
-    .project h1 {
-        font-weight: 400;
-    }
-    .project img {
-        object-fit: cover;
-    }
-
-    @media (min-width: 400px) {
-        .post {
-            width: 95%;
-            margin: 0 auto;
-        }
-    }
-
-    @media (min-width: 550px) {
-        .post {
-            width: 80%;
-            margin: 0 auto;
-        }
-    }
-
-    @media (min-width: 700px) {
-        .post {
-            width: 100%;
-            max-width: 800px;
-            margin: 0 auto;
-        }
-        .post .two-up {
-            column-count: 2; /* Number of columns */
-            column-gap: 2.5rem; /* Spacing between columns */
-        }
-        .mission-and-vision {
-            grid-template-columns: 1fr 1fr;
-        }
-    }
-
-    @media (min-width: 1350px) {
-        .post {
-            width: 100% !important;
-            max-width: 1024px !important;
-        }
-
-        .gh-sidebar {
-            position: absolute;
-            left: 0;
-        }
-
-        .gh-toc {
-            position: sticky;
-            top: 4vmin;
-            max-width: calc((100vw - 900px) / 2);
-            padding-right: 2rem;
-        }
-
-        .projects, .program-support {
-            padding: 60px;
-        }
-    }
-
-    .gh-toc .is-active-link::before {
-        background-color: var(--ghost-accent-color);
-    }
-
-    .team {
-        text-align: center;
-    }
-
-    .team-photo {
-        width: 100%;
-        height: auto;
-        border-radius: 0.5rem;
-        object-fit: cover;
-    }
-
-    .team-info {
-        margin-top: 0.5rem;
-    }
-
-    .team-name {
-        font-weight: bold;
-        font-size: 1.1rem;
-        margin-bottom: 0;
-    }
-
-    .team-title {
-        font-size: 0.9rem;
-    }
-    .level {
-        margin-bottom: 2.5rem;
-        box-shadow: 5px 5px 15px rgba(120, 120, 120, 0.1);
-    }
-    .level.silver, .level.major {
-        width: 45%;
-    }
-    .level .name {
-        padding: 1rem 0 0.25rem 0;
-        margin: auto;
-        border-top-left-radius: .75rem;
-        border-top-right-radius: .75rem;
-
-        h3 {
-            text-align: center;
-
-        }
-    }
-
-    .corporate-sponsors {
-        display: flex;
-        flex-wrap: wrap;
-        justify-content: space-between;
-        gap: 1rem;
-        margin-top: 48px;
-    }
-    .level.ruby, .level.gold {
-        flex: 1 1 100%;
-    }
-    .level.silver, .level.major {
-        flex: 1 1 100%;
-    }
-    @media (min-width: 1024px) {
-        .level.silver, .level.major {
-            flex: 1 1 auto;
-            /* flex-basis: calc(50% - 8px); */
-        }
-    }
-    .level.ruby .name {
-        background-color: var(--color-red);
-        color: var(--color-white);
-    }
-    .level.gold .name {
-        background-color: var(--color-yellow);
-    }
-    .level.silver .name {
-        background-color: var(--color-blue);
-        color: var(--color-white);
-    }
-    .level.major .name {
-        background-color: var(--color-green);
-        color: var(--color-white);
-    }
-    .level .bucket {
-        border-bottom-left-radius: .75rem;
-        border-bottom-right-radius: .75rem;
-        display: flex;
-        justify-content: space-evenly;
-        padding: 1rem;
-        flex-direction: row;
-        flex-wrap: wrap;
-
-        img {
-            height: 66px;
-            margin: 2.5rem;
-        }
-    }
-
-    .pipedriveWebForms {
-        max-width: 100%; /* Ensure the form doesn't exceed the container width */
-        padding: 1em; /* Add some padding for spacing */
-        box-sizing: border-box; /* Include padding in width calculations */
-        margin: 1.5rem 0 0 0;
-      }
-
-      .pipedriveWebForms iframe {
-        width: 100%; /* Ensure the iframe scales to the container */
-        max-width: 600px; /* Set a reasonable max width */
-        height: auto; /* Adjust height proportionally */
-        display: block; /* Ensure it behaves like a block-level element */
-        margin: 1.5rem auto; /* Center the form on the page */
-      }
-}
diff --git a/src/css/pages/about.css b/src/css/pages/about.css
deleted file mode 100644
index a915628..0000000
--- a/src/css/pages/about.css
+++ /dev/null
@@ -1,341 +0,0 @@
-.page-about {
-    main {
-        padding-top: 0;
-    }
-
-    .page-about__hero {
-        align-items: center;
-        background-image: url('/assets/images/about__hero--background.jpg');
-        background-repeat: no-repeat;
-        background-size: cover;
-        color: white;
-        display: flex;
-        justify-content: center;
-    }
-
-    .page-about__hero__inner {
-        max-width: 1135px;
-        padding: 96px 40px;
-
-        h2,
-        p {
-            margin-bottom: 32px;
-        }
-
-        h1 {
-            margin-bottom: 16px;
-            text-transform: uppercase;
-        }
-
-        h2 {
-            font-size: 2rem;
-        }
-    }
-
-    .page-about__position {
-        background: var(--color-offwhite);
-        margin: auto;
-    }
-
-    .page-about__position__inner {
-        display: grid;
-        gap: 48px;
-        grid-template-areas: 'image' 'content';
-        grid-template-columns: 1fr;
-        justify-content: center;
-        margin: auto;
-        max-width: 1135px;
-        padding: 70px 40px;
-    }
-
-    .page-about__position--content {
-        font-family: 'Rubik', sans-serif;
-        font-size: 1rem;
-        grid-area: content;
-        line-height: 1.75rem;
-    }
-
-    .page-about__position--image {
-        border-radius: 8px;
-        grid-area: image;
-        height: 400px;
-        margin: auto;
-        max-width: 345px;
-        object-fit: cover;
-        width: 100%;
-    }
-
-    .page-about__history {
-        background-color: var(--color-navy);
-        margin: auto;
-    }
-
-    .page-about__history__inner {
-        margin: auto;
-        max-width: 1135px;
-        padding: 70px 40px;
-    }
-
-    .page-about__history__title {
-        color: white;
-        margin-bottom: 16px;
-        text-transform: uppercase;
-    }
-
-    .page-about__history__section-one,
-    .page-about__history__section-two {
-        margin-bottom: 48px;
-    }
-
-    .page-about__history__section-one,
-    .page-about__history__section-three {
-        display: grid;
-        gap: 48px;
-        grid-template-columns: 1fr;
-    }
-
-    .page-about__history__section-one--content,
-    .page-about__history__section-three--content {
-        color: white;
-
-        p:first-child {
-            margin-top: 0;
-        }
-    }
-
-    .page-about__history__section-one--image,
-    .page-about__history__section-three--image {
-        border-radius: 8px;
-        height: 400px;
-        object-fit: cover;
-        width: 100%;
-    }
-
-    .page-about__history__section-two {
-        background-color: var(--color-offwhite);
-        border-radius: 8px;
-        display: grid;
-        gap: 48px;
-        grid-template-columns: 1fr;
-        padding: 40px;
-    }
-
-    .page-about__history__section-two--content,
-    .page-about__history__section-three--content {
-        p:first-child {
-            margin-top: 0;
-        }
-
-        p:last-child {
-            margin-bottom: 0;
-        }
-    }
-
-    .page-about__history__section-two--image {
-        border-radius: 8px;
-        height: 150px;
-        object-fit: cover;
-        width: 100%;
-    }
-
-    .page-about__team {
-        display: flex;
-        flex-direction: column;
-        gap: 24px;
-        margin: auto;
-        max-width: 1135px;
-        padding: 96px 40px;
-    }
-
-    .page-about__team__header {
-        h2 {
-            color: var(--color-red);
-            margin-bottom: 16px;
-            text-transform: uppercase;
-        }
-
-        hr {
-            margin-bottom: 16px;
-        }
-
-        p {
-            font-family: 'Rubik', sans-serif;
-            font-size: 1.5rem;
-            font-style: italic;
-            font-weight: 300;
-            line-height: 3rem;
-            margin: 0;
-        }
-    }
-
-    .page-about__team__member {
-        margin: 0;
-
-        h4,
-        p {
-            margin: 0;
-        }
-    }
-
-    .page-about__team__member__image {
-        border-radius: 8px;
-        height: 300px;
-        margin-bottom: 16px;
-        object-fit: cover;
-        width: 100%;
-    }
-
-    .page-about__team__member--details {
-        display: flex;
-        flex-direction: column;
-        gap: 8px;
-    }
-
-    .page-about__team__staff,
-    .page-about__team__directors {
-        background-color: var(--color-offwhite);
-        border-radius: 8px;
-        padding: 36px;
-    }
-
-    .page-about__team__staff__header,
-    .page-about__team__directors__header {
-        margin-bottom: 36px;
-
-        h3 {
-            margin-bottom: 8px;
-        }
-
-        p {
-            margin: 0;
-        }
-    }
-
-    .page-about__team__staff__inner,
-    .page-about__team__directors__inner {
-        display: grid;
-        gap: 24px;
-        grid-template-columns: 1fr;
-    }
-
-    @media (min-width: 600px) {
-        .page-about__team__staff__inner,
-        .page-about__team__directors__inner {
-            grid-template-columns: repeat(2, minmax(0, 1fr));
-        }
-    }
-
-    @media (min-width: 834px) {
-        .page-about__hero {
-            min-height: 834px;
-        }
-
-        .page-about__hero__inner {
-            padding: 0 56px;
-
-            h2 {
-                font-size: 2rem;
-            }
-        }
-
-        .page-about__position__inner {
-            align-items: center;
-            grid-template-areas: 'image content';
-            grid-template-columns: repeat(2, minmax(0, 1fr));
-        }
-
-        .page-about__position--content {
-            font-size: 1.125rem;
-        }
-
-        .page-about__position--image {
-            height: 100%;
-        }
-
-        .page-about__history__section-one,
-        .page-about__history__section-two {
-            margin-bottom: 96px;
-        }
-
-        .page-about__history__section-one,
-        .page-about__history__section-three {
-            grid-template-columns: 1fr 1fr;
-        }
-
-        .page-about__history__section-one--image,
-        .page-about__history__section-three--image {
-            height: 100%;
-            max-height: 550px;
-        }
-
-        .page-about__history__section-two--image {
-            height: 300px;
-        }
-
-        .page-about__team {
-            gap: 48px;
-        }
-
-        .page-about__team__header {
-            p {
-                font-size: 2rem;
-            }
-        }
-
-        .page-about__team__staff__inner,
-        .page-about__team__directors__inner {
-            grid-template-columns: repeat(3, minmax(0, 1fr));
-        }
-    }
-
-    @media (min-width: 1440px) {
-        .page-about__hero {
-            min-height: 980px;
-        }
-
-        .page-about__hero__inner {
-            padding: 0;
-        }
-
-        .page-about__position__inner {
-            grid-template-columns: 352px 1fr;
-        }
-
-        .page-about__position--content {
-            font-size: 1.5rem;
-        }
-
-        .page-about__position--image {
-            max-height: 500px;
-            max-width: 100%;
-        }
-
-        .page-about__history__section-one,
-        .page-about__history__section-three {
-            grid-template-columns: 450px 1fr;
-        }
-
-        .page-about__history__section-one--image,
-        .page-about__history__section-three--image {
-            max-height: 350px;
-        }
-
-        .page-about__history__section-two--image {
-            height: 375px;
-        }
-
-        .page-about__team {
-            gap: 96px;
-            padding: 96px 0;
-        }
-
-        .page-about__team__header {
-            margin-bottom: -24px;
-        }
-
-        .page-about__team__staff__inner,
-        .page-about__team__directors__inner {
-            grid-template-columns: repeat(4, minmax(0, 1fr));
-        }
-    }
-}
diff --git a/src/css/pages/conferences.css b/src/css/pages/conferences.css
deleted file mode 100644
index 9dd5c04..0000000
--- a/src/css/pages/conferences.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.page-conferences {
-    #rubyconf a,
-    #railsconf a,
-    .static-content a {
-        text-shadow: 0 2px 0 var(--color-white), 1px 2px 0 var(--color-white),
-            -1px 2px 0 var(--color-white), 2px 2px 0 var(--color-white),
-            -2px 2px 0 var(--color-white);
-    }
-}
diff --git a/src/css/pages/home.css b/src/css/pages/home.css
deleted file mode 100644
index 8946a2e..0000000
--- a/src/css/pages/home.css
+++ /dev/null
@@ -1,410 +0,0 @@
-.home-template {
-    .home-template__hero {
-        display: flex;
-        flex-direction: column;
-        gap: 14px;
-        padding: 20px 40px 40px;
-        max-width: var(--layout-inner-max-width);
-        margin: auto;
-
-        h1 {
-            color: var(--color-red);
-            font-size: 2rem;
-            font-weight: 700;
-            line-height: normal;
-            text-transform: uppercase;
-        }
-
-        h2 {
-            color: var(--color-navy);
-            font-size: 1.5rem;
-            font-weight: 500;
-            line-height: 2.25rem;
-            text-transform: unset;
-        }
-
-        h3 {
-            color: var(--color-navy);
-            font-size: 0.875rem;
-            font-weight: 400;
-            line-height: 1.125rem;
-        }
-    }
-
-    .home-template__pillars {
-        color: white;
-        background-image: url('/assets/images/home__pillars--background.jpg');
-    }
-
-    .home-template__pillars,
-    .home-template__support {
-        h2 {
-            margin-bottom: 16px;
-            text-transform: uppercase;
-        }
-    }
-
-    .home-template__community {
-        color: white;
-        background-image: url('/assets/images/home__community--background.jpg');
-    }
-
-    .home-template__pillars,
-    .home-template__community {
-        background-position: bottom center;
-        background-size: cover;
-        background-repeat: no-repeat;
-        width: 100%;
-        border-radius: 0;
-        padding: 40px;
-    }
-
-    .home-template__pillars__inner,
-    .home-template__community__inner {
-        max-width: var(--layout-inner-max-width);
-        margin: auto;
-    }
-
-    .home-template__pillars__details,
-    .home-template__community__details {
-        display: grid;
-        background-color: var(--color-navy);
-        border-radius: 8px;
-        gap: 48px;
-        grid-template-columns: 1fr;
-        padding: 36px 24px;
-    }
-
-    .home-template__pillars__details {
-        grid-template-areas: 'image-grid' 'content' 'stats';
-    }
-
-    .home-template__community__details {
-        grid-template-areas: 'image' 'content' 'stats';
-    }
-
-    .home-template__pillars__details--image-grid {
-        display: grid;
-        gap: 16px;
-        grid-area: image-grid;
-        grid-template-areas: 'image-item-three' 'image-item-one' 'image-item-two';
-
-        img {
-            border-radius: 8px;
-            height: 140px;
-            object-fit: cover;
-            object-position: center;
-            width: 100%;
-        }
-
-        .home-template__pillars__details--image-grid_item--one {
-            grid-area: image-item-one;
-        }
-
-        .home-template__pillars__details--image-grid_item--two {
-            grid-area: image-item-two;
-            object-position: top;
-        }
-
-        .home-template__pillars__details--image-grid_item--three {
-            grid-area: image-item-three;
-        }
-    }
-
-    .home-template__community__details--image {
-        border-radius: 8px;
-        grid-area: image;
-        object-fit: cover;
-        width: 100%;
-    }
-
-    .home-template__pillars__details--content,
-    .home-template__community__details--content {
-        display: flex;
-        flex-direction: column;
-        gap: 16px;
-        grid-area: content;
-
-        p {
-            margin-bottom: 0;
-        }
-
-        p:first-of-type {
-            flex-grow: 1;
-        }
-
-        small {
-            font-size: 0.875rem;
-            line-height: 1.5rem;
-        }
-
-        .kg-button-card a.kg-btn,
-        .kg-button-card a.kg-btn-accent {
-            box-shadow: none;
-        }
-    }
-
-    .home-template__pillars__details--stats,
-    .home-template__community__details--stats {
-        align-items: start;
-        background-color: var(--color-mutednavy);
-        border-radius: 8px;
-        display: grid;
-        grid-template-columns: 1fr;
-        gap: 8px;
-        grid-area: stats;
-        padding: 20px;
-
-        section {
-            display: flex;
-            flex-direction: column;
-            gap: 12px;
-            justify-content: center;
-            padding: 12px;
-
-            h3,
-            p {
-                text-align: center;
-            }
-
-            h3 {
-                font-size: 1.5rem;
-                font-weight: 500;
-                line-height: 1.75rem;
-                text-transform: uppercase;
-            }
-
-            p {
-                font-size: 1rem;
-                line-height: 1.25rem;
-                margin: 0;
-            }
-        }
-    }
-
-    .home-template__open-source {
-        display: grid;
-        gap: 48px;
-        grid-template-areas: 'open-source-content' 'open-source-stats';
-        grid-template-columns: 1fr;
-        margin: auto;
-        max-width: 900px;
-        padding: 70px 40px;
-
-        h2 {
-            text-transform: uppercase;
-        }
-    }
-
-    .home-template__open-source__content {
-        color: var(--color-navy);
-        display: flex;
-        flex-direction: column;
-        gap: 16px;
-        grid-area: open-source-content;
-
-        p:first-of-type {
-            flex-grow: 1;
-        }
-
-        small {
-            font-size: 0.875rem;
-            line-height: 1.5rem;
-        }
-
-        hr {
-            margin: 0;
-        }
-    }
-
-    .home-template__open-source__stats {
-        color: white;
-        background-color: var(--color-red);
-        border-radius: 8px;
-        display: flex;
-        flex-direction: column;
-        justify-content: space-between;
-        gap: 16px;
-        grid-area: open-source-stats;
-        padding: 48px 20px;
-
-        section {
-            display: flex;
-            flex-direction: column;
-            gap: 8px;
-
-            h3,
-            p {
-                text-align: center;
-            }
-
-            h3 {
-                font-size: 2rem;
-                line-height: 3rem;
-                text-transform: uppercase;
-            }
-
-            p {
-                font-size: 1rem;
-                line-height: 1rem;
-                margin: 0;
-            }
-        }
-    }
-
-    .home-template__support {
-        max-width: var(--layout-inner-max-width);
-        margin: auto;
-        padding: 70px 40px 0;
-
-        h2,
-        p {
-            text-align: center;
-        }
-
-        hr {
-            margin: 0 auto 30px;
-        }
-    }
-
-    @media (min-width: 834px) {
-        .home-template__hero {
-            gap: 24px;
-            padding: 48px 56px 96px;
-
-            h1 {
-                font-size: 4.5rem;
-            }
-
-            h2 {
-                font-size: 2.625rem;
-                line-height: 3rem;
-            }
-
-            h3 {
-                font-size: 1.125rem;
-                line-height: 1.75em;
-            }
-        }
-
-        .home-template__pillars,
-        .home-template__community {
-            padding: 96px 56px;
-        }
-
-        .home-template__pillars__details,
-        .home-template__community__details {
-            padding: 80px 48px;
-        }
-
-        .home-template__pillars__details--image-grid {
-            grid-template-areas: 'image-item-three image-item-three' 'image-item-one image-item-two';
-            grid-template-columns: repeat(2, minmax(0, 1fr));
-
-            img {
-                height: 220px;
-            }
-        }
-
-        .home-template__community__details--image {
-            height: 350px;
-        }
-
-        .home-template__pillars__details--stats,
-        .home-template__community__details--stats {
-            gap: 0;
-            grid-template-columns: repeat(3, minmax(0, 1fr));
-        }
-
-        .home-template__open-source {
-            grid-template-areas: 'open-source-stats open-source-content';
-            grid-template-columns: 275px 1fr;
-            padding: 70px;
-        }
-
-        .home-template__open-source__stats {
-            gap: 55px;
-        }
-
-        .home-template__support {
-            padding: 96px 56px 0;
-        }
-    }
-
-    @media (min-width: 1440px) {
-        .home-template__hero {
-            padding: 48px 0 96px;
-
-            h3 {
-                font-size: 1.5rem;
-                line-height: 1.75rem;
-                max-width: 693px;
-            }
-        }
-
-        .home-template__pillars {
-            padding: 96px 0;
-        }
-
-        .home-template__pillars__details {
-            grid-template-areas: 'content image-grid' 'stats stats';
-            grid-template-columns: 335px 1fr;
-        }
-
-        .home-template__community__details {
-            grid-template-areas: 'image content' 'stats stats';
-            grid-template-columns: 1fr 335px;
-        }
-
-        .home-template__pillars__details--content,
-        .home-template__community__details--content {
-            h3 {
-                margin-bottom: 8px;
-            }
-        }
-
-        .home-template__pillars__details--image-grid {
-            grid-template-areas: 'image-item-one image-item-three' 'image-item-two image-item-three';
-            grid-template-columns: 1fr 1fr;
-            grid-template-rows: 1fr 1fr;
-
-            img {
-                height: 100%;
-            }
-        }
-
-        .home-template__community__details--image {
-            height: 445px;
-            object-position: 50% 65%;
-        }
-
-        .home-template__pillars__details--stats,
-        .home-template__community__details--stats {
-            section {
-                h3 {
-                    font-size: 2.625rem;
-                    line-height: 3rem;
-                }
-            }
-        }
-
-        .home-template__open-source {
-            gap: 96px;
-            grid-template-columns: 330px 1fr;
-            padding: 70px 0;
-        }
-
-        .home-template__open-source__stats {
-            section {
-                h3 {
-                    font-size: 2.625rem;
-                    line-height: 3rem;
-                }
-            }
-        }
-
-        .home-template__support {
-            padding: 96px 0 66px;
-        }
-    }
-}
diff --git a/src/css/pages/open-source.css b/src/css/pages/open-source.css
deleted file mode 100644
index 758c5e2..0000000
--- a/src/css/pages/open-source.css
+++ /dev/null
@@ -1,18 +0,0 @@
-.page-open-source {
-    .page-open-source__team {
-        display: grid;
-        grid-template-columns: 1fr;
-    }
-
-    @media (min-width: 485px) {
-        .page-open-source__team {
-            grid-template-columns: repeat(2, minmax(0, 1fr));
-        }
-    }
-
-    @media (min-width: 834px) {
-        .page-open-source__team {
-            grid-template-columns: repeat(4, minmax(0, 1fr));
-        }
-    }
-}
diff --git a/src/css/pages/post.css b/src/css/pages/post.css
deleted file mode 100644
index bc7e9f2..0000000
--- a/src/css/pages/post.css
+++ /dev/null
@@ -1,124 +0,0 @@
-/* These styles define the layout of the post (and page) */
-
-.post {
-  width: 95%;
-  margin: 0 auto;
-  margin-block-end: 3rem;
-}
-
-.post p {
-  line-height: 1.4rem;
-}
-
-.post h1,
-.post h2,
-.post h3 {
-  margin-bottom: 0.25rem;
-}
-
-.post h1 {
-  font-size: 32px;
-}
-
-.post h2 {
-  font-size: 24px;
-}
-
-.post h3 {
-  font-size: 18px;
-}
-
-.post p,
-.post ul {
-  margin-bottom: 27px;
-}
-
-.post ul li {
-  line-height: 1.25rem;
-  margin-bottom: 0.5em;
-}
-
-.post__list {
-  display: flex;
-  flex-direction: column;
-  gap: 24px;
-}
-
-.post__list__item {
-  a {
-    color: var(--color-red);
-    font-size: 1.5rem;
-    font-weight: 700;
-    line-height: 2rem;
-  }
-
-  p {
-    font-style: italic;
-    margin-top: 8px;
-  }
-}
-
-/* tocbot stuff */
-.gh-toc > .toc-list {
-  position: relative;
-  margin-bottom: 1rem;
-}
-
-.toc-list {
-  overflow: hidden;
-  list-style: none;
-}
-
-.toc-list-item {
-  margin-bottom: 5px;
-}
-
-#railsconf-interest {
-  background: #fff;
-  border: 2px solid #f4eee6;
-  color: var(--color-text);
-}
-
-@media (min-width: 400px) {
-  .post {
-    width: 95%;
-    margin: 0 auto;
-  }
-}
-
-@media (min-width: 550px) {
-  .post {
-    width: 80%;
-    margin: 0 auto;
-  }
-}
-
-@media (min-width: 700px) {
-  .post {
-    width: 60%;
-    max-width: 800px;
-    margin: 0 auto;
-  }
-}
-
-@media (min-width: 1350px) {
-  .post {
-    width: 800px;
-  }
-
-  .gh-sidebar {
-    position: absolute;
-    left: 0;
-  }
-
-  .gh-toc {
-    position: sticky;
-    top: 4vmin;
-    max-width: calc((100vw - 800px) / 2);
-    padding-right: 2rem;
-  }
-}
-
-.gh-toc .is-active-link::before {
-  background-color: var(--ghost-accent-color);
-}
diff --git a/src/css/resets/_normalize.css b/src/css/resets/_normalize.css
new file mode 100644
index 0000000..92517d3
--- /dev/null
+++ b/src/css/resets/_normalize.css
@@ -0,0 +1,356 @@
+/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
+
+/* Document
+   ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+html {
+  line-height: 1.15; /* 1 */
+  -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+   ========================================================================== */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+  margin: 0;
+}
+
+/**
+ * Render the `main` element consistently in IE.
+ */
+
+main {
+  display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+
+/* Grouping content
+   ========================================================================== */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+  box-sizing: border-box; /* 1 */
+  height: 0; /* 1 */
+  overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+  font-family: monospace, monospace; /* 1 */
+  font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+   ========================================================================== */
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+  background-color: transparent;
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+  border-bottom: none; /* 1 */
+  text-decoration: underline; /* 2 */
+  text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+  font-family: monospace, monospace; /* 1 */
+  font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+  font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+/* Embedded content
+   ========================================================================== */
+
+/**
+ * Remove the border on images inside links in IE 10.
+ */
+
+img {
+  border-style: none;
+}
+
+/* Forms
+   ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: inherit; /* 1 */
+  font-size: 100%; /* 1 */
+  line-height: 1.15; /* 1 */
+  margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input {
+  /* 1 */
+  overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select {
+  /* 1 */
+  text-transform: none;
+}
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+  -webkit-appearance: button;
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+  border-style: none;
+  padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+  outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+  padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ *    `fieldset` elements in all browsers.
+ */
+
+legend {
+  color: inherit; /* 2 */
+  display: table; /* 1 */
+  max-width: 100%; /* 1 */
+  padding: 0; /* 3 */
+  white-space: normal; /* 1 */
+}
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+  vertical-align: baseline;
+}
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+  overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+  padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+  -webkit-appearance: textfield; /* 1 */
+  outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+  -webkit-appearance: button; /* 1 */
+  font: inherit; /* 2 */
+}
+
+/* Interactive
+   ========================================================================== */
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+  display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+  display: list-item;
+}
+
+/* Misc
+   ========================================================================== */
+
+/**
+ * Add the correct display in IE 10+.
+ */
+
+template {
+  display: none;
+}
+
+/**
+ * Add the correct display in IE 10.
+ */
+
+[hidden] {
+  display: none;
+}
+
+
+*,
+*::before,
+*::after {
+  box-sizing: inherit;
+}
diff --git a/src/css/utilities/_container.css b/src/css/utilities/_container.css
new file mode 100644
index 0000000..30db7a3
--- /dev/null
+++ b/src/css/utilities/_container.css
@@ -0,0 +1,11 @@
+.u-container {
+  box-sizing: border-box;
+  margin-inline: auto;
+  max-width: var(--container--base);
+  padding-inline: var(--space--medium);
+  width: 100%;
+}
+
+.u-container--narrow {
+  max-width: var(--container--narrow);
+}
diff --git a/src/css/utilities/_grid.css b/src/css/utilities/_grid.css
new file mode 100644
index 0000000..adb0716
--- /dev/null
+++ b/src/css/utilities/_grid.css
@@ -0,0 +1,49 @@
+.u-grid {
+  --cols: 7;
+
+  display: grid;
+  gap: var(--space--medium);
+  grid-template-columns: minmax(0, 1fr);
+
+  @media screen and (min-width: 55em) {
+    grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
+  }
+}
+
+.u-grid--trio {
+  --cols: 3;
+}
+
+.u-grid--quad {
+  --cols: 4;
+}
+
+.u-grid-span-1 {
+  grid-column: span 1;
+}
+
+@media screen and (min-width: 55em) {
+  .u-grid-span-2 {
+    grid-column: span 2;
+  }
+
+  .u-grid-span-3 {
+    grid-column: span 3;
+  }
+
+  .u-grid-span-4 {
+    grid-column: span 4;
+  }
+
+  .u-grid-span-5 {
+    grid-column: span 5;
+  }
+
+  .u-grid-span-6 {
+    grid-column: span 6;
+  }
+
+  .u-grid-span-7 {
+    grid-column: span 7;
+  }
+}
diff --git a/src/css/utilities/_hide-visually.css b/src/css/utilities/_hide-visually.css
new file mode 100644
index 0000000..57ec57b
--- /dev/null
+++ b/src/css/utilities/_hide-visually.css
@@ -0,0 +1,24 @@
+.u-hide-visually {
+  border: 0;
+  clip: rect(1px, 1px, 1px, 1px);
+  clip-path: inset(100%);
+  height: 1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px;
+}
+
+.u-hide-visually--focus-unhide:focus {
+  clip: auto;
+  clip-path: none;
+  height: auto;
+  overflow: visible;
+  padding-block: var(--space--small);
+  padding-inline: var(--space--medium);
+  position: absolute;
+  text-align: center;
+  white-space: inherit;
+  width: auto;
+  z-index: calc(var(--z-index--layout) + 1);
+}
diff --git a/src/js/app/global-nav.js b/src/js/app/global-nav.js
new file mode 100644
index 0000000..3e1dabf
--- /dev/null
+++ b/src/js/app/global-nav.js
@@ -0,0 +1,12 @@
+const nav = document.querySelector("[data-global-nav]");
+const navToggle = document.querySelector("[data-global-nav-toggle]");
+
+function toggleNav() {
+    const isOpen = nav.classList.contains("is-open");
+
+    nav.classList.toggle("is-open", !isOpen);
+    nav.classList.toggle("is-closed", isOpen);
+    navToggle.setAttribute("aria-expanded", !isOpen);
+}
+
+navToggle.addEventListener("click", toggleNav);
diff --git a/src/js/app/home-involvement.js b/src/js/app/home-involvement.js
new file mode 100644
index 0000000..e5867ad
--- /dev/null
+++ b/src/js/app/home-involvement.js
@@ -0,0 +1,20 @@
+const involvementFigure = document.querySelector('[data-involvement-image]');
+const involvementLinks = document.querySelectorAll('.home-involvement [data-image]');
+
+if (involvementFigure && involvementLinks.length) {
+    const img = involvementFigure.querySelector('img');
+    const defaultSrc = img.src;
+    const defaultSrcset = img.srcset;
+
+    involvementLinks.forEach((link) => {
+        link.addEventListener('mouseenter', () => {
+            img.srcset = '';
+            img.src = link.dataset.image;
+        });
+
+        link.addEventListener('mouseleave', () => {
+            img.src = defaultSrc;
+            img.srcset = defaultSrcset;
+        });
+    });
+}
diff --git a/src/js/app/index.js b/src/js/app/index.js
index a5d6079..867e30d 100644
--- a/src/js/app/index.js
+++ b/src/js/app/index.js
@@ -1,5 +1,14 @@
-import "../../css/app.css"
-import './navigation-top';
+import './global-nav';
+import './home-involvement';
+import './timeline';
+
+// Mark active tag nav link based on current path
+const currentPath = window.location.pathname;
+document.querySelectorAll('[data-tag-nav] a').forEach(link => {
+    if (link.getAttribute('href') === currentPath) {
+        link.setAttribute('aria-current', 'page');
+    }
+});
 
 document.querySelectorAll('.section-header').forEach((header) => {
     header.addEventListener('click', function () {
diff --git a/src/js/app/navigation-top.js b/src/js/app/navigation-top.js
deleted file mode 100644
index 1ef2b16..0000000
--- a/src/js/app/navigation-top.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const mobileTrigger = document.getElementById(
-    'navigation__mobile-menu-trigger',
-);
-const list = document.querySelector('.navigation--top .navigation__list');
-
-function toggleMobileMenu() {
-    this.classList.toggle('closed');
-    this.classList.toggle('opened');
-
-    if (this.classList.contains('closed')) {
-        list.classList.add('navigation__list--mobile-closed');
-        list.classList.remove('navigation__list--mobile-opened');
-    } else {
-        list.classList.remove('navigation__list--mobile-closed');
-        list.classList.add('navigation__list--mobile-opened');
-    }
-}
-
-mobileTrigger.addEventListener('click', toggleMobileMenu);
diff --git a/src/js/app/timeline.js b/src/js/app/timeline.js
new file mode 100644
index 0000000..b84c789
--- /dev/null
+++ b/src/js/app/timeline.js
@@ -0,0 +1,30 @@
+const timelineItems = document.querySelectorAll('[data-timeline-item]');
+const detailPanels = document.querySelectorAll('[data-timeline-detail]');
+
+function selectItem(item) {
+    const year = item.dataset.year;
+
+    timelineItems.forEach(el => el.setAttribute('aria-pressed', 'false'));
+    item.setAttribute('aria-pressed', 'true');
+
+    detailPanels.forEach(panel => {
+        const isMatch = panel.dataset.timelineDetail === year;
+        const hasContent = panel.querySelector('.timeline__detail-body')?.textContent.trim().length > 0;
+        panel.hidden = !isMatch || !hasContent;
+    });
+}
+
+if (timelineItems.length && detailPanels.length) {
+    timelineItems.forEach(item => {
+        item.addEventListener('click', () => selectItem(item));
+    });
+
+    const defaultItem = document.querySelector('[data-timeline-item][data-default]')
+        || timelineItems[timelineItems.length - 1];
+    selectItem(defaultItem);
+
+    const scroll = document.querySelector('.timeline__scroll');
+    if (scroll) requestAnimationFrame(() => {
+        scroll.scrollLeft = scroll.scrollWidth;
+    });
+}
diff --git a/src/js/post/index.js b/src/js/post/index.js
index c604cac..932bf35 100644
--- a/src/js/post/index.js
+++ b/src/js/post/index.js
@@ -1,8 +1,4 @@
-// Ship JS only active on post pages for better performance
-import tocbot from 'tocbot';
-
 // Set data-language on 
 elements so CSS can display a clean label.
-// Runs on load to ensure Prism's autoloader has finished highlighting.
 window.addEventListener('load', () => {
     document.querySelectorAll('pre > code[class*="language-"]').forEach((code) => {
         const match = code.className.match(/\blanguage-(\w+)\b/);
@@ -22,13 +18,43 @@ document.querySelectorAll('pre').forEach((pre) => {
     }
 });
 
-tocbot.init({
-    // Where to render the table of contents.
-    tocSelector: '.gh-toc',
-    // Where to grab the headings to build the table of contents.
-    contentSelector: '.post',
-    // Which headings to grab inside of the contentSelector element.
-    headingSelector: 'h2, h3, h4',
-    // Ensure correct positioning
-    hasInnerContainers: true,
-});
+// Table of contents
+const toc = document.querySelector('[data-toc]');
+const post = document.querySelector('[data-post-content]');
+
+if (toc && post) {
+    const headings = [...post.querySelectorAll('h2')].filter(h => h.id);
+
+    if (headings.length > 0) {
+        const list = document.createElement('ul');
+        list.className = 'post-toc__list';
+
+        headings.forEach(heading => {
+            const item = document.createElement('li');
+            item.className = 'post-toc__item';
+            const link = document.createElement('a');
+            link.href = `#${heading.id}`;
+            link.textContent = heading.textContent;
+            link.className = 'post-toc__link';
+            item.appendChild(link);
+            list.appendChild(item);
+        });
+
+        toc.appendChild(list);
+
+        const observer = new IntersectionObserver(entries => {
+            entries.forEach(entry => {
+                const link = toc.querySelector(`a[href="#${entry.target.id}"]`);
+                if (link) {
+                    if (entry.isIntersecting) {
+                        link.setAttribute('aria-current', 'location');
+                    } else {
+                        link.removeAttribute('aria-current');
+                    }
+                }
+            });
+        }, { rootMargin: '0px 0px -80% 0px' });
+
+        headings.forEach(h => observer.observe(h));
+    }
+}
diff --git a/utils/reload.js b/utils/reload.js
index dcb885f..99aefe3 100644
--- a/utils/reload.js
+++ b/utils/reload.js
@@ -1,5 +1,10 @@
+const path = require('path');
 const livereload = require('livereload');
 
-const server = livereload.createServer();
-server.watch('../assets');
+const server = livereload.createServer({
+  extraExts: ['hbs'],
+  exclusions: ['node_modules/', 'dist/'],
+});
+
+server.watch(path.join(__dirname, '..'));
 console.log('Reload server started...');