- {(['mixed', 'handwritten', 'typed'] as FontMode[]).map((mode) => (
+ {/* 2. Primary Actions: Shuffle, Scatter/Grid (Always Visible) */}
+
+
+
+ {/* Scatter / Grid Toggle */}
+
- ))}
-
-
+
+
- {/* 3. Desk Texture Selector */}
-
-
- {/* 4. Sliders: Cards, Grain, Attach, Light */}
-
- {/* Cards Count */}
-
-
Cards
-
onUpdateSettings({ cardCount: Number(e.target.value) })}
- className="w-14 accent-amber-500 cursor-pointer h-1.5 bg-neutral-700 rounded-lg appearance-none"
- />
-
- {settings.cardCount}
-
+ {/* Add New Card (+) Button */}
+
- {/* Grain */}
-
-
Grain
-
onUpdateSettings({ grain: Number(e.target.value) })}
- className="w-14 accent-amber-500 cursor-pointer h-1.5 bg-neutral-700 rounded-lg appearance-none"
- />
-
- {settings.grain.toFixed(2)}
-
+ {/* 3. Desktop-Only Controls (hidden on small/medium screens) */}
+
+ {/* Typography Mode */}
+
+ {(['mixed', 'handwritten', 'typed'] as FontMode[]).map((mode) => (
+
+ ))}
+
+
+ {/* Desk Texture Selector */}
+
+ Desk:
+
+
+
+ {/* Cards Count */}
+
+ Cards
+ onUpdateSettings({ cardCount: Number(e.target.value) })}
+ className="w-14 accent-amber-500 cursor-pointer h-1.5 bg-neutral-700 rounded-lg appearance-none"
+ />
+
+ {settings.cardCount}
+
+
+
+ {/* Grain */}
+
+ Grain
+ onUpdateSettings({ grain: Number(e.target.value) })}
+ className="w-14 accent-amber-500 cursor-pointer h-1.5 bg-neutral-700 rounded-lg appearance-none"
+ />
+
+ {settings.grain.toFixed(2)}
+
+
+
+ {/* Light Angle */}
+
+ Light
+ onUpdateSettings({ lightAngle: Number(e.target.value) })}
+ className="w-14 accent-amber-400 cursor-pointer h-1.5 bg-neutral-700 rounded-lg appearance-none"
+ />
+
+ {settings.lightAngle}掳
+
+
+
+ {/* Checkboxes: Props, Motion, Pen */}
+
+
+
+
+ {/* Sound Toggle */}
+
+
+ {/* Card Type Filter */}
+
+
+ {/* Portfolio */}
+
- {/* Attach Chance */}
-
- Attach
- onUpdateSettings({ attachChance: Number(e.target.value) })}
- className="w-14 accent-amber-500 cursor-pointer h-1.5 bg-neutral-700 rounded-lg appearance-none"
- />
-
- {Math.round(settings.attachChance * 100)}%
-
-
-
- {/* Dynamic Light Direction Dial */}
-
- Light
- onUpdateSettings({ lightAngle: Number(e.target.value) })}
- className="w-14 accent-amber-400 cursor-pointer h-1.5 bg-neutral-700 rounded-lg appearance-none"
- />
-
- {settings.lightAngle}掳
-
-
-
-
- {/* 5. Checkboxes: Props, Motion, Pen */}
-
-
-
-
-
-
-
-
- {/* 6. Action Buttons & Filter */}
-
+ {/* 4. Mobile Settings Trigger (always accessible on mobile & tablet) */}
+
- {/* Sound Toggle */}
-
+ {/* 5. Mobile Drawer / Bottom Sheet */}
+ {mobileMenuOpen && (
+
+
+
+
+
+
Desk Controls & Tools
+
+
+
- {/* Card Type Filter */}
-
+ {/* Desk Surface Texture */}
+
+
+
+ {[
+ { id: 'oak', label: 'Oak Desk' },
+ { id: 'walnut', label: 'Walnut' },
+ { id: 'cutting-mat', label: 'Mat' },
+ { id: 'corkboard', label: 'Cork' },
+ { id: 'blueprint', label: 'Blueprint' },
+ { id: 'dark-slate', label: 'Slate' },
+ { id: 'marble', label: 'Marble' }
+ ].map((d) => (
+
+ ))}
+
+
- {/* Add New Card (+) Button */}
-
+ {/* Typography */}
+
+
+
+ {(['mixed', 'handwritten', 'typed'] as FontMode[]).map((mode) => (
+
+ ))}
+
+
- {/* Portfolio Mode / Presets Modal Button */}
-
+ {/* Sliders: Density, Grain, Light */}
+
+
+
+ Card Count
+ {settings.cardCount} sheets
+
+
onUpdateSettings({ cardCount: Number(e.target.value) })}
+ className="w-full accent-amber-500 cursor-pointer h-2 bg-neutral-800 rounded-lg"
+ />
+
- {/* Stats readout like in original */}
-
- {totalCards}/{totalCards} sheets
-
-
-
+
+
+ Paper Texture Grain
+ {settings.grain.toFixed(2)}
+
+
onUpdateSettings({ grain: Number(e.target.value) })}
+ className="w-full accent-amber-500 cursor-pointer h-2 bg-neutral-800 rounded-lg"
+ />
+
+
+
+
+ Lighting Angle
+ {settings.lightAngle}掳
+
+
onUpdateSettings({ lightAngle: Number(e.target.value) })}
+ className="w-full accent-amber-400 cursor-pointer h-2 bg-neutral-800 rounded-lg"
+ />
+
+
+
+ {/* Quick Toggles */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+ >
);
};
diff --git a/src/utils/proceduralCards.ts b/src/utils/proceduralCards.ts
index 42101ca..e63275d 100644
--- a/src/utils/proceduralCards.ts
+++ b/src/utils/proceduralCards.ts
@@ -286,10 +286,12 @@ export function generateProceduralCards(
fontMode: 'mixed' | 'handwritten' | 'typed' = 'mixed'
): CardItem[] {
const cards: CardItem[] = [];
- const paddingX = 80;
- const paddingY = 90;
- const usableWidth = Math.max(500, canvasWidth - paddingX * 2);
- const usableHeight = Math.max(400, canvasHeight - paddingY * 2);
+ const isMobile = canvasWidth < 768;
+ const scale = isMobile ? Math.min(1, Math.max(0.75, canvasWidth / 500)) : 1.0;
+ const paddingX = isMobile ? 25 : 80;
+ const paddingY = isMobile ? 70 : 90;
+ const usableWidth = Math.max(260, canvasWidth - paddingX * 2);
+ const usableHeight = Math.max(380, canvasHeight - paddingY * 2);
const availableFonts = FONTS_BY_MODE[fontMode];
@@ -345,8 +347,8 @@ export function generateProceduralCards(
vx: 0,
vy: 0,
rotation: rotation,
- width: preset.width || 180,
- height: preset.height || 180,
+ width: Math.round((preset.width || 180) * scale),
+ height: Math.round((preset.height || 180) * scale),
zIndex: i + 1,
isPinned: false,
attachType: attachType,