mirror of
https://github.com/Such-Software/such.software.git
synced 2026-10-17 05:32:05 +02:00
feat(brand): regenerate every mark and animation from the such-graphics pack
All branding and animation assets now come from packs/such-software/pack.json
(such-graphics feat/brand-full-blast) instead of hand-maintained files:
- anim1_pulse / anim3_matrix / anim_type_v4 (both themes): regenerated with
the corrected U bowl, measured pulse timing (the hand-authored node delays
ran ~17% fast), and CSS animation with real prefers-reduced-motion support.
- clean marks, lockups (clean_*_w_text), favicons (svg + 192px png), and the
OG banner: regenerated; the OG card is the pack's 1200x630 projection.
- splash-such: rebuilt from the pack -- the old one carried the divergent U,
an off-palette cyan frame, and the pre-correction radius. Now theme-aware:
two inlined data URIs (hero-splash shows the light palette on light, the
dark palette on dark) since the pack's dark hues are tuned for near-black.
- new assets available: games_pulse (the launch arch with the rocket, wired
into /apps), morph, ambient_{atom,mesh,leaf}, favicon_dots, favicon_live,
icon-192/512 + maskable-512 (wired into manifest.json), /favicon.ico.
- animation embeds switched <img> -> <object>: Chrome freezes CSS animations
inside SVG-as-img (the old files animated because they were SMIL); an
object hosts a real SVG document where CSS animation and the
reduced-motion query both work. Verified live in Chrome.
This commit is contained in:
@@ -115,18 +115,8 @@ export default function LinksPage() {
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center mt-12 mb-6 motion-reduce:hidden">
|
||||
<img
|
||||
src="/images/animations/anim1_pulse_light.svg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className="w-20 h-20 opacity-50 block dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src="/images/animations/anim1_pulse.svg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className="w-20 h-20 opacity-50 hidden dark:block"
|
||||
/>
|
||||
<object data="/images/animations/games_pulse_light.svg" type="image/svg+xml" aria-hidden="true" className="w-20 h-20 opacity-50 block dark:hidden pointer-events-none"></object>
|
||||
<object data="/images/animations/games_pulse.svg" type="image/svg+xml" aria-hidden="true" className="w-20 h-20 opacity-50 hidden dark:block pointer-events-none"></object>
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
|
||||
@@ -30,18 +30,8 @@ export default function BlogPage() {
|
||||
|
||||
{/* Animated accent */}
|
||||
<div className="flex justify-center mb-12 motion-reduce:hidden">
|
||||
<img
|
||||
src="/images/animations/anim_type_v4_light.svg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className="w-24 h-24 opacity-60 block dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src="/images/animations/anim_type_v4.svg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className="w-24 h-24 opacity-60 hidden dark:block"
|
||||
/>
|
||||
<object data="/images/animations/anim_type_v4_light.svg" type="image/svg+xml" aria-hidden="true" className="w-24 h-24 opacity-60 block dark:hidden pointer-events-none"></object>
|
||||
<object data="/images/animations/anim_type_v4.svg" type="image/svg+xml" aria-hidden="true" className="w-24 h-24 opacity-60 hidden dark:block pointer-events-none"></object>
|
||||
</div>
|
||||
|
||||
{posts.length === 0 ? (
|
||||
|
||||
@@ -58,7 +58,7 @@ const structuredData = {
|
||||
"@type": "Organization",
|
||||
name: "Such Software LLC",
|
||||
url: "https://such.software",
|
||||
logo: "https://such.software/images/branding/clean_dark_w_text.svg",
|
||||
logo: "https://such.software/images/branding/icon-512.png",
|
||||
description: "E-commerce infrastructure, custom app development, and accessible web applications. Engineered for scale, compliance, and performance.",
|
||||
address: {
|
||||
"@type": "PostalAddress",
|
||||
|
||||
@@ -159,18 +159,8 @@ export default function ProductsPage() {
|
||||
<ProductsGrid products={products} />
|
||||
|
||||
<div className="flex justify-center mt-16 motion-reduce:hidden">
|
||||
<img
|
||||
src="/images/animations/anim3_matrix_light.svg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className="w-20 h-20 opacity-40 block dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src="/images/animations/anim3_matrix.svg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className="w-20 h-20 opacity-50 hidden dark:block"
|
||||
/>
|
||||
<object data="/images/animations/anim3_matrix_light.svg" type="image/svg+xml" aria-hidden="true" className="w-20 h-20 opacity-40 block dark:hidden pointer-events-none"></object>
|
||||
<object data="/images/animations/anim3_matrix.svg" type="image/svg+xml" aria-hidden="true" className="w-20 h-20 opacity-50 hidden dark:block pointer-events-none"></object>
|
||||
</div>
|
||||
</div>
|
||||
<MobileNav />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import Link from "next/link";
|
||||
import { ChevronDown, LayoutGrid, Smartphone, Wrench, Info } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { SPLASH_LOGO_SRC } from "./splash-logo-data";
|
||||
import { SPLASH_LOGO_SRC_DARK, SPLASH_LOGO_SRC_LIGHT } from "./splash-logo-data";
|
||||
|
||||
const navButtons = [
|
||||
{ label: "Portfolio", href: "/products", Icon: LayoutGrid, corner: "left-4 top-6 sm:left-6 sm:top-24 lg:left-8 lg:top-32" },
|
||||
@@ -179,10 +179,17 @@ export function HeroSplash({ onEnter, sectionRef, leaving }: { onEnter: () => vo
|
||||
{/* Data URI (no network request) so the logo paints with FCP; it is the
|
||||
mobile LCP element. */}
|
||||
<img
|
||||
src={SPLASH_LOGO_SRC}
|
||||
src={SPLASH_LOGO_SRC_LIGHT}
|
||||
alt="Such Software"
|
||||
fetchPriority="high"
|
||||
className="h-auto w-[min(72vw,42vh)]"
|
||||
className="h-auto w-[min(72vw,42vh)] dark:hidden"
|
||||
/>
|
||||
<img
|
||||
src={SPLASH_LOGO_SRC_DARK}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
fetchPriority="high"
|
||||
className="hidden h-auto w-[min(72vw,42vh)] dark:block"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// AUTO-GENERATED from public/images/branding/splash-such.svg.
|
||||
// Inlined as a data URI so the splash logo (the homepage LCP element) needs no
|
||||
// network request and paints with first contentful paint. Regenerate if the
|
||||
// mark changes.
|
||||
export const SPLASH_LOGO_SRC =
|
||||
"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20200%20200%22%20role%3D%22img%22%20aria-label%3D%22Such%20Software%22%3E%3Cdefs%3E%3Cfilter%20id%3D%22splash-glow%22%20x%3D%22-30%25%22%20y%3D%22-30%25%22%20width%3D%22160%25%22%20height%3D%22160%25%22%3E%3CfeGaussianBlur%20stdDeviation%3D%221.6%22%20result%3D%22b%22%2F%3E%3CfeMerge%3E%3CfeMergeNode%20in%3D%22b%22%2F%3E%3CfeMergeNode%20in%3D%22SourceGraphic%22%2F%3E%3C%2FfeMerge%3E%3C%2Ffilter%3E%3C%2Fdefs%3E%3Crect%20x%3D%2214%22%20y%3D%2214%22%20width%3D%22172%22%20height%3D%22172%22%20rx%3D%2216%22%20fill%3D%22none%22%20stroke%3D%22%2322d3ee%22%20stroke-width%3D%223.5%22%20filter%3D%22url%28%23splash-glow%29%22%20opacity%3D%220.45%22%2F%3E%3Cg%20fill%3D%22none%22%20stroke-width%3D%2214%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M%2078%2C36%20H%2036%20V%2058%20H%2078%20V%2082%20H%2036%22%20stroke%3D%22%2335c98e%22%2F%3E%3Cpath%20d%3D%22m%20118%2C36%20v%2034%20c%200%2C12.15%209.85%2C14%2022%2C14%2012.15%2C0%2022%2C-1.85%2022%2C-14%20V%2036%22%20stroke%3D%22%23e8689e%22%2F%3E%3Cpath%20d%3D%22M%2078%2C118%20H%2036%20V%20164%20H%2078%22%20stroke%3D%22%234aade0%22%2F%3E%3Cpath%20d%3D%22M%20118%2C118%20V%20164%20M%20162%2C118%20V%20164%20M%20118%2C141%20H%20162%22%20stroke%3D%22%2345c99e%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E";
|
||||
// AUTO-GENERATED from packs/such-software/pack.json (such-graphics).
|
||||
// Inlined as data URIs so the splash logo (the homepage LCP element) needs no
|
||||
// network request and paints with first contentful paint. Two theme variants:
|
||||
// the pack's dark hues are the light hues lifted for contrast on near-black,
|
||||
// so each ground gets the palette that was tuned for it. Regenerate from the
|
||||
// pack if the mark changes; public/images/branding/splash-such.svg mirrors
|
||||
// the dark variant for anything that hotlinks it.
|
||||
export const SPLASH_LOGO_SRC_DARK =
|
||||
"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20200%20200%22%20role%3D%22img%22%20aria-label%3D%22Such%20Software%22%3E%3Cdefs%3E%3Cfilter%20id%3D%22splash-glow%22%20x%3D%22-30%25%22%20y%3D%22-30%25%22%20width%3D%22160%25%22%20height%3D%22160%25%22%3E%3CfeGaussianBlur%20stdDeviation%3D%221.6%22%20result%3D%22b%22%2F%3E%3CfeMerge%3E%3CfeMergeNode%20in%3D%22b%22%2F%3E%3CfeMergeNode%20in%3D%22SourceGraphic%22%2F%3E%3C%2FfeMerge%3E%3C%2Ffilter%3E%3C%2Fdefs%3E%3Crect%20x%3D%2214%22%20y%3D%2214%22%20width%3D%22172%22%20height%3D%22172%22%20rx%3D%2212%22%20fill%3D%22none%22%20stroke%3D%22%2345c99e%22%20stroke-width%3D%223.5%22%20filter%3D%22url%28%23splash-glow%29%22%20opacity%3D%220.45%22%2F%3E%3Cg%20fill%3D%22none%22%20stroke-width%3D%2214%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M%2078%2C36%20H%2036%20V%2058%20H%2078%20V%2082%20H%2036%22%20stroke%3D%22%2335925c%22%20transform%3D%22translate%283%2C0%29%22%2F%3E%3Cpath%20d%3D%22m%20118%2C36%20v%2034%20c%200%2C12.15%209.85%2C13%2022%2C13%2012.15%2C0%2022%2C-3.1%2022%2C-13%20V%2036%22%20stroke%3D%22%23e8689e%22%20transform%3D%22translate%28-3%2C0%29%22%2F%3E%3Cpath%20d%3D%22M%2078%2C118%20H%2036%20V%20164%20H%2078%22%20stroke%3D%22%234aade0%22%20transform%3D%22translate%283%2C0%29%22%2F%3E%3Cpath%20d%3D%22M%20118%2C118%20V%20164%20M%20162%2C118%20V%20164%20M%20118%2C141%20H%20162%22%20stroke%3D%22%233ad4c6%22%20transform%3D%22translate%28-3%2C0%29%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E";
|
||||
export const SPLASH_LOGO_SRC_LIGHT =
|
||||
"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20200%20200%22%20role%3D%22img%22%20aria-label%3D%22Such%20Software%22%3E%3Cdefs%3E%3Cfilter%20id%3D%22splash-glow%22%20x%3D%22-30%25%22%20y%3D%22-30%25%22%20width%3D%22160%25%22%20height%3D%22160%25%22%3E%3CfeGaussianBlur%20stdDeviation%3D%221.6%22%20result%3D%22b%22%2F%3E%3CfeMerge%3E%3CfeMergeNode%20in%3D%22b%22%2F%3E%3CfeMergeNode%20in%3D%22SourceGraphic%22%2F%3E%3C%2FfeMerge%3E%3C%2Ffilter%3E%3C%2Fdefs%3E%3Crect%20x%3D%2214%22%20y%3D%2214%22%20width%3D%22172%22%20height%3D%22172%22%20rx%3D%2212%22%20fill%3D%22none%22%20stroke%3D%22%231a5c38%22%20stroke-width%3D%223.5%22%20filter%3D%22url%28%23splash-glow%29%22%20opacity%3D%220.45%22%2F%3E%3Cg%20fill%3D%22none%22%20stroke-width%3D%2214%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M%2078%2C36%20H%2036%20V%2058%20H%2078%20V%2082%20H%2036%22%20stroke%3D%22%231a5c38%22%20transform%3D%22translate%283%2C0%29%22%2F%3E%3Cpath%20d%3D%22m%20118%2C36%20v%2034%20c%200%2C12.15%209.85%2C13%2022%2C13%2012.15%2C0%2022%2C-3.1%2022%2C-13%20V%2036%22%20stroke%3D%22%23b83670%22%20transform%3D%22translate%28-3%2C0%29%22%2F%3E%3Cpath%20d%3D%22M%2078%2C118%20H%2036%20V%20164%20H%2078%22%20stroke%3D%22%23176a92%22%20transform%3D%22translate%283%2C0%29%22%2F%3E%3Cpath%20d%3D%22M%20118%2C118%20V%20164%20M%20162%2C118%20V%20164%20M%20118%2C141%20H%20162%22%20stroke%3D%22%2312857e%22%20transform%3D%22translate%28-3%2C0%29%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E";
|
||||
|
||||
@@ -99,7 +99,7 @@ export function articleLd(opts: { title: string; description: string; slug: stri
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "Such Software",
|
||||
logo: { "@type": "ImageObject", url: `${SITE}/images/branding/clean_dark_w_text.svg` },
|
||||
logo: { "@type": "ImageObject", url: `${SITE}/images/branding/icon-512.png` },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user