pushing for review
This commit is contained in:
parent
620b4b3de4
commit
b1d7569150
19 changed files with 3742 additions and 228 deletions
3239
Cargo.lock
generated
3239
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -9,6 +9,8 @@ edition = "2021"
|
|||
anyhow = "1.0.79"
|
||||
askama = "0.12.1"
|
||||
axum = "0.7.4"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
surrealdb = { version = "1.2.0", features = ["kv-speedb"] }
|
||||
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] }
|
||||
tower = "0.4.13"
|
||||
tower-http = { version = "0.5.1", features = ["fs"] }
|
||||
|
|
|
|||
BIN
assets/SK-test-logo.png
Normal file
BIN
assets/SK-test-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
BIN
assets/aocollapse.png
Normal file
BIN
assets/aocollapse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
324
assets/main.css
324
assets/main.css
|
|
@ -767,6 +767,16 @@ select {
|
|||
inset: -0.125rem;
|
||||
}
|
||||
|
||||
.-inset-x-4 {
|
||||
left: -1rem;
|
||||
right: -1rem;
|
||||
}
|
||||
|
||||
.-inset-y-6 {
|
||||
top: -1.5rem;
|
||||
bottom: -1.5rem;
|
||||
}
|
||||
|
||||
.inset-y-0 {
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
|
|
@ -776,12 +786,21 @@ select {
|
|||
left: 0px;
|
||||
}
|
||||
|
||||
.left-4 {
|
||||
left: 1rem;
|
||||
.z-0 {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.top-4 {
|
||||
top: 1rem;
|
||||
.z-10 {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.z-20 {
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.mx-4 {
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.mx-72 {
|
||||
|
|
@ -794,12 +813,36 @@ select {
|
|||
margin-right: auto;
|
||||
}
|
||||
|
||||
.-mb-8 {
|
||||
margin-bottom: -2rem;
|
||||
.mb-24 {
|
||||
margin-bottom: 6rem;
|
||||
}
|
||||
|
||||
.-ml-px {
|
||||
margin-left: -1px;
|
||||
.ml-2 {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.ml-4 {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.mr-12 {
|
||||
margin-right: 3rem;
|
||||
}
|
||||
|
||||
.mt-12 {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.mt-4 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.mt-6 {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
|
|
@ -814,14 +857,18 @@ select {
|
|||
display: inline-flex;
|
||||
}
|
||||
|
||||
.flow-root {
|
||||
display: flow-root;
|
||||
.grid {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.h-12 {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
.h-16 {
|
||||
height: 4rem;
|
||||
}
|
||||
|
|
@ -830,42 +877,22 @@ select {
|
|||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.h-5 {
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
.h-8 {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.h-full {
|
||||
height: 100%;
|
||||
.w-12 {
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.w-6 {
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.w-0 {
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
.w-0\.5 {
|
||||
width: 0.125rem;
|
||||
}
|
||||
|
||||
.w-5 {
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.w-8 {
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.min-w-0 {
|
||||
min-width: 0px;
|
||||
}
|
||||
|
||||
.max-w-7xl {
|
||||
max-width: 80rem;
|
||||
}
|
||||
|
|
@ -874,6 +901,32 @@ select {
|
|||
flex: 1 1 0%;
|
||||
}
|
||||
|
||||
.flex-none {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.scale-95 {
|
||||
--tw-scale-x: .95;
|
||||
--tw-scale-y: .95;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.grid-cols-1 {
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid-cols-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
|
@ -886,6 +939,19 @@ select {
|
|||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.gap-4 {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.gap-x-12 {
|
||||
-moz-column-gap: 3rem;
|
||||
column-gap: 3rem;
|
||||
}
|
||||
|
||||
.gap-y-16 {
|
||||
row-gap: 4rem;
|
||||
}
|
||||
|
||||
.space-x-4 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(1rem * var(--tw-space-x-reverse));
|
||||
|
|
@ -898,62 +964,42 @@ select {
|
|||
margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.space-x-3 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(0.75rem * var(--tw-space-x-reverse));
|
||||
margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
|
||||
.whitespace-nowrap {
|
||||
white-space: nowrap;
|
||||
.rounded-full {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.rounded-md {
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
.rounded-full {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.bg-gray-900 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-stone-200 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(231 229 228 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-stone-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(168 162 158 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-stone-800 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(41 37 36 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-stone-900 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-blue-500 {
|
||||
.bg-white {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(59 130 246 / var(--tw-bg-opacity));
|
||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-gray-200 {
|
||||
.bg-zinc-50 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-gray-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(156 163 175 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-green-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
|
||||
background-color: rgb(250 250 250 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.p-2 {
|
||||
|
|
@ -979,10 +1025,18 @@ select {
|
|||
padding-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.pb-4 {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.pb-6 {
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.pt-12 {
|
||||
padding-top: 3rem;
|
||||
}
|
||||
|
||||
.pt-2 {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
|
@ -991,22 +1045,19 @@ select {
|
|||
padding-top: 1.5rem;
|
||||
}
|
||||
|
||||
.pb-8 {
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.pt-1 {
|
||||
padding-top: 0.25rem;
|
||||
}
|
||||
|
||||
.pt-1\.5 {
|
||||
padding-top: 0.375rem;
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.text-4xl {
|
||||
font-size: 2.25rem;
|
||||
line-height: 2.5rem;
|
||||
|
|
@ -1022,6 +1073,10 @@ select {
|
|||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.font-extrabold {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
|
@ -1030,6 +1085,15 @@ select {
|
|||
font-weight: 500;
|
||||
}
|
||||
|
||||
.font-semibold {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.text-emerald-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(110 231 183 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(209 213 219 / var(--tw-text-opacity));
|
||||
|
|
@ -1060,25 +1124,42 @@ select {
|
|||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-500 {
|
||||
.text-zinc-800 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(107 114 128 / var(--tw-text-opacity));
|
||||
color: rgb(39 39 42 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-900 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(17 24 39 / var(--tw-text-opacity));
|
||||
.opacity-0 {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.ring-8 {
|
||||
.shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.shadow-zinc-800\/5 {
|
||||
--tw-shadow-color: rgb(39 39 42 / 0.05);
|
||||
--tw-shadow: var(--tw-shadow-colored);
|
||||
}
|
||||
|
||||
.ring-1 {
|
||||
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
}
|
||||
|
||||
.ring-white {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity));
|
||||
.ring-zinc-900\/5 {
|
||||
--tw-ring-color: rgb(24 24 27 / 0.05);
|
||||
}
|
||||
|
||||
.transition {
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.hover\:bg-gray-700:hover {
|
||||
|
|
@ -1086,6 +1167,11 @@ select {
|
|||
background-color: rgb(55 65 81 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-stone-300:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(214 211 209 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-stone-700:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(68 64 60 / var(--tw-bg-opacity));
|
||||
|
|
@ -1116,7 +1202,27 @@ select {
|
|||
--tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.group:hover .group-hover\:scale-100 {
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.group:hover .group-hover\:text-emerald-500 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(16 185 129 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.group:hover .group-hover\:opacity-100 {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.sm\:-inset-x-6 {
|
||||
left: -1.5rem;
|
||||
right: -1.5rem;
|
||||
}
|
||||
|
||||
.sm\:ml-6 {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
|
@ -1129,6 +1235,10 @@ select {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.sm\:grid-cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.sm\:items-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
|
@ -1137,6 +1247,10 @@ select {
|
|||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.sm\:rounded-2xl {
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.sm\:px-6 {
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
|
|
@ -1144,8 +1258,52 @@ select {
|
|||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.lg\:grid-cols-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.lg\:px-8 {
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.dark\:border {
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.dark\:border-zinc-700\/50 {
|
||||
border-color: rgb(63 63 70 / 0.5);
|
||||
}
|
||||
|
||||
.dark\:bg-zinc-800 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(39 39 42 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark\:bg-zinc-800\/50 {
|
||||
background-color: rgb(39 39 42 / 0.5);
|
||||
}
|
||||
|
||||
.dark\:text-emerald-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(4 120 87 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-stone-100 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(245 245 244 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-zinc-100 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(244 244 245 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:ring-0 {
|
||||
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
}
|
||||
}
|
||||
BIN
assets/sk-extract.png
Normal file
BIN
assets/sk-extract.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 588 B |
BIN
assets/sunserver.png
Normal file
BIN
assets/sunserver.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4 KiB |
|
|
@ -5,6 +5,8 @@ pkgs.rustPlatform.buildRustPackage rec {
|
|||
version = "1.0.0";
|
||||
cargoLock.lockFile = ../Cargo.lock;
|
||||
src = pkgs.lib.cleanSource ../.;
|
||||
buildInputs = [ ];
|
||||
buildInputs = with pkgs; [
|
||||
surrealdb
|
||||
];
|
||||
# doCheck = false;
|
||||
}
|
||||
|
|
@ -1,17 +1,26 @@
|
|||
{ pkgs ? import <nixpkgs> { } }:
|
||||
pkgs.mkShell {
|
||||
# Get dependencies from the main package
|
||||
inputsFrom = [ (pkgs.callPackage ./default.nix { }) ];
|
||||
# Additional tooling
|
||||
buildInputs = with pkgs; [
|
||||
cargo
|
||||
cargo-watch
|
||||
rustc
|
||||
rustup
|
||||
clippy
|
||||
rust-analyzer
|
||||
pkg-config
|
||||
bacon
|
||||
nodePackages_latest.pnpm
|
||||
let
|
||||
runtimeLibs = [
|
||||
pkgs.libclang
|
||||
pkgs.rocksdb
|
||||
];
|
||||
}
|
||||
in
|
||||
pkgs.mkShell {
|
||||
# Get dependencies from the main package
|
||||
inputsFrom = [ (pkgs.callPackage ./default.nix { }) ];
|
||||
# Additional tooling
|
||||
buildInputs = with pkgs; [
|
||||
cargo
|
||||
cargo-watch
|
||||
rustc
|
||||
rustup
|
||||
clippy
|
||||
rust-analyzer
|
||||
pkg-config
|
||||
bacon
|
||||
nodePackages_latest.pnpm
|
||||
surrealdb
|
||||
libclang
|
||||
];
|
||||
LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath runtimeLibs}";
|
||||
}
|
||||
|
|
|
|||
27
src/handlers.rs
Normal file
27
src/handlers.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use super::templates;
|
||||
use axum::response::IntoResponse;
|
||||
|
||||
pub async fn blog_post() -> impl IntoResponse {
|
||||
let template = templates::PostTemplate {
|
||||
title:"Test Tile".to_string(),
|
||||
description:"this is a test description of a test blog post for rendering in its post template".to_string(),
|
||||
post_date:"02/21/2024".to_string()
|
||||
};
|
||||
templates::HtmlTemplate(template)
|
||||
}
|
||||
pub async fn root() -> impl IntoResponse {
|
||||
let template = templates::HomeTemplate {};
|
||||
templates::HtmlTemplate(template)
|
||||
}
|
||||
pub async fn blog() -> impl IntoResponse {
|
||||
let template = templates::BlogTemplate {};
|
||||
templates::HtmlTemplate(template)
|
||||
}
|
||||
pub async fn resume() -> impl IntoResponse {
|
||||
let template = templates::ResumeTemplate {};
|
||||
templates::HtmlTemplate(template)
|
||||
}
|
||||
pub async fn projects() -> impl IntoResponse {
|
||||
let template = templates::ProjectsTemplate {};
|
||||
templates::HtmlTemplate(template)
|
||||
}
|
||||
88
src/main.rs
88
src/main.rs
|
|
@ -1,18 +1,23 @@
|
|||
use askama::Template;
|
||||
use axum::{
|
||||
http::StatusCode,
|
||||
response::{Html, IntoResponse, Response},
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use tower_http::services::ServeDir;
|
||||
use tracing::info;
|
||||
use std::env;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
mod router;
|
||||
mod handlers;
|
||||
mod templates;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let assets_path = std::env::current_dir().unwrap();
|
||||
setup_tracing();
|
||||
|
||||
let assets_path = env::current_dir().unwrap().join("assets");
|
||||
let app = router::router(&assets_path);
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
println!("Listening on port 3000");
|
||||
}
|
||||
|
||||
fn setup_tracing(){
|
||||
tracing_subscriber::registry()
|
||||
.with(
|
||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
|
|
@ -20,71 +25,6 @@ async fn main() {
|
|||
)
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
|
||||
info!("hello, web server!");
|
||||
// build our application with a single route
|
||||
let app = Router::new()
|
||||
.route("/", get(root))
|
||||
.route("/blog", get(blog))
|
||||
.route("/resume", get(resume))
|
||||
.route("/projects", get(projects))
|
||||
.nest_service("/assets", ServeDir::new(format!("{}/assets", assets_path.to_str().unwrap())),);
|
||||
// run our app with hyper, listening globally on port 3000
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
async fn root() -> impl IntoResponse {
|
||||
let template = HelloTemplate {};
|
||||
HtmlTemplate(template)
|
||||
}
|
||||
async fn blog() -> impl IntoResponse {
|
||||
let template = BlogTemplate {};
|
||||
HtmlTemplate(template)
|
||||
}
|
||||
async fn resume() -> impl IntoResponse {
|
||||
let template = ResumeTemplate {};
|
||||
HtmlTemplate(template)
|
||||
}
|
||||
async fn projects() -> impl IntoResponse {
|
||||
let template = ProjectsTemplate {};
|
||||
HtmlTemplate(template)
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "index.html")]
|
||||
struct HelloTemplate;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "blog.html")]
|
||||
struct BlogTemplate;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "resume.html")]
|
||||
struct ResumeTemplate;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "projects.html")]
|
||||
struct ProjectsTemplate;
|
||||
|
||||
/// A wrapper type that we'll use to encapsulate HTML parsed by askama into valid HTML for axum to serve.
|
||||
struct HtmlTemplate<T>(T);
|
||||
|
||||
/// Allows us to convert Askama HTML templates into valid HTML for axum to serve in the response.
|
||||
impl<T> IntoResponse for HtmlTemplate<T>
|
||||
where
|
||||
T: Template,
|
||||
{
|
||||
fn into_response(self) -> Response {
|
||||
// Attempt to render the template with askama
|
||||
match self.0.render() {
|
||||
// If we're able to successfully parse and aggregate the template, serve it
|
||||
Ok(html) => Html(html).into_response(),
|
||||
// If we're not, return an error or some bit of fallback HTML
|
||||
Err(err) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Failed to render template. Error: {}", err),
|
||||
)
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/router.rs
Normal file
14
src/router.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use axum::{Router, routing::get};
|
||||
use tower_http::services::ServeDir;
|
||||
use std::path::Path;
|
||||
use super::handlers;
|
||||
|
||||
pub fn router(assets_path: &Path) -> Router {
|
||||
Router::new()
|
||||
.route("/", get(handlers::root))
|
||||
.route("/blog", get(handlers::blog))
|
||||
.route("/blog/post", get(handlers::blog_post))
|
||||
.route("/resume", get(handlers::resume))
|
||||
.route("/projects", get(handlers::projects))
|
||||
.nest_service("/assets", ServeDir::new(assets_path))
|
||||
}
|
||||
52
src/templates.rs
Normal file
52
src/templates.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
use askama::Template;
|
||||
use axum::{
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Html, Response}
|
||||
};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "post.html")]
|
||||
pub struct PostTemplate {
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
pub post_date: String,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "index.html")]
|
||||
pub struct HomeTemplate;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "blog.html")]
|
||||
pub struct BlogTemplate;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "resume.html")]
|
||||
pub struct ResumeTemplate;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "projects.html")]
|
||||
pub struct ProjectsTemplate;
|
||||
|
||||
/// A wrapper type that we'll use to encapsulate HTML parsed by askama into valid HTML for axum to serve.
|
||||
pub struct HtmlTemplate<T>(pub T);
|
||||
|
||||
/// Allows us to convert Askama HTML templates into valid HTML for axum to serve in the response.
|
||||
impl<T> IntoResponse for HtmlTemplate<T>
|
||||
where
|
||||
T: Template,
|
||||
{
|
||||
fn into_response(self) -> Response {
|
||||
// Attempt to render the template with askama
|
||||
match self.0.render() {
|
||||
// If we're able to successfully parse and aggregate the template, serve it
|
||||
Ok(html) => Html(html).into_response(),
|
||||
// If we're not, return an error or some bit of fallback HTML
|
||||
Err(err) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Failed to render template. Error: {}", err),
|
||||
)
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
</head>
|
||||
|
||||
<body class="bg-stone-400">
|
||||
<nav class="bg-stone-800">
|
||||
<nav class="bg-stone-900">
|
||||
<div class="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
|
||||
<div class="relative flex h-16 items-center justify-between">
|
||||
<div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
|
||||
|
|
@ -41,14 +41,14 @@
|
|||
<div class="hidden sm:ml-6 sm:block">
|
||||
<div class="flex space-x-4">
|
||||
<!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
|
||||
<a href="/" class="bg-stone-900 text-stone-100 rounded-md px-3 py-2 text-sm font-medium"
|
||||
<a href="/" class="bg-stone-900 text-stone-100 rounded-md px-3 py-2 text-sm font-bold"
|
||||
aria-current="page">Home</a>
|
||||
<a href="/blog"
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium">Blog</a>
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white rounded-md px-3 py-2 text-sm font-bold">Blog</a>
|
||||
<a href="/projects"
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium">Projects</a>
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white rounded-md px-3 py-2 text-sm font-bold">Projects</a>
|
||||
<a href="/resume"
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium">Resume</a>
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white rounded-md px-3 py-2 text-sm font-bold">Resume</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -62,11 +62,11 @@
|
|||
<a href="/" class="bg-stone-900 text-white block rounded-md px-3 py-2 text-base font-medium"
|
||||
aria-current="page">Home</a>
|
||||
<a href="/blog"
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Blog</a>
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white block rounded-md px-3 py-2 text-base font-bold">Blog</a>
|
||||
<a href="/projects"
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Projects</a>
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white block rounded-md px-3 py-2 text-base font-bold">Projects</a>
|
||||
<a href="/resume"
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Resume</a>
|
||||
class="text-stone-300 hover:bg-stone-700 hover:text-white block rounded-md px-3 py-2 text-base font-bold">Resume</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
|||
|
|
@ -2,5 +2,48 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>HI</h1>
|
||||
<div class="grid grid-cols-3 gap-4 mt-4 mx-4">
|
||||
<div class="cols-span-1 bg-stone-200 pt-12 hover:bg-stone-300">
|
||||
<a href="#"></a>
|
||||
<h1 class="font-extrabold text-center text-2xl">Title</h1>
|
||||
<p class="text-center ml-4">post desc</p>
|
||||
<p class="text-right pt-12 pb-4 mr-12 font-bold">post date</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="cols-span-1 bg-stone-200 pt-12 hover:bg-stone-300">
|
||||
<a href="#">
|
||||
<h1 class="font-extrabold text-center text-2xl">Title</h1>
|
||||
<p class="text-center ml-4">post desc</p>
|
||||
<p class="text-right pt-12 pb-4 mr-12 font-bold">post date</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="cols-span-1 bg-stone-200 pt-12 hover:bg-stone-300">
|
||||
<a href="#">
|
||||
<h1 class="font-extrabold text-center text-2xl">Title</h1>
|
||||
<p class="text-center ml-4">post desc</p>
|
||||
<p class="text-right pt-12 pb-4 mr-12 font-bold">post date</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="cols-span-1 bg-stone-200 pt-12 hover:bg-stone-300">
|
||||
<a href="#">
|
||||
<h1 class="font-extrabold text-center text-2xl">Title</h1>
|
||||
<p class="text-center ml-4">post desc</p>
|
||||
<p class="text-right pt-12 pb-4 mr-12 font-bold">post date</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="cols-span-1 bg-stone-200 pt-12 hover:bg-stone-300">
|
||||
<a href="#">
|
||||
<h1 class="font-extrabold text-center text-2xl">Title</h1>
|
||||
<p class="text-center ml-4">post desc</p>
|
||||
<p class="text-right pt-12 pb-4 mr-12 font-bold">post date</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="cols-span-1 bg-stone-200 pt-12 hover:bg-stone-300">
|
||||
<a href="#">
|
||||
<h1 class="font-extrabold text-center text-2xl">Title</h1>
|
||||
<p class="text-center ml-4">post desc</p>
|
||||
<p class="text-right pt-12 pb-4 mr-12 font-bold">post date</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -24,4 +24,5 @@
|
|||
social media because I view those as channels primarily for discoverability. In contrast, this website represents my
|
||||
own space on the web—a space I own, moderate, and host. This independence ensures that my content remains unaffected
|
||||
by the profit-driven algorithms of other platforms.</p>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
8
templates/post.html
Normal file
8
templates/post.html
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<!-- prettier-ignore -->
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="text-4xl">{{ title }}</h1>
|
||||
<p class="font-bold">{{ description }}</p>
|
||||
<p class="font-extrabold">{{ post_date }}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -2,4 +2,108 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="mx-72">
|
||||
<h1 class="text-4xl mt-12">Things I’ve made trying to put my dent in the universe.</h1>
|
||||
|
||||
<p class="mb-24">I’ve worked on tons of little projects over the years but these are the ones that I’m most proud
|
||||
of.
|
||||
Many of them
|
||||
are open-source, so if you see something that piques your interest, check out the code and contribute if you have
|
||||
ideas
|
||||
for how it can be improved.</p>
|
||||
<ul role="list" class="grid grid-cols-1 gap-x-12 gap-y-16 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<li class="group relative flex flex-col items-start">
|
||||
<div
|
||||
class="relative z-10 flex h-12 w-12 items-center justify-center rounded-full bg-white shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0">
|
||||
<img alt="" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="h-8 w-8"
|
||||
style="color: transparent;" src="/assets/sk-extract.png">
|
||||
</div>
|
||||
<h2 class="mt-6 text-base font-semibold text-zinc-800 dark:text-zinc-100">
|
||||
<div
|
||||
class="absolute -inset-x-4 -inset-y-6 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 sm:-inset-x-6 sm:rounded-2xl dark:bg-zinc-800/50">
|
||||
</div><a href="#"><span class="absolute -inset-x-4 -inset-y-6 z-20 sm:-inset-x-6 sm:rounded-2xl"></span><span
|
||||
class="relative z-10">SK-Extract</span></a>
|
||||
</h2>
|
||||
<p class="relative z-10 mt-2 text-sm text-stone-100 dark:text-stone-100">Single binary tool for all of your
|
||||
extraction needs!</p>
|
||||
<p
|
||||
class="relative z-10 mt-6 flex text-sm font-medium text-emerald-300 transition group-hover:text-emerald-500 dark:text-emerald-700">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" class="h-6 w-6 flex-none">
|
||||
<path
|
||||
d="M15.712 11.823a.75.75 0 1 0 1.06 1.06l-1.06-1.06Zm-4.95 1.768a.75.75 0 0 0 1.06-1.06l-1.06 1.06Zm-2.475-1.414a.75.75 0 1 0-1.06-1.06l1.06 1.06Zm4.95-1.768a.75.75 0 1 0-1.06 1.06l1.06-1.06Zm3.359.53-.884.884 1.06 1.06.885-.883-1.061-1.06Zm-4.95-2.12 1.414-1.415L12 6.344l-1.415 1.413 1.061 1.061Zm0 3.535a2.5 2.5 0 0 1 0-3.536l-1.06-1.06a4 4 0 0 0 0 5.656l1.06-1.06Zm4.95-4.95a2.5 2.5 0 0 1 0 3.535L17.656 12a4 4 0 0 0 0-5.657l-1.06 1.06Zm1.06-1.06a4 4 0 0 0-5.656 0l1.06 1.06a2.5 2.5 0 0 1 3.536 0l1.06-1.06Zm-7.07 7.07.176.177 1.06-1.06-.176-.177-1.06 1.06Zm-3.183-.353.884-.884-1.06-1.06-.884.883 1.06 1.06Zm4.95 2.121-1.414 1.414 1.06 1.06 1.415-1.413-1.06-1.061Zm0-3.536a2.5 2.5 0 0 1 0 3.536l1.06 1.06a4 4 0 0 0 0-5.656l-1.06 1.06Zm-4.95 4.95a2.5 2.5 0 0 1 0-3.535L6.344 12a4 4 0 0 0 0 5.656l1.06-1.06Zm-1.06 1.06a4 4 0 0 0 5.657 0l-1.061-1.06a2.5 2.5 0 0 1-3.535 0l-1.061 1.06Zm7.07-7.07-.176-.177-1.06 1.06.176.178 1.06-1.061Z"
|
||||
fill="currentColor"></path>
|
||||
</svg><span class="ml-2">github.com</span>
|
||||
</p>
|
||||
</li>
|
||||
<li class="group relative flex flex-col items-start">
|
||||
<div
|
||||
class="relative z-10 flex h-12 w-12 items-center justify-center rounded-full bg-white shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0">
|
||||
<img alt="" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="h-8 w-8"
|
||||
style="color: transparent;" src="/assets/SK-test-logo.png">
|
||||
</div>
|
||||
<h2 class="mt-6 text-base font-semibold text-zinc-800 dark:text-zinc-100">
|
||||
<div
|
||||
class="absolute -inset-x-4 -inset-y-6 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 sm:-inset-x-6 sm:rounded-2xl dark:bg-zinc-800/50">
|
||||
</div><a href="#"><span class="absolute -inset-x-4 -inset-y-6 z-20 sm:-inset-x-6 sm:rounded-2xl"></span><span
|
||||
class="relative z-10">Skout-Bot</span></a>
|
||||
</h2>
|
||||
<p class="relative z-10 mt-2 text-sm text-stone-100 dark:text-stone-100">A discord bot to help manage my private
|
||||
server.</p>
|
||||
<p
|
||||
class="relative z-10 mt-6 flex text-sm font-medium text-emerald-300 transition group-hover:text-emerald-500 dark:text-emerald-700">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" class="h-6 w-6 flex-none">
|
||||
<path
|
||||
d="M15.712 11.823a.75.75 0 1 0 1.06 1.06l-1.06-1.06Zm-4.95 1.768a.75.75 0 0 0 1.06-1.06l-1.06 1.06Zm-2.475-1.414a.75.75 0 1 0-1.06-1.06l1.06 1.06Zm4.95-1.768a.75.75 0 1 0-1.06 1.06l1.06-1.06Zm3.359.53-.884.884 1.06 1.06.885-.883-1.061-1.06Zm-4.95-2.12 1.414-1.415L12 6.344l-1.415 1.413 1.061 1.061Zm0 3.535a2.5 2.5 0 0 1 0-3.536l-1.06-1.06a4 4 0 0 0 0 5.656l1.06-1.06Zm4.95-4.95a2.5 2.5 0 0 1 0 3.535L17.656 12a4 4 0 0 0 0-5.657l-1.06 1.06Zm1.06-1.06a4 4 0 0 0-5.656 0l1.06 1.06a2.5 2.5 0 0 1 3.536 0l1.06-1.06Zm-7.07 7.07.176.177 1.06-1.06-.176-.177-1.06 1.06Zm-3.183-.353.884-.884-1.06-1.06-.884.883 1.06 1.06Zm4.95 2.121-1.414 1.414 1.06 1.06 1.415-1.413-1.06-1.061Zm0-3.536a2.5 2.5 0 0 1 0 3.536l1.06 1.06a4 4 0 0 0 0-5.656l-1.06 1.06Zm-4.95 4.95a2.5 2.5 0 0 1 0-3.535L6.344 12a4 4 0 0 0 0 5.656l1.06-1.06Zm-1.06 1.06a4 4 0 0 0 5.657 0l-1.061-1.06a2.5 2.5 0 0 1-3.535 0l-1.061 1.06Zm7.07-7.07-.176-.177-1.06 1.06.176.178 1.06-1.061Z"
|
||||
fill="currentColor"></path>
|
||||
</svg><span class="ml-2">github.com</span>
|
||||
</p>
|
||||
</li>
|
||||
<li class="group relative flex flex-col items-start">
|
||||
<div
|
||||
class="relative z-10 flex h-12 w-12 items-center justify-center rounded-full bg-white shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0">
|
||||
<img alt="" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="h-8 w-8"
|
||||
style="color: transparent;" src="/assets/sunserver.png">
|
||||
</div>
|
||||
<h2 class="mt-6 text-base font-semibold text-zinc-800 dark:text-zinc-100">
|
||||
<div
|
||||
class="absolute -inset-x-4 -inset-y-6 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 sm:-inset-x-6 sm:rounded-2xl dark:bg-zinc-800/50">
|
||||
</div><a href="#"><span class="absolute -inset-x-4 -inset-y-6 z-20 sm:-inset-x-6 sm:rounded-2xl"></span><span
|
||||
class="relative z-10">Sun Server</span></a>
|
||||
</h2>
|
||||
<p class="relative z-10 mt-2 text-sm text-stone-100 dark:text-stone-100">Data source for Node RED lighting control
|
||||
</p>
|
||||
<p
|
||||
class="relative z-10 mt-6 flex text-sm font-medium text-emerald-300 transition group-hover:text-emerald-500 dark:text-emerald-700">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" class="h-6 w-6 flex-none">
|
||||
<path
|
||||
d="M15.712 11.823a.75.75 0 1 0 1.06 1.06l-1.06-1.06Zm-4.95 1.768a.75.75 0 0 0 1.06-1.06l-1.06 1.06Zm-2.475-1.414a.75.75 0 1 0-1.06-1.06l1.06 1.06Zm4.95-1.768a.75.75 0 1 0-1.06 1.06l1.06-1.06Zm3.359.53-.884.884 1.06 1.06.885-.883-1.061-1.06Zm-4.95-2.12 1.414-1.415L12 6.344l-1.415 1.413 1.061 1.061Zm0 3.535a2.5 2.5 0 0 1 0-3.536l-1.06-1.06a4 4 0 0 0 0 5.656l1.06-1.06Zm4.95-4.95a2.5 2.5 0 0 1 0 3.535L17.656 12a4 4 0 0 0 0-5.657l-1.06 1.06Zm1.06-1.06a4 4 0 0 0-5.656 0l1.06 1.06a2.5 2.5 0 0 1 3.536 0l1.06-1.06Zm-7.07 7.07.176.177 1.06-1.06-.176-.177-1.06 1.06Zm-3.183-.353.884-.884-1.06-1.06-.884.883 1.06 1.06Zm4.95 2.121-1.414 1.414 1.06 1.06 1.415-1.413-1.06-1.061Zm0-3.536a2.5 2.5 0 0 1 0 3.536l1.06 1.06a4 4 0 0 0 0-5.656l-1.06 1.06Zm-4.95 4.95a2.5 2.5 0 0 1 0-3.535L6.344 12a4 4 0 0 0 0 5.656l1.06-1.06Zm-1.06 1.06a4 4 0 0 0 5.657 0l-1.061-1.06a2.5 2.5 0 0 1-3.535 0l-1.061 1.06Zm7.07-7.07-.176-.177-1.06 1.06.176.178 1.06-1.061Z"
|
||||
fill="currentColor"></path>
|
||||
</svg><span class="ml-2">github.com</span>
|
||||
</p>
|
||||
</li>
|
||||
<li class="group relative flex flex-col items-start">
|
||||
<div
|
||||
class="relative z-10 flex h-12 w-12 items-center justify-center rounded-full bg-white shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0">
|
||||
<img alt="" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="h-8 w-8"
|
||||
style="color: transparent;" src="/assets/aocollapse.png">
|
||||
</div>
|
||||
<h2 class="mt-6 text-base font-semibold text-zinc-800 dark:text-zinc-100">
|
||||
<div
|
||||
class="absolute -inset-x-4 -inset-y-6 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 sm:-inset-x-6 sm:rounded-2xl dark:bg-zinc-800/50">
|
||||
</div><a href="#"><span class="absolute -inset-x-4 -inset-y-6 z-20 sm:-inset-x-6 sm:rounded-2xl"></span><span
|
||||
class="relative z-10">AO Collapse</span></a>
|
||||
</h2>
|
||||
<p class="relative z-10 mt-2 text-sm text-stone-100 dark:text-stone-100">Wave Function Collapse proceduaral
|
||||
generation library written in rust.</p>
|
||||
<p
|
||||
class="relative z-10 mt-6 flex text-sm font-medium text-emerald-300 transition group-hover:text-emerald-500 dark:text-emerald-700">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" class="h-6 w-6 flex-none">
|
||||
<path
|
||||
d="M15.712 11.823a.75.75 0 1 0 1.06 1.06l-1.06-1.06Zm-4.95 1.768a.75.75 0 0 0 1.06-1.06l-1.06 1.06Zm-2.475-1.414a.75.75 0 1 0-1.06-1.06l1.06 1.06Zm4.95-1.768a.75.75 0 1 0-1.06 1.06l1.06-1.06Zm3.359.53-.884.884 1.06 1.06.885-.883-1.061-1.06Zm-4.95-2.12 1.414-1.415L12 6.344l-1.415 1.413 1.061 1.061Zm0 3.535a2.5 2.5 0 0 1 0-3.536l-1.06-1.06a4 4 0 0 0 0 5.656l1.06-1.06Zm4.95-4.95a2.5 2.5 0 0 1 0 3.535L17.656 12a4 4 0 0 0 0-5.657l-1.06 1.06Zm1.06-1.06a4 4 0 0 0-5.656 0l1.06 1.06a2.5 2.5 0 0 1 3.536 0l1.06-1.06Zm-7.07 7.07.176.177 1.06-1.06-.176-.177-1.06 1.06Zm-3.183-.353.884-.884-1.06-1.06-.884.883 1.06 1.06Zm4.95 2.121-1.414 1.414 1.06 1.06 1.415-1.413-1.06-1.061Zm0-3.536a2.5 2.5 0 0 1 0 3.536l1.06 1.06a4 4 0 0 0 0-5.656l-1.06 1.06Zm-4.95 4.95a2.5 2.5 0 0 1 0-3.535L6.344 12a4 4 0 0 0 0 5.656l1.06-1.06Zm-1.06 1.06a4 4 0 0 0 5.657 0l-1.061-1.06a2.5 2.5 0 0 1-3.535 0l-1.061 1.06Zm7.07-7.07-.176-.177-1.06 1.06.176.178 1.06-1.061Z"
|
||||
fill="currentColor"></path>
|
||||
</svg><span class="ml-2">github.com</span>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -2,5 +2,4 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>HI</h1>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue