FIX: mpa, nuxt4 future, improvements in intro and services

Added mpa support, nuxt4 future compatibility, improvements in intro and services
This commit is contained in:
webfussel 2025-02-12 13:18:55 +01:00
parent 078d4bfd82
commit 9642496e5a
35 changed files with 324 additions and 172 deletions

75
app/assets/css/button.css Normal file
View file

@ -0,0 +1,75 @@
.Button {
all: unset;
transition: 250ms;
cursor: pointer;
padding: 1rem 1.5rem;
outline: 3px solid transparent;
box-shadow: 0 0 0 0 var(--color-orange);
border-radius: 99999px;
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
&.default {
background: var(--color-orange);
color: var(--color-black);
}
&.white {
background: var(--color-white);
color: var(--color-black);
}
&:hover {
outline-color: var(--color-black);
box-shadow: 0 0 0 6px var(--color-orange);
}
&.cta {
font-size: clamp(1rem, 2vw, 1.5rem);
}
}
.DualButton {
--size: 2.2rem;
display: flex;
width: 100%;
& .divider {
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-black);
color: var(--color-white);
border-radius: 9999px;
width: var(--size);
height: var(--size);
padding: var(--size);
font-size: 1.2rem;
z-index: 1;
margin-left: calc(var(--size) * -1 - 25px);
border: 2px solid var(--color-black);
}
.Button {
border: 2px solid currentColor;
}
& .Button:hover {
outline: none;
box-shadow: none;
background-color: var(--color-black);
color: var(--color-white);
border-color: var(--color-orange);
}
& .Button:first-child {
padding-right: calc(var(--size) * 2);
}
& .Button:last-child {
padding-left: calc(var(--size) * 2);
margin-left: calc(var(--size) * -1 - 25px);
}
}

View file

@ -0,0 +1,112 @@
.Customers {
& .customer-list {
display: flex;
flex-wrap: wrap;
& img {
height: 50px;
&.white {
filter: brightness(0) invert(1);
}
}
}
& .projects-list {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
& > article {
flex-grow: 1;
flex-shrink: 0;
flex-basis: clamp(350px, calc(33% - 3rem), 400px);
height: 350px;
display: grid;
overflow: hidden;
& .bg {
padding: 0;
height: 350px;
width: 100%;
& img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
& > * {
grid-column: 1;
grid-row: 1;
}
& > div {
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.88);
backdrop-filter: blur(1px);
transition: var(--transition-time);
height: 100%;
text-shadow: 0 0 5px rgba(0, 0, 0, .7);
text-align: center;
padding: 1rem;
& > main {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
max-height: 6rem;
overflow: hidden;
transition: var(--transition-time);
& .customer {
font-size: 1rem;
color: var(--color-white-transparent);
}
& .title {
margin-top: -1rem;
}
& ul {
gap: 1rem;
justify-content: center;
}
& a {
color: var(--color-orange);
&:hover {
color: var(--color-white);
}
}
}
&:hover {
backdrop-filter: blur(5px);
& > main {
max-height: 25rem;
}
}
}
}
}
}
@media (width <= 780px) {
.Customers {
& .customer-list {
align-items: center;
justify-content: center;
}
}
}

24
app/assets/css/fonts.css Normal file
View file

@ -0,0 +1,24 @@
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
font-stretch: 100%;
font-display: swap;
src: url('/fonts/opensans.woff2') format('woff2');
}
@font-face {
font-family: 'Roboto Condensed';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url('/fonts/roboto_con_reg.woff2') format('woff2');
}
@font-face {
font-family: 'Roboto Condensed';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/fonts/roboto_con_bold.woff2') format('woff2');
}

27
app/assets/css/footer.css Normal file
View file

