@nebutra/brand 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/og/og-template.tsx"],"sourcesContent":["/**\n * Brand OG image template — props-driven, hex/rgba values only.\n *\n * IMPORTANT: Satori (used by next/og's ImageResponse) does NOT resolve\n * CSS custom properties (`var(--brand-primary)` etc.). All colors must be\n * passed as explicit hex or rgba values. The `colors` export from\n * `@nebutra/brand/metadata` is the authoritative source — callers must\n * import from there and pass the values as props. Do NOT add CSS vars here.\n *\n * Wordmark letterform GEOMETRY cannot be auto-generated from a name string.\n * The component renders the brand name as text; operators who need precise\n * wordmark letterforms must supply replacement SVGs via brand.config/assets/logo/.\n */\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface OgThemePalette {\n /** Background fill — must be explicit hex/rgba, not a CSS var */\n bg: string;\n /** Grid/rule color — rgba for transparency */\n grid: string;\n /** Primary glow color — rgba for transparency */\n glowA: string;\n /** Secondary glow color — rgba for transparency */\n glowB: string;\n /** Heading text color */\n title: string;\n /** Body/label text color — rgba for partial opacity */\n subtitle: string;\n /** Brand accent color — explicit hex */\n accent: string;\n}\n\nexport interface OgTemplateProps {\n /** Page or post title */\n title: string;\n /** Optional subtitle or description */\n subtitle?: string;\n /** Brand name to display in the eyebrow (from brand.name — no literal) */\n brandName: string;\n /** Theme palette with explicit hex/rgba values — no CSS vars */\n palette: OgThemePalette;\n}\n\n// ─── Default palettes (using brand color values, NOT var()) ──────────────────\n\n/**\n * Dark-theme palette.\n * Colors are sourced from @nebutra/brand/metadata colors object — callers\n * may import from there to keep them in sync with brand:apply changes.\n */\nexport const OG_PALETTE_DARK: OgThemePalette = {\n bg: \"#020617\", // colors.neutral[\"950\"]\n grid: \"rgba(255,255,255,0.04)\",\n glowA: \"rgba(0,51,254,0.28)\", // colors.primary[\"500\"] at 28% opacity\n glowB: \"rgba(11,241,195,0.22)\", // colors.accent[\"500\"] at 22% opacity\n title: \"#ffffff\",\n subtitle: \"rgba(255,255,255,0.72)\",\n accent: \"#0bf1c3\", // colors.accent[\"500\"]\n};\n\n/**\n * Light-theme palette.\n */\nexport const OG_PALETTE_LIGHT: OgThemePalette = {\n bg: \"#ffffff\",\n grid: \"rgba(0,0,0,0.05)\",\n glowA: \"rgba(0,51,254,0.22)\", // colors.primary[\"500\"] at 22% opacity\n glowB: \"rgba(11,241,195,0.20)\", // colors.accent[\"500\"] at 20% opacity\n title: \"#0a0a0a\",\n subtitle: \"rgba(10,10,10,0.66)\",\n accent: \"#0033fe\", // colors.primary[\"500\"]\n};\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\n/**\n * OG image template for use with Satori / next/og ImageResponse.\n *\n * @example\n * ```tsx\n * import { colors, brand } from \"@nebutra/brand/metadata\";\n * import { OgTemplate, OG_PALETTE_DARK } from \"@nebutra/brand/og\";\n * import { ImageResponse } from \"next/og\";\n *\n * return new ImageResponse(\n * <OgTemplate\n * title=\"My Page\"\n * brandName={brand.name}\n * palette={OG_PALETTE_DARK}\n * />,\n * { width: 1200, height: 630 }\n * );\n * ```\n */\nexport function OgTemplate({ title, subtitle, brandName, palette }: OgTemplateProps) {\n return (\n <div\n style={{\n height: \"100%\",\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n justifyContent: \"flex-end\",\n padding: \"80px\",\n backgroundColor: palette.bg,\n backgroundImage: `radial-gradient(ellipse 80% 50% at 50% 42%, ${palette.glowA} 0%, transparent 72%), radial-gradient(ellipse 60% 40% at 72% 70%, ${palette.glowB} 0%, transparent 75%)`,\n }}\n >\n {/* Grid overlay */}\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n backgroundImage: `linear-gradient(${palette.grid} 1px, transparent 1px), linear-gradient(90deg, ${palette.grid} 1px, transparent 1px)`,\n backgroundSize: \"48px 48px\",\n display: \"flex\",\n }}\n />\n\n {/* Brand eyebrow */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n color: palette.accent,\n fontSize: \"28px\",\n fontWeight: 600,\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n }}\n >\n {brandName}\n </div>\n\n {/* Title */}\n <div\n style={{\n display: \"flex\",\n color: palette.title,\n fontSize: \"78px\",\n fontWeight: 700,\n lineHeight: 1.05,\n letterSpacing: \"-0.02em\",\n marginTop: \"24px\",\n maxWidth: \"1040px\",\n }}\n >\n {title}\n </div>\n\n {/* Optional subtitle */}\n {subtitle ? (\n <div\n style={{\n display: \"flex\",\n color: palette.subtitle,\n fontSize: \"32px\",\n fontWeight: 400,\n lineHeight: 1.35,\n marginTop: \"20px\",\n maxWidth: \"1040px\",\n }}\n >\n {subtitle}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";AAgGI,SAcE,KAdF;AA9CG,IAAM,kBAAkC;AAAA,EAC7C,IAAI;AAAA;AAAA,EACJ,MAAM;AAAA,EACN,OAAO;AAAA;AAAA,EACP,OAAO;AAAA;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA;AACV;AAKO,IAAM,mBAAmC;AAAA,EAC9C,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,OAAO;AAAA;AAAA,EACP,OAAO;AAAA;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA;AACV;AAuBO,SAAS,WAAW,EAAE,OAAO,UAAU,WAAW,QAAQ,GAAoB;AACnF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,SAAS;AAAA,QACT,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,SAAS;AAAA,QACT,iBAAiB,QAAQ;AAAA,QACzB,iBAAiB,+CAA+C,QAAQ,KAAK,sEAAsE,QAAQ,KAAK;AAAA,MAClK;AAAA,MAGA;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,iBAAiB,mBAAmB,QAAQ,IAAI,kDAAkD,QAAQ,IAAI;AAAA,cAC9G,gBAAgB;AAAA,cAChB,SAAS;AAAA,YACX;AAAA;AAAA,QACF;AAAA,QAGA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,OAAO,QAAQ;AAAA,cACf,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,eAAe;AAAA,cACf,eAAe;AAAA,YACjB;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QAGA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,OAAO,QAAQ;AAAA,cACf,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,YAAY;AAAA,cACZ,eAAe;AAAA,cACf,WAAW;AAAA,cACX,UAAU;AAAA,YACZ;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QAGC,WACC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,OAAO,QAAQ;AAAA,cACf,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,YAAY;AAAA,cACZ,WAAW;AAAA,cACX,UAAU;AAAA,YACZ;AAAA,YAEC;AAAA;AAAA,QACH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/metadata.ts","../../src/og/og-template.tsx"],"sourcesContent":["/**\n * Nebutra Brand Metadata\n * Central source of truth for brand identity\n *\n * AUTO-GENERATED by `pnpm brand:apply` from `scripts/brand-types.ts`\n * (DEFAULT_BRAND) or a sibling `brand.config.ts` if present. Do NOT\n * edit by hand — your edits will be wiped on the next brand:apply.\n *\n * To rebrand, edit DEFAULT_BRAND in scripts/brand-types.ts and run\n * `pnpm brand:apply`. To extend the shape, add a field to BrandConfig,\n * set its value in DEFAULT_BRAND, then read it from this writer.\n *\n * Pipeline guard: tests/architecture/brand-metadata-drift.test.ts\n * asserts `metadata.ts` is byte-identical to what brand:apply emits.\n */\n\nexport const brand = {\n name: \"Nebutra\",\n nameCn: \"云毓智能\",\n nameFull: \"无锡云毓智能科技有限公司\",\n nameFullEn: \"Wuxi Nebutra Intelligence Technology Co., Ltd.\",\n\n tagline: \"Ship AI products, not boilerplate.\",\n taglineCn: \"AI原生·快速出海·即刻交付\",\n description:\n \"Production-ready Next.js monorepo template for AI SaaS products. Auth, billing, multi-tenancy, AI services, design system, and enterprise infrastructure — pre-configured.\",\n descriptionCn:\n \"面向AI创业者的一体化SaaS基础设施模板,覆盖认证、计费、多租户、AI服务与设计系统,开箱即产品\",\n\n story: {\n concept:\n \"Logo以首字母N的基础造型概念为主要设计框架,通过几何正负空间构建隐形'N',形成近似六边形的稳定结构\",\n colorMeaning: \"蓝绿渐变体现未来感与科技锋芒,'云'代表云端平台,'毓'寓意孕育与转化\",\n values: [\"AI Native\", \"Ship Fast\", \"Open by Default\", \"Global-Ready\", \"Enterprise-Grade\"],\n missionStatement:\n \"Help AI founders and SaaS teams go from idea to production 10x faster by providing the infrastructure layer they shouldn't have to build.\",\n },\n\n domains: {\n landing: \"nebutra.com\",\n app: \"app.nebutra.com\",\n api: \"api.nebutra.com\",\n auth: \"auth.nebutra.com\",\n sso: \"sso.nebutra.com\",\n studio: \"studio.nebutra.com\",\n cdn: \"cdn.nebutra.com\",\n router: \"router.nebutra.com\",\n forge: \"forge.nebutra.com\",\n design: \"design.nebutra.com\",\n status: \"status.nebutra.com\",\n open: \"open.nebutra.com\",\n admin: \"admin.nebutra.com\",\n analytics: \"analytics.nebutra.com\",\n pebble: \"pebble.nebutra.com\",\n carina: \"carina.nebutra.com\",\n kuanlan: \"kuanlan.nebutra.com\",\n origin: \"origin.nebutra.com\",\n },\n\n social: {\n twitter: \"https://twitter.com/nebutra\",\n github: \"https://github.com/nebutra\",\n discord: \"https://discord.gg/nebutra\",\n linkedin: \"https://linkedin.com/company/nebutra\",\n },\n} as const;\n\n/**\n * Brand Colors — full VI palette + brand gradients + semantic colors.\n * Aligned with @nebutra/design-tokens DTCG SSOT (tokens/core.json).\n */\nexport const colors = {\n primary: {\n \"50\": \"#f0f4ff\",\n \"100\": \"#dbe4ff\",\n \"200\": \"#bac8ff\",\n \"300\": \"#91a7ff\",\n \"400\": \"#5c7cfa\",\n \"500\": \"#0033FE\",\n \"600\": \"#002ad4\",\n \"700\": \"#0021ab\",\n \"800\": \"#001882\",\n \"900\": \"#000f59\",\n \"950\": \"#000830\",\n },\n accent: {\n \"50\": \"#e6fff8\",\n \"100\": \"#b3ffec\",\n \"200\": \"#80ffe0\",\n \"300\": \"#4dfcd4\",\n \"400\": \"#1af7c8\",\n \"500\": \"#0BF1C3\",\n \"600\": \"#09c9a3\",\n \"700\": \"#07a183\",\n \"800\": \"#057963\",\n \"900\": \"#035143\",\n \"950\": \"#012923\",\n },\n neutral: {\n \"0\": \"#ffffff\",\n \"50\": \"#f9fafb\",\n \"100\": \"#f3f4f6\",\n \"200\": \"#e4e5e8\",\n \"300\": \"#d2d4d8\",\n \"400\": \"#9fa1a5\",\n \"500\": \"#717377\",\n \"600\": \"#515357\",\n \"700\": \"#3f4044\",\n \"800\": \"#26272a\",\n \"900\": \"#18191c\",\n \"950\": \"#0b0c0d\",\n },\n white: \"#FFFFFF\",\n black: \"#000000\",\n gradient: {\n primary: \"linear-gradient(135deg, #0033FE 0%, #00A2E9 50%, #0BF1C3 100%)\",\n primaryReverse: \"linear-gradient(135deg, #0BF1C3 0%, #00A2E9 50%, #0033FE 100%)\",\n primaryVertical: \"linear-gradient(180deg, #0033FE 0%, #00A2E9 50%, #0BF1C3 100%)\",\n primaryRadial: \"radial-gradient(circle, #0BF1C3 0%, #00A2E9 50%, #0033FE 100%)\",\n },\n p3Overrides: {\n primary500: \"color(display-p3 0.03 0.19 0.99)\",\n accent500: \"color(display-p3 0.07 0.94 0.79)\",\n },\n success: \"#22c55e\",\n warning: \"#f59e0b\",\n error: \"#ef4444\",\n info: \"#0033FE\",\n} as const;\n\n/**\n * Typography. fontFamily is read from design-tokens core.json:fontFamily by\n * brand:apply — change faces there, not here.\n */\nexport const typography = {\n fontFamily: {\n en: '\"Geist\", -apple-system, BlinkMacSystemFont, system-ui, sans-serif',\n cn: '\"MiSans\", \"PingFang SC\", \"Microsoft YaHei\", sans-serif',\n sans: '\"Geist\", \"MiSans\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, system-ui, sans-serif',\n mono: '\"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace',\n display: '\"DM Sans\", \"MiSans\", \"PingFang SC\", sans-serif',\n heading: '\"DM Sans\", \"MiSans\", \"PingFang SC\", sans-serif',\n },\n fontWeight: {\n thin: 100,\n extraLight: 200,\n light: 300,\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n extraBold: 800,\n black: 900,\n },\n letterSpacing: {\n display: \"-0.04em\",\n heading: \"-0.03em\",\n subheading: \"-0.02em\",\n body: \"0em\",\n caption: \"0.01em\",\n mono: \"0em\",\n },\n lineHeight: {\n none: 1,\n tight: 1.2,\n snug: 1.4,\n normal: 1.6,\n relaxed: 1.75,\n loose: 2,\n },\n} as const;\n\n/**\n * Logo asset paths (relative to package), dual-edition structure:\n * - classic (v1.0): preferred for UX / product surfaces\n * - compliant (v2.0): required for commercial / legal contexts\n */\nexport const logoAssets = {\n classic: {\n default: \"assets/logo/logo-color.svg\",\n color: \"assets/logo/logo-color.svg\",\n inverse: \"assets/logo/logo-inverse.svg\",\n mono: \"assets/logo/logo-mono.svg\",\n en: \"assets/logo/logo-en.svg\",\n zh: \"assets/logo/logo-zh.svg\",\n zhEn: \"assets/logo/logo-zh-en.svg\",\n horizontalEn: \"assets/logo/logo-horizontal-en.svg\",\n horizontalZh: \"assets/logo/logo-horizontal-zh.svg\",\n verticalEn: \"assets/logo/logo-vertical-en.svg\",\n verticalZh: \"assets/logo/logo-vertical-zh.svg\",\n },\n compliant: {\n default: \"assets/logo-compliant/logo-color.svg\",\n color: \"assets/logo-compliant/logo-color.svg\",\n inverse: \"assets/logo-compliant/logo-inverse.svg\",\n mono: \"assets/logo-compliant/logo-mono.svg\",\n en: \"assets/logo-compliant/logo-en.svg\",\n zh: \"assets/logo-compliant/logo-zh.svg\",\n zhEn: \"assets/logo-compliant/logo-zh-en.svg\",\n horizontalEn: \"assets/logo-compliant/logo-horizontal-en.svg\",\n horizontalZh: \"assets/logo-compliant/logo-horizontal-zh.svg\",\n verticalEn: \"assets/logo-compliant/logo-vertical-en.svg\",\n verticalZh: \"assets/logo-compliant/logo-vertical-zh.svg\",\n horizontalEnMono: \"assets/logo-compliant/logo-horizontal-en-mono.svg\",\n horizontalZhMono: \"assets/logo-compliant/logo-horizontal-zh-mono.svg\",\n verticalEnMono: \"assets/logo-compliant/logo-vertical-en-mono.svg\",\n verticalZhMono: \"assets/logo-compliant/logo-vertical-zh-mono.svg\",\n },\n} as const;\n\n/**\n * Font asset paths (relative to package).\n */\nexport const fontAssets = {\n poppins: {\n thin: \"assets/fonts/poppins/Poppins-Thin.otf\",\n thinItalic: \"assets/fonts/poppins/Poppins-ThinItalic.otf\",\n extraLight: \"assets/fonts/poppins/Poppins-ExtraLight.otf\",\n extraLightItalic: \"assets/fonts/poppins/Poppins-ExtraLightItalic.otf\",\n light: \"assets/fonts/poppins/Poppins-Light.otf\",\n lightItalic: \"assets/fonts/poppins/Poppins-LightItalic.otf\",\n regular: \"assets/fonts/poppins/Poppins-Regular.otf\",\n italic: \"assets/fonts/poppins/Poppins-Italic.otf\",\n medium: \"assets/fonts/poppins/Poppins-Medium.otf\",\n mediumItalic: \"assets/fonts/poppins/Poppins-MediumItalic.otf\",\n semiBold: \"assets/fonts/poppins/Poppins-SemiBold.otf\",\n semiBoldItalic: \"assets/fonts/poppins/Poppins-SemiBoldItalic.otf\",\n bold: \"assets/fonts/poppins/Poppins-Bold.otf\",\n boldItalic: \"assets/fonts/poppins/Poppins-BoldItalic.otf\",\n extraBold: \"assets/fonts/poppins/Poppins-ExtraBold.otf\",\n extraBoldItalic: \"assets/fonts/poppins/Poppins-ExtraBoldItalic.otf\",\n black: \"assets/fonts/poppins/Poppins-Black.otf\",\n blackItalic: \"assets/fonts/poppins/Poppins-BlackItalic.otf\",\n },\n} as const;\n\n/**\n * Favicon assets.\n */\nexport const faviconAssets = {\n ico: \"assets/favicon/favicon.ico\",\n svg: \"assets/favicon/favicon.svg\",\n apple: \"assets/favicon/apple-touch-icon.png\",\n android192: \"assets/favicon/android-chrome-192x192.png\",\n android512: \"assets/favicon/android-chrome-512x512.png\",\n} as const;\n\n/**\n * OG Image dimensions.\n */\nexport const ogImageDimensions = {\n default: {\n width: 1200,\n height: 630,\n },\n twitter: {\n width: 1200,\n height: 600,\n },\n square: {\n width: 1200,\n height: 1200,\n },\n} as const;\n\nexport type BrandColors = typeof colors;\nexport type BrandTypography = typeof typography;\nexport type LogoAssets = typeof logoAssets;\n","/**\n * Brand OG image template — props-driven, hex/rgba values only.\n *\n * IMPORTANT: Satori (used by next/og's ImageResponse) does NOT resolve\n * CSS custom properties (`var(--brand-primary)` etc.). All colors must be\n * passed as explicit hex or rgba values. The `colors` export from\n * `@nebutra/brand/metadata` is the authoritative source — callers must\n * import from there and pass the values as props. Do NOT add CSS vars here.\n *\n * Wordmark letterform GEOMETRY cannot be auto-generated from a name string.\n * The component renders the brand name as text; operators who need precise\n * wordmark letterforms must supply replacement SVGs via brand.config/assets/logo/.\n */\n\nimport { colors } from \"../metadata\";\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface OgThemePalette {\n /** Background fill — must be explicit hex/rgba, not a CSS var */\n bg: string;\n /** Grid/rule color — rgba for transparency */\n grid: string;\n /** Primary glow color — rgba for transparency */\n glowA: string;\n /** Secondary glow color — rgba for transparency */\n glowB: string;\n /** Heading text color */\n title: string;\n /** Body/label text color — rgba for partial opacity */\n subtitle: string;\n /** Brand accent color — explicit hex */\n accent: string;\n}\n\nexport interface OgTemplateProps {\n /** Page or post title */\n title: string;\n /** Optional subtitle or description */\n subtitle?: string;\n /** Brand name to display in the eyebrow (from brand.name — no literal) */\n brandName: string;\n /** Theme palette with explicit hex/rgba values — no CSS vars */\n palette: OgThemePalette;\n}\n\n// ─── Default palettes (using brand color values, NOT var()) ──────────────────\n\n/** `#rrggbb` at an alpha, as rgba() — satori cannot resolve var() or color-mix(). */\nfunction withAlpha(hex: string, alpha: number): string {\n const n = Number.parseInt(hex.replace(\"#\", \"\"), 16);\n return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${alpha})`;\n}\n\n/**\n * Dark-theme palette, read from the brand colours (brand:apply's output).\n * The comments here used to name the source while the values had drifted\n * from it — bg was pre-House Slate while claiming to be neutral-950.\n */\nexport const OG_PALETTE_DARK: OgThemePalette = {\n bg: colors.neutral[\"950\"],\n grid: \"rgba(255,255,255,0.04)\",\n glowA: withAlpha(colors.primary[\"500\"], 0.28),\n glowB: withAlpha(colors.accent[\"500\"], 0.22),\n title: colors.white,\n subtitle: \"rgba(255,255,255,0.72)\",\n accent: colors.accent[\"500\"],\n};\n\n/**\n * Light-theme palette.\n */\nexport const OG_PALETTE_LIGHT: OgThemePalette = {\n bg: colors.white,\n grid: \"rgba(0,0,0,0.05)\",\n glowA: withAlpha(colors.primary[\"500\"], 0.22),\n glowB: withAlpha(colors.accent[\"500\"], 0.2),\n title: colors.neutral[\"950\"],\n subtitle: withAlpha(colors.neutral[\"950\"], 0.66),\n accent: colors.primary[\"500\"],\n};\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\n/**\n * OG image template for use with Satori / next/og ImageResponse.\n *\n * @example\n * ```tsx\n * import { colors, brand } from \"@nebutra/brand/metadata\";\n * import { OgTemplate, OG_PALETTE_DARK } from \"@nebutra/brand/og\";\n * import { ImageResponse } from \"next/og\";\n *\n * return new ImageResponse(\n * <OgTemplate\n * title=\"My Page\"\n * brandName={brand.name}\n * palette={OG_PALETTE_DARK}\n * />,\n * { width: 1200, height: 630 }\n * );\n * ```\n */\nexport function OgTemplate({ title, subtitle, brandName, palette }: OgTemplateProps) {\n return (\n <div\n style={{\n height: \"100%\",\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n justifyContent: \"flex-end\",\n padding: \"80px\",\n backgroundColor: palette.bg,\n backgroundImage: `radial-gradient(ellipse 80% 50% at 50% 42%, ${palette.glowA} 0%, transparent 72%), radial-gradient(ellipse 60% 40% at 72% 70%, ${palette.glowB} 0%, transparent 75%)`,\n }}\n >\n {/* Grid overlay */}\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n backgroundImage: `linear-gradient(${palette.grid} 1px, transparent 1px), linear-gradient(90deg, ${palette.grid} 1px, transparent 1px)`,\n backgroundSize: \"48px 48px\",\n display: \"flex\",\n }}\n />\n\n {/* Brand eyebrow */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n color: palette.accent,\n fontSize: \"28px\",\n fontWeight: 600,\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n }}\n >\n {brandName}\n </div>\n\n {/* Title */}\n <div\n style={{\n display: \"flex\",\n color: palette.title,\n fontSize: \"78px\",\n fontWeight: 700,\n lineHeight: 1.05,\n letterSpacing: \"-0.02em\",\n marginTop: \"24px\",\n maxWidth: \"1040px\",\n }}\n >\n {title}\n </div>\n\n {/* Optional subtitle */}\n {subtitle ? (\n <div\n style={{\n display: \"flex\",\n color: palette.subtitle,\n fontSize: \"32px\",\n fontWeight: 400,\n lineHeight: 1.35,\n marginTop: \"20px\",\n maxWidth: \"1040px\",\n }}\n >\n {subtitle}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebutra/brand",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Nebutra brand assets, logos, and identity components",
5
5
  "private": false,
6
6
  "nebutra": {