Files
alpenwerk-hr/components/brand/Logo.tsx
Andrei Laas 76009d6db6
Some checks failed
CI / Lint, Typen, Tests, Build (push) Failing after 5m27s
CI / Migrationen auf leerer Datenbank (push) Has been cancelled
Update Logo component
2026-09-15 21:10:49 +02:00

86 lines
3.4 KiB
TypeScript

// Das Manner-Logo und die Wortmarke der Anwendung — an einer Stelle, weil
// Kopfleiste und Anmeldeseite dasselbe zeigen sollen.
//
// ═══ Welches Logo ═══
//
// Verwendet wird das **Markenlogo** (CD §4.1): der Schriftzug allein, ohne
// den Stephansdom-Medaillon. Das Unternehmenslogo (§3.1) waere nach §3.2 das
// formal richtige, wo „Josef Manner & Comp. AG" als Absender auftritt — es
// steht hier aber nicht zur Verfuegung.
//
// ═══ Eine Datei, zwei Faelle ═══
//
// Die Vorlage ist ein PNG mit durchsichtigem Grund: nur der Schriftzug, blau
// (#164194, der Wert aus §1.1) mit weisser Kontur, kein Feld darunter.
//
// §1.2 laesst den Schriftzug ausschliesslich zur Gaenze auf Rosa zu, und das
// Manual kennt dafuer zwei Lagen:
//
// • **In einem grossflaechigen rosa Umfeld** (§3.1) wird er „mit genuegend
// Freiraum rundum integriert" — die Flaeche ist schon da. Das ist
// `aufRosa`: nur Freiraum, kein eigener Grund.
//
// • **Auf Weiss** (§4.1) gehoert er „in ein rechteckiges rosa Feld, das den
// Regeln des Freiraums folgt". Dieses Feld zeichnet das Bauteil selbst,
// aus derselben Polsterung.
//
// Vorher lagen dafuer zwei SVG nebeneinander, eines mit eingebackenem Feld
// und eines ohne. Das war eine Datei zu viel — und die Fassung mit Feld liess
// sich auf einer rosa Flaeche nicht sauber unterbringen, weil ihr Rechteck
// sichtbar blieb, sobald ueber der Flaeche noch irgendetwas lag.
//
// Als <img> und nicht inline: der Browser holt die Datei einmal und nimmt sie
// danach aus dem Zwischenspeicher, statt sie in jeder Seitenauslieferung
// mitzuschleppen.
/** Seitenverhaeltnis der Vorlage: 1203 x 484 Pixel. */
const VERHAELTNIS = 1203 / 484;
export function MannerLogo({ hoehe = 28, className = "" }: { hoehe?: number; className?: string }) {
const breite = Math.round(hoehe * VERHAELTNIS);
// Der Freiraum nach §4.1: X/3, wobei X als Hoehe des Schriftzugs gelesen
// ist. Er steckt hier und nicht in den Aufrufstellen — sonst haengt seine
// Einhaltung daran, dass jede einzelne daran denkt.
const freiraum = Math.round(hoehe / 3);
return (
<span
style={{ padding: freiraum }}
// Ohne Eckenrundung: §4.1 spricht von einem rechteckigen Feld.
className={`inline-flex shrink-0 items-center ${aufRosa ? "" : "bg-accent-500"} ${className}`}
>
{/* next/image bringt Groessenvarianten und Ladelogik fuer Fotos mit; fuer
eine Bildmarke fester Groesse ist beides Ballast. */}
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src="/brand/manner-logo.png" alt="Manner" width={breite} height={hoehe} style={{ width: breite, height: hoehe }} />
</span>
);
}
/**
* Logo plus Produktname.
*
* Die beiden gehoeren zusammen und meinen Verschiedenes: das Logo sagt, wem
* das System gehoert, der Name sagt, was es ist.
*/
export function AppWortmarke({
hoehe = 26,
aufRosa = false,
textKlasse = "text-ink",
className = "",
}: {
hoehe?: number;
aufRosa?: boolean;
textKlasse?: string;
className?: string;
}) {
return (
// Nur ein schmaler Abstand: den Hauptteil der Trennung leistet der
// Freiraum des Logos, der ohnehin frei bleiben muss.
<span className={`flex items-center gap-2 ${className}`}>
<MannerLogo hoehe={hoehe} aufRosa={aufRosa} />
<span className={`text-base font-extrabold tracking-tight ${textKlasse}`}>Alpenwerk HR</span>
</span>
);
}