diff --git a/docs/assets/img/soccergametracker- ingamesummary-thumb.webp b/docs/assets/img/soccergametracker- ingamesummary-thumb.webp new file mode 100644 index 00000000..19855b1f Binary files /dev/null and b/docs/assets/img/soccergametracker- ingamesummary-thumb.webp differ diff --git a/docs/assets/img/soccergametracker- ingamesummary.webp b/docs/assets/img/soccergametracker- ingamesummary.webp new file mode 100644 index 00000000..a7ddbcf2 Binary files /dev/null and b/docs/assets/img/soccergametracker- ingamesummary.webp differ diff --git a/docs/assets/img/soccergametracker-addnewplayer-thumb.webp b/docs/assets/img/soccergametracker-addnewplayer-thumb.webp new file mode 100644 index 00000000..2a4bccae Binary files /dev/null and b/docs/assets/img/soccergametracker-addnewplayer-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-addnewplayer.webp b/docs/assets/img/soccergametracker-addnewplayer.webp new file mode 100644 index 00000000..fb28296b Binary files /dev/null and b/docs/assets/img/soccergametracker-addnewplayer.webp differ diff --git a/docs/assets/img/soccergametracker-endgame-thumb.webp b/docs/assets/img/soccergametracker-endgame-thumb.webp new file mode 100644 index 00000000..7c3b068c Binary files /dev/null and b/docs/assets/img/soccergametracker-endgame-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-endgame.webp b/docs/assets/img/soccergametracker-endgame.webp new file mode 100644 index 00000000..bd5b9e71 Binary files /dev/null and b/docs/assets/img/soccergametracker-endgame.webp differ diff --git a/docs/assets/img/soccergametracker-firsthalfsummary-thumb.webp b/docs/assets/img/soccergametracker-firsthalfsummary-thumb.webp new file mode 100644 index 00000000..279a924f Binary files /dev/null and b/docs/assets/img/soccergametracker-firsthalfsummary-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-firsthalfsummary.webp b/docs/assets/img/soccergametracker-firsthalfsummary.webp new file mode 100644 index 00000000..46483408 Binary files /dev/null and b/docs/assets/img/soccergametracker-firsthalfsummary.webp differ diff --git a/docs/assets/img/soccergametracker-gamedetails-thumb.webp b/docs/assets/img/soccergametracker-gamedetails-thumb.webp new file mode 100644 index 00000000..25175eee Binary files /dev/null and b/docs/assets/img/soccergametracker-gamedetails-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-gamedetails.webp b/docs/assets/img/soccergametracker-gamedetails.webp new file mode 100644 index 00000000..cff54486 Binary files /dev/null and b/docs/assets/img/soccergametracker-gamedetails.webp differ diff --git a/docs/assets/img/soccergametracker-goalassignment-thumb.webp b/docs/assets/img/soccergametracker-goalassignment-thumb.webp new file mode 100644 index 00000000..30427662 Binary files /dev/null and b/docs/assets/img/soccergametracker-goalassignment-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-goalassignment.webp b/docs/assets/img/soccergametracker-goalassignment.webp new file mode 100644 index 00000000..f701132f Binary files /dev/null and b/docs/assets/img/soccergametracker-goalassignment.webp differ diff --git a/docs/assets/img/soccergametracker-halftime-thumb.webp b/docs/assets/img/soccergametracker-halftime-thumb.webp new file mode 100644 index 00000000..2461ba19 Binary files /dev/null and b/docs/assets/img/soccergametracker-halftime-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-halftime.webp b/docs/assets/img/soccergametracker-halftime.webp new file mode 100644 index 00000000..ece26585 Binary files /dev/null and b/docs/assets/img/soccergametracker-halftime.webp differ diff --git a/docs/assets/img/soccergametracker-history-thumb.webp b/docs/assets/img/soccergametracker-history-thumb.webp new file mode 100644 index 00000000..ee820d4c Binary files /dev/null and b/docs/assets/img/soccergametracker-history-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-history.webp b/docs/assets/img/soccergametracker-history.webp new file mode 100644 index 00000000..978f9963 Binary files /dev/null and b/docs/assets/img/soccergametracker-history.webp differ diff --git a/docs/assets/img/soccergametracker-history02-thumb.webp b/docs/assets/img/soccergametracker-history02-thumb.webp new file mode 100644 index 00000000..0c38bfa6 Binary files /dev/null and b/docs/assets/img/soccergametracker-history02-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-history02.webp b/docs/assets/img/soccergametracker-history02.webp new file mode 100644 index 00000000..59d7880a Binary files /dev/null and b/docs/assets/img/soccergametracker-history02.webp differ diff --git a/docs/assets/img/soccergametracker-newgame-thumb.webp b/docs/assets/img/soccergametracker-newgame-thumb.webp new file mode 100644 index 00000000..c74c2fc1 Binary files /dev/null and b/docs/assets/img/soccergametracker-newgame-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-newgame.webp b/docs/assets/img/soccergametracker-newgame.webp new file mode 100644 index 00000000..0d11e530 Binary files /dev/null and b/docs/assets/img/soccergametracker-newgame.webp differ diff --git a/docs/assets/img/soccergametracker-phone-history-details-thumb.webp b/docs/assets/img/soccergametracker-phone-history-details-thumb.webp new file mode 100644 index 00000000..3ef0a78a Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-history-details-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-history-details.webp b/docs/assets/img/soccergametracker-phone-history-details.webp new file mode 100644 index 00000000..4d4d9806 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-history-details.webp differ diff --git a/docs/assets/img/soccergametracker-phone-history-thumb.webp b/docs/assets/img/soccergametracker-phone-history-thumb.webp new file mode 100644 index 00000000..98b6da6f Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-history-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-history.webp b/docs/assets/img/soccergametracker-phone-history.webp new file mode 100644 index 00000000..24fb65ea Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-history.webp differ diff --git a/docs/assets/img/soccergametracker-phone-livegame-thumb.webp b/docs/assets/img/soccergametracker-phone-livegame-thumb.webp new file mode 100644 index 00000000..1f2082a6 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-livegame-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-livegame.webp b/docs/assets/img/soccergametracker-phone-livegame.webp new file mode 100644 index 00000000..8ce97c47 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-livegame.webp differ diff --git a/docs/assets/img/soccergametracker-phone-newgame-thumb.webp b/docs/assets/img/soccergametracker-phone-newgame-thumb.webp new file mode 100644 index 00000000..378d04aa Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-newgame-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-newgame.webp b/docs/assets/img/soccergametracker-phone-newgame.webp new file mode 100644 index 00000000..60d102a0 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-newgame.webp differ diff --git a/docs/assets/img/soccergametracker-phone-rosters-thumb.webp b/docs/assets/img/soccergametracker-phone-rosters-thumb.webp new file mode 100644 index 00000000..91f4ff6e Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-rosters-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-rosters.webp b/docs/assets/img/soccergametracker-phone-rosters.webp new file mode 100644 index 00000000..b6114b9f Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-rosters.webp differ diff --git a/docs/assets/img/soccergametracker-phone-subs-01-thumb.webp b/docs/assets/img/soccergametracker-phone-subs-01-thumb.webp new file mode 100644 index 00000000..33e2756d Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-subs-01-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-subs-01.webp b/docs/assets/img/soccergametracker-phone-subs-01.webp new file mode 100644 index 00000000..034ff885 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-subs-01.webp differ diff --git a/docs/assets/img/soccergametracker-phone-subs-02-thumb.webp b/docs/assets/img/soccergametracker-phone-subs-02-thumb.webp new file mode 100644 index 00000000..7eca5a55 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-subs-02-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-subs-02.webp b/docs/assets/img/soccergametracker-phone-subs-02.webp new file mode 100644 index 00000000..7b5ef5bf Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-subs-02.webp differ diff --git a/docs/assets/img/soccergametracker-phone-subs-03-thumb.webp b/docs/assets/img/soccergametracker-phone-subs-03-thumb.webp new file mode 100644 index 00000000..0f1b4293 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-subs-03-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-subs-03.webp b/docs/assets/img/soccergametracker-phone-subs-03.webp new file mode 100644 index 00000000..6984bfcc Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-subs-03.webp differ diff --git a/docs/assets/img/soccergametracker-phone-summary-thumb.webp b/docs/assets/img/soccergametracker-phone-summary-thumb.webp new file mode 100644 index 00000000..d8640397 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-summary-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-phone-summary.webp b/docs/assets/img/soccergametracker-phone-summary.webp new file mode 100644 index 00000000..e88f2493 Binary files /dev/null and b/docs/assets/img/soccergametracker-phone-summary.webp differ diff --git a/docs/assets/img/soccergametracker-playerstats01-thumb.webp b/docs/assets/img/soccergametracker-playerstats01-thumb.webp new file mode 100644 index 00000000..5e726829 Binary files /dev/null and b/docs/assets/img/soccergametracker-playerstats01-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-playerstats01.webp b/docs/assets/img/soccergametracker-playerstats01.webp new file mode 100644 index 00000000..0bc84313 Binary files /dev/null and b/docs/assets/img/soccergametracker-playerstats01.webp differ diff --git a/docs/assets/img/soccergametracker-playerstats02-thumb.webp b/docs/assets/img/soccergametracker-playerstats02-thumb.webp new file mode 100644 index 00000000..f4109931 Binary files /dev/null and b/docs/assets/img/soccergametracker-playerstats02-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-playerstats02.webp b/docs/assets/img/soccergametracker-playerstats02.webp new file mode 100644 index 00000000..64670a00 Binary files /dev/null and b/docs/assets/img/soccergametracker-playerstats02.webp differ diff --git a/docs/assets/img/soccergametracker-roster-thumb.webp b/docs/assets/img/soccergametracker-roster-thumb.webp new file mode 100644 index 00000000..f4005e62 Binary files /dev/null and b/docs/assets/img/soccergametracker-roster-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-roster.webp b/docs/assets/img/soccergametracker-roster.webp new file mode 100644 index 00000000..be270655 Binary files /dev/null and b/docs/assets/img/soccergametracker-roster.webp differ diff --git a/docs/assets/img/soccergametracker-secondhalfsummary-thumb.webp b/docs/assets/img/soccergametracker-secondhalfsummary-thumb.webp new file mode 100644 index 00000000..eda55618 Binary files /dev/null and b/docs/assets/img/soccergametracker-secondhalfsummary-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-secondhalfsummary.webp b/docs/assets/img/soccergametracker-secondhalfsummary.webp new file mode 100644 index 00000000..f2a646d8 Binary files /dev/null and b/docs/assets/img/soccergametracker-secondhalfsummary.webp differ diff --git a/docs/assets/img/soccergametracker-startgame-thumb.webp b/docs/assets/img/soccergametracker-startgame-thumb.webp new file mode 100644 index 00000000..e8a9811e Binary files /dev/null and b/docs/assets/img/soccergametracker-startgame-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-startgame.webp b/docs/assets/img/soccergametracker-startgame.webp new file mode 100644 index 00000000..b40413f3 Binary files /dev/null and b/docs/assets/img/soccergametracker-startgame.webp differ diff --git a/docs/assets/img/soccergametracker-substituteprompt-thumb.webp b/docs/assets/img/soccergametracker-substituteprompt-thumb.webp new file mode 100644 index 00000000..c1cbb5fa Binary files /dev/null and b/docs/assets/img/soccergametracker-substituteprompt-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-substituteprompt.webp b/docs/assets/img/soccergametracker-substituteprompt.webp new file mode 100644 index 00000000..07bb853c Binary files /dev/null and b/docs/assets/img/soccergametracker-substituteprompt.webp differ diff --git a/docs/assets/img/soccergametracker-substitutionsummary-thumb.webp b/docs/assets/img/soccergametracker-substitutionsummary-thumb.webp new file mode 100644 index 00000000..4fdeb8be Binary files /dev/null and b/docs/assets/img/soccergametracker-substitutionsummary-thumb.webp differ diff --git a/docs/assets/img/soccergametracker-substitutionsummary.webp b/docs/assets/img/soccergametracker-substitutionsummary.webp new file mode 100644 index 00000000..6134b98f Binary files /dev/null and b/docs/assets/img/soccergametracker-substitutionsummary.webp differ diff --git a/docs/case-studies/soccertracker/index.html b/docs/case-studies/soccertracker/index.html new file mode 100644 index 00000000..84b17d6a --- /dev/null +++ b/docs/case-studies/soccertracker/index.html @@ -0,0 +1,341 @@ + + + + + + Soccer Game Tracker | Adam Jolicoeur + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+

