is a list item again */
+ &.group {
+ height: auto;
+ display: list-item;
+ padding: 0.4rem 0 0;
+
+ a {
+ display: inline-block;
+ padding: 0;
+ text-indent: 0;
+ }
+
+ > a {
+ padding: 0 0 0.5rem;
+
+ &::before {
display: none;
}
+ }
- a {
+ &:has(li.active) {
+ > a {
+ color: var(--text);
padding-left: 0.25rem;
}
}
}
+
+ /* active item */
+ &.active
+ {
+ &::after {
+ display: none;
+ }
+
+ a {
+ padding-left: 0.25rem;
+ }
+ }
}
}
+ /* homepage artwork moves to the right as a stack */
body#default
{
main
@@ -1229,7 +1538,8 @@ body#values {
padding: 0 1.5rem;
hgroup {
- padding: 10dvh 0 0;
+ margin-top: 10dvh;
+ padding: 0;
}
#semicircle {
@@ -1309,16 +1619,51 @@ body#values {
}
}
+ /* single page docs */
body#values main > article {
- padding: 10dvh 0 0;
+ padding: 10dvh 0 5dvh;
> header {
- padding: 0 10dvw 0 0;
+ padding: 0 5dvw 0 5dvw; /* make this 0 10dvw 0 0 to use same left position as rest of site */
}
> section {
grid-column-start: 2;
}
}
+
+ /* honeycomb case study artwork now includes the triangle */
+ body#honeycomb
+ {
+ main > header
+ {
+ aside {
+ margin-bottom: 12dvh;
+ }
+ #grid {
+ --shape-size: max(16dvh, 6rem);
+
+ #shapes {
+ gap: 4rem;
+ grid-template-columns: 1fr 1fr 1fr 1fr;
+
+ #triangle {
+ display: block;
+ }
+ }
+
+ #circle::before,
+ #rectangle::before,
+ #rectangle::after {
+ left: -4rem;
+ width: 4rem;
+ }
+ #rectangle::after {
+ left: auto;
+ right: -4rem;
+ }
+ }
+ }
+ }
}
/* desktops */
@@ -1336,13 +1681,15 @@ body#values {
font-size: 17px;
}
+ /* move the page title down */
main > header
{
> hgroup {
- padding-top: 6rem;
+ margin-top: 6rem;
}
}
+ /* homepage footer alignment */
body#default
{
> footer {
@@ -1355,6 +1702,7 @@ body#values {
}
}
+ /* single page docs */
body#values main > article
{
> header {
@@ -1380,6 +1728,7 @@ body#values {
line-height: 1.6;
}
+ /* more room on the top pane and figures */
main
{
> header > aside {
@@ -1410,15 +1759,16 @@ body#values {
font-size: 0.925rem;
ol li {
- padding-top: 0.5rem;
+ padding-top: 0.5rem;
}
}
}
+ /* case studies cards move beyond the edges */
section#studies
{
article {
- width: calc(var(--column-width) + 4rem);
+ width: calc(var(--column-width) + 4rem + 8px);
}
}
}
diff --git a/content/studies/honeycomb/index.md b/content/studies/honeycomb/index.md
new file mode 100644
index 0000000..1c36aa7
--- /dev/null
+++ b/content/studies/honeycomb/index.md
@@ -0,0 +1,324 @@
+---
+title: "Accessible design system"
+layout: "study"
+slug: "honeycomb"
+summary: "Building a native-first, accessible design system that could actually be adopted across six very different education products."
+draft: false
+
+hero:
+ title: "Accessible design system"
+ deck: "Building a **native-first, accessible design system** to support six different products, tech stacks, and development timelines."
+ html: '
'
+list:
+ more: "My company needed a design system to unify six very different products as one new edtech platform. We did that while managing very different frontends and skill levels, urgent accessibility needs, and no single framework that everyone could share."
+ color: yellow
+ facts:
+ - key: Role
+ color: blue
+ - key: tools
+ color: red
+ - key: industry
+ color: green
+study:
+ facts:
+ - label: "Role"
+ value: "Principal designer, frontend architect"
+ icon: "hat"
+ class: "min"
+ - label: "Timeline"
+ value: "Ongoing production system"
+ icon: "calendar"
+ - label: "Tools"
+ value: "HTML, CSS, JS, Typescript, Figma"
+ icon: "pen"
+ - label: "Industry"
+ value: "K-12 education SaaS"
+ icon: "briefcase"
+ - label: "Scope"
+ value: "6 products, many stacks"
+ icon: "users"
+ toc:
+ - id: "intro"
+ label: "Introduction"
+ - id: "overview"
+ label: "Project overview"
+ - id: "constraints"
+ label: "Adoption constraints"
+ - id: highlights
+ label: "Highlights"
+ num: "04."
+ children:
+ - id: "native"
+ label: "Browser-native"
+ - id: "layout"
+ label: "Unified layout"
+ - id: "updates"
+ label: "Stable updates"
+ - id: "docs"
+ label: "Documentation"
+ - id: "impact"
+ label: "Impact"
+ - id: "reflection"
+ label: "Reflection"
+ footnotes:
+ - symbol: "†"
+ note: "The naming here is intentionally a little in flux. Honeycomb is the public design-system name; Schooltastic is the anonymized company/product framing used elsewhere in this portfolio. I may replace this with SchoolStatus where it makes sense, since that connection is easy to infer."
+ - symbol: "‡"
+ note: "The DOJ's Title II web and mobile accessibility rule set WCAG 2.1 Level AA as the technical standard for state and local government web content and mobile apps. The original 2026 and 2027 compliance dates were later extended in 2026, but the rule's substance and procurement pressure remained important for education vendors."
+---
+
+{{< intro id="intro" title="A design system is only valuable if teams can actually use it" >}}
+
+Honeycomb was a large, foundational design-system effort: a **unified design language and implemented component library for _six acquired products_** that all looked, felt, and behaved differently. We designed and built 40+ components, plus the supporting patterns, layout scaffolds, utilities, documentation, and [connected](https://github.com/figma/code-connect) Figma components needed to make those products feel like they belonged to the same company.
+
+But this case study is not primarily about the mechanics of building a design system. Many systems define tokens, document components, and create a composable UI. The more interesting problem was **how we designed Honeycomb from the start _to be used_ inside our particular set of constraints**: different products, different codebases, different teams, different levels of frontend skill, and very different modernization timelines.
+
+That shaped both the earliest decisions and the later priorities: browser-native web technologies, a small JavaScript footprint, CSS variables for theming, progressive adoption, and [unusually thorough documentation](https://honeycomb.style). The system had to meet teams where they were, so the central design and engineering constraint became: make the right thing, but make it easy to adopt before the organization was technically uniform enough to deserve a perfect system.
+
+{{< /intro >}}
+
+{{< overview
+ id="overview"
+ title="Project overview"
+>}}
+
+Honeycomb was built to support six education products with different histories, product roadmaps, engineering teams, and frontend maturity. We had products that ran the gamut from "we manually copy `jquery.min.js` and cannot install npm" to "everything is React." The system also existed in two connected places: a Figma component library for design work, and an implemented HTML/CSS package documented through a hand-built site.
+
+The package was intentionally native-first. Most components shipped as documented **HTML plus compiled CSS, with minimal JavaScript reserved for interactions that could not be handled reliably** with browser behavior alone. That meant product teams could drop in the CSS, copy the documented markup into whatever view file or component system they were using, and get a large amount of visual consistency and accessibility handling without committing to React, installing Tailwind, or rebuilding their app shell.
+
+This was also a design strategy. Our products needed to feel like one company without erasing their existing workflows overnight. The system provided shared foundations: header, left navigation, layout scaffolding, form controls, tables, buttons, alerts, theming, icons, and more complex components like datepickers and drawers. From there, each product could adopt progressively.
+
+{{< /overview >}}
+
+{{< problems id="constraints" title="Adoption constraints" >}}
+
+The first major decision was accepting that adoption mattered more than technical purity. While many were pushing React aggressively, our reality was that we could not pick a fashionable component model and tell every product team to catch up.
+
+{{< problem
+ title="Six products had six different technical realities"
+>}}
+
+The system had to support product teams with very different stacks and skill levels. Some could add one more npm package easily. Some were entirely React-based and would eventually wrap Honeycomb in React components. Others needed a more basic path: copy a CSS file, include a font folder, and use documented HTML in server-rendered views.
+
+That ruled out a React-only system as the first deliverable. It also ruled out a system that assumed every team wanted to learn Tailwind, Sass, or a new build pipeline. The adoption path had to be boring in the best possible way š.
+
+{{< /problem >}}
+
+{{< problem
+ title="Adoption had to be progressive with no massive rewrites"
+>}}
+
+There was no appetite for a synchronized redesign across every product. Each app had its own customer expectations and roadmap pressure, so **Honeycomb had to support progressive adoption**: a new header now, tables and form controls there, updated buttons and modals in the next feature area, then deeper layout changes when a team was ready.
+
+Components therefore needed stable class names that were prefixed to avoid any collisions, predictable HTML that would ideally never change, and compatibility with existing application markup. Our goal was that if a team adopted a component once, **future Honeycomb updates should only change presentation through CSS** and never require an underlying HTML update.
+
+{{< /problem >}}
+
+{{< problem
+ title="The system had to cover patterns, not just components"
+>}}
+
+The most valuable work was often not a button or alert, it was the repeatable and difficult stuff product teams kept rebuilding inconsistently: app shells, responsive layouts, table controls, drawer-based filters, form sections, empty states, and primary/secondary navigation.
+
+By documenting those patterns, the design team handled decisions that would otherwise be made inconsistently across teams. Honeycomb became a shared product language, not just a visual toolkit. **Our design team became a shared product support team as well.**
+
+{{< /problem >}}
+
+{{< problem
+ title="Federal accessibility requirements created real urgency"
+>}}
+
+Accessibility was not just a quality goal or a design value—it had become a business requirement. Most Schooltastic customers are public school districts, and the [DOJ's Title II web and mobile accessibility rule](https://www.ada.gov/resources/2024-03-08-web-rule/) created a concrete expectation that public entities would bring web content and mobile apps into [WCAG 2.1 Level AA](https://www.w3.org/TR/WCAG21/) conformance‡.
+
+For an edtech platform this meant we could lose some of our largest districts (and theoretically almost all of our customers) if we didn't meet these requirements. It also meant that the the product teams could not just treat accessibility as something to "handle whenever we feel like it," and we could not rely on every team independently interpreting the WCAG, writing accessible markup, handling keyboard behavior, and testing every interaction with a screen reader. **The company needed accessibility that product teams could pick up off the shelf** as part of normal feature work.
+
+Honeycomb had to absorb as much of that responsibility as possible and we took it very seriously.
+
+* Everyone on the team got accessibility training.
+* Documentation included implementation rules and accessible attributes in every component, and distilled down requirements to plain English.
+* Our team tested everything with screen readers and ran through various disability simulators.
+* We also leveraged browser-native elements that brought accessibility in for free as much as possible.
+
+{{< /problem >}}
+
+{{< /problems >}}
+
+
+
+{{< section id="native" title="Browser-native by default" >}}
+
+The most important implementation decision was that Honeycomb would not belong to any single product stack or require any kind of upgrade. We decided to be as out-of-the-way as possible and belong primarily to the browser.
+
+Despite the extended discussion, this pretty quickly ruled out a React-first design system early on. Some products would eventually wrap Honeycomb in React components (which was great!) but React could not be the system's lowest common denominator. **If the baseline required a modern JavaScript framework, two products would be locked out for too long** and the design system would fail at the thing it most needed to do: create consistency across the company before every app was modernized.
+
+So Honeycomb's first-class output was HTML and CSS. Each product team could import a compiled CSS file, copy documented markup, and start using components without changing their build process. That made adoption possible for older apps while still leaving a better path for teams with more modern tooling.
+
+### Sass on top of Tailwind
+
+Under the hood, **we authored Honeycomb as Sass-based components on top of Tailwind**. Tailwind helped us write and maintain the system faster, and the decision was also practical: two products already used Tailwind, so they could compile Honeycomb alongside their own Tailwind configuration and benefit from the same tree-shaking and build process. Other products were encouraged to move in that direction (and one did), but they were not blocked if they could not get there immediately.
+
+JavaScript followed the same model. We exported small vanilla JS modules, and later added a few framework-agnostic web components for interactions that needed more behavior. Teams could include those individually or as a bundle, but static components did not require JavaScript just to look and behave correctly. This included interactive components like dropdowns too!
+
+[ interactive dropdown example ]
+
+### Native elements whenever possible
+
+We were also strict about using real browser controls wherever possible. A checkbox was an ``, not a div managed by a JavaScript checkbox library. A button was a `