feat: custom theme

This commit is contained in:
2026-01-10 05:15:42 +02:00
parent 6286672fa5
commit ccf76a5616
13 changed files with 644 additions and 17 deletions

3
_includes/fonts.html Normal file
View File

@@ -0,0 +1,3 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Finlandica:ital,wght@0,400..700;1,400..700&family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&display=swap" rel="stylesheet">

View File

@@ -49,11 +49,13 @@ website:
format:
html:
theme: cosmo
theme: custom-theme.scss
css: styles.css
toc: false
page-layout: article
include-in-header: _includes/analytics.html
include-in-header:
- _includes/analytics.html
- _includes/fonts.html
execute:
freeze: auto

View File

@@ -1,15 +1,13 @@
---
title: "About"
title: "About Oleh Omelchenko"
page-layout: article
---
## Hi, I'm Oleh Omelchenko
<!-- Replace this template with your actual bio and information -->
### Background
Add your background, education, and experience here.
### Skills & Expertise
@@ -42,7 +40,5 @@ Check out my [portfolio](/portfolio/) and [projects](/projects/) pages to see ex
### Contact
- GitHub: [github.com/olehomelchenko](https://github.com/olehomelchenko)
- Email: [your-email@example.com](mailto:your-email@example.com)
- LinkedIn: [olehomelchenko](https://linkedin.com/in/olehomelchenko)
---

14
custom-theme.scss Normal file
View File

@@ -0,0 +1,14 @@
/*-- scss:defaults --*/
// Import variables FIRST (must come before Bootstrap)
@import "scss/variables";
/*-- scss:rules --*/
// Import our custom modules
@import "scss/colors";
@import "scss/typography";
@import "scss/utilities";
@import "scss/components";
@import "scss/dataviz";
@import "scss/layout";

44
scss/_colors.scss Normal file
View File

@@ -0,0 +1,44 @@
:root {
// Brand Colors
--color-primary-blue: #{$primary-blue};
--color-primary-yellow: #{$primary-yellow};
--color-text: #{$text-color};
--color-background: #{$background-color};
// Semantic colors
--text: #2c2a26;
--background: #f5f3f0;
--primary: #296eb3;
--secondary: #fdba35;
--accent: #188afb;
// UI Elements
--link-color: #{$primary-blue};
--link-hover-color: #{darken($primary-blue, 10%)};
// Data Visualization Colors
--dataviz-cat-1: #{$dataviz-cat-1};
--dataviz-cat-2: #{$dataviz-cat-2};
--dataviz-cat-3: #{$dataviz-cat-3};
--dataviz-cat-4: #{$dataviz-cat-4};
--dataviz-cat-5: #{$dataviz-cat-5};
--dataviz-cat-6: #{$dataviz-cat-6};
--dataviz-cat-7: #{$dataviz-cat-7};
--dataviz-cat-8: #{$dataviz-cat-8};
}
// Apply colors
body {
background-color: var(--color-background);
color: var(--color-text);
}
a {
color: var(--link-color);
text-decoration: none;
&:hover {
color: var(--link-hover-color);
text-decoration: underline;
}
}

100
scss/_components.scss Normal file
View File

@@ -0,0 +1,100 @@
// Navbar styling
.navbar {
background-color: var(--color-background) !important;
border-bottom: 2px solid var(--color-text);
.navbar-brand {
color: var(--color-text) !important;
font-family: $headings-font-family;
font-weight: 600;
}
.navbar-nav .nav-link {
color: var(--color-text) !important;
&:hover {
color: var(--color-primary-blue) !important;
}
&.active {
color: var(--color-primary-blue) !important;
}
}
}
// Footer
.nav-footer {
background-color: var(--color-background);
border-top: 2px solid var(--color-text);
color: var(--color-text);
a {
color: var(--color-primary-blue);
}
}
// Buttons
.btn-primary {
background-color: var(--color-primary-blue);
border-color: var(--color-primary-blue);
color: white;
&:hover {
background-color: #{darken($primary-blue, 10%)};
border-color: #{darken($primary-blue, 10%)};
}
}
.btn-secondary {
background-color: var(--color-primary-yellow);
border-color: var(--color-primary-yellow);
color: var(--color-text);
&:hover {
background-color: #{darken($primary-yellow, 10%)};
border-color: #{darken($primary-yellow, 10%)};
}
}
// Code blocks
pre.sourceCode {
background-color: rgba(45, 42, 38, 0.05);
border: 1px solid rgba(45, 42, 38, 0.1);
padding: 1em;
}
code.sourceCode {
color: var(--color-text);
}
// Quarto title block
.quarto-title-block {
border-bottom: 2px solid var(--color-text);
margin-bottom: 2rem;
.quarto-title .title {
font-family: $headings-font-family;
color: var(--color-text);
}
}
// Listing pages
.quarto-listing-default {
.listing-item {
border: 1px solid rgba(45, 42, 38, 0.2);
padding: 1rem;
margin-bottom: 1rem;
&:hover {
border-color: var(--color-primary-blue);
}
}
.listing-title a {
color: var(--color-text);
&:hover {
color: var(--color-primary-blue);
}
}
}

53
scss/_dataviz.scss Normal file
View File

@@ -0,0 +1,53 @@
// Sequential color ramps
// Blue sequential (5 steps from light to dark)
:root {
--dataviz-blue-seq-1: #e6f2ff;
--dataviz-blue-seq-2: #9bccfd;
--dataviz-blue-seq-3: #3699fc;
--dataviz-blue-seq-4: #047ffb;
--dataviz-blue-seq-5: #024c97;
// Yellow sequential (5 steps)
--dataviz-yellow-seq-1: #fff6e6;
--dataviz-yellow-seq-2: #fedd9a;
--dataviz-yellow-seq-3: #fdba35;
--dataviz-yellow-seq-4: #ca8702;
--dataviz-yellow-seq-5: #654401;
// Diverging scale (blue ↔ neutral ↔ yellow)
--dataviz-diverging-1: #296EB4;
--dataviz-diverging-2: #9FDFDC;
--dataviz-diverging-3: #f5f3f0;
--dataviz-diverging-4: #FDB833;
--dataviz-diverging-5: #fca903;
}
// Categorical color utility classes (for future use)
.dataviz-cat-1 { color: $dataviz-cat-1; }
.dataviz-cat-2 { color: $dataviz-cat-2; }
.dataviz-cat-3 { color: $dataviz-cat-3; }
.dataviz-cat-4 { color: $dataviz-cat-4; }
.dataviz-cat-5 { color: $dataviz-cat-5; }
.dataviz-cat-6 { color: $dataviz-cat-6; }
.dataviz-cat-7 { color: $dataviz-cat-7; }
.dataviz-cat-8 { color: $dataviz-cat-8; }
.dataviz-cat-bg-1 { background-color: $dataviz-cat-1; }
.dataviz-cat-bg-2 { background-color: $dataviz-cat-2; }
.dataviz-cat-bg-3 { background-color: $dataviz-cat-3; }
.dataviz-cat-bg-4 { background-color: $dataviz-cat-4; }
.dataviz-cat-bg-5 { background-color: $dataviz-cat-5; }
.dataviz-cat-bg-6 { background-color: $dataviz-cat-6; }
.dataviz-cat-bg-7 { background-color: $dataviz-cat-7; }
.dataviz-cat-bg-8 { background-color: $dataviz-cat-8; }
/*
* Data Visualization Color System
*
* Categorical (8 colors): Use .dataviz-cat-1 through .dataviz-cat-8
* Sequential Blue: var(--dataviz-blue-seq-1) through var(--dataviz-blue-seq-5)
* Sequential Yellow: var(--dataviz-yellow-seq-1) through var(--dataviz-yellow-seq-5)
* Diverging: var(--dataviz-diverging-1) through var(--dataviz-diverging-5)
*
* All colors are colorblind-safe as per brand guidelines.
*/

2
scss/_layout.scss Normal file
View File

@@ -0,0 +1,2 @@
// Layout-specific styles
// Initially empty - for future layout customizations

31
scss/_typography.scss Normal file
View File

@@ -0,0 +1,31 @@
// Body text
body {
font-family: $font-family-sans-serif;
font-optical-sizing: auto;
}
// Headings
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
font-family: $headings-font-family;
font-optical-sizing: auto;
color: var(--color-text);
}
// Code blocks
code, pre, kbd, samp {
font-family: $font-family-monospace;
}
// Quarto-specific code blocks
.sourceCode {
font-family: $font-family-monospace;
}
// Inline code
p code, li code {
font-family: $font-family-monospace;
background-color: rgba(45, 42, 38, 0.05);
padding: 0.2em 0.4em;
color: var(--color-text);
}

36
scss/_utilities.scss Normal file
View File

@@ -0,0 +1,36 @@
// Global border-radius override (sharp corners principle)
* {
border-radius: 0 !important;
}
// Remove any gradients from buttons
.btn {
background-image: none !important;
border-radius: 0 !important;
}
// Navbar - sharp corners, solid colors
.navbar {
border-radius: 0 !important;
background-image: none !important;
}
// Cards and panels
.card {
border-radius: 0 !important;
}
// Code blocks
pre, code {
border-radius: 0 !important;
}
// Quarto-specific elements
.quarto-title-block {
border-radius: 0 !important;
}
// Input elements
input, select, textarea, button {
border-radius: 0 !important;
}

33
scss/_variables.scss Normal file
View File

@@ -0,0 +1,33 @@
// Brand Colors
$primary-blue: #1789fc;
$primary-yellow: #fdb833;
$text-color: #2d2a26;
$background-color: #f5f3f0;
// Bootstrap/Quarto Variable Overrides
$primary: $primary-blue;
$secondary: $primary-yellow;
$body-bg: $background-color;
$body-color: $text-color;
// Typography
$font-family-sans-serif: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
$font-family-monospace: "IBM Plex Mono", "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
$headings-font-family: "Finlandica", "IBM Plex Sans", sans-serif;
// Design Principles
$border-radius: 0;
$border-radius-sm: 0;
$border-radius-lg: 0;
$enable-rounded: false;
$enable-gradients: false;
// Data Viz Categorical Colors
$dataviz-cat-1: #296EB4;
$dataviz-cat-2: #FDB833;
$dataviz-cat-3: #CCE160;
$dataviz-cat-4: #9FDFDC;
$dataviz-cat-5: #8A983E;
$dataviz-cat-6: #C7C7FA;
$dataviz-cat-7: #D02F2F;
$dataviz-cat-8: #A62191;

View File

@@ -31,9 +31,9 @@
}
.vega-bindings:not(:empty) {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 8px;
background: var(--color-background, #f5f3f0);
border: 1px solid rgba(45, 42, 38, 0.2);
border-radius: 0;
padding: 15px 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
width: fit-content;
@@ -44,28 +44,28 @@
align-items: center;
gap: 10px;
margin-right: 20px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-size: 14px;
color: #495057;
color: var(--color-text, #2d2a26);
font-weight: 500;
}
.vega-bindings input,
.vega-bindings select {
padding: 6px 12px;
border: 1px solid #ced4da;
border-radius: 4px;
border: 1px solid rgba(45, 42, 38, 0.2);
border-radius: 0;
background: white;
font-size: 14px;
color: #495057;
color: var(--color-text, #2d2a26);
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.vega-bindings input:focus,
.vega-bindings select:focus {
border-color: #80bdff;
border-color: var(--color-primary-blue, #1789fc);
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
box-shadow: 0 0 0 0.2rem rgba(23, 137, 252, 0.25);
}
.vega-bindings select {

313
themes-guide.md Normal file
View File

@@ -0,0 +1,313 @@
## Personal Design System
### Brand Colors
| Role | Hex | Usage |
|------|-----|-------|
| Primary Blue | `#1789fc` | UI accents, links, interactive elements |
| Primary Yellow | `#fdb833` | Highlights, secondary accents |
| Text | `#2d2a26` | Body text, headings |
| Background | `#f5f3f0` | Page background |
### Data Visualization
**Categorical (8 colors):**
`#296EB4` `#FDB833` `#CCE160` `#9FDFDC` `#8A983E` `#C7C7FA` `#D02F2F` `#A62191`
**Sequential:** Ramps derived from `#1789fc` (blue) or `#fdb833` (yellow)
**Diverging:** Blue ↔ neutral midpoint ↔ Yellow
### Typography
| Role | Font |
|------|------|
| Headings | Finlandica |
| Body | IBM Plex Sans |
| Code | IBM Plex Mono |
### Design Principles
- Sharp corners, no border-radius
- Solid fills over gradients
- Light mode only
- Colorblind-safe palette
## Font instructions from Google Fonts
Code below was generated by Google Fonts:
```
Embed code in the <head> of your html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Finlandica:ital,wght@0,400..700;1,400..700&family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&display=swap" rel="stylesheet">
IBM Plex Sans: CSS class for a variable style
.ibm-plex-sans-<uniquifier> {
font-family: "IBM Plex Sans", sans-serif;
font-optical-sizing: auto;
font-weight: <weight>;
font-style: normal;
font-variation-settings:
"wdth" 100;
}
Finlandica: CSS class for a variable style
.finlandica-<uniquifier> {
font-family: "Finlandica", sans-serif;
font-optical-sizing: auto;
font-weight: <weight>;
font-style: normal;
}
IBM Plex Mono: CSS classes
.ibm-plex-mono-thin {
font-family: "IBM Plex Mono", monospace;
font-weight: 100;
font-style: normal;
}
.ibm-plex-mono-extralight {
font-family: "IBM Plex Mono", monospace;
font-weight: 200;
font-style: normal;
}
.ibm-plex-mono-light {
font-family: "IBM Plex Mono", monospace;
font-weight: 300;
font-style: normal;
}
.ibm-plex-mono-regular {
font-family: "IBM Plex Mono", monospace;
font-weight: 400;
font-style: normal;
}
.ibm-plex-mono-medium {
font-family: "IBM Plex Mono", monospace;
font-weight: 500;
font-style: normal;
}
.ibm-plex-mono-semibold {
font-family: "IBM Plex Mono", monospace;
font-weight: 600;
font-style: normal;
}
.ibm-plex-mono-bold {
font-family: "IBM Plex Mono", monospace;
font-weight: 700;
font-style: normal;
}
.ibm-plex-mono-thin-italic {
font-family: "IBM Plex Mono", monospace;
font-weight: 100;
font-style: italic;
}
.ibm-plex-mono-extralight-italic {
font-family: "IBM Plex Mono", monospace;
font-weight: 200;
font-style: italic;
}
.ibm-plex-mono-light-italic {
font-family: "IBM Plex Mono", monospace;
font-weight: 300;
font-style: italic;
}
.ibm-plex-mono-regular-italic {
font-family: "IBM Plex Mono", monospace;
font-weight: 400;
font-style: italic;
}
.ibm-plex-mono-medium-italic {
font-family: "IBM Plex Mono", monospace;
font-weight: 500;
font-style: italic;
}
.ibm-plex-mono-semibold-italic {
font-family: "IBM Plex Mono", monospace;
font-weight: 600;
font-style: italic;
}
.ibm-plex-mono-bold-italic {
font-family: "IBM Plex Mono", monospace;
font-weight: 700;
font-style: italic;
}
```
## Colors for website theme
The code below was generated by Realtime Colors website.
General variables:
```
:root[data-theme="light"] {
--text: #2c2a26;
--background: #f5f3f0;
--primary: #296eb3;
--secondary: #fdba35;
--accent: #188afb;
}
:root[data-theme="dark"] {
--text: #d9d7d3;
--background: #0f0d0a;
--primary: #4c91d6;
--secondary: #ca8702;
--accent: #0475e7;
}
```
Option with shades:
```
:root[data-theme="light"] {
--text-50: #f3f3f1;
--text-100: #e7e6e4;
--text-200: #d0cdc8;
--text-300: #b8b4ad;
--text-400: #a09b92;
--text-500: #888277;
--text-600: #6d685f;
--text-700: #524e47;
--text-800: #37342f;
--text-900: #1b1a18;
--text-950: #0e0d0c;
--background-50: #f5f3f0;
--background-100: #ebe7e0;
--background-200: #d6cec2;
--background-300: #c2b6a3;
--background-400: #ad9d85;
--background-500: #998566;
--background-600: #7a6a52;
--background-700: #5c503d;
--background-800: #3d3529;
--background-900: #1f1b14;
--background-950: #0f0d0a;
--primary-50: #eaf2fa;
--primary-100: #d5e5f6;
--primary-200: #acccec;
--primary-300: #82b2e3;
--primary-400: #5999d9;
--primary-500: #2f7fd0;
--primary-600: #2666a6;
--primary-700: #1c4c7d;
--primary-800: #133353;
--primary-900: #09192a;
--primary-950: #050d15;
--secondary-50: #fff6e6;
--secondary-100: #feeecd;
--secondary-200: #fedd9a;
--secondary-300: #fdcb68;
--secondary-400: #fdba35;
--secondary-500: #fca903;
--secondary-600: #ca8702;
--secondary-700: #976502;
--secondary-800: #654401;
--secondary-900: #322201;
--secondary-950: #191100;
--accent-50: #e6f2ff;
--accent-100: #cde5fe;
--accent-200: #9bccfd;
--accent-300: #68b2fd;
--accent-400: #3699fc;
--accent-500: #047ffb;
--accent-600: #0366c9;
--accent-700: #024c97;
--accent-800: #023364;
--accent-900: #011932;
--accent-950: #000d19;
}
:root[data-theme="dark"] {
--text-50: #0e0d0c;
--text-100: #1b1a18;
--text-200: #37342f;
--text-300: #524e47;
--text-400: #6d685f;
--text-500: #888277;
--text-600: #a09b92;
--text-700: #b8b4ad;
--text-800: #d0cdc8;
--text-900: #e7e6e4;
--text-950: #f3f3f1;
--background-50: #0f0d0a;
--background-100: #1f1b14;
--background-200: #3d3529;
--background-300: #5c503d;
--background-400: #7a6a52;
--background-500: #998566;
--background-600: #ad9d85;
--background-700: #c2b6a3;
--background-800: #d6cec2;
--background-900: #ebe7e0;
--background-950: #f5f3f0;
--primary-50: #050d15;
--primary-100: #09192a;
--primary-200: #133353;
--primary-300: #1c4c7d;
--primary-400: #2666a6;
--primary-500: #2f7fd0;
--primary-600: #5999d9;
--primary-700: #82b2e3;
--primary-800: #acccec;
--primary-900: #d5e5f6;
--primary-950: #eaf2fa;
--secondary-50: #191100;
--secondary-100: #322201;
--secondary-200: #654401;
--secondary-300: #976502;
--secondary-400: #ca8702;
--secondary-500: #fca903;
--secondary-600: #fdba35;
--secondary-700: #fdcb68;
--secondary-800: #fedd9a;
--secondary-900: #feeecd;
--secondary-950: #fff6e6;
--accent-50: #000d19;
--accent-100: #011932;
--accent-200: #023364;
--accent-300: #024c97;
--accent-400: #0366c9;
--accent-500: #047ffb;
--accent-600: #3699fc;
--accent-700: #68b2fd;
--accent-800: #9bccfd;
--accent-900: #cde5fe;
--accent-950: #e6f2ff;
}
```