{"version":3,"sources":["../../src/core/constants.ts","../../src/core/format.ts","../../src/og/generatePriceCardSVG.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"&#x20C3;\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n\tlocale: string,\n\tdecimals: number,\n\tnotation: \"standard\" | \"compact\" = \"standard\",\n): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}:${notation}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: notation === \"compact\" ? 0 : decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t\t...(notation === \"compact\" && {\n\t\t\t\tnotation: \"compact\",\n\t\t\t\tcompactDisplay: \"short\",\n\t\t\t}),\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n\n\t/**\n\t * Number notation style.\n\t * - `\"standard\"` — full digits (e.g. 1,500,000.00)\n\t * - `\"compact\"` — abbreviated (e.g. 1.5M)\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100);          // \"\\u20C3 100.00\"\n * formatDirham(1234.5);       // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true });   // \"AED 100.00\"\n * formatDirham(1500000, { notation: \"compact\" }); // \"\\u20C3 1.5M\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t\tnotation = \"standard\",\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals, notation).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\");                  // 1234.5\n * parseDirham(\"AED 100.00\");                        // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\");                  // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(/[\\u0660-\\u0669]/g, (d) =>\n\t\t\tString(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n","import { formatDirham } from \"../core/format\";\n\nconst DIRHAM_SVG_PATH =\n\t\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\";\n\nexport interface PriceCardSVGOptions {\n\tamount: number;\n\ttitle?: string;\n\tsubtitle?: string;\n\tlocale?: string;\n\tdecimals?: number;\n\tnotation?: \"standard\" | \"compact\";\n\twidth?: number;\n\theight?: number;\n\tbackground?: string;\n\ttextColor?: string;\n\taccentColor?: string;\n\tborderRadius?: number;\n}\n\n/**\n * Generate a self-contained SVG string for a shareable Dirham price card.\n *\n * Works server-side with zero dependencies on React or a browser DOM.\n * The returned SVG can be embedded in HTML meta tags, saved to a file, or\n * converted to PNG via sharp / resvg / Inkscape.\n *\n * @example\n * ```ts\n * import { generatePriceCardSVG } from \"dirham/og\";\n *\n * const svg = generatePriceCardSVG({\n *   amount: 1234.5,\n *   title: \"Total Due\",\n * });\n * // → <svg …>…</svg>\n * ```\n */\nexport function generatePriceCardSVG(options: PriceCardSVGOptions): string {\n\tconst {\n\t\tamount,\n\t\ttitle,\n\t\tsubtitle,\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tnotation = \"standard\",\n\t\twidth = 1200,\n\t\theight = 630,\n\t\tbackground = \"#0a0a0a\",\n\t\ttextColor = \"#ffffff\",\n\t\taccentColor = \"#22c55e\",\n\t\tborderRadius = 0,\n\t} = options;\n\n\tconst formatted = Number.isFinite(amount)\n\t\t? formatDirham(amount, { locale, decimals, notation, useCode: true })\n\t\t\t\t.replace(\"AED\", \"\")\n\t\t\t\t.trim()\n\t\t: \"—\";\n\n\tconst isRTL = locale.startsWith(\"ar\");\n\tconst cx = width / 2;\n\n\t// Scale elements proportionally to card size\n\tconst scale = Math.min(width / 1200, height / 630);\n\tconst fontSize = Math.round(80 * scale);\n\tconst capHeight = fontSize * 0.72;\n\tconst symbolSize = Math.round(capHeight);\n\tconst titleFontSize = Math.round(32 * scale);\n\tconst subtitleFontSize = Math.round(24 * scale);\n\tconst badgeFontSize = Math.round(14 * scale);\n\n\t// Vertical positions\n\tconst titleY = height * 0.2;\n\tconst centerY = height * 0.46;\n\tconst amountBaseline = centerY + capHeight / 2;\n\tconst subtitleY = height * 0.78;\n\n\t// Approximate the half-width of the formatted text\n\tconst avgCharWidth = fontSize * 0.48;\n\tconst textHalfWidth = (formatted.length * avgCharWidth) / 2;\n\n\t// Place symbol to the left (or right for RTL) of the text with a visible gap\n\tconst gap = Math.round(20 * scale);\n\tconst symbolLeftX = isRTL\n\t\t? cx + textHalfWidth + gap\n\t\t: cx - textHalfWidth - symbolSize - gap;\n\tconst symbolTopY = centerY - symbolSize / 2;\n\n\tconst escHtml = (s: string) =>\n\t\ts\n\t\t\t.replace(/&/g, \"&amp;\")\n\t\t\t.replace(/</g, \"&lt;\")\n\t\t\t.replace(/>/g, \"&gt;\")\n\t\t\t.replace(/\"/g, \"&quot;\");\n\n\t// Hex to RGB helper for gradient\n\tconst hexToRgb = (hex: string) => {\n\t\tconst h = hex.replace(\"#\", \"\");\n\t\treturn `${Number.parseInt(h.substring(0, 2), 16)},${Number.parseInt(h.substring(2, 4), 16)},${Number.parseInt(h.substring(4, 6), 16)}`;\n\t};\n\tconst accentRgb = hexToRgb(accentColor);\n\n\tlet svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">`;\n\n\t// Background\n\tif (borderRadius > 0) {\n\t\tsvg += `<rect width=\"${width}\" height=\"${height}\" rx=\"${borderRadius}\" fill=\"${escHtml(background)}\" />`;\n\t} else {\n\t\tsvg += `<rect width=\"${width}\" height=\"${height}\" fill=\"${escHtml(background)}\" />`;\n\t}\n\n\t// Defs: grid + radial glow + vignette\n\tsvg += \"<defs>\";\n\tsvg += `<pattern id=\"grid\" width=\"40\" height=\"40\" patternUnits=\"userSpaceOnUse\">`;\n\tsvg += `<path d=\"M 40 0 L 0 0 0 40\" fill=\"none\" stroke=\"${escHtml(textColor)}\" stroke-opacity=\"0.03\" stroke-width=\"1\"/>`;\n\tsvg += \"</pattern>\";\n\tsvg += `<radialGradient id=\"glow\" cx=\"50%\" cy=\"44%\" r=\"35%\"><stop offset=\"0%\" stop-color=\"rgb(${accentRgb})\" stop-opacity=\"0.08\"/><stop offset=\"100%\" stop-color=\"rgb(${accentRgb})\" stop-opacity=\"0\"/></radialGradient>`;\n\tsvg += `<radialGradient id=\"vignette\" cx=\"50%\" cy=\"50%\" r=\"70%\"><stop offset=\"0%\" stop-color=\"${escHtml(background)}\" stop-opacity=\"0\"/><stop offset=\"100%\" stop-color=\"${escHtml(background)}\" stop-opacity=\"0.5\"/></radialGradient>`;\n\tsvg += \"</defs>\";\n\n\t// Grid\n\tsvg += `<rect width=\"${width}\" height=\"${height}\" fill=\"url(#grid)\" />`;\n\t// Accent glow behind price area\n\tsvg += `<rect width=\"${width}\" height=\"${height}\" fill=\"url(#glow)\" />`;\n\n\t// Top accent line\n\tconst topLineW = Math.round(120 * scale);\n\tsvg += `<rect x=\"${cx - topLineW / 2}\" y=\"0\" width=\"${topLineW}\" height=\"3\" fill=\"${escHtml(accentColor)}\" opacity=\"0.5\" />`;\n\n\t// Title\n\tif (title) {\n\t\tsvg += `<text x=\"${cx}\" y=\"${titleY}\" text-anchor=\"middle\" font-family=\"system-ui, -apple-system, sans-serif\" font-size=\"${titleFontSize}\" font-weight=\"500\" fill=\"${escHtml(textColor)}\" opacity=\"0.7\">${escHtml(title)}</text>`;\n\t}\n\n\t// Dirham symbol + price\n\tconst priceGroup = isRTL ? \"rtl\" : \"ltr\";\n\tsvg += `<g direction=\"${priceGroup}\">`;\n\n\t// Dirham symbol icon — vertically centered with price text\n\tsvg += `<svg x=\"${symbolLeftX}\" y=\"${symbolTopY}\" width=\"${symbolSize}\" height=\"${symbolSize}\" viewBox=\"0 0 1000 870\">`;\n\tsvg += `<path d=\"${DIRHAM_SVG_PATH}\" fill=\"${escHtml(accentColor)}\" />`;\n\tsvg += \"</svg>\";\n\n\t// Price text\n\tsvg += `<text x=\"${cx}\" y=\"${amountBaseline}\" text-anchor=\"middle\" font-family=\"system-ui, -apple-system, sans-serif\" font-size=\"${fontSize}\" font-weight=\"700\" fill=\"${escHtml(textColor)}\" letter-spacing=\"-2\">${escHtml(formatted)}</text>`;\n\n\tsvg += \"</g>\";\n\n\t// \"AED\" badge\n\tconst badgeW = Math.round(60 * scale);\n\tconst badgeH = Math.round(28 * scale);\n\tconst badgeY = amountBaseline + Math.round(20 * scale);\n\tsvg += `<rect x=\"${cx - badgeW / 2}\" y=\"${badgeY}\" width=\"${badgeW}\" height=\"${badgeH}\" rx=\"${badgeH / 2}\" fill=\"${escHtml(accentColor)}\" opacity=\"0.15\" />`;\n\tsvg += `<text x=\"${cx}\" y=\"${badgeY + badgeH * 0.68}\" text-anchor=\"middle\" font-family=\"system-ui, -apple-system, sans-serif\" font-size=\"${badgeFontSize}\" font-weight=\"600\" fill=\"${escHtml(accentColor)}\" letter-spacing=\"2\">AED</text>`;\n\n\t// Subtitle\n\tif (subtitle) {\n\t\tsvg += `<text x=\"${cx}\" y=\"${subtitleY}\" text-anchor=\"middle\" font-family=\"system-ui, -apple-system, sans-serif\" font-size=\"${subtitleFontSize}\" font-weight=\"400\" fill=\"${escHtml(textColor)}\" opacity=\"0.45\">${escHtml(subtitle)}</text>`;\n\t}\n\n\t// Bottom branding + accent line\n\tconst bottomY = height - Math.round(36 * scale);\n\tsvg += `<text x=\"${cx}\" y=\"${bottomY}\" text-anchor=\"middle\" font-family=\"system-ui, -apple-system, sans-serif\" font-size=\"${Math.round(12 * scale)}\" font-weight=\"500\" fill=\"${escHtml(textColor)}\" opacity=\"0.15\" letter-spacing=\"4\">DIRHAM.JS.ORG</text>`;\n\tconst lineW = Math.round(80 * scale);\n\tsvg += `<rect x=\"${cx - lineW / 2}\" y=\"${height - Math.round(16 * scale)}\" width=\"${lineW}\" height=\"${Math.round(3 * scale)}\" rx=\"1.5\" fill=\"${escHtml(accentColor)}\" opacity=\"0.5\" />`;\n\n\t// Vignette overlay\n\tsvg += `<rect width=\"${width}\" height=\"${height}\" fill=\"url(#vignette)\" />`;\n\n\tsvg += \"</svg>\";\n\n\treturn svg;\n}\n"]}