diff --git a/src/App/GamepadModal/GamepadDiagram.tsx b/src/App/GamepadModal/GamepadDiagram.tsx
index 5aaa2a5ca..860969390 100644
--- a/src/App/GamepadModal/GamepadDiagram.tsx
+++ b/src/App/GamepadModal/GamepadDiagram.tsx
@@ -78,20 +78,20 @@ const GamepadDiagram = () => {
- {/* ===== L2 / R2 TRIGGERS (drawn first, behind everything) ===== */}
-
- {BTN.L2}
-
- {BTN.R2}
-
- {/* ===== CONTROLLER BODY ===== */}
+
+
+ {BTN.L2}
+
+ {BTN.R2}
+
{
strokeWidth={'2.5'}
/>
- {/* ===== TOUCHPAD ===== */}
-
+
+
+
+
+ {BTN.L1}
+
+
+
+ {BTN.R1}
+
+
+
+
+ △
+
+
+
+
+ ○
+
+
+
+
+ ✕
+
+
+
+
+ □
+
+
+
+
+
+
+
+ ↑
+ ↓
+ ←
+ →
+
+
+
+
+
+ {ARROW.UP}
+ {ARROW.DOWN}
+ {ARROW.LEFT}
+ {ARROW.RIGHT}
+
- {/* ===== L1 / R1 BUMPERS (on top of body, on shoulder edge) ===== */}
-
-
- {BTN.L1}
-
-
-
- {BTN.R1}
- {/* ===== FACE BUTTONS (right, centered at CX+BX) ===== */}
- {/* △ */}
-
-
- △
-
- {/* ○ */}
-
-
- ○
-
- {/* ✕ */}
-
-
- ✕
-
- {/* □ */}
-
-
- □
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- {/* ===== D-PAD (left, mirrored at CX-BX) — cosmetic only ===== */}
-
-
-
- {/* ===== LEFT STICK (CX-STX) ===== */}
-
-
-
- ↑
- ↓
- ←
- →
+
+ {t('GAMEPAD_ACTION_PREV_TAB')}
+ {t('GAMEPAD_ACTION_NAVIGATE')}
+ {t('GAMEPAD_ACTION_GUIDE')}
+ {t('GAMEPAD_LABEL_PLAY_PAUSE_PLAYER')}
+ {t('GAMEPAD_ACTION_NEXT_TAB')}
+ {t('GAMEPAD_ACTION_FULLSCREEN')}
+ {t('GAMEPAD_ACTION_BACK')}
+ {t('GAMEPAD_ACTION_SELECT')}
+ {t('GAMEPAD_LABEL_SEEK_VOL')}
+ {t('GAMEPAD_LABEL_COMPAT')}
-
- {/* ===== RIGHT STICK (CX+STX) ===== */}
-
-
-
- {ARROW.UP}
- {ARROW.DOWN}
- {ARROW.LEFT}
- {ARROW.RIGHT}
-
-
- {/* ============================= */}
- {/* ===== LABELS — LEFT ===== */}
- {/* ============================= */}
-
- {/* L1 */}
-
-
- {t('GAMEPAD_ACTION_PREV_TAB')}
-
- {/* Left stick */}
-
-
- {t('GAMEPAD_ACTION_NAVIGATE')}
-
- {/* □ Square */}
-
-
- {t('GAMEPAD_ACTION_GUIDE')}
- {t('GAMEPAD_LABEL_PLAY_PAUSE_PLAYER')}
-
- {/* ============================= */}
- {/* ===== LABELS — RIGHT ===== */}
- {/* ============================= */}
-
- {/* R1 */}
-
-
- {t('GAMEPAD_ACTION_NEXT_TAB')}
-
- {/* △ Triangle */}
-
-
- {t('GAMEPAD_ACTION_FULLSCREEN')}
-
- {/* ○ Circle */}
-
-
- {t('GAMEPAD_ACTION_BACK')}
-
- {/* ✕ Cross */}
-
-
- {t('GAMEPAD_ACTION_SELECT')}
-
- {/* Right stick */}
-
-
- {t('GAMEPAD_LABEL_SEEK_VOL')}
-
- {/* Compat note */}
- {t('GAMEPAD_LABEL_COMPAT')}
);
};
diff --git a/src/App/GamepadModal/styles.less b/src/App/GamepadModal/styles.less
index 870c4c92d..e512aa333 100644
--- a/src/App/GamepadModal/styles.less
+++ b/src/App/GamepadModal/styles.less
@@ -93,10 +93,50 @@
}
}
+ @keyframes draw-stroke {
+ from { stroke-dashoffset: 2000; }
+ to { stroke-dashoffset: 0; }
+ }
+
+ @keyframes draw-line {
+ from { stroke-dashoffset: 800; }
+ to { stroke-dashoffset: 0; }
+ }
+
+ @keyframes fade-in {
+ from { opacity: 0; }
+ to { opacity: 1; }
+ }
+
.diagram {
width: 100%;
max-width: 48rem;
height: auto;
+
+ .anim-body {
+ stroke-dasharray: 2000;
+ stroke-dashoffset: 0;
+ animation: draw-stroke 1.4s ease-in-out;
+ }
+
+ .anim-controls {
+ animation: fade-in 0.6s ease-out 1s both;
+ }
+
+ .anim-lines {
+ line {
+ stroke-dasharray: 800;
+ stroke-dashoffset: 0;
+ animation: draw-line 0.8s ease-out 1.6s both;
+ }
+ circle {
+ animation: fade-in 0.3s ease-out 2s both;
+ }
+ }
+
+ .anim-labels {
+ animation: fade-in 0.5s ease-out 2.2s both;
+ }
}
.sections {