# @readysetcloud/ui — Agent Guide Instructions for AI agents (and humans) consuming or migrating apps onto the shared Ready, Set, Cloud design system. This is the complete API surface and the rules that keep the three surfaces converged. ## What this package is The single source of truth for brand, components, and auth across: | Surface | Repo | Consumes via | | --- | --- | --- | | Newsletter dashboard | `readysetcloud/newsletter-service` → `dashboard-ui/` | npm | | Concurrency bootcamp platform | `concurrency-bootcamp` → `platform/` | npm | | Bootcamp course pages (vanilla JS) | `concurrency-bootcamp` → `js/` | hosted `auth.global.js` | | readysetcloud.io (Hugo) | `readysetcloud/ready-set-cloud` | hosted `styles/*.css` | Source lives in `rsc-core/ui`. **Never fork or copy this code into an app — change it here, version it, consume it.** ## Hard rules (violating these defeats the package's purpose) 1. **Never hardcode brand colors** in an app. Use token variables (`rgb(var(--primary-600))`), the Tailwind preset scales (`bg-primary-600`), or the shipped classes (`.btn-primary`). 2. **Raleway is the wordmark face only.** It exists as `--font-logo` for text-rendered logo lockups. Never set UI text in Raleway. Headings = Sora (`--font-display`), body = Manrope (`--font-sans`), data/code = JetBrains Mono (`--font-mono`). 3. **Don't re-implement components that exist here.** If an app needs a variant, add it to this package first. 4. **Respect the responsive contract.** Components ship with 44px touch targets, ≥16px mobile inputs, fluid type, and safe-area handling. Don't override these down. 5. **Don't change the `rsc:auth` session contract** (`{idToken, refreshToken, expiresAt}` in localStorage under key `rsc:auth`). The vanilla course pages and the platform share sessions through it. Change it only deliberately, on both sides, in this package. 6. **Dark mode** is system-preference by default with `` override. Never implement a separate theming mechanism. 7. **Never stack `dark:` variants on token colors.** The token scales AUTO-INVERT in dark mode (`--success-100` flips dark, `--success-900` flips light), so a single token class (`bg-success-100 text-success-800`) is already correct in both themes. Adding a Tailwind `dark:` override on top double-inverts and washes out contrast. If a component looks wrong in dark mode, fix the token usage — don't add `dark:`. ## Install (React apps) ```bash npm install @readysetcloud/ui # public npm ``` ```ts // main.tsx — ALWAYS import the stylesheet once, before app styles import '@readysetcloud/ui/styles.css'; // only if the app doesn't already load brand fonts in index.html: import '@readysetcloud/ui/fonts.css'; ``` ```js // tailwind.config.js module.exports = { presets: [require('@readysetcloud/ui/tailwind-preset')], content: [ './index.html', './src/**/*.{ts,tsx}', './node_modules/@readysetcloud/ui/dist/**/*.js' // REQUIRED — components use token classes ] }; ``` The preset aliases `blue`→primary, `green`/`teal`→success, `red`/`rose`→error, `orange`/`amber`/`yellow`→warning, `gray`/`slate`→secondary, so existing utility classes stay on-brand during migration without a rename sweep. ## Components — `import { ... } from '@readysetcloud/ui'` All components are typed, accept `className`, and forward standard HTML props. | Component | Key props | Notes | | --- | --- | --- | | `Button` | `variant: 'primary'\|'secondary'\|'success'\|'warning'\|'error'\|'ghost'`, `size: 'sm'\|'md'\|'lg'`, `block`, `loading`, `loadingLabel` | `loading` disables + spinner + optional label swap. Default `type="button"`. | | `Input` | `label` (required), `error`, `hint` + all input props | Label/aria wiring automatic. `error` renders red border + `role="alert"` message. | | `PasswordInput` | same as Input, no `type` | Show/hide toggle built in. | | `CodeInput` | `label?`, `error`, `length` (default 6) | Numeric, `autoComplete="one-time-code"`, monospace centered. | | `TextArea` / `Select` | `label`, `error`, `hint` | Same Field wiring. Select takes `