feat: add initial base pages and mobile-first framework
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
This project aims to create a playful online-tool to plan a date.
|
||||
In the end, there will be multiple pages that act like a choose-your-own-adventure story, where users can select different options to plan their ideal date
|
||||
|
||||
A first, i need you to create a simple, mobile-first oriented style framework
|
||||
Most users will access the tool from their mobile devices, so the design should prioritize ease of use and readability on smaller screens
|
||||
|
||||
the base color is some love-rose shade, with complementary colors that evoke warmth and romance. The typography should be clean and legible, with a focus on larger font sizes for headings and body text to enhance readability on mobile devices.
|
||||
|
||||
I want you to create a few first pages:
|
||||
- a page where the user is asked if he/she wants to go on a date with me: with a yes and a no option. when the no-option is selected, the no-button shrinks to 66% of its original size. and the yes-button grows by 33% of its original size. That behaviour happens everytime the no-button is clicked. The page should have a playful and inviting design, with a heart-shaped background.
|
||||
|
||||
- next page selects an activity for the date: options. for now its
|
||||
- Indisch essen gehen
|
||||
- Kinofilm
|
||||
- Film zu Hause + Essen bestellen
|
||||
- Walk in the forrest
|
||||
- Museum für gegenwartskunst
|
||||
- Picknick auf der Wiese
|
||||
I want the selection to display in a grid structure, each activity has a central icon / simple image
|
||||
|
||||
please create everything in german, but english code/classes/functions
|
||||
|
||||
stay at plain html/css/javascript for now. that will be later extended by a simple solution to save it somehow to a database / storage/ textfile
|
||||
@@ -0,0 +1,74 @@
|
||||
/* ==========================================================================
|
||||
Page: Aktivitäts-Auswahl (activity.html)
|
||||
========================================================================== */
|
||||
|
||||
.page-activity .intro {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.page-activity .intro p {
|
||||
color: var(--color-text-light);
|
||||
}
|
||||
|
||||
.activity-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
.activity-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.activity-card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
min-height: 140px;
|
||||
padding: 16px 10px;
|
||||
background: var(--color-white);
|
||||
border: 2px solid transparent;
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-soft);
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
|
||||
.activity-card:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.activity-card .icon {
|
||||
font-size: 2.6rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.activity-card .label {
|
||||
font-family: var(--font-heading);
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
text-align: center;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.activity-card.selected {
|
||||
border-color: var(--color-rose);
|
||||
background: linear-gradient(135deg, var(--color-rose-light) 0%, var(--color-white) 100%);
|
||||
box-shadow: var(--shadow-strong);
|
||||
}
|
||||
|
||||
.activity-card.selected::after {
|
||||
content: "✓";
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 10px;
|
||||
color: var(--color-rose-dark);
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||
<title>Wähle eure Aktivität – Date-Planer</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&family=Quicksand:wght@600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<link rel="stylesheet" href="activity.css" />
|
||||
</head>
|
||||
<body class="page-activity has-continue-bar">
|
||||
<main class="container">
|
||||
<a class="back-link" href="index.html">‹ Zurück</a>
|
||||
<div class="intro">
|
||||
<h1>Worauf hast du Lust? 🥰</h1>
|
||||
<p>Wähle eure gemeinsame Aktivität für das Date aus.</p>
|
||||
</div>
|
||||
|
||||
<div class="activity-grid" id="activityGrid"></div>
|
||||
</main>
|
||||
|
||||
<div class="continue-bar">
|
||||
<div class="container">
|
||||
<button id="continueBtn" class="btn btn-primary" type="button" disabled>Weiter</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="activity.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// Aktivitäts-Auswahl: lädt Aktivitäten aus appsettings.json, Kartenauswahl + Weiter-Button
|
||||
|
||||
(function () {
|
||||
const activityGrid = document.getElementById("activityGrid");
|
||||
const continueBtn = document.getElementById("continueBtn");
|
||||
|
||||
let selectedActivity = null;
|
||||
|
||||
fetch("appsettings.json")
|
||||
.then((response) => response.json())
|
||||
.then((settings) => renderActivities(settings.activities || []))
|
||||
.catch(() => {
|
||||
activityGrid.textContent = "Aktivitäten konnten nicht geladen werden.";
|
||||
});
|
||||
|
||||
function renderActivities(activities) {
|
||||
activities.forEach((activity) => {
|
||||
const card = document.createElement("button");
|
||||
card.type = "button";
|
||||
card.className = "activity-card";
|
||||
card.dataset.activity = activity.name;
|
||||
|
||||
const icon = document.createElement("span");
|
||||
icon.className = "icon";
|
||||
icon.setAttribute("aria-hidden", "true");
|
||||
icon.textContent = activity.icon;
|
||||
|
||||
const label = document.createElement("span");
|
||||
label.className = "label";
|
||||
label.textContent = activity.name;
|
||||
|
||||
card.append(icon, label);
|
||||
card.addEventListener("click", () => {
|
||||
activityGrid.querySelectorAll(".activity-card").forEach((c) => c.classList.remove("selected"));
|
||||
card.classList.add("selected");
|
||||
selectedActivity = activity.name;
|
||||
continueBtn.disabled = false;
|
||||
});
|
||||
|
||||
activityGrid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
continueBtn.addEventListener("click", () => {
|
||||
if (!selectedActivity) {
|
||||
return;
|
||||
}
|
||||
// Ablage für die spätere Anbindung an Datenbank/Storage
|
||||
localStorage.setItem("selectedActivity", selectedActivity);
|
||||
window.location.href = "datetime.html";
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,47 @@
|
||||
/* ==========================================================================
|
||||
Page: Frage-Seite (index.html)
|
||||
Heart-shaped decorative background
|
||||
========================================================================== */
|
||||
|
||||
body.page-ask {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.page-ask .content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
max-width: 480px;
|
||||
margin: 0 auto;
|
||||
padding: 24px 20px;
|
||||
}
|
||||
|
||||
.page-ask .question {
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.page-ask .subtitle {
|
||||
color: var(--color-text-light);
|
||||
font-size: clamp(1rem, 4vw, 1.1rem);
|
||||
margin-bottom: 2.5em;
|
||||
}
|
||||
|
||||
.page-ask .button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.page-ask .btn {
|
||||
transform-origin: center;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Frage-Seite: Ja/Nein-Interaktion
|
||||
// Der Nein-Button schrumpft und der Ja-Button wächst bei jedem Klick auf "Nein".
|
||||
|
||||
(function () {
|
||||
const yesBtn = document.getElementById("yesBtn");
|
||||
const noBtn = document.getElementById("noBtn");
|
||||
|
||||
const SHRINK_FACTOR = 0.66;
|
||||
const GROW_FACTOR = 1.33;
|
||||
const MIN_NO_SCALE = 0.12; // bleibt minimal antippbar
|
||||
const MAX_YES_SCALE = 3.2; // wird nicht größer als der Bildschirm
|
||||
|
||||
let noScale = 1;
|
||||
let yesScale = 1;
|
||||
|
||||
noBtn.addEventListener("click", () => {
|
||||
noScale = Math.max(MIN_NO_SCALE, noScale * SHRINK_FACTOR);
|
||||
yesScale = Math.min(MAX_YES_SCALE, yesScale * GROW_FACTOR);
|
||||
|
||||
noBtn.style.transform = `scale(${noScale})`;
|
||||
yesBtn.style.transform = `scale(${yesScale})`;
|
||||
});
|
||||
|
||||
yesBtn.addEventListener("click", () => {
|
||||
window.location.href = "activity.html";
|
||||
});
|
||||
})();
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||
<title>Willst du mit mir gehen? – Date-Planer</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&family=Quicksand:wght@600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<link rel="stylesheet" href="ask.css" />
|
||||
</head>
|
||||
<body class="page-ask">
|
||||
<div class="heart-background" aria-hidden="true">
|
||||
<div class="heart-shape"></div>
|
||||
</div>
|
||||
|
||||
<main class="content">
|
||||
<h1 class="question">Hättest du Lust,<br />mit mir auszugehen? 💕</h1>
|
||||
<p class="subtitle">Eine kleine Frage mit hoffentlich großer Antwort …</p>
|
||||
|
||||
<div class="button-group">
|
||||
<button id="yesBtn" class="btn btn-yes" type="button">Ja!</button>
|
||||
<button id="noBtn" class="btn btn-no" type="button">Nein</button>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script src="ask.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,204 @@
|
||||
/* ==========================================================================
|
||||
Date-Planer – Shared mobile-first stylesheet
|
||||
Base color: love-rose, complemented by warm peach and gold tones.
|
||||
========================================================================== */
|
||||
|
||||
:root {
|
||||
--color-rose: #e0577e;
|
||||
--color-rose-dark: #b83a5e;
|
||||
--color-rose-light: #ffd1dc;
|
||||
--color-peach: #ffb4a2;
|
||||
--color-gold: #ffd166;
|
||||
--color-bg: #fff5f7;
|
||||
--color-bg-gradient: linear-gradient(160deg, #fff5f7 0%, #ffe8ec 45%, #ffe3d6 100%);
|
||||
--color-text: #4a2c3d;
|
||||
--color-text-light: #7a5568;
|
||||
--color-white: #fffdfd;
|
||||
|
||||
--font-heading: "Quicksand", "Segoe UI", sans-serif;
|
||||
--font-body: "Nunito", "Segoe UI", sans-serif;
|
||||
|
||||
--radius-lg: 24px;
|
||||
--radius-md: 16px;
|
||||
--shadow-soft: 0 8px 24px rgba(184, 58, 94, 0.2);
|
||||
--shadow-strong: 0 12px 32px rgba(184, 58, 94, 0.32);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
font-family: var(--font-body);
|
||||
font-size: clamp(1rem, 3.6vw, 1.15rem);
|
||||
line-height: 1.5;
|
||||
color: var(--color-text);
|
||||
background: var(--color-bg-gradient);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
font-family: var(--font-heading);
|
||||
font-weight: 700;
|
||||
margin: 0 0 0.5em;
|
||||
color: var(--color-rose-dark);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(1.75rem, 7vw, 2.5rem);
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 480px;
|
||||
margin: 0 auto;
|
||||
padding: 24px 20px 40px;
|
||||
}
|
||||
|
||||
/* Buttons -------------------------------------------------------------- */
|
||||
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 56px;
|
||||
padding: 14px 28px;
|
||||
border: none;
|
||||
border-radius: var(--radius-lg);
|
||||
font-family: var(--font-heading);
|
||||
font-size: clamp(1.05rem, 4.5vw, 1.25rem);
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s ease, opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.btn-yes {
|
||||
background: linear-gradient(135deg, var(--color-rose) 0%, var(--color-rose-dark) 100%);
|
||||
color: var(--color-white);
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
.btn-no {
|
||||
background: var(--color-white);
|
||||
color: var(--color-text-light);
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
width: 100%;
|
||||
background: linear-gradient(135deg, var(--color-rose) 0%, var(--color-rose-dark) 100%);
|
||||
color: var(--color-white);
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
.btn-primary:disabled {
|
||||
background: #e6d3d8;
|
||||
color: #b39aa4;
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Heart-shaped decorative background (reused across pages) -------------- */
|
||||
|
||||
.heart-background {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.heart-shape {
|
||||
position: relative;
|
||||
width: 62vmin;
|
||||
height: 56vmin;
|
||||
}
|
||||
|
||||
.heart-shape::before,
|
||||
.heart-shape::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 31vmin;
|
||||
height: 50vmin;
|
||||
background: linear-gradient(135deg, var(--color-rose-light) 0%, var(--color-peach) 100%);
|
||||
border-radius: 31vmin 31vmin 0 0;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.heart-shape::before {
|
||||
left: 31vmin;
|
||||
transform: rotate(45deg);
|
||||
transform-origin: 0 100%;
|
||||
}
|
||||
|
||||
.heart-shape::after {
|
||||
left: 0;
|
||||
transform: rotate(-45deg);
|
||||
transform-origin: 100% 100%;
|
||||
}
|
||||
|
||||
/* Fixed bottom bar for a primary continue action ------------------------- */
|
||||
|
||||
body.has-continue-bar {
|
||||
padding-bottom: 96px;
|
||||
}
|
||||
|
||||
.continue-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 16px 20px calc(16px + env(safe-area-inset-bottom));
|
||||
background: linear-gradient(0deg, var(--color-bg) 60%, rgba(255, 245, 247, 0));
|
||||
}
|
||||
|
||||
.continue-bar .container {
|
||||
padding: 0;
|
||||
max-width: 480px;
|
||||
}
|
||||
|
||||
/* Back link --------------------------------------------------------------- */
|
||||
|
||||
.back-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-bottom: 12px;
|
||||
color: var(--color-text-light);
|
||||
font-family: var(--font-heading);
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Utility ---------------------------------------------------------------- */
|
||||
|
||||
.visually-hidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
white-space: nowrap;
|
||||
}
|
||||
Reference in New Issue
Block a user