diff --git a/apps/web/src/app/create/worksheets/components/config-panel/RuleThermometer.tsx b/apps/web/src/app/create/worksheets/components/config-panel/RuleThermometer.tsx
index 35e6a1fe..b8e45c14 100644
--- a/apps/web/src/app/create/worksheets/components/config-panel/RuleThermometer.tsx
+++ b/apps/web/src/app/create/worksheets/components/config-panel/RuleThermometer.tsx
@@ -9,6 +9,8 @@ export interface RuleThermometerProps {
value: RuleMode
onChange: (value: RuleMode) => void
isDark?: boolean
+ /** When value is 'auto', this shows which value 'auto' resolves to */
+ resolvedValue?: RuleMode
}
const RULE_OPTIONS: Array<{ value: RuleMode; label: string; short: string }> = [
@@ -26,8 +28,10 @@ export function RuleThermometer({
value,
onChange,
isDark = false,
+ resolvedValue,
}: RuleThermometerProps) {
const selectedIndex = RULE_OPTIONS.findIndex((opt) => opt.value === value)
+ const isAutoSelected = value === 'auto'
return (
{RULE_OPTIONS.map((option, index) => {
const isSelected = value === option.value
+ // When 'auto' is selected, show which value it resolves to with secondary color
+ const isAutoResolved = isAutoSelected && resolvedValue === option.value
const isLeftmost = index === 0
const isRightmost = index === RULE_OPTIONS.length - 1
@@ -82,16 +88,31 @@ export function RuleThermometer({
key={option.value}
type="button"
onClick={() => onChange(option.value)}
- title={option.label}
+ title={isAutoResolved ? `${option.label} (currently selected by Auto)` : option.label}
className={css({
flex: 1,
px: '2',
py: '1.5',
fontSize: '2xs',
- fontWeight: isSelected ? 'bold' : 'medium',
- color: isSelected ? (isDark ? 'white' : 'white') : isDark ? 'gray.400' : 'gray.600',
- bg: isSelected ? 'brand.500' : 'transparent',
- border: 'none',
+ fontWeight: isSelected ? 'bold' : isAutoResolved ? 'semibold' : 'medium',
+ color: isSelected
+ ? 'white'
+ : isAutoResolved
+ ? isDark
+ ? 'green.300'
+ : 'green.700'
+ : isDark
+ ? 'gray.400'
+ : 'gray.600',
+ bg: isSelected
+ ? 'brand.500'
+ : isAutoResolved
+ ? isDark
+ ? 'green.900/30'
+ : 'green.100'
+ : 'transparent',
+ border: isAutoResolved ? '1px solid' : 'none',
+ borderColor: isAutoResolved ? (isDark ? 'green.700' : 'green.300') : 'transparent',
borderTopLeftRadius: isLeftmost ? 'md' : '0',
borderBottomLeftRadius: isLeftmost ? 'md' : '0',
borderTopRightRadius: isRightmost ? 'md' : '0',
@@ -99,7 +120,15 @@ export function RuleThermometer({
cursor: 'pointer',
transition: 'all 0.15s',
_hover: {
- bg: isSelected ? 'brand.600' : isDark ? 'gray.600' : 'gray.200',
+ bg: isSelected
+ ? 'brand.600'
+ : isAutoResolved
+ ? isDark
+ ? 'green.800/40'
+ : 'green.200'
+ : isDark
+ ? 'gray.600'
+ : 'gray.200',
color: isSelected ? 'white' : isDark ? 'gray.200' : 'gray.800',
},
})}
diff --git a/apps/web/src/app/create/worksheets/components/config-sidebar/ScaffoldingTab.tsx b/apps/web/src/app/create/worksheets/components/config-sidebar/ScaffoldingTab.tsx
index afb9aff0..a28ef613 100644
--- a/apps/web/src/app/create/worksheets/components/config-sidebar/ScaffoldingTab.tsx
+++ b/apps/web/src/app/create/worksheets/components/config-sidebar/ScaffoldingTab.tsx
@@ -7,6 +7,7 @@ import { useTheme } from '@/contexts/ThemeContext'
import { RuleThermometer } from '../config-panel/RuleThermometer'
import type { DisplayRules } from '../../displayRules'
import { defaultAdditionConfig } from '@/app/create/worksheets/config-schemas'
+import { getSkillById } from '../../skills'
export function ScaffoldingTab() {
const { formState, onChange } = useWorksheetConfig()
@@ -18,6 +19,33 @@ export function ScaffoldingTab() {
// Check if we're in mastery+mixed mode (needs operator-specific rules)
const isMasteryMixed = formState.mode === 'mastery' && formState.operator === 'mixed'
+ // Get resolved display rules for showing what 'auto' defers to
+ let resolvedDisplayRules: DisplayRules | undefined
+
+ if (formState.mode === 'mastery') {
+ const operator = formState.operator ?? 'addition'
+
+ if (operator === 'mixed') {
+ // Mixed mode: Use addition skill's recommendations for now (could show both)
+ const skillId = formState.currentAdditionSkillId
+ if (skillId) {
+ const skill = getSkillById(skillId as any)
+ resolvedDisplayRules = skill?.recommendedScaffolding
+ }
+ } else {
+ // Single operator: Use its skill's recommendations
+ const skillId =
+ operator === 'addition'
+ ? formState.currentAdditionSkillId
+ : formState.currentSubtractionSkillId
+
+ if (skillId) {
+ const skill = getSkillById(skillId as any)
+ resolvedDisplayRules = skill?.recommendedScaffolding
+ }
+ }
+ }
+
const updateRule = (key: keyof DisplayRules, value: DisplayRules[keyof DisplayRules]) => {
const newDisplayRules = {
...displayRules,
@@ -199,6 +227,7 @@ export function ScaffoldingTab() {
value={displayRules.answerBoxes}
onChange={(value) => updateRule('answerBoxes', value)}
isDark={isDark}
+ resolvedValue={resolvedDisplayRules?.answerBoxes}
/>
updateRule('placeValueColors', value)}
isDark={isDark}
+ resolvedValue={resolvedDisplayRules?.placeValueColors}
/>
updateRule('carryBoxes', value)}
isDark={isDark}
+ resolvedValue={resolvedDisplayRules?.carryBoxes}
/>
{(formState.operator === 'subtraction' || formState.operator === 'mixed') && (
@@ -236,6 +267,7 @@ export function ScaffoldingTab() {
value={displayRules.borrowNotation}
onChange={(value) => updateRule('borrowNotation', value)}
isDark={isDark}
+ resolvedValue={resolvedDisplayRules?.borrowNotation}
/>
)}
@@ -246,6 +278,7 @@ export function ScaffoldingTab() {
value={displayRules.borrowingHints}
onChange={(value) => updateRule('borrowingHints', value)}
isDark={isDark}
+ resolvedValue={resolvedDisplayRules?.borrowingHints}
/>
)}
@@ -255,6 +288,7 @@ export function ScaffoldingTab() {
value={displayRules.tenFrames}
onChange={(value) => updateRule('tenFrames', value)}
isDark={isDark}
+ resolvedValue={resolvedDisplayRules?.tenFrames}
/>
)