blog.grace.moe

Source for the blog blog.grace.moe
git clone https://git.grace.moe/blog.grace.moe
Log | Files | Refs

commit d78fb5d0861b557940fb7ee5e3439e4237be6c7f
parent 477c745471cf5f99d23fec15027b2cb927ba2756
Author: gracefu <81774659+gracefuu@users.noreply.github.com>
Date:   Sun,  4 May 2025 09:55:38 +0800

More decorating

Diffstat:
Aassets/fonts/AtkinsonHyperlegibleMonoVF-Variable.woff2 | 0
Mcontent/posts/b.smd | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mlayouts/templates/base.shtml | 485++++---------------------------------------------------------------------------
Alayouts/templates/template.shtml | 468+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mzine.ziggy | 2+-
5 files changed, 661 insertions(+), 482 deletions(-)

diff --git a/assets/fonts/AtkinsonHyperlegibleMonoVF-Variable.woff2 b/assets/fonts/AtkinsonHyperlegibleMonoVF-Variable.woff2 Binary files differ. diff --git a/content/posts/b.smd b/content/posts/b.smd @@ -1,8 +1,8 @@ --- -.title = "B POPL 2025 Student Research Competition", +.title = "Testing page", .date = @date("2025-01-14T16:38:35+08:00"), .author = "Grace Tan", -.description = "What happened at POPL SRC", +.description = "For testing", .layout = "post.shtml", .alternatives = [{ .name = "raw", @@ -12,36 +12,190 @@ .draft = true, --- -# B POPL 2025 Student Research Competition +# Testing page -I submitted an extended abstract to the POPL 2025 Student Research competition, which has been accepted into the poster presentation stage. See you at POPL 2025! +Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. -[Download Extended Abstract]($link.siteAsset("docs/POPL-2025-SRC-Grace-Tan-Extended-Abstract.pdf")) +Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. Paragraph. ----- - -**Update 2025-01-23**: I proceeded to Round 3 (Oral presentation) and gave my talk, here are my slides! +>[]($block.attrs('wide-content')) +>Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. Wide paragraph. -[Link to Presentation Slides](https://docs.google.com/presentation/d/1IRLBLujk5qB1ekCzD-k7LSTpECGeYWXDenZrtXp1Lvc/view) +>[]($block.attrs('full-bleed-content')) +>Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. Full bleed paragraph. ----- +Paragraph with `code`. Paragraph with `code`. Paragraph with `code`. Paragraph with `code`. Paragraph with `code`. Paragraph with `code`. Paragraph with `code`. Paragraph with `code`. Paragraph with `code`. Paragraph with `code`. -**Update 2025-01-23**: I'm honoured to receive the Gold prize ($500) and advance to the ACM SRC Grand Finals! Thank you for our discussions during the poster session and for listening to my talk! - -```=html -<p class="full-bleed"> -I submitted an extended abstract to the POPL 2025 Student Research competition, which has been accepted into the poster presentation stage. See you at POPL 2025! -</p> -``` +Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). Paragraph with [`zine`]($text.attrs('zig')). ``` code ``` +>[]($block.attrs('wide-content')) +>```zig +>pub const BuildAsset = struct { +> /// Name of this asset +> name: []const u8, +> /// LazyPath of the generated asset. +> /// +> /// The LazyPath cannot be generated by calling `b.path`. +> /// Use the 'assets' directory for non-buildtime assets. +> lp: std.Build.LazyPath, +> /// Installation path relative to the website's asset output path prefix. +> /// +> /// It is recommended to give the file an appropriate file extension. +> /// No need to specify this value if the asset is not meant to be +> /// `link()`ed +> install_path: ?[]const u8 = null, +> /// Installs the asset unconditionally when set to true. +> /// +> /// When set to false, the asset will be installed only if `link()`ed +> /// in a content file or layout (requires `install_path` to be set). +> /// +> /// Note that even when this property is set to false the asset will be +> /// generated by the Zig build system regardless. +> install_always: bool = false, +>}; +> +>/// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +>``` + +```=html +<textarea></textarea> +``` + > quote > > another quote +- tight + - tight + - tight + - tight +- tight +- tight + +---- + +- loose loose loose loose loose loose + - tight tight tight tight tight tight + - tight tight tight tight tight tight + - tight tight tight tight tight tight + +- loose loose loose loose loose loose + +- loose loose loose loose loose loose + +---- + +- tight tight tight tight tight tight + - loose loose loose loose loose loose + + - loose loose loose loose loose loose + + - loose loose loose loose loose loose +- tight tight tight tight tight tight +- tight tight tight tight tight tight + +---- + +- loose loose loose loose loose loose + + - loose loose loose loose loose loose + + - loose loose loose loose loose loose + + - loose loose loose loose loose loose + +- loose loose loose loose loose loose + +- loose loose loose loose loose loose + Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. +# Heading 1 Heading 1 + +## Heading 2 Heading 2 + +### Heading 3 Heading 3 + +#### Heading 4 Heading 4 + +##### Heading 5 Heading 5 + +###### Heading 6 Heading 6 + +# Heading 1 Heading 1 + +## Heading 2 Heading 2 + +### Heading 3 Heading 3 + +#### Heading 4 Heading 4 + +##### Heading 5 Heading 5 + +###### Heading 6 Heading 6 + +The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. + +# Heading 1 Heading 1 + +The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. + +## Heading 2 Heading 2 + +The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. + +### Heading 3 Heading 3 + +The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. + +#### Heading 4 Heading 4 + The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. + +##### Heading 5 Heading 5 + +The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. + +###### Heading 6 Heading 6 + +The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. + +# Heading 1 Heading 1 + +- list list list +- list list list +- list list list + +## Heading 2 Heading 2 + +- list list list +- list list list +- list list list + +### Heading 3 Heading 3 + +- list list list +- list list list +- list list list + +#### Heading 4 Heading 4 + +- list list list +- list list list +- list list list + +##### Heading 5 Heading 5 + +- list list list +- list list list +- list list list + +###### Heading 6 Heading 6 + +- list list list +- list list list +- list list list diff --git a/layouts/templates/base.shtml b/layouts/templates/base.shtml @@ -1,463 +1,20 @@ -<!DOCTYPE html> -<html lang="en"> - <head id="head"> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> - <title :text="$site.title"></title> - <meta name="author" content="$page.author"> - <meta name="description" content="$page.description"> - <meta name="generator" content="Zine"> - <link rel="apple-touch-icon" sizes="180x180" href="$site.asset('icons/apple-touch-icon.png').link()"> - <link rel="icon" type="image/png" sizes="32x32" href="$site.asset('icons/favicon-32x32.png').link()"> - <link rel="icon" type="image/png" sizes="16x16" href="$site.asset('icons/favicon-16x16.png').link()"> - <link rel="manifest" href="$site.asset('icons/site.webmanifest').link()"> - <link rel="mask-icon" href="$site.asset('icons/safari-pinned-tab.svg').link()" color="#ffb6c1"> - <link rel="shortcut icon" href="$site.asset('icons/favicon.ico').link()"> - <meta name="msapplication-TileColor" content="#603cba"> - <meta name="msapplication-config" content="$site.asset('icons/browserconfig.xml').link()"> - <meta name="theme-color" content="#fdf9ee"> - <!-- preloading seems broken on firefox, sticking with the convoluted .font-loading solution --> - <!-- <link rel="preload" href="/fonts/AtkinsonHyperlegibleNextVF-Variable.woff2" as="font" type="font/woff2" crossorigin="anonymous"> --> - <!-- <link type="text/css" rel="stylesheet" href="$site.asset('style.css').link()"> --> - <!-- <link type="text/css" rel="stylesheet" href="$site.asset('highlight.css').link()"> --> - <!-- mathtex --> - <!-- <link type="text/css" rel="stylesheet" href="$site.asset('Temml-Local.css').link()"> --> - <!-- <script defer src="$site.asset('temml.min.js').link()"></script> --> - <!-- <script defer src="$site.asset('render-mathtex.js').link()"></script> --> - <!-- /mathtex --> - <style> - /* Modern CSS Reset https://www.joshwcomeau.com/css/custom-css-reset/ */ - *, *::before, *::after { box-sizing: border-box; } - * { margin: 0; } - @media (prefers-reduced-motion: no-preference) { html { interpolate-size: allow-keywords; } } - body { line-height: 1.5; -webkit-font-smoothing: antialiased; } - img, picture, video, canvas, svg { display: block; max-width: 100%; } - input, button, textarea, select { font: inherit; } - p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; hyphens: auto; } - p { text-wrap: pretty; } - h1, h2, h3, h4, h5, h6 { text-wrap: balance; } - #content { isolation: isolate; } - - /* Reset pointer events cause it messes up hitboxes */ - /* [href] is obviously needed for links, the rest are because */ - /* they make the cursor I shaped when hovering over text. */ - * { pointer-events: none; } - :is( - h1, h2, h3, h4, h5, h6, - blockquote, aside, details, - p, ul, ol, menu, dl, pre, [href]), - :is( - h1, h2, h3, h4, h5, h6, - blockquote, aside, details, - p, ul, ol, menu, dl, pre, [href]) * { - pointer-events: auto; - } - </style> - <style> - /* Sizes */ - :root { - --viewport-width: min(100vw, 600px); - --viewport-padding: 15px; - --content-width: calc(var(--viewport-width) - 2 * var(--viewport-padding)); - --wide-viewport-width: min(100vw, 900px); - --wide-content-width: calc(var(--wide-viewport-width) - 2 * var(--viewport-padding)); - --full-bleed-width: calc(100vw - 2 * var(--viewport-padding)); - --rem: 14pt; - } - </style> - <style> - /* Font face */ - @font-face { font-family: 'Atkinson Hyperlegible Next'; font-display: swap; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; src: url(/fonts/AtkinsonHyperlegibleNextVF-Variable.woff2) format('woff2'); } - </style> - <style> - /* Font loading magic to avoid Flash of Invisible Text */ - html { font-size: var(--rem); font-family: Arial, Helvetica, sans-serif; font-size-adjust: 0.52; } - html.font-loaded { font-family: 'Atkinson Hyperlegible Next', Arial, Helvetica, sans-serif; font-size-adjust: none; } - </style> - <style> - /* Horizontal spacing management */ - /* Philosophy: everything should be width = ~100vw by default, and limited at the last minute */ - div, header, footer, section, article, - h1, h2, h3, h4, h5, h6, - blockquote, aside, details, - p, ul, ol, menu, dl, pre { - width: 100%; - } - - /* 2 ways to limit: limit-children and limit-self */ - .limit-self, - .limit-children > * { - width: var(--content-width); - margin-inline: auto; - transition: all .3s cubic-bezier(0, 0, 0, 1); - } - .limit-children > .full-bleed { - width: var(--full-bleed-width); - } - padding-toggle:has(> padding-side > details[open]):has(> padding-side > details:not([open])) - > padding-main .limit-children > *:not(.full-bleed), - padding-toggle:has(> padding-side > details[open]):has(> padding-side > details:not([open])) - > padding-main .limit-self { - width: var(--wide-content-width); - } - - padding-toggle { - display: flex; - flex-direction: row; - align-items: stretch; - width: 100%; - } - padding-main { - pointer-events: none; - width: 100%; - } - padding-side { - display: block; - width: 0; - } - padding-side[right] { - direction: rtl; - } - padding-side > details { - height: 100%; - width: calc(max(var(--viewport-padding), 50vw - var(--content-width) / 2 - var(--viewport-padding))); - transition: all .3s cubic-bezier(0, 0, 0, 1); - } - padding-toggle:has(> padding-side > details[open]):has(> padding-side > details:not([open])) - > padding-side > details { - width: calc(max(var(--viewport-padding), 50vw - var(--wide-content-width) / 2 - var(--viewport-padding))); - } - padding-side > details > summary { - display: block; - height: 100%; - border-radius: var(--viewport-padding); - } - padding-side > details > summary:hover { - background: rgba(128, 0, 0, 2%); - } - </style> - <style> - /* Hierarchical vertical spacing management */ - /* Enable with .hierarchical, disable inside a .hierarchical with .non-hierarchical */ - /* Enable for a single element with .hierarchical-self */ - - /* Blocky texts */ - /* Headings: h1, h2, h3, h4, h5, h6 */ - /* Biglets: blockquote, figure, img, video, figcaption, details, pre, dl, ul, ol, menu */ - /* Paras: p, li, dt, dd */ - - /* Lists have special rules: They remove spacing from their children. */ - /* Lists: ul, ol, dl, menu */ - - /* Everything gets some start and end margin. */ - /* Biglets additionally get some padding. */ - - :root { - --paras-start: .5lh; - --paras-end: .25lh; - --biglets-padding: .2lh; - --hr-start: 1em; - --hr-end: 1em; - } - - h1, h2, h3, h4, h5, h6 { - line-height: 1; - } - - :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self):not(:is(ol, ul, dl, menu).tight > li > *) a:hover { - text-decoration: 2.5px dotted underline; - text-underline-position: under; - } - - :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self):not(:is(ol, ul, dl, menu).tight > li > *):not(:first-child - ):is( - h1, h2, h3, h4, h5, h6, - blockquote, figure, img, video, figcaption, details, pre, dl, ul, ol, menu, - p, :is(ol, ul, dl, menu).loose > :is(li, dt, dd) - ) { - margin-block-start: var(--paras-start); - } - - :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self):not(:is(ol, ul, dl, menu).tight > li > *):not(:last-child - ):is( - h1, h2, h3, h4, h5, h6, - blockquote, figure, img, video, figcaption, details, pre, dl, ul, ol, menu, - p, :is(ol, ul, dl, menu).loose > :is(li, dt, dd) - ) { - margin-block-end: var(--paras-end); - } - - :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self):not(:is(ol, ul, dl, menu).tight > li > *):not(:first-child - ):is( - blockquote, figure, img, video, figcaption, details, pre, dl, ul, ol, menu - ) { - padding-block-start: var(--biglets-padding); - } - - :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self):not(:is(ol, ul, dl, menu).tight > li > *):not(:last-child - ):is( - blockquote, figure, img, video, figcaption, details, pre, dl, ul, ol, menu - ) { - padding-block-end: var(--biglets-padding); - } - - hr:is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self):not(:is(ol, ul, dl, menu).tight > li > *) { - margin-block-start: var(--hr-start); - margin-block-end: var(--hr-end); - } - </style> - <style> - /* PERSONAL STYLE SECTION */ - /* Colours, sizes, lines, links, etc. */ - body { - background-color: #fdf9ee; - } - - ::selection { - background-color: #ff002630; - } - - h1 { - font-size: 1.9em; - } - - hr { - border: none; - border-top: 1px solid; - } - - a { - text-decoration: none; - } - a:hover { - text-decoration: 1px dotted underline; - } - a { color: #ac1052; } - a:hover { color: #7b0c3b; } - a:visited { color: #994016; } - a:visited:hover { color: #753111; } - - blockquote { - padding-inline-start: 15px; - border-inline-start: 3px solid gray; - } - - ul, ol, dl, menu { - padding-inline-start: 1.5em; - } - - tags { - display: flex; - gap: 0.5ch; - font-size: 0.8em; - color: #711; - } - tags > * { - background: #ffe8c8; - border-radius: 5px; - padding-inline: 0.5ch; - pointer-events: auto; - } - tags > tag { - background: #cef; - } - </style> - <style> - /* Template styling */ - #base-everything { - display: flex; - flex-direction: column; - align-items: center; - min-height: 100vh; - } - - #base-nav { - margin-inline: var(--viewport-padding); - } - - #base-nav a:not(:hover) { - color: #000; - text-decoration: none; - } - - #base-site-title-text { - padding-block-start: 12px; - text-align: center; - } - - #base-links { - display: flex; - justify-content: center; - flex-wrap: wrap; - gap: 20px; - row-gap: 0px; - } - - #base-links>a { - padding-block: 3px 12px; - } - - #base-header { - overflow: hidden; - } - - #base-header-rule { - margin-inline: calc(0px - mod(-100vw, 40px) / 2); - margin-block-end: 30px; - border-block-start: 10px dotted lightpink; - } - - #base-footer { - margin-block-start: auto; - } - - #base-footer-rule { - max-width: 25ch; - margin-block-start: 20px; - margin-inline: auto; - border-block-start: 1.5px dotted brown; - } - - #base-no-cookie { - max-width: var(--content-width); - margin-block-end: 15px; - padding-block-start: .4lh; - text-align: center; - color: brown; - } - </style> - </head> - <body id="body"> - <span style="position: absolute; color: #fdf9ee; left: 0; top: 0; font-family: 'Atkinson Hyperlegible Next'">.</span> - <div id="base-everything"> - <header id="base-header"> - <nav id="base-nav"> - <a id="base-site-title" href="$site.page('').link()"> - <h2 id="base-site-title-text" :text="$site.title"></h2> - </a> - <div id="base-links"> - <a href="$site.page('').link()">Home</a> - <a href="$site.page('posts').link()">Posts</a> - <a href="$site.page('bio').link()">Bio</a> - <a href="$site.page('teaching').link()">Teaching</a> - </div> - </nav> - <hr id="base-header-rule"> - </header> - <padding-toggle> - <padding-side left><details><summary></summary></details></padding-side> - <padding-main> - <div id="content"> - <super> - </div> - </padding-main> - <padding-side right><details><summary></summary></details></padding-side> - </padding-toggle> - <footer id="base-footer" class="limit-children"> - <hr id="base-footer-rule"> - <p id="base-no-cookie">This - <a rel="noreferrer" href="//git.grace.moe/blog.grace.moe/log.html">site</a> - uses no cookies. ❌🍪</p> - </footer> - </div> - <script> - /* Font Face Observer v2.3.0 - © Bram Stein. License: BSD-3-Clause */(function(){function p(a,c){document.addEventListener?a.addEventListener("scroll",c,!1):a.attachEvent("scroll",c)}function u(a){document.body?a():document.addEventListener?document.addEventListener("DOMContentLoaded",function b(){document.removeEventListener("DOMContentLoaded",b);a()}):document.attachEvent("onreadystatechange",function g(){if("interactive"==document.readyState||"complete"==document.readyState)document.detachEvent("onreadystatechange",g),a()})};function w(a){this.g=document.createElement("div");this.g.setAttribute("aria-hidden","true");this.g.appendChild(document.createTextNode(a));this.h=document.createElement("span");this.i=document.createElement("span");this.m=document.createElement("span");this.j=document.createElement("span");this.l=-1;this.h.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.i.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;"; - this.j.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.m.style.cssText="display:inline-block;width:200%;height:200%;font-size:16px;max-width:none;";this.h.appendChild(this.m);this.i.appendChild(this.j);this.g.appendChild(this.h);this.g.appendChild(this.i)} - function x(a,c){a.g.style.cssText="max-width:none;min-width:20px;min-height:20px;display:inline-block;overflow:hidden;position:absolute;width:auto;margin:0;padding:0;top:-999px;white-space:nowrap;font-synthesis:none;font:"+c+";"}function B(a){var c=a.g.offsetWidth,b=c+100;a.j.style.width=b+"px";a.i.scrollLeft=b;a.h.scrollLeft=a.h.scrollWidth+100;return a.l!==c?(a.l=c,!0):!1}function C(a,c){function b(){var e=g;B(e)&&null!==e.g.parentNode&&c(e.l)}var g=a;p(a.h,b);p(a.i,b);B(a)};function D(a,c,b){c=c||{};b=b||window;this.family=a;this.style=c.style||"normal";this.weight=c.weight||"normal";this.stretch=c.stretch||"normal";this.context=b}var E=null,F=null,G=null,H=null;function I(a){null===F&&(M(a)&&/Apple/.test(window.navigator.vendor)?(a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))(?:\.([0-9]+))/.exec(window.navigator.userAgent),F=!!a&&603>parseInt(a[1],10)):F=!1);return F}function M(a){null===H&&(H=!!a.document.fonts);return H} - function N(a,c){var b=a.style,g=a.weight;if(null===G){var e=document.createElement("div");try{e.style.font="condensed 100px sans-serif"}catch(q){}G=""!==e.style.font}return[b,g,G?a.stretch:"","100px",c].join(" ")} - D.prototype.load=function(a,c){var b=this,g=a||"BESbswy",e=0,q=c||3E3,J=(new Date).getTime();return new Promise(function(K,L){if(M(b.context)&&!I(b.context)){var O=new Promise(function(r,t){function h(){(new Date).getTime()-J>=q?t(Error(""+q+"ms timeout exceeded")):b.context.document.fonts.load(N(b,'"'+b.family+'"'),g).then(function(n){1<=n.length?r():setTimeout(h,25)},t)}h()}),P=new Promise(function(r,t){e=setTimeout(function(){t(Error(""+q+"ms timeout exceeded"))},q)});Promise.race([P,O]).then(function(){clearTimeout(e); - K(b)},L)}else u(function(){function r(){var d;if(d=-1!=k&&-1!=l||-1!=k&&-1!=m||-1!=l&&-1!=m)(d=k!=l&&k!=m&&l!=m)||(null===E&&(d=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),E=!!d&&(536>parseInt(d[1],10)||536===parseInt(d[1],10)&&11>=parseInt(d[2],10))),d=E&&(k==y&&l==y&&m==y||k==z&&l==z&&m==z||k==A&&l==A&&m==A)),d=!d;d&&(null!==f.parentNode&&f.parentNode.removeChild(f),clearTimeout(e),K(b))}function t(){if((new Date).getTime()-J>=q)null!==f.parentNode&&f.parentNode.removeChild(f), - L(Error(""+q+"ms timeout exceeded"));else{var d=b.context.document.hidden;if(!0===d||void 0===d)k=h.g.offsetWidth,l=n.g.offsetWidth,m=v.g.offsetWidth,r();e=setTimeout(t,50)}}var h=new w(g),n=new w(g),v=new w(g),k=-1,l=-1,m=-1,y=-1,z=-1,A=-1,f=document.createElement("div");f.dir="ltr";x(h,N(b,"sans-serif"));x(n,N(b,"serif"));x(v,N(b,"monospace"));f.appendChild(h.g);f.appendChild(n.g);f.appendChild(v.g);b.context.document.body.appendChild(f);y=h.g.offsetWidth;z=n.g.offsetWidth;A=v.g.offsetWidth;t(); - C(h,function(d){k=d;r()});x(h,N(b,'"'+b.family+'",sans-serif'));C(n,function(d){l=d;r()});x(n,N(b,'"'+b.family+'",serif'));C(v,function(d){m=d;r()});x(v,N(b,'"'+b.family+'",monospace'))})})};"object"===typeof module?module.exports=D:(window.FontFaceObserver=D,window.FontFaceObserver.prototype.load=D.prototype.load);}()); - - var font = new FontFaceObserver('Atkinson Hyperlegible Next'); - font.load().then(function () { - document.querySelector('html').classList.add('font-loaded'); - console.log("Loaded."); - }, function () { - document.querySelector('html').classList.add('font-loaded'); - console.log("Failed."); - }); - </script> - <script> - const promises = {}; - const results = {}; - - function mouseEnterListener() { - const href = this.href; - console.log('enter', this, href, promises[href]); - if (promises[href] === undefined) { - promises[href] = new Promise((resolve) => { - const req = new XMLHttpRequest(); - req.addEventListener("load", function() { - results[href] = new DOMParser().parseFromString(this.response, "text/html").querySelector('#content'); - console.log('ho', results[href]); - resolve(results[href]); - }); - req.open("GET", href + '/index.raw.html'); - req.send(); - }); - } - } - - function clickListener(event) { - const href = this.href; - console.log('click', this, href, promises[href]); - if (promises[href] !== undefined) { - event.preventDefault(); - promises[href].then((content) => { - document.querySelector('#content').innerHTML = content.innerHTML; - history.pushState(null, '', href + '#body'); - history.replaceState(null, '', href); - refreshLinks(); - }); - } - } - - function refreshLinks() { - for (let a of document.querySelectorAll("a")) { - if ( - !a.href.endsWith("/") || - a.href.match("^.*//[^/]*/")[0] !== - location.href.match("^.*//[^/]*/")[0] || - a.href.match("^.*//[^/]*/git") !== null - ) { - continue; - } - console.log(a); - a.onmouseenter = mouseEnterListener; - a.onclick = clickListener; - } - } - refreshLinks(); - - function popStateListener(event) { - console.log('popstate'); - const href = location.href; - if (results[location.href] === undefined) { - if (promises[href] === undefined) { - promises[href] = new Promise((resolve) => { - const req = new XMLHttpRequest(); - req.addEventListener("load", function() { - results[href] = new DOMParser().parseFromString(this.response, "text/html").querySelector('#content'); - console.log('ho', results[href]); - resolve(results[href]); - }); - req.open("GET", href + '/index.raw.html'); - req.send(); - }); - } - promises[href].then((content) => { - document.querySelector('#content').innerHTML = content.innerHTML; - refreshLinks(); - }); - } else { - document.querySelector('#content').innerHTML = results[location.href].innerHTML; - refreshLinks(); - } - } - - window.onpopstate = popStateListener; - </script> - </body> -</html> -\ No newline at end of file +<extend template="template.shtml"> +<head id="head"> + <style> + #base-links>a { + padding-block: 3px 12px; + } + </style> +</head> +<div id="base-links"> + <a href="$site.page('').link()">Home</a> + <a href="$site.page('posts').link()">Posts</a> + <a href="$site.page('bio').link()">Bio</a> + <a href="$site.page('teaching').link()">Teaching</a> +</div> +<div id="content"><super></div> +<footer id="base-footer"> + <p id="base-no-cookie">This + <a rel="noreferrer" href="//git.grace.moe/blog.grace.moe/log.html">site</a> + uses no cookies. ❌🍪</p> +</footer> +\ No newline at end of file diff --git a/layouts/templates/template.shtml b/layouts/templates/template.shtml @@ -0,0 +1,467 @@ +<!DOCTYPE html> +<html lang="en"> + <head id="head"> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <title :text="$site.title"></title> + <meta name="author" content="$page.author"> + <meta name="description" content="$page.description"> + <meta name="generator" content="Zine"> + <!-- Generate your favicons --> + <link rel="apple-touch-icon" sizes="180x180" href="$site.asset('icons/apple-touch-icon.png').link()"> + <link rel="icon" type="image/png" sizes="32x32" href="$site.asset('icons/favicon-32x32.png').link()"> + <link rel="icon" type="image/png" sizes="16x16" href="$site.asset('icons/favicon-16x16.png').link()"> + <link rel="manifest" href="$site.asset('icons/site.webmanifest').link()"> + <link rel="mask-icon" href="$site.asset('icons/safari-pinned-tab.svg').link()" color="#ffb6c1"> + <link rel="shortcut icon" href="$site.asset('icons/favicon.ico').link()"> + <meta name="msapplication-TileColor" content="#603cba"> + <meta name="msapplication-config" content="$site.asset('icons/browserconfig.xml').link()"> + <meta name="theme-color" content="#fdf9ee"> + <!-- preloading seems broken on firefox, sticking with the convoluted .font-loading solution --> + <!-- <link rel="preload" href="/fonts/AtkinsonHyperlegibleNextVF-Variable.woff2" as="font" type="font/woff2" crossorigin="anonymous"> --> + <!-- <link type="text/css" rel="stylesheet" href="$site.asset('style.css').link()"> --> + <!-- <link type="text/css" rel="stylesheet" href="$site.asset('highlight.css').link()"> --> + <!-- mathtex --> + <!-- <link type="text/css" rel="stylesheet" href="$site.asset('Temml-Local.css').link()"> --> + <!-- <script defer src="$site.asset('temml.min.js').link()"></script> --> + <!-- <script defer src="$site.asset('render-mathtex.js').link()"></script> --> + <!-- /mathtex --> + <style> + /* Modern CSS Reset https://www.joshwcomeau.com/css/custom-css-reset/ */ + *, *::before, *::after { box-sizing: border-box; } + * { margin: 0; } + @media (prefers-reduced-motion: no-preference) { html { interpolate-size: allow-keywords; } } + body { line-height: 1.5; -webkit-font-smoothing: antialiased; } + img, picture, video, canvas, svg { display: block; max-width: 100%; } + input, button, textarea, select { font: inherit; } + p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; hyphens: auto; } + p { text-wrap: pretty; } + h1, h2, h3, h4, h5, h6 { text-wrap: balance; } + #content { isolation: isolate; } + + /* My own resets */ + h1, h2, h3, h4, h5, h6 { line-height: 1; } + textarea { display: block; max-width: 100%; } + pre { overflow-x: scroll; } + + /* Remove pointer events from structural elements cause it messes up hitboxes */ + div, main, header, footer, section, article, [structural] { + pointer-events: none; + } + /* pointer-events is inherited, so we have to reset it to auto for children */ + :is(div, main, header, footer, section, article, [structural]) + > *:not(div, main, header, footer, section, article, [structural]) { + pointer-events: auto; + } + </style> + <style> + /* Sizes */ + :root { + --viewport-width: min(100vw, 600px); + --viewport-padding: 15px; + --content-width: calc(var(--viewport-width) - 2 * var(--viewport-padding)); + --wide-viewport-width: min(100vw, 900px); + --wide-content-width: calc(var(--wide-viewport-width) - 2 * var(--viewport-padding)); + --full-bleed-width: calc(100vw - 2 * var(--viewport-padding)); + --rem: 14pt; + } + </style> + <style> + /* Font face */ + @font-face { font-family: 'Atkinson Hyperlegible Next'; font-display: swap; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; src: url(/fonts/AtkinsonHyperlegibleNextVF-Variable.woff2) format('woff2'); } + @font-face { font-family: 'Atkinson Hyperlegible Mono'; font-display: swap; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; src: url(/fonts/AtkinsonHyperlegibleMonoVF-Variable.woff2) format('woff2'); } + </style> + <style> + /* Font loading magic to avoid Flash of Invisible Text */ + html { font-size: var(--rem); font-family: Arial, Helvetica, sans-serif; font-size-adjust: 0.52; } + html.font-loaded { font-family: 'Atkinson Hyperlegible Next', Arial, Helvetica, sans-serif; font-size-adjust: none; } + html.font-loaded :is(code, pre, tt, kbd, samp) { font-family: 'Atkinson Hyperlegible Mono', monospace; } + </style> + <style> + /* Horizontal spacing management */ + /* Philosophy: everything should be width = ~100vw by default, and limited at the last minute */ + div, header, footer, section, article, + h1, h2, h3, h4, h5, h6, + blockquote, aside, details, + p, ul, ol, menu, dl, pre { + width: 100%; + } + + /* 2 ways to limit: limit-children and limit-self */ + .limit-self, + .limit-children > * { + width: var(--content-width); + margin-inline: auto; + transition: all .3s cubic-bezier(0, 0, 0, 1); + } + .limit-children > .full-bleed-content { + width: var(--full-bleed-width); + } + .limit-children > .wide-content { + width: var(--wide-content-width); + } + #base-middle.wide > #content .limit-children > *:not(.full-bleed-content), + #base-middle.wide > #content .limit-self { + width: var(--wide-content-width); + } + + #base-middle { + display: flex; + flex-direction: row; + align-items: stretch; + width: 100%; + } + #content { + pointer-events: none; + width: 100%; + } + .base-padding { + width: 0; + } + .base-padding.right { + direction: rtl; + } + .base-padding > button { + height: 100%; + border-radius: var(--viewport-padding); + border: none; + background: none; + padding: 0; + width: calc(max(var(--viewport-padding), 50vw - var(--content-width) / 2 - var(--viewport-padding))); + transition: all .3s cubic-bezier(0, 0, 0, 1); + } + .base-padding > button:hover { + background: rgba(128, 0, 0, 2%); + } + #base-middle.wide > .base-padding > button { + width: calc(max(var(--viewport-padding), 50vw - var(--wide-content-width) / 2 - var(--viewport-padding))); + } + </style> + <style> + /* Hierarchical vertical spacing management */ + /* Enable with .hierarchical, disable inside a .hierarchical with .non-hierarchical */ + /* Enable for a single element with .hierarchical-self */ + + /* Blocky texts */ + /* Headings: h1, h2, h3, h4, h5, h6 */ + /* Biglets: blockquote, figure, img, video, figcaption, details, pre, dl, ul, ol, menu */ + /* Everything else: p, li, dt, dd, ... */ + + /* Lists have special rules: They remove spacing from their children. */ + /* Lists: ul, ol, dl, menu */ + + /* Everything gets some start and end margin. */ + /* Biglets additionally get some padding. */ + + :root { + --headings-start: 1rlh; + --paras-start: .5lh; + --paras-end: .25lh; + --biglets-padding: .2lh; + --hr-start: 1em; + --hr-end: 1em; + } + + :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self + ):not(:is(ol, ul, dl, menu).tight > li, :is(ol, ul, dl, menu).tight > li > *) a:hover { + text-decoration: 2.5px dotted underline; + text-underline-position: under; + } + + :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self + ):not(:is(ol, ul, dl, menu).tight > li, :is(ol, ul, dl, menu).tight > li > *, :first-child + ):not(:is(h1, h2, h3, h4, h5, h6) + *) { + margin-block-start: var(--paras-start); + } + + :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self + ):not(:is(ol, ul, dl, menu).tight > li, :is(ol, ul, dl, menu).tight > li > *, :first-child + ):not(:is(h1, h2, h3, h4, h5, h6) + *):is(h1, h2, h3, h4, h5, h6) { + margin-block-start: var(--headings-start); + } + + :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self + ):not(:is(ol, ul, dl, menu).tight > li, :is(ol, ul, dl, menu).tight > li > *, :last-child) { + margin-block-end: var(--paras-end); + } + + :is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self + ):not(:is(ol, ul, dl, menu).tight > li, :is(ol, ul, dl, menu).tight > li > * + ):is(blockquote, figure, img, video, figcaption, details, pre, dl, ul, ol, menu) { + padding-block-end: var(--biglets-padding); + padding-block-start: var(--biglets-padding); + } + + hr:is(.hierarchical *:not(.non-hierarchical *), .hierarchical-self + ):not(:is(ol, ul, dl, menu).tight > li, :is(ol, ul, dl, menu).tight > li > *) { + margin-block-start: var(--hr-start); + margin-block-end: var(--hr-end); + } + </style> + <style> + /* PERSONAL STYLE SECTION */ + /* Colours, sizes, lines, links, etc. */ + body { + background-color: #fdf9ee; + } + + ::selection { + background-color: #ff002630; + } + + h1 { + font-size: 1.9em; + } + + hr { + border: none; + border-top: 1px solid; + } + + a { + text-decoration: none; + } + a:hover { + text-decoration: 1px dotted underline; + } + a { color: #ac1052; } + a:hover { color: #7b0c3b; } + a:visited { color: #994016; } + a:visited:hover { color: #753111; } + + blockquote { + padding-inline-start: 15px; + border-inline-start: 3px solid gray; + } + + ul, ol, dl, menu { + padding-inline-start: 1.5em; + } + + tags { + display: flex; + gap: 0.5ch; + font-size: 0.8em; + color: #711; + } + tags > * { + background: #ffe8c8; + border-radius: calc(0.5ch / 0.4142135623730951); + padding: 0.5ch; + pointer-events: auto; + line-height: 1; + } + tags > tag { + background: #cef; + } + + code:not(pre *) { + line-height: 1.3; + background: #ffe8c8; + padding: 0.1lh; + border-radius: calc(0.1lh / 0.4142135623730951); + } + pre { + line-height: 1.3; + background-image: + linear-gradient(to right, #ffe8c8, #ffe8c8), + linear-gradient(to right, #ffe8c8, #ffe8c8), + linear-gradient(to right, rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0)), + linear-gradient(to left, rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0)); + background-position: left center, right center, left center, right center; + background-repeat: no-repeat; + background-color: #ffe8c8; + background-size: 20px 100%, 20px 100%, 15px 100%, 15px 100%; + background-attachment: local, local, scroll, scroll; + padding: 0.3lh; + border-radius: calc(0.3lh / 0.4142135623730951); + } + </style> + <style> + /* Template styling */ + #base-everything { + display: flex; + flex-direction: column; + align-items: center; + min-height: 100vh; + } + + #base-nav { + margin-inline: var(--viewport-padding); + } + + #base-nav a:not(:hover) { + color: #000; + text-decoration: none; + } + + #base-site-title-text { + padding-block-start: 12px; + text-align: center; + } + + #base-links { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 20px; + row-gap: 0px; + } + + #base-header { + overflow: hidden; + } + + #base-header-rule { + margin-inline: calc(0px - mod(-100vw, 40px) / 2); + margin-block-end: 30px; + border-block-start: 10px dotted lightpink; + } + + #base-footer { + margin-block-start: auto; + } + + #base-footer-rule { + max-width: 25ch; + margin-block-start: 20px; + margin-inline: auto; + border-block-start: 1.5px dotted brown; + } + + #base-no-cookie { + max-width: var(--content-width); + margin-block-end: 15px; + padding-block-start: .4lh; + text-align: center; + color: brown; + } + </style> + <super> + </head> + <body id="body"> + <span style="position: absolute; color: #fdf9ee; left: -10em; top: -10em; font-family: 'Atkinson Hyperlegible Next'">.</span> + <span style="position: absolute; color: #fdf9ee; left: -10em; top: -10em; font-family: 'Atkinson Hyperlegible Mono'">.</span> + <div id="base-everything"> + <header id="base-header"> + <nav id="base-nav"> + <a id="base-site-title" href="$site.page('').link()"> + <h2 id="base-site-title-text" :text="$site.title"></h2> + </a> + <div id="base-links"> + <super> + </div> + </nav> + <hr id="base-header-rule"> + </header> + <div id="base-middle"> + <div class="base-padding left"><button onclick="document.querySelector('#base-middle').classList.toggle('wide');"></button></div> + <div id="content"><super></div> + <div class="base-padding right"><button onclick="document.querySelector('#base-middle').classList.toggle('wide');"></button></div> + </div> + <footer id="base-footer" class="limit-children"> + <hr id="base-footer-rule"> + <super> + </footer> + </div> + <script> + /* Font Face Observer v2.3.0 - © Bram Stein. License: BSD-3-Clause */(function(){function p(a,c){document.addEventListener?a.addEventListener("scroll",c,!1):a.attachEvent("scroll",c)}function u(a){document.body?a():document.addEventListener?document.addEventListener("DOMContentLoaded",function b(){document.removeEventListener("DOMContentLoaded",b);a()}):document.attachEvent("onreadystatechange",function g(){if("interactive"==document.readyState||"complete"==document.readyState)document.detachEvent("onreadystatechange",g),a()})};function w(a){this.g=document.createElement("div");this.g.setAttribute("aria-hidden","true");this.g.appendChild(document.createTextNode(a));this.h=document.createElement("span");this.i=document.createElement("span");this.m=document.createElement("span");this.j=document.createElement("span");this.l=-1;this.h.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.i.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;"; + this.j.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.m.style.cssText="display:inline-block;width:200%;height:200%;font-size:16px;max-width:none;";this.h.appendChild(this.m);this.i.appendChild(this.j);this.g.appendChild(this.h);this.g.appendChild(this.i)} + function x(a,c){a.g.style.cssText="max-width:none;min-width:20px;min-height:20px;display:inline-block;overflow:hidden;position:absolute;width:auto;margin:0;padding:0;top:-999px;white-space:nowrap;font-synthesis:none;font:"+c+";"}function B(a){var c=a.g.offsetWidth,b=c+100;a.j.style.width=b+"px";a.i.scrollLeft=b;a.h.scrollLeft=a.h.scrollWidth+100;return a.l!==c?(a.l=c,!0):!1}function C(a,c){function b(){var e=g;B(e)&&null!==e.g.parentNode&&c(e.l)}var g=a;p(a.h,b);p(a.i,b);B(a)};function D(a,c,b){c=c||{};b=b||window;this.family=a;this.style=c.style||"normal";this.weight=c.weight||"normal";this.stretch=c.stretch||"normal";this.context=b}var E=null,F=null,G=null,H=null;function I(a){null===F&&(M(a)&&/Apple/.test(window.navigator.vendor)?(a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))(?:\.([0-9]+))/.exec(window.navigator.userAgent),F=!!a&&603>parseInt(a[1],10)):F=!1);return F}function M(a){null===H&&(H=!!a.document.fonts);return H} + function N(a,c){var b=a.style,g=a.weight;if(null===G){var e=document.createElement("div");try{e.style.font="condensed 100px sans-serif"}catch(q){}G=""!==e.style.font}return[b,g,G?a.stretch:"","100px",c].join(" ")} + D.prototype.load=function(a,c){var b=this,g=a||"BESbswy",e=0,q=c||3E3,J=(new Date).getTime();return new Promise(function(K,L){if(M(b.context)&&!I(b.context)){var O=new Promise(function(r,t){function h(){(new Date).getTime()-J>=q?t(Error(""+q+"ms timeout exceeded")):b.context.document.fonts.load(N(b,'"'+b.family+'"'),g).then(function(n){1<=n.length?r():setTimeout(h,25)},t)}h()}),P=new Promise(function(r,t){e=setTimeout(function(){t(Error(""+q+"ms timeout exceeded"))},q)});Promise.race([P,O]).then(function(){clearTimeout(e); + K(b)},L)}else u(function(){function r(){var d;if(d=-1!=k&&-1!=l||-1!=k&&-1!=m||-1!=l&&-1!=m)(d=k!=l&&k!=m&&l!=m)||(null===E&&(d=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),E=!!d&&(536>parseInt(d[1],10)||536===parseInt(d[1],10)&&11>=parseInt(d[2],10))),d=E&&(k==y&&l==y&&m==y||k==z&&l==z&&m==z||k==A&&l==A&&m==A)),d=!d;d&&(null!==f.parentNode&&f.parentNode.removeChild(f),clearTimeout(e),K(b))}function t(){if((new Date).getTime()-J>=q)null!==f.parentNode&&f.parentNode.removeChild(f), + L(Error(""+q+"ms timeout exceeded"));else{var d=b.context.document.hidden;if(!0===d||void 0===d)k=h.g.offsetWidth,l=n.g.offsetWidth,m=v.g.offsetWidth,r();e=setTimeout(t,50)}}var h=new w(g),n=new w(g),v=new w(g),k=-1,l=-1,m=-1,y=-1,z=-1,A=-1,f=document.createElement("div");f.dir="ltr";x(h,N(b,"sans-serif"));x(n,N(b,"serif"));x(v,N(b,"monospace"));f.appendChild(h.g);f.appendChild(n.g);f.appendChild(v.g);b.context.document.body.appendChild(f);y=h.g.offsetWidth;z=n.g.offsetWidth;A=v.g.offsetWidth;t(); + C(h,function(d){k=d;r()});x(h,N(b,'"'+b.family+'",sans-serif'));C(n,function(d){l=d;r()});x(n,N(b,'"'+b.family+'",serif'));C(v,function(d){m=d;r()});x(v,N(b,'"'+b.family+'",monospace'))})})};"object"===typeof module?module.exports=D:(window.FontFaceObserver=D,window.FontFaceObserver.prototype.load=D.prototype.load);}()); + + var font = new FontFaceObserver('Atkinson Hyperlegible Next'); + font.load().then(function () { + document.querySelector('html').classList.add('font-loaded'); + console.log("Loaded."); + }, function () { + document.querySelector('html').classList.add('font-loaded'); + console.log("Failed."); + }); + </script> + <script> + const promises = {}; + const results = {}; + + function mouseEnterListener() { + const href = this.href; + console.log('enter', this, href, promises[href]); + if (promises[href] === undefined) { + promises[href] = new Promise((resolve) => { + const req = new XMLHttpRequest(); + req.addEventListener("load", function() { + results[href] = new DOMParser().parseFromString(this.response, "text/html").querySelector('#content'); + console.log('ho', results[href]); + resolve(results[href]); + }); + req.open("GET", href + '/index.raw.html'); + req.send(); + }); + } + } + + function clickListener(event) { + const href = this.href; + console.log('click', this, href, promises[href]); + if (promises[href] !== undefined) { + event.preventDefault(); + promises[href].then((content) => { + document.querySelector('#content').innerHTML = content.innerHTML; + history.pushState(null, '', href + '#body'); + history.replaceState(null, '', href); + refreshLinks(); + }); + } + } + + function refreshLinks() { + for (let a of document.querySelectorAll("a")) { + if ( + !a.href.endsWith("/") || + a.href.match("^.*//[^/]*/")[0] !== + location.href.match("^.*//[^/]*/")[0] || + a.href.match("^.*//[^/]*/git") !== null + ) { + continue; + } + console.log(a); + a.onmouseenter = mouseEnterListener; + a.onclick = clickListener; + } + } + refreshLinks(); + + function popStateListener(event) { + console.log('popstate'); + const href = location.href; + if (results[location.href] === undefined) { + if (promises[href] === undefined) { + promises[href] = new Promise((resolve) => { + const req = new XMLHttpRequest(); + req.addEventListener("load", function() { + results[href] = new DOMParser().parseFromString(this.response, "text/html").querySelector('#content'); + console.log('ho', results[href]); + resolve(results[href]); + }); + req.open("GET", href + '/index.raw.html'); + req.send(); + }); + } + promises[href].then((content) => { + document.querySelector('#content').innerHTML = content.innerHTML; + refreshLinks(); + }); + } else { + document.querySelector('#content').innerHTML = results[location.href].innerHTML; + refreshLinks(); + } + } + + window.onpopstate = popStateListener; + </script> + </body> +</html> +\ No newline at end of file diff --git a/zine.ziggy b/zine.ziggy @@ -6,10 +6,10 @@ Site { .assets_dir_path = "assets", .static_assets = [ "docs/POPL-2025-SRC-Grace-Tan-Extended-Abstract.pdf", - "404.html", "css/AtkinsonHyperlegibleNext.css", "fonts/AtkinsonHyperlegibleNextVF-Variable.woff2", + "fonts/AtkinsonHyperlegibleMonoVF-Variable.woff2", "icons/android-chrome-192x192.png", "icons/android-chrome-512x512.png", "icons/apple-touch-icon.png",