Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | /**
* Timing configuration for progressive help system
*
* Production values give the kid time to try on their own before hints appear.
* Debug values allow fast iteration during development.
*/
export const HELP_TIMING = {
production: {
/** Delay before showing coach hint */
coachHintDelayMs: 5000,
/** Delay before showing bead tooltip */
beadTooltipDelayMs: 10000,
/** Duration of celebration animation */
celebrationDurationMs: 800,
/** Duration of fade-out transition */
transitionDurationMs: 300,
},
debug: {
/** Delay before showing coach hint */
coachHintDelayMs: 1000,
/** Delay before showing bead tooltip */
beadTooltipDelayMs: 3000,
/** Duration of celebration animation */
celebrationDurationMs: 500,
/** Duration of fade-out transition */
transitionDurationMs: 200,
},
} as const
export type HelpTimingConfig = {
readonly coachHintDelayMs: number
readonly beadTooltipDelayMs: number
readonly celebrationDurationMs: number
readonly transitionDurationMs: number
}
/**
* Get timing configuration based on debug mode
*/
export function getHelpTiming(debug: boolean): HelpTimingConfig {
return debug ? HELP_TIMING.debug : HELP_TIMING.production
}
/**
* Progressive assistance timing configuration
*
* Controls the escalation from idle → encouragement → help offer → auto-pause.
* Production values give kids time; debug values allow fast iteration.
*/
export const PROGRESSIVE_ASSISTANCE_TIMING = {
production: {
/** Default encouragement delay when not enough data for stats (ms) */
defaultEncouragementMs: 15_000,
/** Default help offer delay when not enough data for stats (ms) */
defaultHelpOfferMs: 30_000,
/** Min clamp for encouragement threshold (ms) */
minEncouragementMs: 8_000,
/** Max clamp for encouragement threshold (ms) */
maxEncouragementMs: 45_000,
/** Min clamp for help offer threshold (ms) */
minHelpOfferMs: 15_000,
/** Max clamp for help offer threshold (ms) */
maxHelpOfferMs: 90_000,
/** Min clamp for auto-pause threshold (ms) */
minAutoPauseMs: 15_000,
/** Max clamp for auto-pause threshold (ms) */
maxAutoPauseMs: 300_000,
/** Number of wrong answers before suggesting help */
wrongAnswerThreshold: 3,
/** Grace period after all terms helped before moveOn becomes available (ms) */
moveOnGraceMs: 12_000,
},
debug: {
defaultEncouragementMs: 3_000,
defaultHelpOfferMs: 6_000,
minEncouragementMs: 2_000,
maxEncouragementMs: 10_000,
minHelpOfferMs: 4_000,
maxHelpOfferMs: 15_000,
minAutoPauseMs: 8_000,
maxAutoPauseMs: 30_000,
wrongAnswerThreshold: 2,
moveOnGraceMs: 3_000,
},
} as const
export interface ProgressiveAssistanceTimingConfig {
readonly defaultEncouragementMs: number
readonly defaultHelpOfferMs: number
readonly minEncouragementMs: number
readonly maxEncouragementMs: number
readonly minHelpOfferMs: number
readonly maxHelpOfferMs: number
readonly minAutoPauseMs: number
readonly maxAutoPauseMs: number
readonly wrongAnswerThreshold: number
readonly moveOnGraceMs: number
}
/**
* Get progressive assistance timing based on debug mode
*/
export function getProgressiveAssistanceTiming(debug: boolean): ProgressiveAssistanceTimingConfig {
return debug ? PROGRESSIVE_ASSISTANCE_TIMING.debug : PROGRESSIVE_ASSISTANCE_TIMING.production
}
/**
* Check if we should use debug timing
* - Always false in production builds
* - True in development if localStorage flag is set or storybook
*/
export function shouldUseDebugTiming(): boolean {
if (typeof window === 'undefined') return false
if (process.env.NODE_ENV === 'production') return false
// Check for storybook
if (window.location?.href?.includes('storybook')) return true
// Check for localStorage flag
try {
return localStorage.getItem('helpDebugTiming') === 'true'
} catch {
return false
}
}
|