@typeroll/mcp-server 0.45.64 → 0.45.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -115,6 +115,22 @@ shortening, adding a CTA, tweaking SEO description.
115
115
  Don't `update_page status:"published"` without an explicit "looks
116
116
  good, publish it" from the user. Same for `trigger_deploy`.
117
117
 
118
+ ## Instead of the content workflows
119
+
120
+ `start_workflow` types `content_generation` and `content_improvement` run the
121
+ model with the Organization's own AI key. On a Site without that access they
122
+ fail with `failure_code: "ai_not_enabled"`; don't retry them. Do the work with
123
+ this recipe and tell the user you did it yourself:
124
+
125
+ - **Generate a page** (`content_generation { topic, tone?, audience? }`):
126
+ steps 1–5 for that topic, created as a draft.
127
+ - **Improve content** (`content_improvement { limit? }`): `list_pages
128
+ status="published"` and `batch_read_pages`, rank the pages by thin text,
129
+ missing `seo_title`/`seo_description` and age (not updated for a year), and
130
+ rewrite the weakest few (five by default) in the site's voice. Keep facts,
131
+ URLs and structure; leave the rewrites as unsaved drafts and show previews
132
+ before anything is saved or published.
133
+
118
134
  ## SEO conventions worth knowing
119
135
 
120
136
  - **`kind: "article"`** for blog posts and news. Switches to
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: tr-edit-site
3
- description: Edit or create Typeroll pages with a person’s usual AI assistant. Confirm one site, find the right page, preview changes and save with permission.
3
+ description: Edit or create Typeroll pages with a person’s usual AI assistant. Confirm one site, find the right page, handle everyday requests (page links, images, menus, site-wide changes, settings, analytics, structured data), preview changes and save with permission.
4
4
  ---
5
5
 
6
6
  # Work on one Typeroll site
@@ -33,6 +33,93 @@ description: Edit or create Typeroll pages with a person’s usual AI assistant.
33
33
  draft durable; saving and deploying are different actions. Publish only
34
34
  when authorized and readiness passes. Report the actual result and URL.
35
35
 
36
+ ## Everyday requests
37
+
38
+ Read the page or global block first, change only what was asked, and keep
39
+ everything else. When several pages fit the description, ask before editing.
40
+
41
+ **Addresses and preview links.** `list_pages` and `read_page` return each
42
+ page's `url` (its path). The public address is `get_site` → `urls.production`
43
+ plus that path, and it serves the page only after it is published and
44
+ deployed. Never invent a domain; when there is none, say why and offer a
45
+ preview instead: `get_preview_link page_id=… include_working_copy:true` shows
46
+ drafts and unpublished pages. Mint one link and reuse it while iterating.
47
+
48
+ **Images the user provides.** Upload first: a URL with `upload_media_from_url`,
49
+ a local file with `create_upload_url` (see `tr-images`); `list_media` finds
50
+ existing ones. Use the returned CDN URL exactly. With a named target, place it
51
+ there (`add_block` with `core/image` on a block page; an `<img>` with `alt` in
52
+ `html_content` on an HTML page). Without one, ask what the image is for. Ask
53
+ for alt text when none was given. Afterwards say in one sentence where it
54
+ landed; to answer "has it been added?", read the page again rather than
55
+ trusting the conversation.
56
+
57
+ **Small edits and new pages.** Block pages: `get_page_blocks`, then
58
+ `update_block` on the one block. HTML pages: `read_page`, then `update_page`
59
+ with the complete `html_content`, never a fragment. New pages: `create_page`
60
+ (draft by default) with a realistic start: heading, introduction and one
61
+ section. A Page template is `update_page` `template` (an allowed ID, or null
62
+ for the content type default). `discard_working_copy` throws an unsaved draft
63
+ away. Publishing means saving the draft, `update_page` `status: "published"`
64
+ (applies immediately) and, when the user wants it live now, `trigger_deploy`.
65
+
66
+ **Site-wide changes are composition, not a series of page edits.** "Change
67
+ every hero", "a CTA on every product page", "our phone number in every
68
+ footer":
69
+
70
+ 1. `list_partials` shows what is already shared: header, footer and free
71
+ global blocks.
72
+ 2. If a fitting global block exists, edit it once. Run
73
+ `find_pages_using_block` first and tell the user the blast radius ("this
74
+ block is on 8 pages and one template — go ahead?"); a header or footer
75
+ among the results means every page.
76
+ 3. If nothing fits, propose a global block: `make_block_global` turns an
77
+ existing block into one, or `create_free_block` with a kebab-case ID. Place
78
+ it with `core/global_block` on block pages or `<x-include name="…" />` on
79
+ HTML pages. Layout that every Page of a type shares belongs in its Page
80
+ template (`tr-page-template`).
81
+ 4. Edit pages one by one only for content that really differs per page, such
82
+ as each page's SEO description. Confirm the page list first.
83
+
84
+ "All 23 pages" or "every page" is a strong hint for a global block. Say what
85
+ you will do and wait for confirmation before editing many pages.
86
+
87
+ **Extract while you sweep.** Even when the user asked for per-page edits,
88
+ pause when the same content is about to land on a third page and offer to
89
+ make it a global block instead ("I'm adding the same CTA to several pages —
90
+ make it a reusable `newsletter-cta` block so future edits happen once?").
91
+ Check `list_partials` and `find_pages_using_block` first so you extend an
92
+ existing block rather than create a duplicate.
93
+
94
+ **Menu and footer.** `read_partial partial_id="header"`. In a block header,
95
+ change the `core/navigation` block's `links` with `update_block`; in an HTML
96
+ header, add the `<a href="/pricing">Pricing</a>` to the nav and write back the
97
+ complete HTML with `update_partial`. The footer works the same way. Building
98
+ either from scratch: `tr-header-footer`.
99
+
100
+ **Settings, not page edits.** Brand colors, fonts, logo, icons and contact
101
+ details are `update_site_settings` (admin), for example `colors.primary`. A new
102
+ logo must be uploaded first. Analytics, advertising pixels and chat widgets
103
+ are set by ID in the Integrations app (`read_app app_id="integrations"`, then
104
+ `update_app`), not pasted as scripts; turn on the cookie banner
105
+ (`update_site_settings` `cookie_consent: { enabled: true }`) so they wait for
106
+ consent. Only a tag the Integrations catalog lacks goes in
107
+ `cookie_consent.scripts_optional`. Both reach the site with the next deploy.
108
+
109
+ **Redirects, forms, listings.** A renamed URL gets `create_redirect` (301
110
+ unless the user says otherwise); changing a page's `path` creates one on save.
111
+ Place forms with a `core/form` block or `<x-form id="…" />`, never a
112
+ hand-written `<form>` (`tr-forms`). Lists of articles are a `core/page_list`
113
+ block, never hand-written HTML (`tr-blog`).
114
+
115
+ **Structured data.** For an FAQ, recipe or event page use `add_faq_schema`,
116
+ `add_recipe_schema` or `add_event_schema` instead of hand-writing `json_ld`;
117
+ see `tr-seo`.
118
+
119
+ **When something is out of reach.** If a tool refuses, tell the user what they
120
+ can do about it, not only the error. When no tool covers a request (billing,
121
+ for example), say so plainly and point to the relevant portal page.
122
+
36
123
  ## Compact discovery
37
124
 
38
125
  Find tools with `search_tools`, inspect one schema with `describe_tool`, then
@@ -5,6 +5,10 @@ description: Use when the user wants to import or migrate content from a non-Wor
5
5
 
6
6
  # Import content from a non-WordPress site
7
7
 
8
+ **Who runs this:** this recipe is for the user's own AI agent (Claude Code, Codex or
9
+ another MCP client) working through MCP and the public API. The portal's built-in
10
+ AI assistant has no migration tools: it does not import, convert or verify sites.
11
+
8
12
  **Before bulk conversion:** read `tr-migration-evidence` with `read_skill`.
9
13
  Complete its source baseline and one verified prototype per active template.
10
14
  Read target content to protect edits, not to justify accidental target defaults.
@@ -194,8 +198,11 @@ get_deploy_status job_id=<id>
194
198
  several. Fix it.
195
199
  - **Squarespace/Wix forms.** They won't work after import — the backend
196
200
  is vendor-locked. Create a Typeroll form instead: `create_form`.
197
- - **Analytics/tracking code.** If the source has GA4 or similar, don't
198
- copy it into pages. Set it via `update_site_settings scripts_head="..."`.
201
+ - **Scripts and tracking.** Never copy the source's JavaScript. Carry
202
+ analytics and advertising tags (GA4, GTM, Meta Pixel and others) over by
203
+ ID in the Integrations app, with the cookie banner enabled so they wait for
204
+ consent; never paste the vendor snippet into `scripts_head`. See
205
+ tr-migration-evidence, "Scripts, tracking and consent".
199
206
  - **Videos.** YouTube/Vimeo embeds are fine (`<iframe>` is allowed).
200
207
  Hosted MP4s need re-uploading if the source URL won't persist.
201
208
 
@@ -5,6 +5,10 @@ description: Migrate an existing Astro site, including Astro Content Collections
5
5
 
6
6
  # Migrate an Astro site
7
7
 
8
+ **Who runs this:** this recipe is for the user's own AI agent (Claude Code, Codex or
9
+ another MCP client) working through MCP and the public API. The portal's built-in
10
+ AI assistant has no migration tools: it does not import, convert or verify sites.
11
+
8
12
  **Before bulk conversion:** read `tr-migration-evidence` with `read_skill`.
