1
0

feat: Implement Services, About, and start Values section

This commit is contained in:
2026-02-11 18:03:24 +01:00
parent 9dde6f8b1c
commit 050522d035
11 changed files with 451 additions and 11 deletions
+35 -6
View File
@@ -2,10 +2,9 @@
@import url("../styles/poppins.css");
:root {
--font-sans:
"Poppins", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
sans-serif;
--font-sans: "Poppins", system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
"Helvetica Neue", sans-serif;
/* --fs-md: clamp(1.25rem, 0.25vw + 1rem, 2.5rem); */
--fs-md: 1.25rem;
@@ -17,11 +16,14 @@
--leading-paragraph: 1.5;
--tracking-narrow: -0.09375rem;
--base-grid: repeat(12, 1fr);
--max-content-width: 1920px;
--clr-light-400: hsl(0 10% 100%);
--clr-dark-400: hsl(0 17.6% 3.3%);
--clr-ts-warm-red-400: hsl(3 94% 60%);
--gradient-heading: linear-gradient(
--gradient-page-title: linear-gradient(
to bottom,
hsl(from var(--clr-light-400) h s l),
hsl(from var(--clr-light-400) h s calc(l - 10)),
@@ -31,6 +33,22 @@
hsl(from var(--clr-light-400) h s calc(l - 40)),
hsl(from var(--clr-light-400) h s calc(l - 80))
);
--gradient-heading: linear-gradient(
to bottom,
hsl(from var(--clr-light-400) h s l),
hsl(from var(--clr-light-400) h s calc(l - 10)),
hsl(from var(--clr-light-400) h s calc(l - 30)),
hsl(from var(--clr-light-400) h s calc(l - 80)),
hsl(from var(--clr-light-400) h s calc(l - 90))
);
--gradient-overlay: linear-gradient(
to bottom,
rgba(0, 0, 0, 0.3) 0%,
rgba(0, 0, 0, 0) 40%,
rgba(0, 0, 0, 0.3) 100%
);
}
body {
@@ -47,7 +65,18 @@
h1,
h2,
h3 {
h3,
h4 {
font-weight: 600;
}
h1 {
background: var(--gradient-page-title);
background-clip: text;
color: transparent;
}
h2 {
background: var(--gradient-heading);
background-clip: text;
color: transparent;
+107
View File
@@ -0,0 +1,107 @@
---
import AboutImage from "../../assets/img/about.jpg";
import { Picture } from "astro:assets";
---
<Fragment>
<div class="about">
<h2>
<span>Creative.</span>
<span>Innovative.</span>
<span>Authentic.</span>
</h2>
<div class="text">
<p>
Based in the beautiful city of Vienna, Austria, Tideshift aims
to create long lasting partnerships built on sustainable tech
and processes.
</p>
<p>
Whether you're just starting out as a business or you're an
enterprise, we will cater to your specific needs and provide
creative and tailored solutions that solve your individual
problems.
</p>
</div>
</div>
<div class="image">
<Picture
class="background"
src={AboutImage}
alt="A winding abstract form in purple and blue"
/>
<p>
Tideshift is a digital agency specializing in digital sovereignty
and innovative systems built with modern web technologies and open
source software.
</p>
</div>
</Fragment>
<style>
.about {
display: grid;
grid-template-columns: var(--base-grid);
max-width: var(--max-content-width);
margin-inline: auto;
padding-block: 8rem 5.5rem;
padding-inline: 5rem;
}
h2 {
grid-column: 1 / 6;
font-size: 4.75rem;
line-height: var(--leading-title);
letter-spacing: var(--tracking-narrow);
span {
display: block;
}
}
.text {
grid-column: -1 / -6;
font-size: 1.125rem;
line-height: var(--leading-text);
* + * {
margin-top: 1.25rem;
}
}
.image {
display: grid;
grid-template-columns: 1fr auto 1fr;
justify-content: center;
align-items: center;
margin-bottom: 8rem;
min-height: 400px;
max-height: 500px;
& picture {
display: block;
grid-column: 1 / -1;
grid-row: 1 / -1;
}
& .background {
display: block;
width: 100%;
max-width: 100%;
object-fit: cover;
}
& p {
grid-column: 2;
grid-row: 1;
max-width: 43ch;
font-size: 2rem;
line-height: var(--leading-text);
}
}
</style>
+11 -5
View File
@@ -1,12 +1,17 @@
---
import Image from "astro/components/Image.astro";
import Picture from "astro/components/Picture.astro";
import HeroImage from "../../assets/img/hero.jpg";
import ArrowDown from "../icons/ArrowDown.astro";
---
<div class="hero">
<div class="image-wrapper">
<Image class="image" src={HeroImage} alt="todo" />
<Picture
class="image"
src={HeroImage}
formats={["jpg", "jpeg", "webp"]}
alt="todo"
/>
</div>
<div class="content">
@@ -30,10 +35,11 @@ import ArrowDown from "../icons/ArrowDown.astro";
<style>
.hero {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-columns: var(--base-grid);
height: 100svh;
padding-inline: 5rem;
max-width: var(--max-content-width);
margin-inline: auto;
}
.image-wrapper {
@@ -53,9 +59,9 @@ import ArrowDown from "../icons/ArrowDown.astro";
.content {
display: grid;
row-gap: 2.25em;
grid-template-columns: subgrid;
grid-template-rows: 1fr 1fr;
row-gap: 2.25em;
grid-column: 1 / -1;
grid-row: 1;
+92
View File
@@ -0,0 +1,92 @@
---
import { Picture } from "astro:assets";
interface Props {
title: string;
image: {
src: ImageMetadata;
alt: string;
};
items: Array<string>;
}
const { title, image, items } = Astro.props;
---
<div class="card">
<Picture class="image" src={image.src} alt={image.alt} />
<h3>{title}</h3>
{
!!items.length ? (
<ul class="list">
{items.map((item) => (
<li class="item">{item}</li>
))}
</ul>
) : null
}
</div>
<style>
.card {
display: grid;
grid-template-rows: auto 1fr auto;
/* padding: 2.5rem; */
min-height: 36rem;
& > * {
grid-column: 1;
}
}
picture {
display: block;
grid-row: 1 / -1;
position: relative;
z-index: -1;
}
picture::after {
content: "";
display: block;
width: 100%;
height: 100%;
background: var(--gradient-overlay);
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.image {
display: inline-block;
width: 100%;
max-width: 100%;
height: 100%;
object-fit: cover;
}
h3 {
grid-row: 1;
font-size: 2.25rem;
line-height: var(--leading-title);
padding: 2.5rem;
max-width: 10ch;
}
ul {
display: grid;
gap: 1.25rem;
grid-row: 3;
list-style: none;
padding: 2.5rem;
}
li {
max-width: 26ch;
font-size: 1.125rem;
line-height: 1;
}
</style>
@@ -0,0 +1,99 @@
---
import type { ComponentProps } from "astro/types";
import ServicesCard from "./ServicesCard.astro";
import Image1 from "../../assets/img/services/1.jpg";
import Image2 from "../../assets/img/services/2.jpg";
import Image3 from "../../assets/img/services/3.jpg";
const services: Array<ComponentProps<typeof ServicesCard>> = [
{
title: "Innovative Solutions",
image: {
src: Image1,
alt: "A picture showing an abstract form in teal",
},
items: [
"Modern Websites",
"Specialized Web Applications",
"Cross-platform Mobile Apps",
],
},
{
title: "Tailored Designs",
image: {
src: Image2,
alt: "A picture showing an abstract form in blue/purple",
},
items: ["Webdesign", "App Design", "Brand/Identity Design"],
},
{
title: "Flexible Projects",
image: {
src: Image3,
alt: "A picture showing an abstract form in red",
},
items: ["Digital Sovereignty", "Freelancing", "Consulting"],
},
];
---
<div class="services">
<div class="heading">
<h2>Our Services.</h2>
<p>
Together as partners, we will tackle your digital challenge and turn
your vision into reality.
</p>
</div>
<ul>
{services.map((service) => <ServicesCard {...service} />)}
</ul>
</div>
<style>
.services {
display: grid;
grid-template-columns: var(--base-grid);
max-width: var(--max-content-width);
margin-inline: auto;
padding-block: 8rem;
padding-inline: 5rem;
}
.heading {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / -1;
& h2 {
grid-column: 1 / 6;
font-size: 4.75rem;
line-height: var(--leading-title);
letter-spacing: var(--tracking-narrow);
}
& p {
grid-column: -1 / -6;
justify-self: end;
max-width: 32ch;
font-size: 1.5rem;
line-height: var(--leading-text);
}
}
ul {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
grid-column: 1 / -1;
list-style: none;
margin-top: 7rem;
}
</style>
@@ -0,0 +1,98 @@
---
import { late } from "astro:schema";
const values = [
{
title: "Sustainability",
text: "Choosing Tideshift as your digital partner is a sustainable way to build your next project and keep it running. We will build your vision on open tech and support you in gaining digital sovereignty.",
},
{
title: "Collaboration",
text: "Tideshift is creative at heart and we want your projects to succeed. Iteration is a core principle of creativity and where there is a place to reinvent, there is opportunity for innovation. So feel free to help us improve - feedback and new ideas are always welcome.",
},
{
title: "Privacy",
text: "We strongly believe that individuals and businesses should be in control of their data and stay aware of what is happening with their creative work. That's why we focus on using technology and services that protect your data instead of selling it for profit.",
},
];
function formatIndex(index: number) {
return `0${index + 1}`.slice(-2);
}
---
<Fragment>
<div class="values">
<h2>Our Values.</h2>
<ul>
{
values.map((v, index) => (
<li>
{/* List is grid container */}
<div>
{/* Item title */}
<h3>{v.title}</h3>
{/* Item text */}
<p>{v.text}</p>
</div>
{/* two digit number left */}
<span>{formatIndex(index)}</span>
</li>
))
}
</ul>
</div>
</Fragment>
<style>
.values {
display: grid;
grid-template-columns: var(--base-grid);
max-width: var(--max-content-width);
margin-in line: auto;
padding-block: 8rem 5.5rem;
padding-inline: 5rem;
}
h2 {
grid-column: 1 / -1;
font-size: 4.75rem;
line-height: var(--leading-title);
letter-spacing: var(--tracking-narrow);
span {
display: block;
}
}
ul {
margin-top: 5.5rem;
list-style: none;
grid-column: 1 / -1;
}
li {
}
h3 {
font-size: 3rem;
line-height: var(--leading-title);
}
p {
margin-top: 1.875rem;
font-size: 1.5rem;
line-height: var(--leading-text);
}
span {
font-size: 15.625rem;
font-weight: 600;
line-height: 0.9;
}
</style>