This commit is contained in:
Lars Nolden
2026-08-13 18:47:55 +02:00
parent 2c1a8ae9b5
commit 33690b30a3
30 changed files with 1070 additions and 186 deletions
@@ -0,0 +1,125 @@
import * as React from "react"
/**
* GebOS line icons drawn on the lucide grid (24×24, currentColor stroke) for
* the motifs lucide has no equivalent of. Stroke is a hair lighter than
* lucide's 2 because these render large (≈48px) in feature bands.
*/
function LineIcon({
strokeWidth = 1.6,
children,
...props
}: React.ComponentProps<"svg">) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={strokeWidth}
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
{...props}
>
{children}
</svg>
)
}
/**
* Euro glyph inside a ring: costs stay transparent and under control.
* lucide has the bare glyph only, so it is shrunk about the icon centre and
* its stroke width divided by the same factor to keep the ring's weight.
*/
function EuroCircleIcon({
strokeWidth = 1.6,
...props
}: React.ComponentProps<"svg">) {
const glyphScale = 0.52
return (
<LineIcon strokeWidth={strokeWidth} {...props}>
<circle cx="12" cy="12" r="9.6" />
<g
transform={`translate(12 12) scale(${glyphScale}) translate(-12 -12)`}
strokeWidth={Number(strokeWidth) / glyphScale}
>
<path d="M4 10h12" />
<path d="M4 14h9" />
<path d="M19 6a7.7 7.7 0 0 0-5.2-2A7.9 7.9 0 0 0 6 12c0 4.4 3.5 8 7.8 8 2 0 3.8-.8 5.2-2" />
</g>
</LineIcon>
)
}
/** Cycle arrows around a radio dot: hardware that arrives ready to run. */
function PreconfiguredIcon(props: React.ComponentProps<"svg">) {
return (
<LineIcon {...props}>
<path d="M3.2 10.13A9 9 0 0 1 20.8 10.13" />
<path d="M22.11 7.66 20.8 10.13 18.59 8.41" />
<path d="M20.8 13.87A9 9 0 0 1 3.2 13.87" />
<path d="M1.89 16.34 3.2 13.87 5.41 15.59" />
<circle cx="10" cy="12" r="1.2" fill="currentColor" stroke="none" />
<path d="M11.93 9.7A3 3 0 0 1 11.93 14.3" />
<path d="M13.41 7.94A5.3 5.3 0 0 1 13.41 16.06" />
</LineIcon>
)
}
/**
* Wrench crossed with a screwdriver: install it yourself or hand it to a
* trade. Wrench contour is lucide's, mirrored onto the "\" diagonal so the
* jaw sits top-left; the screwdriver is drawn along +x and rotated onto "/",
* nudged clear of the jaw and filled with the card surface so it reads as
* lying on top of the wrench.
*/
function CrossedToolsIcon(props: React.ComponentProps<"svg">) {
return (
<LineIcon {...props}>
<path
transform="translate(24 0) scale(-1 1)"
d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"
/>
<path
transform="rotate(-45 12 12) translate(-0.6 1.2)"
fill="var(--card)"
d="M5.7 9.9H10.4V10.5H11.8V11.25H17.6L18.3 10.95H20.4V13.05H18.3L17.6 12.75H11.8V13.5H10.4V14.1H5.7A2.1 2.1 0 0 1 5.7 9.9Z"
/>
</LineIcon>
)
}
/** Cloud with a bolt: metering data flows and is processed without anyone. */
function CloudAutomationIcon(props: React.ComponentProps<"svg">) {
return (
<LineIcon {...props}>
<path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z" />
<path d="M13.1 10.7 10.5 14.6h1.85l-.68 2.6 2.6-3.9h-1.85z" />
</LineIcon>
)
}
/** Dashboard gauge on a screen: every building and meter in one portal. */
function PortalGaugeIcon(props: React.ComponentProps<"svg">) {
return (
<LineIcon {...props}>
<rect x="4.6" y="4" width="14.8" height="13.8" rx="2.4" />
<path d="M3 20h18" />
<path d="M8.02 13.18A4 4 0 0 1 15.98 13.18" />
<path d="M12 13.6 13.89 10.9" />
<circle cx="12" cy="13.6" r="0.8" fill="currentColor" stroke="none" />
</LineIcon>
)
}
export {
CloudAutomationIcon,
CrossedToolsIcon,
EuroCircleIcon,
LineIcon,
PortalGaugeIcon,
PreconfiguredIcon,
}