kv-netflix/frontend/styles/base.css

196 lines
No EOL
4.1 KiB
CSS
Executable file

/* ============================================
KV-Stream - Base Styles
PIXEL-PERFECT NETFLIX BASE STYLES
============================================ */
/* ============================================
RESET & FOUNDATION
============================================ */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 16px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
scroll-behavior: smooth;
scrollbar-width: none;
-ms-overflow-style: none;
}
html::-webkit-scrollbar {
display: none;
}
body {
font-family: var(--font-family);
font-size: var(--font-size-base);
font-weight: var(--font-weight-regular);
line-height: var(--line-height-normal);
color: var(--netflix-text);
background-color: var(--netflix-bg);
min-height: 100vh;
overflow-x: hidden;
}
/* ============================================
SCROLLBAR HIDING
============================================ */
::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
background: transparent;
}
/* ============================================
SELECTION
============================================ */
::selection {
background: var(--netflix-red);
color: var(--netflix-text);
}
/* ============================================
LINKS
============================================ */
a {
color: inherit;
text-decoration: none;
}
a:hover {
color: var(--netflix-text-secondary);
}
/* ============================================
IMAGES
============================================ */
img {
max-width: 100%;
height: auto;
display: block;
}
/* ============================================
NETFLIX SHIMMER ANIMATION
============================================ */
@keyframes shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
.shimmer {
background: linear-gradient(90deg,
var(--netflix-bg-card) 25%,
var(--netflix-bg-elevated) 50%,
var(--netflix-bg-card) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
/* ============================================
LOADING STATES
============================================ */
.loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
gap: 16px;
color: var(--netflix-text-secondary);
}
.loading__spinner {
width: 48px;
height: 48px;
border: 3px solid var(--netflix-bg-elevated);
border-top-color: var(--netflix-red);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* ============================================
EMPTY STATES
============================================ */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80px 20px;
text-align: center;
color: var(--netflix-text-secondary);
}
.empty-state svg {
opacity: 0.3;
margin-bottom: 16px;
}
.empty-state h2 {
font-size: var(--font-size-xl);
color: var(--netflix-text);
margin-bottom: 8px;
}
.empty-state p {
font-size: var(--font-size-base);
}
/* ============================================
UTILITY CLASSES
============================================ */
.text-match {
color: var(--netflix-green) !important;
}
.text-muted {
color: var(--netflix-text-secondary) !important;
}
.text-red {
color: var(--netflix-red) !important;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* ============================================
FOCUS STYLES (Accessibility)
============================================ */
:focus-visible {
outline: 2px solid var(--netflix-red);
outline-offset: 2px;
}
button:focus:not(:focus-visible),
a:focus:not(:focus-visible) {
outline: none;
}