adding document mode

I've been thinking a lot about the treehouse and I feel like it's time to say goodbye to the tree format.
This commit is contained in:
りき萌 2025-07-10 16:50:41 +02:00
parent 550c062327
commit 36705e7c1e
31 changed files with 940 additions and 409 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View file

@ -1,4 +1,4 @@
/* Color scheme. */
/* Color scheme */
:root {
--accent-red: #fb4c9e;
@ -36,6 +36,18 @@
}
}
/* Animations */
:root {
--transition-duration: 0.15s;
}
@media (prefers-reduced-motion: reduce) {
:root {
--transition-duration: 0;
}
}
/* Reset things to more sensible sizing rules */
* {

84
static/css/doc.css Normal file
View file

@ -0,0 +1,84 @@
main.doc {
--doc-text-width: 80ch;
display: flex;
flex-direction: row;
align-items: start;
& .vertical-center {
min-height: 100vh;
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
& .doc-text {
padding: 1.6rem;
max-width: var(--doc-text-width);
line-height: 1.6;
/* I was thinking a bunch about whether documents should be justified, and it honestly
causes more awkwardness than it solves. Web pages aren't quite books, unfortunately.
A cool feature that would help is text-wrap: pretty; but only Safari implements a nice
text layout algorithm for it. (Chrome prevents short last lines, Firefox doesn't
implement it at all) */
/* text-align: justify;
hyphens: auto; */
& p {
padding-top: 0.5lh;
padding-bottom: 0.5lh;
}
& h2 {
margin: 0;
padding-top: 1lh;
padding-bottom: 0.5lh;
}
& ul,
& ol {
/* Is there a better way to add spacing to the marker, other than adding whitespace? */
list-style: " ";
margin-top: 0;
margin-bottom: 0;
padding-bottom: 0.5lh;
}
}
& section.feed {
max-width: 40ch;
padding: 0.8rem;
padding-top: 3.2rem;
}
}
@media (max-width: 1500px) {
main.doc {
flex-direction: column;
align-items: center;
& .vertical-center {
min-height: 0;
}
& footer {
padding: 0.8rem;
}
& section.feed {
max-width: var(--doc-text-width);
margin-top: 2.4em;
padding: 1.6rem;
border-top: 1px solid var(--border-1);
}
}
}

View file

@ -1,73 +1,46 @@
/* Lay out the main containers. */
/* Main layout */
body {
--top-min-spacing: 40px;
--main-min-size: 100vh;
margin: 0;
display: grid;
grid-template-columns:
[left] minmax(
0,
clamp(136px, calc(100vw - (1920px - 360px - 160px)), 160px)
)
[center] minmax(0, auto)
[right] minmax(0, calc(100vw - (1920px - 360px)));
[left] 1fr
[right] auto;
grid-template-rows:
[top] minmax(
clamp(
var(--top-min-spacing),
calc(100vw - (1920px - 360px - 160px)),
128px
),
min-content
)
[title] minmax(9.6rem, min-content)
[main] 1fr
[bottom] min-content;
[nav] auto
[main] minmax(var(--main-min-size), auto)
[virtual] 100vh;
}
html {
/* Try to always leave a bunch of empty space at the bottom, but don't overdo it.
It's kind of awkward when you scroll to the bottom and your page just turns blank. */
--virtual-space-ratio: 1.75;
height: calc(100% * var(--virtual-space-ratio));
/* Leave a bunch of space at the top when scrolling to elements.
I'm honestly not sure why this is needed on <html> and not the scrolled-to element... */
scroll-padding-top: 10vh;
}
body {
min-height: calc(100% / var(--virtual-space-ratio));
.sidebar-sticky {
grid-column: right;
grid-row: main;
}
.noscript {
grid-row: top;
grid-column: center;
}
aside.sidebar {
position: sticky;
top: 0px;
#nav-logo {
grid-row: title;
grid-column: left;
max-width: 50rem;
height: 100vh;
padding: 0.8rem;
align-self: center;
justify-self: end;
}
section.page-header {
grid-row: title;
grid-column: center;
align-self: center;
display: flex;
}
main {
grid-column: left;
grid-row: main;
grid-column: center / center;
margin-right: 0.8rem;
min-width: 0;
}
footer {
@ -75,27 +48,25 @@ footer {
grid-column: center / center;
}
@media (max-width: 1200px) {
main {
grid-column: left / -1;
}
/* Narrower layout: sidebar is pushed to the top */
footer {
grid-column: 1 / -1;
}
}
@media (max-width: 450px) {
@media (max-width: 1280px) {
body {
--top-min-spacing: 0px;
--main-min-size: 0;
}
section.page-header {
grid-column: 1 / -1;
.sidebar-sticky {
grid-column: left;
grid-row: nav;
display: flex;
justify-content: center;
}
nav#nav-logo {
display: none;
aside.sidebar {
position: relative;
height: auto;
padding: 0;
}
}
@ -119,16 +90,6 @@ body {
/* Set up typography */
@font-face {
font-family: "RecVar";
/* NOTE: I put the hash in here manually instead of adding the complexity of piping CSS through
Handlebars because I don't really think it's worth it for this single asset.
Other assets are referenced rarely enough that caching probably isn't gonna make too much of
an impact.
It's unlikely I'll ever update the font anyways, so eh, whatever. */
src: url("../font/Recursive_VF_1.085.woff2?v=b3-41236e2f");
}
body,
pre,
code,
@ -192,7 +153,7 @@ input {
h1 {
--recursive-wght: 900;
font-size: 5.6rem;
font-size: 4.8rem;
font-feature-settings: var(--recursive-simplified-r) 0;
}
@ -246,6 +207,12 @@ h6 {
text-wrap: balance;
}
/* Other classes for controlling typography */
.nowrap {
white-space: nowrap;
}
/* Lay out elements a bit more compactly */
p,
@ -320,21 +287,21 @@ th-literate-program {
overflow: auto;
}
/* Also don't let images get out of hand */
/* Images */
img {
/* Prevent images from causing horizontal scrolling */
max-width: 100%;
height: auto;
}
/* Also regarding images - make them look a bit more pretty by default */
img.pic {
border-radius: 0.6rem;
margin: 0.8rem 0;
}
/* Image hints for tweaking rendering */
img {
/* Hints for tweaking rendering */
&[src*="+pixel"] {
image-rendering: pixelated;
border-radius: 0;
@ -378,8 +345,6 @@ a:visited {
color: var(--link-color-visited);
}
/* Allow for some secret links */
a.secret {
color: var(--text-color);
text-decoration: none;
@ -460,32 +425,224 @@ hr {
color: #6c2380;
}
/* Navigation button */
/* Feeds */
#nav-logo {
width: min-content;
height: min-content;
section.feed {
display: flex;
flex-direction: column;
/* Titles */
& a,
& a:visited {
color: var(--text-color);
}
& a:visited {
color: color-mix(
in srgb,
var(--background-color),
var(--text-color) 60%
);
}
& h1 {
--recursive-wght: 800;
font-size: 125%;
padding-top: 1.2rem;
padding-bottom: 1.2rem;
}
& h2 {
--recursive-wght: 600;
font-size: 100%;
padding: 0;
}
/* Articles */
& article {
display: flex;
flex-direction: column;
padding-bottom: 1.2rem;
line-height: 1.4;
& .info {
display: flex;
flex-direction: row;
flex-wrap: wrap;
font-size: 87.5%;
& > *:not(:first-child)::before {
content: "·";
padding: 0 0.4rem;
}
}
& .categories {
display: flex;
flex-direction: row;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
& > *::before {
content: "#";
}
& > *:not(:first-child)::before {
padding-left: 0.4rem;
}
}
}
}
#nav-logo .logo {
/* NOTE: Measurements in px for pixel perfection */
width: 120px;
height: 120px;
/* Page sidebar */
display: block;
opacity: 100%;
color: var(--text-color);
aside.sidebar {
overflow: clip;
& > a {
display: block;
height: min-content;
margin-top: auto;
}
}
header.floof {
margin-top: auto;
position: relative;
& > img {
display: block;
min-width: 0;
object-fit: cover;
object-position: 33% 0;
}
& > h1 {
position: absolute;
top: 3rem;
left: 3rem;
display: flex;
flex-direction: column;
line-height: 1;
width: min-content;
--recursive-wght: 900;
font-size: 5.6rem;
text-align: right;
transform: skew(-5deg, -5deg);
& .rikis {
width: max-content;
background-color: var(--text-color);
color: var(--background-color);
padding: 0.1em;
--shadow-color: var(--accent-pink);
box-shadow:
0.5px 0.5px 0 var(--shadow-color),
1px 1px 0 var(--shadow-color),
1.5px 1.5px 0 var(--shadow-color),
2px 2px 0 var(--shadow-color),
2.5px 2.5px 0 var(--shadow-color),
3px 3px 0 var(--shadow-color),
3.5px 3.5px 0 var(--shadow-color),
4px 4px 0 var(--shadow-color);
/*
import math
print("box-shadow:")
x = 0
max_x = 16
while x < max_x:
print(f"{x}px {x}px {math.pow(x / max_x, 2) * 16}px rgba(from var(--shadow-color) r g b / {math.pow(1 - x / max_x, 3)}),")
x += 0.5
*/
/* prettier-ignore */
box-shadow:
0px 0px 0.0px rgba(from var(--shadow-color) r g b / 1.0),
0.5px 0.5px 0.015625px rgba(from var(--shadow-color) r g b / 0.909149169921875),
1.0px 1.0px 0.0625px rgba(from var(--shadow-color) r g b / 0.823974609375),
1.5px 1.5px 0.140625px rgba(from var(--shadow-color) r g b / 0.744293212890625),
2.0px 2.0px 0.25px rgba(from var(--shadow-color) r g b / 0.669921875),
2.5px 2.5px 0.390625px rgba(from var(--shadow-color) r g b / 0.600677490234375),
3.0px 3.0px 0.5625px rgba(from var(--shadow-color) r g b / 0.536376953125),
3.5px 3.5px 0.765625px rgba(from var(--shadow-color) r g b / 0.476837158203125),
4.0px 4.0px 1.0px rgba(from var(--shadow-color) r g b / 0.421875),
4.5px 4.5px 1.265625px rgba(from var(--shadow-color) r g b / 0.371307373046875),
5.0px 5.0px 1.5625px rgba(from var(--shadow-color) r g b / 0.324951171875),
5.5px 5.5px 1.890625px rgba(from var(--shadow-color) r g b / 0.282623291015625),
6.0px 6.0px 2.25px rgba(from var(--shadow-color) r g b / 0.244140625),
6.5px 6.5px 2.640625px rgba(from var(--shadow-color) r g b / 0.209320068359375),
7.0px 7.0px 3.0625px rgba(from var(--shadow-color) r g b / 0.177978515625),
7.5px 7.5px 3.515625px rgba(from var(--shadow-color) r g b / 0.149932861328125),
8.0px 8.0px 4.0px rgba(from var(--shadow-color) r g b / 0.125),
8.5px 8.5px 4.515625px rgba(from var(--shadow-color) r g b / 0.102996826171875),
9.0px 9.0px 5.0625px rgba(from var(--shadow-color) r g b / 0.083740234375),
9.5px 9.5px 5.640625px rgba(from var(--shadow-color) r g b / 0.067047119140625),
10.0px 10.0px 6.25px rgba(from var(--shadow-color) r g b / 0.052734375),
10.5px 10.5px 6.890625px rgba(from var(--shadow-color) r g b / 0.040618896484375),
11.0px 11.0px 7.5625px rgba(from var(--shadow-color) r g b / 0.030517578125),
11.5px 11.5px 8.265625px rgba(from var(--shadow-color) r g b / 0.022247314453125),
12.0px 12.0px 9.0px rgba(from var(--shadow-color) r g b / 0.015625),
12.5px 12.5px 9.765625px rgba(from var(--shadow-color) r g b / 0.010467529296875),
13.0px 13.0px 10.5625px rgba(from var(--shadow-color) r g b / 0.006591796875),
13.5px 13.5px 11.390625px rgba(from var(--shadow-color) r g b / 0.003814697265625),
14.0px 14.0px 12.25px rgba(from var(--shadow-color) r g b / 0.001953125),
14.5px 14.5px 13.140625px rgba(from var(--shadow-color) r g b / 0.000823974609375),
15.0px 15.0px 14.0625px rgba(from var(--shadow-color) r g b / 0.000244140625),
15.5px 15.5px 15.015625px rgba(from var(--shadow-color) r g b / 3.0517578125e-05)
;
}
& .fluffy-little-house {
display: flex;
flex-direction: column;
background-color: var(--background-color);
width: min-content;
align-self: end;
padding-left: 0.8rem;
padding-right: 0.8rem;
padding-top: 0.4rem;
z-index: -1;
color: var(--text-color);
& .adjectives {
--recursive-wght: 800;
font-size: 1.6rem;
padding-top: 0.6rem;
}
& .house {
margin-top: -0.2em;
font-size: 3.6rem;
}
}
}
}
/* Navigation header (contains page title & breadcrumbs) */
h1.page-title {
--recursive-wght: 850;
--recursive-wght: 900;
margin-top: 0.32rem;
margin-bottom: 0.32rem;
margin-left: 3.6rem;
font-size: 4rem;
line-height: 1.2;
padding-top: 3lh;
padding-bottom: 0.5lh;
& a {
color: var(--text-color);
@ -506,7 +663,18 @@ h1.page-title {
}
}
/* Style badges */
@media (max-width: 1280px) {
h1.page-title {
padding-top: 0.25lh;
}
}
@media (max-width: 700px) {
h1.page-title {
font-size: 4rem;
}
}
span.badge {
--recursive-wght: 800;
--recursive-mono: 1;
@ -533,11 +701,9 @@ span.badge {
/* Style the footer */
footer {
padding-left: 1.6rem;
padding-right: 1.6rem;
margin-top: 6.4rem;
padding-bottom: 6.4rem;
width: 100%;
max-width: 90ch;
padding: 1.6rem 0.8rem;
display: flex;
flex-direction: row;
@ -610,9 +776,9 @@ dialog[open] {
/* Style emojis to be readable */
img[data-cast~="emoji"] {
max-width: 1.5em;
max-height: 1.5em;
vertical-align: bottom;
max-width: 1.3125em;
max-height: 1.3125em;
vertical-align: text-bottom;
object-fit: contain;
}

View file

@ -1,98 +1,3 @@
h1.page-title {
--recursive-wght: 900;
font-size: 5.6rem;
display: flex;
flex-direction: column;
line-height: 1;
width: min-content;
transform: skew(-5deg, -5deg);
& .rikis {
width: max-content;
background-color: var(--text-color);
color: var(--background-color);
padding: 0.1em;
--shadow-color: var(--accent-pink);
box-shadow:
0.5px 0.5px 0 var(--shadow-color),
1px 1px 0 var(--shadow-color),
1.5px 1.5px 0 var(--shadow-color),
2px 2px 0 var(--shadow-color),
2.5px 2.5px 0 var(--shadow-color),
3px 3px 0 var(--shadow-color),
3.5px 3.5px 0 var(--shadow-color),
4px 4px 0 var(--shadow-color);
/*
import math
print("box-shadow:")
x = 0
max_x = 16
while x < max_x:
print(f"{x}px {x}px {math.pow(x / max_x, 2) * 16}px rgba(from var(--shadow-color) r g b / {math.pow(1 - x / max_x, 3)}),")
x += 0.5
*/
/* prettier-ignore */
box-shadow:
0px 0px 0.0px rgba(from var(--shadow-color) r g b / 1.0),
0.5px 0.5px 0.015625px rgba(from var(--shadow-color) r g b / 0.909149169921875),
1.0px 1.0px 0.0625px rgba(from var(--shadow-color) r g b / 0.823974609375),
1.5px 1.5px 0.140625px rgba(from var(--shadow-color) r g b / 0.744293212890625),
2.0px 2.0px 0.25px rgba(from var(--shadow-color) r g b / 0.669921875),
2.5px 2.5px 0.390625px rgba(from var(--shadow-color) r g b / 0.600677490234375),
3.0px 3.0px 0.5625px rgba(from var(--shadow-color) r g b / 0.536376953125),
3.5px 3.5px 0.765625px rgba(from var(--shadow-color) r g b / 0.476837158203125),
4.0px 4.0px 1.0px rgba(from var(--shadow-color) r g b / 0.421875),
4.5px 4.5px 1.265625px rgba(from var(--shadow-color) r g b / 0.371307373046875),
5.0px 5.0px 1.5625px rgba(from var(--shadow-color) r g b / 0.324951171875),
5.5px 5.5px 1.890625px rgba(from var(--shadow-color) r g b / 0.282623291015625),
6.0px 6.0px 2.25px rgba(from var(--shadow-color) r g b / 0.244140625),
6.5px 6.5px 2.640625px rgba(from var(--shadow-color) r g b / 0.209320068359375),
7.0px 7.0px 3.0625px rgba(from var(--shadow-color) r g b / 0.177978515625),
7.5px 7.5px 3.515625px rgba(from var(--shadow-color) r g b / 0.149932861328125),
8.0px 8.0px 4.0px rgba(from var(--shadow-color) r g b / 0.125),
8.5px 8.5px 4.515625px rgba(from var(--shadow-color) r g b / 0.102996826171875),
9.0px 9.0px 5.0625px rgba(from var(--shadow-color) r g b / 0.083740234375),
9.5px 9.5px 5.640625px rgba(from var(--shadow-color) r g b / 0.067047119140625),
10.0px 10.0px 6.25px rgba(from var(--shadow-color) r g b / 0.052734375),
10.5px 10.5px 6.890625px rgba(from var(--shadow-color) r g b / 0.040618896484375),
11.0px 11.0px 7.5625px rgba(from var(--shadow-color) r g b / 0.030517578125),
11.5px 11.5px 8.265625px rgba(from var(--shadow-color) r g b / 0.022247314453125),
12.0px 12.0px 9.0px rgba(from var(--shadow-color) r g b / 0.015625),
12.5px 12.5px 9.765625px rgba(from var(--shadow-color) r g b / 0.010467529296875),
13.0px 13.0px 10.5625px rgba(from var(--shadow-color) r g b / 0.006591796875),
13.5px 13.5px 11.390625px rgba(from var(--shadow-color) r g b / 0.003814697265625),
14.0px 14.0px 12.25px rgba(from var(--shadow-color) r g b / 0.001953125),
14.5px 14.5px 13.140625px rgba(from var(--shadow-color) r g b / 0.000823974609375),
15.0px 15.0px 14.0625px rgba(from var(--shadow-color) r g b / 0.000244140625),
15.5px 15.5px 15.015625px rgba(from var(--shadow-color) r g b / 3.0517578125e-05)
;
}
& .adjectives {
--recursive-wght: 800;
font-size: 2rem;
vertical-align: 50%;
}
& .house {
width: max-content;
font-size: 4rem;
padding-left: 1em;
padding-top: 0.1em;
}
}
@media (hover: none) {
h1.page-title a {
text-decoration: none;
}
}
@media (max-width: 450px) {
body {
--top-min-spacing: 40px;

View file

@ -2,7 +2,6 @@
:root {
--tree-indent-width: 3.2rem;
--transition-duration: 0.15s;
--button-bar-icon-size: 2.8rem;
}
@ -82,6 +81,21 @@
.tree {
--tree-indent-guide-dim: transparent;
--tree-indent-guide-highlighted: transparent;
display: flex;
flex-direction: column;
align-self: start;
align-items: center;
& > article {
padding: 1.6rem;
width: 100%;
}
& > footer {
max-width: none;
}
}
.tree:has(.branch-container:hover) {
@ -116,8 +130,9 @@
}
/* Top level should not have an indent or a border. */
.tree > ul {
.tree article > ul {
padding-left: 0;
margin-left: 0;
border-left: none;
}