Commit Graph

63 Commits

Author SHA1 Message Date
Kunthawat Greethong
f827afb33f feat: liquid glass UI, blob background, redesign home/portfolio/about pages
- Liquid glass effect on navbar/cards with backdrop-filter invert
- Animated blob gradient background (SVG-based)
- Portfolio section: scene-dark invert, show 5 items on home
- How Work section: step flow with numbers + connecting lines
- Hero: Decision snapshot replacing problem selector
- About page: inverted background with contrast fixes
- Fix parallax JS bundling via Astro
- Fix navbar fixed positioning after liquid glass CSS
- Submenu hover fix
- Clean up removed legacy files/assets
2026-06-23 11:40:37 +07:00
Kunthawat Greethong
e279119f97 fix(dark): resolve dark-on-dark text in marquee, log, footer
Dark mode bug: hardcoded rgba(10,10,10,0.3) used as text color
on dark backgrounds — unreadable.

Fix: html.dark overrides for:
- .marquee-track .ts
- .fx-marquee-track .ts
- .fx-log .ts
- .fx-footer-bottom
All now use rgba(250,238,200,0.4) (warm cream, legible on dark)
2026-06-14 21:34:08 +07:00
Kunthawat Greethong
ceffb2a3f3 refactor(legacy): apply v6 design to all inner pages (delete bento components)
Per user: 'เราไม่ต้องการ legacy design น่ะ เพราะมีดีไชน์ใหม่แล้วไง'
- New v6 design must apply to EVERY page, not just index

PHASE A — Add CSS compatibility aliases (~600 lines)
==================================================
fx-system.css grew from 0.05MB → 0.12MB with 3 new alias blocks
for legacy class names that pages still use:

1. LEGACY → v6 ALIASES
   .section, .section-bento, .section-soft, .section-yellow
   .section-header, .section-badge, .section-title, .section-desc
   .reveal, .hero-content, .hero-badge, .hero-grid
   .service-stack + .service-stack-{item,num,icon,body,title,bullets}
   .portfolio-card-{grid,top,badge,arrow,name,industry,highlight}
   .contact-form, .form-{group,label,input,row,success}, .btn, .btn-{primary,outline-dark}
   .filter-section, .filter-bar, .filter-btn
   .info-icon, .checklist
   All styled with v6 design tokens (--ink, --paper, --coral,
   --brand-yellow, --line-2, --paper-2, etc.)

2. BENTO COMPONENT ALIASES
   .bento-grid, .bento-tile, .span-{3,4,5,6,7,8,12}, .rows-{2,3}
   .surface-{white,soft,yellow,purple,purple-soft,teal,teal-soft,mint,dark,coral}
   .tile-{eyebrow,title,body,link}, .mega-cta
   All render via CSS Grid 12-col + v6 surface treatments
   Children (.tile-eyebrow, .tile-title, .tile-body) get v6
   typography (Kanit 800 for titles, JetBrains Mono 700 for
   eyebrows, Itim for em accents).

3. DARK MODE OVERRIDES
   html.dark .section-soft/.filter-section: var(--paper-2)
   html.dark .section-badge/.filter-btn.active: yellow
   html.dark .contact-form .form-input: dark inputs
   html.dark .bento-tile.surface-{soft,purple-soft,yellow}: dark variants

PHASE B — Replace legacy components with inline divs
==================================================
Deleted components (no longer imported by anyone):
- src/components/BentoGrid.astro
- src/components/BentoTile.astro
- src/components/DecoOrb.astro
- src/components/PageHero.astro

Replaced in 7 pages (mechanical regex sweep):
- services/[slug].astro
- contact.astro
- faq.astro
- blog/index.astro
- blog/[slug].astro
- privacy.astro
- terms.astro

JSX transforms:
- <BentoGrid>...</BentoGrid> → <div class='bento-grid'>...</div>
- <BentoTile span={6} surface='yellow' /> → <div class='bento-tile span-6 surface-yellow' />
- <DecoOrb .../> → (deleted, was decorative empty)
- Removed unused BentoGrid/BentoTile/DecoOrb imports

Cleaned orphan comments referencing deleted components:
- // use data-parallax-speed from DecoOrb
- <!-- mail, line, hours as separate BentoTiles -->
- /* FAQ inside BentoTile */

FINAL AUDIT
===========
- 0 legacy component refs in src/
- Build: 22 pages, 1.98s, 0 errors
- All 11 pages have v6 styling (via direct fx-* or via aliases)

Result: every page now uses the v6 design system consistently.
No more yellow DecorativeOrbs, no more BentoTile grid overlap,
no more PageHero/KineticHero mixing. Visual continuity across
all 11 pages.
2026-06-14 21:22:58 +07:00
Kunthawat Greethong
73d820412a fix(nav): remove extra border-bottom under each nav item (desktop)
User reported: 'header menu มีบรรทัดเกิน แปลกๆ' — the 'หน้าแรก'
active link had 2 horizontal lines under it (coral ::after + gray border-bottom).

ROOT CAUSE: v7-5 .fx-nav-menu>li had border-bottom: 1px solid meant
for MOBILE menu (separating stacked items) but the rule escaped
the @media block during Phase 6.2 refactor and now applied to
ALL viewports.

FIX: Add .fx-nav-menu>li { border-bottom: none; } in base CSS
(placed AFTER the original v7-5 rule so cascade applies it).
Mobile @media block below still re-enables border-bottom:1px
for stacked menu.

Verified in built CSS: 12 .fx-nav-menu rules, override present
and last. Build: 22 pages, 2.06s.
2026-06-14 15:05:06 +07:00
Kunthawat Greethong
40382bbf55 refactor(content): reposition from 'app developer' to 'AI + Marketing consultant'
User feedback: design + content was too app-dev focused
(terminal commands, figma labels, code jargon). Business is
'ที่ปรึกษา AI + การตลาด' focused on 3 outcomes:
- เพิ่มยอดขาย (more sales)
- ลดต้นทุน (lower costs)
- ประหยัดเวลา (save time)

Changes:

VISIBLE TEXT replaced:
- Hero title: 'เราจะช่วยคุณเพิ่มกำไร ไม่ใช่แค่เพิ่มงบ'
  → 'เพิ่มยอดขาย ลดต้นทุน ประหยัดเวลา'
