Modern glow-up: glassmorphism, animated transitions, floating blobs

- Font: Inter → Nunito (warm, rounded, friendly)
- Glassmorphism: frosted-glass on all cards (question, dim, resource, audience, overall)
- Floating gradient blobs: 4 animated pastel blobs in background (CSS-only)
- Direction-aware question slides: left/right based on prev/next
- Staggered reveal: dim cards, resource cards, audience cards animate in sequence
- Completion badge pop-in, progress bar shimmer, wheel float animation
- Button polish: lift + glow on hover, smooth cubic-bezier transitions
- Option hover: slide right + tint, CTA active press-down
- Results wheel: drop-shadow glow on hover
- Print-safe: glass removed, blobs hidden in print
- Mobile: reduced blur/opacity for perf, blob 4 hidden
This commit is contained in:
2026-07-21 16:12:53 -04:00
parent b533c0f6f1
commit 60aacbf65a
+136 -4
View File
@@ -6,11 +6,11 @@
<title>Wheel of Wellness Assessment</title>
<meta name="description" content="Find the resources your family needs in 5 minutes. A wellness assessment across six dimensions.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<style>
:root{--primary:#C08B8B;--primary-dark:#A66E6E;--primary-light:#D4A5A5;--secondary:#E8A87C;--cream:#FFF9F5;--charcoal:#3D3232;--gray-100:#FBF7F7;--gray-200:#F0E6E6;--gray-300:#E0D0D0;--gray-400:#B8A0A0;--gray-500:#8C7878;--green:#7FB98C;--green-light:#EFF7F1;--yellow:#E8C46C;--yellow-light:#FDF8EC;--red:#D4857E;--red-light:#FDF0EF;--blue:#7EACB9;--blue-light:#EFF5F7;--lavender:#B8A4CC;--lavender-light:#F3EFF7;--shadow-sm:0 1px 3px rgba(0,0,0,.05);--shadow-md:0 4px 12px rgba(0,0,0,.07);--shadow-lg:0 8px 30px rgba(0,0,0,.09)}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif;background:var(--cream);color:var(--charcoal);-webkit-font-smoothing:antialiased;min-height:100vh;display:flex;flex-direction:column}
body{font-family:'Nunito',-apple-system,BlinkMacSystemFont,sans-serif;background:var(--cream);color:var(--charcoal);-webkit-font-smoothing:antialiased;min-height:100vh;display:flex;flex-direction:column;overflow-x:hidden}
a{color:var(--primary);text-decoration:none}
/* Header */
@@ -171,7 +171,7 @@ a{color:var(--primary);text-decoration:none}
/* Print styles */
@media print{
.site-header,.site-footer,.actions-bar,.btn-reset,.history-section,.disclaimer{display:none!important}
.site-header,.site-footer,.actions-bar,.btn-reset,.history-section,.disclaimer,.bg-blobs{display:none!important}
body{background:white}
.screen{display:block!important}
.container{padding:0;max-width:100%}
@@ -180,11 +180,137 @@ a{color:var(--primary);text-decoration:none}
.dim-card,.resource-card{break-inside:avoid;box-shadow:none;border:1px solid #ddd}
.overall-card{break-inside:avoid}
.resource-section{break-inside:avoid}
.question-card,.dim-card,.resource-card,.overall-card,.audience-card{background:white!important;backdrop-filter:none!important}
}
/* ═══════════════════════════════════════════
MODERN GLOW-UP
═══════════════════════════════════════════ */
/* Floating gradient blobs */
.bg-blobs{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.bg-blobs .blob{position:absolute;border-radius:50%;filter:blur(80px);opacity:.25;animation:blobFloat 20s ease-in-out infinite}
.bg-blobs .blob:nth-child(1){width:400px;height:400px;background:#D4A5A5;top:-100px;left:-80px;animation-delay:0s}
.bg-blobs .blob:nth-child(2){width:350px;height:350px;background:#B8A4CC;top:40%;right:-100px;animation-delay:-5s}
.bg-blobs .blob:nth-child(3){width:300px;height:300px;background:#7FB98C;bottom:-60px;left:30%;animation-delay:-10s}
.bg-blobs .blob:nth-child(4){width:250px;height:250px;background:#7EACB9;top:20%;left:50%;animation-delay:-15s}
@keyframes blobFloat{
0%,100%{transform:translate(0,0) scale(1)}
25%{transform:translate(30px,-40px) scale(1.05)}
50%{transform:translate(-20px,30px) scale(.95)}
75%{transform:translate(40px,20px) scale(1.02)}
}
/* Ensure content sits above blobs */
.site-header,.screen,.site-footer{position:relative;z-index:1}
/* Glassmorphism mixin — applied to cards */
.question-card{background:rgba(255,255,255,.65);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(255,255,255,.5);box-shadow:0 8px 32px rgba(61,50,50,.08)}
.audience-card{background:rgba(255,255,255,.5);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:2px solid rgba(255,255,255,.4);transition:all .25s cubic-bezier(.4,0,.2,1)}
.audience-card:hover{border-color:var(--primary);box-shadow:0 8px 24px rgba(192,139,139,.15);transform:translateY(-3px)}
.audience-card.selected{border-color:var(--primary);background:rgba(192,139,139,.12);box-shadow:0 4px 20px rgba(192,139,139,.2)}
.dim-card{background:rgba(255,255,255,.55);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.45);transition:all .2s}
.dim-card:hover{box-shadow:0 6px 20px rgba(61,50,50,.1);transform:translateY(-2px)}
.resource-card{background:rgba(255,255,255,.55);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.45);transition:all .25s}
.resource-card:hover{box-shadow:0 8px 24px rgba(61,50,50,.1);transform:translateY(-3px)}
.overall-card{background:rgba(255,255,255,.6);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(255,255,255,.5)}
.history-item{background:rgba(255,255,255,.5);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
/* Animated screen transitions */
.screen{display:none}
.screen.active{display:block;animation:screenIn .4s cubic-bezier(.4,0,.2,1) both}
@keyframes screenIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}
/* Question slide animation — direction-aware */
#question-area{position:relative;min-height:200px}
.question-card.slide-left{animation:slideLeft .3s cubic-bezier(.4,0,.2,1) both}
.question-card.slide-right{animation:slideRight .3s cubic-bezier(.4,0,.2,1) both}
@keyframes slideLeft{from{opacity:0;transform:translateX(40px)}to{opacity:1;transform:translateX(0)}}
@keyframes slideRight{from{opacity:0;transform:translateX(-40px)}to{opacity:1;transform:translateX(0)}}
/* Dimension cards stagger reveal */
.dim-card{opacity:0;animation:fadeUp .4s cubic-bezier(.4,0,.2,1) both}
.dim-card:nth-child(1){animation-delay:.05s}
.dim-card:nth-child(2){animation-delay:.1s}
.dim-card:nth-child(3){animation-delay:.15s}
.dim-card:nth-child(4){animation-delay:.2s}
.dim-card:nth-child(5){animation-delay:.25s}
.dim-card:nth-child(6){animation-delay:.3s}
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
/* Resource cards stagger */
.resource-card{opacity:0;animation:fadeUp .4s cubic-bezier(.4,0,.2,1) both}
.resource-card:nth-child(1){animation-delay:.35s}
.resource-card:nth-child(2){animation-delay:.4s}
.resource-card:nth-child(3){animation-delay:.45s}
.resource-card:nth-child(4){animation-delay:.5s}
.resource-card:nth-child(5){animation-delay:.55s}
.resource-card:nth-child(6){animation-delay:.6s}
.resource-card:nth-child(7){animation-delay:.65s}
.resource-card:nth-child(8){animation-delay:.7s}
/* Completion badge pop */
.completion-badge{animation:badgePop .5s cubic-bezier(.175,.885,.32,1.275) .1s both}
@keyframes badgePop{from{opacity:0;transform:scale(.7)}to{opacity:1;transform:scale(1)}}
/* Overall score count-up shimmer */
.overall-card{animation:fadeUp .5s cubic-bezier(.4,0,.2,1) .35s both}
/* Progress bar shimmer */
.progress-bar-fill{position:relative;overflow:hidden}
.progress-bar-fill::after{content:'';position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.3),transparent);animation:shimmer 2s ease-in-out infinite}
@keyframes shimmer{0%{left:-100%}100%{left:100%}}
/* Option item hover micro-interaction */
.option-item{transition:all .2s cubic-bezier(.4,0,.2,1)}
.option-item:hover{transform:translateX(4px);border-color:var(--primary-light);background:rgba(212,165,165,.06)}
.option-item.selected{transform:translateX(0)}
/* CTA button glow */
.cta-button{transition:all .25s cubic-bezier(.4,0,.2,1)}
.cta-button:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 28px rgba(192,139,139,.35)}
.cta-button:active:not(:disabled){transform:translateY(0)}
/* Nav button polish */
.btn-next,.btn-submit{transition:all .2s cubic-bezier(.4,0,.2,1)}
.btn-next:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 12px rgba(192,139,139,.25)}
.btn-submit:hover{transform:translateY(-2px);box-shadow:0 6px 20px rgba(192,139,139,.3)}
/* Wheel SVG subtle float */
.wheel-svg{animation:wheelFloat 6s ease-in-out infinite}
@keyframes wheelFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
/* Results wheel glow on hover */
.results-wheel-wrap svg{transition:filter .3s}
.results-wheel-wrap:hover svg{filter:drop-shadow(0 4px 16px rgba(192,139,139,.25))}
/* Audience grid stagger on load */
.audience-card{opacity:0;animation:fadeUp .35s cubic-bezier(.4,0,.2,1) both}
.audience-card:nth-child(1){animation-delay:.05s}
.audience-card:nth-child(2){animation-delay:.1s}
.audience-card:nth-child(3){animation-delay:.15s}
.audience-card:nth-child(4){animation-delay:.2s}
.audience-card:nth-child(5){animation-delay:.25s}
.audience-card:nth-child(6){animation-delay:.3s}
.audience-card:nth-child(7){animation-delay:.35s}
/* Button polish */
.actions-bar button{transition:all .2s cubic-bezier(.4,0,.2,1)}
.actions-bar button:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(61,50,50,.08)}
/* Mobile: disable blobs for perf */
@media(max-width:640px){
.bg-blobs .blob{filter:blur(60px);opacity:.15}
.bg-blobs .blob:nth-child(4){display:none}
}
</style>
</head>
<body>
<div class="bg-blobs" aria-hidden="true">
<div class="blob"></div><div class="blob"></div><div class="blob"></div><div class="blob"></div>
</div>
<header class="site-header">
<div class="brand">
<div class="logo-icon"></div>
@@ -549,6 +675,7 @@ const RESOURCES = {
let selectedAudience = null;
let currentQ = 0;
let lastQ = -1; // ponytail: track direction for slide animation
let answers = {};
let lastResults = null;
@@ -703,6 +830,7 @@ function showScreen(name) {
function startAssessment() {
if (!selectedAudience) return;
currentQ = 0;
lastQ = -1;
answers = {};
showScreen('questions');
renderQuestion();
@@ -714,6 +842,7 @@ function resumeAssessment() {
if (!saved) return;
selectedAudience = saved.audience;
currentQ = saved.currentQ;
lastQ = -1;
answers = saved.answers || {};
document.getElementById('btn-start').disabled = false;
showScreen('questions');
@@ -753,7 +882,9 @@ function renderQuestion() {
return `<div class="option-item${selected}" onclick="selectOption('${item.id}',${i})"><div class="radio-circle"></div>${emoji}<span>${s}</span></div>`;
}).join('');
area.innerHTML = `<div class="question-card"><div class="q-dim-label" style="color:${dim.color}">${dim.label}</div><div class="q-number">${item.id}</div><div class="q-text">${item.text}</div><div class="options-list">${optionsHtml}</div></div>`;
const slideClass = lastQ < 0 ? '' : (currentQ > lastQ ? ' slide-left' : ' slide-right');
area.innerHTML = `<div class="question-card${slideClass}"><div class="q-dim-label" style="color:${dim.color}">${dim.label}</div><div class="q-number">${item.id}</div><div class="q-text">${item.text}</div><div class="options-list">${optionsHtml}</div></div>`;
lastQ = currentQ;
document.getElementById('btn-prev').style.visibility = currentQ === 0 ? 'hidden' : 'visible';
const nextBtn = document.getElementById('btn-next');
@@ -988,6 +1119,7 @@ function shareResults() {
function retake() {
answers = {};
currentQ = 0;
lastQ = -1;
selectedAudience = null;
lastResults = null;
clearProgress();