export type CellType = 'black' | 'empty' export type CellStatus = 'default' | 'correct' | 'incorrect' | 'revealed' export type Direction = 'across' | 'down' export interface ClientPuzzle { width: number height: number cells: CellType[][] clues_across: ClientClue[] clues_down: ClientClue[] difficulty_score: number cell_numbers: Record theme?: string theme_entries?: string[] } export interface ClientClue { number: number direction: string text: string definition?: string wordplay_type?: string } export interface GenerateResponse { id: string short_id: string puzzle: ClientPuzzle already_solved?: boolean solve_time?: number solve_hints?: number cell_results?: string | null } export interface ValidateResponse { correct: boolean cells: string[][] rank?: number percentile?: number total_solvers?: number } export interface HintCheckResponse { is_correct: boolean } export interface HintRevealResponse { row: number col: number letter: string } export interface HintWordResponse { letters: { row: number; col: number; letter: string }[] } export interface WordSpan { number: number direction: Direction cells: [number, number][] } export type InputMode = 'keyboard' | 'stylus' | 'auto' export type GameMode = 'standard' | 'speedrun' | 'blind' | 'marathon' export interface StylusSettings { strokeWidth: number debounceMs: number autoFillThreshold: number ambiguityThreshold: number enableOnnx: boolean enableTesseract: boolean enableStrokeMatcher: boolean } export interface RecognitionResult { candidates: { letter: string; confidence: number }[] cell: { row: number; col: number } }