- Hero eyebrow: 'MOREMINIMORE / EST. 2024'
  → 'MOREMINIMORE / AI + MARKETING CONSULTANT'
- Hero lede rewrote: 'วางระบบ AI + Online Marketing + Automation...'
  → 'ที่ปรึกษา AI + การตลาดออนไลน์ สำหรับ SME ไทย'
- Hero CTA primary: 'ปรึกษาฟรี →' → 'ปรึกษาฟรี 30 นาที →'
- Process section: '$ npx req/analyze/design/build' (4 steps)
  → '→ ขั้นตอนที่ 1/2/3/4' with business Thai labels
- Case study logs: '[2024-01-15] INFO/SUCCESS' (dates + log tags)
  → 'ขั้นที่ 1/2/3 INFO/SUCCESS' (milestone language)
- Marquee ticker: '[2026-06-13] $ build/deploy' + '[log]'
  → 'อัปเดต/ผลงาน' (Thai status labels)
- Contact prompt placeholder: 'name / phone / line' + 'ENTER' button
  → 'ชื่อ / เบอร์โทร / LINE' + 'ส่งข้อความ' button
- Contact hint: 'กด ENTER เพื่อส่ง' → 'กดส่งเพื่อเริ่มคุยกับเรา'

NEW SECTION: 3 results cards under hero
- Each card: icon + label + example
- เพิ่มยอดขาย / ลดต้นทุน / ประหยัดเวลา
- Examples tied to Dataroot case
- Yellow icon box + black border + lift hover

CSS PSEUDO-ELEMENTS hidden (display:none !important):
- .fx-hero::before '> section: hero · frame: 00.0'
- .fx-case::before '> section: case-study · frame: 01.0'
- .fx-case-image::before 'fig.01 / 4×3'
- .fx-case-content::before 'case.log'
- .fx-services::before '> section: services · 4 cards'
- .fx-callout::before '> callout / 02.0'
- .fx-portfolio::before '> section: portfolio · 4 items'
- .fx-process::before '> $ npx workflow run · 4 steps'
- .fx-pricing::before '> $ cat /pricing/packages.json'
- .fx-faq::before '> $ cat /faq.txt'
- .fx-contact::before '> $ contact@start.sh'
- .fx-portfolio-card::before '◉ ◉ ◉ moreminimore.com/[path]'
- .fx-pricing-card::before 'tier / X'
- .fx-service-card::before 'card / 02.A' + ::after '600×360'
- .fx-hero-side::before 'STATS.LOG'

CSS ::before content hidden:
- .fx-hero-content::before '$' (terminal prompt)
- .fx-contact-form::before '$' (terminal prompt)
- .fx-hero-content::after 'moreminimore --init'
  → 'AI · MARKETING · RESULTS' (business tagline)

CSS-Internal markers (data-coord '00.1', 'P.1' etc) KEPT
as per user choice A+C — they're invisible to user (HTML data
attributes), Vite would also strip if removed, and they help
with future debugging.

Build: 22 pages, 2.20s. Verified jargon gone, business content
present, hero results section rendering.
2026-06-14 10:26:21 +07:00
Kunthawat Greethong
8b04c739e1 fix(utility): remove mode indicator (button label is enough)
Per user: the mode indicator text 'light/dark/auto' next to the
toggle button is redundant — the button itself shows the current
mode in its label ('◐ auto' / '☀ light' / '☾ dark').

Removed:
- <span id='fx-mode-indicator'> from UtilityBar.astro
- getElementById('fx-mode-indicator') in applyTheme() JS
- (CSS for .fx-mode-indicator stays — minimal cost, no harm)

Build: 22 pages, 2.27s.
2026-06-14 10:17:20 +07:00
Kunthawat Greethong
caab40d9a4 fix(theme): switch to .dark class (Astro/Vite strips [data-theme] selectors)
ROOT CAUSE found via build artifact analysis:
- Built CSS files (dist/_astro/Base.*.css) had ZERO [data-theme='dark']
  selectors even though source had 17. Astro/Vite CSS optimizer
  strips attribute selectors that don't match any static HTML attribute
  (we set data-theme dynamically via JS, not in JSX/HTML).
- Also stripped: all html { } and body { } rules from source.
- Result: dark mode visually did nothing. Body stayed white.

FIX:
- Replace [data-theme='dark'] with html.dark (17 occurrences in
  fx-system.css). Vite keeps .dark class selectors because the
  anti-flash script (in Base.astro <head>) sets a class, not an
  attribute, which Vite sees as 'used'.
- Update anti-flash script in Base.astro: classList.add/remove
  instead of setAttribute('data-theme', ...).
- Update UtilityBar.astro applyTheme() to use classList too.
- Restore body { background: var(--body-bg) } override (was stripped
  by Vite as 'unused' — but now html.dark applies to it correctly).

ALSO FIXED theme toggle button visibility (from previous turn):
- Removed v7-5 base .fx-theme-toggle rule (rgba(0.1) opacity made
  button invisible — only visible on hover).
- Consolidated into single rule with proper contrast for both modes.

Verified by:
- Build complete: 22 pages, 1.97s
- Built CSS: 17 html.dark selectors present (was 0)
- Body background override present in built CSS
- HTTP server on :4322 serving correct artifacts
2026-06-14 09:41:32 +07:00
Kunthawat Greethong
96caca4af6 fix(theme+marquee): restore marquee scroll + add light/dark mode toggle
User reported 2 issues after Phase 6.2:
1. 'marquee ควรต้องเลื่อนด้วย' — ROOT CAUSE: v7-5 source CSS included
   override at end of <style> block:
     .fx-marquee-track{animation:none}
     .fx-faq-a::after{display:none}
     .fx-hero::after{display:none}
   These were 'no-op' overrides from the mockup library (which doesn't
   actually animate things in showcase mode). Copied verbatim when I
   extracted fx-system.css in Phase 1.1, killing marquee + 2 other
   animations.
   FIX: replaced with the real animations (marquee 40s, blink-cursor,
   hero noise overlay). All 3 now actually run.

