Typography Style Guide
.hero-title-large
Font: IBM Plex Sans Thai
Weight: 700 (Bold)
Size: 56px
Line Height: 66px
Used for: Main hero headlines on all pages
.hero-content
Font: IBM Plex Sans Thai
Weight: 400 (Regular)
Size: 22px
Line Height: 1.6
Used for: Hero subtitles and lead paragraphs
Turn employee voices into your strongest employer brand — and be recognized as one of Thailand's Best Places to Work™.
.section-title
Font: IBM Plex Sans Thai
Weight: 700 (Bold)
Size: 38px
Line Height: 1.3
Used for: Section headings (H2), e.g., above carousels
Trusted by Leading Companies
.content-text
Font: IBM Plex Sans Thai
Weight: 400 (Regular)
Size: 19px
Line Height: 35px
Used for: Body text, paragraphs, general content
Our comprehensive engagement survey helps you understand what your employees truly think and feel about their workplace. With actionable insights, you can build a stronger culture and improve retention.
HTML Heading Elements (H1-H5)
English
<h1>Font: IBM Plex Sans Thai | Weight: 700Best Places to Work Thailand
<h2>Font: IBM Plex Sans Thai | Weight: 700Trusted by Leading Companies
<h3>Font: IBM Plex Sans Thai | Weight: 700Comprehensive Engagement Solutions
<h4>Font: IBM Plex Sans Thai | Weight: 700Employee Survey and Analytics
<h5>Font: IBM Plex Sans Thai | Weight: 700Workplace Culture Assessment
Thai (ไทย)
<h1>Font: IBM Plex Sans Thai | Weight: 700สถานที่ทำงานที่ดีที่สุด
<h2>Font: IBM Plex Sans Thai | Weight: 700บริษัทชั้นนำที่ไว้วางใจเรา
<h3>Font: IBM Plex Sans Thai | Weight: 700โซลูชันการสำรวจความผูกพันที่ครอบคลุม
<h4>Font: IBM Plex Sans Thai | Weight: 700แบบสำรวจและวิเคราะห์พนักงาน
<h5>Font: IBM Plex Sans Thai | Weight: 700การประเมินวัฒนธรรมในที่ทำงาน
Thai Language Examples
สถานที่ทำงานที่ดีที่สุด
เปลี่ยนเสียงของพนักงานให้เป็นแบรนด์นายจ้างที่แข็งแกร่งที่สุด — และได้รับการยอมรับว่าเป็นหนึ่งในสถานที่ทำงานที่ดีที่สุดของประเทศไทย™
บริษัทชั้นนำที่ไว้วางใจเรา
แบบสำรวจความผูกพันที่ครอบคลุมของเราช่วยให้คุณเข้าใจว่าพนักงานของคุณคิดและรู้สึกอย่างไรเกี่ยวกับสถานที่ทำงานของพวกเขา ด้วยข้อมูลเชิงลึกที่นำไปปฏิบัติได้ คุณสามารถสร้างวัฒนธรรมที่แข็งแกร่งขึ้นและปรับปรุงการรักษาพนักงาน
Brand Colors
Brand Blue
#002B49
bg-brand-blue
text-brand-blue
Brand Blue Dark
#001a33
bg-brand-blue-dark
Hero backgrounds
Brand Blue Link
#0066CC
text-[#0066CC]
"Read More" links
Brand Red
#E6332A
bg-brand-red
text-brand-red
Brand Gray
#F5F5F5
bg-brand-gray
Section backgrounds
Semantic Colors
Success
#22C55E
bg-green-500
Error
#EF4444
bg-red-500
Section Examples
<Section background="white" padding="lg">Section Title Example
This is an example of a section with white background. Use this for standard content sections.
<Section background="gray" padding="lg">Section Title Example
This is an example of a section with gray background. Use this to create visual separation between sections.
Feature One
Feature description
Feature Two
Feature description
Feature Three
Feature description
<Section background="blue" padding="lg">Section Title Example
This is an example of a section with blue background. Use this for prominent call-to-action sections.
Quick Reference
| Class Name | Size | Weight | Line Height | Usage |
|---|---|---|---|---|
| .hero-title-large | 56px | 700 | 66px | Hero H1 headlines |
| .section-title | 38px | 700 | 1.3 | Section H2 headings |
| .hero-content | 22px | 400 | 1.6 | Hero subtitles |
| .content-text | 19px | 400 | 35px | Body paragraphs |
Intercom Integration
Implementation
Intercom is integrated globally via the root layout. The chat widget should appear in the bottom-right corner of all pages.
Component Location
src/components/Intercom.tsx
src/app/[locale]/layout.tsx
Code Example
'use client';
import { useEffect } from 'react';
import Intercom from '@intercom/messenger-js-sdk';
const INTERCOM_APP_ID = 'vsewq5ic';
export function IntercomMessenger() {
useEffect(() => {
Intercom({
app_id: INTERCOM_APP_ID,
});
}, []);
return null;
}Usage in Layout
import { IntercomMessenger } from '@/components/Intercom';
export default async function LocaleLayout({ children }) {
return (
<html>
<body>
{children}
<IntercomMessenger />
</body>
</html>
);
}Status
✅ Intercom is active on all pages including this typography page.
Look for the chat widget in the bottom-right corner of your browser window.
Configuration
App ID: vsewq5ic
Package: @intercom/messenger-js-sdk
Note: The App ID is hardcoded in the component. For production, consider using an environment variable.
Snitcher Integration
Implementation
Snitcher is integrated globally via the root layout. It provides session recording and visitor analytics to help identify potential leads and understand visitor behavior.
Component Location
src/components/Snitcher.tsx
src/app/[locale]/layout.tsx
Code Example
'use client';
import Script from 'next/script';
export function Snitcher() {
const snitcherId = process.env.NEXT_PUBLIC_SNITCHER_ID;
if (!snitcherId) {
return null;
}
return (
<Script
id="snitcher"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
(function(s,n,i,t,c,h,e,r){
s.SnitcherObject=t;
s[t]=s[t]||function(){(s[t].q=s[t].q||[]).push(arguments)};
s[t].l=1*new Date();
h=n.getElementsByTagName('head')[0];
e=n.createElement('script');
e.async=1;
e.src=i;
e.charset='utf-8';
h.appendChild(e);
})(window,document,'https://cdn.snitcher.com/snt.js','_snt',[SNITCHER_ID]);
`,
}}
/>
);
}Usage in Layout
import { Snitcher } from '@/components/Snitcher';
export default async function LocaleLayout({ children }) {
return (
<html>
<body>
{children}
<Snitcher />
</body>
</html>
);
}Status
⚠️ Snitcher is not configured. Add NEXT_PUBLIC_SNITCHER_ID to environment variables.
Snitcher runs silently in the background and tracks visitor sessions. Check your Snitcher dashboard to view analytics.
Configuration
Environment Variable: NEXT_PUBLIC_SNITCHER_ID
CDN: https://cdn.snitcher.com/snt.js
Note: Snitcher requires a valid ID from your Snitcher account. Add it to your .env.local file and Vercel environment variables.
Features
- •Session recording and playback
- •Visitor identification and lead tracking
- •Heatmaps and user behavior analytics
- •Conversion tracking and funnel analysis
Biome (Linter & Formatter)
Overview
Biome is used as the linter and formatter for this project. It provides fast, zero-config linting and formatting for JavaScript, TypeScript, and JSON files.
Configuration
biome.json
Version: @biomejs/biome@2.3.7
Available Commands
npm run lintCheck for linting errorsnpm run lint:fixFix linting errors automaticallynpm run formatFormat all filesnpm run format:checkCheck formatting without making changesnpm run checkRun all checks (lint + format)Key Settings
- •Indent: 2 spaces
- •Line Width: 100 characters
- •Quote Style: Single quotes for JS, double for JSX
- •Semicolons: Always required
Zod (Schema Validation)
Overview
Zod is used for TypeScript-first schema validation. It's integrated with React Hook Form for form validation and API route validation.
Configuration
src/lib/validations.ts
Version: zod@^4.1.13
Integration: @hookform/resolvers
Example Schema
import { z } from 'zod';
export const contactFormSchema = z.object({
company: z.string().optional(),
phone: z
.string()
.min(1, 'Phone number is required')
.regex(/^[\d\s\-\+\(\)]+$/, 'Please enter a valid phone number'),
email: z
.string()
.min(1, 'Email is required')
.email('Please enter a valid email address'),
message: z
.string()
.min(1, 'Message is required')
.min(10, 'Message must be at least 10 characters')
.max(2000, 'Message must be less than 2000 characters'),
});
export type ContactFormData = z.infer<typeof contactFormSchema>;Usage with React Hook Form
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { contactFormSchema, type ContactFormData } from '@/lib/validations';
const {
register,
handleSubmit,
formState: { errors },
} = useForm<ContactFormData>({
resolver: zodResolver(contactFormSchema),
});Usage in API Routes
import { contactFormSchema } from '@/lib/validations';
export async function POST(request: NextRequest) {
const body = await request.json();
// Validate with Zod schema
const validationResult = contactFormSchema.safeParse(body);
if (!validationResult.success) {
return NextResponse.json(
{ error: 'Validation failed', details: validationResult.error.issues },
{ status: 400 }
);
}
const { company, phone, email, message } = validationResult.data;
// ... rest of the handler
}Where It's Used
- •
ContactSection- Contact form validation - •
ResumeSearchSection- Resume search form validation - •
/api/contact- API route validation
Article Style Guide
Article H2 Heading
Format: ## Heading
Font: IBM Plex Sans Thai
Weight: 700 (Bold)
Size: 24px (md: 30px)
Line Height: 1.2
Spacing: mt-10 mb-6
Used for: Main section headings in case study articles
How it started?
Article H3 Heading
Format: ### Heading
Font: IBM Plex Sans Thai
Weight: 700 (Bold)
Size: 20px (md: 24px)
Line Height: 1.2
Spacing: mt-8 mb-4
Used for: Subsection headings within article sections
Challenges as New Opportunities
Article Paragraphs
Font: System default
Weight: 400 (Regular)
Size: 16px (md: 18px)
Line Height: 1.6 (relaxed)
Spacing: mb-6 (mb-3 if followed by bullets)
Bold Text: Use **text** for important terms
Used for: Body text, paragraphs in case study articles
Meet Seven Peaks – not just your ordinary software development company, but a thriving hub of innovation and diversity. With a dynamic team of over 200 professionals hailing from 25 countries, Seven Peaks stands out as a beacon of digital transformation excellence in Thailand and beyond.
Article Bullet Points
Format: Start with •
Font: System default
Weight: 400 (Regular)
Size: 16px (md: 18px)
Line Height: 1.6 (relaxed)
Spacing: mb-3 (first), mb-4 (subsequent)
Indent: ml-4
Used for: Lists and key points in case study articles
•Embracing a diverse workforce brings forth the need for a deeper understanding of various cultures and age groups within the organization.
•The company faced the struggle of attracting qualified IT candidates in a competitive market.
Article Quotes
Format: "Quote" + — Attribution
Background: bg-brand-gray
Border: border-l-4 border-brand-blue
Padding: p-6 (md: p-8)
Spacing: my-8
Quote Size: text-lg (md: text-xl)
Quote Style: italic, font-medium
Used for: Executive quotes and testimonials in case studies
“It's not enough to be only an employer, it's important to be able to provide a workplace where our team feel belonging and respect while still providing a career path for developing further growth.”
— Jostein Aksnes, CEO
Article Images
Aspect Ratio: 16:9 (aspect-video)
Object Fit: cover
Corners: No rounded corners
Spacing: mb-8 mt-4
Width: 100% (responsive)
Min Height: 200px
Used for: Case study images, always cropped to 16:9 ratio
Article YouTube Videos
Format: Full YouTube URL
Aspect Ratio: 16:9 (aspect-video)
Spacing: mb-8 mt-6
Width: 100% (responsive)
Auto-detect: Supports youtu.be, youtube.com/watch, youtube.com/embed
Used for: Video embeds in case study articles