QR Web
Handy ansicht und website ansicht für den Qr gemacht
This commit is contained in:
1 parent
9725e0229d
commit
c09f674653
15 files changed
+639
-103
No files matched your search
@@ -0,0 +1,129 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export interface CouponContent {
|
||||
/** Mono-Caps über dem Satz, z. B. „Ihr Messe-Special“. */
|
||||
kicker: string;
|
||||
/** Der Nachlass in Display-Ziffern, z. B. „−20“. */
|
||||
rate: string;
|
||||
/** Einheit neben der Zahl, z. B. „%“. */
|
||||
unit: string;
|
||||
/** Worauf er gilt – der eine Satz, der den Gutschein trägt. */
|
||||
on: string;
|
||||
/** Was drinsteckt. Eine Zeile je Leistung, mit goldenem Strich davor. */
|
||||
includes: readonly string[];
|
||||
/** Frist und Stichwort im Abriss unter der Perforation. */
|
||||
valid: { label: string; value: string };
|
||||
code: { label: string; value: string };
|
||||
}
|
||||
|
||||
export interface CouponProps {
|
||||
content: CouponContent;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const MONO = "font-mono text-xs tracking-[0.06em] tabular-nums";
|
||||
|
||||
/**
|
||||
* Der Grund eines Gutscheins: blasses Gold, goldene Haarlinie, runde Ecken.
|
||||
*
|
||||
* Exportiert, weil zwei Bauteile denselben Gegenstand darstellen – der große
|
||||
* Gutschein im Hero und der kleine Hinweis über dem Kontaktformular, dass der
|
||||
* Vorteil schon anhängt. Sie müssen gleich aussehen, also gibt es die Werte
|
||||
* einmal. Die runden Ecken sind die ausdrückliche Ausnahme von „Radius 0“
|
||||
* (Kundenwunsch 10.09.2026) und gelten nur für diese beiden Stellen.
|
||||
*/
|
||||
export const COUPON_SURFACE = "rounded-[14px] border border-gold-700 bg-gold-100 text-ink";
|
||||
|
||||
/**
|
||||
* Die Reißkante: gestrichelte Haarlinie über die volle Breite, an beiden Enden
|
||||
* eine Kerbe. Die Kerben sind auf die Ecke gestellte Quadrate in der Grundfarbe
|
||||
* des umgebenden Abschnitts (`bg-bg`) – sie sehen aus wie gestanzt und kommen
|
||||
* ohne einen einzigen Eckenradius aus. Auf hellem Grund elfenbein, auf dunklem
|
||||
* tintenschwarz, ganz von selbst.
|
||||
*/
|
||||
export function CouponPerforation() {
|
||||
return (
|
||||
<div aria-hidden="true" className="relative border-t border-dashed border-gold-700">
|
||||
<span className="absolute left-0 top-0 h-3.5 w-3.5 -translate-x-1/2 -translate-y-1/2 rotate-45 bg-bg" />
|
||||
<span className="absolute right-0 top-0 h-3.5 w-3.5 translate-x-1/2 -translate-y-1/2 rotate-45 bg-bg" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Der Messe-Gutschein (/her-career/, Sektion 01).
|
||||
*
|
||||
* Er soll als Gutschein erkennbar sein, ohne aus dem Haus-Stil zu fallen –
|
||||
* also kein abgerundetes Ticket mit Schatten und Fremdschrift, sondern die
|
||||
* drei Merkmale, die ein Gutschein wirklich braucht, in der Sprache der Seite:
|
||||
*
|
||||
* 0. Runde Ecken. Die einzige Stelle der Website mit einem Eckenradius
|
||||
* (Projektregel ist sonst Radius 0, ausdrückliche Ausnahme vom 10.09.2026):
|
||||
* Der Gutschein stellt einen Gegenstand dar, kein Interface-Element, und
|
||||
* ein Gutschein mit scharfen Ecken sieht aus wie eine Tabelle. Der Radius
|
||||
* bleibt auf dieses eine Bauteil beschränkt – Knöpfe, Rahmen und Tafeln
|
||||
* ringsum sind weiter eckig.
|
||||
* 1. Ein eigener Grund. `--gold-100` ist der blasse Goldton der Palette –
|
||||
* bis hierher nirgends als Fläche benutzt und damit frei für genau das
|
||||
* eine Objekt, das sich vom Elfenbein abheben soll. Die Schrift darauf ist
|
||||
* Tinte, nicht Gold: Gold auf Gold liest sich nicht, und goldene Schrift
|
||||
* bleibt ohnehin dem dunklen Grund vorbehalten.
|
||||
* 2. Eine Reißkante. Gestrichelte Haarlinie über die volle Breite, an beiden
|
||||
* Enden eine Kerbe. Die Kerben sind auf die Ecke gestellte Quadrate in der
|
||||
* Grundfarbe der Sektion – gestanzt aussehende Löcher ohne einen einzigen
|
||||
* Eckenradius.
|
||||
* 3. Ein Abriss. Unter der Kante stehen Frist und Stichwort, das Stichwort im
|
||||
* eigenen Kästchen wie ein Stempelfeld.
|
||||
*
|
||||
* Der Block steht immer auf `data-theme="light"`; die Kerben nehmen mit `bg-bg`
|
||||
* den Grund der Sektion an.
|
||||
*/
|
||||
export function Coupon({ content, className }: CouponProps) {
|
||||
const { kicker, rate, unit, on, includes, valid, code } = content;
|
||||
|
||||
return (
|
||||
<div className={cn("relative", COUPON_SURFACE, className)}>
|
||||
<div className="p-7 sm:p-12">
|
||||
<p className={cn(MONO, "uppercase tracking-[0.16em] text-gold-900")}>{kicker}</p>
|
||||
|
||||
{/* Zahl und Einheit auf einer Grundlinie; die Einheit misst sich an der Zahl. */}
|
||||
<p className="mt-5 flex items-baseline gap-[0.1em] font-display font-normal leading-[0.82] tracking-[-0.02em] [font-variant-numeric:lining-nums]">
|
||||
<span className="text-[clamp(4.5rem,2.2rem+9vw,8.5rem)]">{rate}</span>
|
||||
<span className="text-[clamp(1.75rem,1rem+3vw,3rem)]">{unit}</span>
|
||||
</p>
|
||||
|
||||
<p className="mt-6 max-w-[22ch] font-display text-[clamp(1.75rem,1.35rem+1.5vw,2.75rem)] font-normal leading-[1.08] tracking-[-0.01em] [text-wrap:balance]">
|
||||
{on}
|
||||
</p>
|
||||
|
||||
{/* Dieselben Schienen wie <Facts variant="stack"/>: Strich | Text. */}
|
||||
<ul className={cn(MONO, "mt-9 grid gap-y-3")}>
|
||||
{includes.map((item) => (
|
||||
<li key={item} className="grid grid-cols-[1.5rem_1fr] gap-x-3">
|
||||
<span aria-hidden="true" className="mt-[0.55em] h-px w-6 self-start bg-gold-900" />
|
||||
<span>{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<CouponPerforation />
|
||||
|
||||
{/* Der Abriss: Frist links, Stichwort rechts im Stempelfeld. */}
|
||||
<dl className={cn(MONO, "flex flex-wrap items-center justify-between gap-x-10 gap-y-4 p-7 sm:px-12 sm:py-8")}>
|
||||
<div className="flex items-baseline gap-2">
|
||||
<dt className="text-gold-900">{valid.label}</dt>
|
||||
<dd>{valid.value}</dd>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<dt className="text-gold-900">{code.label}</dt>
|
||||
{/* Kein `uppercase`: „herCAREER“ ist gemischt geschrieben, Versalien
|
||||
machten daraus ein „HERCAREER“, das die Messe so nicht führt. */}
|
||||
<dd className="rounded-[6px] border border-gold-700 px-3 py-1.5 tracking-[0.14em]">{code.value}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Coupon;
|
||||
Reference in new issue
Block a user