howdy-jekyll-theme 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/AGENTS.md +49 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.md +431 -0
- data/_includes/analytics.html +19 -0
- data/_includes/blog-pagination.html +31 -0
- data/_includes/comments.html +46 -0
- data/_includes/dark-mode-toggle.html +18 -0
- data/_includes/head.html +137 -0
- data/_includes/hero-carousel.html +80 -0
- data/_includes/logo.html +5 -0
- data/_includes/navigation.html +24 -0
- data/_includes/newsletter.html +10 -0
- data/_includes/share-buttons.html +70 -0
- data/_includes/social-links.html +37 -0
- data/_includes/toc.html +29 -0
- data/_layouts/autopage_collection.html +43 -0
- data/_layouts/blog.html +42 -0
- data/_layouts/default.html +86 -0
- data/_layouts/home.html +5 -0
- data/_layouts/page.html +33 -0
- data/_layouts/post.html +76 -0
- data/_layouts/project.html +61 -0
- data/_plugins/sort_projects.rb +6 -0
- data/_plugins/user_colors.rb +68 -0
- data/_posts/2026-01-01-beyond-pixels.md +21 -0
- data/_posts/2026-01-02-collaboration.md +25 -0
- data/_posts/2026-01-03-design-feeling.md +25 -0
- data/_posts/2026-01-04-finding-inspiration.md +25 -0
- data/_posts/2026-01-05-freebies.md +35 -0
- data/_posts/2026-01-06-ux-research-methods.md +25 -0
- data/_posts/2026-01-07-color-theory.md +25 -0
- data/_posts/2026-01-08-responsive-design.md +25 -0
- data/_posts/2026-01-09-web-performance.md +25 -0
- data/_posts/2026-01-10-mobile-first.md +25 -0
- data/_posts/2026-04-15-crafting-visual-hierarchy.md +27 -0
- data/_posts/2026-04-16-building-design-systems.md +27 -0
- data/_posts/2026-04-18-accessibility-matters.md +25 -0
- data/_posts/2026-04-19-motion-design.md +29 -0
- data/_posts/2026-04-20-typography-basics.md +25 -0
- data/_posts/2026-04-22-product-design-best-practices.md +239 -0
- data/_projects/atlas.md +26 -0
- data/_projects/luminous.md +26 -0
- data/_projects/nova.md +31 -0
- data/_projects/osaka.md +26 -0
- data/_sass/_base.scss +181 -0
- data/_sass/_components.scss +767 -0
- data/_sass/_dark-mode.scss +39 -0
- data/_sass/_layout.scss +1033 -0
- data/_sass/_typography.scss +394 -0
- data/_sass/_user-colors.scss +1 -0
- data/_sass/_variables.scss +165 -0
- data/about.md +62 -0
- data/assets/css/main.scss +10 -0
- data/assets/css/swiper-bundle.min.css +13 -0
- data/assets/fonts/ChaumontScript-Regular.otf +0 -0
- data/assets/fonts/DMSans-Italic-Variable.ttf +0 -0
- data/assets/fonts/DMSans-Variable.ttf +0 -0
- data/assets/illustrations/analytics.svg +218 -0
- data/assets/illustrations/business-strategy.svg +161 -0
- data/assets/illustrations/designer.svg +267 -0
- data/assets/illustrations/email.svg +123 -0
- data/assets/illustrations/friends-taking-selfie.svg +189 -0
- data/assets/illustrations/launch.svg +230 -0
- data/assets/illustrations/love-animals.svg +83 -0
- data/assets/illustrations/meeting.svg +292 -0
- data/assets/illustrations/mobile-shopping.svg +113 -0
- data/assets/illustrations/online-shopping.svg +148 -0
- data/assets/illustrations/oops-something-went-wrong.svg +97 -0
- data/assets/illustrations/podcast.svg +199 -0
- data/assets/illustrations/presentation.svg +138 -0
- data/assets/illustrations/programmer.svg +240 -0
- data/assets/illustrations/task-management.svg +174 -0
- data/assets/illustrations/tasks-complete.svg +161 -0
- data/assets/illustrations/travel-booking-hotel.svg +214 -0
- data/assets/illustrations/video-call.svg +178 -0
- data/assets/images/apple-touch-icon.png +0 -0
- data/assets/images/favicon-dark.png +0 -0
- data/assets/images/favicon-light.png +0 -0
- data/assets/images/howdy-theme-dark.png +0 -0
- data/assets/images/howdy-theme-light.png +0 -0
- data/assets/images/og-image.png +0 -0
- data/assets/js/hero-carousel.js +36 -0
- data/assets/js/mobile-nav.js +62 -0
- data/assets/js/swiper-bundle.min.js +13 -0
- data/assets/js/swiper-bundle.min.js.map +1 -0
- data/assets/js/theme-toggle.js +54 -0
- data/assets/resume.pdf +683 -0
- data/contact.md +74 -0
- data/howdy-jekyll-theme.gemspec +25 -0
- data/lib/howdy-jekyll-theme.rb +19 -0
- metadata +245 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: post
|
|
3
|
+
title: "Product Design Best Practices"
|
|
4
|
+
date: 2026-04-22
|
|
5
|
+
category: "Tutorials"
|
|
6
|
+
image: /assets/illustrations/tasks-complete.svg
|
|
7
|
+
excerpt: "Professional design methodology — intentional, justified decisions that hold up to user testing."
|
|
8
|
+
tags: [methodology, process, best practices, craft]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Don't guess. Make intentional, justified decisions.
|
|
12
|
+
|
|
13
|
+
> If you showed this to 10 users tomorrow, what would they remember?
|
|
14
|
+
|
|
15
|
+
## Before You Design: Discovery
|
|
16
|
+
|
|
17
|
+
Never design blind. Answer these first:
|
|
18
|
+
|
|
19
|
+
**What** are we building: Screen type, platform, scope
|
|
20
|
+
|
|
21
|
+
**Who** is this for: Audience, technical level
|
|
22
|
+
|
|
23
|
+
**What** should users do: Primary action, success metric
|
|
24
|
+
|
|
25
|
+
**What** feeling to evoke: Tone, energy
|
|
26
|
+
|
|
27
|
+
**What job** does this do: Help me decide, convince me, get me started
|
|
28
|
+
|
|
29
|
+
**What** objections exist: Is it worth it? Is it legit? Will it work?
|
|
30
|
+
|
|
31
|
+
**What** should they remember: The hook, the differentiator
|
|
32
|
+
|
|
33
|
+
**Any** constraints: Brand, tech requirements, inspirations
|
|
34
|
+
|
|
35
|
+
Write a design brief before you open Figma:
|
|
36
|
+
|
|
37
|
+
> I'm designing a **[WHAT]** for **[WHO]** that helps them **[GOAL]** and should feel **[TONE]**.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Research & Analysis
|
|
42
|
+
|
|
43
|
+
### Research ≠ Copying the Average
|
|
44
|
+
|
|
45
|
+
Research is about understanding *why* choices work, not copying *what* everyone does.
|
|
46
|
+
|
|
47
|
+
- Best practices are a starting point, not a destination
|
|
48
|
+
- Safe often means forgettable
|
|
49
|
+
- Document your reasoning: "Most use X, but we chose Y because..."
|
|
50
|
+
|
|
51
|
+
### Three Lenses
|
|
52
|
+
|
|
53
|
+
**Structure:** Layout, components, information hierarchy. Common solutions to common problems.
|
|
54
|
+
|
|
55
|
+
**Visual Craft:** For each strong reference, notice typography, color, spacing, details, icons, and overall vibe.
|
|
56
|
+
|
|
57
|
+
**Conversion & Soul:** What's the hook in the first 3 seconds? How do they handle objections? Where's the trust? What's unique? What microcopy has personality? What would a user remember tomorrow?
|
|
58
|
+
|
|
59
|
+
### Build a Steal List
|
|
60
|
+
|
|
61
|
+
When you research, document specific tactics with exact details:
|
|
62
|
+
|
|
63
|
+
- "Linear: 13px/20px body, -0.01em tracking, 48px section gaps, accent at 8% opacity for hover"
|
|
64
|
+
- Not "Linear: clean design"
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Typography
|
|
69
|
+
|
|
70
|
+
### Scale
|
|
71
|
+
|
|
72
|
+
Use a consistent ratio: 1.2 (minor third) works well. Limit yourself to 6–8 sizes:
|
|
73
|
+
|
|
74
|
+
| Size | Usage |
|
|
75
|
+
|------|-------|
|
|
76
|
+
| Display (48–64px) | Hero sections |
|
|
77
|
+
| H1 (36–48px) | Page titles |
|
|
78
|
+
| H2 (24–32px) | Section headers |
|
|
79
|
+
| Body (16–18px) | Main content |
|
|
80
|
+
| Small (13–14px) | Captions, metadata |
|
|
81
|
+
| Caption (11–12px) | Fine print |
|
|
82
|
+
|
|
83
|
+
### Leading
|
|
84
|
+
|
|
85
|
+
Large text = tight (1.0–1.2). Body = loose (1.5–1.6).
|
|
86
|
+
|
|
87
|
+
### Letter-Spacing
|
|
88
|
+
|
|
89
|
+
This is the detail most designers skip. Don't:
|
|
90
|
+
|
|
91
|
+
| Text Type | Letter-Spacing |
|
|
92
|
+
|-----------|----------------|
|
|
93
|
+
| Body (14–18px) | `0` |
|
|
94
|
+
| Small text (11–13px) | `0.01–0.02em` |
|
|
95
|
+
| UI labels/buttons | `0.02em` |
|
|
96
|
+
| ALL CAPS | `0.06–0.1em` |
|
|
97
|
+
| Large headings (32px+) | `-0.01` to `-0.02em` |
|
|
98
|
+
| Display (48px+) | `-0.02` to `-0.03em` |
|
|
99
|
+
|
|
100
|
+
### Rules
|
|
101
|
+
|
|
102
|
+
- Line length: 50–75 characters
|
|
103
|
+
- Max 2 typefaces
|
|
104
|
+
- Use weights within a family before adding another font
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Color
|
|
109
|
+
|
|
110
|
+
### Palette Structure
|
|
111
|
+
|
|
112
|
+
**Neutrals:** 70–90% of the interface
|
|
113
|
+
|
|
114
|
+
**Primary accent:** 5–10%
|
|
115
|
+
|
|
116
|
+
**Semantic:** success, warning, danger
|
|
117
|
+
|
|
118
|
+
**Effects:** rare, used sparingly
|
|
119
|
+
|
|
120
|
+
### Working with Your Primary
|
|
121
|
+
|
|
122
|
+
Pick one brand color and build a scale (50–950). Use 600 as default, 700 for hover, 800 for active states.
|
|
123
|
+
|
|
124
|
+
### Contrast
|
|
125
|
+
|
|
126
|
+
- 4.5:1 minimum for body text
|
|
127
|
+
- 3:1 minimum for large text
|
|
128
|
+
|
|
129
|
+
### Dark Theme
|
|
130
|
+
|
|
131
|
+
Dark theme is not an inversion. Use `#0f0f0f` for background, not `#000`. Use `#f0f0f0` for text, not `#fff`. Build a separate neutral scale.
|
|
132
|
+
|
|
133
|
+
### Tokens
|
|
134
|
+
|
|
135
|
+
Name tokens by purpose (`--color-primary`), not by color (`--color-blue`). This makes rebranding painless.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Spacing
|
|
140
|
+
|
|
141
|
+
### The Scale
|
|
142
|
+
|
|
143
|
+
Base unit: 4px or 8px. Everything multiplies from this.
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
4px scale: 4, 8, 12, 16, 24, 32, 48, 64, 96
|
|
147
|
+
8px scale: 8, 16, 24, 32, 48, 64, 96, 128
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Proximity = Relationship
|
|
151
|
+
|
|
152
|
+
Closer elements feel connected. Farther elements feel separate. Use spacing to communicate hierarchy and grouping.
|
|
153
|
+
|
|
154
|
+
### Density
|
|
155
|
+
|
|
156
|
+
Match spacing to context: dense for dashboards (8-12px padding), default for product UI (16-24px), spacious for marketing (24-32px).
|
|
157
|
+
|
|
158
|
+
### Responsive
|
|
159
|
+
|
|
160
|
+
Structural spacing (sections, containers) scales down 0.5-0.75x on mobile. Internal component spacing (icon-to-text, button padding) stays fixed.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Motion
|
|
165
|
+
|
|
166
|
+
Motion serves one of three purposes: **feedback** (it worked), **continuity** (where it went), or **hierarchy** (look here). If it doesn't do one of these, remove it.
|
|
167
|
+
|
|
168
|
+
| Category | Duration |
|
|
169
|
+
|----------|----------|
|
|
170
|
+
| Instant (hover, press, toggle) | 90–150ms |
|
|
171
|
+
| State change (accordion, tabs) | 160–240ms |
|
|
172
|
+
| Large transition (modal, drawer) | 240–360ms |
|
|
173
|
+
|
|
174
|
+
### Easing
|
|
175
|
+
|
|
176
|
+
Enter = ease-out. Exit = ease-in. Change = ease-in-out.
|
|
177
|
+
|
|
178
|
+
### Rules
|
|
179
|
+
|
|
180
|
+
- Always support `prefers-reduced-motion`
|
|
181
|
+
- No animation over 500ms in product UI
|
|
182
|
+
- Never use `transition: all`
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Icons
|
|
187
|
+
|
|
188
|
+
- Pick one style (outline OR solid) and stick with it
|
|
189
|
+
- Geometric center ≠ visual center; arrows and chevrons need a 0.5–1px optical shift
|
|
190
|
+
- Use `currentColor` by default
|
|
191
|
+
- Hit area should be 44×44px minimum
|
|
192
|
+
- Action icons need `aria-label`
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## The Persuasion Layer
|
|
197
|
+
|
|
198
|
+
Before you design, fill this out:
|
|
199
|
+
|
|
200
|
+
**Hook** (first 3 seconds): Hero headline + visual
|
|
201
|
+
|
|
202
|
+
**Story arc:** Problem → Solution → Proof → Action
|
|
203
|
+
|
|
204
|
+
**Objection killers:** List the top 3 reasons someone would hesitate
|
|
205
|
+
|
|
206
|
+
**Trust signals:** Social proof, guarantees, security badges, specifics
|
|
207
|
+
|
|
208
|
+
**The memorable thing:** What will users screenshot or tell someone about?
|
|
209
|
+
|
|
210
|
+
If you can't fill this out, you're designing decoration, not persuasion.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## The Soul
|
|
215
|
+
|
|
216
|
+
Aim for roughly 80% proven patterns and 20% unique choices.
|
|
217
|
+
|
|
218
|
+
- One bold visual choice: a color, a type treatment, an illustration style
|
|
219
|
+
- Voice and personality in the copy
|
|
220
|
+
- Micro-interactions that surprise
|
|
221
|
+
- One detail users will remember
|
|
222
|
+
|
|
223
|
+
The test: if someone screenshots your work, would they know it's from *this* product?
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Implementation Quality Gate
|
|
228
|
+
|
|
229
|
+
Before shipping, check:
|
|
230
|
+
|
|
231
|
+
**Functional:** Is the primary action obvious? Error states handled? Works on mobile?
|
|
232
|
+
|
|
233
|
+
**Visual:** Does the squint test pass? Spacing rhythm consistent? Typography intentional?
|
|
234
|
+
|
|
235
|
+
**Persuasion:** Hook in 3 seconds? Two or more trust signals? Objections addressed?
|
|
236
|
+
|
|
237
|
+
**Polish:** No orphaned words? Icons aligned? Buttons consistent?
|
|
238
|
+
|
|
239
|
+
Good design isn't about following rules blindly. It's about making decisions you can defend, and caring about the details that most people won't notice until they're missing.
|
data/_projects/atlas.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: project
|
|
3
|
+
title: "Atlas Design System"
|
|
4
|
+
subtitle: "Creating a shared language for product teams"
|
|
5
|
+
category: "Design Systems"
|
|
6
|
+
year: "2024"
|
|
7
|
+
image: /assets/illustrations/business-strategy.svg
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## About Atlas
|
|
11
|
+
|
|
12
|
+
Atlas is a design system built to bring consistency and speed to a growing product organization. It serves multiple teams across web and mobile, providing a shared foundation of components, tokens, and patterns.
|
|
13
|
+
|
|
14
|
+
## Challenge
|
|
15
|
+
|
|
16
|
+
As the team grew, every designer and developer was solving the same problems slightly differently. Buttons looked different across screens, spacing was inconsistent, and onboarding new team members took longer than it should.
|
|
17
|
+
|
|
18
|
+
## Solution
|
|
19
|
+
|
|
20
|
+
I built Atlas around a simple principle: make the right thing the easy thing. Starting with design tokens — colors, spacing, typography — I worked outward to create a library of flexible, well-documented components. Everything was designed in Figma and shipped as code, keeping design and engineering in sync.
|
|
21
|
+
|
|
22
|
+
## Results
|
|
23
|
+
|
|
24
|
+
- **Faster:** Features ship 40% faster with 60% fewer design revisions
|
|
25
|
+
- **Consistent:** Design inconsistency issues dropped by 80% in audit scores
|
|
26
|
+
- **Scalable:** New team members reach full productivity in 3 days instead of 3 weeks
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: project
|
|
3
|
+
title: "Luminous Brand & Marketing Site"
|
|
4
|
+
subtitle: "Building a brand that grows with the product"
|
|
5
|
+
category: "Brand & Web"
|
|
6
|
+
year: "2022"
|
|
7
|
+
image: /assets/illustrations/launch.svg
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## About Luminous
|
|
11
|
+
|
|
12
|
+
A complete brand refresh and marketing site redesign for a growing SaaS company. The project covered visual identity, web design, and a shared component library for both marketing and product teams.
|
|
13
|
+
|
|
14
|
+
## Challenge
|
|
15
|
+
|
|
16
|
+
The company's brand no longer reflected the quality of their product. The website felt patchwork, built over years by different hands with no cohesive direction. Every redesign conversation ended with "we should fix this, but we don't have the bandwidth."
|
|
17
|
+
|
|
18
|
+
## Solution
|
|
19
|
+
|
|
20
|
+
I started by defining the visual foundations — color, typography, spacing, and motion — then built a component library that both marketing and product could use. The brand language centers on clarity and warmth, using light and space to make complex ideas feel approachable.
|
|
21
|
+
|
|
22
|
+
## Results
|
|
23
|
+
|
|
24
|
+
- Pages load in 1.2s (down from 4.7s) with a 98 Lighthouse performance score
|
|
25
|
+
- Component library adopted by all 6 product teams, reducing duplicate work by 35%
|
|
26
|
+
- Brand guide referenced weekly by every team, not shelved but actually used
|
data/_projects/nova.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: project
|
|
3
|
+
title: "Nova AI Copilot"
|
|
4
|
+
subtitle: "Making AI feel like a natural part of the workflow"
|
|
5
|
+
category: "AI / Machine Learning"
|
|
6
|
+
year: "2025"
|
|
7
|
+
image: /assets/illustrations/programmer.svg
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## About Nova
|
|
11
|
+
|
|
12
|
+
Nova is an AI assistant built into a creative tool, helping users draft content, explore options, and move through repetitive tasks without leaving their flow.
|
|
13
|
+
|
|
14
|
+
## Challenge
|
|
15
|
+
|
|
16
|
+
AI features in creative tools often feel tacked on — a separate mode, a different interface, something you "switch to." The goal was to make AI feel like it was always there, ready when needed and invisible when not.
|
|
17
|
+
|
|
18
|
+
## Solution
|
|
19
|
+
|
|
20
|
+
I designed Nova as a contextual panel that surfaces suggestions based on what the user is doing right now. Instead of a chat box you talk to, it offers relevant actions inline — rewrite this heading, generate alternatives, summarize this section. Every suggestion is clearly marked as AI-generated and always editable.
|
|
21
|
+
|
|
22
|
+
Design principles:
|
|
23
|
+
- **Augment, don't replace:** the user stays in control
|
|
24
|
+
- **Context over conversation:** suggest actions, don't require prompts
|
|
25
|
+
- **Trust through transparency:** always show what's AI-generated
|
|
26
|
+
|
|
27
|
+
## Results
|
|
28
|
+
|
|
29
|
+
- First drafts completed in 4.2 minutes on average, 3x faster than the control group
|
|
30
|
+
- 72% adoption across the user base within the first 8 weeks
|
|
31
|
+
- Featured in Product Hunt's "Design Tools of the Year" roundup
|
data/_projects/osaka.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: project
|
|
3
|
+
title: "Osaka Analytics Platform"
|
|
4
|
+
subtitle: "Designing data tools that people actually enjoy using"
|
|
5
|
+
category: "Data Visualization"
|
|
6
|
+
year: "2023"
|
|
7
|
+
image: /assets/illustrations/analytics.svg
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## About Osaka
|
|
11
|
+
|
|
12
|
+
An analytics platform built for teams who need answers from their data without needing to write code or wait on a data team.
|
|
13
|
+
|
|
14
|
+
## Challenge
|
|
15
|
+
|
|
16
|
+
Most analytics tools force a choice: either use rigid pre-built dashboards or learn a query language. Neither works for teams that need flexibility without the learning curve.
|
|
17
|
+
|
|
18
|
+
## Solution
|
|
19
|
+
|
|
20
|
+
I designed Osaka around progressive complexity: start simple, go deeper when ready. The query builder uses visual blocks instead of SQL, and the dashboard system suggests chart types based on the data you're looking at. Color palettes are accessible by default, tooltips provide context without clutter, and everything works on mobile.
|
|
21
|
+
|
|
22
|
+
## Results
|
|
23
|
+
|
|
24
|
+
- 83% of queries completed without writing SQL
|
|
25
|
+
- Dashboard creation shifted from 3-day requests to 15-minute self-service
|
|
26
|
+
- Data team ticket volume for basic queries dropped by 60%
|
data/_sass/_base.scss
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// Howdy Jekyll Theme - Base Styles
|
|
2
|
+
|
|
3
|
+
@use "variables" as *;
|
|
4
|
+
|
|
5
|
+
html {
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
scroll-behavior: smooth;
|
|
8
|
+
overflow-x: hidden;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
*, *::before, *::after {
|
|
12
|
+
box-sizing: inherit;
|
|
13
|
+
-webkit-font-smoothing: inherit;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
html, body {
|
|
17
|
+
margin: 0;
|
|
18
|
+
padding: 0;
|
|
19
|
+
overflow-x: hidden;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
body {
|
|
23
|
+
background-color: var(--howdy-bg-light-gray);
|
|
24
|
+
color: var(--howdy-text-primary);
|
|
25
|
+
font-family: var(--howdy-font-primary);
|
|
26
|
+
font-size: 16px;
|
|
27
|
+
line-height: 1.4;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
h1, h2, h3, h4, h5, h6, p, figure {
|
|
31
|
+
margin: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
input, textarea, select, button {
|
|
35
|
+
font-family: var(--howdy-font-primary);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
a {
|
|
39
|
+
color: var(--howdy-text-secondary);
|
|
40
|
+
text-decoration: none;
|
|
41
|
+
transition: var(--howdy-transition);
|
|
42
|
+
|
|
43
|
+
&:hover {
|
|
44
|
+
color: var(--howdy-text-primary);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
img {
|
|
49
|
+
max-width: 100%;
|
|
50
|
+
height: auto;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Focus-visible — global accessible focus ring
|
|
54
|
+
:focus-visible {
|
|
55
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
56
|
+
outline-offset: 2px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Remove outline on focus for elements that use border/box-shadow as feedback
|
|
60
|
+
input:focus-visible,
|
|
61
|
+
textarea:focus-visible,
|
|
62
|
+
select:focus-visible {
|
|
63
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
64
|
+
outline-offset: 0;
|
|
65
|
+
border-color: var(--howdy-accent-green);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Theme toggle focus ring
|
|
69
|
+
.theme-toggle:focus-visible {
|
|
70
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
71
|
+
outline-offset: 2px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Nav links focus ring
|
|
75
|
+
.site-nav a:focus-visible {
|
|
76
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
77
|
+
outline-offset: 2px;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Social links focus ring — ensure ring is visible outside the container
|
|
81
|
+
.social-links a:focus-visible {
|
|
82
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
83
|
+
outline-offset: 2px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Share buttons focus ring
|
|
87
|
+
.share-btn:focus-visible {
|
|
88
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
89
|
+
outline-offset: 2px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Pagination focus ring
|
|
93
|
+
.pagination-page:focus-visible {
|
|
94
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
95
|
+
outline-offset: 2px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// TOC links focus ring
|
|
99
|
+
.toc a:focus-visible {
|
|
100
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
101
|
+
outline-offset: 2px;
|
|
102
|
+
border-radius: 2px;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Nav toggle (hamburger) focus ring
|
|
106
|
+
.nav-toggle:focus-visible {
|
|
107
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
108
|
+
outline-offset: 2px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// FAQ details/summary focus ring
|
|
112
|
+
.faq-question:focus-visible {
|
|
113
|
+
outline: 2px solid var(--howdy-accent-green);
|
|
114
|
+
outline-offset: 2px;
|
|
115
|
+
border-radius: 2px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Main wrapper — matches Framer root frame
|
|
119
|
+
.main-container {
|
|
120
|
+
background-color: var(--howdy-bg-white);
|
|
121
|
+
width: 100%;
|
|
122
|
+
min-height: 100vh;
|
|
123
|
+
position: relative;
|
|
124
|
+
overflow-x: hidden;
|
|
125
|
+
padding: 0;
|
|
126
|
+
margin: 0;
|
|
127
|
+
transition: var(--howdy-transition);
|
|
128
|
+
|
|
129
|
+
@media (max-width: $howdy-xxl) {
|
|
130
|
+
max-width: 1200px;
|
|
131
|
+
margin: 0 auto;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@media (max-width: $howdy-xl) {
|
|
135
|
+
max-width: 1024px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@media (max-width: $howdy-lg) {
|
|
139
|
+
max-width: calc(100% - (var(--howdy-container-margin-lg) * 2));
|
|
140
|
+
margin: var(--howdy-container-margin-lg) auto;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@media (max-width: $howdy-md) {
|
|
144
|
+
max-width: calc(100% - (var(--howdy-container-margin-md) * 2));
|
|
145
|
+
margin: var(--howdy-container-margin-md) auto;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@media (max-width: $howdy-sm) {
|
|
149
|
+
max-width: calc(100% - (var(--howdy-container-margin-sm) * 2));
|
|
150
|
+
margin: var(--howdy-container-margin-sm) auto;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@media (max-width: $howdy-xs) {
|
|
154
|
+
max-width: calc(100% - (var(--howdy-container-margin-xs) * 2));
|
|
155
|
+
margin: var(--howdy-container-margin-xs) auto;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Container fills the main wrapper
|
|
160
|
+
.container {
|
|
161
|
+
width: 100%;
|
|
162
|
+
height: 100%;
|
|
163
|
+
padding: 0;
|
|
164
|
+
margin: 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Accessibility: Reduced motion support
|
|
168
|
+
@media (prefers-reduced-motion: reduce) {
|
|
169
|
+
*,
|
|
170
|
+
*::before,
|
|
171
|
+
*::after {
|
|
172
|
+
animation-duration: 0.01ms !important;
|
|
173
|
+
animation-iteration-count: 1 !important;
|
|
174
|
+
transition-duration: 0.01ms !important;
|
|
175
|
+
scroll-behavior: auto !important;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.logos-scroll {
|
|
179
|
+
animation: none !important;
|
|
180
|
+
}
|
|
181
|
+
}
|