projects/hsdesign-landing

Overview

HS Design official landing page — company showcase website.

URL: https://hsdesign-7ni.pages.dev Custom Domain: https://hsdesign.biz (CNAME → hsdesign-7ni.pages.dev) GitHub: JakeBilu/Landing-Page


Tech Stack

  • Hosting: Cloudflare Pages
  • Framework: (Vite + React + TypeScript based)
  • Database: Cloudflare D1
  • Domain: hsdesign.biz via Cloudflare DNS

Key Files

FilePurpose
wrangler.tomlCloudflare Pages config
functions/Pages Functions (API routes)

D1 Database

Database ID: 8d776216-e135-4c9f-b1bb-9669cb10bd85 Database Name: hsdesign-quotes

Tables

  • quotes — Quote submissions
  • subscribers — Email subscribers

Deployment

# Local development
cd D:\OpenClaw_Home\.openclaw\workspace\projects\hs-design-landing
 
# Deploy to Cloudflare Pages
npx wrangler pages deploy


Local Dev Environment (2026-07)

Local workspace: C:\Users\titic\.gemini\antigravity\scratch\hs-design [IDAPC] Local dev server: npx wrangler pages dev .http://localhost:8788 Pristine CSS backup: style_pristine.css (always keep a copy before editing CSS)

⚠️ Cloudflare Deployment Notes

  • 不要频繁部署到 Cloudflare,过多部署会触发 Cloudflare Access 拦截 (403)
  • 先在本地 wrangler pages dev . 完成所有测试,用户确认后才 npx wrangler pages deploy .
  • 部署命令: npx wrangler pages deploy .

Architecture Notes (2026-07)

文件结构

  • index.html — 主页(Hero, About, Portfolio preview, Services, Process, FAQ preview, Contact)
  • portfolio.html — 作品集详情页(Skudai, Johor Jaya, Huatea)
  • faq.html — 完整FAQ页面(14条FAQ,分4个分类)
  • style.css — 所有样式(从 style_pristine.css 恢复 + 手动追加 fixes)
  • images/ — 项目图片(skudai_*.webp, johor_jaya_*.webp, huatea_*.webp

导航栏结构 (nav)

nav > nav-inner
  ├── nav-main-row
  │   ├── .logo (HS Design)
  │   ├── .nav-links (desktop only: Studio, Portfolio, Services...)
  │   ├── .nav-actions
  │   │   ├── .nav-social.desktop-social (7个社交图标, desktop only)
  │   │   ├── #langToggleBtn (中/EN 切换)
  │   │   ├── .nav-cta (WhatsApp button)
  │   │   └── .hamburger (mobile only)
  │   └──
  └── .nav-social.mobile-social (7个社交图标, mobile only, 第二行)

社交平台链接


踩坑记录 (Lessons Learned)

1. CSS 括号平衡

问题: PowerShell Set-Content 替换命令意外吃掉 } 括号,导致 CSS 全面崩溃 解决: 每次编辑 CSS 后立刻验证 {} 数量是否相等 验证命令: python -c "css=open('style.css',encoding='utf-8').read(); print(css.count('{'), css.count('}'))"

2. Windows 编码问题 (cp1252 vs UTF-8)

问题: Python 的 print() 默认用 cp1252 编码,中文字符会报错 解决: 在脚本开头加 sys.stdout.reconfigure(encoding='utf-8'),或用 open(file, encoding='utf-8') 读写

3. 正则替换会破坏 HTML

问题: 用 re.sub() 批量替换 HTML 时,贪婪匹配 .*? 会把不相关的部分也吞掉 解决: 优先用精确的字符串 .replace(),只在万不得已时用正则

4. FAQ 页面被”污染”

问题: rebuild_faq.py 从 index.html 提取 header 时,regex (.*?</nav>...) 不小心抓到了整个 homepage 的内容 解决: 只提取 <head></nav> + mobile-overlay,然后拼接 FAQ body + footer

5. Portfolio 智能滚轮 (wheel event)

问题: e.preventDefault() 放在 if (e.deltaY !== 0) 里面,但 behavior: 'smooth' 导致动画期间页面仍然滚动 解决: 把 e.preventDefault()e.stopPropagation() 放到 if 外面,并用直接赋值 gallery.scrollLeft += 代替 scrollBy({behavior:'smooth'})

要求: 正方形黑底白字,字不触碰边缘 实现: width: 18px; height: 18px; (顶栏) / width: 24px; height: 24px; (底部), font-size: 5-6px, transform: scale(0.8)

7. Mobile 导航栏

问题: 旧 CSS .logo { flex: 1 1 100%; justify-content: center; } 让 logo 占满整行并居中,把其他元素挤出去 解决: 改为 .logo { flex-shrink: 0; white-space: nowrap; } 社交图标间距: .mobile-social { justify-content: space-evenly; } 让图标均匀分布

8. AI SEO Blog Architecture (2026-07)

Note: Implemented a 30-article AI SEO blog matrix. Structure: <span class="lang-en">...</span><span class="lang-zh">...</span> used for full bilingual support via the existing toggle button. No images used to maximize crawl speed. FAQPage and Article JSON-LD schemas injected. Cloudflare Auth: Deployed using npx wrangler pages deploy with CLOUDFLARE_API_TOKEN set via cmd/powershell environment variables extracted from previous local script (update_access.py).

