feature/bootstrap-refactor #1

Merged
blightbow merged 42 commits from feature/bootstrap-refactor into main 2025-11-15 13:00:11 +00:00
Owner

Web UI refactor is ready.

Web UI refactor is ready.
Previously, the reflection prompt (triggered every N ticks to guide
the assistant in reviewing its performance and journal entries) was
hardcoded in assistant_script.py. This made it impossible for admins
to customize the reflection questions or metrics display without
modifying code.

Changes:
- Add script.db.reflection_prompt_template attribute with default
- Update _trigger_reflection() to use template with .format()
- Add Section 9 to prompt preview showing reflection template
- Add update handler with placeholder validation
- Template requires: reflection_interval, tasks_attempted,
  tasks_completed, success_rate, top_tools, recent_errors

Admins can now customize the reflection prompt through the
/ai/prompt-preview/ web interface, making it easier to tune the
assistant's self-evaluation behavior without touching source code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Phase 1, Step 1 of Bootstrap refactoring: migrate from custom modal
implementation to Bootstrap's native modal component.

Changes:
- Replace custom modal HTML with Bootstrap 4 modal markup
- Add proper ARIA attributes (role, aria-labelledby, aria-hidden)
- Use Bootstrap modal API ($().modal('show/hide'))
- Remove 122 lines of custom modal CSS
- Remove 9 lines of inline style manipulation from JavaScript
- Remove manual event listeners (Bootstrap handles via data-dismiss)

Benefits:
- Better accessibility with built-in ARIA support
- Keyboard navigation (Escape key) out of the box
- Mobile responsive behavior
- Consistent with Evennia's design system
- Simpler code maintenance

CSS reduction: 122 lines removed
JS simplification: All inline styles removed from modal functions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Phase 1, Step 2 of Bootstrap refactoring: migrate from custom navigation
implementation to Bootstrap's native nav-pills component.

Changes:
- Replace all <div class="dashboard-nav"> with <ul class="nav nav-pills">
- Update all navigation items to use proper <li><a> structure
- Use Bootstrap .nav-link and .active classes
- Add Bootstrap utility classes (mb-3, bg-white, p-3, rounded, shadow-sm)
- Remove 28 lines of custom navigation CSS from dashboard.css

Updated templates:
- dashboard.html, goals.html, session_memory.html
- projects.html, journal.html, prompt_preview.html

Benefits:
- Consistent navigation styling across all pages
- Better accessibility with proper semantic HTML (ul/li structure)
- Responsive behavior out of the box
- Proper focus states for keyboard navigation
- Simpler maintenance

CSS reduction: 28 lines removed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Phase 1, Step 3 of Bootstrap refactoring: migrate from custom badge
styles to Bootstrap's native badge component with color variants.

Changes:
- Update prompt_preview.js to use .badge .badge-primary for token badges
- Update prompt_preview.js to use .badge with dynamic color classes
- Add getStatusBadgeClass() helper to map status → badge variant
- Update dashboard.js to use .badge-success/.badge-danger
- Remove 32 lines of custom badge CSS from prompt_preview.css
- Remove 15 lines of custom badge CSS from dashboard.css

Badge mappings:
- token-badge → badge badge-primary (blue)
- status-badge.success → badge badge-success (green)
- status-badge.failure → badge badge-danger (red)
- status-badge.active → badge badge-success (green)
- status-badge.planning → badge badge-warning (yellow)
- status-badge.paused → badge badge-secondary (gray)

Benefits:
- Consistent badge styling across application
- Standard color semantics (success=green, danger=red, etc.)
- Better contrast and accessibility
- Simpler code maintenance

CSS reduction: 47 lines removed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Phase 1, Step 4 of Bootstrap refactoring: eliminate the "nuclear
option" of applying inline styles via JavaScript DOM manipulation.

Changes:
- Remove 14 lines of inline style manipulation from prompt_preview.js
- Add !important declarations to CSS rules for .section-text
- Add !important declarations to CSS rules for .project-context
- Move text wrapping logic from JavaScript to CSS with proper specificity

Previous approach:
- JavaScript applied inline styles after DOM rendering
- Comment described it as "nuclear option for CSS conflicts"
- Required DOM traversal and manipulation on every render

New approach:
- CSS rules with !important override Bootstrap/Django admin
- Applied immediately when elements render
- No JavaScript DOM manipulation required
- Better performance and maintainability

