diff --git a/.gitignore b/.gitignore index 4f19501..4cf7aec 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ _build _tmp .directory *~ +.sass-cache diff --git a/Makefile b/Makefile index 05d26f8..21957d6 100644 --- a/Makefile +++ b/Makefile @@ -19,16 +19,17 @@ OUTPUTPOSTS = \ $(BUILDDIR)/index.html $(BUILDDIR)/rss.xml STYLE != find style -type f -OUTPUTSTYLE = $(patsubst %,$(BUILDDIR)/%,$(STYLE)) +OUTPUTSTYLE = $(patsubst %.scss,%.css,$(patsubst %,$(BUILDDIR)/%,$(STYLE))) -OUTPUT = $(OUTPUTPOSTS) $(OUTPUTSTYLE) +SCRIPT != find script -type f +OUTPUTSCRIPT = $(patsubst %.ts,%.js,$(patsubst %,$(BUILDDIR)/%,$(SCRIPT))) + +OUTPUT = $(OUTPUTPOSTS) $(OUTPUTSTYLE) $(OUTPUTSCRIPT) ALL_TAGS = $(TMPDIR)/all-tags POST_LISTS = $(TMPDIR)/post-lists COMBO_FILTER = $(TMPDIR)/combo-filter -EXECS = \ - $(LAANTAS_SCRIPT) \ - $(ALL_TAGS) $(POST_LISTS) $(COMBO_FILTER) +EXECS = $(ALL_TAGS) $(POST_LISTS) $(COMBO_FILTER) CABAL_FLAGS ?= -O @@ -58,8 +59,17 @@ $(BUILDDIR)/%.html: $(TMPDIR)/%.md $(POSTDEPS) ; $(call pandoc-simple,meta.htm $(BUILDDIR)/rss.xml: $(TMPDIR)/index.md $(POSTDEPS) $(call pandoc,rss.xml,--metadata-file rss.yaml --write html) -.PHONY: langfilter laantas-script -langfilter laantas-script: %: ; cabal build $@ +$(BUILDDIR)/%.css: %.scss + @echo "[sass]" $@ + mkdir -p $(dir $@) + sass --no-source-map -I style $< $@ + +$(BUILDDIR)/%.js: %.ts + @echo "[tsc]" $@ + mkdir -p $(dir $@) + tsc --strict --noUncheckedIndexedAccess --noEmitOnError \ + --lib dom,es2021 --target es2015 \ + --outDir $(dir $@) $^ # $(1): template file # $(2): extra flags diff --git a/blog-meta/all-tags.hs b/blog-meta/all-tags.hs index 9bbc6ec..e2e7c02 100644 --- a/blog-meta/all-tags.hs +++ b/blog-meta/all-tags.hs @@ -61,8 +61,8 @@ getTags file = do makeYAML :: [Set Text] -> LazyBS.ByteString makeYAML tags = "---\n" <> yaml <> "\n...\n" where yaml = YAML.encode1 $ YAML.obj - [("title" ##= YAML.str "all tags"), - ("all-tags" ##= collate tags)] + ["title" ##= YAML.str "all tags", "meta" ##= True, + "all-tags" ##= collate tags] -- | generates a makefile to include that generates the index and individual -- tag pages. example: @@ -112,7 +112,7 @@ data Tag = instance YAML.ToYAML Tag where toYAML (Tag {name, slug, count}) = YAML.obj $ - [("name" ##= name), ("slug" ##= slug), ("count" ##= count)] + ["name" ##= name, "slug" ##= slug, "count" ##= count] -- | counts occurrences of each tag, and checks they all have distinct slugs collate :: [Set Text] -> [Tag] diff --git a/blog-meta/post-lists.hs b/blog-meta/post-lists.hs index cbdbe9a..01d61f9 100644 --- a/blog-meta/post-lists.hs +++ b/blog-meta/post-lists.hs @@ -64,7 +64,7 @@ makeTagInfo infos title basename outdir = do makeContent :: Text -> [PostInfo] -> LazyBS.ByteString makeContent title is' = "---\n" <> YAML.encode1 val <> "...\n" where is = sortBy (flip $ comparing date) is' - val = YAML.obj [("title" ##= title), ("posts" ##= is)] + val = YAML.obj ["title" ##= title, "posts" ##= is, "meta" ##= True] allTags :: Foldable t => t PostInfo -> Set Text allTags = foldMap (Set.fromList . tags) diff --git a/cabal.project b/cabal.project index 485c837..15865bd 100644 --- a/cabal.project +++ b/cabal.project @@ -4,13 +4,13 @@ packages: source-repository-package type: git location: https://git.rhiannon.website/rhi/lang.git - tag: ed54ec4c5af5b2b8ea25f0274e11c2f8c87714c3 + tag: c4a430facbeaa55a9de8edd69145243475c94087 subdir: langfilter source-repository-package type: git location: https://git.rhiannon.website/rhi/lang.git - tag: ed54ec4c5af5b2b8ea25f0274e11c2f8c87714c3 + tag: c4a430facbeaa55a9de8edd69145243475c94087 subdir: laantas-script source-repository-package diff --git a/posts/new-new-theme.md b/posts/new-new-theme.md new file mode 100644 index 0000000..8ef62b9 --- /dev/null +++ b/posts/new-new-theme.md @@ -0,0 +1,14 @@ +--- +title: <em>new</em> new theme +date: 2024-12-05 +summary: for real this time. probably +tags: [december adventure] +... + +yeah i redid it. + +it's more _on brand_ now, i think. and the actual css is nice and organised now. i am grudgingly using [sass] now because i really want those mixins. and functions. + +so yeah! honestly i don't think there is much to talk about with something like this. you can see the results. + +bye diff --git a/posts/new-theme.md b/posts/new-theme.md new file mode 100644 index 0000000..f003eb5 --- /dev/null +++ b/posts/new-theme.md @@ -0,0 +1,18 @@ +--- +title: new theme +date: 2024-12-04 +tags: [december adventure] +summary: wow! +... + +hi today's `@december adventure@` was… + +:::banner +redesigning this page +::: + +maybe you noticed when you opened it. i know it's pretty subtle. + +:::aside +**note to readers from the future**: it was not subtle. +::: diff --git a/posts/quorientation.md b/posts/quorientation.md index d40f526..9c06c34 100644 --- a/posts/quorientation.md +++ b/posts/quorientation.md @@ -29,6 +29,8 @@ so. one sentence at a time. # one +you know! the thing! from the game! + :::glosses - suatł pattalal šilbari gulaigúšḿ fulla - [ˌsuətɫ̩ ˈpatːɐləlʲ ˈʃilʲbɐɾɪ ɡɔˈlaɪɣɔːʃm̩ fʊɫːɑ] @@ -37,18 +39,13 @@ so. one sentence at a time. - use your warps to skip some floors ::: -you know! the thing! from the game! - -<figure class='floating right'> -<figcaption> well. from the fan translation </figcaption> -<img src=quorientation/skip-some-floors.png class=pixel alt=''> -</figure> +{.floating .right .pixel} - out of context, `{!patta}` means door. i suppose a portal would be a magic door, an `{!ustaitł patta}`. but in the context of someone making one right in front of you, it is clear what kind of door we're talking about. - :::{.aside .no-line} + :::aside the word `{!ustail}` also means "songs". did you know there's an old english word for magic, `{ġealdor}`, that comes from the proto-germanic `{galdr}`, meaning both "song" and "incantation"? i thought it was cute. @@ -88,7 +85,7 @@ babylon no longer exists, so it doesn't need protecting. go have fun mean something like "is possible/necessary". "{flowers grow here} is possible". - :::{.aside .no-line} + :::aside the similarity of `{!fulla}` and `{!bulla}` is just a weird accident, in case you're wondering. i made the words at different times. no etymology puzzle here, sorry @@ -112,7 +109,7 @@ babylon no longer exists, so it doesn't need protecting. go have fun # abbreviation list -:::{.twocol .abbr-list} +:::{.abbr-list} DEF : [definite](https://lang.niss.website/laantas/nouns.html#definiteness) ["the"]{.note} diff --git a/posts/rainbow-quox.md b/posts/rainbow-quox.md index e71b0bc..17c51f3 100644 --- a/posts/rainbow-quox.md +++ b/posts/rainbow-quox.md @@ -6,17 +6,18 @@ summary: q.t. colour scheme generator header-includes: | <style> #relcolor { - max-width: 20em; margin: auto; - display: grid; grid-template-columns: 1fr 1fr; gap: .5em; + max-width: 20em; margin: 1em auto auto; + display: grid; grid-template-columns: 1fr 1fr; gap: 3em; font-weight: bold; --hi: #ea9aa1; --wow: oklch(from var(--hi) l c calc(h + 180)); } #relcolor div { text-align: center; font-size: 125%; - padding: .4em; border-radius: .5em; + padding: .4em; color: black; background: var(--bg); border: 4px solid oklch(from var(--bg) .25 75% h); + box-shadow: 0.5em 0.5em 0 color-mix(in srgb, var(--bg) 50%, transparent); } #hi { --bg: var(--hi); } #wow { --bg: var(--wow); } @@ -69,7 +70,7 @@ if you look at [mdn], you might see this interesting [`hue-rotate()`][hr] thing well that doesn't sound very encouraging. but maybe it'll be fine. -i shoved [all of the colours][jofo] to hue 0° (using krita's _hue HSL_ blend mode), and used `hue-rotate()` to change it back to the 'main' colour of each region. +i shoved [all of the colours][jofo] to hue 0° (using krita's `@hue HSL@` blend mode), and used `hue-rotate()` to change it back to the 'main' colour of each region. it won't look exact, but it'll be close. right? @@ -171,27 +172,27 @@ a good place to start is the same place everyone does: with complementary and tr using this as a starting point, i pick some evenly-spaced colours for each bit. the final palettes come out like this! :::{#result} -- fins: +- fins <svg viewBox='-0.1 -0.1 8.7 1.2'> <rect fill=#770084 width=2 height=1 /> <rect fill=#9d0058 width=2 height=1 x=2 /> <rect fill=#a11916 width=2 height=1 x=4 /> <rect fill=#eead91 width=2 height=1 x=6.5 /> </svg> -- body: +- body <svg viewBox='-0.1 -0.1 6.7 1.2'> <rect fill=#00709b width=2 height=1 /> <rect fill=#008fca width=2 height=1 x=2 /> <rect fill=#7dd1f1 width=2 height=1 x=4.5 /> </svg> -- belly: +- belly <svg viewBox='-0.1 -0.1 8.7 1.2'> <rect fill=#dc8d7b width=2 height=1 /> <rect fill=#efa4b0 width=2 height=1 x=2 /> <rect fill=#f9aba1 width=2 height=1 x=4.5 /> <rect fill=#e3adbc width=2 height=1 x=6.5 /> </svg> -- mask/claws/socks: +- mask/claws/socks <svg viewBox='-0.1 -0.1 9.2 1.2'> <rect fill=#ebc1c8 width=2 height=1 /> <rect fill=#b4aaae width=2 height=1 x=2.5 /> diff --git a/script/hue.ts b/script/hue.ts new file mode 100644 index 0000000..2d4f459 --- /dev/null +++ b/script/hue.ts @@ -0,0 +1,6 @@ +export {} + +document.addEventListener('DOMContentLoaded', () => { + const hue = `${Math.random() * 360}`; + document.documentElement.style.setProperty('--base-hue', hue); +}); diff --git a/style/colours.scss b/style/colours.scss new file mode 100644 index 0000000..35c4393 --- /dev/null +++ b/style/colours.scss @@ -0,0 +1,43 @@ + +$lighter: oklch(95% 8% var(--base-hue)); +$light: oklch(90% 12% var(--base-hue)); +$mid: oklch(40% 20% var(--base-hue)); +$dark: oklch(20% 45% var(--base-hue)); +$darker: oklch(10% 40% var(--base-hue)); + +$dark-accent: oklch(56% 40% calc(var(--base-hue) - 180)); +$light-accent: oklch(90% 30% calc(var(--base-hue) - 180)); + +@function halfalpha($col) { + @return color-mix(in srgb, #{$col} 50%, transparent); +} + + +@mixin color-var($name, $light, $dark: null) { + @property #{$name} { + syntax: "<color>"; + inherits: true; + initial-value: #{$light}; + } + :root { + #{$name}: #{$light}; + @if $dark != null { + @media (prefers-color-scheme: dark) { #{$name}: #{$dark}; } + } + } +} + +@mixin apply-colors($fg, $bg, $accent: null) { + --fg: #{$fg}; + --bg: #{$bg}; + @if $accent { --accent: #{$accent}; } + + color: var(--fg); + background: var(--bg); +} + +@mixin inverted($padding: 0.5em) { + @include apply-colors($fg: var(--counter-fg), $bg: var(--counter-bg), + $accent: var(--counter-accent)); + padding: $padding; +} diff --git a/style/counters.css b/style/counters.css index 6821348..53ceb1a 100644 --- a/style/counters.css +++ b/style/counters.css @@ -16,53 +16,14 @@ suffix: " "; } -main :is(h1, h2, h3, h4, h5, h6):not(.unnumbered)::before { - padding-right: 1ex; -} +main h1 { + &:not(.unnumbered) { counter-increment: h1; } -main h1:not(.unnumbered) { counter-increment: h1; } -main h1 { counter-reset: h2 h3 h4 h5 h6; } -main h1:not(.unnumbered)::before { - content: counter(h1, inv-circled); + &::before { + font-family: PragmataPro; + font-style: normal; + content: counter(h1, inv-circled); + padding-right: 1ex; + } + &.unnumbered::before { content: "\2B8A"; } } -main h1.unnumbered::before { - content: "\2B8A "; -} - -/* - -main h2:not(.unnumbered) { counter-increment: h2; } -main h2:not(.unnumbered)::before { - content: counter(h1) '.' counter(h2); -} -main h2 { counter-reset: h3 h4 h5 h6; } - -main h3:not(.unnumbered) { counter-increment: h3; } -main h3 { counter-reset: h4 h5 h6; } -main h3:not(.unnumbered)::before { - content: counter(h1) '.' counter(h2) '.' counter(h3); -} - -main h4:not(.unnumbered) { counter-increment: h4; } -main h4 { counter-reset: h5 h6; } -main h4:not(.unnumbered)::before { - content: - counter(h1) '.' counter(h2) '.' counter(h3) '.' counter(h4); -} - -main h5:not(.unnumbered) { counter-increment: h5; } -main h5 { counter-reset: h6; } -main h5:not(.unnumbered)::before { - content: - counter(h1) '.' counter(h2) '.' counter(h3) '.' counter(h4) '.' - counter(h5); -} - -main h6:not(.unnumbered) { counter-increment: h6; } -main h6:not(.unnumbered)::before { - content: - counter(h1) '.' counter(h2) '.' counter(h3) '.' counter(h4) '.' - counter(h5) '.' counter(h6); -} - -*/ diff --git a/style/fonts.scss b/style/fonts.scss new file mode 100644 index 0000000..30b9891 --- /dev/null +++ b/style/fonts.scss @@ -0,0 +1,51 @@ +@import url(fonts/pragmatapro/pragmatapro.css); +@import url(fonts/muller/muller.css); +@import url(fonts/junicodevf/junicodevf.css); + + +$normal-weight: 400; +$bold-weight: 600; +$boldbold-weight: 700; +$main-heading-weight: 300; +$heading-weight: $bold-weight; +$small-weight: 500; + +$body-size: 14pt; +$small-size: $body-size * 0.75; +$code-font-scale: 0.85; + +@mixin main-font { font-family: Muller, sans-serif; } + +@mixin heading-font { @include main-font; } + +@mixin code-font { + font-family: PragmataPro, monospace; + font-size: 100% * $code-font-scale; +} + +@mixin ipa-font { + font-family: JunicodeVF, serif; + font-feature-settings: "ccmp", "calt", "liga", "loca", "mark", "mkmk", "ss01"; + font-weight: 550; + font-stretch: 110%; +} + +@mixin small-font { + font-size: 80%; + font-weight: $small-weight; +} + +@mixin note-font { + @include small-font; + font-style: italic; +} + +@mixin symbol-font { + font-family: PragmataPro, sans-serif; +} + +@mixin heading-size($level) { + $step: 1.2; + font-size: #{pow($step, max(4 - $level, 0))}rem; +} + diff --git a/style/meta.scss b/style/meta.scss new file mode 100644 index 0000000..cd16243 --- /dev/null +++ b/style/meta.scss @@ -0,0 +1,34 @@ +@use 'colours' as *; +@use 'fonts' as *; +@import url(page.css); + +.tag-list { + columns: 2; +} + +.post-list li + li { + margin-top: 0.5em; +} + +.post-desc { + margin: 0; + line-height: 125%; + + p { margin: 0; } + p + p { margin-top: .5em; } +} + +.post-list > li { list-style: '✎ '; } +.tag-list > li { list-style: '🏷 '; } + +.post-list .date, .tag-list .count, .post-desc { + @include note-font; +} + +#toc > ul { + columns: 2; + margin-left: 2em; + margin-right: 2em; + > li { list-style: circled; } +} + diff --git a/style/niss.png b/style/niss.png deleted file mode 100644 index 0e2009e..0000000 Binary files a/style/niss.png and /dev/null differ diff --git a/style/page.css b/style/page.css deleted file mode 100644 index 6a16d69..0000000 --- a/style/page.css +++ /dev/null @@ -1,708 +0,0 @@ -@import url(counters.css); -@import url(fonts/schola/schola.css); -@import url(fonts/muller/muller.css); -@import url(fonts/junius/junius.css); -@import url(fonts/pragmatapro/pragmatapro.css); - -:root { - --ipa-font: JuniusX; - - --light: #feb; - --dark: #325; - --mid: #83869e; - --red1: #f42; - --red2: #d16; - - --fg: var(--dark); - --bg: var(--light); - --accent: var(--red1); - --other-accent: var(--red2); -} - -:root { - background: var(--bg); - color: var(--fg); - - font-family: PragmataPro; - font-size: 13pt; -} - -@media (prefers-color-scheme: dark) { - :root { - --fg: var(--light); - --bg: var(--dark); - --accent: var(--red2); - --other-accent: var(--red1); - } -} - -:root, body { margin: 0; padding: 0; } - -main, footer { max-width: 50rem; } - -main { - min-height: 100%; - margin: 1em auto 0; - padding: 0.5em 2em; - - line-height: 150%; - - box-sizing: border-box; -} - -header { - text-align: center; - text-wrap: balance; - background: var(--fg); - color: var(--bg); - --accent: var(--other-accent); - padding: 1em; -} - -header h1 { - font-size: 200%; - margin: 0; - font-weight: normal; - text-transform: uppercase; - letter-spacing: 0.4ch; -} - -/* h1, h2, h3, h4, h5, h6 { */ -main h1 { - margin: 1em 0 0.25em; - - font-weight: normal; - font-variant-east-asian: full-width; - -moz-font-feature-settings: "fwid"; - -webkit-font-feature-settings: "fwid"; - font-feature-settings: "fwid"; - - clear: both; - - font-size: 100%; -} - -h1 small { - font-variant-east-asian: normal; - -moz-font-feature-settings: normal; - -webkit-font-feature-settings: normal; - font-feature-settings: normal; -} - - -h1 { font-size: 125%; } -h2 { font-size: 125%; } -h3 { font-size: 120%; } -h4 { font-size: 110%; } -h5 { font-size: 100%; } -h6 { font-size: 100%; } - -main h1 { - background: var(--fg); - color: var(--bg); - padding: 0.25rem 0.75rem; - margin-bottom: 1rem; -} - -main :is(h2, h3, h4, h5, h6) { - padding: 0.25rem 0.75rem; - border-bottom: 2px dotted var(--fg); - margin-bottom: 1rem; -} - -hr { - border: none; - border-bottom: 2px dotted var(--fg); - height: 0; -} - -pre + hr { - margin-top: 1.5em; -} - -.meta { - margin-top: 1rem; - display: flex; - column-gap: 2em; - align-items: baseline; - justify-content: center; -} - -header .date { - font-variant-east-asian: normal; - -moz-font-feature-settings: normal; - -webkit-font-feature-settings: normal; - font-feature-settings: normal; - font-size: 100%; - - margin: 0; -} - -.tags ul { - display: inline; - padding: 0; -} - -.tags li { - list-style: none; - display: inline; -} - -.tags li + li { - margin-left: 0.75ex; -} - -.tag-list { - columns: 2; -} - -.post-list .date, .tag-list .count { - font-size: 85%; -} - -.post-list li + li { - margin-top: 0.5em; -} - -.post-desc { - margin: 0; - font-size: small; - font-style: italic; - line-height: 125%; -} - -.post-desc p { - margin: 0; -} -.post-desc p + p { - margin-top: .5em; -} - - -a { - color: inherit; - text-decoration: 2px dotted underline var(--accent); -} -a:hover { color: var(--accent); } - -b, strong { - font-weight: 600; -} - -dfn { - font-style: normal; - font-weight: 500; -} - -ul li { list-style: '❀ '; } -.post-list li { list-style: '✒ '; } -.tag-list li { list-style: ' '; } /* a tag in pragmatapro */ - -table { - margin: auto; - border-spacing: 0; - border-top: 2px solid var(--fg); - border-bottom: 2px solid var(--fg); -} - -th { - font-weight: 500; -} - -thead th { - border-bottom: 1px solid var(--fg); -} - -td, th { - padding: 0 0.5em; - vertical-align: text-bottom; -} - - -pre, code { - font-family: PragmataPro; - font-size: inherit; -} - -pre, :not(pre) > code { - background: hsla(0deg 0% 100% / 40%); - border: 2px dotted color-mix(in srgb, currentcolor 75%, transparent); -} - -@media (prefers-color-scheme: dark) { - pre, :not(pre) > code { background: hsla(0deg 0% 00% / 30%); } -} - -:not(pre) > code { padding: 0 5px; white-space: nowrap; } - -pre { - clear: both; - width: min-content; - margin: 0.5em auto; - padding: 0.5em 0.8em; -} - - -.ipa, .lang, .ebnf-t { - /* font-family: var(--ipa-font); */ - - font-feature-settings: - "ccmp", "calt", "liga", "loca", "mark", "mkmk", "ss01"; - /* ss01 to use modern Þþð design, others to make juniusx go brrr - * maybe i can just turn loca off but idk what other regional forms - * it does that i actually want */ - - text-underline-offset: 0.125em; -} - -.lang, .ebnf-t { font-weight: 500; } - -.abbr-list dt { - font-family: PragmataPro; - font-weight: normal; -} - -.abbr, .abbr-list dt { - font-variant: all-small-caps; -} - -.scr { - height: 1.5em; - vertical-align: -40%; -} - -.gloss-split, .gloss-gloss { - font-size: 80%; -} - -:is(.gloss, .bigscr) .scr { - height: 2em; -} - -.hugescr .scr { - height: 4em; -} - -:is(.splash, .example) .scr { - height: unset; - display: block; - margin: auto; -} - -.example { - margin: auto; -} - -.example .text { - display: block; - text-align: center; - width: 80%; - margin: 0.75em auto 0; -} - -blockquote { - font-style: italic; -} - - -.letter-list { - margin: 1.25em auto 0; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: space-around; - width: 80%; - row-gap: 0.5em; - column-gap: 1.5em; -} - -.letter-list + .letter-list { - margin-top: 2.5em; -} - -.letter-list .lang { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -} - -.letter-list .scr { - height: 3em; - margin-left: 0.5em; -} - -.letter-list .text { - font-size: 125%; -} - - -#toc > ul { - columns: 2; - margin-left: 2em; - margin-right: 2em; - > li { list-style: circled; } -} - -figure img { - max-width: 100%; -} -figure:not(.nobg, .hasborder) img:not(.scr) { - border: 3px solid currentcolor; -} -figure.nobg a img { - /* fake outline */ - filter: - drop-shadow(1px 1px 0 currentcolor) - drop-shadow(1px -1px 0 currentcolor) - drop-shadow(-1px 1px 0 currentcolor) - drop-shadow(-1px -1px 0 currentcolor) - drop-shadow(1px 0 0 currentcolor) - drop-shadow(-1px 0 0 currentcolor) - drop-shadow(0 1px 0 currentcolor) - drop-shadow(0 -1px 0 currentcolor) ; -} -figure.lightbg img { - background: var(--light); -} -figure:not(.left) { - text-align: center; -} -figure:not(.left) table { - display: inline-table; -} -.twocol-grid figure { - margin: 0; -} -figure table { - margin: 1em 0.5em; -} -.gloss { - border: none; - text-align: left; -} - -figure ul { - text-align: left; - margin-left: 5em; - margin-right: 5em; - columns: 2; -} -figure li { - break-inside: avoid; -} - -figcaption { - font-size: 80%; - line-height: 125%; - font-style: italic; - margin: 0 auto; - text-align: center; - text-wrap: balance; -} -figcaption em { - font-style: normal; -} -:not(.floating) > figcaption { - width: 75%; -} - -dt { - font-weight: 500; - display: inline; - break-after: avoid; -} - -dd { - margin-left: 1em; - display: inline; - break-before: avoid; -} - -dd::after { - content: ''; - display: block; -} - -u u { - text-decoration: double underline; -} - -:is(.twocol, .threecol):not(:is(ul, ol) *) { - margin-top: 1em; -} -.twocol { - columns: 2; -} -.threecol { - columns: 3; -} -.twocol :first-child, .threecol :first-child { - margin-top: 0; -} - -.twocol-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 1em; - margin: 1em 0; -} - -.twocol-grid .gloss { - margin-left: 0; -} - -footer { - clear: both; - border-top: 2px dotted var(--fg); - margin: 1.5em auto 3em; - - font-size: 80%; - font-weight: 500; - text-align: center; -} - -footer ul::before { - margin: 0; - content: '➸ '; -} - -footer ul::after { - margin: 0; - content: ' 🐌︎'; -} - -footer li { - display: inline; - list-style: none; -} -footer li + li::before { content: ' · '; } - - -.ebnf { - border: none; -} - -.ebnf td { - padding: 0 0.15em; -} - -.ebnf-nt { - font-weight: 500; - color: hsl(155deg, 80%, 30%); - white-space: nowrap; -} - -.ebnf-punc { - color: hsl(25deg, 40%, 30%); -} - -.ebnf-sub, .ebnf-brack { - color: hsl(210deg, 80%, 35%); - font-weight: 500; -} - -.ebnf-brack { - padding: 0 0.05em; -} - -.ebnf-s { - font-style: italic; - color: hsl(330deg, 80%, 30%); -} - -blockquote { - max-width: 85%; - border-left: 1px solid black; - padding-left: 1em; - margin: auto; -} - - -.note, aside { - font-size: 90%; -} - -.note { - font-style: italic; -} - -.banner { - font-size: 125%; - font-weight: bolder; - text-align: center; - text-wrap: balance; -} -.banner p:first-child::before { content: '☛ '; } -.banner p:last-child::after { content: ' ☚'; } - -:is(h1, h2) .note { - font-size: 75%; -} - -aside { - margin: 0.5em 3em; -} -aside:not(.no-line) { - padding-left: 1em; - border-left: 2px solid var(--fg); -} - -aside > details summary { - font-weight: 600; -} - -aside :is(h1, h2, h3, h4, h5, h6) { - margin-top: 0.25em; - font-weight: 600; -} -aside h1 { font-size: 115%; } -aside :is(h2, h3, h4, h5, h6) { font-size: 100%; } - -:is(aside, figure).floating { - max-width: 33%; -} -aside.floating { - padding: 0.25em 0.75em; - margin: 0.15em 1em 0; -} -figure.floating { - margin: 0 0.5em; -} - -aside.floating :first-child { margin-top: 0; } -aside.floating :last-child { margin-bottom: 0; } - -.kw { color: hsl(300deg, 60%, 30%); } -.pp { color: hsl(343deg, 100%, 40%); /* font-weight: 500; */ } -.dt { color: hsl(173deg, 100%, 24%); /* font-weight: 500; */ } -.fu, .at { color: hsl(34deg, 100%, 30%); /* font-weight: 500; */ } -.va { color: hsl(203deg, 100%, 30%); /* font-weight: 500; */ } -.cf { color: hsl(276deg, 75%, 35%); /* font-weight: 500; */ } -.op { color: hsl(220deg, 40%, 33%); } -.co { color: hsl(221deg, 10%, 39%); /* font-style: italic; */ } -.bu { color: hsl(120deg, 85%, 25%); } -.st, .fl, .dv, .bn, .sc, .ss { color: hsl(143deg, 100%, 20%); } -.wa { color: hsl(350deg, 80%, 25%); text-decoration: wavy 1.5px underline; } -.al { color: hsl(350deg, 80%, 25%); } -.cn { color: hsl(343deg, 100%, 30%); } - -@media (prefers-color-scheme: dark) { - .kw { color: hsl(300deg, 60%, 80%); } - .pp { color: hsl(343deg, 100%, 85%); /* font-weight: 500; */ } - .dt { color: hsl(193deg, 60%, 74%); /* font-weight: 500; */ } - .fu, .at { color: hsl(34deg, 100%, 70%); /* font-weight: 500; */ } - .va { color: hsl(203deg, 100%, 75%); /* font-weight: 500; */ } - .cf { color: hsl(276deg, 75%, 85%); /* font-weight: 500; */ } - .op { color: hsl(220deg, 40%, 70%); } - .co { color: hsl(221deg, 10%, 80%); /* font-style: italic; */ } - .bu { color: hsl(120deg, 55%, 75%); } - .st, .fl, .dv, .bn, .sc, .ss { color: hsl(143deg, 70%, 80%); } - .wa { color: hsl(350deg, 80%, 77%); text-decoration: wavy 1.5px underline; } - .al { color: hsl(350deg, 80%, 77%); } - .cn { color: hsl(343deg, 80%, 70%); } -} - -.floating { - float: right; - margin: 0.5em 1em 0.5em 2em; -} - -.floating.left { - float: left; - margin: 0.5em 2em 0.5em 1em; -} - -.shaped { - /* maybe one day... */ - /* shape-outside: attr(src url); */ - shape-margin: 1em; -} - -.shadow { filter: drop-shadow(5px 5px 8px #0006); } - -.pixel { - image-rendering: crisp-edges; - image-rendering: pixelated; -} - -.emoji { - height: 1em; - width: 1em; - vertical-align: -0.1em; -} - -.bigemoji { - height: 2em; - width: 2em; - vertical-align: -0.2em; -} - -.emojiseq { white-space: nowrap; } - - -.citation { - font-size: 90%; -} - -#refs { - margin-top: 0.75em; -} -.csl-entry { - margin-left: 2em; - text-indent: -2em; -} -/* -.csl-entry { - display: grid; - grid-template-columns: 4ch auto; - grid-gap: 1ex; -} -.csl-left-margin { - justify-self: end; -} -*/ - -math[display=block] { - border: 2px dotted var(--fg); - - padding: 1em 3em; - margin: auto; - width: min-content; - -} -.rulebox math[display=block] { - border: none; - padding: 0; -} - -.texdefs { - display: none; -} - -.rulebox { - float: right; - border: 1px solid var(--fg); - background: #ffffff66; - padding: .4em 1.2em; - margin-left: 3em; -} - -/* the last thing in the :is is for priority fuckery */ -.rulebox :is(p, .math, mjx-container, #asd) { - margin: 0; - padding: 0; -} - -.clear { clear: both; } - -mark { - mix-blend-mode: multiply; - background: #fbc; - padding: 0 0.35ch; -} - -.light { - background: var(--light); - color: var(--dark); -} diff --git a/style/page.scss b/style/page.scss new file mode 100644 index 0000000..dc76bd8 --- /dev/null +++ b/style/page.scss @@ -0,0 +1,617 @@ +@use 'sass:math'; +@use 'colours' as *; +@use 'fonts' as *; + +@import url(counters.css); + + +@layer colordefs { + @property --base-hue { + syntax: "<number>"; + inherits: true; + initial-value: 336; + } + + @include color-var(--fg, $darker, $light); + @include color-var(--bg, $light, $darker); + @include color-var(--counter-fg, $lighter, $lighter); + @include color-var(--counter-bg, $dark, $mid); + @include color-var(--accent, $dark-accent, $light-accent); + @include color-var(--counter-accent, $light-accent, $dark-accent); + @include color-var(--box-base, $light, $mid); + @include color-var(--box-fg, $darker, $lighter); + @include color-var(--box-shadow, halfalpha($mid)); + + :root { + --gradient: linear-gradient( + 120deg in oklch, + oklch(93% 27.1% 96deg), + oklch(84.03% 22% 15deg), + oklch(80% 29.3% 303deg), + oklch(84% 23% 233deg), + oklch(89% 25% 161deg) + ); + + @media (prefers-color-scheme: dark) { + // todo oklch + --gradient: + linear-gradient(20deg in oklch, + hsl(300deg 30% 20%), + hsl(220deg 30% 20%), + hsl(150deg 30% 20%), + hsl(30deg 30% 20%), + hsl(350deg 30% 20%)); + } + } +} + + +@mixin boxy-margin { margin: 1rem 0; } + +@mixin boxy-shadow($dst: 0.5rem) { + box-shadow: 0.5rem 0.5rem 0 var(--box-shadow); +} + +@function border-style($fg: var(--fg)) { @return 3px solid $fg; } + +@mixin boxy-unpadded($bg, $fg: var(--box-fg), $border: $fg, $dst: 0.5em) +{ + color: $fg; + background: $bg; + border: border-style($border); + @include boxy-shadow; +} + +@mixin boxy($bg, $clear: true, $args...) { + @include boxy-unpadded($bg, $args...); + @include boxy-margin; + padding: 0.5rem 0.8rem; + @if $clear { + clear: both; + } @else { + overflow: hidden; // makes the box dodge floats?????? idk why + } + :first-child { margin-top: 0; } + :last-child { margin-bottom: 0; } +} + +@mixin fake-border { + border: none; + filter: + drop-shadow(1px 1px 0 currentcolor) + drop-shadow(1px -1px 0 currentcolor) + drop-shadow(-1px 1px 0 currentcolor) + drop-shadow(-1px -1px 0 currentcolor) + drop-shadow(1px 0 0 currentcolor) + drop-shadow(-1px 0 0 currentcolor) + drop-shadow(0 1px 0 currentcolor) + drop-shadow(0 -1px 0 currentcolor); +} + +@mixin decorations($before, $after: $before, $size: null, $color: null) { + &::before, &::after { + @include symbol-font; + font-style: normal; + @if $size { font-size: $size; } + @if $color { color: $color; } + margin: 0 0.5rem; + } + &::before { content: $before; } + &::after { content: $after; } +} + + +@mixin inline-lists { + ul, menu, li { display: inline; } + ul, menu { padding-left: 0; } + li { list-style: none; } + li + li { margin-left: 0.75ex; } +} + +@mixin center { + text-align: center; + text-wrap: balance; +} + + +@layer outer { + * { box-sizing: border-box; } + + :root { + background: var(--gradient) fixed; + color: var(--fg); + + @include main-font; + font-size: $body-size; + line-height: 150%; + } + + body { + @include boxy-unpadded(var(--bg)); + margin: 2em auto; + + $darkbg: oklch(from var(--bg) calc(l * 0.9) calc(c * 1.25) h); + background: linear-gradient(to bottom in oklch, var(--bg), $darkbg); + + width: min(54rem, 85vw); + } + + main { + margin: 0 2rem; + } +} + +@layer header { + header { + @include inverted; + @include inline-lists; + + text-align: center; + text-wrap: balance; + padding: 1em; + + h1 { + @include decorations('✿', $size: 60%); + @include heading-size(0); + @include heading-font; + font-weight: $main-heading-weight; + font-style: italic; + letter-spacing: 0.1ch; + margin: { top: 0; bottom: 0.5rem; } + + em { font-weight: $normal-weight; } + } + + .meta { + @include small-font; + display: flex; + gap: 2em; + justify-content: center; + + * { display: inline; } + } + } +} + +@layer footer { + footer { + @include inverted(0.75rem); + @include small-font; + @include inline-lists; + + clear: both; + margin: 2rem 0 0 0; + + display: flex; + justify-content: center; + + menu { @include decorations('➸', ''); } + } +} + +@layer headings { + main { + h1, h2, h3, h4, h5, h6 { @include heading-font; } + + h1 { + @include inverted; + @include boxy-margin; + @include boxy-shadow; + @include heading-size(1); + letter-spacing: 0.075ch; + clear: both; + } + + h2 { @include heading-size(2); } + h3 { @include heading-size(3); } + h4, h5, h6 { font-size: 1rem; } + + h2, h3, h4, h5, h6 { + padding: 0.25rem 0.75rem; + border-bottom: border-style(); + margin-bottom: 1rem; + } + } +} + +@layer links { + a { + color: inherit; + text-decoration: 2px solid underline var(--accent); + text-underline-offset: 0.175em; + &:hover { color: var(--accent); } + } +} + +@layer banner { + .banner { + @include boxy(var(--accent), $fg: var(--banner-fg), + $border: var(--banner-border)); + @include decorations('☛', '☚'); + @include heading-size(2); + + font-weight: $boldbold-weight; + width: fit-content; + margin: auto; + + p { display: inline; } + + &:has(a) { + background: var(--accent); + a { text-decoration: none; } + a:hover { color: var(--counter-accent); } + } + + --banner-fg: #{$lighter}; + --banner-border: #{$dark}; + @media (prefers-color-scheme: dark) { + --banner-fg: #{$darker}; + --banner-border: #{$lighter}; + } + } +} + + +@layer code { + pre { + @include code-font; + font-size: 1rem * $code-font-scale; + } + + :where(:not(pre)) > code { + @include code-font; + white-space: nowrap; + } + + /* syntax highlighting */ + .kw { color: hsl(300deg, 60%, 30%); } + .pp { color: hsl(343deg, 100%, 40%); } + .dt { color: hsl(173deg, 100%, 24%); } + .fu, .at { color: hsl(34deg, 100%, 30%); } + .va { color: hsl(203deg, 100%, 30%); } + .cf { color: hsl(276deg, 75%, 35%); } + .op { color: hsl(220deg, 40%, 33%); } + .co { color: hsl(221deg, 10%, 39%); } + .bu { color: hsl(120deg, 85%, 25%); } + .st, .fl, .dv, .bn, .sc, .ss { color: hsl(143deg, 100%, 20%); } + .wa { color: hsl(350deg, 80%, 25%); text-decoration: wavy 1.5px underline; } + .al { color: hsl(350deg, 80%, 25%); } + .cn { color: hsl(343deg, 100%, 30%); } + + @media (prefers-color-scheme: dark) { + .kw { color: hsl(300deg, 60%, 80%); } + .pp { color: hsl(343deg, 100%, 85%); } + .dt { color: hsl(193deg, 60%, 74%); } + .fu, .at { color: hsl(34deg, 100%, 70%); } + .va { color: hsl(203deg, 100%, 75%); } + .cf { color: hsl(276deg, 75%, 85%); } + .op { color: hsl(220deg, 40%, 70%); } + .co { color: hsl(221deg, 10%, 80%); } + .bu { color: hsl(120deg, 55%, 75%); } + .st, .fl, .dv, .bn, .sc, .ss { color: hsl(143deg, 70%, 80%); } + .wa { color: hsl(350deg, 80%, 77%); text-decoration: wavy 1.5px underline; } + .al { color: hsl(350deg, 80%, 77%); } + .cn { color: hsl(343deg, 80%, 70%); } + } +} + + + +@layer figures { + figure { + img { max-width: 100%; } + + &:where(:not(.nobg, .hasborder)) { + a img { border: border-style(); } + a:hover img { border: border-style(var(--accent)); } + } + + &.nobg a img { @include fake-border; } + &.lightbg img { background: var(--light); } + } + + figcaption { + @include note-font; + @include center; + + em { font-style: normal; } + } + + :not(.floating) > figcaption { width: 75%; } +} + + +@layer tables { + table { + margin: auto; + border-spacing: 0; + border: { top: border-style(); bottom: border-style(); } + } + + th { font-weight: $bold-weight; } + + thead th { + border-bottom: border-style(halfalpha(var(--fg))); + } + + td, th { + padding: 0 0.5em; + vertical-align: text-bottom; + } +} + + +@layer boxes { + pre, aside, blockquote { + $hue: calc(h + var(--hue-nudge)); + --box-bg: oklch(from var(--box-base) var(--luma) c #{$hue}); + @include boxy(var(--box-bg), $clear: false); + + --luma: calc(l * 1.05); + @media (prefers-color-scheme: dark) { --luma: calc(l / 1.05); } + } + + :is(pre, .sourceCode, aside, blockquote) { + & + & { margin-top: 1.5em; } + } + + pre { + --hue-nudge: 60; + } + + aside { + @include note-font; + --hue-nudge: -80; + } + + blockquote { + @include note-font; + --hue-nudge: 180; + } + + .light { + @include apply-colors($fg: $darker, $bg: $lighter); + } +} + + +@layer conlangs { + .ipa { @include ipa-font; } + + .lang, .ebnf-t { + @include ipa-font; + font-weight: 700; + font-variation-settings: "ENLA" 25; + /* ENLA (increased x-height) not defined for IPA characters */ + } + + .scr { + vertical-align: -40%; + height: 1.5em; + + :is(.gloss, .bigscr) & { height: 2em; } + .hugescr & { height: 4em; } + } + + .gloss { + border: none; + text-align: left; + & + & { margin-top: 2em; } + } + + .gloss-split, .gloss-gloss { @include small-font; } + + .glosses.left .gloss { margin-left: 0; } + + .abbr-list { + dl { + display: grid; + grid-template-columns: 1fr 8fr 1fr 8fr; + } + dt { @extend .abbr; } + } + +} + + +@layer spans { + + dfn, b, strong, dt { font-weight: $bold-weight; } + + dfn { font-style: normal; } + + abbr, .abbr { font-variant: all-small-caps; } + + u u { text-decoration: double underline; } + + .note { @include note-font; } + :is(h1, h2) .note { font-size: 75%; } + + mark { + --mark-hue: calc(var(--hue) + 90) + padding: 0 0.35ch; + mix-blend-mode: multiply; + background: oklch(95% 40% var(--mark-hue) / 30%); + + @media (prefers-color-scheme: dark) { + mix-blend-mode: screen; + } + } + +} + +@layer lists { + :not(ol) > li { + list-style: '☀ '; + + &::marker { + @include symbol-font; + font-size: 80%; + } + } + +} + + +@layer dl { + + dt { + font-weight: bold; + display: inline; + break-after: avoid; + } + + dd { + margin-left: 1em; + display: inline; + break-before: avoid; + } + + dd::after { + content: ''; + display: block; + } + +} + +@layer twocol { + .twocol { + columns: 2; + > :first-child { margin-top: 0; } + } + + .twocol-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1em; + } +} + +@layer ebnf { + + .ebnf { + border: none; + } + + .ebnf td { + padding: 0 0.15em; + } + + .ebnf-nt { + font-weight: bold; + color: hsl(155deg, 80%, 30%); + white-space: nowrap; + } + + .ebnf-punc { + color: hsl(25deg, 40%, 30%); + } + + .ebnf-sub, .ebnf-brack { + color: hsl(210deg, 80%, 35%); + font-weight: bold; + } + + .ebnf-brack { + padding: 0 0.05em; + } + + .ebnf-s { + font-style: italic; + color: hsl(330deg, 80%, 30%); + } +} + + +@layer floats { + .floating { + max-width: 33%; + margin: 0.5em 1em; + + &:not(.left) { + float: right; + margin-right: 0; + } + + &.left { + float: left; + margin-left: 0; + } + } + + .shaped { shape-margin: 1em; } +} + + +@layer images { + + .pixel { + image-rendering: crisp-edges; + image-rendering: pixelated; + } + + .emoji { + height: 1em; + width: 1em; + vertical-align: -0.1em; + } + + .bigemoji { + height: 2em; + width: 2em; + vertical-align: -0.2em; + } + + .emojiseq { white-space: nowrap; } +} + +@layer citations { + +.citation { + font-size: 90%; +} + +#refs { + margin-top: 0.75em; +} +.csl-entry { + margin-left: 2em; + text-indent: -2em; +} + +} + +@layer math { + + math[display=block] { + border: 2px solid var(--fg); + + padding: 1em 3em; + margin: auto; + width: min-content; + + } + .rulebox math[display=block] { + border: none; + padding: 0; + } + + .texdefs { + display: none; + } + + .rulebox { + float: right; + border: 1px solid var(--fg); + background: #ffffff66; + padding: .4em 1.2em; + margin-left: 3em; + + // "#asd" for specificity + :is(p, .math, mjx-container, #asd) { + margin: 0; + padding: 0; + } + } + +} diff --git a/style/paper.png b/style/paper.png deleted file mode 100644 index 5977961..0000000 Binary files a/style/paper.png and /dev/null differ diff --git a/templates/foot.html b/templates/foot.html index 2af6f48..63b964e 100644 --- a/templates/foot.html +++ b/templates/foot.html @@ -1,10 +1,10 @@ $if(hide-footer)$$else$ <footer> - <ul> + <menu> <li><a href=/index.html>all posts</a> <li><a href=/all-tags.html>all tags</a> <li><a href=/rss.xml>rss</a> - </ul> + </menu> </footer> $endif$ diff --git a/templates/head.html b/templates/head.html index 7e6b37c..2cbac9f 100644 --- a/templates/head.html +++ b/templates/head.html @@ -4,11 +4,16 @@ <meta name=viewport content="width=device-width, initial-scale=1"> <link rel=stylesheet href=/style/page.css> +$if(meta)$ +<link rel=stylesheet href=/style/meta.css> +$endif$ $for(css)$ <link rel=stylesheet href=/style/$css$> $endfor$ <link rel=alternate href=/rss.xml type=application/rss+xml> +<script src=/script/hue.js type=module></script> + $for(header-includes)$ $header-includes$ $endfor$ diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..309f42d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "strict": true, + "noUncheckedIndexedAccess": true, + "noEmitOnError": true, + "lib": ["ES2021", "dom"], + "target": "ES2015" + } +}