Improve layout and visual styles for search pages

Enhanced the MainLayout and search pages with improved CSS for smoother scrolling, better overflow handling, and more visually appealing backgrounds. Updated the SearchShows match result section for a cleaner, more modern look. Refined keyframe animations and mobile responsiveness for a more polished user experience.
This commit is contained in:
2025-08-26 09:29:12 -04:00
parent 9f238ebafc
commit 26a7b04e82
3 changed files with 344 additions and 151 deletions
@@ -1,5 +1,4 @@
@inherits LayoutComponentBase
<div class="page">
<main class="main-content">
<article class="content">
@@ -7,25 +6,90 @@
</article>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
overflow-x: hidden;
overflow-y: auto;
}
.page {
display: flex;
height: 100vh;
overflow: hidden;
min-height: 100vh;
}
.main-content {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
}
.content {
min-height: 100%;
}
html {
scroll-behavior: smooth;
}
.main-content::-webkit-scrollbar {
width: 8px;
}
.main-content::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1);
border-radius: 4px;
}
.main-content::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.3);
border-radius: 4px;
transition: background 0.3s ease;
}
.main-content::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, 0.5);
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHZpZXdCb3g9IjAgMCA1NiA0OSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzLjUgNi41QzE0LjA1MjMgNi41IDE0LjUgNi4wNTIyOCAxNC41IDUuNUMxNC41IDQuOTQ3NzIgMTQuMDUyMyA0LjUgMTMuNSA0LjVIMTEuNUM5LjU2NzA5IDQuNSA4IDYuMDY3MDkgOCA4VjEwLjVDOCAxMS4wNTIzIDguNDQ3NzIgMTEuNSA5IDExLjVDOS41NTIyOCAxMS41IDEwIDExLjA1MjMgMTAgMTAuNVY4QzEwIDcuMTcxNTcgMTAuNjcxNiA2LjUgMTEuNSA2LjVIMTMuNVoiIGZpbGw9IiM1MTVBNUE1QTUiLz4KPC9zdmc+) no-repeat 1rem/1.8rem, #b32121;
color: white;
padding: 1rem 1rem 1rem 3.7rem;
position: fixed;
top: 0;
width: 100%;
z-index: 1001;
display: none;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
</style>
@@ -176,20 +176,24 @@
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
position: relative;
overflow-x: hidden;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
top: -100px;
left: -100px;
right: -100px;
bottom: -100px;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="2" fill="rgba(255,255,255,0.1)"/><circle cx="20" cy="20" r="1" fill="rgba(255,255,255,0.08)"/><circle cx="80" cy="30" r="1.5" fill="rgba(255,255,255,0.06)"/></svg>') repeat;
opacity: 0.3;
pointer-events: none;
animation: float 20s ease-in-out infinite;
animation: floatContained 20s ease-in-out infinite;
z-index: -1;
will-change: transform;
backface-visibility: hidden;
transform-style: preserve-3d;
}
.search-container {
@@ -199,32 +203,51 @@
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
position: relative;
z-index: 1;
overflow: hidden;
}
.search-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
top: -100px;
left: -100px;
right: -100px;
bottom: -100px;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="2" fill="rgba(255,255,255,0.1)"/><circle cx="20" cy="20" r="1" fill="rgba(255,255,255,0.08)"/><circle cx="80" cy="30" r="1.5" fill="rgba(255,255,255,0.06)"/></svg>') repeat;
opacity: 0.3;
pointer-events: none;
animation: float 20s ease-in-out infinite;
animation: floatContained 20s ease-in-out infinite;
z-index: -1;
overflow: hidden;
will-change: transform;
backface-visibility: hidden;
transform-style: preserve-3d;
}
@@keyframes float {
@@keyframes floatContained {
0%, 100%
{
transform: translateY(0px) rotate(0deg);
transform: translateY(0px) rotate(0deg) scale(1);
}
25% {
transform: translateY(-5px) rotate(45deg) scale(1.02);
}
50% {
transform: translateY(-20px) rotate(180deg);
transform: translateY(-8px) rotate(90deg) scale(0.98);
}
75% {
transform: translateY(-5px) rotate(135deg) scale(1.02);
}
}
html {
overflow-x: hidden;
scroll-behavior: smooth;
}
.search-header {
@@ -799,6 +822,7 @@
font-weight: 500;
}
/* Mobile optimization */
@@media (max-width: 768px) {
.search-container
@@ -828,6 +852,31 @@
gap: 1rem;
}
body::before,
.search-container::before {
animation: floatContained 25s ease-in-out infinite;
}
@@keyframes floatContained {
0%, 100%
{
transform: translateY(0px) rotate(0deg) scale(1);
}
25% {
transform: translateY(-3px) rotate(45deg) scale(1.01);
}
50% {
transform: translateY(-5px) rotate(90deg) scale(0.99);
}
75% {
transform: translateY(-3px) rotate(135deg) scale(1.01);
}
}
}
</style>
@@ -73,30 +73,20 @@
@if (_matchedShow != null)
{
<div class="matched-show-section">
<h4 class="section-title">Your Search Match</h4>
<div class="show-card featured">
<div class="poster-container">
<img class="poster-image"
src="@($"https://image.tmdb.org/t/p/w500{_matchedShow.ShowPosterPath}")"
<h4 class="section-title">
<span class="match-indicator"></span>
Your Search Result
</h4>
<div class="search-match-banner">
<div class="match-poster">
<img src="@($"https://image.tmdb.org/t/p/w200{_matchedShow.ShowPosterPath}")"
alt="@_matchedShow.ShowTitle Poster"
loading="lazy" />
<div class="match-badge">✨ Match</div>
<div class="poster-overlay">
<div class="overlay-content">
<span class="view-details">View Details</span>
</div>
</div>
</div>
<div class="card-content">
<h5 class="show-title">@_matchedShow.ShowTitle</h5>
<div class="character-name">as @_matchedShow.CharacterName</div>
@if (!string.IsNullOrEmpty(_matchedShow.Overview?.Trim()))
{
<p class="show-overview expanded">
@_matchedShow.Overview.Trim()
</p>
}
<div class="air-date">First aired: @_matchedShow.FirstAirDate</div>
<div class="match-info">
<h5 class="match-title">@_matchedShow.ShowTitle</h5>
<div class="match-character">as @_matchedShow.CharacterName</div>
<div class="match-date">First aired: @_matchedShow.FirstAirDate</div>
</div>
</div>
</div>
@@ -179,40 +169,78 @@
</div>
<style>
body {
margin: 0;
padding: 0;
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
min-height: 100vh;
position: relative;
overflow-x: hidden;
}
body::before {
content: '';
position: fixed;
top: -100px;
left: -100px;
right: -100px;
bottom: -100px;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect x="10" y="20" width="15" height="10" fill="rgba(255,255,255,0.06)" rx="2"/><rect x="70" y="10" width="20" height="15" fill="rgba(255,255,255,0.04)" rx="2"/><rect x="30" y="70" width="12" height="8" fill="rgba(255,255,255,0.05)" rx="1"/></svg>') repeat;
opacity: 0.4;
pointer-events: none;
animation: floatContained 25s ease-in-out infinite;
z-index: -1;
will-change: transform;
backface-visibility: hidden;
transform-style: preserve-3d;
}
.search-container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 1rem;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
min-height: 100vh;
position: relative;
z-index: 1;
overflow: hidden;
}
.search-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
top: -100px;
left: -100px;
right: -100px;
bottom: -100px;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect x="10" y="20" width="15" height="10" fill="rgba(255,255,255,0.06)" rx="2"/><rect x="70" y="10" width="20" height="15" fill="rgba(255,255,255,0.04)" rx="2"/><rect x="30" y="70" width="12" height="8" fill="rgba(255,255,255,0.05)" rx="1"/></svg>') repeat;
opacity: 0.4;
pointer-events: none;
animation: float 25s ease-in-out infinite;
animation: floatContained 25s ease-in-out infinite;
z-index: -1;
overflow: hidden;
will-change: transform;
backface-visibility: hidden;
transform-style: preserve-3d;
}
@@keyframes float {
0%, 100%
{
transform: translateY(0px) rotate(0deg);
@@keyframes floatContained {
0%, 100% {
transform: translateY(0px) rotate(0deg) scale(1);
}
25% {
transform: translateY(-5px) rotate(45deg) scale(1.02);
}
50% {
transform: translateY(-30px) rotate(180deg);
transform: translateY(-8px) rotate(90deg) scale(0.98);
}
75% {
transform: translateY(-5px) rotate(135deg) scale(1.02);
}
}
html {
overflow-x: hidden;
scroll-behavior: smooth;
}
.search-header {
@@ -285,18 +313,14 @@
}
@@keyframes slideInDown {
from
{
from {
opacity: 0;
transform: translateY(-50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.search-subtitle {
@@ -307,16 +331,12 @@
}
@@keyframes fadeIn {
from
{
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.search-form {
@@ -333,18 +353,14 @@
}
@@keyframes slideInUp {
from
{
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.input-group {
@@ -433,16 +449,12 @@
}
@@keyframes spin {
0%
{
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.loading-state, .welcome-state, .no-results {
@@ -478,16 +490,12 @@
}
@@keyframes bounce {
0%, 80%, 100%
{
0%, 80%, 100% {
transform: scale(0);
}
40% {
transform: scale(1);
}
}
.welcome-icon, .no-results-icon {
@@ -497,16 +505,12 @@
}
@@keyframes pulse {
0%, 100%
{
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
.results-section {
@@ -549,7 +553,65 @@
}
.matched-show-section {
margin-bottom: 3rem;
margin-bottom: 2rem;
}
.search-match-banner {
background: rgba(255,255,255,0.15);
border-radius: 1rem;
padding: 1.5rem;
display: flex;
align-items: center;
gap: 1.5rem;
backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.2);
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
.match-poster {
flex-shrink: 0;
}
.match-poster img {
width: 80px;
height: 120px;
object-fit: cover;
border-radius: 0.5rem;
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
}
.match-info {
flex: 1;
color: white;
}
.match-title {
font-size: 1.25rem;
font-weight: 600;
margin: 0 0 0.5rem 0;
color: white;
}
.match-character {
font-size: 0.95rem;
color: rgba(255,255,255,0.8);
margin-bottom: 0.25rem;
}
.match-date {
font-size: 0.85rem;
color: rgba(255,255,255,0.6);
}
.match-indicator {
font-family: 'Courier New', monospace;
background: rgba(16, 185, 129, 0.8);
color: white;
padding: 0.25rem 0.75rem;
border-radius: 0.5rem;
font-size: 0.8rem;
font-weight: 600;
margin-right: 0.5rem;
}
.section-title {
@@ -730,10 +792,9 @@
font-weight: 500;
}
/* Mobile optimization */
@@media (max-width: 768px) {
.search-container
{
.search-container {
padding: 1rem;
}
@@ -759,6 +820,25 @@
gap: 1rem;
}
body::before,
.search-container::before {
animation: floatContained 30s ease-in-out infinite;
}
@@keyframes floatContained {
0%, 100% {
transform: translateY(0px) rotate(0deg) scale(1);
}
25% {
transform: translateY(-3px) rotate(45deg) scale(1.01);
}
50% {
transform: translateY(-5px) rotate(90deg) scale(0.99);
}
75% {
transform: translateY(-3px) rotate(135deg) scale(1.01);
}
}
}
</style>