Our GTM team is actively working to deliver outcomes by automating GTM functions and improving customer experience. The idea is to ask our engineering team to focus on core infrastructure products and systems, while encouraging non-engineers to drive outcomes with software.
As you can imagine, biting off an entire tech stack is more than we can comfortably chew. So, we’ve started peeling off areas that are slowing us down. One example we can probably all relate to: presentations and decks!
The presentation problem
Anyone who’s worked on a customer-facing team knows the pain: take months of complex work and distill it into a few slides. Make those slides clear and on-brand, maybe even beautiful. Keep them current, especially as they get picked up and used for dozens of different meetings. It’s no wonder there is an entire industry built around churning out presentations!
As we started to systematize our presentation materials, we hit a predictable wall: traditional slide templates require far too much internal upkeep while simultaneously not keeping up with an evolving business. And so, we re-evaluated.
The goals were simple enough.
- We knew we wanted to leverage version control.
- We wanted to automate slide deck maintenance.
- We needed to provide flexibility for different use cases (e.g. client-facing presentations, Community Huddles, board meetings, etc).
We landed on using markdown files in git, combined with a reusable theme and shared content blocks that stay in sync across decks. Since we leverage a lot of Claude these days across our business, we picked it as our primary coding partner.
Validation is the name of the game
We’ve had our eye on Slidev (a markdown-based presentation tool built on Vue and Vite) for a while. Their developer-friendly experience combined with the promise of version control and customized presentation system was enough for us to test it out.
We started by asking Claude to build a complete Slidev theme using our Datum brand guidelines. That single prompt generated forty-five files and 13,000+ lines of code: a full CSS token system, six layout variants, licensed font loading for Canela Text and Alliance No.1 with Google Fonts fallbacks, and a working Vite config with custom plugins.
While not flawless, the output validated how we might approach things: a shared-slide workflow that could scale across a number of people; the option to make broad-based theme edits; the ability to work with different slide themes; and a script to pull key bits of persistent data directly from our website (via the Strapi CMS editor API).
I guess there is nothing quite like a Claude dopamine hit to keep you moving forward, so from there we built a shared content layer. This will probably take a lot of exploration over time, but having shared content in place is what helps us empower colleagues to create new presentations without starting from scratch (or worse, using an outdated deck!).
How it works
To make sure we could get to a first version quickly, we focused on generating a simple Company Overview deck with an intro, team slide, product overview, and an architecture diagram.
Some content is used often across decks, so this is where the shared content layer comes into play. To make it work, we have a shared/ directory of markdown files that contain reusable content that gets symlinked into every deck automatically. This gives us the ability to update the shared slide once, and every other deck picks up the change.
The vite.config.ts has a sharedSyncPlugin() that watches shared/ at the dev-server startup and on every file change, then symlinks new files into all deck directories. It also auto-links fonts, so a new deck doesn't need any kind of manual setup to get the brand typefaces.
Finally, two scripts to call the Claude API when it’s time to build: fetch-leadership.mjs generates a leadership roster slide from structured data (again without manual intervention!) and fetch-architecture.mjs regenerates a platform architecture diagram using Mermaid. The architecture slide rewrites itself when any of the underlying data changes.
What we learned
A few things tripped us up, but we think we’re still on the right path. Here are some notable stumbles:
CSS styling > inline theme styling. It took longer than I’d like to admit, but defining where styles live dictated how we could make theme switching work. Inline styles are invisible to the theme engine, so we had to move all styling into CSS. Once we made this migration, we were able to render changes correctly across layout variants (one exception was the <colgroup> widths, since they’re layout-specific and not dependent on visual styling elements).
Mermaid diagrams live inside a shadow DOM. Since Mermaid diagrams render inside a shadow DOM, normal <style> rules don't reach it. We fixed this with a dedicated styles/mermaid.css file with shadow-DOM-aware selectors. It wasn’t clearly documented, so it took a bit of trial and error to figure out.
Slidev has two layers of icon resolution. What seems like a subtle issue, ended up being a big one for us, at least once we resolved it. Slidedev handles icons at two different stages: Vue component registration at runtime, and Vite's pre-transform at build time. You need both working together or you get icons in dev that disappear in production, which is annoying. The @iconify-json/<collection> package is required for the build step even if you've registered every component globally at runtime. It’s easy to miss (learn from our mistakes!).
A good brief determines the output, no matter how much time you invest. The thing that probably saved us the most time was starting with a solid brief for any new presentation. The clearer and more detailed we were with the prompt (our goals, what the deck needed to do, what brand rules applied, and importantly, what specifically is out of scope) the less iteration we needed mid-project.
Invest in your brand file early. Upon reflection, the Datum brand.md spec is the single most useful file in the repo, and we expect to continue investing in this alongside our other brand resources.
Where we go from here
What we’ve built so far is just the start, and honestly it’s not quite good enough for the team to want to adopt it en masse. But we’re excited to have produced a foundation from which we can build. Next up, we’ll extract recurring patterns (callout, icon-grid, gtm-cards, and numbered-lists) out of individual decks into reusable Vue components that live in the theme.
Once we’ve nailed the canonical “company” deck, the goal is to make it accessible for anyone on the team to write, publish and share a deck without needing to touch the underlying system.
One down. The rest of the stack to go.