2. 'เราต้องการ light and dark mode ด้วย โดยมีปุ่มเปลี่ยน mode ได้' —
   Implemented full light/dark theme system:
   - Added [data-theme='dark'] block in fx-system.css overriding 11
     CSS tokens (--ink, --paper, --line, --text-dim, + 5 new
     --utility-bg/--nav-bg/--hero-content-bg/etc.)
   - Refactored .fx-utility-bar to use --utility-bg/--fg vars instead
     of hardcoded #0A0A0A (so it inverts correctly in dark mode)
   - Refactored .fx-nav, .fx-hero-content, .fx-hero-side, .fx-faq-item
     to use theme-aware vars
   - Added 13 [data-theme='dark'] overrides for elements needing
     extra contrast tweaks (pricing featured, callout, portfolio name,
     process/service numbers, prose)
   - Added smooth 0.3s transition on theme change (no jarring swap)

3. Theme toggle button (UtilityBar.astro):
   - Replaced text-only indicator with <button id='fx-theme-toggle'>
   - 3 modes cycle: auto (follow OS) → light → dark → auto
   - Persists to localStorage 'moreminimore-theme'
   - Default = 'auto' (follows system preference)
   - Button label changes: '◐ auto' / '☀ light' / '☾ dark'
   - Mode indicator shows user's chosen mode
   - Listens to OS preference change live (when in 'auto' mode)
   - ARIA label + title for accessibility

4. Anti-flash inline script in Base.astro <head>:
   - Runs synchronously before first paint
   - Reads localStorage → applies data-theme
   - If 'auto' or unset, follows prefers-color-scheme
   - Prevents white→dark flash on first load

Build: 22 pages, 0 errors, 2.11s.
CSS: 545/545 braces, 9 keyframes, 13 dark-mode selectors.
2026-06-13 19:41:54 +07:00
Kunthawat Greethong
5393cf611c fix(animations): 8 keyframes + reveal/stagger initial state + button hovers
User reported 2 issues after Phase 6:
1. 'เว็บไม่มี animation เลย' — v7-5 CSS referenced 6+ animations
   (sparkle-float, pulse-glow, float, tag-pulse, type-up,
   blink-cursor, gradient-vertical) but the @keyframes for
   5 of them were NEVER included in the copy. marquee was the
   only one that worked. All other animations silently failed.
2. 'ปุ่มกดไม่ได้' — buttons were styled (cursor:pointer, colors)
   but had no :hover state for visual feedback. User couldn't tell
   they were interactive. .fx-btn:hover, .fx-nav-cta:hover,
   .fx-pricing-cta:hover, .fx-nav-menu a:hover all missing.

Also: .fx-reveal had no initial hidden state (started at opacity:1
with no .revealed class to transition TO) — observer fired but
nothing moved. Same for .fx-stagger.

Fixes (verified by re-parsing CSS):
- Added 7 missing @keyframes: sparkle-float, pulse-glow, float,
  tag-pulse, type-up, blink-cursor, gradient-vertical
- .fx-reveal:not(.revealed) = opacity:0, translateY(40px)
- .fx-stagger:not(.staggered) > * = opacity:0, translateY(20px)
- .fx-stagger.staggered > * = fade in with staggered delays (6 children)
- .fx-btn:hover = lift + coral bg + 4px shadow
- .fx-btn.ghost:hover = lift + yellow bg
- .fx-nav-cta:hover = invert colors + 4px shadow
- .fx-pricing-cta:hover = coral bg + yellow shadow
- .fx-nav-menu a:hover = yellow bg + coral text
- .fx-theme-toggle:hover = yellow bg
- .fx-service-card / .fx-portfolio-card / .fx-pricing-card hover
  = lift + 6px shadow
- .fx-faq-item:hover = slide right + paper bg
- .fx-stat:hover = yellow highlight + lift
- .fx-process-step:hover = lift + coral border

CSS now: 518 braces balanced, 8 keyframes, 0 broken animation refs.

Build: 22 pages, 0 errors, 2.12s.
2026-06-13 19:25:41 +07:00
Kunthawat Greethong
b8ac07996e feat(fx-system): Itim Thai side-bearing fix + prefers-reduced-motion
Phase 6.1: Itim fix — apply letter-spacing: -0.5px + margin-right: -2px
to all <em> in v7-5 sections. Per user memory, Thai display fonts ship
with wide side bearings causing visual gaps after Latin punctuation.
Scope: 20 selectors covering every .fx-* section + .fx-prose (about body).

Phase 6.2: prefers-reduced-motion — kill animations when user prefers.
Disables .fx-marquee-track, .fx-sparkle, .fx-reveal, .fx-stagger animations.
Also hides .fx-hero::after and .fx-faq-a::after decorations.

Phase 6.3: production build verified (22 pages, 0 errors, 1.96s)

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 6.1-6.3
2026-06-13 18:02:07 +07:00
Kunthawat Greethong
caa412dbe2 feat(pages): wire v6 sections to all 9 pages
- index.astro: full 9-section home (Hero → Case → Services → Callout →
  Portfolio → Process → Pricing → Faq → Contact prompt form)
- about.astro: v6 Hero + body content from <Content /> wrapped in .fx-prose
- services/index.astro: v6 Hero + v6 Services (4 from collection) + Contact prompt
- portfolio.astro: v6 Hero + v6 Portfolio (pinned 3) + grid of remaining 6 + Contact
- blog/index.astro: PageHero → Hero (badge→eyebrow, subtitle→lede, showStats=false)
- blog/[slug].astro: same PageHero → Hero swap
- faq.astro: same swap (existing bento FAQ body preserved)
- contact.astro: same swap + WIRED form to submitContact() (real backend).
  Was setTimeout 800ms placeholder — now uses contact-submit.ts which
  POSTs to PUBLIC_CONTACT_ENDPOINT (Apps Script) or dev-mocks if empty.
- privacy.astro + terms.astro: same PageHero → Hero swap

