First custom design layout

This commit is contained in:
2026-02-24 21:07:04 +02:00
parent 151efc88fc
commit 52c1739149
8 changed files with 44 additions and 108 deletions

View File

@@ -1,92 +1,23 @@
<svg viewBox="0 0 463 383" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 128 128"
xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Cut third of a log">
<defs> <defs>
<linearGradient id="a" x1="347.737" y1="-11.816" x2="248.4" y2="478.227" gradientUnits="userSpaceOnUse"> <radialGradient id="bg" cx="1" cy="0" r="1.25">
<stop stop-color="#1593F5"/> <stop offset="0" stop-color="#C99763"/>
<stop offset="1" stop-color="#0084CE"/> <stop offset="1" stop-color="#EED5B8"/>
</linearGradient> </radialGradient>
<linearGradient id="b" x1="338.003" y1="518.992" x2="-78.452" y2="-148.902" gradientUnits="userSpaceOnUse"> <linearGradient id="wood" x1="0" y1="0" x2="1" y2="1">
<stop stop-color="#1593F5"/> <stop offset="0" stop-color="#8E4F24"/>
<stop offset="1" stop-color="#0084CE"/> <stop offset="1" stop-color="#4C250E"/>
</linearGradient>
<linearGradient id="c" x1="611.99" y1="530.235" x2="361.19" y2="80.271" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#15ABFF"/>
</linearGradient>
<linearGradient id="d" x1="167.455" y1="-262.399" x2="380.368" y2="225.387" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#79CFFF"/>
</linearGradient>
<linearGradient id="e" x1="406.927" y1="-76.821" x2="68.518" y2="392.18" gradientUnits="userSpaceOnUse">
<stop stop-color="#0057E5"/>
<stop offset="1" stop-color="#0084CE"/>
</linearGradient>
<linearGradient id="f" x1="330.245" y1="-94.545" x2="223.798" y2="199.049" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#15ABFF"/>
</linearGradient>
<linearGradient id="g" x1="463.1" y1="491.08" x2="-71.75" y2="-214.82" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#79CFFF"/>
</linearGradient>
<linearGradient id="h" x1="369.836" y1="-165.821" x2="95.393" y2="376.47" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="#79CFFF"/>
</linearGradient> </linearGradient>
</defs> </defs>
<mask id="m1" maskUnits="userSpaceOnUse" x="214" y="334" width="117" height="49" style="mask-type:luminance"> <path d="M6 6H98A24 24 0 0 1 122 30V122H30A24 24 0 0 1 6 98V6Z" fill="url(#bg)"/>
<path d="M214.285 382.848L289.742 376.963C289.742 376.963 315.548 372.759 330.696 347.817L277.399 334.926L214.285 382.848Z" fill="white"/>
</mask> <g transform="translate(48 50) rotate(-18)">
<g mask="url(#m1)"> <path d="M0 0 L56 0 A56 56 0 0 1 -28 48.5 Z" fill="url(#wood)"/>
<path d="M339.952 336.888L326.208 405.548L204.748 380.886L218.773 312.226L339.952 336.888Z" fill="url(#a)"/> <path d="M0 0 L43 0 A43 43 0 0 1 -21.5 37.24 Z" fill="#B86B34"/>
</g> <path d="M0 0 L32 0 A32 32 0 0 1 -16 27.71 Z" fill="#CD8750"/>
<path d="M0 0 L22 0 A22 22 0 0 1 -11 19.05 Z" fill="#E3A977"/>
<mask id="m2" maskUnits="userSpaceOnUse" x="45" y="206" width="286" height="147" style="mask-type:luminance"> <path d="M0 0 L8 0 A8 8 0 0 1 -4 6.93 Z" fill="#F5D1A9"/>
<path d="M109.937 206.012C87.496 207.133 45.981 211.057 45.981 211.057L226.908 342.493L268.143 352.862L330.696 348.098L148.647 216.381C148.647 216.381 134.06 206.012 113.022 206.012C111.9 206.012 111.059 206.012 109.937 206.012Z" fill="white"/>
</mask>
<g mask="url(#m2)">
<path d="M125.645 480.654L-20.219 247.209L250.751 78.22L396.895 311.665L125.645 480.654Z" fill="url(#b)"/>
</g>
<mask id="m3" maskUnits="userSpaceOnUse" x="343" y="132" width="120" height="48" style="mask-type:luminance">
<path d="M343.319 179.949L421.019 175.185C421.019 175.185 447.667 171.262 462.815 146.6L407.555 132.868L343.319 179.949Z" fill="white"/>
</mask>
<g mask="url(#m3)">
<path d="M371.65 230.674L323.122 143.798L434.483 81.863L483.011 168.74L371.65 230.674Z" fill="url(#c)"/>
</g>
<mask id="m4" maskUnits="userSpaceOnUse" x="167" y="0" width="297" height="151" style="mask-type:luminance">
<path d="M233.36 0.591C210.078 1.432 167.441 4.795 167.441 4.795L355.941 139.314L398.578 150.243L463.095 146.32L273.472 11.521C273.472 11.521 257.764 0.591 235.604 0.591C235.043 0.591 234.201 0.591 233.36 0.591Z" fill="white"/>
</mask>
<g mask="url(#m4)">
<path d="M415.689 -107.584L518.074 126.422L214.846 258.699L112.461 24.693L415.689 -107.584Z" fill="url(#d)"/>
</g>
<mask id="m5" maskUnits="userSpaceOnUse" x="0" y="210" width="267" height="173" style="mask-type:luminance">
<path d="M1.1 240.202C0.819 240.483 0.819 240.763 0.819 241.043L50.469 276.915L99.558 312.506L182.027 372.199C209.797 392.096 247.385 383.689 266.46 352.862L216.249 316.71L166.038 280.558L84.41 221.146C74.312 213.859 63.092 210.496 51.872 210.496C32.236 210.496 12.881 220.865 1.1 240.202Z" fill="white"/>
</mask>
<g mask="url(#m5)">
<path d="M352.856 272.711L175.295 518.207L-85.577 329.881L91.704 84.385L352.856 272.711Z" fill="url(#e)"/>
</g>
<mask id="m6" maskUnits="userSpaceOnUse" x="122" y="4" width="277" height="177" style="mask-type:luminance">
<path d="M123.401 33.661C123.401 33.941 123.12 34.221 122.84 34.501L174.453 71.214L226.067 107.646L311.902 168.74C340.794 189.198 379.504 181.07 398.578 150.523L346.404 113.251L294.23 76.258L208.956 15.444C198.296 7.878 186.235 4.235 174.453 4.235C154.537 4.515 135.182 14.604 123.401 33.661Z" fill="white"/>
</mask>
<g mask="url(#m6)">
<path d="M457.765 25.814L366.601 277.475L63.653 167.619L155.098 -84.043L457.765 25.814Z" fill="url(#f)"/>
</g>
<mask id="m7" maskUnits="userSpaceOnUse" x="86" y="71" width="283" height="231" style="mask-type:luminance">
<path d="M86.935 75.137L153.415 148.001C156.501 152.205 159.867 156.128 163.794 159.491L293.388 301.857L357.905 297.933C376.979 267.386 369.125 225.91 340.233 205.452L254.398 144.358L203.065 107.926L151.452 71.214L86.935 75.137Z" fill="white"/>
</mask>
<g mask="url(#m7)">
<path d="M192.967 441.7L-24.426 155.568L271.228 -68.349L488.341 217.783L192.967 441.7Z" fill="url(#g)"/>
</g>
<mask id="m8" maskUnits="userSpaceOnUse" x="76" y="75" width="228" height="227" style="mask-type:luminance">
<path d="M86.374 75.978C67.58 106.244 75.434 147.16 103.765 167.338L188.759 227.872L241.214 264.864L293.388 301.857C312.463 271.31 304.608 229.833 275.716 209.375L190.162 148.562L138.548 111.849L86.935 75.137C86.935 75.417 86.654 75.698 86.374 75.978Z" fill="white"/>
</mask>
<g mask="url(#m8)">
<path d="M404.189 121.658L262.532 400.784L-23.865 255.896L117.791 -23.51L404.189 121.658Z" fill="url(#h)"/>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 946 B