9
13
  Complete its source baseline and one verified prototype per active template.
10
14
  Read target content to protect edits, not to justify accidental target defaults.
@@ -50,6 +54,9 @@ assume that a filename alone determines the production URL.
50
54
  - Browser scripts, integrations and server-rendered endpoints need separate
51
55
  review. A static Page cannot inherit a private server runtime by copying its
52
56
  source text. Configure the supported Forms/Extension runtime explicitly.
57
+ Do not copy client scripts; analytics and advertising tags move to the
58
+ Integrations app behind the cookie banner (tr-migration-evidence, "Scripts,
59
+ tracking and consent").
53
60
 
54
61
  Create templates with `create_page_template`, types with `create_content_type`,
55
62
  then one `create_page` per source record. Use returned Page IDs, not source IDs
@@ -5,6 +5,10 @@ description: Use when migrating SEVERAL sites at once — a WordPress multisite
5
5
 
6
6
  # Migrate a multisite / multi-domain family to Typeroll
7
7
 
8
+ **Who runs this:** this recipe is for the user's own AI agent (Claude Code, Codex or
9
+ another MCP client) working through MCP and the public API. The portal's built-in
10
+ AI assistant has no migration tools: it does not import, convert or verify sites.
11
+
8
12
  **Before bulk conversion:** read `tr-migration-evidence` with `read_skill`.
9
13
  Complete its source baseline and one verified prototype per active template.
10
14
  Read target content to protect edits, not to justify accidental target defaults.
@@ -163,6 +167,11 @@ language and attribution. Use authorized synthetic tests with a safe recipient;
163
167
  record delivery UNVERIFIED when it cannot be tested safely. Never create real
164
168
  leads or send mail to third parties as a routine migration test.
165
169
 
170
+ Scripts follow tr-migration-evidence, "Scripts, tracking and consent": copy no
171
+ source JavaScript, and carry each market's own analytics and advertising IDs
172
+ over in that site's Integrations app with its cookie banner enabled. Never
173
+ reuse one market's tracking IDs on another.
174
+
166
175
  ## Phase 5 — Redirects for everything you didn't preserve
167
176
 
168
177
  Work the coverage report, not your memory:
@@ -271,6 +280,7 @@ new canonical build and is not an inventory-only operation):
271
280
  - [ ] Complete `verify_migration_urls` → 0 `missing`, 0 `broken_redirect`, 0 `error`, 0 untested variants
272
281
  - [ ] `record_migration_seo_acceptance` is accepted for the latest deploy
273
282
  - [ ] `get_migration_launch_report` → `launch_ready: true`
283
+ - [ ] No source JavaScript copied; analytics/advertising via the Integrations app with the cookie banner on (`scripts.status: "clean"` in the launch report)
274
284
  - [ ] hreflang cluster written on both/all sides, absolute, final domains
275
285
  - [ ] `language` set on the site; `<html lang>` correct in the deployed HTML
276
286
  - [ ] Internal links rewritten (no lingering absolute links to the old domain)
@@ -5,6 +5,10 @@ description: Use when the user asks to migrate a WordPress site to Typeroll, men
5
5
 
6
6
  # Migrate from WordPress to Typeroll
7
7
 
8
+ **Who runs this:** this recipe is for the user's own AI agent (Claude Code, Codex or
9
+ another MCP client) working through MCP and the public API. The portal's built-in
10
+ AI assistant has no migration tools: it does not import, convert or verify sites.
11
+
8
12
  **Before bulk conversion:** read `tr-migration-evidence` with `read_skill`.
9
13
  Complete its source baseline and one verified prototype per active template.
10
14
  Read target content to protect edits, not to justify accidental target defaults.
@@ -146,6 +150,9 @@ a. Fetch from WP. Prefer the helper plugin's authenticated endpoint
146
150
  b. Clean the HTML. Strip Elementor / Gutenberg / Breakdance class
147
151
  soup. Drop empty `<div>` and `<span>` wrappers. Keep semantic tags,
148
152
  tables, iframes from known hosts (YouTube / Vimeo / Calendly).
153
+ Remove every `<script>`: plugin and theme JavaScript is never copied.
154
+ Analytics and advertising tags move to the Integrations app behind the
155
+ cookie banner (tr-migration-evidence, "Scripts, tracking and consent").
149
156
 
150
157
  c. Migrate referenced images with `upload_media_from_url`. The customer's
151
158
  transfer Worker copies and verifies them directly in R2. Use the returned
@@ -291,6 +298,11 @@ get_deploy_status job_id=<id> # poll
291
298
  - **Image bandwidth.** R2 upload is metered. Use `find_pages_matching`
292
299
  contains="<old-domain>" on already-imported content to spot images
293
300
  that weren't transferred.
301
+ - **Plugin JavaScript.** Never copy scripts from plugins, the theme or
302
+ WordPress core into settings, pages, partials or block types, and never
303
+ copy the cookie plugin. Carry analytics and advertising over by ID in the
304
+ Integrations app with `cookie_consent.enabled: true`. The launch report
305
+ fails on copied source scripts and on tracking outside consent.
294
306
  - **WP-specific JSON-LD** (Yoast, Rank Math) is usually wrong after a
295
307
  redesign because it references old URLs. Strip it; let Typeroll
296
308
  emit fresh Article/Page schemas via `kind: 'article'` + `author`.
@@ -5,6 +5,10 @@ description: Source-first design baseline, native capability mapping and evidenc
5
5
 
6
6
  # Migration evidence contract
7
7
 
8
+ **Who runs this:** this recipe is for the user's own AI agent (Claude Code, Codex or
9
+ another MCP client) working through MCP and the public API. The portal's built-in
10
+ AI assistant has no migration tools: it does not import, convert or verify sites.
11
+
8
12
  Use this shared contract with WordPress, Astro, URL and multisite recipes.
9
13
  Default to preserving the source appearance and behavior. A redesign requires
10
14
  explicit scope. A partly migrated target is not the design reference.
@@ -115,6 +119,33 @@ interaction and conversion separately; only use an authorized synthetic mode and
115
119
  safe recipient. Unavailable delivery remains UNVERIFIED. No real leads or mail
116
120
  to third parties merely to fill a checklist.
117
121
 