Soccer Game Tracker

+

Native iOS app for coaches to track game data. Solo project, in active use.

+ + + +
+

Project Overview #

+
+

A native iOS app, built by a coach, who needed fast and reliable game tracking without surrendering data to a third-party platform — designed for the sideline, built in Swift.

+
+
+

ROLE: Designer & Developer

+

STACK: SwiftUI

+

STATUS: Work in progress

+
+
+
+

Introduction #

+

Coaching a youth soccer team generates a surprising amount of data. Scores, substitutions, player minutes, goals, assists, saves, cards. The problem isn’t that the data is hard to capture — it’s that every existing option forces a tradeoff I wasn’t willing to make. Pen and paper is fast but produces nothing useful afterward. Third-party apps are convenient but own your data, require accounts, and are built for organizations, not individual coaches. I wanted something purpose-built for how I actually work on a sideline: fast to set up, minimal interaction during play, and with data I control entirely.

+
+
+
+
+ New Game setup screen +
set the roster - starters and substitutes
+
+
+
+
+
+
+ New Game setup screen +
add game info - team size, location, date & time
+
+
+
+
+
+
+

The harder right choice #

+

I built SoccerGameTracker as a native iOS app in Swift — solo, from scratch. The easier path would have been a PWA or React Native wrapper; I’ve shipped both, and they’re faster to build. I chose Swift because a sideline app has a specific performance contract: launch instantly, respond without lag when a goal gets scored, never drop data if the phone gets pocketed. Native with local storage and no network dependency satisfies all three. No sync to worry about, no account to authenticate, no API that might be down at kickoff.

