feat(shared): gate paid features from one entitlement source

Desktop, web, mobile, and the API each decided locally what a tier could do,
so a plan change could unlock a feature on one surface and not another.
Entitlement checks now live in `@d3ro/core` and are exercised by tests.

The shared theme and design-system packages also gain the tokens the new
surfaces consume, and the api-client exposes the dictionary and team types
the clients now send.
This commit is contained in:
Yun Chan 2026-09-16 23:24:18 +09:00
parent 6ba25f53b7
commit f6a29db95a
13 changed files with 576 additions and 11 deletions

View file

@ -20,7 +20,7 @@ export function MetalCard({ children, inset = false, style, ...rest }: MetalCard
borderColor: palette.border.subtle,
overflow: 'hidden',
// RN 그림자
shadowColor: palette.shadow ?? '#000',
shadowColor: palette.shadow,
shadowOffset: { width: 0, height: 4 },
shadowOpacity: inset ? 0 : 0.25,
shadowRadius: inset ? 0 : 8,

View file

@ -1,5 +1,5 @@
// packages/ui-native — RN DS barrel
// apps/mobile file: dependency
// Consumed by the React Native app via file: workspace dependencies.
export {
d3roNativePalette,

View file

@ -44,6 +44,17 @@ export interface D3roNativePalette {
green: string
blue: string
}
/** v3: 시맨틱 상태 역할 (액센트와 분리) */
status: {
success: string
successBg: string
warning: string
warningBg: string
danger: string
dangerBg: string
info: string
infoBg: string
}
led: { off: string }
shadow?: string
}
@ -87,9 +98,37 @@ export const d3roNativePalette: D3roNativePalette = {
green: '#22c55e',
blue: '#3b82f6'
},
status: {
success: '#4ade80',
successBg: 'rgba(74, 222, 128, 0.14)',
warning: '#fbbf24',
warningBg: 'rgba(251, 191, 36, 0.14)',
danger: '#f87171',
dangerBg: 'rgba(248, 113, 113, 0.14)',
info: '#60a5fa',
infoBg: 'rgba(96, 165, 250, 0.14)'
},
led: {
off: '#111111'
}
},
shadow: '#000000'
} as const
// ── v3: 간격·컨트롤·웨이트·모션 (RN은 px 숫자) ──
export const d3roNativeSpace = {
s1: 4, s2: 8, s3: 12, s4: 16, s5: 24, s6: 40, s7: 64, s8: 96
} as const
export const d3roNativeControl = {
h: 44, hSm: 36, padX: 16, padXSm: 10
} as const
export const d3roNativeWeight = {
body: '400' as const, medium: '500' as const, strong: '600' as const
} as const
export const d3roNativeMotion = {
instant: 100, quick: 200, normal: 350, slow: 600
} as const
// v3 "타이포그래피 퍼스트" — packages/ui d3roTypo v3와 동일 철학.