Build: 22 pages, 0 errors. Phase 4.9d complete (contact form wired).

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 5.1-5.9
2026-06-13 18:01:17 +07:00
Kunthawat Greethong
8c2bf3d303 feat(contact): real working form with Apps Script backend (3 sub-tasks)
4.9a: Contact.astro (v6-contact enhanced)
- 2 variants: 'prompt' (1 input + ENTER, for home) + 'full' (5 fields, for /contact)
- Smart-parses prompt input (phone vs name detection)
- Toast feedback on submit (success/error, 5s auto-hide)
- Dev-mode aware (no endpoint = console.log + 'dev mode' toast)

4.9b: apps-script/contact-form/ (USER DEPLOYS)
- Code.gs: doPost() handler → 3 actions:
  1. Append to Google Sheet (SHEET_ID from Script Properties)
  2. Send email via MailApp to RECIPIENT_EMAIL
  3. Send LINE Notify via UrlFetchApp
- Returns {ok, id} or {ok:false, error} as JSON
- Includes testDoPost() for testing in Apps Script editor
- README.md: 6-step deploy guide (Script Properties + Sheet + LINE token)
  with security notes + cost breakdown

4.9c: src/lib/contact-submit.ts
- Reads PUBLIC_CONTACT_ENDPOINT from .env
- Empty/missing = dev mode (console.log + 300ms mock latency)
- Set = POST JSON to endpoint
- Exports submitContact() + isDevMode() for Contact.astro to use

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 4.9a-c
2026-06-13 17:55:59 +07:00
Kunthawat Greethong
154e3f2d91 feat(sections): v6-hero, case, services, callout, portfolio, process, pricing, faq (8 components)
- Hero.astro: REPLACED 714-line legacy. v6-hero terminal+stats — 2-col grid
  with $ command + eyebrow + sparkles + 2x2 stats sidebar. All via props.