+
+

every decision went through one person - me

+
+

Constraint clarified scope. Without a backend, multi-device sync and shared rosters aren’t on the table — and that’s fine. Knowing what the app isn’t made it easier to build what it is. I handled both the design and implementation entirely, which meant every decision — from interaction model to data structure — went through one person. That’s mostly an advantage when you need to move fast and stay opinionated.

+
+
+

Designing for the sideline #

+
+

The core design problem is attention.

+
+

During a live game, a coach is watching players, calling substitutions, talking to parents. The app gets a glance and a thumb tap, not focused interaction. Every decision on the Live Game screen follows from that.

+
+
Pregame
+
+ The pre-game setup flow handles the overhead up front. +
New Game collects opposition, date, location, and half duration — everything you'd put on a physical scoresheet — plus roster selection from a pre-built player list with jersey number and position. +
The Game vs. Scrimmage toggle is a small but deliberate decision: scrimmages have different stakes and different lineup dynamics, and I wanted the history to reflect that distinction clearly. +
+
+
+
Scoreboard & Quick Actions
+
+ The scoreboard and half timer sit at the top, readable in a second. The Quick Actions section — Team Goal and Opponent Goal — are the two largest tap targets in the app, sized and colored for immediate recognition in any lighting. Correction actions (Remove Team Goal, Subtract Goal) are present but visually subordinate: same area, smaller, lighter. Reachable when you need them, harder to hit by accident. +
+
+
+
Players & Activity
+
+ Below the quick actions is where the app earns its depth. Each player in the active roster is tappable, opening a detail view where you can log individual stats in real time: goals, assists, saves, shots, yellow cards, red cards. Every action is timestamped and tied to the game half — building a full action log that the post-game summary renders as a timeline. That's the data that makes post-game review actually useful: not just who won, but who contributed, when, and how often. +
+
+
+
+
+ Live Game screen showing scoreboard, timer, Quick Actions, and player list +
Live Game screen showing scoreboard, timer, Quick Actions, and player list
+
+
+
+
+

Substitutions #

+
+

Substitutions were a meaningful product decision. Mid-game sub support — with a distinct “substituted out” state separate from bench status — reflects how substitutions actually work: a player who comes off isn’t the same as a player who never started. Getting that distinction right matters for per-player stats to be accurate.

+
+
+
+
+
+ View a player's stats and position before substituting them on or off +
View a player's stats and position before substituting them on or off
+
+
+
+
+
+
+ Substitutes cannot accidentally have statistics assigned +
Substitutes cannot accidentally have statistics assigned
+
+
+
+
+
+
+ View who subbed in and out of the game by half +
View who subbed in and out of the game by half
+
+
+
+
+
+
+

After the game #

+
+

As a coach, being able to view historical information is a key part in planning practices, setting lineups, and determining strategy.

+
+

History #

+
+
+
+
+ View historical game data, zooming in to see each game's details +
View historical game data, with key info front and center
+
+
+
+
+
+
+ View historical game data, zooming in to see each game's details +
Zooming into any game shows player-by-player stats
+
+
+
+
+
+
+

Where it stands #

+
+

The app is in active use this season, tested against the real constraint it was built for: a sideline, in real game conditions. Feedback from that use has been indispensable, with the per-player stats used between games to inform lineup and substitution planning. That’s the outcome I was building toward.

+

What real use has surfaced is mostly sequencing: the transition from pre-game setup into the live view needs less friction, and the post-game summary screen is still being refined. Those are the next iterations.

+
+
+

An App Store release is planned once the final rough edges are resolved. The app does one thing, does it reliably, and doesn’t ask for anything it doesn’t need.

