{{ .Title }}
+{{ .Summary }}
+diff --git a/README.md b/README.md
index 18e0744..121cfad 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,17 @@
# Portfolio and case studies
Showcase of past UI/UX work by Andrew Gioia.
+
+## Local development
+
+Run the Hugo dev server:
+
+```bash
+hugo server -D
+```
+
+Build the site:
+
+```bash
+hugo
+```
diff --git a/archetypes/default.md b/archetypes/default.md
new file mode 100644
index 0000000..5fadf6a
--- /dev/null
+++ b/archetypes/default.md
@@ -0,0 +1,5 @@
+---
+title: "{{ replace .File.ContentBaseName `-` ` ` | title }}"
+date: {{ .Date }}
+draft: true
+---
diff --git a/assets/css/site.css b/assets/css/site.css
new file mode 100644
index 0000000..a683224
--- /dev/null
+++ b/assets/css/site.css
@@ -0,0 +1,513 @@
+:root {
+ --bg: #f0ede6;
+ --text: #171717;
+ --hover: #070707;
+ --muted: #676767;
+ --faded: #979797;
+ --primary: #00b0CD;
+ --secondary: #80c0cc;
+ --gray: #6f6f6f;
+ --pink: #E463D2;
+ --cyan: #00C4D8;
+ --green: #00D771;
+ --blue: #2096F6;
+ --orange: #E78B05;
+ /*--line: rgba(23, 23, 23, 0.12);*/
+ --line: #272727;
+ --light: #dfdfdf;
+ --white: #f7f7f7;
+ --surface: rgba(255, 255, 255, 0.28);
+ --font-sans: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ --font-serif: "Source Serif", "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Georgia, serif;
+ --column-width: min(72rem, calc(100% - 3rem));
+ --content-width: min(48rem, calc(100% - 3rem));
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 14px;
+ background: var(--bg);
+}
+
+a {
+ color: inherit;
+ font-weight: 500;
+ text-decoration: underline;
+ text-decoration-thickness: 1px;
+ text-underline-offset: 0.2rem;
+
+ &:hover {
+ color: var(--hover);
+ text-decoration: underline;
+ text-decoration-thickness: 1px;
+ text-underline-offset: 0.2rem;
+ }
+}
+
+.icon {
+ align-items: center;
+ display: inline-flex;
+ flex: 0 0 auto;
+ height: 1em;
+ justify-content: center;
+ line-height: 1;
+ width: 1em;
+}
+
+.icon svg {
+ display: block;
+ height: 100%;
+ width: 100%;
+}
+
+h1 {
+ font-size: clamp(2.5rem, 10dvw, 4rem);
+ font-weight: 700;
+ letter-spacing: -0.5px;
+ line-height: 1;
+ margin: 0 0 1rem;
+}
+
+h2 {
+ font-size: clamp(1.5rem, 4vw, 2rem);
+ font-weight: 700;
+ line-height: 1.3;
+ margin: 0 0 1.5rem;
+}
+
+h3 {
+ color: var(--muted);
+ font-size: 1.4rem;
+ font-weight: 700;
+ line-height: 1.3;
+}
+
+body {
+ margin: 0 auto;
+ padding: 0;
+ min-height: 100dvh;
+ background: var(--bg);
+ color: var(--text);
+ display: grid;
+ font-family: var(--font-sans);
+ grid-template-rows: 5rem 1fr auto;
+ line-height: 1.6;
+ -webkit-font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
+ width: 100dvw;
+
+ /* site header and footer defaults */
+ > header,
+ > footer {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ }
+
+ /* site header */
+ > header {
+ border-bottom: 1px solid var(--light);
+ padding: 0 1.5rem;
+
+ .title {
+ align-items: center;
+ display: flex;
+ gap: 1rem;
+ height: 100%;
+ align-items: stretch;
+ }
+
+ .logo,
+ .page {
+ align-items: center;
+ display: flex;
+ font-size: 1.5rem;
+ gap: 0.5rem;
+ text-decoration: none;
+ }
+
+ .logo {
+ font-weight: 700;
+ }
+
+ .page {
+ font-weight: 700;
+ }
+
+ .logo:has(+ .page) {
+ color: var(--faded);
+ }
+
+ .scheme {
+ color: var(--faded);
+ }
+
+ .param {
+ color: var(--text);
+ }
+
+ nav {
+ align-items: center;
+ display: none;
+ gap: 1.5rem;
+ font-size: 1rem;
+
+ a {
+ text-decoration: none;
+ }
+ }
+ }
+
+ /* site footer */
+ > footer {
+ color: var(--muted);
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ padding-top: 2rem;
+
+ section {
+ width: var(--column-width);
+ }
+
+ #footnotes ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+
+ li {
+ display: grid;
+ grid-template-columns: 1.5rem auto;
+
+ span.symbol {
+ font-size: 1.25rem;
+ }
+ }
+ }
+ }
+}
+
+/* case study wrapper */
+main {
+ display: grid;
+ justify-items: center;
+
+ /* layout handling for the top sections */
+ header,
+ aside {
+ display: flex;
+ width: var(--column-width);
+ }
+
+ /* top hero */
+ header {
+ padding: 0;
+
+ /* temporary height clamping */
+ &:has(+ aside) {
+ display: grid;
+ align-content: end;
+ min-height: clamp(12rem, 50dvh, 18rem);
+ }
+
+ .lede {
+ margin: 1rem 0 0;
+ font-size: 1.6rem;
+ line-height: 1.4;
+ }
+ }
+
+ /* stats */
+ aside {
+ align-items: flex-start;
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+ justify-content: flex-start;
+ margin-top: 3rem;
+
+ figure {
+ display: grid;
+ grid-template-columns: 2.25rem auto;
+ grid-template-rows: 1.5rem auto;
+ margin: 0;
+ --icon: var(--blue);
+
+ span.icon {
+ width: 1.5rem;
+ height: 1.5rem;
+ color: var(--icon);
+ }
+
+ label {
+ color: var(--text);
+ font-size: 1rem;
+ text-transform: uppercase;
+ font-weight: 600;
+ }
+
+ figcaption {
+ color: var(--muted);
+ font-size: 1.05rem;
+ line-height: 1.4;
+ grid-column-start: 2;
+ }
+
+ &:nth-child(2) {
+ --icon: var(--orange);
+ }
+ &:nth-child(3) {
+ --icon: var(--green);
+ }
+ &:nth-child(4) {
+ --icon: var(--pink);
+ }
+ &:nth-child(5) {
+ --icon: var(--cyan);
+ }
+ }
+ }
+}
+
+/* case study content */
+article {
+ background: var(--white);
+ display: grid;
+ gap: 2rem;
+ grid-template-columns: 1fr;
+ justify-content: center;
+ padding: 4rem 1.5rem 3rem;
+ width: 100%;
+
+ nav#toc {
+ align-self: start;
+ position: sticky;
+ margin-left: -1.5rem;
+ top: 0;
+ width: calc(100% + 3rem);
+
+ ol {
+ border-top: 3px solid var(--light);
+ display: grid;
+ list-style: decimal-leading-zero;
+ list-style-position: inside;
+ margin: 0;
+ padding: 0;
+
+ li {
+ background: var(--white);
+ border-bottom: 1px solid var(--light);
+ height: 2.5rem;
+ padding: 0.4rem 0.25rem 0;
+
+ &::marker {
+ color: var(--muted);
+ }
+
+ &:last-child {
+ border: none;
+ }
+ }
+ }
+
+ a {
+ color: var(--muted);
+ text-decoration: none;
+ transition: padding 125ms ease;
+
+ &.active {
+ color: var(--text);
+ font-weight: 700;
+ padding-left: 0.25rem;
+ }
+
+ &:hover {
+ color: var(--text);
+ }
+ }
+ }
+
+ #content {
+ display: grid;
+ gap: 1.5rem;
+ }
+
+ section {
+ width: 100%;
+
+ intro {
+ p:first-of-type {
+ font-size: 1.1rem;
+ }
+ }
+ }
+
+ figure {
+ /*background: var(--bg);*/
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ justify-content: center;
+ margin: 2rem 0;
+ padding: 0;
+ position: relative;
+
+ img {
+ max-width: 100%;
+
+ &.desktop {
+ aspect-ratio: 1.4 / 1;
+ }
+ &.mobile {
+ aspect-ratio: 0.46 / 1;
+ height: 20rem;
+ }
+ }
+
+ figcaption {
+ color: var(--muted);
+ font-size: 0.875rem;
+ line-height: 1.5;
+ }
+ }
+}
+
+
+/**
+ * display queries */
+
+.tablet-show,
+.laptop-show,
+.display-show {
+ display: none;
+}
+
+/* tablets */
+@media (min-width: 640px)
+{
+ html {
+ font-size: 16px;
+ }
+
+ body > header {
+ padding: 0 2rem;
+
+ nav {
+ display: flex;
+ }
+ }
+
+ main {
+ header {
+ .lede {
+ max-width: 60%;
+ }
+ }
+ aside {
+ flex-direction: row;
+ gap: 2rem;
+
+ figure {
+ grid-template-columns: auto;
+ grid-template-rows: 2rem 2rem auto;
+ max-width: 20%;
+ padding-right: 1rem;
+
+ figcaption {
+ grid-column-start: 1;
+ }
+ }
+ }
+ }
+
+ .tablet-show {
+ display: block;
+ }
+ .tablet-hide {
+ display: none;
+ }
+}
+
+/* laptops */
+@media (min-width: 1024px)
+{
+ article {
+ gap: 3rem;
+ grid-template-columns: 12rem var(--content-width);
+
+ nav#toc {
+ margin-left: 0;
+ top: 4rem;
+ width: 12rem;
+
+ ol {
+ margin-top: 0.75rem;
+ }
+ }
+ }
+}
+
+/* desktops */
+@media (min-width: 1280px)
+{
+ html {
+ font-size: 17px;
+ }
+
+ article {
+ gap: 0;
+ grid-template-columns: 16rem var(--content-width) 8rem;
+ }
+}
+
+/* displays */
+@media (min-width: 1440px)
+{
+ html {
+ font-size: 18px;
+ }
+
+ article {
+ padding: 4rem 0 3rem;
+
+ nav#toc {
+ font-size: 0.925rem;
+
+ ol li {
+ padding-top: 0.5rem;
+ }
+ }
+
+ figure {
+ align-items: flex-end;
+ flex-direction: row;
+
+ figcaption {
+ font-size: 0.75rem;
+ position: absolute;
+ right: -10rem;
+ bottom: 1rem;
+ width: 8rem;
+ }
+ }
+ }
+}
+
+
+/**
+ * deprecate? */
+@media (max-width: 900px) {
+
+ article #content {
+ width: 100%;
+ }
+
+ article section {
+ width: 100%;
+ }
+}
\ No newline at end of file
diff --git a/assets/icons/briefcase.svg b/assets/icons/briefcase.svg
new file mode 100644
index 0000000..090f49a
--- /dev/null
+++ b/assets/icons/briefcase.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/calendar.svg b/assets/icons/calendar.svg
new file mode 100644
index 0000000..ab26be0
--- /dev/null
+++ b/assets/icons/calendar.svg
@@ -0,0 +1,10 @@
+
diff --git a/assets/icons/hat.svg b/assets/icons/hat.svg
new file mode 100644
index 0000000..42d5d28
--- /dev/null
+++ b/assets/icons/hat.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/pen.svg b/assets/icons/pen.svg
new file mode 100644
index 0000000..0364d38
--- /dev/null
+++ b/assets/icons/pen.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/users.svg b/assets/icons/users.svg
new file mode 100644
index 0000000..419c858
--- /dev/null
+++ b/assets/icons/users.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/content/_index.md b/content/_index.md
new file mode 100644
index 0000000..f1bd5fd
--- /dev/null
+++ b/content/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Portfolio"
+---
+
+Product case studies and selected work.
diff --git a/content/studies/_index.md b/content/studies/_index.md
new file mode 100644
index 0000000..f97a04f
--- /dev/null
+++ b/content/studies/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Case Studies"
+---
+
+Selected product design and UX case studies.
diff --git a/content/studies/legacy/img/overview-desktop.png b/content/studies/legacy/img/overview-desktop.png
new file mode 100644
index 0000000..aad40ca
Binary files /dev/null and b/content/studies/legacy/img/overview-desktop.png differ
diff --git a/content/studies/legacy/img/overview-mobile.png b/content/studies/legacy/img/overview-mobile.png
new file mode 100644
index 0000000..4da78e6
Binary files /dev/null and b/content/studies/legacy/img/overview-mobile.png differ
diff --git a/content/studies/legacy/img/overview.png b/content/studies/legacy/img/overview.png
new file mode 100644
index 0000000..51a9b0e
Binary files /dev/null and b/content/studies/legacy/img/overview.png differ
diff --git a/content/studies/legacy/index.md b/content/studies/legacy/index.md
new file mode 100644
index 0000000..1a9e3f7
--- /dev/null
+++ b/content/studies/legacy/index.md
@@ -0,0 +1,138 @@
+---
+title: "Legacy app refresh"
+layout: "study"
+slug: "legacy"
+summary: "Reshaping a complex and outdated school forms workflow into a clearer, calmer experience for administrators and families."
+draft: false
+
+hero:
+ title: "Legacy app refresh"
+ deck: "Reshaping a critical but outdated school forms workflow into a calmer, clearer experience for administrators and families."
+ tags:
+ - label: "Figma"
+ tone: "green"
+ - label: "Product Design"
+ tone: "yellow"
+ - label: "B2B SaaS"
+ tone: "cyan"
+ - label: "Workflow UX"
+ tone: "blue"
+
+study:
+ facts:
+ - label: "Role"
+ value: "Product Design"
+ icon: "hat"
+ - label: "Timeline"
+ value: "Est. 6 months, expanded to 18 months"
+ icon: "calendar"
+ - label: "Tools"
+ value: "Figma"
+ icon: "pen"
+ - label: "Industry"
+ value: "K-12 education SaaS"
+ icon: "briefcase"
+ - label: "Stakeholders"
+ value: "Product, engineering, and school operations"
+ icon: "users"
+ toc:
+ - id: "intro"
+ label: "Introduction"
+ - id: "overview"
+ label: "Project overview"
+ - id: "problems"
+ label: "Core problems"
+ - id: "context"
+ label: "Delivery context"
+ - id: "response"
+ label: "Response"
+ - id: "impact"
+ label: "Impact"
+ - id: "reflection"
+ label: "Reflection"
+ footnotes:
+ - symbol: "†"
+ note: "Product names have been changed to maintain confidentiality. I'm happy to answer product questions as needed, but would need permission to share specifics like names and customers."
+---
+
+{{< intro id="intro" title="Designing for clarity over polish in complex admin software" >}}
+
+Wallabyte† supports schools and families through critical paperwork—from permissions to registrations and even student health information. It solved this and more, but was **woefully unusable, even by admin-ware standards**. The forms experience had become frustrating enough that major customers, like NYC, were at risk of churn unless the workflow became **clearer, calmer, and easier to use**.
+
+This case study covers how I approached that challenge—from identifying the highest impact issues to shaping a more coherent forms experience—all within the paradox of a userbase simultaneously frustrated yet resistant to change.
+
+It is also meant to show how I simplify complex systems; work in a difficult set of circumstances; and **design to please the user, not myself**.
+
+{{< /intro >}}
+
+{{< overview
+ id="overview"
+ title="Project overview"
+>}}
+
+Wallabyte had two halves: an administrative app for creating and managing forms, and a parent- and staff-facing app for completing forms. This redesign only touched this second, smaller part—called **Wallabyte Central**—due to the particular churn risk it was creating.
+
+The existing experience had become painful enough that major customers, including NYC, were at risk of leaving unless the product became significantly easier to use. My job was to figure out how to make their mobile and desktop experiences more efficient and pleasant.
+
+At the same time, Wallabyte was also rebranding as **Schooltastic Forms**, now a year after it had been acquired by Schooltastic. This project was my first interaction with this app and team, and not only did I have to get up to speed quickly, its users could be seeing a lot of sudden change.
+
+
+
{{ .Section }}
+{{ .Summary }}
+No entries yet.
+ {{ end }} +{{ .Section | title }}
+{{ . }}
+ {{ end }} +{{ . }}
+ {{- end -}} + {{- if and (not .Params.hero.deck) .Summary -}} +{{ .Summary }}
+ {{- end -}} +Portfolio
++ A custom Hugo setup for showcasing product and UX work without relying on a theme. +
+Selected work
+{{ .Summary }}
+Footer.
+