Drei Befunde aus dem Test: Logo, Geplant-Filter, Anstehend-Farben
**Das Logo auf der Anmeldeseite.** Statt des Schriftzugs stand dort der Ersatztext "Manner". Die SVG-Fassung war gueltiges XML, lag im Repository und war committet — warum sie im Betrieb nicht geladen wurde, laesst sich von hier aus nicht feststellen; dafuer braucht es die Antwort des Servers auf die URL. Statt das weiter zu raten, faellt die Angriffsflaeche weg: es gibt jetzt eine Datei, manner-logo.png, der Schriftzug mit durchsichtigem Grund. Kein XML, kein Beschnitt, kein eingebackenes Feld. Das Blau darin ist #164194, also der Wert aus §1.1. Damit verschwinden auch die zwei Fassungen. §1.2 laesst den Schriftzug nur zur Gaenze auf Rosa zu, und das Manual kennt dafuer zwei Lagen: auf Weiss gehoert er nach §4.1 in ein rechteckiges rosa Feld, in einem grossflaechigen rosa Umfeld nach §3.1 nur mit Freiraum. Beides entsteht jetzt aus derselben Datei — das Feld zeichnet das Bauteil, aus derselben Polsterung wie den Freiraum. **Der Filter "Geplant" fand Ausgetretene.** Die Ableitung pruefte den Eintritt vor dem Austritt, und wer einen Eintritt in der Zukunft hatte, galt als geplant — auch wenn der Austritt laengst verbucht war. Das trifft genau den No-Show (Migration 20260814100000): eingestellt, nie erschienen, Austritt vor dem Eintrittstag. Im Bestand sind das Zeilen mit Eintritt 01.10.2026, die der Filter mitzaehlte, waehrend die Liste daneben "Ausgetreten" anzeigte. employees.status, das die SQL-Funktion beim Austritt setzt, sagte von Anfang an das Richtige; falsch war die Ableitung in der Anwendung. Ein abgeschlossener Austritt wird jetzt zuerst geprueft: er beendet das Verhaeltnis, gleichgueltig ob der Eintritt schon war oder noch kommt. Ein Austritt, der selbst noch bevorsteht, nimmt den Eintritt nicht zurueck — wer am 01.10. anfaengt und am 31.12. aufhoert, ist heute geplant. Die SQL-Fassung in lib/employee-status-filter.ts bildet dieselbe Reihenfolge ab. Keine Migration: beide Fassungen der Regel liegen in TypeScript. In SQL wird nur der Karenz-Teil wiederholt, fuer die Fuehrungslinie, und der ist nicht betroffen. **Die vier Anstehend-Chips.** Zwei davon standen in der Markenfarbe, weil die Farbe ueber den Beschriftungstext aus der Tabelle der Protokoll-Aktionen geholt wurde — und die kennt eine andere Sprache: "Neueinstellung", nicht "Eintritt". Wer dort nicht steht, bekam den neutralen Chip. Ein Nachschlagen, das bei einem Fehlschlag still etwas Plausibles liefert, faellt eben nicht auf. Die vier haben jetzt eine eigene Zuordnung, nach dem Wert verschluesselt und nicht nach der Beschriftung: Eintritt gruen, Austritt rot, Wiedervorlage gelb, Rueckkehr violett. Tuerkis waere fuer die Rueckkehr die naheliegendere Lesart gewesen, kam gegen das Gruen des Eintritts aber nur auf dE 13.0; Violett steht mit 30.8 eindeutig daneben. Schwaechstes Paar der vier: 14.2, schwaechster Kontrast 5.49:1. Zehn Tests dazu, darunter die drei Faelle, an denen der Filter gescheitert war. Lint, Typen, Schemaabgleich, 562 Tests und der Build sind sauber. Im Browser nicht gesehen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,41 +6,35 @@
|
||||
// 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, und das Markenlogo ist die Fassung,
|
||||
// die vorliegt.
|
||||
// steht hier aber nicht zur Verfuegung.
|
||||
//
|
||||
// ═══ Freiraum ═══
|
||||
// ═══ Eine Datei, zwei Faelle ═══
|
||||
//
|
||||
// §4.1 verlangt „genuegend Freiraum rundum (X, X/3)". X ist der Modul des
|
||||
// Logos; gelesen wird er hier als seine Hoehe, der Freiraum also als ein
|
||||
// Drittel davon. Er steckt als Polsterung in diesem Bauteil und nicht in den
|
||||
// Aufrufstellen — sonst haengt die Einhaltung daran, dass jede einzelne
|
||||
// daran denkt.
|
||||
// Die Vorlage ist ein PNG mit durchsichtigem Grund: nur der Schriftzug, blau
|
||||
// (#164194, der Wert aus §1.1) mit weisser Kontur, kein Feld darunter.
|
||||
//
|
||||
// ═══ Rosa — und warum es zwei Dateien gibt ═══
|
||||
// §1.2 laesst den Schriftzug ausschliesslich zur Gaenze auf Rosa zu, und das
|
||||
// Manual kennt dafuer zwei Lagen:
|
||||
//
|
||||
// §1.2: der Schriftzug darf ausschliesslich zur Gaenze auf Rosa stehen. Das
|
||||
// Manual kennt dafuer zwei Faelle, und sie brauchen verschiedene Dateien:
|
||||
// • **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 das Logo „in ein rechteckiges rosa Feld".
|
||||
// Das ist manner-logo.svg — der Schriftzug samt seiner rosa Flaeche.
|
||||
// • **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.
|
||||
//
|
||||
// • **In einem grossflaechigen rosa Umfeld** (§3.1) wird es „mit genuegend
|
||||
// Freiraum rundum integriert" — die Flaeche ist dann schon da. Dafuer
|
||||
// gibt es manner-logo-auf-rosa.svg, den Schriftzug ohne eigenes Feld.
|
||||
// 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.
|
||||
//
|
||||
// Die zweite Fassung ist nicht nur schoener, sie ist noetig: mit Feld stand
|
||||
// auf dem rosa Panel ein Rechteck in leicht anderem Ton. Der Ton war dabei
|
||||
// derselbe — was ihn verschob, war die Lichtblende, die ueber der Panelflaeche
|
||||
// liegt und unter dem Logo endet. Ohne eigenes Feld gibt es nichts mehr, wo
|
||||
// sie enden koennte.
|
||||
//
|
||||
// Als <img> und nicht inline: die Datei holt der Browser einmal und nimmt sie
|
||||
// danach aus dem Zwischenspeicher, statt in jeder Seitenauslieferung
|
||||
// mitzureisen.
|
||||
// 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 beider Dateien: viewBox 288.6781 x 116.18912. */
|
||||
const VERHAELTNIS = 288.6781 / 116.18912;
|
||||
/** Seitenverhaeltnis der Vorlage: 1203 x 484 Pixel. */
|
||||
const VERHAELTNIS = 1203 / 484;
|
||||
|
||||
export function MannerLogo({
|
||||
hoehe = 28,
|
||||
@@ -48,26 +42,27 @@ export function MannerLogo({
|
||||
className = "",
|
||||
}: {
|
||||
hoehe?: number;
|
||||
/** Fuer rosa Untergruende: die Fassung ohne eigenes Feld. */
|
||||
/** Fuer rosa Untergruende: ohne eigenes Feld, nur mit Freiraum. */
|
||||
aufRosa?: boolean;
|
||||
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 (
|
||||
// next/image bringt Groessenvarianten und Ladelogik fuer Fotos mit; fuer
|
||||
// eine Vektordatei fester Groesse ist beides Ballast, und die
|
||||
// Bildoptimierung laesst SVG ohnehin unveraendert durch.
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={aufRosa ? "/brand/manner-logo-auf-rosa.svg" : "/brand/manner-logo.svg"}
|
||||
alt="Manner"
|
||||
width={breite}
|
||||
height={hoehe}
|
||||
// Der Freiraum nach §4.1, als Polsterung. `box-content`, damit die
|
||||
// Breite oben die des Logos bleibt und nicht die des Feldes.
|
||||
style={{ padding: Math.round(hoehe / 3), width: breite, height: hoehe }}
|
||||
className={`box-content shrink-0 ${className}`}
|
||||
/>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -89,7 +84,9 @@ export function AppWortmarke({
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<span className={`flex items-center ${className}`}>
|
||||
// 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>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
||||
import { SegmentedControl } from "@/components/ui/SegmentedControl";
|
||||
import { actionBadgeStyle } from "@/lib/colors";
|
||||
import { ANSTEHEND_STYLES } from "@/lib/colors";
|
||||
import {
|
||||
ANSTEHEND_ARTEN,
|
||||
STANDARD_ZEITRAUM,
|
||||
@@ -57,7 +57,7 @@ export function AnstehendFilter({ zeitraum, arten }: { zeitraum: Zeitraum; arten
|
||||
onClick={() => artUmschalten(a.value)}
|
||||
aria-pressed={aktiv}
|
||||
className={`rounded-full px-2 py-0.5 text-xs font-semibold focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-500 ${
|
||||
aktiv ? actionBadgeStyle(a.label) : "bg-surface text-ink-muted hover:text-ink"
|
||||
aktiv ? ANSTEHEND_STYLES[a.value] : "bg-surface text-ink-muted hover:text-ink"
|
||||
}`}
|
||||
>
|
||||
{a.label}
|
||||
|
||||
Reference in New Issue
Block a user