+
+
+ +
+ + +
+ + + + + + + + + diff --git a/docs/css/style.css b/docs/css/style.css index b02231c0..489a9820 100644 --- a/docs/css/style.css +++ b/docs/css/style.css @@ -813,6 +813,10 @@ section { justify-content: space-between !important; } +.justify-content-around { + justify-content: space-around !important; +} + .justify-content-end { justify-content: flex-end !important; } diff --git a/docs/css/style.css.map b/docs/css/style.css.map index 8a674f8e..1b1c434e 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/_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;AAAA;EAEE;;;AAEF;AAAA;EAEE;EACA;EACA;EACA;;;AAEF;AAAA;EAEE;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;AEpKA;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;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;;AAEF;AAAA;EAEE;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;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;AAAA;EAEE;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAEF;AAAA;AAAA;AAAA;EAIE;EACA;;;AAEF;EACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EAIE;;;AAIJ;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;ACzPF;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;EACA;;AAGF;EAhMA;EAmME;;AAjMF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAyLF;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;EAjPF;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAuOA;EAEE;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;;AAGJ;AdvIA","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;AAAA;EAEE;;;AAEF;AAAA;EAEE;EACA;EACA;EACA;;;AAEF;AAAA;EAEE;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;AEpKA;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;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;;AAEF;AAAA;EAEE;;;AAEF;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;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;AAAA;EAEE;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAEF;AAAA;AAAA;AAAA;EAIE;EACA;;;AAEF;EACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EAIE;;;AAIJ;AACA;AAAA;EAEE;EACA;EACA;EACA;EACA;;;ACzPF;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;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;;;AAEF;EACE;;;AAEF;EACE,SA7CK;;;AA+CP;EACE,gBA/CO;;;AAiDT;EACE,aAjDO;;;AAmDT;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;ACzEF;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;EACA;;AAGF;EAhMA;EAmME;;AAjMF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAyLF;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;EAjPF;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAuOA;EAEE;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;;AAGJ;AdvIA","file":"style.css"} \ No newline at end of file diff --git a/docs/feed.json b/docs/feed.json index 247a587c..e2f60ca6 100644 --- a/docs/feed.json +++ b/docs/feed.json @@ -26,6 +26,46 @@ "url": "" }, "items": [ + { + "id": "/development/archparser/", + "url": "/development/archparser/", + "title": "ArchParser: Architectural Drawing Analysis Platform", + "date_published": "2026-03-26T01:47:27Z", + "date": "2026-03-26T01:47:27Z" + } + , + { + "id": "/designs/task-it/", + "url": "/designs/task-it/", + "title": "Task Management System", + "date_published": "2026-03-26T01:47:27Z", + "date": "2026-03-26T01:47:27Z" + } + , + { + "id": "/designs/component-library/", + "url": "/designs/component-library/", + "title": "Component Library", + "date_published": "2026-03-26T01:47:27Z", + "date": "2026-03-26T01:47:27Z" + } + , + { + "id": "/designs/alm/", + "url": "/designs/alm/", + "title": "Application Lifecycle Management", + "date_published": "2026-03-26T01:47:27Z", + "date": "2026-03-26T01:47:27Z" + } + , + { + "id": "/case-studies/soccertracker/", + "url": "/case-studies/soccertracker/", + "title": "Soccer Game Tracker", + "date_published": "2026-03-26T01:32:09Z", + "date": "2026-03-26T01:32:09Z" + } + , { "id": "/reference/", "url": "/reference/", @@ -90,14 +130,6 @@ "date": "2026-01-19T16:58:02Z" } , - { - "id": "/development/archparser/", - "url": "/development/archparser/", - "title": "ArchParser: Architectural Drawing Analysis Platform", - "date_published": "2026-01-19T16:58:02Z", - "date": "2026-01-19T16:58:02Z" - } - , { "id": "/designs/customer-engagement/", "url": "/designs/customer-engagement/", @@ -122,30 +154,6 @@ "date": "2026-01-05T19:31:33Z" } , - { - "id": "/designs/task-it/", - "url": "/designs/task-it/", - "title": "Task Management System", - "date_published": "2026-01-01T16:25:50Z", - "date": "2026-01-01T16:25:50Z" - } - , - { - "id": "/designs/component-library/", - "url": "/designs/component-library/", - "title": "Component Library", - "date_published": "2026-01-01T16:25:50Z", - "date": "2026-01-01T16:25:50Z" - } - , - { - "id": "/designs/alm/", - "url": "/designs/alm/", - "title": "Application Lifecycle Management", - "date_published": "2026-01-01T16:25:50Z", - "date": "2026-01-01T16:25:50Z" - } - , { "id": "/archives/", "url": "/archives/", diff --git a/docs/sass/style.css b/docs/sass/style.css index 21c9b8b0..1db4dbe7 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}html::-webkit-scrollbar{width:16px}::-webkit-scrollbar{width:16px}html::-webkit-scrollbar-thumb{background:linear-gradient(var(--accent-coral-dark),var(--accent-coral));background-clip:content-box;border:2px solid transparent;border-radius:2rem}::-webkit-scrollbar-thumb{background:linear-gradient(var(--accent-coral-dark),var(--accent-coral));background-clip:content-box;border:2px solid transparent;border-radius:2rem}html::-webkit-scrollbar-track{border:1px solid var(--earth-sage);background:0 0;border-radius:2rem;padding:0 2px}::-webkit-scrollbar-track{border:1px solid var(--earth-sage);background:0 0;border-radius:2rem;padding:0 2px}@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;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-sm,.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{-ms-flex-direction:column;flex-direction:column;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:center;align-self:center;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}html::-webkit-scrollbar{width:16px}::-webkit-scrollbar{width:16px}html::-webkit-scrollbar-thumb{background:linear-gradient(var(--accent-coral-dark),var(--accent-coral));background-clip:content-box;border:2px solid transparent;border-radius:2rem}::-webkit-scrollbar-thumb{background:linear-gradient(var(--accent-coral-dark),var(--accent-coral));background-clip:content-box;border:2px solid transparent;border-radius:2rem}html::-webkit-scrollbar-track{border:1px solid var(--earth-sage);background:0 0;border-radius:2rem;padding:0 2px}::-webkit-scrollbar-track{border:1px solid var(--earth-sage);background:0 0;border-radius:2rem;padding:0 2px}@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;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-around{-ms-flex-pack:distribute!important;justify-content:space-around!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-sm,.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{-ms-flex-direction:column;flex-direction:column;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:center;align-self:center;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 e0c108df..511f5672 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -91,26 +91,6 @@ 2025-12-03T21:10:08.000Z - - https://www.adamjolicoeur.com/designs/alm/ - 2026-01-01T16:25:50.000Z - - - - https://www.adamjolicoeur.com/designs/component-library/ - 2026-01-01T16:25:50.000Z - - - - https://www.adamjolicoeur.com/designs/task-it/ - 2026-01-01T16:25:50.000Z - - - - https://www.adamjolicoeur.com/ - 2026-01-05T16:14:23.050Z - - https://www.adamjolicoeur.com/apps/taskstat-privacy.html 2026-01-05T19:31:33.000Z @@ -126,11 +106,6 @@ 2026-01-19T16:58:02.000Z - - https://www.adamjolicoeur.com/development/archparser/ - 2026-01-19T16:58:02.000Z - - https://www.adamjolicoeur.com/presentations/ 2026-01-19T16:58:02.000Z @@ -176,4 +151,34 @@ 2026-03-25T23:19:14.237Z + + https://www.adamjolicoeur.com/case-studies/soccertracker/ + 2026-03-26T01:32:09.000Z + + + + https://www.adamjolicoeur.com/designs/alm/ + 2026-03-26T01:47:27.000Z + + + + https://www.adamjolicoeur.com/designs/component-library/ + 2026-03-26T01:47:27.000Z + + + + https://www.adamjolicoeur.com/designs/task-it/ + 2026-03-26T01:47:27.000Z + + + + https://www.adamjolicoeur.com/development/archparser/ + 2026-03-26T01:47:27.000Z + + + + https://www.adamjolicoeur.com/ + 2026-03-26T01:59:11.541Z + + diff --git a/src/assets/img-raw/soccergametracker-phone-history-details.png b/src/assets/img-raw/soccergametracker-phone-history-details.png new file mode 100644 index 00000000..a74fedec Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-history-details.png differ diff --git a/src/assets/img-raw/soccergametracker-phone-history.png b/src/assets/img-raw/soccergametracker-phone-history.png new file mode 100644 index 00000000..86144b70 Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-history.png differ diff --git a/src/assets/img-raw/soccergametracker-phone-livegame.png b/src/assets/img-raw/soccergametracker-phone-livegame.png new file mode 100644 index 00000000..22dea14a Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-livegame.png differ diff --git a/src/assets/img-raw/soccergametracker-phone-newgame.png b/src/assets/img-raw/soccergametracker-phone-newgame.png new file mode 100644 index 00000000..bda0c653 Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-newgame.png differ diff --git a/src/assets/img-raw/soccergametracker-phone-rosters.png b/src/assets/img-raw/soccergametracker-phone-rosters.png new file mode 100644 index 00000000..3decd897 Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-rosters.png differ diff --git a/src/assets/img-raw/soccergametracker-phone-subs-01.png b/src/assets/img-raw/soccergametracker-phone-subs-01.png new file mode 100644 index 00000000..585f5826 Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-subs-01.png differ diff --git a/src/assets/img-raw/soccergametracker-phone-subs-02.png b/src/assets/img-raw/soccergametracker-phone-subs-02.png new file mode 100644 index 00000000..0a7baca3 Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-subs-02.png differ diff --git a/src/assets/img-raw/soccergametracker-phone-subs-03.png b/src/assets/img-raw/soccergametracker-phone-subs-03.png new file mode 100644 index 00000000..7cebcdcf Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-subs-03.png differ diff --git a/src/assets/img-raw/soccergametracker-phone-summary.png b/src/assets/img-raw/soccergametracker-phone-summary.png new file mode 100644 index 00000000..356c6306 Binary files /dev/null and b/src/assets/img-raw/soccergametracker-phone-summary.png differ diff --git a/src/assets/img/soccergametracker- ingamesummary-thumb.webp b/src/assets/img/soccergametracker- ingamesummary-thumb.webp new file mode 100644 index 00000000..19855b1f Binary files /dev/null and b/src/assets/img/soccergametracker- ingamesummary-thumb.webp differ diff --git a/src/assets/img/soccergametracker- ingamesummary.webp b/src/assets/img/soccergametracker- ingamesummary.webp new file mode 100644 index 00000000..a7ddbcf2 Binary files /dev/null and b/src/assets/img/soccergametracker- ingamesummary.webp differ diff --git a/src/assets/img/soccergametracker-addnewplayer-thumb.webp b/src/assets/img/soccergametracker-addnewplayer-thumb.webp new file mode 100644 index 00000000..2a4bccae Binary files /dev/null and b/src/assets/img/soccergametracker-addnewplayer-thumb.webp differ diff --git a/src/assets/img/soccergametracker-addnewplayer.webp b/src/assets/img/soccergametracker-addnewplayer.webp new file mode 100644 index 00000000..fb28296b Binary files /dev/null and b/src/assets/img/soccergametracker-addnewplayer.webp differ diff --git a/src/assets/img/soccergametracker-endgame-thumb.webp b/src/assets/img/soccergametracker-endgame-thumb.webp new file mode 100644 index 00000000..7c3b068c Binary files /dev/null and b/src/assets/img/soccergametracker-endgame-thumb.webp differ diff --git a/src/assets/img/soccergametracker-endgame.webp b/src/assets/img/soccergametracker-endgame.webp new file mode 100644 index 00000000..bd5b9e71 Binary files /dev/null and b/src/assets/img/soccergametracker-endgame.webp differ diff --git a/src/assets/img/soccergametracker-firsthalfsummary-thumb.webp b/src/assets/img/soccergametracker-firsthalfsummary-thumb.webp new file mode 100644 index 00000000..279a924f Binary files /dev/null and b/src/assets/img/soccergametracker-firsthalfsummary-thumb.webp differ diff --git a/src/assets/img/soccergametracker-firsthalfsummary.webp b/src/assets/img/soccergametracker-firsthalfsummary.webp new file mode 100644 index 00000000..46483408 Binary files /dev/null and b/src/assets/img/soccergametracker-firsthalfsummary.webp differ diff --git a/src/assets/img/soccergametracker-gamedetails-thumb.webp b/src/assets/img/soccergametracker-gamedetails-thumb.webp new file mode 100644 index 00000000..25175eee Binary files /dev/null and b/src/assets/img/soccergametracker-gamedetails-thumb.webp differ diff --git a/src/assets/img/soccergametracker-gamedetails.webp b/src/assets/img/soccergametracker-gamedetails.webp new file mode 100644 index 00000000..cff54486 Binary files /dev/null and b/src/assets/img/soccergametracker-gamedetails.webp differ diff --git a/src/assets/img/soccergametracker-goalassignment-thumb.webp b/src/assets/img/soccergametracker-goalassignment-thumb.webp new file mode 100644 index 00000000..30427662 Binary files /dev/null and b/src/assets/img/soccergametracker-goalassignment-thumb.webp differ diff --git a/src/assets/img/soccergametracker-goalassignment.webp b/src/assets/img/soccergametracker-goalassignment.webp new file mode 100644 index 00000000..f701132f Binary files /dev/null and b/src/assets/img/soccergametracker-goalassignment.webp differ diff --git a/src/assets/img/soccergametracker-halftime-thumb.webp b/src/assets/img/soccergametracker-halftime-thumb.webp new file mode 100644 index 00000000..2461ba19 Binary files /dev/null and b/src/assets/img/soccergametracker-halftime-thumb.webp differ diff --git a/src/assets/img/soccergametracker-halftime.webp b/src/assets/img/soccergametracker-halftime.webp new file mode 100644 index 00000000..ece26585 Binary files /dev/null and b/src/assets/img/soccergametracker-halftime.webp differ diff --git a/src/assets/img/soccergametracker-history-thumb.webp b/src/assets/img/soccergametracker-history-thumb.webp new file mode 100644 index 00000000..ee820d4c Binary files /dev/null and b/src/assets/img/soccergametracker-history-thumb.webp differ diff --git a/src/assets/img/soccergametracker-history.webp b/src/assets/img/soccergametracker-history.webp new file mode 100644 index 00000000..978f9963 Binary files /dev/null and b/src/assets/img/soccergametracker-history.webp differ diff --git a/src/assets/img/soccergametracker-history02-thumb.webp b/src/assets/img/soccergametracker-history02-thumb.webp new file mode 100644 index 00000000..0c38bfa6 Binary files /dev/null and b/src/assets/img/soccergametracker-history02-thumb.webp differ diff --git a/src/assets/img/soccergametracker-history02.webp b/src/assets/img/soccergametracker-history02.webp new file mode 100644 index 00000000..59d7880a Binary files /dev/null and b/src/assets/img/soccergametracker-history02.webp differ diff --git a/src/assets/img/soccergametracker-newgame-thumb.webp b/src/assets/img/soccergametracker-newgame-thumb.webp new file mode 100644 index 00000000..c74c2fc1 Binary files /dev/null and b/src/assets/img/soccergametracker-newgame-thumb.webp differ diff --git a/src/assets/img/soccergametracker-newgame.webp b/src/assets/img/soccergametracker-newgame.webp new file mode 100644 index 00000000..0d11e530 Binary files /dev/null and b/src/assets/img/soccergametracker-newgame.webp differ diff --git a/src/assets/img/soccergametracker-phone-history-details-thumb.webp b/src/assets/img/soccergametracker-phone-history-details-thumb.webp new file mode 100644 index 00000000..3ef0a78a Binary files /dev/null and b/src/assets/img/soccergametracker-phone-history-details-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-history-details.webp b/src/assets/img/soccergametracker-phone-history-details.webp new file mode 100644 index 00000000..4d4d9806 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-history-details.webp differ diff --git a/src/assets/img/soccergametracker-phone-history-thumb.webp b/src/assets/img/soccergametracker-phone-history-thumb.webp new file mode 100644 index 00000000..98b6da6f Binary files /dev/null and b/src/assets/img/soccergametracker-phone-history-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-history.webp b/src/assets/img/soccergametracker-phone-history.webp new file mode 100644 index 00000000..24fb65ea Binary files /dev/null and b/src/assets/img/soccergametracker-phone-history.webp differ diff --git a/src/assets/img/soccergametracker-phone-livegame-thumb.webp b/src/assets/img/soccergametracker-phone-livegame-thumb.webp new file mode 100644 index 00000000..1f2082a6 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-livegame-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-livegame.webp b/src/assets/img/soccergametracker-phone-livegame.webp new file mode 100644 index 00000000..8ce97c47 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-livegame.webp differ diff --git a/src/assets/img/soccergametracker-phone-newgame-thumb.webp b/src/assets/img/soccergametracker-phone-newgame-thumb.webp new file mode 100644 index 00000000..378d04aa Binary files /dev/null and b/src/assets/img/soccergametracker-phone-newgame-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-newgame.webp b/src/assets/img/soccergametracker-phone-newgame.webp new file mode 100644 index 00000000..60d102a0 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-newgame.webp differ diff --git a/src/assets/img/soccergametracker-phone-rosters-thumb.webp b/src/assets/img/soccergametracker-phone-rosters-thumb.webp new file mode 100644 index 00000000..91f4ff6e Binary files /dev/null and b/src/assets/img/soccergametracker-phone-rosters-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-rosters.webp b/src/assets/img/soccergametracker-phone-rosters.webp new file mode 100644 index 00000000..b6114b9f Binary files /dev/null and b/src/assets/img/soccergametracker-phone-rosters.webp differ diff --git a/src/assets/img/soccergametracker-phone-subs-01-thumb.webp b/src/assets/img/soccergametracker-phone-subs-01-thumb.webp new file mode 100644 index 00000000..33e2756d Binary files /dev/null and b/src/assets/img/soccergametracker-phone-subs-01-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-subs-01.webp b/src/assets/img/soccergametracker-phone-subs-01.webp new file mode 100644 index 00000000..034ff885 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-subs-01.webp differ diff --git a/src/assets/img/soccergametracker-phone-subs-02-thumb.webp b/src/assets/img/soccergametracker-phone-subs-02-thumb.webp new file mode 100644 index 00000000..7eca5a55 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-subs-02-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-subs-02.webp b/src/assets/img/soccergametracker-phone-subs-02.webp new file mode 100644 index 00000000..7b5ef5bf Binary files /dev/null and b/src/assets/img/soccergametracker-phone-subs-02.webp differ diff --git a/src/assets/img/soccergametracker-phone-subs-03-thumb.webp b/src/assets/img/soccergametracker-phone-subs-03-thumb.webp new file mode 100644 index 00000000..0f1b4293 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-subs-03-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-subs-03.webp b/src/assets/img/soccergametracker-phone-subs-03.webp new file mode 100644 index 00000000..6984bfcc Binary files /dev/null and b/src/assets/img/soccergametracker-phone-subs-03.webp differ diff --git a/src/assets/img/soccergametracker-phone-summary-thumb.webp b/src/assets/img/soccergametracker-phone-summary-thumb.webp new file mode 100644 index 00000000..d8640397 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-summary-thumb.webp differ diff --git a/src/assets/img/soccergametracker-phone-summary.webp b/src/assets/img/soccergametracker-phone-summary.webp new file mode 100644 index 00000000..e88f2493 Binary files /dev/null and b/src/assets/img/soccergametracker-phone-summary.webp differ diff --git a/src/assets/img/soccergametracker-playerstats01-thumb.webp b/src/assets/img/soccergametracker-playerstats01-thumb.webp new file mode 100644 index 00000000..5e726829 Binary files /dev/null and b/src/assets/img/soccergametracker-playerstats01-thumb.webp differ diff --git a/src/assets/img/soccergametracker-playerstats01.webp b/src/assets/img/soccergametracker-playerstats01.webp new file mode 100644 index 00000000..0bc84313 Binary files /dev/null and b/src/assets/img/soccergametracker-playerstats01.webp differ diff --git a/src/assets/img/soccergametracker-playerstats02-thumb.webp b/src/assets/img/soccergametracker-playerstats02-thumb.webp new file mode 100644 index 00000000..f4109931 Binary files /dev/null and b/src/assets/img/soccergametracker-playerstats02-thumb.webp differ diff --git a/src/assets/img/soccergametracker-playerstats02.webp b/src/assets/img/soccergametracker-playerstats02.webp new file mode 100644 index 00000000..64670a00 Binary files /dev/null and b/src/assets/img/soccergametracker-playerstats02.webp differ diff --git a/src/assets/img/soccergametracker-roster-thumb.webp b/src/assets/img/soccergametracker-roster-thumb.webp new file mode 100644 index 00000000..f4005e62 Binary files /dev/null and b/src/assets/img/soccergametracker-roster-thumb.webp differ diff --git a/src/assets/img/soccergametracker-roster.webp b/src/assets/img/soccergametracker-roster.webp new file mode 100644 index 00000000..be270655 Binary files /dev/null and b/src/assets/img/soccergametracker-roster.webp differ diff --git a/src/assets/img/soccergametracker-secondhalfsummary-thumb.webp b/src/assets/img/soccergametracker-secondhalfsummary-thumb.webp new file mode 100644 index 00000000..eda55618 Binary files /dev/null and b/src/assets/img/soccergametracker-secondhalfsummary-thumb.webp differ diff --git a/src/assets/img/soccergametracker-secondhalfsummary.webp b/src/assets/img/soccergametracker-secondhalfsummary.webp new file mode 100644 index 00000000..f2a646d8 Binary files /dev/null and b/src/assets/img/soccergametracker-secondhalfsummary.webp differ diff --git a/src/assets/img/soccergametracker-startgame-thumb.webp b/src/assets/img/soccergametracker-startgame-thumb.webp new file mode 100644 index 00000000..e8a9811e Binary files /dev/null and b/src/assets/img/soccergametracker-startgame-thumb.webp differ diff --git a/src/assets/img/soccergametracker-startgame.webp b/src/assets/img/soccergametracker-startgame.webp new file mode 100644 index 00000000..b40413f3 Binary files /dev/null and b/src/assets/img/soccergametracker-startgame.webp differ diff --git a/src/assets/img/soccergametracker-substituteprompt-thumb.webp b/src/assets/img/soccergametracker-substituteprompt-thumb.webp new file mode 100644 index 00000000..c1cbb5fa Binary files /dev/null and b/src/assets/img/soccergametracker-substituteprompt-thumb.webp differ diff --git a/src/assets/img/soccergametracker-substituteprompt.webp b/src/assets/img/soccergametracker-substituteprompt.webp new file mode 100644 index 00000000..07bb853c Binary files /dev/null and b/src/assets/img/soccergametracker-substituteprompt.webp differ diff --git a/src/assets/img/soccergametracker-substitutionsummary-thumb.webp b/src/assets/img/soccergametracker-substitutionsummary-thumb.webp new file mode 100644 index 00000000..4fdeb8be Binary files /dev/null and b/src/assets/img/soccergametracker-substitutionsummary-thumb.webp differ diff --git a/src/assets/img/soccergametracker-substitutionsummary.webp b/src/assets/img/soccergametracker-substitutionsummary.webp new file mode 100644 index 00000000..6134b98f Binary files /dev/null and b/src/assets/img/soccergametracker-substitutionsummary.webp differ diff --git a/src/pages/case-studies/case-studies.json b/src/pages/case-studies/case-studies.json new file mode 100644 index 00000000..2dd05d0b --- /dev/null +++ b/src/pages/case-studies/case-studies.json @@ -0,0 +1,4 @@ +{ + "layout": "page", + "permalink": "/case-studies/{{ page.fileSlug }}/" +} diff --git a/src/pages/case-studies/soccertracker.md b/src/pages/case-studies/soccertracker.md new file mode 100644 index 00000000..003b7b70 --- /dev/null +++ b/src/pages/case-studies/soccertracker.md @@ -0,0 +1,212 @@ +--- +layout: markdown.njk +title: 'Soccer Game Tracker' +date: git Last Modified +abbreviation: 'soccertracker' +description: 'Native iOS app for coaches to track game data. Solo project, in active use.' +eleventyNavigation: + key: CaseStudies + parent: CaseStudies + order: 2 +containers: true +--- + +:::section + + ## Project Overview + + > A native iOS app, built by a coach, who needed fast and reliable game tracking without surrendering data to a third-party platform — designed for the sideline, built in Swift. + + :::card + + **ROLE**: Designer & Developer + + **STACK**: SwiftUI + + **STATUS**: Work in progress + +::: + +::::section + +## Introduction + + Coaching a youth soccer team generates a surprising amount of data. Scores, substitutions, player minutes, goals, assists, saves, cards. The problem isn't that the data is hard to capture — it's that every existing option forces a tradeoff I wasn't willing to make. Pen and paper is fast but produces nothing useful afterward. Third-party apps are convenient but own your data, require accounts, and are built for organizations, not individual coaches. I wanted something purpose-built for how I actually work on a sideline: fast to set up, minimal interaction during play, and with data I control entirely. + +
+
+
+
+ New Game setup screen +
set the roster - starters and substitutes
+
+
+
+
+
+
+ New Game setup screen +
add game info - team size, location, date & time
+
+
+
+
+:::: + +::::section +## The harder right choice + + I built SoccerGameTracker as a native iOS app in Swift — solo, from scratch. The easier path would have been a PWA or React Native wrapper; I've shipped both, and they're faster to build. I chose Swift because a sideline app has a specific performance contract: launch instantly, respond without lag when a goal gets scored, never drop data if the phone gets pocketed. Native with local storage and no network dependency satisfies all three. No sync to worry about, no account to authenticate, no API that might be down at kickoff. + + > every decision went through one person - me + + **Constraint clarified scope**. Without a backend, multi-device sync and shared rosters aren't on the table — and that's fine. Knowing what the app isn't made it easier to build what it is. I handled both the design and implementation entirely, which meant every decision — from interaction model to data structure — went through one person. That's mostly an advantage when you need to move fast and stay opinionated. +:::: + +::::section + + ## Designing for the sideline + + > The core design problem is attention. + + During a live game, a coach is watching players, calling substitutions, talking to parents. The app gets a glance and a thumb tap, not focused interaction. Every decision on the Live Game screen follows from that. + +
+
Pregame
+
+ The pre-game setup flow handles the overhead up front. +
New Game collects opposition, date, location, and half duration — everything you'd put on a physical scoresheet — plus roster selection from a pre-built player list with jersey number and position. +
The Game vs. Scrimmage toggle is a small but deliberate decision: scrimmages have different stakes and different lineup dynamics, and I wanted the history to reflect that distinction clearly. +
+
+ +
+
Scoreboard & Quick Actions
+
+ The scoreboard and half timer sit at the top, readable in a second. The Quick Actions section — Team Goal and Opponent Goal — are the two largest tap targets in the app, sized and colored for immediate recognition in any lighting. Correction actions (Remove Team Goal, Subtract Goal) are present but visually subordinate: same area, smaller, lighter. Reachable when you need them, harder to hit by accident. +
+
+ +
+
Players & Activity
+
+ Below the quick actions is where the app earns its depth. Each player in the active roster is tappable, opening a detail view where you can log individual stats in real time: goals, assists, saves, shots, yellow cards, red cards. Every action is timestamped and tied to the game half — building a full action log that the post-game summary renders as a timeline. That's the data that makes post-game review actually useful: not just who won, but who contributed, when, and how often. +
+
+ +
+
+
+ Live Game screen showing scoreboard, timer, Quick Actions, and player list +
Live Game screen showing scoreboard, timer, Quick Actions, and player list
+
+
+
+
+ + ### Substitutions + + :::card + Substitutions were a meaningful product decision. Mid-game sub support — with a distinct "substituted out" state separate from bench status — reflects how substitutions actually work: a player who comes off isn't the same as a player who never started. Getting that distinction right matters for per-player stats to be accurate. + ::: + +
+
+
+
+ View a player's stats and position before substituting them on or off +
View a player's stats and position before substituting them on or off
+
+
+
+
+
+
+ Substitutes cannot accidentally have statistics assigned +
Substitutes cannot accidentally have statistics assigned
+
+
+
+
+
+
+ View who subbed in and out of the game by half +
View who subbed in and out of the game by half
+
+
+
+
+:::: + +::::section + + ## After the game + + > As a coach, being able to view historical information is a key part in planning practices, setting lineups, and determining strategy. + + ### History + +
+
+
+
+ View historical game data, zooming in to see each game's details +
View historical game data, with key info front and center
+
+
+
+
+
+
+ View historical game data, zooming in to see each game's details +
Zooming into any game shows player-by-player stats
+
+
+
+
+:::: + +::::section + ## Where it stands + + :::card + The app is in active use this season, tested against the real constraint it was built for: a sideline, in real game conditions. Feedback from that use has been indispensable, with the per-player stats used between games to inform lineup and substitution planning. That's the outcome I was building toward. + + What real use has surfaced is mostly sequencing: the transition from pre-game setup into the live view needs less friction, and the post-game summary screen is still being refined. **Those are the next iterations.** + ::: + + > An App Store release is planned once the final rough edges are resolved. The app does one thing, does it reliably, and doesn't ask for anything it doesn't need. +:::: diff --git a/src/sass/_layout.scss b/src/sass/_layout.scss index 72ea329a..e1f91f17 100644 --- a/src/sass/_layout.scss +++ b/src/sass/_layout.scss @@ -15,6 +15,9 @@ section { .justify-content-between { justify-content: space-between !important; } +.justify-content-around { + justify-content: space-around !important; +} .justify-content-end { justify-content: flex-end !important; }