Writing & Insights

Blog

Thoughts on design decisions, engineering explorations, and lessons learned from building human-centered digital experiences.

5 Lessons from Designing Industrial HMI Systems

When I started as a Designing Engineer at GEE KAY VEE HYDRAULICS, I expected the work to be straightforward — take the existing screens and make them look better. I was wrong. Industrial UX is a fundamentally different discipline from consumer app design, and it taught me lessons I carry into every project.

1. Design for Gloved Hands, Not Fingertips

The mobile industry settled on 44px as the minimum touch target size. In industrial settings, that number is meaningless. Operators wear thick protective gloves, and their hands are often damp or oily. We sized all interactive elements at 64px minimum — 45% larger than the mobile standard — and added haptic-style visual feedback (scale animations on tap) to compensate for the reduced tactile precision.

2. Color is a Safety System, Not Decoration

In a consumer app, a red badge might mean "you have notifications." In an HMI, red means "pressure is about to exceed safe limits." The semantic weight of color is dramatically higher. We established a strict color vocabulary: green = operational, amber = caution/approaching threshold, red = critical/emergency. Every color token was documented with its operational meaning, not just its hex value.

3. Glanceability Beats Comprehensiveness

Operators don't sit and read the screen. They glance at it every 2-3 seconds while performing physical tasks. This means the most important information must be perceivable in under 500ms. We used large numeric displays, animated gauges (needle position is faster to read than digits), and spatial consistency — the temperature is always in the top-right, pressure always in the center.

4. Design for the Worst Case

Most UI design optimizes for the happy path. Industrial design must optimize for the failure state. The emergency shutdown button was always visible, always one tap, and always in the same position — regardless of which screen the operator was viewing. We tested the emergency flow under simulated stress conditions with actual operators.

5. The Design System is the Product

With 4 different hydraulic press types, each with slightly different telemetry requirements, a component library wasn't a nice-to-have — it was the core deliverable. The 150+ Figma components with 8 state variants each became the engineering team's implementation spec. The design system reduced cross-project design time by an estimated 60%.

Industrial UX taught me that design constraints aren't limitations — they're the foundation of focused, effective design work. Every constraint forced a better solution.


Why Accessibility is a Design Problem, Not Just an Engineering One

There's a common pattern in product teams: designers create the "ideal" visual design, then engineers add accessibility as a compliance checkbox at the end. ARIA labels here, alt text there, maybe a skip link. This approach produces technically compliant but experientially poor interfaces.

Accessibility is a design problem. It requires understanding how different users perceive, navigate, and interact with your interface — and making intentional design decisions to accommodate those differences.

Contrast is a Design Decision

When I design a color palette, I test every combination for WCAG contrast ratios before committing to it. Not after. The primary color (#8B5F6 on dark backgrounds) was chosen partly because it meets 4.5:1 contrast against the background — that's not a happy accident, it's a design constraint.

Keyboard Navigation Needs Visual Design

A visible focus indicator isn't just an engineering addition — it needs to be designed. Our 2px solid primary-color focus ring was a conscious decision: thick enough to be visible, colored to be distinctive, positioned to not obscure content. Engineers implemented it, but design defined it.

Screen Readers Reveal Information Architecture Flaws

When I navigated my portfolio with VoiceOver for the first time, the heading structure exposed a disorganized page. Screen readers don't see your beautiful layout — they see your HTML structure. If your heading hierarchy doesn't make sense when read linearly, your information architecture has problems that visual design can't hide.

Reduced Motion is Empathy in Code

Some users experience motion sickness, vestibular disorders, or anxiety from animations. The prefers-reduced-motion media query isn't a nice-to-have — it's a fundamental respect for user diversity. Every animation in this portfolio is gracefully degraded when this preference is detected.

The Business Case

Beyond the moral imperative, accessible design is better design. High contrast improves readability for everyone. Clear heading hierarchy improves SEO. Keyboard navigation improves power-user efficiency. Focus management improves form completion rates. Accessibility doesn't limit design — it elevates it.

My portfolio explicitly documents its accessibility implementation — not because accessibility is a feature, but because it's evidence of design maturity.


Building a Scrollytelling Hero with Canvas Frame Scrubbing

The scrollytelling hero animation on this portfolio replaces a traditional <video> tag with something more interactive and performant: a sequence of 75 WebP images rendered on an HTML5 Canvas, scrubbed by the user's scroll position. Here's how it works, why I chose this approach, and what I learned.

Why Not Just Use a Video?

Video tags are simple but have critical limitations for scroll-linked interaction: no frame-precise control (you're at the mercy of the browser's buffering), codec compatibility issues across browsers, and inability to pause at exact positions. Canvas gives us pixel-perfect frame control synced to scroll position.

The Image Sequence Pipeline

The animation was originally a 3-second cinematic AI-generated video. I converted it to WebP format using ezgif at 15fps, then split it into 75 individual frames. Each frame is approximately 8KB — totaling ~600KB for the entire sequence. Compare this to the original 15MB video file: a 96% size reduction with better control.

The RAF Lerp Loop

The rendering engine uses requestAnimationFrame with linear interpolation (lerp). When the user scrolls, we calculate a target frame index based on scroll progress (0-1 mapped to frame 0-74). The lerp function smoothly interpolates between the current frame and target frame with a factor of 0.15, creating buttery-smooth transitions even when scroll input is jumpy.

The key insight: don't render on scroll events. Render on every animation frame, and let the scroll handler just update the target. This decouples input from rendering and prevents frame drops.

Progressive Preloading

All 75 frames are preloaded via JavaScript Image objects before the canvas renders anything. We track load progress and show a loading indicator. Frames are rendered as soon as they load (not waiting for all 75), so the user sees the animation progressively appear. This means even on slow connections, the experience degrades gracefully.

The Vignette Overlay

A critical detail: the canvas sits behind the content, and a CSS vignette overlay blends the animation edges into the page background color (#07090e). This gradient mask ensures seamless transitions between the animated hero and the content sections below, making the scroll container feel like a natural part of the page rather than a disconnected visual element.

Performance Results

The animation runs at 60fps on mid-range devices (tested on a 2020 MacBook Air and Pixel 6). The total asset weight is ~600KB (frames) + ~85KB (gzipped JS bundle). On Netlify, immutable caching headers ensure frames are cached after first load, making subsequent visits essentially free.

This project reinforced my belief that creative development isn't about using the fanciest library — it's about choosing the right tool for the interaction you want to create, and engineering it with performance as a constraint from day one.