diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..12744dd
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "themes/hugo-book"]
+ path = themes/hugo-book
+ url = https://github.com/alex-shpak/hugo-book
diff --git a/archetypes/docs.md b/archetypes/docs.md
new file mode 100644
index 0000000..17e014c
--- /dev/null
+++ b/archetypes/docs.md
@@ -0,0 +1,10 @@
+---
+title: "{{ .Name | humanize | title }}"
+weight: 1
+# bookFlatSection: false
+# bookToc: true
+# bookHidden: false
+# bookCollapseSection: false
+# bookComments: false
+# bookSearchExclude: false
+---
diff --git a/archetypes/posts.md b/archetypes/posts.md
new file mode 100644
index 0000000..f897e95
--- /dev/null
+++ b/archetypes/posts.md
@@ -0,0 +1,6 @@
+---
+title: "{{ .Name | humanize | title }}"
+date: {{ .Date }}
+# bookComments: false
+# bookSearchExclude: false
+---
diff --git a/archetypes/default.md b/archetypes_bak/default.md
similarity index 100%
rename from archetypes/default.md
rename to archetypes_bak/default.md
diff --git a/assets/_custom.scss b/assets/_custom.scss
new file mode 100644
index 0000000..0de9ae1
--- /dev/null
+++ b/assets/_custom.scss
@@ -0,0 +1,3 @@
+/* You can add custom styles here. */
+
+// @import "plugins/numbered";
diff --git a/assets/_defaults.scss b/assets/_defaults.scss
new file mode 100644
index 0000000..96c4d84
--- /dev/null
+++ b/assets/_defaults.scss
@@ -0,0 +1,65 @@
+// Used in layout
+$padding-1: 1px !default;
+$padding-4: 0.25rem !default;
+$padding-8: 0.5rem !default;
+$padding-16: 1rem !default;
+
+$font-size-base: 16px !default;
+$font-size-12: 0.75rem !default;
+$font-size-14: 0.875rem !default;
+$font-size-16: 1rem !default;
+
+$border-radius: $padding-4 !default;
+
+$body-font-weight: normal !default;
+
+$body-min-width: 20rem !default;
+$container-max-width: 80rem !default;
+
+$menu-width: 16rem !default;
+$toc-width: 16rem !default;
+
+$mobile-breakpoint: $menu-width + $body-min-width * 1.2 + $toc-width !default;
+
+$hint-colors: (
+ info: #6bf,
+ warning: #fd6,
+ danger: #f66,
+) !default;
+
+// Themes
+@mixin theme-light {
+ --gray-100: #f8f9fa;
+ --gray-200: #e9ecef;
+ --gray-500: #adb5bd;
+
+ --color-link: #0055bb;
+ --color-visited-link: #8440f1;
+
+ --body-background: white;
+ --body-font-color: black;
+
+ --icon-filter: none;
+
+ --hint-color-info: #6bf;
+ --hint-color-warning: #fd6;
+ --hint-color-danger: #f66;
+}
+
+@mixin theme-dark {
+ --gray-100: #494e54;
+ --gray-200: #5c6165;
+ --gray-500: #999d9f;
+
+ --color-link: #84b2ff;
+ --color-visited-link: #b88dff;
+
+ --body-background: #343a40;
+ --body-font-color: #e9ecef;
+
+ --icon-filter: brightness(0) invert(1);
+
+ --hint-color-info: #6bf;
+ --hint-color-warning: #fd6;
+ --hint-color-danger: #f66;
+}
diff --git a/assets/_fonts.scss b/assets/_fonts.scss
new file mode 100644
index 0000000..dbd10ce
--- /dev/null
+++ b/assets/_fonts.scss
@@ -0,0 +1,31 @@
+@font-face {
+ font-family: 'Noto Sans';
+ font-style: normal;
+ font-weight: 400;
+ font-display: fallback;
+ src: url('/fonts/NotoSans-Regular.ttf') format('truetype');
+}
+
+@font-face {
+ font-family: 'Noto Sans';
+ font-style: normal;
+ font-weight: 700;
+ font-display: fallback;
+ src: url('/fonts/NotoSans-Bold.ttf') format('truetype');
+}
+
+@font-face {
+ font-family: 'Noto Sans Mono';
+ font-style: normal;
+ font-weight: 400;
+ font-display: fallback;
+ src: url('/fonts/NotoSansMono-Regular.ttf') format('truetype');
+}
+
+body {
+ font-family: 'Noto Sans', sans-serif;
+}
+
+code {
+ font-family: 'Noto Sans Mono', monospace;
+}
\ No newline at end of file
diff --git a/assets/_main.scss b/assets/_main.scss
new file mode 100644
index 0000000..8b4e687
--- /dev/null
+++ b/assets/_main.scss
@@ -0,0 +1,374 @@
+html {
+ font-size: $font-size-base;
+ scroll-behavior: smooth;
+ touch-action: manipulation;
+ scrollbar-gutter: stable;
+}
+
+body {
+ min-width: $body-min-width;
+ color: var(--body-font-color);
+ background: var(--body-background);
+
+ // letter-spacing: 0.33px;
+ font-weight: $body-font-weight;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ box-sizing: border-box;
+ * {
+ box-sizing: inherit;
+ }
+}
+
+h1,
+h2,
+h3,
+h4,
+h5 {
+ font-weight: $body-font-weight;
+}
+
+a {
+ text-decoration: none;
+ color: var(--color-link);
+}
+
+img {
+ vertical-align: baseline;
+}
+
+:focus {
+ @include outline;
+}
+
+aside nav ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+
+ li {
+ margin: 1em 0;
+ position: relative;
+ }
+
+ a {
+ display: block;
+ }
+
+ a:hover {
+ opacity: 0.5;
+ }
+
+ ul {
+ padding-inline-start: $padding-16;
+ }
+}
+
+ul.pagination {
+ display: flex;
+ justify-content: center;
+ list-style-type: none;
+ padding-inline-start: 0px;
+
+ .page-item a {
+ padding: $padding-16;
+ }
+}
+
+.container {
+ max-width: $container-max-width;
+ margin: 0 auto;
+}
+
+.book-icon {
+ filter: var(--icon-filter);
+}
+
+a .book-icon {
+ height: 1em;
+ width: 1em;
+ margin-inline-end: .5em;
+}
+
+.book-brand {
+ margin-top: 0;
+ margin-bottom: $padding-16;
+
+ img {
+ height: 1.5em;
+ width: 1.5em;
+ margin-inline-end: $padding-8;
+ }
+}
+
+.book-menu {
+ flex: 0 0 $menu-width;
+ font-size: $font-size-14;
+
+ .book-menu-content {
+ width: $menu-width;
+ padding: $padding-16;
+ background: var(--body-background);
+
+ @include fixed;
+ }
+
+ a,
+ label {
+ color: inherit;
+ cursor: pointer;
+ word-wrap: break-word;
+ }
+
+ a.active {
+ color: var(--color-link);
+ }
+
+ input.toggle + label + ul {
+ display: none;
+ }
+
+ input.toggle:checked + label + ul {
+ display: block;
+ }
+
+ input.toggle + label::after {
+ content: "βΈ";
+ }
+
+ input.toggle:checked + label::after {
+ content: "βΎ";
+ }
+}
+
+// for RTL support
+body[dir="rtl"] .book-menu {
+ input.toggle + label::after {
+ content: "β";
+ }
+
+ input.toggle:checked + label::after {
+ content: "βΎ";
+ }
+}
+
+.book-section-flat {
+ margin: $padding-16 * 2 0;
+
+ > a,
+ > span,
+ > label {
+ font-weight: bolder;
+ }
+
+ > ul {
+ padding-inline-start: 0;
+ }
+}
+
+.book-page {
+ min-width: $body-min-width;
+ flex-grow: 1;
+ padding: $padding-16;
+}
+
+.book-post {
+ margin-bottom: $padding-16 * 2;
+
+ .book-post-date img {
+ height: 1em;
+ width: 1em;
+ margin-inline-end: .5em;
+ }
+
+ .book-post-content > :first-child {
+ margin-top: $padding-16;
+ }
+}
+
+.book-header {
+ display: none;
+ margin-bottom: $padding-16;
+
+ label {
+ line-height: 0;
+ }
+
+ h3 {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ margin: 0 $padding-16;
+ }
+
+ img.book-icon {
+ height: 1.5em;
+ width: 1.5em;
+ }
+}
+
+.book-search {
+ position: relative;
+ margin: $padding-16 0;
+ border-bottom: 1px solid transparent;
+
+ input {
+ width: 100%;
+ padding: $padding-8;
+
+ border: 0;
+ border-radius: $border-radius;
+
+ background: var(--gray-100);
+ color: var(--body-font-color);
+
+ &:required + .book-search-spinner {
+ display: block;
+ }
+ }
+
+ .book-search-spinner {
+ position: absolute;
+ top: 0;
+ margin: $padding-8;
+ margin-inline-start: calc(100% - #{$padding-16 + $padding-8});
+
+ width: $padding-16;
+ height: $padding-16;
+
+ border: $padding-1 solid transparent;
+ border-top-color: var(--body-font-color);
+ border-radius: 50%;
+
+ @include spin(1s);
+ }
+
+ small {
+ opacity: 0.5;
+ }
+}
+
+.book-toc {
+ flex: 0 0 $toc-width;
+ font-size: $font-size-12;
+
+ .book-toc-content {
+ width: $toc-width;
+ padding: $padding-16;
+
+ @include fixed;
+ }
+
+ img {
+ height: 1em;
+ width: 1em;
+ }
+
+ nav > ul > li:first-child {
+ margin-top: 0;
+ }
+}
+
+.book-footer {
+ padding-top: $padding-16;
+ font-size: $font-size-14;
+}
+
+.book-comments {
+ margin-top: $padding-16;
+}
+
+.book-languages {
+ margin-block-end: $padding-16 * 2;
+
+ ul {
+ padding-inline-start: 1.5em;
+ }
+}
+
+// Responsive styles
+.book-menu-content,
+.book-toc-content,
+.book-page,
+.book-header aside,
+.markdown {
+ transition: 0.2s ease-in-out;
+ transition-property: transform, margin, opacity, visibility;
+ will-change: transform, margin, opacity;
+}
+
+@media screen and (max-width: $mobile-breakpoint) {
+ #menu-control,
+ #toc-control {
+ display: inline;
+ }
+
+ .book-menu {
+ visibility: hidden;
+ margin-inline-start: -$menu-width;
+ z-index: 1;
+ }
+
+ .book-toc {
+ display: none;
+ }
+
+ .book-header {
+ display: block;
+ }
+
+ #menu-control:focus ~ main label[for="menu-control"] {
+ @include outline;
+ }
+
+ #menu-control:checked ~ main {
+ .book-menu {
+ visibility: initial;
+ }
+
+ .book-menu .book-menu-content {
+ transform: translateX($menu-width);
+ box-shadow: 0 0 $padding-8 rgba(0, 0, 0, 0.1);
+ }
+
+ .book-page {
+ opacity: 0.25;
+ }
+
+ .book-menu-overlay {
+ display: block;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ }
+ }
+
+ #toc-control:focus ~ main label[for="toc-control"] {
+ @include outline;
+ }
+
+ #toc-control:checked ~ main {
+ .book-header aside {
+ display: block;
+ }
+ }
+
+ // for RTL support
+ body[dir="rtl"] #menu-control:checked ~ main {
+ .book-menu .book-menu-content {
+ transform: translateX(-$menu-width);
+ }
+ }
+}
+
+// Extra space for big screens
+@media screen and (min-width: $container-max-width) {
+ .book-page,
+ .book-menu .book-menu-content,
+ .book-toc .book-toc-content {
+ padding: $padding-16 * 2 $padding-16;
+ }
+}
diff --git a/assets/_markdown.scss b/assets/_markdown.scss
new file mode 100644
index 0000000..2a95453
--- /dev/null
+++ b/assets/_markdown.scss
@@ -0,0 +1,212 @@
+@import "variables";
+
+.markdown {
+ line-height: 1.6;
+
+ // remove padding at the beginning of page
+ > :first-child {
+ margin-top: 0;
+ }
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ font-weight: normal;
+ line-height: 1;
+ margin-top: 1.5em;
+ margin-bottom: $padding-16;
+
+ a.anchor {
+ opacity: 0;
+ font-size: 0.75em;
+ vertical-align: middle;
+ text-decoration: none;
+ }
+
+ &:hover a.anchor,
+ a.anchor:focus {
+ opacity: initial;
+ }
+ }
+
+ h4,
+ h5,
+ h6 {
+ font-weight: bolder;
+ }
+
+ h5 {
+ font-size: 0.875em;
+ }
+
+ h6 {
+ font-size: 0.75em;
+ }
+
+ b,
+ optgroup,
+ strong {
+ font-weight: bolder;
+ }
+
+ a {
+ text-decoration: none;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ &:visited {
+ color: var(--color-visited-link);
+ }
+ }
+
+ img {
+ max-width: 100%;
+ height: auto;
+ }
+
+ code {
+ direction: ltr;
+ unicode-bidi: embed;
+ padding: 0 $padding-4;
+ background: var(--gray-200);
+ border-radius: $border-radius;
+ font-size: 0.875em;
+ }
+
+ pre {
+ direction: ltr;
+ unicode-bidi: embed;
+ padding: $padding-16;
+ background: var(--gray-100);
+ border-radius: $border-radius;
+ overflow-x: auto;
+
+ code {
+ padding: 0;
+ background: none;
+ }
+ }
+
+ p {
+ word-wrap: break-word;
+ }
+
+ blockquote {
+ margin: $padding-16 0;
+ padding: $padding-8 $padding-16 $padding-8 ($padding-16 - $padding-4); //to keep total left space 16dp
+
+ border-inline-start: $padding-4 solid var(--gray-200);
+ border-radius: $border-radius;
+
+ :first-child {
+ margin-top: 0;
+ }
+ :last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ table {
+ overflow: auto;
+ display: block;
+ border-spacing: 0;
+ border-collapse: collapse;
+ margin-top: $padding-16;
+ margin-bottom: $padding-16;
+
+ tr th,
+ tr td {
+ padding: $padding-8 $padding-16;
+ border: $padding-1 solid var(--gray-200);
+ }
+
+ tr:nth-child(2n) {
+ background: var(--gray-100);
+ }
+ }
+
+ hr {
+ height: $padding-1;
+ border: none;
+ background: var(--gray-200);
+ }
+
+ ul,
+ ol {
+ padding-inline-start: $padding-16 * 2;
+ word-wrap: break-word;
+ }
+
+ dl {
+ dt {
+ font-weight: bolder;
+ margin-top: $padding-16;
+ }
+
+ dd {
+ margin-inline-start: 0;
+ margin-bottom: $padding-16;
+ }
+ }
+
+ // Special case for highlighted code with line numbers
+ .highlight {
+ direction: ltr;
+ unicode-bidi: embed;
+ border-radius: $border-radius;
+ overflow: hidden;
+
+ table tr {
+ td pre code > span {
+ display: flex;
+ }
+
+ td:nth-child(1) pre {
+ margin: 0;
+ padding-inline-end: 0;
+ }
+ td:nth-child(2) pre {
+ margin: 0;
+ padding-inline-start: 0;
+ }
+ }
+ }
+
+ details {
+ padding: $padding-16;
+ border: $padding-1 solid var(--gray-200);
+ border-radius: $border-radius;
+
+ summary {
+ line-height: 1;
+ padding: $padding-16;
+ margin: -$padding-16;
+ cursor: pointer;
+ }
+
+ &[open] summary {
+ margin-bottom: 0;
+ }
+ }
+
+ figure {
+ margin: $padding-16 0;
+ figcaption p {
+ margin-top: 0;
+ }
+ }
+}
+
+.markdown-inner {
+ // Util class to remove extra margin in nested markdown content
+ > :first-child {
+ margin-top: 0;
+ }
+ > :last-child {
+ margin-bottom: 0;
+ }
+}
diff --git a/assets/_print.scss b/assets/_print.scss
new file mode 100644
index 0000000..8ae2901
--- /dev/null
+++ b/assets/_print.scss
@@ -0,0 +1,17 @@
+@media print {
+ .book-menu,
+ .book-footer,
+ .book-toc {
+ display: none;
+ }
+
+ .book-header,
+ .book-header aside {
+ display: block;
+ }
+
+ main {
+ // Fix for https://bugzilla.mozilla.org/show_bug.cgi?id=939897
+ display: block !important;
+ }
+}
diff --git a/assets/_shortcodes.scss b/assets/_shortcodes.scss
new file mode 100644
index 0000000..41a8e3e
--- /dev/null
+++ b/assets/_shortcodes.scss
@@ -0,0 +1,104 @@
+.markdown {
+ // {{< expand "Label" "icon" >}}
+ .book-expand {
+ margin-top: $padding-16;
+ margin-bottom: $padding-16;
+
+ border: $padding-1 solid var(--gray-200);
+ border-radius: $border-radius;
+
+ overflow: hidden;
+
+ .book-expand-head {
+ background: var(--gray-100);
+ padding: $padding-8 $padding-16;
+ cursor: pointer;
+ }
+
+ .book-expand-content {
+ display: none;
+ padding: $padding-16;
+ }
+
+ input[type="checkbox"]:checked + .book-expand-content {
+ display: block;
+ }
+ }
+
+ // {{< tabs >}}
+ .book-tabs {
+ margin-top: $padding-16;
+ margin-bottom: $padding-16;
+
+ border: $padding-1 solid var(--gray-200);
+ border-radius: $border-radius;
+
+ overflow: hidden;
+
+ display: flex;
+ flex-wrap: wrap;
+
+ label {
+ display: inline-block;
+ padding: $padding-8 $padding-16;
+ border-bottom: $padding-1 transparent;
+ cursor: pointer;
+ }
+
+ .book-tabs-content {
+ order: 999; //Move content blocks to the end
+ width: 100%;
+ border-top: $padding-1 solid var(--gray-100);
+ padding: $padding-16;
+ display: none;
+ }
+
+ input[type="radio"]:checked + label {
+ border-bottom: $padding-1 solid var(--color-link);
+ }
+ input[type="radio"]:checked + label + .book-tabs-content {
+ display: block;
+ }
+ input[type="radio"]:focus + label {
+ @include outline;
+ }
+ }
+
+ // {{< columns >}}
+ .book-columns {
+ margin-left: -$padding-16;
+ margin-right: -$padding-16;
+
+ > div {
+ margin: $padding-16 0;
+ min-width: $body-min-width * 0.66;
+ padding: 0 $padding-16;
+ }
+ }
+
+ // {{< button >}}
+ a.book-btn {
+ display: inline-block;
+ font-size: $font-size-14;
+ color: var(--color-link);
+ line-height: $padding-16 * 2;
+ padding: 0 $padding-16;
+ border: $padding-1 solid var(--color-link);
+ border-radius: $border-radius;
+ cursor: pointer;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+
+ // {{< hint >}}
+ .book-hint {
+ @each $name, $color in $hint-colors {
+ &.#{$name} {
+ border-color: $color;
+ background-color: rgba($color, 0.1);
+ }
+ }
+ }
+}
diff --git a/assets/_utils.scss b/assets/_utils.scss
new file mode 100644
index 0000000..92fad0f
--- /dev/null
+++ b/assets/_utils.scss
@@ -0,0 +1,96 @@
+.flex {
+ display: flex;
+}
+
+.flex-auto {
+ flex: 1 1 auto;
+}
+
+.flex-even {
+ flex: 1 1;
+}
+
+.flex-wrap {
+ flex-wrap: wrap;
+}
+
+.justify-start {
+ justify-content: flex-start;
+}
+
+.justify-end {
+ justify-content: flex-end;
+}
+
+.justify-center {
+ justify-content: center;
+}
+
+.justify-between {
+ justify-content: space-between;
+}
+
+.align-center {
+ align-items: center;
+}
+
+.mx-auto {
+ margin: 0 auto;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.text-small {
+ font-size: .875em;
+}
+
+.hidden {
+ display: none;
+}
+
+input.toggle {
+ height: 0;
+ width: 0;
+ overflow: hidden;
+ opacity: 0;
+ position: absolute;
+}
+
+.clearfix::after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+@mixin spin($duration) {
+ animation: spin $duration ease infinite;
+ @keyframes spin {
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+}
+
+@mixin fixed {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+@mixin outline {
+ outline-style: auto;
+ outline-color: currentColor;
+ outline-color: -webkit-focus-ring-color;
+}
diff --git a/assets/_variables.scss b/assets/_variables.scss
new file mode 100644
index 0000000..6e34d16
--- /dev/null
+++ b/assets/_variables.scss
@@ -0,0 +1,3 @@
+/* You can override SASS variables here. */
+
+// @import "plugins/dark";
diff --git a/assets/book.scss b/assets/book.scss
new file mode 100644
index 0000000..59369fa
--- /dev/null
+++ b/assets/book.scss
@@ -0,0 +1,15 @@
+@import "defaults";
+@import "variables";
+@import "themes/{{ default "light" .Site.Params.BookTheme }}";
+
+@import "normalize";
+@import "utils";
+@import "main";
+@import "fonts";
+@import "print";
+
+@import "markdown";
+@import "shortcodes";
+
+// Custom defined styles
+@import "custom";
diff --git a/assets/clipboard.js b/assets/clipboard.js
new file mode 100644
index 0000000..2799f2f
--- /dev/null
+++ b/assets/clipboard.js
@@ -0,0 +1,24 @@
+(function () {
+ function select(element) {
+ const selection = window.getSelection();
+
+ const range = document.createRange();
+ range.selectNodeContents(element);
+
+ selection.removeAllRanges();
+ selection.addRange(range);
+ }
+
+ document.querySelectorAll("pre code").forEach(code => {
+ code.addEventListener("click", function (event) {
+ if (window.getSelection().toString()) {
+ return;
+ }
+ select(code.parentElement);
+
+ if (navigator.clipboard) {
+ navigator.clipboard.writeText(code.parentElement.textContent);
+ }
+ });
+ });
+})();
diff --git a/assets/css/dropdown.css b/assets/css/dropdown.css
deleted file mode 100644
index c6d7c1a..0000000
--- a/assets/css/dropdown.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/* assets/css/dropdown.css */
-
-/* Remove float; use flex defaults and ensure dropdown items are positioned relatively */
-nav li {
- position: relative;
-}
-
-/* The rest of your dropdown styles remain the same */
-nav li a, .dropbtn {
- display: inline-block;
- background-color: var(--oc-gray-0);
- text-align: center;
- padding: 14px 16px;
- text-decoration: none;
-}
-nav li a:hover, .dropdown:hover .dropbtn {
- background-color: var(--oc-teal-7);
-}
-.dropdown-content {
- display: none;
- position: absolute;
- background-color: var(--oc-gray-0);
- min-width: 160px;
- z-index: 1;
- box-shadow: 0px 8px 16px rgba(0,0,0,0.2);
-}
-.dropdown-content a {
- color: var(--oc-gray-8);
- padding: 12px 16px;
- text-decoration: none;
- display: block;
- text-align: left;
-}
-.dropdown-content a:hover {
- background-color: var(--oc-gray-2);
-}
-.dropdown:hover .dropdown-content {
- display: block;
-}
diff --git a/assets/css/nav.css b/assets/css/nav.css
deleted file mode 100644
index 73357e5..0000000
--- a/assets/css/nav.css
+++ /dev/null
@@ -1,107 +0,0 @@
-/* assets/css/nav.css */
-
-/* Base nav styles */
-nav {
- background-color: var(--oc-teal-8);
- padding: 10px 0;
- }
-
- nav ul {
- list-style-type: none;
- margin: 0;
- padding: 0;
- display: flex;
- justify-content: center;
- }
-
- nav ul li {
- margin: 0 15px;
- }
-
- nav ul li a {
- text-decoration: none;
- color: var(--oc-gray-0);
- font-weight: bold;
- font-size: 1.1rem;
- }
-
- nav ul li a:hover {
- color: var(--oc-orange-5);
- }
-
- /* Desktop nav */
- @media (min-width: 769px) {
- nav ul {
- gap: 1rem;
- }
- }
-
- /* Mobile nav, dropdowns, and hamburger */
- @media (max-width: 768px) {
- /* Hamburger menu */
- .hamburger {
- display: flex;
- flex-direction: column;
- cursor: pointer;
- padding: 10px;
- margin-left: 20px;
- gap: 0.5rem;
- }
-
- .hamburger span {
- height: 3px;
- width: 25px;
- background: var(--oc-gray-0);
- border-radius: 2px;
- transition: all 0.3s ease;
- }
-
- .hamburger.active span:nth-child(1) {
- transform: rotate(45deg) translate(5px, 5px);
- }
-
- .hamburger.active span:nth-child(2) {
- opacity: 0;
- }
-
- .hamburger.active span:nth-child(3) {
- transform: rotate(-45deg) translate(5px, -5px);
- }
-
- /* Nav collapse behavior */
- nav ul {
- flex-direction: column;
- align-items: flex-start;
- overflow: hidden;
- max-height: 0;
- transition: max-height 0.3s ease-out;
- }
-
- nav ul.active {
- max-height: 500px;
- }
-
- nav li,
- nav a {
- width: 100%;
- }
-
- /* Dropdown mobile behavior */
- .dropdown-content {
- position: static;
- }
-
- .dropdown-content a {
- padding: 1rem;
- font-size: 1.1rem;
- }
-
- .dropdown:hover .dropdown-content {
- display: none;
- }
-
- .dropdown .dropbtn:focus + .dropdown-content,
- .dropdown .dropbtn.active + .dropdown-content {
- display: block;
- }
- }
\ No newline at end of file
diff --git a/assets/css/styles.css b/assets/css/styles.css
deleted file mode 100644
index b03a4e5..0000000
--- a/assets/css/styles.css
+++ /dev/null
@@ -1,163 +0,0 @@
-/* assets/css/styles.css */
-
-@font-face {
- font-family: 'Noto Sans';
- src: url('../fonts/static/NotoSans-Regular.ttf') format('truetype');
- font-weight: normal;
-}
-
-
-@font-face {
- font-family: 'Noto Sans';
- src: url('../fonts/static/NotoSans-Bold.ttf') format('truetype');
- font-weight: bold;
-}
-
-@media (max-width: 600px) {
- header h1 {
- font-size: 1.8rem;
- }
-
- header p {
- font-size: 1rem;
- }
-}
-
-
-
-@media (max-width: 600px) {
- .btn {
- width: 100%;
- }
-}
-
-.container {
- width: 90%;
- max-width: 1200px;
- margin: 2rem auto;
- padding: 1rem;
-}
-
-img {
- max-width: 100%;
- height: auto;
-}
-
-
-
-body {
- font-family: 'Noto Sans', arial;
- margin: 0;
- padding: 0;
- text-align: center;
- margin-top: 50px;
- background: var(--oc-gray-0);
- color: var(--gray-9);
-}
-
-header {
- background: var(--oc-teal-9);
- color: var(--oc-gray-0);
- text-align: center;
- padding: 2rem 1rem;
-}
-
-header h1 {
- font-size: 2.5rem;
- margin: 0;
-}
-
-header p {
- font-size: 1.2rem;
- margin: 0.5rem 0 0;
-}
-
-
-
-
-.section {
- margin-bottom: 2rem;
- padding: 1.5rem;
- background: var(--oc-gray-0);
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.section h2 {
- font-size: 1.8rem;
- margin-bottom: 1rem;
- color: var(--oc-teal-9);
-}
-
-.btn {
- display: inline-block;
- padding: 0.8rem 1.5rem;
- background: var(--oc-teal-9);
- color: var(--oc-gray-0);
- text-decoration: none;
- border-radius: 5px;
- transition: background 0.3s;
- padding: 0.75rem 1.5rem;
- display: inline-block;
- text-align: center;
-}
-
-.btn:hover {
- background: var(--oc-orange-5);
-}
-
-@media (max-width: 600px) {
- .btn {
- width: 100%;
- }
-}
-
-footer {
- text-align: center;
- padding: 1rem 0;
- background: var(--oc-teal-9);
- color: var(--oc-gray-0);
-}
-
-
-/* Logo link styling */
-.logo-link {
- text-decoration: none;
- display: inline-block;
- margin-right: 10px;
-}
-
-/* Logo image styling */
-.logo-image {
- vertical-align: middle;
- width: 128px;
- height: 128px;
- margin-right: 10px;
-}
-
-
-/* Spinning logo */
-.logo-spin {
- width: 96px;
- height: auto;
- margin-top: 2rem;
- animation: spin 10s linear infinite;
- transform-origin: center;
-}
-
-@keyframes spin {
- from { transform: rotate(0deg); }
- to { transform: rotate(-360deg); }
-}
-
-.ascii-art {
- font-family: "Courier New", Courier, monospace;
- background-color: #f0f0f0;
- padding: 15px;
- border: 1px solid #ddd;
- display: inline-block;
- margin-top: 20px;
- font-size: 14px;
- line-height: 1.4;
- white-space: pre;
-}
\ No newline at end of file
diff --git a/assets/images/README.md b/assets/images/README.md
deleted file mode 100644
index 8b13789..0000000
--- a/assets/images/README.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/assets/manifest.json b/assets/manifest.json
new file mode 100644
index 0000000..3e0314f
--- /dev/null
+++ b/assets/manifest.json
@@ -0,0 +1,15 @@
+{
+ "name": "{{ .Site.Title }}",
+ "short_name": "{{ .Site.Title }}",
+ "start_url": "{{ "./" | relURL }}",
+ "scope": "{{ "./" | relURL }}",
+ "display": "standalone",
+ "background_color": "#000000",
+ "theme_color": "#000000",
+ "icons": [
+ {
+ "src": "{{ "./favicon.svg" | relURL }}",
+ "sizes": "512x512"
+ }
+ ]
+}
diff --git a/assets/menu-reset.js b/assets/menu-reset.js
new file mode 100644
index 0000000..37cb47b
--- /dev/null
+++ b/assets/menu-reset.js
@@ -0,0 +1,7 @@
+(function() {
+ var menu = document.querySelector("aside .book-menu-content");
+ addEventListener("beforeunload", function(event) {
+ localStorage.setItem("menu.scrollTop", menu.scrollTop);
+ });
+ menu.scrollTop = localStorage.getItem("menu.scrollTop");
+})();
diff --git a/assets/mermaid.json b/assets/mermaid.json
new file mode 100644
index 0000000..0a3f4fb
--- /dev/null
+++ b/assets/mermaid.json
@@ -0,0 +1,6 @@
+{
+ "flowchart": {
+ "useMaxWidth":true
+ },
+ "theme": "default"
+}
diff --git a/assets/normalize.css b/assets/normalize.css
new file mode 100644
index 0000000..192eb9c
--- /dev/null
+++ b/assets/normalize.css
@@ -0,0 +1,349 @@
+/*! 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: content-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 {
+ box-sizing: border-box; /* 1 */
+ 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"] {
+ box-sizing: border-box; /* 1 */
+ 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;
+}
diff --git a/assets/openColour/open-color.less b/assets/openColour/open-color.less
deleted file mode 100644
index dc5eddf..0000000
--- a/assets/openColour/open-color.less
+++ /dev/null
@@ -1,234 +0,0 @@
-//
-//
-// π π’ π π’ π₯
-// v 1.6.3
-//
-// βββββββββββββββββββββββββββββββββββ
-
-
-// General
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-white: #ffffff;
-@oc-black: #000000;
-
-
-// Gray
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-gray-list: #f8f9fa, #f1f3f5, #e9ecef, #dee2e6, #ced4da, #adb5bd, #868e96, #495057, #343a40, #212529;
-
-@oc-gray-0: extract(@oc-gray-list, 1);
-@oc-gray-1: extract(@oc-gray-list, 2);
-@oc-gray-2: extract(@oc-gray-list, 3);
-@oc-gray-3: extract(@oc-gray-list, 4);
-@oc-gray-4: extract(@oc-gray-list, 5);
-@oc-gray-5: extract(@oc-gray-list, 6);
-@oc-gray-6: extract(@oc-gray-list, 7);
-@oc-gray-7: extract(@oc-gray-list, 8);
-@oc-gray-8: extract(@oc-gray-list, 9);
-@oc-gray-9: extract(@oc-gray-list, 10);
-
-
-// Red
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-red-list: #fff5f5, #ffe3e3, #ffc9c9, #ffa8a8, #ff8787, #ff6b6b, #fa5252, #f03e3e, #e03131, #c92a2a;
-
-@oc-red-0: extract(@oc-red-list, 1);
-@oc-red-1: extract(@oc-red-list, 2);
-@oc-red-2: extract(@oc-red-list, 3);
-@oc-red-3: extract(@oc-red-list, 4);
-@oc-red-4: extract(@oc-red-list, 5);
-@oc-red-5: extract(@oc-red-list, 6);
-@oc-red-6: extract(@oc-red-list, 7);
-@oc-red-7: extract(@oc-red-list, 8);
-@oc-red-8: extract(@oc-red-list, 9);
-@oc-red-9: extract(@oc-red-list, 10);
-
-
-// Pink
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-pink-list: #fff0f6, #ffdeeb, #fcc2d7, #faa2c1, #f783ac, #f06595, #e64980, #d6336c, #c2255c, #a61e4d;
-
-@oc-pink-0: extract(@oc-pink-list, 1);
-@oc-pink-1: extract(@oc-pink-list, 2);
-@oc-pink-2: extract(@oc-pink-list, 3);
-@oc-pink-3: extract(@oc-pink-list, 4);
-@oc-pink-4: extract(@oc-pink-list, 5);
-@oc-pink-5: extract(@oc-pink-list, 6);
-@oc-pink-6: extract(@oc-pink-list, 7);
-@oc-pink-7: extract(@oc-pink-list, 8);
-@oc-pink-8: extract(@oc-pink-list, 9);
-@oc-pink-9: extract(@oc-pink-list, 10);
-
-
-// Grape
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-grape-list: #f8f0fc, #f3d9fa, #eebefa, #e599f7, #da77f2, #cc5de8, #be4bdb, #ae3ec9, #9c36b5, #862e9c;
-
-@oc-grape-0: extract(@oc-grape-list, 1);
-@oc-grape-1: extract(@oc-grape-list, 2);
-@oc-grape-2: extract(@oc-grape-list, 3);
-@oc-grape-3: extract(@oc-grape-list, 4);
-@oc-grape-4: extract(@oc-grape-list, 5);
-@oc-grape-5: extract(@oc-grape-list, 6);
-@oc-grape-6: extract(@oc-grape-list, 7);
-@oc-grape-7: extract(@oc-grape-list, 8);
-@oc-grape-8: extract(@oc-grape-list, 9);
-@oc-grape-9: extract(@oc-grape-list, 10);
-
-
-// Violet
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-violet-list: #f3f0ff, #e5dbff, #d0bfff, #b197fc, #9775fa, #845ef7, #7950f2, #7048e8, #6741d9, #5f3dc4;
-
-@oc-violet-0: extract(@oc-violet-list, 1);
-@oc-violet-1: extract(@oc-violet-list, 2);
-@oc-violet-2: extract(@oc-violet-list, 3);
-@oc-violet-3: extract(@oc-violet-list, 4);
-@oc-violet-4: extract(@oc-violet-list, 5);
-@oc-violet-5: extract(@oc-violet-list, 6);
-@oc-violet-6: extract(@oc-violet-list, 7);
-@oc-violet-7: extract(@oc-violet-list, 8);
-@oc-violet-8: extract(@oc-violet-list, 9);
-@oc-violet-9: extract(@oc-violet-list, 10);
-
-
-// Indigo
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-indigo-list: #edf2ff, #dbe4ff, #bac8ff, #91a7ff, #748ffc, #5c7cfa, #4c6ef5, #4263eb, #3b5bdb, #364fc7;
-
-@oc-indigo-0: extract(@oc-indigo-list, 1);
-@oc-indigo-1: extract(@oc-indigo-list, 2);
-@oc-indigo-2: extract(@oc-indigo-list, 3);
-@oc-indigo-3: extract(@oc-indigo-list, 4);
-@oc-indigo-4: extract(@oc-indigo-list, 5);
-@oc-indigo-5: extract(@oc-indigo-list, 6);
-@oc-indigo-6: extract(@oc-indigo-list, 7);
-@oc-indigo-7: extract(@oc-indigo-list, 8);
-@oc-indigo-8: extract(@oc-indigo-list, 9);
-@oc-indigo-9: extract(@oc-indigo-list, 10);
-
-
-// Blue
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-blue-list: #e7f5ff, #d0ebff, #a5d8ff, #74c0fc, #4dabf7, #339af0, #228be6, #1c7ed6, #1971c2, #1864ab;
-
-@oc-blue-0: extract(@oc-blue-list, 1);
-@oc-blue-1: extract(@oc-blue-list, 2);
-@oc-blue-2: extract(@oc-blue-list, 3);
-@oc-blue-3: extract(@oc-blue-list, 4);
-@oc-blue-4: extract(@oc-blue-list, 5);
-@oc-blue-5: extract(@oc-blue-list, 6);
-@oc-blue-6: extract(@oc-blue-list, 7);
-@oc-blue-7: extract(@oc-blue-list, 8);
-@oc-blue-8: extract(@oc-blue-list, 9);
-@oc-blue-9: extract(@oc-blue-list, 10);
-
-
-// Cyan
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-cyan-list: #e3fafc, #c5f6fa, #99e9f2, #66d9e8, #3bc9db, #22b8cf, #15aabf, #1098ad, #0c8599, #0b7285;
-
-@oc-cyan-0: extract(@oc-cyan-list, 1);
-@oc-cyan-1: extract(@oc-cyan-list, 2);
-@oc-cyan-2: extract(@oc-cyan-list, 3);
-@oc-cyan-3: extract(@oc-cyan-list, 4);
-@oc-cyan-4: extract(@oc-cyan-list, 5);
-@oc-cyan-5: extract(@oc-cyan-list, 6);
-@oc-cyan-6: extract(@oc-cyan-list, 7);
-@oc-cyan-7: extract(@oc-cyan-list, 8);
-@oc-cyan-8: extract(@oc-cyan-list, 9);
-@oc-cyan-9: extract(@oc-cyan-list, 10);
-
-
-// Teal
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-teal-list: #e6fcf5, #c3fae8, #96f2d7, #63e6be, #38d9a9, #20c997, #12b886, #0ca678, #099268, #087f5b;
-
-@oc-teal-0: extract(@oc-teal-list, 1);
-@oc-teal-1: extract(@oc-teal-list, 2);
-@oc-teal-2: extract(@oc-teal-list, 3);
-@oc-teal-3: extract(@oc-teal-list, 4);
-@oc-teal-4: extract(@oc-teal-list, 5);
-@oc-teal-5: extract(@oc-teal-list, 6);
-@oc-teal-6: extract(@oc-teal-list, 7);
-@oc-teal-7: extract(@oc-teal-list, 8);
-@oc-teal-8: extract(@oc-teal-list, 9);
-@oc-teal-9: extract(@oc-teal-list, 10);
-
-
-// Green
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-green-list: #ebfbee, #d3f9d8, #b2f2bb, #8ce99a, #69db7c, #51cf66, #40c057, #37b24d, #2f9e44, #2b8a3e;
-
-@oc-green-0: extract(@oc-green-list, 1);
-@oc-green-1: extract(@oc-green-list, 2);
-@oc-green-2: extract(@oc-green-list, 3);
-@oc-green-3: extract(@oc-green-list, 4);
-@oc-green-4: extract(@oc-green-list, 5);
-@oc-green-5: extract(@oc-green-list, 6);
-@oc-green-6: extract(@oc-green-list, 7);
-@oc-green-7: extract(@oc-green-list, 8);
-@oc-green-8: extract(@oc-green-list, 9);
-@oc-green-9: extract(@oc-green-list, 10);
-
-
-// Lime
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-lime-list: #f4fce3, #e9fac8, #d8f5a2, #c0eb75, #a9e34b, #94d82d, #82c91e, #74b816, #66a80f, #5c940d;
-
-@oc-lime-0: extract(@oc-lime-list, 1);
-@oc-lime-1: extract(@oc-lime-list, 2);
-@oc-lime-2: extract(@oc-lime-list, 3);
-@oc-lime-3: extract(@oc-lime-list, 4);
-@oc-lime-4: extract(@oc-lime-list, 5);
-@oc-lime-5: extract(@oc-lime-list, 6);
-@oc-lime-6: extract(@oc-lime-list, 7);
-@oc-lime-7: extract(@oc-lime-list, 8);
-@oc-lime-8: extract(@oc-lime-list, 9);
-@oc-lime-9: extract(@oc-lime-list, 10);
-
-
-// Yellow
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-yellow-list: #fff9db, #fff3bf, #ffec99, #ffe066, #ffd43b, #fcc419, #fab005, #f59f00, #f08c00, #e67700;
-
-@oc-yellow-0: extract(@oc-yellow-list, 1);
-@oc-yellow-1: extract(@oc-yellow-list, 2);
-@oc-yellow-2: extract(@oc-yellow-list, 3);
-@oc-yellow-3: extract(@oc-yellow-list, 4);
-@oc-yellow-4: extract(@oc-yellow-list, 5);
-@oc-yellow-5: extract(@oc-yellow-list, 6);
-@oc-yellow-6: extract(@oc-yellow-list, 7);
-@oc-yellow-7: extract(@oc-yellow-list, 8);
-@oc-yellow-8: extract(@oc-yellow-list, 9);
-@oc-yellow-9: extract(@oc-yellow-list, 10);
-
-
-// Orange
-// βββββββββββββββββββββββββββββββββββ
-
-@oc-orange-list: #fff4e6, #ffe8cc, #ffd8a8, #ffc078, #ffa94d, #ff922b, #fd7e14, #f76707, #e8590c, #d9480f;
-
-@oc-orange-0: extract(@oc-orange-list, 1);
-@oc-orange-1: extract(@oc-orange-list, 2);
-@oc-orange-2: extract(@oc-orange-list, 3);
-@oc-orange-3: extract(@oc-orange-list, 4);
-@oc-orange-4: extract(@oc-orange-list, 5);
-@oc-orange-5: extract(@oc-orange-list, 6);
-@oc-orange-6: extract(@oc-orange-list, 7);
-@oc-orange-7: extract(@oc-orange-list, 8);
-@oc-orange-8: extract(@oc-orange-list, 9);
-@oc-orange-9: extract(@oc-orange-list, 10);
diff --git a/assets/openColour/open-color.scss b/assets/openColour/open-color.scss
deleted file mode 100644
index d4c2bc5..0000000
--- a/assets/openColour/open-color.scss
+++ /dev/null
@@ -1,399 +0,0 @@
-//
-//
-// π π’ π π’ π₯
-// v 1.6.3
-//
-// βββββββββββββββββββββββββββββββββββ
-
-
-// General
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-white: #ffffff;
-$oc-black: #000000;
-
-
-// Gray
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-gray-list: (
- "0": #f8f9fa,
- "1": #f1f3f5,
- "2": #e9ecef,
- "3": #dee2e6,
- "4": #ced4da,
- "5": #adb5bd,
- "6": #868e96,
- "7": #495057,
- "8": #343a40,
- "9": #212529
-);
-
-$oc-gray-0: map-get($oc-gray-list, "0");
-$oc-gray-1: map-get($oc-gray-list, "1");
-$oc-gray-2: map-get($oc-gray-list, "2");
-$oc-gray-3: map-get($oc-gray-list, "3");
-$oc-gray-4: map-get($oc-gray-list, "4");
-$oc-gray-5: map-get($oc-gray-list, "5");
-$oc-gray-6: map-get($oc-gray-list, "6");
-$oc-gray-7: map-get($oc-gray-list, "7");
-$oc-gray-8: map-get($oc-gray-list, "8");
-$oc-gray-9: map-get($oc-gray-list, "9");
-
-
-// Red
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-red-list: (
- "0": #fff5f5,
- "1": #ffe3e3,
- "2": #ffc9c9,
- "3": #ffa8a8,
- "4": #ff8787,
- "5": #ff6b6b,
- "6": #fa5252,
- "7": #f03e3e,
- "8": #e03131,
- "9": #c92a2a
-);
-
-$oc-red-0: map-get($oc-red-list, "0");
-$oc-red-1: map-get($oc-red-list, "1");
-$oc-red-2: map-get($oc-red-list, "2");
-$oc-red-3: map-get($oc-red-list, "3");
-$oc-red-4: map-get($oc-red-list, "4");
-$oc-red-5: map-get($oc-red-list, "5");
-$oc-red-6: map-get($oc-red-list, "6");
-$oc-red-7: map-get($oc-red-list, "7");
-$oc-red-8: map-get($oc-red-list, "8");
-$oc-red-9: map-get($oc-red-list, "9");
-
-
-// Pink
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-pink-list: (
- "0": #fff0f6,
- "1": #ffdeeb,
- "2": #fcc2d7,
- "3": #faa2c1,
- "4": #f783ac,
- "5": #f06595,
- "6": #e64980,
- "7": #d6336c,
- "8": #c2255c,
- "9": #a61e4d
-);
-
-$oc-pink-0: map-get($oc-pink-list, "0");
-$oc-pink-1: map-get($oc-pink-list, "1");
-$oc-pink-2: map-get($oc-pink-list, "2");
-$oc-pink-3: map-get($oc-pink-list, "3");
-$oc-pink-4: map-get($oc-pink-list, "4");
-$oc-pink-5: map-get($oc-pink-list, "5");
-$oc-pink-6: map-get($oc-pink-list, "6");
-$oc-pink-7: map-get($oc-pink-list, "7");
-$oc-pink-8: map-get($oc-pink-list, "8");
-$oc-pink-9: map-get($oc-pink-list, "9");
-
-
-// Grape
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-grape-list: (
- "0": #f8f0fc,
- "1": #f3d9fa,
- "2": #eebefa,
- "3": #e599f7,
- "4": #da77f2,
- "5": #cc5de8,
- "6": #be4bdb,
- "7": #ae3ec9,
- "8": #9c36b5,
- "9": #862e9c
-);
-
-$oc-grape-0: map-get($oc-grape-list, "0");
-$oc-grape-1: map-get($oc-grape-list, "1");
-$oc-grape-2: map-get($oc-grape-list, "2");
-$oc-grape-3: map-get($oc-grape-list, "3");
-$oc-grape-4: map-get($oc-grape-list, "4");
-$oc-grape-5: map-get($oc-grape-list, "5");
-$oc-grape-6: map-get($oc-grape-list, "6");
-$oc-grape-7: map-get($oc-grape-list, "7");
-$oc-grape-8: map-get($oc-grape-list, "8");
-$oc-grape-9: map-get($oc-grape-list, "9");
-
-
-// Violet
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-violet-list: (
- "0": #f3f0ff,
- "1": #e5dbff,
- "2": #d0bfff,
- "3": #b197fc,
- "4": #9775fa,
- "5": #845ef7,
- "6": #7950f2,
- "7": #7048e8,
- "8": #6741d9,
- "9": #5f3dc4
-);
-
-$oc-violet-0: map-get($oc-violet-list, "0");
-$oc-violet-1: map-get($oc-violet-list, "1");
-$oc-violet-2: map-get($oc-violet-list, "2");
-$oc-violet-3: map-get($oc-violet-list, "3");
-$oc-violet-4: map-get($oc-violet-list, "4");
-$oc-violet-5: map-get($oc-violet-list, "5");
-$oc-violet-6: map-get($oc-violet-list, "6");
-$oc-violet-7: map-get($oc-violet-list, "7");
-$oc-violet-8: map-get($oc-violet-list, "8");
-$oc-violet-9: map-get($oc-violet-list, "9");
-
-
-// Indigo
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-indigo-list: (
- "0": #edf2ff,
- "1": #dbe4ff,
- "2": #bac8ff,
- "3": #91a7ff,
- "4": #748ffc,
- "5": #5c7cfa,
- "6": #4c6ef5,
- "7": #4263eb,
- "8": #3b5bdb,
- "9": #364fc7
-);
-
-$oc-indigo-0: map-get($oc-indigo-list, "0");
-$oc-indigo-1: map-get($oc-indigo-list, "1");
-$oc-indigo-2: map-get($oc-indigo-list, "2");
-$oc-indigo-3: map-get($oc-indigo-list, "3");
-$oc-indigo-4: map-get($oc-indigo-list, "4");
-$oc-indigo-5: map-get($oc-indigo-list, "5");
-$oc-indigo-6: map-get($oc-indigo-list, "6");
-$oc-indigo-7: map-get($oc-indigo-list, "7");
-$oc-indigo-8: map-get($oc-indigo-list, "8");
-$oc-indigo-9: map-get($oc-indigo-list, "9");
-
-
-// Blue
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-blue-list: (
- "0": #e7f5ff,
- "1": #d0ebff,
- "2": #a5d8ff,
- "3": #74c0fc,
- "4": #4dabf7,
- "5": #339af0,
- "6": #228be6,
- "7": #1c7ed6,
- "8": #1971c2,
- "9": #1864ab
-);
-
-$oc-blue-0: map-get($oc-blue-list, "0");
-$oc-blue-1: map-get($oc-blue-list, "1");
-$oc-blue-2: map-get($oc-blue-list, "2");
-$oc-blue-3: map-get($oc-blue-list, "3");
-$oc-blue-4: map-get($oc-blue-list, "4");
-$oc-blue-5: map-get($oc-blue-list, "5");
-$oc-blue-6: map-get($oc-blue-list, "6");
-$oc-blue-7: map-get($oc-blue-list, "7");
-$oc-blue-8: map-get($oc-blue-list, "8");
-$oc-blue-9: map-get($oc-blue-list, "9");
-
-
-// Cyan
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-cyan-list: (
- "0": #e3fafc,
- "1": #c5f6fa,
- "2": #99e9f2,
- "3": #66d9e8,
- "4": #3bc9db,
- "5": #22b8cf,
- "6": #15aabf,
- "7": #1098ad,
- "8": #0c8599,
- "9": #0b7285
-);
-
-$oc-cyan-0: map-get($oc-cyan-list, "0");
-$oc-cyan-1: map-get($oc-cyan-list, "1");
-$oc-cyan-2: map-get($oc-cyan-list, "2");
-$oc-cyan-3: map-get($oc-cyan-list, "3");
-$oc-cyan-4: map-get($oc-cyan-list, "4");
-$oc-cyan-5: map-get($oc-cyan-list, "5");
-$oc-cyan-6: map-get($oc-cyan-list, "6");
-$oc-cyan-7: map-get($oc-cyan-list, "7");
-$oc-cyan-8: map-get($oc-cyan-list, "8");
-$oc-cyan-9: map-get($oc-cyan-list, "9");
-
-
-// Teal
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-teal-list: (
- "0": #e6fcf5,
- "1": #c3fae8,
- "2": #96f2d7,
- "3": #63e6be,
- "4": #38d9a9,
- "5": #20c997,
- "6": #12b886,
- "7": #0ca678,
- "8": #099268,
- "9": #087f5b
-);
-
-$oc-teal-0: map-get($oc-teal-list, "0");
-$oc-teal-1: map-get($oc-teal-list, "1");
-$oc-teal-2: map-get($oc-teal-list, "2");
-$oc-teal-3: map-get($oc-teal-list, "3");
-$oc-teal-4: map-get($oc-teal-list, "4");
-$oc-teal-5: map-get($oc-teal-list, "5");
-$oc-teal-6: map-get($oc-teal-list, "6");
-$oc-teal-7: map-get($oc-teal-list, "7");
-$oc-teal-8: map-get($oc-teal-list, "8");
-$oc-teal-9: map-get($oc-teal-list, "9");
-
-
-// Green
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-green-list: (
- "0": #ebfbee,
- "1": #d3f9d8,
- "2": #b2f2bb,
- "3": #8ce99a,
- "4": #69db7c,
- "5": #51cf66,
- "6": #40c057,
- "7": #37b24d,
- "8": #2f9e44,
- "9": #2b8a3e
-);
-
-$oc-green-0: map-get($oc-green-list, "0");
-$oc-green-1: map-get($oc-green-list, "1");
-$oc-green-2: map-get($oc-green-list, "2");
-$oc-green-3: map-get($oc-green-list, "3");
-$oc-green-4: map-get($oc-green-list, "4");
-$oc-green-5: map-get($oc-green-list, "5");
-$oc-green-6: map-get($oc-green-list, "6");
-$oc-green-7: map-get($oc-green-list, "7");
-$oc-green-8: map-get($oc-green-list, "8");
-$oc-green-9: map-get($oc-green-list, "9");
-
-
-// Lime
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-lime-list: (
- "0": #f4fce3,
- "1": #e9fac8,
- "2": #d8f5a2,
- "3": #c0eb75,
- "4": #a9e34b,
- "5": #94d82d,
- "6": #82c91e,
- "7": #74b816,
- "8": #66a80f,
- "9": #5c940d
-);
-
-$oc-lime-0: map-get($oc-lime-list, "0");
-$oc-lime-1: map-get($oc-lime-list, "1");
-$oc-lime-2: map-get($oc-lime-list, "2");
-$oc-lime-3: map-get($oc-lime-list, "3");
-$oc-lime-4: map-get($oc-lime-list, "4");
-$oc-lime-5: map-get($oc-lime-list, "5");
-$oc-lime-6: map-get($oc-lime-list, "6");
-$oc-lime-7: map-get($oc-lime-list, "7");
-$oc-lime-8: map-get($oc-lime-list, "8");
-$oc-lime-9: map-get($oc-lime-list, "9");
-
-
-// Yellow
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-yellow-list: (
- "0": #fff9db,
- "1": #fff3bf,
- "2": #ffec99,
- "3": #ffe066,
- "4": #ffd43b,
- "5": #fcc419,
- "6": #fab005,
- "7": #f59f00,
- "8": #f08c00,
- "9": #e67700
-);
-
-$oc-yellow-0: map-get($oc-yellow-list, "0");
-$oc-yellow-1: map-get($oc-yellow-list, "1");
-$oc-yellow-2: map-get($oc-yellow-list, "2");
-$oc-yellow-3: map-get($oc-yellow-list, "3");
-$oc-yellow-4: map-get($oc-yellow-list, "4");
-$oc-yellow-5: map-get($oc-yellow-list, "5");
-$oc-yellow-6: map-get($oc-yellow-list, "6");
-$oc-yellow-7: map-get($oc-yellow-list, "7");
-$oc-yellow-8: map-get($oc-yellow-list, "8");
-$oc-yellow-9: map-get($oc-yellow-list, "9");
-
-
-// Orange
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-orange-list: (
- "0": #fff4e6,
- "1": #ffe8cc,
- "2": #ffd8a8,
- "3": #ffc078,
- "4": #ffa94d,
- "5": #ff922b,
- "6": #fd7e14,
- "7": #f76707,
- "8": #e8590c,
- "9": #d9480f
-);
-
-$oc-orange-0: map-get($oc-orange-list, "0");
-$oc-orange-1: map-get($oc-orange-list, "1");
-$oc-orange-2: map-get($oc-orange-list, "2");
-$oc-orange-3: map-get($oc-orange-list, "3");
-$oc-orange-4: map-get($oc-orange-list, "4");
-$oc-orange-5: map-get($oc-orange-list, "5");
-$oc-orange-6: map-get($oc-orange-list, "6");
-$oc-orange-7: map-get($oc-orange-list, "7");
-$oc-orange-8: map-get($oc-orange-list, "8");
-$oc-orange-9: map-get($oc-orange-list, "9");
-
-
-// Color list
-// βββββββββββββββββββββββββββββββββββ
-
-$oc-color-spectrum: 9;
-
-$oc-color-list: (
- $oc-gray-list: "gray",
- $oc-red-list: "red",
- $oc-pink-list: "pink",
- $oc-grape-list: "grape",
- $oc-violet-list: "violet",
- $oc-indigo-list: "indigo",
- $oc-blue-list: "blue",
- $oc-cyan-list: "cyan",
- $oc-teal-list: "teal",
- $oc-green-list: "green",
- $oc-lime-list: "lime",
- $oc-yellow-list: "yellow",
- $oc-orange-list: "orange"
-);
diff --git a/assets/openColour/open-color.styl b/assets/openColour/open-color.styl
deleted file mode 100644
index 260b6b3..0000000
--- a/assets/openColour/open-color.styl
+++ /dev/null
@@ -1,377 +0,0 @@
-//
-//
-// π π’ π π’ π₯
-// v 1.6.3
-//
-// βββββββββββββββββββββββββββββββββββ
-
-
-// General
-// βββββββββββββββββββββββββββββββββββ
-
-oc-white = #ffffff
-oc-black = #000000
-
-
-// Gray
-// βββββββββββββββββββββββββββββββββββ
-
-oc-gray-list = {
- '0': #f8f9fa,
- '1': #f1f3f5,
- '2': #e9ecef,
- '3': #dee2e6,
- '4': #ced4da,
- '5': #adb5bd,
- '6': #868e96,
- '7': #495057,
- '8': #343a40,
- '9': #212529
-}
-
-oc-gray-0 = oc-gray-list['0']
-oc-gray-1 = oc-gray-list['1']
-oc-gray-2 = oc-gray-list['2']
-oc-gray-3 = oc-gray-list['3']
-oc-gray-4 = oc-gray-list['4']
-oc-gray-5 = oc-gray-list['5']
-oc-gray-6 = oc-gray-list['6']
-oc-gray-7 = oc-gray-list['7']
-oc-gray-8 = oc-gray-list['8']
-oc-gray-9 = oc-gray-list['9']
-
-
-// Red
-// βββββββββββββββββββββββββββββββββββ
-
-oc-red-list = {
- '0': #fff5f5,
- '1': #ffe3e3,
- '2': #ffc9c9,
- '3': #ffa8a8,
- '4': #ff8787,
- '5': #ff6b6b,
- '6': #fa5252,
- '7': #f03e3e,
- '8': #e03131,
- '9': #c92a2a
-}
-
-oc-red-0 = oc-red-list['0']
-oc-red-1 = oc-red-list['1']
-oc-red-2 = oc-red-list['2']
-oc-red-3 = oc-red-list['3']
-oc-red-4 = oc-red-list['4']
-oc-red-5 = oc-red-list['5']
-oc-red-6 = oc-red-list['6']
-oc-red-7 = oc-red-list['7']
-oc-red-8 = oc-red-list['8']
-oc-red-9 = oc-red-list['9']
-
-
-// Pink
-// βββββββββββββββββββββββββββββββββββ
-
-oc-pink-list = {
- '0': #fff0f6,
- '1': #ffdeeb,
- '2': #fcc2d7,
- '3': #faa2c1,
- '4': #f783ac,
- '5': #f06595,
- '6': #e64980,
- '7': #d6336c,
- '8': #c2255c,
- '9': #a61e4d
-}
-
-oc-pink-0 = oc-pink-list['0']
-oc-pink-1 = oc-pink-list['1']
-oc-pink-2 = oc-pink-list['2']
-oc-pink-3 = oc-pink-list['3']
-oc-pink-4 = oc-pink-list['4']
-oc-pink-5 = oc-pink-list['5']
-oc-pink-6 = oc-pink-list['6']
-oc-pink-7 = oc-pink-list['7']
-oc-pink-8 = oc-pink-list['8']
-oc-pink-9 = oc-pink-list['9']
-
-
-// Grape
-// βββββββββββββββββββββββββββββββββββ
-
-oc-grape-list = {
- '0': #f8f0fc,
- '1': #f3d9fa,
- '2': #eebefa,
- '3': #e599f7,
- '4': #da77f2,
- '5': #cc5de8,
- '6': #be4bdb,
- '7': #ae3ec9,
- '8': #9c36b5,
- '9': #862e9c
-}
-
-oc-grape-0 = oc-grape-list['0']
-oc-grape-1 = oc-grape-list['1']
-oc-grape-2 = oc-grape-list['2']
-oc-grape-3 = oc-grape-list['3']
-oc-grape-4 = oc-grape-list['4']
-oc-grape-5 = oc-grape-list['5']
-oc-grape-6 = oc-grape-list['6']
-oc-grape-7 = oc-grape-list['7']
-oc-grape-8 = oc-grape-list['8']
-oc-grape-9 = oc-grape-list['9']
-
-
-// Violet
-// βββββββββββββββββββββββββββββββββββ
-
-oc-violet-list = {
- '0': #f3f0ff,
- '1': #e5dbff,
- '2': #d0bfff,
- '3': #b197fc,
- '4': #9775fa,
- '5': #845ef7,
- '6': #7950f2,
- '7': #7048e8,
- '8': #6741d9,
- '9': #5f3dc4
-}
-
-oc-violet-0 = oc-violet-list['0']
-oc-violet-1 = oc-violet-list['1']
-oc-violet-2 = oc-violet-list['2']
-oc-violet-3 = oc-violet-list['3']
-oc-violet-4 = oc-violet-list['4']
-oc-violet-5 = oc-violet-list['5']
-oc-violet-6 = oc-violet-list['6']
-oc-violet-7 = oc-violet-list['7']
-oc-violet-8 = oc-violet-list['8']
-oc-violet-9 = oc-violet-list['9']
-
-
-// Indigo
-// βββββββββββββββββββββββββββββββββββ
-
-oc-indigo-list = {
- '0': #edf2ff,
- '1': #dbe4ff,
- '2': #bac8ff,
- '3': #91a7ff,
- '4': #748ffc,
- '5': #5c7cfa,
- '6': #4c6ef5,
- '7': #4263eb,
- '8': #3b5bdb,
- '9': #364fc7
-}
-
-oc-indigo-0 = oc-indigo-list['0']
-oc-indigo-1 = oc-indigo-list['1']
-oc-indigo-2 = oc-indigo-list['2']
-oc-indigo-3 = oc-indigo-list['3']
-oc-indigo-4 = oc-indigo-list['4']
-oc-indigo-5 = oc-indigo-list['5']
-oc-indigo-6 = oc-indigo-list['6']
-oc-indigo-7 = oc-indigo-list['7']
-oc-indigo-8 = oc-indigo-list['8']
-oc-indigo-9 = oc-indigo-list['9']
-
-
-// Blue
-// βββββββββββββββββββββββββββββββββββ
-
-oc-blue-list = {
- '0': #e7f5ff,
- '1': #d0ebff,
- '2': #a5d8ff,
- '3': #74c0fc,
- '4': #4dabf7,
- '5': #339af0,
- '6': #228be6,
- '7': #1c7ed6,
- '8': #1971c2,
- '9': #1864ab
-}
-
-oc-blue-0 = oc-blue-list['0']
-oc-blue-1 = oc-blue-list['1']
-oc-blue-2 = oc-blue-list['2']
-oc-blue-3 = oc-blue-list['3']
-oc-blue-4 = oc-blue-list['4']
-oc-blue-5 = oc-blue-list['5']
-oc-blue-6 = oc-blue-list['6']
-oc-blue-7 = oc-blue-list['7']
-oc-blue-8 = oc-blue-list['8']
-oc-blue-9 = oc-blue-list['9']
-
-
-// Cyan
-// βββββββββββββββββββββββββββββββββββ
-
-oc-cyan-list = {
- '0': #e3fafc,
- '1': #c5f6fa,
- '2': #99e9f2,
- '3': #66d9e8,
- '4': #3bc9db,
- '5': #22b8cf,
- '6': #15aabf,
- '7': #1098ad,
- '8': #0c8599,
- '9': #0b7285
-}
-
-oc-cyan-0 = oc-cyan-list['0']
-oc-cyan-1 = oc-cyan-list['1']
-oc-cyan-2 = oc-cyan-list['2']
-oc-cyan-3 = oc-cyan-list['3']
-oc-cyan-4 = oc-cyan-list['4']
-oc-cyan-5 = oc-cyan-list['5']
-oc-cyan-6 = oc-cyan-list['6']
-oc-cyan-7 = oc-cyan-list['7']
-oc-cyan-8 = oc-cyan-list['8']
-oc-cyan-9 = oc-cyan-list['9']
-
-
-// Teal
-// βββββββββββββββββββββββββββββββββββ
-
-oc-teal-list = {
- '0': #e6fcf5,
- '1': #c3fae8,
- '2': #96f2d7,
- '3': #63e6be,
- '4': #38d9a9,
- '5': #20c997,
- '6': #12b886,
- '7': #0ca678,
- '8': #099268,
- '9': #087f5b
-}
-
-oc-teal-0 = oc-teal-list['0']
-oc-teal-1 = oc-teal-list['1']
-oc-teal-2 = oc-teal-list['2']
-oc-teal-3 = oc-teal-list['3']
-oc-teal-4 = oc-teal-list['4']
-oc-teal-5 = oc-teal-list['5']
-oc-teal-6 = oc-teal-list['6']
-oc-teal-7 = oc-teal-list['7']
-oc-teal-8 = oc-teal-list['8']
-oc-teal-9 = oc-teal-list['9']
-
-
-// Green
-// βββββββββββββββββββββββββββββββββββ
-
-oc-green-list = {
- '0': #ebfbee,
- '1': #d3f9d8,
- '2': #b2f2bb,
- '3': #8ce99a,
- '4': #69db7c,
- '5': #51cf66,
- '6': #40c057,
- '7': #37b24d,
- '8': #2f9e44,
- '9': #2b8a3e
-}
-
-oc-green-0 = oc-green-list['0']
-oc-green-1 = oc-green-list['1']
-oc-green-2 = oc-green-list['2']
-oc-green-3 = oc-green-list['3']
-oc-green-4 = oc-green-list['4']
-oc-green-5 = oc-green-list['5']
-oc-green-6 = oc-green-list['6']
-oc-green-7 = oc-green-list['7']
-oc-green-8 = oc-green-list['8']
-oc-green-9 = oc-green-list['9']
-
-
-// Lime
-// βββββββββββββββββββββββββββββββββββ
-
-oc-lime-list = {
- '0': #f4fce3,
- '1': #e9fac8,
- '2': #d8f5a2,
- '3': #c0eb75,
- '4': #a9e34b,
- '5': #94d82d,
- '6': #82c91e,
- '7': #74b816,
- '8': #66a80f,
- '9': #5c940d
-}
-
-oc-lime-0 = oc-lime-list['0']
-oc-lime-1 = oc-lime-list['1']
-oc-lime-2 = oc-lime-list['2']
-oc-lime-3 = oc-lime-list['3']
-oc-lime-4 = oc-lime-list['4']
-oc-lime-5 = oc-lime-list['5']
-oc-lime-6 = oc-lime-list['6']
-oc-lime-7 = oc-lime-list['7']
-oc-lime-8 = oc-lime-list['8']
-oc-lime-9 = oc-lime-list['9']
-
-
-// Yellow
-// βββββββββββββββββββββββββββββββββββ
-
-oc-yellow-list = {
- '0': #fff9db,
- '1': #fff3bf,
- '2': #ffec99,
- '3': #ffe066,
- '4': #ffd43b,
- '5': #fcc419,
- '6': #fab005,
- '7': #f59f00,
- '8': #f08c00,
- '9': #e67700
-}
-
-oc-yellow-0 = oc-yellow-list['0']
-oc-yellow-1 = oc-yellow-list['1']
-oc-yellow-2 = oc-yellow-list['2']
-oc-yellow-3 = oc-yellow-list['3']
-oc-yellow-4 = oc-yellow-list['4']
-oc-yellow-5 = oc-yellow-list['5']
-oc-yellow-6 = oc-yellow-list['6']
-oc-yellow-7 = oc-yellow-list['7']
-oc-yellow-8 = oc-yellow-list['8']
-oc-yellow-9 = oc-yellow-list['9']
-
-
-// Orange
-// βββββββββββββββββββββββββββββββββββ
-
-oc-orange-list = {
- '0': #fff4e6,
- '1': #ffe8cc,
- '2': #ffd8a8,
- '3': #ffc078,
- '4': #ffa94d,
- '5': #ff922b,
- '6': #fd7e14,
- '7': #f76707,
- '8': #e8590c,
- '9': #d9480f
-}
-
-oc-orange-0 = oc-orange-list['0']
-oc-orange-1 = oc-orange-list['1']
-oc-orange-2 = oc-orange-list['2']
-oc-orange-3 = oc-orange-list['3']
-oc-orange-4 = oc-orange-list['4']
-oc-orange-5 = oc-orange-list['5']
-oc-orange-6 = oc-orange-list['6']
-oc-orange-7 = oc-orange-list['7']
-oc-orange-8 = oc-orange-list['8']
-oc-orange-9 = oc-orange-list['9']
diff --git a/assets/plugins/_numbered.scss b/assets/plugins/_numbered.scss
new file mode 100644
index 0000000..d7ad4d5
--- /dev/null
+++ b/assets/plugins/_numbered.scss
@@ -0,0 +1,34 @@
+$startLevel: 1;
+$endLevel: 6;
+
+.book-page .markdown.book-article {
+ @for $currentLevel from $startLevel through $endLevel {
+ h#{$currentLevel} {
+ counter-increment: h#{$currentLevel};
+ counter-reset: h#{$currentLevel + 1};
+
+ $content: "";
+ @for $n from $startLevel through $currentLevel {
+ $content: $content + 'counter(h#{$n})"."';
+ }
+
+ &::before {
+ content: unquote($content) " ";
+ }
+ }
+ }
+}
+
+.book-toc nav#TableOfContents ul {
+ counter-reset: item;
+
+ li {
+ counter-increment: item;
+
+ &:before {
+ content: counters(item, ".") ". ";
+ float: left;
+ margin-inline-end: $padding-4;
+ }
+ }
+}
diff --git a/assets/plugins/_scrollbars.scss b/assets/plugins/_scrollbars.scss
new file mode 100644
index 0000000..0062582
--- /dev/null
+++ b/assets/plugins/_scrollbars.scss
@@ -0,0 +1,26 @@
+@import "defaults";
+@import "variables";
+
+// Webkit
+::-webkit-scrollbar {
+ width: $padding-8;
+}
+
+::-webkit-scrollbar-thumb {
+ background: transparent;
+ border-radius: $padding-8;
+}
+
+:hover::-webkit-scrollbar-thumb {
+ background: var(--gray-500);
+}
+
+// MS
+body {
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+}
+
+// Future
+.book-menu nav {
+ scrollbar-color: transparent var(--gray-500);
+}
diff --git a/assets/search-data.json b/assets/search-data.json
new file mode 100644
index 0000000..0a65bf0
--- /dev/null
+++ b/assets/search-data.json
@@ -0,0 +1,17 @@
+[
+{{- $pages := where .Site.Pages "Kind" "in" (slice "page" "section") -}}
+{{- $pages = where $pages "Params.bookSearchExclude" "!=" true -}}
+{{/* Remove until we know why it does not work, see https://github.com/alex-shpak/hugo-book/issues/528 */}}
+{{/*- $pages = where $pages "Content" "not in" (slice nil "") -*/}}
+{{- $pages = where $pages "Content" "!=" "" -}}
+
+{{ range $index, $page := $pages }}
+{{ if gt $index 0}},{{end}} {
+ "id": {{ $index }},
+ "href": "{{ $page.RelPermalink }}",
+ "title": {{ (partial "docs/title" $page) | jsonify }},
+ "section": {{ (partial "docs/title" $page.Parent) | jsonify }},
+ "content": {{ $page.Plain | jsonify }}
+}
+{{- end -}}
+]
diff --git a/assets/search.js b/assets/search.js
new file mode 100644
index 0000000..91add6f
--- /dev/null
+++ b/assets/search.js
@@ -0,0 +1,113 @@
+'use strict';
+
+{{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }}
+{{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify | resources.Fingerprint }}
+{{ $searchConfig := i18n "bookSearchConfig" | default "{}" }}
+
+(function () {
+ const searchDataURL = '{{ $searchData.RelPermalink }}';
+ const indexConfig = Object.assign({{ $searchConfig }}, {
+ includeScore: true,
+ useExtendedSearch: true,
+ fieldNormWeight: 1.5,
+ threshold: 0.2,
+ ignoreLocation: true,
+ keys: [
+ {
+ name: 'title',
+ weight: 0.7
+ },
+ {
+ name: 'content',
+ weight: 0.3
+ }
+ ]
+ });
+
+ const input = document.querySelector('#book-search-input');
+ const results = document.querySelector('#book-search-results');
+
+ if (!input) {
+ return
+ }
+
+ input.addEventListener('focus', init);
+ input.addEventListener('keyup', search);
+
+ document.addEventListener('keypress', focusSearchFieldOnKeyPress);
+
+ /**
+ * @param {Event} event
+ */
+ function focusSearchFieldOnKeyPress(event) {
+ if (event.target.value !== undefined) {
+ return;
+ }
+
+ if (input === document.activeElement) {
+ return;
+ }
+
+ const characterPressed = String.fromCharCode(event.charCode);
+ if (!isHotkey(characterPressed)) {
+ return;
+ }
+
+ input.focus();
+ event.preventDefault();
+ }
+
+ /**
+ * @param {String} character
+ * @returns {Boolean}
+ */
+ function isHotkey(character) {
+ const dataHotkeys = input.getAttribute('data-hotkeys') || '';
+ return dataHotkeys.indexOf(character) >= 0;
+ }
+
+ function init() {
+ input.removeEventListener('focus', init); // init once
+ input.required = true;
+
+ fetch(searchDataURL)
+ .then(pages => pages.json())
+ .then(pages => {
+ window.bookSearchIndex = new Fuse(pages, indexConfig);
+ })
+ .then(() => input.required = false)
+ .then(search);
+ }
+
+ function search() {
+ while (results.firstChild) {
+ results.removeChild(results.firstChild);
+ }
+
+ if (!input.value) {
+ return;
+ }
+
+ const searchHits = window.bookSearchIndex.search(input.value).slice(0,10);
+ searchHits.forEach(function (page) {
+ const li = element('
');
+ const a = li.querySelector('a'), small = li.querySelector('small');
+
+ a.href = page.item.href;
+ a.textContent = page.item.title;
+ small.textContent = page.item.section;
+
+ results.appendChild(li);
+ });
+ }
+
+ /**
+ * @param {String} content
+ * @returns {Node}
+ */
+ function element(content) {
+ const div = document.createElement('div');
+ div.innerHTML = content;
+ return div.firstChild;
+ }
+})();
diff --git a/assets/sw-register.js b/assets/sw-register.js
new file mode 100644
index 0000000..e5d1761
--- /dev/null
+++ b/assets/sw-register.js
@@ -0,0 +1,7 @@
+{{- $swJS := resources.Get "sw.js" | resources.ExecuteAsTemplate "sw.js" . -}}
+if (navigator.serviceWorker) {
+ navigator.serviceWorker.register(
+ "{{ $swJS.RelPermalink }}",
+ { scope: "{{ "./" | relURL }}" }
+ );
+}
diff --git a/assets/sw.js b/assets/sw.js
new file mode 100644
index 0000000..2ff11fc
--- /dev/null
+++ b/assets/sw.js
@@ -0,0 +1,55 @@
+const cacheName = self.location.pathname
+const pages = [
+{{ if eq .Site.Params.BookServiceWorker "precache" }}
+ {{ range .Site.AllPages -}}
+ "{{ .RelPermalink }}",
+ {{ end -}}
+{{ end }}
+];
+
+self.addEventListener("install", function (event) {
+ self.skipWaiting();
+
+ caches.open(cacheName).then((cache) => {
+ return cache.addAll(pages);
+ });
+});
+
+self.addEventListener("fetch", (event) => {
+ const request = event.request;
+ if (request.method !== "GET") {
+ return;
+ }
+
+ /**
+ * @param {Response} response
+ * @returns {Promise}
+ */
+ function saveToCache(response) {
+ if (cacheable(response)) {
+ return caches
+ .open(cacheName)
+ .then((cache) => cache.put(request, response.clone()))
+ .then(() => response);
+ } else {
+ return response;
+ }
+ }
+
+ /**
+ * @param {Error} error
+ */
+ function serveFromCache(error) {
+ return caches.open(cacheName).then((cache) => cache.match(request.url));
+ }
+
+ /**
+ * @param {Response} response
+ * @returns {Boolean}
+ */
+ function cacheable(response) {
+ return response.type === "basic" && response.ok && !response.headers.has("Content-Disposition")
+ }
+
+ event.respondWith(fetch(request).then(saveToCache).catch(serveFromCache));
+});
diff --git a/assets/themes/_auto.scss b/assets/themes/_auto.scss
new file mode 100644
index 0000000..31d7f9a
--- /dev/null
+++ b/assets/themes/_auto.scss
@@ -0,0 +1,9 @@
+:root {
+ @include theme-light;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ @include theme-dark;
+ }
+}
diff --git a/assets/themes/_dark.scss b/assets/themes/_dark.scss
new file mode 100644
index 0000000..e00e38e
--- /dev/null
+++ b/assets/themes/_dark.scss
@@ -0,0 +1,3 @@
+:root {
+ @include theme-dark;
+}
diff --git a/assets/themes/_light.scss b/assets/themes/_light.scss
new file mode 100644
index 0000000..8c0e346
--- /dev/null
+++ b/assets/themes/_light.scss
@@ -0,0 +1,3 @@
+:root {
+ @include theme-light;
+}
diff --git a/assets_bak/css/components/breadcrumbs.css b/assets_bak/css/components/breadcrumbs.css
new file mode 100644
index 0000000..1fea322
--- /dev/null
+++ b/assets_bak/css/components/breadcrumbs.css
@@ -0,0 +1,38 @@
+/* assets/css/components/breadcrumbs.css */
+
+/* Container */
+.breadcrumbs {
+ display: inline-flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0.5rem;
+ margin: 1.5rem 0; /* more breathing room */
+ padding: 0.5rem 1rem; /* subtle padding */
+ background: var(--oc-gray-1); /* light neutral background */
+ border-radius: 0.25rem;
+ font-size: 0.9rem;
+ color: var(--oc-gray-7);
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+}
+
+/* βHomeβ icon or bullet (you could swap this for an SVG or emoji) */
+.breadcrumbs::before {
+ content: "π ";
+ margin-right: 0.5rem;
+}
+
+/* Links */
+.breadcrumbs a {
+ color: var(--color-brand);
+ text-decoration: none;
+ transition: color 0.2s ease;
+}
+.breadcrumbs a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+/* Separator */
+.breadcrumbs .sep {
+ color: var(--oc-gray-5);
+}
\ No newline at end of file
diff --git a/assets_bak/css/components/callout.css b/assets_bak/css/components/callout.css
new file mode 100644
index 0000000..15d75b8
--- /dev/null
+++ b/assets_bak/css/components/callout.css
@@ -0,0 +1,29 @@
+/* assets/css/components/callout.css */
+
+.callout {
+ padding: 1rem;
+ margin: 1.5rem 0;
+ border-radius: 4px;
+ background: var(--color-surface, var(--oc-gray-0));
+ color: var(--color-text, #212529);
+ border-left: 4px solid currentColor;
+}
+
+.callout.tip {
+ border-color: var(--oc-green-6);
+}
+
+.callout.note {
+ border-color: var(--oc-blue-6);
+}
+
+.callout.warning {
+ border-color: var(--oc-orange-6);
+}
+
+@media (prefers-color-scheme: dark) {
+ .callout {
+ background: var(--color-surface, var(--oc-gray-8));
+ color: var(--oc-gray-0);
+ }
+}
\ No newline at end of file
diff --git a/assets_bak/css/components/code.css b/assets_bak/css/components/code.css
new file mode 100644
index 0000000..affa626
--- /dev/null
+++ b/assets_bak/css/components/code.css
@@ -0,0 +1,23 @@
+/* assets/css/components/callout.css */
+
+.code-block-wrapper {
+ position: relative;
+}
+
+.copy-code-button {
+ position: absolute;
+ top: 0.5rem;
+ right: 0.5rem;
+ background: var(--oc-gray-2);
+ border: none;
+ padding: 0.3rem 0.6rem;
+ font-size: 0.8rem;
+ cursor: pointer;
+ border-radius: 4px;
+ opacity: 0.7;
+ transition: opacity 0.2s ease;
+}
+
+.copy-code-button:hover {
+ opacity: 1;
+}
\ No newline at end of file
diff --git a/assets_bak/css/components/kb.css b/assets_bak/css/components/kb.css
new file mode 100644
index 0000000..5e08efc
--- /dev/null
+++ b/assets_bak/css/components/kb.css
@@ -0,0 +1,46 @@
+/* assets/css/components/callout.css */
+
+.knowledge-base-links {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 20px;
+ justify-content: center;
+ text-align: center;
+}
+
+.kb-item {
+ background-color: var(--oc-gray-1);
+ border: 1px solid var(--oc-gray-2);
+ border-radius: 8px;
+ padding: 20px;
+ width: 300px;
+ box-shadow: 0 2px 4px var(--oc-gray-3);
+ text-align: center;
+}
+
+.kb-item h4 {
+ margin-bottom: 10px;
+ color: var(--oc-gray-8);
+}
+
+.kb-item p {
+ margin-bottom: 15px;
+ color: var(--oc-gray-5);
+}
+
+/* For internal Hugo buttons */
+.button,
+.kb-btn {
+ display: inline-block;
+ padding: 0.8rem 1.5rem;
+ background-color: var(--oc-blue-5);
+ color: var(--oc-gray-0);
+ text-decoration: none;
+ border-radius: 4px;
+ transition: background-color 0.3s ease;
+}
+
+.button:hover,
+.kb-btn:hover {
+ background-color: var(--oc-orange-5);
+}
\ No newline at end of file
diff --git a/assets_bak/css/components/note.css b/assets_bak/css/components/note.css
new file mode 100644
index 0000000..a55f7ad
--- /dev/null
+++ b/assets_bak/css/components/note.css
@@ -0,0 +1,22 @@
+/* assets/css/components/note.css */
+
+.note, .warning, .tip {
+ padding: 1rem;
+ border-left: 6px solid;
+ border-radius: 4px;
+ margin: 1rem 0;
+ font-size: 1rem;
+}
+
+.note {
+ background: var(--oc-cyan-0);
+ border-color: var(--oc-cyan-4);
+}
+.warning {
+ background: var(--oc-yellow-1);
+ border-color: var(--oc-yellow-7);
+}
+.tip {
+ background: var(--oc-teal-0);
+ border-color: var(--oc-green-4);
+}
\ No newline at end of file
diff --git a/assets_bak/css/components/tab.css b/assets_bak/css/components/tab.css
new file mode 100644
index 0000000..8da95d4
--- /dev/null
+++ b/assets_bak/css/components/tab.css
@@ -0,0 +1,58 @@
+/* assets/css/components/tab.css */
+
+/* --- Your Original Tab Button Styles --- */
+.tab-buttons {
+ display: flex;
+ gap: 10px;
+ margin-bottom: 1rem;
+}
+.tab {
+ background: var(--color-surface);
+ border: 1px solid var(--color-brand);
+ padding: 0.5rem 1rem;
+ cursor: pointer;
+}
+.tab.active {
+ background: var(--color-brand);
+ color: white;
+}
+.tab-content {
+ display: none;
+}
+.tab-content.active {
+ display: block;
+}
+
+/* --- Hugo Book Theme Tab Styles --- */
+.book-tabs {
+ display: flex;
+ flex-direction: column;
+}
+.book-tabs-label {
+ cursor: pointer;
+ display: inline-block;
+ padding: 0.5em 1em;
+ background: #f8f9fa;
+ border: 1px solid #dee2e6;
+ margin-right: 0.1em;
+ border-bottom: none;
+ /* Add slight border radius for consistency if desired: */
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+.book-tabs-toggle {
+ display: none;
+}
+.book-tabs-panel {
+ display: none;
+ padding: 1em;
+ border: 1px solid #dee2e6;
+ border-top: none;
+}
+.book-tabs-toggle:checked + .book-tabs-label + .book-tabs-panel {
+ display: block;
+}
+.book-tabs-label.active {
+ background: #e9ecef;
+ border-bottom: 1px solid #e9ecef;
+}
\ No newline at end of file
diff --git a/assets_bak/css/dropdown.css b/assets_bak/css/dropdown.css
new file mode 100644
index 0000000..dacabde
--- /dev/null
+++ b/assets_bak/css/dropdown.css
@@ -0,0 +1,58 @@
+/* assets/css/dropdown.css */
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ 4. DROPDOWN (NESTED MENUS)
+βββββββββββββββββββββββββββββββββββββββββββ*/
+.book-nav li.has-children {
+ position: relative;
+}
+.book-nav li.has-children > .book-nav--nested {
+ display: none;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ background: var(--color-surface);
+ border-top: 1px solid var(--oc-gray-3);
+ position: static; /* flows down in the list */
+ overflow: hidden;
+}
+.book-nav li.has-children:hover > .book-nav--nested {
+ display: block;
+ animation: slideDown 0.2s ease forwards;
+}
+
+.book-nav--nested {
+ list-style: none;
+ margin: 0.25rem 0 0 0;
+ padding: 0;
+}
+
+.book-nav--nested li {
+ margin: 0;
+ padding: 0;
+}
+
+.book-nav--nested li a {
+ display: block; /* full-width clickable */
+ padding: 0.5rem 1; /* small vertical padding */
+ background: transparent; /* remove button BG */
+ border-radius: 0; /* remove corners */
+ font-size: 1rem; /* slightly smaller */
+ font-weight: 600; /* semi-bold */
+ color: var(--color-text); /* same as your body text */
+ text-decoration: underline dotted var(--color-accent);
+ text-decoration-thickness: 2px;
+ text-underline-offset: 3px;
+ transition: color var(--transition-fast);
+}
+
+.book-nav--nested li a:hover {
+ color: var(--color-accent); /* your orange accent */
+ text-decoration-color: var(--color-accent);
+ background: transparent;
+}
+/* slide-down keyframes */
+@keyframes slideDown {
+ from { max-height: 0; opacity: 0; }
+ to { max-height: 500px; opacity: 1; }
+}
\ No newline at end of file
diff --git a/assets_bak/css/fonts.css b/assets_bak/css/fonts.css
new file mode 100644
index 0000000..a974dca
--- /dev/null
+++ b/assets_bak/css/fonts.css
@@ -0,0 +1,49 @@
+/* assets/css/fonts.css β Noto Sans with weights + performance tweaks */
+
+@font-face {
+ font-family: 'Noto Sans';
+ src: url('/fonts/NotoSans-Light.ttf') format('truetype');
+ font-weight: 300;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans';
+ src: url('/fonts/NotoSans-Regular.ttf') format('truetype');
+ font-weight: 400;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans';
+ src: url('/fonts/NotoSans-Medium.ttf') format('truetype');
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans';
+ src: url('/fonts/NotoSans-SemiBold.ttf') format('truetype');
+ font-weight: 600;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans';
+ src: url('/fonts/NotoSans-Bold.ttf') format('truetype');
+ font-weight: 700;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans';
+ src: url('/fonts/NotoSans-Black.ttf') format('truetype');
+ font-weight: 900;
+ font-style: normal;
+ font-display: swap;
+}
\ No newline at end of file
diff --git a/assets_bak/css/nav.css b/assets_bak/css/nav.css
new file mode 100644
index 0000000..de8b97e
--- /dev/null
+++ b/assets_bak/css/nav.css
@@ -0,0 +1,52 @@
+/* assets/css/nav.css */
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ 3. BRAND + NAV LINKS
+βββββββββββββββββββββββββββββββββββββββββββ*/
+/* Brand/title */
+.book-brand {
+ display: block;
+ text-align: center;
+ font-size: 1.25rem;
+ font-weight: bold;
+ color: var(--color-text);
+ margin-bottom: 1rem;
+ transition: color var(--transition-fast);
+}
+.book-brand:hover {
+ color: var(--color-accent);
+}
+
+/* Nav container */
+.book-nav {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ transition: margin-top 0.3s ease;
+}
+
+/* Links */
+.book-nav li a {
+ text-align: center;
+ display: block;
+ padding: 0.5rem 1rem;
+ background: var(--color-brand);
+ color: var(--color-bg);
+ text-decoration: none;
+ border-radius: 5px;
+ font-weight: 500;
+ transition: background var(--transition-fast),
+ color var(--transition-fast);
+}
+.book-nav li a:hover {
+ background: var(--color-accent);
+ color: var(--color-bg);
+}
+.book-nav li a.active {
+ border-left: 3px solid var(--color-brand);
+ background: var(--oc-gray-1);
+ padding-left: 0.5rem;
+}
diff --git a/assets_bak/css/search.css b/assets_bak/css/search.css
new file mode 100644
index 0000000..91a74d3
--- /dev/null
+++ b/assets_bak/css/search.css
@@ -0,0 +1,71 @@
+/* assets/css/search.css */
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ SEARCH BOX & RESULTS PANEL
+βββββββββββββββββββββββββββββββββββββββββββ*/
+
+/* Wrapper & stacking context */
+.book-search {
+ position: relative;
+ display: flex;
+ justify-content: center;
+ margin: 1rem 0;
+}
+
+/* Input styling */
+.book-search input {
+ width: 100%;
+ max-width: 600px;
+ padding: 0.5rem 1rem;
+ font-size: 1.25rem;
+ border: 1px solid var(--oc-gray-4);
+ border-radius: 5px;
+ background: var(--color-bg);
+ color: var(--color-text);
+ text-align: center;
+ transition: box-shadow var(--transition-fast);
+}
+.book-search input:focus {
+ outline: none;
+ box-shadow: 0 0 0 3px var(--primary);
+}
+
+/* Push menu down while `.active` */
+.book-search.active ~ .book-nav {
+ margin-top: calc((5 * 2.5rem) + 2.5rem);
+ transition: margin-top 0.3s ease;
+}
+
+/* Results dropdown (absolute, centered) */
+#search-results {
+ position: absolute;
+ top: 100%; /* just below the input */
+ left: 50%;
+ transform: translateX(-50%);
+ width: 90%;
+ max-height: calc(5 * 2.5rem);
+ margin-top: 0.5rem;
+ padding: 0;
+ list-style: none;
+ background: var(--color-bg);
+ overflow-y: auto;
+ text-align: center;
+ z-index: 100;
+}
+
+/* Individual result links */
+#search-results li {
+ margin: 0;
+}
+#search-results li a {
+ display: block;
+ padding: 0.5rem 1rem;
+ background: var(--oc-gray-0);
+ border-bottom: 1px solid var(--oc-gray-3);
+ color: var(--color-brand);
+ text-decoration: none;
+ transition: background var(--transition-fast);
+}
+#search-results li a:hover {
+ background: var(--oc-gray-1);
+}
\ No newline at end of file
diff --git a/assets_bak/css/sidebar.css b/assets_bak/css/sidebar.css
new file mode 100644
index 0000000..8194608
--- /dev/null
+++ b/assets_bak/css/sidebar.css
@@ -0,0 +1,65 @@
+/* assets/css/sidebar.css */
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ 2. TOGGLE + SIDEBAR SLIDE
+βββββββββββββββββββββββββββββββββββββββββββ*/
+/* hide the checkbox input */
+.hidden,
+#menu-control {
+ position: absolute;
+ left: -9999px;
+}
+
+/* hamburger toggle button */
+.menu-toggle {
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
+ position: fixed;
+ top: 1rem;
+ left: 0;
+ background: var(--color-brand);
+ color: #fff; /* icon stays white */
+ font-size: 1.5rem;
+ padding: 0.5rem 1rem;
+ border-radius: 0 5px 5px 0;
+ cursor: pointer;
+ z-index: 1100;
+ transition: background var(--transition-fast),
+ transform var(--transition-slow);
+}
+.menu-toggle:hover {
+ background: var(--color-accent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+}
+
+/* slide toggle icon with sidebar */
+#menu-control:checked ~ .menu-toggle {
+ transform: translateX(var(--sidebar-width));
+}
+
+/* sidebar panel */
+.book-menu {
+ position: fixed;
+ top: 0; left: 0; bottom: 0;
+ width: var(--sidebar-width);
+ background: var(--color-surface);
+ border-right: 1px solid var(--oc-gray-3);
+ padding: 2rem 1rem;
+ overflow-y: auto;
+ z-index: 1000;
+ transform: translateX(-100%);
+ transition: transform var(--transition-slow);
+}
+#menu-control:checked ~ .book-menu {
+ transform: translateX(0);
+}
+
+/* push page content over */
+.layout-wrapper { display: flex; }
+.main-frame {
+ flex-grow: 1;
+ margin-left: 0;
+ transition: margin-left var(--transition-slow);
+}
+#menu-control:checked ~ .main-frame {
+ margin-left: var(--sidebar-width);
+}
\ No newline at end of file
diff --git a/assets_bak/css/styles.css b/assets_bak/css/styles.css
new file mode 100644
index 0000000..fbeb89d
--- /dev/null
+++ b/assets_bak/css/styles.css
@@ -0,0 +1,243 @@
+/* assets/css/styles.css β layout, structure, theme */
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ VARIABLES
+βββββββββββββββββββββββββββββββββββββββββββ*/
+:root {
+ --sidebar-width: 250px;
+ --transition-fast: 0.2s ease;
+ --transition-slow: 0.3s ease;
+}
+
+/* Global reset & font */
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ font-family: 'Noto Sans', Arial, sans-serif;
+ font-size: 1.125rem; /* ~18px */
+ line-height: 1.6;
+ background: var(--gray-1);
+ color: var(--text);
+}
+
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ LAYOUT CONTAINERS
+βββββββββββββββββββββββββββββββββββββββββββ*/
+.container {
+ max-width: 960px;
+ margin: 2rem auto;
+ padding: 0 2rem;
+}
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ HEADERS
+βββββββββββββββββββββββββββββββββββββββββββ*/
+header {
+ background: var(--brand);
+ color: var(--gray-0);
+ padding: 3rem 1rem 2rem;
+ text-align: center;
+}
+header h1 {
+ font-size: 2.5rem;
+ font-weight: 700;
+ display: inline-flex;
+ align-items: center;
+ gap: 1rem;
+}
+header p {
+ font-size: 1.2rem;
+ margin-top: 0.5rem;
+}
+
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ GLOBAL FONT & BODY TEXT SPACING
+βββββββββββββββββββββββββββββββββββββββββββ*/
+html, body, .book-nav li a, #search-results li a, p, h1, h2, h3, h4 {
+ font-family: 'Noto Sans', Arial, sans-serif !important;
+}
+
+
+
+p {
+ margin-bottom: 1rem;
+}
+
+body {
+ font-family: 'Noto Sans', Arial, sans-serif;
+ font-weight: 400;
+ margin: 0;
+ padding: 0;
+ background: var(--oc-gray-1);
+ color: var(--color-text);;
+}
+
+/* 4) Ensure container sections (if you wrap each in .container) stay centered */
+.container > .section {
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 960px;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Header */
+header {
+ background: var(--color-brand);;
+ color: var(--color-bg);
+ padding: 3rem 1rem 2rem;
+ text-align: center;
+}
+
+header h1 {
+ font-size: 2.5rem;
+ margin: 0;
+ font-weight: 700;
+ color: var(--color-bg); /* β
this ensures it's white on green */
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 1rem;
+}
+
+header p {
+ font-size: 1.2rem;
+ margin: 0.5rem 0 0;
+}
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ CARDS (.section)
+βββββββββββββββββββββββββββββββββββββββββββ*/
+.section {
+ width: 100%;
+ max-width: 960px;
+ margin: 2rem auto;
+ padding: 2rem 1.5rem;
+ background: var(--oc-gray-0);
+ border-radius: 1rem;
+ box-shadow:
+ /* subtle ambient shadow */
+ 0 1px 3px rgba(0,0,0,0.08),
+ /* slightly stronger underlay */
+ 0 4px 6px rgba(0,0,0,0.04);
+ transition: box-shadow var(--transition-fast);
+ text-align: center;
+}
+
+.section:hover {
+ box-shadow:
+ 0 4px 8px rgba(0,0,0,0.12),
+ 0 8px 16px rgba(0,0,0,0.08);
+}
+
+.section h2 {
+ font-size: 1.8rem;
+ margin-bottom: 1rem;
+ padding-bottom: 0.5rem;
+ color: var(--color-brand);
+ font-size: 1.8rem;
+ font-weight: 600;
+ position: relative;
+ display: inline-block;
+ padding-right: 1rem;
+}
+
+.section h2::after {
+ content: "";
+ position: absolute;
+ bottom: 0rem;
+ left: 0;
+ width: 3rem;
+ height: 0.25rem;
+ background: var(--color-accent);
+ border-radius: 2px;
+}
+
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ BUTTONS & LINKS
+βββββββββββββββββββββββββββββββββββββββββββ*/
+.btn {
+ display: inline-block;
+ padding: 0.8rem 1.5rem;
+ background: var(--color-brand);;
+ color: var(--color-bg);
+ text-decoration: none;
+ border-radius: 5px;
+ font-weight: 500;
+ transition: background var(--transition-fast);
+ text-align: center;
+}
+
+.btn:hover {
+ background: var(--color-accent);
+}
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ FOOTER
+βββββββββββββββββββββββββββββββββββββββββββ*/
+footer {
+ text-align: center;
+ padding: 1rem 0;
+ background: var(--color-brand);;
+ color: var(--color-bg);
+}
+
+
+/*βββββββββββββββββββββββββββββββββββββββββββ
+ MEDIA QUERIES
+βββββββββββββββββββββββββββββββββββββββββββ*/
+@media (max-width: 600px) {
+ header h1 { font-size: 1.8rem; }
+ header p { font-size: 1rem; }
+ .btn { width: 100%; text-align: center; }
+}
+
+
+/* Logo */
+.logo-link {
+ text-decoration: none;
+ display: inline-block;
+ margin-right: 10px;
+}
+
+.logo-image {
+ vertical-align: middle;
+ width: 128px;
+ height: 128px;
+}
+
+/* Animation */
+.logo-spin {
+ width: 96px;
+ margin-top: 2rem;
+ animation: spin 10s linear infinite;
+ transform-origin: center;
+}
+
+@keyframes spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(-360deg); }
+}
+
+/* ASCII Art Block */
+.ascii-art {
+ font-family: "Courier New", Courier, monospace;
+ background-color: #f0f0f0;
+ padding: 15px;
+ border: 1px solid #ddd;
+ display: inline-block;
+ margin-top: 20px;
+ font-size: 14px;
+ line-height: 1.4;
+ white-space: pre;
+}
diff --git a/assets_bak/css/tokens.css b/assets_bak/css/tokens.css
new file mode 100644
index 0000000..0e4de99
--- /dev/null
+++ b/assets_bak/css/tokens.css
@@ -0,0 +1,21 @@
+/* assets/css/tokens.css β semantic layer on top of Open Color */
+
+:root {
+ /* Enforce light mode appearance */
+ color-scheme: light;
+
+ /* Semantic color tokens (light only) */
+ --color-bg: var(--oc-gray-0);
+ --color-surface: var(--oc-gray-1);
+ --color-text: var(--oc-gray-9);
+ --color-brand: var(--oc-teal-9); /* consistent brand */
+ --color-brand-hover: var(--oc-teal-7);
+ --color-accent: var(--oc-orange-5);
+
+ /* Shorthand aliases (for legacy support) */
+ --primary: var(--color-brand);
+ --primary-hover: var(--color-brand-hover);
+ --accent: var(--color-accent);
+ --bg: var(--color-bg);
+ --text: var(--color-text);
+}
\ No newline at end of file
diff --git a/assets_bak/css/top_nav.css b/assets_bak/css/top_nav.css
new file mode 100644
index 0000000..9e50a61
--- /dev/null
+++ b/assets_bak/css/top_nav.css
@@ -0,0 +1,31 @@
+/* assets/css/top_nav.css */
+
+.top-nav {
+ position: sticky;
+ top: 0;
+ background: white;
+ border-bottom: 1px solid #dee2e6;
+ z-index: 1000;
+ padding: 0.5rem 1rem;
+}
+
+.top-nav ul {
+ display: flex;
+ gap: 1rem;
+ justify-content: center;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+.top-nav a {
+ text-decoration: none;
+ color: var(--text, #222); /* fallback color for safety */
+ font-weight: 500;
+}
+@media (max-width: 600px) {
+ .top-nav ul {
+ gap: 0.5rem;
+ font-size: 0.95rem;
+ flex-wrap: wrap;
+ }
+}
\ No newline at end of file
diff --git a/assets/openColour/open-color.css b/assets_bak/openColour/open-color.css
similarity index 99%
rename from assets/openColour/open-color.css
rename to assets_bak/openColour/open-color.css
index 5152f87..6cbb925 100644
--- a/assets/openColour/open-color.css
+++ b/assets_bak/openColour/open-color.css
@@ -1,3 +1,5 @@
+/* assets/openColour/open-color.css */
+
/*
*
* π π’ π π’ π₯
@@ -340,4 +342,4 @@
--oc-orange-9: #d9480f;
--oc-orange-9-rgb: 217, 72, 15;
-}
+}
\ No newline at end of file
diff --git a/config.toml b/config.toml
index 315dd55..c37278b 100644
--- a/config.toml
+++ b/config.toml
@@ -1,7 +1,6 @@
baseURL = 'https://cybermonkey.net.au'
languageCode = 'en-us'
title = 'Code Monkey Cybersecurity'
-theme = "" # (Optional β only if you're using a theme)
# Optional: better URLs
canonifyURLs = true
@@ -15,27 +14,73 @@ buildDrafts = false
buildFuture = false
buildExpired = false
+[module]
+[[module.imports]]
+ path = "github.com/alex-shpak/hugo-book"
+
# Site-wide metadata
[params]
author = "Henry Oliver"
- description = "Cybersecurity with Humans. Managed XDR, backup, DevSecOps, and open source tools from Fremantle."
+ description = "Cybersecurity. With Humans.. Managed XDR, backup, DevSecOps, and open source tools from Fremantle."
keywords = ["Cybersecurity", "XDR", "SIEM", "Penetration Testing", "Backup", "Open Source", "Australia"]
contact_email = "main@cybermonkey.net.au"
umami_script = "https://u.cybermonkey.dev/script.js"
umami_site_id = "970ff30a-ab5d-4c66-8f77-55cafc76083c"
assetDir = "assets"
+ BookToC = true
+
+[languages]
+[languages.en]
+ languageName = 'English'
+ contentDir = 'content'
+ weight = 1
+
+[menu]
+[[menu.after]]
+name = "Github"
+url = "https://github.com/alex-shpak/hugo-book"
+weight = 10
+
+[[menu.after]]
+name = "Hugo Themes"
+url = "https://themes.gohugo.io/themes/hugo-book/"
+weight = 20
+
+[sitemap]
+ changefreq = "monthly"
+ priority = 0.5
+ filename = "sitemap.xml"
# Optional: social links
[social]
github = "https://github.com/CodeMonkeyCybersecurity"
facebook = "https://facebook.com/codemonkeycyber"
- twitter = "https://x.com/codemonkeycyber"
+ instagram = "..."
+ linkedin = "..."
+
+[outputs]
+home = ["HTML", "RSS", "JSON"]
+
+[outputFormats.Robots]
+mediaType = "text/plain"
+baseName = "robots"
+isPlainText = true
+notAlternative = true
+
+[outputFormats.JSON]
+mediaType = "application/json"
+baseName = "index"
+isPlainText = true
# Optional: default settings for content
[markup]
[markup.goldmark.renderer]
- unsafe = true # Allow inline HTML in markdown
+ unsafe = true
+ [markup.goldmark.extensions]
+ attribute = true
+ [markup.tableOfContents]
+ startLevel = 1
# Optional: default frontmatter for new pages
[frontmatter]
- date = ["lastmod", ":git", "date"]
+ date = ["lastmod", ":git", "date"]
\ No newline at end of file
diff --git a/content/_index.md b/content/_index.md
new file mode 100644
index 0000000..85e021f
--- /dev/null
+++ b/content/_index.md
@@ -0,0 +1,65 @@
+---
+title: "Code Monkey Cybersecurity"
+description: "Cybersecurity. With Humans"
+---
+
+## Code Monkey Cybersecurity
+
+**Human-first security for those who need it most.**
+
+---
+
+Weβre building a new kind of cybersecurity platform: one that empowers small teams, nonprofits, high-impact organizations, and anyone left out by βbig securityβ vendors.
+
+## π¦Ύ What We Do
+
+- **Managed XDR & SIEM**
+ Real-time, actionable alerts. No jargon. No noise. Powered by open source, curated by humans.
+
+- **Delphi Platform**
+ Our flagship: a hardened, multi-tenant XDR & SIEM built on [Wazuh](https://wazuh.com/), [OpenSearch](https://opensearch.org/), and open identity tools.
+ - [Learn more about Delphi](/delphi/)
+
+- **Self-Hosted & Fully Managed**
+ Run it yourself, or let us handle deployment, monitoring, and updates. Choose the level of control you want.
+
+- **Backup & Recovery**
+ Enterprise-grade data protectionβwithout enterprise headaches.
+
+## π Who We Help
+
+- **Small businesses** who want real-world security, not checkbox compliance.
+- **NGOs & community orgs** who value privacy and transparency.
+- **MSPs** who need tenant-aware, white-label security tooling.
+- **Anyone** who wants more trust, less BS.
+
+---
+
+## π οΈ Why Code Monkey?
+
+- **Transparent, ethical, open source** β every major component is audit-friendly and community-driven.
+- **No black boxes, no lock-in** β your data, your security, your rules.
+- **Real support by real people** β security with empathy, not bots.
+
+## π Our Promise
+
+We protect people, not just machines. Our mission is to bring **affordable, trustworthy cybersecurity** to those who need it mostβno matter your size or resources.
+
+---
+
+## Get Started
+
+- [Pricing & Plans](/pricing/)
+- [Security & Privacy](/security/)
+- [Contact Us](/contact/)
+- [Knowledge Base](https://wiki.cybermonkey.net.au) (Athena)
+
+Or jump right in with [Delphi](https://delphi.cybermonkey.net.au) (Beta)!
+
+---
+
+> **Code Monkey Cybersecurity:**
+> Security, with humans.
+> Serving Fremantle, WA and beyond.
+
+---
diff --git a/content/docs/_index.md b/content/docs/_index.md
new file mode 100644
index 0000000..85e021f
--- /dev/null
+++ b/content/docs/_index.md
@@ -0,0 +1,65 @@
+---
+title: "Code Monkey Cybersecurity"
+description: "Cybersecurity. With Humans"
+---
+
+## Code Monkey Cybersecurity
+
+**Human-first security for those who need it most.**
+
+---
+
+Weβre building a new kind of cybersecurity platform: one that empowers small teams, nonprofits, high-impact organizations, and anyone left out by βbig securityβ vendors.
+
+## π¦Ύ What We Do
+
+- **Managed XDR & SIEM**
+ Real-time, actionable alerts. No jargon. No noise. Powered by open source, curated by humans.
+
+- **Delphi Platform**
+ Our flagship: a hardened, multi-tenant XDR & SIEM built on [Wazuh](https://wazuh.com/), [OpenSearch](https://opensearch.org/), and open identity tools.
+ - [Learn more about Delphi](/delphi/)
+
+- **Self-Hosted & Fully Managed**
+ Run it yourself, or let us handle deployment, monitoring, and updates. Choose the level of control you want.
+
+- **Backup & Recovery**
+ Enterprise-grade data protectionβwithout enterprise headaches.
+
+## π Who We Help
+
+- **Small businesses** who want real-world security, not checkbox compliance.
+- **NGOs & community orgs** who value privacy and transparency.
+- **MSPs** who need tenant-aware, white-label security tooling.
+- **Anyone** who wants more trust, less BS.
+
+---
+
+## π οΈ Why Code Monkey?
+
+- **Transparent, ethical, open source** β every major component is audit-friendly and community-driven.
+- **No black boxes, no lock-in** β your data, your security, your rules.
+- **Real support by real people** β security with empathy, not bots.
+
+## π Our Promise
+
+We protect people, not just machines. Our mission is to bring **affordable, trustworthy cybersecurity** to those who need it mostβno matter your size or resources.
+
+---
+
+## Get Started
+
+- [Pricing & Plans](/pricing/)
+- [Security & Privacy](/security/)
+- [Contact Us](/contact/)
+- [Knowledge Base](https://wiki.cybermonkey.net.au) (Athena)
+
+Or jump right in with [Delphi](https://delphi.cybermonkey.net.au) (Beta)!
+
+---
+
+> **Code Monkey Cybersecurity:**
+> Security, with humans.
+> Serving Fremantle, WA and beyond.
+
+---
diff --git a/content/docs/contact/_index.md b/content/docs/contact/_index.md
new file mode 100644
index 0000000..01663b3
--- /dev/null
+++ b/content/docs/contact/_index.md
@@ -0,0 +1,22 @@
+---
+title: "Contact Us"
+---
+
+## Contact Us
+
+Email: [main@cybermonkey.net.au](mailto:main@cybermonkey.net.au)
+
+Phone: (+61) 0432 038 310
+
+Location: Fremantle, WA
+
+ABN: 77 177 673 061
+
+Part of Code Monkey Technologies
+
+## Public Key
+
+Trust, but verify:
+
+ Download
+ View
diff --git a/content/docs/delphi/_index.md b/content/docs/delphi/_index.md
new file mode 100644
index 0000000..7b17205
--- /dev/null
+++ b/content/docs/delphi/_index.md
@@ -0,0 +1,55 @@
+---
+title: "Delphi"
+---
+
+## What Is Delphi?
+
+**Delphi** is Code Monkey Cybersecurityβs managed **XDR** (Extended Detection and Response) and **SIEM** (Security Information and Event Management) platform β built for real-world security, not checkbox compliance.
+
+At its core, Delphi helps you detect threats, understand what they mean, and act fast. It's built on **Wazuh**, a trusted open-source platform used by security teams worldwide β but weβve hardened it, simplified it, and layered on human-first support.
+
+## Key Features
+
+**Real-Time Threat Detection**
+ Continuous monitoring of endpoints, servers, cloud resources, and more β with detection rules tailored for small business and nonprofit environments.
+
+**Human-Curated Alerts**
+ We donβt just spam you with logs. Each alert is reviewed, categorized, and explained in plain English β with recommended next steps.
+
+**Custom Dashboards & Reports**
+ Gain visibility into your security posture with dashboards tailored to your industry and assets.
+
+**Self-Hosted or Fully Managed**
+ Run it yourself with our open-source scripts, or let us handle everything β deployment, maintenance, tuning, and updates.
+
+**Multi-Tenant Support (Beta)**
+ Isolate customer environments while maintaining central visibility β ideal for MSPs or multi-org setups.
+
+## Built on Proven Tools
+
+Delphi integrates and hardens:
+**Wazuh** for SIEM/XDR core
+**OpenSearch** for log analytics and dashboards
+**Keycloak** for secure identity and access
+**Vault** for secret and token management
+**EOS** and **Hecate** for automated deployment, backup, and reverse proxy setup
+
+## Who's It For?
+
+Small businesses who canβt afford a SOC but still need security.
+Nonprofits and community orgs who value privacy and transparency.
+Managed service providers (MSPs) who want a white-labeled, tenant-aware solution.
+Cybersecurity teams who want full control without full overhead.
+
+## Coming Soon
+
+Self-service agent enrollment
+Automatic remediation for common threats
+Secure file collection (e.g. forensic triage)
+Chatbot-integrated alert explanations (LLM-powered)
+
+## Try Delphi
+
+Want to test it yourself?
+Visit the live beta: [delphi.cybermonkey.net.au](https://delphi.cybermonkey.net.au)
+Or head to the [Athena Knowledge Base](https://wiki.cybermonkey.net.au/Delphi) for setup guides.
diff --git a/content/docs/delphi/delphi-notify/_index.md b/content/docs/delphi/delphi-notify/_index.md
new file mode 100644
index 0000000..e57af75
--- /dev/null
+++ b/content/docs/delphi/delphi-notify/_index.md
@@ -0,0 +1,7 @@
+---
+title: "Delphi Notify"
+---
+
+### Delphi Notify
+
+Welcome to Delphi Notify, our Wazuh-powered XDR/SIEM platform.
diff --git a/content/docs/delphi/delphi-notify/use-cases.md b/content/docs/delphi/delphi-notify/use-cases.md
new file mode 100644
index 0000000..6c6d25e
--- /dev/null
+++ b/content/docs/delphi/delphi-notify/use-cases.md
@@ -0,0 +1,17 @@
+---
+title: "Example use cases"
+---
+
+### Example use cases
+
+### Small IT Team
+
+Receive critical alerts in Mattermost only after a human has confirmed they're not false positives.
+
+### NGO Field Ops
+
+Route verified alerts to satellite-connected email devices or mobile phones to avoid noisy flapping.
+
+### MSSP
+
+Allow Tier 1 analysts to verify and forward only the most relevant security events.
diff --git a/content/docs/pricing/_index.md b/content/docs/pricing/_index.md
new file mode 100644
index 0000000..63036af
--- /dev/null
+++ b/content/docs/pricing/_index.md
@@ -0,0 +1,7 @@
+---
+title: "Pricing"
+---
+
+## Pricing
+
+Our pricing guideβ¦
diff --git a/content/docs/pricing/roadmap.md b/content/docs/pricing/roadmap.md
new file mode 100644
index 0000000..d1870d0
--- /dev/null
+++ b/content/docs/pricing/roadmap.md
@@ -0,0 +1,21 @@
+---
+title: "Roadmap"
+---
+
+## Roadmap
+
+### Now: Delphi Notify (MVP)
+
+Email, Telegram, Mattermost output
+Wazuh and Suricata input
+Verification UI
+
+### Next: Delphi Notify Teams
+
+Audit log, alert history
+Team-based routing
+
+### Future: Delphi Full
+
+Dashboard, playbooks, XDR
+Tenant isolation and alert enrichment
diff --git a/content/docs/security/_index.md b/content/docs/security/_index.md
new file mode 100644
index 0000000..12df279
--- /dev/null
+++ b/content/docs/security/_index.md
@@ -0,0 +1,11 @@
+---
+title: "Security"
+description: "Learn about our security measures."
+---
+Weβd love to hear from you.
+
+Email: [main@cybermonkey.net.au](mailto:main@cybermonkey.net.au)
+
+Signal: Ask for our public key
+
+GitHub: [CodeMonkeyCybersecurity](https://github.com/CodeMonkeyCybersecurity)
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..f762f22
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module github.com/CodeMonkeyCybersecurity/helen
+
+go 1.24.3
+
+require github.com/alex-shpak/hugo-book v0.0.0-20250527212653-0c86b5d29dcd // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..bc2de8a
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
+github.com/alex-shpak/hugo-book v0.0.0-20250527212653-0c86b5d29dcd h1:H0AFKepaiMlFj9l/utWLK9pii3LGAdHOZHclHJs49wM=
+github.com/alex-shpak/hugo-book v0.0.0-20250527212653-0c86b5d29dcd/go.mod h1:L4NMyzbn15fpLIpmmtDg9ZFFyTZzw87/lk7M2bMQ7ds=
diff --git a/layouts/404.html b/layouts/404.html
new file mode 100644
index 0000000..909430e
--- /dev/null
+++ b/layouts/404.html
@@ -0,0 +1,34 @@
+
+
+
+
+ {{ partial "docs/html-head" . }}
+ {{ partial "docs/inject/head" . }}
+
+
+
+
+
+
+
+
404
+
Page Not Found
+
+
+
+
+ {{ partial "docs/inject/body" . }}
+
+
+
diff --git a/layouts/_default/_markup/render-heading.html b/layouts/_default/_markup/render-heading.html
new file mode 100644
index 0000000..5439d20
--- /dev/null
+++ b/layouts/_default/_markup/render-heading.html
@@ -0,0 +1,4 @@
+
+ {{ .Text | safeHTML }}
+ #
+
diff --git a/layouts/_default/_markup/render-image.html b/layouts/_default/_markup/render-image.html
new file mode 100644
index 0000000..148cbaf
--- /dev/null
+++ b/layouts/_default/_markup/render-image.html
@@ -0,0 +1,19 @@
+{{- if .Page.Site.Params.BookPortableLinks -}}
+ {{- template "portable-image" . -}}
+{{- else -}}
+
+{{- end -}}
+
+{{- define "portable-image" -}}
+ {{- $isRemote := or (in .Destination "://") (strings.HasPrefix .Destination "//") }}
+ {{- if not $isRemote }}
+ {{- $path := print .Page.File.Dir .Destination }}
+ {{- if strings.HasPrefix .Destination "/" }}
+ {{- $path = print "/static" .Destination }}
+ {{- end }}
+ {{- if not (fileExists $path) }}
+ {{- warnf "Image '%s' not found in '%s'" .Destination .Page.File }}
+ {{- end }}
+ {{- end }}
+
+{{- end -}}
diff --git a/layouts/_default/_markup/render-link.html b/layouts/_default/_markup/render-link.html
new file mode 100644
index 0000000..288d81c
--- /dev/null
+++ b/layouts/_default/_markup/render-link.html
@@ -0,0 +1,29 @@
+{{- if .Page.Site.Params.BookPortableLinks -}}
+ {{- template "portable-link" . -}}
+{{- else -}}
+ {{ .Text | safeHTML }}
+{{- end -}}
+
+{{- define "portable-link" -}}
+ {{- $destination := .Destination }}
+ {{- $isRemote := or (in .Destination ":") (strings.HasPrefix .Destination "//") }}
+ {{- $isFragment := strings.HasPrefix .Destination "#" }}
+ {{- if and (not $isRemote) (not $isFragment) }}
+ {{- $url := urls.Parse .Destination }}
+ {{- $path := strings.TrimSuffix "/_index.md" $url.Path }}
+ {{- $path = strings.TrimSuffix "/_index" $path }}
+ {{- $path = strings.TrimSuffix ".md" $path }}
+ {{- $page := .Page.GetPage $path }}
+ {{- if $page }}
+ {{- $destination = $page.RelPermalink }}
+ {{- if $url.Fragment }}
+ {{- $destination = print $destination "#" $url.Fragment }}
+ {{- end }}
+ {{- else if fileExists (print .Page.File.Dir .Destination) }}
+
+ {{- else -}}
+ {{- warnf "Page '%s' not found in '%s'" .Destination .Page.File }}
+ {{- end }}
+ {{- end }}
+ {{ .Text | safeHTML }}
+{{- end -}}
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
index 23165dd..a6c4c07 100644
--- a/layouts/_default/baseof.html
+++ b/layouts/_default/baseof.html
@@ -1,16 +1,83 @@
-
+
- {{ partial "head.html" . }}
+ {{ partial "docs/html-head" . }}
+ {{ partial "docs/inject/head" . }}
-
- {{ partial "header.html" . }}
- {{ partial "nav.html" . }}
+
+
+
+
+
-
- {{ block "main" . }}{{ end }}
+
+
+
+ {{ partial "docs/inject/content-before" . }}
+ {{ template "main" . }}
+ {{ partial "docs/inject/content-after" . }}
+
+
+
+ {{ template "comments" . }}
+
+
+
+
+ {{ if default true (default .Site.Params.BookToC .Params.BookToC) }}
+
+ {{ end }}
- {{ partial "footer.html" . }}
+ {{ partial "docs/inject/body" . }}
-
\ No newline at end of file
+
+
+{{ define "menu" }}
+ {{ partial "docs/menu" . }}
+{{ end }}
+
+{{ define "header" }}
+ {{ partial "docs/header" . }}
+
+ {{ if default true (default .Site.Params.BookToC .Params.BookToC) }}
+
+ {{ template "toc" . }}
+
+ {{ end }}
+{{ end }}
+
+{{ define "footer" }}
+ {{ partial "docs/footer" . }}
+{{ end }}
+
+{{ define "comments" }}
+ {{ if and .Content (default true (default .Site.Params.BookComments .Params.BookComments)) }}
+
+ {{ end }}
+{{ end }}
+
+{{ define "main" }}
+
+ {{- .Content -}}
+
+{{ end }}
+
+{{ define "toc" }}
+ {{ partial "docs/toc" . }}
+{{ end }}
diff --git a/layouts/_default/list.html b/layouts/_default/list.html
new file mode 100644
index 0000000..0dc8b68
--- /dev/null
+++ b/layouts/_default/list.html
@@ -0,0 +1 @@
+{{ define "dummy" }}{{ end }}
diff --git a/layouts/_default/single.html b/layouts/_default/single.html
new file mode 100644
index 0000000..0dc8b68
--- /dev/null
+++ b/layouts/_default/single.html
@@ -0,0 +1 @@
+{{ define "dummy" }}{{ end }}
diff --git a/layouts/page/single.html b/layouts/page/single.html
deleted file mode 100644
index 3b13742..0000000
--- a/layouts/page/single.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{{ define "main" }}
-
- {{ .Title }}
- {{ .Content }}
-
-{{ end }}
diff --git a/layouts/partials/docs/brand.html b/layouts/partials/docs/brand.html
new file mode 100644
index 0000000..fa7f415
--- /dev/null
+++ b/layouts/partials/docs/brand.html
@@ -0,0 +1,8 @@
+
diff --git a/layouts/partials/docs/comments.html b/layouts/partials/docs/comments.html
new file mode 100644
index 0000000..59c5f22
--- /dev/null
+++ b/layouts/partials/docs/comments.html
@@ -0,0 +1,2 @@
+
+{{ template "_internal/disqus.html" . }}
diff --git a/layouts/partials/docs/date.html b/layouts/partials/docs/date.html
new file mode 100644
index 0000000..8c75361
--- /dev/null
+++ b/layouts/partials/docs/date.html
@@ -0,0 +1,6 @@
+
+{{- $format := default "January 2, 2006" .Format -}}
+{{- return (time.Format $format .Date) -}}
diff --git a/layouts/partials/docs/footer.html b/layouts/partials/docs/footer.html
new file mode 100644
index 0000000..77e96d8
--- /dev/null
+++ b/layouts/partials/docs/footer.html
@@ -0,0 +1,27 @@
+
+
+{{ if and .GitInfo .Site.Params.BookRepo }}
+
+ {{- $date := partial "docs/date" (dict "Date" .GitInfo.AuthorDate.Local "Format" .Site.Params.BookDateFormat) -}}
+
+
+ {{ $date }}
+
+
+{{ end }}
+
+{{ if and .File .Site.Params.BookRepo .Site.Params.BookEditPath }}
+
+{{ end }}
+
+
+
+{{ $script := resources.Get "clipboard.js" | resources.Minify }}
+{{ with $script.Content }}
+
+{{ end }}
diff --git a/layouts/partials/docs/header.html b/layouts/partials/docs/header.html
new file mode 100644
index 0000000..646b8ff
--- /dev/null
+++ b/layouts/partials/docs/header.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
{{ partial "docs/title" . }}
+
+
+ {{ if default true (default .Site.Params.BookToC .Params.BookToC) }}
+
+ {{ end }}
+
+
diff --git a/layouts/partials/docs/html-head-favicon.html b/layouts/partials/docs/html-head-favicon.html
new file mode 100644
index 0000000..8278050
--- /dev/null
+++ b/layouts/partials/docs/html-head-favicon.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/layouts/partials/docs/html-head-title.html b/layouts/partials/docs/html-head-title.html
new file mode 100644
index 0000000..49a109d
--- /dev/null
+++ b/layouts/partials/docs/html-head-title.html
@@ -0,0 +1 @@
+{{ partial "docs/title" . }} | {{ .Site.Title -}}
diff --git a/layouts/partials/docs/html-head.html b/layouts/partials/docs/html-head.html
new file mode 100644
index 0000000..6a6d0ec
--- /dev/null
+++ b/layouts/partials/docs/html-head.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+{{- with .Page.Params.BookHref -}}
+
+{{- end -}}
+
+{{- template "_internal/opengraph.html" . -}}
+
+{{ partial "docs/html-head-title" . }}
+{{ partial "docs/html-head-favicon" . }}
+
+{{- $manifest := resources.Get "manifest.json" | resources.ExecuteAsTemplate "manifest.json" . }}
+
+
+
+{{- range .Translations }}
+
+{{- end -}}
+
+
+{{- $styles := resources.Get "book.scss" | resources.ExecuteAsTemplate "book.scss" . | css.Sass | resources.Minify | resources.Fingerprint }}
+
+{{- if default true .Site.Params.BookSearch -}}
+ {{- $searchJSFile := printf "%s.search.js" .Language.Lang }}
+ {{- $searchJS := resources.Get "search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Minify | resources.Fingerprint }}
+
+
+{{ end -}}
+
+{{- if .Site.Params.BookServiceWorker -}}
+ {{- $swJS := resources.Get "sw-register.js" | resources.ExecuteAsTemplate "sw.js" . | resources.Minify | resources.Fingerprint }}
+
+{{ end -}}
+
+{{- template "_internal/google_analytics.html" . -}}
+
+
+{{- with .OutputFormats.Get "rss" -}}
+ {{ printf ` ` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
+{{ end -}}
+
+{{ "" | safeHTML }}
+
+{{- define "integrity" -}}
+ {{- if (urls.Parse .Permalink).Host -}}
+ integrity="{{ .Data.Integrity }}" crossorigin="anonymous"
+ {{- end -}}
+{{- end -}}
diff --git a/layouts/partials/docs/inject/body.html b/layouts/partials/docs/inject/body.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/inject/content-after.html b/layouts/partials/docs/inject/content-after.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/inject/content-before.html b/layouts/partials/docs/inject/content-before.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/inject/footer.html b/layouts/partials/docs/inject/footer.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/inject/head.html b/layouts/partials/docs/inject/head.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/inject/menu-after.html b/layouts/partials/docs/inject/menu-after.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/inject/menu-before.html b/layouts/partials/docs/inject/menu-before.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/inject/toc-after.html b/layouts/partials/docs/inject/toc-after.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/inject/toc-before.html b/layouts/partials/docs/inject/toc-before.html
new file mode 100644
index 0000000..e69de29
diff --git a/layouts/partials/docs/languages.html b/layouts/partials/docs/languages.html
new file mode 100644
index 0000000..51aabdd
--- /dev/null
+++ b/layouts/partials/docs/languages.html
@@ -0,0 +1,33 @@
+
+{{ $bookTranslatedOnly := default false .Site.Params.BookTranslatedOnly }}
+{{ $translations := dict }}
+{{ if (eq $bookTranslatedOnly false ) }}
+ {{ range .Site.Home.Translations }}
+ {{ $translations = merge $translations (dict .Language.Lang .) }}
+ {{ end }}
+{{ end }}
+{{ range .Translations }}
+ {{ $translations = merge $translations (dict .Language.Lang .) }}
+{{ end }}
+
+
diff --git a/layouts/partials/docs/links/commit.html b/layouts/partials/docs/links/commit.html
new file mode 100644
index 0000000..8ab9334
--- /dev/null
+++ b/layouts/partials/docs/links/commit.html
@@ -0,0 +1,2 @@
+{{- $commitPath := default "commit" .Site.Params.BookCommitPath -}}
+{{- .Site.Params.BookRepo }}/{{ $commitPath }}/{{ .GitInfo.Hash -}}
\ No newline at end of file
diff --git a/layouts/partials/docs/links/edit.html b/layouts/partials/docs/links/edit.html
new file mode 100644
index 0000000..920affa
--- /dev/null
+++ b/layouts/partials/docs/links/edit.html
@@ -0,0 +1,2 @@
+{{- $bookFilePath := (strings.TrimPrefix hugo.WorkingDir .Page.File.Filename | path.Join) -}}
+{{- .Site.Params.BookRepo }}/{{ .Site.Params.BookEditPath }}{{ ($bookFilePath) -}}
\ No newline at end of file
diff --git a/layouts/partials/docs/menu-filetree.html b/layouts/partials/docs/menu-filetree.html
new file mode 100644
index 0000000..1494588
--- /dev/null
+++ b/layouts/partials/docs/menu-filetree.html
@@ -0,0 +1,49 @@
+{{ $bookSection := default "docs" .Site.Params.BookSection }}
+{{ if eq $bookSection "*" }}
+ {{ $bookSection = "/" }}{{/* Backward compatibility */}}
+{{ end }}
+
+{{ with .Site.GetPage $bookSection }}
+ {{ template "book-section-children" (dict "Section" . "CurrentPage" $) }}
+{{ end }}
+
+{{ define "book-section-children" }}{{/* (dict "Section" .Section "CurrentPage" .CurrentPage) */}}
+
+ {{ range (where .Section.Pages "Params.bookHidden" "ne" true) }}
+ {{ if .IsSection }}
+
+ {{ template "book-page-link" (dict "Page" . "CurrentPage" $.CurrentPage) }}
+ {{ template "book-section-children" (dict "Section" . "CurrentPage" $.CurrentPage) }}
+
+ {{ else if and .IsPage .Content }}
+
+ {{ template "book-page-link" (dict "Page" . "CurrentPage" $.CurrentPage) }}
+
+ {{ end }}
+ {{ end }}
+
+{{ end }}
+
+{{ define "book-page-link" }}{{/* (dict "Page" .Page "CurrentPage" .CurrentPage) */}}
+ {{ $current := eq .CurrentPage .Page }}
+ {{ $ancestor := .Page.IsAncestor .CurrentPage }}
+
+ {{ if .Page.Params.BookCollapseSection }}
+
+
+
+ {{- partial "docs/title" .Page -}}
+
+
+ {{ else if .Page.Params.BookHref }}
+
+ {{- partial "docs/title" .Page -}}
+
+ {{ else if .Page.Content }}
+
+ {{- partial "docs/title" .Page -}}
+
+ {{ else }}
+ {{- partial "docs/title" .Page -}}
+ {{ end }}
+{{ end }}
diff --git a/layouts/partials/docs/menu-hugo.html b/layouts/partials/docs/menu-hugo.html
new file mode 100644
index 0000000..5f01be0
--- /dev/null
+++ b/layouts/partials/docs/menu-hugo.html
@@ -0,0 +1,28 @@
+
+{{ if . }}
+ {{ template "book-menu-hugo" . }}
+{{ end }}
+
+{{ define "book-menu-hugo" }}
+
+{{ end }}
diff --git a/layouts/partials/docs/menu.html b/layouts/partials/docs/menu.html
new file mode 100644
index 0000000..dbb2e49
--- /dev/null
+++ b/layouts/partials/docs/menu.html
@@ -0,0 +1,21 @@
+
+{{ partial "docs/brand" . }}
+{{ partial "docs/search" . }}
+{{ if hugo.IsMultilingual }}
+ {{ partial "docs/languages" . }}
+{{ end }}
+
+{{ partial "docs/inject/menu-before" . }}
+{{ partial "docs/menu-hugo" .Site.Menus.before }}
+
+{{ partial "docs/menu-filetree" . }}
+
+{{ partial "docs/menu-hugo" .Site.Menus.after }}
+{{ partial "docs/inject/menu-after" . }}
+
+
+
+{{ $script := resources.Get "menu-reset.js" | resources.Minify }}
+{{ with $script.Content }}
+
+{{ end }}
diff --git a/layouts/partials/docs/post-meta.html b/layouts/partials/docs/post-meta.html
new file mode 100644
index 0000000..457e2c0
--- /dev/null
+++ b/layouts/partials/docs/post-meta.html
@@ -0,0 +1,16 @@
+{{ with .Date }}
+
+
+
{{ partial "docs/date" (dict "Date" . "Format" $.Site.Params.BookDateFormat) }}
+
+{{ end }}
+
+{{ range $taxonomy, $_ := .Site.Taxonomies }}
+ {{ with $terms := $.GetTerms $taxonomy }}
+
+ {{ range $n, $term := $terms }}{{ if $n }}, {{ end }}
+
{{ $term.Title }}
+ {{- end }}
+
+ {{ end }}
+{{ end }}
diff --git a/layouts/partials/docs/search.html b/layouts/partials/docs/search.html
new file mode 100644
index 0000000..937f595
--- /dev/null
+++ b/layouts/partials/docs/search.html
@@ -0,0 +1,8 @@
+{{ if default true .Site.Params.BookSearch }}
+
+
+{{ end }}
diff --git a/layouts/partials/docs/taxonomy.html b/layouts/partials/docs/taxonomy.html
new file mode 100644
index 0000000..63ef315
--- /dev/null
+++ b/layouts/partials/docs/taxonomy.html
@@ -0,0 +1,19 @@
+
+
+ {{ range $term, $_ := .Site.Taxonomies }}
+ {{ with $.Site.GetPage (printf "/%s" $term | urlize) }}
+
+ {{ .Title | title }}
+
+ {{ range .Pages }}
+
+ {{ .Title }}
+ {{ len .Pages }}
+
+ {{ end }}
+
+
+ {{ end }}
+ {{ end }}
+
+
diff --git a/layouts/partials/docs/title.html b/layouts/partials/docs/title.html
new file mode 100644
index 0000000..83df5b6
--- /dev/null
+++ b/layouts/partials/docs/title.html
@@ -0,0 +1,17 @@
+
+{{ $title := "" }}
+
+{{ if .LinkTitle }}
+ {{ $title = .LinkTitle }}
+{{ else if .Title }}
+ {{ $title = .Title }}
+{{ else if and .IsSection .File }}
+ {{ $title = path.Base .File.Dir | humanize | title }}
+{{ else if and .IsPage .File }}
+ {{ $title = .File.BaseFileName | humanize | title }}
+{{ end }}
+
+{{ return $title }}
diff --git a/layouts/partials/docs/toc.html b/layouts/partials/docs/toc.html
new file mode 100644
index 0000000..64697a4
--- /dev/null
+++ b/layouts/partials/docs/toc.html
@@ -0,0 +1,3 @@
+{{ partial "docs/inject/toc-before" . }}
+{{ .TableOfContents }}
+{{ partial "docs/inject/toc-after" . }}
diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html
deleted file mode 100644
index 06e78a5..0000000
--- a/layouts/partials/footer.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
deleted file mode 100644
index bdc332d..0000000
--- a/layouts/partials/head.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-{{ .Title }} | Code Monkey Cybersecurity
-
-
-
-
-
-
\ No newline at end of file
diff --git a/layouts/partials/header.html b/layouts/partials/header.html
deleted file mode 100644
index a9c9960..0000000
--- a/layouts/partials/header.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
\ No newline at end of file
diff --git a/layouts/partials/kb-item.html b/layouts/partials/kb-item.html
deleted file mode 100644
index c012ae5..0000000
--- a/layouts/partials/kb-item.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/layouts/partials/nav.html b/layouts/partials/nav.html
deleted file mode 100644
index 8887494..0000000
--- a/layouts/partials/nav.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/layouts/partials/single.html b/layouts/partials/single.html
deleted file mode 100644
index acef7e3..0000000
--- a/layouts/partials/single.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{{ define "main" }}
-
- {{ .Content }}
-
-{{ end }}
\ No newline at end of file
diff --git a/layouts/posts/list.html b/layouts/posts/list.html
new file mode 100644
index 0000000..aff32f5
--- /dev/null
+++ b/layouts/posts/list.html
@@ -0,0 +1,22 @@
+{{ define "main" }}
+ {{ range sort .Paginator.Pages }}
+
+
+ {{ partial "docs/post-meta" . }}
+
+ {{- .Summary -}}
+ {{ if .Truncated }}
+
...
+ {{ end }}
+
+
+ {{ end }}
+
+ {{ template "_internal/pagination.html" . }}
+{{ end }}
+
+{{ define "toc" }}
+ {{ partial "docs/taxonomy" . }}
+{{ end }}
diff --git a/layouts/posts/single.html b/layouts/posts/single.html
new file mode 100644
index 0000000..cebdd11
--- /dev/null
+++ b/layouts/posts/single.html
@@ -0,0 +1,15 @@
+{{ define "main" }}
+
+
+ {{ partial "docs/title.html" . }}
+
+ {{ partial "docs/post-meta" . }}
+
+ {{- .Content -}}
+
+
+{{ end }}
+
+{{ define "toc" }}
+ {{ partial "docs/toc" . }}
+{{ end }}
diff --git a/layouts/shortcodes/button.html b/layouts/shortcodes/button.html
new file mode 100644
index 0000000..efae3e0
--- /dev/null
+++ b/layouts/shortcodes/button.html
@@ -0,0 +1,12 @@
+{{- $ref := "" }}
+{{- $target := "" -}}
+{{- with .Get "href" -}}
+ {{- $ref = . -}}
+ {{- $target = "_blank" -}}
+{{- end -}}
+{{- with .Get "relref" -}}
+ {{- $ref = relref $ . -}}
+{{- end -}}
+
+ {{- .InnerDeindent -}}
+
diff --git a/layouts/shortcodes/columns.html b/layouts/shortcodes/columns.html
new file mode 100644
index 0000000..bb01da9
--- /dev/null
+++ b/layouts/shortcodes/columns.html
@@ -0,0 +1,9 @@
+{{- $ratio := (split (.Get "ratio") ":") -}}
+
+{{ range $index, $content := split .InnerDeindent "<--->" }}
+ {{- $grow := default 1 (index $ratio $index) -}}
+
+ {{ $content | safeHTML }}
+
+{{ end }}
+
diff --git a/layouts/shortcodes/details.html b/layouts/shortcodes/details.html
new file mode 100644
index 0000000..a80209b
--- /dev/null
+++ b/layouts/shortcodes/details.html
@@ -0,0 +1,7 @@
+
+ {{- $summary := cond .IsNamedParams (.Get "title") (.Get 0) -}}
+ {{ $summary }}
+
+ {{ .InnerDeindent | safeHTML }}
+
+
diff --git a/layouts/shortcodes/hint.html b/layouts/shortcodes/hint.html
new file mode 100644
index 0000000..95e4f83
--- /dev/null
+++ b/layouts/shortcodes/hint.html
@@ -0,0 +1,3 @@
+
+ {{ .Inner | safeHTML }}
+
diff --git a/layouts/shortcodes/html.html b/layouts/shortcodes/html.html
new file mode 100644
index 0000000..b447d45
--- /dev/null
+++ b/layouts/shortcodes/html.html
@@ -0,0 +1 @@
+{{- .Inner | safeHTML -}}
\ No newline at end of file
diff --git a/layouts/shortcodes/i18n.html b/layouts/shortcodes/i18n.html
new file mode 100644
index 0000000..b65f70a
--- /dev/null
+++ b/layouts/shortcodes/i18n.html
@@ -0,0 +1,2 @@
+{{- $content := .Get 0 -}}
+{{- default $content (i18n $content) -}}
\ No newline at end of file
diff --git a/layouts/shortcodes/katex.html b/layouts/shortcodes/katex.html
new file mode 100644
index 0000000..4eafc35
--- /dev/null
+++ b/layouts/shortcodes/katex.html
@@ -0,0 +1,13 @@
+{{- if not (.Page.Scratch.Get "katex") -}}
+
+
+
+
+{{- .Page.Scratch.Set "katex" true -}}
+{{- end -}}
+
+
+ {{ with .Get "display" }}\[{{else}}\({{end}}
+ {{- .InnerDeindent -}}
+ {{ with .Get "display" }}\]{{else}}\){{end}}
+
diff --git a/layouts/shortcodes/mermaid.html b/layouts/shortcodes/mermaid.html
new file mode 100644
index 0000000..07a3bfc
--- /dev/null
+++ b/layouts/shortcodes/mermaid.html
@@ -0,0 +1,12 @@
+{{ if not (.Page.Scratch.Get "mermaid") }}
+
+
+{{ with resources.Get "mermaid.json" }}
+
+{{ end }}
+{{ .Page.Scratch.Set "mermaid" true }}
+{{ end }}
+
+
+ {{- .Inner -}}
+
diff --git a/layouts/shortcodes/section.html b/layouts/shortcodes/section.html
new file mode 100644
index 0000000..b700ec4
--- /dev/null
+++ b/layouts/shortcodes/section.html
@@ -0,0 +1,13 @@
+{{- warnf "Section shortcode is deprecated and will be removed" -}}
+
+{{ range .Page.Pages }}
+
+ {{ partial "docs/title" . }}
+
+ {{ if (in $.Params "summary") -}}
+
+ {{ default .Summary .Description }}
+
+ {{ end -}}
+{{ end }}
+
diff --git a/layouts/shortcodes/tab.html b/layouts/shortcodes/tab.html
new file mode 100644
index 0000000..b5a753d
--- /dev/null
+++ b/layouts/shortcodes/tab.html
@@ -0,0 +1,9 @@
+{{- $group := printf "tabs-%v" (default .Parent.Ordinal (.Parent.Get 0)) -}}
+{{- $tab := printf "%s-%d" $group .Ordinal }}
+
+
+ {{- .Get 0 -}}
+
+
+ {{- .Inner -}}
+
diff --git a/layouts/shortcodes/tabs.html b/layouts/shortcodes/tabs.html
new file mode 100644
index 0000000..fecbbeb
--- /dev/null
+++ b/layouts/shortcodes/tabs.html
@@ -0,0 +1,3 @@
+
+{{ .Inner }}
+
diff --git a/layouts/taxonomy/list.html b/layouts/taxonomy/list.html
new file mode 100644
index 0000000..1d3e763
--- /dev/null
+++ b/layouts/taxonomy/list.html
@@ -0,0 +1,13 @@
+{{ define "main" }}
+
+ {{ .Title | title }}
+ {{ $taxonomies := index .Site.Taxonomies .Page.Type }}
+ {{ range $taxonomies }}
+
+ {{ end }}
+
+{{ end }}
+
+{{ define "toc" }}
+ {{ partial "docs/taxonomy" . }}
+{{ end }}
diff --git a/layouts/taxonomy/taxonomy.html b/layouts/taxonomy/taxonomy.html
new file mode 100644
index 0000000..badf0f6
--- /dev/null
+++ b/layouts/taxonomy/taxonomy.html
@@ -0,0 +1,22 @@
+{{ define "main" }}
+ {{ range sort .Paginator.Pages }}
+
+
+ {{ partial "docs/post-meta" . }}
+
+ {{- .Summary -}}
+ {{ if .Truncated }}
+ ...
+ {{ end }}
+
+
+ {{ end }}
+
+ {{ template "_internal/pagination.html" . }}
+{{ end }}
+
+{{ define "toc" }}
+ {{ partial "docs/taxonomy" . }}
+{{ end }}
diff --git a/layouts_bak/_default/baseof.html b/layouts_bak/_default/baseof.html
new file mode 100644
index 0000000..5e60f0d
--- /dev/null
+++ b/layouts_bak/_default/baseof.html
@@ -0,0 +1,37 @@
+{{/* layouts/_default/baseof.html */}}
+
+
+
+
+ {{ partial "head.html" . }}
+
+
+
+ {{/* β
Required for sidebar layout logic */}}
+
+ {{/* Sidebar Toggle Checkbox (invisible but functional) */}}
+
+
+ {{/* Toggle Button */}}
+
+
+ {{/* Sidebar Menu */}}
+ {{ partial "nav.html" . }}
+
+ {{/* Content wrapper that slides */}}
+
+
+ {{/* Site header with title and logo */}}
+ {{ partial "header.html" . }}
+
+ {{/* Page content */}}
+
+ {{ partial "breadcrumbs.html" . }}
+ {{ block "main" . }}{{ end }}
+
+
+ {{ partial "footer.html" . }}
+
+
+
+
\ No newline at end of file
diff --git a/layouts_bak/_default/list.html b/layouts_bak/_default/list.html
new file mode 100644
index 0000000..f1b78b4
--- /dev/null
+++ b/layouts_bak/_default/list.html
@@ -0,0 +1,26 @@
+{{/* layouts/_default/list.html */}}
+
+{{ define "main" }}
+
+ {{ .Title }}
+ {{ with .Content }}
+ {{ . }}
+ {{ end }}
+
+ {{ $pages := .Pages.ByDate.Reverse }}
+ {{ $paginator := .Paginate $pages 12 }}
+
+
+
+ {{ partial "pagination.html" . }}
+
+{{ end }}
\ No newline at end of file
diff --git a/layouts_bak/_default/single.html b/layouts_bak/_default/single.html
new file mode 100644
index 0000000..fbca037
--- /dev/null
+++ b/layouts_bak/_default/single.html
@@ -0,0 +1,13 @@
+{{/* layouts/_default/single.html */}}
+
+{{ define "main" }}
+
+ {{ .Title }}
+
+
+ On this page {{ .TableOfContents }}
+
+
+ {{ .Content }}
+
+{{ end }}
\ No newline at end of file
diff --git a/layouts/index.html b/layouts_bak/index.html
similarity index 91%
rename from layouts/index.html
rename to layouts_bak/index.html
index 9790b38..bddcf04 100644
--- a/layouts/index.html
+++ b/layouts_bak/index.html
@@ -1,11 +1,8 @@
-{{ define "main" }}
+{{/* layouts/index.html */}}
-
- Code Monkey Cybersecurity | Home
- Cybersecurity with Humans
-
+{{ define "main" }}
-
+{{/* Services */}}
Our Services
Penetration Testing, Vulnerability Assessment & Custom Consulting
@@ -15,7 +12,7 @@ Our Services
Open source tools and guides via Athena
-
+{{/* Why Choose Us */}}
Why Choose Us?
We combine cutting-edge tech with a human-first approach.
@@ -23,7 +20,7 @@ Why Choose Us?
Contact us
-
+{{/* Roadmap */}}
Roadmap
We're deploying our HA XDR/SIEM cluster soon.
@@ -32,7 +29,7 @@ Roadmap
Set it up yourself
-
+{{/* Delphi Notify */}}
Delphi
Powered by Wazuh
@@ -41,7 +38,7 @@ Powered by Wazuh
Coming Soon
-
+{{/* Knowledge Base */}}
Knowledge Base
@@ -54,7 +51,7 @@
Knowledge Base
-
+{{/* Contact */}}
-
+{{/* Public Key */}}
Public Key
- Verify our identity:
+ Trust, but verify:
Download
View
-{{ end }}
+{{ end }}
\ No newline at end of file
diff --git a/layouts_bak/index.json.json.tmpl b/layouts_bak/index.json.json.tmpl
new file mode 100644
index 0000000..d2d3616
--- /dev/null
+++ b/layouts_bak/index.json.json.tmpl
@@ -0,0 +1,16 @@
+{{/* layouts/index.json.json */}}
+[
+ {{- $first := true -}}
+ {{- /* include page, section, and home kinds; drop taxonomy/terms */ -}}
+ {{- $all := where .Site.Pages "Kind" "not in" (slice "taxonomy" "taxonomyTerm") -}}
+ {{- range $all -}}
+ {{- if not $first }},{{ end -}}
+ {{- $first = false -}}
+ {
+ "title": {{ printf "%q" .Title }},
+ "url": {{ printf "%q" .Permalink }},
+ "summary": {{ printf "%q" (plainify .Summary | chomp) }},
+ "body": {{ printf "%q" (plainify .Content | chomp) }}
+ }
+ {{- end -}}
+]
\ No newline at end of file
diff --git a/layouts_bak/partials/breadcrumbs-schema.html b/layouts_bak/partials/breadcrumbs-schema.html
new file mode 100644
index 0000000..659762b
--- /dev/null
+++ b/layouts_bak/partials/breadcrumbs-schema.html
@@ -0,0 +1,36 @@
+{{/* layouts/partials/breadcrumbs-schema.html */}}
+
+{{- if not .IsHome }}
+
+{{- end }}
\ No newline at end of file
diff --git a/layouts_bak/partials/breadcrumbs.html b/layouts_bak/partials/breadcrumbs.html
new file mode 100644
index 0000000..0d79c72
--- /dev/null
+++ b/layouts_bak/partials/breadcrumbs.html
@@ -0,0 +1,20 @@
+{{/* layouts/partials/breadcrumbs.html */}}
+
+{{- /* Grab the section name (e.g. βpricingβ, βdocsβ, etc.) */ -}}
+{{- $sectionName := .Section -}}
+
+
+ Home
+
+ {{- /* If this page lives in a section, look it up */ -}}
+ {{- if $sectionName }}
+ {{- $secPage := .Site.GetPage "section" $sectionName -}}
+ {{- if $secPage }}
+ /
+ {{ $secPage.Title }}
+ {{- end }}
+ {{- end }}
+
+ /
+ {{ .Title }}
+
\ No newline at end of file
diff --git a/layouts_bak/partials/footer.html b/layouts_bak/partials/footer.html
new file mode 100644
index 0000000..7dc6003
--- /dev/null
+++ b/layouts_bak/partials/footer.html
@@ -0,0 +1,27 @@
+{{/* layouts/partials/footer.html */}}
+
+
+
+
\ No newline at end of file
diff --git a/layouts_bak/partials/get-breadcrumbs.html b/layouts_bak/partials/get-breadcrumbs.html
new file mode 100644
index 0000000..ad6b955
--- /dev/null
+++ b/layouts_bak/partials/get-breadcrumbs.html
@@ -0,0 +1,17 @@
+{{/* layouts/partials/get-breadcrumbs.html */}}
+
+{{- /* Initialize a crumbs slice in page Scratch */ -}}
+{{- $.Scratch.Set "crumbs" (slice) -}}
+
+{{- /* Walk up at most 10 levels */ -}}
+{{- $p := . -}}
+{{- range seq 1 10 -}}
+ {{- if not $p -}}
+ {{- /* once we hit the top, stop looping */ -}}
+ {{- break -}}
+ {{- end -}}
+ {{- /* prepend current page to crumbs */ -}}
+ {{- $.Scratch.Set "crumbs" (append ($.Scratch.Get "crumbs") $p) -}}
+ {{- /* go to parent */ -}}
+ {{- $p = $p.Parent -}}
+{{- end -}}
\ No newline at end of file
diff --git a/layouts_bak/partials/head.html b/layouts_bak/partials/head.html
new file mode 100644
index 0000000..1cbcd43
--- /dev/null
+++ b/layouts_bak/partials/head.html
@@ -0,0 +1,96 @@
+{{/* layouts/partials/head.html */}}
+
+{{- /* --------- METADATA ---------- */ -}}
+{{- $title := printf "%s | Code Monkey Cybersecurity" .Title -}}
+{{- $desc := .Params.description | default "Cybersecurity. With Humans." -}}
+
+
+
+
+ {{/* teal-7, adjust if needed */}}
+
+{{ $title }}
+
+
+{{/* OpenGraph */}}
+
+
+
+
+
+
+{{/* Twitter Card */}}
+
+
+
+
+
+
+
+
+{{- $openColor := resources.Get "openColour/open-color.css" }}
+{{- $tokens := resources.Get "css/tokens.css" }}
+{{- $fonts := resources.Get "css/fonts.css" }}
+{{- $styles := resources.Get "css/styles.css" }}
+{{- $sidebar := resources.Get "css/sidebar.css" }}
+{{- $nav := resources.Get "css/nav.css" }}
+{{- $dropdown := resources.Get "css/dropdown.css" }}
+{{- $search := resources.Get "css/search.css" }}
+{{- $breadcrumbs := resources.Get "css/components/breadcrumbs.css" }}
+{{- $kb := resources.Get "css/components/kb.css" }}
+{{- $callout := resources.Get "css/components/callout.css" }}
+{{- $code := resources.Get "css/components/code.css" }}
+{{- $tab := resources.Get "css/components/tab.css" }}
+
+{{- $css := slice
+ $openColor $tokens $fonts $styles
+ $sidebar $nav $dropdown
+ $search $kb $callout $code
+ $tab
+ | resources.Concat "css/site.css"
+ | resources.Minify
+ | resources.Fingerprint -}}
+
+{{- $css := slice $openColor $tokens $styles $sidebar $nav $dropdown $kb | resources.Concat "css/site.css" | resources.Minify | resources.Fingerprint -}}
+
+
+
+{{/* ---- JS ---- */}}
+
+
+
+
+{{/* Umami Analytics */}}
+{{ with .Site.Params.umami_script }}
+ {{ $umamiID := $.Site.Params.umami_site_id }}
+ {{ if $umamiID }}
+
+ {{ end }}
+{{ end }}
+
+{{ if not .IsHome }}
+ {{ partial "breadcrumbs-schema.html" . }}
+{{ end }}
+
+{{/* Organization Schema */}}
+
\ No newline at end of file
diff --git a/layouts_bak/partials/header.html b/layouts_bak/partials/header.html
new file mode 100644
index 0000000..aa72cbb
--- /dev/null
+++ b/layouts_bak/partials/header.html
@@ -0,0 +1,13 @@
+{{/* layouts/partials/header.html */}}
+
+
\ No newline at end of file
diff --git a/layouts_bak/partials/kb-item.html b/layouts_bak/partials/kb-item.html
new file mode 100644
index 0000000..55ec89f
--- /dev/null
+++ b/layouts_bak/partials/kb-item.html
@@ -0,0 +1,11 @@
+{{/* layouts/partials/kb-item.html */}}
+
+
\ No newline at end of file
diff --git a/layouts_bak/partials/nav.html b/layouts_bak/partials/nav.html
new file mode 100644
index 0000000..28f0b95
--- /dev/null
+++ b/layouts_bak/partials/nav.html
@@ -0,0 +1,27 @@
+{{/* layouts/partials/nav.html */}}
+
\ No newline at end of file
diff --git a/layouts_bak/partials/single.html b/layouts_bak/partials/single.html
new file mode 100644
index 0000000..a0a4762
--- /dev/null
+++ b/layouts_bak/partials/single.html
@@ -0,0 +1,22 @@
+{{/* layouts/partials/single.html */}}
+
+{{ define "main" }}
+
+ Home
+ {{ with .CurrentSection }}
+ {{ template "breadcrumb" . }}
+ {{ end }}
+ / {{ .Title }}
+
+
+
+ {{ .Content }}
+
+{{ end }}
+
+{{ define "breadcrumb" }}
+ {{ if .Parent }}
+ {{ template "breadcrumb" .Parent }} /
+ {{ end }}
+ {{ .Title }}
+{{ end }}
\ No newline at end of file
diff --git a/layouts_bak/partials/top_nav.html b/layouts_bak/partials/top_nav.html
new file mode 100644
index 0000000..09555cd
--- /dev/null
+++ b/layouts_bak/partials/top_nav.html
@@ -0,0 +1,15 @@
+{{/* layouts/partials/top_nav.html */}}
+
+
+
+
\ No newline at end of file
diff --git a/layouts_bak/shortcodes/callout.html b/layouts_bak/shortcodes/callout.html
new file mode 100644
index 0000000..ee87a21
--- /dev/null
+++ b/layouts_bak/shortcodes/callout.html
@@ -0,0 +1,5 @@
+{{/* layouts/partials/callout.html */}}
+
+
+ {{ .Get 0 | title }}: {{ .Inner }}
+
\ No newline at end of file
diff --git a/layouts_bak/shortcodes/tab.html b/layouts_bak/shortcodes/tab.html
new file mode 100644
index 0000000..1b816c3
--- /dev/null
+++ b/layouts_bak/shortcodes/tab.html
@@ -0,0 +1,9 @@
+{{/* layouts/shortcodes/tab.html */}}
+
+{{- $group := .Parent.Get 0 | default (now.UnixNano) -}}
+{{- $title := .Get 0 -}}
+
+{{ $title }}
+
+ {{ .Inner | markdownify }}
+
\ No newline at end of file
diff --git a/layouts_bak/shortcodes/tabs.html b/layouts_bak/shortcodes/tabs.html
new file mode 100644
index 0000000..5a9dbf6
--- /dev/null
+++ b/layouts_bak/shortcodes/tabs.html
@@ -0,0 +1,6 @@
+{{/* layouts/shortcodes/tabs.html */}}
+
+{{- $tabId := .Get 0 | default (now.UnixNano) -}}
+
+ {{ .Inner }}
+
\ No newline at end of file
diff --git a/static/assets/fonts b/static/assets/fonts
deleted file mode 120000
index 862375b..0000000
--- a/static/assets/fonts
+++ /dev/null
@@ -1 +0,0 @@
-../../assets/fonts
\ No newline at end of file
diff --git a/assets/images/favicon-circular-128x128.png b/static/favicon-circular-128x128.png
similarity index 100%
rename from assets/images/favicon-circular-128x128.png
rename to static/favicon-circular-128x128.png
diff --git a/assets/images/favicon-circular-16x16.png b/static/favicon-circular-16x16.png
similarity index 100%
rename from assets/images/favicon-circular-16x16.png
rename to static/favicon-circular-16x16.png
diff --git a/assets/images/favicon-circular-32x32.png b/static/favicon-circular-32x32.png
similarity index 100%
rename from assets/images/favicon-circular-32x32.png
rename to static/favicon-circular-32x32.png
diff --git a/assets/images/favicon-circular-64x64.png b/static/favicon-circular-64x64.png
similarity index 100%
rename from assets/images/favicon-circular-64x64.png
rename to static/favicon-circular-64x64.png
diff --git a/assets/images/favicon-circular-apple-touch.png b/static/favicon-circular-apple-touch.png
similarity index 100%
rename from assets/images/favicon-circular-apple-touch.png
rename to static/favicon-circular-apple-touch.png
diff --git a/assets/images/fingerprint_flipped_whitebackground_circle_1000dp_oc-teal-9_FILL0_wght400_GRAD0_opsz48.png b/static/fingerprint_flipped_whitebackground_circle_1000dp_oc-teal-9_FILL0_wght400_GRAD0_opsz48.png
similarity index 100%
rename from assets/images/fingerprint_flipped_whitebackground_circle_1000dp_oc-teal-9_FILL0_wght400_GRAD0_opsz48.png
rename to static/fingerprint_flipped_whitebackground_circle_1000dp_oc-teal-9_FILL0_wght400_GRAD0_opsz48.png
diff --git a/assets/fonts/NotoSans-Black.ttf b/static/fonts/NotoSans-Black.ttf
similarity index 100%
rename from assets/fonts/NotoSans-Black.ttf
rename to static/fonts/NotoSans-Black.ttf
diff --git a/assets/fonts/NotoSans-BlackItalic.ttf b/static/fonts/NotoSans-BlackItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-BlackItalic.ttf
rename to static/fonts/NotoSans-BlackItalic.ttf
diff --git a/assets/fonts/NotoSans-Bold.ttf b/static/fonts/NotoSans-Bold.ttf
similarity index 100%
rename from assets/fonts/NotoSans-Bold.ttf
rename to static/fonts/NotoSans-Bold.ttf
diff --git a/assets/fonts/NotoSans-BoldItalic.ttf b/static/fonts/NotoSans-BoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-BoldItalic.ttf
rename to static/fonts/NotoSans-BoldItalic.ttf
diff --git a/assets/fonts/NotoSans-ExtraBold.ttf b/static/fonts/NotoSans-ExtraBold.ttf
similarity index 100%
rename from assets/fonts/NotoSans-ExtraBold.ttf
rename to static/fonts/NotoSans-ExtraBold.ttf
diff --git a/assets/fonts/NotoSans-ExtraBoldItalic.ttf b/static/fonts/NotoSans-ExtraBoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-ExtraBoldItalic.ttf
rename to static/fonts/NotoSans-ExtraBoldItalic.ttf
diff --git a/assets/fonts/NotoSans-ExtraLight.ttf b/static/fonts/NotoSans-ExtraLight.ttf
similarity index 100%
rename from assets/fonts/NotoSans-ExtraLight.ttf
rename to static/fonts/NotoSans-ExtraLight.ttf
diff --git a/assets/fonts/NotoSans-ExtraLightItalic.ttf b/static/fonts/NotoSans-ExtraLightItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-ExtraLightItalic.ttf
rename to static/fonts/NotoSans-ExtraLightItalic.ttf
diff --git a/assets/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf b/static/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf
similarity index 100%
rename from assets/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf
rename to static/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf
diff --git a/assets/fonts/NotoSans-Italic.ttf b/static/fonts/NotoSans-Italic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-Italic.ttf
rename to static/fonts/NotoSans-Italic.ttf
diff --git a/assets/fonts/NotoSans-Light.ttf b/static/fonts/NotoSans-Light.ttf
similarity index 100%
rename from assets/fonts/NotoSans-Light.ttf
rename to static/fonts/NotoSans-Light.ttf
diff --git a/assets/fonts/NotoSans-LightItalic.ttf b/static/fonts/NotoSans-LightItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-LightItalic.ttf
rename to static/fonts/NotoSans-LightItalic.ttf
diff --git a/assets/fonts/NotoSans-Medium.ttf b/static/fonts/NotoSans-Medium.ttf
similarity index 100%
rename from assets/fonts/NotoSans-Medium.ttf
rename to static/fonts/NotoSans-Medium.ttf
diff --git a/assets/fonts/NotoSans-MediumItalic.ttf b/static/fonts/NotoSans-MediumItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-MediumItalic.ttf
rename to static/fonts/NotoSans-MediumItalic.ttf
diff --git a/assets/fonts/NotoSans-Regular.ttf b/static/fonts/NotoSans-Regular.ttf
similarity index 100%
rename from assets/fonts/NotoSans-Regular.ttf
rename to static/fonts/NotoSans-Regular.ttf
diff --git a/assets/fonts/NotoSans-SemiBold.ttf b/static/fonts/NotoSans-SemiBold.ttf
similarity index 100%
rename from assets/fonts/NotoSans-SemiBold.ttf
rename to static/fonts/NotoSans-SemiBold.ttf
diff --git a/assets/fonts/NotoSans-SemiBoldItalic.ttf b/static/fonts/NotoSans-SemiBoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-SemiBoldItalic.ttf
rename to static/fonts/NotoSans-SemiBoldItalic.ttf
diff --git a/assets/fonts/NotoSans-Thin.ttf b/static/fonts/NotoSans-Thin.ttf
similarity index 100%
rename from assets/fonts/NotoSans-Thin.ttf
rename to static/fonts/NotoSans-Thin.ttf
diff --git a/assets/fonts/NotoSans-ThinItalic.ttf b/static/fonts/NotoSans-ThinItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans-ThinItalic.ttf
rename to static/fonts/NotoSans-ThinItalic.ttf
diff --git a/assets/fonts/NotoSans-VariableFont_wdth,wght.ttf b/static/fonts/NotoSans-VariableFont_wdth,wght.ttf
similarity index 100%
rename from assets/fonts/NotoSans-VariableFont_wdth,wght.ttf
rename to static/fonts/NotoSans-VariableFont_wdth,wght.ttf
diff --git a/assets/fonts/NotoSans_Condensed-Black.ttf b/static/fonts/NotoSans_Condensed-Black.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-Black.ttf
rename to static/fonts/NotoSans_Condensed-Black.ttf
diff --git a/assets/fonts/NotoSans_Condensed-BlackItalic.ttf b/static/fonts/NotoSans_Condensed-BlackItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-BlackItalic.ttf
rename to static/fonts/NotoSans_Condensed-BlackItalic.ttf
diff --git a/assets/fonts/NotoSans_Condensed-Bold.ttf b/static/fonts/NotoSans_Condensed-Bold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-Bold.ttf
rename to static/fonts/NotoSans_Condensed-Bold.ttf
diff --git a/assets/fonts/NotoSans_Condensed-BoldItalic.ttf b/static/fonts/NotoSans_Condensed-BoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-BoldItalic.ttf
rename to static/fonts/NotoSans_Condensed-BoldItalic.ttf
diff --git a/assets/fonts/NotoSans_Condensed-ExtraBold.ttf b/static/fonts/NotoSans_Condensed-ExtraBold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-ExtraBold.ttf
rename to static/fonts/NotoSans_Condensed-ExtraBold.ttf
diff --git a/assets/fonts/NotoSans_Condensed-ExtraBoldItalic.ttf b/static/fonts/NotoSans_Condensed-ExtraBoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-ExtraBoldItalic.ttf
rename to static/fonts/NotoSans_Condensed-ExtraBoldItalic.ttf
diff --git a/assets/fonts/NotoSans_Condensed-ExtraLight.ttf b/static/fonts/NotoSans_Condensed-ExtraLight.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-ExtraLight.ttf
rename to static/fonts/NotoSans_Condensed-ExtraLight.ttf
diff --git a/assets/fonts/NotoSans_Condensed-ExtraLightItalic.ttf b/static/fonts/NotoSans_Condensed-ExtraLightItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-ExtraLightItalic.ttf
rename to static/fonts/NotoSans_Condensed-ExtraLightItalic.ttf
diff --git a/assets/fonts/NotoSans_Condensed-Italic.ttf b/static/fonts/NotoSans_Condensed-Italic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-Italic.ttf
rename to static/fonts/NotoSans_Condensed-Italic.ttf
diff --git a/assets/fonts/NotoSans_Condensed-Light.ttf b/static/fonts/NotoSans_Condensed-Light.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-Light.ttf
rename to static/fonts/NotoSans_Condensed-Light.ttf
diff --git a/assets/fonts/NotoSans_Condensed-LightItalic.ttf b/static/fonts/NotoSans_Condensed-LightItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-LightItalic.ttf
rename to static/fonts/NotoSans_Condensed-LightItalic.ttf
diff --git a/assets/fonts/NotoSans_Condensed-Medium.ttf b/static/fonts/NotoSans_Condensed-Medium.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-Medium.ttf
rename to static/fonts/NotoSans_Condensed-Medium.ttf
diff --git a/assets/fonts/NotoSans_Condensed-MediumItalic.ttf b/static/fonts/NotoSans_Condensed-MediumItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-MediumItalic.ttf
rename to static/fonts/NotoSans_Condensed-MediumItalic.ttf
diff --git a/assets/fonts/NotoSans_Condensed-Regular.ttf b/static/fonts/NotoSans_Condensed-Regular.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-Regular.ttf
rename to static/fonts/NotoSans_Condensed-Regular.ttf
diff --git a/assets/fonts/NotoSans_Condensed-SemiBold.ttf b/static/fonts/NotoSans_Condensed-SemiBold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-SemiBold.ttf
rename to static/fonts/NotoSans_Condensed-SemiBold.ttf
diff --git a/assets/fonts/NotoSans_Condensed-SemiBoldItalic.ttf b/static/fonts/NotoSans_Condensed-SemiBoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-SemiBoldItalic.ttf
rename to static/fonts/NotoSans_Condensed-SemiBoldItalic.ttf
diff --git a/assets/fonts/NotoSans_Condensed-Thin.ttf b/static/fonts/NotoSans_Condensed-Thin.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-Thin.ttf
rename to static/fonts/NotoSans_Condensed-Thin.ttf
diff --git a/assets/fonts/NotoSans_Condensed-ThinItalic.ttf b/static/fonts/NotoSans_Condensed-ThinItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_Condensed-ThinItalic.ttf
rename to static/fonts/NotoSans_Condensed-ThinItalic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-Black.ttf b/static/fonts/NotoSans_ExtraCondensed-Black.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-Black.ttf
rename to static/fonts/NotoSans_ExtraCondensed-Black.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-BlackItalic.ttf b/static/fonts/NotoSans_ExtraCondensed-BlackItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-BlackItalic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-BlackItalic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-Bold.ttf b/static/fonts/NotoSans_ExtraCondensed-Bold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-Bold.ttf
rename to static/fonts/NotoSans_ExtraCondensed-Bold.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-BoldItalic.ttf b/static/fonts/NotoSans_ExtraCondensed-BoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-BoldItalic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-BoldItalic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-ExtraBold.ttf b/static/fonts/NotoSans_ExtraCondensed-ExtraBold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-ExtraBold.ttf
rename to static/fonts/NotoSans_ExtraCondensed-ExtraBold.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-ExtraBoldItalic.ttf b/static/fonts/NotoSans_ExtraCondensed-ExtraBoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-ExtraBoldItalic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-ExtraBoldItalic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-ExtraLight.ttf b/static/fonts/NotoSans_ExtraCondensed-ExtraLight.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-ExtraLight.ttf
rename to static/fonts/NotoSans_ExtraCondensed-ExtraLight.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-ExtraLightItalic.ttf b/static/fonts/NotoSans_ExtraCondensed-ExtraLightItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-ExtraLightItalic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-ExtraLightItalic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-Italic.ttf b/static/fonts/NotoSans_ExtraCondensed-Italic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-Italic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-Italic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-Light.ttf b/static/fonts/NotoSans_ExtraCondensed-Light.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-Light.ttf
rename to static/fonts/NotoSans_ExtraCondensed-Light.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-LightItalic.ttf b/static/fonts/NotoSans_ExtraCondensed-LightItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-LightItalic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-LightItalic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-Medium.ttf b/static/fonts/NotoSans_ExtraCondensed-Medium.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-Medium.ttf
rename to static/fonts/NotoSans_ExtraCondensed-Medium.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-MediumItalic.ttf b/static/fonts/NotoSans_ExtraCondensed-MediumItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-MediumItalic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-MediumItalic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-Regular.ttf b/static/fonts/NotoSans_ExtraCondensed-Regular.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-Regular.ttf
rename to static/fonts/NotoSans_ExtraCondensed-Regular.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-SemiBold.ttf b/static/fonts/NotoSans_ExtraCondensed-SemiBold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-SemiBold.ttf
rename to static/fonts/NotoSans_ExtraCondensed-SemiBold.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-SemiBoldItalic.ttf b/static/fonts/NotoSans_ExtraCondensed-SemiBoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-SemiBoldItalic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-SemiBoldItalic.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-Thin.ttf b/static/fonts/NotoSans_ExtraCondensed-Thin.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-Thin.ttf
rename to static/fonts/NotoSans_ExtraCondensed-Thin.ttf
diff --git a/assets/fonts/NotoSans_ExtraCondensed-ThinItalic.ttf b/static/fonts/NotoSans_ExtraCondensed-ThinItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_ExtraCondensed-ThinItalic.ttf
rename to static/fonts/NotoSans_ExtraCondensed-ThinItalic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-Black.ttf b/static/fonts/NotoSans_SemiCondensed-Black.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-Black.ttf
rename to static/fonts/NotoSans_SemiCondensed-Black.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-BlackItalic.ttf b/static/fonts/NotoSans_SemiCondensed-BlackItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-BlackItalic.ttf
rename to static/fonts/NotoSans_SemiCondensed-BlackItalic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-Bold.ttf b/static/fonts/NotoSans_SemiCondensed-Bold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-Bold.ttf
rename to static/fonts/NotoSans_SemiCondensed-Bold.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-BoldItalic.ttf b/static/fonts/NotoSans_SemiCondensed-BoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-BoldItalic.ttf
rename to static/fonts/NotoSans_SemiCondensed-BoldItalic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-ExtraBold.ttf b/static/fonts/NotoSans_SemiCondensed-ExtraBold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-ExtraBold.ttf
rename to static/fonts/NotoSans_SemiCondensed-ExtraBold.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-ExtraBoldItalic.ttf b/static/fonts/NotoSans_SemiCondensed-ExtraBoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-ExtraBoldItalic.ttf
rename to static/fonts/NotoSans_SemiCondensed-ExtraBoldItalic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-ExtraLight.ttf b/static/fonts/NotoSans_SemiCondensed-ExtraLight.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-ExtraLight.ttf
rename to static/fonts/NotoSans_SemiCondensed-ExtraLight.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-ExtraLightItalic.ttf b/static/fonts/NotoSans_SemiCondensed-ExtraLightItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-ExtraLightItalic.ttf
rename to static/fonts/NotoSans_SemiCondensed-ExtraLightItalic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-Italic.ttf b/static/fonts/NotoSans_SemiCondensed-Italic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-Italic.ttf
rename to static/fonts/NotoSans_SemiCondensed-Italic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-Light.ttf b/static/fonts/NotoSans_SemiCondensed-Light.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-Light.ttf
rename to static/fonts/NotoSans_SemiCondensed-Light.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-LightItalic.ttf b/static/fonts/NotoSans_SemiCondensed-LightItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-LightItalic.ttf
rename to static/fonts/NotoSans_SemiCondensed-LightItalic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-Medium.ttf b/static/fonts/NotoSans_SemiCondensed-Medium.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-Medium.ttf
rename to static/fonts/NotoSans_SemiCondensed-Medium.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-MediumItalic.ttf b/static/fonts/NotoSans_SemiCondensed-MediumItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-MediumItalic.ttf
rename to static/fonts/NotoSans_SemiCondensed-MediumItalic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-Regular.ttf b/static/fonts/NotoSans_SemiCondensed-Regular.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-Regular.ttf
rename to static/fonts/NotoSans_SemiCondensed-Regular.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-SemiBold.ttf b/static/fonts/NotoSans_SemiCondensed-SemiBold.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-SemiBold.ttf
rename to static/fonts/NotoSans_SemiCondensed-SemiBold.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-SemiBoldItalic.ttf b/static/fonts/NotoSans_SemiCondensed-SemiBoldItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-SemiBoldItalic.ttf
rename to static/fonts/NotoSans_SemiCondensed-SemiBoldItalic.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-Thin.ttf b/static/fonts/NotoSans_SemiCondensed-Thin.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-Thin.ttf
rename to static/fonts/NotoSans_SemiCondensed-Thin.ttf
diff --git a/assets/fonts/NotoSans_SemiCondensed-ThinItalic.ttf b/static/fonts/NotoSans_SemiCondensed-ThinItalic.ttf
similarity index 100%
rename from assets/fonts/NotoSans_SemiCondensed-ThinItalic.ttf
rename to static/fonts/NotoSans_SemiCondensed-ThinItalic.ttf
diff --git a/assets/fonts/OFL.txt b/static/fonts/OFL.txt
similarity index 100%
rename from assets/fonts/OFL.txt
rename to static/fonts/OFL.txt
diff --git a/assets/fonts/README.txt b/static/fonts/README.txt
similarity index 100%
rename from assets/fonts/README.txt
rename to static/fonts/README.txt
diff --git a/static/js/search.js b/static/js/search.js
new file mode 100644
index 0000000..3bed96b
--- /dev/null
+++ b/static/js/search.js
@@ -0,0 +1,57 @@
+// static/js/search.js
+document.addEventListener("DOMContentLoaded", () => {
+ const wrapper = document.querySelector(".book-search");
+ const input = document.getElementById("site-search");
+ const resultList = document.getElementById("search-results");
+ if (!wrapper || !input || !resultList) return;
+
+ // toggle an βactiveβ class while focused or containing text
+ function updateActiveState() {
+ const hasText = input.value.trim().length > 0;
+ const isFocused = document.activeElement === input;
+ wrapper.classList.toggle("active", hasText || isFocused);
+ }
+
+ // load your JSON index and initialize Fuse
+ fetch("/index.json")
+ .then(res => {
+ if (!res.ok) throw new Error("Network response was not OK");
+ return res.json();
+ })
+ .then(pages => {
+ const fuse = new Fuse(pages, {
+ keys: [
+ { name: "title", weight: 0.7 },
+ { name: "summary", weight: 0.3 },
+ { name: "body", weight: 0.1 }
+ ],
+ includeScore: true,
+ threshold: 0.4
+ });
+
+ // wire up events
+ input.addEventListener("input", e => {
+ updateActiveState();
+ const q = e.target.value.trim();
+ if (!q) {
+ resultList.innerHTML = "";
+ return;
+ }
+ const hits = fuse.search(q, { limit: 5 });
+ if (hits.length === 0) {
+ resultList.innerHTML = "No results found ";
+ return;
+ }
+ resultList.innerHTML = hits
+ .map(h => `${h.item.title} `)
+ .join("");
+ });
+ input.addEventListener("focus", updateActiveState);
+ input.addEventListener("blur", updateActiveState);
+ })
+ .catch(err => {
+ console.error("Search index load failed:", err);
+ resultList.innerHTML = "Search unavailable ";
+ updateActiveState();
+ });
+});
\ No newline at end of file
diff --git a/static/js/sidebar.js b/static/js/sidebar.js
new file mode 100644
index 0000000..e99b329
--- /dev/null
+++ b/static/js/sidebar.js
@@ -0,0 +1,13 @@
+// static/js/sidebar.js
+document.addEventListener('DOMContentLoaded', () => {
+ const checkbox = document.getElementById('menu-control');
+ const toggleBtn = document.querySelector('.menu-toggle');
+
+ if (!checkbox || !toggleBtn) return;
+
+ toggleBtn.setAttribute('aria-expanded', 'false');
+
+ checkbox.addEventListener('change', () => {
+ toggleBtn.setAttribute('aria-expanded', checkbox.checked.toString());
+ });
+});
\ No newline at end of file
diff --git a/static/js/tab.js b/static/js/tab.js
new file mode 100644
index 0000000..2698831
--- /dev/null
+++ b/static/js/tab.js
@@ -0,0 +1,14 @@
+// static/js/tab.js
+document.addEventListener('DOMContentLoaded', function() {
+ document.querySelectorAll('.tabs').forEach(tabs => {
+ tabs.querySelector('.tab-buttons').addEventListener('click', function(e) {
+ if (!e.target.classList.contains('tab')) return;
+ const target = e.target.dataset.target;
+ tabs.querySelectorAll('.tab').forEach(btn => btn.classList.remove('active'));
+ e.target.classList.add('active');
+ tabs.querySelectorAll('.tab-content').forEach(content =>
+ content.classList.toggle('active', content.id === target)
+ );
+ });
+ });
+});
\ No newline at end of file
diff --git a/static/pub_keys/publickey.cybermonkey.net.au-e3f0434f633b9745e69858add19e08d1ec7a6f2f.asc b/static/pub_keys/publickey.cybermonkey.net.au-e3f0434f633b9745e69858add19e08d1ec7a6f2f.asc
new file mode 100644
index 0000000..b2432de
--- /dev/null
+++ b/static/pub_keys/publickey.cybermonkey.net.au-e3f0434f633b9745e69858add19e08d1ec7a6f2f.asc
@@ -0,0 +1,14 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xjMEZwtSyhYJKwYBBAHaRw8BAQdAUf1VxawipXbRyDz7FurM6XzS5K28SUFF
+loMog7wY6dfNM2hlbnJ5QGN5YmVybW9ua2V5Lm5ldC5hdSA8aGVucnlAY3li
+ZXJtb25rZXkubmV0LmF1PsKMBBAWCgA+BYJnC1LKBAsJBwgJkNGeCNHsem8v
+AxUICgQWAAIBAhkBApsDAh4BFiEE4/BDT2M7l0XmmFit0Z4I0ex6by8AAAqH
+AP9aT2RArWJQT6te3QRtks+UijKSnEl5EfsejFc5fkO9sQD/b7PG0HOiOfFJ
+tPL1UqSmR9xNa/K/iaUbHAVbRl9GYwrOOARnC1LKEgorBgEEAZdVAQUBAQdA
+hZCQBUxbf+KD1wKw3NLIjUNtP/+8wXmFhm7K9hNhzncDAQgHwngEGBYKACoF
+gmcLUsoJkNGeCNHsem8vApsMFiEE4/BDT2M7l0XmmFit0Z4I0ex6by8AAIaX
+AQDXlXsXcwMtlKXlAmOWr6KSYql/gCKy3ADjx+wkYt+DywD9H1mPAVroMtKB
+N2hlLe6x7x6TkgOHbmalvPdfHOEUUAA=
+=zLtx
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/static/pub_keys/publickey.cybermonkey.net.au-e3f0434f633b9745e69858add19e08d1ec7a6f2f.txt b/static/pub_keys/publickey.cybermonkey.net.au-e3f0434f633b9745e69858add19e08d1ec7a6f2f.txt
new file mode 100644
index 0000000..669af5c
--- /dev/null
+++ b/static/pub_keys/publickey.cybermonkey.net.au-e3f0434f633b9745e69858add19e08d1ec7a6f2f.txt
@@ -0,0 +1,14 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xjMEZwtSyhYJKwYBBAHaRw8BAQdAUf1VxawipXbRyDz7FurM6XzS5K28SUFF
+loMog7wY6dfNM2hlbnJ5QGN5YmVybW9ua2V5Lm5ldC5hdSA8aGVucnlAY3li
+ZXJtb25rZXkubmV0LmF1PsKMBBAWCgA+BYJnC1LKBAsJBwgJkNGeCNHsem8v
+AxUICgQWAAIBAhkBApsDAh4BFiEE4/BDT2M7l0XmmFit0Z4I0ex6by8AAAqH
+AP9aT2RArWJQT6te3QRtks+UijKSnEl5EfsejFc5fkO9sQD/b7PG0HOiOfFJ
+tPL1UqSmR9xNa/K/iaUbHAVbRl9GYwrOOARnC1LKEgorBgEEAZdVAQUBAQdA
+hZCQBUxbf+KD1wKw3NLIjUNtP/+8wXmFhm7K9hNhzncDAQgHwngEGBYKACoF
+gmcLUsoJkNGeCNHsem8vApsMFiEE4/BDT2M7l0XmmFit0Z4I0ex6by8AAIaX
+AQDXlXsXcwMtlKXlAmOWr6KSYql/gCKy3ADjx+wkYt+DywD9H1mPAVroMtKB
+N2hlLe6x7x6TkgOHbmalvPdfHOEUUAA=
+=zLtx
+-----END PGP PUBLIC KEY BLOCK-----
\ No newline at end of file
diff --git a/theme.toml b/theme.toml
new file mode 100644
index 0000000..b24899f
--- /dev/null
+++ b/theme.toml
@@ -0,0 +1,16 @@
+# theme.toml template for a Hugo theme
+# See https://github.com/gohugoio/hugoThemes#themetoml for an example
+
+name = "Book"
+license = "MIT"
+licenselink = "https://github.com/alex-shpak/hugo-book/blob/master/LICENSE"
+description = "Hugo documentation theme as simple as plain book"
+homepage = "https://github.com/alex-shpak/hugo-book"
+demosite = "https://hugo-book-demo.netlify.app"
+tags = ["responsive", "clean", "documentation", "docs", "flexbox", "search", "mobile", "multilingual", "disqus"]
+features = []
+min_version = "0.128.0"
+
+[author]
+ name = "Alex Shpak"
+ homepage = "https://github.com/alex-shpak/"
diff --git a/themes/hugo-book b/themes/hugo-book
new file mode 160000
index 0000000..0c86b5d
--- /dev/null
+++ b/themes/hugo-book
@@ -0,0 +1 @@
+Subproject commit 0c86b5d29dcd0ae17b5e8509b51d3fe7d1c2e260