about summary refs log tree commit diff
path: root/src/alf
diff options
context:
space:
mode:
Diffstat (limited to 'src/alf')
-rw-r--r--src/alf/atoms.ts344
-rw-r--r--src/alf/index.tsx1
-rw-r--r--src/alf/themes.ts300
-rw-r--r--src/alf/tokens.ts174
-rw-r--r--src/alf/util/flatten.ts3
5 files changed, 647 insertions, 175 deletions
diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts
index c142f5f71..203c2f282 100644
--- a/src/alf/atoms.ts
+++ b/src/alf/atoms.ts
@@ -4,6 +4,9 @@ export const atoms = {
   /*
    * Positioning
    */
+  fixed: {
+    position: 'fixed',
+  },
   absolute: {
     position: 'absolute',
   },
@@ -32,6 +35,10 @@ export const atoms = {
     zIndex: 50,
   },
 
+  overflow_hidden: {
+    overflow: 'hidden',
+  },
+
   /*
    * Width
    */
@@ -45,6 +52,12 @@ export const atoms = {
   /*
    * Border radius
    */
+  rounded_2xs: {
+    borderRadius: tokens.borderRadius._2xs,
+  },
+  rounded_xs: {
+    borderRadius: tokens.borderRadius.xs,
+  },
   rounded_sm: {
     borderRadius: tokens.borderRadius.sm,
   },
@@ -58,8 +71,8 @@ export const atoms = {
   /*
    * Flex
    */
-  gap_xxs: {
-    gap: tokens.space.xxs,
+  gap_2xs: {
+    gap: tokens.space._2xs,
   },
   gap_xs: {
     gap: tokens.space.xs,
@@ -76,8 +89,17 @@ export const atoms = {
   gap_xl: {
     gap: tokens.space.xl,
   },
-  gap_xxl: {
-    gap: tokens.space.xxl,
+  gap_2xl: {
+    gap: tokens.space._2xl,
+  },
+  gap_3xl: {
+    gap: tokens.space._3xl,
+  },
+  gap_4xl: {
+    gap: tokens.space._4xl,
+  },
+  gap_5xl: {
+    gap: tokens.space._5xl,
   },
   flex: {
     display: 'flex',
@@ -125,9 +147,9 @@ export const atoms = {
   text_right: {
     textAlign: 'right',
   },
-  text_xxs: {
-    fontSize: tokens.fontSize.xxs,
-    lineHeight: tokens.fontSize.xxs,
+  text_2xs: {
+    fontSize: tokens.fontSize._2xs,
+    lineHeight: tokens.fontSize._2xs,
   },
   text_xs: {
     fontSize: tokens.fontSize.xs,
@@ -149,9 +171,21 @@ export const atoms = {
     fontSize: tokens.fontSize.xl,
     lineHeight: tokens.fontSize.xl,
   },
-  text_xxl: {
-    fontSize: tokens.fontSize.xxl,
-    lineHeight: tokens.fontSize.xxl,
+  text_2xl: {
+    fontSize: tokens.fontSize._2xl,
+    lineHeight: tokens.fontSize._2xl,
+  },
+  text_3xl: {
+    fontSize: tokens.fontSize._3xl,
+    lineHeight: tokens.fontSize._3xl,
+  },
+  text_4xl: {
+    fontSize: tokens.fontSize._4xl,
+    lineHeight: tokens.fontSize._4xl,
+  },
+  text_5xl: {
+    fontSize: tokens.fontSize._5xl,
+    lineHeight: tokens.fontSize._5xl,
   },
   leading_tight: {
     lineHeight: 1.25,
@@ -162,11 +196,8 @@ export const atoms = {
   font_normal: {
     fontWeight: tokens.fontWeight.normal,
   },
-  font_semibold: {
-    fontWeight: tokens.fontWeight.semibold,
-  },
   font_bold: {
-    fontWeight: tokens.fontWeight.bold,
+    fontWeight: tokens.fontWeight.semibold,
   },
 
   /*
@@ -183,10 +214,29 @@ export const atoms = {
   },
 
   /*
+   * Shadow
+   */
+  shadow_sm: {
+    shadowRadius: 8,
+    shadowOpacity: 0.1,
+    elevation: 8,
+  },
+  shadow_md: {
+    shadowRadius: 16,
+    shadowOpacity: 0.1,
+    elevation: 16,
+  },
+  shadow_lg: {
+    shadowRadius: 32,
+    shadowOpacity: 0.1,
+    elevation: 24,
+  },
+
+  /*
    * Padding
    */
-  p_xxs: {
-    padding: tokens.space.xxs,
+  p_2xs: {
+    padding: tokens.space._2xs,
   },
   p_xs: {
     padding: tokens.space.xs,
@@ -203,12 +253,21 @@ export const atoms = {
   p_xl: {
     padding: tokens.space.xl,
   },
-  p_xxl: {
-    padding: tokens.space.xxl,
+  p_2xl: {
+    padding: tokens.space._2xl,
   },
-  px_xxs: {
-    paddingLeft: tokens.space.xxs,
-    paddingRight: tokens.space.xxs,
+  p_3xl: {
+    padding: tokens.space._3xl,
+  },
+  p_4xl: {
+    padding: tokens.space._4xl,
+  },
+  p_5xl: {
+    padding: tokens.space._5xl,
+  },
+  px_2xs: {
+    paddingLeft: tokens.space._2xs,
+    paddingRight: tokens.space._2xs,
   },
   px_xs: {
     paddingLeft: tokens.space.xs,
@@ -230,13 +289,25 @@ export const atoms = {
     paddingLeft: tokens.space.xl,
     paddingRight: tokens.space.xl,
   },
-  px_xxl: {
-    paddingLeft: tokens.space.xxl,
-    paddingRight: tokens.space.xxl,
+  px_2xl: {
+    paddingLeft: tokens.space._2xl,
+    paddingRight: tokens.space._2xl,
+  },
+  px_3xl: {
+    paddingLeft: tokens.space._3xl,
+    paddingRight: tokens.space._3xl,
   },
-  py_xxs: {
-    paddingTop: tokens.space.xxs,
-    paddingBottom: tokens.space.xxs,
+  px_4xl: {
+    paddingLeft: tokens.space._4xl,
+    paddingRight: tokens.space._4xl,
+  },
+  px_5xl: {
+    paddingLeft: tokens.space._5xl,
+    paddingRight: tokens.space._5xl,
+  },
+  py_2xs: {
+    paddingTop: tokens.space._2xs,
+    paddingBottom: tokens.space._2xs,
   },
   py_xs: {
     paddingTop: tokens.space.xs,
@@ -258,12 +329,24 @@ export const atoms = {
     paddingTop: tokens.space.xl,
     paddingBottom: tokens.space.xl,
   },
-  py_xxl: {
-    paddingTop: tokens.space.xxl,
-    paddingBottom: tokens.space.xxl,
+  py_2xl: {
+    paddingTop: tokens.space._2xl,
+    paddingBottom: tokens.space._2xl,
+  },
+  py_3xl: {
+    paddingTop: tokens.space._3xl,
+    paddingBottom: tokens.space._3xl,
+  },
+  py_4xl: {
+    paddingTop: tokens.space._4xl,
+    paddingBottom: tokens.space._4xl,
   },
-  pt_xxs: {
-    paddingTop: tokens.space.xxs,
+  py_5xl: {
+    paddingTop: tokens.space._5xl,
+    paddingBottom: tokens.space._5xl,
+  },
+  pt_2xs: {
+    paddingTop: tokens.space._2xs,
   },
   pt_xs: {
     paddingTop: tokens.space.xs,
@@ -280,11 +363,20 @@ export const atoms = {
   pt_xl: {
     paddingTop: tokens.space.xl,
   },
-  pt_xxl: {
-    paddingTop: tokens.space.xxl,
+  pt_2xl: {
+    paddingTop: tokens.space._2xl,
+  },
+  pt_3xl: {
+    paddingTop: tokens.space._3xl,
+  },
+  pt_4xl: {
+    paddingTop: tokens.space._4xl,
   },
-  pb_xxs: {
-    paddingBottom: tokens.space.xxs,
+  pt_5xl: {
+    paddingTop: tokens.space._5xl,
+  },
+  pb_2xs: {
+    paddingBottom: tokens.space._2xs,
   },
   pb_xs: {
     paddingBottom: tokens.space.xs,
@@ -301,11 +393,20 @@ export const atoms = {
   pb_xl: {
     paddingBottom: tokens.space.xl,
   },
-  pb_xxl: {
-    paddingBottom: tokens.space.xxl,
+  pb_2xl: {
+    paddingBottom: tokens.space._2xl,
+  },
+  pb_3xl: {
+    paddingBottom: tokens.space._3xl,
+  },
+  pb_4xl: {
+    paddingBottom: tokens.space._4xl,
+  },
+  pb_5xl: {
+    paddingBottom: tokens.space._5xl,
   },
-  pl_xxs: {
-    paddingLeft: tokens.space.xxs,
+  pl_2xs: {
+    paddingLeft: tokens.space._2xs,
   },
   pl_xs: {
     paddingLeft: tokens.space.xs,
@@ -322,11 +423,20 @@ export const atoms = {
   pl_xl: {
     paddingLeft: tokens.space.xl,
   },
-  pl_xxl: {
-    paddingLeft: tokens.space.xxl,
+  pl_2xl: {
+    paddingLeft: tokens.space._2xl,
   },
-  pr_xxs: {
-    paddingRight: tokens.space.xxs,
+  pl_3xl: {
+    paddingLeft: tokens.space._3xl,
+  },
+  pl_4xl: {
+    paddingLeft: tokens.space._4xl,
+  },
+  pl_5xl: {
+    paddingLeft: tokens.space._5xl,
+  },
+  pr_2xs: {
+    paddingRight: tokens.space._2xs,
   },
   pr_xs: {
     paddingRight: tokens.space.xs,
@@ -343,15 +453,24 @@ export const atoms = {
   pr_xl: {
     paddingRight: tokens.space.xl,
   },
-  pr_xxl: {
-    paddingRight: tokens.space.xxl,
+  pr_2xl: {
+    paddingRight: tokens.space._2xl,
+  },
+  pr_3xl: {
+    paddingRight: tokens.space._3xl,
+  },
+  pr_4xl: {
+    paddingRight: tokens.space._4xl,
+  },
+  pr_5xl: {
+    paddingRight: tokens.space._5xl,
   },
 
   /*
    * Margin
    */
-  m_xxs: {
-    margin: tokens.space.xxs,
+  m_2xs: {
+    margin: tokens.space._2xs,
   },
   m_xs: {
     margin: tokens.space.xs,
@@ -368,12 +487,21 @@ export const atoms = {
   m_xl: {
     margin: tokens.space.xl,
   },
-  m_xxl: {
-    margin: tokens.space.xxl,
+  m_2xl: {
+    margin: tokens.space._2xl,
+  },
+  m_3xl: {
+    margin: tokens.space._3xl,
+  },
+  m_4xl: {
+    margin: tokens.space._4xl,
   },
-  mx_xxs: {
-    marginLeft: tokens.space.xxs,
-    marginRight: tokens.space.xxs,
+  m_5xl: {
+    margin: tokens.space._5xl,
+  },
+  mx_2xs: {
+    marginLeft: tokens.space._2xs,
+    marginRight: tokens.space._2xs,
   },
   mx_xs: {
     marginLeft: tokens.space.xs,
@@ -395,13 +523,25 @@ export const atoms = {
     marginLeft: tokens.space.xl,
     marginRight: tokens.space.xl,
   },
-  mx_xxl: {
-    marginLeft: tokens.space.xxl,
-    marginRight: tokens.space.xxl,
+  mx_2xl: {
+    marginLeft: tokens.space._2xl,
+    marginRight: tokens.space._2xl,
+  },
+  mx_3xl: {
+    marginLeft: tokens.space._3xl,
+    marginRight: tokens.space._3xl,
+  },
+  mx_4xl: {
+    marginLeft: tokens.space._4xl,
+    marginRight: tokens.space._4xl,
+  },
+  mx_5xl: {
+    marginLeft: tokens.space._5xl,
+    marginRight: tokens.space._5xl,
   },
-  my_xxs: {
-    marginTop: tokens.space.xxs,
-    marginBottom: tokens.space.xxs,
+  my_2xs: {
+    marginTop: tokens.space._2xs,
+    marginBottom: tokens.space._2xs,
   },
   my_xs: {
     marginTop: tokens.space.xs,
@@ -423,12 +563,24 @@ export const atoms = {
     marginTop: tokens.space.xl,
     marginBottom: tokens.space.xl,
   },
-  my_xxl: {
-    marginTop: tokens.space.xxl,
-    marginBottom: tokens.space.xxl,
+  my_2xl: {
+    marginTop: tokens.space._2xl,
+    marginBottom: tokens.space._2xl,
   },
-  mt_xxs: {
-    marginTop: tokens.space.xxs,
+  my_3xl: {
+    marginTop: tokens.space._3xl,
+    marginBottom: tokens.space._3xl,
+  },
+  my_4xl: {
+    marginTop: tokens.space._4xl,
+    marginBottom: tokens.space._4xl,
+  },
+  my_5xl: {
+    marginTop: tokens.space._5xl,
+    marginBottom: tokens.space._5xl,
+  },
+  mt_2xs: {
+    marginTop: tokens.space._2xs,
   },
   mt_xs: {
     marginTop: tokens.space.xs,
@@ -445,11 +597,20 @@ export const atoms = {
   mt_xl: {
     marginTop: tokens.space.xl,
   },
-  mt_xxl: {
-    marginTop: tokens.space.xxl,
+  mt_2xl: {
+    marginTop: tokens.space._2xl,
+  },
+  mt_3xl: {
+    marginTop: tokens.space._3xl,
   },
-  mb_xxs: {
-    marginBottom: tokens.space.xxs,
+  mt_4xl: {
+    marginTop: tokens.space._4xl,
+  },
+  mt_5xl: {
+    marginTop: tokens.space._5xl,
+  },
+  mb_2xs: {
+    marginBottom: tokens.space._2xs,
   },
   mb_xs: {
     marginBottom: tokens.space.xs,
@@ -466,11 +627,20 @@ export const atoms = {
   mb_xl: {
     marginBottom: tokens.space.xl,
   },
-  mb_xxl: {
-    marginBottom: tokens.space.xxl,
+  mb_2xl: {
+    marginBottom: tokens.space._2xl,
+  },
+  mb_3xl: {
+    marginBottom: tokens.space._3xl,
+  },
+  mb_4xl: {
+    marginBottom: tokens.space._4xl,
   },
-  ml_xxs: {
-    marginLeft: tokens.space.xxs,
+  mb_5xl: {
+    marginBottom: tokens.space._5xl,
+  },
+  ml_2xs: {
+    marginLeft: tokens.space._2xs,
   },
   ml_xs: {
     marginLeft: tokens.space.xs,
@@ -487,11 +657,20 @@ export const atoms = {
   ml_xl: {
     marginLeft: tokens.space.xl,
   },
-  ml_xxl: {
-    marginLeft: tokens.space.xxl,
+  ml_2xl: {
+    marginLeft: tokens.space._2xl,
+  },
+  ml_3xl: {
+    marginLeft: tokens.space._3xl,
+  },
+  ml_4xl: {
+    marginLeft: tokens.space._4xl,
+  },
+  ml_5xl: {
+    marginLeft: tokens.space._5xl,
   },
-  mr_xxs: {
-    marginRight: tokens.space.xxs,
+  mr_2xs: {
+    marginRight: tokens.space._2xs,
   },
   mr_xs: {
     marginRight: tokens.space.xs,
@@ -508,7 +687,16 @@ export const atoms = {
   mr_xl: {
     marginRight: tokens.space.xl,
   },
-  mr_xxl: {
-    marginRight: tokens.space.xxl,
+  mr_2xl: {
+    marginRight: tokens.space._2xl,
+  },
+  mr_3xl: {
+    marginRight: tokens.space._3xl,
+  },
+  mr_4xl: {
+    marginRight: tokens.space._4xl,
+  },
+  mr_5xl: {
+    marginRight: tokens.space._5xl,
   },
 } as const
diff --git a/src/alf/index.tsx b/src/alf/index.tsx
index 1daa0bfed..69a879853 100644
--- a/src/alf/index.tsx
+++ b/src/alf/index.tsx
@@ -5,6 +5,7 @@ import * as themes from '#/alf/themes'
 export * as tokens from '#/alf/tokens'
 export {atoms} from '#/alf/atoms'
 export * from '#/alf/util/platform'
+export * from '#/alf/util/flatten'
 
 type BreakpointName = keyof typeof breakpoints
 
diff --git a/src/alf/themes.ts b/src/alf/themes.ts
index aae5c5893..7c6b7dab4 100644
--- a/src/alf/themes.ts
+++ b/src/alf/themes.ts
@@ -1,108 +1,320 @@
 import * as tokens from '#/alf/tokens'
 import type {Mutable} from '#/alf/types'
+import {atoms} from '#/alf/atoms'
 
-export type ThemeName = 'light' | 'dark'
+export type ThemeName = 'light' | 'dim' | 'dark'
 export type ReadonlyTheme = typeof light
 export type Theme = Mutable<ReadonlyTheme>
+export type ReadonlyPalette = typeof lightPalette
+export type Palette = Mutable<ReadonlyPalette>
 
-export type Palette = {
-  primary: string
-  positive: string
-  negative: string
-}
+export const lightPalette = {
+  white: tokens.color.gray_0,
+  black: tokens.color.gray_1000,
+
+  contrast_25: tokens.color.gray_25,
+  contrast_50: tokens.color.gray_50,
+  contrast_100: tokens.color.gray_100,
+  contrast_200: tokens.color.gray_200,
+  contrast_300: tokens.color.gray_300,
+  contrast_400: tokens.color.gray_400,
+  contrast_500: tokens.color.gray_500,
+  contrast_600: tokens.color.gray_600,
+  contrast_700: tokens.color.gray_700,
+  contrast_800: tokens.color.gray_800,
+  contrast_900: tokens.color.gray_900,
+  contrast_950: tokens.color.gray_950,
+  contrast_975: tokens.color.gray_975,
+
+  primary_25: tokens.color.blue_25,
+  primary_50: tokens.color.blue_50,
+  primary_100: tokens.color.blue_100,
+  primary_200: tokens.color.blue_200,
+  primary_300: tokens.color.blue_300,
+  primary_400: tokens.color.blue_400,
+  primary_500: tokens.color.blue_500,
+  primary_600: tokens.color.blue_600,
+  primary_700: tokens.color.blue_700,
+  primary_800: tokens.color.blue_800,
+  primary_900: tokens.color.blue_900,
+  primary_950: tokens.color.blue_950,
+  primary_975: tokens.color.blue_975,
+
+  positive_25: tokens.color.green_25,
+  positive_50: tokens.color.green_50,
+  positive_100: tokens.color.green_100,
+  positive_200: tokens.color.green_200,
+  positive_300: tokens.color.green_300,
+  positive_400: tokens.color.green_400,
+  positive_500: tokens.color.green_500,
+  positive_600: tokens.color.green_600,
+  positive_700: tokens.color.green_700,
+  positive_800: tokens.color.green_800,
+  positive_900: tokens.color.green_900,
+  positive_950: tokens.color.green_950,
+  positive_975: tokens.color.green_975,
 
-export const lightPalette: Palette = {
-  primary: tokens.color.blue_500,
-  positive: tokens.color.green_500,
-  negative: tokens.color.red_500,
+  negative_25: tokens.color.red_25,
+  negative_50: tokens.color.red_50,
+  negative_100: tokens.color.red_100,
+  negative_200: tokens.color.red_200,
+  negative_300: tokens.color.red_300,
+  negative_400: tokens.color.red_400,
+  negative_500: tokens.color.red_500,
+  negative_600: tokens.color.red_600,
+  negative_700: tokens.color.red_700,
+  negative_800: tokens.color.red_800,
+  negative_900: tokens.color.red_900,
+  negative_950: tokens.color.red_950,
+  negative_975: tokens.color.red_975,
 } as const
 
 export const darkPalette: Palette = {
-  primary: tokens.color.blue_500,
-  positive: tokens.color.green_400,
-  negative: tokens.color.red_400,
+  white: tokens.color.gray_0,
+  black: tokens.color.gray_1000,
+
+  contrast_25: tokens.color.gray_975,
+  contrast_50: tokens.color.gray_950,
+  contrast_100: tokens.color.gray_900,
+  contrast_200: tokens.color.gray_800,
+  contrast_300: tokens.color.gray_700,
+  contrast_400: tokens.color.gray_600,
+  contrast_500: tokens.color.gray_500,
+  contrast_600: tokens.color.gray_400,
+  contrast_700: tokens.color.gray_300,
+  contrast_800: tokens.color.gray_200,
+  contrast_900: tokens.color.gray_100,
+  contrast_950: tokens.color.gray_50,
+  contrast_975: tokens.color.gray_25,
+
+  primary_25: tokens.color.blue_25,
+  primary_50: tokens.color.blue_50,
+  primary_100: tokens.color.blue_100,
+  primary_200: tokens.color.blue_200,
+  primary_300: tokens.color.blue_300,
+  primary_400: tokens.color.blue_400,
+  primary_500: tokens.color.blue_500,
+  primary_600: tokens.color.blue_600,
+  primary_700: tokens.color.blue_700,
+  primary_800: tokens.color.blue_800,
+  primary_900: tokens.color.blue_900,
+  primary_950: tokens.color.blue_950,
+  primary_975: tokens.color.blue_975,
+
+  positive_25: tokens.color.green_25,
+  positive_50: tokens.color.green_50,
+  positive_100: tokens.color.green_100,
+  positive_200: tokens.color.green_200,
+  positive_300: tokens.color.green_300,
+  positive_400: tokens.color.green_400,
+  positive_500: tokens.color.green_500,
+  positive_600: tokens.color.green_600,
+  positive_700: tokens.color.green_700,
+  positive_800: tokens.color.green_800,
+  positive_900: tokens.color.green_900,
+  positive_950: tokens.color.green_950,
+  positive_975: tokens.color.green_975,
+
+  negative_25: tokens.color.red_25,
+  negative_50: tokens.color.red_50,
+  negative_100: tokens.color.red_100,
+  negative_200: tokens.color.red_200,
+  negative_300: tokens.color.red_300,
+  negative_400: tokens.color.red_400,
+  negative_500: tokens.color.red_500,
+  negative_600: tokens.color.red_600,
+  negative_700: tokens.color.red_700,
+  negative_800: tokens.color.red_800,
+  negative_900: tokens.color.red_900,
+  negative_950: tokens.color.red_950,
+  negative_975: tokens.color.red_975,
 } as const
 
 export const light = {
+  name: 'light',
   palette: lightPalette,
   atoms: {
     text: {
-      color: tokens.color.gray_1000,
+      color: lightPalette.black,
     },
     text_contrast_700: {
-      color: tokens.color.gray_700,
+      color: lightPalette.contrast_700,
+    },
+    text_contrast_600: {
+      color: lightPalette.contrast_600,
     },
     text_contrast_500: {
-      color: tokens.color.gray_500,
+      color: lightPalette.contrast_500,
+    },
+    text_contrast_400: {
+      color: lightPalette.contrast_400,
     },
     text_inverted: {
-      color: tokens.color.white,
+      color: lightPalette.white,
     },
     bg: {
-      backgroundColor: tokens.color.white,
+      backgroundColor: lightPalette.white,
+    },
+    bg_contrast_25: {
+      backgroundColor: lightPalette.contrast_25,
+    },
+    bg_contrast_50: {
+      backgroundColor: lightPalette.contrast_50,
     },
     bg_contrast_100: {
-      backgroundColor: tokens.color.gray_100,
+      backgroundColor: lightPalette.contrast_100,
     },
     bg_contrast_200: {
-      backgroundColor: tokens.color.gray_200,
+      backgroundColor: lightPalette.contrast_200,
     },
     bg_contrast_300: {
-      backgroundColor: tokens.color.gray_300,
+      backgroundColor: lightPalette.contrast_300,
+    },
+    border: {
+      borderColor: lightPalette.contrast_100,
+    },
+    border_contrast: {
+      borderColor: lightPalette.contrast_400,
+    },
+    shadow_sm: {
+      ...atoms.shadow_sm,
+      shadowColor: lightPalette.black,
+    },
+    shadow_md: {
+      ...atoms.shadow_md,
+      shadowColor: lightPalette.black,
     },
-    bg_positive: {
-      backgroundColor: tokens.color.green_500,
+    shadow_lg: {
+      ...atoms.shadow_lg,
+      shadowColor: lightPalette.black,
+    },
+  },
+}
+
+export const dim: Theme = {
+  name: 'dim',
+  palette: darkPalette,
+  atoms: {
+    text: {
+      color: darkPalette.white,
+    },
+    text_contrast_700: {
+      color: darkPalette.contrast_800,
     },
-    bg_negative: {
-      backgroundColor: tokens.color.red_400,
+    text_contrast_600: {
+      color: darkPalette.contrast_700,
+    },
+    text_contrast_500: {
+      color: darkPalette.contrast_600,
+    },
+    text_contrast_400: {
+      color: darkPalette.contrast_500,
+    },
+    text_inverted: {
+      color: darkPalette.black,
+    },
+    bg: {
+      backgroundColor: darkPalette.contrast_50,
+    },
+    bg_contrast_25: {
+      backgroundColor: darkPalette.contrast_100,
+    },
+    bg_contrast_50: {
+      backgroundColor: darkPalette.contrast_200,
+    },
+    bg_contrast_100: {
+      backgroundColor: darkPalette.contrast_300,
+    },
+    bg_contrast_200: {
+      backgroundColor: darkPalette.contrast_400,
+    },
+    bg_contrast_300: {
+      backgroundColor: darkPalette.contrast_500,
     },
     border: {
-      borderColor: tokens.color.gray_200,
+      borderColor: darkPalette.contrast_200,
+    },
+    border_contrast: {
+      borderColor: darkPalette.contrast_400,
     },
-    border_contrast_500: {
-      borderColor: tokens.color.gray_500,
+    shadow_sm: {
+      ...atoms.shadow_sm,
+      shadowOpacity: 0.7,
+      shadowColor: tokens.color.trueBlack,
+    },
+    shadow_md: {
+      ...atoms.shadow_md,
+      shadowOpacity: 0.7,
+      shadowColor: tokens.color.trueBlack,
+    },
+    shadow_lg: {
+      ...atoms.shadow_lg,
+      shadowOpacity: 0.7,
+      shadowColor: tokens.color.trueBlack,
     },
   },
 }
 
 export const dark: Theme = {
+  name: 'dark',
   palette: darkPalette,
   atoms: {
     text: {
-      color: tokens.color.white,
+      color: darkPalette.white,
     },
     text_contrast_700: {
-      color: tokens.color.gray_300,
+      color: darkPalette.contrast_700,
+    },
+    text_contrast_600: {
+      color: darkPalette.contrast_600,
     },
     text_contrast_500: {
-      color: tokens.color.gray_500,
+      color: darkPalette.contrast_500,
+    },
+    text_contrast_400: {
+      color: darkPalette.contrast_400,
     },
     text_inverted: {
-      color: tokens.color.gray_1000,
+      color: darkPalette.black,
     },
     bg: {
-      backgroundColor: tokens.color.gray_1000,
+      backgroundColor: darkPalette.black,
+    },
+    bg_contrast_25: {
+      backgroundColor: darkPalette.contrast_50,
+    },
+    bg_contrast_50: {
+      backgroundColor: darkPalette.contrast_100,
     },
     bg_contrast_100: {
-      backgroundColor: tokens.color.gray_900,
+      backgroundColor: darkPalette.contrast_200,
     },
     bg_contrast_200: {
-      backgroundColor: tokens.color.gray_800,
+      backgroundColor: darkPalette.contrast_300,
     },
     bg_contrast_300: {
-      backgroundColor: tokens.color.gray_700,
+      backgroundColor: darkPalette.contrast_400,
     },
-    bg_positive: {
-      backgroundColor: tokens.color.green_400,
+    border: {
+      borderColor: darkPalette.contrast_100,
     },
-    bg_negative: {
-      backgroundColor: tokens.color.red_400,
+    border_contrast: {
+      borderColor: darkPalette.contrast_300,
     },
-    border: {
-      borderColor: tokens.color.gray_800,
+    shadow_sm: {
+      ...atoms.shadow_sm,
+      shadowOpacity: 0.7,
+      shadowColor: tokens.color.trueBlack,
+    },
+    shadow_md: {
+      ...atoms.shadow_md,
+      shadowOpacity: 0.7,
+      shadowColor: tokens.color.trueBlack,
     },
-    border_contrast_500: {
-      borderColor: tokens.color.gray_500,
+    shadow_lg: {
+      ...atoms.shadow_lg,
+      shadowOpacity: 0.7,
+      shadowColor: tokens.color.trueBlack,
     },
   },
 }
diff --git a/src/alf/tokens.ts b/src/alf/tokens.ts
index 4034e0deb..0e370cdc1 100644
--- a/src/alf/tokens.ts
+++ b/src/alf/tokens.ts
@@ -1,79 +1,95 @@
 const BLUE_HUE = 211
-const GRAYSCALE_SATURATION = 22
+const RED_HUE = 346
+const GREEN_HUE = 152
 
 export const color = {
-  white: '#FFFFFF',
+  trueBlack: '#000000',
 
-  gray_0: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 100%)`,
-  gray_100: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 95%)`,
-  gray_200: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 85%)`,
-  gray_300: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 75%)`,
-  gray_400: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 65%)`,
-  gray_500: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 55%)`,
-  gray_600: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 45%)`,
-  gray_700: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 35%)`,
-  gray_800: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 25%)`,
-  gray_900: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 15%)`,
-  gray_1000: `hsl(${BLUE_HUE}, ${GRAYSCALE_SATURATION}%, 5%)`,
+  gray_0: `hsl(${BLUE_HUE}, 20%, 100%)`,
+  gray_25: `hsl(${BLUE_HUE}, 20%, 97%)`,
+  gray_50: `hsl(${BLUE_HUE}, 20%, 95%)`,
+  gray_100: `hsl(${BLUE_HUE}, 20%, 90%)`,
+  gray_200: `hsl(${BLUE_HUE}, 20%, 80%)`,
+  gray_300: `hsl(${BLUE_HUE}, 20%, 70%)`,
+  gray_400: `hsl(${BLUE_HUE}, 20%, 60%)`,
+  gray_500: `hsl(${BLUE_HUE}, 20%, 50%)`,
+  gray_600: `hsl(${BLUE_HUE}, 20%, 42%)`,
+  gray_700: `hsl(${BLUE_HUE}, 20%, 34%)`,
+  gray_800: `hsl(${BLUE_HUE}, 20%, 26%)`,
+  gray_900: `hsl(${BLUE_HUE}, 20%, 18%)`,
+  gray_950: `hsl(${BLUE_HUE}, 20%, 10%)`,
+  gray_975: `hsl(${BLUE_HUE}, 20%, 7%)`,
+  gray_1000: `hsl(${BLUE_HUE}, 20%, 4%)`,
 
-  blue_0: `hsl(${BLUE_HUE}, 99%, 100%)`,
-  blue_100: `hsl(${BLUE_HUE}, 99%, 93%)`,
-  blue_200: `hsl(${BLUE_HUE}, 99%, 83%)`,
-  blue_300: `hsl(${BLUE_HUE}, 99%, 73%)`,
-  blue_400: `hsl(${BLUE_HUE}, 99%, 63%)`,
+  blue_25: `hsl(${BLUE_HUE}, 99%, 97%)`,
+  blue_50: `hsl(${BLUE_HUE}, 99%, 95%)`,
+  blue_100: `hsl(${BLUE_HUE}, 99%, 90%)`,
+  blue_200: `hsl(${BLUE_HUE}, 99%, 80%)`,
+  blue_300: `hsl(${BLUE_HUE}, 99%, 70%)`,
+  blue_400: `hsl(${BLUE_HUE}, 99%, 60%)`,
   blue_500: `hsl(${BLUE_HUE}, 99%, 53%)`,
-  blue_600: `hsl(${BLUE_HUE}, 99%, 43%)`,
-  blue_700: `hsl(${BLUE_HUE}, 99%, 33%)`,
-  blue_800: `hsl(${BLUE_HUE}, 99%, 23%)`,
-  blue_900: `hsl(${BLUE_HUE}, 99%, 13%)`,
-  blue_1000: `hsl(${BLUE_HUE}, 99%, 8%)`,
+  blue_600: `hsl(${BLUE_HUE}, 99%, 42%)`,
+  blue_700: `hsl(${BLUE_HUE}, 99%, 34%)`,
+  blue_800: `hsl(${BLUE_HUE}, 99%, 26%)`,
+  blue_900: `hsl(${BLUE_HUE}, 99%, 18%)`,
+  blue_950: `hsl(${BLUE_HUE}, 99%, 10%)`,
+  blue_975: `hsl(${BLUE_HUE}, 99%, 7%)`,
 
-  green_0: `hsl(130, 60%, 100%)`,
-  green_100: `hsl(130, 60%, 95%)`,
-  green_200: `hsl(130, 60%, 85%)`,
-  green_300: `hsl(130, 60%, 75%)`,
-  green_400: `hsl(130, 60%, 65%)`,
-  green_500: `hsl(130, 60%, 55%)`,
-  green_600: `hsl(130, 60%, 45%)`,
-  green_700: `hsl(130, 60%, 35%)`,
-  green_800: `hsl(130, 60%, 25%)`,
-  green_900: `hsl(130, 60%, 15%)`,
-  green_1000: `hsl(130, 60%, 5%)`,
+  green_25: `hsl(${GREEN_HUE}, 82%, 97%)`,
+  green_50: `hsl(${GREEN_HUE}, 82%, 95%)`,
+  green_100: `hsl(${GREEN_HUE}, 82%, 90%)`,
+  green_200: `hsl(${GREEN_HUE}, 82%, 80%)`,
+  green_300: `hsl(${GREEN_HUE}, 82%, 70%)`,
+  green_400: `hsl(${GREEN_HUE}, 82%, 60%)`,
+  green_500: `hsl(${GREEN_HUE}, 82%, 50%)`,
+  green_600: `hsl(${GREEN_HUE}, 82%, 42%)`,
+  green_700: `hsl(${GREEN_HUE}, 82%, 34%)`,
+  green_800: `hsl(${GREEN_HUE}, 82%, 26%)`,
+  green_900: `hsl(${GREEN_HUE}, 82%, 18%)`,
+  green_950: `hsl(${GREEN_HUE}, 82%, 10%)`,
+  green_975: `hsl(${GREEN_HUE}, 82%, 7%)`,
 
-  red_0: `hsl(349, 96%, 100%)`,
-  red_100: `hsl(349, 96%, 95%)`,
-  red_200: `hsl(349, 96%, 85%)`,
-  red_300: `hsl(349, 96%, 75%)`,
-  red_400: `hsl(349, 96%, 65%)`,
-  red_500: `hsl(349, 96%, 55%)`,
-  red_600: `hsl(349, 96%, 45%)`,
-  red_700: `hsl(349, 96%, 35%)`,
-  red_800: `hsl(349, 96%, 25%)`,
-  red_900: `hsl(349, 96%, 15%)`,
-  red_1000: `hsl(349, 96%, 5%)`,
+  red_25: `hsl(${RED_HUE}, 91%, 97%)`,
+  red_50: `hsl(${RED_HUE}, 91%, 95%)`,
+  red_100: `hsl(${RED_HUE}, 91%, 90%)`,
+  red_200: `hsl(${RED_HUE}, 91%, 80%)`,
+  red_300: `hsl(${RED_HUE}, 91%, 70%)`,
+  red_400: `hsl(${RED_HUE}, 91%, 60%)`,
+  red_500: `hsl(${RED_HUE}, 91%, 50%)`,
+  red_600: `hsl(${RED_HUE}, 91%, 42%)`,
+  red_700: `hsl(${RED_HUE}, 91%, 34%)`,
+  red_800: `hsl(${RED_HUE}, 91%, 26%)`,
+  red_900: `hsl(${RED_HUE}, 91%, 18%)`,
+  red_950: `hsl(${RED_HUE}, 91%, 10%)`,
+  red_975: `hsl(${RED_HUE}, 91%, 7%)`,
 } as const
 
 export const space = {
-  xxs: 2,
+  _2xs: 2,
   xs: 4,
   sm: 8,
   md: 12,
-  lg: 18,
-  xl: 24,
-  xxl: 32,
+  lg: 16,
+  xl: 20,
+  _2xl: 24,
+  _3xl: 28,
+  _4xl: 32,
+  _5xl: 40,
 } as const
 
 export const fontSize = {
-  xxs: 10,
+  _2xs: 10,
   xs: 12,
   sm: 14,
   md: 16,
   lg: 18,
-  xl: 22,
-  xxl: 26,
+  xl: 20,
+  _2xl: 22,
+  _3xl: 26,
+  _4xl: 32,
+  _5xl: 40,
 } as const
 
-// TODO test
 export const lineHeight = {
   none: 1,
   normal: 1.5,
@@ -81,6 +97,8 @@ export const lineHeight = {
 } as const
 
 export const borderRadius = {
+  _2xs: 2,
+  xs: 4,
   sm: 8,
   md: 12,
   full: 999,
@@ -92,6 +110,56 @@ export const fontWeight = {
   bold: '900',
 } as const
 
+export const gradients = {
+  sky: {
+    values: [
+      [0, '#0A7AFF'],
+      [1, '#59B9FF'],
+    ],
+    hover_value: '#0A7AFF',
+  },
+  midnight: {
+    values: [
+      [0, '#022C5E'],
+      [1, '#4079BC'],
+    ],
+    hover_value: '#022C5E',
+  },
+  sunrise: {
+    values: [
+      [0, '#4E90AE'],
+      [0.4, '#AEA3AB'],
+      [0.8, '#E6A98F'],
+      [1, '#F3A84C'],
+    ],
+    hover_value: '#AEA3AB',
+  },
+  sunset: {
+    values: [
+      [0, '#6772AF'],
+      [0.6, '#B88BB6'],
+      [1, '#FFA6AC'],
+    ],
+    hover_value: '#B88BB6',
+  },
+  nordic: {
+    values: [
+      [0, '#083367'],
+      [1, '#9EE8C1'],
+    ],
+    hover_value: '#3A7085',
+  },
+  bonfire: {
+    values: [
+      [0, '#203E4E'],
+      [0.4, '#755B62'],
+      [0.8, '#CD7765'],
+      [1, '#EF956E'],
+    ],
+    hover_value: '#755B62',
+  },
+} as const
+
 export type Color = keyof typeof color
 export type Space = keyof typeof space
 export type FontSize = keyof typeof fontSize
diff --git a/src/alf/util/flatten.ts b/src/alf/util/flatten.ts
new file mode 100644
index 000000000..448716a08
--- /dev/null
+++ b/src/alf/util/flatten.ts
@@ -0,0 +1,3 @@
+import {StyleSheet} from 'react-native'
+
+export const flatten = StyleSheet.flatten