diff --git a/.gitignore b/.gitignore index 3fa7b64..9c9aaec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ target/ .claude/ public/ -content/past/*.md -content/upcoming/*.md +content/events/past/*.md +content/events/upcoming/*.md diff --git a/README.md b/README.md index 7409a2b..20f282e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This repository contains the Zola static site for **rust-munich.de** and a small . ├── Cargo.toml # workspace (CLI) ├── config.toml # Zola config (en default, de alternative) -├── content/ # Pages; events are generated into upcoming/ and past/ +├── content/ # Pages; events are generated into events/upcoming/ and events/past/ ├── data/events/ # Single source of truth: one YAML per event ├── static/img/ # Logo placeholder (replace with icon repo asset) └── tools/contentgen/ # Rust CLI for events and jobs generation diff --git a/config.toml b/config.toml index 9f9ccc6..fc321d4 100644 --- a/config.toml +++ b/config.toml @@ -1,6 +1,6 @@ # Zola configuration for rust-munich.de -# base_url = "https://rust-munich.github.io/website/" -base_url = "/website/" +# For local dev, run: zola serve (automatically uses localhost) +base_url = "https://rust-munich.github.io/website/" title = "Rust Munich" description = "Rust Munich meetup group — events, community, and resources." default_language = "en" @@ -47,8 +47,12 @@ path = "/" [[extra.menu]] title = "Events" -path = "past/" +path = "events/past/" [[extra.menu]] -title = "Job Opportunities" +title = "Rust Jobs" path = "jobs/" + +[[extra.menu]] +title = "Neighborhood" +path = "umgebung/" diff --git a/content/contribute/index.md b/content/contribute/index.md new file mode 100644 index 0000000..28b83ff --- /dev/null +++ b/content/contribute/index.md @@ -0,0 +1,32 @@ ++++ +title = "Contribute" +template = "page.html" ++++ + +This website is open source. Spotted something outdated? Know a meetup we're missing? You can fix it yourself! + +## How to Contribute + +1. Fork the [website repository](https://github.com/rust-munich/website) +2. Make your changes +3. Open a pull request + +That's it. We'll review and merge it. + +## What You Can Help With + +**Add a meetup to [Neighborhood](/website/umgebung/)** +Know a Rust meetup in Bavaria or nearby? Add it to `content/umgebung/index.md`. + +**Update outdated information** +Event details wrong? Link broken? Fix it directly in the relevant file under `content/`. + +**Suggest a host for [Our Hosts](/website/past-hosts/)** +Your company hosted us? Add yourself to `content/past-hosts/_index.md`. + +**Improve the website** +Found a bug? Have a design idea? PRs welcome. + +## Questions? + +Not sure how to proceed? Open an [issue](https://github.com/rust-munich/website/issues) and we'll help you out. diff --git a/content/jobs/_index.md b/content/jobs/_index.md index 62ad42c..b5dc7f2 100644 --- a/content/jobs/_index.md +++ b/content/jobs/_index.md @@ -2,5 +2,3 @@ title = "Job Opportunities" template = "jobs.html" +++ - -We feature Rust job opportunities from companies that support our community. All job postings are submitted via GitHub Pull Request to ensure transparency and community involvement. diff --git a/content/jobs/example-rust-developer.md b/content/jobs/example-rust-developer.md index 71b3131..9226b4d 100644 --- a/content/jobs/example-rust-developer.md +++ b/content/jobs/example-rust-developer.md @@ -12,7 +12,7 @@ application_url = "https://example-tech.com/careers/rust-developer" expires_date = "2030-12-01" salary_range = "€70,000 - €90,000" company_url = "https://example-tech.com" -logo_url = "/img/rust-munich-logo.svg" +logo_url = "https://rust-munich.github.io/website/img/rust-munich-logo.svg" tags = ["rust", "backend", "microservices", "kubernetes"] +++ diff --git a/content/past-hosts/_index.md b/content/past-hosts/_index.md new file mode 100644 index 0000000..2444ee7 --- /dev/null +++ b/content/past-hosts/_index.md @@ -0,0 +1,73 @@ ++++ +title = "Our Hosts" +template = "section.html" ++++ + +Rust Munich wouldn't happen without companies opening their doors to us. A heartfelt thank you to everyone who has provided a space for our community to gather. + +## Thank You + +
+
+ +

SAP

+
+

Garching bei München

+
+
+ +

Google

+
+

München

+
+
+ +

Mainmatter

+
+

München

+
+
+ +

JetBrains

+
+

München

+
+
+ +

mgm security partners

+
+

München

+
+
+

Dock Financial

+

München

+
+
+ +

ZEISS

+
+

München

+
+
+ +

Luminovo

+
+

München

+
+
+ +## Host a Meetup + +Got a meeting room and like Rust? We're always looking for venues. + +**What we need:** +- Space for 30-80 people +- A projector or screen +- Ideally some drinks and snacks (but we can figure that out) + +**What you get:** +- 50+ Rust developers in your office +- A great evening with the community +- Our eternal gratitude and a spot on this page + +Interested? Reach out via [Discord](https://discord.gg/SdB7yuEB) or [Meetup](https://www.meetup.com/de-DE/rust-munich/). diff --git a/content/past/_index.md b/content/past/_index.md deleted file mode 100644 index 6cdbbf4..0000000 --- a/content/past/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Past events" -template = "events/past.html" -sort_by = "date" -# Pages are generated by tools/eventgen from /data/events/*.yml -paginate_by = 12 -+++ diff --git a/content/sponsors/_index.md b/content/sponsors/_index.md deleted file mode 100644 index f4a4345..0000000 --- a/content/sponsors/_index.md +++ /dev/null @@ -1,41 +0,0 @@ -+++ -title = "Sponsors" -+++ - -We are grateful to our sponsors who make Rust Munich possible. Their support helps us organize events, provide refreshments, and create a welcoming space for the Rust community in Munich. - -## Past and Current Sponsors - -
-
- - -

Mainmatter

-

Experts in Rust, Ember.js, and Elixir development

-
-
-
- -## Become a Sponsor - -Are you interested in supporting Rust Munich? We offer various sponsorship opportunities: - -- **Event Sponsorship**: Support individual meetups with refreshments and venue -- **Community Sponsorship**: Ongoing support for our regular activities -- **Workshop Sponsorship**: Enable hands-on learning sessions - -### Benefits for Sponsors - -- Logo placement on our website and event materials -- Mention in our social media channels -- Speaking opportunities at events -- Direct access to Munich's growing Rust community - -### Contact Us - -Ready to sponsor? Reach out to us via: -- Meetup: {{ meetup_link() }} -- Discord: {{ discord_link() }} -- GitHub: {{ github_link() }} - -*Thank you for considering supporting Rust Munich!* diff --git a/content/umgebung/index.md b/content/umgebung/index.md new file mode 100644 index 0000000..5c9b13c --- /dev/null +++ b/content/umgebung/index.md @@ -0,0 +1,21 @@ ++++ +title = "Neighborhood" +template = "page.html" ++++ + +Bavaria and the surrounding region have a vibrant Rust community. Here you can discover other meetups, projects, and events in our neighborhood. + +## Rust Augsburg + +The [Rust Meetup Augsburg](https://www.meetup.com/rust-meetup-augsburg/) invites all Rust enthusiasts to explore the ins and outs of the Rust programming language. Whether you're a seasoned Rustacean or a curious beginner, you are welcome to be part of their community. Together, members dive into the latest Rust updates, exchange knowledge, and work on exciting projects. + +**Location:** Stadtbücherei Augsburg, Ernst-Reuter-Platz 1, Augsburg + +**Links:** +- [Meetup.com](https://www.meetup.com/rust-meetup-augsburg/) +- [GitHub](https://github.com/rust-augsburg/meetup) +- [Presentation slides](https://rust-augsburg.github.io/meetup/) + +--- + +*Know of another Rust meetup or project in the region? [Open a PR](https://github.com/rust-munich/website) and add it!* diff --git a/content/upcoming/_index.md b/content/upcoming/_index.md deleted file mode 100644 index a0a07b4..0000000 --- a/content/upcoming/_index.md +++ /dev/null @@ -1,6 +0,0 @@ -+++ -title = "Upcoming events" -template = "events/upcoming.html" -sort_by = "date" -# Pages are generated by tools/eventgen from /data/events/*.yml -+++ diff --git a/data/events/rust-munich-2023-4.yml b/data/events/rust-munich-2023-4.yml new file mode 100644 index 0000000..cc288e4 --- /dev/null +++ b/data/events/rust-munich-2023-4.yml @@ -0,0 +1,28 @@ +id: "rust-munich-2023-4" +title: "Rust Munich 2023/4" +date: "2023-09-05" +time: "19:00" +venue: "SAP Signavio" +address: "Nymphenburger Str. 82" +city: "Munich" +tags: ["meetup", "hybrid"] +meetup_url: "https://www.meetup.com/rust-munich/events/294186101" +slides_url: "" +youtube_url: "" +ical_url: "" +speakers: ["Vitaly", "Oliver"] +language: "en" +draft: false +description: | + Another meetup of the rust munich meetup! + + The event live stream will be on and the event is recorded. + + Agenda: + + - 18:30 Welcome: prep your beverage! + - 19:15 talk: "Profiling Async Applications in Rust" by Vitaly + - 20:00 talk: "Ensuring Memory Safety for the Transition from C/C++ to Rust" by Oliver + - 21:00 open space/discussion + + Discord for Q/A + Discussions: https://discord.gg/bM5RzVrF2z diff --git a/data/events/rust-munich-2023-5.yml b/data/events/rust-munich-2023-5.yml new file mode 100644 index 0000000..42a9d61 --- /dev/null +++ b/data/events/rust-munich-2023-5.yml @@ -0,0 +1,28 @@ +id: "rust-munich-2023-5" +title: "Rust Munich 2023/5" +date: "2023-12-18" +time: "19:00" +venue: "Dock Financial GmbH" +address: "Arnulfstraße 124" +city: "Munich" +tags: ["meetup", "hybrid"] +meetup_url: "https://www.meetup.com/rust-munich/events/296429053" +slides_url: "" +youtube_url: "" +ical_url: "" +speakers: ["Bastian S.", "Simon"] +language: "en" +draft: false +description: | + Another edition of the rust munich meetup! + + The event live stream will be on and the event is recorded. + + Agenda: + + - 18:15 Hello: prep your beverage! + - 19:00 talk: "OpenAPI @ Dock" by Bastian S. + - 20:00 talk: "Workspaces and feature unification" by Simon + - 21:00 open space/discussion + + Discord for Q/A + Discussions: https://discord.gg/bM5RzVrF2z diff --git a/data/events/rust-munich-2024-1.yml b/data/events/rust-munich-2024-1.yml new file mode 100644 index 0000000..e7d21fd --- /dev/null +++ b/data/events/rust-munich-2024-1.yml @@ -0,0 +1,28 @@ +id: "rust-munich-2024-1" +title: "Rust Munich 2024/1" +date: "2024-05-14" +time: "18:00" +venue: "ZEISS" +address: "Kistlerhofstraße 75" +city: "Munich" +tags: ["meetup", "hybrid"] +meetup_url: "https://www.meetup.com/rust-munich/events/298507657" +slides_url: "" +youtube_url: "" +ical_url: "" +speakers: ["Heiko", "Kevin"] +language: "en" +draft: false +description: | + The good news: We found a location! + + This hybrid meetup features both in-person and remote participation options. + + Agenda: + + - 17:15 Hello: prep your beverage! + - 18:00 talk: "Distributed Tracing" by Heiko + - 18:30 talk: "Heat Cam with Rust" by Kevin + - 19:00 open space/discussion + + Discord for Q/A + Discussions: https://discord.gg/bM5RzVrF2z diff --git a/data/events/rust-munich-2024-2.yml b/data/events/rust-munich-2024-2.yml new file mode 100644 index 0000000..1aaa54c --- /dev/null +++ b/data/events/rust-munich-2024-2.yml @@ -0,0 +1,28 @@ +id: "rust-munich-2024-2" +title: "Rust Munich 2024/2" +date: "2024-07-23" +time: "18:30" +venue: "mgm security partners GmbH" +address: "Taunusstraße 23" +city: "Munich" +tags: ["meetup", "hybrid"] +meetup_url: "https://www.meetup.com/rust-munich/events/301062840" +slides_url: "" +youtube_url: "" +ical_url: "" +speakers: ["Heiko", "Sven"] +language: "en" +draft: false +description: | + Another edition of the rust munich meetup! + + The in-person event is limited to 30 people, but as always, the event live stream will be on and the event is being recorded. + + Agenda: + + - 18:30 Hello: prep your beverage! + - 19:00~ish talk: "Distributed Tracing" by Heiko + - 19:30~ish talk: "Building a DSL parser with Rust and PEGs" by Sven + - 20:00~ish open space/discussion + + Discord for Q/A + Discussions: https://discord.gg/bM5RzVrF2z diff --git a/data/events/rust-munich-2024-3.yml b/data/events/rust-munich-2024-3.yml new file mode 100644 index 0000000..8fe0595 --- /dev/null +++ b/data/events/rust-munich-2024-3.yml @@ -0,0 +1,29 @@ +id: "rust-munich-2024-3" +title: "Rust Munich 2024/3" +date: "2024-10-15" +time: "19:00" +venue: "JetBrains GmbH" +address: "Christoph-Rapparini-Bogen 23" +city: "Munich" +tags: ["meetup", "hybrid"] +meetup_url: "https://www.meetup.com/rust-munich/events/303273953" +slides_url: "" +youtube_url: "https://www.youtube.com/watch?v=sB4eWQ0Tuvo" +ical_url: "" +speakers: ["Matthias", "Aaron"] +language: "en" +draft: false +description: | + Another edition of the rust munich meetup! + + The on-site event has limited capacity, but as always, the event will be live streamed and recorded. + + Agenda: + + - 18:30 Hello: prep your beverage! + - 19:00 talk: "When to (not) use typestate" by Matthias + - 19:30 Food Break + - 19:45 talk: "Machine Learning in Rust" by Aaron + - 20:40 open space/discussion + + Discord for Q/A + Discussions: https://discord.gg/bM5RzVrF2z diff --git a/data/events/rust-munich-2024-4.yml b/data/events/rust-munich-2024-4.yml new file mode 100644 index 0000000..0ddee4d --- /dev/null +++ b/data/events/rust-munich-2024-4.yml @@ -0,0 +1,33 @@ +id: "rust-munich-2024-4" +title: "Rust Munich 2024/4 - Hacking Evening" +date: "2024-12-12" +time: "19:00" +venue: "SAP Labs Munich" +address: "Friedrich-Ludwig-Bauer-Straße 5" +city: "Garching bei München" +tags: ["meetup", "hacking-evening"] +meetup_url: "https://www.meetup.com/rust-munich/events/304827279" +slides_url: "" +youtube_url: "" +ical_url: "" +speakers: [] +language: "en" +draft: false +description: | + Mini-hackathon bringing together up to 24 Rust developers for a hands-on coding session. + + We'll work on the "1 Billion Row Challenge" - focusing on Clap, argument parsing, error handling, and logging. + + Participants work individually or in small groups to complete a project within two hours, with support via a dedicated Discord channel. + + **What to bring:** + - Laptop with display + - Rust compiler (stable) or Docker with rustup + - Your favorite IDE/editor + - GitHub account + + Drinks and snacks provided! + + Challenge repo: https://github.com/rust-munich/hack-evening-2024-4 + + Discord for Q/A + Discussions: https://discord.gg/bM5RzVrF2z diff --git a/data/events/rust-munich-2025-1.yml b/data/events/rust-munich-2025-1.yml new file mode 100644 index 0000000..f5a93a9 --- /dev/null +++ b/data/events/rust-munich-2025-1.yml @@ -0,0 +1,29 @@ +id: "rust-munich-2025-1" +title: "Rust Munich 2025/1" +date: "2025-04-02" +time: "18:30" +venue: "Mainmatter GmbH" +address: "Hans-Sachs-Straße 12" +city: "Munich" +tags: ["meetup", "hybrid"] +meetup_url: "https://www.meetup.com/rust-munich/events/306097261" +slides_url: "" +youtube_url: "https://www.youtube.com/watch?v=SboeO2BtKGo" +ical_url: "" +speakers: ["Marco", "Luca"] +language: "en" +draft: false +description: | + Another edition of the rust munich meetup! + + The on-site event has limited capacity, but as always, the event will be live streamed and recorded. + + Agenda: + + - 18:30 Hello: prep your beverage! + - 19:00 talk: "Intro to Gerust" by Marco + - 19:50 Food Break + - 20:15 talk: "An introduction to Pavex" by Luca + - 20:45 open space/discussion + + Discord for Q/A + Discussions: https://discord.gg/bM5RzVrF2z diff --git a/data/events/rust-munich-2025-2.yml b/data/events/rust-munich-2025-2.yml new file mode 100644 index 0000000..1d49406 --- /dev/null +++ b/data/events/rust-munich-2025-2.yml @@ -0,0 +1,37 @@ +id: "rust-munich-2025-2" +title: "Rust Munich 2025/2 - Hacking Evening" +date: "2025-06-05" +time: "18:30" +venue: "SAP Labs Munich" +address: "Friedrich-Ludwig-Bauer-Straße 5" +city: "Garching bei München" +tags: ["meetup", "hacking-evening"] +meetup_url: "https://www.meetup.com/rust-munich/events/307105443" +slides_url: "" +youtube_url: "" +ical_url: "" +speakers: [] +language: "en" +draft: false +description: | + We are excited to continue the new format of hacking one evening all together that we started in December 2024. + + This time we'll explore solutions from the previous "1 billion row challenge" - what worked and what didn't. + + Participants work individually or in small groups for approximately 2 hours, with initial instructional slides and a dedicated Discord channel for code sharing and assistance. + + **What to bring:** + - Laptop with display + - Rust compiler (stable) or Docker with rustup + - Your favorite IDE/editor (zed.dev, VSCode, or RustRover) + - GitHub and Discord accounts + + Drinks and snacks provided! + + Challenge repo: https://github.com/rust-munich/hack-evening-2025-2 + + **How to get there:** + - U6 to Garching-Forschungszentrum (~10 min walk) + - Free parking available on-site + + Discord: https://discord.gg/SdB7yuEB diff --git a/data/events/rust-munich-2025-4.yml b/data/events/rust-munich-2025-4.yml new file mode 100644 index 0000000..70bc23b --- /dev/null +++ b/data/events/rust-munich-2025-4.yml @@ -0,0 +1,39 @@ +id: "rust-munich-2025-4" +title: "Rust Munich 2025/4 - Hacking Evening" +date: "2025-12-10" +time: "18:30" +venue: "SAP Labs Munich" +address: "Friedrich-Ludwig-Bauer-Straße 5" +city: "Garching bei München" +tags: ["meetup", "hacking-evening"] +meetup_url: "https://www.meetup.com/rust-munich/events/307105932" +slides_url: "" +youtube_url: "" +ical_url: "" +speakers: [] +language: "en" +draft: false +description: | + Hands-on mini-hackathon where up to 24 participants work together on an Advent of Code challenge. + + Similar to university times when you had to solve small problems in the computer lab within an hour - but with Rust programming applied to workplace-relevant skills. + + Participants receive an initial presentation outlining the project and required dependencies, then have approximately 2 hours to complete the task individually or in small groups. + + **What to bring:** + - Laptop with display + - Rust compiler (stable) or Docker with rustup + - Your favorite IDE/editor + - GitHub account + - Discord account (optional) + + Drinks and snacks provided! + + Challenge repo: https://github.com/rust-munich/hack-evening-2025-12 + + **How to get there:** + - U6 to Garching-Forschungszentrum (~10 min walk) + - Exit A9 at "Garching Nord", follow signs to "Forschungszentrum" + - Free parking available on-site + + Discord: https://discord.gg/XG4nbEu9 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..0f489e7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1089 @@ +{ + "name": "rust-munich-zola", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@tailwindcss/cli": "^4.1.14", + "@tailwindcss/typography": "^0.5.19", + "tailwindcss": "^4.1.14" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "hasInstallScript": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/cli": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.14.tgz", + "integrity": "sha512-2cErQRcsI8jIObUMVwcd1H2AWgGxwzozHJk7AKM2KB1taOp7L15xQ8kEsZrvVbOjNrb8yXtnSvNtJ+mhCB7EBg==", + "dependencies": { + "@parcel/watcher": "^2.5.1", + "@tailwindcss/node": "4.1.14", + "@tailwindcss/oxide": "4.1.14", + "enhanced-resolve": "^5.18.3", + "mri": "^1.2.0", + "picocolors": "^1.1.1", + "tailwindcss": "4.1.14" + }, + "bin": { + "tailwindcss": "dist/index.mjs" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.14.tgz", + "integrity": "sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw==", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.0", + "lightningcss": "1.30.1", + "magic-string": "^0.30.19", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.14" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.14.tgz", + "integrity": "sha512-23yx+VUbBwCg2x5XWdB8+1lkPajzLmALEfMb51zZUBYaYVPDQvBSD/WYDqiVyBIo2BZFa3yw1Rpy3G2Jp+K0dw==", + "hasInstallScript": true, + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.5.1" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.14", + "@tailwindcss/oxide-darwin-arm64": "4.1.14", + "@tailwindcss/oxide-darwin-x64": "4.1.14", + "@tailwindcss/oxide-freebsd-x64": "4.1.14", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.14", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.14", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.14", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.14", + "@tailwindcss/oxide-linux-x64-musl": "4.1.14", + "@tailwindcss/oxide-wasm32-wasi": "4.1.14", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.14", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.14" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.14.tgz", + "integrity": "sha512-a94ifZrGwMvbdeAxWoSuGcIl6/DOP5cdxagid7xJv6bwFp3oebp7y2ImYsnZBMTwjn5Ev5xESvS3FFYUGgPODQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.14.tgz", + "integrity": "sha512-HkFP/CqfSh09xCnrPJA7jud7hij5ahKyWomrC3oiO2U9i0UjP17o9pJbxUN0IJ471GTQQmzwhp0DEcpbp4MZTA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.14.tgz", + "integrity": "sha512-eVNaWmCgdLf5iv6Qd3s7JI5SEFBFRtfm6W0mphJYXgvnDEAZ5sZzqmI06bK6xo0IErDHdTA5/t7d4eTfWbWOFw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.14.tgz", + "integrity": "sha512-QWLoRXNikEuqtNb0dhQN6wsSVVjX6dmUFzuuiL09ZeXju25dsei2uIPl71y2Ic6QbNBsB4scwBoFnlBfabHkEw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.14.tgz", + "integrity": "sha512-VB4gjQni9+F0VCASU+L8zSIyjrLLsy03sjcR3bM0V2g4SNamo0FakZFKyUQ96ZVwGK4CaJsc9zd/obQy74o0Fw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.14.tgz", + "integrity": "sha512-qaEy0dIZ6d9vyLnmeg24yzA8XuEAD9WjpM5nIM1sUgQ/Zv7cVkharPDQcmm/t/TvXoKo/0knI3me3AGfdx6w1w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.14.tgz", + "integrity": "sha512-ISZjT44s59O8xKsPEIesiIydMG/sCXoMBCqsphDm/WcbnuWLxxb+GcvSIIA5NjUw6F8Tex7s5/LM2yDy8RqYBQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.14.tgz", + "integrity": "sha512-02c6JhLPJj10L2caH4U0zF8Hji4dOeahmuMl23stk0MU1wfd1OraE7rOloidSF8W5JTHkFdVo/O7uRUJJnUAJg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.14.tgz", + "integrity": "sha512-TNGeLiN1XS66kQhxHG/7wMeQDOoL0S33x9BgmydbrWAb9Qw0KYdd8o1ifx4HOGDWhVmJ+Ul+JQ7lyknQFilO3Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.14.tgz", + "integrity": "sha512-uZYAsaW/jS/IYkd6EWPJKW/NlPNSkWkBlaeVBi/WsFQNP05/bzkebUL8FH1pdsqx4f2fH/bWFcUABOM9nfiJkQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.5", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.14.tgz", + "integrity": "sha512-Az0RnnkcvRqsuoLH2Z4n3JfAef0wElgzHD5Aky/e+0tBUxUhIeIqFBTMNQvmMRSP15fWwmvjBxZ3Q8RhsDnxAA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.14.tgz", + "integrity": "sha512-ttblVGHgf68kEE4om1n/n44I0yGPkCPbLsqzjvybhpwa6mKKtgFfAzy6btc3HRmuW7nHe0OOrSeNP9sQmmH9XA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz", + "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", + "dependencies": { + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "engines": { + "node": ">=18" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", + "integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tar": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", + "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "engines": { + "node": ">=18" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..0045eb6 --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "@tailwindcss/cli": "^4.1.14", + "@tailwindcss/typography": "^0.5.19", + "tailwindcss": "^4.1.14" + } +} diff --git a/sass/components/_marker-underline.scss b/sass/components/_marker-underline.scss new file mode 100644 index 0000000..66aa3b7 --- /dev/null +++ b/sass/components/_marker-underline.scss @@ -0,0 +1,34 @@ +// Marker Underline Component +// Yellow underline effect for links - positioned below text like a real underline + +@mixin marker-underline($height) { + background: linear-gradient( + transparent 85%, + var(--rust-yellow) 85%, + var(--rust-yellow) $height, + transparent $height + ); + text-decoration: none !important; + border-bottom: none !important; +} + +.marker-underline { + @include marker-underline(95%); + + &:hover { + @include marker-underline(100%); + color: inherit; + } +} + +// Auto-apply to links in content areas +.page-content a:not(.inline-block):not(.btn) { + @include marker-underline(95%); + color: var(--color-link); + font-weight: 500; + + &:hover { + @include marker-underline(100%); + color: inherit; + } +} diff --git a/sass/styles.scss b/sass/styles.scss new file mode 100644 index 0000000..11a5dd9 --- /dev/null +++ b/sass/styles.scss @@ -0,0 +1,142 @@ +// Rust Munich Styles +// Modular SCSS with dark/light theme support + +// Theme system +@use "theme/variables"; +@use "theme/light"; +@use "theme/dark"; + +// Components +@use "components/marker-underline"; + +// Base styles using theme variables +body { + background-color: var(--color-bg); + color: var(--color-text); + font-size: 1.125rem; // 18px base + line-height: 1.7; +} + +// Typography - larger, more impactful +h1 { + font-size: 3rem; + line-height: 1.2; + @media (min-width: 768px) { + font-size: 4rem; + } +} + +h2 { + font-size: 2rem; + line-height: 1.3; + @media (min-width: 768px) { + font-size: 2.5rem; + } +} + +h3 { + font-size: 1.5rem; + line-height: 1.4; + @media (min-width: 768px) { + font-size: 1.75rem; + } +} + +// Content area styling +.page-content h2 { + font-family: "Fira Sans", ui-sans-serif, system-ui; + font-weight: 700; + color: var(--color-text); + margin-top: 1.5rem; + margin-bottom: 1rem; +} + +.page-content h3 { + font-family: "Fira Sans", ui-sans-serif, system-ui; + font-weight: 700; + color: var(--color-text); + margin-top: 2rem; + margin-bottom: 1rem; +} + +.page-content p { + font-size: 1.125rem; + margin-bottom: 1.25rem; +} + +// Code blocks +code { + background-color: var(--color-code-bg); +} + +// ============================================ +// Full-bleed section system +// ============================================ + +.section { + padding: 3rem 1rem; + + @media (min-width: 768px) { + padding: 4rem 2rem; + } +} + +.section-inner { + max-width: 72rem; + margin: 0 auto; +} + +// Section color variants +.section-default { + background-color: var(--color-bg); +} + +.section-warm { + background-color: var(--section-warm); +} + +.section-cool { + background-color: var(--section-cool); +} + +.section-dark { + background-color: var(--section-dark); + color: var(--section-dark-text); + + & h1, & h2, & h3, & h4, & p, & span, & div { + color: var(--section-dark-text); + } +} + +// Social icons in footer +.social-icon { + border: 1px solid var(--color-border); + color: var(--color-text-muted); + + &:hover { + background-color: var(--color-card-hover); + border-color: var(--rust-yellow); + color: var(--rust-yellow); + } +} + + +// Card backgrounds +.card-bg { + background-color: var(--color-card-bg); +} + +// Stats section large numbers +.stat-number { + font-size: 3rem; + font-weight: 800; + + @media (min-width: 768px) { + font-size: 4rem; + } +} + +.stat-label { + font-size: 1.125rem; + color: var(--color-text-muted); +} diff --git a/sass/theme/_dark.scss b/sass/theme/_dark.scss new file mode 100644 index 0000000..1aa2d8e --- /dev/null +++ b/sass/theme/_dark.scss @@ -0,0 +1,42 @@ +// Dark Theme +// Soft dark inspired by GitHub dark mode + +// Manual toggle: add data-theme="dark" to +[data-theme="dark"] { + --theme-bg: #0d1117; + --theme-bg-alt: #161b22; + --theme-text: #e6edf3; + --theme-text-muted: #8b949e; + --theme-border: #30363d; + --theme-card-bg: #161b22; + --theme-card-hover: #21262d; + --theme-link: #e6edf3; + --theme-code-bg: #30363d; + + // Section backgrounds - higher contrast + --theme-section-warm: #261a14; // Noticeable rust-brown + --theme-section-cool: #0f1926; // Noticeable blue + --theme-section-dark: #010409; // Near black + --theme-section-dark-text: #e6edf3; +} + +// Auto-detect system preference +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) { + --theme-bg: #0d1117; + --theme-bg-alt: #161b22; + --theme-text: #e6edf3; + --theme-text-muted: #8b949e; + --theme-border: #30363d; + --theme-card-bg: #161b22; + --theme-card-hover: #21262d; + --theme-link: #e6edf3; + --theme-code-bg: #30363d; + + // Section backgrounds - higher contrast + --theme-section-warm: #261a14; + --theme-section-cool: #0f1926; + --theme-section-dark: #010409; + --theme-section-dark-text: #e6edf3; + } +} diff --git a/sass/theme/_light.scss b/sass/theme/_light.scss new file mode 100644 index 0000000..6247bbd --- /dev/null +++ b/sass/theme/_light.scss @@ -0,0 +1,20 @@ +// Light Theme (Default) +// Clean, minimal light appearance + +:root { + --theme-bg: #ffffff; + --theme-bg-alt: #f6f6f6; + --theme-text: #20201f; + --theme-text-muted: #4a5568; + --theme-border: #e2e8f0; + --theme-card-bg: #ffffff; + --theme-card-hover: #f7fafc; + --theme-link: #20201f; + --theme-code-bg: #edf2f7; + + // Section backgrounds - warm to cool flow + --theme-section-warm: #fdf6f0; // Soft peachy cream + --theme-section-cool: #f5f3ff; // Soft lavender + --theme-section-dark: #2d3748; // Charcoal + --theme-section-dark-text: #f7fafc; +} diff --git a/sass/theme/_variables.scss b/sass/theme/_variables.scss new file mode 100644 index 0000000..e4a528d --- /dev/null +++ b/sass/theme/_variables.scss @@ -0,0 +1,26 @@ +// Theme CSS Custom Properties +// These variables are used throughout the site for consistent theming + +:root { + // Brand colors (constant across themes) + --rust-yellow: #ffc832; + --rust-red: #ce422b; + --rust-orange: #dea584; + + // Semantic colors (change per theme) + --color-bg: var(--theme-bg); + --color-bg-alt: var(--theme-bg-alt); + --color-text: var(--theme-text); + --color-text-muted: var(--theme-text-muted); + --color-border: var(--theme-border); + --color-card-bg: var(--theme-card-bg); + --color-card-hover: var(--theme-card-hover); + --color-link: var(--theme-link); + --color-code-bg: var(--theme-code-bg); + + // Section backgrounds + --section-warm: var(--theme-section-warm); + --section-cool: var(--theme-section-cool); + --section-dark: var(--theme-section-dark); + --section-dark-text: var(--theme-section-dark-text); +} diff --git a/templates/base.html b/templates/base.html index 194ef7f..4e5e936 100644 --- a/templates/base.html +++ b/templates/base.html @@ -15,25 +15,18 @@ href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;600;700;800&family=Source+Serif+4:opsz,wght@8..60,400;8..60,600;8..60,700&display=swap" rel="stylesheet" /> - + - +
- {% include "partials/menu.html" %} +
+ {% include "partials/menu.html" %} + +
-
+
{% block content %}{% endblock content %}
-