Skip to content

Commit c55b0d2

Browse files
authored
Merge pull request #1 from BRO3886/claude/polish-ui-animations-kqmeR
2 parents 8113e20 + 0b215d8 commit c55b0d2

File tree

4 files changed

+483
-83
lines changed

4 files changed

+483
-83
lines changed

journals/002-2026-02-18-journal.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Journal Entry 002 - 2026-02-18 - iOS Health-inspired UI polish
2+
3+
## Goal
4+
5+
Polish the Hugo website with microanimations and a professional, iOS Health-inspired design system. Criteria: no flashy effects, professional/detail-oriented feel, looks good on mobile, preserves existing UX.
6+
7+
## What Changed
8+
9+
### `website/assets/css/main.css` (complete rewrite)
10+
11+
**Color system — Apple semantic palette:**
12+
- `--text: #1d1d1f` (Apple near-black, up from `#1a1a1a`)
13+
- `--text-secondary: #6e6e73` (Apple secondary, up from `#666`)
14+
- `--bg-secondary: #f5f5f7` (Apple light surface, was `#f6f6f6`)
15+
- `--accent: #007AFF` (Apple blue, was GitHub blue `#0969da`)
16+
- `--accent-hover: #0055D4` (was `#0550ae`)
17+
- Added `--accent-subtle: rgba(0, 122, 255, 0.08)` for hover backgrounds
18+
- Added `--border-subtle: rgba(0, 0, 0, 0.06)` for hairline separators
19+
- Added `--radius-sm: 6px`, `--radius-md: 10px`, `--radius-lg: 14px`
20+
- Added `--shadow-sm`, `--shadow-md`, `--ease: 0.15s ease`
21+
- Dark mode: `--bg: #1c1c1e`, `--accent: #0A84FF` (Apple exact dark-mode variants)
22+
23+
**Nav — iOS frosted glass:**
24+
```css
25+
.nav {
26+
background: rgba(255, 255, 255, 0.82);
27+
backdrop-filter: saturate(180%) blur(16px);
28+
-webkit-backdrop-filter: saturate(180%) blur(16px);
29+
border-bottom: 1px solid var(--border-subtle);
30+
}
31+
[data-theme="dark"] .nav { background: rgba(28, 28, 30, 0.88); }
32+
```
33+
34+
**Hero — staggered entrance animation:**
35+
```css
36+
@keyframes fadeSlideUp {
37+
from { opacity: 0; transform: translateY(10px); }
38+
to { opacity: 1; transform: translateY(0); }
39+
}
40+
.home-hero h1 { animation: fadeSlideUp 0.45s ease both; }
41+
.home-desc { animation: fadeSlideUp 0.45s 0.07s ease both; }
42+
.home-links { animation: fadeSlideUp 0.45s 0.14s ease both; }
43+
.home-metrics { animation: fadeSlideUp 0.45s 0.21s ease both; }
44+
```
45+
46+
**CTA buttons — Apple HIG-style:**
47+
- Primary: `background: var(--accent)` filled with `box-shadow: 0 1px 4px rgba(0,122,255,0.28)`; hover lifts with `translateY(-1px)` and stronger shadow
48+
- Secondary: outlined with `border: 1px solid var(--border)`, hover fills `--bg-secondary`
49+
50+
**Sidebar active state — iOS selected cell:**
51+
```css
52+
.sidebar-link.active::before {
53+
content: '';
54+
position: absolute;
55+
left: 0; top: 20%; height: 60%;
56+
width: 2.5px;
57+
background: var(--accent);
58+
border-radius: 0 2px 2px 0;
59+
}
60+
```
61+
62+
**Other interactions (all `0.15s ease`):**
63+
- All `a` tags: `transition: color`
64+
- Nav brand: `opacity` fade on hover
65+
- Dark toggle: `color + border-color + background`
66+
- Table rows: `background` on `tbody tr:hover`
67+
- Docs list items: `translateY(-1px) + shadow-md + border-color` on hover
68+
- Mobile sidebar: `slideDown` keyframe entrance + close-on-outside-click
69+
- TOC links: `color` transition + `.toc-active` class set by JS
70+
71+
**Mobile sidebar** adds `animation: slideDown 0.2s ease` on `.sidebar.open`.
72+
73+
**Quick Start steps** — card-style via:
74+
```css
75+
.home-section ol {
76+
list-style: none; padding-left: 0;
77+
display: flex; flex-direction: column; gap: 0.6rem;
78+
}
79+
.home-section ol > li {
80+
padding: 0.85rem 1rem;
81+
background: var(--bg-secondary);
82+
border: 1px solid var(--border-subtle);
83+
border-radius: var(--radius-md);
84+
}
85+
```
86+
87+
**`prefers-reduced-motion`** — disables all animations/transitions for accessibility.
88+
89+
### `website/layouts/index.html`
90+
91+
Added `.home-metrics` section between CTA links and terminal code block:
92+
```html
93+
<div class="home-metrics">
94+
<span class="metric-badge"><span class="badge-dot badge-dot-heart"></span>Heart Rate</span>
95+
<span class="metric-badge"><span class="badge-dot badge-dot-steps"></span>Steps</span>
96+
<span class="metric-badge"><span class="badge-dot badge-dot-sleep"></span>Sleep</span>
97+
<span class="metric-badge"><span class="badge-dot badge-dot-spo2"></span>Blood Oxygen</span>
98+
<span class="metric-badge"><span class="badge-dot badge-dot-vo2"></span>VO2 Max</span>
99+
<span class="metric-badge"><span class="badge-dot badge-dot-workout"></span>Workouts</span>
100+
</div>
101+
```
102+
103+
Badges use iOS Health metric colors: `#FF375F` heart, `#30D158` steps, `#636EFF` sleep, `#5AC8FA` SpO2, `#FF9F0A` VO2, `#FF6B35` workouts.
104+
105+
### `website/static/js/main.js`
106+
107+
- **Mobile sidebar**: Added `document.addEventListener("click", ...)` to close sidebar when tapping outside it or the hamburger button.
108+
- **TOC IntersectionObserver**: Highlights the active TOC link as user scrolls:
109+
```js
110+
var observer = new IntersectionObserver(fn, {
111+
rootMargin: "-8% 0px -75% 0px", threshold: 0
112+
});
113+
```
114+
Uses `rootMargin` trick: heading must be in the top ~17% of the viewport to be "active". Sets `.toc-active` class on the corresponding `<a>` tag.
115+
116+
## Key Insights
117+
118+
### `backdrop-filter` needs explicit dark-mode override
119+
The nav `background: rgba(255,255,255,0.82)` is hardcoded (not `var(--bg)`) because CSS variables can't decompose to `rgba` components. Dark mode requires a separate `[data-theme="dark"] .nav { background: rgba(28,28,30,0.88) }` rule. This is the same pattern iOS itself uses — bg color + blur, not transparency alone.
120+
121+
### Quick Start `ol` card styling doesn't affect docs `ol`
122+
The `.home-section ol` selector is scoped to the homepage only (docs pages don't have `.home-section` ancestors), so stripping `list-style` and adding `display: flex` doesn't leak into docs content.
123+
124+
### Hugo not available in the deployment environment
125+
`hugo` binary was not installed in the session environment (not on PATH, not findable). Validated:
126+
- CSS brace balance via Python (`128 opens == 128 closes`)
127+
- HTML div balance via Python
128+
- JS syntax via `node --check`
129+
Build validation depends on CI (GitHub Actions → Cloudflare Pages).
130+
131+
### IntersectionObserver `rootMargin` for TOC is tricky
132+
`rootMargin: "-8% 0px -75% 0px"` means the "active zone" is from 8% from top to 25% from top of viewport. When a heading scrolls into that narrow band, it becomes active. This gives a natural feel where the TOC highlights slightly ahead of the heading reaching the very top.
133+
134+
## Decisions Made
135+
136+
- **Apple blue (`#007AFF`) over GitHub blue (`#0969da`)** — the project is health-data tooling inspired by iOS Health; Apple blue is more on-brand and warmer. The exact dark-mode variant `#0A84FF` is from Apple's HIG.
137+
- **`fadeSlideUp` not `fadeIn`** — the 10px vertical movement makes the entrance feel physical and intentional, not a flat opacity pop. 0.45s is the sweet spot: fast enough to not feel slow, long enough to read as intentional.
138+
- **Metric badge color dots, not icons** — icons would require SVG assets or an icon font. Tiny colored dots (7px circles) convey the same category identity as iOS Health's chart colors with zero added complexity.
139+
- **No scroll-triggered animations beyond hero** — section headings and content boxes do NOT animate in on scroll. Only the hero (above the fold) gets the entrance animation. Scroll animations on content risk looking like a SaaS landing page.
140+
- **`prefers-reduced-motion`** — zero-cost accessibility improvement, collapses all `animation-duration` and `transition-duration` to `0.01ms`. Important for users with vestibular disorders.
141+
142+
---

0 commit comments

Comments
 (0)