Compare commits

..

8 commits

19 changed files with 589 additions and 49 deletions

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
bake/
www/css/
.sass-cache/

View file

@ -1,38 +1,77 @@
# Template: https://nixos-and-flakes.thiscute.world/development/intro
{
description = "Dev Shell for dobutterfliescry.net";
description = "cry64's dobutterfliescry.net";
inputs = {
systems.url = "github:nix-systems/default";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = {
self,
nixpkgs,
nixpkgs-unstable,
...
}: let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
};
pkgs-unstable = import nixpkgs-unstable {
inherit system;
};
} @ inputs: let
systems = import inputs.systems;
mkPkgs = pkgs: system:
import pkgs {
inherit system;
allowUnfree = false;
allowBroken = false;
overlays = builtins.attrValues self.overlays or {};
};
forAllSystems = f:
nixpkgs.lib.genAttrs systems (system:
f system (mkPkgs nixpkgs system) (mkPkgs nixpkgs-unstable system));
in {
devShells."${system}".default = pkgs.mkShell {
packages = [
# dev local server
pkgs.simple-http-server
# scss->css transpilation
# pkgs.sass seems broken on Nix currently, use pkgs.dark-sass instead
pkgs.dart-sass
# image baking (from .svg)
pkgs.imagemagick
];
shell = "${pkgs.bash}/bin/bash";
overlays.default = self: super: {
dobutterfliescry-net = super.stdenv.mkDerivation {
name = "dobutterfliescry.net";
src = self;
nativeBuildInputs = [super.makeWrapper];
installPhase = ''
mkdir -p $out
cp -r $src/www $out/
'';
};
};
checks = self.packages;
packages = forAllSystems (system: pkgs: upkgs: rec {
default = dobutterfliescry-net;
dobutterfliescry-net = pkgs.dobutterfliescry-net;
});
devShells = forAllSystems (system: pkgs: upkgs: let
devPackages = with pkgs; [
# dev local server
simple-http-server
# css baking
ruby.devEnv
rubyPackages_3_3.sass
# image baking (from .svg)
imagemagick
];
in {
default = pkgs.mkShell {
packages = devPackages;
shell = "${pkgs.bash}/bin/bash";
};
fhs =
(pkgs.buildFHSEnv
(pkgs.appimageTools.defaultFhsEnvArgs
// {
name = "dobutterfliescry.net-fhs";
targetPkgs = devPackages;
runScript = "bash";
extraOutputsToInstall = ["dev"];
})).env;
});
};
}

53
palette.theme Normal file
View file

@ -0,0 +1,53 @@
# REF: https://github.com/rose-pine/fish/blob/main/themes/Ros%C3%A9%20Pine%20Moon.theme
# syntax highlighting variables
# https://fishshell.com/docs/current/interactive.html#syntax-highlighting-variables
fish_color_normal e0def4
fish_color_command c4a7e7
fish_color_keyword 9ccfd8
fish_color_quote f6c177
fish_color_redirection 3e8fb0
fish_color_end 908caa
fish_color_error eb6f92
fish_color_param ea9a97
fish_color_comment 908caa
# fish_color_match --background=brblue
fish_color_selection --reverse
# fish_color_history_current --bold
fish_color_operator e0def4
fish_color_escape 3e8fb0
fish_color_autosuggestion 908caa
fish_color_cwd ea9a97
# fish_color_cwd_root red
fish_color_user f6c177
fish_color_host 9ccfd8
fish_color_host_remote c4a7e7
fish_color_cancel e0def4
fish_color_search_match --background=232136
fish_color_valid_path
# pager color variables
# https://fishshell.com/docs/current/interactive.html#pager-color-variables
fish_pager_color_progress ea9a97
fish_pager_color_background --background=2a273f
fish_pager_color_prefix 9ccfd8
fish_pager_color_completion 908caa
fish_pager_color_description 908caa
fish_pager_color_secondary_background
fish_pager_color_secondary_prefix
fish_pager_color_secondary_completion
fish_pager_color_secondary_description
fish_pager_color_selected_background --background=393552
fish_pager_color_selected_prefix 9ccfd8
fish_pager_color_selected_completion e0def4
fish_pager_color_selected_description e0def4
# custom color variables
fish_color_subtle 908caa
fish_color_text e0def4
fish_color_love eb6f92
fish_color_gold f6c177
fish_color_rose ea9a97
fish_color_pine 3e8fb0
fish_color_foam 9ccfd8
fish_color_iris c4a7e7