122
+ ## Scripts, tracking and consent
123
+
124
+ Do not copy JavaScript from the source site. WordPress plugins and themes
125
+ inject their own runtime: jQuery, sliders, lightboxes, form and cookie
126
+ plugins, page builders (Elementor, Breakdance, Divi), emoji and AJAX calls to
127
+ `admin-ajax.php` or `/wp-json/`. It loads from, or posts to, a site that is
128
+ about to be switched off. Inventory every `<script>` on representative source
129
+ pages (head and body, inline and external, and which plugin or theme it
130
+ belongs to), then decide each one:
131
+
132
+ | Source script | Decision |
133
+ | --- | --- |
134
+ | WordPress core, theme or plugin runtime | Never copy. Rebuild what it did with native blocks, Forms or settings, or report a platform gap (see "Report platform gaps"). |
135
+ | Cookie plugin (CookieYes, Complianz, Cookiebot, Borlabs, …) | Never copy. Enable the site's cookie banner (`cookie_consent.enabled: true`) with Swedish or local text and the privacy policy URL. |
136
+ | Analytics or advertising tag in the Integrations catalog (GA4, GTM, Meta Pixel, LinkedIn, TikTok, Hotjar, Clarity, Pinterest, Snap, Reddit, X, Microsoft Ads, HubSpot, Plausible, Fathom, Matomo) | Carry over the ID only: enable the Integrations app with the source's ID (`list_apps`, `update_app`). Enable the cookie banner; analytics and advertising integrations wait for the visitor's consent. Never paste the vendor snippet. |
137
+ | Tracking tag the catalog does not cover | Only with the owner's approval, in `cookie_consent.scripts_optional` with the banner enabled. Never in `scripts_head`, `scripts_body_end`, `scripts_necessary`, pages or partials. |
138
+ | Partner widget or embed the page needs to work | Prefer a native block or an iframe from an allowlisted host. Keep custom code minimal, record why, and do not load it from the source site. |
139
+
140
+ Ask the owner to confirm the analytics IDs; never invent or reuse one from
141
+ another market. Before launch, `get_migration_launch_report` must show
142
+ `scripts.status: "clean"`: it fails on copied source-platform scripts
143
+ (`source_runtime_script`), tracking outside consent
144
+ (`tracking_outside_consent`) and analytics or advertising integrations without
145
+ the banner (`tracking_without_consent_banner`). In the hosted preview, check
146
+ that no request goes to the source host or `/wp-content/`, no tracking request
147
+ fires before consent, and the tags fire after "accept all".
148
+
118
149
  ## Evidence record (repeat per recipe, viewport and state)
119
150
 
120
151
  - Source URL/date and target URL; Page/template IDs; exact publication ID.
@@ -34,7 +34,13 @@ read_app_documentation when needed; do not bundle private app guides locally.
34
34
  No Site yet? Use hosted MCP with an Organization key and create_site, or create it
35
35
  in the portal. To start from an AI site plan instead of a blank Site, use
36
36
  create_site_and_plan, poll get_workflow and approve its structure review only
37
- with the user's consent. Read back its ID before editing. Use one explicit Site/Version for
37
+ with the user's consent. That AI plan needs the Organization's own portal AI
38
+ key for new Sites; without it the call answers `403 ai_not_enabled` and the
39
+ `site_planning` workflow fails with `failure_code: "ai_not_enabled"`. Then plan
40
+ it yourself: `create_site`, propose the site name, tagline and page list (title,
41
+ slug, purpose, target keywords) from the business description, get the
42
+ user's approval, and build with this recipe. Tell the user you planned it
43
+ yourself; don't retry the workflow. Read back its ID before editing. Use one explicit Site/Version for
38
44
  related operations. Larger changes to an existing site should use a branch.
39
45
 
40
46
  Before importing content or a media library, require get_import_readiness to pass.
package/skills/tr-seo.md CHANGED
@@ -36,7 +36,8 @@ read_site_settings
36
36
  ```
37
37
 
38
38
  For each page, check:
39
- - Is `seo_title` set? (if not, Google uses `title` + suffix — often fine)
39
+ - Is `seo_title` set? (if not, Google uses `title` + suffix — often fine;
40
+ aim for 50–60 characters, longer gets truncated)
40
41
  - Is `seo_description` set? (150–160 chars, unique per page, includes keywords)
41
42
  - Is `og_image` set for the homepage and key landing pages?
42
43
  - Does the page have exactly one `<h1>`?
@@ -79,6 +80,20 @@ update_page page_id="home" patch={
79
80
  }
80
81
  ```
81
82
 
83
+ ### 3b. URL and article conventions
84
+
85
+ When creating or moving pages:
86
+
87
+ - Slugs are lowercase kebab-case: `our-services`, not `Our_Services`.
88
+ - Reflect hierarchy in the address. A team member lives at `/team/jane-doe`
89
+ (set `path`, or use a content type whose `route_template` adds the
90
+ prefix), not at `/jane-doe`. Breadcrumbs and their BreadcrumbList schema
91
+ follow the resolved route.
92
+ - Blog posts and news get `kind: "article"` and an `author`: that emits
93
+ Article JSON-LD and `og:type=article`. No author means no author in the
94
+ rich result.
95
+ - Give shared pages, especially articles, their own `og_image`.
96
+
82
97
  ### 4. Add Open Graph images
