Files
skill-tree-portfolio/src/lib/config.ts
T
TehRiehlDealandClaude Opus 4.8 6c652e7138 refactor: centralize theme/config/utils + fix data and console bugs
Phase 1 of the cohesion refactor (behavior-preserving):

Single source of truth:
- New src/lib/theme.ts: category colors (moved from data.ts, re-exported
  for back-compat), derived hex strings, nebula palette, UI colors, CSS var map
- New src/lib/config.ts: breakpoint, zoom, parallax, node radii, particle
  counts, animation timings (previously scattered magic numbers)
- New src/lib/utils/tree.ts: getNodeById, getNodeRadius, getDistanceFromOrigin,
  getBeamIntensity (pure helpers lifted out of onMount)
- New src/lib/utils/stats.ts: branch ids/labels, proficiency order, and the
  stats-panel aggregation helpers (deduped from inline copies)
- SkillTree.svelte now imports all of the above; removed the duplicated
  getCategoryColorHex, stats helpers, branch id/label lists, and inline magic numbers
- Populated src/lib/index.ts barrel

Bug fixes:
- data.ts: tmdbAPI pypiUrl pointed at tvdbAPI -> corrected to tmdbAPI
- Removed/ gated stray console.log noise (skill-tree-loaded, SW logs)
- Removed dead vars (maxAlpha, glowMaxAlpha) and unused catch binding

Tooling: ESLint + Prettier now clean; added Vitest unit tests for the new
pure utils (14 tests). svelte-check: 0 errors. build: ok.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 09:40:27 -07:00

63 lines
1.9 KiB
TypeScript

// ==========================================================================
// CONFIG — non-colour tunables (colours live in `theme.ts`).
//
// Centralises the magic numbers that were previously scattered through
// SkillTree.svelte so behaviour can be tuned in one place.
// ==========================================================================
/**
* Viewport width (px) below which the mobile layout/behaviour kicks in.
* NOTE: JS treats `< 768` as mobile; CSS media queries use `max-width: 767px`.
* Both make 768px the first desktop width — keep that pairing if you change this.
*/
export const MOBILE_BREAKPOINT = 768;
/** Pan/zoom limits and step sizes. */
export const ZOOM = {
min: 0.3,
max: 2.5,
keyStep: 0.1,
wheelIn: 1.1,
wheelOut: 0.9
} as const;
/** Background parallax lag factors (fraction of tree movement). */
export const PARALLAX = {
star: 0.1,
nebula: 0.07,
gradient: 0.05
} as const;
/** Node radii by size (desktop px); mobile multiplies by MOBILE_RADIUS_FACTOR. */
export const NODE_RADII: Record<string, number> = {
'x-large': 75,
large: 30,
medium: 25,
small: 20,
default: 14
};
export const MOBILE_RADIUS_FACTOR = 0.8;
/** Keyboard pan distance per arrow-key press (px). */
export const PAN_SPEED = 50;
/** Background particle counts (desktop / mobile). */
export const PARTICLE_COUNTS = {
distantStars: { desktop: 200, mobile: 100 },
mediumStars: { desktop: 60, mobile: 30 },
brightStars: { desktop: 15, mobile: 8 },
dust: { desktop: 30, mobile: 15 }
} as const;
/** Entrance-animation timings (seconds), split by device. */
export const TIMINGS = {
titleDuration: { desktop: 2.5, mobile: 1.5 },
zoomDuration: { desktop: 4.5, mobile: 2.5 },
nodeStagger: { desktop: 0.08, mobile: 0.05 }
} as const;
/** Helper: pick a desktop/mobile value. */
export function byDevice<T>(pair: { desktop: T; mobile: T }, isMobile: boolean): T {
return isMobile ? pair.mobile : pair.desktop;
}