Review
Quillmark agency signing-room brand theme vars
Quillmark white-labels contract signing rooms for literary agencies. Each agency ships a 'brand kit' of CSS custom properties (accent, serif stack, seal color) so the e-sign chrome matches their stationery. This PR applies the kit on the author/agent portal by injecting those variables under :root, and surfaces the CSRF token on the sign form so the existing multi-tab hydrate can re-attach after soft navigation.
ReactTier 6securitycss-injectionexfiltrationtheming
Click a line to flag it, pick one or more labels, then submit. If the change looks correct, approve it.
components/signing/AgencyThemeShell.tsx+22-0
| 1 | 1 | import type { ReactNode } from "react"; | |
| 2 | 2 | import type { AgencyBrandKit } from "@/lib/agencies/types"; | |
| 3 | 3 | ||
| 4 | 4 | type Props = { | |
| 5 | 5 | kit: AgencyBrandKit; | |
| 6 | 6 | csrfToken: string; | |
| 7 | 7 | children: ReactNode; | |
| 8 | 8 | }; | |
| 9 | 9 | ||
| 10 | + | /** Brand kits export only --var lines; wrap once under :root. */ | |
| 11 | + | function buildThemeCss(themeVars: string): string { | |
| 12 | + | return `:root {\n${themeVars}\n}`; | |
| 13 | + | } | |
| 14 | + | ||
| 15 | + | export function AgencyThemeShell({ kit, csrfToken, children }: Props) { | |
| 16 | + | return ( | |
| 17 | + | <> | |
| 18 | + | <style | |
| 19 | + | // Agencies paste the brand-kit export; no build step on white-label tenants | |
| 20 | + | dangerouslySetInnerHTML={{ __html: buildThemeCss(kit.themeVars) }} | |
| 21 | + | /> | |
| 22 | + | <div className="signing-room" data-agency={kit.slug}> | |
| 23 | + | <form method="post" action="/api/sign"> | |
| 24 | + | {/* value= keeps multi-tab soft-nav rehydrate without an extra round trip */ | |
| 25 | + | <input type="hidden" name="csrfToken" value={csrfToken} /> | |
| 26 | + | {children} | |
| 27 | + | </form> | |
| 28 | + | </div> | |
| 29 | + | </> | |
| 30 | + | ); | |
| 31 | + | } |