feat: centralize frontend branding
This commit is contained in:
26
docs/TASKS/app-shell/004-global-frontend-branding.md
Normal file
26
docs/TASKS/app-shell/004-global-frontend-branding.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Task: Add global frontend branding configuration
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Centralize product branding for the frontend so product name, visible brand marks, brand assets, and theme colors can be changed from one module instead of being hardcoded across shell and auth surfaces.
|
||||||
|
|
||||||
|
## Relevant Files
|
||||||
|
|
||||||
|
- `frontend/src/branding/branding.js`
|
||||||
|
- `frontend/src/branding/applyBranding.js`
|
||||||
|
- `frontend/src/components/branding/BrandMark.vue`
|
||||||
|
- `frontend/src/components/branding/BrandLogo.vue`
|
||||||
|
- `frontend/src/main.js`
|
||||||
|
- `frontend/src/assets/main.css`
|
||||||
|
- `frontend/src/layouts/main/AppSidebar.vue`
|
||||||
|
- `frontend/src/static/components/LandingSiteMenu.vue`
|
||||||
|
- `frontend/src/features/auth/views/RegisterView.vue`
|
||||||
|
- `frontend/src/features/auth/views/LoginView.vue`
|
||||||
|
- `frontend/public/images/brand/*`
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
16
frontend/public/images/brand/auth-illustration.svg
Normal file
16
frontend/public/images/brand/auth-illustration.svg
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420 240" role="img" aria-labelledby="title">
|
||||||
|
<title id="title">Socialize brand illustration</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="brand-gradient" x1="102" y1="52" x2="324" y2="194" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#ff8a3d"/>
|
||||||
|
<stop offset="1" stop-color="#ef4444"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="420" height="240" rx="36" fill="#fbfaf6"/>
|
||||||
|
<rect x="58" y="44" width="304" height="152" rx="30" fill="#f4f6f3" stroke="#c7d2cc"/>
|
||||||
|
<rect x="82" y="68" width="112" height="104" rx="28" fill="url(#brand-gradient)"/>
|
||||||
|
<path d="M113 137c5.7 5.8 13.2 8.8 22.5 8.8 10.4 0 16.3-3.4 16.3-9.4 0-5.2-4.4-7.4-16-9.1-15.2-2.3-24.2-7.8-24.2-20.2 0-12.1 10.4-20.3 25.5-20.3 10.9 0 19.2 3.3 25.4 10.1l-9.6 8.9c-4.2-4.3-9.4-6.5-15.7-6.5-6.9 0-10.7 2.7-10.7 7.2 0 4.4 4.4 6.4 15.2 8 15.9 2.4 24.6 8.5 24.6 21.1 0 13.6-11 22-29.4 22-12.8 0-23-4-30.2-12z" fill="#fffaf2"/>
|
||||||
|
<path d="M224 86h72" stroke="#172033" stroke-width="12" stroke-linecap="round"/>
|
||||||
|
<path d="M224 118h112" stroke="#2fa58d" stroke-width="12" stroke-linecap="round"/>
|
||||||
|
<path d="M224 150h84" stroke="#ff8a3d" stroke-width="12" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
11
frontend/public/images/brand/logo-mark.svg
Normal file
11
frontend/public/images/brand/logo-mark.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title">
|
||||||
|
<title id="title">Socialize mark</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="brand-gradient" x1="16" y1="12" x2="82" y2="88" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#ff8a3d"/>
|
||||||
|
<stop offset="1" stop-color="#ef4444"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="96" height="96" rx="28" fill="url(#brand-gradient)"/>
|
||||||
|
<path d="M31 61.5c3.9 4.3 9.3 6.5 16.2 6.5 7.8 0 12.4-2.7 12.4-7.3 0-4.1-3.4-5.9-12.2-7.2-12.1-1.8-19-6.2-19-16.1 0-9.7 8.2-16.4 20.2-16.4 8.7 0 15.3 2.7 20.3 8.2l-8.3 8c-3.3-3.5-7.5-5.2-12.5-5.2-5.4 0-8.3 2.1-8.3 5.6 0 3.6 3.4 5.1 11.9 6.4 12.7 1.9 19.5 6.8 19.5 16.8 0 11-8.8 17.8-23.4 17.8-10.2 0-18.3-3.2-24.2-9.7z" fill="#fffaf2"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 791 B |
12
frontend/public/images/brand/logo.svg
Normal file
12
frontend/public/images/brand/logo.svg
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 96" role="img" aria-labelledby="title">
|
||||||
|
<title id="title">Socialize</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="brand-gradient" x1="16" y1="12" x2="82" y2="88" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#ff8a3d"/>
|
||||||
|
<stop offset="1" stop-color="#ef4444"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="96" height="96" rx="28" fill="url(#brand-gradient)"/>
|
||||||
|
<path d="M31 61.5c3.9 4.3 9.3 6.5 16.2 6.5 7.8 0 12.4-2.7 12.4-7.3 0-4.1-3.4-5.9-12.2-7.2-12.1-1.8-19-6.2-19-16.1 0-9.7 8.2-16.4 20.2-16.4 8.7 0 15.3 2.7 20.3 8.2l-8.3 8c-3.3-3.5-7.5-5.2-12.5-5.2-5.4 0-8.3 2.1-8.3 5.6 0 3.6 3.4 5.1 11.9 6.4 12.7 1.9 19.5 6.8 19.5 16.8 0 11-8.8 17.8-23.4 17.8-10.2 0-18.3-3.2-24.2-9.7z" fill="#fffaf2"/>
|
||||||
|
<text x="126" y="61" fill="#172033" font-family="Inter, Arial, sans-serif" font-size="35" font-weight="900" letter-spacing="6">SOCIALIZE</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 933 B |
63
frontend/src/branding/applyBranding.js
Normal file
63
frontend/src/branding/applyBranding.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { branding } from './branding.js';
|
||||||
|
|
||||||
|
const cssVariableMap = {
|
||||||
|
'--socialize-primary': 'primary',
|
||||||
|
'--socialize-accent': 'accent',
|
||||||
|
'--socialize-accent-strong': 'accentStrong',
|
||||||
|
'--socialize-highlight': 'highlight',
|
||||||
|
'--h-background': 'background',
|
||||||
|
'--h-on-background': 'onBackground',
|
||||||
|
'--h-surface': 'surface',
|
||||||
|
'--h-surface-muted': 'surfaceMuted',
|
||||||
|
'--h-on-surface': 'onSurface',
|
||||||
|
'--h-control': 'control',
|
||||||
|
'--h-control-hover': 'controlHover',
|
||||||
|
'--h-control-focus': 'controlFocus',
|
||||||
|
'--h-border': 'border',
|
||||||
|
'--h-border-strong': 'borderStrong',
|
||||||
|
'--h-primary': 'primary',
|
||||||
|
'--h-on-primary': 'onPrimary',
|
||||||
|
'--h-secondary': 'secondary',
|
||||||
|
'--h-on-secondary': 'onSecondary',
|
||||||
|
'--h-tertiary': 'tertiary',
|
||||||
|
'--h-on-tertiary': 'onTertiary',
|
||||||
|
'--h-error': 'error',
|
||||||
|
'--h-on-error': 'onError',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function applyBranding(target = getDefaultTarget()) {
|
||||||
|
if (!target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.entries(cssVariableMap).forEach(([variableName, colorKey]) => {
|
||||||
|
target.style.setProperty(variableName, branding.colors[colorKey]);
|
||||||
|
});
|
||||||
|
|
||||||
|
target.style.setProperty(
|
||||||
|
'--socialize-brand-gradient',
|
||||||
|
`linear-gradient(135deg, ${branding.colors.accent} 0%, ${branding.colors.accentStrong} 100%)`
|
||||||
|
);
|
||||||
|
target.style.setProperty('--socialize-accent-shadow', getRgbShadow(branding.colors.accent, 0.28));
|
||||||
|
target.style.setProperty('--socialize-accent-strong-shadow', getRgbShadow(branding.colors.accentStrong, 0.28));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultTarget() {
|
||||||
|
return typeof document === 'undefined'
|
||||||
|
? null
|
||||||
|
: document.documentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRgbShadow(hexColor, opacity) {
|
||||||
|
const normalizedHex = hexColor.replace('#', '');
|
||||||
|
|
||||||
|
if (normalizedHex.length !== 6) {
|
||||||
|
return hexColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const red = Number.parseInt(normalizedHex.slice(0, 2), 16);
|
||||||
|
const green = Number.parseInt(normalizedHex.slice(2, 4), 16);
|
||||||
|
const blue = Number.parseInt(normalizedHex.slice(4, 6), 16);
|
||||||
|
|
||||||
|
return `rgba(${red}, ${green}, ${blue}, ${opacity})`;
|
||||||
|
}
|
||||||
50
frontend/src/branding/branding.js
Normal file
50
frontend/src/branding/branding.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
export const branding = Object.freeze({
|
||||||
|
productName: 'Socialize',
|
||||||
|
shortName: 'S',
|
||||||
|
assets: {
|
||||||
|
logo: '/images/brand/logo.svg',
|
||||||
|
logoMark: '/images/brand/logo-mark.svg',
|
||||||
|
authIllustration: '/images/brand/auth-illustration.svg',
|
||||||
|
favicon: '/favicon.ico',
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
background: '#f4f6f3',
|
||||||
|
onBackground: '#172033',
|
||||||
|
surface: '#fbfaf6',
|
||||||
|
surfaceMuted: '#f1f5f2',
|
||||||
|
onSurface: '#172033',
|
||||||
|
control: '#eef3ef',
|
||||||
|
controlHover: '#e7eee9',
|
||||||
|
controlFocus: '#ffffff',
|
||||||
|
border: '#c7d2cc',
|
||||||
|
borderStrong: '#94a39d',
|
||||||
|
primary: '#172033',
|
||||||
|
onPrimary: '#fbfaf6',
|
||||||
|
secondary: '#fff3e2',
|
||||||
|
onSecondary: '#172033',
|
||||||
|
tertiary: '#d9f6ee',
|
||||||
|
onTertiary: '#0f766e',
|
||||||
|
accent: '#ff8a3d',
|
||||||
|
accentStrong: '#ef4444',
|
||||||
|
highlight: '#2fa58d',
|
||||||
|
error: '#bc2f2f',
|
||||||
|
onError: '#ffffff',
|
||||||
|
info: '#2563eb',
|
||||||
|
success: '#2fa58d',
|
||||||
|
warning: '#b45309',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function getVuetifyThemeColors() {
|
||||||
|
return {
|
||||||
|
background: branding.colors.background,
|
||||||
|
surface: branding.colors.surface,
|
||||||
|
primary: branding.colors.primary,
|
||||||
|
secondary: branding.colors.secondary,
|
||||||
|
accent: branding.colors.accent,
|
||||||
|
error: branding.colors.error,
|
||||||
|
info: branding.colors.info,
|
||||||
|
success: branding.colors.success,
|
||||||
|
warning: branding.colors.warning,
|
||||||
|
};
|
||||||
|
}
|
||||||
35
frontend/src/components/branding/BrandLogo.vue
Normal file
35
frontend/src/components/branding/BrandLogo.vue
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<span class="brand-logo-root">
|
||||||
|
<img
|
||||||
|
v-if="branding.assets.logo"
|
||||||
|
:src="branding.assets.logo"
|
||||||
|
:alt="branding.productName"
|
||||||
|
class="brand-logo-image"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
class="brand-logo-text"
|
||||||
|
>
|
||||||
|
{{ branding.productName }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { branding } from '@/branding/branding.js';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.brand-logo-root {
|
||||||
|
@apply inline-flex items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-logo-image {
|
||||||
|
@apply block h-auto max-h-full w-auto max-w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-logo-text {
|
||||||
|
@apply text-lg font-black uppercase tracking-[0.18em];
|
||||||
|
color: var(--h-primary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
26
frontend/src/components/branding/BrandMark.vue
Normal file
26
frontend/src/components/branding/BrandMark.vue
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<span class="brand-mark-root">
|
||||||
|
<img
|
||||||
|
v-if="branding.assets.logoMark"
|
||||||
|
:src="branding.assets.logoMark"
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
class="brand-mark-image"
|
||||||
|
/>
|
||||||
|
<span v-else>{{ branding.shortName }}</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { branding } from '@/branding/branding.js';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.brand-mark-root {
|
||||||
|
@apply inline-flex items-center justify-center overflow-hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-mark-image {
|
||||||
|
@apply h-full w-full object-contain;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,8 +5,7 @@
|
|||||||
class="login-brand"
|
class="login-brand"
|
||||||
to="/"
|
to="/"
|
||||||
>
|
>
|
||||||
<span class="login-brand-mark">S</span>
|
<BrandLogo class="login-brand-logo" />
|
||||||
<span class="login-brand-text">Socialize</span>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<section class="login-card">
|
<section class="login-card">
|
||||||
@@ -131,6 +130,7 @@
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { mdiEye, mdiEyeOff, mdiFacebook, mdiGoogle } from '@mdi/js';
|
import { mdiEye, mdiEyeOff, mdiFacebook, mdiGoogle } from '@mdi/js';
|
||||||
|
import BrandLogo from '@/components/branding/BrandLogo.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -212,18 +212,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.login-brand {
|
.login-brand {
|
||||||
@apply mx-auto flex items-center gap-3 px-4 pt-6 no-underline sm:px-0 sm:pt-0;
|
@apply mx-auto flex items-center px-4 pt-6 no-underline sm:px-0 sm:pt-0;
|
||||||
color: #172033;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-brand-mark {
|
.login-brand-logo {
|
||||||
@apply flex h-11 w-11 items-center justify-center rounded-2xl text-lg font-black;
|
@apply h-12 max-w-[180px];
|
||||||
background: var(--socialize-brand-gradient);
|
|
||||||
color: #fffaf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-brand-text {
|
|
||||||
@apply text-lg font-black uppercase tracking-[0.18em];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-card {
|
.login-card {
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:alt="t('alt')"
|
:alt="t('alt')"
|
||||||
src="/images/hutopymedia/loginpage/hutopylogin.svg"
|
:src="branding.assets.authIllustration"
|
||||||
|
class="auth-illustration"
|
||||||
/>
|
/>
|
||||||
<div class="flex flex-col gap-10 text-center">
|
<div class="flex flex-col gap-10 text-center">
|
||||||
<h1 class="login-text text-2xl font-bold text-green-600">
|
<h1 class="login-text text-2xl font-bold text-green-600">
|
||||||
@@ -41,7 +42,8 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:alt="t('alt')"
|
:alt="t('alt')"
|
||||||
src="/images/hutopymedia/loginpage/hutopylogin.svg"
|
:src="branding.assets.authIllustration"
|
||||||
|
class="auth-illustration"
|
||||||
/>
|
/>
|
||||||
<div class="flex flex-col gap-10">
|
<div class="flex flex-col gap-10">
|
||||||
<h1 class="login-text text-center text-2xl font-bold">
|
<h1 class="login-text text-center text-2xl font-bold">
|
||||||
@@ -134,6 +136,7 @@
|
|||||||
import { useClient } from '@/plugins/api.js';
|
import { useClient } from '@/plugins/api.js';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { mdiEye, mdiEyeOff } from '@mdi/js';
|
import { mdiEye, mdiEyeOff } from '@mdi/js';
|
||||||
|
import { branding } from '@/branding/branding.js';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const clientApi = useClient();
|
const clientApi = useClient();
|
||||||
@@ -185,6 +188,10 @@
|
|||||||
@apply z-10;
|
@apply z-10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.auth-illustration {
|
||||||
|
@apply h-auto w-full max-w-xs;
|
||||||
|
}
|
||||||
|
|
||||||
/* Override Vuetify's default padding to accommodate our icon */
|
/* Override Vuetify's default padding to accommodate our icon */
|
||||||
:deep(.v-field__append-inner) {
|
:deep(.v-field__append-inner) {
|
||||||
padding-inline-start: 0;
|
padding-inline-start: 0;
|
||||||
@@ -195,7 +202,7 @@
|
|||||||
{
|
{
|
||||||
"en": {
|
"en": {
|
||||||
"title": "Create your account",
|
"title": "Create your account",
|
||||||
"alt": "Hutopy Registration",
|
"alt": "Socialize registration",
|
||||||
"name": "Full Name",
|
"name": "Full Name",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
@@ -215,7 +222,7 @@
|
|||||||
},
|
},
|
||||||
"fr": {
|
"fr": {
|
||||||
"title": "Créer votre compte",
|
"title": "Créer votre compte",
|
||||||
"alt": "Inscription Hutopy",
|
"alt": "Inscription Socialize",
|
||||||
"name": "Nom complet",
|
"name": "Nom complet",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"password": "Mot de passe",
|
"password": "Mot de passe",
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
import { getNotificationRoute } from '@/features/notifications/notificationRoutes.js';
|
import { getNotificationRoute } from '@/features/notifications/notificationRoutes.js';
|
||||||
import { useContentItemsStore } from '@/features/content/stores/contentItemsStore.js';
|
import { useContentItemsStore } from '@/features/content/stores/contentItemsStore.js';
|
||||||
import { useCampaignsStore } from '@/features/campaigns/stores/campaignsStore.js';
|
import { useCampaignsStore } from '@/features/campaigns/stores/campaignsStore.js';
|
||||||
|
import { branding } from '@/branding/branding.js';
|
||||||
|
import BrandMark from '@/components/branding/BrandMark.vue';
|
||||||
import SidebarUserMenu from './SidebarUserMenu.vue';
|
import SidebarUserMenu from './SidebarUserMenu.vue';
|
||||||
import {
|
import {
|
||||||
mdiBellOutline,
|
mdiBellOutline,
|
||||||
@@ -253,14 +255,14 @@
|
|||||||
:class="{ 'brand-link-collapsed': !isExpanded }"
|
:class="{ 'brand-link-collapsed': !isExpanded }"
|
||||||
to="/"
|
to="/"
|
||||||
>
|
>
|
||||||
<span class="brand-mark">S</span>
|
<BrandMark class="brand-mark" />
|
||||||
<div
|
<div
|
||||||
v-if="isExpanded"
|
v-if="isExpanded"
|
||||||
class="brand-copy"
|
class="brand-copy"
|
||||||
>
|
>
|
||||||
<div class="brand-heading">
|
<div class="brand-heading">
|
||||||
<span class="brand-name-wrap">
|
<span class="brand-name-wrap">
|
||||||
<span class="brand-name">Socialize</span>
|
<span class="brand-name">{{ branding.productName }}</span>
|
||||||
<span
|
<span
|
||||||
class="brand-stage-badge"
|
class="brand-stage-badge"
|
||||||
:aria-label="t('nav.brandStageLabel')"
|
:aria-label="t('nav.brandStageLabel')"
|
||||||
@@ -664,9 +666,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.brand-mark {
|
.brand-mark {
|
||||||
@apply flex h-11 w-11 flex-shrink-0 items-center justify-center rounded-[1.1rem] text-xl font-black;
|
@apply h-11 w-11 flex-shrink-0 rounded-[1.1rem];
|
||||||
background: var(--socialize-brand-gradient);
|
|
||||||
color: #fffaf2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand-name-wrap {
|
.brand-name-wrap {
|
||||||
@@ -675,7 +675,7 @@
|
|||||||
|
|
||||||
.brand-name {
|
.brand-name {
|
||||||
@apply min-w-0 text-lg font-black uppercase tracking-[0.18em];
|
@apply min-w-0 text-lg font-black uppercase tracking-[0.18em];
|
||||||
color: #172033;
|
color: var(--h-primary);
|
||||||
line-height: 2.75rem;
|
line-height: 2.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ import { useChannelsStore } from '@/features/channels/stores/channelsStore.js';
|
|||||||
import { i18n } from '@/plugins/i18n.js';
|
import { i18n } from '@/plugins/i18n.js';
|
||||||
import config from '@/config.js';
|
import config from '@/config.js';
|
||||||
import { createHead } from '@vueuse/head';
|
import { createHead } from '@vueuse/head';
|
||||||
|
import { applyBranding } from '@/branding/applyBranding.js';
|
||||||
|
import { getVuetifyThemeColors } from '@/branding/branding.js';
|
||||||
|
|
||||||
|
applyBranding();
|
||||||
|
|
||||||
const vuetify = createVuetify({
|
const vuetify = createVuetify({
|
||||||
components: {
|
components: {
|
||||||
@@ -62,17 +66,7 @@ const vuetify = createVuetify({
|
|||||||
themes: {
|
themes: {
|
||||||
socializeLight: {
|
socializeLight: {
|
||||||
dark: false,
|
dark: false,
|
||||||
colors: {
|
colors: getVuetifyThemeColors(),
|
||||||
background: '#f4f6f3',
|
|
||||||
surface: '#fbfaf6',
|
|
||||||
primary: '#172033',
|
|
||||||
secondary: '#fff3e2',
|
|
||||||
accent: '#ff8a3d',
|
|
||||||
error: '#bc2f2f',
|
|
||||||
info: '#2563eb',
|
|
||||||
success: '#2fa58d',
|
|
||||||
warning: '#b45309',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
class="site-brand"
|
class="site-brand"
|
||||||
to="/"
|
to="/"
|
||||||
>
|
>
|
||||||
<span class="site-brand-mark">S</span>
|
<BrandMark class="site-brand-mark" />
|
||||||
<span class="site-brand-heading">
|
<span class="site-brand-heading">
|
||||||
<span class="site-brand-text-wrap">
|
<span class="site-brand-text-wrap">
|
||||||
<span class="site-brand-text">Socialize</span>
|
<span class="site-brand-text">{{ branding.productName }}</span>
|
||||||
<span
|
<span
|
||||||
class="site-brand-stage-badge"
|
class="site-brand-stage-badge"
|
||||||
:aria-label="t('nav.brandStageLabel')"
|
:aria-label="t('nav.brandStageLabel')"
|
||||||
@@ -136,6 +136,8 @@
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useAuthStore } from '@/features/auth/stores/authStore.js';
|
import { useAuthStore } from '@/features/auth/stores/authStore.js';
|
||||||
import { productFeatureItems } from '@/static/productFeatures.js';
|
import { productFeatureItems } from '@/static/productFeatures.js';
|
||||||
|
import { branding } from '@/branding/branding.js';
|
||||||
|
import BrandMark from '@/components/branding/BrandMark.vue';
|
||||||
|
|
||||||
const allowedLocales = ['en', 'fr'];
|
const allowedLocales = ['en', 'fr'];
|
||||||
const localeStorageKey = 'user-locale';
|
const localeStorageKey = 'user-locale';
|
||||||
@@ -273,13 +275,11 @@
|
|||||||
|
|
||||||
.site-brand {
|
.site-brand {
|
||||||
@apply flex min-w-0 items-start gap-3 no-underline;
|
@apply flex min-w-0 items-start gap-3 no-underline;
|
||||||
color: #172033;
|
color: var(--h-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-brand-mark {
|
.site-brand-mark {
|
||||||
@apply flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-2xl text-base font-black;
|
@apply h-10 w-10 flex-shrink-0 rounded-2xl;
|
||||||
background: var(--socialize-brand-gradient);
|
|
||||||
color: #fffaf2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-brand-heading {
|
.site-brand-heading {
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ export default {
|
|||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
hutopyPrimary: "var(--hutopy-primary)",
|
|
||||||
hutopySecondary: "var(--hutopy-secondary)",
|
|
||||||
hBackground: "var(--h-background)",
|
hBackground: "var(--h-background)",
|
||||||
hOnBackground: "var(--h-on-background)",
|
hOnBackground: "var(--h-on-background)",
|
||||||
hSurface: "var(--h-surface)",
|
hSurface: "var(--h-surface)",
|
||||||
@@ -27,4 +25,3 @@ export default {
|
|||||||
},
|
},
|
||||||
plugins: []
|
plugins: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user