From 2183e8140db8eeec822012d4cfb5b8afc41e7bcd Mon Sep 17 00:00:00 2001 From: Abhinav Raut Date: Sat, 15 Aug 2026 02:22:49 +0530 Subject: [PATCH] move help center branding columns into theme and ship Instrument Sans --- cmd/helpcenter.go | 26 ++++----- .../admin/help-center/HelpCenterForm.vue | 23 ++++---- .../admin/help-center/helpCenterFormSchema.js | 8 +-- internal/helpcenter/helpcenter.go | 57 +++---------------- internal/helpcenter/models/models.go | 9 +-- internal/helpcenter/queries.sql | 14 ++--- internal/migrations/v2.8.0.go | 4 -- schema.sql | 4 -- static/public/static/help-center-classic.css | 12 ++-- static/public/static/help-center-docs.css | 8 +-- .../web-templates/help/shared/head.html | 3 + 11 files changed, 59 insertions(+), 109 deletions(-) diff --git a/cmd/helpcenter.go b/cmd/helpcenter.go index 52a69244..617bceb2 100644 --- a/cmd/helpcenter.go +++ b/cmd/helpcenter.go @@ -584,7 +584,8 @@ func handleShowHelpCenterHome(r *fastglue.Request) error { root = helpCenterBaseURL(app, helpCenter) locales = helpCenterLocales(helpCenter) pathFor = func(l string) string { return helpCenterHomePath(helpCenter, l) } - metaDescription = firstNonEmpty(tree.HelpCenter.MetaDescription, tree.HelpCenter.HeaderText) + theme = helpCenterTheme(tree.HelpCenter) + metaDescription = firstNonEmpty(tree.HelpCenter.MetaDescription, theme.Header.Heading) ) data := helpCenterTemplateData(app, tree.HelpCenter, locale) return renderHelpCenterPage(r, hcPageName(helpCenter, "help-center"), map[string]interface{}{ @@ -594,7 +595,7 @@ func handleShowHelpCenterHome(r *fastglue.Request) error { "MetaDescription": metaDescription, "CanonicalPath": pathFor(locale), "LandingHero": true, - "OGImage": absoluteURL(root, publicAssetPaths(app, tree.HelpCenter.LogoURL)), + "OGImage": absoluteURL(root, publicAssetPaths(app, theme.LogoURL)), "Alternates": helpCenterAlternates(helpCenter, locales, pathFor), "XDefaultPath": defaultLocalePath(helpCenter, locales, pathFor), "LocaleLinks": helpCenterLocaleLinks(helpCenter, locales, pathFor), @@ -647,7 +648,7 @@ func handleShowHelpCenterCollection(r *fastglue.Request) error { "Title": fmt.Sprintf("%s - %s", collection.Name, helpCenter.Name), "MetaDescription": collection.Description, "CanonicalPath": pathFor(locale), - "OGImage": absoluteURL(root, publicAssetPaths(app, helpCenter.LogoURL)), + "OGImage": absoluteURL(root, publicAssetPaths(app, helpCenterTheme(helpCenter).LogoURL)), "Alternates": helpCenterAlternates(helpCenter, translated, pathFor), "XDefaultPath": defaultLocalePath(helpCenter, translated, pathFor), "LocaleLinks": helpCenterLocaleLinks(helpCenter, translated, pathFor), @@ -715,7 +716,7 @@ func handleShowHelpCenterArticle(r *fastglue.Request) error { pathFor = func(l string) string { return articlePath(helpCenter, l, article.Slug) } metaDescription = firstNonEmpty(article.MetaDescription, article.Excerpt) metaTitle = firstNonEmpty(article.MetaTitle, fmt.Sprintf("%s - %s", article.Title, helpCenter.Name)) - ogImage = absoluteURL(root, publicAssetPaths(app, firstNonEmpty(article.MetaImageURL, helpCenter.LogoURL))) + ogImage = absoluteURL(root, publicAssetPaths(app, firstNonEmpty(article.MetaImageURL, helpCenterTheme(helpCenter).LogoURL))) ) data := helpCenterTemplateData(app, helpCenter, locale) return renderHelpCenterPage(r, hcPageName(helpCenter, "help-article"), map[string]interface{}{ @@ -1330,7 +1331,7 @@ func homeJSONLD(root string, hc hcmodels.HelpCenter, locale string) template.JS "query-input": "required name=search_term_string", }, } - if d := firstNonEmpty(hc.MetaDescription, hc.HeaderText); d != "" { + if d := firstNonEmpty(hc.MetaDescription, helpCenterTheme(hc).Header.Heading); d != "" { site["description"] = d } return jsonLD([]any{site}) @@ -1545,12 +1546,6 @@ func sidebarTree(app *App, hc hcmodels.HelpCenter, locale string) []hcmodels.Tre // helpCenterTemplateData shapes a help center row for the public templates. func helpCenterTemplateData(app *App, hc hcmodels.HelpCenter, locale string) map[string]interface{} { - navLinks := []hcmodels.NavLink{} - if len(hc.NavLinks) > 0 { - if err := json.Unmarshal(hc.NavLinks, &navLinks); err != nil { - navLinks = nil - } - } theme := helpCenterTheme(hc) theme.Favicon = publicAssetPaths(app, theme.Favicon) theme.Header.BackgroundImage = publicAssetPaths(app, theme.Header.BackgroundImage) @@ -1565,15 +1560,15 @@ func helpCenterTemplateData(app *App, hc hcmodels.HelpCenter, locale string) map "BaseURL": helpCenterBaseURL(app, hc), "BasePath": helpCenterHomePath(hc, locale), "PageTitle": hc.PageTitle, - "HeaderText": hc.HeaderText, - "LogoURL": publicAssetPaths(app, hc.LogoURL), - "Color": hc.Color, + "HeaderText": theme.Header.Heading, + "LogoURL": publicAssetPaths(app, theme.LogoURL), + "Color": theme.Color, "DefaultLocale": hc.DefaultLocale, "CurrentLocale": locale, "OGLocale": strings.ReplaceAll(locale, "-", "_"), "Dir": localeDir(locale), "AvailableLocales": helpCenterLocales(hc), - "NavLinks": navLinks, + "NavLinks": theme.NavLinks, "Theme": theme, "ThemeCSS": buildThemeCSSVars(theme), "AnnouncementKey": announcementKey(hc.Slug, theme.Announcement), @@ -1681,7 +1676,6 @@ func validateHelpCenter(r *fastglue.Request, req *helpcenter.HelpCenterRequest) if req.PageTitle == "" { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`page_title`"), nil, envelope.InputError) } - req.LogoURL = publicAssetPaths(app, req.LogoURL) req.Theme = json.RawMessage(publicAssetPaths(app, string(req.Theme))) return nil } diff --git a/frontend/apps/main/src/features/admin/help-center/HelpCenterForm.vue b/frontend/apps/main/src/features/admin/help-center/HelpCenterForm.vue index c6ebd6c4..30c55b11 100644 --- a/frontend/apps/main/src/features/admin/help-center/HelpCenterForm.vue +++ b/frontend/apps/main/src/features/admin/help-center/HelpCenterForm.vue @@ -84,7 +84,7 @@ - +
@@ -151,7 +151,7 @@ :open="openSection === 'brand'" @toggle="toggleSection('brand')" > - + {{ t('globals.terms.logoUrl') }} @@ -161,7 +161,7 @@ - + {{ t('globals.terms.primaryColor') }} @@ -191,7 +191,7 @@ :open="openSection === 'header'" @toggle="toggleSection('header')" > - + {{ t('helpCenter.headerText') }} @@ -666,12 +666,12 @@ import { useI18n } from 'vue-i18n' // Field path prefix -> [tab, section] to reveal when that field errors on submit. const FIELD_LOCATION = [ ['theme.header', 'appearance', 'header'], - ['header_text', 'appearance', 'header'], ['theme.tagline', 'appearance', 'header'], ['theme.announcement', 'appearance', 'announcement'], - ['logo_url', 'appearance', 'brand'], - ['color', 'appearance', 'brand'], + ['theme.logo_url', 'appearance', 'brand'], + ['theme.color', 'appearance', 'brand'], ['theme.favicon', 'appearance', 'brand'], + ['theme.nav_links', 'general', ''], ['theme.layout', 'appearance', 'landing'], ['theme.cards', 'appearance', 'landing'], ['theme.article', 'appearance', 'article'], @@ -720,20 +720,20 @@ const toFormValues = (hc) => ({ template: hc?.template === 'docs' ? 'docs' : 'classic', custom_domain: hc?.custom_domain || '', page_title: hc?.page_title || '', - header_text: hc?.header_text || '', meta_description: hc?.meta_description || '', - logo_url: hc?.logo_url || '', - color: hc?.color || '#1f93ff', - nav_links: Array.isArray(hc?.nav_links) ? hc.nav_links : [], custom_css: hc?.custom_css || '', custom_js: hc?.custom_js || '', default_locale: hc?.default_locale || 'en', allowed_locales: Array.isArray(hc?.allowed_locales) && hc.allowed_locales.length ? hc.allowed_locales : ['en'], theme: { + color: hc?.theme?.color || '#1f93ff', + logo_url: hc?.theme?.logo_url || '', + nav_links: Array.isArray(hc?.theme?.nav_links) ? hc.theme.nav_links : [], favicon: hc?.theme?.favicon || '', tagline: hc?.theme?.tagline || '', header: { + heading: hc?.theme?.header?.heading || '', background_type: hc?.theme?.header?.background_type || 'default', background_color: hc?.theme?.header?.background_color || '#1f93ff', gradient_from: hc?.theme?.header?.gradient_from || '#1f93ff', @@ -829,7 +829,6 @@ watch(localeOptions, (locales) => { const toPayload = (values) => { const payload = JSON.parse(JSON.stringify(values)) const allowed = cleanLocales(payload.allowed_locales) - payload.nav_links = payload.nav_links || [] payload.allowed_locales = allowed.length ? allowed : ['en'] if (payload.theme?.layout) { payload.theme.layout.columns = Number(payload.theme.layout.columns) || 2 diff --git a/frontend/apps/main/src/features/admin/help-center/helpCenterFormSchema.js b/frontend/apps/main/src/features/admin/help-center/helpCenterFormSchema.js index f73314c1..76d9e9f0 100644 --- a/frontend/apps/main/src/features/admin/help-center/helpCenterFormSchema.js +++ b/frontend/apps/main/src/features/admin/help-center/helpCenterFormSchema.js @@ -49,11 +49,7 @@ const createBaseSchema = (t) => { .regex(/^[a-z0-9_-]+$/, t('helpCenter.invalidSlug')), page_title: z.string().min(1, t('globals.messages.required')), template: z.enum(['docs', 'classic']).default('classic'), - header_text: z.string().optional(), meta_description: z.string().optional(), - logo_url: optionalURL, - color: z.string().optional(), - nav_links: linkArray, custom_domain: z .string() .refine( @@ -79,10 +75,14 @@ const createBaseSchema = (t) => { .default(['en']), theme: z .object({ + color: z.string().optional(), + logo_url: optionalURL, + nav_links: linkArray, favicon: optionalURL, tagline: z.string().optional(), header: z .object({ + heading: z.string().optional(), background_type: z.string().optional(), background_color: optionalHexColor, gradient_from: optionalHexColor, diff --git a/internal/helpcenter/helpcenter.go b/internal/helpcenter/helpcenter.go index 828a2076..d374b562 100644 --- a/internal/helpcenter/helpcenter.go +++ b/internal/helpcenter/helpcenter.go @@ -96,11 +96,7 @@ type HelpCenterRequest struct { Name string `json:"name"` Slug string `json:"slug"` PageTitle string `json:"page_title"` - HeaderText string `json:"header_text"` MetaDescription string `json:"meta_description"` - LogoURL string `json:"logo_url"` - Color string `json:"color"` - NavLinks json.RawMessage `json:"nav_links"` CustomCSS string `json:"custom_css"` CustomJS string `json:"custom_js"` DefaultLocale string `json:"default_locale"` @@ -281,13 +277,10 @@ func (m *Manager) CreateHelpCenter(req HelpCenterRequest) (models.HelpCenter, er if err := m.validateLocales(req.DefaultLocale, req.AllowedLocales); err != nil { return hc, err } - if err := m.validateColor(req.Color); err != nil { - return hc, err - } if err := m.validateCustomDomain(req.CustomDomain, 0); err != nil { return hc, err } - if err := m.q.InsertHelpCenter.Get(&hc, req.Name, req.Slug, req.PageTitle, req.HeaderText, req.MetaDescription, req.LogoURL, req.Color, req.NavLinks, req.CustomCSS, req.CustomJS, req.DefaultLocale, req.AllowedLocales, req.Theme, req.CustomDomain, req.Template); err != nil { + if err := m.q.InsertHelpCenter.Get(&hc, req.Name, req.Slug, req.PageTitle, req.MetaDescription, req.CustomCSS, req.CustomJS, req.DefaultLocale, req.AllowedLocales, req.Theme, req.CustomDomain, req.Template); err != nil { if dbutil.IsUniqueViolationError(err) { return hc, envelope.NewError(envelope.ConflictError, m.i18n.T("globals.messages.errorAlreadyExists"), nil) } @@ -306,11 +299,7 @@ func (m *Manager) DraftHelpCenter(id int, req HelpCenterRequest) (models.HelpCen req = normalizeHelpCenterRequest(req) hc.Name = req.Name hc.PageTitle = req.PageTitle - hc.HeaderText = req.HeaderText hc.MetaDescription = req.MetaDescription - hc.LogoURL = req.LogoURL - hc.Color = req.Color - hc.NavLinks = req.NavLinks hc.CustomCSS = req.CustomCSS hc.CustomJS = req.CustomJS hc.DefaultLocale = req.DefaultLocale @@ -318,9 +307,6 @@ func (m *Manager) DraftHelpCenter(id int, req HelpCenterRequest) (models.HelpCen hc.Theme = req.Theme hc.CustomDomain = req.CustomDomain hc.Template = req.Template - if err := m.validateColor(hc.Color); err != nil { - return hc, err - } return hc, nil } @@ -337,13 +323,10 @@ func (m *Manager) UpdateHelpCenter(id int, req HelpCenterRequest) (models.HelpCe if err := m.validateLocalesRetained(id, req.AllowedLocales); err != nil { return hc, err } - if err := m.validateColor(req.Color); err != nil { - return hc, err - } if err := m.validateCustomDomain(req.CustomDomain, id); err != nil { return hc, err } - if err := m.q.UpdateHelpCenter.Get(&hc, id, req.Name, req.Slug, req.PageTitle, req.HeaderText, req.MetaDescription, req.LogoURL, req.Color, req.NavLinks, req.CustomCSS, req.CustomJS, req.DefaultLocale, req.AllowedLocales, req.Theme, req.CustomDomain, req.Template); err != nil { + if err := m.q.UpdateHelpCenter.Get(&hc, id, req.Name, req.Slug, req.PageTitle, req.MetaDescription, req.CustomCSS, req.CustomJS, req.DefaultLocale, req.AllowedLocales, req.Theme, req.CustomDomain, req.Template); err != nil { if dbutil.IsUniqueViolationError(err) { return hc, envelope.NewError(envelope.ConflictError, m.i18n.T("globals.messages.errorAlreadyExists"), nil) } @@ -1403,13 +1386,6 @@ func (m *Manager) validateCustomDomain(domain string, excludeID int) error { return nil } -func (m *Manager) validateColor(color string) error { - if !hexColorRe.MatchString(color) { - return envelope.NewError(envelope.InputError, m.i18n.T("helpCenter.invalidColor"), nil) - } - return nil -} - // validateHelpCenterServesLocale rejects a locale the help center doesn't list. func (m *Manager) validateHelpCenterServesLocale(helpCenterID int, locale string) error { hc, err := m.GetHelpCenterByID(helpCenterID) @@ -1445,15 +1421,10 @@ func normalizeHelpCenterRequest(req HelpCenterRequest) HelpCenterRequest { if req.DefaultLocale == "" { req.DefaultLocale = defaultLocale } - if req.Color == "" { - req.Color = defaultAccentColor - } if !slices.Contains(helpCenterTemplates, req.Template) { req.Template = models.TemplateClassic } req.CustomDomain = strings.TrimRight(strings.TrimSpace(req.CustomDomain), "/") - req.LogoURL = sanitizeAssetURL(req.LogoURL) - req.NavLinks = normalizeNavLinks(req.NavLinks) locales := normalizeLocales(parseLocales(req.AllowedLocales), req.DefaultLocale) if b, err := json.Marshal(locales); err == nil { @@ -1463,23 +1434,6 @@ func normalizeHelpCenterRequest(req HelpCenterRequest) HelpCenterRequest { return req } -// normalizeNavLinks drops header links that aren't absolute or root-relative. Invalid JSON collapses to '[]'. -func normalizeNavLinks(raw json.RawMessage) json.RawMessage { - empty := json.RawMessage("[]") - if len(raw) == 0 { - return empty - } - var links []models.NavLink - if err := json.Unmarshal(raw, &links); err != nil { - return empty - } - b, err := json.Marshal(sanitizeNavLinks(links)) - if err != nil { - return empty - } - return b -} - // normalizeTheme drops any theme color that isn't a valid hex code before it can reach // the injected CSS. Invalid JSON collapses to '{}'. func normalizeTheme(raw json.RawMessage) json.RawMessage { @@ -1490,6 +1444,13 @@ func normalizeTheme(raw json.RawMessage) json.RawMessage { if err := json.Unmarshal(raw, &t); err != nil { return json.RawMessage("{}") } + t.Color = sanitizeHexColor(t.Color) + if t.Color == "" { + t.Color = defaultAccentColor + } + t.LogoURL = sanitizeAssetURL(t.LogoURL) + t.NavLinks = sanitizeNavLinks(t.NavLinks) + t.Header.Heading = strings.TrimSpace(t.Header.Heading) t.Header.BackgroundColor = sanitizeHexColor(t.Header.BackgroundColor) t.Header.GradientFrom = sanitizeHexColor(t.Header.GradientFrom) t.Header.GradientTo = sanitizeHexColor(t.Header.GradientTo) diff --git a/internal/helpcenter/models/models.go b/internal/helpcenter/models/models.go index b569efa2..f423fd52 100644 --- a/internal/helpcenter/models/models.go +++ b/internal/helpcenter/models/models.go @@ -20,11 +20,7 @@ type HelpCenter struct { Name string `db:"name" json:"name"` Slug string `db:"slug" json:"slug"` PageTitle string `db:"page_title" json:"page_title"` - HeaderText string `db:"header_text" json:"header_text"` MetaDescription string `db:"meta_description" json:"meta_description"` - LogoURL string `db:"logo_url" json:"logo_url"` - Color string `db:"color" json:"color"` - NavLinks json.RawMessage `db:"nav_links" json:"nav_links"` CustomCSS string `db:"custom_css" json:"custom_css"` CustomJS string `db:"custom_js" json:"custom_js"` DefaultLocale string `db:"default_locale" json:"default_locale"` @@ -37,6 +33,9 @@ type HelpCenter struct { // Theme holds the customizable branding for a help center's public pages. type Theme struct { + Color string `json:"color"` + LogoURL string `json:"logo_url"` + NavLinks []NavLink `json:"nav_links"` Favicon string `json:"favicon"` Tagline string `json:"tagline"` Header HeaderTheme `json:"header"` @@ -57,6 +56,7 @@ type AnnouncementTheme struct { } type HeaderTheme struct { + Heading string `json:"heading"` BackgroundType string `json:"background_type"` // "solid" | "gradient" | "image" BackgroundColor string `json:"background_color"` GradientFrom string `json:"gradient_from"` @@ -194,6 +194,7 @@ type Insights struct { // DefaultTheme enables the show-flags for elements that must keep rendering when a stored theme predates the flag. func DefaultTheme() Theme { return Theme{ + Color: "#1f93ff", Layout: LayoutTheme{ShowPopularArticles: true}, Cards: CardTheme{ShowIconTile: true}, Article: ArticleTheme{ShowAuthor: true}, diff --git a/internal/helpcenter/queries.sql b/internal/helpcenter/queries.sql index 2ce706de..8aad9891 100644 --- a/internal/helpcenter/queries.sql +++ b/internal/helpcenter/queries.sql @@ -1,32 +1,32 @@ -- name: get-all-help-centers -SELECT id, created_at, updated_at, name, slug, page_title, header_text, meta_description, logo_url, color, nav_links, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template +SELECT id, created_at, updated_at, name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template FROM help_centers ORDER BY created_at DESC; -- name: get-active-help-centers -SELECT id, created_at, updated_at, name, slug, page_title, header_text, meta_description, logo_url, color, nav_links, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template +SELECT id, created_at, updated_at, name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template FROM help_centers WHERE is_active = true ORDER BY created_at DESC; -- name: get-help-center-by-id -SELECT id, created_at, updated_at, name, slug, page_title, header_text, meta_description, logo_url, color, nav_links, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template +SELECT id, created_at, updated_at, name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template FROM help_centers WHERE id = $1; -- name: get-help-center-by-slug -SELECT id, created_at, updated_at, name, slug, page_title, header_text, meta_description, logo_url, color, nav_links, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template +SELECT id, created_at, updated_at, name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, is_active, theme, custom_domain, template FROM help_centers WHERE slug = $1 AND is_active = true; -- name: insert-help-center -INSERT INTO help_centers (name, slug, page_title, header_text, meta_description, logo_url, color, nav_links, custom_css, custom_js, default_locale, allowed_locales, theme, custom_domain, template) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) +INSERT INTO help_centers (name, slug, page_title, meta_description, custom_css, custom_js, default_locale, allowed_locales, theme, custom_domain, template) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING *; -- name: update-help-center UPDATE help_centers -SET name = $2, slug = $3, page_title = $4, header_text = $5, meta_description = $6, logo_url = $7, color = $8, nav_links = $9, custom_css = $10, custom_js = $11, default_locale = $12, allowed_locales = $13, theme = $14, custom_domain = $15, template = $16, updated_at = NOW() +SET name = $2, slug = $3, page_title = $4, meta_description = $5, custom_css = $6, custom_js = $7, default_locale = $8, allowed_locales = $9, theme = $10, custom_domain = $11, template = $12, updated_at = NOW() WHERE id = $1 RETURNING *; diff --git a/internal/migrations/v2.8.0.go b/internal/migrations/v2.8.0.go index 34a61b08..33b0ab28 100644 --- a/internal/migrations/v2.8.0.go +++ b/internal/migrations/v2.8.0.go @@ -48,11 +48,7 @@ func V2_8_0(db *sqlx.DB, fs stuffbin.FileSystem, ko *koanf.Koanf) error { name TEXT NOT NULL, slug TEXT NOT NULL UNIQUE, page_title TEXT NOT NULL DEFAULT '', - header_text TEXT NOT NULL DEFAULT '', meta_description TEXT NOT NULL DEFAULT '', - logo_url TEXT NOT NULL DEFAULT '', - color TEXT NOT NULL DEFAULT '#1f93ff', - nav_links JSONB NOT NULL DEFAULT '[]', custom_css TEXT NOT NULL DEFAULT '', custom_js TEXT NOT NULL DEFAULT '', default_locale TEXT NOT NULL DEFAULT 'en', diff --git a/schema.sql b/schema.sql index 2d5e2798..c2522d36 100644 --- a/schema.sql +++ b/schema.sql @@ -670,11 +670,7 @@ CREATE TABLE help_centers ( name TEXT NOT NULL, slug TEXT NOT NULL UNIQUE, page_title TEXT NOT NULL DEFAULT '', - header_text TEXT NOT NULL DEFAULT '', meta_description TEXT NOT NULL DEFAULT '', - logo_url TEXT NOT NULL DEFAULT '', - color TEXT NOT NULL DEFAULT '#1f93ff', - nav_links JSONB NOT NULL DEFAULT '[]', custom_css TEXT NOT NULL DEFAULT '', custom_js TEXT NOT NULL DEFAULT '', default_locale TEXT NOT NULL DEFAULT 'en', diff --git a/static/public/static/help-center-classic.css b/static/public/static/help-center-classic.css index 3675d608..46881366 100644 --- a/static/public/static/help-center-classic.css +++ b/static/public/static/help-center-classic.css @@ -26,7 +26,7 @@ body { min-height: 100dvh; display: flex; flex-direction: column; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + font-family: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-size: 16px; color: var(--hc-ink); background: var(--hc-page); @@ -96,7 +96,7 @@ a:hover { text-decoration: underline; } .hc-hero h1 { margin: 0 0 1.75rem; font-size: clamp(1.7rem, 3.5vw, 2.1rem); - font-weight: 800; + font-weight: 700; letter-spacing: -.025em; line-height: 1.18; color: var(--hc-header-text, var(--hc-ink)); @@ -176,7 +176,7 @@ main:has(> article.hc-article), main:has(> .hc-collection-head), main:has(> .hc- .hc-breadcrumb li + li::before { content: "/"; color: var(--hc-faint); margin-right: .4rem; } .hc-breadcrumb .hc-current { color: var(--hc-ink); } .hc-page-title { - font-size: clamp(1.7rem, 3.5vw, 2.1rem); font-weight: 800; + font-size: clamp(1.7rem, 3.5vw, 2.1rem); font-weight: 700; letter-spacing: -.025em; line-height: 1.18; margin: 0 0 1.5rem; } /* Popular articles */ @@ -215,7 +215,7 @@ main:has(> article.hc-article), main:has(> .hc-collection-head), main:has(> .hc- .hc-collection-head { margin-bottom: 1.25rem; display: flex; align-items: flex-start; gap: .9rem; } .hc-collection-head .hc-collection-icon { margin: 6px 0 0; } .hc-collection-headings { min-width: 0; } -.hc-collection-head h1 { font-size: clamp(1.7rem, 3.5vw, 2.1rem); font-weight: 800; letter-spacing: -.025em; line-height: 1.18; margin: 0 0 .5rem; } +.hc-collection-head h1 { font-size: clamp(1.7rem, 3.5vw, 2.1rem); font-weight: 700; letter-spacing: -.025em; line-height: 1.18; margin: 0 0 .5rem; } .hc-collection-head .hc-desc { color: var(--hc-muted); margin: 0; font-size: 1rem; } .hc-article-panel { padding: .35rem 1.25rem; @@ -263,7 +263,7 @@ main:has(> article.hc-article), main:has(> .hc-collection-head), main:has(> .hc- /* Article */ article.hc-article { max-width: var(--hc-article-width); } -article.hc-article > h1 { font-size: clamp(1.7rem, 3.5vw, 2.1rem); font-weight: 800; letter-spacing: -.025em; line-height: 1.18; margin: .25rem 0 .6rem; } +article.hc-article > h1 { font-size: clamp(1.7rem, 3.5vw, 2.1rem); font-weight: 700; letter-spacing: -.025em; line-height: 1.18; margin: .25rem 0 .6rem; } .hc-article-excerpt { color: var(--hc-muted); font-size: 1.05rem; line-height: 1.6; margin: 0 0 1rem; } article.hc-article .hc-meta { color: var(--hc-faint); font-size: .86rem; margin: 0 0 2rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--hc-border); } @@ -445,7 +445,7 @@ article.hc-article .hc-meta-byline { display: flex; align-items: center; gap: .6 /* Not found */ .hc-notfound { max-width: 34rem; margin: 1rem auto; text-align: center; } .hc-notfound .hc-code { font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; color: var(--hc-accent-ink); margin: 0 0 .75rem; } -.hc-notfound h1 { font-size: clamp(1.7rem, 3.5vw, 2.1rem); font-weight: 800; letter-spacing: -.025em; line-height: 1.18; margin: 0 0 .75rem; } +.hc-notfound h1 { font-size: clamp(1.7rem, 3.5vw, 2.1rem); font-weight: 700; letter-spacing: -.025em; line-height: 1.18; margin: 0 0 .75rem; } .hc-notfound p { color: var(--hc-muted); margin: 0 0 1.75rem; } .hc-notfound .hc-back { display: inline-flex; align-items: center; gap: .5rem; diff --git a/static/public/static/help-center-docs.css b/static/public/static/help-center-docs.css index 0dc042da..beaa4e9d 100644 --- a/static/public/static/help-center-docs.css +++ b/static/public/static/help-center-docs.css @@ -27,7 +27,7 @@ body.hcd { min-height: 100dvh; display: flex; flex-direction: column; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + font-family: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-size: 16px; color: var(--hc-ink); background: var(--hc-bg); @@ -294,7 +294,7 @@ main#hc-main > * { max-width: var(--hcd-content-w); } margin: 0 0 .5rem; max-width: 34rem; font-size: clamp(1.9rem, 3.4vw, 2.6rem); - font-weight: 800; letter-spacing: -.032em; line-height: 1.12; + font-weight: 700; letter-spacing: -.032em; line-height: 1.12; } .hcd-hero-tagline { margin: 0 0 1.5rem; font-size: 1.05rem; color: var(--hc-muted); } .hcd-hero h1:last-child { margin-bottom: 1.5rem; } @@ -333,7 +333,7 @@ main#hc-main > .hcd-collections-section { max-width: calc(var(--hcd-content-w) + .hcd-collection-head .hc-collection-icon { margin: .45rem 0 0; } .hcd-collection-headings { min-width: 0; } .hcd-collection-head h1, .hcd-page-title, .hcd-article h1 { - font-size: clamp(1.55rem, 3vw, 2rem); font-weight: 800; letter-spacing: -.025em; line-height: 1.18; margin: 0 0 .4rem; + font-size: clamp(1.55rem, 3vw, 2rem); font-weight: 700; letter-spacing: -.025em; line-height: 1.18; margin: 0 0 .4rem; } .hcd-lead { color: var(--hc-muted); font-size: 1.02rem; line-height: 1.6; margin: 0; } @@ -486,7 +486,7 @@ main#hc-main > .hcd-collections-section { max-width: calc(var(--hcd-content-w) + } .hcd-notfound { margin: 6rem auto 3rem; max-width: 34rem; text-align: center; } .hcd-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .8rem; font-weight: 600; letter-spacing: .18em; color: var(--hc-faint); margin: 0 0 .75rem; } -.hcd-notfound h1 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); font-weight: 800; letter-spacing: -.03em; margin: 0 0 .6rem; } +.hcd-notfound h1 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); font-weight: 700; letter-spacing: -.03em; margin: 0 0 .6rem; } .hcd-notfound p { color: var(--hc-muted); margin: 0 0 1.5rem; } .hcd-notfound-search { display: flex; align-items: center; gap: .7rem; diff --git a/static/public/web-templates/help/shared/head.html b/static/public/web-templates/help/shared/head.html index 8bb80671..4b3e3cc9 100644 --- a/static/public/web-templates/help/shared/head.html +++ b/static/public/web-templates/help/shared/head.html @@ -25,6 +25,9 @@ {{ if .Data.OGImage }}{{ end }} {{ if .Data.HelpCenter.Theme.Favicon }}{{ else if ne FaviconURL "" }}{{ end }} + + +