mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-24 03:20:12 +01:00
feat: complete M3 Web UI Enhancement milestone with include/exclude cards, fuzzy matching, mobile responsive design, and performance optimization
- Include/exclude cards feature complete with 300+ card knowledge base and intelligent fuzzy matching - Enhanced visual validation with warning icons and performance benchmarks (100% pass rate) - Mobile responsive design with bottom-floating controls, two-column layout, and horizontal scroll prevention - Dark theme confirmation modal for fuzzy matches with card preview and alternatives - Dual architecture support for web UI staging system and CLI direct build paths - All M3 checklist items completed: fuzzy match modal, enhanced algorithm, summary panel, mobile responsive, Playwright tests
This commit is contained in:
parent
0516260304
commit
cfcc01db85
37 changed files with 3837 additions and 162 deletions
|
|
@ -65,7 +65,7 @@
|
|||
--blue-main: #1565c0; /* balanced blue */
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
html,body{height:100%}
|
||||
html,body{height:100%; overflow-x:hidden; max-width:100vw;}
|
||||
body {
|
||||
font-family: system-ui, Arial, sans-serif;
|
||||
margin: 0;
|
||||
|
|
@ -74,6 +74,7 @@ body {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
/* Honor HTML hidden attribute across the app */
|
||||
[hidden] { display: none !important; }
|
||||
|
|
@ -84,7 +85,7 @@ body {
|
|||
.top-banner{ min-height: var(--banner-h); }
|
||||
.top-banner .top-inner{ margin:0; padding:.5rem 0; display:grid; grid-template-columns: var(--sidebar-w) 1fr; align-items:center; }
|
||||
.top-banner h1{ font-size: 1.1rem; margin:0; padding-left: 1rem; }
|
||||
.banner-status{ color: var(--muted); font-size:.9rem; text-align:left; padding-left: 1.5rem; padding-right: 1.5rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; }
|
||||
.banner-status{ color: var(--muted); font-size:.9rem; text-align:left; padding-left: 1.5rem; padding-right: 1.5rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; min-height:1.2em; }
|
||||
.banner-status.busy{ color:#fbbf24; }
|
||||
.health-dot{ width:10px; height:10px; border-radius:50%; display:inline-block; background:#10b981; box-shadow:0 0 0 2px rgba(16,185,129,.25) inset; }
|
||||
.health-dot[data-state="bad"]{ background:#ef4444; box-shadow:0 0 0 2px rgba(239,68,68,.3) inset; }
|
||||
|
|
@ -125,7 +126,14 @@ body.nav-collapsed .top-banner .top-inner{ padding-left: .5rem; padding-right: .
|
|||
.sidebar{ transform: translateX(-100%); visibility: hidden; }
|
||||
body:not(.nav-collapsed) .layout{ grid-template-columns: var(--sidebar-w) 1fr; }
|
||||
body:not(.nav-collapsed) .sidebar{ transform: translateX(0); visibility: visible; }
|
||||
.content{ padding: .9rem .8rem; }
|
||||
.content{ padding: .9rem .6rem; max-width: 100vw; box-sizing: border-box; overflow-x: hidden; }
|
||||
}
|
||||
|
||||
/* Additional mobile spacing for bottom floating controls */
|
||||
@media (max-width: 720px) {
|
||||
.content {
|
||||
padding-bottom: 6rem !important; /* Extra bottom padding to account for floating controls */
|
||||
}
|
||||
}
|
||||
|
||||
.brand h1{ display:none; }
|
||||
|
|
@ -290,10 +298,36 @@ small, .muted{ color: var(--muted); }
|
|||
.stage-nav .name { font-size:12px; }
|
||||
|
||||
/* Build controls sticky box tweaks */
|
||||
.build-controls { top: calc(var(--banner-offset, 48px) + 6px); }
|
||||
@media (max-width: 720px){
|
||||
.build-controls {
|
||||
position: sticky;
|
||||
top: calc(var(--banner-offset, 48px) + 6px);
|
||||
z-index: 100;
|
||||
background: linear-gradient(180deg, rgba(15,17,21,.98), rgba(15,17,21,.92));
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
margin: 0.5rem 0;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
@media (max-width: 1024px){
|
||||
:root { --banner-offset: 56px; }
|
||||
.build-controls { position: sticky; border-radius: 8px; margin-left: 0; margin-right: 0; }
|
||||
.build-controls {
|
||||
position: fixed !important; /* Fixed to viewport instead of sticky */
|
||||
bottom: 0 !important; /* Anchor to bottom of screen */
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
top: auto !important; /* Override top positioning */
|
||||
border-radius: 0 !important; /* Remove border radius for full width */
|
||||
margin: 0 !important; /* Remove margins for full edge-to-edge */
|
||||
padding: 0.5rem !important; /* Reduced padding */
|
||||
box-shadow: 0 -6px 20px rgba(0,0,0,.4) !important; /* Upward shadow */
|
||||
border-left: none !important;
|
||||
border-right: none !important;
|
||||
border-bottom: none !important; /* Remove bottom border */
|
||||
background: linear-gradient(180deg, rgba(15,17,21,.99), rgba(15,17,21,.95)) !important;
|
||||
z-index: 1000 !important; /* Higher z-index to ensure it's above content */
|
||||
}
|
||||
}
|
||||
@media (min-width: 721px){
|
||||
:root { --banner-offset: 48px; }
|
||||
|
|
@ -347,3 +381,128 @@ img.lqip.loaded { filter: blur(0); opacity: 1; }
|
|||
|
||||
/* Virtualization wrapper should mirror grid to keep multi-column flow */
|
||||
.virt-wrapper { display: grid; }
|
||||
|
||||
/* Mobile responsive fixes for horizontal scrolling issues */
|
||||
@media (max-width: 768px) {
|
||||
/* Prevent horizontal overflow */
|
||||
html, body {
|
||||
overflow-x: hidden !important;
|
||||
width: 100% !important;
|
||||
max-width: 100vw !important;
|
||||
}
|
||||
|
||||
/* Fix modal layout on mobile */
|
||||
.modal {
|
||||
padding: 10px !important;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 100% !important;
|
||||
max-width: calc(100vw - 20px) !important;
|
||||
box-sizing: border-box !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
/* Force single column for include/exclude grid */
|
||||
.include-exclude-grid {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
gap: 1rem !important;
|
||||
}
|
||||
|
||||
/* Fix basics grid */
|
||||
.basics-grid {
|
||||
grid-template-columns: 1fr !important;
|
||||
gap: 1rem !important;
|
||||
}
|
||||
|
||||
/* Ensure all inputs and textareas fit properly */
|
||||
.modal input,
|
||||
.modal textarea,
|
||||
.modal select {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
/* Fix chips containers */
|
||||
.modal [id$="_chips_container"] {
|
||||
max-width: 100% !important;
|
||||
overflow-x: hidden !important;
|
||||
word-wrap: break-word !important;
|
||||
}
|
||||
|
||||
/* Ensure fieldsets don't overflow */
|
||||
.modal fieldset {
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
/* Fix any inline styles that might cause overflow */
|
||||
.modal fieldset > div,
|
||||
.modal fieldset > div > div {
|
||||
max-width: 100% !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.modal-content {
|
||||
padding: 12px !important;
|
||||
margin: 5px !important;
|
||||
}
|
||||
|
||||
.modal fieldset {
|
||||
padding: 8px !important;
|
||||
margin: 6px 0 !important;
|
||||
}
|
||||
|
||||
/* Enhanced mobile build controls */
|
||||
.build-controls {
|
||||
flex-direction: column !important;
|
||||
gap: 0.25rem !important; /* Reduced gap */
|
||||
align-items: stretch !important;
|
||||
padding: 0.5rem !important; /* Reduced padding */
|
||||
}
|
||||
|
||||
/* Two-column grid layout for mobile build controls */
|
||||
.build-controls {
|
||||
display: grid !important;
|
||||
grid-template-columns: 1fr 1fr !important; /* Two equal columns */
|
||||
grid-gap: 0.25rem !important;
|
||||
align-items: stretch !important;
|
||||
}
|
||||
|
||||
.build-controls form {
|
||||
display: contents !important; /* Allow form contents to participate in grid */
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.build-controls button {
|
||||
flex: none !important;
|
||||
padding: 0.4rem 0.5rem !important; /* Much smaller padding */
|
||||
font-size: 12px !important; /* Smaller font */
|
||||
min-height: 36px !important; /* Smaller minimum height */
|
||||
line-height: 1.2 !important;
|
||||
width: 100% !important; /* Full width within grid cell */
|
||||
box-sizing: border-box !important;
|
||||
white-space: nowrap !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
/* Hide non-essential elements on mobile to keep it clean */
|
||||
.build-controls .sep,
|
||||
.build-controls .replace-toggle,
|
||||
.build-controls label[style*="margin-left"] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.build-controls .sep {
|
||||
display: none !important; /* Hide separators on mobile */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue