Skip to content

docs: document removal of the 1.5.0 theme bridge workaround - #432

Open
interacsean wants to merge 12 commits into
mainfrom
docs/1646-remove-theme-bridge-workaround
Open

docs: document removal of the 1.5.0 theme bridge workaround#432
interacsean wants to merge 12 commits into
mainfrom
docs/1646-remove-theme-bridge-workaround

Conversation

@interacsean

Copy link
Copy Markdown
Contributor

Closes tailor-inc/platform-planning#1646

Why

Apps that adopted the 1.5.0-era workaround — pasting the @theme inline block, @custom-variant dark (&:is(.dark *)), and a copy of the palette into their entry CSS while styles was missing the bridge — keep those definitions winning on 1.6+. AppShell imports its palette inside layer(theme.defaults) (theme.css:24) and consumer CSS is unlayered, so the stale copy beats it regardless of specificity or source order.

Nothing warns. The build succeeds, and dark mode breaks silently: surfaces added to AppShell since the copy was made have no dark value at all, so they render light-mode colours in dark mode — white text on white cards, unreadable disabled inputs. The reporter needed a full investigation to trace the symptoms back to their own 1.5.0-era CSS, and expects other projects that took the same workaround to be sitting on it.

There was no migration or upgrade documentation anywhere in docs/, so this had to be written rather than amended.

What changed

docs/concepts/styling-theming.md

  • New Overriding tokens and cascade layers — AppShell's palette lives in a cascade layer, so consumer declarations win by design (that's what makes :root { --radius: … } work without !important). Documents the flip side: a partial palette copy silently pins whatever it defines while everything else tracks AppShell, and the two halves drift apart on upgrade. Two rules: override only the tokens you mean to, and mirror every :root override in .dark.
  • New Upgrading from 1.5.x: remove the theme bridge workaround — the three failure modes (unlayered palette, missing dark values on newer surfaces, :is(.dark *) vs :where(.dark, .dark *)), a grep to detect it, an explicit delete list, before/after entry CSS, and the reporter's own measured values as a verification check (--card #fff#171717, --input #e5e5e5rgba(255,255,255,.15), --destructive #dc2626#f87171).
  • Warning and anchor link near the top so an upgrader hits it on the first screen.
  • Drive-by: the palette example had @import "tailwindcss" last and a duplicated styles line, contradicting the example above it.

catalogue/src/fundamental/design-system.md (§1, §2 — source of the app-shell-patterns skill shipped in the npm package)

  • Stops telling apps to import @tailor-platform/app-shell/theme.css, a deprecated no-op shim since 1.6.0.
  • Dark mode documented as the .dark class, not [data-theme="dark"] — AppShell never sets that attribute.
  • Override example uses tokens that actually exist (--primary, --background), set in both modes.

Plus a patch changeset, since the catalogue edit changes files distributed in the package (files: skills/**).

Notes for the reviewer

  • examples/vite-app/src/index.css is already correct and is cited in the docs as the reference shape — no example app changes were needed.
  • §4 of design-system.md is deliberately untouched. Its token table (--color-surface-1, --color-fg-default, --space-*, …) documents a token set app-shell has never shipped, so agents reading the bundled skill emit bg-surface-1 / text-fg-muted classes that silently resolve to nothing. That's already tracked as tailor-inc/platform-planning#1647, whose fix is mechanical generation of the table plus a CI drift check — out of scope here. This PR does incidentally close two of that ticket's four bullets (§1's theme.css import, the [data-theme="dark"] claim).
  • The issue's "emit a build-time warning" ask is not implemented. It would mean scanning consumer CSS from @tailor-platform/app-shell-vite-plugin, which is opt-in, routing-focused, and reaches no Next.js consumer — poor coverage for real complexity, and it only fires on a rebuild when the people at risk have already upgraded. The reporter offered the documented-detection fallback themselves (「または検出手順をドキュメント化する」); that's the grep recipe above.

Verification

pnpm type-check (9 tasks), pnpm lint (0 warnings / 0 errors), pnpm test (76 files, 1430 tests), pnpm fmt — all pass. Regenerated the skill via catalogue/scripts/generate-skill.mjs and confirmed the output reflects the edits; check-generated-skills.mjs passes. No runtime code changed, so there's nothing to verify in a browser.

🤖 Generated with Claude Code

Apps that adopted the 1.5.0-era workaround — pasting the @theme inline
block, @custom-variant dark, and a copy of the palette into their entry
CSS — keep those definitions winning over AppShell's own palette on 1.6+,
because AppShell imports it inside layer(theme.defaults) while consumer
CSS is unlayered. Nothing warns, and dark mode breaks silently.

- docs/concepts/styling-theming.md: add "Overriding tokens and cascade
  layers" and "Upgrading from 1.5.x", covering detection, removal, the
  correct minimal entry CSS, and how to verify the fix. Fix the import
  order in the palette example while here.
- catalogue design-system.md (source of the shipped app-shell-patterns
  skill): stop instructing apps to import the deprecated theme.css no-op
  shim, document dark mode as the .dark class rather than
  [data-theme="dark"], and warn against copying the palette.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@interacsean

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

API Design Review completed successfully!

API Design Review: no in-scope files changed. All 3 changed files are documentation or changeset (.changeset/gentle-moons-repeat.md, catalogue/src/fundamental/design-system.md, docs/concepts/styling-theming.md). No packages/**/*.ts, packages/**/*.tsx, or packages/**/package.json files were modified — review scope does not apply to this PR.

interacsean and others added 3 commits August 12, 2026 12:46
Adversarial review found the migration note named the wrong version and
would have broken apps that followed it.

- The bridge came back in 1.7.0 (ff30974), not 1.6.0. 1.6.0 only restored
  theme.css as a no-op shim; theme.bridge.css does not exist at 1.6.1.
  On 1.5.0-1.6.1 the workaround is load-bearing, so the section now says
  to upgrade to >=1.7.0 before deleting anything.
- Recommend :root / :root.dark for overrides. Only the default palette is
  layered; cream and bloom are imported unlayered and define dark values
  on :root.dark, which outranks a bare .dark, so the previously
  documented .dark override silently lost on branded palettes.
- The delete list omitted the *-foreground pairs (plus --status-*,
  --alert-*, --semantic-shadow-*) — the very tokens behind white-on-white
  text. Say "all of it" rather than enumerating a partial set.
- The detection grep had no term for the theme.css import and hardcoded
  src/, missing app/ and styles/. Broadened, and dropped the false
  all-clear that followed it.
- Verification quoted hex values that never appear: custom properties
  compute to their authored token stream, so getPropertyValue("--card")
  echoes the copy either way. Check a Card's rendered background-color.
- design-system.md §4 still attributed tokens to theme.css, contradicting
  §1 two sections earlier in the same shipped skill.

Also tightened both new sections: dropped the redundant re-derivation of
the layer mechanism, the 24-line "before" block, and one H3 level.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- The detection grep's `^ *--` term matched every custom property in the
  tree and `grep -r .` walked node_modules: on a fixture with just two
  AppShell palette files installed, 163 of 168 hits were library CSS the
  reader must not touch — under a sentence saying every hit is
  actionable. Now matches AppShell-specific token names with
  --exclude-dir, which also catches tab-indented properties the old
  anchor missed (6/6 real hits on the same fixture).
- "getPropertyValue echoes whatever is authored" was wrong. The computed
  value is the winning declaration, which is exactly how the reporter
  diagnosed #1646. The real caveat is notation: AppShell authors
  rgba(23, 23, 23, 1), so a hex comparison fails even when correct.
- ":root-only leaks into dark mode" holds only for the layered default
  palette. Against cream/bloom's :root.dark (0,2,0) a consumer's :root
  (0,1,0) loses, so the override stops applying in dark instead. Both
  symptoms now stated.
- The :root.dark recommendation had dropped scoped overrides while
  design-system.md kept telling readers to use them. Restored, with the
  selector shape they need, plus a note that :root.dark does not match a
  subtree .dark region.
- Tightened the 1.6.x warning: rounded-lg resolves to Tailwind's default
  rather than failing, and dark: falls back to prefers-color-scheme.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@interacsean

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

API Design Review completed successfully!

PR #432 is documentation-only. No packages//*.ts, packages//*.tsx, or packages/**/package.json files were changed. API design review has nothing to evaluate — no issues found.

@interacsean
interacsean marked this pull request as ready for review August 12, 2026 05:36
@interacsean
interacsean requested a review from a team as a code owner August 12, 2026 05:36
Comment thread docs/concepts/styling-theming.md Outdated
interacsean and others added 2 commits August 13, 2026 12:10
Per review on #432: version-specific migration steps are easier to find,
and easier for AI agents to consume, in one dedicated place than spread
across the concept doc they happen to touch. CHANGELOG.md nominally
covers this but mixes breaking changes in with features and fixes.

- Add docs/migrations.md: an index table plus one section per change,
  newest first, scoped to changes that require the reader to edit their
  app. Explicitly not a changelog, and entries are never pruned, since
  apps upgrade across arbitrary version gaps.
- Move the theme bridge section there from concepts/styling-theming.md,
  which keeps only the evergreen "Overriding tokens" guidance and links
  out.
- Repoint the two in-doc references and the shipped skill's link.
- List the page in README.md's docs section.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e-bridge-workaround

# Conflicts:
#	catalogue/src/fundamental/design-system.md
interacsean and others added 5 commits August 13, 2026 14:23
The published tarball is dist/** and skills/** plus README.md and
package.json — no docs/, and no CHANGELOG.md. A consumer app therefore
had no migration record available locally at all, which is the visibility
gap this ticket is about: the breakage in #1646 is silent, so someone
hitting it has nothing local to consult.

- generate-skill.mjs copies docs/migrations.md to the skill as
  references/migrations.md. The source is authored for GitHub, so its
  relative links (which resolve against docs/) are rewritten to absolute
  repo URLs, and the frontmatter is dropped to match the other copied
  references. Single authored source; the drift test now covers it.
- SKILL.md gains a Migrations section, and the skill description names
  upgrades and post-version-bump styling breakage as triggers so agents
  find it at the point they need it.
- packages/core/README.md links the guide — the README is the only
  human-readable file npm publishes.

Verified with npm pack --dry-run: both README.md and
skills/app-shell-patterns/references/migrations.md are in the tarball.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ons.md

Per review: docs describing how AppShell works should describe the
version you are on, with version history confined to migrations.md.

- styling-theming.md drops the "Since 1.7.0" qualifier and both links to
  the migration entry; the rules it states (entry CSS declares none of
  the palette/bridge/dark-variant, override individual tokens rather than
  copying) are true of the current version on their own terms.
- The same version history had accumulated in the shipped skill's
  design-system.md, so it gets the same treatment. SKILL.md's Migrations
  section is the entry point there, as README and the docs index are for
  docs/, so no inline pointers are needed.

Verified 248 relative links and their anchors across docs/ still resolve.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Audited all 73 releases in packages/core/CHANGELOG.md so the page lands
in an accurate state rather than describing only the change that
prompted it.

1.x entries, each with what breaks and what to do:

- 1.11.0 react/react-dom floor raised to 19.2.7 and React Router v8
  (1.10.1 had deliberately stayed on v7, so this hop crosses a major)
- 1.11.0 non-modal Sheet drops its backdrop
- 1.8.0 stream removed from useAIChat()
- 1.5.0 loader removed from file-based page definitions
- 1.3.0 inferColumns() no longer sets a default render, and badge
  variants default to outline-neutral
- 1.0.2 Toaster no longer accepts richColors

Pre-1.0 changes are condensed into one table (0.4.0 through 0.33.0 —
mostly auth and routing), pointing at the CHANGELOG for the code. They
supersede each other, so the ordering is called out: 0.13.0 replaced
defaultResourceRedirectPath with redirectToResource, which 0.24.0 then
removed in favour of guards + redirectTo().

Excluded pure additions, internal dependency bumps, and visual polish
that needs no consumer edit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Surfaced by the migrations.md audit: repo-level agent guidance was
pointing at APIs that no longer exist, which is the same failure mode as
#1647 — docs describing a package that isn't the one being shipped.

- CLAUDE.md said redirects use `redirectToResource()` "instead of
  deprecated `defaultResourceRedirectPath`". Both were removed (0.13.0
  and 0.24.0); neither appears anywhere in packages/core/src. The current
  form is a guard returning `redirectTo("/path")`.
- CLAUDE.md said routing uses react-router v7. It has been v8 since
  1.11.0 (packages/core/package.json pins ^8.3.0).
- The create-changeset skill's "major changeset" example demonstrated the
  same dead pair. Swapped for accessControl → guards, a real 0.24.0
  breaking change whose after-state is still the current API; verified
  `pass`/`hidden`/`redirectTo` are exported and match the signatures used.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@IzumiSy
IzumiSy self-requested a review August 14, 2026 07:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants