Files
Codewhale/web/tailwind.config.ts
CodeWhale BotandClaude Opus 5.5 332f60beef fix(web): keep admin POSTs across the host move and truthful locale coverage
Audit 0.10.1 js-ops, web (W01), Refs #6561:

- W01-07: the www -> apex canonical-host redirect is 308, not 301, so a
  client never replays an admin login/post form as a body-less GET. 308
  is still a permanent move for crawlers.
- W01-02: FAQ English answers render for every non-Chinese route locale;
  their five internal links now follow that locale instead of /en.
- W01-03: /computer-use coverage in the content-locale registry is
  derived from the COMPUTER_USE dictionary (hasComputerUseTranslation),
  so canonical, hreflang and sitemap list its 18 translated locales
  instead of canonicalizing them to English.
- W01-04: /docs/guide leaves the registry override. Its fr/de/ca/hi/tr/
  it/pl/ar dictionaries translate only the overview and headings; the
  getting-started steps that are the body ship in en/zh, so those
  variants canonicalize to English like other partial pages.
- W01-m1: Tailwind scans lib/i18n/dictionaries, where the Arabic and
  Hindi guide's leading-loose lives.
- W01-m2: the default caption track follows the page locale when it has
  captions, else English.

Validation (web, npm ci, vitest 4.1.11):
- vitest run middleware, faq-schema, media-manifest, docs-ia, page-meta,
  lib/i18n, public-surface-contract, public-copy: Test Files 14 passed,
  Tests 142 passed.
- tsc --noEmit -p web: exit 0. eslint on touched files: exit 0.
- Negative controls: middleware.ts at HEAD -> "keeps an admin form POST"
  fails (expected 301 to be 308). tailwind.config.ts at HEAD -> built
  utilities contain leading-loose 0 times (1 with the fix).
- Sitemap count 99 -> 107 (+16 computer-use, -8 docs/guide) asserted in
  docs-ia.test.ts.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: CodeWhale Bot <[email protected]>
2026-09-30 00:36:40 -07:00

91 lines
3.4 KiB
TypeScript

import type { Config } from "tailwindcss";
export default {
// Dictionaries carry per-locale class names (e.g. the Arabic and Hindi
// docs guide's `leading-loose`); unscanned, those utilities never exist.
content: ["./app/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}", "./lib/i18n/dictionaries/**/*.ts"],
theme: {
extend: {
colors: {
// Every colour resolves through the role tokens
// (app/styles/tokens-roles.css), so the stage and both appearances
// re-ink it. Alpha modifiers mix the role toward transparent.
...Object.fromEntries(
Object.entries({
canvas: "--bg",
surface: "--surface",
panel: "--panel",
fg: "--text",
muted: "--muted",
line: "--line",
accent: "--accent",
"on-accent": "--on-accent",
hover: "--hover",
selected: "--selected",
attention: "--attention",
live: "--live",
success: "--success",
danger: "--danger",
// Legacy names still used by the docs pages (post-renovation sweep).
paper: "--paper",
"paper-deep": "--paper-deep",
"paper-edge": "--paper-edge",
"paper-card": "--paper-card",
"paper-line": "--paper-line",
"paper-line-soft": "--paper-line-soft",
ink: "--ink",
"ink-soft": "--ink-soft",
"ink-mute": "--ink-mute",
indigo: "--indigo",
"indigo-deep": "--indigo-deep",
"indigo-pale": "--indigo-pale",
ochre: "--ochre",
jade: "--jade",
cobalt: "--cobalt",
}).map(([name, role]) => [
name,
`color-mix(in srgb, var(${role}) calc(<alpha-value> * 100%), transparent)`,
]),
),
},
fontFamily: {
// One face, as GPUI set_theme: every family resolves through the
// role stacks in app/styles/tokens-roles.css (Shannon Sans subsets
// loaded in app/[locale]/layout.tsx; system mono for code).
display: ["var(--font-display)"],
body: ["var(--font-body)"],
cjk: ["var(--font-cjk)"],
mono: ["var(--font-mono)"],
},
// `transition-colors` and friends use the same motion tokens as
// app/styles, so reduced motion stills them too.
transitionDuration: { DEFAULT: "var(--dur-state)" },
transitionTimingFunction: { DEFAULT: "var(--ease-spring)" },
},
// Replaces Tailwind's scale with the GPUI radius grammar
// (app/styles/tokens-roles.css): 6px controls, 10px surfaces (cards,
// code, menus), 14px raised sheets, and pills. Nothing in between.
borderRadius: {
none: "0",
sm: "var(--radius-control)",
DEFAULT: "var(--radius-control)",
lg: "var(--radius-surface)",
xl: "var(--radius-sheet)",
full: "var(--radius-pill)",
},
// Replaces Tailwind's scale so wide tracking cannot be generated: labels
// are sentence case at normal tracking. `wide` stays for Han body copy.
letterSpacing: {
tighter: "-0.05em",
tight: "-0.025em",
crisp: "-0.018em",
normal: "0em",
wide: "0.025em",
},
},
// No all-caps anywhere, as in the GPUI app: the `uppercase` utility and
// its siblings are not generated.
corePlugins: { textTransform: false },
plugins: [],
} satisfies Config;