Improve design

This commit is contained in:
Anders Englöf Ytterström 2025-02-06 11:34:06 +01:00
parent 2c52b9c266
commit 1fd4b6794a
7 changed files with 289 additions and 228 deletions

View file

@ -1,41 +1,31 @@
<script lang="ts"> <script lang="ts">
// import svelteLogo from "./assets/svelte.svg"; // import svelteLogo from "./assets/svelte.svg";
// import viteLogo from "/vite.svg"; // import viteLogo from "/vite.svg";
import { currentView } from "./lib/store"; import { currentView } from "./lib/store";
import Summary from "./lib/Summary.svelte"; import Summary from "./lib/Summary.svelte";
import GymProgress from "./lib/GymProgress.svelte"; import GymProgress from "./lib/GymProgress.svelte";
import CardioProgress from "./lib/CardioProgress.svelte"; import CardioProgress from "./lib/CardioProgress.svelte";
import DietProgress from "./lib/DietProgress.svelte"; import DietProgress from "./lib/DietProgress.svelte";
import Info from "./lib/Info.svelte"
</script> </script>
<div class="chrome"> <div class="chrome">
<main> {#if $currentView === 0}
{#if $currentView === 0} <Summary />
<Summary /> {/if}
{/if} {#if $currentView === 1}
{#if $currentView === 1} <GymProgress />
<GymProgress /> {/if}
{/if} {#if $currentView === 2}
{#if $currentView === 2} <CardioProgress />
<CardioProgress /> {/if}
{/if} {#if $currentView === 3}
{#if $currentView === 3} <DietProgress />
<DietProgress /> {/if}
{/if} {#if $currentView === 4}
</main> <Info />
{/if}
</div> </div>
<style> <style>
.chrome {
height: 100vh;
display: flex;
flex-direction: column-reverse;
main {
flex: 1;
overflow: auto;
text-align: center;
padding: 0.5em;
}
}
</style> </style>

View file

@ -1,11 +1,9 @@
:root { :root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; font-family: "Open Sans", Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5; line-height: 1.5;
font-weight: 400; font-weight: 400;
color-scheme: light; color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none; font-synthesis: none;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
@ -13,56 +11,109 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body { body {
margin: 0; margin: 0;
} }
h1 { main {
font-size: 3.2em; min-height: 100vh;
line-height: 1.1; display: flex;
flex-direction: column;
background-color: #e0e0e0;
box-sizing: border-box;
padding: 1em;
} }
.card { h1 {
padding: 2em; font-size: 3em;
line-height: 1.1;
margin: 1.25em 0;
text-wrap: balance;
padding-left: 0.5em;
} }
button { button {
border-radius: 8px; appearance: none;
border: 1px solid transparent; border-radius: 0;
padding: 0.6em 1.2em; border: 0;
padding: 0;
font-size: 1em; font-size: 1em;
font-weight: 500; font-weight: 500;
font-family: inherit; font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
} }
@media (prefers-color-scheme: light) { article {
:root { opacity: 0.8;
color: #213547; label {
background-color: #ffffff; display: grid;
grid-template-columns: auto 1fr;
grid-template-areas: "name name" "date input";
padding: 1em;
input {
grid-area: input;
}
strong {
grid-area: name;
}
small {
grid-area: date;
}
}
}
article:has(:checked) {
opacity: 0.25;
+ article:not(:has(:checked)) {
opacity: 1;
}
} }
a:hover {
color: #747bff; .clickable {
box-shadow: 0 3px 0 rgba(0, 0, 0, .75);
border: 2px solid #222;
border-radius: 8px;
background-color: #f1f1f1;
display: block;
&:hover, &:focus {
background-color: #e1e1e1;
} }
button {
background-color: #f9f9f9; &:active {
transform: translateY(1px);
} }
} }
.back {
background-color: #e0e0e0;
color: #000;
&:hover, &:focus {
background-color: #d0d0d0;
}
}
.calendar {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 1.75em 0.5em;
}
header {
display: flex;
padding: 1em;
gap: 0.5em;
align-items: center;
button {
padding: 0.5em 1em;
}
h1 {
font-size: 1.25em;
flex: 1;
margin: 0;
}
}

View file

@ -9,15 +9,17 @@
}; };
</script> </script>
<div> <header>
<button onclick={() => back()}>&lt;-</button> <button class="clickable back" onclick={() => back()}></button>
<h1> <h1>
Cardio {done}/{remaining} Cardio {done}/{remaining}
</h1> </h1>
<progress max={remaining} value={done}></progress> </header>
<main>
<progress hidden max={remaining} value={done}></progress>
<div class="calendar"> <div class="calendar">
{#each $cardio as col, i} {#each $cardio as col, i}
<article> <article class="clickable">
<label> <label>
<input type="checkbox" bind:checked={col.completed} /> <input type="checkbox" bind:checked={col.completed} />
<strong <strong
@ -30,42 +32,14 @@
</article> </article>
{/each} {/each}
</div> </div>
</div> </main>
<style> <style>
.calendar { main {
display: grid; background-color: #5dc5f8;
grid-template-columns: 1fr 1fr 1fr; border-top: 4px solid rgba(0, 0, 0, 0.2)
gap: 0.5em 0.25em;
} }
article {
border: 2px solid #aaa;
border-radius: 7px;
label {
display: grid;
grid-template-columns: auto 1fr;
grid-template-areas: "input name" "input date";
padding: 1.5em;
input {
grid-area: input;
}
strong {
grid-area: name;
}
small {
grid-area: date;
}
}
}
article:has(:checked) {
border-color: #080;
background-color: #afa;
}
article:nth-child(1) { article:nth-child(1) {
grid-column: 2; grid-column: 2;
} }

View file

@ -6,13 +6,22 @@
const back = () => { const back = () => {
currentView.update((_) => 0); currentView.update((_) => 0);
}; };
const M = ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
const dm = (date) => {
const d = new Date(date)
return `${d.getDate()} ${M[d.getMonth()]}`
}
</script> </script>
<div> <header>
<button onclick={() => back()}>&lt;-</button> <button class="clickable back" onclick={() => back()}></button>
<h1> <h1>
Diet {done}/{dayscount} Diet {done}/{dayscount}
</h1> </h1>
</header>
<main>
<ul> <ul>
<li title="Nothing except meals.">Stop snacking.</li> <li title="Nothing except meals.">Stop snacking.</li>
<li <li
@ -33,11 +42,11 @@
<p> <p>
-- <a href="https://www.youtube.com/watch?v=fB_ESE2XwOU">Alan Thrall</a> -- <a href="https://www.youtube.com/watch?v=fB_ESE2XwOU">Alan Thrall</a>
</p> </p>
<progress max={dayscount} value={done}></progress> <progress max={dayscount} hidden value={done}></progress>
<div class="calendar"> <div class="calendar">
{#each $diet.days as day, i} {#each $diet.days as day, i}
<article> <article class="clickable">
{#if day.date in $diet.reds} {#if day.date in $diet.reds}
<div class="red"> <div class="red">
{$diet.reds[day.date]} {$diet.reds[day.date]}
@ -45,25 +54,35 @@
{:else} {:else}
<label> <label>
<input type="checkbox" bind:checked={day.completed} /> <input type="checkbox" bind:checked={day.completed} />
{day.date} {dm(day.date)}
</label> </label>
{/if} {/if}
</article> </article>
{/each} {/each}
</div> </div>
</div> </main>
<style> <style>
main {
background-color: #35d450;
border-top: 4px solid rgba(0, 0, 0, 0.2)
}
.calendar { .calendar {
display: flex; grid-template-columns: repeat(7, 1fr);
flex-direction: column;
gap: 0.5em 0.25em;
} }
.red { .red {
background: #ddd; background: #ddd;
color: #888; color: #888;
padding: 1.5em; padding: 0.75em;
overflow: hidden;
font-size: 6px;
}
article:has(.red) {
pointer-events: none;
opacity: 0.5;
} }
ul { ul {
@ -76,33 +95,21 @@
} }
article { article {
border: 2px solid #aaa; > * {
border-radius: 7px; padding: 0.75em;
text-align: center;
label { &:first-word {
display: grid; font-size: 2em;
grid-template-columns: auto 1fr; display: block;
grid-template-areas: "input name" "input date"; }
padding: 1.5em;
input { input {
grid-area: input; position: absolute;
} opacity: 0;
strong { pointer-events: none;
grid-area: name;
}
small {
grid-area: date;
} }
} }
} }
article:has(:checked) {
border-color: #080;
background-color: #afa;
}
article:nth-child(1) {
grid-column: 3;
}
</style> </style>

View file

@ -8,15 +8,17 @@
}; };
</script> </script>
<div> <header>
<button onclick={() => back()}>&lt;-</button> <button class="clickable back" onclick={() => back()}></button>
<h1> <h1>
Gym {done}/{remaining} Gym {done}/{remaining}
</h1> </h1>
<progress max={remaining} value={done}></progress> </header>
<main>
<progress hidden max={remaining} value={done}></progress>
<div class="calendar"> <div class="calendar">
{#each $gym as col} {#each $gym as col}
<article> <article class="clickable">
<label> <label>
<input type="checkbox" bind:checked={col.completed} /> <input type="checkbox" bind:checked={col.completed} />
<strong>{col.name}</strong> <strong>{col.name}</strong>
@ -25,40 +27,12 @@
</article> </article>
{/each} {/each}
</div> </div>
</div> </main>
<style> <style>
.calendar { main {
display: grid; background-color: #f62b5a;
grid-template-columns: 1fr 1fr 1fr; border-top: 4px solid rgba(0, 0, 0, 0.2)
gap: 0.5em 0.25em;
}
article {
border: 2px solid #aaa;
border-radius: 7px;
label {
display: grid;
grid-template-columns: auto 1fr;
grid-template-areas: "input name" "input date";
padding: 1.5em;
input {
grid-area: input;
}
strong {
grid-area: name;
}
small {
grid-area: date;
}
}
}
article:has(:checked) {
border-color: #080;
background-color: #afa;
} }
article:nth-child(1) { article:nth-child(1) {

51
src/lib/Info.svelte Normal file
View file

@ -0,0 +1,51 @@
<script lang="ts">
import { currentView } from "./store";
const back = () => {
currentView.update((_) => 0);
};
</script>
<main>
<div class="infobox">
<h1>Hej, Jag har en 40-årskris.</h1>
<p><em>Dessutom hägrar en vecka på Sweden rock festival.</em></p>
<p>Ryggen och benen behöver vara i form.</p>
<p>
För att göra träningen litet mer belönande skapades denna app för att ge mig
möjlighet att bocka i allt jag gör. Jag planerar att göra nedanstående:
</p>
<ul>
<li>Börja löpträna. Mål: 5km löpning efter 7 veckor.</li>
<li>
Återuppta styrkelyft. Mål: 11 veckors träning, med avslutande toppning och
maxsinglar.
</li>
<li>
Inleda diet. Äta fasta måltider och skippa fika, snacks, godis och
sockerläsk.
</li>
</ul>
</div>
<button class="clickable" on:click={back()}>
Tillbaka
</button>
</main>
<style>
main {
background-color: #ff0;
}
.infobox {
margin: 1em 0;
background-color: #fff;
border: 2px solid #aaa;
border-radius: 8px;
padding: 0.5em 1.5em;
}
button {
padding: 1em;
margin: 2em auto;
}
</style>

View file

@ -1,62 +1,76 @@
<script lang="ts"> <script lang="ts">
import { gym, cardio, diet, currentView } from "./store"; import { gym, cardio, diet, currentView } from "./store";
let gymProgress = $derived($gym.filter((c) => c.completed).length); let gymProgress = $derived($gym.filter((c) => c.completed).length);
let cardioProgress = $derived($cardio.filter((c) => c.completed).length); let cardioProgress = $derived($cardio.filter((c) => c.completed).length);
let dietProgress = $derived($diet.days.filter((c) => c.completed).length); let dietProgress = $derived($diet.days.filter((c) => c.completed).length);
const navigate = (v: 0 | 1 | 2 | 3) => { const navigate = (v: 0 | 1 | 2 | 3 | 4) => {
currentView.update((_) => v); currentView.update((_) => v);
}; };
</script> </script>
<div> <main>
<h1>Summary</h1> <h1>Dags att komma i form!</h1>
<ul class="cards"> <div class="cards">
<li> <button class="clickable gym" onclick={() => navigate(1)}>
<button onclick={() => navigate(1)}> <i>{gymProgress}</i> / {$gym.length} <span>gympass gjorda</span>
<i>{gymProgress}</i> / {$gym.length} <span>gympass gjorda</span> </button>
</button> <button class="clickable cardio" onclick={() => navigate(2)}>
</li> <i>{cardioProgress}</i> / {$cardio.length}
<li> <span>löppass lufsade</span>
<button onclick={() => navigate(2)}> </button>
<i>{cardioProgress}</i> / {$cardio.length} <button class="clickable diet" onclick={() => navigate(3)}>
<span>löppass lufsade</span> <i>{dietProgress}</i> / {$diet.days.length}
</button> <span>dagar på diet</span>
</li> </button>
<li> <button class="clickable info" onclick={() => navigate(4)}>
<button onclick={() => navigate(3)}> <i>?</i>
<i>{dietProgress}</i> / {$diet.days.length} </button>
<span>dagar på diet</span>
</button>
</li>
</ul>
</div> </div>
</main>
<style> <style>
.cards { .cards {
list-style: none; list-style: none;
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 1em; gap: 1em;
> li { button {
flex: 1; padding: 1.5em;
border: 2px solid #aaa;
border-radius: 5px;
padding: 0;
button { &:hover {
padding: 1em; filter: brightness(95%);
} }
i {
font-size: 2em;
font-style: normal;
}
span {
display: block;
}
}
} }
.gym {
background-color: #f62b5a;
color: #fff;
}
.cardio {
background-color: #5dc5f8;
color: #000;
}
.diet {
background-color: #35d450;
color: #fff;
}
.info {
background-color: #ff0;
color: #000;
}
i {
font-size: 2em;
font-style: normal;
}
span {
display: block;
}
}
</style> </style>