8
serve
View file

@ -4,7 +4,7 @@
# | sass
# ===== Configuration ===== #
ADDR="127.0.01" # bind address
ADDR="127.0.0.1" # bind address
PORT="8000" # bind port
WEBROOT="www" # root web directory
USE_INDEX=true
@ -32,7 +32,7 @@ function watch_scss {
}
function host {
local args=$@
local args=( "$@" )
# Apply Flags
if [[ "$NO_CACHE" == true ]]; then
args+=("--nocache")
@ -44,7 +44,7 @@ function host {
# Apply Options
args+=(--ip "$ADDR" --port "$PORT")
simple-http-server $args $@ -- "$WEBROOT"
simple-http-server "${args[@]}" "$@" -- "$WEBROOT"
}
trap cleanup EXIT
@ -56,4 +56,4 @@ watch_scss &
SASS_PID=$!
# host dev server
host ${SRV_ARGS[@]}
host "${SRV_ARGS[@]}"

View file

@ -0,0 +1,72 @@
html, body {
height: 100%;
margin: 0;
background-color: #0e0d14;
}
.centered {
position: absolute;
inset: 0 0 0 0;
margin: auto;
display: flex;
}
.heading {
font-family: monospace;
font-size: 2em;
font-weight: bold;
color: #ffc0cb; /* #ac4aed */
}
/* =========================================================== *
* Type Writer Effect *
/* =========================================================== */
#typing-wrapper {
margin: auto auto;
width: 13ch; /* prompt + command + cursor length */
text-align: start;
border: 0.5ch solid #ffc0cb; /* #ac4aed */
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
align-items: start;
}
#typing-prompt {
width: 12ch; /* prompt + command length */
animation: typing 3s steps(10), cursor-blink 0.6s steps(1, start) 3s infinite alternate;
white-space: nowrap;
overflow: hidden;
border-right: 1ch solid;
}
#typing-result {
/* "3.8s" means the result is shown 0.8s after typing ends */
animation: unhide 1s 3.8s forwards;
visibility: hidden;
white-space: pre-wrap; /* preserve linebreaks */
}
@keyframes typing {
from {
width: 5ch /* ignore prompt width */
}
}
@keyframes cursor-blink {
50% {
border-color: transparent
}
}
@keyframes unhide {
to {
visibility: visible
}
}

View file