Benefits:
- Cleaner separation of concerns (styling in CSS, not JS)
- Better performance (no post-render DOM manipulation)
- Easier to debug and maintain CSS
- Proper cascade with explicit precedence

JavaScript reduction: 14 lines of DOM manipulation removed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Existing assistants created before commit 69c0a93ff don't have the
reflection_prompt_template attribute, causing Section 9 to not
appear in the prompt preview UI.

Changes:
- Add migration check in at_start() method
- Automatically add reflection_prompt_template if missing
- Log when migration occurs for visibility

This ensures all assistants (new and existing) have the reflection
prompt template available for editing via the web UI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Replaced custom <pre> elements with <div> + Bootstrap utility classes
for cleaner, simpler code that properly wraps text.

Changes:
- JavaScript: <pre class="section-text"> → <div class="section-text text-monospace bg-light p-3 rounded border-left-primary">
- JavaScript: <pre class="project-context"> → <div class="project-context text-monospace bg-light p-3 rounded border-left-success">
- CSS: Removed ~30 lines of complex specificity rules and !important hacks
- CSS: Simplified to minimal custom rules (white-space, max-height, border accent)

Bootstrap utilities now handle:
- .text-monospace - monospace font family
- .bg-light - light gray background
- .p-3 - padding
- .rounded - border radius

Custom CSS only needed for:
- white-space: pre-wrap (preserve line breaks, allow wrapping)
- max-height + overflow-y (scrollable sections)
- border-left accent colors

Result: Cleaner code, proper text wrapping, no browser default fighting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Refactored execution log table to use Bootstrap's native table component
instead of custom CSS, reducing 37 lines while improving consistency.

