screen-companion / static /style.css
irkan's picture
Deploy screen-companion from a3c8581
e20a06c verified
Raw
History Blame Contribute Delete
17.9 kB
/* ═══════════════════════════════════════════════════════════════════════════
SCREEN COMPANION β€” Styles
Section A: Landing page
Section B: PiP window (injected via <link>)
═══════════════════════════════════════════════════════════════════════════ */
:root {
--font-display: 'Silkscreen', monospace;
--font-body: 'Space Grotesk', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
--bg-deep: #0c0a1a;
--bg-surface: rgba(28, 24, 60, 0.6);
--bg-glass: rgba(60, 50, 120, 0.25);
--border-glass: rgba(140, 120, 255, 0.2);
--text-primary: #eae8ff;
--text-secondary: #a8a0cc;
--text-muted: #6b6394;
--accent: #b8e6ff;
--accent-glow: rgba(184, 230, 255, 0.3);
--accent-hot: #ffe066;
--accent-sad: #c8b8ff;
--accent-mint: #d4f0d4;
--pip-body: #b8e6ff;
--pip-blush: #ffb3c6;
--pip-eyes: #2d2d2d;
}
/* ═══════════════════════════════════════════════════════════════════════════
A. LANDING PAGE
═══════════════════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: var(--font-body);
background: linear-gradient(170deg, var(--bg-deep) 0%, #1a0f33 40%, #0d1b2a 100%);
color: var(--text-primary);
min-height: 100vh;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
.page {
max-width: 680px;
margin: 0 auto;
padding: 2rem 1.5rem 4rem;
}
/* ─── Banners ─────────────────────────────────────────────────────── */
.banner {
padding: 0.75rem 1rem;
border-radius: 8px;
margin-bottom: 1.5rem;
font-size: 0.85rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.banner--warn {
background: rgba(255, 200, 50, 0.12);
border: 1px solid rgba(255, 200, 50, 0.3);
color: #ffe066;
}
.banner--error {
background: rgba(255, 80, 80, 0.12);
border: 1px solid rgba(255, 80, 80, 0.3);
color: #ff8888;
}
.banner__icon { font-size: 1.1rem; }
.banner__link { color: inherit; font-weight: 500; }
/* ─── Header ──────────────────────────────────────────────────────── */
.header {
text-align: center;
margin: 2rem 0 2.5rem;
}
.header__title {
font-family: var(--font-display);
font-size: clamp(2.5rem, 8vw, 4rem);
letter-spacing: 2px;
color: var(--accent);
text-shadow: 0 0 40px var(--accent-glow), 0 0 80px rgba(184, 230, 255, 0.1);
}
.header__sub {
font-size: 1rem;
color: var(--text-secondary);
margin-top: 0.25rem;
letter-spacing: 0.5px;
}
/* ─── Hero / PiP preview ─────────────────────────────────────────── */
.hero {
display: flex;
justify-content: center;
margin-bottom: 3rem;
}
.pip-frame {
width: 220px;
border-radius: 16px;
overflow: hidden;
background: #1c1c2e;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.5),
0 0 0 1px rgba(140, 120, 255, 0.15),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.pip-frame__chrome {
display: flex;
gap: 5px;
padding: 8px 10px;
background: #2a2844;
}
.pip-frame__dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #4a4470;
}
.pip-frame__dot:first-child { background: #ff5f57; }
.pip-frame__dot:nth-child(2) { background: #ffbd2e; }
.pip-frame__dot:nth-child(3) { background: #28ca41; }
.pip-frame__body {
padding: 1.5rem 1rem 1rem;
display: flex;
justify-content: center;
min-height: 220px;
}
.companion-preview {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}
.companion-preview .companion-svg {
width: 120px;
height: 120px;
}
/* Speech bubble (demo on landing) */
.speech-bubble--demo {
margin-top: 0.75rem;
background: white;
color: #2d2d3a;
padding: 0.5rem 0.75rem;
border-radius: 12px;
font-size: 0.72rem;
font-family: var(--font-body);
max-width: 180px;
text-align: center;
position: relative;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.speech-bubble--demo::before {
content: '';
position: absolute;
top: -6px;
left: 50%;
margin-left: -6px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid white;
}
.speech-bubble__text {
transition: opacity 0.3s;
}
/* ─── Steps ───────────────────────────────────────────────────────── */
.steps {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
margin-bottom: 3rem;
}
.step {
background: var(--bg-glass);
border: 1px solid var(--border-glass);
border-radius: 12px;
padding: 1.25rem 1rem;
text-align: center;
backdrop-filter: blur(8px);
transition: transform 0.2s, box-shadow 0.2s;
}
.step:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(140, 120, 255, 0.1);
}
.step__num {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 50%;
background: var(--accent);
color: var(--bg-deep);
font-family: var(--font-display);
font-size: 0.75rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.step__title {
font-family: var(--font-display);
font-size: 0.8rem;
color: var(--text-primary);
margin-bottom: 0.4rem;
}
.step__desc {
font-size: 0.75rem;
color: var(--text-secondary);
line-height: 1.4;
}
/* ─── Launch button ───────────────────────────────────────────────── */
.launch-section {
text-align: center;
margin-bottom: 2.5rem;
}
.launch-btn {
font-family: var(--font-display);
font-size: 1rem;
padding: 1rem 2.5rem;
border: none;
border-radius: 50px;
background: linear-gradient(135deg, #7c5cff 0%, #4ecdc4 100%);
color: white;
cursor: pointer;
transition: transform 0.15s, box-shadow 0.15s;
box-shadow:
0 6px 20px rgba(124, 92, 255, 0.3),
0 0 0 0 rgba(124, 92, 255, 0);
display: inline-flex;
align-items: center;
gap: 0.6rem;
}
.launch-btn:hover:not(:disabled) {
transform: translateY(-2px) scale(1.02);
box-shadow:
0 10px 30px rgba(124, 92, 255, 0.4),
0 0 0 4px rgba(124, 92, 255, 0.1);
}
.launch-btn:active:not(:disabled) {
transform: translateY(0) scale(0.98);
}
.launch-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.launch-btn__ghost {
font-size: 1.4rem;
}
.launch-section__note {
margin-top: 0.75rem;
font-size: 0.8rem;
color: var(--text-muted);
min-height: 1.2rem;
}
/* ─── Privacy badge ───────────────────────────────────────────────── */
.privacy {
display: flex;
justify-content: center;
margin-bottom: 2rem;
}
.privacy__badge {
display: flex;
align-items: flex-start;
gap: 0.75rem;
padding: 0.75rem 1.25rem;
border: 1px dashed var(--border-glass);
border-radius: 10px;
font-size: 0.75rem;
color: var(--text-secondary);
max-width: 380px;
}
.privacy__icon {
font-size: 1.2rem;
flex-shrink: 0;
}
/* ─── Footer ──────────────────────────────────────────────────────── */
.footer {
text-align: center;
padding-top: 2rem;
border-top: 1px solid var(--border-glass);
font-size: 0.72rem;
color: var(--text-muted);
}
.footer a {
color: var(--accent);
text-decoration: none;
}
.footer a:hover { text-decoration: underline; }
/* ─── Responsive ──────────────────────────────────────────────────── */
@media (max-width: 600px) {
.steps { grid-template-columns: 1fr; gap: 0.75rem; }
.pip-frame { width: 180px; }
}
/* ═══════════════════════════════════════════════════════════════════════════
B. PiP WINDOW STYLES
═══════════════════════════════════════════════════════════════════════════ */
.pip-body {
margin: 0;
padding: 0;
font-family: 'Space Grotesk', system-ui, sans-serif;
background: #2a1f3d;
overflow: hidden;
height: 100%;
position: relative;
image-rendering: pixelated;
}
/* ─── Cozy House Exterior (image-based, day/night) ────────────────── */
.pip-scene {
position: absolute;
inset: 0;
z-index: 0;
overflow: hidden;
background-image: url('/static/day_house.jpg');
background-size: 200% 200%;
background-position: 50% 80%;
background-repeat: no-repeat;
transition: background-position 1.5s ease-in-out;
image-rendering: pixelated;
}
.pip-scene[data-time="night"] {
background-image: url('/static/night_house.jpg');
}
.pip-container {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
height: 100%;
padding: 0 0.5rem 1.4rem;
}
.companion-wrap {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: transform 1.5s ease-in-out;
}
.speech-area {
flex: 0 0 auto;
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 0.25rem;
min-height: 48px;
max-height: 60px;
}
/* ─── SVG base styles ─────────────────────────────────────────────── */
.companion-svg {
width: 100px;
height: 100px;
filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.5));
}
.body { fill: var(--pip-body); }
.blush { fill: var(--pip-blush); opacity: 0.5; }
.eye-white { fill: white; stroke: #e0e0e0; stroke-width: 0.3; }
.pupil { fill: var(--pip-eyes); }
.pupil-group { transition: transform 0.05s linear; }
.highlight { fill: white; }
.arm { stroke: var(--pip-body); }
/* ─── Emotion colors ──────────────────────────────────────────────── */
.emotion-happy .body { fill: #b8e6ff; }
.emotion-happy .arm { stroke: #b8e6ff; }
.emotion-excited .body { fill: #ffe066; }
.emotion-excited .arm { stroke: #ffe066; }
.emotion-excited .blush { fill: #ff9e6e; opacity: 0.7; }
.emotion-sad .body { fill: #c8b8ff; }
.emotion-sad .arm { stroke: #c8b8ff; }
.emotion-neutral .body { fill: #d4f0d4; }
.emotion-neutral .arm { stroke: #d4f0d4; }
.emotion-curious .body { fill: #b8f0e6; }
.emotion-curious .arm { stroke: #b8f0e6; }
.emotion-restless .body { fill: #f0d4b8; }
.emotion-restless .arm { stroke: #f0d4b8; }
/* ─── Animation states ────────────────────────────────────────────── */
/* Idle: gentle bounce + blink */
.state-idle .body-group {
animation: bounce 2.5s ease-in-out infinite;
}
.state-idle .eyes-group {
animation: blink 4s steps(1) infinite;
transform-origin: center 30px;
}
/* Walk closer: slide in + scale up */
.state-walk .body-group {
animation: slide-in 1.2s ease-out forwards;
}
/* Knock: arm + body nudge */
.state-knock .arm-group {
animation: knock-arm 1s ease-in-out;
transform-origin: 48px 36px;
}
.state-knock .body-group {
animation: knock-nudge 1s ease-in-out;
}
/* Speak: slight wiggle while talking */
.state-speak .body-group {
animation: wiggle 0.8s ease-in-out infinite;
}
/* Celebrate: fast bounce + wiggle */
.state-celebrate .body-group {
animation: celebrate-bounce 0.4s ease-in-out 4;
}
.state-celebrate .eyes-group {
animation: squint-happy 0.4s ease-in-out 4;
}
/* Sleep: slow breathing, closed eyes */
.state-sleep .body-group {
animation: bounce 5s ease-in-out infinite;
}
.state-sleep .eyes-group {
transform: scaleY(0.15);
transform-origin: center;
}
.state-sleep .blush { opacity: 0.7; }
/* ─── Keyframes ───────────────────────────────────────────────────── */
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-5px); }
}
@keyframes blink {
0%, 92%, 100% { transform: scaleY(1); }
94% { transform: scaleY(0.1); }
96% { transform: scaleY(1); }
}
@keyframes slide-in {
0% { transform: translateX(40px) scale(0.7); opacity: 0.4; }
100% { transform: translateX(0) scale(1); opacity: 1; }
}
@keyframes knock-arm {
0%, 100% { transform: rotate(0deg); }
15%, 45%, 75% { transform: rotate(-20deg) translateX(4px); }
30%, 60% { transform: rotate(0deg); }
}
@keyframes knock-nudge {
0%, 100% { transform: translateX(0); }
15%, 45%, 75% { transform: translateX(4px); }
30%, 60% { transform: translateX(0); }
}
@keyframes wiggle {
0%, 100% { transform: rotate(0deg) translateY(0); }
25% { transform: rotate(-1.5deg) translateY(-1px); }
75% { transform: rotate(1.5deg) translateY(-1px); }
}
@keyframes celebrate-bounce {
0%, 100% { transform: translateY(0) scale(1); }
50% { transform: translateY(-12px) scale(1.05); }
}
@keyframes squint-happy {
0%, 100% { transform: scaleY(1); }
40%, 60% { transform: scaleY(0.6); }
}
/* ─── Speech bubble (PiP) ─────────────────────────────────────────── */
.speech-bubble {
background: rgba(255, 255, 255, 0.95);
color: #1a1a2e;
padding: 0.45rem 0.7rem;
border-radius: 12px;
font-size: 0.75rem;
font-family: 'Space Grotesk', sans-serif;
max-width: 200px;
text-align: center;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
opacity: 0;
transform: scale(0.85) translateY(-4px);
transition: opacity 0.25s, transform 0.25s;
line-height: 1.35;
}
.speech-bubble.visible {
opacity: 1;
transform: scale(1) translateY(0);
}
/* Typing dots animation */
.typing-dots span {
display: inline-block;
font-size: 1.4em;
font-weight: bold;
line-height: 0.5;
animation: typing-pulse 1.2s ease-in-out infinite;
}
.typing-dots span:nth-child(1) { animation-delay: 0s; }
.typing-dots span:nth-child(2) { animation-delay: 0.2s; }
.typing-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes typing-pulse {
0%, 60%, 100% { transform: scale(1); opacity: 0.4; }
30% { transform: scale(1.6); opacity: 1; }
}
.speech-bubble::before {
content: '';
position: absolute;
top: -6px;
left: 50%;
margin-left: -6px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid rgba(255, 255, 255, 0.95);
}
/* ─── PiP Controls ────────────────────────────────────────────────── */
.pip-controls {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
gap: 0.25rem;
padding: 0.2rem 0.3rem;
background: #1a1225;
border-top: 1px solid #3a2a5a;
z-index: 50;
}
.pip-ctrl {
border: none;
background: #2e2244;
color: #eee;
font-size: 0.65rem;
padding: 0.15rem 0.4rem;
border-radius: 6px;
cursor: pointer;
font-family: 'Space Grotesk', sans-serif;
transition: background 0.15s, color 0.15s;
border: 1px solid #4a3a6a;
line-height: 1.2;
}
.pip-ctrl:hover {
background: #4a3a6a;
color: white;
}
/* ─── Confetti celebration ─────────────────────────────────────────── */
.confetti-burst {
position: absolute;
top: 30%;
left: 50%;
pointer-events: none;
z-index: 10;
}
.confetti-piece {
position: absolute;
width: 6px;
height: 6px;
border-radius: 1px;
animation: confetti-fly 2.5s ease-out forwards;
animation-delay: calc(var(--i) * 0.05s);
}
.confetti-piece:nth-child(1) { background: #ff6b6b; }
.confetti-piece:nth-child(2) { background: #ffd93d; }
.confetti-piece:nth-child(3) { background: #6bcb77; }
.confetti-piece:nth-child(4) { background: #4d96ff; }
.confetti-piece:nth-child(5) { background: #ff6b6b; }
.confetti-piece:nth-child(6) { background: #ffd93d; }
.confetti-piece:nth-child(7) { background: #6bcb77; }
.confetti-piece:nth-child(8) { background: #4d96ff; }
.confetti-piece:nth-child(9) { background: #ff6b6b; }
.confetti-piece:nth-child(10) { background: #ffd93d; }
.confetti-piece:nth-child(11) { background: #6bcb77; }
.confetti-piece:nth-child(12) { background: #4d96ff; }
@keyframes confetti-fly {
0% {
transform: translate(0, 0) rotate(0deg) scale(1);
opacity: 1;
}
100% {
transform:
translate(
calc((var(--i) - 6) * 15px),
calc(-40px + var(--i) * 8px)
)
rotate(calc(var(--i) * 120deg))
scale(0.3);
opacity: 0;
}
}