@ -26,6 +26,7 @@ html, body {
#typing-wrapper {
margin: auto auto;
width: 39ch; /* prompt + command + cursor length */
height: 10ch;
text-align: start;
border: 0.5ch solid #ffc0cb; /* #ac4aed */
@ -33,7 +34,7 @@ html, body {
display: flex;
flex-direction: column;
justify-content: center;
justify-content: start;
align-content: center;
align-items: start;
}
@ -44,13 +45,14 @@ html, body {
white-space: nowrap;
overflow: hidden;
border-right: 1ch solid;
margin-bottom: 0.5ch;
}
#typing-result {
/* "3.8s" means the result is shown 0.8s after typing ends */
animation: unhide 1s 3.8s forwards;
/* "1.8s" means the result is shown 1.8s after typing ends */
animation: unhide 1s 4.8s forwards;
visibility: hidden;
white-space: pre-wrap; /* preserve linebreaks */
/* white-space: pre-wrap; /* preserve linebreaks */ */
}
@keyframes typing {

114
www/css-old/typing2.css Normal file
View file

@ -0,0 +1,114 @@
html, body {
height: 100%;
margin: 0;
background-color: #0e0d14;
}
.centered {
position: absolute;
inset: 0 0 0 0;
margin: auto;
display: flex;
}
.heading {
font-family: monospace;
font-size: 2em;
font-weight: bold;
color: #ffc0cb; /* #ac4aed */
}
/* =========================================================== *
* Type Writer Effect *
/* =========================================================== */
#typing-wrapper {
margin: auto auto;
width: 71ch; /* prompt + command + cursor length */
height: 21ch;
text-align: start;
border: 0.5ch solid #ffc0cb; /* #ac4aed */
padding: 20px;
display: flex;
flex-direction: column;
justify-content: start;
align-content: center;
align-items: start;
}
#typing-prompt {
width: 10ch; /* prompt + command length */
animation: kfs-typing 0.5s steps(4), kfs-cursor-blink 1.2s steps(1, start) 0.6s forwards;
white-space: nowrap;
overflow: hidden;
border-right: 1ch solid;
margin-bottom: 0.5ch;
}
#typing-result {
/* "4.8s" means the result is shown 1.8s after typing ends */
animation: unhide 1s 1.8s forwards;
visibility: hidden;
white-space: nowrap; /* preserve linebreaks */
}
#typing-prompt-segfault {
width: 47ch; /* prompt + command length */
/* animation: kfs-typing-segfault 3s steps(36) 2.6s, cursor-blink 0.6s steps(1, start) 3s infinite alternate; */
animation: kfs-typing-segfault 3s steps(36) 4s forwards, cursor-blink-segfault 0.6s steps(1, start) 7.1s infinite alternate;
white-space: nowrap;
overflow: hidden;
border-right: 1ch solid;
margin-bottom: 0.5ch;
visibility: hidden;
}
#typing-result-segfault {
/* "4.8s" means the result is shown 1.8s after typing ends */
animation: unhide 1s 8.3s forwards;
visibility: hidden;
white-space: nowrap; /* preserve linebreaks */
}
@keyframes kfs-typing {
from {
width: 6ch; /* ignore prompt width */
}
}
@keyframes kfs-typing-segfault {
from {
width: 11ch; /* ignore prompt width */
visibility: visible;
}
to {
visibility: visible;
}
}
@keyframes kfs-cursor-blink {
from {
border-color: transparent;
}
50% {
border-color: currentColor;
}
to {
border-color: transparent;
}
}
@keyframes cursor-blink-segfault {
50% {
border-color: transparent;
}
}
@keyframes unhide {
to {
visibility: visible;
}
}

80
www/css/tty_intro.css Normal file
View file

@ -0,0 +1,80 @@
/* background */
/* text */
/* #ac4aed */
html, body {
height: 100%;
margin: 0;
background-color: #0e0d14; }
.centered {
position: absolute;
inset: 0 0 0 0;
margin: auto;
display: flex; }
.heading {
font-family: monospace;
font-size: 2em;
font-weight: bold;
color: #ffc0cb;
}
/* =========================================================== *
* Type Writer Effect *
/* =========================================================== */
/* ==================
* Graphical Container
*/
/* ==================
* TTY Prompt
*/
@keyframes cursor-blink {
50% {
border-color: transparent; } }
/* =====================
* TTY Output
*/
@keyframes unhide-result {
to {
visibility: visible; } }
/* =========================
* Intended Public Interface
*/
.typing-wrapper-2ch-36ch {
margin: auto auto;
width: 39ch;
text-align: start;
border: 0.5ch solid #ffc0cb;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
align-items: start;
}
.typing-prompt-2ch-36ch-3s-0_6s {
width: 38ch;
/* XXX: fix scss leaves typing as a function! */
animation: kfs-typing-2ch 3s steps(36ch), cursor-blink 0.6s steps(1, start) 3s infinite alternate;
white-space: nowrap;
overflow: hidden;
border-right: 1ch solid;
}
.typing-result-3s-0_8s {
animation: unhide-result 1s 3.8s forwards;
visibility: hidden;
white-space: pre-wrap;
}
/* XXX: NAME CHANGED TO GENERIC */
@keyframes kfs-typing-2ch {
from {
width: 2ch /* ignore prompt width */
}
}
/*# sourceMappingURL=tty_intro.css.map */

View file

@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "AAAqB,gBAAgB;AAChB,gBAAgB;AAAE,aAAa;AAEpD,UAAW;EACT,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,CAAC;EACT,gBAAgB,EANN,OAAO;;AASnB,SAAU;EACR,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,OAAO;EACd,MAAM,EAAE,IAAI;EAEZ,OAAO,EAAE,IAAI;;AAGf,QAAS;EACP,WAAW,EAAE,SAAS;EACtB,SAAS,EAAE,GAAG;EACd,WAAW,EAAE,IAAI;EACjB,KAAK,EApBK,OAAO;;ACDnB;;iEAEiE;AAsBjE;;GAEG;AAsBH;;GAEG;AA2BH,uBAIC;EAHC,GAAI;IACF,YAAY,EAAE,WAAW;AAI7B;;GAEG;AAcH,wBAIC;EAHC,EAAG;IACD,UAAU,EAAE,OAAO;AAIvB;;GAEG;AA/ED,wBAAmD;EAEjD,MAAM,EAAE,SAAS;EACjB,KAAK,EAAE,IAAoC;EAG3C,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,MAAM;EACtB,eAAe,EAAE,MAAM;EACvB,aAAa,EAAE,MAAM;EACrB,WAAW,EAAE,KAAK;EAClB,UAAU,EAAE,KAAK;EAGjB,0CAA0C;EAC1C,MAAM,EAAE,mBAAmB;EAC3B,OAAO,EAAE,IAAI;;AAUf,+BAAqG;EACnG,KAAK,EAAE,IAA8B;EACrC,YAAY,EAAE,SAAS;EAGvB,WAAW,EAAE,MAAM;EACnB,QAAQ,EAAE,MAAM;EAGhB,SAAS,EACP,mFAC8E;;AAwBlF,sBAAkE;EAChE,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,QAAQ;EAGrB,SAAS,EACP,8BAA4D",
"sources": ["../scss/_base.scss","../scss/_tty.scss"],
"names": [],
"file": "tty_intro.css"
}