View File

@@ -1,15 +1,20 @@
@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap");
@import "tailwindcss"; @import "tailwindcss";
:root {
font-family: "Manrope", "Avenir Next", "Segoe UI", sans-serif;
}
#app { #app {
user-select: none; user-select: none;
} }
main { main {
@apply flex flex-col items-center justify-center min-h-screen bg-gray-50 gap-8 px-4; @apply flex flex-col items-center justify-center min-h-screen bg-[#EED5B8] text-[#4C250E] gap-8 px-4;
} }
h1 { h1 {
@apply uppercase text-6xl text-sky-700 font-thin; @apply uppercase text-6xl text-[#8E4F24] font-thin;
} }
button { button {

View File

@@ -6,7 +6,7 @@ export default function Counter() {
return ( return (
<button <button
class="w-52 rounded-full bg-gray-100 border-2 border-gray-300 focus:border-gray-400 py-4" class="w-52 rounded-full bg-[#F5D1A9] border-2 border-[#C99763] text-[#4C250E] focus:border-[#A56C38] hover:bg-[#EED5B8] transition-colors py-4"
onclick={() => setCount(prev => prev + 1)} onclick={() => setCount(prev => prev + 1)}
> >
{t("counter.clicks")}: {count()} {t("counter.clicks")}: {count()}

View File

@@ -16,14 +16,14 @@ export default function ErrorNotification() {
return ( return (
<Show when={typeof searchParams.error === "string" && searchParams.error} keyed> <Show when={typeof searchParams.error === "string" && searchParams.error} keyed>
{msg => ( {msg => (
<aside class="flex items-start gap-3 fixed bottom-4 left-4 max-w-sm bg-red-50 border border-red-200 rounded-xl p-4 shadow-lg z-50 transition-all duration-300 text-sm"> <aside class="flex items-start gap-3 fixed bottom-4 left-4 max-w-sm bg-[#F5D1A9] border border-[#C99763] rounded-xl p-4 shadow-lg z-50 transition-all duration-300 text-sm">
<div> <div>
<strong class="font-medium text-red-800">{t("error.title")}</strong> <strong class="font-medium text-[#4C250E]">{t("error.title")}</strong>
<p class="text-red-700 mt-1 select-text">{msg}</p> <p class="text-[#70421E] mt-1 select-text">{msg}</p>
</div> </div>
<button <button
onclick={() => setSearchParams({ error: "" })} onclick={() => setSearchParams({ error: "" })}
class="text-red-400 hover:text-red-600 transition-colors" class="text-[#A56C38] hover:text-[#4C250E] transition-colors"
> >
<X class="w-4 h-4" /> <X class="w-4 h-4" />
</button> </button>

View File

@@ -9,27 +9,27 @@ export default function Nav() {
const isAbout = useMatch(() => "/about"); const isAbout = useMatch(() => "/about");
return ( return (
<nav class="fixed top-0 left-0 w-full bg-sky-800 shadow-sm z-50 flex items-center justify-between py-3 px-4 font-medium text-sm"> <nav class="fixed top-0 left-0 w-full bg-[#70421E] shadow-sm z-50 flex items-center justify-between py-3 px-4 font-medium text-sm">
<a <a
href="/" href="/"
class={`px-3 py-2 text-sky-100 uppercase transition-colors duration-200 border-b-2 ${isHome() ? "border-sky-300 text-white" : "border-transparent hover:text-white" class={`px-3 py-2 text-[#F5D1A9] uppercase transition-colors duration-200 border-b-2 ${isHome() ? "border-[#E3A977] text-[#FFF7EE]" : "border-transparent hover:text-[#FFF7EE]"
}`} }`}
> >
{t("nav.home")} {t("nav.home")}
</a> </a>
<a <a
href="/about" href="/about"
class={`px-3 py-2 text-sky-100 uppercase transition-colors duration-200 border-b-2 ${isAbout() ? "border-sky-300 text-white" : "border-transparent hover:text-white" class={`px-3 py-2 text-[#F5D1A9] uppercase transition-colors duration-200 border-b-2 ${isAbout() ? "border-[#E3A977] text-[#FFF7EE]" : "border-transparent hover:text-[#FFF7EE]"
}`} }`}
> >
{t("nav.about")} {t("nav.about")}
</a> </a>
<div class="ml-auto flex items-center gap-2"> <div class="ml-auto flex items-center gap-2">
<div class="flex items-center gap-1 rounded-md border border-sky-700 bg-sky-700/40 p-1"> <div class="flex items-center gap-1 rounded-md border border-[#8E4F24] bg-[#8E4F24]/45 p-1">
<button <button
type="button" type="button"
onclick={() => setLanguage("fi")} onclick={() => setLanguage("fi")}
class={`px-2 py-1 text-xs rounded ${language() === "fi" ? "bg-sky-200 text-sky-900" : "text-sky-100 hover:text-white" class={`px-2 py-1 text-xs rounded ${language() === "fi" ? "bg-[#E3A977] text-[#4C250E]" : "text-[#F5D1A9] hover:text-[#FFF7EE]"
}`} }`}
> >
{t("nav.language.fi")} {t("nav.language.fi")}
@@ -37,7 +37,7 @@ export default function Nav() {
<button <button
type="button" type="button"
onclick={() => setLanguage("en")} onclick={() => setLanguage("en")}
class={`px-2 py-1 text-xs rounded ${language() === "en" ? "bg-sky-200 text-sky-900" : "text-sky-100 hover:text-white" class={`px-2 py-1 text-xs rounded ${language() === "en" ? "bg-[#E3A977] text-[#4C250E]" : "text-[#F5D1A9] hover:text-[#FFF7EE]"
}`} }`}
> >
{t("nav.language.en")} {t("nav.language.en")}
@@ -48,7 +48,7 @@ export default function Nav() {
fallback={ fallback={
<a <a
href="/login" href="/login"
class="px-4 py-2 text-sky-100 bg-sky-700 border border-sky-600 rounded-md hover:bg-sky-600 hover:text-white focus:outline-none transition-colors duration-200" class="px-4 py-2 text-[#F5D1A9] bg-[#8E4F24] border border-[#A56C38] rounded-md hover:bg-[#A56C38] hover:text-[#FFF7EE] focus:outline-none transition-colors duration-200"
> >
{t("nav.login")} {t("nav.login")}
</a> </a>
@@ -57,7 +57,7 @@ export default function Nav() {
<form action={logout} method="post"> <form action={logout} method="post">
<button <button
type="submit" type="submit"
class="px-4 py-2 text-sky-100 bg-sky-700 border border-sky-600 rounded-md hover:bg-sky-600 hover:text-white focus:outline-none transition-colors duration-200" class="px-4 py-2 text-[#F5D1A9] bg-[#8E4F24] border border-[#A56C38] rounded-md hover:bg-[#A56C38] hover:text-[#FFF7EE] focus:outline-none transition-colors duration-200"
> >
{t("nav.signOut")} {t("nav.signOut")}
</button> </button>

View File

@@ -9,7 +9,7 @@ export default function NotFound() {
{t("notFound.message")} {t("notFound.message")}
<a <a
href="/" href="/"
class="px-4 py-2 border border-gray-300 rounded-xl text-gray-700 hover:bg-gray-100 transition-colors duration-200" class="px-4 py-2 border border-[#C99763] rounded-xl text-[#70421E] hover:bg-[#F5D1A9] transition-colors duration-200"
> >
{t("notFound.goHome")} {t("notFound.goHome")}
</a> </a>

View File

@@ -10,7 +10,7 @@ export default function About() {
return ( return (
<main> <main>
<Title>{t("about.title")}</Title> <Title>{t("about.title")}</Title>
<p class="text-gray-700 text-center"> <p class="text-[#70421E] text-center">
{t("about.apiVersion")}: {t("about.apiVersion")}:
<Show when={apiVersion()} fallback={t("about.loading")}> <Show when={apiVersion()} fallback={t("about.loading")}>
{apiVersion()} {apiVersion()}

View File

@@ -34,7 +34,7 @@ function PasswordLogin() {
autocomplete="email" autocomplete="email"
placeholder="john@doe.com" placeholder="john@doe.com"
required required
class="bg-white mt-1 block w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-sky-500" class="bg-[#FFF7EE] mt-1 block w-full px-4 py-2 border border-[#C99763] rounded-md focus:outline-none focus:ring-2 focus:ring-[#A56C38]"
/> />
</label> </label>
<label for="password" class="block text-left w-full"> <label for="password" class="block text-left w-full">
@@ -47,18 +47,18 @@ function PasswordLogin() {
placeholder="••••••••" placeholder="••••••••"
minLength={6} minLength={6}
required required
class="bg-white mt-1 block w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-sky-500" class="bg-[#FFF7EE] mt-1 block w-full px-4 py-2 border border-[#C99763] rounded-md focus:outline-none focus:ring-2 focus:ring-[#A56C38]"
/> />
</label> </label>
<button <button
type="submit" type="submit"
disabled={submission.pending} disabled={submission.pending}
class="w-full px-4 py-2 bg-gradient-to-r from-sky-600 to-blue-600 text-white rounded-lg hover:from-sky-700 hover:to-blue-700 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-300 shadow-lg shadow-sky-500/25" class="w-full px-4 py-2 bg-gradient-to-r from-[#A56C38] to-[#70421E] text-[#FFF7EE] rounded-lg hover:from-[#8E4F24] hover:to-[#4C250E] focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-300 shadow-lg shadow-[#70421E]/30"
> >
{t("login.submit")} {t("login.submit")}
</button> </button>
<Show when={submission.error} keyed> <Show when={submission.error} keyed>
{({ message }) => <p class="text-red-600 mt-2 text-xs text-center">{message}</p>} {({ message }) => <p class="text-[#8E4F24] mt-2 text-xs text-center">{message}</p>}
</Show> </Show>
</form> </form>
); );