deckhearth/components/CardItem.js

427 lines
15 KiB
JavaScript
Raw Normal View History

/* eslint-disable @next/next/no-img-element -- External card image URLs; next/image migration is out of scope. */
import { useState } from 'react';
import { useRouter } from 'next/router';
import { VOCAB } from '../lib/collection-vocabulary.js';
// Expanding Add Button Component
function ExpandingAddButton({ card, onAddToCollection, onAddToDeck, onMarkAsOwned }) {
const [isExpanded, setIsExpanded] = useState(false);
const handleMainClick = (e) => {
e.stopPropagation();
if (!isExpanded) {
setIsExpanded(true);
} else {
// Default action when expanded - add to collection
onAddToCollection([card]);
setIsExpanded(false);
}
};
const handleOptionClick = (e, action) => {
e.stopPropagation();
action();
setIsExpanded(false);
};
return (
<div className="relative">
{/* Expanded Options */}
{isExpanded && (
<div className="absolute bottom-full left-0 mb-1 flex flex-col space-y-1">
<button
onClick={(e) => handleOptionClick(e, () => onAddToCollection([card]))}
className="p-1.5 rounded-md shadow-lg transition-all duration-150 hover:scale-105 flex items-center space-x-1 text-xs whitespace-nowrap"
style={{ backgroundColor: 'var(--accent-flame)', color: 'white' }}
title={VOCAB.ADD_TO_LIST}
>
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
<span>Collection</span>
</button>
<button
onClick={(e) => handleOptionClick(e, () => onAddToDeck([card]))}
className="p-1.5 rounded-md shadow-lg transition-all duration-150 hover:scale-105 flex items-center space-x-1 text-xs whitespace-nowrap"
style={{ backgroundColor: 'var(--accent-gold)', color: 'white' }}
title="Add to Deck"
>
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
<span>Deck</span>
</button>
<button
onClick={(e) => handleOptionClick(e, onMarkAsOwned)}
className="p-1.5 rounded-md shadow-lg transition-all duration-150 hover:scale-105 flex items-center space-x-1 text-xs whitespace-nowrap"
style={{ backgroundColor: 'var(--accent-ember)', color: 'white' }}
title={VOCAB.ADD_TO_MY_COLLECTION}
>
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
<span>Own</span>
</button>
</div>
)}
{/* Main Add Button */}
<button
onClick={handleMainClick}
className="p-1.5 rounded-md shadow-lg transition-all duration-150 hover:scale-105 relative"
style={{
backgroundColor: 'var(--accent-ember)',
color: 'white',
boxShadow: '0 0 0 2px var(--accent-ember), 0 4px 6px -1px rgba(216, 67, 21, 0.3)'
}}
title={isExpanded ? VOCAB.ADD_TO_LIST : 'Show Options'}
>
<svg
className={`w-4 h-4 transition-transform duration-150 ${isExpanded ? 'rotate-45' : ''}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
</svg>
</button>
{/* Click outside to close */}
{isExpanded && (
<div
className="fixed inset-0 z-[-1]"
onClick={(e) => {
e.stopPropagation();
setIsExpanded(false);
}}
/>
)}
</div>
);
}
export default function CardItem({
card,
viewMode = 'grid',
isSelected = false,
onToggleSelect,
onAddToCollection,
onAddToDeck,
onToggleFavorite,
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
isFavorited = false
}) {
const [imageError, setImageError] = useState(false);
const router = useRouter();
const handleSelectChange = (e) => {
e.stopPropagation();
onToggleSelect(card);
};
const handleImageError = () => {
setImageError(true);
};
const handleCardClick = (e) => {
// Don't navigate if clicking on interactive elements
if (e.target.closest('input, button, a')) {
return;
}
router.push(`/card/${card.id}`);
};
// Get rarity-based styling
const getRarityEffects = (rarity) => {
const rarityLower = rarity?.toLowerCase() || '';
if (rarityLower.includes('mythic') || rarityLower.includes('legendary')) {
return {
glow: 'rarity-glow-mythic',
particles: 'rarity-particles-mythic',
border: 'border-yellow-400',
shadow: 'shadow-yellow-400/50'
};
} else if (rarityLower.includes('rare') || rarityLower.includes('holo')) {
return {
glow: 'rarity-glow-rare',
particles: 'rarity-particles-rare',
border: 'border-purple-400',
shadow: 'shadow-purple-400/50'
};
} else if (rarityLower.includes('uncommon')) {
return {
glow: 'rarity-glow-uncommon',
particles: 'rarity-particles-uncommon',
border: 'border-blue-400',
shadow: 'shadow-blue-400/30'
};
} else if (rarityLower.includes('enchanted') || rarityLower.includes('secret')) {
return {
glow: 'rarity-glow-enchanted',
particles: 'rarity-particles-enchanted',
border: 'border-pink-400',
shadow: 'shadow-pink-400/60'
};
}
return {
glow: '',
particles: '',
border: 'border-gray-200',
shadow: ''
};
};
const rarityEffects = getRarityEffects(card.rarity);
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
// Panel positioning no longer needed - using simple hover buttons
📱 Implement Mobile-First Responsive Design 🎯 Mobile Slide-In Navigation: - Added mobile menu button with hamburger icon - Implemented slide-in sidebar with smooth transitions - Added mobile overlay with click-to-close functionality - Mobile menu auto-closes when navigating to new pages - Proper z-index layering for mobile interactions 🃏 Smart Card Panel Positioning: - Panels now open on opposite side for right-edge cards - Added cardIndex and cardsPerRow props to CardItem - Dynamic positioning based on card's position in grid - Prevents panels from extending off-screen edges - Maintains hover functionality on desktop 📱 Mobile-Optimized Bulk Actions: - Toolbar now spans full width on mobile devices - Icon-only buttons on mobile, full labels on desktop - Responsive spacing and padding adjustments - Improved touch targets for mobile interaction - Maintains functionality across all screen sizes 🎨 Enhanced Grid Layout: - Improved mobile grid: 2 columns with tighter spacing - Better space utilization on all device sizes - Responsive gap spacing that adapts to screen size - Optimized padding for mobile vs desktop - Cards now fill available space properly ✅ Cross-Device Experience: - Mobile: Slide-in nav, icon-only actions, 2-column grid - Tablet: Responsive layout with appropriate spacing - Desktop: Full sidebar, labeled actions, hover panels - Large screens: Maximum columns with side panel space The app now provides an optimal mobile experience while maintaining desktop functionality! ��💻🖥️
2025-07-26 01:49:42 -04:00
if (viewMode === 'list') {
return (
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
<div
className="flex items-center p-4 rounded-xl transition-all duration-200 cursor-pointer nav-item-hover"
style={{
backgroundColor: isSelected
? 'rgba(255, 110, 0, 0.08)'
: 'transparent',
border: '1px solid',
borderColor: isSelected ? 'var(--accent-ember)' : 'var(--border)',
boxShadow: isSelected ? 'var(--rim-light-inner)' : 'none',
}}
onClick={handleCardClick}
>
{/* Selection Checkbox */}
<div className="flex-shrink-0 mr-4">
<input
type="checkbox"
checked={isSelected}
onChange={handleSelectChange}
refactor(design): site-wide sweep — broken Tailwind tokens, rounded corners, SearchBar primitive (#117) (#117) Comprehensive design sweep across the rest of the app following the shipped Liquid Glass + corner-border-light system (#116). ## Three classes of finding ### 1. Broken Tailwind token classes (HIGH — pages were unstyled) The decks / deck-builder / deck-detail cluster relied on Tailwind classes that don't exist in `tailwind.config.js` (no `bg-bg-*`, `text-text-*`, `border-border`, `bg-accent-ember`, `focus:ring-accent-ember`, `hover:bg-accent-ember-dark`). Those classes produced ZERO CSS — backgrounds were transparent, borders invisible, hover states absent. Rewrote with inline `style={{ ... CSS vars ... }}` + the `<Button>` / `<SearchBar>` primitives + `glass-panel` surfaces: - `pages/decks.js` (full page) - `pages/deck/[id].js` (header, stats sidebar, group-by controls, card list) - `pages/deck-builder.js` (loading spinner) - `components/DeckBuilderView.js` (toolbar + main panel) - `components/DeckBuilderCardBrowser.js` (full rewrite; integrated `<SearchBar>` for the card-picker input) - `components/DeckBuilderDeckList.js` (full rewrite) - `components/DeckBuilderStatsBar.js` - `components/ManaSymbolSettings.js` - `components/ManaSymbols.js` (single `text-text-secondary`) - `pages/admin/card-editor.js` cluster was already clean ### 2. Duplicative / stale page searches Replaced raw `<input>` search controls with the `<SearchBar>` primitive (adds clear button, ember focus ring, system-consistent rounded corners). Kept page-specific filter searches (they filter the visible list — distinct from the global TopSearchBar command palette): - `pages/my-cards.js` - `pages/community/collections.js` - `components/CardsPageView.js` - `components/CollectionPageView.js` - `components/DeckBuilderCardBrowser.js` `pages/my-cards.js` filter wrapper also lifted into a `glass-panel` chip instead of a solid `var(--bg-primary)` band. ### 3. Square corners + stale palette in shared views - `components/CollectionPageView.js`: 10 action buttons (`rounded-lg` + `hover:bg-gray-50`) → `rounded-xl` + `nav-item-hover`; 4 filter selects (`focus:ring-purple-500 rounded-lg`) → `.input-field`; view-mode toggle (`bg-white text-gray-900` — invisible in dark mode) → tokenised; SYSTEM badge gradient (`from-blue-500 to-purple-600`) → ember↔flame; tooltip (`bg-gray-900`) → `glass-panel-strong`; search-results dropdown (`bg-white border-gray-200` — invisible in dark mode) → `glass-panel-strong`; Activity / game-count / TCG-game badges palette-aligned. - `components/CardsPageView.js`: "Load More Cards" button (`bg-gradient-to-r from-blue-500 to-purple-600 rounded-lg`) → `<Button variant="primary" size="lg">`. - `components/CollectionsPageView.js`: matching SYSTEM badge + tooltip cleanup. - `components/ShareModal.js`: user-search dropdown (`border-gray-200 hover:bg-gray-50`) and email-invite card moved onto `glass-panel` + `nav-item-hover`; social-share buttons `rounded-lg hover:bg-gray-50` → `rounded-xl nav-item-hover`. - `components/Layout.js`: profile-menu dropdown row (`hover:bg-gray-50 dark:hover:bg-gray-700`) → `nav-item-hover`. - `components/CardItem.js`: bulk-select checkbox `focus:ring-purple-500` → ember. ### 4. `dark:` modifier classes (broken with `[data-theme]` theming) This app uses `[data-theme="dark"]` CSS selector theming, not Tailwind's `class` strategy, so `dark:bg-green-900/20` etc. produced no CSS in dark mode. Affected alerts on `pages/settings.js` and `pages/profile.js` — replaced with `glass-panel` + semantic border colour (flame for success, #dc2626 for error). `pages/settings.js` sidebar nav also moved off its hardcoded full-ember fill onto the system `nav-item` / `nav-item-active` / `nav-item-hover` pattern for consistency with the global sidebar. ## Verification - `npm run build` — green (Next 16 + Turbopack) - `npm run lint` — 0 errors, 1 unrelated pre-existing warning - `npm run test:run` — 113/113 pass (no test changes needed) Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 15:06:22 -04:00
className="w-4 h-4 rounded focus:ring-2"
style={{
accentColor: 'var(--accent-ember)',
'--tw-ring-color': 'var(--accent-ember)',
}}
/>
</div>
{/* Card Image */}
<div className="flex-shrink-0 mr-4">
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
<div
className="w-16 h-22 rounded-lg overflow-hidden"
style={{ backgroundColor: 'var(--bg-tertiary)' }}
>
{!imageError ? (
<img
src={card.image_url}
alt={card.name}
className="w-full h-full object-cover"
onError={handleImageError}
/>
) : (
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
<div
className="w-full h-full flex items-center justify-center text-xs"
style={{ color: 'var(--text-secondary)' }}
>
No Image
</div>
)}
</div>
</div>
{/* Card Info */}
<div className="flex-1 min-w-0">
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
<h3
className="font-semibold truncate"
style={{ color: 'var(--text-primary)' }}
>
{card.name}
</h3>
<p className="text-sm" style={{ color: 'var(--text-secondary)' }}>
{card.set_name} {card.rarity}
</p>
<p className="text-sm" style={{ color: 'var(--text-secondary)' }}>
{card.card_type}
</p>
</div>
{/* Game Badge */}
<div className="flex-shrink-0 mx-4">
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
<span
className="px-2 py-1 text-xs font-medium rounded-full"
style={{
backgroundColor: 'var(--bg-tertiary)',
color: 'var(--text-primary)',
border: '1px solid var(--border)',
}}
>
{card.game}
</span>
</div>
{/* Price */}
<div className="flex-shrink-0 mx-4">
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
<span
className="text-lg font-bold"
style={{ color: 'var(--accent-flame)' }}
>
${card.market_price}
</span>
</div>
{/* Actions */}
<div className="flex-shrink-0 flex items-center space-x-2">
<button
onClick={(e) => {
e.stopPropagation();
onToggleFavorite(card);
}}
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
className="nav-item-hover p-2 rounded-xl transition-colors"
style={{
color: isFavorited
? 'var(--accent-ember)'
: 'var(--text-secondary)',
}}
>
<svg className="w-5 h-5" fill={isFavorited ? "currentColor" : "none"} stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
</svg>
</button>
<button
onClick={(e) => {
e.stopPropagation();
onAddToCollection(card);
}}
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
className="nav-item-hover p-2 rounded-xl transition-colors"
style={{ color: 'var(--accent-ember)' }}
title={VOCAB.ADD_TO_LIST}
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
</button>
<button
onClick={(e) => {
e.stopPropagation();
onAddToDeck(card);
}}
refactor(card-item): tokenize list-mode palette (Brief 1) (#128) Brief 1 of cleanup-card-item-list-and-share-modal-palette convoy. Pure token sweep across lines ~181-295 of components/CardItem.js (the list-mode branch only — grid-mode at L290+ stays untouched per Brief 1 § Known constraints). Migrations: - Outer row container: - `border-purple-500 bg-purple-50 shadow-md` (selected) → `borderColor: 'var(--accent-ember)' + backgroundColor: 'rgba(255, 110, 0, 0.08)' + boxShadow: 'var(--rim-light-inner)'`. - `border-gray-200 hover:border-gray-300 hover:shadow-sm` (default) → `borderColor: 'var(--border)' + nav-item-hover` class for the ember-tinted hover state from the unify convoy. - `rounded-lg` → `rounded-xl` (convoy-wide rounding consistency). - Image placeholder: - `bg-gray-200` → `var(--bg-tertiary)`. - `text-gray-400` on the "No Image" fallback → `var(--text-secondary)`. - Card info text: - `text-gray-900` → `var(--text-primary)` (card name). - `text-gray-600` / `text-gray-500` → `var(--text-secondary)` (set/rarity/type). - Game badge: - `bg-blue-100 text-blue-800` → `var(--bg-tertiary)` + `var(--text-primary)` + `1px solid var(--border)` for visible delimiter in both themes. - Price: - `text-green-600` → `var(--accent-flame)`. Decision: chose brand-warm over semantic-green because the rest of the row is on the ember palette and a single warm-tone price tag reads as "primary value" rather than "positive delta from baseline". Easy to revert to `#16a34a` literal if dark-mode reviewers prefer the green. - Favorite button: - `text-red-500 hover:text-red-600` (favorited) → `var(--accent-ember)`. - `text-gray-400 hover:text-red-500` (default) → `var(--text-secondary)` + nav-item-hover. - Add-to-collection button: - `text-blue-600 hover:text-blue-700 hover:bg-blue-50` → `var(--accent-ember)` + nav-item-hover. - Add-to-deck button: - `text-green-600 hover:text-green-700 hover:bg-green-50` → `var(--accent-flame)` + nav-item-hover. Distinguishes from add-to-collection by warm-tier (flame vs ember). - `rounded-lg` on all action buttons → `rounded-xl`. Verification: - `sed -n '181,295p' components/CardItem.js | grep -nE 'bg-(purple|blue|gray|red|green)-[0-9]|text-(...)|border-(...)'` → 0 matches. ✅ - `npm run lint` passes (1 pre-existing unrelated warning). - `npm run test:run`: 118/118 tests pass. Grid-mode (L290+) intentionally untouched per Brief 1 scope. The 5 remaining palette hardcodes in CardItem.js are all in grid-mode getRarityEffects() at L150/157/172/350/359 — out of scope for this brief; the convoy didn't target those because the grid render path has its own visual treatment. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:55:36 -04:00
className="nav-item-hover p-2 rounded-xl transition-colors"
style={{ color: 'var(--accent-flame)' }}
title="Add to Deck"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
</button>
</div>
</div>
);
}
// Grid view
return (
<div className="card-item-container card-grid-outer-glow relative group bg-transparent rounded-xl transition-all duration-150 overflow-visible transform hover:scale-102 hover:z-10">
{/* Main Card Container */}
<div
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
className={`relative rounded-xl border-2 transition-all duration-200 overflow-hidden cursor-pointer ${
isSelected
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
? 'shadow-xl ring-2 ring-opacity-50'
: 'group-hover:shadow-xl'
} ${rarityEffects.glow}`}
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
style={{
backgroundColor: 'var(--bg-primary)',
borderColor: isSelected ? 'var(--accent-ember)' : 'var(--border)',
'--tw-ring-color': isSelected ? 'var(--accent-ember)' : 'transparent'
}}
onClick={handleCardClick}
>
{/* Rarity Particles */}
{rarityEffects.particles && (
<div className={`absolute inset-0 pointer-events-none ${rarityEffects.particles}`}></div>
)}
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
{/* Card Image */}
<div className="aspect-[2.5/3.5] bg-gray-200 overflow-hidden">
{!imageError ? (
<img
src={card.image_url}
alt={card.name}
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
className="w-full h-full object-cover"
onError={handleImageError}
/>
) : (
<div className="w-full h-full flex items-center justify-center text-gray-400">
<div className="text-center">
<svg className="w-12 h-12 mx-auto mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
<p className="text-xs">No Image</p>
</div>
</div>
)}
</div>
</div>
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
{/* Hover Action Buttons */}
{/* Top Left - Checkbox */}
<div className="absolute top-2 left-2 opacity-0 group-hover:opacity-100 transition-opacity duration-150 z-20">
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
<button
onClick={(e) => {
e.stopPropagation();
onToggleSelect(card);
}}
className="p-1 rounded-md shadow-lg transition-all duration-150 hover:scale-105"
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
style={{ backgroundColor: 'var(--bg-primary)' }}
>
<input
type="checkbox"
checked={isSelected}
onChange={() => {}}
className="w-4 h-4 rounded focus:ring-1 focus:ring-offset-1"
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
style={{
accentColor: 'var(--accent-ember)',
backgroundColor: 'var(--bg-primary)',
borderColor: 'var(--border)'
}}
/>
</button>
</div>
{/* Top Right - Favorite */}
<div className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity duration-150 z-20">
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
<button
onClick={(e) => {
e.stopPropagation();
onToggleFavorite(card);
}}
className="p-1 rounded-md shadow-lg transition-all duration-150 hover:scale-105"
⚡ Massive Performance Boost - Remove Heavy Hover Panels 🚀 Performance Optimizations: - Completely removed complex side hover panels (massive DOM reduction) - Eliminated 240+ lines of heavy panel HTML per card - Removed expensive panel positioning calculations - Simplified hover animations from 300ms to 200ms - Removed redundant image scaling (double transform) 🎯 New Lightweight Hover System: - Simple card scaling on hover (transform: scale(1.05)) - Slide-in action buttons in corners - Checkbox & favorite in top-right corner - Ownership indicator & add button in bottom-left - All buttons use opacity transitions (GPU accelerated) 🔥 Fire-Themed Interactive Elements: - Checkbox: Ember red accent color - Favorite: Ember red background when active - Add/Own button: Wood brown background - Ownership indicator: Gold dot when owned - All buttons have subtle hover scaling (scale(1.1)) 📱 Enhanced Grid Layout: - Removed right padding (no more panel space needed) - Increased grid density: lg:4 cols, xl:5 cols, 2xl:6 cols - Better space utilization across all screen sizes - Cleaner, more focused card browsing experience ✨ User Experience Improvements: - Much faster card grid rendering - Smoother hover interactions - Reduced layout shift and jank - Cleaner visual hierarchy - Quick access to essential actions 💾 Code Cleanup: - Removed cardIndex and cardsPerRow props - Eliminated panel positioning logic - Simplified component structure - Reduced bundle size significantly The cards page should now be lightning fast! ⚡🔥
2025-07-26 09:45:38 -04:00
style={{
backgroundColor: isFavorited ? 'var(--accent-ember)' : 'var(--bg-primary)',
color: isFavorited ? 'white' : 'var(--accent-ember)'
}}
title="Toggle Favorite"
>
<svg className="w-4 h-4" fill={isFavorited ? "currentColor" : "none"} stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
</svg>
</button>
</div>
{/* Bottom Left - Expanding Add Button */}
<div className="absolute bottom-2 left-2 opacity-0 group-hover:opacity-100 transition-opacity duration-150 z-20">
<ExpandingAddButton
card={card}
onAddToCollection={onAddToCollection}
onAddToDeck={onAddToDeck}
onMarkAsOwned={() => alert(`${VOCAB.ADD_TO_MY_COLLECTION} (coming soon)`)}
/>
</div>
</div>
);
}