From 9cf3ad5397ab1a7632e93439589e66c3a887aefc Mon Sep 17 00:00:00 2001 From: Wanjohi Date: Mon, 21 Jul 2025 17:55:55 +0300 Subject: [PATCH] feat(web): Add landing page --- .../src/components/astro/HeroComponent.astro | 173 ++++++++++++++++++ packages/web/src/components/solidjs/Stack.tsx | 136 ++++++++++++++ .../src/components/solidjs/index.module.css | 92 ++++++++++ packages/web/src/components/solidjs/index.ts | 1 + packages/web/src/layouts/Layout.astro | 56 +++--- packages/web/src/pages/index.astro | 33 +++- packages/web/src/styles/global.css | 12 ++ 7 files changed, 466 insertions(+), 37 deletions(-) create mode 100644 packages/web/src/components/astro/HeroComponent.astro create mode 100644 packages/web/src/components/solidjs/Stack.tsx create mode 100644 packages/web/src/components/solidjs/index.module.css create mode 100644 packages/web/src/components/solidjs/index.ts diff --git a/packages/web/src/components/astro/HeroComponent.astro b/packages/web/src/components/astro/HeroComponent.astro new file mode 100644 index 00000000..329f93fc --- /dev/null +++ b/packages/web/src/components/astro/HeroComponent.astro @@ -0,0 +1,173 @@ +--- +import { Stack } from "../solidjs/index.ts"; +--- + +
+ + +
+ +
+
+
+
+
+
+
+
+
+
+ + diff --git a/packages/web/src/components/solidjs/Stack.tsx b/packages/web/src/components/solidjs/Stack.tsx new file mode 100644 index 00000000..4d78e58a --- /dev/null +++ b/packages/web/src/components/solidjs/Stack.tsx @@ -0,0 +1,136 @@ +import { type JSX, splitProps } from "solid-js"; +import styles from "./index.module.css"; + +export interface StackProps { + stackFlex?: string; + stackDirection?: "column" | "row" | "row-reverse" | "column-reverse"; + stackAlign?: "start" | "end" | "center" | "stretch" | "baseline"; + stackJustify?: "start" | "end" | "center" | "space-between" | "space-around" | "space-evenly"; + stackPadding?: string; + smStackGap?: string; + mdStackGap?: string; + lgStackGap?: string; + xlStackGap?: string; + smStackDirection?: string; + smStackAlign?: string; + smStackJustify?: string; + smStackPadding?: string; + mdStackDirection?: string; + mdStackAlign?: string; + mdStackJustify?: string; + mdStackPadding?: string; + lgStackDirection?: string; + lgStackAlign?: string; + lgStackJustify?: string; + lgStackPadding?: string; + xlStackDirection?: string; + xlStackAlign?: string; + xlStackJustify?: string; + xlStackPadding?: string; + children?: JSX.Element | JSX.Element[]; + class?: string; +} + +const defaultProps: Omit = { + stackFlex: "initial", + stackDirection: "row", + stackAlign: "stretch", + stackJustify: "center", + stackPadding: "0px", + smStackGap: "16px", + mdStackGap: "24px", + lgStackGap: "24px", + xlStackGap: "24px", + smStackDirection: undefined, + smStackAlign: undefined, + smStackJustify: undefined, + smStackPadding: undefined, + mdStackDirection: undefined, + mdStackAlign: undefined, + mdStackJustify: undefined, + mdStackPadding: undefined, + lgStackDirection: undefined, + lgStackAlign: undefined, + lgStackJustify: undefined, + lgStackPadding: undefined, + xlStackDirection: undefined, + xlStackAlign: undefined, + xlStackJustify: undefined, + xlStackPadding: undefined, +}; + +export function Stack(props: StackProps) { + const [local, others] = splitProps({ ...defaultProps, ...props }, [ + "stackFlex", + "stackDirection", + "stackAlign", + "stackJustify", + "stackPadding", + "smStackGap", + "mdStackGap", + "lgStackGap", + "xlStackGap", + "smStackDirection", + "smStackAlign", + "smStackJustify", + "smStackPadding", + "mdStackDirection", + "mdStackAlign", + "mdStackJustify", + "mdStackPadding", + "lgStackDirection", + "lgStackAlign", + "lgStackJustify", + "lgStackPadding", + "xlStackDirection", + "xlStackAlign", + "xlStackJustify", + "xlStackPadding", + "children", + "class" + ]); + + const styleVars: Record = { + "--stack-flex": local.stackFlex, + "--stack-direction": local.stackDirection, + "--stack-align": local.stackAlign, + "--stack-justify": local.stackJustify, + "--stack-padding": local.stackPadding, + "--sm-stack-gap": local.smStackGap, + "--md-stack-gap": local.mdStackGap, + "--lg-stack-gap": local.lgStackGap, + "--xl-stack-gap": local.xlStackGap, + ...(local.smStackDirection && { "--sm-stack-direction": local.smStackDirection }), + ...(local.smStackAlign && { "--sm-stack-align": local.smStackAlign }), + ...(local.smStackJustify && { "--sm-stack-justify": local.smStackJustify }), + ...(local.smStackPadding && { "--sm-stack-padding": local.smStackPadding }), + ...(local.mdStackDirection && { "--md-stack-direction": local.mdStackDirection }), + ...(local.mdStackAlign && { "--md-stack-align": local.mdStackAlign }), + ...(local.mdStackJustify && { "--md-stack-justify": local.mdStackJustify }), + ...(local.mdStackPadding && { "--md-stack-padding": local.mdStackPadding }), + ...(local.lgStackDirection && { "--lg-stack-direction": local.lgStackDirection }), + ...(local.lgStackAlign && { "--lg-stack-align": local.lgStackAlign }), + ...(local.lgStackJustify && { "--lg-stack-justify": local.lgStackJustify }), + ...(local.lgStackPadding && { "--lg-stack-padding": local.lgStackPadding }), + ...(local.xlStackDirection && { "--xl-stack-direction": local.xlStackDirection }), + ...(local.xlStackAlign && { "--xl-stack-align": local.xlStackAlign }), + ...(local.xlStackJustify && { "--xl-stack-justify": local.xlStackJustify }), + ...(local.xlStackPadding && { "--xl-stack-padding": local.xlStackPadding }), + }; + + const styleStr = Object.entries(styleVars) + .filter(([, v]) => v !== undefined) + .map(([k, v]) => `${k}: ${v}`) + .join("; "); + + return ( +
+ {local.children} +
+ ); +} + diff --git a/packages/web/src/components/solidjs/index.module.css b/packages/web/src/components/solidjs/index.module.css new file mode 100644 index 00000000..48d2b50c --- /dev/null +++ b/packages/web/src/components/solidjs/index.module.css @@ -0,0 +1,92 @@ +.stack { + display: flex; + flex-direction: var(--stack-direction, column); + align-items: var(--stack-align, stretch); + justify-content: var(--stack-justify, flex-start); + flex: var(--stack-flex, initial); + gap: var(--stack-gap, 0); +} + +.stack_padding { + padding: var(--stack-padding, 0); +} + +@media screen and (max-width: 600px) { + .stack { + --stack-direction: var(--sm-stack-direction); + --stack-align: var(--sm-stack-align); + --stack-justify: var(--sm-stack-justify); + --stack-padding: var(--sm-stack-padding); + --stack-gap: var(--sm-stack-gap); + } +} + +@media screen and (min-width: 601px) and (max-width: 960px) { + .stack { + --stack-direction: var(--md-stack-direction, var(--sm-stack-direction)); + --stack-align: var(--md-stack-align, var(--sm-stack-align)); + --stack-justify: var(--md-stack-justify, var(--sm-stack-justify)); + --stack-padding: var(--md-stack-padding, var(--sm-stack-padding)); + --stack-gap: var(--md-stack-gap, var(--sm-stack-gap)); + } +} + +@media screen and (min-width: 961px) and (max-width: 1200px) { + .stack { + --stack-direction: var( + --lg-stack-direction, + var(--md-stack-direction, var(--sm-stack-direction)) + ); + --stack-align: var( + --lg-stack-align, + var(--md-stack-align, var(--sm-stack-align)) + ); + --stack-justify: var( + --lg-stack-justify, + var(--md-stack-justify, var(--sm-stack-justify)) + ); + --stack-padding: var( + --lg-stack-padding, + var(--md-stack-padding, var(--sm-stack-padding)) + ); + --stack-gap: var( + --lg-stack-gap, + var(--md-stack-gap, var(--sm-stack-gap)) + ); + } +} + +@media screen and (min-width: 1201px) { + .stack { + --stack-direction: var( + --xl-stack-direction, + var( + --lg-stack-direction, + var(--md-stack-direction, var(--sm-stack-direction)) + ) + ); + --stack-align: var( + --xl-stack-align, + var(--lg-stack-align, var(--md-stack-align, var(--sm-stack-align))) + ); + --stack-justify: var( + --xl-stack-justify, + var( + --lg-stack-justify, + var(--md-stack-justify, var(--sm-stack-justify)) + ) + ); + --stack-padding: var( + --xl-stack-padding, + var( + --lg-stack-padding, + var(--md-stack-padding, var(--sm-stack-padding)) + ) + ); + --stack-gap: var( + --xl-stack-gap, + var(--lg-stack-gap, var(--md-stack-gap, var(--sm-stack-gap))) + ); + } +} + diff --git a/packages/web/src/components/solidjs/index.ts b/packages/web/src/components/solidjs/index.ts new file mode 100644 index 00000000..ca947f63 --- /dev/null +++ b/packages/web/src/components/solidjs/index.ts @@ -0,0 +1 @@ +export * from "./Stack" diff --git a/packages/web/src/layouts/Layout.astro b/packages/web/src/layouts/Layout.astro index 91e14ea0..563d3228 100644 --- a/packages/web/src/layouts/Layout.astro +++ b/packages/web/src/layouts/Layout.astro @@ -1,18 +1,18 @@ --- -import '../styles/global.css'; +import "../styles/global.css"; import "@fontsource/geist-sans/400.css"; import "@fontsource/geist-sans/500.css"; import "@fontsource/geist-sans/600.css"; import "@fontsource/geist-sans/700.css"; import "@fontsource/geist-sans/800.css"; import "@fontsource/geist-sans/900.css"; -import '@fontsource-variable/geist-mono'; +import "@fontsource-variable/geist-mono"; --- - - + + - - - - - Nestri - - - + + + + + Nestri - Stream apps and games from the cloud + + - + - diff --git a/packages/web/src/pages/index.astro b/packages/web/src/pages/index.astro index 79e58d95..740670ce 100644 --- a/packages/web/src/pages/index.astro +++ b/packages/web/src/pages/index.astro @@ -1,10 +1,35 @@ --- import Layout from "../layouts/Layout.astro"; +import HeroComponent from "../components/astro/HeroComponent.astro"; --- -
-

