From 6041fc4d3b6efe3b136f70b15df40b8e88161ba3 Mon Sep 17 00:00:00 2001
From: Adam Jolicoeur
Date: Mon, 5 Jan 2026 12:34:00 -0500
Subject: [PATCH 1/2] feat: add TaskStat pages
---
docs/about/resume/index.html | 11 +-
docs/apps/taskstat-privacy.html | 409 +++++++++++++++++++++++++++++
docs/apps/taskstat.html | 234 +++++++++++++++++
docs/credits/index.html | 7 +-
docs/css/markdown.css | 18 ++
docs/css/style.css | 6 -
docs/css/style.css.map | 2 +-
docs/feed.json | 20 +-
docs/sass/markdown.css | 1 +
docs/sass/style.css | 2 +-
docs/sitemap.xml | 22 +-
src/_includes/markdown.njk | 11 +-
src/pages/apps/taskstat-privacy.md | 307 ++++++++++++++++++++++
src/pages/apps/taskstat.md | 100 +++++++
src/sass/_markdown.scss | 5 -
src/sass/markdown.scss | 16 ++
src/sass/style.scss | 1 -
17 files changed, 1136 insertions(+), 36 deletions(-)
create mode 100644 docs/apps/taskstat-privacy.html
create mode 100644 docs/apps/taskstat.html
create mode 100644 docs/css/markdown.css
create mode 100644 docs/sass/markdown.css
create mode 100644 src/pages/apps/taskstat-privacy.md
create mode 100644 src/pages/apps/taskstat.md
delete mode 100644 src/sass/_markdown.scss
create mode 100644 src/sass/markdown.scss
diff --git a/docs/about/resume/index.html b/docs/about/resume/index.html
index d9fefb1c..f7638073 100644
--- a/docs/about/resume/index.html
+++ b/docs/about/resume/index.html
@@ -72,16 +72,16 @@
-
+
+
Adam Jolicoeur
-
- Lead Product Designer with 15+ years at AWS, Red Hat, and high-growth B2B companies
-
+ Lead Product Designer with 15+ years at AWS, Red Hat, and high-growth B2B companies
-
+
+
Adam Jolicoeur
contact@adamjolicoeur.com
@@ -128,6 +128,7 @@ Also available
GitHub
+
diff --git a/docs/apps/taskstat-privacy.html b/docs/apps/taskstat-privacy.html
new file mode 100644
index 00000000..2736943f
--- /dev/null
+++ b/docs/apps/taskstat-privacy.html
@@ -0,0 +1,409 @@
+
+
+
+
+
+ TaskStat Privacy Policy | Adam Jolicoeur
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mastodon
+
+ Skip to main content
+
+
+
+
+
+
+
+
+
+ TaskStat Privacy Policy
+ Privacy policy for TaskStat - a privacy-first task management app for iOS
+
+
+
+
+Last Updated: January 5, 2026
+Effective Date: January 5, 2026
+Our Privacy Commitment #
+TaskStat is built with privacy as a core principle. We believe your task data is yours alone, and we’ve designed TaskStat to ensure your information stays completely private and under your control.
+The short version: We don’t collect, transmit, or store any of your data on our servers. Everything stays on your device.
+
+What We DON’T Collect #
+TaskStat does NOT collect, transmit, or have access to:
+
+❌ Your task data
+❌ Your personal information
+❌ Your usage patterns or analytics
+❌ Your device identifiers
+❌ Your location data
+❌ Your contacts or calendar information
+❌ Any tracking or advertising identifiers
+❌ Crash reports or diagnostic data (beyond iOS system-level reporting)
+
+What IS Stored on Your Device #
+TaskStat stores the following information locally on your device only :
+Task Data (SwiftData/SQLite) #
+
+Task titles
+Task descriptions and notes
+Status, priority, and type classifications
+Project assignments
+Assignee names (if you enter them)
+Creation dates
+Completion status
+
+App Preferences (UserDefaults) #
+
+Your default filter settings (status, priority, project)
+Your default grouping preferences
+Your default values for new tasks
+UI customization preferences
+
+Important: All of this data is stored exclusively in your device’s local storage using Apple’s SwiftData framework. It is never transmitted to our servers or any third-party services.
+Data Storage Location #
+Local Storage Only #
+TaskStat uses local-only storage via SwiftData (Apple’s native persistence framework). Your data is stored in a SQLite database within the app’s sandboxed container on your device.
+No Cloud Synchronization #
+TaskStat intentionally does not use:
+
+iCloud sync
+CloudKit
+Any proprietary cloud services
+Any third-party cloud storage
+
+This design choice ensures your task data never leaves your device unless you explicitly export it.
+What Happens to Your Data #
+
+When you use the app: Data is read from and written to local storage only
+When you close the app: Data persists in local storage
+When you delete the app: All app data is permanently deleted from your device
+When you upgrade iOS: Data remains in local storage (standard iOS behavior)
+
+Data Sharing and Export #
+User-Controlled Export Only #
+TaskStat includes a CSV export feature that allows you to export your task list. This is entirely under your control :
+
+✅ You initiate the export by tapping the export button
+✅ You choose where to share using iOS’s native share sheet
+✅ You control the recipients (email, files, cloud storage, etc.)
+✅ We never receive the exported file
+
+What’s in an Export #
+When you export your tasks to CSV, the file contains:
+
+Task State
+Task Title
+Task Type
+Task Status
+Assignee
+Priority
+Project
+Notes
+Entry Date
+
+Important: Once you share an exported CSV file via email, cloud storage, or messaging apps, that data is subject to the privacy policies of those services. We recommend being mindful of what you share and with whom.
+Third-Party Services #
+TaskStat does NOT integrate with any third-party services, including:
+
+❌ Analytics platforms (Google Analytics, Firebase Analytics, Amplitude, etc.)
+❌ Crash reporting services (Crashlytics, Sentry, Bugsnag, etc.)
+❌ Advertising networks
+❌ Social media platforms
+❌ Cloud storage providers
+❌ Backend-as-a-service platforms
+
+The only external code included in TaskStat consists of:
+
+Apple’s native iOS frameworks (SwiftUI, SwiftData, Foundation, UIKit)
+
+Network Activity #
+Zero Network Requests #
+TaskStat makes zero network requests . The app:
+
+❌ Does not connect to any servers
+❌ Does not send any data over the internet
+❌ Does not require an internet connection to function
+❌ Does not check for updates (uses App Store’s standard update mechanism)
+
+You can use TaskStat in airplane mode, offline, or with network access completely disabled.
+Data Security #
+How We Protect Your Data #
+Since all data is stored locally on your device:
+
+
+iOS Security Model: Your data benefits from iOS’s robust security architecture, including:
+
+App sandboxing (TaskStat cannot access other apps’ data)
+Encryption at rest (if you enable device encryption)
+Secure enclave protection (on supported devices)
+
+
+
+No Transmission Risk: Since data never leaves your device, there’s no risk of interception during transmission
+
+
+No Server Breaches: We don’t have servers, so there’s no risk of server-side data breaches
+
+
+No Password Storage: TaskStat doesn’t require an account, so there are no passwords to compromise
+
+
+Your Responsibility #
+To keep your task data secure:
+
+✅ Use a device passcode or biometric authentication
+✅ Keep your device’s operating system updated
+✅ Be mindful when exporting and sharing CSV files
+✅ Only install TaskStat from the official Apple App Store
+
+Children’s Privacy #
+TaskStat does not collect any personal information from anyone, including children under 13. Since all data stays on the device and we have no servers or data collection mechanisms, TaskStat is safe for users of all ages.
+Parents should be aware that:
+
+The app stores task information locally on the device
+Users can enter any text content into tasks
+CSV exports could be shared if the device is not properly secured
+
+Your Privacy Rights #
+Complete Data Ownership #
+You have complete ownership and control over your data:
+
+✅ Access: You can view all your data within the app at any time
+✅ Export: You can export all your data to CSV format
+✅ Delete: You can delete individual tasks, projects, or all data
+✅ Modify: You can edit any task information at any time
+
+How to Exercise Your Rights #
+
+To access your data: Open TaskStat—all your data is visible
+To export your data: Use the CSV export feature in the task list
+To delete specific data: Swipe to delete tasks or projects, or use multi-select
+To delete all data: Delete the TaskStat app from your device
+
+No Data Requests Needed #
+Since we don’t collect or store your data on our servers, you don’t need to submit data access or deletion requests to us. You have direct, immediate control over all your information.
+Changes to Data Practices #
+Current Status #
+As of January 2026, TaskStat:
+
+✅ Does not collect any user data
+✅ Uses local-only storage
+✅ Makes zero network requests
+✅ Includes no third-party services
+
+If This Changes #
+We are committed to maintaining TaskStat’s privacy-first design. However, if we ever:
+
+Add cloud synchronization features
+Integrate third-party services
+Implement analytics or crash reporting
+Change our data collection practices
+
+We will:
+
+Update this privacy policy with clear explanations
+Make these features opt-in (not mandatory)
+Notify users through App Store update notes
+
+Any changes to this privacy policy will be posted to this page and reflected in the app’s version history.
+Legal Compliance #
+Regulatory Compliance #
+TaskStat’s privacy-first design ensures compliance with major privacy regulations:
+
+GDPR (General Data Protection Regulation): We don’t collect personal data, so GDPR’s data protection requirements don’t apply
+CCPA (California Consumer Privacy Act): We don’t sell or share personal information
+COPPA (Children’s Online Privacy Protection Act): We don’t collect information from children
+Apple App Store Privacy Requirements: We accurately disclose that we collect zero data
+
+App Store Privacy Nutrition Label #
+In accordance with Apple’s App Privacy details requirements, TaskStat’s privacy label states:
+
+Data Used to Track You: None
+Data Linked to You: None
+Data Not Linked to You: None
+
+This accurately reflects that TaskStat collects no data.
+Open Source and Transparency #
+Code Transparency #
+While TaskStat is not currently open source, we are committed to transparency about our privacy practices:
+
+This privacy policy accurately reflects our app’s behavior
+You can verify our claims using network monitoring tools
+We welcome security researchers to audit our app’s data practices
+
+Verification #
+If you’re technically inclined, you can verify our privacy claims by:
+
+Using network monitoring tools (Charles Proxy, Wireshark, etc.) to confirm zero network traffic
+Reviewing the app’s storage using iOS system tools
+Examining iOS privacy permissions (TaskStat requests none)
+
+
+Questions or Concerns #
+If you have questions about this privacy policy or TaskStat’s data practices:
+
+Data Breach Notification #
+Since TaskStat doesn’t collect or store data on our servers, we cannot experience a data breach of user information. Any data security is determined by your device’s security posture.
+International Users #
+TaskStat is available worldwide. Since all data is stored locally on your device and never transmitted to our servers, there are no cross-border data transfer concerns. Your data never leaves your device unless you explicitly export and share it.
+Summary #
+In Plain English:
+
+✅ TaskStat stores your tasks only on your device
+✅ We never see, collect, or transmit your data
+✅ No internet connection is required
+✅ No account or registration needed
+✅ Export features are entirely under your control
+✅ Delete the app = delete your data permanently
+✅ No tracking, analytics, or third-party services
+
+TaskStat is designed to be the most private task manager possible. Your data is yours, and only yours.
+Acknowledgment #
+By using TaskStat, you acknowledge that you have read and understood this privacy policy. Given that we don’t collect any data, your use of the app does not involve sharing personal information with us.
+TaskStat Privacy Policy Version 1.0
+Simple tasks. Complete privacy.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/apps/taskstat.html b/docs/apps/taskstat.html
new file mode 100644
index 00000000..d55db1c3
--- /dev/null
+++ b/docs/apps/taskstat.html
@@ -0,0 +1,234 @@
+
+
+
+
+
+ TaskStat | Adam Jolicoeur
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mastodon
+
+ Skip to main content
+
+
+
+
+
+
+
+
+
+ TaskStat
+ Privacy-first task management for iOS. Your tasks stay on your device—no accounts, no tracking, no cloud sync.
+
+
+
+
+About TaskStat #
+TaskStat is a native iOS task management app built with privacy as a core principle. Unlike cloud-based task managers, TaskStat stores all your data locally on your device using SwiftData—ensuring complete privacy and offline functionality.
+Key Features #
+
+Complete Privacy - 100% local storage, zero data collection
+Smart Organization - Filter and group tasks by project, status, or priority
+Flexible Projects - Organize tasks into Personal, Work, or custom projects
+Rich Task Details - Track status, priority, type, assignees, and notes
+Multi-Select Operations - Efficiently manage multiple tasks at once
+CSV Export - Export and backup your data anytime
+Native iOS Design - Built with SwiftUI for iOS 18+
+
+Task Management Essentials #
+TaskStat provides comprehensive task tracking with:
+
+Task States: Open, Closed, or Archived
+Status Levels: To Do, In Progress, Completed, or Blocked
+Priority Flags: None, Low, Medium, High, or Urgent
+Task Types: Personal, Work, Other, or Misc
+Assignee Tracking: Assign tasks to team members or yourself
+Detailed Notes: Add context and details to any task
+
+Privacy-First Design #
+
+✅ All data stored locally on your device
+✅ No account creation or sign-in required
+✅ No data collection or analytics
+✅ No third-party services or tracking
+✅ Works completely offline
+✅ No cloud sync means no sync conflicts or data loss
+
+Read the full Privacy Policy
+Screenshots #
+Coming soon - Screenshots will be added once the app is published to the App Store
+
+App Icon #
+Coming soon - App icons will be added once finalized
+
+Download #
+Platform: iOS 18.0 or later
+App Store: Coming soon - Link will be added when published
+
+Requirements #
+
+iPhone running iOS 18 or later
+No internet connection required
+No account or registration needed
+
+Support #
+Questions or issues?
+
+Technical Details #
+TaskStat is built using:
+
+SwiftUI for native iOS interface
+SwiftData for local persistence
+No third-party dependencies
+
+TaskStat: Simple tasks. Complete privacy.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/credits/index.html b/docs/credits/index.html
index 5cddb192..9e77b5b5 100644
--- a/docs/credits/index.html
+++ b/docs/credits/index.html
@@ -72,13 +72,12 @@
-
+
+
+
diff --git a/docs/css/markdown.css b/docs/css/markdown.css
new file mode 100644
index 00000000..5a8a8c4b
--- /dev/null
+++ b/docs/css/markdown.css
@@ -0,0 +1,18 @@
+pre {
+ background-color: var(--earth-cream);
+ padding: var(--space-md, 1rem);
+ border-radius: var(--radius-md, 12px);
+}
+
+section h2 {
+ margin-top: var(--space-lg, 2rem) !important;
+}
+
+section h3 {
+ margin-bottom: var(--space-md, 1rem) !important;
+}
+
+section ul,
+section ol {
+ margin-bottom: var(--space-md, 1rem) !important;
+}
diff --git a/docs/css/style.css b/docs/css/style.css
index 73d79922..39056a38 100644
--- a/docs/css/style.css
+++ b/docs/css/style.css
@@ -1450,12 +1450,6 @@ footer {
color: var(--text-secondary);
}
-pre {
- background-color: var(--earth-cream);
- padding: var(--space-md, 1rem);
- border-radius: var(--radius-md, 12px);
-}
-
/* stylelint-disable */
.gallery {
--size: 100px;
diff --git a/docs/css/style.css.map b/docs/css/style.css.map
index 7ade228a..e3d1b1ae 100644
--- a/docs/css/style.css.map
+++ b/docs/css/style.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../../src/sass/style.scss","../../src/sass/_variables.scss","../../src/sass/_animations.scss","../../src/sass/_fonts.scss","../../src/sass/_typography.scss","../../src/sass/_spacing.scss","../../src/sass/_layout.scss","../../src/sass/_lists.scss","../../src/sass/_highlight.scss","../../src/sass/_navigation.scss","../../src/sass/_footer.scss","../../src/sass/_badge.scss","../../src/sass/_buttons.scss","../../src/sass/_cards.scss","../../src/sass/_markdown.scss","../../src/sass/_gallery.scss"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;ACSA;AACE;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;;;AD3DF;EACE;EACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;IACE;IACA;AAEA;AAEA;IACA;;AAGF;EACA;IACE;;EAEF;AAAA;AAAA;IAGE;IACA;IACA;;;AAGJ;AAAA;EAEE;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA,YACE,iDAC2B;;;AAE/B;EACE;EACA;EACA;;;AAGF;EAEE;EACA;EACA;;;AAEF;EACE;EACA;EACA,YACE,iDAC2B;;;AAE/B;EACE;;;AAGF;AACA;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;AEjJA;AAAA;AAAA;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;EACE;IAAI;;EACJ;IAAK;;EACL;IAAK;;EACL;IAAM;;;AAGR;EACE;IAAI;;EACJ;IAAK;;EACL;IAAK;;EACL;IAAM;;;AAGR;EACE;AAED;;;AAGD;EACE;AAED;;;AAGD;EACE;AAED;;;AC/CD;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AC7EF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAEF;AAAA;EAEE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AACA;EACE;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EAEE;;;AAIJ;AACA;EACE;EACA;EACA;EACA;EACA;;;ACtOF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;ACjIF;AACA;EACE;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;;;AAEF;EACE;;;AAEF;EACE,SA1CK;;;AA4CP;EACE,gBA5CO;;;AA8CT;EACE,aA9CO;;;AAgDT;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;ACtEF;AAAA;AAAA;AAAA;AAAA;EAKE;EACA;;;ACNF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;ACVF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAGF;EACI;IACA;IACA;IACA;;EAKF;IACE;;;ACvEJ;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;AAAA;EAEE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;AAAA;EAEE;EACA;;;AAEF;AAAA;EAEE;;;AC9DF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;ACvBF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;AAAA;EAEE;EACA;;;AAMF;AACA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAMF;AACA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAKF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAMF;AACA;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EAIA;;;AC3IF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAIF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAIF;AACA;EACE;EACA;;;AAEF;EACE;;;AAIA;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;;;AAGF;AACA;EACE;;;AAEF;EACE;EACA;;;AAGF;EACE;IACE;;;AAIJ;EACE;;;AAGF;AACA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EAEA;;;AAEF;EACE;IACE;IAEA;;EAEF;IACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;;AAEF;EACE;IACE;;;AAKJ;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AC3RF;EACE;EACA;EACA;;;ACHF;AACA;EACE;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;EACA;EACA;EAGA,YACE;EAEF;EACA;;AAEA;EACE;;AAGF;EAEE;EAGA;EACA,YACE;;AAIJ;EACE;EACA;;;AAKN;AA+BE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAGF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EA/LA;EAkME;;AAhMF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAwLF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EAhPF;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAsOA;EAEE;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;;AAGJ;AfzJA","file":"style.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../../src/sass/style.scss","../../src/sass/_variables.scss","../../src/sass/_animations.scss","../../src/sass/_fonts.scss","../../src/sass/_typography.scss","../../src/sass/_spacing.scss","../../src/sass/_layout.scss","../../src/sass/_lists.scss","../../src/sass/_highlight.scss","../../src/sass/_navigation.scss","../../src/sass/_footer.scss","../../src/sass/_badge.scss","../../src/sass/_buttons.scss","../../src/sass/_cards.scss","../../src/sass/_gallery.scss"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;ACSA;AACE;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;;;AD3DF;EACE;EACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;IACE;IACA;AAEA;AAEA;IACA;;AAGF;EACA;IACE;;EAEF;AAAA;AAAA;IAGE;IACA;IACA;;;AAGJ;AAAA;EAEE;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA,YACE,iDAC2B;;;AAE/B;EACE;EACA;EACA;;;AAGF;EAEE;EACA;EACA;;;AAEF;EACE;EACA;EACA,YACE,iDAC2B;;;AAE/B;EACE;;;AAGF;AACA;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;AEjJA;AAAA;AAAA;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;EACE;IAAI;;EACJ;IAAK;;EACL;IAAK;;EACL;IAAM;;;AAGR;EACE;IAAI;;EACJ;IAAK;;EACL;IAAK;;EACL;IAAM;;;AAGR;EACE;AAED;;;AAGD;EACE;AAED;;;AAGD;EACE;AAED;;;AC/CD;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AC7EF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAEF;AAAA;EAEE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AACA;EACE;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EAEE;;;AAIJ;AACA;EACE;EACA;EACA;EACA;EACA;;;ACtOF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;ACjIF;AACA;EACE;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;;;AAEF;EACE;;;AAEF;EACE,SA1CK;;;AA4CP;EACE,gBA5CO;;;AA8CT;EACE,aA9CO;;;AAgDT;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;ACtEF;AAAA;AAAA;AAAA;AAAA;EAKE;EACA;;;ACNF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;ACVF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAGF;EACI;IACA;IACA;IACA;;EAKF;IACE;;;ACvEJ;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;AAAA;EAEE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;AAAA;EAEE;EACA;;;AAEF;AAAA;EAEE;;;AC9DF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;ACvBF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;AAAA;EAEE;EACA;;;AAMF;AACA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAMF;AACA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAKF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAMF;AACA;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EAIA;;;AC3IF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAIF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAIF;AACA;EACE;EACA;;;AAEF;EACE;;;AAIA;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;;;AAGF;AACA;EACE;;;AAEF;EACE;EACA;;;AAGF;EACE;IACE;;;AAIJ;EACE;;;AAGF;AACA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EAEA;;;AAEF;EACE;IACE;IAEA;;EAEF;IACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;;AAEF;EACE;IACE;;;AAKJ;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AC3RF;AACA;EACE;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;EACA;EACA;EAGA,YACE;EAEF;EACA;;AAEA;EACE;;AAGF;EAEE;EAGA;EACA,YACE;;AAIJ;EACE;EACA;;;AAKN;AA+BE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAEF;EAGE;;AAGF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EA/LA;EAkME;;AAhMF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAwLF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EAhPF;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAsOA;EAEE;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;;AAGJ;Ad1JA","file":"style.css"}
\ No newline at end of file
diff --git a/docs/feed.json b/docs/feed.json
index 193bb328..f317d38e 100644
--- a/docs/feed.json
+++ b/docs/feed.json
@@ -26,12 +26,28 @@
"url": ""
},
"items": [
+ {
+ "id": "/apps/taskstat.html",
+ "url": "/apps/taskstat.html",
+ "title": "TaskStat",
+ "date_published": "2026-01-05T17:33:31Z",
+ "date": "2026-01-05T17:33:31Z"
+ }
+ ,
+ {
+ "id": "/apps/taskstat-privacy.html",
+ "url": "/apps/taskstat-privacy.html",
+ "title": "TaskStat Privacy Policy",
+ "date_published": "2026-01-05T17:33:31Z",
+ "date": "2026-01-05T17:33:31Z"
+ }
+ ,
{
"id": "/portfolio/",
"url": "/portfolio/",
"title": "My Work",
- "date_published": "2026-01-01T16:25:50Z",
- "date": "2026-01-01T16:25:50Z"
+ "date_published": "2026-01-02T02:38:29Z",
+ "date": "2026-01-02T02:38:29Z"
}
,
{
diff --git a/docs/sass/markdown.css b/docs/sass/markdown.css
new file mode 100644
index 00000000..aa10a161
--- /dev/null
+++ b/docs/sass/markdown.css
@@ -0,0 +1 @@
+pre{background-color:var(--earth-cream);padding:var(--space-md,1rem);border-radius:var(--radius-md,12px)}section h2{margin-top:var(--space-lg,2rem)!important}section h3,section ul,section ol{margin-bottom:var(--space-md,1rem)!important}
\ No newline at end of file
diff --git a/docs/sass/style.css b/docs/sass/style.css
index 79b508f1..f99d5fb9 100644
--- a/docs/sass/style.css
+++ b/docs/sass/style.css
@@ -1 +1 @@
-:root{--font-family-sans:"Inter",system-ui,-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,sans-serif;--font-family-serif:"Playfair Display",serif;--font-family-mono:"Fira Code","Courier New",courier,monospace;--font-family-heading:"Pirata One",cursive;--white:#f0f0f0;--black:#010101;--earth-dark:#2d1f12;--earth-brown:#4a3426;--earth-sage:#5a6b4f;--earth-sand:#c9b89a;--earth-cream:#f5f1e8;--accent-coral:#d35f3d;--accent-coral-dark:#b34a2d;--text-primary:#2d1f12;--text-secondary:#4a3426;--text-muted:#6b5d52;--shadow:rgba(45,31,18,.15);--shadow-heavy:rgba(45,31,18,.25);--shadow-light:rgba(45,31,18,.08);--font-size-xs:.75rem;--font-size-sm:.875rem;--font-size-md:1rem;--font-size-lg:1.125rem;--font-size-xl:1.25rem;--font-size-2xl:1.5rem;--font-size-3xl:2rem;--font-size-4xl:2.5rem;--font-size-5xl:3rem;--font-size-6xl:4rem;--space-2xs:.25rem;--space-xs:.5rem;--space-sm:.75rem;--space-md:1rem;--space-lg:1.5rem;--space-xl:2rem;--space-2xl:3rem;--space-3xl:6rem;--radius-sm:8px;--radius-md:12px;--radius-lg:16px;--radius-xl:20px;--radius-pill:50px;--border-thin:2px;--border-medium:4px;--border-thick:6px;--border-extra-thick:8px}*{box-sizing:border-box;margin:0;padding:0}:focus-visible{outline:var(--border-thin)solid var(--accent-coral);outline-offset:2px}html{scroll-behavior:smooth}body{font-family:var(--font-family-sans);background:linear-gradient(135deg,var(--earth-cream)0%,#e8dcc8 100%);color:var(--text-primary);min-height:100vh;line-height:1.6;position:relative}@media (prefers-reduced-motion:reduce){.animated-element{opacity:1;transition:none;animation:none}body{scroll-behavior:auto}*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}.display-none,.d-none{display:none!important}.hero{text-align:center;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;max-width:900px;margin:0 auto;padding:6rem 2rem;display:-ms-flexbox;display:flex}.rounded{border-radius:var(--radius-xl,20px)!important}.circle{border-radius:999px!important;padding:1rem!important}.fade-in{opacity:0;visibility:hidden;transition:opacity .5s ease-in,visibility 0s linear .5s}.fade-in.show,.show{opacity:1;visibility:visible;transition-delay:0s}.hide{opacity:0;visibility:hidden;transition:opacity .5s ease-in,visibility 0s linear .5s}.hide-on-screen{display:none!important}@media (max-width:768px){.hero h1{font-size:var(--font-size-5xl,3rem)}.no-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.hide-on-mobile{display:none!important}.work-grid,.callouts-grid{grid-template-columns:1fr}h2{font-size:var(--font-size-3xl,2rem)}}figcaption{font-size:var(--font-size-sm,.875rem);color:var(--text-secondary);text-align:center;font-style:italic;line-height:1.4}.arrows{width:60px;height:72px;margin-left:-30px;position:absolute;bottom:20px;left:50%}.arrows path{stroke:#bfe7fa;fill:transparent;stroke-width:1px;animation:2s infinite arrow}@keyframes arrow{0%{opacity:0}40%{opacity:1}80%{opacity:0}to{opacity:0}}.arrows path.a1{animation-delay:-1s}.arrows path.a2{animation-delay:-.5s}.arrows path.a3{animation-delay:0s}.pirata-one-regular{font-family:Pirata One,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue;font-style:normal;font-weight:400}.inter-400{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:400}.inter-500{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:500}.inter-600{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:600}.inter-700{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:700}.inter-800{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:800}.inter-900{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:900}.playfair-display-400{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:400}.playfair-display-500{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:500}.playfair-display-600{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:600}.playfair-display-700{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:700}.playfair-display-800{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:800}.playfair-display-900{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:900}h1,.text-h1{color:var(--text-primary);letter-spacing:2px;text-shadow:3px 3px 0 var(--accent-coral);font-family:Pirata One,cursive;font-size:max(2.5rem,min(8vw,5rem));line-height:1.2}.text-display{color:var(--text-primary);letter-spacing:2px;text-shadow:3px 3px 0 var(--accent-coral);font-family:Pirata One,cursive;font-size:max(3rem,min(10vw,6rem));line-height:1.1}.hero h1{font-family:var(--font-family-heading);color:var(--text-primary);text-shadow:3px 3px 0 var(--accent-coral);letter-spacing:2px;margin-bottom:1rem;font-size:6rem;line-height:1.2}h2,.text-h2{color:var(--text-primary);margin-bottom:var(--space-md,1.5rem);font-family:Playfair Display,serif;font-size:max(2rem,min(5vw,3rem));font-weight:700;line-height:1.3}.text-h2.no-underline:after{margin-bottom:var(--space-2xs,.25rem);display:none}h2:after,.text-h2:after{content:"";background:var(--accent-coral);border:3px solid var(--earth-brown);width:100px;height:5px;margin:1rem auto;display:block}h3,.text-h3{color:var(--text-primary);font-family:Playfair Display,serif;font-size:max(1.5rem,min(3vw,2rem));font-weight:600;line-height:1.3}h4,.text-h4{color:var(--text-primary);font-family:Playfair Display,serif;font-size:max(1.25rem,min(2.5vw,1.5rem));font-weight:600;line-height:1.4}h5,.text-h5{color:var(--text-primary);font-family:Inter,sans-serif;font-size:max(1.1rem,min(2vw,1.25rem));font-weight:700;line-height:1.4}h6,.text-h6{color:var(--text-primary);text-transform:uppercase;letter-spacing:.5px;font-family:Inter,sans-serif;font-size:1rem;font-weight:700;line-height:1.4}.text-body-lg{font-size:max(1.1rem,min(1.5vw,1.25rem))!important;line-height:1.7!important}p,.text-body{color:var(--text-primary);padding-bottom:var(--space-xs,.5rem);font-size:max(.95rem,min(1.5vw,1rem));line-height:1.7}p:last-child,.text-body:last-child{margin-bottom:0}.hero p{color:var(--earth-brown);max-width:720px;margin:0 auto;font-size:max(1.1rem,min(2vw,1.25rem))}.card-body p:first-of-type,.card-body .text-body:first-of-type{margin-top:var(--space-md,16px)}.text-body-sm{font-size:max(.85rem,min(1.2vw,.9rem));line-height:1.6}.text-caption{font-size:clamp(var(--space-sm),1vw,.85rem);color:var(--text-muted);line-height:1.5}.text-callout{color:var(--text-primary);margin:var(--space-lg,1.5rem);padding:var(--space-lg,1.5rem);background:var(--earth-sand-light);border-left:var(--border-medium)solid var(--accent-coral);font-size:max(1rem,min(1.5vw,1.1rem));font-weight:600;line-height:1.6}code,.code{font-family:var(--font-family-mono);font-size:max(.85rem,min(1vw,.9rem))}code.code-inline,.code.code-inline{background:var(--earth-sand);border-radius:var(--radius-sm);padding:.1rem .3rem}.code-block{background:var(--earth-sand);border-radius:var(--radius-md);border:var(--border-thin)solid var(--earth-sage);padding:1rem;font-size:max(.85rem,min(1vw,.9rem));display:block;overflow-x:auto}.text-muted{color:var(--text-muted)}.text-secondary{color:var(--text-secondary)}.text-accent{color:var(--accent-coral)}.text-semibold{font-weight:600}.text-bold{font-weight:700}.text-center{text-align:center}.lead,.text-lead{color:var(--text-secondary);font-size:max(1.1rem,min(2vw,1.35rem));line-height:1.7}a,.link{color:var(--earth-sage);border-bottom:1px solid var(--earth-sage);font-weight:var(--font-weight-semibold,600);text-decoration:none;transition:all .2s}a:hover,a:focus,.link:hover,.link:focus{color:var(--earth-brown);border-bottom-color:var(--earth-brown)}.link-brackets{margin-left:var(--space-md)!important}.link-brackets:after{content:"]";color:var(--earth-sage);margin-left:.2rem;transition:all .2s;position:absolute}.link-brackets:before{content:"[";color:var(--earth-sage);margin-left:-.8rem;transition:all .2s;position:absolute}.link-brackets:hover:after,.link-brackets:hover:before,.link-brackets:focus:after,.link-brackets:focus:before{color:var(--accent-coral)}blockquote,.blockquote{border-left:var(--border-thin)solid var(--earth-brown);padding-left:var(--space-md,1rem);margin:var(--space-lg,1.5rem)0;color:var(--text-secondary);font-style:italic}.mb-1{margin-bottom:var(--space-2xs)!important}.mb-2{margin-bottom:var(--space-xs)!important}.mb-3{margin-bottom:var(--space-sm)!important}.mb-4{margin-bottom:var(--space-md)!important}.mb-5{margin-bottom:var(--space-xl)!important}.mt-1{margin-top:var(--space-2xs)!important}.mt-2{margin-top:var(--space-xs)!important}.mt-3{margin-top:var(--space-sm)!important}.mt-4{margin-top:var(--space-md)!important}.mt-5{margin-top:var(--space-xl)!important}.ml-1{margin-left:var(--space-2xs)!important}.ml-2{margin-left:var(--space-xs)!important}.ml-3{margin-left:var(--space-sm)!important}.ml-4{margin-left:var(--space-md)!important}.ml-5{margin-left:var(--space-xl)!important}.mr-1{margin-right:var(--space-2xs)!important}.mr-2{margin-right:var(--space-xs)!important}.mr-3{margin-right:var(--space-sm)!important}.mr-4{margin-right:var(--space-md)!important}.mr-5{margin-right:var(--space-xl)!important}.p-1{padding:var(--space-2xs)!important}.p-2{padding:var(--space-xs)!important}.p-3{padding:var(--space-sm)!important}.p-4{padding:var(--space-md)!important}.p-5{padding:var(--space-xl)!important}.pt-1{padding-top:var(--space-2xs)!important}.pt-2{padding-top:var(--space-xs)!important}.pt-3{padding-top:var(--space-sm)!important}.pt-4{padding-top:var(--space-md)!important}.pt-5{padding-top:var(--space-xl)!important}.pb-1{padding-bottom:var(--space-2xs)!important}.pb-2{padding-bottom:var(--space-xs)!important}.pb-3{padding-bottom:var(--space-sm)!important}.pb-4{padding-bottom:var(--space-md)!important}.pb-5{padding-bottom:var(--space-xl)!important}.pl-1{padding-left:var(--space-2xs)!important}.pl-2{padding-left:var(--space-xs)!important}.pl-3{padding-left:var(--space-sm)!important}.pl-4{padding-left:var(--space-md)!important}.pl-5{padding-left:var(--space-xl)!important}.pr-1{padding-right:var(--space-2xs)!important}.pr-2{padding-right:var(--space-xs)!important}.pr-3{padding-right:var(--space-sm)!important}.pr-4{padding-right:var(--space-md)!important}.pr-5{padding-right:var(--space-xl)!important}section{max-width:1200px;padding:var(--space-3xl,6rem)var(--space-lg,2rem);margin:0 auto}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.row{gap:var(--space-lg,2rem);-ms-flex-wrap:wrap;flex-wrap:wrap;display:-ms-flexbox;display:flex}@media (min-width:768px){.row{gap:var(--space-xs,.5rem)}.card-body .row{gap:0}}.button-row{gap:1rem}.no-wrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.d-flex{display:-ms-flexbox;display:flex}.flex-column{-ms-flex-direction:column;flex-direction:column}.align-items-center{-ms-flex-align:center;align-items:center}.work-grid{gap:var(--space-lg,2rem);margin-bottom:var(--space-lg,2rem);grid-template-columns:repeat(auto-fit,minmax(300px,1fr));display:grid}.divider{width:50%;height:var(--space-md,1.5rem);background:var(--accent-coral);border:var(--border-medium,4px)outset var(--earth-dark);margin:0 auto;display:block}.divider.vertical{width:var(--space-2xs,.25rem);background:var(--earth-dark);border-radius:var(--radius-sm);height:100%;margin:0;border:none!important}ul,ol,.card-body ul,.card-body ol,ul.list,ol.list{margin-left:var(--space-lg)!important;padding-left:var(--space-md)!important}.highlight-block{-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.header-highlight{text-align:center;margin:var(--space-md)auto;padding:var(--space-md);width:100%}nav{z-index:1000;backdrop-filter:blur(24px);filter:url(#lensFilter)saturate(120%)brightness(1.15);border:var(--border-medium,4px)solid var(--earth-brown);padding:var(--space-sm)2rem;box-shadow:0 8px 24px var(--shadow-heavy);background:rgba(245,241,232,.5);border-radius:50px;position:fixed;top:2rem;left:50%;transform:translate(-50%)}.main-nav{width:fit-content;margin:0 auto;position:sticky;top:2rem;left:0;right:0;transform:none!important}nav ul{-ms-flex-pack:center;justify-content:center;gap:2rem;list-style:none;display:-ms-flexbox;display:flex;margin-left:0!important;padding-left:0!important}nav a{color:var(--text-primary);padding:var(--space-2xs)var(--space-xs,.5rem);border-bottom:none;font-size:.95rem;font-weight:500;text-decoration:none;transition:color .3s}nav a:hover,nav a:focus{color:var(--accent-coral);outline:var(--border-thin)solid var(--accent-coral);outline-offset:2px}nav a.active{color:var(--accent-coral)}nav a.sub-page{outline:var(--border-thin)solid var(--text-secondary);outline-offset:2px}nav a.sub-page:hover{outline-color:var(--accent-coral)}@media (max-width:768px){nav{top:var(--space-sm,1rem)!important;padding:var(--space-xs,.5rem)var(--space-sm,1rem)!important;margin:0 auto!important}nav ul{gap:var(--space-sm,1rem)}}footer{background:var(--earth-dark);color:var(--earth-cream);padding:var(--space-2xl,3rem)var(--space-xl,2rem);margin-top:var(--space-3xl,6rem);border-top:var(--border-extra-thick,8px)solid var(--earth-brown);box-shadow:0 -10px 30px var(--shadow)}.footer-content{grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:3rem;max-width:1200px;margin:0 auto;display:grid}.footer-section h3{color:var(--accent-coral);margin-bottom:var(--space-md,1rem);font-family:Playfair Display,serif;font-size:max(1.2rem,min(2vw,1.5rem))}.footer-section h4{margin-bottom:var(--space-md,1rem);font-family:Playfair Display,serif;font-size:max(1.1rem,min(1.25vw,1.125rem));color:rgba(255,255,255,.5)!important}.footer-section p,.footer-section li{color:var(--earth-cream);margin-bottom:var(--space-xs,.5rem);line-height:1.6}.footer-section ul{padding:0;list-style:none}.footer-section li{margin-bottom:var(--space-xs,.5rem)}.footer-bottom{text-align:center;margin-top:var(--space-2xl,3rem);padding-top:var(--space-xl,2rem);border-top:var(--border-medium,4px)solid var(--earth-brown);color:var(--earth-sand)}.footer-bottom p{font-size:var(--font-size-sm);color:var(--earth-cream);margin:0}.footer-section a,.footer-bottom a{color:var(--earth-cream);text-decoration:underline}.footer-section a:hover,.footer-bottom a:hover{color:var(--accent-coral)}.badge{padding:var(--space-2xs,.25rem)var(--space-sm,.75rem);background:var(--earth-sage);color:var(--earth-cream);border:var(--border-thin,2px)solid var(--earth-brown);border-radius:var(--radius-pill);font-size:.85rem;font-weight:600;display:inline-block}.badge-accent{background:var(--accent-coral-dark)}.badge-outline{color:inherit;background:0 0}.badges,.row-badges{gap:var(--space-2xs,.25rem);-ms-flex-wrap:wrap;flex-wrap:wrap;display:-ms-flexbox;display:flex}.btn{padding:var(--space-sm,.75rem)var(--space-lg,1.5rem);font-family:var(--font-family-sans);font-size:var(--font-size-md,1rem);border-radius:var(--radius-md,12px);cursor:pointer;text-align:center;border:none;font-weight:600;text-decoration:none;transition:all .2s;display:inline-block}.btn:hover,.btn:focus{box-shadow:2px 2px 0 var(--earth-brown);transform:translate(2px,2px)}.btn-primary{background:var(--accent-coral-dark);color:var(--white);border:var(--border-medium,4px)solid var(--earth-brown);box-shadow:4px 4px 0 var(--earth-brown)}.btn-primary:hover,.btn-primary:focus{background:var(--accent-coral-dark);color:var(--white)}.btn-secondary{background:var(--earth-cream);color:var(--text-primary);border:var(--border-medium,4px)solid var(--earth-brown);box-shadow:4px 4px 0 var(--earth-sage)}.btn-secondary:hover,.btn-secondary:focus{background:var(--earth-sand);color:var(--text-primary);box-shadow:2px 2px 0 var(--earth-sage);outline:var(--border-thin)solid var(--earth-dark);transform:translate(2px,2px)}.btn-outline{backdrop-filter:blur(24px);filter:url(#lensFilter)saturate(120%)brightness(1.15);color:var(--text-primary)!important;border:var(--border-medium,4px)solid var(--earth-brown)!important;box-shadow:none!important;background:rgba(255,255,255,.5)!important}.btn-outline:hover,.btn-outline:focus{color:var(--earth-cream);text-decoration:underline}.btn-sm{padding:var(--space-xs,.5rem)var(--space-md,1rem)!important;border-width:var(--border-thin)!important;font-size:.9rem!important}.btn-lg{padding:var(--space-md,1rem)var(--space-xl,2rem)!important;font-size:1.1rem!important}.skip-link{background:var(--accent-coral);color:var(--white);padding:var(--space-sm,.75rem)var(--space-lg,1.5rem);border:var(--border-medium,4px)solid var(--earth-brown);z-index:2000;clip:rect(0,0,0,0);font-weight:600;text-decoration:none;position:absolute;top:-100px;left:0;overflow:hidden}.skip-link:focus{clip:auto;top:1rem;left:1rem;overflow:visible}.social-links{-ms-flex-wrap:wrap;flex-wrap:wrap;gap:1rem;display:-ms-flexbox;display:flex}.social-link{padding:var(--space-xs,.5rem)var(--space-md,1rem);background:var(--earth-sage);color:var(--white);border:var(--border-medium,4px)solid var(--earth-sand);border-radius:8px;font-size:.95rem;font-weight:500;transition:all .3s;display:inline-block;text-decoration:none!important}.social-link:hover,.social-link:focus{background:var(--accent-coral);transform:translateY(-2px);color:var(--white)!important}.card{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--earth-brown);border-radius:var(--radius-xl,20px);padding:var(--space-lg,1.5rem);box-shadow:8px 8px 0 var(--shadow-heavy);transition:transform .3s,box-shadow .3s}.card:hover{box-shadow:12px 12px 0 var(--shadow-heavy);transform:translateY(-5px)}.card:focus-within{box-shadow:12px 12px 0 var(--shadow-heavy);transform:translateY(-5px)}.card-layered{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--earth-brown);border-radius:var(--radius-xl,20px);padding:var(--space-xl,2rem);box-shadow:12px 12px 0 var(--earth-sage),12px 12px 0 5px var(--earth-brown)}.card-shadow{background:var(--earth-cream);border-radius:var(--radius-lg,16px);padding:var(--space-md,1.5rem);box-shadow:10px 10px 0 var(--shadow-heavy);border:none}.card-accent{background:var(--earth-cream);border:var(--border-extra-thick,8px)solid var(--earth-brown);border-radius:var(--radius-xl,20px);box-shadow:16px 16px 0 var(--accent-coral),16px 16px 0 6px var(--earth-brown);overflow:hidden}.card-flex{-ms-flex-direction:column;flex-direction:column;display:-ms-flexbox;display:flex}.card-flex p{-ms-flex:1 0;flex:1 0}.card-with-columns .row{-ms-flex-align:start;align-items:flex-start;gap:var(--space-md,1rem);-ms-flex-item-align:stretch;align-self:stretch;display:-ms-flexbox;display:flex}.card-with-columns .column{-ms-flex:1 0 0;flex:1 0 0;-ms-flex-item-align:stretch;align-self:stretch;-ms-flex-align:start;align-items:flex-start;display:-ms-flexbox;display:flex}.card-header{margin-bottom:var(--space-md,1rem);padding-bottom:var(--space-md,1rem);border-bottom:var(--border-thin,2px)solid var(--earth-sand)}.card-body{margin-bottom:var(--space-md)}.card-body img{object-fit:cover;width:100%}@media (min-width:768px){.img-thumbnail{max-width:50%}}.card-body:last-child{margin-bottom:0}.card-footer{margin-top:var(--space-md,1rem);padding-top:var(--space-md,1rem);border-top:var(--border-thin,2px)solid var(--earth-sand)}.showcase-content{padding:var(--space-lg,2rem)}.showcase-content h3{font-family:var(--font-family-serif);color:var(--text-primary);margin-bottom:var(--space-sm,1rem);font-size:max(1.3rem,min(2.5vw,1.8rem))}.showcase-content p{color:var(--text-secondary);margin-bottom:var(--space-md,1.5rem);font-size:max(.95rem,min(1.5vw,1rem))}.showcase-small{background:var(--earth-sand);border:4px solid var(--earth-brown);border-radius:var(--radius-lg,16px);padding:var(--space-md,1.5rem);box-shadow:6px 6px 0 var(--shadow-heavy);transition:transform .3s}.showcase-small:hover{transform:translateY(-4px)}.showcase-small:focus-within{transform:translateY(-4px)}.showcase-small h4{font-family:var(--font-family-serif);color:var(--text-primary);margin-bottom:var(--space-xs,.5rem);font-size:max(1.1rem,min(2vw,1.3rem))}.showcase-small p{color:var(--text-secondary);font-size:max(.9rem,min(1.5vw,.95rem))}.about-card{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--earth-brown);padding:var(--space-2xl,3rem);border-radius:var(--border-radius-xl,20px);box-shadow:12px 12px 0 var(--earth-sage),12px 12px 0 5px var(--earth-brown);margin:0 auto}@media (max-width:768px){.about-card{box-shadow:6px 6px 0 var(--earth-sage),6px 6px 0 4px var(--earth-brown);padding:var(--space-md,1rem)}.about-grid{grid-template-columns:1fr!important}}.about-card p{color:var(--text-primary);margin-bottom:var(--space-lg,1.5rem);font-size:max(1rem,min(1.5vw,1.1rem));line-height:1.8}.about-card p:last-child{margin-bottom:0}.about-grid{gap:var(--space-xl,2rem);margin-top:var(--space-xl,2rem);grid-template-columns:repeat(auto-fit,minmax(350px,1fr));display:grid}.showcase-large{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--earth-brown);border-radius:var(--radius-xl,20px);box-shadow:12px 12px 0 var(--accent-coral),12px 12px 0 6px var(--earth-brown);transition:transform .3s;overflow:hidden}@media (max-width:768px){.showcase-large{box-shadow:6px 6px 0 var(--accent-coral),6px 6px 0 4px var(--earth-brown)}}.showcase-large:hover{transform:translateY(-8px)}.showcase-large:focus-within{transform:translateY(-8px)}.showcase-image{background:linear-gradient(135deg,var(--earth-sage)0%,var(--earth-sand)100%);width:100%;height:300px;padding:var(--space-md,1rem);font-size:var(--font-size-5xl,3rem);color:var(--earth-cream);border-bottom:var(--border-thick,6px)solid var(--earth-brown);object-fit:contain;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.showcase-image-dark{background:linear-gradient(135deg,var(--black)0%,var(--earth-dark)100%)}.small-showcase-cards{gap:var(--space-md,1.5rem);margin-top:var(--space-sm,1rem);grid-column:1/-1;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));display:grid}.callouts-grid{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:2rem;margin-top:2rem;display:grid}.callout{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--accent-coral-dark);border-radius:var(--radius-xl,20px);box-shadow:8px 8px 0 var(--shadow-heavy);-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:end;align-items:flex-end;padding:2rem;transition:transform .3s,box-shadow .3s;display:-ms-flexbox;display:flex;position:relative}.callout:hover{box-shadow:12px 12px 0 var(--shadow-heavy);transform:translateY(-5px)}.callout:focus-within{box-shadow:12px 12px 0 var(--shadow-heavy);transform:translateY(-5px)}.callout:before{content:"\"";font-family:var(--font-family-serif);font-size:var(--font-size-6xl,4rem);color:var(--accent-coral);line-height:1;position:absolute;top:10px;left:20px}.callout-text{margin-bottom:var(--space-md,1.5rem);padding-top:var(--space-sm,1rem);color:var(--text-primary);font-style:italic}.callout-author{color:var(--text-primary);font-weight:600;display:block}.callout-role{font-size:var(--font-size-sm,.9rem);color:var(--text-secondary)}pre{background-color:var(--earth-cream);padding:var(--space-md,1rem);border-radius:var(--radius-md,12px)}.gallery{--size:100px;grid-template-columns:repeat(6,var(--size));grid-auto-rows:var(--size);margin-bottom:var(--size);-ms-flex-align:start;align-items:start;justify-items:center;gap:5px;display:grid}.gallery:has(:hover) picture:not(:hover){filter:brightness(.5)contrast(.5)}.gallery:has(:focus) picture:not(:focus){filter:brightness(.5)contrast(.5)}.gallery picture{object-fit:cover;width:calc(var(--size)*2);height:calc(var(--size)*2);clip-path:path("M90,10 C100,0 100,0 110,10 190,90 190,90 190,90 200,100 200,100 190,110 190,110 110,190 110,190 100,200 100,200 90,190 90,190 10,110 10,110 0,100 0,100 10,90Z");border-radius:5px;grid-column:auto/span 2;transition:clip-path .25s,filter .75s}.gallery picture:nth-child(5n-1){grid-column:2/span 2}.gallery picture:hover,.gallery picture:focus{clip-path:path("M0,0 C0,0 200,0 200,0 200,0 200,100 200,100 200,100 200,200 200,200 200,200 100,200 100,200 100,200 100,200 0,200 0,200 0,100 0,100 0,100 0,100 0,100Z");z-index:1;transition:clip-path .25s,filter .25s}.gallery picture:focus{outline-offset:-5px;outline:1px dashed #000}.carousel>input{clip:rect(1px,1px,1px,1px);clip-path:inset(50%);width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.carousel>input:nth-of-type(15):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1400%}.carousel>input:nth-of-type(14):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1300%}.carousel>input:nth-of-type(13):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1200%}.carousel>input:nth-of-type(12):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1100%}.carousel>input:nth-of-type(11):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1000%}.carousel>input:nth-of-type(10):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-900%}.carousel>input:nth-of-type(9):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-800%}.carousel>input:nth-of-type(8):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-700%}.carousel>input:nth-of-type(7):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-600%}.carousel>input:nth-of-type(6):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-500%}.carousel>input:nth-of-type(5):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-400%}.carousel>input:nth-of-type(4):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-300%}.carousel>input:nth-of-type(3):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-200%}.carousel>input:nth-of-type(2):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-100%}.carousel>input:first-of-type:checked~.carousel__slides .carousel__slide:first-of-type{margin-left:0%}.carousel>input:first-of-type:checked~.carousel__thumbnails li:first-of-type,.carousel>input:nth-of-type(2):checked~.carousel__thumbnails li:nth-of-type(2),.carousel>input:nth-of-type(3):checked~.carousel__thumbnails li:nth-of-type(3),.carousel>input:nth-of-type(4):checked~.carousel__thumbnails li:nth-of-type(4),.carousel>input:nth-of-type(5):checked~.carousel__thumbnails li:nth-of-type(5),.carousel>input:nth-of-type(6):checked~.carousel__thumbnails li:nth-of-type(6),.carousel>input:nth-of-type(7):checked~.carousel__thumbnails li:nth-of-type(7),.carousel>input:nth-of-type(8):checked~.carousel__thumbnails li:nth-of-type(8),.carousel>input:nth-of-type(9):checked~.carousel__thumbnails li:nth-of-type(9),.carousel>input:nth-of-type(10):checked~.carousel__thumbnails li:nth-of-type(10),.carousel>input:nth-of-type(11):checked~.carousel__thumbnails li:nth-of-type(11),.carousel>input:nth-of-type(12):checked~.carousel__thumbnails li:nth-of-type(12),.carousel>input:nth-of-type(13):checked~.carousel__thumbnails li:nth-of-type(13),.carousel>input:nth-of-type(14):checked~.carousel__thumbnails li:nth-of-type(14),.carousel>input:nth-of-type(15):checked~.carousel__thumbnails li:nth-of-type(15){box-shadow:0 0 0 5px rgba(0,0,255,.5)}.carousel__slides{z-index:1;white-space:nowrap;box-sizing:border-box;margin:0;padding:0;display:-ms-flexbox;display:flex;position:relative;overflow:hidden}.carousel__slide{vertical-align:top;box-sizing:border-box;white-space:normal;-ms-flex:1 0 100%;flex:1 0 100%;width:100%;height:100%;transition:all .3s ease-out;display:block;position:relative;overflow:hidden}.carousel__slide figure{margin:0;display:-ms-flexbox;display:flex}.carousel__slide div{width:100%;position:relative}.carousel__slide div:before{content:"";width:100%;padding-top:66.6667%;display:block}.carousel__slide div>img{width:100%;height:100%;position:absolute;top:0;bottom:0;left:0;right:0}.carousel__slide img{object-fit:cover;-ms-flex:auto;flex:auto;display:block}.carousel__slide figcaption{-ms-flex:none;flex:none;-ms-flex-item-align:end;align-self:flex-end;width:25%;min-width:150px;padding:20px 20px 0}.carousel__slide .credit{color:rgba(0,0,0,.5);margin-top:1rem;display:block}.carousel__slide.scrollable{overflow-y:scroll}.carousel__thumbnails{margin:0 -10px;padding:0;list-style:none;display:-ms-flexbox;display:flex}.carousel__slides+.carousel__thumbnails{margin-top:20px}.carousel__thumbnails li{-ms-flex:auto;flex:auto;max-width:calc(16.6667% - 20px);margin:0 10px;transition:all .3s ease-in-out}.carousel__thumbnails label{display:block;position:relative}.carousel__thumbnails label:before{content:"";width:100%;padding-top:100%;display:block}.carousel__thumbnails label>img{width:100%;height:100%;position:absolute;top:0;bottom:0;left:0;right:0}.carousel__thumbnails label:hover,.carousel__thumbnails label:focus{cursor:pointer}.carousel__thumbnails label:hover img,.carousel__thumbnails label:focus img{transition:all .3s ease-in-out;box-shadow:0 0 0 1px rgba(0,0,0,.25)}.carousel__thumbnails img{object-fit:cover;width:100%;height:100%;display:block}
\ No newline at end of file
+:root{--font-family-sans:"Inter",system-ui,-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,sans-serif;--font-family-serif:"Playfair Display",serif;--font-family-mono:"Fira Code","Courier New",courier,monospace;--font-family-heading:"Pirata One",cursive;--white:#f0f0f0;--black:#010101;--earth-dark:#2d1f12;--earth-brown:#4a3426;--earth-sage:#5a6b4f;--earth-sand:#c9b89a;--earth-cream:#f5f1e8;--accent-coral:#d35f3d;--accent-coral-dark:#b34a2d;--text-primary:#2d1f12;--text-secondary:#4a3426;--text-muted:#6b5d52;--shadow:rgba(45,31,18,.15);--shadow-heavy:rgba(45,31,18,.25);--shadow-light:rgba(45,31,18,.08);--font-size-xs:.75rem;--font-size-sm:.875rem;--font-size-md:1rem;--font-size-lg:1.125rem;--font-size-xl:1.25rem;--font-size-2xl:1.5rem;--font-size-3xl:2rem;--font-size-4xl:2.5rem;--font-size-5xl:3rem;--font-size-6xl:4rem;--space-2xs:.25rem;--space-xs:.5rem;--space-sm:.75rem;--space-md:1rem;--space-lg:1.5rem;--space-xl:2rem;--space-2xl:3rem;--space-3xl:6rem;--radius-sm:8px;--radius-md:12px;--radius-lg:16px;--radius-xl:20px;--radius-pill:50px;--border-thin:2px;--border-medium:4px;--border-thick:6px;--border-extra-thick:8px}*{box-sizing:border-box;margin:0;padding:0}:focus-visible{outline:var(--border-thin)solid var(--accent-coral);outline-offset:2px}html{scroll-behavior:smooth}body{font-family:var(--font-family-sans);background:linear-gradient(135deg,var(--earth-cream)0%,#e8dcc8 100%);color:var(--text-primary);min-height:100vh;line-height:1.6;position:relative}@media (prefers-reduced-motion:reduce){.animated-element{opacity:1;transition:none;animation:none}body{scroll-behavior:auto}*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}.display-none,.d-none{display:none!important}.hero{text-align:center;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;max-width:900px;margin:0 auto;padding:6rem 2rem;display:-ms-flexbox;display:flex}.rounded{border-radius:var(--radius-xl,20px)!important}.circle{border-radius:999px!important;padding:1rem!important}.fade-in{opacity:0;visibility:hidden;transition:opacity .5s ease-in,visibility 0s linear .5s}.fade-in.show,.show{opacity:1;visibility:visible;transition-delay:0s}.hide{opacity:0;visibility:hidden;transition:opacity .5s ease-in,visibility 0s linear .5s}.hide-on-screen{display:none!important}@media (max-width:768px){.hero h1{font-size:var(--font-size-5xl,3rem)}.no-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.hide-on-mobile{display:none!important}.work-grid,.callouts-grid{grid-template-columns:1fr}h2{font-size:var(--font-size-3xl,2rem)}}figcaption{font-size:var(--font-size-sm,.875rem);color:var(--text-secondary);text-align:center;font-style:italic;line-height:1.4}.arrows{width:60px;height:72px;margin-left:-30px;position:absolute;bottom:20px;left:50%}.arrows path{stroke:#bfe7fa;fill:transparent;stroke-width:1px;animation:2s infinite arrow}@keyframes arrow{0%{opacity:0}40%{opacity:1}80%{opacity:0}to{opacity:0}}.arrows path.a1{animation-delay:-1s}.arrows path.a2{animation-delay:-.5s}.arrows path.a3{animation-delay:0s}.pirata-one-regular{font-family:Pirata One,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue;font-style:normal;font-weight:400}.inter-400{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:400}.inter-500{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:500}.inter-600{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:600}.inter-700{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:700}.inter-800{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:800}.inter-900{font-optical-sizing:auto;font-family:Inter,sans-serif;font-style:normal;font-weight:900}.playfair-display-400{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:400}.playfair-display-500{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:500}.playfair-display-600{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:600}.playfair-display-700{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:700}.playfair-display-800{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:800}.playfair-display-900{font-optical-sizing:auto;font-family:Playfair Display,serif;font-style:normal;font-weight:900}h1,.text-h1{color:var(--text-primary);letter-spacing:2px;text-shadow:3px 3px 0 var(--accent-coral);font-family:Pirata One,cursive;font-size:max(2.5rem,min(8vw,5rem));line-height:1.2}.text-display{color:var(--text-primary);letter-spacing:2px;text-shadow:3px 3px 0 var(--accent-coral);font-family:Pirata One,cursive;font-size:max(3rem,min(10vw,6rem));line-height:1.1}.hero h1{font-family:var(--font-family-heading);color:var(--text-primary);text-shadow:3px 3px 0 var(--accent-coral);letter-spacing:2px;margin-bottom:1rem;font-size:6rem;line-height:1.2}h2,.text-h2{color:var(--text-primary);margin-bottom:var(--space-md,1.5rem);font-family:Playfair Display,serif;font-size:max(2rem,min(5vw,3rem));font-weight:700;line-height:1.3}.text-h2.no-underline:after{margin-bottom:var(--space-2xs,.25rem);display:none}h2:after,.text-h2:after{content:"";background:var(--accent-coral);border:3px solid var(--earth-brown);width:100px;height:5px;margin:1rem auto;display:block}h3,.text-h3{color:var(--text-primary);font-family:Playfair Display,serif;font-size:max(1.5rem,min(3vw,2rem));font-weight:600;line-height:1.3}h4,.text-h4{color:var(--text-primary);font-family:Playfair Display,serif;font-size:max(1.25rem,min(2.5vw,1.5rem));font-weight:600;line-height:1.4}h5,.text-h5{color:var(--text-primary);font-family:Inter,sans-serif;font-size:max(1.1rem,min(2vw,1.25rem));font-weight:700;line-height:1.4}h6,.text-h6{color:var(--text-primary);text-transform:uppercase;letter-spacing:.5px;font-family:Inter,sans-serif;font-size:1rem;font-weight:700;line-height:1.4}.text-body-lg{font-size:max(1.1rem,min(1.5vw,1.25rem))!important;line-height:1.7!important}p,.text-body{color:var(--text-primary);padding-bottom:var(--space-xs,.5rem);font-size:max(.95rem,min(1.5vw,1rem));line-height:1.7}p:last-child,.text-body:last-child{margin-bottom:0}.hero p{color:var(--earth-brown);max-width:720px;margin:0 auto;font-size:max(1.1rem,min(2vw,1.25rem))}.card-body p:first-of-type,.card-body .text-body:first-of-type{margin-top:var(--space-md,16px)}.text-body-sm{font-size:max(.85rem,min(1.2vw,.9rem));line-height:1.6}.text-caption{font-size:clamp(var(--space-sm),1vw,.85rem);color:var(--text-muted);line-height:1.5}.text-callout{color:var(--text-primary);margin:var(--space-lg,1.5rem);padding:var(--space-lg,1.5rem);background:var(--earth-sand-light);border-left:var(--border-medium)solid var(--accent-coral);font-size:max(1rem,min(1.5vw,1.1rem));font-weight:600;line-height:1.6}code,.code{font-family:var(--font-family-mono);font-size:max(.85rem,min(1vw,.9rem))}code.code-inline,.code.code-inline{background:var(--earth-sand);border-radius:var(--radius-sm);padding:.1rem .3rem}.code-block{background:var(--earth-sand);border-radius:var(--radius-md);border:var(--border-thin)solid var(--earth-sage);padding:1rem;font-size:max(.85rem,min(1vw,.9rem));display:block;overflow-x:auto}.text-muted{color:var(--text-muted)}.text-secondary{color:var(--text-secondary)}.text-accent{color:var(--accent-coral)}.text-semibold{font-weight:600}.text-bold{font-weight:700}.text-center{text-align:center}.lead,.text-lead{color:var(--text-secondary);font-size:max(1.1rem,min(2vw,1.35rem));line-height:1.7}a,.link{color:var(--earth-sage);border-bottom:1px solid var(--earth-sage);font-weight:var(--font-weight-semibold,600);text-decoration:none;transition:all .2s}a:hover,a:focus,.link:hover,.link:focus{color:var(--earth-brown);border-bottom-color:var(--earth-brown)}.link-brackets{margin-left:var(--space-md)!important}.link-brackets:after{content:"]";color:var(--earth-sage);margin-left:.2rem;transition:all .2s;position:absolute}.link-brackets:before{content:"[";color:var(--earth-sage);margin-left:-.8rem;transition:all .2s;position:absolute}.link-brackets:hover:after,.link-brackets:hover:before,.link-brackets:focus:after,.link-brackets:focus:before{color:var(--accent-coral)}blockquote,.blockquote{border-left:var(--border-thin)solid var(--earth-brown);padding-left:var(--space-md,1rem);margin:var(--space-lg,1.5rem)0;color:var(--text-secondary);font-style:italic}.mb-1{margin-bottom:var(--space-2xs)!important}.mb-2{margin-bottom:var(--space-xs)!important}.mb-3{margin-bottom:var(--space-sm)!important}.mb-4{margin-bottom:var(--space-md)!important}.mb-5{margin-bottom:var(--space-xl)!important}.mt-1{margin-top:var(--space-2xs)!important}.mt-2{margin-top:var(--space-xs)!important}.mt-3{margin-top:var(--space-sm)!important}.mt-4{margin-top:var(--space-md)!important}.mt-5{margin-top:var(--space-xl)!important}.ml-1{margin-left:var(--space-2xs)!important}.ml-2{margin-left:var(--space-xs)!important}.ml-3{margin-left:var(--space-sm)!important}.ml-4{margin-left:var(--space-md)!important}.ml-5{margin-left:var(--space-xl)!important}.mr-1{margin-right:var(--space-2xs)!important}.mr-2{margin-right:var(--space-xs)!important}.mr-3{margin-right:var(--space-sm)!important}.mr-4{margin-right:var(--space-md)!important}.mr-5{margin-right:var(--space-xl)!important}.p-1{padding:var(--space-2xs)!important}.p-2{padding:var(--space-xs)!important}.p-3{padding:var(--space-sm)!important}.p-4{padding:var(--space-md)!important}.p-5{padding:var(--space-xl)!important}.pt-1{padding-top:var(--space-2xs)!important}.pt-2{padding-top:var(--space-xs)!important}.pt-3{padding-top:var(--space-sm)!important}.pt-4{padding-top:var(--space-md)!important}.pt-5{padding-top:var(--space-xl)!important}.pb-1{padding-bottom:var(--space-2xs)!important}.pb-2{padding-bottom:var(--space-xs)!important}.pb-3{padding-bottom:var(--space-sm)!important}.pb-4{padding-bottom:var(--space-md)!important}.pb-5{padding-bottom:var(--space-xl)!important}.pl-1{padding-left:var(--space-2xs)!important}.pl-2{padding-left:var(--space-xs)!important}.pl-3{padding-left:var(--space-sm)!important}.pl-4{padding-left:var(--space-md)!important}.pl-5{padding-left:var(--space-xl)!important}.pr-1{padding-right:var(--space-2xs)!important}.pr-2{padding-right:var(--space-xs)!important}.pr-3{padding-right:var(--space-sm)!important}.pr-4{padding-right:var(--space-md)!important}.pr-5{padding-right:var(--space-xl)!important}section{max-width:1200px;padding:var(--space-3xl,6rem)var(--space-lg,2rem);margin:0 auto}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.row{gap:var(--space-lg,2rem);-ms-flex-wrap:wrap;flex-wrap:wrap;display:-ms-flexbox;display:flex}@media (min-width:768px){.row{gap:var(--space-xs,.5rem)}.card-body .row{gap:0}}.button-row{gap:1rem}.no-wrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.d-flex{display:-ms-flexbox;display:flex}.flex-column{-ms-flex-direction:column;flex-direction:column}.align-items-center{-ms-flex-align:center;align-items:center}.work-grid{gap:var(--space-lg,2rem);margin-bottom:var(--space-lg,2rem);grid-template-columns:repeat(auto-fit,minmax(300px,1fr));display:grid}.divider{width:50%;height:var(--space-md,1.5rem);background:var(--accent-coral);border:var(--border-medium,4px)outset var(--earth-dark);margin:0 auto;display:block}.divider.vertical{width:var(--space-2xs,.25rem);background:var(--earth-dark);border-radius:var(--radius-sm);height:100%;margin:0;border:none!important}ul,ol,.card-body ul,.card-body ol,ul.list,ol.list{margin-left:var(--space-lg)!important;padding-left:var(--space-md)!important}.highlight-block{-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.header-highlight{text-align:center;margin:var(--space-md)auto;padding:var(--space-md);width:100%}nav{z-index:1000;backdrop-filter:blur(24px);filter:url(#lensFilter)saturate(120%)brightness(1.15);border:var(--border-medium,4px)solid var(--earth-brown);padding:var(--space-sm)2rem;box-shadow:0 8px 24px var(--shadow-heavy);background:rgba(245,241,232,.5);border-radius:50px;position:fixed;top:2rem;left:50%;transform:translate(-50%)}.main-nav{width:fit-content;margin:0 auto;position:sticky;top:2rem;left:0;right:0;transform:none!important}nav ul{-ms-flex-pack:center;justify-content:center;gap:2rem;list-style:none;display:-ms-flexbox;display:flex;margin-left:0!important;padding-left:0!important}nav a{color:var(--text-primary);padding:var(--space-2xs)var(--space-xs,.5rem);border-bottom:none;font-size:.95rem;font-weight:500;text-decoration:none;transition:color .3s}nav a:hover,nav a:focus{color:var(--accent-coral);outline:var(--border-thin)solid var(--accent-coral);outline-offset:2px}nav a.active{color:var(--accent-coral)}nav a.sub-page{outline:var(--border-thin)solid var(--text-secondary);outline-offset:2px}nav a.sub-page:hover{outline-color:var(--accent-coral)}@media (max-width:768px){nav{top:var(--space-sm,1rem)!important;padding:var(--space-xs,.5rem)var(--space-sm,1rem)!important;margin:0 auto!important}nav ul{gap:var(--space-sm,1rem)}}footer{background:var(--earth-dark);color:var(--earth-cream);padding:var(--space-2xl,3rem)var(--space-xl,2rem);margin-top:var(--space-3xl,6rem);border-top:var(--border-extra-thick,8px)solid var(--earth-brown);box-shadow:0 -10px 30px var(--shadow)}.footer-content{grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:3rem;max-width:1200px;margin:0 auto;display:grid}.footer-section h3{color:var(--accent-coral);margin-bottom:var(--space-md,1rem);font-family:Playfair Display,serif;font-size:max(1.2rem,min(2vw,1.5rem))}.footer-section h4{margin-bottom:var(--space-md,1rem);font-family:Playfair Display,serif;font-size:max(1.1rem,min(1.25vw,1.125rem));color:rgba(255,255,255,.5)!important}.footer-section p,.footer-section li{color:var(--earth-cream);margin-bottom:var(--space-xs,.5rem);line-height:1.6}.footer-section ul{padding:0;list-style:none}.footer-section li{margin-bottom:var(--space-xs,.5rem)}.footer-bottom{text-align:center;margin-top:var(--space-2xl,3rem);padding-top:var(--space-xl,2rem);border-top:var(--border-medium,4px)solid var(--earth-brown);color:var(--earth-sand)}.footer-bottom p{font-size:var(--font-size-sm);color:var(--earth-cream);margin:0}.footer-section a,.footer-bottom a{color:var(--earth-cream);text-decoration:underline}.footer-section a:hover,.footer-bottom a:hover{color:var(--accent-coral)}.badge{padding:var(--space-2xs,.25rem)var(--space-sm,.75rem);background:var(--earth-sage);color:var(--earth-cream);border:var(--border-thin,2px)solid var(--earth-brown);border-radius:var(--radius-pill);font-size:.85rem;font-weight:600;display:inline-block}.badge-accent{background:var(--accent-coral-dark)}.badge-outline{color:inherit;background:0 0}.badges,.row-badges{gap:var(--space-2xs,.25rem);-ms-flex-wrap:wrap;flex-wrap:wrap;display:-ms-flexbox;display:flex}.btn{padding:var(--space-sm,.75rem)var(--space-lg,1.5rem);font-family:var(--font-family-sans);font-size:var(--font-size-md,1rem);border-radius:var(--radius-md,12px);cursor:pointer;text-align:center;border:none;font-weight:600;text-decoration:none;transition:all .2s;display:inline-block}.btn:hover,.btn:focus{box-shadow:2px 2px 0 var(--earth-brown);transform:translate(2px,2px)}.btn-primary{background:var(--accent-coral-dark);color:var(--white);border:var(--border-medium,4px)solid var(--earth-brown);box-shadow:4px 4px 0 var(--earth-brown)}.btn-primary:hover,.btn-primary:focus{background:var(--accent-coral-dark);color:var(--white)}.btn-secondary{background:var(--earth-cream);color:var(--text-primary);border:var(--border-medium,4px)solid var(--earth-brown);box-shadow:4px 4px 0 var(--earth-sage)}.btn-secondary:hover,.btn-secondary:focus{background:var(--earth-sand);color:var(--text-primary);box-shadow:2px 2px 0 var(--earth-sage);outline:var(--border-thin)solid var(--earth-dark);transform:translate(2px,2px)}.btn-outline{backdrop-filter:blur(24px);filter:url(#lensFilter)saturate(120%)brightness(1.15);color:var(--text-primary)!important;border:var(--border-medium,4px)solid var(--earth-brown)!important;box-shadow:none!important;background:rgba(255,255,255,.5)!important}.btn-outline:hover,.btn-outline:focus{color:var(--earth-cream);text-decoration:underline}.btn-sm{padding:var(--space-xs,.5rem)var(--space-md,1rem)!important;border-width:var(--border-thin)!important;font-size:.9rem!important}.btn-lg{padding:var(--space-md,1rem)var(--space-xl,2rem)!important;font-size:1.1rem!important}.skip-link{background:var(--accent-coral);color:var(--white);padding:var(--space-sm,.75rem)var(--space-lg,1.5rem);border:var(--border-medium,4px)solid var(--earth-brown);z-index:2000;clip:rect(0,0,0,0);font-weight:600;text-decoration:none;position:absolute;top:-100px;left:0;overflow:hidden}.skip-link:focus{clip:auto;top:1rem;left:1rem;overflow:visible}.social-links{-ms-flex-wrap:wrap;flex-wrap:wrap;gap:1rem;display:-ms-flexbox;display:flex}.social-link{padding:var(--space-xs,.5rem)var(--space-md,1rem);background:var(--earth-sage);color:var(--white);border:var(--border-medium,4px)solid var(--earth-sand);border-radius:8px;font-size:.95rem;font-weight:500;transition:all .3s;display:inline-block;text-decoration:none!important}.social-link:hover,.social-link:focus{background:var(--accent-coral);transform:translateY(-2px);color:var(--white)!important}.card{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--earth-brown);border-radius:var(--radius-xl,20px);padding:var(--space-lg,1.5rem);box-shadow:8px 8px 0 var(--shadow-heavy);transition:transform .3s,box-shadow .3s}.card:hover{box-shadow:12px 12px 0 var(--shadow-heavy);transform:translateY(-5px)}.card:focus-within{box-shadow:12px 12px 0 var(--shadow-heavy);transform:translateY(-5px)}.card-layered{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--earth-brown);border-radius:var(--radius-xl,20px);padding:var(--space-xl,2rem);box-shadow:12px 12px 0 var(--earth-sage),12px 12px 0 5px var(--earth-brown)}.card-shadow{background:var(--earth-cream);border-radius:var(--radius-lg,16px);padding:var(--space-md,1.5rem);box-shadow:10px 10px 0 var(--shadow-heavy);border:none}.card-accent{background:var(--earth-cream);border:var(--border-extra-thick,8px)solid var(--earth-brown);border-radius:var(--radius-xl,20px);box-shadow:16px 16px 0 var(--accent-coral),16px 16px 0 6px var(--earth-brown);overflow:hidden}.card-flex{-ms-flex-direction:column;flex-direction:column;display:-ms-flexbox;display:flex}.card-flex p{-ms-flex:1 0;flex:1 0}.card-with-columns .row{-ms-flex-align:start;align-items:flex-start;gap:var(--space-md,1rem);-ms-flex-item-align:stretch;align-self:stretch;display:-ms-flexbox;display:flex}.card-with-columns .column{-ms-flex:1 0 0;flex:1 0 0;-ms-flex-item-align:stretch;align-self:stretch;-ms-flex-align:start;align-items:flex-start;display:-ms-flexbox;display:flex}.card-header{margin-bottom:var(--space-md,1rem);padding-bottom:var(--space-md,1rem);border-bottom:var(--border-thin,2px)solid var(--earth-sand)}.card-body{margin-bottom:var(--space-md)}.card-body img{object-fit:cover;width:100%}@media (min-width:768px){.img-thumbnail{max-width:50%}}.card-body:last-child{margin-bottom:0}.card-footer{margin-top:var(--space-md,1rem);padding-top:var(--space-md,1rem);border-top:var(--border-thin,2px)solid var(--earth-sand)}.showcase-content{padding:var(--space-lg,2rem)}.showcase-content h3{font-family:var(--font-family-serif);color:var(--text-primary);margin-bottom:var(--space-sm,1rem);font-size:max(1.3rem,min(2.5vw,1.8rem))}.showcase-content p{color:var(--text-secondary);margin-bottom:var(--space-md,1.5rem);font-size:max(.95rem,min(1.5vw,1rem))}.showcase-small{background:var(--earth-sand);border:4px solid var(--earth-brown);border-radius:var(--radius-lg,16px);padding:var(--space-md,1.5rem);box-shadow:6px 6px 0 var(--shadow-heavy);transition:transform .3s}.showcase-small:hover{transform:translateY(-4px)}.showcase-small:focus-within{transform:translateY(-4px)}.showcase-small h4{font-family:var(--font-family-serif);color:var(--text-primary);margin-bottom:var(--space-xs,.5rem);font-size:max(1.1rem,min(2vw,1.3rem))}.showcase-small p{color:var(--text-secondary);font-size:max(.9rem,min(1.5vw,.95rem))}.about-card{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--earth-brown);padding:var(--space-2xl,3rem);border-radius:var(--border-radius-xl,20px);box-shadow:12px 12px 0 var(--earth-sage),12px 12px 0 5px var(--earth-brown);margin:0 auto}@media (max-width:768px){.about-card{box-shadow:6px 6px 0 var(--earth-sage),6px 6px 0 4px var(--earth-brown);padding:var(--space-md,1rem)}.about-grid{grid-template-columns:1fr!important}}.about-card p{color:var(--text-primary);margin-bottom:var(--space-lg,1.5rem);font-size:max(1rem,min(1.5vw,1.1rem));line-height:1.8}.about-card p:last-child{margin-bottom:0}.about-grid{gap:var(--space-xl,2rem);margin-top:var(--space-xl,2rem);grid-template-columns:repeat(auto-fit,minmax(350px,1fr));display:grid}.showcase-large{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--earth-brown);border-radius:var(--radius-xl,20px);box-shadow:12px 12px 0 var(--accent-coral),12px 12px 0 6px var(--earth-brown);transition:transform .3s;overflow:hidden}@media (max-width:768px){.showcase-large{box-shadow:6px 6px 0 var(--accent-coral),6px 6px 0 4px var(--earth-brown)}}.showcase-large:hover{transform:translateY(-8px)}.showcase-large:focus-within{transform:translateY(-8px)}.showcase-image{background:linear-gradient(135deg,var(--earth-sage)0%,var(--earth-sand)100%);width:100%;height:300px;padding:var(--space-md,1rem);font-size:var(--font-size-5xl,3rem);color:var(--earth-cream);border-bottom:var(--border-thick,6px)solid var(--earth-brown);object-fit:contain;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.showcase-image-dark{background:linear-gradient(135deg,var(--black)0%,var(--earth-dark)100%)}.small-showcase-cards{gap:var(--space-md,1.5rem);margin-top:var(--space-sm,1rem);grid-column:1/-1;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));display:grid}.callouts-grid{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:2rem;margin-top:2rem;display:grid}.callout{background:var(--earth-cream);border:var(--border-thick,6px)solid var(--accent-coral-dark);border-radius:var(--radius-xl,20px);box-shadow:8px 8px 0 var(--shadow-heavy);-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:end;align-items:flex-end;padding:2rem;transition:transform .3s,box-shadow .3s;display:-ms-flexbox;display:flex;position:relative}.callout:hover{box-shadow:12px 12px 0 var(--shadow-heavy);transform:translateY(-5px)}.callout:focus-within{box-shadow:12px 12px 0 var(--shadow-heavy);transform:translateY(-5px)}.callout:before{content:"\"";font-family:var(--font-family-serif);font-size:var(--font-size-6xl,4rem);color:var(--accent-coral);line-height:1;position:absolute;top:10px;left:20px}.callout-text{margin-bottom:var(--space-md,1.5rem);padding-top:var(--space-sm,1rem);color:var(--text-primary);font-style:italic}.callout-author{color:var(--text-primary);font-weight:600;display:block}.callout-role{font-size:var(--font-size-sm,.9rem);color:var(--text-secondary)}.gallery{--size:100px;grid-template-columns:repeat(6,var(--size));grid-auto-rows:var(--size);margin-bottom:var(--size);-ms-flex-align:start;align-items:start;justify-items:center;gap:5px;display:grid}.gallery:has(:hover) picture:not(:hover){filter:brightness(.5)contrast(.5)}.gallery:has(:focus) picture:not(:focus){filter:brightness(.5)contrast(.5)}.gallery picture{object-fit:cover;width:calc(var(--size)*2);height:calc(var(--size)*2);clip-path:path("M90,10 C100,0 100,0 110,10 190,90 190,90 190,90 200,100 200,100 190,110 190,110 110,190 110,190 100,200 100,200 90,190 90,190 10,110 10,110 0,100 0,100 10,90Z");border-radius:5px;grid-column:auto/span 2;transition:clip-path .25s,filter .75s}.gallery picture:nth-child(5n-1){grid-column:2/span 2}.gallery picture:hover,.gallery picture:focus{clip-path:path("M0,0 C0,0 200,0 200,0 200,0 200,100 200,100 200,100 200,200 200,200 200,200 100,200 100,200 100,200 100,200 0,200 0,200 0,100 0,100 0,100 0,100 0,100Z");z-index:1;transition:clip-path .25s,filter .25s}.gallery picture:focus{outline-offset:-5px;outline:1px dashed #000}.carousel>input{clip:rect(1px,1px,1px,1px);clip-path:inset(50%);width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.carousel>input:nth-of-type(15):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1400%}.carousel>input:nth-of-type(14):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1300%}.carousel>input:nth-of-type(13):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1200%}.carousel>input:nth-of-type(12):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1100%}.carousel>input:nth-of-type(11):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-1000%}.carousel>input:nth-of-type(10):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-900%}.carousel>input:nth-of-type(9):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-800%}.carousel>input:nth-of-type(8):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-700%}.carousel>input:nth-of-type(7):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-600%}.carousel>input:nth-of-type(6):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-500%}.carousel>input:nth-of-type(5):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-400%}.carousel>input:nth-of-type(4):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-300%}.carousel>input:nth-of-type(3):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-200%}.carousel>input:nth-of-type(2):checked~.carousel__slides .carousel__slide:first-of-type{margin-left:-100%}.carousel>input:first-of-type:checked~.carousel__slides .carousel__slide:first-of-type{margin-left:0%}.carousel>input:first-of-type:checked~.carousel__thumbnails li:first-of-type,.carousel>input:nth-of-type(2):checked~.carousel__thumbnails li:nth-of-type(2),.carousel>input:nth-of-type(3):checked~.carousel__thumbnails li:nth-of-type(3),.carousel>input:nth-of-type(4):checked~.carousel__thumbnails li:nth-of-type(4),.carousel>input:nth-of-type(5):checked~.carousel__thumbnails li:nth-of-type(5),.carousel>input:nth-of-type(6):checked~.carousel__thumbnails li:nth-of-type(6),.carousel>input:nth-of-type(7):checked~.carousel__thumbnails li:nth-of-type(7),.carousel>input:nth-of-type(8):checked~.carousel__thumbnails li:nth-of-type(8),.carousel>input:nth-of-type(9):checked~.carousel__thumbnails li:nth-of-type(9),.carousel>input:nth-of-type(10):checked~.carousel__thumbnails li:nth-of-type(10),.carousel>input:nth-of-type(11):checked~.carousel__thumbnails li:nth-of-type(11),.carousel>input:nth-of-type(12):checked~.carousel__thumbnails li:nth-of-type(12),.carousel>input:nth-of-type(13):checked~.carousel__thumbnails li:nth-of-type(13),.carousel>input:nth-of-type(14):checked~.carousel__thumbnails li:nth-of-type(14),.carousel>input:nth-of-type(15):checked~.carousel__thumbnails li:nth-of-type(15){box-shadow:0 0 0 5px rgba(0,0,255,.5)}.carousel__slides{z-index:1;white-space:nowrap;box-sizing:border-box;margin:0;padding:0;display:-ms-flexbox;display:flex;position:relative;overflow:hidden}.carousel__slide{vertical-align:top;box-sizing:border-box;white-space:normal;-ms-flex:1 0 100%;flex:1 0 100%;width:100%;height:100%;transition:all .3s ease-out;display:block;position:relative;overflow:hidden}.carousel__slide figure{margin:0;display:-ms-flexbox;display:flex}.carousel__slide div{width:100%;position:relative}.carousel__slide div:before{content:"";width:100%;padding-top:66.6667%;display:block}.carousel__slide div>img{width:100%;height:100%;position:absolute;top:0;bottom:0;left:0;right:0}.carousel__slide img{object-fit:cover;-ms-flex:auto;flex:auto;display:block}.carousel__slide figcaption{-ms-flex:none;flex:none;-ms-flex-item-align:end;align-self:flex-end;width:25%;min-width:150px;padding:20px 20px 0}.carousel__slide .credit{color:rgba(0,0,0,.5);margin-top:1rem;display:block}.carousel__slide.scrollable{overflow-y:scroll}.carousel__thumbnails{margin:0 -10px;padding:0;list-style:none;display:-ms-flexbox;display:flex}.carousel__slides+.carousel__thumbnails{margin-top:20px}.carousel__thumbnails li{-ms-flex:auto;flex:auto;max-width:calc(16.6667% - 20px);margin:0 10px;transition:all .3s ease-in-out}.carousel__thumbnails label{display:block;position:relative}.carousel__thumbnails label:before{content:"";width:100%;padding-top:100%;display:block}.carousel__thumbnails label>img{width:100%;height:100%;position:absolute;top:0;bottom:0;left:0;right:0}.carousel__thumbnails label:hover,.carousel__thumbnails label:focus{cursor:pointer}.carousel__thumbnails label:hover img,.carousel__thumbnails label:focus img{transition:all .3s ease-in-out;box-shadow:0 0 0 1px rgba(0,0,0,.25)}.carousel__thumbnails img{object-fit:cover;width:100%;height:100%;display:block}
\ No newline at end of file
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index a1f53b32..641c095b 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -121,11 +121,6 @@
2025-12-05T21:31:27.629Z
-
- https://www.adamjolicoeur.com/
- 2025-12-13T13:50:01.052Z
-
-
https://www.adamjolicoeur.com/designs/alm/
2026-01-01T16:25:50.000Z
@@ -153,7 +148,22 @@
https://www.adamjolicoeur.com/portfolio/
- 2026-01-01T16:25:50.000Z
+ 2026-01-02T02:38:29.000Z
+
+
+
+ https://www.adamjolicoeur.com/
+ 2026-01-05T16:14:23.050Z
+
+
+
+ https://www.adamjolicoeur.com/apps/taskstat-privacy.html
+ 2026-01-05T17:33:31.659Z
+
+
+
+ https://www.adamjolicoeur.com/apps/taskstat.html
+ 2026-01-05T17:33:31.659Z
diff --git a/src/_includes/markdown.njk b/src/_includes/markdown.njk
index 8d1abe4a..f62a50c8 100644
--- a/src/_includes/markdown.njk
+++ b/src/_includes/markdown.njk
@@ -2,13 +2,12 @@
layout: base.njk
---
-
+
+
{{ title }}
-
- {{ description }}
-
+ {{ description }}
{%- if (headerButton) -%}
{{ primaryAction }}
{%- else -%}{%- endif -%}
@@ -19,5 +18,7 @@ layout: base.njk
{{ content | safe }}
{% else %}
- {{ content | safe }}
+
{% endif %}
diff --git a/src/pages/apps/taskstat-privacy.md b/src/pages/apps/taskstat-privacy.md
new file mode 100644
index 00000000..e4731336
--- /dev/null
+++ b/src/pages/apps/taskstat-privacy.md
@@ -0,0 +1,307 @@
+---
+layout: 'markdown'
+permalink: 'apps/taskstat-privacy.html'
+title: 'TaskStat Privacy Policy'
+date: git Last Modified
+abbreviation: 'taskstat-privacy'
+description: 'Privacy policy for TaskStat - a privacy-first task management app for iOS'
+eleventyNavigation:
+ key: TaskStat Privacy
+ parent: Apps
+ order: 20
+---
+
+
+
+**Last Updated:** January 5, 2026
+**Effective Date:** January 5, 2026
+
+## Our Privacy Commitment
+
+TaskStat is built with privacy as a core principle. We believe your task data is yours alone, and we've designed TaskStat to ensure your information stays completely private and under your control.
+
+**The short version:** We don't collect, transmit, or store any of your data on our servers. Everything stays on your device.
+
+## Information Collection and Use
+
+### What We DON'T Collect
+
+TaskStat does **NOT** collect, transmit, or have access to:
+
+- ❌ Your task data
+- ❌ Your personal information
+- ❌ Your usage patterns or analytics
+- ❌ Your device identifiers
+- ❌ Your location data
+- ❌ Your contacts or calendar information
+- ❌ Any tracking or advertising identifiers
+- ❌ Crash reports or diagnostic data (beyond iOS system-level reporting)
+
+### What IS Stored on Your Device
+
+TaskStat stores the following information **locally on your device only**:
+
+#### Task Data (SwiftData/SQLite)
+
+- Task titles
+- Task descriptions and notes
+- Status, priority, and type classifications
+- Project assignments
+- Assignee names (if you enter them)
+- Creation dates
+- Completion status
+
+#### App Preferences (UserDefaults)
+
+- Your default filter settings (status, priority, project)
+- Your default grouping preferences
+- Your default values for new tasks
+- UI customization preferences
+
+**Important:** All of this data is stored exclusively in your device's local storage using Apple's SwiftData framework. It is never transmitted to our servers or any third-party services.
+
+## Data Storage Location
+
+### Local Storage Only
+
+TaskStat uses **local-only storage** via SwiftData (Apple's native persistence framework). Your data is stored in a SQLite database within the app's sandboxed container on your device.
+
+### No Cloud Synchronization
+
+TaskStat **intentionally does not use:**
+
+- iCloud sync
+- CloudKit
+- Any proprietary cloud services
+- Any third-party cloud storage
+
+This design choice ensures your task data never leaves your device unless you explicitly export it.
+
+### What Happens to Your Data
+
+- **When you use the app:** Data is read from and written to local storage only
+- **When you close the app:** Data persists in local storage
+- **When you delete the app:** All app data is permanently deleted from your device
+- **When you upgrade iOS:** Data remains in local storage (standard iOS behavior)
+
+## Data Sharing and Export
+
+### User-Controlled Export Only
+
+TaskStat includes a CSV export feature that allows you to export your task list. This is **entirely under your control**:
+
+- ✅ **You initiate the export** by tapping the export button
+- ✅ **You choose where to share** using iOS's native share sheet
+- ✅ **You control the recipients** (email, files, cloud storage, etc.)
+- ✅ **We never receive the exported file**
+
+### What's in an Export
+
+When you export your tasks to CSV, the file contains:
+
+- Task State
+- Task Title
+- Task Type
+- Task Status
+- Assignee
+- Priority
+- Project
+- Notes
+- Entry Date
+
+**Important:** Once you share an exported CSV file via email, cloud storage, or messaging apps, that data is subject to the privacy policies of those services. We recommend being mindful of what you share and with whom.
+
+## Third-Party Services
+
+TaskStat does **NOT** integrate with any third-party services, including:
+
+- ❌ Analytics platforms (Google Analytics, Firebase Analytics, Amplitude, etc.)
+- ❌ Crash reporting services (Crashlytics, Sentry, Bugsnag, etc.)
+- ❌ Advertising networks
+- ❌ Social media platforms
+- ❌ Cloud storage providers
+- ❌ Backend-as-a-service platforms
+
+The only external code included in TaskStat consists of:
+
+- Apple's native iOS frameworks (SwiftUI, SwiftData, Foundation, UIKit)
+
+## Network Activity
+
+### Zero Network Requests
+
+TaskStat makes **zero network requests**. The app:
+
+- ❌ Does not connect to any servers
+- ❌ Does not send any data over the internet
+- ❌ Does not require an internet connection to function
+- ❌ Does not check for updates (uses App Store's standard update mechanism)
+
+You can use TaskStat in airplane mode, offline, or with network access completely disabled.
+
+## Data Security
+
+### How We Protect Your Data
+
+Since all data is stored locally on your device:
+
+1. **iOS Security Model:** Your data benefits from iOS's robust security architecture, including:
+
+ - App sandboxing (TaskStat cannot access other apps' data)
+ - Encryption at rest (if you enable device encryption)
+ - Secure enclave protection (on supported devices)
+
+2. **No Transmission Risk:** Since data never leaves your device, there's no risk of interception during transmission
+
+3. **No Server Breaches:** We don't have servers, so there's no risk of server-side data breaches
+
+4. **No Password Storage:** TaskStat doesn't require an account, so there are no passwords to compromise
+
+### Your Responsibility
+
+To keep your task data secure:
+
+- ✅ Use a device passcode or biometric authentication
+- ✅ Keep your device's operating system updated
+- ✅ Be mindful when exporting and sharing CSV files
+- ✅ Only install TaskStat from the official Apple App Store
+
+## Children's Privacy
+
+TaskStat does not collect any personal information from anyone, including children under 13. Since all data stays on the device and we have no servers or data collection mechanisms, TaskStat is safe for users of all ages.
+
+Parents should be aware that:
+
+- The app stores task information locally on the device
+- Users can enter any text content into tasks
+- CSV exports could be shared if the device is not properly secured
+
+## Your Privacy Rights
+
+### Complete Data Ownership
+
+You have complete ownership and control over your data:
+
+- ✅ **Access:** You can view all your data within the app at any time
+- ✅ **Export:** You can export all your data to CSV format
+- ✅ **Delete:** You can delete individual tasks, projects, or all data
+- ✅ **Modify:** You can edit any task information at any time
+
+### How to Exercise Your Rights
+
+- **To access your data:** Open TaskStat—all your data is visible
+- **To export your data:** Use the CSV export feature in the task list
+- **To delete specific data:** Swipe to delete tasks or projects, or use multi-select
+- **To delete all data:** Delete the TaskStat app from your device
+
+### No Data Requests Needed
+
+Since we don't collect or store your data on our servers, you don't need to submit data access or deletion requests to us. You have direct, immediate control over all your information.
+
+## Changes to Data Practices
+
+### Current Status
+
+As of January 2026, TaskStat:
+
+- ✅ Does not collect any user data
+- ✅ Uses local-only storage
+- ✅ Makes zero network requests
+- ✅ Includes no third-party services
+
+### If This Changes
+
+We are committed to maintaining TaskStat's privacy-first design. However, if we ever:
+
+- Add cloud synchronization features
+- Integrate third-party services
+- Implement analytics or crash reporting
+- Change our data collection practices
+
+We will:
+
+1. **Update this privacy policy** with clear explanations
+2. **Make these features opt-in** (not mandatory)
+3. **Notify users** through App Store update notes
+
+Any changes to this privacy policy will be posted to this page and reflected in the app's version history.
+
+## Legal Compliance
+
+### Regulatory Compliance
+
+TaskStat's privacy-first design ensures compliance with major privacy regulations:
+
+- **GDPR (General Data Protection Regulation):** We don't collect personal data, so GDPR's data protection requirements don't apply
+- **CCPA (California Consumer Privacy Act):** We don't sell or share personal information
+- **COPPA (Children's Online Privacy Protection Act):** We don't collect information from children
+- **Apple App Store Privacy Requirements:** We accurately disclose that we collect zero data
+
+### App Store Privacy Nutrition Label
+
+In accordance with Apple's App Privacy details requirements, TaskStat's privacy label states:
+
+- **Data Used to Track You:** None
+- **Data Linked to You:** None
+- **Data Not Linked to You:** None
+
+This accurately reflects that TaskStat collects no data.
+
+## Open Source and Transparency
+
+### Code Transparency
+
+While TaskStat is not currently open source, we are committed to transparency about our privacy practices:
+
+- This privacy policy accurately reflects our app's behavior
+- You can verify our claims using network monitoring tools
+- We welcome security researchers to audit our app's data practices
+
+### Verification
+
+If you're technically inclined, you can verify our privacy claims by:
+
+1. Using network monitoring tools (Charles Proxy, Wireshark, etc.) to confirm zero network traffic
+2. Reviewing the app's storage using iOS system tools
+3. Examining iOS privacy permissions (TaskStat requests none)
+
+## Contact Information
+
+### Questions or Concerns
+
+If you have questions about this privacy policy or TaskStat's data practices:
+
+- **Email:** [support@adamjolicoeur.com](mailto:support@adamjolicoeur.com)
+- **Website:** [adamjolicoeur.com](https://www.adamjolicoeur.com/apps/taskstat)
+- **App Store:** Leave a review or question on the TaskStat App Store page
+
+### Data Breach Notification
+
+Since TaskStat doesn't collect or store data on our servers, we cannot experience a data breach of user information. Any data security is determined by your device's security posture.
+
+## International Users
+
+TaskStat is available worldwide. Since all data is stored locally on your device and never transmitted to our servers, there are no cross-border data transfer concerns. Your data never leaves your device unless you explicitly export and share it.
+
+## Summary
+
+**In Plain English:**
+
+1. ✅ TaskStat stores your tasks only on your device
+2. ✅ We never see, collect, or transmit your data
+3. ✅ No internet connection is required
+4. ✅ No account or registration needed
+5. ✅ Export features are entirely under your control
+6. ✅ Delete the app = delete your data permanently
+7. ✅ No tracking, analytics, or third-party services
+
+TaskStat is designed to be the most private task manager possible. Your data is yours, and only yours.
+
+## Acknowledgment
+
+By using TaskStat, you acknowledge that you have read and understood this privacy policy. Given that we don't collect any data, your use of the app does not involve sharing personal information with us.
+
+**TaskStat Privacy Policy Version 1.0**
+_Simple tasks. Complete privacy._
+
+
diff --git a/src/pages/apps/taskstat.md b/src/pages/apps/taskstat.md
new file mode 100644
index 00000000..fdb99b68
--- /dev/null
+++ b/src/pages/apps/taskstat.md
@@ -0,0 +1,100 @@
+---
+layout: "markdown"
+permalink: "apps/{{ abbreviation | slugify }}.html"
+title: "TaskStat"
+date: git Last Modified
+abbreviation: "taskstat"
+description: "Privacy-first task management for iOS. Your tasks stay on your device—no accounts, no tracking, no cloud sync."
+eleventyNavigation:
+ key: TaskStat
+ parent: Apps
+ order: 8
+---
+
+
+
+## About TaskStat
+
+TaskStat is a native iOS task management app built with privacy as a core principle. Unlike cloud-based task managers, TaskStat stores all your data locally on your device using SwiftData—ensuring complete privacy and offline functionality.
+
+### Key Features
+
+- **Complete Privacy** - 100% local storage, zero data collection
+- **Smart Organization** - Filter and group tasks by project, status, or priority
+- **Flexible Projects** - Organize tasks into Personal, Work, or custom projects
+- **Rich Task Details** - Track status, priority, type, assignees, and notes
+- **Multi-Select Operations** - Efficiently manage multiple tasks at once
+- **CSV Export** - Export and backup your data anytime
+- **Native iOS Design** - Built with SwiftUI for iOS 18+
+
+### Task Management Essentials
+
+TaskStat provides comprehensive task tracking with:
+
+- **Task States:** Open, Closed, or Archived
+- **Status Levels:** To Do, In Progress, Completed, or Blocked
+- **Priority Flags:** None, Low, Medium, High, or Urgent
+- **Task Types:** Personal, Work, Other, or Misc
+- **Assignee Tracking:** Assign tasks to team members or yourself
+- **Detailed Notes:** Add context and details to any task
+
+### Privacy-First Design
+
+- ✅ All data stored locally on your device
+- ✅ No account creation or sign-in required
+- ✅ No data collection or analytics
+- ✅ No third-party services or tracking
+- ✅ Works completely offline
+- ✅ No cloud sync means no sync conflicts or data loss
+
+Read the full [Privacy Policy](/apps/taskstat-privacy.html)
+
+## Screenshots
+
+*Coming soon - Screenshots will be added once the app is published to the App Store*
+
+
+
+## App Icon
+
+*Coming soon - App icons will be added once finalized*
+
+
+
+## Download
+
+**Platform:** iOS 18.0 or later
+
+**App Store:** *Coming soon - Link will be added when published*
+
+
+## Requirements
+
+- iPhone running iOS 18 or later
+- No internet connection required
+- No account or registration needed
+
+## Support
+
+**Questions or issues?**
+
+- **Email:** [support@adamjolicoeur.com](mailto:support@adamjolicoeur.com)
+- **Privacy Policy:** [View Privacy Policy](/apps/taskstat-privacy.html)
+
+## Technical Details
+
+TaskStat is built using:
+- **SwiftUI** for native iOS interface
+- **SwiftData** for local persistence
+- **No third-party dependencies**
+
+TaskStat: Simple tasks. Complete privacy.
+
+
diff --git a/src/sass/_markdown.scss b/src/sass/_markdown.scss
deleted file mode 100644
index 632f6c83..00000000
--- a/src/sass/_markdown.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-pre {
- background-color: var(--earth-cream);
- padding: var(--space-md, 1rem);
- border-radius: var(--radius-md, 12px);
-}
diff --git a/src/sass/markdown.scss b/src/sass/markdown.scss
new file mode 100644
index 00000000..e0432c01
--- /dev/null
+++ b/src/sass/markdown.scss
@@ -0,0 +1,16 @@
+pre {
+ background-color: var(--earth-cream);
+ padding: var(--space-md, 1rem);
+ border-radius: var(--radius-md, 12px);
+}
+
+section h2 {
+ margin-top: var(--space-lg, 2rem) !important;
+}
+section h3 {
+ margin-bottom: var(--space-md, 1rem) !important;
+}
+section ul,
+section ol {
+ margin-bottom: var(--space-md, 1rem) !important;
+}
diff --git a/src/sass/style.scss b/src/sass/style.scss
index 5b0ff6ae..50599053 100644
--- a/src/sass/style.scss
+++ b/src/sass/style.scss
@@ -156,7 +156,6 @@ figcaption {
@import 'badge';
@import 'buttons';
@import 'cards';
-@import 'markdown';
@import 'gallery';
/* stylint-enable */
From 2395d1f713e0477e43a33bc2b7918994ccba34df Mon Sep 17 00:00:00 2001
From: Adam Jolicoeur
Date: Mon, 5 Jan 2026 12:51:24 -0500
Subject: [PATCH 2/2] feat: update TaskStat with images
---
docs/apps/taskstat.html | 45 +++++++++++++-----
docs/assets/img/TaskStat_Dark-thumb.jpg | Bin 0 -> 9676 bytes
docs/assets/img/TaskStat_Dark-thumb.webp | Bin 0 -> 6242 bytes
docs/assets/img/TaskStat_Dark.jpg | Bin 0 -> 79241 bytes
docs/assets/img/TaskStat_Dark.webp | Bin 0 -> 31484 bytes
docs/assets/img/TaskStat_Default-thumb.jpg | Bin 0 -> 11113 bytes
docs/assets/img/TaskStat_Default-thumb.webp | Bin 0 -> 6736 bytes
docs/assets/img/TaskStat_Default.jpg | Bin 0 -> 86138 bytes
docs/assets/img/TaskStat_Default.webp | Bin 0 -> 34302 bytes
docs/assets/img/TaskStat_Tinted-thumb.jpg | Bin 0 -> 9065 bytes
docs/assets/img/TaskStat_Tinted-thumb.webp | Bin 0 -> 5258 bytes
docs/assets/img/TaskStat_Tinted.jpg | Bin 0 -> 68931 bytes
docs/assets/img/TaskStat_Tinted.webp | Bin 0 -> 25830 bytes
.../taskstat-screenshot-dashboard-thumb.jpg | Bin 0 -> 16579 bytes
.../taskstat-screenshot-dashboard-thumb.webp | Bin 0 -> 9742 bytes
.../img/taskstat-screenshot-dashboard.jpg | Bin 0 -> 130222 bytes
.../img/taskstat-screenshot-dashboard.webp | Bin 0 -> 54066 bytes
.../img/taskstat-screenshot-details-thumb.jpg | Bin 0 -> 18513 bytes
.../taskstat-screenshot-details-thumb.webp | Bin 0 -> 10958 bytes
.../img/taskstat-screenshot-details.jpg | Bin 0 -> 139240 bytes
.../img/taskstat-screenshot-details.webp | Bin 0 -> 59546 bytes
.../img/taskstat-screenshot-list-thumb.jpg | Bin 0 -> 17523 bytes
.../img/taskstat-screenshot-list-thumb.webp | Bin 0 -> 10054 bytes
docs/assets/img/taskstat-screenshot-list.jpg | Bin 0 -> 134616 bytes
docs/assets/img/taskstat-screenshot-list.webp | Bin 0 -> 57926 bytes
.../taskstat-screenshot-settings-thumb.jpg | Bin 0 -> 23448 bytes
.../taskstat-screenshot-settings-thumb.webp | Bin 0 -> 15230 bytes
.../img/taskstat-screenshot-settings.jpg | Bin 0 -> 188568 bytes
.../img/taskstat-screenshot-settings.webp | Bin 0 -> 83898 bytes
docs/feed.json | 8 ++--
docs/sitemap.xml | 4 +-
src/assets/img-raw/TaskStat_Dark.png | Bin 0 -> 2245419 bytes
src/assets/img-raw/TaskStat_Default.png | Bin 0 -> 1766259 bytes
src/assets/img-raw/TaskStat_Tinted.png | Bin 0 -> 1449413 bytes
.../img-raw/taskstat-screenshot-dashboard.png | Bin 0 -> 215681 bytes
.../img-raw/taskstat-screenshot-details.png | Bin 0 -> 235593 bytes
.../img-raw/taskstat-screenshot-list.png | Bin 0 -> 258053 bytes
.../img-raw/taskstat-screenshot-settings.png | Bin 0 -> 378136 bytes
src/assets/img/TaskStat_Dark-thumb.jpg | Bin 0 -> 9676 bytes
src/assets/img/TaskStat_Dark-thumb.webp | Bin 0 -> 6242 bytes
src/assets/img/TaskStat_Dark.jpg | Bin 0 -> 79241 bytes
src/assets/img/TaskStat_Dark.webp | Bin 0 -> 31484 bytes
src/assets/img/TaskStat_Default-thumb.jpg | Bin 0 -> 11113 bytes
src/assets/img/TaskStat_Default-thumb.webp | Bin 0 -> 6736 bytes
src/assets/img/TaskStat_Default.jpg | Bin 0 -> 86138 bytes
src/assets/img/TaskStat_Default.webp | Bin 0 -> 34302 bytes
src/assets/img/TaskStat_Tinted-thumb.jpg | Bin 0 -> 9065 bytes
src/assets/img/TaskStat_Tinted-thumb.webp | Bin 0 -> 5258 bytes
src/assets/img/TaskStat_Tinted.jpg | Bin 0 -> 68931 bytes
src/assets/img/TaskStat_Tinted.webp | Bin 0 -> 25830 bytes
.../taskstat-screenshot-dashboard-thumb.jpg | Bin 0 -> 16579 bytes
.../taskstat-screenshot-dashboard-thumb.webp | Bin 0 -> 9742 bytes
.../img/taskstat-screenshot-dashboard.jpg | Bin 0 -> 130222 bytes
.../img/taskstat-screenshot-dashboard.webp | Bin 0 -> 54066 bytes
.../img/taskstat-screenshot-details-thumb.jpg | Bin 0 -> 18513 bytes
.../taskstat-screenshot-details-thumb.webp | Bin 0 -> 10958 bytes
.../img/taskstat-screenshot-details.jpg | Bin 0 -> 139240 bytes
.../img/taskstat-screenshot-details.webp | Bin 0 -> 59546 bytes
.../img/taskstat-screenshot-list-thumb.jpg | Bin 0 -> 17523 bytes
.../img/taskstat-screenshot-list-thumb.webp | Bin 0 -> 10054 bytes
src/assets/img/taskstat-screenshot-list.jpg | Bin 0 -> 134616 bytes
src/assets/img/taskstat-screenshot-list.webp | Bin 0 -> 57926 bytes
.../taskstat-screenshot-settings-thumb.jpg | Bin 0 -> 23448 bytes
.../taskstat-screenshot-settings-thumb.webp | Bin 0 -> 15230 bytes
.../img/taskstat-screenshot-settings.jpg | Bin 0 -> 188568 bytes
.../img/taskstat-screenshot-settings.webp | Bin 0 -> 83898 bytes
src/pages/apps/taskstat.md | 34 ++++++++-----
67 files changed, 61 insertions(+), 30 deletions(-)
create mode 100644 docs/assets/img/TaskStat_Dark-thumb.jpg
create mode 100644 docs/assets/img/TaskStat_Dark-thumb.webp
create mode 100644 docs/assets/img/TaskStat_Dark.jpg
create mode 100644 docs/assets/img/TaskStat_Dark.webp
create mode 100644 docs/assets/img/TaskStat_Default-thumb.jpg
create mode 100644 docs/assets/img/TaskStat_Default-thumb.webp
create mode 100644 docs/assets/img/TaskStat_Default.jpg
create mode 100644 docs/assets/img/TaskStat_Default.webp
create mode 100644 docs/assets/img/TaskStat_Tinted-thumb.jpg
create mode 100644 docs/assets/img/TaskStat_Tinted-thumb.webp
create mode 100644 docs/assets/img/TaskStat_Tinted.jpg
create mode 100644 docs/assets/img/TaskStat_Tinted.webp
create mode 100644 docs/assets/img/taskstat-screenshot-dashboard-thumb.jpg
create mode 100644 docs/assets/img/taskstat-screenshot-dashboard-thumb.webp
create mode 100644 docs/assets/img/taskstat-screenshot-dashboard.jpg
create mode 100644 docs/assets/img/taskstat-screenshot-dashboard.webp
create mode 100644 docs/assets/img/taskstat-screenshot-details-thumb.jpg
create mode 100644 docs/assets/img/taskstat-screenshot-details-thumb.webp
create mode 100644 docs/assets/img/taskstat-screenshot-details.jpg
create mode 100644 docs/assets/img/taskstat-screenshot-details.webp
create mode 100644 docs/assets/img/taskstat-screenshot-list-thumb.jpg
create mode 100644 docs/assets/img/taskstat-screenshot-list-thumb.webp
create mode 100644 docs/assets/img/taskstat-screenshot-list.jpg
create mode 100644 docs/assets/img/taskstat-screenshot-list.webp
create mode 100644 docs/assets/img/taskstat-screenshot-settings-thumb.jpg
create mode 100644 docs/assets/img/taskstat-screenshot-settings-thumb.webp
create mode 100644 docs/assets/img/taskstat-screenshot-settings.jpg
create mode 100644 docs/assets/img/taskstat-screenshot-settings.webp
create mode 100644 src/assets/img-raw/TaskStat_Dark.png
create mode 100644 src/assets/img-raw/TaskStat_Default.png
create mode 100644 src/assets/img-raw/TaskStat_Tinted.png
create mode 100644 src/assets/img-raw/taskstat-screenshot-dashboard.png
create mode 100644 src/assets/img-raw/taskstat-screenshot-details.png
create mode 100644 src/assets/img-raw/taskstat-screenshot-list.png
create mode 100644 src/assets/img-raw/taskstat-screenshot-settings.png
create mode 100644 src/assets/img/TaskStat_Dark-thumb.jpg
create mode 100644 src/assets/img/TaskStat_Dark-thumb.webp
create mode 100644 src/assets/img/TaskStat_Dark.jpg
create mode 100644 src/assets/img/TaskStat_Dark.webp
create mode 100644 src/assets/img/TaskStat_Default-thumb.jpg
create mode 100644 src/assets/img/TaskStat_Default-thumb.webp
create mode 100644 src/assets/img/TaskStat_Default.jpg
create mode 100644 src/assets/img/TaskStat_Default.webp
create mode 100644 src/assets/img/TaskStat_Tinted-thumb.jpg
create mode 100644 src/assets/img/TaskStat_Tinted-thumb.webp
create mode 100644 src/assets/img/TaskStat_Tinted.jpg
create mode 100644 src/assets/img/TaskStat_Tinted.webp
create mode 100644 src/assets/img/taskstat-screenshot-dashboard-thumb.jpg
create mode 100644 src/assets/img/taskstat-screenshot-dashboard-thumb.webp
create mode 100644 src/assets/img/taskstat-screenshot-dashboard.jpg
create mode 100644 src/assets/img/taskstat-screenshot-dashboard.webp
create mode 100644 src/assets/img/taskstat-screenshot-details-thumb.jpg
create mode 100644 src/assets/img/taskstat-screenshot-details-thumb.webp
create mode 100644 src/assets/img/taskstat-screenshot-details.jpg
create mode 100644 src/assets/img/taskstat-screenshot-details.webp
create mode 100644 src/assets/img/taskstat-screenshot-list-thumb.jpg
create mode 100644 src/assets/img/taskstat-screenshot-list-thumb.webp
create mode 100644 src/assets/img/taskstat-screenshot-list.jpg
create mode 100644 src/assets/img/taskstat-screenshot-list.webp
create mode 100644 src/assets/img/taskstat-screenshot-settings-thumb.jpg
create mode 100644 src/assets/img/taskstat-screenshot-settings-thumb.webp
create mode 100644 src/assets/img/taskstat-screenshot-settings.jpg
create mode 100644 src/assets/img/taskstat-screenshot-settings.webp
diff --git a/docs/apps/taskstat.html b/docs/apps/taskstat.html
index d55db1c3..df303c2f 100644
--- a/docs/apps/taskstat.html
+++ b/docs/apps/taskstat.html
@@ -115,18 +115,41 @@
Screenshots #
-Coming soon - Screenshots will be added once the app is published to the App Store
-
+
+
+
+ Dashboard
+
+
+
+ Task List
+
+
+
+ Task Details
+
+
+
+ Settings
+
+
App Icon #
-Coming soon - App icons will be added once finalized
-
+
+
+
+Light
+Dark
+Tinted
+
+
+
+
+
+
+
+
+
+
Download #
Platform: iOS 18.0 or later
App Store: Coming soon - Link will be added when published
diff --git a/docs/assets/img/TaskStat_Dark-thumb.jpg b/docs/assets/img/TaskStat_Dark-thumb.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9c3c3b2b5f22129708aa46570f77cdb5dff75c8d
GIT binary patch
literal 9676
zcmch6byQSQ)b9-4CCwlpATXpuOLup-lr+*MC{ikt!wenLT|<|G^dL3TDFV_+O9^lE
zd*6ENd;fiJz4hI@);)Khea`vq``i2MbJn@{bN7n?1ppon4lWKh9xg5}K0Y1+5hXDZ
zAt4bR#RF1GMtY`)jPxK7GaDZV^CKQs5QtNhi$~yzkdP1)hq#m&M3PTX2=aFjAU-}m
z5g`#RF)=NK1;hgRZ(sM_0CGGa50D2F_y~YO4#Xq}-uD4O000ICCJ+etKNk)V0}~4y
z7Z0sfBLe_2F#%XOBslok08DfnAmFc(9EXDC$pbk(@8n5bO6o_f?D__Vwm#7M9x677
z{G0s8g2D>+1&FmHJ72$uFG3>6=%MKU_WUn608AhT7B&uA$3u=b0u6+P0mS+X@)rk#
z924t_9>oI|%1016Z0|R$g7UWd$@TXO03uBEP~@2802#p5A3S*gS#(eVG}w$%uU+k-
zg82YZ+Jjc$KsaX$?@Yx_mug9i-nh||n`D93M6(Uh9?I`Uy`fhha+wQ08GrEc{aoOm
z<^HcC*I#`6f5v{(STL?Ib$RBwz2;da-GB^p^yn!VP8m6hYxCEA8@+M5_`;5`bCkl$
z&Bf!Z#C$Hb+@+|~&-9%RdS^HZv6Yp-Tg-9IT-F3oCUaCTu%e8EpP83K{r8{Jl*^h_
znL+!6J5BxRjh8`Bk4?`Wzq6BI6g(ajTxGdkYNiv3|8`e0=;kEMP1?u4!Aq$2K8zr^
zB$9^;Zr=%g`vlk56NE*9VM<2Q6N$c(n}~pu(5@6-jS&
z`-0bTH|jodhvs?4z?Y6h%WdV~;(adgfI+`GrahfO+FTD-9+?X|!(&2szYUX1dLv&2
zTT!xi(iV4`{Gm2`+?+xUZp3+nUs%h0Eb=^bP~W=Md30upaI*xWC=*OR`(m^46*o%Z
z-MSgW6BjeYD+!`c(zv~5sS;O`9)weTnc^NDZzTtq%VfIV*>lW@GR4Yw%vHLhegwEF
zuCHj0RtM^x^Jy02ZkFjA8Opju55W*mf0qoXhO^+wVvqrSBhB&Iz5^iY2XY0XyXmc}2Z)$;sVibBtO}%e
z;_xJxcRvA4-S5%fyvUq@$TS57y2ZauKjgLm8|WZ$%3v%6s#q+TY~et*eSr5zAYp?}
zfyr*!zhRP-YZP?kxbv($YMNE)EHrqq4*3~KpDYxt&9t9fJ!MzwN_a{=9ai&c?r32_&35d^THPt*hymC@
z%N!?j=|611!;oY3X;`Gv<9KUNPQMyYzh6dBQK!WKr6&T+TbyD`<$ETihL9
z{VH1fvhx$6R&(yO(n^mOZS0d>Q0SJ+t??-J!=D;2S@|mY6}iH)UpDoe!}%6hBHHHV
zX$sWgtWY{--Dox(Js1msPM%U?Ki2`cCzT+ikE4tDWkTzRiW{tw?hUFR|C}EpA?w^L
ziL4N#{5(M2D;2i<*uo1}l$?6N
zUBbFK{gQBgVG{Our+L|7qrSnk{9sdW9Pf|w1e4$SUIh#A!cw-(lF*&drcWb5xzT-X
zRpR!E4BCgaJivu(ks4<0}Mq)n1{|xBZ+#7X8XgoHapYOrO0}CBC
zBQkj^MzzJ{1U6`hf|j
zi?Al#WkE8t8EQ^2@A8}$%0Zpm^hUyEx>Y>Ma@})vS|f2&hI|5Ql0LPzzu_ej$pIsvypol)vLayhto|eE
z*S2Tyg_E|WV*h&pBT07P@Ypo+!~|P6pRmA@oq#Nyoz5hN4$Ma0_hsuLbCyRtDeK(h
zRwRop-L%B`+UM^T8wJ$}9&Kc0Vn}dWar3-=!SgDCj69?^?gmsSjkt|$0zkfxnOz>&
z-Wd__vikkpWG3saNGQe%gwHW&p`Bat^~7qpSzP7UVavSz1EovluTTf64$t;8uuMjTQTDgFLA>Cn<*?+xVjI)(g
zvNG&+7Rz*b54h&;aEgd>K9D>`Ayjgr2gL`zde_QDSc%#B2+F*aTz$c!tA2K}=fZe^
zDcGNVUX;T*?Gb8QO-x@3@b=KrzKbq(LTtYoh@Qy%YumHoJxeLd0HKHP?g99DDC#SC
za8>LU|NMO9MeSr0Th6w%%)I2!KN@!
zx5L<=h>r~W&~1^l;2rTb-HQhc?#Z!y1F1m+qd|;Z_kf0_SGL|h=}s@)wmov09!HSh
zhTo!gmy3h