Fairy Chess

Challenge: Large, deeply-nested, and inter-dependent state objects that determine view rendering.
Solution: Unidirectional data-flow with a single useReducer. Its dispatch is shared app-wide with useContext.
Challenge: ~150 different chess pieces with precise, non-random movement algorithms.
Solution: A concise but readable encoding system that translates into movement algorithms. And, a higher-level algorithm to recursively recombine pieces, so complex pieces can be defined in the model by listing "component" pieces rather than listing moves.
Challenge: "background-attachment: fixed;" broken in Chrome with animations.
Solution: Wrapper component that reads the element's boundingClientRect and adjusts its background position to simulate a fixed position relative to viewport point (0, 0)