Lab

Engineering decisions, tested in the product.

Real failure modes, working code, interface decisions, and the evidence used to verify each solution.

5shipped products examined
3real code paths explained
1working state model to test

From TrailDesk · Responsive system

One product, two deliberate layouts.

Interface study
Problem
A desktop planning hierarchy becomes cramped and ambiguous on a phone.
Decision
Reorder the interface around the next useful action instead of shrinking it.
Result
Context remains visible on desktop while mobile actions become linear.
TrailDesk destination discovery interface at desktop width
Desktop · destination context stays visible
TrailDesk interface adapted to a narrow mobile viewport
Mobile · actions become linear

The layout changes hierarchy rather than shrinking the desktop composition.

From DigiLearn · Engineering note

Local progress is parsed defensively.

Problem
Browser storage can be missing, malformed, duplicated, or unexpectedly large.
Decision
Validate shape, size, version, and identifiers before accepting saved progress.
Result
A damaged payload falls back safely without breaking the learning interface.
DigiLearn · lib/learning-storage.ts · excerpt
export function parseProgress(raw: string | null) {
  if (!raw || raw.length > 2_000_000) return EMPTY_PROGRESS;
  try {
    const value = record(JSON.parse(raw));
    if (!value) return EMPTY_PROGRESS;
    return {
      version: 2,
      completedLessonIds: uniqueIds(value.completedLessonIds),
      openedLessonIds: uniqueIds(value.openedLessonIds),
      completedChecks: uniqueIds(value.completedChecks),
    };
  } catch {
    return EMPTY_PROGRESS;
  }
}

Versioned local storage learning state survives malformed storage, duplicate IDs, and oversized payloads.

From SafeSignal · Component states

Safety states communicate without relying on colour.

Problem
Colour alone cannot reliably explain an urgent check-in state.
Decision
Pair every state with a name, time signal, and explicit next action.
Result
Meaning survives low vision, poor screens, bright light, and grayscale.
01Normal24 min remaining
02ApproachingCheck-in soon
03GraceContact worker
04OverdueEscalation required
See the real state logic
SafeSignal · lib/session.ts · excerpt
export function deriveTimerState(session: ActiveSession, now = Date.now()) {
  if (session.phase === "overdue") return "overdue";
  if (session.phase === "grace") {
    return remainingSeconds(session.graceDeadlineAt || session.deadlineAt, now) > 0
      ? "grace"
      : "overdue";
  }
  const left = remainingSeconds(session.deadlineAt, now);
  if (left <= 60) return "due-soon";
  if (left <= Math.min(300, Math.max(120, session.intervalMinutes * 60 * .2)))
    return "approaching";
  return "normal";
}

From ElectraCore · Code and result

Technical content earns the screen.

Live product
Problem
A calculator answer without assumptions is difficult to trust or learn from.
Decision
Show the result first, then expose the reasoning and design path beneath it.
Result
The same workflow supports quick trade use and deeper technical learning.
electracore.vercel.app/calculate
ElectraCore electrical calculation tools rendered from the live application
Eight calculators with local saved results
electracore.vercel.app/design
ElectraCore circuit designer rendered from the live application
Load to cable design workflow

The calculator, designer, lesson diagrams, checks, and progress state are separate working systems. Each screen states its assumptions and review limits.

Verification · This portfolio

A feature is not finished when it only looks right.

Repeatable checks
01

Code

Lint, TypeScript, and a production build catch structural failures before release.

02

Routes

Every internal route and every external project link is checked for a real response.

03

Interface

Phone and desktop viewports are checked for overflow, missing labels, small controls, and browser errors.

04

Human use

Keyboard focus, reduced motion, readable hierarchy, and status meaning are treated as product requirements.

npm run lintnpm run typechecknpm run buildnpm run check:links