Welcome to My Astro Site

-

This is a subtitle

-
+
+
+
+ + + +
+
+
diff --git a/packages/web/src/styles/global.css b/packages/web/src/styles/global.css index 419c858b..22a73e64 100644 --- a/packages/web/src/styles/global.css +++ b/packages/web/src/styles/global.css @@ -102,6 +102,9 @@ --color-background-100: hsl(0 0% 100%); --color-background-200: hsl(0 0% 98%); + + --color-shadow-border: 0 0 0 1px rgba(0, 0, 0, 0.08); + --color-shadow-border-small: var(--color-shadow-border), 0px 2px 2px rgba(0, 0, 0, 0.04); } .dark { @@ -206,6 +209,9 @@ --color-background-100: hsl(0 0% 4%); --color-background-200: hsl(0 0% 0%); + + --color-shadow-border: 0 0 0 1px rgba(255, 255, 255, 0.145); + --color-shadow-border-small: var(--color-shadow-border), 0px 1px 2px rgba(0, 0, 0, 0.16) } @theme { @@ -311,6 +317,12 @@ --color-background-100: var(--color-background-100); --color-background-200: var(--color-background-200); + --color-brand: rgb(255, 79, 1); + --color-brand-alpha: rgba(255, 79, 1, 0.1); + --color-shadow-border-small: var(--color-shadow-border-small); + --font-sans: "Geist Sans", sans-serif; --font-mono: "Geist Mono Variable", monospace; + + --breakpoint-mobile: 600px; }