Templating?
This commit is contained in:
parent
2295b7d5ef
commit
8dd1ffbdf5
9 changed files with 305 additions and 9 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,6 +1,6 @@
|
||||||
/target
|
/target
|
||||||
/.direnv
|
/.direnv
|
||||||
|
/static/style.css
|
||||||
|
|
||||||
# Added by cargo
|
# Added by cargo
|
||||||
#
|
#
|
||||||
|
|
117
Cargo.lock
generated
117
Cargo.lock
generated
|
@ -156,6 +156,12 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
|
@ -259,6 +265,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.12"
|
version = "0.5.12"
|
||||||
|
@ -268,6 +283,15 @@ dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.19"
|
version = "0.8.19"
|
||||||
|
@ -352,6 +376,16 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fs2"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fsevent-sys"
|
name = "fsevent-sys"
|
||||||
version = "4.1.0"
|
version = "4.1.0"
|
||||||
|
@ -450,6 +484,15 @@ dependencies = [
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fxhash"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.7"
|
||||||
|
@ -624,6 +667,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "instant"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
|
@ -703,8 +755,10 @@ dependencies = [
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"config",
|
"config",
|
||||||
"futures",
|
"futures",
|
||||||
|
"minijinja",
|
||||||
"notify",
|
"notify",
|
||||||
"redact",
|
"redact",
|
||||||
|
"sled",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
|
@ -750,6 +804,15 @@ dependencies = [
|
||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minijinja"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7165d0e94806d52ad5295e4b54a95176d831814840bc067298ca647e1c956338"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -863,6 +926,17 @@ version = "3.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||||
|
dependencies = [
|
||||||
|
"instant",
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core 0.8.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.2"
|
version = "0.12.2"
|
||||||
|
@ -870,7 +944,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
|
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"parking_lot_core",
|
"parking_lot_core 0.9.10",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"instant",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall 0.2.16",
|
||||||
|
"smallvec",
|
||||||
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1002,6 +1090,15 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -1219,6 +1316,22 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sled"
|
||||||
|
version = "0.34.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"fs2",
|
||||||
|
"fxhash",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"parking_lot 0.11.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.13.2"
|
version = "1.13.2"
|
||||||
|
@ -1308,7 +1421,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"parking_lot",
|
"parking_lot 0.12.2",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
|
|
@ -10,8 +10,10 @@ axum = { version = "0.7.5", features = ["macros", "tokio"] }
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
config = "0.14.0"
|
config = "0.14.0"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
|
minijinja = "2.0.1"
|
||||||
notify = "6.1.1"
|
notify = "6.1.1"
|
||||||
redact = { version = "0.1.9", features = ["serde"] }
|
redact = { version = "0.1.9", features = ["serde"] }
|
||||||
|
sled = "0.34.7"
|
||||||
tokio = { version = "1.37.0", features = ["full"] }
|
tokio = { version = "1.37.0", features = ["full"] }
|
||||||
tower = "0.4.13"
|
tower = "0.4.13"
|
||||||
tower-http = { version = "0.5.2", features = ["fs"] }
|
tower-http = { version = "0.5.2", features = ["fs"] }
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
lldb
|
lldb
|
||||||
pkg-config
|
pkg-config
|
||||||
inotify-tools
|
inotify-tools
|
||||||
|
tailwindcss
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
73
src/main.rs
73
src/main.rs
|
@ -1,13 +1,20 @@
|
||||||
use axum::{serve, Router};
|
use axum::extract::State;
|
||||||
|
use axum::response::IntoResponse;
|
||||||
|
use axum::routing::get;
|
||||||
|
use axum::{http::StatusCode, response::Html, serve, Router};
|
||||||
|
use minijinja::{context, Environment};
|
||||||
use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
|
use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
|
use std::sync::Arc;
|
||||||
use std::{path::PathBuf, str::FromStr, sync::OnceLock};
|
use std::{path::PathBuf, str::FromStr, sync::OnceLock};
|
||||||
use tokio::sync::mpsc::channel;
|
use tokio::sync::mpsc::channel;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
use tower_livereload::{LiveReloadLayer, Reloader};
|
use tower_livereload::{LiveReloadLayer, Reloader};
|
||||||
pub use tracing::{debug, error, info, warn};
|
pub use tracing::{debug, error, info, warn};
|
||||||
|
|
||||||
type Berr = Box<dyn std::error::Error>;
|
#[derive(Debug)]
|
||||||
type Besult<T> = Result<T, Berr>;
|
struct Berr(Box<dyn std::error::Error>);
|
||||||
|
type Besult<T> = std::result::Result<T, Berr>;
|
||||||
|
|
||||||
mod observe {
|
mod observe {
|
||||||
pub fn setup_logging() {
|
pub fn setup_logging() {
|
||||||
|
@ -28,23 +35,58 @@ fn static_file_dir() -> &'static PathBuf {
|
||||||
STATIC_FILE_DIR.get_or_init(|| PathBuf::from_str("static").unwrap())
|
STATIC_FILE_DIR.get_or_init(|| PathBuf::from_str("static").unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AppState {
|
||||||
|
templates: Arc<Mutex<Environment<'static>>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Besult<()> {
|
async fn main() -> Besult<()> {
|
||||||
// load configuration?
|
// load configuration?
|
||||||
observe::setup_logging();
|
observe::setup_logging();
|
||||||
|
|
||||||
|
// TODO: only start tailwind if in dev mode?
|
||||||
|
tokio::spawn(async move {
|
||||||
|
info!("Starting tailwind...");
|
||||||
|
let tw = tokio::process::Command::new("tailwindcss")
|
||||||
|
.args(["-i", "src/style.css", "-o", "static/style.css", "--watch"])
|
||||||
|
.spawn();
|
||||||
|
info!("Tailwind spawned. {tw:#?}");
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut templates = Arc::new(Mutex::new(Environment::new()));
|
||||||
|
while let Some(d) = tokio::fs::read_dir("templates").await?.next_entry().await? {
|
||||||
|
templates.clone().lock().await.add_template(
|
||||||
|
d.path().to_string_lossy().as_ref(),
|
||||||
|
&std::fs::read_to_string(d.path())?,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
// pulling the watcher into main's scope lets it live until the program dies
|
// pulling the watcher into main's scope lets it live until the program dies
|
||||||
let (rl_layer, _watcher) = live_reload_layer()?;
|
let (rl_layer, _watcher) = live_reload_layer()?;
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
info!("Listening on {listener:#?}");
|
info!("Listening on {listener:#?}");
|
||||||
let router = Router::new()
|
let router = Router::new()
|
||||||
|
.route("/", get(index))
|
||||||
.nest_service("/static", ServeDir::new(static_file_dir()))
|
.nest_service("/static", ServeDir::new(static_file_dir()))
|
||||||
.layer(rl_layer);
|
.layer(rl_layer)
|
||||||
|
.with_state(AppState { templates });
|
||||||
|
|
||||||
Ok(serve(listener, router).await?)
|
Ok(serve(listener, router).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn index(State(state): State<AppState>) -> Besult<Html<String>> {
|
||||||
|
Ok(Html(
|
||||||
|
state
|
||||||
|
.templates
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.get_template("page.html")?
|
||||||
|
.render(context!())?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn live_reload_layer() -> Besult<(LiveReloadLayer, RecommendedWatcher)> {
|
fn live_reload_layer() -> Besult<(LiveReloadLayer, RecommendedWatcher)> {
|
||||||
let rl_layer = LiveReloadLayer::new();
|
let rl_layer = LiveReloadLayer::new();
|
||||||
let rl = rl_layer.reloader();
|
let rl = rl_layer.reloader();
|
||||||
|
@ -90,3 +132,26 @@ fn static_file_watcher(
|
||||||
|
|
||||||
Ok(watcher)
|
Ok(watcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for Berr {
|
||||||
|
fn into_response(self) -> axum::http::Response<axum::body::Body> {
|
||||||
|
error!("webserver error: {:?}", self.0);
|
||||||
|
(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("internal server error: {}", self.0),
|
||||||
|
)
|
||||||
|
.into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This enables using `?` on functions that return `Result<_, anyhow::Error>`
|
||||||
|
// to turn them into `Result<_, AppError>`. That way you don't need to do that
|
||||||
|
// manually.
|
||||||
|
impl<E> From<E> for Berr
|
||||||
|
where
|
||||||
|
E: Into<Box<dyn std::error::Error>>,
|
||||||
|
{
|
||||||
|
fn from(err: E) -> Self {
|
||||||
|
Self(err.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
65
src/style.css
Normal file
65
src/style.css
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* Catppuccin Mocha */
|
||||||
|
--Rosewater: #f5e0dc;
|
||||||
|
--Flamingo: #f2cdcd;
|
||||||
|
--Pink: #f5c2e7;
|
||||||
|
--Mauve: #cba6f7;
|
||||||
|
--Red: #f38ba8;
|
||||||
|
--Maroon: #eba0ac;
|
||||||
|
--Peach: #fab387;
|
||||||
|
--Yellow: #f9e2af;
|
||||||
|
--Green: #a6e3a1;
|
||||||
|
--Teal: #94e2d5;
|
||||||
|
--Sky: #89dceb;
|
||||||
|
--Sapphire: #74c7ec;
|
||||||
|
--Blue: #89b4fa;
|
||||||
|
--Lavender: #b4befe;
|
||||||
|
--Text: #cdd6f4;
|
||||||
|
--Subtext1: #bac2de;
|
||||||
|
--Subtext0: #a6adc8;
|
||||||
|
--Overlay2: #9399b2;
|
||||||
|
--Overlay1: #7f849c;
|
||||||
|
--Overlay0: #6c7086;
|
||||||
|
--Surface2: #585b70;
|
||||||
|
--Surface1: #45475a;
|
||||||
|
--Surface0: #313244;
|
||||||
|
--Base: #1e1e2e;
|
||||||
|
--Mantle: #181825;
|
||||||
|
--Crust: #11111b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
/* Catppuccin Latte */
|
||||||
|
--Rosewater: #dc8a78;
|
||||||
|
--Flamingo: #dd7878;
|
||||||
|
--Pink: #ea76cb;
|
||||||
|
--Mauve: #8839ef;
|
||||||
|
--Red: #d20f39;
|
||||||
|
--Maroon: #e64553;
|
||||||
|
--Peach: #fe640b;
|
||||||
|
--Yellow: #df8e1d;
|
||||||
|
--Green: #40a02b;
|
||||||
|
--Teal: #179299;
|
||||||
|
--Sky: #04a5e5;
|
||||||
|
--Sapphire: #209fb5;
|
||||||
|
--Blue: #1e66f5;
|
||||||
|
--Lavender: #7287fd;
|
||||||
|
--Text: #4c4f69;
|
||||||
|
--Subtext1: #5c5f77;
|
||||||
|
--Subtext0: #6c6f85;
|
||||||
|
--Overlay2: #7c7f93;
|
||||||
|
--Overlay1: #8c8fa1;
|
||||||
|
--Overlay0: #9ca0b0;
|
||||||
|
--Surface2: #acb0be;
|
||||||
|
--Surface1: #bcc0cc;
|
||||||
|
--Surface0: #ccd0da;
|
||||||
|
--Base: #eff1f5;
|
||||||
|
--Mantle: #e6e9ef;
|
||||||
|
--Crust: #dce0e8;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
Sup Dawg
|
|
40
tailwind.config.js
Normal file
40
tailwind.config.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: ["./src/**/*.rs","./static/**/*.{html,js}"], theme: {
|
||||||
|
colors: {
|
||||||
|
|
||||||
|
rosewater: "var(--Rosewater)",
|
||||||
|
flamingo: "var(--Flamingo)",
|
||||||
|
pink: "var(--Pink)",
|
||||||
|
mauve: "var(--Mauve)",
|
||||||
|
red: "var(--Red)",
|
||||||
|
maroon: "var(--Maroon)",
|
||||||
|
peach: "var(--Peach)",
|
||||||
|
yellow: "var(--Yellow)",
|
||||||
|
green: "var(--Green)",
|
||||||
|
teal: "var(--Teal)",
|
||||||
|
sky: "var(--Sky)",
|
||||||
|
sapphire: "var(--Sapphire)",
|
||||||
|
blue: "var(--Blue)",
|
||||||
|
lavender: "var(--Lavender)",
|
||||||
|
text: "var(--Text)",
|
||||||
|
subtext1: "var(--Subtext1)",
|
||||||
|
subtext0: "var(--Subtext0)",
|
||||||
|
overlay2: "var(--Overlay2)",
|
||||||
|
overlay1: "var(--Overlay1)",
|
||||||
|
overlay0: "var(--Overlay0)",
|
||||||
|
surface2: "var(--Surface2)",
|
||||||
|
surface1: "var(--Surface1)",
|
||||||
|
surface0: "var(--Surface0)",
|
||||||
|
base: "var(--Base)",
|
||||||
|
mantle: "var(--Mantle)",
|
||||||
|
crust: "var(--Crust)",
|
||||||
|
|
||||||
|
},
|
||||||
|
extend: {
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
}
|
||||||
|
|
12
templates/page.html
Normal file
12
templates/page.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Sup</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/style.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-base text-text">
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in a new issue