masterconcept.ai — how this site is actually built
Everything you need to make your first safe change to the Master Concept website, and the list of traps that cost us time so they don't cost you any. Read sections 1–4 on day one; the rest is reference you'll come back to.
01What this site is
The five-minute mental model. If you only remember one thing, make it the last paragraph.
masterconcept.ai is Master Concept's public marketing site: a WordPress install on SiteGround, fronted by Cloudflare, running the Hello Elementor theme with Elementor Pro and ElementsKit on top, translated into four languages by WPML.
| Language | Code | URL prefix | Pages | Posts |
|---|---|---|---|---|
| English default | en | / | 152 | 537 |
| 繁體中文 (Taiwan) | zh-hant | /zh-hant/ | 99 | 614 |
| 繁體中文 (Hong Kong) | zh-hk | /zh-hk/ | 13 | 22 |
| 简体中文 | zh-cn | /zh-cn/ | 28 | 24 |
Counts taken from the REST API, Nov 2026. Note how thin zh-hk and zh-cn are — that imbalance drives a lot of section 6.
Three kinds of page live here
Elementor pages legacy
Still the majority, and still what the live header and footer run on. Built visually; the layout is JSON in the database. You'll maintain these — you won't start new ones.
Native HTML the direction
Hand-written HTML + CSS in the page content, no Elementor, built from Figma with the skill. Exact, fast, reviewable. Section 8 and section 10.
Plugin-rendered
Lists, author pages and nav columns rendered by our own WP Buddy plugin through wpb_ shortcodes. Content comes from the database, not from markup.
We are moving off Elementor and onto our own hand-built HTML, produced from the Figma design with the figma-to-wp skill. That is the direction for all new work.
So: new pages are native HTML, not Elementor. Elementor stays for the hundreds of pages already built in it, and it is still what the live header and footer run on — but it isn't where you start. If you're about to open the Elementor editor to build something new, check first.
Why we're moving: Elementor layouts live as JSON in the database, so they can't be reviewed, diffed or version-controlled, they're slow to load, and matching a Figma design inside a visual builder is guesswork. Native HTML is exact, fast, and reviewable before it ships. Sections 8 and 10 are the how.
There is no staging site. Every change you make is on production, visible to the public the moment the cache clears. Work locally, review locally, then push — and always know which of the four languages you are editing.
02Access you need
Ask Tommy for these on day one. They're granted individually, so say what you need and why.
- WordPress login (wp-admin)Your own account — never a shared one. The login URL is not
/wp-login.php; the site hides it. Ask for the real URL. - Application PasswordGenerated inside your WP profile. Needed for any script or tool that talks to the REST API as you.
- GitHub — mcailab/wpbuddyPushing to
maindeploys the plugin to the live site, so this is a production credential. - FigmaDesigns come from Figma; page builds read measurements straight out of the file.
- Claude — via Magic LoginThe shared mc-marketing account. Section 10 has the full flow.
- A password manager of your ownFor your credentials — WP login, application password, GitHub. See the box below.
You won't need either. The repo deploys itself — push to main and GitHub Actions syncs your WP Buddy change onto the live site. That's the whole deployment story for plugin code, and it's why repo access is the one credential that reaches production.
Where passwords go
Two different things, and it's worth keeping them straight:
Shared team logins
Magic Login. You sign in as yourself and it hands you the shared account — Claude's mc-marketing among them. You never see or store the password.
Your own credentials
Keep them in a password manager, never a text file or a note. The company runs 1Password — ask Tommy whether you get a seat. Bitwarden is a solid free alternative if you'd rather run your own.
- A password lives in a password manager and nowhere else. Never in code, never in a commit, never in a ticket, never pasted into a chat.
- The plugin reads every key it needs from the WordPress database at runtime — so there is never a reason to hardcode one.
- If you think you need a credential in a file, ask first. There's almost always an existing helper.
Bookmark these
| What | Link |
|---|---|
| The site | masterconcept.ai |
| Plugin repo | github.com/mcailab/wpbuddy |
| Shared logins | magic.mcai.dev |
| Live sitemap | WP Buddy → Content Tree |
| Menus | Appearance → Menus |
| Brand tokens | WP Buddy → Brand Kit |
| Shortcode reference | WP Buddy → Shortcode |
| Audit log | Simple History |
| PHP snippets | Code Snippets |
| Media library | Media |
| Guide colleagues use | Claude Design to WordPress |
wp-admin links need you signed in — and the sign-in URL isn't /wp-login.php, so get that from Tommy first.
03The stack
39 plugins are active. These are the dozen that will actually affect your work.
| What | Why it matters to you |
|---|---|
| Hello Elementor theme | Deliberately minimal. It does almost nothing — which is why native HTML pages need the full-bleed override in section 8. |
| Elementor + Elementor Pro | The visual page builder. Layout lives in the DB as JSON, not in files. |
| ElementsKit Lite/Pro | Supplies the header, the nav bar and the mega menu. Section 7. |
| WPML (+ String, Media, SEO) | All four languages. The single biggest source of surprises — read section 6 before touching anything multilingual. |
| Permalink Manager Pro | URLs are not derived from the page slug. It stores a URI per post. Change a slug and you must regenerate the permalink. |
| WP Buddy ours | Our own plugin — the only part of the site that lives in git. Section 4. |
| Code Snippets | ~17 PHP snippets (GTM, Amplitude, assorted fixes) stored in the database. Not in git. Check here when behaviour has no visible source. |
| Speed Optimizer (SiteGround) | Combines + minifies CSS/JS and full-page-caches for logged-out visitors. The reason your change "didn't work". Section 11. |
| Safe SVG | SVG uploads to the media library are allowed and sanitised. Icons can be real SVG. |
| All in One SEO, Redirection, IndexNow | Meta, redirects, search-engine pings. Don't change URLs without checking Redirection. |
| Security Optimizer, AIOS, WPS Hide Login | A WAF sits in front of the site, and the login URL is hidden. Both will bite you — see Gotchas. |
| Simple History | Audit log. When you need to know who changed what and when, look here first. |
Hello Elementor 3.5.1 · Elementor 4.3.5 / Pro 4.3.2 · ElementsKit Lite 4.0.9 / Pro 4.5.0 · WPML 5.1.0 · WP Buddy 4.14. Verified Nov 2026.
04Where each thing lives
The most useful table on this page. Before you change anything, find its row — editing in the wrong place is the most common way to lose work here.
| Customisation | Lives in | In git? | How you change it |
|---|---|---|---|
| WP Buddy plugin | wp-content/plugins/wp-buddy/ | Yes repo | Edit locally → push to main → CI deploys |
| Code Snippets (~17) | Database | No | wp-admin → Snippets |
| Child theme / functions.php | wp-content/themes/… | No | No deploy path exists for the theme — ask Tommy |
| Pages & Elementor layouts | Database (post_content, _elementor_data) | No | Elementor editor, or REST POST /wp/v2/pages/{id} |
| Menus | Database (nav_menu terms) | No | Appearance → Menus |
| Settings, WPML config, permalink URIs | Database | No | wp-admin |
| Images, SVG, PDFs | Media library (files + DB) | No | Media → Add New, or REST upload |
Only one row is version-controlled. Everything else is live state with no undo — and post revisions are disabled site-wide. Before you overwrite a page, save a copy of its current HTML locally. Every time.
The WP Buddy repo — github.com/mcailab/wpbuddy
wp-buddy/
├── plugin/ ← this is what deploys
│ ├── wp-buddy.php ← main file, version + include list + changelog
│ ├── includes/ ← one file per feature
│ └── assets/ ← enqueued CSS/JS
├── docs/ ← design + implementation notes (read these)
├── .github/workflows/ ← auto-deploy to the live site
└── README.md
No build step — plain PHP, vanilla JS and CSS. Nothing to compile, nothing to install.
Shortcodes it provides
[wpb_post_list] · [wpb_authors] · [wpb_hs_form] · [wpb_zoom] · [wpbuddy_nav] · [wpbuddy_menu]
House rule: reusable dynamic content goes through a shortcode, never hardcoded markup. If you find yourself pasting the same list of links into four language versions of a page, stop — that's a shortcode.
Its admin screens
wp-admin → WP Buddy: Tools · Analytics Dashboard · Tags Management · Content Tree · AI Builder (Beta) · Brand Kit · Shortcode · PageSpeed · Toolkit.
05Sitemap
The shape of the site at a glance. English structure shown — the other three languages mirror it, minus what hasn't been translated.
Open the live sitemap — WP Buddy → Content TreeThe list below is a static snapshot for orientation. WP Buddy → Content Tree is the authoritative one: pages, posts and templates as an expandable tree, filtered per language, with translation status and quick edit / duplicate / trash on every row. Bookmark it.
There's also a public /site-map/ page for visitors — don't confuse the two.
Pages — top level (English)
| Page | Path | Children |
|---|---|---|
| Home | / | — |
| Solutions | /solutions/ | 26 |
| Partners | /partners/ | 6 groups |
| AI Academy | /aiacademy/ | 11 |
| How To Use Google Meet | /how-to-use-google-meet/ | 16 |
| Resources | /resources/ | — |
| Success Stories | /success-stories/ | — |
| Learning Articles | /learning-articles/ | — |
| Download | /download/ | — |
| About Master Concept | /about-master-concept/ | — |
| Why Master Concept | /why-master-concept/ | — |
| Contact Us | /contact-us/ | — |
| Media Relations | /media-relations/ | — |
| Privacy Policy | /website-privacy/ | — |
| Event Privacy | /event-privacy/ | — |
| Information Security Statement | /information-security-statement/ | — |
| Thank You (Contact / Download) | /thank-you/, /thank-you-download/ | — |
| Site Map | /site-map/ | — |
| Previews & test not public nav | /footer-preview/, /mega-solutions-preview/, /stylekit-ml/, /test/ | — |
Solutions — all 26 children
- AI & productivity
- Generative AI and Machine Learning /solutions/generative-ai-and-machine-learning/
- Maco Chat /solutions/maco-chat/
- Productivity and Collaboration /solutions/productivity-and-collaboration/
- Remote Office /solutions/remote-office/
- AI Governance /solutions/ai-governance/
- AI for Enterprise — knowledge base & chatbots /solutions/ai-solutions-for-enterprise…/
- Geospatial
- Geospatial Solutions Overview /solutions/geospatial/
- Geographical Information System /solutions/geographical-information-system/
- Master Planner /solutions/master-planner/
- MasterPulse /solutions/masterpulse/
- MasterScape AI /solutions/masterscape-ai/
- Google Maps Geospatial Analytics /solutions/google-maps-geospatial-analytics/
- Last Mile Fleet Solution (LMFS) /solutions/lmfs-solutions/
- ODRD Solutions /solutions/odrd-solutions/
- Cloud & DevOps
- DevOps /solutions/devops/
- App & Web Development /solutions/app-web-development/
- Cloud Solutions /solutions/enterprise-cloud-solutions/
- Managed Service Provider /solutions/managed-service-provider/
- Cloud Migration /solutions/cloud-migration/
- Cybersecurity
- Zero Trust Security Model /solutions/zero-trust-security-model/
- ISO Compliance /solutions/iso-compliance/
- Unified Endpoint Management /solutions/unified-endpoint-management/
- Identity and Access Management /solutions/identity-and-access-management/
- Secure Access Service Edge /solutions/secure-access-service-edge/
- IoT Security /solutions/iot-security/
- Analytics & marketing
- Digital Action Lab /solutions/digital-ai-lab/ 6 children
The five groupings above are how the mega menu presents them — WordPress itself stores all 26 as flat children of /solutions/.
Partners — 6 groups
- Google & Cloud /partners/google-cloud/ 8
- DevOps & Security /partners/devops-security/ 14
- Work & Collaboration /partners/work-collaboration/ 7
- Analytics & Marketing /partners/analytics-marketing/ 6
- Geotab /partners/geotab/ 2
- Bright Data /partners/bright-data/
~40 partner pages in total. This is the branch behind the Partners mega menu, still to be rebuilt.
Posts — by category
Posts are organised by category, not by parent. The category decides where a post appears in a listing, and getting it wrong makes a post vanish from a page while looking perfectly fine in wp-admin.
| Category | Slug | Posts | Sub-categories |
|---|---|---|---|
| Blog | /blog/ | 247 | — |
| News | /news/ | 61 | — |
| Event | /event/ | 54 | — |
| Webinar | /webinar/ | 44 | — |
| Success Stories | /success-stories/ | 33 | by partner — Google Workspace, Google Cloud, Asana, Google Maps Platform, Freshworks, OKTA, HubSpot, monday.com, Amplitude, Docusign |
| Learning Articles | /learning-articles/ | 27 | Google Workspace, Google Maps Platform, Work Management, Google Cloud, Information Security, Martech |
| Cloud Computing Academy | /cloud-computing-academy/ | 26 | Google Cloud, Professions Training |
| Download | /download/ | 22 | — |
| MCTV | /mctv/ | 9 | — |
| Digital Action Lab | /digital-action-lab/ | 6 | Data Analytics |
| Whitepaper | /whitepaper/ | 4 | — |
| Data & AI Lab | /data-ai-lab/ | 3 | — |
- Posts also carry a region — Hong Kong · Taiwan · Singapore · Malaysia · China · All. The wrong region makes a post disappear from that region's listing while looking perfectly correct in WordPress.
- No cover image means a blank tile in every listing it appears in.
06Languages & WPML
Four languages, uneven content, and a translation layer with sharp edges. This section exists because each of these cost us a day.
WPML falls back to the default language and nowhere else. There is no chain. A missing zh-hk page does not fall back to zh-hant, which is what a Hong Kong reader would actually want — it falls back to English.
Where we need 香港 → 繁中 → English, we build that chain ourselves in the menu. Don't assume WPML did it.
Create a nav_menu term via REST and it is born in the default language. WPML then silently strips every item in it that points at another language's page. The menu saves, the API lists the items back to you, and the front end renders nothing.
Fix: set the term's language before filling it. We added a route for exactly this:
POST /wp-json/wpbuddy/v1/set-term-language
{ "term_id": 1091, "taxonomy": "nav_menu", "language": "zh-hant" }
Menus created by hand in wp-admin already carry the right language and are unaffected.
Content gaps you'll run into
| Area | Status |
|---|---|
| Solution pages | EN 24 of 24 · 繁中 17 · 简中 4 · 香港 0 gap |
| 隱私政策 (privacy policy) | English only gap |
| 简中 About dropdown | Missing from the SC mega menu gap |
So zh-hk and zh-cn menus are mostly showing fallback links today. That is known, not a bug you need to fix on sight — but it's why those languages look thin.
Rules of thumb
- Always know which language you're editing. The URL prefix tells you.
- A page is not "translated" until WPML links it to its original — a standalone page in another language is invisible to the switcher.
- English copy runs ~30–40% longer than Chinese for the same meaning. Type sizes are tuned down for EN. Check both.
- If a language renders empty where another renders fine, suspect the cache first (section 11), then WPML.
08Building a page
The native-HTML route, where most of your frontend work will happen. These patterns are battle-tested — use them before inventing your own.
Full-bleed layout — the #1 recurring issue
With Elementor off, the page renders through Hello Elementor, whose main.site-main boxes content to 1140px and adds a top gap. Elementor sections used to break out of that; raw HTML doesn't, so you get grey strips down both sides.
Every native page carries a page-specific, unscoped override. Inline <style> only loads on that page, so it's safe:
main.site-main{max-width:none!important;margin:0!important;padding:0!important;width:100%!important}
main.site-main>.page-content{max-width:none!important;margin:0!important;padding:0!important}
.page-content>p:empty{display:none!important;margin:0!important;height:0!important}
That last rule kills the empty paragraph wpautop inserts at the top. Also strip the content and collapse whitespace between tags before pushing, so wpautop has nothing to chew on.
A section background goes on the full-width <section>, never on an inner max-width .wrap — otherwise white strips show at both edges. Pattern: section carries the background, inner .wrap (max-width 1180, margin:0 auto, padding:0 28px) centres the content.
Centring a button
Use a text-align:center wrapper. The theme overrides both align-self:center and auto-margins on flex children — both failed silently in production.
<div class="cta"><a class="btn">了解更多</a></div>
.cta{text-align:center;margin-top:auto} /* centre + pin to bottom of flex column */
.btn{display:inline-block} /* stays inline-block so text-align works */
That margin-top:auto also gives you Elementor-style equal-height cards: image at the top, button pinned to the bottom, regardless of how long the copy is.
Figma-exported pages
Some pages come straight out of Figma as a fixed 1440px canvas with every element absolutely positioned. They scale down with a --hp-scale variable.
The stylesheet reads --hp-scale but nothing sets it, so below 1440px the canvas gets clipped at the right edge. Any such page needs a small script that measures the container and sets the variable. If a design page is cut off on your laptop, this is why.
And a judgement call worth internalising: a Figma design with 20 fixed slots cannot hold 24 real items. When real content outgrows a fixed layout, convert it to a flowing one (grid + shortcode) rather than squeezing or dropping items. We did exactly that to the Solutions panel.
Images and assets
- Deduplicate Figma images by
fills[].imageRef, not by layer name — designers reuse names while each fill is a distinct image. - Upload to the media library with
curl. Python's urllib gets 403'd by the WAF unless you send a browser/curlUser-Agent. - A reused filename gets a
-1suffix — check the URL you got back, don't assume.
09Design system
Navy and orange. The contrast rules below are computed, not opinions — please don't quietly break them.
| Token | Hex | Use |
|---|---|---|
| Navy | #1B365D | Headings, dark sections, ink |
| Orange | #FF9E1B | Primary CTA fill, accents |
| Green | #12BF6D | Hover, success |
| Body gray | #4D4D4D | Body copy |
| Blue | #4285F4 / #1A73E8 | Links, card titles |
| Border | #EAEDF2 | Card borders, dividers |
Orange text on a light background is 1.90:1 — unreadable. Never use it for text, a thin line, or an icon on white. Navy on an orange fill is 5.86:1 and is the correct usage. White on orange is 2.07:1 and is never correct.
Type
Raleway across the site, Arial fallback. Hero H1 50px desktop / 32px mobile at weight 900; H2 36/24 at 800; body 16–18px. Sizes come from clamp-based tokens in :root — --fs-h1, --fs-h2, --fs-lead, --fs-body — so set the token, don't hardcode a px value in a rule.
Cards
Floating white cards, not flat-bordered: 12px radius, 24–32px padding, soft shadow (0 6px 24px rgba(16,40,80,.10)) that deepens and lifts 4px on hover. The image sits inset on a light-blue panel with its own 10px radius — not bleeding to the card edge. Title centred and brand-blue, body left-aligned and grey.
Layout
- Container
max-width:1140px,padding:0 20px - Section padding 80px desktop / 60px mobile
- Fixed transparent header, 90px desktop / ~70px mobile — every hero needs a dark background or overlay, or the white header text vanishes
The live tokens also sit in wp-admin under WP Buddy → Brand Kit.
Accessibility we hold ourselves to
- Never encode meaning by colour alone — add a shape, a glyph, or a label. Roughly one man in twelve has a red–green deficiency.
- Anything clickable shows a pointer cursor, including the little arrow glyphs beside menu text. They're separate elements and are easy to miss.
- Check desktop and mobile on every change. Not optional.
10Figma & Claude → WordPress
A lot of pages here are built with Claude rather than by hand. This is how you get in, and which of the two routes you're on.
Signing in to Claude
We use a shared mc-marketing Claude account for this work — not a personal one, so that projects, skills and history stay with the team.
- Go to magic.mcai.dev and sign in with your Master Concept Google account.
- Find the mc-marketing tile and use it to sign in to Claude. Magic Login holds the password and the one-time code.
- That's it — no password ever gets copied into a file, a note, or a chat.
An internal single page that reads the team's shared logins out of 1Password at the moment you open it. Sign-in is your own Workspace identity, so access can be granted and revoked per person. If a tile is missing, ask Tommy to add it rather than looking for the password elsewhere.
Route A — Figma → WordPress yours
This is the technical route, and the one you'll live in. The figma-to-wp skill drives it:
- Pulls the frame's render, its copy verbatim, its colour and type tokens, its box geometry and its images out of Figma.
- You then write the HTML against those real numbers, one section at a time — the skill does not generate the page for you.
verifyconfirms every string survived and the site's hard rules hold ·auditnames which element is wrong and by how much ·diffscreenshots the result and scores each section against the Figma render ·mobileruns the phone checks the frame can't answer.- Then it uploads the media and creates the page as a draft, with the right slug and Permalink Manager URI.
pullgoes the other way — start from a page that already exists in WordPress.
Figma is read through its API with a read-only token — ask Tommy to set it up for you rather than minting your own. Nothing publishes itself; a draft is always the end state until someone says otherwise.
New pages are built this way now — see the direction note in section 1. If a design arrives and your instinct is to rebuild it in Elementor, that's the habit we're moving away from.
Route B — Claude Design → WordPress colleagues
Non-technical colleagues build a page in Claude Design and hand over a link; Claude publishes it. You should know this route exists because you will be the one who fixes it when the result needs a human.
Read the guide we give colleaguesIt's one page covering what they send, page vs post, which language, category and region, cover image and SEO, the web address, and where it sits in the menu. Worth ten minutes — it's the shared vocabulary everyone here uses when they ask for a page.
Both routes end in the same WordPress, with the same cache, the same four languages and the same no-revisions rule. Nothing about using Claude changes sections 4, 6 or 11.
11Deploy & verify
Two different pipelines depending on what you changed — and one cache that will lie to you.
Plugin code → git
- Edit under
plugin/ php -l <file>— CI doesn't lint yet- Bump
WPBUDDY_VERSIONand add a changelog line inwp-buddy.phpfor anything user-facing - Commit → push to
main - GitHub Actions syncs
plugin/→wp-content/plugins/wp-buddy/on the live site
Watch it land: gh run list --repo mcailab/wpbuddy — or the Actions tab. No FTP, no server login; the push is the deploy.
Page content → REST
Pages are pushed as raw HTML via the REST API using a dedicated user that holds unfiltered_html. The plugin exposes named abilities for the fiddly parts:
| Ability | Does |
|---|---|
mc/set-post-html | Write raw HTML into a post without KSES stripping it |
mc/create-localized-page | Create a page in a given WPML language, optionally linked as a translation |
mc/regenerate-permalink | Rebuild the Permalink Manager URI after a slug change |
mc/find-posts | Search posts/pages across languages |
mc/set-language · mc/set-terms · mc/get-meta · mc/brand-guide | Language assignment, taxonomy, metadata, brand tokens |
SiteGround full-page-caches for logged-out visitors and Cloudflare sits in front of that. A change can be live and still invisible in an incognito window for minutes.
- Query strings do not bust the SiteGround page cache.
?bust=1is not a test. - Logged-in (admin) views bypass the cache — which is why it "works for you" and not for anyone else.
- Clear it properly with 清除 SG 快取 in the admin bar. Re-saving a page also purges that page.
- Check response headers
x-proxy-cacheandcf-cache-statusto see which layer served you.
Screenshots show stale renders. To confirm a change truly landed, read the live DOM or computed style — fetch the page and grep for your markup, or use getBoundingClientRect / computed CSS in the console. Pixels can be cached; the parsed DOM you just fetched cannot.
Preferred workflow
Edit local → review local → push to prod → verify via DOM. Reviewing locally first avoids the entire cache problem, which is why we do it that way round.
12Gotchas
Every one of these has already cost someone here real time. Skim now; come back when something behaves impossibly.
| Symptom | Cause & fix |
|---|---|
| REST response isn't valid JSON | Elementor injects <style> blocks into REST responses. Parse from after the last </style>. |
| Python HTTP call returns 403, curl works | The WAF blocks the default urllib user-agent. Send a browser or curl/8 User-Agent. |
| Menu saves, API lists items, front end is empty | WPML stripped cross-language items from a menu created in the wrong language. Section 6, trap 2. |
| One language looks broken, the others are fine | Almost always the page cache. Confirm before debugging anything else. |
Your inline <script> never runs | Inline scripts in post content are stripped on output. Enqueue through assets/wpbuddy-page.js instead. |
| A CSS-only "fix" that nobody can see | Check the element is actually in the DOM and the rule isn't overridden in the combined stylesheet — and ask whether the page has the JS it needs at all. A panel with no JavaScript can't open no matter how good its styles are. |
| An Elementor popup link breaks | esc_url() mangles #elementor-action hrefs — they're already percent-encoded. Use esc_attr(). |
| A URL 404s after you changed the slug | Permalink Manager stores URIs separately. Regenerate the permalink. |
| Design page clipped on the right | --hp-scale never set. Section 8. |
| A post is missing from a listing page | Wrong region, or wrong category. Section 5. |
| Blank tile in a listing | No cover image on the post. |
You can't find /wp-login.php | WPS Hide Login. Get the real URL from Tommy. |
| You overwrote a page and want it back | Post revisions are disabled. There is no undo. Check Simple History for what changed, and your own local backup for the content. |
13House rules
Short list. Mostly about not surprising the next person.
Code
- Match the surrounding code — its naming, its comment density, its idiom. Don't import a different house style into one file.
- Names are canonical and domain-free: no leaking one customer's or one page's vocabulary into shared code.
- Reusable dynamic content → a shortcode. Never four hardcoded copies, one per language.
php -lbefore you commit.- Bump the version and write the changelog line for anything user-facing.
Working on production
- Back up the current HTML of any page before you overwrite it.
- Review locally first.
- Verify by DOM after pushing.
- If you changed something and can't see it, suspect cache before you suspect your code — then suspect your code.
Asking
Ask early about: anything touching the live header or footer, anything that changes a URL, anything multilingual you're unsure about, and anything that needs a credential. None of those are things to figure out quietly on production.
14Your work & how it reaches you
Three places, and they're in transition. Start with the sheet; learn the other two in your first fortnight.
1 · Your task list start here
Open your task listThe sheet is the live list — work from it, tick things off there, and ask Tommy if a row isn't clear. Everything you need in order to do those tasks is somewhere on this page; the sections above are in roughly the order you'll need them.
2 · Asana — the team board today
Open the Asana boardWhere the wider team's work is tracked today. Requests from the business arrive through Asana Forms rather than as ad-hoc messages — someone fills in the form, it lands on the board as a card with the details already structured. If a colleague asks you for something in chat, the right answer is usually "put it through the form", so it's tracked and nobody loses it.
3 · Wilco → Plane — where we're heading the goal
This is the workflow automation we're building toward, and it's already running on this site. It removes the retyping step entirely:
- Someone spots a problem on a live page and pins feedback directly on it — on the page itself, not in a ticket describing the page.
- Wilco captures the pin with its page, its position, the device, the author and any screenshot.
- One action turns it into a work item in Plane —
MC-1,MC-4,MC-5and so on — tracked, assignable, closable. - Any pin reopens the real page with the pin in place via
?fb=<id>, so you see exactly what they saw.
Four projects are wired up: Master Concept Website, ATS (careers), EIP and Aptitude Test. The website currently has 3 open pins, all already linked to Plane items.
Asana is what we use today; Wilco + Plane is the end state. Don't treat the overlap as confusion — it's a migration in progress, the same as section 1's. When in doubt about where something belongs, ask rather than opening a fourth place to track work.
Known open work on the site
Independent of the sheet, these are live and unfinished today:
- Header preview exists in 繁中 only — the other three need their top-bar labels translated.
- Mobile design for the header: hamburger + tap-to-expand accordion, deliberately different from the desktop hover mega menu.
- Partners mega menu — ~40 items, needs the brand logos uploaded first.
- The 24 solution pages don't exist in zh-hk at all, and only 4 of 24 exist in 简中.
- Swap the live ElementsKit Solutions panels over to render from the
mega-solutionsmenu. - 12 unused footer menus (Footer Solutions / Company / Customers × 4) left over from a dropped layout — pending a decision to delete.
15Glossary & contacts
Terms that get used around here as if everyone already knows them.
| Term | Means |
|---|---|
| AI page | A page built as hand-written native HTML + CSS, with Elementor switched off. Not generated at runtime. |
| WP Buddy | Our own WordPress plugin — the only version-controlled part of the site. |
| Ability | A named operation the plugin exposes over the API, e.g. mc/set-post-html. |
| Content Tree | WP Buddy's live sitemap screen — pages, posts and templates as a tree. |
| Magic Login | Our shared-login page at magic.mcai.dev. Reads team credentials out of 1Password; you sign in as yourself. |
| mc-marketing | The shared Claude account used for site work. |
| hp-page | A Figma-exported page: fixed 1440px canvas, absolutely positioned elements. |
| ElementsKit | The Elementor add-on that provides the header, nav and mega menu. |
| Mega panel | The dropdown of a mega-menu item — a separate Elementor document. |
| Code Snippets | PHP snippets stored in the database, managed in wp-admin, not in git. |
| SG cache | SiteGround's full-page cache. Clear it from the admin bar. |
| 繁中 / 简中 / 香港 | zh-hant (Taiwan) / zh-cn (Simplified) / zh-hk (Hong Kong). |
Where to look things up
| For | Go to |
|---|---|
| Plugin architecture, deployment, access | wp-buddy/README.md |
| Page layout patterns and fixes | AI-PAGE-PATTERNS.md (in the WordPress project folder) |
| Colours, type, buttons, spacing | wp-buddy/docs/WP-Buddy-Design-Guide.md · Brand Kit |
| The live sitemap | WP Buddy → Content Tree |
| Deploy status | GitHub Actions |
| How colleagues ask for a page | Claude Design to WordPress |
| Who changed what on the live site | Simple History |
| Shared team logins | Magic Login |
| Everything else | Tommy |