@@ -2,6 +2,7 @@ import * as React from "react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { IconBadge } from "@/components/gebos/icon-tile"
|
||||
import { GlassNumber } from "@/components/gebos/site-assets"
|
||||
|
||||
export interface ProcessStep {
|
||||
icon?: React.ReactNode
|
||||
@@ -13,7 +14,7 @@ export interface ProcessStep {
|
||||
|
||||
/**
|
||||
* Numbered process row ("So funktioniert GebOS", steps 1–5):
|
||||
* numbered chips joined by a dotted teal line, device icon, title, copy.
|
||||
* glass numerals joined by a dotted teal line, device icon, title, copy.
|
||||
*/
|
||||
function ProcessSteps({
|
||||
steps,
|
||||
@@ -32,16 +33,14 @@ function ProcessSteps({
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="absolute inset-x-[10%] top-3.5 hidden border-t-2 border-dotted-brand lg:block"
|
||||
className="absolute inset-x-[10%] top-[17px] hidden border-t-2 border-dotted-brand lg:block"
|
||||
/>
|
||||
{steps.map((step, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="relative flex flex-col items-center gap-3 text-center"
|
||||
>
|
||||
<span className="z-10 flex size-7 items-center justify-center rounded-full bg-card text-xs font-bold text-primary shadow-pill ring-2 ring-brand-300">
|
||||
{i + 1}
|
||||
</span>
|
||||
<GlassNumber n={i + 1} className="z-10 size-9" />
|
||||
{step.media ?? (
|
||||
<IconBadge variant="outline" shape="squircle" size="xl">
|
||||
{step.icon}
|
||||
@@ -73,14 +72,12 @@ function NumberedList({
|
||||
<ol className={cn("relative flex flex-col gap-6", className)}>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="absolute top-2 bottom-2 left-3.5 border-l-2 border-dotted-brand"
|
||||
className="absolute top-2 bottom-2 left-[17px] border-l-2 border-dotted-brand"
|
||||
/>
|
||||
{steps.map((step, i) => (
|
||||
<li key={i} className="relative flex items-start gap-4">
|
||||
<span className="z-10 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary text-xs font-bold text-primary-foreground shadow-pill">
|
||||
{i + 1}
|
||||
</span>
|
||||
<div className="pt-0.5">
|
||||
<GlassNumber n={i + 1} className="z-10 size-9" />
|
||||
<div className="flex min-h-9 flex-col justify-center">
|
||||
<h3 className="text-sm font-bold text-navy">{step.title}</h3>
|
||||
{step.description ? (
|
||||
<p className="mt-0.5 text-sm leading-relaxed text-muted-foreground">
|
||||
@@ -95,7 +92,7 @@ function NumberedList({
|
||||
}
|
||||
|
||||
/**
|
||||
* Step rail on a card (Selbstinstallation, steps 1–5): numbered rings threaded
|
||||
* Step rail on a card (Selbstinstallation, steps 1–5): glass numerals threaded
|
||||
* on a solid teal rail, hairline-divided columns beneath, each an asset render
|
||||
* over title and copy. Each column draws its own half of the rail, so the run
|
||||
* ends at the first and last ring whatever the step count. Rail and dividers
|
||||
@@ -120,16 +117,14 @@ function StepRail({
|
||||
<li key={i} className="relative flex flex-col items-center">
|
||||
<span
|
||||
aria-hidden="true"
|
||||
/* rail sits on the ring's centre line (size-9 ring → 18px) */
|
||||
/* rail sits on the badge's centre line (size-9 badge → 18px) */
|
||||
className={cn(
|
||||
"absolute top-[17px] hidden h-0.5 bg-brand-300 lg:block",
|
||||
i === 0 ? "left-1/2" : "left-0",
|
||||
i === steps.length - 1 ? "right-1/2" : "right-0"
|
||||
)}
|
||||
/>
|
||||
<span className="z-10 flex size-9 items-center justify-center rounded-full bg-card text-sm font-bold text-navy ring-2 ring-brand-300">
|
||||
{i + 1}
|
||||
</span>
|
||||
<GlassNumber n={i + 1} className="z-10 size-9" />
|
||||
<div
|
||||
className={cn(
|
||||
"mt-5 flex w-full flex-1 flex-col items-center px-2 text-center",
|
||||
|
||||
@@ -447,4 +447,56 @@ function AssetRender({
|
||||
)
|
||||
}
|
||||
|
||||
export { AssetRender, icons, renders, vectors }
|
||||
/** glossy glass numerals, index 0 = "1" */
|
||||
const glassNumbers = [
|
||||
renders.glassBadge1,
|
||||
renders.glassBadge2,
|
||||
renders.glassBadge3,
|
||||
renders.glassBadge4,
|
||||
renders.glassBadge5,
|
||||
renders.glassBadge6,
|
||||
]
|
||||
|
||||
/**
|
||||
* Glass numeral for a step in an ordered list. Decorative on purpose: the
|
||||
* enclosing <ol> already carries the ordinal, so the badge is not announced a
|
||||
* second time. Only 1–6 exist as renders; a longer list falls back to the
|
||||
* numeral on a teal disc rather than losing its number.
|
||||
*/
|
||||
function GlassNumber({
|
||||
n,
|
||||
className,
|
||||
loading = "lazy",
|
||||
}: {
|
||||
n: number
|
||||
/** sizes the badge – pass a `size-*` utility */
|
||||
className?: string
|
||||
loading?: "lazy" | "eager"
|
||||
}) {
|
||||
const render = glassNumbers[n - 1]
|
||||
|
||||
if (!render) {
|
||||
return (
|
||||
<span
|
||||
className={cn(
|
||||
"flex shrink-0 items-center justify-center rounded-full bg-primary text-xs font-bold text-primary-foreground shadow-pill",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{n}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<AssetRender
|
||||
render={render}
|
||||
alt=""
|
||||
className={cn("flex shrink-0 items-center justify-center", className)}
|
||||
imgClassName="size-full"
|
||||
loading={loading}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { AssetRender, GlassNumber, icons, renders, vectors }
|
||||
|
||||
Reference in New Issue
Block a user