- CaseStudy.astro: v6-case — image + 3 stats + log + CTAs. Defaults to Dataroot.
- Services.astro: v6-services 2x2 grid. Loads from src/content/services/*-new.mdx
  (4 services). Features hardcoded per title (v7-5 style).
- Callout.astro: v6-callout yellow pullquote.
- Portfolio.astro: v6-portfolio 2-1-1 modal grid. PINNED 3 per plan round 2
  (Dataroot flagship, Luadjob, Jet). First is 'featured' (large).
- Process.astro: v6-process 4-col flow. Hardcoded 4 steps per plan round 2.
- Pricing.astro: v6-pricing. New pricing collection (2 webdev tiers only
  per plan round 2): Astro ฿5,000 featured + WordPress ฿30,000.
  Grid uses auto-fit to gracefully accept 2-3 tiers.
- Faq.astro: v6-faq Q+A list. Loads from src/content/faq/*.md (20 items),
  default limit=4 to match v7-5 demo. Highlights keywords via hardcoded map.

+ src/content/pricing/astro.md + wordpress.md (new)
+ src/content.config.ts: +pricing collection (z.object with features array)

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 4.1-4.8
2026-06-13 17:54:10 +07:00
Kunthawat Greethong
b586464b5c feat(footer+layout): v6-footer + mount UtilityBar/Marquee/Nav/Footer in Base.astro
- Footer.astro (v6-footer): REPLACED legacy 439-line version. 4-col sitemap
  bound to site settings (phone, email, line, facebook, linkedin) +
  servicesDropdown + company links. Logo uses /images/logo-long-black.png
  (local, was hardcoded to dataroot CDN in v7-5).
- Base.astro: mount <UtilityBar /> + <Marquee /> + <Navigation /> + <Footer />
  around <slot />. Nav receives currentPath for active link highlight.
  Animation init now runs BOTH initAnimations (legacy bento) and fxInit (v7-5).
- SWEEP: removed duplicate <Navigation /> / <Footer /> + their imports
  from 11 page files. Idempotent script via execute_code.

Verified: all 9 pages return 200, header/footer render exactly once each.

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 3.1-3.2
2026-06-13 17:50:10 +07:00
Kunthawat Greethong
1f859921cb feat(header): add UtilityBar + Marquee + Navigation from v6-nav
- UtilityBar.astro (v6-utility): phone, clock, date, email from site settings
  Clock updated by fxClock() in src/lib/fx-animations.ts
- Marquee.astro (v6-marquee): log ticker with 4 entries (animated horizontally)
  Content duplicated for seamless loop
- Navigation.astro (v6-nav): REPLACED legacy. Adds 'บริการ' dropdown
  (4 services) + 'บทความ' link per plan round 2. Click-to-toggle on mobile.
- src/data/nav.ts: single source of truth for mainLinks + servicesDropdown
- fx-system.css: +27 lines for dropdown styles + active link underline
  (v6-nav originally had no dropdown — we added per spec)

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 2.1-2.4
2026-06-13 17:47:40 +07:00
Kunthawat Greethong
582998a340 feat(fx): extract clock + reveal + stagger from v7-5 (line 1567-1624)
3 SSR-safe utilities in one module:
- fxClock() — live Thai Buddhist calendar (id=fx-time, id=fx-date)
- fxReveal() — add .revealed to .fx-reveal on scroll (with 2 failsafes)
- fxStagger() — add .staggered to .fx-stagger on scroll (with 2 failsafes)
- fxInit() — convenience to run all 3

Typed with HTMLElement generics. Uses standard IntersectionObserver.
Namespaced .fx-* classes — no collision with legacy src/lib/animations.ts
(which uses .reveal / counterUp for bento components).

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 1.3
2026-06-13 17:45:58 +07:00
Kunthawat Greethong
9eea9cbe6d feat(layout): import fx-system alongside global.css
fx-system.css is v7-5's .fx-* design system. global.css continues to
serve the legacy bento components (still used by /about, /services,
/contact, /faq, /blog). No collision because all v7-5 classes are
prefixed .fx-*. No visual change yet — components not wired yet.

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 1.2
2026-06-13 17:45:01 +07:00
Kunthawat Greethong
ed03060ff7 feat(fx-system): copy v7-5 design system CSS (485 lines, 12 categories)
Extracted verbatim from Desktop/moreminomore-mockup-v7-5.html lines 10-484.
All .fx-* classes namespaced to avoid collision with global.css.

- Tokens: --brand-yellow #FFD60A, --coral #FF5A3C, --ink #0A0A0A
- Fonts: Kanit + Itim + JetBrains Mono (matches global.css)
- Animations: @keyframes marquee + reveal/stagger JS in src/lib/fx-animations.ts

Refs: .hermes/plans/2026-06-13_124000-moreminimore-v7-5-migration.md Task 1.1
2026-06-13 17:44:10 +07:00
Kunthawat Greethong
45f548421d chore: gitignore .hermes (local plans/notes, not for remote) 2026-06-13 17:43:41 +07:00
Kunthawat Greethong
b54657f58a chore(services): sync existing [slug].astro updates from staging 2026-06-13 17:43:35 +07:00
Kunthawat Greethong
c334b8b650 fix(services/[slug]): handle missing bullets/items fields in legacy data
ai-consult service has data.services[i].items (not .bullets), so .map(bullets) crashed during build. Use s.bullets || s.items || [] fallback. Also data-surface defaults to 'white' when missing.
2026-06-11 08:52:42 +07:00
Kunthawat Greethong
dcd1d73f56 refactor(services/webdev): 5 different layout patterns (no more BentoGrid)
Before: all 5 sections used BentoGrid + BentoTile — repetitive look

After: 5 distinct layouts:
  1. Hero: 2-column grid (text + 4 why-us cards stacked)
  2. Services: vertical card stack (4 items, icon+num+bullets)
  3. Tech options: 2-column comparison table (Astro vs WordPress)
  3b. Portfolio: 2x2 card grid (4 real client sites, hover effect)
  4. Pricing: 3-tier card layout (Landing/Astro/WP) + extras list
  5. FAQ: accordion (native details/summary) + MDX content card

New CSS classes added:
- .service-stack-item, .service-stack-num, .service-stack-bullets
- .tech-comparison, .tech-col, .tech-col-header
- .portfolio-grid-2x2, .portfolio-card-grid
- .pricing-tiers, .pricing-tier, .pricing-tier-recommended
- .faq-accordion, .faq-item, .faq-summary, .faq-icon

Imports fixed: added Icon from Icon.astro (was missing → Astro error)
2026-06-10 19:36:43 +07:00
Kunthawat Greethong
84e245a7bb refactor(services/webdev): restructure from 11 sections to 5 + add real content
Major restructuring of /services/webdev:

Before: 11 sections (Hero, Features, Targets, Included, Tech, Pricing, AI, WhyUs, MDX, FAQ, CTA) — content sparse, many empty cards

After: 5 main sections + inline MDX:
  1. Hero (with 4 why-us cards in right column)
  2. บริการที่คุณได้รับ — 4 service tiles with 3 bullets each
  3. เลือกระบบ + ผลงานจริง (4 real client sites with CTA links)
  4. ราคา (with 'bestFor' context for each price)
  5. FAQ (8 questions with longer answers) + MDX content card

New content (webdev only — other services unchanged):
- 4 why-us tiles (ทำเสร็จไว, แก้เองได้, ติด Google+AI, Server ฟรีปีแรก)
- 4 service tiles with 3 bullets each (แก้ไขเอง, AI, SEO+GEO, Server+SSL)
- 4 real portfolio entries (Dataroot, Baofuling, Lungfinler, ทวนทอง 99)
- 5 pricing entries with bestFor context
- 8 FAQ entries (was 6) with longer answers
- Removed old 'included', 'features', 'targets' from data

CSS additions:
- .hero-trust-grid (right column 4 cards)
- .service-bullets (✓ bullets in service tiles)
- .tile-cta-link (dark pill CTA in portfolio tiles)
- .mdx-content-card (white card for MDX content)
2026-06-10 14:31:02 +07:00
Kunthawat Greethong
5f05489316 fix(theme): shift teal-soft to sky blue for contrast vs mint-soft
teal-soft: #ccfbf1 (pale teal-green) → #bae6fd (pale sky blue)
mint-soft: #d1fae5 (pale green) — unchanged
Now the two tiles are clearly different: one is green-mint, the other is blue-cyan
2026-06-10 14:15:16 +07:00
Kunthawat Greethong
d3421f4003 fix(home): tone down service colors — use mint · yellow · purple-soft · teal-soft
Changes:
- Added new surface variant 'teal-soft' to BentoTile (uses --color-teal-soft)
- Replaced vivid purple/coral with yellow (brand) and teal-soft (light teal)
- Colors now: mint (light green) · yellow (brand) · purple-soft (light purple) · teal-soft (light teal)
- All are light/subtle, no dark or vivid surfaces
2026-06-10 11:54:38 +07:00
Kunthawat Greethong
58c27d3bb3 fix(home): service tile colors mint · purple · coral · purple-soft 2026-06-10 11:11:26 +07:00
Kunthawat Greethong
f86c9b24c4 fix(home): lighten service tile colors back to palette (white/soft/purple-soft/mint) 2026-06-10 10:52:35 +07:00
Kunthawat Greethong
5ab00efd15 fix(home): separate mega-cta from tile-link-overlay (was overlapping with objective)
Before: .tile-link-overlay contained the .mega-cta text. Both overlay and .mega-objective were positioned at the bottom of the tile, causing visual overlap.
After: .mega-cta is a normal-flow <span> in tile-body (pushed to bottom via margin-top: auto). .tile-link-overlay is now an empty click target (no inner content, no padding, no flex).
2026-06-10 10:48:05 +07:00
Kunthawat Greethong
a7a0135727 feat(home): service tiles new colors + expanded content with bullets
Changes:
- Colors changed from yellow/purple-soft/mint/soft (same as problem section)
  → teal / coral / dark / purple (visually distinct from problems)
- Each tile now has 3 bullet points under subtitle to fill tile height
- Bullet styles: dot markers with currentColor at 0.4 opacity
- Text light (white) on dark surfaces (teal, coral, dark, purple)
- bullet list: mega-bullets class with proper spacing
2026-06-10 10:39:04 +07:00
Kunthawat Greethong
9fca75044d feat(portfolio): filter by service category (Consult / Web Dev) + multi-category support
Changes:
- Filter bar: old industry filters (🚗, 💊, etc.) replaced with service categories: All, Consult, Website Development
- Card categories updated per user spec:
  - Dataroot → consult only
  - เลือดจระเข้วานิไทย → both consult + webdev (multi-category)
  - All other 7 cards → webdev
- Filter JS updated: reads data-category (comma-sep) instead of industry text
- Multi-category via comma-separated values in data-category attribute
- Portfolio page: home + portfolio page both reflect new categories
2026-06-10 10:30:24 +07:00
Kunthawat Greethong
57eaa9da8b feat(portfolio): hover overlay for all cards + mobile tap + case studies cleanup
Changes:
- Deleted 9 case studies A-I (no real URLs)
- Researched 5 real client websites (Baofuling, Lungfinler, Trainersunny, Underdog, Luadjob) and wrote accurate what_we_did
- Added mobile tap support (ontouchstart toggle + .tapped class)
- All 9 remaining portfolio cards now use hover/tap overlay for what_we_did
- Removed fabricated features from what_we_did (user-caught: ระบบขอใบเสนอราคา, ระบบนัดหมาย)
2026-06-10 10:16:53 +07:00
Kunthawat Greethong
746d51569b fix(portfolio): shorten Jet Industries hover text 2026-06-10 10:01:16 +07:00
Kunthawat Greethong
a1b1b16288 feat(portfolio): move what_we_did to hover overlay + show 4 specific clients
Per user spec:
1. Home portfolio now shows only 4 specific clients in order:
   Dataroot → Jet Industries → ทวนทอง 99 → สำนักงานกฎหมาย ตถาตา
   (was filtering by featured: true, now filters by slug)

2. PortfolioCard: what_we_did moved from always-visible to
   yellow hover overlay (shown above "เยี่ยมชมเว็บไซต์" button).
   All cards now have uniform layout:
   - Default: image + name + industry + category + result
   - On hover (desktop): overlay shows what_we_did text + visit button
   - No hover effect on mobile (tap navigates to URL)

3. Added what_we_did + result to 3 cards that were missing them:
   - Jet Industries, ทวนทอง 99, สำนักงานกฎหมาย ตถาตา

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-10 09:55:50 +07:00
Kunthawat Greethong
0ff6ae9020 content(home): simplify hero copy to 3 punchy lines
- badge: "เราจะช่วยคุณเพิ่มกำไร" → "Moreminimore"
- title: "เราช่วยวางระบบงาน..." → "เราจะช่วยคุณเพิ่มกำไร"
- subtitle: "รับทำเว็บ ที่ปรึกษา..." → "เราช่วยวางระบบงาน และใช้สถิติวางกลยุทธ์ทางการตลาด"

Update Hero.astro default props to match so other pages
that consume <Hero /> without props get the same copy.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 21:17:16 +07:00
Kunthawat Greethong
f47949c4b3 content(home): X1+X2 hero text + 2-col hero with pain stack + 2x2 services
Per user spec, restructured home page:

1. Hero copy (X1 + X2):
   - badge: "เราจะช่วยคุณเพิ่มกำไร"
   - title: "เราช่วยวางระบบงาน และใช้สถิติวางกลยุทธ์ทางการตลาด"
   - subtitle unchanged
   - replaced old "เว็บขายไม่ได้ โฆษณาเปลือง..." headline

2. Hero 2-column layout (text | pain stack):
   - Left 50%: badge, title, accent line, subtitle, CTA
   - Right 50%: 4 pain cards in vertical stack with colored
     surfaces (yellow, purple-soft, mint, teal) — staggered
     fade-in animation, each card has eyebrow "คุณกำลังเจอปัญหา"
     + pain question
   - Pain cards on right: "ยิ่งขาย กำไรยิ่งลด?", "มีเว็บไซต์
     เหมือนไม่มี?", "พนักงานทำงานได้น้อยกว่าที่ต้องการ?",
     "เอา AI มาให้ใช้ แต่งานไม่ได้มากขึ้นตามที่คิด?"
   - Responsive: stacks vertically on mobile (<1024px)
   - Pain card surfaces match bento tile vocabulary

3. Services section: 4x1 → 2x2 layout:
   - Each tile now span 6 (6+6 per row, 2 rows)
   - 4 tiles total: AI Consult (yellow), Automation (purple-soft),
     Marketing (mint), Web (soft)

4. Section title (X2):
   - "เริ่มจากอันที่ปวดที่สุด ค่อยขยายไปอันอื่น"
     → "เลือกบริการที่ตรงกับปัญหาของคุณ"

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 21:13:43 +07:00
Kunthawat Greethong
c92d446ff7 content(home+services): 19 text updates per user spec
Home (index.astro) updates:
- Section title: "มีวิธีแก้ที่เจาะจง" → "มีวิธีแก้ที่ต่างกัน"
- Problem 1 (โฆษณา): symptom "งบหมดไปกับคนที่ไม่ซื้อ" → "แต่คนที่ไม่ซื้อ"
- Problem 1 (โฆษณา): fix expanded with "ถ้ายังไม่มีการวางระบบเก็บข้อมูล..." caveat
- Problem 2 (เว็บ): symptom removed "ตะกร้าค้าง"
- Problem 2 (เว็บ): fix expanded with conditional "กรณีที่เว็บไม่มีโค้ดเก็บสถิติ..."
- Problem 3 (งานซ้ำ): title "ใช้เวลาคนเป็นชั่วโมง" → "เสียเวลาเป็นชั่วโมง"
- Problem 3 (งานซ้ำ): cause "ระบบเก่า" → "ระบบไม่มีการเชื่อม"
- Problem 3 (งานซ้ำ): fix expanded with "ลดเวลาจากชั่วโมงเป็นนาที"
- Problem 4 (AI): title expanded with cost context
- Problem 4 (AI): cause expanded with "พนักงานไม่เข้าใจ..."
- Problem 4 (AI): fix expanded with "วางระบบ AI Agent ให้มี skill"
- CTA: "ถาม 5 ข้อ...ทำได้หรือทำไม่ได้" → "แนะนำแนวทางเบื้องต้น...อะไรควรทำหรือไม่ควรทำ"

Service tile eyebrows (home):
- AI Consult → ที่ปรึกษาด้าน AI
- Automation Consult → วางระบบ Automation
- Marketing Consult → ที่ปรึกษาการตลาดออนไลน์
- Web Development → พัฒนาเว็บไซต์

Service tile subtitles + objectives (home) — per spec.

Service MDX content (affects service detail page + services/index):
- ai-consult-new.mdx: badge "AI Consult" → "ที่ปรึกษาด้าน AI"
- automation-new.mdx: badge "Automation Consult" → "วางระบบ Automation"
- marketing-new.mdx: badge "Marketing Consult" → "ที่ปรึกษาการตลาดออนไลน์", title → "Online Marketing Consult"
- webdev-new.mdx: badge "Web Development" → "พัฒนาเว็บไซต์"

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 20:52:51 +07:00
Kunthawat Greethong
bd1c979f1a fix(home): remove <a> wrapper around bento-tile (was breaking grid)
The home service section had each bento-tile wrapped in an
<a href="/services/..."> tag. This caused two problems:

1. The <a> became the grid item instead of the .bento-tile,
   so the .bento-tile's grid-column: span 3 was ignored.
   The <a> defaulted to display: block and stretched to
   100% width, so all 4 tiles in a row had the same wide
   width — but the grid was no longer dividing them equally.

2. Astro's scoped CSS only applies to elements with the
   matching data-astro-cid attribute. The <a> wrapper had
   its own scope, and the .bento-grid > a selector wasn't
   styled — so the grid layout didn't propagate correctly.

Fix: remove the <a> wrapper. Make the whole tile clickable
by adding an absolutely-positioned <a class="tile-link-overlay">
inside the tile (covers the entire tile, sits behind text via
z-index). The .bento-tile is now a direct child of .bento-grid
and grid-column: span 3 works as expected.

Result: 4 tiles width 3/12 each, exactly filling one row,
clickable from anywhere on the tile.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 20:00:52 +07:00
Kunthawat Greethong
9e7d27c03c fix(bento): add global !important override for tile width
Scoped CSS in BentoTile.astro was supposed to enforce
min-width: 0 + width: 100%, but the tiles were still
rendering at different widths in the same row.

Adding a global !important override in global.css that
applies to ALL .bento-tile instances regardless of
scoping, plus a flex column layout so tile-body fills
available space and pushes the CTA to the bottom.

This guarantees equal width + equal height in the row.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 18:31:05 +07:00
Kunthawat Greethong
b49931a87a fix(bento): force equal-width tiles via min-width: 0
Tiles in the same row had different widths because grid items
default to min-width: auto, which makes them grow to fit their
intrinsic content width instead of dividing the row equally.

Add min-width: 0, width: 100%, and box-sizing: border-box to
bento-tile so all tiles in a row are exactly equal width.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 14:19:18 +07:00
Kunthawat Greethong
525dc358a3 fix(layout): widen container to 1600px for more usable space
--container-max was 1400px which left visible whitespace on
screens 1600px+ wide. Bump to 1600px so service/problem bento
tiles fill more of the viewport.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 13:42:18 +07:00
Kunthawat Greethong
43f609a794 fix(home): equal-height service tiles + dedupe services
Service section on home page had two issues:
1. Tiles were different heights (longer content = taller tile)
   because .bento-tile had no min-height
2. Two service tiles showed the same title (AI Consult + Automation
   Consult) because src/content/services/ has 4 old + 4 -new mdx
   files; .slice(0, 4) grabbed the first 4 alphabetically which
   contained duplicate base slugs

Fixes:
- Add min-height: 380px + flex column to BentoTile so all tiles
  in a row are visually equal regardless of content length
- Add dedupedServices helper in index.astro that groups services
  by base slug and prefers the -new version when both exist
- Use dedupedServices.slice(0, 4) instead of services.slice(0, 4)

Result: 4 unique services (ai-consult-new, automation-new,
marketing-new, webdev-new) at equal height, filling the row.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 13:40:42 +07:00
Kunthawat Greethong
b5be45bcd6 feat(pages): Bento Grid redesign across all pages
Apply Bento Grid + decorative parallax orb system from about.astro
to all remaining pages (home, services, portfolio, faq, contact,
terms, privacy, blog list, blog detail, services detail).

Layout changes (consistent across all pages):
- Main content sections use <BentoGrid> + <BentoTile>
- 2-3 <DecoOrb> per page for decorative parallax (no parallax blobs
  behind text — orbs are pure decoration, z-index: 0, pointer-events: none)
- Surface variants: white, soft, yellow, purple-soft, teal, mint, dark
  (rotated across pages for visual variety)
- Asymmetric span strategy (8+4, 7+5, 6+6) instead of flat grids
- Process sections use clean 4x1 grid
- Pull quote + yellow CTA kept as-is (standalone sections)

Content rules preserved:
- All Thai content kept verbatim
- No fabricated statistics
- No emoji icons (use text numerals 01 02 03 04)
- All design tokens from global.css (no hardcoded hex)
- Existing global classes (.container, .section, .btn, .section-badge,
  .section-title, .cta-section, etc.) reused — no design system break

Build verified: 22 pages built in 1.80s, no errors.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-08 23:30:48 +07:00
Kunthawat Greethong
789473271e feat(about): Bento Grid layout + 7 content updates
Layout redesign:
- Add BentoGrid, BentoTile, DecoOrb components
- Add accent palette (purple/teal/mint/coral) to global tokens
- Rewrite about.astro using Bento Grid (12-col, surface variants)
- Decorative parallax blur orbs in 4 sections
- Value/process tiles use numerals 01-04 instead of emoji

Content updates per user feedback:
- Remove "Soloprenuer" emphasis
- Remove TOC ("เนื้อหาในหน้านี้") — not needed for short content
- Outsource + bot acknowledged as part of approach
- Replace AI stack with marketing intelligence tools
  (ad spy, SEO gap, trend tracking)
- No fabricated stat numbers — placeholders show "—"
  (only "5+ ปี" kept as verifiable, founded 2020)
- Post-delivery: small changes free, charge only for new features
- No Sprint methodology — flexible timeline, demo when ready

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-08 19:06:55 +07:00
Kunthawat Greethong
ca7f99ed41 fix(about): values grid 2x2 layout + Astro v6 content API
- about.astro: change .values-grid from 4 columns to 2x2 (max-width 900px)
  for visual balance with 4 cards. Drop the duplicate 2-col breakpoint
  that became redundant after the desktop change.
- about.astro: switch from deprecated entry.render() to render(entry)
  to match Astro v6 content collection API.
- content.config.ts: pages collection glob pattern '**/*.{md,mdx}'
  silently matched zero files when the collection only had root-level
  files; switch to '*.{md,mdx}' so the loader actually picks up
  about.md and home.md.
