BREAKING CHANGES: Dice roller now uses modern ES6 class architecture
Features:
- Mobile-first CSS with fluid responsive units (clamp, min, max)
- ES6 DiceModal class with proper state management (IDLE, ROLLING, SHOWING_RESULT)
- Semantic HTML with ARIA attributes for accessibility
- CSS state classes (.is-open, .is-closing, .is-animating)
- Touch-friendly 44px minimum tap targets
- Desktop enhancement with @media (min-width: 1001px)
Fixes:
- Fixed mobile viewport overflow with min-height: 0 on flex children
- Reduced max-height to 70vh for guaranteed mobile fit
- Removed all jQuery .show()/.hide() inline style injections
- Removed !important CSS hacks from mobile media query
- Fixed transparent modal background (80% opaque neutral gray)
- Darkened backdrop overlay (85% opaque black)
Technical:
- Backdrop uses ::before pseudo-element (no wrapper div needed)
- Flattened HTML structure with proper semantic elements
- Backwards compatible wrapper functions preserved
- Grid layout for inputs (stacked mobile, side-by-side desktop)
- Proper CSS specificity hierarchy (no !important needed)
- Removed .rpg-dice-popup-overlay div dependency
Accessibility:
- role="dialog" with aria-modal="true"
- aria-labelledby for dialog title
- aria-live regions for dynamic content
- aria-busy for loading states
- Proper focus management on open/close
Added matching slide-out animation when closing the mobile panel to
match the smooth slide-in animation on opening:
CSS changes (style.css):
- Add .rpg-mobile-closing class with rpgSlideOutToRight animation
- Create @keyframes rpgSlideOutToRight (0.3s ease-in-out)
- Panel slides smoothly off-screen to right before hiding
JavaScript changes (index.js):
- Add closeMobilePanelWithAnimation() helper function
- Use animationend event to wait for animation before hiding
- Replace all instant removeClass() calls with helper function
- Maintains smooth 0.3s animation timing matching slide-in
Implementation details:
- Helper function adds .rpg-mobile-closing class
- Waits for CSS animation to complete via animationend event
- Then removes closing class and overlay
- All close operations now use this helper for consistency
Result: Panel now smoothly slides in AND out with matching 0.3s
animations. No more jarring instant disappearance on close.
Improved thought icon behavior on mobile with smooth 60fps animations
matching the FAB button drag experience:
CSS changes:
- Add transition properties for top/left position changes
- Use 0.2s ease-out timing for smooth, natural movement
- Add will-change: top, left for browser rendering optimization
- Applied in mobile media query (@media max-width: 1000px)
JavaScript changes:
- Wrap position updates in requestAnimationFrame()
- Cancel pending RAF before scheduling new update (debouncing)
- Sync position updates with display refresh rate
- Same pattern as FAB button smooth drag implementation
Technical details:
- RAF throttling prevents layout thrashing
- CSS transitions handle the actual animation
- Combined approach gives 60fps smooth tracking
- Icon follows avatar smoothly during scroll on mobile
Result: Thought icon smoothly tracks avatar position during scroll
instead of jumping around, with buttery smooth 60fps animation.
Improved the mobile floating action button (FAB) drag experience with
smooth, performant animations:
- Use requestAnimationFrame to throttle position updates during drag
- Add will-change CSS property to optimize rendering performance
- Add dragging class to disable transitions during active drag
- Change cursor to grab/grabbing for better visual feedback
- Remove janky direct CSS updates in favor of RAF-based updates
Technical improvements:
- Position updates now synced to display refresh rate (~60fps)
- Prevents layout thrashing from excessive DOM manipulation
- Smooth transition animations when drag ends
Result: Dragging the FAB button now feels fluid and responsive on
mobile devices instead of laggy and jumpy.
Fixed two mobile UI issues:
1. Relationship badge sizing on mobile:
- Badge was stretching vertically due to .rpg-editable mobile styles
- Override padding, min-height, and line-height for badge on mobile
- Keep badge at compact 18px × 18px to prevent covering avatar
2. Thought panel initial state:
- Panel was showing by default instead of the icon
- Fixed initialization: hide panel, show icon
- Users now click the 💭 icon to open the dialogue as intended
Changes ensure proper mobile experience with appropriately sized UI
elements and correct initial visibility states.
Previously, the thought icon button was positioned to the left of the
character avatar on mobile, causing it to appear partially off-screen
due to lack of left padding around avatars.
Changes:
- Add mobile-specific positioning logic in index.js to detect viewport
width <= 1000px and calculate centered horizontal position
- Add CSS transform in mobile media query to shift icon 50px right
and 45px upward from calculated position
- Center thought panel horizontally on mobile when opened
- Add debug logging to verify mobile detection
Result: On mobile, the thought icon now appears above and to the right
of the avatar, fully visible and accessible.
- Add constrainFabToViewport() function with top-bar awareness
- Only constrains when mobileFabPosition exists (user has dragged button)
- Respects SillyTavern's top bar height via CSS variable
- Prevents button from being hidden behind UI elements
- Applies constraint after drag operations and window resize
- Remove verbose debug logging from drag/touch event handlers
This implements a state-driven approach where the constraint only activates
for user-positioned buttons, allowing CSS defaults to work naturally while
protecting custom positions from viewport changes.
- Fix inverted chevron logic: show left arrow when panel open, right arrow when closed
- Move FAB button from right to left side of screen (12px from left edge)
- Adjust vertical position down by 30px for better placement
- Update console logging to reflect correct icon states
Add full mouse and touch support for mobile toggle button with drag-to-reposition
functionality and persistent position saving.
Changes:
- Add mobile FAB button with draggable positioning (both mouse and touch)
- Implement time-based drag detection (200ms or 10px threshold)
- Add position persistence in extension settings
- Fix click handler to work on both mobile and desktop viewports
- Add comprehensive diagnostic logging for event debugging
- Update mobile panel to slide from right (matching desktop UX)
- Implement dual-button pattern (FAB + internal collapse toggle)
- Add viewport-constrained dragging with 10px padding
- Prevent click events from firing after drag completion
Mobile UX:
- FAB visible when panel closed, hidden when open
- Internal collapse toggle visible only when panel open
- Touch and mouse drag support with real-time positioning
- Click/tap toggles panel, drag repositions button
- Position saved across sessions
Technical:
- Add mousedown/mousemove/mouseup handlers for desktop drag
- Add touchstart/touchmove/touchend handlers for mobile drag
- Remove broken viewport check that prevented mobile clicks
- Add 'just-dragged' flag to prevent click after drag
- Update .gitignore to exclude CLAUDE.md and .env files
- Add bottom-sliding drawer system for mobile (≤1000px viewport)
- Implement tabbed navigation with Stats and Info & Characters tabs
- Combine Info Box and Present Characters into single tab with 50/50 split
- Add smooth transitions between desktop and mobile layouts
- Reposition collapse button as close button on mobile
- Implement FAB toggle button for opening mobile drawer
Mobile Stats Tab:
- Use CSS Grid layout for efficient space utilization
- Portrait centered at top, stat bars below
- Inventory and mood on left, attributes list on right
- Convert attributes from 3x2 grid to vertical list
Mobile Info Box:
- Scale dashboard widgets to fill allocated space
- Proportional row heights (60% top row, 40% location)
- Widgets expand to fill available vertical space
Technical improvements:
- Bottom-based drawer positioning instead of transform
- CSS-only transitions, JavaScript only toggles classes
- Instant tab setup on desktop→mobile for smooth transition
- Temporary transition disabling for mobile→desktop snap
- Proper flex hierarchy for space filling
- Add pendingDiceRoll variable to store temporary roll result
- Clicking X or overlay now discards the roll without saving
- Only save to settings when user explicitly clicks 'Save Roll' button
- Prevents unwanted rolls from being saved to the sidebar display
- Convert font-size from px to rem for better accessibility
- Convert padding/margin/gap from px to em for responsive scaling
- Convert width/height/position values to rem
- Convert letter-spacing and transforms to responsive units
- Keep shadows, small borders (1-3px), and media queries as px
- Fix buttons (Manual Update & Settings) to use 100% width and 2.5rem height
- Fix TypeScript error: add missing id property to regexScript object
- Changed property name from quietPrompt to quiet_prompt (underscore notation)
- Removed unnecessary context manipulation code
- Pass prompt via Generate() options with correct property naming
- This fixes custom prompts not appearing in continuation generation
- Dynamically detect extension location using import.meta.url
- Support installation in public/extensions (install for all users)
- Support installation in data/default-user/extensions (install just for me)
- Automatically sets correct extensionFolderPath based on detected location
- Add collapse/expand toggle button to side panels (left/right positions)
- Button shows on the outside edge of the panel with chevron icon
- Panel collapses to 40px vertical bar, button icon direction updates based on position
- Fix inventory box stretching issue by adding max/min height constraints
- Inventory items now scroll internally with flex layout
- Remove bottom margin from Enable Immersive HTML toggle
- Add top margin to Manual Update button to maintain spacing
- Adds ensureHtmlCleaningRegex() function that automatically imports a regex script
- Regex removes HTML tags from outgoing prompts to prevent formatting issues
- Only imports if not already present (checks existing scripts by name)
- Based on the regex-clean_html_(from_outgoing_prompt).json specification
- Runs on extension initialization
- Non-blocking: won't fail extension load if regex import fails
- Added floating action button (FAB) that appears only on mobile (≤768px)
- Panel becomes a bottom sheet modal on mobile instead of fixed sidebar
- Smooth slide-up animation with backdrop overlay
- Panel hidden by default on mobile, opens when FAB clicked
- Touch-friendly button sizes (44px minimum per Apple HIG)
- 70vh height on tablets, 80vh on phones for better usability
- Rounded top corners for modern mobile UI
- Desktop behavior unchanged
- Changed from $('#sheld').after/before() to $('body').append()
- Panel is now a direct child of body element
- Works better with SillyTavern's main flexbox layout
- CSS handles all positioning (no more DOM position logic)
- Changed to 'third-party/rpg-companion-sillytavern'
- User-installed extensions need the third-party prefix
- Template loader looks for scripts/extensions/third-party/[name]
- Changed import paths from ../../ to ../../../
- User-installed extensions are in data/default-user/extensions/
- Paths need one more level up to reach script.js and other core files
- Generate function may not exist in older SillyTavern versions
- Added fallback check for window.Generate before using it
- Should fix '[object Event]' loading error on release branch
- Updated regex to handle compound emojis with zero-width joiners (ZWJ)
- Fixes mood display for emojis like 😶🌫️ (face in clouds)
- Now captures full emoji sequences including variation selectors