2
www/hown/README.md Normal file
View file

@ -0,0 +1,2 @@
# Html With Nix (HOWN/hown)
Hown is a system for static html/css compilation with the NixExpr language.

6
www/hown/default.nix Normal file
View file

@ -0,0 +1,6 @@
{mix, ...} @ inputs:
mix.newMixture inputs (mixture: {
includes.public = [
./tty.nix
];
})

8
www/hown/index.html Normal file
View file

@ -0,0 +1,8 @@
<!-->
{Text, mkTypingEffect, ...}:
mkTypingEffect {
head = Text "$ Do butterflies cry when they're sad?";
body = Text "Segmentation fault (core dumped)";
}
<-->

100
www/hown/tty.nix Normal file
View file

@ -0,0 +1,100 @@
# XXX: TODO: The howl.Div, howl.Text, ... types implement
# XXX: TODO: the HtmlTag' typeclass, which in turn implements
# XXX: TODO: a morphism to the nt.String type. This makes compiling
# XXX: TODO: to html super duper simple!!
{
nt,
howl,
...
}: let
inherit
(nt)
projectOnto
;
inherit
(howl)
# HTML
Div
Text
# CSS
StyleClass
StyleSheet
ContinuousAnimation
DiscreteAnimation
;
in {
typing = StyleSheet {
include = [./tty.css];
classes = {
typing-wrapper = null;
typing-prompt = promptLength: commandLength: duration: period:
StyleClass {
width = promptLength + commandLength; # ignore cursor
border.right = "TODO"; # cursor
# hide what the animation hasn't shown yet
whitespace = "nowrap";
overflow = "hidden";
# run typing animation then start cursor blink
animations = [
(DiscreteAnimation {
inherit duration;
keyframes = {
"0"
};
})
];
};
typing-result = typingDuration: delay:
StyleClass {
visibility = "hidden";
whitespace = "pre-wrap"; # preserve linebreaks
# show result once typing duration + delay is over
animations = [
(ContinuousAnimation {
name = "unhide-result";
duration = 1; # animation-duration
# timingFn = ; # animation-timing-function
delay = typingDuration + delay; # animation-delay
# animation-iteration-count
direction = "forwards"; # animation-direction
# animation-fill-mode
# animation-play-state
keyframes = {
"100" = {
visibility = "visible";
};
};
})
];
};
};
};
mkTypingEffect = decl': let
decl =
decl'
|> projectOnto
{
head = "";
body = "";
};
in
Div {
id = "typing-wrapper";
content = [
(Div {
id = "typing-prompt";
content = Text decl.head;
})
(Div {
id = "typing-result";
content = Text decl.body;
})
];
};
}

21
www/index-old.html Normal file
View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css-old/typing.css">
</head>
<body>
<div class="centered heading">
<div id="typing-wrapper">
<div id="typing-prompt">
$ do butterflies cry when they're sad?
</div>
<div id="typing-result">
Segmentation fault (core dumped)
</div>
</div>
</div>
</body>
</html>

