This commit is contained in:
xbl
2025-10-22 11:51:33 +02:00
commit 94e1502aa2
14 changed files with 1684 additions and 0 deletions
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

+168
View File
@@ -0,0 +1,168 @@
document.addEventListener("DOMContentLoaded", () => {
const labels = ['Energy','Calm','Relax','Sleep','Focus','Inspire'];
let userData = [...window.appData.initialUserData];
const profiles = window.appData.profiles;
const youLineColor = 'rgba(255,255,255,0.69)';
const pointBgColor = 'rgba(0,0,0,0.1)';
const youFillColor = 'rgba(255,255,255,0.1)';
const matchLineColor = 'rgb(191,181,49)';
const matchFillColor = 'rgba(191,181,49,0.420)';
const radialLineColor= 'rgba(255,255,255,0.420)';
function distance(a,b){ return Math.sqrt(a.reduce((s,v,i)=>s+(v-b[i])**2,0)); }
function getTopMatches() {
return Object.entries(profiles)
.sort((a,b)=>distance(userData,a[1].values)-distance(userData,b[1].values))
.slice(0,3);
}
function getFontSize(){ return window.innerWidth < 600 ? 10 : 39; }
function getBottomChartFontSize(){ return window.innerWidth < 600 ? 8 : 24; }
function getPointRadius(){ return window.innerWidth < 600 ? 11 : 24; }
function getPointHoverRadius(){ return window.innerWidth < 600 ? 12 : 39; }
function getPointBorderColor(){ return '#BFB531'; }
// === Initialize charts ===
const charts = [1,2,3].map(i => {
const ctx = document.getElementById(`chart-${i}`).getContext('2d');
const isBest = i === 1;
const datasets = isBest ? [
{
label:'You',
data:[...userData],
fill:true,
borderColor: youLineColor,
backgroundColor: youFillColor,
pointBackgroundColor: pointBgColor,
pointBorderColor: getPointBorderColor(),
pointRadius: getPointRadius(),
pointHoverRadius: getPointHoverRadius()
},
{
label:'Match',
data:[],
fill:true,
borderColor: matchLineColor,
backgroundColor: matchFillColor,
pointBackgroundColor: matchLineColor,
pointRadius:0
}
] : [
{
label:'Match',
data:[],
fill:true,
borderColor: matchLineColor,
backgroundColor: matchFillColor,
pointBackgroundColor: matchLineColor,
pointRadius:0
}
];
return new Chart(ctx,{
type:'radar',
data:{ labels, datasets },
options:{
responsive:true,
maintainAspectRatio:false,
scales:{
r:{
min:0, max:80,
ticks:{ display:false, stepSize:20 },
pointLabels:{ font:{ size:isBest?getFontSize():getBottomChartFontSize(), weight:'bold' }, color:'#FFF' },
angleLines:{ color:radialLineColor },
grid:{ drawticks:false, drawOnChartArea:false, circular:false }
}
},
plugins:{
tooltip:{ enabled:false },
legend:{ display:false }
}
}
});
});
// === Update charts & DOM ===
function updateCharts(){
const matches = getTopMatches();
matches.forEach(([name, prof], idx)=>{
const chart = charts[idx];
if(idx===0){
chart.data.datasets[0].data = [...userData];
chart.data.datasets[1].data = prof.values;
chart.data.datasets[1].label = name;
} else {
chart.data.datasets[0].data = prof.values;
chart.data.datasets[0].label = name;
}
chart.options.scales.r.pointLabels.font.size = idx===0 ? getFontSize() : getBottomChartFontSize();
chart.update('none');
// Update main card
document.getElementById(`name-${idx+1}`).textContent = name;
for (let i = 0; i <= 4; i++) {
const el = document.getElementById(`info${i}-${idx+1}`);
if (el) el.textContent = prof[`info_text${i}`] || '';
}
// Update popup
const popupName = document.getElementById(`popup-name-${idx+1}`);
if (popupName) popupName.textContent = name;
for (let i = 0; i <= 4; i++) {
const popupEl = document.getElementById(`popup-info${i}-${idx+1}`);
if (popupEl) popupEl.textContent = prof[`info_text${i}`] || '';
}
});
}
updateCharts();
// === Reset button ===
document.getElementById('resetBtn').addEventListener('click', ()=>{
userData = [...window.appData.initialUserData];
updateCharts();
});
// === Dragging top chart ===
const topChart = charts[0];
const topCanvas = document.getElementById('chart-1');
topCanvas.style.touchAction = 'none';
let draggingIndex = null;
topCanvas.addEventListener('pointerdown', e => {
const points = topChart.getElementsAtEventForMode(e, 'nearest', {intersect:true}, true);
if(points.length && points[0].datasetIndex===0) draggingIndex = points[0].index;
});
topCanvas.addEventListener('pointermove', e => {
if(draggingIndex===null) return;
const rect = topCanvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const cx = rect.width/2;
const cy = rect.height/2;
const dx = x-cx;
const dy = cy-y;
const dist = Math.sqrt(dx*dx + dy*dy);
const rMax = Math.min(rect.width, rect.height)/2 * 0.9;
let value = (dist/rMax)*80;
value = Math.min(Math.max(Math.round(value),0),80);
userData[draggingIndex] = value;
updateCharts();
});
topCanvas.addEventListener('pointerup', ()=> draggingIndex=null);
topCanvas.addEventListener('pointerleave', ()=> draggingIndex=null);
// bottom charts scroll normally
[2,3].forEach(i => {
document.getElementById(`chart-${i}`).style.touchAction='auto';
});
window.addEventListener('resize', updateCharts);
});
+16
View File
@@ -0,0 +1,16 @@
function togglePopup(event, id) {
event.stopPropagation();
const popup = document.getElementById(id);
if (popup.classList.contains('active')) {
popup.classList.remove('active');
} else {
document.querySelectorAll('.popup').forEach(p => p.classList.remove('active'));
popup.classList.add('active');
}
}
// Close on outside click
document.addEventListener('click', () => {
document.querySelectorAll('.popup').forEach(p => p.classList.remove('active'));
});
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