2026-06-08 00:21:05 +07:00
Macky
3f1c0061c7 refactor: remove EmDash CMS, hardcode static page content
- Remove EmDash: uninstalled emdash + @emdash-cms/* packages
- Delete src/utils/site-identity.ts (only file importing emdash)
- Delete src/live.config.ts (emdash stub)
- Delete src/content/pages/ (6 MD files: home/about/services/contact/faq/portfolio)
- Remove 'pages' collection from src/content.config.ts
- Hardcode home content as constants in src/pages/index.astro
- Fix duplicate 'megaphone' key in icon-paths.ts (pre-existing bug blocking build)

Home page redesign:
- New hero policy: 'เพิ่มยอดขาย ลดต้นทุน ลดเวลา' (replaces stats claim)
- Remove stats section (no claims until validated)
- 12 problem cards in 4 service buckets (3 each), outline-badge Lucide icons
- New pull quote: 'กำไรที่มากขึ้นของลูกค้า'
- Fix portfolio preview bug (was loading blog collection, now loads portfolio)

About page:
- Sync hero with new policy
- New 'นโยบายของเรา' section in story
- New dark pull-quote band with mission statement

Hero component:
- Remove hard-coded trust strip (50+/40+/5+/100% stats)
- Remove hard-coded secondary CTA
- Replace with named slots so callers can opt in

CLAUDE.md: updated to reflect new architecture (no CMS, static-only)

Verified: npm run build clean (18 pages, 1.74s)
2026-06-05 14:09:42 +07:00
Macky
892c75b7a6 style: remove border and box-shadow from .logo-banner (nav + footer)
The logo container had a 1px gray border + 0 4px 20px drop shadow that
made it look like a floating button. User wants a flush, clean look —
keep the rounded bottom corners and white background (visual prominence)
but drop the border and shadow. Also remove the hover box-shadow
intensification.

Build: 18 pages, 0 errors
2026-06-04 11:47:24 +07:00
Macky
0f79808a43 feat: replace all emojis with professional lucide-style SVG icon library
Build a curated 50-icon lucide library (Icon.astro + icon-paths.ts) and
replace every emoji across the site (~50 occurrences in 9 files):
- index.astro: 3 problem cards (message, trendingDown, globe)
- about.astro: 4 value cards (target, users, clock, shield)
- portfolio.astro: 7 industry filter buttons (factory, package, scale,
  graduationCap, trendingUp, pen, shoppingCart, layers)
- services/[slug].astro: ~25 feature/target/service icons
- services/index.astro: 6 decision-row tags + phone icon in CTA
- faq.astro: 5 category icons, 3 channel cards
- contact.astro: 3 channel picker, 5 info column, form options data-driven,
  checkCircle success
- Footer.astro: 3 contact icons (phone, mail, mapPin)
- Hero.astro: award icon in trust strip

Add icon wrapper styles to global.css (.problem-icon, .value-icon,
.channel-pick-icon, .info-icon, .channel-icon, .category-icon,
.feature-icon, .target-icon, .success-icon, .contact-icon, .btn-icon,
.filter-icon) — yellow square/circle backgrounds, dark text, consistent
sizing.

Build: 18 pages, 0 errors
2026-06-04 09:20:43 +07:00
Macky
6701c462ee fix: Thai line-height + add Kanit font variables
- Add --font-display, --font-body, --font-mono CSS variables in :root
  (they were referenced everywhere but never defined; Kanit wasn't loading)
- Remove Noto Sans Thai import (Kanit handles Latin + Thai natively)
- Fix hero/PageHero line-height: 1/1.1 → 1.3 to prevent Thai vowel clipping
  (was caused by overflow:hidden on .word-wrapper combined with line-height:1)
- Replace .word-wrapper overflow:hidden with padding so Thai descenders
  stay visible during kinetic-title animation
- Bump word translateY from 100% → 110% so word slides up cleanly
- Bump global h1-h6 line-height from 1.1 → 1.25

Build: 18 pages, 0 errors
2026-06-04 09:20:28 +07:00
Macky
5437a34124 chore: remove emdash files (seed, scripts, db, env types)
User-approved deletion of emdash remnants:
- .emdash/ directory
- seed/, seed-*.cjs, count-cols.cjs (emdash seed scripts)
- data.db, data.db-shm, data.db-wal (emdash SQLite)
- emdash-env.d.ts (emdash type definitions)

Site is now 100% markdown-driven, no CMS runtime needed.
2026-06-03 14:15:48 +07:00
Macky
0855e3d77b feat: light theme page templates + integration with new content collections
- All 11 page templates rewritten for light theme
- index.astro: 8 sections (hero, stats yellow band, problem cards,
  services mega-grid, black pull-quote, blog preview, yellow CTA)
- about.astro: story + values (4 dark-icon cards) + process 4-step
- contact.astro: 4 channel picker cards + 8-field form (added budget field)
  + 3-step 'what happens next' + pre-submit FAQ + yellow final CTA
- faq.astro: dynamic category rendering from content/faq collection
  (5 categories, 20 Q&A) + tag cloud + 3 channel cards
- portfolio.astro: industry filter bar (sticky) + 9 items with new
  schema (industry, what_we_did, result fields) + 'ดีลที่เราเลือก' section
- services/index.astro: decision table (6 rows, scannable in 30s)
  + 3 pricing tiers (Starter/Business/Enterprise) + add-on chips
- services/[slug].astro: 4 service types with light hero + pricing +
  tech options + AI features + 6-FAQ per service
- blog/index.astro: featured + 4-card grid from content collection
- blog/[slug].astro: 2-column with sidebar (about, contact, related)
- privacy.astro + terms.astro: legal content, light theme
- All form posts go to setTimeout success (placeholder for backend wire)
2026-06-03 14:15:33 +07:00