Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion .eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const pluginTOC = require('eleventy-plugin-toc');
const pluginDropcap = require('eleventy-plugin-dropcap');
const markdownIt = require("markdown-it");
const markdownItAnchor = require("markdown-it-anchor");
const markdownItHighlightJS = require('markdown-it-highlightjs')
const markdownItHighlightJS = require('markdown-it-highlightjs');
const markdownItContainer = require('markdown-it-container');
const emojiReadTime = require("@11tyrocks/eleventy-plugin-emoji-readtime");
const packageVersion = require("./package.json").version;
const eleventySass = require("@11tyrocks/eleventy-plugin-sass-lightningcss");
Expand Down Expand Up @@ -118,6 +119,41 @@ module.exports = function (eleventyConfig) {
markdownIt(mdOptions)
.use(markdownItAnchor, mdAnchorOpts)
.use(markdownItHighlightJS)
.use(markdownItContainer, 'card', {
render(tokens, idx) {
return tokens[idx].nesting === 1
? '<div class="card">\n'
: '</div>\n';
}
})
.use(markdownItContainer, 'section', {
render(tokens, idx) {
return tokens[idx].nesting === 1
? '<section class="prose-section">\n'
: '</section>\n';
}
})
.use(markdownItContainer, 'cards', {
render(tokens, idx) {
return tokens[idx].nesting === 1
? '<div class="cards-row">\n'
: '</div>\n';
}
})
.use(markdownItContainer, 'card-basic', {
render(tokens, idx) {
return tokens[idx].nesting === 1
? '<div class="card-basic">\n'
: '</div>\n';
}
})
.use(markdownItContainer, 'card-shadow', {
render(tokens, idx) {
return tokens[idx].nesting === 1
? '<div class="card-shadow">\n'
: '</div>\n';
}
})
);

// Plugins
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Changelog

All notable changes to this project will be documented in this file.

## [Unreleased]

### Added

- TimeTracker Pro case study page for the Weekly Report AI feature
— `src/pages/development/timetracker.md`, `src/assets/img/timetracker-*.{webp,jpg}`, `src/assets/img-raw/timetracker-*.png`
(full case study covering design decisions, two-panel layout, tone selection, and AI prompt architecture; 8 screenshots with full-size + thumbnail variants)

- Markdown containers system via `markdown-it-container` plugin
— `.eleventy.js`, `src/sass/containers.scss`, `src/_includes/markdown.njk`
(registers `:::card`, `:::section`, `:::cards`, `:::card-basic`, `:::card-shadow` fenced blocks; opt-in per page via `containers: true` in front matter)

### Fixed

- Production build now compiles all SCSS files to `docs/css/` (previously only `style.scss` was compiled, leaving `markdown.css`, `print.css`, etc. missing in production)
— `package.json` `build:sass-site` script changed from single-file to directory compilation (`src/sass:docs/css`)
31 changes: 27 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ scripts/
- `markdown-it-anchor`: Auto-heading anchors with `#` symbols
- `markdown-it-highlightjs`: Syntax highlighting
- `markdown-it-eleventy-img`: Image optimization
- `markdown-it-container`: Fenced container blocks (`:::card`, `:::section`, `:::cards`, `:::card-basic`, `:::card-shadow`)

### Eleventy Plugins Active
1. `@11ty/eleventy-plugin-syntaxhighlight` - Code block highlighting
Expand Down Expand Up @@ -185,19 +186,41 @@ Edit `eleventyNavigation` in page front matter:
- `title`: Display text in nav
- `order`: Menu position (lower numbers first)

### Using Markdown Containers

Pages using `layout: markdown.njk` can opt in to fenced container syntax by adding `containers: true` to front matter. This loads `containers.css` and enables all five container types:

| Syntax | Output | Use case |
|--------|--------|----------|
| `:::card` | `<div class="card">` | Bootstrap card component |
| `:::section` | `<section class="prose-section">` | Semantic section with spacing |
| `:::cards` | `<div class="cards-row">` | Flex row wrapper for adjacent cards |
| `:::card-basic` | `<div class="card-basic">` | Bordered card, earth-sand background |
| `:::card-shadow` | `<div class="card-shadow">` | Cream background, box shadow |

```yaml
---
layout: markdown.njk
containers: true
---
```

To add new container types: add `md.use(markdownItContainer, 'name', { render... })` in `.eleventy.js` and add styles in `src/sass/containers.scss`.

## Working with Styles

### SCSS File Organization
- **Main**: `src/sass/style.scss` (imports Bootstrap + custom partials)
- **Main**: `src/sass/style.scss` (imports Bootstrap + custom partials, including containers)
- **Colors**: `src/sass/_colors.scss`
- **Typography**: `src/sass/_typography.scss`
- **Layout**: `src/sass/_layout.scss`
- **Components**: Individual `_component.scss` files (buttons, cards, gallery, etc.)
- **Containers**: `src/sass/containers.scss` (prose-section, card overrides for markdown context)

### CSS Build Process
- **Development**: Auto-compiles via `npm run start` watcher
- **Production**: `npm run build:sass` PostCSS → minified output
- **Output**: `docs/css/style.css` (~98KB)
- **Development**: Auto-compiles entire `src/sass/` → `docs/css/` via `watch:sass`
- **Production**: `npm run build:sass` compiles entire `src/sass/` → `docs/css/` → PostCSS → minified
- **Output**: `docs/css/style.css` (main bundle), `docs/css/containers.css`, `docs/css/markdown.css`, etc.

