@agimon-ai/po-web-components 0.0.0-alpha.5 → 0.0.0-alpha.7

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.
package/README.md CHANGED
@@ -13,7 +13,7 @@ Because every colour is a token, a theme config recolours the whole cockpit at r
13
13
  | `.` | Actions and chips: `Button`, `Badge`, `StatusBadge`, `Dot`, `Kbd`, `NavTab*`, `Tabs*`. Fields: `Input`, `Textarea`, `Label`, `Checkbox`, `Switch`, `RadioGroup*`, `Select*`. Overlays: `Dialog*`, `Sheet*`, `Popover*`, `DropdownMenu*`, `Tooltip*`, `Toast*`, `Command*`. Layout and content: `Panel*`, `SectionLabel`, `Separator`, `EmptyState`, `ScrollArea`, `Collapsible*`, `Accordion*`, `OptionList`, `OptionRow`, `MessageItem*`, `MessageLines`. Feedback: `Spinner`, `Progress`, `Skeleton`, `Avatar*`, `StreamCursor`. Files: `CodeEditor`, `MediaPreview`. Review: `DiffView`, `ReviewCommentDraft`. Plus the curated icon set, `cn`, `collapseLines`, `grammarKeyOf`, `mediaKindOf`, the review helpers (`buildReviewPrompt`, `reviewCommentAnchor`, `diffRangeOf`), `groupByDirectory`, the option-list key helpers, and the tone vocabularies with the maps between them |
14
14
  | `./theme` | `ThemeConfig`, the token lists, `BUILTIN_THEMES`, `applyTheme`, `parseThemeConfig`, `themeFromPiTheme`, the stored-preference helpers |
