Rust library to generate static websites
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(website): Make it more responsive

Princesseuh f3b118ae 3118b9c9

+27 -25
+2
crates/cli/src/dev/server.rs
··· 99 99 let service = (move || handle_404(socket_addr, host, dist_dir)).into_service(); 100 100 let serve_dir = ServeDir::new(dist_dir).not_found_service(service); 101 101 102 + // TODO: Return a `.well-known/appspecific/com.chrome.devtools.json` for Chrome 103 + 102 104 let router = Router::new() 103 105 .route("/ws", get(ws_handler)) 104 106 .fallback_service(serve_dir)
+8 -5
website/assets/prin.css
··· 33 33 34 34 .btn { 35 35 color: var(--color-brand-red); 36 - font-size: 1.35rem; 36 + font-size: 1.55rem; 37 37 font-weight: bold; 38 38 } 39 39 ··· 61 61 } 62 62 63 63 .hero-background { 64 - background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZpZXdCb3g9IjAgMCA0NjYgNDY1Ij48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48cGF0aCBkPSJNMjMgMTRoNDc2djQ3NUgyM1ptMjQ3IDU4Yy0yOCAwLTU1IDYtODEgMjBhMTY0IDE2NCAwIDAgMC03MCAyMjRjNDUgODEgMTQ3IDExMSAyMjkgNjggODMtNDMgMTE0LTE0NCA3MC0yMjRsLTEzIDdjNDAgNzMgMTIgMTY0LTY0IDIwNC03NSAzOS0xNjggMTEtMjA4LTYyLTQxLTc0LTEyLTE2NSA2My0yMDRzMTY5LTExIDIwOSA2MmwxMy03Yy0zMC01Ni04OC04Ny0xNDgtODhabTcyIDI0OSAzNCA2di01MmwtMi01Mi00LTIyLTMtMjIgNC0zIDUtM2MxLTIgMi02IDEtMTItMS00LTEtNS00LTdzLTMtMi04LTJoLTZsLTQgNS00IDV2MTJsNCAzIDMgMi0xMSAzOGMtMTAgMzYtMTEgMzktMTQgMzlsLTI2LTc3IDMtMSA0LTNjMi0zIDEtOC0xLTEzLTItNC0zLTQtNy01bC03IDFjLTMgMy00IDMtNSA3bC0xIDQgMyA0IDMgNC04IDMxLTExIDM3LTMgOWMtMSAyLTQtMy0xNS0yNC0xMS0yMi0xMS0yMi0xNS0zNGwtNC0xNCAzLTdjMy04IDMtMTAgMS0xNS0zLTQtNi02LTEyLTQtNCAwLTQgMS04IDVsLTQgNCAxIDYgNSAxMSAyIDVhMTIzMSAxMjMxIDAgMCAwLTExIDQwbC0zIDEwLTM1LTQ1LTgtMTIgMS0yIDItNy0yLTgtNi0yYy00LTEtNC0xLTcgMS00IDItNCAyLTQgNi0xIDUgMSAxMSA1IDEybDEgMSAyIDY5IDMgNjlhOTA4IDkwOCAwIDAgMSA1OS00bDQxLTIgMjAgMmMyMSAwIDIxIDAgNTMgNnYiIGNsYXNzPSJwb3dlcmNsaXAiIHN0eWxlPSJjb2xvcjojMDAwO2ZpbGw6I2ZmZjtzdHJva2Utd2lkdGg6MTstaW5rc2NhcGUtc3Ryb2tlOm5vbmUiLz48L2NsaXBQYXRoPjwvZGVmcz48cGF0aCBkPSJNNDU3IDQxMWMtNyAwLTE1IDItMjEgNy0zNSAyNi0xMCA3NSAzMSA0MSAzMy0yNyAxNC00OS0xMC00OFpNMjkwIDE5Yy0zMSAwLTY3IDE0LTg3IDI1LTE1IDgtNjQgMzctMTA3IDQ2LTU1IDEwLTg3IDYzLTU1IDkwIDU0IDQ0IDU2IDEwMSAxNiAxNDMtNDQgNDYgMSAxMTMgNjQgMTA2IDYzLTggODkgMCAxMjEgMzIgNDEgNDEgMTMyIDI1IDE1NC0zMyAxMC0yNiAyNC01NiA1OC02OCA0MS0xNCA1My01OSAyNi05MS0xOS0yMy0yMS00NyA1LTk1IDIyLTQwIDUtODQtNTYtODEtNDUgMy02NC0yNy05Ny01OWE1OSA1OSAwIDAgMC00Mi0xNXoiIGNsaXAtcGF0aD0idXJsKCNhKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI4IC0xOSkiIGZpbGw9IiNiYTFmMzMiLz48L3N2Zz4K"); 64 + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZpZXdCb3g9IjAgMCA0NjYgNDY1Ij48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjMgMTRoNDc2djQ3NUgyM1ptMjQ3IDU4Yy0yOCAwLTU1IDYtODEgMjBhMTY0IDE2NCAwIDAgMC03MCAyMjRjNDUgODEgMTQ3IDExMSAyMjkgNjggODMtNDMgMTE0LTE0NCA3MC0yMjRsLTEzIDdjNDAgNzMgMTIgMTY0LTY0IDIwNC03NSAzOS0xNjggMTEtMjA4LTYyLTQxLTc0LTEyLTE2NSA2My0yMDRzMTY5LTExIDIwOSA2MmwxMy03Yy0zMC01Ni04OC04Ny0xNDgtODhabTcyIDI0OSAzNCA2di01MmwtMi01Mi00LTIyLTMtMjIgNC0zIDUtM2MxLTIgMi02IDEtMTItMS00LTEtNS00LTdzLTMtMi04LTJoLTZsLTQgNS00IDV2MTJsNCAzIDMgMi0xMSAzOGMtMTAgMzYtMTEgMzktMTQgMzlsLTI2LTc3IDMtMSA0LTNjMi0zIDEtOC0xLTEzLTItNC0zLTQtNy01bC03IDFjLTMgMy00IDMtNSA3bC0xIDQgMyA0IDMgNC04IDMxLTExIDM3LTMgOWMtMSAyLTQtMy0xNS0yNC0xMS0yMi0xMS0yMi0xNS0zNGwtNC0xNCAzLTdjMy04IDMtMTAgMS0xNS0zLTQtNi02LTEyLTQtNCAwLTQgMS04IDVsLTQgNCAxIDYgNSAxMSAyIDVhMTIzMSAxMjMxIDAgMCAwLTExIDQwbC0zIDEwLTM1LTQ1LTgtMTIgMS0yIDItNy0yLTgtNi0yYy00LTEtNC0xLTcgMS00IDItNCAyLTQgNi0xIDUgMSAxMSA1IDEybDEgMSAyIDY5IDMgNjlhOTA4IDkwOCAwIDAgMSA1OS00bDQxLTIgMjAgMmMyMSAwIDIxIDAgNTMgNnoiIGNsYXNzPSJwb3dlcmNsaXAiIGNvbG9yPSIjMDAwIiBzdHlsZT0iLWlua3NjYXBlLXN0cm9rZTpub25lIi8+PC9jbGlwUGF0aD48L2RlZnM+PHBhdGggZmlsbD0iI2ZhZmFmYSIgZD0ibTM3Mi4xODUgMzcxLjcxMi0xMTEuMDg5IDM2LjM0LTExNi4zMi0xMS40NTItNjguODg5LTk0LjQyMi0yNS4wNTMtMTE0LjE2NSA2OC41MTMtOTQuNjk2TDIyMC4xODMgMzQuMjFsMTExLjIzMiAzNS44OTcgODcuMzczIDc3LjYzNi4yMzMgMTE2Ljg4MVoiIHBhaW50LW9yZGVyPSJzdHJva2UgZmlsbCBtYXJrZXJzIi8+PHBhdGggZmlsbD0iI2JhMWYzMyIgZD0iTTQ1NyA0MTFjLTcgMC0xNSAyLTIxIDctMzUgMjYtMTAgNzUgMzEgNDEgMzMtMjcgMTQtNDktMTAtNDhaTTI5MCAxOWMtMzEgMC02NyAxNC04NyAyNS0xNSA4LTY0IDM3LTEwNyA0Ni01NSAxMC04NyA2My01NSA5MCA1NCA0NCA1NiAxMDEgMTYgMTQzLTQ0IDQ2IDEgMTEzIDY0IDEwNiA2My04IDg5IDAgMTIxIDMyIDQxIDQxIDEzMiAyNSAxNTQtMzMgMTAtMjYgMjQtNTYgNTgtNjggNDEtMTQgNTMtNTkgMjYtOTEtMTktMjMtMjEtNDcgNS05NSAyMi00MCA1LTg0LTU2LTgxLTQ1IDMtNjQtMjctOTctNTlhNTkgNTkgMCAwIDAtNDItMTV6IiBjbGlwLXBhdGg9InVybCgjYSkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yOCAtMTkpIi8+PC9zdmc+"); 65 65 background-repeat: no-repeat; 66 - background-position-x: calc(100%); 66 + background-position-x: calc(50%); 67 + background-position-y: calc(100%); 68 + background-size: 175px; 67 69 } 68 70 69 - @media (min-width: 1280px) { 71 + @media (max-width: 1250px) { 70 72 .hero-background { 71 - background-position-x: calc(100% - 4rem); 73 + background-size: 100px; 74 + background-position-y: calc(50%); 72 75 } 73 76 }
+1 -1
website/assets/wax-seal.svg
··· 1 - <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 466 465"><defs><clipPath id="a" clipPathUnits="userSpaceOnUse"><path d="M23 14h476v475H23Zm247 58c-28 0-55 6-81 20a164 164 0 0 0-70 224c45 81 147 111 229 68 83-43 114-144 70-224l-13 7c40 73 12 164-64 204-75 39-168 11-208-62-41-74-12-165 63-204s169-11 209 62l13-7c-30-56-88-87-148-88Zm72 249 34 6v-52l-2-52-4-22-3-22 4-3 5-3c1-2 2-6 1-12-1-4-1-5-4-7s-3-2-8-2h-6l-4 5-4 5v12l4 3 3 2-11 38c-10 36-11 39-14 39l-26-77 3-1 4-3c2-3 1-8-1-13-2-4-3-4-7-5l-7 1c-3 3-4 3-5 7l-1 4 3 4 3 4-8 31-11 37-3 9c-1 2-4-3-15-24-11-22-11-22-15-34l-4-14 3-7c3-8 3-10 1-15-3-4-6-6-12-4-4 0-4 1-8 5l-4 4 1 6 5 11 2 5a1231 1231 0 0 0-11 40l-3 10-35-45-8-12 1-2 2-7-2-8-6-2c-4-1-4-1-7 1-4 2-4 2-4 6-1 5 1 11 5 12l1 1 2 69 3 69a908 908 0 0 1 59-4l41-2 20 2c21 0 21 0 53 6z" class="powerclip" style="color:#000;fill:#fff;stroke-width:1;-inkscape-stroke:none"/></clipPath></defs><path d="M457 411c-7 0-15 2-21 7-35 26-10 75 31 41 33-27 14-49-10-48ZM290 19c-31 0-67 14-87 25-15 8-64 37-107 46-55 10-87 63-55 90 54 44 56 101 16 143-44 46 1 113 64 106 63-8 89 0 121 32 41 41 132 25 154-33 10-26 24-56 58-68 41-14 53-59 26-91-19-23-21-47 5-95 22-40 5-84-56-81-45 3-64-27-97-59a59 59 0 0 0-42-15z" clip-path="url(#a)" transform="translate(-28 -19)" fill="#ba1f33"/></svg> 1 + <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 466 465"><defs><clipPath id="a" clipPathUnits="userSpaceOnUse"><path fill="#fff" d="M23 14h476v475H23Zm247 58c-28 0-55 6-81 20a164 164 0 0 0-70 224c45 81 147 111 229 68 83-43 114-144 70-224l-13 7c40 73 12 164-64 204-75 39-168 11-208-62-41-74-12-165 63-204s169-11 209 62l13-7c-30-56-88-87-148-88Zm72 249 34 6v-52l-2-52-4-22-3-22 4-3 5-3c1-2 2-6 1-12-1-4-1-5-4-7s-3-2-8-2h-6l-4 5-4 5v12l4 3 3 2-11 38c-10 36-11 39-14 39l-26-77 3-1 4-3c2-3 1-8-1-13-2-4-3-4-7-5l-7 1c-3 3-4 3-5 7l-1 4 3 4 3 4-8 31-11 37-3 9c-1 2-4-3-15-24-11-22-11-22-15-34l-4-14 3-7c3-8 3-10 1-15-3-4-6-6-12-4-4 0-4 1-8 5l-4 4 1 6 5 11 2 5a1231 1231 0 0 0-11 40l-3 10-35-45-8-12 1-2 2-7-2-8-6-2c-4-1-4-1-7 1-4 2-4 2-4 6-1 5 1 11 5 12l1 1 2 69 3 69a908 908 0 0 1 59-4l41-2 20 2c21 0 21 0 53 6z" class="powerclip" color="#000" style="-inkscape-stroke:none"/></clipPath></defs><path fill="#fafafa" d="m372.185 371.712-111.089 36.34-116.32-11.452-68.889-94.422-25.053-114.165 68.513-94.696L220.183 34.21l111.232 35.897 87.373 77.636.233 116.881Z" paint-order="stroke fill markers"/><path fill="#ba1f33" d="M457 411c-7 0-15 2-21 7-35 26-10 75 31 41 33-27 14-49-10-48ZM290 19c-31 0-67 14-87 25-15 8-64 37-107 46-55 10-87 63-55 90 54 44 56 101 16 143-44 46 1 113 64 106 63-8 89 0 121 32 41 41 132 25 154-33 10-26 24-56 58-68 41-14 53-59 26-91-19-23-21-47 5-95 22-40 5-84-56-81-45 3-64-27-97-59a59 59 0 0 0-42-15z" clip-path="url(#a)" transform="translate(-28 -19)"/></svg>
+1 -1
website/content/news/maudit01.md
··· 48 48 49 49 In general, if there's a compromise to be made, we prefer to optimize for developer experience over raw performance. However, we still aim to keep Maudit fast enough for most use cases. 50 50 51 - On a 2020 M1 MacBook Pro, [we've found that the final binary of a Maudit project can build a project with 4000 Markdown files in roughly 900ms](https://github.com/bruits/maudit/tree/main/crates/md-benchmark), which we consider quite reasonable. 51 + On a 2020 M1 MacBook Pro, [we've found that the final binary of a Maudit project can build a project with 4000 Markdown files in a little over 900ms](https://github.com/bruits/maudit/tree/main/crates/md-benchmark), which we consider quite reasonable. 52 52 53 53 [![Build Status](/01-performance.png)](https://github.com/bruits/maudit/tree/main/crates/md-benchmark) 54 54
+1 -1
website/src/layout.rs
··· 57 57 (header(ctx, bottom_border)) 58 58 (main) 59 59 footer.bg-our-black.text-white { 60 - div.container.mx-auto.py-8.flex.justify-between.items-center { 60 + div.container.mx-auto.px-8.py-8.flex.justify-between.items-center.flex-col-reverse."sm:flex-row".gap-y-12 { 61 61 div.grow."basis-[0]" { 62 62 a.text-md.font-bold href="https://bruits.org" { 63 63 "Copyright © 2025 Bruits."
+1 -1
website/src/layout/header.rs
··· 14 14 (PreEscaped(include_str!("../../assets/logo.svg"))) 15 15 h1.text-2xl.tracking-wide { "Maudit" } 16 16 } 17 - nav.text-lg.flex.gap-x-12.relative."top-[2px]" { 17 + nav.text-lg.gap-x-12.relative."top-[2px]".hidden."sm:flex" { 18 18 a href="/docs/" { "Documentation" } 19 19 a href="/news/" { "News" } 20 20 a href="/contribute/" { "Contribute" }
+1 -1
website/src/pages/404.rs
··· 10 10 fn render(&self, ctx: &mut RouteContext) -> RenderResult { 11 11 layout( 12 12 html! { 13 - div.container.mx-auto.text-center.my-50.flex.items-center.flex-col.gap-y-4 { 13 + div.container.mx-auto.text-center.my-50.flex.items-center.flex-col."gap-y-4"."px-8"."sm:px-0" { 14 14 (PreEscaped(include_str!("../../assets/logo.svg"))) 15 15 h1.text-6xl { "404 - Not Found" } 16 16 p.text-xl { "All the site's a stage, but this page plays not its part." }
+9 -12
website/src/pages/index.rs
··· 7 7 #[route("/")] 8 8 pub struct Index; 9 9 10 - const LATEST_NEWS: (&str, &str) = ("Introducing Maudit", "/news/maudit01"); 11 - 12 10 impl Page for Index { 13 11 fn render(&self, ctx: &mut RouteContext) -> RenderResult { 14 12 let features = [ ··· 23 21 layout( 24 22 html! { 25 23 div.w-full { 26 - div."lg:container".mx-auto.hero-background.relative { 27 - div.px-4.py-14.mx-6.my-28 { 28 - a.bg-our-black.text-our-white.rounded-sm.px-2.py-1.text-sm.mb-2.inline-block."hover:!text-brighter-brand"."hover:cursor-pointer" href=(LATEST_NEWS.1) { 29 - (format!("{}", LATEST_NEWS.0)) 30 - } 31 - h2.text-5xl."w-[22ch]"."xl:w-[30ch]"."mb-1"."leading-[1.15]" { 24 + div."lg:container".mx-auto.relative { 25 + div."px-4"."sm:py-8"."sm:mx-6"."sm:my-26"."my-14"."mb-20".flex.flex-col.justify-center.items-center.text-center { 26 + h2."sm:text-6xl"."text-5xl"."sm:w-[22ch]"."xl:w-[30ch]"."mb-2"."leading-[1.15]" { 32 27 "Lo, " span.text-brand-red { "the still scrolls of the web"} ", unchanging and steadfast, at last!" 33 28 } 34 29 p.opacity-80.italic { 35 30 "Or, in simpler words, " span.text-brand-red {"a static site generator"} "." 36 31 } 37 32 div.mt-6.leading-tight { 38 - a.btn.block.group.inline-block href="/docs/" { "Get Started" span.inline-block."group-hover:translate-x-3".transition-transform.translate-x-2 { "→" } } 33 + a.btn.block.group.inline-block href="/docs/" { "Get Started" } 39 34 p.opacity-80.italic { "or scroll down to learn more" } 40 35 } 41 36 } 42 37 } 43 38 } 44 39 45 - div.h-14.bg-linear-to-b."from-darker-white".border-t.border-t-borders{} 40 + div."hero-background"."w-[175px]"."h-[175px]".absolute."left-1/2"."-translate-x-1/2"."-translate-y-1/2" {} 41 + 42 + div.h-14.bg-linear-to-b."from-darker-white".border-t.border-t-borders."sm:mb-24".mb-10 {} 46 43 47 44 section.banner.py-14.text-center { 48 - div."px-52"."lg:container".mx-auto { 45 + div."sm:px-52"."px-4"."lg:container".mx-auto { 49 46 h3.text-4xl."mb-5".inline-block { "Crafted for timeless sites" } 50 47 p.font-bold { 51 48 "Maudit was built for one purpose: creating static websites." ··· 75 72 div.h-12.bg-linear-to-b."from-darker-white".border-t.border-t-borders{} 76 73 77 74 }, 78 - false, 75 + true, 79 76 true, 80 77 ctx, 81 78 )
+3 -3
website/src/pages/news.rs
··· 104 104 105 105 layout( 106 106 html! { 107 - div.container.mx-auto."py-10"."pb-24"."max-w-[80ch]" { 107 + div.container.mx-auto."py-10"."pb-24"."max-w-[80ch]"."px-8"."sm:px-0" { 108 108 section.mb-4.border-b."border-[#e9e9e7]".pb-2 { 109 109 @if let Some(date) = &entry.data.date { 110 110 p.text-sm.font-bold { (date) } 111 111 } 112 - h1."text-7xl".font-bold { (entry.data.title) } 112 + h1."text-6xl"."sm:text-7xl".font-bold { (entry.data.title) } 113 113 @if let Some(description) = &entry.data.description { 114 - p.text-2xl { (description) } 114 + p.text-xl."sm:text-2xl" { (description) } 115 115 } 116 116 } 117 117