83
98
 
84
99
  Set `og_image` on pages that get shared on social media. If the site has
@@ -116,6 +131,37 @@ repeating it on every page (`null` clears it):
116
131
  update_site_settings organization={"name":"Acme Studio","logo":"<cdn_url>","same_as":["https://www.linkedin.com/company/acme"]}
117
132
  ```
118
133
 
134
+ **FAQ, recipe and event pages have tools.** They validate the input, build
135
+ the schema.org JSON-LD and merge it into the page's `json_ld` (a node of the
136
+ same type is replaced, anything else is kept). Use them instead of
137
+ hand-writing JSON-LD, and copy the content from what the page visibly shows:
138
+
139
+ ```
140
+ add_faq_schema page_id="faq" items=[
141
+ {"question": "Do you deliver on weekends?", "answer": "Yes, Saturdays 9–15."}
142
+ ]
143
+ add_recipe_schema page_id="kanelbullar" name="Kanelbullar"
144
+ ingredients=["500 g vetemjöl", "2 tsk kanel"] instructions=["Blanda degen.", "Grädda i 225 °C."]
145
+ prep_time="PT1H30M" cook_time="PT10M" recipe_yield="24 bullar" image_url="<cdn_url>"
146
+ add_event_schema page_id="sommarkonsert" name="Sommarkonsert"
147
+ start_date="2026-06-12T19:00:00+02:00" location_name="Stadshuset"
148
+ location_address="Storgatan 1, Sundsvall" offers_price=250 offers_currency="SEK"
149
+ ```
150
+
151
+ Rules they enforce: FAQ needs at least one question with an answer; a recipe
152
+ needs a name, ingredients and steps, durations are ISO 8601 (`PT30M`) and
153
+ URLs absolute; an event needs a name and an ISO 8601 `start_date` (include
154
+ the UTC offset), `end_date` not before it, and a price needs
155
+ `offers_currency`. Read the returned `warnings`: a recipe without an image or
156
+ an event without a location is valid but not eligible for Google's rich
157
+ results. Like other content writes they land in the draft — `save: true` or
158
+ `commit_working_copy` when approved.
159
+
160
+ FAQ markup only belongs on a page that visibly presents those questions and
161
+ answers; Google penalizes FAQ markup for content the page does not show.
162
+
163
+ For other types write `json_ld` yourself:
164
+
119
165
  ```