15
15
  | `./styles.css` | The token stylesheet: the bundled fonts, then `styles/theme.css` (`:root` defaults, the Tailwind `@theme inline` mapping, shadcn semantic aliases, base styles, and the `@source` for this package's classes) |
16
- | `./themes/*.json` | The shipped theme configs: `po-one-dark` (default), `po-one-light`, `po-nord-dark` |
16
+ | `./themes/*.json` | The shipped theme configs: `po-one-light` (default), `po-nord-dark` |
17
17
 
18
18
  ## Using it from the cockpit host
19
19
 
@@ -27,7 +27,7 @@ Because every colour is a token, a theme config recolours the whole cockpit at r
27
27
  import { Button, Dialog, DialogContent, StatusBadge } from '@agimon-ai/po-web-components';
28
28
  import { applyTheme, builtinTheme, readThemePreference } from '@agimon-ai/po-web-components/theme';
29
29
 
30
- applyTheme(builtinTheme(readThemePreference(localStorage) ?? 'po-one-dark')!, document.documentElement);
30
+ applyTheme(builtinTheme(readThemePreference(localStorage) ?? 'po-one-light')!, document.documentElement);
31
31
  ```
32
32
 
33
33
  ## Tones
@@ -1,7 +1,7 @@
1
1
  import { ThemeConfig } from "../types/theme.mjs";
2
2
  //#region src/theme/builtinThemes.d.ts
3
3
  /** The theme the cockpit renders with until a preference says otherwise. */
4
- export declare const DEFAULT_THEME_NAME = "po-one-dark";
4
+ export declare const DEFAULT_THEME_NAME = "po-one-light";
5
5
  /** The themes this package ships, default first. */
6
6
  export declare const BUILTIN_THEMES: readonly ThemeConfig[];
7
7
  export declare const DEFAULT_THEME: ThemeConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"builtinThemes.d.mts","names":[],"sources":["../../../../../../src/theme/builtinThemes.ts"],"mappings":";;;qBAaa;;qBAGA,yBAAyB;qBAMzB,eAAe;;wBAGZ,aAAa,eAAe"}
1
+ {"version":3,"file":"builtinThemes.d.mts","names":[],"sources":["../../../../../../src/theme/builtinThemes.ts"],"mappings":";;;qBAYa;;qBAGA,yBAAyB;qBAKzB,eAAe;;wBAGZ,aAAa,eAAe"}
@@ -1,2 +1,2 @@
1
- import e from"../../themes/po-nord-dark.mjs";import t from"../../themes/po-one-dark.mjs";import n from"../../themes/po-one-light.mjs";import{parseThemeConfig as r}from"./parse.mjs";function i(e,t){let n=r(e);if(n===null)throw Error(`The shipped theme ${t} is malformed.`);return n}const a=`po-one-dark`,o=[i(t,`po-one-dark.json`),i(n,`po-one-light.json`),i(e,`po-nord-dark.json`)],s=o[0];function c(e){return o.find(t=>t.name===e)}export{o as BUILTIN_THEMES,s as DEFAULT_THEME,a as DEFAULT_THEME_NAME,c as builtinTheme};
1
+ import e from"../../themes/po-nord-dark.mjs";import t from"../../themes/po-one-light.mjs";import{parseThemeConfig as n}from"./parse.mjs";function r(e,t){let r=n(e);if(r===null)throw Error(`The shipped theme ${t} is malformed.`);return r}const i=`po-one-light`,a=[r(t,`po-one-light.json`),r(e,`po-nord-dark.json`)],o=a[0];function s(e){return a.find(t=>t.name===e)}export{a as BUILTIN_THEMES,o as DEFAULT_THEME,i as DEFAULT_THEME_NAME,s as builtinTheme};
2
2
  //# sourceMappingURL=builtinThemes.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"builtinThemes.mjs","names":["poOneDark","poOneLight","poNordDark","po_nord_dark_default","po_one_dark_default","po_one_light_default","shipped","theme","parseThemeConfig","input","file","DEFAULT_THEME_NAME","BUILTIN_THEMES","DEFAULT_THEME","builtinTheme","name"],"sources":["../../../../../../src/theme/builtinThemes.ts"],"sourcesContent":["import poNordDark from '../../themes/po-nord-dark.json' with { type: 'json' };\nimport poOneDark from '../../themes/po-one-dark.json' with { type: 'json' };\nimport poOneLight from '../../themes/po-one-light.json' with { type: 'json' };\nimport type { ThemeConfig } from '../types/theme';\nimport { parseThemeConfig } from './parse';\n\nfunction shipped(input: unknown, file: string): ThemeConfig {\n const theme = parseThemeConfig(input);\n if (theme === null) throw new Error(`The shipped theme ${file} is malformed.`);\n return theme;\n}\n\n/** The theme the cockpit renders with until a preference says otherwise. */\nexport const DEFAULT_THEME_NAME = 'po-one-dark';\n\n/** The themes this package ships, default first. */\nexport const BUILTIN_THEMES: readonly ThemeConfig[] = [\n shipped(poOneDark, 'po-one-dark.json'),\n shipped(poOneLight, 'po-one-light.json'),\n shipped(poNordDark, 'po-nord-dark.json'),\n];\n\nexport const DEFAULT_THEME: ThemeConfig = BUILTIN_THEMES[0];\n\n/** A shipped theme by name, or undefined for a name nothing shipped under. */\nexport function builtinTheme(name: string): ThemeConfig | undefined {\n return BUILTIN_THEMES.find((theme) => theme.name === name);\n}\n"],"mappings":"qLAMA,SAASM,EAAQ,EAAgB,EAA2B,CAC1D,IAAMC,EAAQC,EAAiBC,CAAK,EACpC,GAAIF,IAAU,KAAM,MAAU,MAAM,qBAAqBG,EAAK,eAAe,EAC7E,OAAOH,CACT,CAGA,MAAaI,EAAqB,cAGrBC,EAAyC,CACpDN,EAAQN,EAAW,kBAAkB,EACrCM,EAAQL,EAAY,mBAAmB,EACvCK,EAAQJ,EAAY,mBAAmB,CACzC,EAEaW,EAA6BD,EAAe,GAGzD,SAAgBE,EAAa,EAAuC,CAClE,OAAOF,EAAe,KAAM,GAAUL,EAAM,OAASQ,CAAI,CAC3D"}
1
+ {"version":3,"file":"builtinThemes.mjs","names":["poOneLight","poNordDark","po_nord_dark_default","po_one_light_default","shipped","theme","parseThemeConfig","input","file","DEFAULT_THEME_NAME","BUILTIN_THEMES","DEFAULT_THEME","builtinTheme","name"],"sources":["../../../../../../src/theme/builtinThemes.ts"],"sourcesContent":["import poNordDark from '../../themes/po-nord-dark.json' with { type: 'json' };\nimport poOneLight from '../../themes/po-one-light.json' with { type: 'json' };\nimport type { ThemeConfig } from '../types/theme';\nimport { parseThemeConfig } from './parse';\n\nfunction shipped(input: unknown, file: string): ThemeConfig {\n const theme = parseThemeConfig(input);\n if (theme === null) throw new Error(`The shipped theme ${file} is malformed.`);\n return theme;\n}\n\n/** The theme the cockpit renders with until a preference says otherwise. */\nexport const DEFAULT_THEME_NAME = 'po-one-light';\n\n/** The themes this package ships, default first. */\nexport const BUILTIN_THEMES: readonly ThemeConfig[] = [\n shipped(poOneLight, 'po-one-light.json'),\n shipped(poNordDark, 'po-nord-dark.json'),\n];\n\nexport const DEFAULT_THEME: ThemeConfig = BUILTIN_THEMES[0];\n\n/** A shipped theme by name, or undefined for a name nothing shipped under. */\nexport function builtinTheme(name: string): ThemeConfig | undefined {\n return BUILTIN_THEMES.find((theme) => theme.name === name);\n}\n"],"mappings":"yIAKA,SAASI,EAAQ,EAAgB,EAA2B,CAC1D,IAAMC,EAAQC,EAAiBC,CAAK,EACpC,GAAIF,IAAU,KAAM,MAAU,MAAM,qBAAqBG,EAAK,eAAe,EAC7E,OAAOH,CACT,CAGA,MAAaI,EAAqB,eAGrBC,EAAyC,CACpDN,EAAQJ,EAAY,mBAAmB,EACvCI,EAAQH,EAAY,mBAAmB,CACzC,EAEaU,EAA6BD,EAAe,GAGzD,SAAgBE,EAAa,EAAuC,CAClE,OAAOF,EAAe,KAAM,GAAUL,EAAM,OAASQ,CAAI,CAC3D"}
@@ -1,2 +1,2 @@
1
- import{ACCENT_TOKENS as e,PALETTE_TOKENS as t}from"../types/theme.mjs";import{builtinTheme as n}from"./builtinThemes.mjs";import"./derive.mjs";const r=4,i={xs:2,sm:3,md:5,lg:10},a={...i,DEFAULT:4,full:9999},o={"2xs":{size:9,leading:1.45},xs:{size:10,leading:1.45},sm:{size:12,leading:1.45},base:{size:13,leading:1.5},lg:{size:15,leading:1.4},xl:{size:18,leading:1.3},"2xl":{size:22,leading:1.25},"3xl":{size:28,leading:1.2}},s={xl:-.01,"2xl":-.01,"3xl":-.01},c=1.625,l={regular:`400`,medium:`500`,semibold:`600`},u={fade:140,pop:160,rise:160,slide:180,easing:[.16,1,.3,1]},d={sans:{family:`IBM Plex Sans`,ios:`System`,android:`sans-serif`},mono:{family:`JetBrains Mono`,ios:`Menlo`,android:`monospace`}},f=/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;function p(e){if(!f.test(e))throw Error(`Native themes need hex colours; got "${e}".`);let t=e.length===4?e.slice(1).split(``).map(e=>e+e).join(``):e.slice(1);return[0,2,4].map(e=>Number.parseInt(t.slice(e,e+2),16))}function m(e,t,n){let r=t/100,i=p(e),a=p(n);return`#${i.map((e,t)=>{let n=Math.round(e*r+a[t]*(1-r));return Math.min(255,Math.max(0,n)).toString(16).padStart(2,`0`)}).join(``)}`}function h(e,t){let n=Math.min(255,Math.max(0,Math.round(t/100*255)));return`#${[...p(e),n].map(e=>e.toString(16).padStart(2,`0`)).join(``)}`}function g(e){let t={};for(let n of Object.keys(o))t[n]=e(n);return t}function _(n){let r=n.tokens,i={};for(let e of t)i[e]=n.tokens[e];let f=(e,t)=>{i[e]=r[e]??t()};for(let t of e)f(`tint-${t}`,()=>m(i[t],16,i.panel));for(let t of e)f(`edge-${t}`,()=>m(i[t],40,i.border));return f(`on-selected`,()=>m(i.selected,12,`#ffffff`)),{scheme:n.scheme,colors:i,spacing:e=>e*4,borderRadius:a,fontSize:g(e=>o[e].size),lineHeight:g(e=>Math.round(o[e].size*o[e].leading)),lineHeightRelaxed:g(e=>Math.round(o[e].size*c)),letterSpacing:g(e=>{let t=s[e]??0;return Math.round(o[e].size*t*100)/100}),fontWeight:l,fontFamily:d,motion:u}}function v(e){let t=n(e);if(t===void 0)throw Error(`The shipped theme ${e} is missing.`);return _(t)}const y={dark:v(`po-one-dark`),light:v(`po-one-light`)};export{a as NATIVE_BORDER_RADIUS,d as NATIVE_FONT_FAMILY,l as NATIVE_FONT_WEIGHT,c as NATIVE_LEADING_RELAXED,s as NATIVE_LETTER_SPACING_EM,u as NATIVE_MOTION,i as NATIVE_RADII,r as NATIVE_SPACING_BASE,y as NATIVE_THEMES,o as NATIVE_TYPE_RAMP,m as mixHex,_ as nativeTheme,h as withAlpha};
1
+ import{ACCENT_TOKENS as e,PALETTE_TOKENS as t}from"../types/theme.mjs";import{builtinTheme as n}from"./builtinThemes.mjs";import"./derive.mjs";const r=4,i={xs:2,sm:3,md:5,lg:10},a={...i,DEFAULT:4,full:9999},o={"2xs":{size:9,leading:1.45},xs:{size:10,leading:1.45},sm:{size:12,leading:1.45},base:{size:13,leading:1.5},lg:{size:15,leading:1.4},xl:{size:18,leading:1.3},"2xl":{size:22,leading:1.25},"3xl":{size:28,leading:1.2}},s={xl:-.01,"2xl":-.01,"3xl":-.01},c=1.625,l={regular:`400`,medium:`500`,semibold:`600`},u={fade:140,pop:160,rise:160,slide:180,easing:[.16,1,.3,1]},d={sans:{family:`IBM Plex Sans`,ios:`System`,android:`sans-serif`},mono:{family:`JetBrains Mono`,ios:`Menlo`,android:`monospace`}},f=/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;function p(e){if(!f.test(e))throw Error(`Native themes need hex colours; got "${e}".`);let t=e.length===4?e.slice(1).split(``).map(e=>e+e).join(``):e.slice(1);return[0,2,4].map(e=>Number.parseInt(t.slice(e,e+2),16))}function m(e,t,n){let r=t/100,i=p(e),a=p(n);return`#${i.map((e,t)=>{let n=Math.round(e*r+a[t]*(1-r));return Math.min(255,Math.max(0,n)).toString(16).padStart(2,`0`)}).join(``)}`}function h(e,t){let n=Math.min(255,Math.max(0,Math.round(t/100*255)));return`#${[...p(e),n].map(e=>e.toString(16).padStart(2,`0`)).join(``)}`}function g(e){let t={};for(let n of Object.keys(o))t[n]=e(n);return t}function _(n){let r=n.tokens,i={};for(let e of t)i[e]=n.tokens[e];let f=(e,t)=>{i[e]=r[e]??t()};for(let t of e)f(`tint-${t}`,()=>m(i[t],16,i.panel));for(let t of e)f(`edge-${t}`,()=>m(i[t],40,i.border));return f(`on-selected`,()=>m(i.selected,12,`#ffffff`)),{scheme:n.scheme,colors:i,spacing:e=>e*4,borderRadius:a,fontSize:g(e=>o[e].size),lineHeight:g(e=>Math.round(o[e].size*o[e].leading)),lineHeightRelaxed:g(e=>Math.round(o[e].size*c)),letterSpacing:g(e=>{let t=s[e]??0;return Math.round(o[e].size*t*100)/100}),fontWeight:l,fontFamily:d,motion:u}}function v(e){let t=n(e);if(t===void 0)throw Error(`The shipped theme ${e} is missing.`);return _(t)}const y={dark:v(`po-nord-dark`),light:v(`po-one-light`)};export{a as NATIVE_BORDER_RADIUS,d as NATIVE_FONT_FAMILY,l as NATIVE_FONT_WEIGHT,c as NATIVE_LEADING_RELAXED,s as NATIVE_LETTER_SPACING_EM,u as NATIVE_MOTION,i as NATIVE_RADII,r as NATIVE_SPACING_BASE,y as NATIVE_THEMES,o as NATIVE_TYPE_RAMP,m as mixHex,_ as nativeTheme,h as withAlpha};
2
2
  //# sourceMappingURL=nativeTheme.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"nativeTheme.mjs","names":["NATIVE_SPACING_BASE","NATIVE_RADII","NATIVE_BORDER_RADIUS","NATIVE_TYPE_RAMP","NATIVE_LETTER_SPACING_EM","NATIVE_LEADING_RELAXED","NATIVE_FONT_WEIGHT","NATIVE_MOTION","NATIVE_FONT_FAMILY","HEX_COLOR","hexChannels","hex","digits","digit","offset","mixHex","weight","percent","a","first","b","second","mixed","channel","index","withAlpha","alpha","rampValues","values","step","pick","nativeTheme","pinned","config","colors","token","PALETTE_TOKENS","resolve","fallback","accent","ACCENT_TOKENS","steps","em","shippedNative","theme","builtinTheme","name","NATIVE_THEMES"],"sources":["../../../../../../src/theme/nativeTheme.ts"],"sourcesContent":["import { ACCENT_TOKENS, PALETTE_TOKENS, type ThemeConfig, type ThemeScheme, type ThemeToken } from '../types/theme';\nimport { builtinTheme } from './builtinThemes';\nimport { EDGE_MIX_PERCENT, ON_SELECTED_MIX_PERCENT, TINT_MIX_PERCENT } from './derive';\n\n/*\n * The React Native copy of the web theme. Native styles cannot read CSS\n * custom properties or evaluate color-mix(), so this module resolves the same\n * tokens to plain values. The scales below mirror styles/theme.css by hand\n * (CSS cannot import TypeScript); tests/nativeTheme.test.ts fails when the two\n * drift.\n *\n * ponytail: bundle IBM Plex Sans and JetBrains Mono through expo-font when the\n * native visual review starts; until then the named families fall back to the\n * platform fonts below.\n * ponytail: add a native theme picker later; the shell follows the system\n * scheme between `light` and `dark` for now.\n * ponytail: `--tracking-*` (tracked uppercase micro-labels) is not ported;\n * docs/design.md bans tracked uppercase on new surfaces.\n * ponytail: `shadow-2xl` is not ported; native surfaces (sheets, modals,\n * headers) draw their own platform shadows.\n */\n\n/** The spacing unit, matching `--spacing: 0.25rem` at a 16px root. */\nexport const NATIVE_SPACING_BASE = 4;\n\n/** Corner radii in px, matching `--radius-*`. */\nexport const NATIVE_RADII = { xs: 2, sm: 3, md: 5, lg: 10 } as const;\n\n/**\n * Every radius a native style may name: the retunable `--radius-*` steps, plus\n * Tailwind's hardcoded bare `rounded` (4px) and `rounded-full`.\n */\nexport const NATIVE_BORDER_RADIUS = { ...NATIVE_RADII, DEFAULT: 4, full: 9999 } as const;\n\n/** The type ramp, matching `--text-*` (px) and `--text-*--line-height` (a multiple of the size). */\nexport const NATIVE_TYPE_RAMP = {\n '2xs': { size: 9, leading: 1.45 },\n xs: { size: 10, leading: 1.45 },\n sm: { size: 12, leading: 1.45 },\n base: { size: 13, leading: 1.5 },\n lg: { size: 15, leading: 1.4 },\n xl: { size: 18, leading: 1.3 },\n '2xl': { size: 22, leading: 1.25 },\n '3xl': { size: 28, leading: 1.2 },\n} as const;\n\n/** Title tracking in em, matching `--text-*--letter-spacing`; steps not listed track at 0. */\nexport const NATIVE_LETTER_SPACING_EM = { xl: -0.01, '2xl': -0.01, '3xl': -0.01 } as const;\n\n/** Tailwind's `leading-relaxed` multiple, which theme.css does not override. */\nexport const NATIVE_LEADING_RELAXED = 1.625;\n\n/** Font weights as React Native takes them, matching `font-normal`, `font-medium` and `font-semibold`. */\nexport const NATIVE_FONT_WEIGHT = { regular: '400', medium: '500', semibold: '600' } as const;\n\n/**\n * Durations in ms and the shared easing curve of `--animate-po-*`. `slide`\n * covers both slide directions; `easing` is the `cubic-bezier()` control points\n * for Reanimated's `Easing.bezier`.\n */\nexport const NATIVE_MOTION = {\n fade: 140,\n pop: 160,\n rise: 160,\n slide: 180,\n easing: [0.16, 1, 0.3, 1],\n} as const;\n\n/** A font as native styles name it: one family, plus the platform font to use until it is bundled. */\nexport interface NativeFontStack {\n family: string;\n ios: string;\n android: string;\n}\n\n/** The sans and mono families of `--font-sans` and `--po-font-mono`, with system fallbacks. */\nexport const NATIVE_FONT_FAMILY: { readonly sans: NativeFontStack; readonly mono: NativeFontStack } = {\n sans: { family: 'IBM Plex Sans', ios: 'System', android: 'sans-serif' },\n mono: { family: 'JetBrains Mono', ios: 'Menlo', android: 'monospace' },\n};\n\n/** The foreground `on-selected` mixes toward, as `white` in derive.ts. */\nconst ON_SELECTED_BASE = '#ffffff';\nconst HEX_COLOR = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst PERCENT = 100;\nconst CHANNEL_MAX = 255;\n/** Rounds px values to hundredths so `18 * -0.01` reads -0.18, not a float tail. */\nconst PX_PRECISION = 100;\n\nexport type NativeColorToken = Exclude<ThemeToken, 'font-mono'>;\nexport type NativeTypeStep = keyof typeof NATIVE_TYPE_RAMP;\nexport type NativeNamedTheme = 'dark' | 'light';\n\nexport interface PoNativeTheme {\n scheme: ThemeScheme;\n colors: Record<NativeColorToken, string>;\n /** `spacing(n)` is n steps of the 4px base, as Tailwind's `p-n`. */\n spacing: (steps: number) => number;\n borderRadius: typeof NATIVE_BORDER_RADIUS;\n fontSize: Record<NativeTypeStep, number>;\n /** Absolute line heights in px, since native styles take no unitless multiple. */\n lineHeight: Record<NativeTypeStep, number>;\n /** `leading-relaxed` line heights in px, for reading text such as markdown bodies. */\n lineHeightRelaxed: Record<NativeTypeStep, number>;\n /** Letter spacing in px per step; titles track slightly tight, the rest at 0. */\n letterSpacing: Record<NativeTypeStep, number>;\n fontWeight: typeof NATIVE_FONT_WEIGHT;\n fontFamily: typeof NATIVE_FONT_FAMILY;\n motion: typeof NATIVE_MOTION;\n}\n\nfunction hexChannels(hex: string): [number, number, number] {\n if (!HEX_COLOR.test(hex)) throw new Error(`Native themes need hex colours; got \"${hex}\".`);\n const digits =\n hex.length === 4\n ? hex\n .slice(1)\n .split('')\n .map((digit) => digit + digit)\n .join('')\n : hex.slice(1);\n return [0, 2, 4].map((offset) => Number.parseInt(digits.slice(offset, offset + 2), 16)) as [number, number, number];\n}\n\n/**\n * `color-mix(in srgb, first percent%, second)` for hex inputs: a straight\n * per-channel blend, rounded to the nearest 8-bit value.\n */\nexport function mixHex(first: string, percent: number, second: string): string {\n const weight = percent / PERCENT;\n const a = hexChannels(first);\n const b = hexChannels(second);\n return `#${a\n .map((channel, index) => {\n const mixed = Math.round(channel * weight + b[index]! * (1 - weight));\n return Math.min(CHANNEL_MAX, Math.max(0, mixed)).toString(16).padStart(2, '0');\n })\n .join('')}`;\n}\n\n/**\n * A hex colour at `percent` opacity as `#rrggbbaa`: the native form of\n * Tailwind's `/40`-style opacity modifiers.\n */\nexport function withAlpha(hex: string, percent: number): string {\n const alpha = Math.min(CHANNEL_MAX, Math.max(0, Math.round((percent / PERCENT) * CHANNEL_MAX)));\n const channels = [...hexChannels(hex), alpha];\n return `#${channels.map((channel) => channel.toString(16).padStart(2, '0')).join('')}`;\n}\n\nfunction rampValues(pick: (step: NativeTypeStep) => number): Record<NativeTypeStep, number> {\n const values = {} as Record<NativeTypeStep, number>;\n for (const step of Object.keys(NATIVE_TYPE_RAMP) as NativeTypeStep[]) values[step] = pick(step);\n return values;\n}\n\n/** Resolves a web theme config to native values; tokens the theme pins win over the derived mix. */\nexport function nativeTheme(config: ThemeConfig): PoNativeTheme {\n const pinned = config.tokens as Partial<Record<ThemeToken, string>>;\n const colors = {} as Record<NativeColorToken, string>;\n for (const token of PALETTE_TOKENS) colors[token] = config.tokens[token];\n const resolve = (token: NativeColorToken, fallback: () => string): void => {\n colors[token] = pinned[token] ?? fallback();\n };\n for (const accent of ACCENT_TOKENS) {\n resolve(`tint-${accent}`, () => mixHex(colors[accent], TINT_MIX_PERCENT, colors.panel));\n }\n for (const accent of ACCENT_TOKENS) {\n resolve(`edge-${accent}`, () => mixHex(colors[accent], EDGE_MIX_PERCENT, colors.border));\n }\n resolve('on-selected', () => mixHex(colors.selected, ON_SELECTED_MIX_PERCENT, ON_SELECTED_BASE));\n\n return {\n scheme: config.scheme,\n colors,\n spacing: (steps) => steps * NATIVE_SPACING_BASE,\n borderRadius: NATIVE_BORDER_RADIUS,\n fontSize: rampValues((step) => NATIVE_TYPE_RAMP[step].size),\n lineHeight: rampValues((step) => Math.round(NATIVE_TYPE_RAMP[step].size * NATIVE_TYPE_RAMP[step].leading)),\n lineHeightRelaxed: rampValues((step) => Math.round(NATIVE_TYPE_RAMP[step].size * NATIVE_LEADING_RELAXED)),\n letterSpacing: rampValues((step) => {\n const em = (NATIVE_LETTER_SPACING_EM as Partial<Record<NativeTypeStep, number>>)[step] ?? 0;\n return Math.round(NATIVE_TYPE_RAMP[step].size * em * PX_PRECISION) / PX_PRECISION;\n }),\n fontWeight: NATIVE_FONT_WEIGHT,\n fontFamily: NATIVE_FONT_FAMILY,\n motion: NATIVE_MOTION,\n };\n}\n\nfunction shippedNative(name: string): PoNativeTheme {\n const theme = builtinTheme(name);\n if (theme === undefined) throw new Error(`The shipped theme ${name} is missing.`);\n return nativeTheme(theme);\n}\n\n/** The native themes by the names the native shell registers: `dark` and `light`. */\nexport const NATIVE_THEMES: Readonly<Record<NativeNamedTheme, PoNativeTheme>> = {\n dark: shippedNative('po-one-dark'),\n light: shippedNative('po-one-light'),\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"nativeTheme.mjs","names":["NATIVE_SPACING_BASE","NATIVE_RADII","NATIVE_BORDER_RADIUS","NATIVE_TYPE_RAMP","NATIVE_LETTER_SPACING_EM","NATIVE_LEADING_RELAXED","NATIVE_FONT_WEIGHT","NATIVE_MOTION","NATIVE_FONT_FAMILY","HEX_COLOR","hexChannels","hex","digits","digit","offset","mixHex","weight","percent","a","first","b","second","mixed","channel","index","withAlpha","alpha","rampValues","values","step","pick","nativeTheme","pinned","config","colors","token","PALETTE_TOKENS","resolve","fallback","accent","ACCENT_TOKENS","steps","em","shippedNative","theme","builtinTheme","name","NATIVE_THEMES"],"sources":["../../../../../../src/theme/nativeTheme.ts"],"sourcesContent":["import { ACCENT_TOKENS, PALETTE_TOKENS, type ThemeConfig, type ThemeScheme, type ThemeToken } from '../types/theme';\nimport { builtinTheme } from './builtinThemes';\nimport { EDGE_MIX_PERCENT, ON_SELECTED_MIX_PERCENT, TINT_MIX_PERCENT } from './derive';\n\n/*\n * The React Native copy of the web theme. Native styles cannot read CSS\n * custom properties or evaluate color-mix(), so this module resolves the same\n * tokens to plain values. The scales below mirror styles/theme.css by hand\n * (CSS cannot import TypeScript); tests/nativeTheme.test.ts fails when the two\n * drift.\n *\n * ponytail: bundle IBM Plex Sans and JetBrains Mono through expo-font when the\n * native visual review starts; until then the named families fall back to the\n * platform fonts below.\n * ponytail: add a native theme picker later; the shell follows the system\n * scheme between `light` and `dark` for now.\n * ponytail: `--tracking-*` (tracked uppercase micro-labels) is not ported;\n * docs/design.md bans tracked uppercase on new surfaces.\n * ponytail: `shadow-2xl` is not ported; native surfaces (sheets, modals,\n * headers) draw their own platform shadows.\n */\n\n/** The spacing unit, matching `--spacing: 0.25rem` at a 16px root. */\nexport const NATIVE_SPACING_BASE = 4;\n\n/** Corner radii in px, matching `--radius-*`. */\nexport const NATIVE_RADII = { xs: 2, sm: 3, md: 5, lg: 10 } as const;\n\n/**\n * Every radius a native style may name: the retunable `--radius-*` steps, plus\n * Tailwind's hardcoded bare `rounded` (4px) and `rounded-full`.\n */\nexport const NATIVE_BORDER_RADIUS = { ...NATIVE_RADII, DEFAULT: 4, full: 9999 } as const;\n\n/** The type ramp, matching `--text-*` (px) and `--text-*--line-height` (a multiple of the size). */\nexport const NATIVE_TYPE_RAMP = {\n '2xs': { size: 9, leading: 1.45 },\n xs: { size: 10, leading: 1.45 },\n sm: { size: 12, leading: 1.45 },\n base: { size: 13, leading: 1.5 },\n lg: { size: 15, leading: 1.4 },\n xl: { size: 18, leading: 1.3 },\n '2xl': { size: 22, leading: 1.25 },\n '3xl': { size: 28, leading: 1.2 },\n} as const;\n\n/** Title tracking in em, matching `--text-*--letter-spacing`; steps not listed track at 0. */\nexport const NATIVE_LETTER_SPACING_EM = { xl: -0.01, '2xl': -0.01, '3xl': -0.01 } as const;\n\n/** Tailwind's `leading-relaxed` multiple, which theme.css does not override. */\nexport const NATIVE_LEADING_RELAXED = 1.625;\n\n/** Font weights as React Native takes them, matching `font-normal`, `font-medium` and `font-semibold`. */\nexport const NATIVE_FONT_WEIGHT = { regular: '400', medium: '500', semibold: '600' } as const;\n\n/**\n * Durations in ms and the shared easing curve of `--animate-po-*`. `slide`\n * covers both slide directions; `easing` is the `cubic-bezier()` control points\n * for Reanimated's `Easing.bezier`.\n */\nexport const NATIVE_MOTION = {\n fade: 140,\n pop: 160,\n rise: 160,\n slide: 180,\n easing: [0.16, 1, 0.3, 1],\n} as const;\n\n/** A font as native styles name it: one family, plus the platform font to use until it is bundled. */\nexport interface NativeFontStack {\n family: string;\n ios: string;\n android: string;\n}\n\n/** The sans and mono families of `--font-sans` and `--po-font-mono`, with system fallbacks. */\nexport const NATIVE_FONT_FAMILY: { readonly sans: NativeFontStack; readonly mono: NativeFontStack } = {\n sans: { family: 'IBM Plex Sans', ios: 'System', android: 'sans-serif' },\n mono: { family: 'JetBrains Mono', ios: 'Menlo', android: 'monospace' },\n};\n\n/** The foreground `on-selected` mixes toward, as `white` in derive.ts. */\nconst ON_SELECTED_BASE = '#ffffff';\nconst HEX_COLOR = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst PERCENT = 100;\nconst CHANNEL_MAX = 255;\n/** Rounds px values to hundredths so `18 * -0.01` reads -0.18, not a float tail. */\nconst PX_PRECISION = 100;\n\nexport type NativeColorToken = Exclude<ThemeToken, 'font-mono'>;\nexport type NativeTypeStep = keyof typeof NATIVE_TYPE_RAMP;\nexport type NativeNamedTheme = 'dark' | 'light';\n\nexport interface PoNativeTheme {\n scheme: ThemeScheme;\n colors: Record<NativeColorToken, string>;\n /** `spacing(n)` is n steps of the 4px base, as Tailwind's `p-n`. */\n spacing: (steps: number) => number;\n borderRadius: typeof NATIVE_BORDER_RADIUS;\n fontSize: Record<NativeTypeStep, number>;\n /** Absolute line heights in px, since native styles take no unitless multiple. */\n lineHeight: Record<NativeTypeStep, number>;\n /** `leading-relaxed` line heights in px, for reading text such as markdown bodies. */\n lineHeightRelaxed: Record<NativeTypeStep, number>;\n /** Letter spacing in px per step; titles track slightly tight, the rest at 0. */\n letterSpacing: Record<NativeTypeStep, number>;\n fontWeight: typeof NATIVE_FONT_WEIGHT;\n fontFamily: typeof NATIVE_FONT_FAMILY;\n motion: typeof NATIVE_MOTION;\n}\n\nfunction hexChannels(hex: string): [number, number, number] {\n if (!HEX_COLOR.test(hex)) throw new Error(`Native themes need hex colours; got \"${hex}\".`);\n const digits =\n hex.length === 4\n ? hex\n .slice(1)\n .split('')\n .map((digit) => digit + digit)\n .join('')\n : hex.slice(1);\n return [0, 2, 4].map((offset) => Number.parseInt(digits.slice(offset, offset + 2), 16)) as [number, number, number];\n}\n\n/**\n * `color-mix(in srgb, first percent%, second)` for hex inputs: a straight\n * per-channel blend, rounded to the nearest 8-bit value.\n */\nexport function mixHex(first: string, percent: number, second: string): string {\n const weight = percent / PERCENT;\n const a = hexChannels(first);\n const b = hexChannels(second);\n return `#${a\n .map((channel, index) => {\n const mixed = Math.round(channel * weight + b[index]! * (1 - weight));\n return Math.min(CHANNEL_MAX, Math.max(0, mixed)).toString(16).padStart(2, '0');\n })\n .join('')}`;\n}\n\n/**\n * A hex colour at `percent` opacity as `#rrggbbaa`: the native form of\n * Tailwind's `/40`-style opacity modifiers.\n */\nexport function withAlpha(hex: string, percent: number): string {\n const alpha = Math.min(CHANNEL_MAX, Math.max(0, Math.round((percent / PERCENT) * CHANNEL_MAX)));\n const channels = [...hexChannels(hex), alpha];\n return `#${channels.map((channel) => channel.toString(16).padStart(2, '0')).join('')}`;\n}\n\nfunction rampValues(pick: (step: NativeTypeStep) => number): Record<NativeTypeStep, number> {\n const values = {} as Record<NativeTypeStep, number>;\n for (const step of Object.keys(NATIVE_TYPE_RAMP) as NativeTypeStep[]) values[step] = pick(step);\n return values;\n}\n\n/** Resolves a web theme config to native values; tokens the theme pins win over the derived mix. */\nexport function nativeTheme(config: ThemeConfig): PoNativeTheme {\n const pinned = config.tokens as Partial<Record<ThemeToken, string>>;\n const colors = {} as Record<NativeColorToken, string>;\n for (const token of PALETTE_TOKENS) colors[token] = config.tokens[token];\n const resolve = (token: NativeColorToken, fallback: () => string): void => {\n colors[token] = pinned[token] ?? fallback();\n };\n for (const accent of ACCENT_TOKENS) {\n resolve(`tint-${accent}`, () => mixHex(colors[accent], TINT_MIX_PERCENT, colors.panel));\n }\n for (const accent of ACCENT_TOKENS) {\n resolve(`edge-${accent}`, () => mixHex(colors[accent], EDGE_MIX_PERCENT, colors.border));\n }\n resolve('on-selected', () => mixHex(colors.selected, ON_SELECTED_MIX_PERCENT, ON_SELECTED_BASE));\n\n return {\n scheme: config.scheme,\n colors,\n spacing: (steps) => steps * NATIVE_SPACING_BASE,\n borderRadius: NATIVE_BORDER_RADIUS,\n fontSize: rampValues((step) => NATIVE_TYPE_RAMP[step].size),\n lineHeight: rampValues((step) => Math.round(NATIVE_TYPE_RAMP[step].size * NATIVE_TYPE_RAMP[step].leading)),\n lineHeightRelaxed: rampValues((step) => Math.round(NATIVE_TYPE_RAMP[step].size * NATIVE_LEADING_RELAXED)),\n letterSpacing: rampValues((step) => {\n const em = (NATIVE_LETTER_SPACING_EM as Partial<Record<NativeTypeStep, number>>)[step] ?? 0;\n return Math.round(NATIVE_TYPE_RAMP[step].size * em * PX_PRECISION) / PX_PRECISION;\n }),\n fontWeight: NATIVE_FONT_WEIGHT,\n fontFamily: NATIVE_FONT_FAMILY,\n motion: NATIVE_MOTION,\n };\n}\n\nfunction shippedNative(name: string): PoNativeTheme {\n const theme = builtinTheme(name);\n if (theme === undefined) throw new Error(`The shipped theme ${name} is missing.`);\n return nativeTheme(theme);\n}\n\n/** The native themes by the names the native shell registers: `dark` and `light`. */\nexport const NATIVE_THEMES: Readonly<Record<NativeNamedTheme, PoNativeTheme>> = {\n dark: shippedNative('po-nord-dark'),\n light: shippedNative('po-one-light'),\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("../../themes/po-nord-dark.cjs"),t=require("../../themes/po-one-dark.cjs"),n=require("../../themes/po-one-light.cjs"),r=require("./parse.cjs");function i(e,t){let n=r.parseThemeConfig(e);if(n===null)throw Error(`The shipped theme ${t} is malformed.`);return n}const a=[i(t.default,`po-one-dark.json`),i(n.default,`po-one-light.json`),i(e.default,`po-nord-dark.json`)],o=a[0];function s(e){return a.find(t=>t.name===e)}exports.BUILTIN_THEMES=a,exports.DEFAULT_THEME=o,exports.DEFAULT_THEME_NAME=`po-one-dark`,exports.builtinTheme=s;
1
+ const e=require("../../themes/po-nord-dark.cjs"),t=require("../../themes/po-one-light.cjs"),n=require("./parse.cjs");function r(e,t){let r=n.parseThemeConfig(e);if(r===null)throw Error(`The shipped theme ${t} is malformed.`);return r}const i=[r(t.default,`po-one-light.json`),r(e.default,`po-nord-dark.json`)],a=i[0];function o(e){return i.find(t=>t.name===e)}exports.BUILTIN_THEMES=i,exports.DEFAULT_THEME=a,exports.DEFAULT_THEME_NAME=`po-one-light`,exports.builtinTheme=o;
2
2
  //# sourceMappingURL=builtinThemes.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"builtinThemes.cjs","names":["parseThemeConfig","poOneDark","poOneLight","poNordDark","require_po_nord_dark","require_po_one_dark","require_po_one_light","require_parse","shipped","theme","input","file","BUILTIN_THEMES","DEFAULT_THEME","builtinTheme","name"],"sources":["../../../src/theme/builtinThemes.ts"],"sourcesContent":["import poNordDark from '../../themes/po-nord-dark.json' with { type: 'json' };\nimport poOneDark from '../../themes/po-one-dark.json' with { type: 'json' };\nimport poOneLight from '../../themes/po-one-light.json' with { type: 'json' };\nimport type { ThemeConfig } from '../types/theme';\nimport { parseThemeConfig } from './parse';\n\nfunction shipped(input: unknown, file: string): ThemeConfig {\n const theme = parseThemeConfig(input);\n if (theme === null) throw new Error(`The shipped theme ${file} is malformed.`);\n return theme;\n}\n\n/** The theme the cockpit renders with until a preference says otherwise. */\nexport const DEFAULT_THEME_NAME = 'po-one-dark';\n\n/** The themes this package ships, default first. */\nexport const BUILTIN_THEMES: readonly ThemeConfig[] = [\n shipped(poOneDark, 'po-one-dark.json'),\n shipped(poOneLight, 'po-one-light.json'),\n shipped(poNordDark, 'po-nord-dark.json'),\n];\n\nexport const DEFAULT_THEME: ThemeConfig = BUILTIN_THEMES[0];\n\n/** A shipped theme by name, or undefined for a name nothing shipped under. */\nexport function builtinTheme(name: string): ThemeConfig | undefined {\n return BUILTIN_THEMES.find((theme) => theme.name === name);\n}\n"],"mappings":"+JAMA,SAASQ,EAAQ,EAAgB,EAA2B,CAC1D,IAAMC,EAAQT,EAAAA,iBAAiBU,CAAK,EACpC,GAAID,IAAU,KAAM,MAAU,MAAM,qBAAqBE,EAAK,eAAe,EAC7E,OAAOF,CACT,CAGA,MAGaG,EAAyC,CACpDJ,EAAQP,EAAAA,QAAW,kBAAkB,EACrCO,EAAQN,EAAAA,QAAY,mBAAmB,EACvCM,EAAQL,EAAAA,QAAY,mBAAmB,CACzC,EAEaU,EAA6BD,EAAe,GAGzD,SAAgBE,EAAa,EAAuC,CAClE,OAAOF,EAAe,KAAM,GAAUH,EAAM,OAASM,CAAI,CAC3D"}
1
+ {"version":3,"file":"builtinThemes.cjs","names":["parseThemeConfig","poOneLight","poNordDark","require_po_nord_dark","require_po_one_light","require_parse","shipped","theme","input","file","BUILTIN_THEMES","DEFAULT_THEME","builtinTheme","name"],"sources":["../../../src/theme/builtinThemes.ts"],"sourcesContent":["import poNordDark from '../../themes/po-nord-dark.json' with { type: 'json' };\nimport poOneLight from '../../themes/po-one-light.json' with { type: 'json' };\nimport type { ThemeConfig } from '../types/theme';\nimport { parseThemeConfig } from './parse';\n\nfunction shipped(input: unknown, file: string): ThemeConfig {\n const theme = parseThemeConfig(input);\n if (theme === null) throw new Error(`The shipped theme ${file} is malformed.`);\n return theme;\n}\n\n/** The theme the cockpit renders with until a preference says otherwise. */\nexport const DEFAULT_THEME_NAME = 'po-one-light';\n\n/** The themes this package ships, default first. */\nexport const BUILTIN_THEMES: readonly ThemeConfig[] = [\n shipped(poOneLight, 'po-one-light.json'),\n shipped(poNordDark, 'po-nord-dark.json'),\n];\n\nexport const DEFAULT_THEME: ThemeConfig = BUILTIN_THEMES[0];\n\n/** A shipped theme by name, or undefined for a name nothing shipped under. */\nexport function builtinTheme(name: string): ThemeConfig | undefined {\n return BUILTIN_THEMES.find((theme) => theme.name === name);\n}\n"],"mappings":"qHAKA,SAASM,EAAQ,EAAgB,EAA2B,CAC1D,IAAMC,EAAQP,EAAAA,iBAAiBQ,CAAK,EACpC,GAAID,IAAU,KAAM,MAAU,MAAM,qBAAqBE,EAAK,eAAe,EAC7E,OAAOF,CACT,CAGA,MAGaG,EAAyC,CACpDJ,EAAQL,EAAAA,QAAY,mBAAmB,EACvCK,EAAQJ,EAAAA,QAAY,mBAAmB,CACzC,EAEaS,EAA6BD,EAAe,GAGzD,SAAgBE,EAAa,EAAuC,CAClE,OAAOF,EAAe,KAAM,GAAUH,EAAM,OAASM,CAAI,CAC3D"}
@@ -1,2 +1,2 @@
1
- const e=require("../types/theme.cjs"),t=require("./builtinThemes.cjs");require("./derive.cjs");const n={xs:2,sm:3,md:5,lg:10},r={...n,DEFAULT:4,full:9999},i={"2xs":{size:9,leading:1.45},xs:{size:10,leading:1.45},sm:{size:12,leading:1.45},base:{size:13,leading:1.5},lg:{size:15,leading:1.4},xl:{size:18,leading:1.3},"2xl":{size:22,leading:1.25},"3xl":{size:28,leading:1.2}},a={xl:-.01,"2xl":-.01,"3xl":-.01},o=1.625,s={regular:`400`,medium:`500`,semibold:`600`},c={fade:140,pop:160,rise:160,slide:180,easing:[.16,1,.3,1]},l={sans:{family:`IBM Plex Sans`,ios:`System`,android:`sans-serif`},mono:{family:`JetBrains Mono`,ios:`Menlo`,android:`monospace`}},u=/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;function d(e){if(!u.test(e))throw Error(`Native themes need hex colours; got "${e}".`);let t=e.length===4?e.slice(1).split(``).map(e=>e+e).join(``):e.slice(1);return[0,2,4].map(e=>Number.parseInt(t.slice(e,e+2),16))}function f(e,t,n){let r=t/100,i=d(e),a=d(n);return`#${i.map((e,t)=>{let n=Math.round(e*r+a[t]*(1-r));return Math.min(255,Math.max(0,n)).toString(16).padStart(2,`0`)}).join(``)}`}function p(e,t){let n=Math.min(255,Math.max(0,Math.round(t/100*255)));return`#${[...d(e),n].map(e=>e.toString(16).padStart(2,`0`)).join(``)}`}function m(e){let t={};for(let n of Object.keys(i))t[n]=e(n);return t}function h(t){let n=t.tokens,u={};for(let n of e.PALETTE_TOKENS)u[n]=t.tokens[n];let d=(e,t)=>{u[e]=n[e]??t()};for(let t of e.ACCENT_TOKENS)d(`tint-${t}`,()=>f(u[t],16,u.panel));for(let t of e.ACCENT_TOKENS)d(`edge-${t}`,()=>f(u[t],40,u.border));return d(`on-selected`,()=>f(u.selected,12,`#ffffff`)),{scheme:t.scheme,colors:u,spacing:e=>e*4,borderRadius:r,fontSize:m(e=>i[e].size),lineHeight:m(e=>Math.round(i[e].size*i[e].leading)),lineHeightRelaxed:m(e=>Math.round(i[e].size*o)),letterSpacing:m(e=>{let t=a[e]??0;return Math.round(i[e].size*t*100)/100}),fontWeight:s,fontFamily:l,motion:c}}function g(e){let n=t.builtinTheme(e);if(n===void 0)throw Error(`The shipped theme ${e} is missing.`);return h(n)}const _={dark:g(`po-one-dark`),light:g(`po-one-light`)};exports.NATIVE_BORDER_RADIUS=r,exports.NATIVE_FONT_FAMILY=l,exports.NATIVE_FONT_WEIGHT=s,exports.NATIVE_LEADING_RELAXED=o,exports.NATIVE_LETTER_SPACING_EM=a,exports.NATIVE_MOTION=c,exports.NATIVE_RADII=n,exports.NATIVE_SPACING_BASE=4,exports.NATIVE_THEMES=_,exports.NATIVE_TYPE_RAMP=i,exports.mixHex=f,exports.nativeTheme=h,exports.withAlpha=p;
1
+ const e=require("../types/theme.cjs"),t=require("./builtinThemes.cjs");require("./derive.cjs");const n={xs:2,sm:3,md:5,lg:10},r={...n,DEFAULT:4,full:9999},i={"2xs":{size:9,leading:1.45},xs:{size:10,leading:1.45},sm:{size:12,leading:1.45},base:{size:13,leading:1.5},lg:{size:15,leading:1.4},xl:{size:18,leading:1.3},"2xl":{size:22,leading:1.25},"3xl":{size:28,leading:1.2}},a={xl:-.01,"2xl":-.01,"3xl":-.01},o=1.625,s={regular:`400`,medium:`500`,semibold:`600`},c={fade:140,pop:160,rise:160,slide:180,easing:[.16,1,.3,1]},l={sans:{family:`IBM Plex Sans`,ios:`System`,android:`sans-serif`},mono:{family:`JetBrains Mono`,ios:`Menlo`,android:`monospace`}},u=/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;function d(e){if(!u.test(e))throw Error(`Native themes need hex colours; got "${e}".`);let t=e.length===4?e.slice(1).split(``).map(e=>e+e).join(``):e.slice(1);return[0,2,4].map(e=>Number.parseInt(t.slice(e,e+2),16))}function f(e,t,n){let r=t/100,i=d(e),a=d(n);return`#${i.map((e,t)=>{let n=Math.round(e*r+a[t]*(1-r));return Math.min(255,Math.max(0,n)).toString(16).padStart(2,`0`)}).join(``)}`}function p(e,t){let n=Math.min(255,Math.max(0,Math.round(t/100*255)));return`#${[...d(e),n].map(e=>e.toString(16).padStart(2,`0`)).join(``)}`}function m(e){let t={};for(let n of Object.keys(i))t[n]=e(n);return t}function h(t){let n=t.tokens,u={};for(let n of e.PALETTE_TOKENS)u[n]=t.tokens[n];let d=(e,t)=>{u[e]=n[e]??t()};for(let t of e.ACCENT_TOKENS)d(`tint-${t}`,()=>f(u[t],16,u.panel));for(let t of e.ACCENT_TOKENS)d(`edge-${t}`,()=>f(u[t],40,u.border));return d(`on-selected`,()=>f(u.selected,12,`#ffffff`)),{scheme:t.scheme,colors:u,spacing:e=>e*4,borderRadius:r,fontSize:m(e=>i[e].size),lineHeight:m(e=>Math.round(i[e].size*i[e].leading)),lineHeightRelaxed:m(e=>Math.round(i[e].size*o)),letterSpacing:m(e=>{let t=a[e]??0;return Math.round(i[e].size*t*100)/100}),fontWeight:s,fontFamily:l,motion:c}}function g(e){let n=t.builtinTheme(e);if(n===void 0)throw Error(`The shipped theme ${e} is missing.`);return h(n)}const _={dark:g(`po-nord-dark`),light:g(`po-one-light`)};exports.NATIVE_BORDER_RADIUS=r,exports.NATIVE_FONT_FAMILY=l,exports.NATIVE_FONT_WEIGHT=s,exports.NATIVE_LEADING_RELAXED=o,exports.NATIVE_LETTER_SPACING_EM=a,exports.NATIVE_MOTION=c,exports.NATIVE_RADII=n,exports.NATIVE_SPACING_BASE=4,exports.NATIVE_THEMES=_,exports.NATIVE_TYPE_RAMP=i,exports.mixHex=f,exports.nativeTheme=h,exports.withAlpha=p;
2
2
  //# sourceMappingURL=nativeTheme.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"nativeTheme.cjs","names":["PALETTE_TOKENS","ACCENT_TOKENS","builtinTheme","require_theme","require_builtinThemes","NATIVE_RADII","NATIVE_BORDER_RADIUS","NATIVE_TYPE_RAMP","NATIVE_LETTER_SPACING_EM","NATIVE_LEADING_RELAXED","NATIVE_FONT_WEIGHT","NATIVE_MOTION","NATIVE_FONT_FAMILY","HEX_COLOR","hexChannels","hex","digits","digit","offset","mixHex","weight","percent","a","first","b","second","mixed","channel","index","withAlpha","alpha","rampValues","values","step","pick","nativeTheme","pinned","config","colors","token","resolve","fallback","accent","steps","em","shippedNative","theme","name","NATIVE_THEMES"],"sources":["../../../src/theme/nativeTheme.ts"],"sourcesContent":["import { ACCENT_TOKENS, PALETTE_TOKENS, type ThemeConfig, type ThemeScheme, type ThemeToken } from '../types/theme';\nimport { builtinTheme } from './builtinThemes';\nimport { EDGE_MIX_PERCENT, ON_SELECTED_MIX_PERCENT, TINT_MIX_PERCENT } from './derive';\n\n/*\n * The React Native copy of the web theme. Native styles cannot read CSS\n * custom properties or evaluate color-mix(), so this module resolves the same\n * tokens to plain values. The scales below mirror styles/theme.css by hand\n * (CSS cannot import TypeScript); tests/nativeTheme.test.ts fails when the two\n * drift.\n *\n * ponytail: bundle IBM Plex Sans and JetBrains Mono through expo-font when the\n * native visual review starts; until then the named families fall back to the\n * platform fonts below.\n * ponytail: add a native theme picker later; the shell follows the system\n * scheme between `light` and `dark` for now.\n * ponytail: `--tracking-*` (tracked uppercase micro-labels) is not ported;\n * docs/design.md bans tracked uppercase on new surfaces.\n * ponytail: `shadow-2xl` is not ported; native surfaces (sheets, modals,\n * headers) draw their own platform shadows.\n */\n\n/** The spacing unit, matching `--spacing: 0.25rem` at a 16px root. */\nexport const NATIVE_SPACING_BASE = 4;\n\n/** Corner radii in px, matching `--radius-*`. */\nexport const NATIVE_RADII = { xs: 2, sm: 3, md: 5, lg: 10 } as const;\n\n/**\n * Every radius a native style may name: the retunable `--radius-*` steps, plus\n * Tailwind's hardcoded bare `rounded` (4px) and `rounded-full`.\n */\nexport const NATIVE_BORDER_RADIUS = { ...NATIVE_RADII, DEFAULT: 4, full: 9999 } as const;\n\n/** The type ramp, matching `--text-*` (px) and `--text-*--line-height` (a multiple of the size). */\nexport const NATIVE_TYPE_RAMP = {\n '2xs': { size: 9, leading: 1.45 },\n xs: { size: 10, leading: 1.45 },\n sm: { size: 12, leading: 1.45 },\n base: { size: 13, leading: 1.5 },\n lg: { size: 15, leading: 1.4 },\n xl: { size: 18, leading: 1.3 },\n '2xl': { size: 22, leading: 1.25 },\n '3xl': { size: 28, leading: 1.2 },\n} as const;\n\n/** Title tracking in em, matching `--text-*--letter-spacing`; steps not listed track at 0. */\nexport const NATIVE_LETTER_SPACING_EM = { xl: -0.01, '2xl': -0.01, '3xl': -0.01 } as const;\n\n/** Tailwind's `leading-relaxed` multiple, which theme.css does not override. */\nexport const NATIVE_LEADING_RELAXED = 1.625;\n\n/** Font weights as React Native takes them, matching `font-normal`, `font-medium` and `font-semibold`. */\nexport const NATIVE_FONT_WEIGHT = { regular: '400', medium: '500', semibold: '600' } as const;\n\n/**\n * Durations in ms and the shared easing curve of `--animate-po-*`. `slide`\n * covers both slide directions; `easing` is the `cubic-bezier()` control points\n * for Reanimated's `Easing.bezier`.\n */\nexport const NATIVE_MOTION = {\n fade: 140,\n pop: 160,\n rise: 160,\n slide: 180,\n easing: [0.16, 1, 0.3, 1],\n} as const;\n\n/** A font as native styles name it: one family, plus the platform font to use until it is bundled. */\nexport interface NativeFontStack {\n family: string;\n ios: string;\n android: string;\n}\n\n/** The sans and mono families of `--font-sans` and `--po-font-mono`, with system fallbacks. */\nexport const NATIVE_FONT_FAMILY: { readonly sans: NativeFontStack; readonly mono: NativeFontStack } = {\n sans: { family: 'IBM Plex Sans', ios: 'System', android: 'sans-serif' },\n mono: { family: 'JetBrains Mono', ios: 'Menlo', android: 'monospace' },\n};\n\n/** The foreground `on-selected` mixes toward, as `white` in derive.ts. */\nconst ON_SELECTED_BASE = '#ffffff';\nconst HEX_COLOR = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst PERCENT = 100;\nconst CHANNEL_MAX = 255;\n/** Rounds px values to hundredths so `18 * -0.01` reads -0.18, not a float tail. */\nconst PX_PRECISION = 100;\n\nexport type NativeColorToken = Exclude<ThemeToken, 'font-mono'>;\nexport type NativeTypeStep = keyof typeof NATIVE_TYPE_RAMP;\nexport type NativeNamedTheme = 'dark' | 'light';\n\nexport interface PoNativeTheme {\n scheme: ThemeScheme;\n colors: Record<NativeColorToken, string>;\n /** `spacing(n)` is n steps of the 4px base, as Tailwind's `p-n`. */\n spacing: (steps: number) => number;\n borderRadius: typeof NATIVE_BORDER_RADIUS;\n fontSize: Record<NativeTypeStep, number>;\n /** Absolute line heights in px, since native styles take no unitless multiple. */\n lineHeight: Record<NativeTypeStep, number>;\n /** `leading-relaxed` line heights in px, for reading text such as markdown bodies. */\n lineHeightRelaxed: Record<NativeTypeStep, number>;\n /** Letter spacing in px per step; titles track slightly tight, the rest at 0. */\n letterSpacing: Record<NativeTypeStep, number>;\n fontWeight: typeof NATIVE_FONT_WEIGHT;\n fontFamily: typeof NATIVE_FONT_FAMILY;\n motion: typeof NATIVE_MOTION;\n}\n\nfunction hexChannels(hex: string): [number, number, number] {\n if (!HEX_COLOR.test(hex)) throw new Error(`Native themes need hex colours; got \"${hex}\".`);\n const digits =\n hex.length === 4\n ? hex\n .slice(1)\n .split('')\n .map((digit) => digit + digit)\n .join('')\n : hex.slice(1);\n return [0, 2, 4].map((offset) => Number.parseInt(digits.slice(offset, offset + 2), 16)) as [number, number, number];\n}\n\n/**\n * `color-mix(in srgb, first percent%, second)` for hex inputs: a straight\n * per-channel blend, rounded to the nearest 8-bit value.\n */\nexport function mixHex(first: string, percent: number, second: string): string {\n const weight = percent / PERCENT;\n const a = hexChannels(first);\n const b = hexChannels(second);\n return `#${a\n .map((channel, index) => {\n const mixed = Math.round(channel * weight + b[index]! * (1 - weight));\n return Math.min(CHANNEL_MAX, Math.max(0, mixed)).toString(16).padStart(2, '0');\n })\n .join('')}`;\n}\n\n/**\n * A hex colour at `percent` opacity as `#rrggbbaa`: the native form of\n * Tailwind's `/40`-style opacity modifiers.\n */\nexport function withAlpha(hex: string, percent: number): string {\n const alpha = Math.min(CHANNEL_MAX, Math.max(0, Math.round((percent / PERCENT) * CHANNEL_MAX)));\n const channels = [...hexChannels(hex), alpha];\n return `#${channels.map((channel) => channel.toString(16).padStart(2, '0')).join('')}`;\n}\n\nfunction rampValues(pick: (step: NativeTypeStep) => number): Record<NativeTypeStep, number> {\n const values = {} as Record<NativeTypeStep, number>;\n for (const step of Object.keys(NATIVE_TYPE_RAMP) as NativeTypeStep[]) values[step] = pick(step);\n return values;\n}\n\n/** Resolves a web theme config to native values; tokens the theme pins win over the derived mix. */\nexport function nativeTheme(config: ThemeConfig): PoNativeTheme {\n const pinned = config.tokens as Partial<Record<ThemeToken, string>>;\n const colors = {} as Record<NativeColorToken, string>;\n for (const token of PALETTE_TOKENS) colors[token] = config.tokens[token];\n const resolve = (token: NativeColorToken, fallback: () => string): void => {\n colors[token] = pinned[token] ?? fallback();\n };\n for (const accent of ACCENT_TOKENS) {\n resolve(`tint-${accent}`, () => mixHex(colors[accent], TINT_MIX_PERCENT, colors.panel));\n }\n for (const accent of ACCENT_TOKENS) {\n resolve(`edge-${accent}`, () => mixHex(colors[accent], EDGE_MIX_PERCENT, colors.border));\n }\n resolve('on-selected', () => mixHex(colors.selected, ON_SELECTED_MIX_PERCENT, ON_SELECTED_BASE));\n\n return {\n scheme: config.scheme,\n colors,\n spacing: (steps) => steps * NATIVE_SPACING_BASE,\n borderRadius: NATIVE_BORDER_RADIUS,\n fontSize: rampValues((step) => NATIVE_TYPE_RAMP[step].size),\n lineHeight: rampValues((step) => Math.round(NATIVE_TYPE_RAMP[step].size * NATIVE_TYPE_RAMP[step].leading)),\n lineHeightRelaxed: rampValues((step) => Math.round(NATIVE_TYPE_RAMP[step].size * NATIVE_LEADING_RELAXED)),\n letterSpacing: rampValues((step) => {\n const em = (NATIVE_LETTER_SPACING_EM as Partial<Record<NativeTypeStep, number>>)[step] ?? 0;\n return Math.round(NATIVE_TYPE_RAMP[step].size * em * PX_PRECISION) / PX_PRECISION;\n }),\n fontWeight: NATIVE_FONT_WEIGHT,\n fontFamily: NATIVE_FONT_FAMILY,\n motion: NATIVE_MOTION,\n };\n}\n\nfunction shippedNative(name: string): PoNativeTheme {\n const theme = builtinTheme(name);\n if (theme === undefined) throw new Error(`The shipped theme ${name} is missing.`);\n return nativeTheme(theme);\n}\n\n/** The native themes by the names the native shell registers: `dark` and `light`. */\nexport const NATIVE_THEMES: Readonly<Record<NativeNamedTheme, PoNativeTheme>> = {\n dark: shippedNative('po-one-dark'),\n light: shippedNative('po-one-light'),\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"nativeTheme.cjs","names":["PALETTE_TOKENS","ACCENT_TOKENS","builtinTheme","require_theme","require_builtinThemes","NATIVE_RADII","NATIVE_BORDER_RADIUS","NATIVE_TYPE_RAMP","NATIVE_LETTER_SPACING_EM","NATIVE_LEADING_RELAXED","NATIVE_FONT_WEIGHT","NATIVE_MOTION","NATIVE_FONT_FAMILY","HEX_COLOR","hexChannels","hex","digits","digit","offset","mixHex","weight","percent","a","first","b","second","mixed","channel","index","withAlpha","alpha","rampValues","values","step","pick","nativeTheme","pinned","config","colors","token","resolve","fallback","accent","steps","em","shippedNative","theme","name","NATIVE_THEMES"],"sources":["../../../src/theme/nativeTheme.ts"],"sourcesContent":["import { ACCENT_TOKENS, PALETTE_TOKENS, type ThemeConfig, type ThemeScheme, type ThemeToken } from '../types/theme';\nimport { builtinTheme } from './builtinThemes';\nimport { EDGE_MIX_PERCENT, ON_SELECTED_MIX_PERCENT, TINT_MIX_PERCENT } from './derive';\n\n/*\n * The React Native copy of the web theme. Native styles cannot read CSS\n * custom properties or evaluate color-mix(), so this module resolves the same\n * tokens to plain values. The scales below mirror styles/theme.css by hand\n * (CSS cannot import TypeScript); tests/nativeTheme.test.ts fails when the two\n * drift.\n *\n * ponytail: bundle IBM Plex Sans and JetBrains Mono through expo-font when the\n * native visual review starts; until then the named families fall back to the\n * platform fonts below.\n * ponytail: add a native theme picker later; the shell follows the system\n * scheme between `light` and `dark` for now.\n * ponytail: `--tracking-*` (tracked uppercase micro-labels) is not ported;\n * docs/design.md bans tracked uppercase on new surfaces.\n * ponytail: `shadow-2xl` is not ported; native surfaces (sheets, modals,\n * headers) draw their own platform shadows.\n */\n\n/** The spacing unit, matching `--spacing: 0.25rem` at a 16px root. */\nexport const NATIVE_SPACING_BASE = 4;\n\n/** Corner radii in px, matching `--radius-*`. */\nexport const NATIVE_RADII = { xs: 2, sm: 3, md: 5, lg: 10 } as const;\n\n/**\n * Every radius a native style may name: the retunable `--radius-*` steps, plus\n * Tailwind's hardcoded bare `rounded` (4px) and `rounded-full`.\n */\nexport const NATIVE_BORDER_RADIUS = { ...NATIVE_RADII, DEFAULT: 4, full: 9999 } as const;\n\n/** The type ramp, matching `--text-*` (px) and `--text-*--line-height` (a multiple of the size). */\nexport const NATIVE_TYPE_RAMP = {\n '2xs': { size: 9, leading: 1.45 },\n xs: { size: 10, leading: 1.45 },\n sm: { size: 12, leading: 1.45 },\n base: { size: 13, leading: 1.5 },\n lg: { size: 15, leading: 1.4 },\n xl: { size: 18, leading: 1.3 },\n '2xl': { size: 22, leading: 1.25 },\n '3xl': { size: 28, leading: 1.2 },\n} as const;\n\n/** Title tracking in em, matching `--text-*--letter-spacing`; steps not listed track at 0. */\nexport const NATIVE_LETTER_SPACING_EM = { xl: -0.01, '2xl': -0.01, '3xl': -0.01 } as const;\n\n/** Tailwind's `leading-relaxed` multiple, which theme.css does not override. */\nexport const NATIVE_LEADING_RELAXED = 1.625;\n\n/** Font weights as React Native takes them, matching `font-normal`, `font-medium` and `font-semibold`. */\nexport const NATIVE_FONT_WEIGHT = { regular: '400', medium: '500', semibold: '600' } as const;\n\n/**\n * Durations in ms and the shared easing curve of `--animate-po-*`. `slide`\n * covers both slide directions; `easing` is the `cubic-bezier()` control points\n * for Reanimated's `Easing.bezier`.\n */\nexport const NATIVE_MOTION = {\n fade: 140,\n pop: 160,\n rise: 160,\n slide: 180,\n easing: [0.16, 1, 0.3, 1],\n} as const;\n\n/** A font as native styles name it: one family, plus the platform font to use until it is bundled. */\nexport interface NativeFontStack {\n family: string;\n ios: string;\n android: string;\n}\n\n/** The sans and mono families of `--font-sans` and `--po-font-mono`, with system fallbacks. */\nexport const NATIVE_FONT_FAMILY: { readonly sans: NativeFontStack; readonly mono: NativeFontStack } = {\n sans: { family: 'IBM Plex Sans', ios: 'System', android: 'sans-serif' },\n mono: { family: 'JetBrains Mono', ios: 'Menlo', android: 'monospace' },\n};\n\n/** The foreground `on-selected` mixes toward, as `white` in derive.ts. */\nconst ON_SELECTED_BASE = '#ffffff';\nconst HEX_COLOR = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst PERCENT = 100;\nconst CHANNEL_MAX = 255;\n/** Rounds px values to hundredths so `18 * -0.01` reads -0.18, not a float tail. */\nconst PX_PRECISION = 100;\n\nexport type NativeColorToken = Exclude<ThemeToken, 'font-mono'>;\nexport type NativeTypeStep = keyof typeof NATIVE_TYPE_RAMP;\nexport type NativeNamedTheme = 'dark' | 'light';\n\nexport interface PoNativeTheme {\n scheme: ThemeScheme;\n colors: Record<NativeColorToken, string>;\n /** `spacing(n)` is n steps of the 4px base, as Tailwind's `p-n`. */\n spacing: (steps: number) => number;\n borderRadius: typeof NATIVE_BORDER_RADIUS;\n fontSize: Record<NativeTypeStep, number>;\n /** Absolute line heights in px, since native styles take no unitless multiple. */\n lineHeight: Record<NativeTypeStep, number>;\n /** `leading-relaxed` line heights in px, for reading text such as markdown bodies. */\n lineHeightRelaxed: Record<NativeTypeStep, number>;\n /** Letter spacing in px per step; titles track slightly tight, the rest at 0. */\n letterSpacing: Record<NativeTypeStep, number>;\n fontWeight: typeof NATIVE_FONT_WEIGHT;\n fontFamily: typeof NATIVE_FONT_FAMILY;\n motion: typeof NATIVE_MOTION;\n}\n\nfunction hexChannels(hex: string): [number, number, number] {\n if (!HEX_COLOR.test(hex)) throw new Error(`Native themes need hex colours; got \"${hex}\".`);\n const digits =\n hex.length === 4\n ? hex\n .slice(1)\n .split('')\n .map((digit) => digit + digit)\n .join('')\n : hex.slice(1);\n return [0, 2, 4].map((offset) => Number.parseInt(digits.slice(offset, offset + 2), 16)) as [number, number, number];\n}\n\n/**\n * `color-mix(in srgb, first percent%, second)` for hex inputs: a straight\n * per-channel blend, rounded to the nearest 8-bit value.\n */\nexport function mixHex(first: string, percent: number, second: string): string {\n const weight = percent / PERCENT;\n const a = hexChannels(first);\n const b = hexChannels(second);\n return `#${a\n .map((channel, index) => {\n const mixed = Math.round(channel * weight + b[index]! * (1 - weight));\n return Math.min(CHANNEL_MAX, Math.max(0, mixed)).toString(16).padStart(2, '0');\n })\n .join('')}`;\n}\n\n/**\n * A hex colour at `percent` opacity as `#rrggbbaa`: the native form of\n * Tailwind's `/40`-style opacity modifiers.\n */\nexport function withAlpha(hex: string, percent: number): string {\n const alpha = Math.min(CHANNEL_MAX, Math.max(0, Math.round((percent / PERCENT) * CHANNEL_MAX)));\n const channels = [...hexChannels(hex), alpha];\n return `#${channels.map((channel) => channel.toString(16).padStart(2, '0')).join('')}`;\n}\n\nfunction rampValues(pick: (step: NativeTypeStep) => number): Record<NativeTypeStep, number> {\n const values = {} as Record<NativeTypeStep, number>;\n for (const step of Object.keys(NATIVE_TYPE_RAMP) as NativeTypeStep[]) values[step] = pick(step);\n return values;\n}\n\n/** Resolves a web theme config to native values; tokens the theme pins win over the derived mix. */\nexport function nativeTheme(config: ThemeConfig): PoNativeTheme {\n const pinned = config.tokens as Partial<Record<ThemeToken, string>>;\n const colors = {} as Record<NativeColorToken, string>;\n for (const token of PALETTE_TOKENS) colors[token] = config.tokens[token];\n const resolve = (token: NativeColorToken, fallback: () => string): void => {\n colors[token] = pinned[token] ?? fallback();\n };\n for (const accent of ACCENT_TOKENS) {\n resolve(`tint-${accent}`, () => mixHex(colors[accent], TINT_MIX_PERCENT, colors.panel));\n }\n for (const accent of ACCENT_TOKENS) {\n resolve(`edge-${accent}`, () => mixHex(colors[accent], EDGE_MIX_PERCENT, colors.border));\n }\n resolve('on-selected', () => mixHex(colors.selected, ON_SELECTED_MIX_PERCENT, ON_SELECTED_BASE));\n\n return {\n scheme: config.scheme,\n colors,\n spacing: (steps) => steps * NATIVE_SPACING_BASE,\n borderRadius: NATIVE_BORDER_RADIUS,\n fontSize: rampValues((step) => NATIVE_TYPE_RAMP[step].size),\n lineHeight: rampValues((step) => Math.round(NATIVE_TYPE_RAMP[step].size * NATIVE_TYPE_RAMP[step].leading)),\n lineHeightRelaxed: rampValues((step) => Math.round(NATIVE_TYPE_RAMP[step].size * NATIVE_LEADING_RELAXED)),\n letterSpacing: rampValues((step) => {\n const em = (NATIVE_LETTER_SPACING_EM as Partial<Record<NativeTypeStep, number>>)[step] ?? 0;\n return Math.round(NATIVE_TYPE_RAMP[step].size * em * PX_PRECISION) / PX_PRECISION;\n }),\n fontWeight: NATIVE_FONT_WEIGHT,\n fontFamily: NATIVE_FONT_FAMILY,\n motion: NATIVE_MOTION,\n };\n}\n\nfunction shippedNative(name: string): PoNativeTheme {\n const theme = builtinTheme(name);\n if (theme === undefined) throw new Error(`The shipped theme ${name} is missing.`);\n return nativeTheme(theme);\n}\n\n/** The native themes by the names the native shell registers: `dark` and `light`. */\nexport const NATIVE_THEMES: Readonly<Record<NativeNamedTheme, PoNativeTheme>> = {\n dark: shippedNative('po-nord-dark'),\n light: shippedNative('po-one-light'),\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-web-components",
3
- "version": "0.0.0-alpha.5",
3
+ "version": "0.0.0-alpha.7",
4
4
  "description": "Shared web components and theme tokens for the Po cockpit and its web plugins: shadcn-style primitives on Radix, tuned to the Po palette, with runtime theme configs.",
5
5
  "keywords": [
6
6
  "ai",
@@ -106,8 +106,8 @@
106
106
  "tailwind-merge": "3.7.0"
107
107
  },
108
108
  "devDependencies": {
109
- "@agimon-ai/po-core": "0.0.0-alpha.5",
110
- "@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.5",
109
+ "@agimon-ai/po-core": "0.0.0-alpha.7",
110
+ "@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.7",
111
111
  "@types/node": "26.6.5",
112
112
  "@types/react": "19.3.0",
113
113
  "@types/react-dom": "19.3.0",
package/styles/theme.css CHANGED
@@ -2,7 +2,7 @@
2
2
  * Po web theme tokens and base styles, reached through tokens.css (which adds
3
3
  * the fonts) or directly by mcp.css (which must not).
4
4
  *
5
- * Tokens are plain custom properties on :root (the shipped dark theme, so a
5
+ * Tokens are plain custom properties on :root (the shipped light theme, so a
6
6
  * page without JavaScript already looks right) mapped inline into Tailwind's
7
7
  * theme, which is what lets applyTheme() swap every utility's colour at
8
8
  * runtime by rewriting the properties. The shadcn semantic names alias the
@@ -20,33 +20,32 @@
20
20
  @source "../dist";
21
21
 
22
22
  :root {
23
- color-scheme: dark;
24
- --po-bg: #1a1d1b;
25
- --po-rail: #151816;
26
- --po-panel: #222724;
27
- --po-deep: #121513;
28
- --po-border: #4f5852;
29
- --po-border-soft: #303733;
30
- --po-hi: #f2efe8;
31
- --po-text: #dfdcd4;
32
- --po-dim: #aeb2aa;
33
- --po-faint: #a1a69e;
34
- --po-blue: #8db8cc;
35
- --po-green: #74c9a2;
36
- --po-yellow: #dcbc85;
37
- --po-red: #ec9387;
38
- --po-magenta: #e8aebd;
39
- --po-violet: #b6a6d2;
40
- --po-cyan: #94c7c6;
41
- --po-orange: #d9ad84;
42
- --po-teal: #93c3ab;
23
+ color-scheme: light;
24
+ --po-bg: #f6f1e7;
25
+ --po-rail: #efe9dc;
26
+ --po-panel: #fffcf5;
27
+ --po-deep: #e7e0d1;
28
+ --po-border: #9a9587;
29
+ --po-border-soft: #ddd6c6;
30
+ --po-hi: #18271f;
31
+ --po-text: #2a3a31;
32
+ --po-dim: #55625a;
33
+ --po-faint: #56645b;
34
+ --po-blue: #285d80;
35
+ --po-green: #1a6b4b;
36
+ --po-yellow: #7a5d1c;
37
+ --po-red: #ad4036;
38
+ --po-magenta: #a2445f;
39
+ --po-violet: #675a80;
40
+ --po-cyan: #2b696c;
41
+ --po-orange: #8c5932;
42
+ --po-teal: #256b52;
43
43
  --po-selected: #2b7a62;
44
44
  --po-tint-blue: color-mix(in srgb, var(--po-blue) 16%, var(--po-panel));
45
45
  --po-tint-green: color-mix(in srgb, var(--po-green) 16%, var(--po-panel));
46
46
  --po-tint-yellow: color-mix(in srgb, var(--po-yellow) 16%, var(--po-panel));
47
47
  --po-tint-red: color-mix(in srgb, var(--po-red) 16%, var(--po-panel));
48
- /* Pinned: the derived mix lands muddy brown on the green-grey panel. */
49
- --po-tint-magenta: #3a2a31;
48
+ --po-tint-magenta: color-mix(in srgb, var(--po-magenta) 16%, var(--po-panel));
50
49
  --po-tint-violet: color-mix(in srgb, var(--po-violet) 16%, var(--po-panel));
51
50
  --po-tint-cyan: color-mix(in srgb, var(--po-cyan) 16%, var(--po-panel));
52
51
  --po-tint-orange: color-mix(in srgb, var(--po-orange) 16%, var(--po-panel));
@@ -55,7 +54,7 @@
55
54
  --po-edge-green: color-mix(in srgb, var(--po-green) 40%, var(--po-border));
56
55
  --po-edge-yellow: color-mix(in srgb, var(--po-yellow) 40%, var(--po-border));
57
56
  --po-edge-red: color-mix(in srgb, var(--po-red) 40%, var(--po-border));
58
- --po-edge-magenta: #8c5f6e;
57
+ --po-edge-magenta: color-mix(in srgb, var(--po-magenta) 40%, var(--po-border));
59
58
  --po-edge-violet: color-mix(in srgb, var(--po-violet) 40%, var(--po-border));
60
59
  --po-edge-cyan: color-mix(in srgb, var(--po-cyan) 40%, var(--po-border));
61
60
  --po-edge-orange: color-mix(in srgb, var(--po-orange) 40%, var(--po-border));
@@ -1,2 +0,0 @@
1
- var e={name:`po-one-dark`,label:`Po Bloom (dark)`,scheme:`dark`,tokens:{bg:`#1a1d1b`,rail:`#151816`,panel:`#222724`,deep:`#121513`,border:`#4f5852`,"border-soft":`#303733`,hi:`#f2efe8`,text:`#dfdcd4`,dim:`#aeb2aa`,faint:`#a1a69e`,blue:`#8db8cc`,green:`#74c9a2`,yellow:`#dcbc85`,red:`#ec9387`,magenta:`#e8aebd`,violet:`#b6a6d2`,cyan:`#94c7c6`,orange:`#d9ad84`,teal:`#93c3ab`,selected:`#2b7a62`,"tint-magenta":`#3a2a31`,"edge-magenta":`#8c5f6e`,"on-selected":`#fffcf6`}};export{e as default};
2
- //# sourceMappingURL=po-one-dark.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"po-one-dark.mjs","names":["po_one_dark_default","\"bg\"","\"rail\"","\"panel\"","\"deep\"","\"border\"","\"hi\"","\"text\"","\"dim\"","\"faint\"","\"blue\"","\"green\"","\"yellow\"","\"red\"","\"magenta\"","\"violet\"","\"cyan\"","\"orange\"","\"teal\"","\"selected\""],"sources":["../../../../../themes/po-one-dark.json"],"sourcesContent":[""],"mappings":""}
@@ -1,2 +0,0 @@
1
- var e={name:`po-one-dark`,label:`Po Bloom (dark)`,scheme:`dark`,tokens:{bg:`#1a1d1b`,rail:`#151816`,panel:`#222724`,deep:`#121513`,border:`#4f5852`,"border-soft":`#303733`,hi:`#f2efe8`,text:`#dfdcd4`,dim:`#aeb2aa`,faint:`#a1a69e`,blue:`#8db8cc`,green:`#74c9a2`,yellow:`#dcbc85`,red:`#ec9387`,magenta:`#e8aebd`,violet:`#b6a6d2`,cyan:`#94c7c6`,orange:`#d9ad84`,teal:`#93c3ab`,selected:`#2b7a62`,"tint-magenta":`#3a2a31`,"edge-magenta":`#8c5f6e`,"on-selected":`#fffcf6`}};Object.defineProperty(exports,"default",{enumerable:!0,get:function(){return e}});
2
- //# sourceMappingURL=po-one-dark.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"po-one-dark.cjs","names":["po_one_dark_default","\"bg\"","\"rail\"","\"panel\"","\"deep\"","\"border\"","\"hi\"","\"text\"","\"dim\"","\"faint\"","\"blue\"","\"green\"","\"yellow\"","\"red\"","\"magenta\"","\"violet\"","\"cyan\"","\"orange\"","\"teal\"","\"selected\""],"sources":["../../themes/po-one-dark.json"],"sourcesContent":[""],"mappings":""}
@@ -1,30 +0,0 @@
1
- {
2
- "name": "po-one-dark",
3
- "label": "Po Bloom (dark)",
4
- "scheme": "dark",
5
- "tokens": {
6
- "bg": "#1a1d1b",
7
- "rail": "#151816",
8
- "panel": "#222724",
9
- "deep": "#121513",
10
- "border": "#4f5852",
11
- "border-soft": "#303733",
12
- "hi": "#f2efe8",
13
- "text": "#dfdcd4",
14
- "dim": "#aeb2aa",
15
- "faint": "#a1a69e",
16
- "blue": "#8db8cc",
17
- "green": "#74c9a2",
18
- "yellow": "#dcbc85",
19
- "red": "#ec9387",
20
- "magenta": "#e8aebd",
21
- "violet": "#b6a6d2",
22
- "cyan": "#94c7c6",
23
- "orange": "#d9ad84",
24
- "teal": "#93c3ab",
25
- "selected": "#2b7a62",
26
- "tint-magenta": "#3a2a31",
27
- "edge-magenta": "#8c5f6e",
28
- "on-selected": "#fffcf6"
29
- }
30
- }