"use client"; import { useLayoutEffect, useRef, useState } from "react"; import Image from "next/image"; // Native size of the hand-drawn underline texture (icon-merke-dir-underline.png, // exported from the Figma "label-underline" node) — used as the SSR/pre-hydration // fallback width before the label's actual rendered width is measured. const UNDERLINE_NATIVE_WIDTH = 136; // Blockquote "Merke dir:" label + sparkle icon + underline (see RichText.tsx's // "quote" case). Split out as its own client component because the underline // needs to be stretched to match the label's actual rendered width — a fixed // width only ever matched the one label length it was eyeballed against, // leaving the underline too short (overflowing labels) or too long (sparse- // looking short labels) for anything else. export function QuoteLabel({ label }: { label: string }) { const labelRef = useRef(null); const [underlineWidth, setUnderlineWidth] = useState(UNDERLINE_NATIVE_WIDTH); useLayoutEffect(() => { const el = labelRef.current; if (!el) return; const measure = () => setUnderlineWidth(el.offsetWidth); measure(); const observer = new ResizeObserver(measure); observer.observe(el); return () => observer.disconnect(); }, [label]); return (
{label} {/* object-fill (not cover) — the box's height stays fixed, only the width tracks the label, so the texture stretches horizontally to match rather than getting cropped. */}
); }