问题: Portfolio 里面的横向画廊 (project-gallery) 在结合 Lenis 平滑滚动时,会出现鼠标滚轮 (wheel) 滚动不顺滑,甚至部分项目完全滑不动的问题。 解决: Lenis 会全局拦截 wheel 事件。要在特定容器恢复原生/自定义滚轮行为,必须在容器上加上 data-lenis-prevent="true" 属性,比如 <div class="project-gallery" data-lenis-prevent="true">。这样我们手写的 gallery.scrollBy 逻辑就能完美运行,丝般顺滑。

10. AI SEO 与 Sitemap (2026-07)

策略: AI SEO 文章生成后,必须使用 Python 脚本全量提取 *.htmlblog/*.html 生成 sitemap.xml收录量: 目前从最初的 7 个基础页面,成功扩展到了 36 个页面(包含了 30 篇长尾词深度文章)。 生效方式: 必须在 Google Search Console (GSC) 主动提交 https://hsdesign.biz/sitemap.xml 才能强迫 Googlebot 第一时间抓取,避免几周的被动等待期。

11. Founder Section (E-E-A-T 策略)

设计: 为了兼顾“The Studio”的极简清冷感和对 Google 搜索引擎的 E-E-A-T(经验、专业度、权威性、可信度)指标,“The Founder” 介绍块默认使用 CSS display: none 隐藏,由一个不显眼的按钮触发显示。 效果: Googlebot 依然能爬取这段蕴含极高信息密度(讲师身份、Vibe Coding 极客精神、极度自律健康生活)的文本,有效提升域名权威度,而不会破坏首屏设计美感。

问题: Portfolio 里面的横向画廊 (project-gallery) 在结合 Lenis 平滑滚动时,会出现鼠标滚轮 (wheel) 滚动不顺滑,甚至部分项目完全滑不动的问题。 解决: Lenis 会全局拦截 wheel 事件。要在特定容器恢复原生/自定义滚轮行为,必须在容器上加上 data-lenis-prevent="true" 属性,比如 <div class="project-gallery" data-lenis-prevent="true">。这样我们手写的 gallery.scrollBy 逻辑就能完美运行,丝般顺滑。

10. AI SEO 与 Sitemap (2026-07)

策略: AI SEO 文章生成后,必须使用 Python 脚本全量提取 *.htmlblog/*.html 生成 sitemap.xml收录量: 目前从最初的 7 个基础页面,成功扩展到了 36 个页面(包含了 30 篇长尾词深度文章)。 生效方式: 必须在 Google Search Console (GSC) 主动提交 https://hsdesign.biz/sitemap.xml 才能强迫 Googlebot 第一时间抓取,避免几周的被动等待期。

11. Founder Section (E-E-A-T 策略)

设计: 为了兼顾“The Studio”的极简清冷感和对 Google 搜索引擎的 E-E-A-T(经验、专业度、权威性、可信度)指标,“The Founder” 介绍块默认使用 CSS display: none 隐藏,由一个不显眼的按钮触发显示。 效果: Googlebot 依然能爬取这段蕴含极高信息密度(讲师身份、Vibe Coding 极客精神、极度自律健康生活)的文本,有效提升域名权威度,而不会破坏首屏设计美感。

12. Trilingual Architecture (2026-07)

策略: 将原本的中英双语系统扩展为了三语(英文、中文、马来文)。 技术栈: 没有使用任何繁重的 i18n JSON 或前端框架,而是维持了极简的 CSS DOM 树过滤机制。 具体实现:

  • HTML 端:针对需要翻译的文案增加 <span class="lang-ms"> 标签。
  • CSS 端:通过改变 html 标签的 lang 属性来互斥显示。例如 html[lang="en"] .lang-zh, html[lang="en"] .lang-ms { display: none !important; }
  • JS 端:实现 en -> zh -> ms -> en 的三向循环切换逻辑。
  • 按钮UI: 为了保持极简设计,语言切换按钮本身并没有显示所有语言,而是仅根据当前的 lang 环境,通过 CSS 自动显示目标语言。例如,目前是英文环境时,按钮就会显示 “中文”,引导用户点击进入中文版本。

Frontend UI & Layout Bugs Fixed (2026-07)

1. Mobile Hamburger Menu Not Clickable on Subpages

  • Issue: The JS script was only written in index.html. When users clicked the menu on faq.html or blog.html, nothing happened.
  • Fix: Extracted the DOMContentLoaded logic for #mobileMenuBtn, #closeMenuBtn, and #mobileOverlay and injected it before </body> on ALL html files.

2. Fixed Navbar Overlapping Page Titles

  • Issue: The <nav> is position: fixed. Subpages like blog.html used a naked <header class="faq-header"> which naturally flowed underneath the frosted glass navbar (Y=0), making the title text unreadable.
  • Fix: Injected padding-top: clamp(140px, 18vh, 220px); to the header container to dynamically push it down below the 60px navbar on all screen sizes.

3. Text Invisible (CSS Contrast Conflict)

  • Issue: The style.css globally set h1 { color: var(--ink); } (Dark Grey). blog.html and blog articles used <body style="background: var(--bg-dark);"> (Dark Grey). The result was Dark Grey text on a Dark Grey background.
  • Fix: Explicitly added style="color: #fff;" to all <h1> tags inside dark mode pages.