@ -0,0 +1,27 @@
.Footer {
align-items: center;
padding: 1rem 15vw;
& .notes {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-evenly;
gap: 3rem .5rem;
}
& a:hover {
color: var(--color-orange);
}
& p {
color: var(--color-white-transparent);
white-space: nowrap;
}
& .sitemap {
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
}

252
app/assets/css/global.css Normal file
View file

@ -0,0 +1,252 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::selection {
background: var(--color-orange);
color: var(--color-black);
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar-thumb {
border-radius: 20px;
background: #b2bec3;
transition: var(--transition-time);
}
::-webkit-scrollbar-track {
border-radius: 20px;
background: rgba(0, 0, 0, 0.3);
}
::-webkit-scrollbar-corner {
border-radius: 100%;
background: #b2bec3;
}
:root {
--spacing-standard: 3rem;
--transition-time: 250ms;
--radius-standard: 4px;
--color-white: #ecf0f1;
--color-white-transparent: rgba(236, 240, 241, 0.7);
--color-black: #2a2723;
--color-black-transparent: #2a2723aa;
--color-orange: #ff9100;
--color-orange-light: #ffc36f;
--color-orange-black: #332b22;
}
html,
body {
min-height: 100vh;
width: 100vw;
}
html {
scroll-behavior: smooth;
scrollbar-gutter: auto;
overflow-y: auto;
overflow-x: hidden;
&.layer {
overflow: hidden;
}
}
body {
font-family: 'Open Sans', sans-serif;
color: var(--color-white);
background: var(--color-black);
}
.h1, .h2, .h3, .h4, .h5, .h6,
h1, h2, h3, h4, h5, h6 {
text-align: left;
font-family: 'Roboto Condensed', sans-serif;
}
h1 {
font-size: 4rem;
}
.h2,
h2,
h3 {
font-size: 1.5rem;
font-weight: bold;
}
a {
text-decoration: none;
transition: var(--transition-time);
color: var(--color-white);
}
.nowrap {
white-space: nowrap;
}
a.mail {
display: inline-flex;
align-items: center;
gap: .5rem;
color: var(--color-orange);
font-weight: bold;
& img {
filter: invert(50%) sepia(84%) saturate(868%) hue-rotate(1deg) brightness(103%) contrast(100%);
}
&:hover {
color: var(--color-orange-light);
& img {
filter: invert(72%) sepia(59%) saturate(390%) hue-rotate(343deg) brightness(102%) contrast(103%);
}
}
}
ul {
list-style: none;
display: flex;
}
span.highlight {
color: var(--color-orange);
}
span.chip {
background: var(--color-orange);
border-radius: 999px;
font-size: 1rem;
color: var(--color-black);
height: max-content;
padding: .5em 1em;
user-select: none;
}
.card {
padding: 2rem;
background: var(--color-black);
border-radius: 20px;
min-width: 300px;
flex: 1;
}
.color-icon {
filter: invert(50%) sepia(84%) saturate(868%) hue-rotate(1deg) brightness(103%) contrast(100%);
}
.content {
position: relative;
z-index: 100;
padding: 150px 15vw;
}
.full {
min-height: 100vh;
}
.margin-top {
margin-top: 3rem;
}
.margin-top-big {
margin-top: 6rem;
}
.flex-col {
display: flex;
flex-direction: column;
}
.default-gap {
gap: 3rem;
}
.z-0 {
box-shadow: 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(0, 0, 0, 0);
}
.z-1 {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
.z-2 {
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
}
.z-3 {
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
}
.z-4 {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.z-5 {
box-shadow: 0 19px 38px rgba(0, 0, 0, 0.30), 0 15px 12px rgba(0, 0, 0, 0.22);
}
.tip-container {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}
.tip-container .tip {
scale: 0;
position: absolute;
top: -3rem;
width: max-content;
border: 1px solid var(--color-white);
border-radius: 999px;
background-color: var(--color-black);
padding: .5em 1.5rem;
transition: 150ms;
}
.tip-container:hover .tip {
scale: 1;
}
.animate-up-down {
animation: up-down 1.5s ease-in-out alternate-reverse infinite;
}
@keyframes up-down {
0% {
translate: 0 -0.1rem;
}
100% {
translate: 0 0.4em;
}
}
@media (width <= 780px) {
h1, h2, h3, h4, h5, h6, p {
text-align: center;
}
}
@media (width <= 450px) {
.content {
padding: 150px 10vw;
}
}

189
app/assets/css/header.css Normal file
View file

@ -0,0 +1,189 @@
.stickyWatch {
height: 0;
}
.Header {
padding: 15px calc(15vw - 30px);
width: 100%;
background: transparent;
top: 0;
position: fixed;
z-index: 1000;
& .logo {
fill-rule: evenodd;
clip-rule: evenodd;
stroke-linecap: round;
stroke-linejoin: round;
stroke-miterlimit: 1.5;
& .fussel {
stroke: white;
fill: var(--color-black);
stroke-width: 20px;
}
& .glasses {
fill: none;
stroke: white;
stroke-width: 62px;
}
}
& strong {
font-family: 'Roboto Condensed', sans-serif;
font-size: 1.5rem;
flex: 1.5;
cursor: default;
display: flex;
align-items: center;
gap: 1rem;
& svg {
--size: 40px;
width: var(--size);
height: var(--size);
}
}
& nav {
position: relative;
font-weight: normal;
font-size: 1.2rem;
display: flex;
justify-content: space-between;
align-items: center;
& .active {
color: var(--color-orange);
}
}
& > .wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px 22px;
transition: 750ms;
backdrop-filter: blur(10px);
border-radius: 0;
& > label {
display: none;
width: 30px;
height: 25px;
position: relative;
transform: rotate(0deg);
transition: var(--transition-time) ease-in-out;
cursor: pointer;
z-index: 20000;
& > span {
display: block;
position: absolute;
height: 5px;
width: 100%;
background: var(--color-white);
border-radius: 9px;
opacity: 1;
left: 0;
transform: rotate(0deg);
transition: .25s ease-in-out;
&:nth-child(1) {
top: 0;
}
&:nth-child(2), &:nth-child(3) {
top: 9px;
}
&:nth-child(4) {
top: 18px;
}
}
}
& > input[type="checkbox"]:checked + label span:nth-child(1) {
top: 18px;
width: 0;
left: 50%;
}
& > input[type="checkbox"]:checked + label span:nth-child(2) {
transform: rotate(45deg);
}
& > input[type="checkbox"]:checked + label span:nth-child(3) {
transform: rotate(-45deg);
}
& > input[type="checkbox"]:checked + label span:nth-child(4) {
top: 18px;
width: 0;
left: 50%;
}
}
&.sticks > .wrapper {
background: var(--color-black-transparent);
border-radius: 20px;
}
& input[type="checkbox"] {
display: none;
}
& ul {
gap: var(--spacing-standard);
transform: scale(1);
& a {
display: block;
text-align: center;
&:hover {
transform: scale(1.15);
color: var(--color-orange);
}
}
}
}
@media screen and (width < 1180px) {
.Header {
& > .wrapper.wrapper > label {
display: block;
}
& input[type="checkbox"]:checked ~ nav {
transform: translateX(-15vw);
}
& nav {
background: var(--color-black);
position: absolute;
overflow: hidden;
height: 100vh;
width: 100vw;
top: -15px;
transition: var(--transition-time);
transform: translateX(100%);
color: var(--color-white);
flex-direction: column;
& ul {
flex-direction: column;
justify-content: center;
height: 100vh;
gap: 8vh;
& li {
font-size: clamp(1rem, 10vw, 3rem);
}
}
}
}
}

82
app/assets/css/intro.css Normal file
View file

@ -0,0 +1,82 @@
.Intro {
background-image: radial-gradient(circle at -50vw -50vh, rgba(255,145,0,0.2) 0%, rgba(0,0,0,0) 63%, rgba(0,0,0,0) 100%);
background-repeat: no-repeat;
display: grid;
grid-template-columns: 1fr 1fr;
& .intro-img {
width: 750px;
display: flex;
position: absolute;
bottom: 0;
right: 0;
& img {
transition: 250ms;
position: relative;
width: 100%;
}
}
.intro-text {
height: 100%;
justify-content: center;
z-index: 1;
& h1 {
position: relative;
& .dot {
position: relative;
right: 1rem;
}
& small {
position: absolute;
font-size: 1.5rem;
rotate: -30deg;
translate: -30px -20px;
&:before {
content: '(';
}
&:after {
content: ')';
}
}
}
& .fulltext {
color: var(--color-white);
}
}
}
@media (width <= 430px) {
.Intro {
& .intro-img{
width: 430px;
}
}
}
@media (width < 900px) {
.Intro {
grid-template-columns: 1fr;
& .intro-text, & .intro-img {
grid-column-start: 1;
}
& .intro-text,
& h1 {
align-items: center;
text-align: center;
}
& .intro-img img {
filter: brightness(.5);
}
}
}

41
app/assets/css/person.css Normal file
View file

@ -0,0 +1,41 @@
.Person {
flex-basis: clamp(350px, calc(33% - 3rem), 500px);
flex-grow: 1;
flex-shrink: 0;
align-items: center;
justify-content: stretch;
gap: 1rem;
& img {
outline: 4px solid var(--color-orange);
border-radius: 50%;
width: 150px;
height: 150px;
object-fit: cover;
}
& span {
font-family: 'Roboto Condensed', sans-serif;
font-weight: bold;
&:not(:last-child):after {
content: " | "
}
}
& p {
text-align: center;
white-space: pre-wrap;
&:first-of-type {
margin-top: -1rem;
}
}
& .flavour {}
& .button {
margin-top: auto;
}
}

View file

@ -0,0 +1,72 @@
.Services {
background-image: radial-gradient(circle at 100vw 100vh, rgba(255,145,0,0.2) 0%, rgba(0,0,0,0) 63%, rgba(0,0,0,0) 100%);
background-color: var(--color-orange-black);
background-repeat: no-repeat;
.service-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-template-rows: repeat(4, auto);
& article {
grid-row: span 4;
display: grid;
grid-template-rows: subgrid;
position: relative;
& .chip {
position: absolute;
right: -1rem;
top: calc(-1rem - 3px);
}
& header {
display: flex;
}
& ul {
gap: 1rem;
& li {
display: flex;
align-items: center;
gap: 1rem;
}
}
& .extra {
margin-top: auto;
}
}
}
.network-list {
width: 100%;
overflow-x: auto;
padding-top: 4px;
& .scroll-container {
display: flex;
padding-bottom: 3rem;
}
}
}
@media (width < 1423px) {
.Services {
& .service-list article:last-child {
grid-column: 1/-1;
}
}
}
@media (width < 600px) {
.Services {
& .network-list {
--height: 380px;
& article {
flex-basis: 70vw;
}
}
}
}

20
app/assets/css/skills.css Normal file
View file

@ -0,0 +1,20 @@
.Skills {
background: var(--color-orange-black);
background-image: radial-gradient(circle at 90vw 0, rgba(255,145,0,0.2) 0%, rgba(0,0,0,0) 63%, rgba(0,0,0,0) 100%);
background-repeat: no-repeat;
& .skill-list {
display: flex;
flex-wrap: wrap;
}
& .tech-list ul {
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
& .bottom {
align-items: center;
}
}

View file

@ -0,0 +1,16 @@
.Technology {
position: relative;
align-items: center;
&.s img {
height: 15px;
}
&.m img {
height: 30px;
}
&.l img {
height: 50px;
}
}