120
166
  update_page page_id="home" patch={
121
167
  "json_ld": "{\"@context\":\"https://schema.org\",\"@type\":\"LocalBusiness\",\"name\":\"Acme Studio\",\"url\":\"https://acme.se\",\"telephone\":\"+46812345\",\"address\":{\"@type\":\"PostalAddress\",\"streetAddress\":\"Drottninggatan 1\",\"addressLocality\":\"Stockholm\",\"postalCode\":\"111 51\",\"addressCountry\":\"SE\"}}"
@@ -124,16 +170,25 @@ update_page page_id="home" patch={
124
170
 
125
171
  **Important:** JSON-LD goes in the `json_ld` field as a JSON *string*
126
172
  (not a nested object). The renderer injects it inside
127
- `<script type="application/ld+json">`.
173
+ `<script type="application/ld+json">`. To keep several nodes on one page,
174
+ store them as `{"@context":"https://schema.org","@graph":[…]}` — the
175
+ `add_*_schema` tools do this for you. Read the page first: an update
176
+ replaces the whole `json_ld` value.
128
177
 
129
178
  Common schemas worth adding:
130
179
  - Homepage: `LocalBusiness` or `Organization`
131
180
  - About: `AboutPage`
132
181
  - Contact: `ContactPage`
133
182
  - Blog articles: auto-generated from `kind:"article"` + `author`
134
- - Events: `Event` with `startDate`, `location`
183
+ - FAQ, recipe and event pages: the `add_*_schema` tools above
135
184
  - Products: `Product` with `offers`
136
185
 
186
+ **Instead of the `schema_markup` workflow.** That workflow runs the model with
187
+ the Organization's own AI key; on a Site without that access it fails with
188
+ `failure_code: "ai_not_enabled"`. Don't retry it. Do the same work here: read
189
+ each published page, pick the one type it genuinely represents (or none),
190
+ apply the tool or `json_ld` above, and tell the user you did it yourself.
191
+
137
192
  ### 6. robots.txt
138
193
 
139
194
  The default robots.txt allows all crawlers. Update if needed:
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: tr-starter-design
3
+ description: Reference for the default design new Typeroll sites start with — CSS variables, spacing, radii, container width, header and footer skeletons. Read it when a site is blank or clearly follows these conventions and you need new markup or CSS to fit in; skip it for sites with their own design.
4
+ ---
5
+
6
+ # Starter design system
7
+
8
+ A reference for the *default* design that ships with new Typeroll sites.
9
+ The customer may have replaced it — always inspect the actual header partial
10
+ (`read_partial partial_id="header"`) and an existing page before assuming any
11
+ of this is in use. On a site with its own design, mirror what is there.
12
+
13
+ ## CSS variables
14
+
15
+ Colors (set in site settings `colors`; each key becomes `--color-<key>`,
16
+ `text_light` becomes `--color-text-light`):
17
+ --color-primary brand CTAs, links, accents
18
+ --color-secondary supporting brand color (rarely used)
19
+ --color-accent a third highlight (badges, callouts)
20
+ --color-background page background (the body)
21
+ --color-surface slightly raised areas (header, footer, cards)
22
+ --color-text body copy + headings
23
+ --color-text-light secondary text (captions, meta, footer fine-print)
24
+
25
+ For subtle borders/dividers that follow the text color without being heavy,
26
+ use `color-mix(in srgb, var(--color-text) 8%, transparent)` (6% for very soft).
27
+
28
+ Spacing scale:
29
+ --spacing-xs (0.25rem) --spacing-sm (0.5rem) --spacing-md (1rem)
30
+ --spacing-lg (2rem) --spacing-xl (4rem)
31
+
32
+ Layout:
33
+ --container-medium (1080px) Center page content with
34
+ `max-width: var(--container-medium); margin: 0 auto; padding: var(--spacing-md);`
35
+ --container-narrow (720px) and --container-wide (1400px) exist for prose
36
+ and wide layouts.
37
+
38
+ Radii:
39
+ --radius-sm (0.25rem) --radius-md (0.5rem) --radius-lg (1rem)
40
+
41
+ Typography (set in site settings `fonts`):
42
+ --font-heading Use for h1-h6 and brand wordmark
43
+ --font-body Default for everything else
44
+ --font-size-base (the rem baseline)
45
+
46
+ Block-mode pages get these through the blocks and named styles; reach for the
47
+ variables in custom CSS, HTML-mode pages and template markup.
48
+
49
+ ## Default header skeleton
50
+
51
+ Surface-tinted bar with a hairline bottom border. Brand text on the left
52
+ in the heading font, bold, slight negative letter-spacing. Nav on the
53
+ right. Last nav item is typically a primary CTA: `background:
54
+ var(--color-primary); color: var(--color-background); border-radius:
55
+ var(--radius-md)`.
56
+
57
+ ## Default footer skeleton
58
+
59
+ Three-column responsive grid (brand+tagline / Site links / Get in touch),
60
+ then a fine-print row with copyright + Typeroll attribution. Top border
61
+ uses the same color-mix() recipe as the header.
62
+
63
+ ## When to use this
64
+
65
+ - A brand new site, or one where the header partial still matches this
66
+ layout.
67
+ - A page or block where the customer wants something that "fits the rest
68
+ of the site" and the rest follows these conventions.
69
+
70
+ ## When NOT to use this
71
+
72
+ - The customer has a totally different design (e.g. dark mode, custom
73
+ utility classes, no CSS variables, migrated theme).
74
+ - The customer says "use this brand color" — honor their literal request
75
+ instead of substituting a CSS variable.
76
+ - Mid-edit on an existing page that doesn't follow these conventions —
77
+ match what's already there.
78
+ - Choosing a new palette or fonts is brand work (the MCP recipe `tr-brand`),
79
+ not this reference.