View file

@ -1,17 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/typing.css">
<link rel="stylesheet" href="css/tty_intro.css">
</head>
<body>
<div class="centered heading">
<div id="typing-wrapper">
<div id="typing-wrapper-2ch-36ch">
<div id="typing-prompt">
<div id="typing-prompt-2ch-36ch-3s-0_6s">
$ Do butterflies cry when they're sad?
</div>
<div id="typing-result">
<div id="typing-result-3s-0_8s">
Segmentation fault (core dumped)
</div>

View file

@ -1,24 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/typing.css">
<link rel="stylesheet" href="css-old/typing2.css">
</head>
<body>
<div class="centered heading">
<div id="typing-wrapper">
<div id="typing-prompt">
grub> boot
<span style="color: #9ccfd8;">grub></span> <span style="color: #c4a7e7;">boot</span>
</div>
<div id="typing-result">
ERROR: Root device mounted successfully, but /sbin/init does not exist.
<div id="typing-result" style="color: #f6c177;">
ERROR: Root device mounted successfully, but /sbin/init does not exist.<br/><br/>
Bailing out, you are on your own.
Good luck
<i style="color: #eb6f92;">Bailing out, you are on your own.</i><br/>
<i style="color: #eb6f92;">Good luck</i><br/><br/>
sh: can't access tty; job control turned off
[rootfs ]#
sh: can't access tty; job control turned off<br/><br/>
</div>
<div id="typing-prompt-segfault">
<span style="color: #9ccfd8;">[rootfs ]#</span>
<span style="color: #c4a7e7;">do butterflies cry when they're sad?</span>
</div>
<div id="typing-result-segfault">
<i style="color: #eb6f92;">Segmentation fault (core dumped)</i>
</div>
</div>

View file

@ -2,7 +2,25 @@
* Type Writer Effect *
/* =========================================================== */
@use 'base';
/// Replace `$search` with `$replace` in `$string`
/// @author Kitty Giraudel
/// @param {String} $string - Initial string
/// @param {String} $search - Substring to replace
/// @param {String} $replace ('') - New value
/// @return {String} - Updated string
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function sanitize-int($int) {
@return str-replace(#{$int}, '.', '_')
}
/* ==================
* Graphical Container
@ -21,7 +39,9 @@
align-items: start;
text-align: start;
border: 0.5ch solid base.$color-txt;
// XXX: TODO: for some reason this causes an error??
/* border: 0.5ch solid base.$color-txt; */
border: 0.5ch solid #ffc0cb;
padding: 20px;
}
}
@ -30,7 +50,9 @@
* TTY Prompt
*/
@mixin typing-prompt($prompt-width, $command-width, $typing-duration, $blink-period) {
.typing-prompt-#{$prompt-width}-#{$command-width}-#{$typing-duration}-#{$blink-period} {
// XXX: TODO: relearn SCSS cause the thing below will break whenever an input is given as a float
// XXX: TODO: (period character interpretted as sub-attribute)
.typing-prompt-#{$prompt-width}-#{$command-width}-#{$typing-duration}-#{sanitize-int($blink-period)} {
width: $prompt-width + $command-width; // ignore cursor (right border)
border-right: 1ch solid; // cursor
@ -40,7 +62,7 @@
// typing animation then start cursor blink
animation:
typing $typing-duration steps($command-width),
typing($prompt-width) $typing-duration steps($command-width),
cursor-blink $blink-period steps(1, start) $typing-duration infinite alternate;
}
}
@ -63,7 +85,9 @@
* TTY Output
*/
@mixin typing-result($typing-duration, $reveal-delay) {
.typing-result-#{$typing-duration}-#{$reveal-delay} {
// XXX: TODO: relearn SCSS cause the thing below will break whenever an input is given as a float
// XXX: TODO: (period character interpretted as sub-attribute)
.typing-result-#{$typing-duration}-#{sanitize-int($reveal-delay)} {
visibility: hidden;
white-space: pre-wrap; // preserve linebreaks

View file

@ -1,3 +1,4 @@
@import "base";
@import "tty";
@include tty(2ch, 36ch, 3s, 0.6s, 0.8s);