+687
View File
@@ -0,0 +1,687 @@
/* === Reset & Base Styles === */
* { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
font-family: Arial, sans-serif;
color: #FFFFFF;
overflow-x: hidden;
}
h1, h2, h3 {
line-height: 1.3;
font-weight: bold;
text-align: center;
margin: 0 0 0 0;
}
h1 {
font-size: 2.25rem;
}
.top-match h2 {
font-size: 4rem;
}
.top-match h3 {
margin-top: 0.25em;
font-size: 2rem;
}
.bottom-row h3 {
margin-top: 0.25em;
font-size: 1.5rem;
}
.top-match p {
font-size: 1.5rem;
line-height: 1;
margin: 0.5em 0 0.5em;
color: #FFFFFF;
}
.bottom-row h2 {
font-size: 3rem;
}
.bottom-row p {
font-size: 1.25rem;
margin: 0 0 0;
}
.info-block {
#border: 3px solid #BFB531;
border-radius: 25px;
padding: 0.5em 0.5em;
margin: 0.5em 4em;
background-color: rgba(191,181,49,0.1);
text-align: center;
box-sizing: border-box;
}
.profile-info-block {
width: 100%;
}
/* ABOUT PAGE*/
.aboutbody {
display: flex;
flex-direction: column;
}
.abouttext a, p {
font-size: 1.25rem;
text-align: center;
text-decoration: none;
}
.abouttextcontainer {
margin-top: 3vh;
margin-bottom: 3vh;
}
.aboutlink {
color: #BFB531;
}
.made {
font-weight: bold;
color: #FF6600;
}
.aboutlogocontainer {
display: flex;
justify-content: center;
align-items: center;
}
.aboutlogo {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
flex: 1;
max-height: 150px;
max-width: 95%;
width: auto;
margin-top: 1em;
margin-bottom: 3em;
}
.aboutlogo img {
max-height: 100%;
max-width: 100%;
object-fit: contain;
}
input[type="hidden"] { display: none; }
/* === Body & Sticky Footer === */
body {
display: flex;
flex-direction: column;
min-height: 95vh; /* ensures footer sticks at bottom */
background: #1A202C;
}
/* === Page container fills remaining space === */
.page-container {
flex: 1;
display: flex;
flex-direction: column;
width: 100%;
padding: 20px;
}
/* === Logo === */
.logo-container {
display: flex;
justify-content: center;
align-items: center;
}
.logo {
width: 100%;
height: auto;
max-width: 480px;
}
/* === Grid Layout (profiles page) === */
.profile-grid {
display: grid;
padding: 20px;
grid-template-columns: repeat(auto-fit, minmax(420px, 420px));
gap: 25px;
width: 100%;
margin: 0 auto;
justify-content: center;
}
.profile-grid canvas {
width: 100%;
max-width: 420px;
height: auto;
max-height: 420px;
display: block;
object-fit: contain;
}
/* === Footer === */
.footer {
padding: 15px;
flex-shrink: 0; /* ensure footer doesn't shrink */
text-align: center;
}
.footer p {
font-size: 1rem;
color: #FFFFFF;
}
/* === Cards === */
.profile-card {
background: rgba(0,0,0,0.39);
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0,0,0,0.12);
display: flex;
flex-direction: column;
width: 100%;
}
.profile-profile-card {
padding: 1em;
flex-direction: column;
align-items: center;
background: rgba(0,0,0,0.39);
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0,0,0,0.12);
display: flex;
max-width: 420px;
max-height: 690px;
}
.profile-profile-card canvas {
display: block;
width: 100%;
height: auto;
max-width: 420px;
max-height: 420px;
margin: 1em auto;
}
/* Canvas sizing */
.profile-card canvas {
margin: 3em 0;
touch-action: pan-y;
#height: auto;
max-height: 840px;
margin: 0.5em;
display: block;
object-fit: contain;
z-index: 0;
}
/* === Matches container === */
.matches-container {
display: flex;
flex-direction: column;
gap: 18px;
align-items: stretch;
width: 100%;
}
/* Top row: full width */
.best-row {
width: 100%;
}
/* Bottom row: use CSS grid for auto-equal height columns */
.bottom-row {
display: grid;
grid-template-columns: 1fr; /* mobile default: one column */
gap: 15px;
width: 100%;
justify-content: center;
#align-items: stretch;
}
/* Profile-card inside grid cells fill the cell */
.bottom-row .profile-card {
width: 100%;
height: auto;
align-items: stretch;
display: flex;
flex-direction: column;
text-align: center;
}
/* Top match card styling */
.best-card {
border: 2px solid #BFB531;
box-shadow: 0 6px 24px rgba(0,0,0,0.18);
width: 100%;
display: flex;
flex-direction: column;
}
/* Side match default layout (stacked) */
.side-match {
width: 100%;
display: flex;
flex-direction: column;
}
/* === Buttons === */
button[type="submit"],
button.magenta-button {
display: block;
margin: 16px 0;
padding: 11px 22px;
font-size: 1em;
font-weight: 700;
color: rgba(0,0,0,1);
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 10px rgba(0,0,0,0.18);
transition: background-color 0.18s ease, transform 0.12s ease;
}
button[type="submit"] { background-color: #808080; }
button[type="submit"]:hover { background-color: #FFFFFF; transform: translateY(1px); }
button[type="submit"]:active { background-color: #000000; transform: translateY(0); }
button.magenta-button { background-color: #BFB531; }
button.magenta-button:hover { background-color: #9E9928; transform: translateY(1px); }
button.magenta-button:active { background-color: #E6E66B; transform: translateY(0); }
.button-row {
display: flex;
justify-content: center;
gap: 12px;
flex-wrap: wrap;
margin: 0.5em 0;
width: 100%;
}
/* Popup hidden initially */
.popup {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.6);
z-index: 9999;
justify-content: center;
align-items: center;
}
/* Show when active */
.popup.active {
display: flex;
}
.popup-content {
background: #262626;
padding: 1.5em 0;
border-radius: 12px;
border: 2px solid #BFB531;
max-width: 500px;
width: 90%;
color: #FFF;
text-align: center;
box-shadow: 0 8px 28px rgba(0,0,0,0.5);
font-size: 2rem;
}
.glow-text {
text-shadow:
0 0 5px #BFB531,
0 0 10px #BFB531,
0 0 20px #BFB531,
0 0 40px #BFB531;
}
.glow-info {
padding-bottom: 0.25em;
text-shadow:
0 0 5px #000000,
0 0 10px #000000,
0 0 20px #000000,
0 0 40px #000000;
}
.info-text {
padding: 0.1em 0;
margin: 0.1em 0;
}
.popup-content h3 {
font-size: 3rem;
margin: 0.5em;
}
.popup-content h4 {
font-size: 2rem;
margin: 0.5em 0 0 0;
color: rgba(181,191,49,0.42);
}
.popup-content p {
font-size: 1.5rem;
margin: 0 0 1em 0;
}
/* Circle "i" info icon */
.info-icon {
display: inline-flex;
justify-content: center;
align-items: center;
width: 69px;
height: 69px;
border-radius: 50%;
background-color: rgba(191,181,49,0.25); /* golden circle */
color: #BFB531;
font-weight: bold;
cursor: pointer;
position: relative;
font-size: 42px;
}
.profile-info-icon {
width: 42px;
height: 42px;
font-size: 2rem;
}
.bottom-row .info-icon {
width: 32px; /* smaller circle */
height: 32px;
margin-right: 0;
}
.bottom-row .info-icon::before {
font-size: 24px;
}
.info-icon::before {
content: "i"; /* the actual "i" */
font-family: Arial, sans-serif;
line-height: 1;
font-weight: 900;
}
/* Hover effect */
.info-icon:hover {
background-color: #FFF;
}
.title-with-icon {
display: block;
#align-items: center;
margin: 0.25em 1em 0.25em 1em;
}
/* === Animations === */
@keyframes gradientMove {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* === Small mobile tweaks (≤600px) === */
@media (max-width: 600px) {
.profile-card {
width: 100%;
max-width: 100%;
padding: 0.5em;
margin: 0;
}
.profile-card canvas {
max-height: 360px;
}
.top-match h2, .bottom-row h2 {
font-size: 1.5rem;
}
.top-match h3, .bottom-row h3 {
font-size: 1rem;
margin: 0;
padding: 0;
}
.top-match p, .bottom-row p {
font-size: 1rem;
}
.info-block {
padding: 0.25em 2em;
margin: 0.25em;
}
.button-row {
gap: 5px;
}
button.magenta-button {
padding: 5px 10px;
}
input[type="hidden"] { display: none; }
.info-icon {
width: 32px;
height: 32px;
}
.info-icon::before {
font-size: 17px;
}
.bottom-row .info-icon {
width: 24px;
height: 24px;
}
.bottom-row .info-icon::before {
font-size: 13px;
}
.popup-content h3 {
font-size: 2rem;
margin: 0.5em;
}
.popup-content h4 {
font-size: 1.5rem;
margin: 0.5em 0 0 0;
color: rgba(181,191,49,0.42);
}
.popup-content p {
font-size: 1rem;
margin: 0 0 1em 0;
}
.cards-container {
grid-template-columns: 1fr;
align-items: center;
}
.footer p {
font-size: 0.5rem;
}
}
/* === Large screen width (≥1000px) === */
@media (min-width: 1000px) {
/* Bottom row: two equal columns */
.bottom-row {
grid-template-columns: repeat(2, 1fr);
justify-content: center;
}
/* Top card canvas larger */
.best-card canvas {
max-height: 50vh;
}
/* Side match canvas */
.bottom-row .profile-card canvas {
}
.cards-container {
grid-template-columns: repeat(2, 1fr);
align-items: center;
}
}
/* === Landscape Center Hero + Sidecards layout === */
@media only screen and (orientation: landscape) {
.aboutbody {
flex-direction: row;
align-items: flex-start;
justify-content: center;
}
.abouttextcontainer {
min-width: 500px;
}
.matches-container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* left, center, right */
gap: 20px;
align-items: start;
}
.footer {
display: flex;
justify-content: center;
left: 0;
width: 100%;
bottom: 0;
position: fixed;
}
.best-row {
grid-column: 2;
grid-row: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.best-card {
max-width: 50vw;
width: 100%;
}
.info-icon {
height: 39px;
width: 39px;
font-size: 1.5rem;
}
.title-with-icon h2 {
font-size: 2rem;
}
.top-match p {
font-size: 1.25rem;
}
.title-with-icon p {
font-size: 1.25rem;
}
.profile-card h3 {
font-size: 1.5rem;
}
/* Place children explicitly */
.best-row {
grid-column: 2;
grid-row: 1;
display: flex;
flex-direction: column;
justify-content: center;
margin: 0;
padding: 0;
}
.bottom-row {
display: contents; /* flatten so its children can go left/right */
}
#card-2 {
grid-column: 1;
grid-row: 1;
align-self: center;
}
#card-3 {
grid-column: 3;
grid-row: 1;
align-self: center;
}
/* Scale down side cards relative to the hero */
#card-2, #card-3 {
transform: scale(0.85);
}
.best-card canvas {
max-height: 39vh;
}
.profile-card canvas {
max-height: 45vh;
}
}
/* === Category Cards === */
.cards-container {
display: grid;
gap: 15px;
padding: 20px;
width: 90%;
max-width: 1000px;
margin: 0 auto;
}
.category-card {
background: rgba(0, 0, 0, 0.24);
border-radius: 10px;
padding: 20px;
text-align: center;
cursor: pointer;
border: 3px solid transparent;
transition: all 0.3s ease;
user-select: none;
position: relative;
}
.category-card.active {
border-color: #;
background: rgba(0, 0, 0, 0.69);
}
.category-card.emphasis {
border-color: #BFB531;
background: rgba(0, 0, 0, 0.69);
}
.category-card .checkmark {
position: absolute;
top: 8px;
right: 16px;
font-size: 25px;
font-weight: bold;
color: #BFB531;
opacity: 1;
}
.category-card .checkmark span {
opacity: 0.39;
}
.category-card.active .checkmark span.first {
opacity: 1;
}
.category-card.emphasis .checkmark span.first,
.category-card.emphasis .checkmark span.second {
opacity: 1;
}
/* === Confetti canvas fix === */
canvas.confetti-canvas {
display: block;
position: fixed;
top: 0;
left: 0;
width: 100% !important;
height: 100% !important;
pointer-events: none; /* dont block buttons/links */
z-index: 9999; /* stays above your charts/cards */
}