Changes:
- HTML: .execution-table → .table .table-striped .table-hover .table-sm
- HTML: .table-wrapper → .table-responsive (Bootstrap horizontal scroll)
- HTML: <thead> → <thead class="table-light"> (Bootstrap header background)
- HTML: Loading cell → .text-center .text-muted .py-5 (Bootstrap utilities)
- CSS: Removed 45 lines of custom table styling
- CSS: Kept 13 lines for column widths and font-size (Bootstrap doesn't handle)

Bootstrap now provides:
- Table structure, borders, spacing
- Striped rows (alternating colors)
- Hover effects
- Compact padding (.table-sm)
- Responsive scrolling (.table-responsive)
- Header styling (.table-light)

Custom CSS retained only for:
- Column width percentages (th:nth-child width rules)
- Font-size override (0.9em desktop, 0.8em mobile)

Result: 37 lines removed, better mobile UX, cleaner maintainability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Refactored all card-like components to use Bootstrap's native .card
component, reducing 104 lines of CSS while improving consistency.

Changes:
- Metric cards: Custom .metric-card → .card .shadow-sm .border-top
  - Grid: CSS grid → Bootstrap .row .col-sm-6 .col-lg-3
  - Kept: Hover effect (transform + enhanced shadow), letter-spacing

- Chart sections: Custom .chart-section → .card .shadow-sm
  - Grid: CSS grid → Bootstrap .row .col-lg-6
  - Kept: Chart wrapper height constraints (Chart.js requirement)

- Execution log: Custom .execution-log-section → .card
  - Added: .card-header with controls, .card-footer for pagination
  - Controls: Custom buttons → .btn .btn-sm, custom select → .form-select
  - Kept: Table column widths (Bootstrap doesn't handle percentages)

Bootstrap now provides:
- Card structure (white bg, padding, shadow, border-radius)
- Responsive grid layouts (.row with .g-3, .g-4 gap)
- Typography (.card-title, .display-4, .fw-bold, .text-muted, .small)
- Form controls (.btn, .form-select with sizing)
- Flex utilities (.d-flex, .justify-content-between, .gap-2)
- Spacing utilities (.mb-3, .mb-4, .p-0)

Custom CSS retained only for:
- Metric card hover animation (transform, shadow transition)
- Card title letter-spacing (0.5px)
- Chart canvas height (300px for Chart.js)
- Table column width percentages

Result: 104 lines CSS removed (353 → 249), better responsive
behavior, consistent Bootstrap visual language, easier maintenance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Refactored all manual flexbox layouts to use Bootstrap's flex utilities,
reducing 86 lines of CSS while improving consistency.

Changes:
- Dashboard header: Custom flexbox → .d-flex .justify-content-between
- Header right: flex-column → .d-flex .flex-column .align-items-end
- Assistant selector: Custom flex → .d-flex .align-items-center .gap-2
  - Select: Custom styling → .form-select .form-select-sm
  - Label: Custom font → .text-muted .small .fw-medium
- Status indicator: Custom flex → .d-flex .align-items-center .p-3
  - Layout: flex → .d-flex
  - Background: #f5f5f5 → .bg-light
  - Border: border-left → .border-start .border-success .border-4
  - Border radius: custom → .rounded
- Pagination: Custom flex → Bootstrap flex utilities
  - Removed custom button styling (delegated to Bootstrap .btn)

Bootstrap now provides:
- Flex layouts (.d-flex, .justify-content-*, .align-items-*, .flex-column)
- Spacing (.gap-2, .mb-3, .mb-4, .pb-3)
- Form controls (.form-select with sizing variants)
- Typography (.small, .text-muted, .fw-medium, .mb-0)
- Borders (.border-bottom, .border-start with color/width)
- Backgrounds (.bg-light)
- Border radius (.rounded)

Custom CSS retained only for:
- Select focus color (#3498db brand color with custom shadow)
- Status indicator disabled state (border-left-color override)
- Pagination active button (brand blue background)
- Status dot animation and sizing (custom component)

Result: 86 lines removed (249 → 163), better responsive flex
behavior, consistent Bootstrap spacing/sizing, easier maintenance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Refactored pagination controls to use Bootstrap button components,
eliminating custom button CSS and improving consistency.

Changes:
- JavaScript: Updated renderPagination() to generate Bootstrap buttons
  - Base buttons: .btn .btn-sm .btn-outline-secondary
  - Active page: .btn .btn-sm .btn-primary (solid blue)
  - Container: Added .d-flex .justify-content-center .gap-2 dynamically
  - Ellipsis: Added .px-2 spacing to separator spans

- CSS: Removed all custom pagination button styling (12 lines)
  - Deleted custom padding, borders, border-radius, transitions
  - Deleted custom hover states (.pagination button:hover)
  - Deleted custom disabled state opacity
  - Deleted custom active button colors

Bootstrap now provides:
- Button structure and sizing (.btn, .btn-sm)
- Button variants (.btn-primary for active, .btn-outline-secondary)
- Disabled state styling (handles disabled attribute automatically)
- Hover, focus, and active states
- Flex container layout (applied via className in JS)

Result: 12 lines removed (163 → 151), consistent button styling
across dashboard, better accessibility with Bootstrap button states.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Replace custom .prompt-section and .project-slot card implementations
with Bootstrap .card components and utilities:

- Convert section/project containers to .card with .shadow-sm and .mb-3
- Replace custom headers with .card-header and Bootstrap flex utilities
- Replace .edit-btn with Bootstrap .btn classes
- Use conditional .border.border-success for active projects
- Update event listener selectors to match new button classes

Remove 100 lines of custom CSS:
- Card structure (background, border-radius, box-shadow, padding)
- Header layouts (flexbox, alignment, padding)
- Button styling (colors, hover states, disabled state)

Maintain functional CSS for expand/collapse animation and content
scrolling. Reduces prompt_preview.css from 273 to 172 lines (37%).
Replace custom .preview-tabs/.tab-btn with Bootstrap .nav .nav-pills:
- Update HTML to use standard Bootstrap nav structure
- Change button selectors in JavaScript from .tab-btn to .nav-link
- Add emoji icons (📋 📁) for visual consistency with dashboard

Remove obsolete CSS:
- 28 lines of custom tab styling (button states, transitions, layout)
- 3 lines of unused .section-body (replaced by .card-body)

Maintain .tab-content display logic for JS-driven tab switching.
Reduces prompt_preview.css from 172 to 141 lines (18% reduction).
Creates consistent navigation UX across all AI admin views.
Add missing 'btn' base class to refresh-preview button to ensure
proper Bootstrap styling is applied.
Run make format to ensure code follows project standards:
- Add blank lines after imports (isort)
- Reformat long lines to 100-character limit (black)
- Add trailing commas to multi-line structures (black)
- Normalize quote style and line breaks (black)

No functional changes - formatting only.
Three fixes based on user testing feedback:

1. Line breaks not rendering: Add !important to white-space: pre-wrap
   to ensure it overrides any Bootstrap defaults

2. Token overview outside card: Wrap token-overview div in Bootstrap
   card component, remove 9 lines of custom card-like CSS

3. Token counter placement: Move badge from card-header (next to Edit
   button) to below content (more natural flow - counts what's above it)
   - Remove from header's flex container
   - Add below section-text with right alignment (.text-end)
   - Add mb-2 spacing to section-text

Reduces prompt_preview.css from 141 to 132 lines.
- Reduced embedded CSS from 121 to 42 lines (65% reduction)
- Applied unified Bootstrap template pattern
- Converted custom grid to Bootstrap .row/.col-md-4
- Replaced custom cards with .card .shadow-sm .h-100
- Replaced custom badges with .badge .badge-primary
- Replaced custom alert with .alert .alert-warning
- Header now matches dashboard/prompt-preview aesthetic
- All JavaScript unchanged, functionality preserved
- Kept only essential custom CSS for item borders and text styling
- Reduced embedded CSS from 166 to 44 lines (73% reduction)
- Applied unified Bootstrap template pattern
- Converted statistics to metric cards with border-top styling
- Converted 2fr 1fr grid to Bootstrap .row/.col-lg-8/.col-lg-4
- Replaced custom progress bars with Bootstrap .progress component
- Replaced custom badges with .badge .badge-primary/.badge-success
- Replaced custom flexbox with Bootstrap utilities (.d-flex, .gap-3)
- All JavaScript functionality preserved
- Kept only essential custom CSS for goal items and hierarchy
- Reduced embedded CSS from 168 to 64 lines (62% reduction)
- Applied unified Bootstrap template pattern
- Kept active project banner gradient for visual distinction
- Replaced custom cards with .card .shadow-sm .border-top
- Replaced custom badges with .badge .badge-success/warning/secondary
- Replaced custom flexbox with Bootstrap utilities
- Used .alert .alert-secondary for no active project message
- Kept CSS Grid auto-fill for responsive card layout
- All JavaScript functionality preserved
- Reduced embedded CSS from 199 to 49 lines (75% reduction)
- Applied unified Bootstrap template pattern
- Converted search bar to .card with .row grid layout
- Replaced custom inputs with .form-control and .form-select
- Replaced custom buttons with .btn .btn-primary
- Replaced custom pagination with Bootstrap flex utilities
- Used Bootstrap text and spacing utilities throughout
- All JavaScript functionality preserved (search, pagination, filters)
- Kept only essential custom CSS for entry styling and tags
- Dashboard: Remove 'ms' suffix from avg execution time (redundant with label)
- Prompt Preview: Update header to unified Bootstrap pattern for proper alignment
- Projects: Use consistent .alert styling for empty states

Note: Carriage returns issue may require hard browser refresh (Ctrl+Shift+R)
- Replace .empty-state with Bootstrap .alert .alert-secondary
- Consistent styling across all views (loading, empty, error states)
- Removed unused .empty-state CSS (16 lines)
Eliminates legacy JavaScript and CSS collapse implementation in favor
of Bootstrap's native collapse component for prompt preview sections.

Changes:
- Use Bootstrap data-toggle="collapse" and data-target attributes
- Remove custom toggleSection() function and event listeners
- Remove expand-icon animation and section-content max-height CSS
- Add event.stopPropagation() to Edit buttons to prevent collapse toggle
- Sections now collapse by default (.collapse class without .show)

This fixes the issue where sections appeared fully expanded instead
of collapsed as intended. Bootstrap's collapse component provides
more reliable behavior and better accessibility support.
Replace custom escapeHtmlPreserveNewlines() workaround with proper
semantic HTML. The <pre> element inherently preserves whitespace and
newlines, eliminating the need for custom JavaScript manipulation.

Changes:
- Replace <div class="section-text text-monospace"> with <pre class="section-text">
- Replace <div class="project-context text-monospace"> with <pre class="project-context">
- Remove escapeHtmlPreserveNewlines() function (no longer needed)
- Update CSS: remove !important flags, add margin-bottom: 0 for <pre>
- Add chevron indicator (▶) with rotation animation for collapsible sections
- Add aria-expanded attribute for accessibility

Benefits:
- Uses correct semantic HTML element for preformatted text
- Newlines preserved natively by browser, not JavaScript
- Simpler code with no custom newline conversion
- Better accessibility (screen readers recognize <pre> elements)
- Follows Bootstrap 4 documentation for displaying code/preformatted content

This aligns with Bootstrap 4's official approach to displaying multi-line
code and preformatted text, as documented at:
https://getbootstrap.com/docs/4.0/content/code/
The <pre> element preserves whitespace and newlines but doesn't
automatically break long words that exceed container width. This
caused horizontal overflow for long unbroken strings.

Changes:
- Add word-wrap: break-word to force long words to wrap
- Add overflow-wrap: break-word (modern CSS3 standard)
- Applied to both .section-text and .project-context

The combination of white-space: pre-wrap (preserve whitespace +
allow wrapping) with word-wrap: break-word (break long words)
ensures text wraps properly while maintaining all formatting.
The <pre> elements were not wrapping text at all, causing horizontal
overflow. The issue was using max-width: 100% instead of width: 100%.

Root cause: max-width only sets a maximum - it doesn't force the
element to constrain to that width. The <pre> element's intrinsic
content width was exceeding the container, creating a scrollbar.

Changes:
- Replace max-width: 100% with width: 100% to force constraint
- Add box-sizing: border-box to include padding in width calculation
- Change overflow-x from auto to hidden (no longer needed)

The combination of width: 100% and box-sizing: border-box ensures
the <pre> element (including its Bootstrap .p-3 padding) fits exactly
within its container, forcing text to wrap at word boundaries via
white-space: pre-wrap.
Bootstrap 4 sets word-break properties that prevent normal text wrapping
at word boundaries in pre elements. Adding word-break: normal explicitly
overrides this behavior and allows text to wrap properly while preserving
whitespace and newlines.

Applied to both .section-text and .project-context classes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Revert to simpler CSS combination:
- Use max-width: 100% instead of width: 100%
- Remove word-break: normal override
- Remove box-sizing and overflow-x properties

This cleaner approach matches established patterns for wrapping
pre elements with Bootstrap 4.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Apply research assistant's suggestion to use white-space: pre-line
for all pre elements within card bodies. This preserves line breaks
while allowing text to wrap normally, preventing horizontal overflow.

The .card-body pre selector has higher specificity than .section-text,
so this will override the pre-wrap setting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Bootstrap's reboot styles override both white-space and word-wrap
properties for <pre> elements, preventing text wrapping. This commit
uses higher CSS specificity (.card .card-body pre) and overrides all
relevant properties to force wrapping behavior:

- white-space: pre-wrap (preserve whitespace, allow wrapping)
- word-wrap: break-word (break long words)
- overflow-wrap: break-word (modern alternative)
- -ms-word-wrap: break-word (IE compatibility)

Changed from white-space: pre-line to pre-wrap to preserve both
whitespace AND line breaks (pre-line collapses multiple spaces).

Credit: Research assistant identified Bootstrap override issue.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The smoking gun: Bootstrap sets overflow-x: auto on pre elements,
which tells the browser to enable horizontal scrolling instead of
wrapping text. This completely negates white-space: pre-wrap.

Replaced -ms-word-wrap with overflow-x: visible to override
Bootstrap's default and allow text to wrap normally.

Credit: Research assistant identified overflow-x as root cause.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Bootstrap 4 sets a triple-threat of properties that prevent wrapping:
1. white-space: pre (not pre-wrap!)
2. overflow: auto (includes both overflow-x and overflow-y)
3. word-wrap: normal (prevents word breaking)

Higher CSS specificity alone wasn't enough. Using !important to
force override all three Bootstrap properties:

- white-space: pre-wrap !important
- overflow: visible !important (overrides overflow: auto)
- word-wrap: break-word !important
- overflow-wrap: break-word !important

This "nuclear option" is necessary because Bootstrap's cascade
order or specificity is higher than our custom styles.

Credit: Research assistant identified Bootstrap's triple-threat.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Key insight from Bootstrap source exploration:
- Bootstrap 4.6 sets `overflow: auto` (both x and y)
- Browser defaults: `white-space: pre`, `word-wrap: normal`

The bug: `overflow: visible` doesn't PREVENT overflow - it makes it
visible! This allowed horizontal scrolling to continue.

The fix: Split overflow control:
- overflow-x: hidden !important (prevent horizontal scroll)
- overflow-y: auto !important (allow vertical scroll)

This forces text to wrap within the container width while still
allowing vertical scrolling for long content.

Updated comments to reflect that white-space and word-wrap are
browser defaults, not Bootstrap overrides.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: All AI templates used {% block header_insert %} but the
base template (evennia/web/templates/website/base.html) defines
{% block header_ext %}.

This meant CSS files were NEVER loaded, explaining why none of the
text wrapping fixes worked - Bootstrap's defaults were never overridden.

Changed all 6 AI templates:
- dashboard.html
- goals.html
- journal.html
- projects.html
- prompt_preview.html
- session_memory.html

From: {% block header_insert %}
To:   {% block header_ext %}

This should now properly load:
- ai/dashboard.css (all pages)
- ai/prompt_preview.css (prompt preview page)
- Inline <style> blocks (goals, journal, projects, session_memory)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
All AI templates were using {% block title %} but the base template
defines {% block titleblock %}. This caused page titles to fall back
to the default instead of using the AI template-specific titles.

Changed in all 6 templates:
- dashboard.html
- goals.html
- journal.html
- projects.html
- prompt_preview.html
- session_memory.html

From: {% block title %}
To:   {% block titleblock %}

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Now that templates properly load CSS (titleblock fix), two visual
bugs became visible:

1. Token bar gradient: Bar had static green→yellow→red gradient but
   width changed with utilization. At 6.8%, entire gradient was
   compressed into tiny bar showing all colors.

   Fix: Remove static gradient from CSS, set background color
   dynamically in JavaScript based on utilization thresholds:
   - <70%: Green (#4CAF50)
   - 70-90%: Yellow (#FFC107)
   - >90%: Red (#F44336)

2. Projects empty state width: "No projects created yet" rendered
   in single grid column (350px) while "No active project" alert
   spanned full width.

   Fix: Add CSS rule making .alert elements inside .projects-grid
   span all columns with grid-column: 1 / -1.

Files changed:
- prompt_preview.css: Remove static gradient, add background transition
- prompt_preview.js: Add color logic to updateTokenOverview()
- projects.html: Add grid-column rule for alerts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Previous implementation used custom CSS and inline backgroundColor
manipulation. This is exactly what Bootstrap's progress component
is designed for.

Changes:
- prompt_preview.html: Replace custom .token-bar-container and
  .token-bar divs with Bootstrap .progress and .progress-bar
  - Added proper ARIA attributes (role, aria-valuenow, etc.)
  - Used inline height style (30px) for custom sizing
  - Replaced .token-label with Bootstrap utility classes

- prompt_preview.css: Removed 21 lines of custom CSS:
  - Deleted .token-bar-container, .token-bar, .token-label styles
  - Bootstrap handles all styling via .progress component

- prompt_preview.js: Updated updateTokenOverview() to use Bootstrap
  contextual classes instead of inline styles:
  - Remove: bar.style.backgroundColor = '#...'
  - Add: bar.classList.add('bg-success'|'bg-warning'|'bg-danger')
  - Added: bar.setAttribute('aria-valuenow', utilization) for a11y

Benefits:
- 21 fewer lines of custom CSS
- Semantic HTML with proper ARIA roles
- Leverages Bootstrap's battle-tested component
- Follows "don't fight the system" principle

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Changed align-items-center to align-items-start so the "Refresh
Preview" button aligns with the progress bar at the top instead
of centering vertically between the progress bar and text label.

Visual issue: Button was appearing at the same level as the text
label at the bottom, creating misalignment with the progress bar.

Fix: align-items-start aligns both the left content and button to
the top of the card, creating a cleaner visual alignment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Eliminated 38 lines of custom code by leveraging Bootstrap's built-in
tab component and removing unused spinner CSS.

Changes:

1. Custom Tab Switching → Bootstrap Tabs
   - prompt_preview.html: Replace <button> with <a data-toggle="tab">
     - Changed from custom data-tab="standard" to href="#standard"
     - Added role="tablist" and role="tab" for accessibility
     - Converted .tab-content divs to .tab-pane with .fade transition
     - Wrapped panes in .tab-content container (Bootstrap requirement)

   - prompt_preview.js: Deleted 24 lines of custom tab code
     - Removed: Custom click handlers and switchTab() function
     - Added: Bootstrap 'shown.bs.tab' event listener
     - Bootstrap now handles .active class management automatically

   Benefits: Tab switching managed by Bootstrap's battle-tested code,
   proper ARIA attributes, smooth fade transitions

2. Custom Tab Visibility CSS → Bootstrap .tab-pane
   - prompt_preview.css: Deleted 7 lines
     - Removed: .tab-content { display: none } / .active { display: block }
     - Bootstrap's .tab-pane/.fade classes handle visibility

   Benefits: Eliminates duplicate CSS for tab visibility

3. Unused Loading Spinner CSS
   - dashboard.css: Deleted 14 lines of dead code
     - Removed: @keyframes spin and .loading-spinner CSS
     - Never used in templates or JavaScript (uses .loading class instead)

   Benefits: Removes unused code

Net Result: -38 lines of custom code, fully leveraging Bootstrap 4.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Replaced .ai-dashboard-container with Bootstrap's .container-xl,
reducing custom CSS from 6 lines to 1 line (max-width override).

Changes:

1. All 6 Templates: .ai-dashboard-container → .container-xl py-4
   - dashboard.html, goals.html, journal.html, projects.html,
     prompt_preview.html, session_memory.html
   - Bootstrap .container-xl provides: responsive width, margin: 0 auto,
     horizontal padding (15px)
   - Bootstrap .py-4 utility provides: vertical padding (1.5rem ≈ 24px)

2. dashboard.css: Minimal override
   - Removed: margin: 0 auto (Bootstrap provides)
   - Removed: padding: 20px (replaced with .py-4 utility)
   - Removed: font-family (Bootstrap's default system stack is equivalent)
   - Kept: max-width: 1400px override (Bootstrap default is 1140px)

3. dashboard.js: Update selector
   - Changed querySelector('.ai-dashboard-container') to
     querySelector('.container-xl') in showError() function

Benefits:
- Leverages Bootstrap's responsive container behavior
- Eliminates 5 lines of redundant CSS
- Uses Bootstrap utility classes (.py-4) instead of custom padding
- Maintains 1400px max-width for dashboard pages

Note: This overrides .container-xl globally. If other parts of the
site need different max-width, this can be scoped to a wrapper class.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Moved Error column before Reasoning to better utilize horizontal space.
Error messages are typically shorter and can use a fixed width, while
Reasoning content is most verbose and benefits from being rightmost.

Changes:

1. dashboard.html: Reorder table header columns
   - Swapped positions: Error (col 7) ↔ Reasoning (col 8)

2. dashboard.js: Reorder table row cells and fix colspan
   - Swapped <td> order in renderExecutionLog() to match header
   - Fixed showLogError() colspan: 7 → 8 (was missing Details column)

3. dashboard.css: Fix and reorder column widths
   - Added missing column 4 width: 10% (Details - was undefined)
   - Column 7 (Error): 32% → 15% (fixed width for error messages)
   - Column 8 (Reasoning): 25% → 32% (most space for verbose content)

Column Layout (all 8 columns now defined):
- Tick: 5%
- Timestamp: 12%
- Tool: 10%
- Details: 10% (was missing, caused misalignment)
- Status: 8%
- Duration: 8%
- Error: 15% (was 32%, moved from col 8)
- Reasoning: 32% (was 25%, moved to col 8 for max space)

Benefits:
- Error column gets adequate space without wasting it
- Reasoning gets maximum available space at table edge
- All columns now have explicit widths (was missing Details)
- Better use of horizontal space for debugging data

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Added horizontal margin and font weight to pagination info text to
prevent crowding between Previous/Next buttons.

Changed:
- evennia/contrib/ai/templates/ai/journal.html line 117-121:
  * Removed gap-3 from flex container (no longer needed)
  * Added mx-4 (1.5rem horizontal margin) to pagination-info span
  * Added fw-medium for slightly bolder text

Reasoning:
- Previous layout crowded "1-0 of 0" text between buttons
- Bootstrap mx-4 (24px) provides proper breathing room on both sides
- fw-medium gives pagination info appropriate visual weight
- Uniform aesthetic with Bootstrap spacing utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
blightbow/evennia_ai!1
No description provided.