diff --git a/apps/web/src/app/(auth)/login/page.tsx b/apps/web/src/app/(auth)/login/page.tsx index b1d788f..5284daa 100644 --- a/apps/web/src/app/(auth)/login/page.tsx +++ b/apps/web/src/app/(auth)/login/page.tsx @@ -43,11 +43,16 @@ export default function LoginPage() { className="hidden md:flex md:flex-1 items-center justify-center" style={{ backgroundColor: BRAND_YELLOW }} > -
- -

- {t('branding.tagline')} -

+
+
diff --git a/apps/web/src/components/brand/tessera-logo.test.tsx b/apps/web/src/components/brand/tessera-logo.test.tsx index e23ebbf..48e24f3 100644 --- a/apps/web/src/components/brand/tessera-logo.test.tsx +++ b/apps/web/src/components/brand/tessera-logo.test.tsx @@ -46,11 +46,36 @@ describe('TesseraLogo', () => { expect(screen.getByText('Tessera')).toBeInTheDocument(); }); - it('variant "stacked" renders the img-role mark and the visible wordmark text', () => { - render(); + it('renders no tagline unless one is passed', () => { + render(); - expect(screen.getByRole('img', { name: 'Tessera Logo' })).toBeInTheDocument(); - expect(screen.getByText('Tessera')).toBeInTheDocument(); + // Hand-geschriebener Erwartungstext, bewusst NICHT aus derselben Quelle + // gebildet, aus der die Komponente ihn zoege. + expect( + screen.queryByText('Modulare Workflow-Plattform fuer Ihr Unternehmen'), + ).not.toBeInTheDocument(); + }); + + it('places mark, wordmark and tagline in that document order when a tagline is passed', () => { + render( + , + ); + + const mark = screen.getByRole('img', { name: 'Tessera Logo' }); + const wordmark = screen.getByText('Tessera'); + const tagline = screen.getByText( + 'Modulare Workflow-Plattform fuer Ihr Unternehmen', + ); + + expect(mark).toBeInTheDocument(); + // Node.compareDocumentPosition: DOCUMENT_POSITION_FOLLOWING === 4. + // Prueft die tatsaechliche Reihenfolge im Baum — Bildmarke vor Schriftzug, + // Schriftzug vor Untertitel — statt nur deren Vorhandensein. + expect(mark.compareDocumentPosition(wordmark) & 4).toBe(4); + expect(wordmark.compareDocumentPosition(tagline) & 4).toBe(4); }); it('enables the dark-mode plate outline class by default', () => { diff --git a/apps/web/src/components/brand/tessera-logo.tsx b/apps/web/src/components/brand/tessera-logo.tsx index 9018d26..c497c68 100644 --- a/apps/web/src/components/brand/tessera-logo.tsx +++ b/apps/web/src/components/brand/tessera-logo.tsx @@ -3,13 +3,19 @@ import { useTranslations } from 'next-intl'; import { BRAND_OLIVE, BRAND_PLATE, BRAND_YELLOW } from './brand'; -export type TesseraLogoVariant = 'mark' | 'horizontal' | 'stacked'; +export type TesseraLogoVariant = 'mark' | 'horizontal'; export interface TesseraLogoProps { /** Welche Bausteine gerendert werden. Vorgabe: `'horizontal'`. */ variant?: TesseraLogoVariant; /** Kantenlaenge der Bildmarke in Pixeln. Vorgabe: 32. */ size?: number; + /** + * Optionaler Untertitel unter dem Schriftzug, rechts neben der Bildmarke — + * die Anordnung der gelieferten Datei `tessera-logo-schriftzug.svg`. Ohne + * Angabe steht rechts nur der Name. Nur fuer `variant="horizontal"`. + */ + tagline?: string; /** * Schaltet die halbtransparente helle Kontur der Grundplatte im dunklen * Erscheinungsbild ein. Auf Flaechen, die unabhaengig vom @@ -19,8 +25,10 @@ export interface TesseraLogoProps { plateOutline?: boolean; /** Zusaetzliche Klassen fuer das aeusserste Element der gewaehlten Variante. */ className?: string; - /** Zusaetzliche Klassen fuer den Schriftzug (nur `horizontal`/`stacked`). */ + /** Zusaetzliche Klassen fuer den Schriftzug (nur `horizontal`). */ wordmarkClassName?: string; + /** Zusaetzliche Klassen fuer den Untertitel (nur zusammen mit `tagline`). */ + taglineClassName?: string; } function LogoMark({ @@ -86,9 +94,11 @@ function LogoMark({ export function TesseraLogo({ variant = 'horizontal', size = 32, + tagline, plateOutline = true, className, wordmarkClassName, + taglineClassName, }: TesseraLogoProps) { const t = useTranslations('common'); const ariaLabel = t('brand.logoAlt'); @@ -104,26 +114,21 @@ export function TesseraLogo({ ); } - if (variant === 'stacked') { - return ( - - - + // Bildmarke links, Schriftzug rechts daneben. Traegt die Komponente einen + // Untertitel, steht er unter dem Namen — dieselbe Anordnung wie in der + // gelieferten Datei `tessera-logo-schriftzug.svg`. + return ( + + + + {t('appName')} - - ); - } - - return ( - - - - {t('appName')} + {tagline ? ( + + {tagline} + + ) : null} );