## Environment Variables

Expand Down
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,60 @@ I'm a user experience designer with 15+ years of enterprise experience at compan

----

## Markdown Containers

Pages using `layout: markdown.njk` can opt in to fenced container blocks by adding `containers: true` to front matter. This enables container syntax without writing raw HTML.

```yaml
---
layout: markdown.njk
containers: true
---
```

```markdown
:::section
## Section Heading
Content here.
:::

:::card
### Card Title
Card content here.
:::

:::cards
:::card
Card one.
:::
:::card
Card two.
:::
:::

:::card-basic
Basic styled card.
:::

:::card-shadow
Elevated card with shadow.
:::
```

Available containers and their rendered output:

| Syntax | Output |
|--------|--------|
| `:::card` | `<div class="card">` |
| `:::section` | `<section class="prose-section">` |
| `:::cards` | `<div class="cards-row">` (flex row wrapper) |
| `:::card-basic` | `<div class="card-basic">` (bordered, earth-sand background) |
| `:::card-shadow` | `<div class="card-shadow">` (cream background, box shadow) |

Pages without `containers: true` are unaffected. To add new container types, register them in `.eleventy.js` and add styles in `src/sass/containers.scss`.

----

## References and Resources

**Libraries**
Expand Down
5 changes: 3 additions & 2 deletions docs/about/resume/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@
<link rel="stylesheet" href="/css/print.css" media="print" />
<link rel="stylesheet" href="/css/markdown.css" />


<section class="hero">
<h1>Adam Jolicoeur</h1>
<p class="text-lead mb-4">Lead Product Designer with 15+ years at AWS, Red Hat, and high-growth B2B companies</p></section>


<section>
<content>
<section class="hide-on-screen print">
<h1>Adam Jolicoeur</h1>
<caption>contact@adamjolicoeur.com</caption>
Expand Down Expand Up @@ -128,7 +129,7 @@ <h3>Also available</h3>
<a href="https://www.github.com/AdamJ" class="btn btn-social" target="_blank" alt="Click to visit my GitHub profile"><i class="fa-brands fa-github"></i> GitHub</a>
</section>

</section>
</content>


</main>
Expand Down
5 changes: 3 additions & 2 deletions docs/apps/taskstat-privacy.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@
<link rel="stylesheet" href="/css/print.css" media="print" />
<link rel="stylesheet" href="/css/markdown.css" />


<section class="hero">
<h1>TaskStat Privacy Policy</h1>
<p class="text-lead mb-4">Privacy policy for TaskStat - a privacy-first task management app for iOS</p></section>


<section>
<content>
<section>
<p><strong>Last Updated:</strong> January 5, 2026<br>
<strong>Effective Date:</strong> January 5, 2026</p>
Expand Down Expand Up @@ -328,7 +329,7 @@ <h2 id="acknowledgment" tabindex="-1">Acknowledgment <a class="anchor-link" href
<em>Simple tasks. Complete privacy.</em></p>
</section>

</section>
</content>


</main>
Expand Down
5 changes: 3 additions & 2 deletions docs/apps/taskstat.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@
<link rel="stylesheet" href="/css/print.css" media="print" />
<link rel="stylesheet" href="/css/markdown.css" />


<section class="hero">
<h1>TaskStat</h1>
<p class="text-lead mb-4">Privacy-first task management for iOS. Your tasks stay on your device—no accounts, no tracking, no cloud sync.</p></section>


<section>
<content>
<section>
<h2 id="about-taskstat" tabindex="-1">About TaskStat <a class="anchor-link" href="#about-taskstat">#</a></h2>
<p>TaskStat is a native iOS task management app built with privacy as a core principle. Unlike cloud-based task managers, TaskStat stores all your data locally on your device using SwiftData—ensuring complete privacy and offline functionality.</p>
Expand Down Expand Up @@ -176,7 +177,7 @@ <h2 id="technical-details" tabindex="-1">Technical Details <a class="anchor-link
<div class="text-callout">TaskStat: Simple tasks. Complete privacy.</div>
</section>

</section>
</content>


</main>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/TimeTrackerPro-1920x1080-thumb.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/TimeTrackerPro-1920x1080.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/TimeTrackerPro-1920x1080.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-generated-summary.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-loading-state.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-loading-state.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-start-thumb.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-start-thumb.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-start.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-start.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-tone-client-thumb.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-tone-client.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-tone-client.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-tone-retro-thumb.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-tone-retro.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-tone-retro.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/timetracker-tone-standup.jpg
Binary file added docs/assets/img/timetracker-tone-standup.webp
Binary file added docs/assets/img/timetracker-weekly-report.jpg
Binary file added docs/assets/img/timetracker-weekly-report.webp
1 change: 1 addition & 0 deletions docs/credits/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
<link rel="stylesheet" href="/css/print.css" media="print" />
<link rel="stylesheet" href="/css/markdown.css" />


<section class="hero">
<h1>Credits</h1>
<p class="text-lead mb-4"></p></section>
Expand Down
82 changes: 82 additions & 0 deletions docs/css/containers.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/css/containers.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions docs/css/markdown.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/css/markdown.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading