Compare commits
11 Commits
c1872d10c8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a701d0291 | ||
|
|
913c40b9ec | ||
|
|
e06ec3d5df | ||
|
|
42174ac9f7 | ||
|
|
30fbe7be35 | ||
|
|
44aa84a127 | ||
|
|
c3375f6cfd | ||
|
|
70228b655f | ||
|
|
3899e37f1e | ||
|
|
7ef669f852 | ||
|
|
ad7c6f2b65 |
@@ -1,78 +0,0 @@
|
||||
# Current Color Usage Inventory
|
||||
|
||||
## Mantine Color Variables Used
|
||||
|
||||
### Basic Colors
|
||||
- White: `var(--mantine-color-white)`
|
||||
- Black: `var(--mantine-color-black)`
|
||||
- Body: `var(--mantine-color-body)`
|
||||
|
||||
### Blue Shades
|
||||
- Blue-0: `var(--mantine-color-blue-0)`
|
||||
- Blue-1: `var(--mantine-color-blue-1)`
|
||||
- Blue-4: `var(--mantine-color-blue-4)`
|
||||
- Blue-6: `var(--mantine-color-blue-6)`
|
||||
- Blue-7: `var(--mantine-color-blue-7)`
|
||||
- Blue-filled: `var(--mantine-color-blue-filled)`
|
||||
|
||||
### Gray Shades
|
||||
- Gray-0: `var(--mantine-color-gray-0)`
|
||||
- Gray-3: `var(--mantine-color-gray-3)`
|
||||
- Gray-4: `var(--mantine-color-gray-4)`
|
||||
- Gray-5: `var(--mantine-color-gray-5)`
|
||||
- Gray-7: `var(--mantine-color-gray-7)`
|
||||
|
||||
### Dark Shades
|
||||
- Dark-0: `var(--mantine-color-dark-0)`
|
||||
- Dark-4: `var(--mantine-color-dark-4)`
|
||||
- Dark-6: `var(--mantine-color-dark-6)`
|
||||
- Dark-8: `var(--mantine-color-dark-8)`
|
||||
|
||||
## Color Usage By Component
|
||||
|
||||
### HeroTitle
|
||||
- Background: `light-dark(var(--mantine-color-white), var(--mantine-color-dark-8))`
|
||||
- Text: `light-dark(var(--mantine-color-black), var(--mantine-color-white))`
|
||||
|
||||
### Welcome
|
||||
- Text: `light-dark(var(--mantine-color-black), var(--mantine-color-white))`
|
||||
|
||||
### HeaderSimple
|
||||
- Background: `var(--mantine-color-body)`
|
||||
- Border: `light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4))`
|
||||
- Text: `light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0))`
|
||||
- Menu Background: `light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6))`
|
||||
- Active Item Background: `var(--mantine-color-blue-filled)`
|
||||
- Active Item Text: `var(--mantine-color-white)`
|
||||
|
||||
### ContactIcons
|
||||
- Icon Color: `var(--mantine-color-white)`
|
||||
- Icon Hover Color: `var(--mantine-color-blue-0)`
|
||||
- Text Color: `var(--mantine-color-white)`
|
||||
|
||||
### Contact
|
||||
- Background: `light-dark(var(--mantine-color-white), var(--mantine-color-dark-8))`
|
||||
|
||||
### ContactUs
|
||||
- Gradient: `linear-gradient(to bottom right, var(--mantine-color-blue-4) 0%, var(--mantine-color-blue-7) 100%)`
|
||||
- Title Color: `var(--mantine-color-white)`
|
||||
- Subtitle Color: `var(--mantine-color-blue-0)`
|
||||
- Form Background: `var(--mantine-color-white)`
|
||||
- Form Button Text: `var(--mantine-color-white)`
|
||||
- Form Button Hover: `var(--mantine-color-blue-1)`
|
||||
- Input Background: `var(--mantine-color-white)`
|
||||
- Input Border: `var(--mantine-color-gray-4)`
|
||||
- Input Text: `var(--mantine-color-black)`
|
||||
- Input Placeholder: `var(--mantine-color-gray-5)`
|
||||
- Submit Button Background: `var(--mantine-color-blue-6)`
|
||||
|
||||
## Issues Identified
|
||||
- Inconsistent use of blue shades across components
|
||||
- Mix of direct color variables and light-dark functions
|
||||
- No centralized theme definition with brand colors
|
||||
- No semantic color naming (e.g., primary, secondary, etc.)
|
||||
|
||||
## Next Steps
|
||||
- Define a comprehensive color palette in theme.ts
|
||||
- Create semantic color tokens
|
||||
- Standardize light/dark mode transitions
|
||||
@@ -1,182 +0,0 @@
|
||||
# Color System Migration Guide
|
||||
|
||||
This guide will help you migrate your components to use our new standardized color system.
|
||||
|
||||
## Why Migrate?
|
||||
|
||||
- **Consistency**: Ensure all UI elements have consistent colors
|
||||
- **Maintainability**: Easier to update the design system
|
||||
- **Accessibility**: Better contrast and readability
|
||||
- **Dark Mode**: Simplified light/dark mode support
|
||||
|
||||
## Migration Steps
|
||||
|
||||
### 1. Identify Current Color Usage
|
||||
|
||||
First, identify all hardcoded colors or direct Mantine color variables in your component:
|
||||
|
||||
```css
|
||||
/* Before */
|
||||
.element {
|
||||
color: #333;
|
||||
background-color: var(--mantine-color-blue-6);
|
||||
border: 1px solid var(--mantine-color-gray-3);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Replace with Theme Color Tokens
|
||||
|
||||
Replace hardcoded colors and direct Mantine variables with our standardized tokens:
|
||||
|
||||
```css
|
||||
/* After */
|
||||
.element {
|
||||
color: var(--mantine-color-brand-gray-7);
|
||||
background-color: var(--mantine-color-brand-primary-6);
|
||||
border: 1px solid var(--mantine-color-brand-gray-3);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Use Semantic Color Tokens Where Available
|
||||
|
||||
For common UI elements, use semantic tokens:
|
||||
|
||||
```css
|
||||
/* Before */
|
||||
.header {
|
||||
background-color: var(--mantine-color-body);
|
||||
border-bottom: 1px solid var(--mantine-color-gray-3);
|
||||
}
|
||||
|
||||
/* After */
|
||||
.header {
|
||||
background-color: var(--mantine-other-headerBgColor);
|
||||
border-bottom: 1px solid var(--mantine-other-headerBorderColor);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Use Light/Dark Mode Consistently
|
||||
|
||||
For elements that need different colors in light/dark mode:
|
||||
|
||||
```css
|
||||
/* Before */
|
||||
.text {
|
||||
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0));
|
||||
}
|
||||
|
||||
/* After */
|
||||
.text {
|
||||
color: light-dark(var(--mantine-color-brand-gray-7), var(--mantine-color-brand-gray-0));
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Update Inline Styles in Components
|
||||
|
||||
For inline styles in components:
|
||||
|
||||
```tsx
|
||||
// Before
|
||||
<Box style={{ color: theme.colors.blue[6] }} />
|
||||
|
||||
// After
|
||||
<Box style={{ color: 'var(--mantine-color-brand-primary-6)' }} />
|
||||
|
||||
// Or better, use Mantine props
|
||||
<Box c="brand-primary.6" />
|
||||
```
|
||||
|
||||
## Mapping Old Colors to New Colors
|
||||
|
||||
Use this reference to map old color values to our new color system:
|
||||
|
||||
| Old Color | New Color |
|
||||
|-----------|-----------|
|
||||
| `var(--mantine-color-blue-0)` | `var(--mantine-color-brand-primary-0)` |
|
||||
| `var(--mantine-color-blue-1)` | `var(--mantine-color-brand-primary-1)` |
|
||||
| `var(--mantine-color-blue-4)` | `var(--mantine-color-brand-primary-4)` |
|
||||
| `var(--mantine-color-blue-6)` | `var(--mantine-color-brand-primary-6)` |
|
||||
| `var(--mantine-color-blue-7)` | `var(--mantine-color-brand-primary-7)` |
|
||||
| `var(--mantine-color-blue-filled)` | `var(--mantine-other-navigationActiveColor)` |
|
||||
| `var(--mantine-color-gray-0)` | `var(--mantine-color-brand-gray-0)` |
|
||||
| `var(--mantine-color-gray-3)` | `var(--mantine-color-brand-gray-3)` |
|
||||
| `var(--mantine-color-gray-4)` | `var(--mantine-color-brand-gray-4)` |
|
||||
| `var(--mantine-color-gray-5)` | `var(--mantine-color-brand-gray-5)` |
|
||||
| `var(--mantine-color-gray-7)` | `var(--mantine-color-brand-gray-7)` |
|
||||
| `var(--mantine-color-dark-0)` | `var(--mantine-color-brand-gray-0)` |
|
||||
| `var(--mantine-color-dark-4)` | `var(--mantine-color-brand-gray-4)` |
|
||||
| `var(--mantine-color-dark-6)` | `var(--mantine-color-brand-gray-6)` |
|
||||
| `var(--mantine-color-dark-8)` | `var(--mantine-color-brand-gray-8)` |
|
||||
|
||||
## Examples
|
||||
|
||||
### Header Component Example
|
||||
|
||||
```css
|
||||
/* Before */
|
||||
.header {
|
||||
background-color: var(--mantine-color-body);
|
||||
border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
|
||||
}
|
||||
|
||||
.link {
|
||||
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0));
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--mantine-color-blue-filled);
|
||||
color: var(--mantine-color-white);
|
||||
}
|
||||
|
||||
/* After */
|
||||
.header {
|
||||
background-color: var(--mantine-other-headerBgColor);
|
||||
border-bottom: 1px solid var(--mantine-other-headerBorderColor);
|
||||
}
|
||||
|
||||
.link {
|
||||
color: light-dark(var(--mantine-color-brand-gray-7), var(--mantine-color-brand-gray-0));
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
background-color: light-dark(var(--mantine-color-brand-gray-1), var(--mantine-color-brand-gray-8));
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--mantine-other-navigationActiveColor);
|
||||
color: var(--mantine-color-white);
|
||||
}
|
||||
```
|
||||
|
||||
### Button Component Example
|
||||
|
||||
```tsx
|
||||
// Before
|
||||
<Button
|
||||
style={{
|
||||
backgroundColor: theme.colors.blue[6],
|
||||
color: 'white'
|
||||
}}
|
||||
>
|
||||
Click me
|
||||
</Button>
|
||||
|
||||
// After
|
||||
<Button color="brand-primary">Click me</Button>
|
||||
```
|
||||
|
||||
## Testing Your Migration
|
||||
|
||||
After migrating, run stylelint to ensure you're not using hardcoded colors:
|
||||
|
||||
```bash
|
||||
yarn stylelint
|
||||
```
|
||||
|
||||
## Need Help?
|
||||
|
||||
Refer to the `color-tokens.md` file or the `ColorPalette` component in Storybook for a complete reference of our color system.
|
||||
@@ -2,12 +2,12 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||
<link rel="icon" type="image/png" href="/src/assets/darkmode-small.png" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="minimum-scale=1, initial-scale=1, width=device-width, user-scalable=no"
|
||||
/>
|
||||
<title>Vite + Mantine App</title>
|
||||
<title>Craig Macfadyen</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
BIN
frontend/vite-template-master/src/assets/darkmode-small.png
Normal file
BIN
frontend/vite-template-master/src/assets/darkmode-small.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -13,4 +13,4 @@ const meta = {
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {};
|
||||
export const Default: Story = {};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Anchor, Container, Text, Stack } from '@mantine/core';
|
||||
import { Anchor, Container, Stack, Text } from '@mantine/core';
|
||||
import classes from './Contact.module.css';
|
||||
|
||||
export function Contact() {
|
||||
@@ -25,7 +25,11 @@ export function Contact() {
|
||||
</Text>
|
||||
<Text size="lg">
|
||||
LinkedIn:{' '}
|
||||
<Anchor href="https://www.linkedin.com/in/craig-macfadyen-9a2041197" target="_blank" className={classes.link}>
|
||||
<Anchor
|
||||
href="https://www.linkedin.com/in/craig-macfadyen-9a2041197"
|
||||
target="_blank"
|
||||
className={classes.link}
|
||||
>
|
||||
linkedin.com/in/craigmacfadyen
|
||||
</Anchor>
|
||||
</Text>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.section {
|
||||
margin-top: 80px;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Carousel } from '@mantine/carousel';
|
||||
import { Container, Grid, Image, Stack, Text, Title } from '@mantine/core';
|
||||
import classes from './ExpertiseSection.module.css';
|
||||
|
||||
interface ExpertiseSectionProps {
|
||||
title: string;
|
||||
content: string;
|
||||
images: { url: string; alt: string }[];
|
||||
viewMoreLink: string;
|
||||
imageOnLeft?: boolean;
|
||||
}
|
||||
|
||||
const ExpertiseSection: React.FC<ExpertiseSectionProps> = ({
|
||||
title,
|
||||
content,
|
||||
images,
|
||||
viewMoreLink: _viewMoreLink,
|
||||
imageOnLeft = false,
|
||||
}) => {
|
||||
const slides = images.map((image) => (
|
||||
<Carousel.Slide key={image.url}>
|
||||
<Image
|
||||
src={image.url}
|
||||
alt={image.alt}
|
||||
style={{ width: '100%', height: 'auto', objectFit: 'cover' }}
|
||||
/>
|
||||
</Carousel.Slide>
|
||||
));
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Grid className={classes.section}>
|
||||
<Grid.Col order={imageOnLeft ? 2 : 1} span={{ xs: 6, md: 8 }}>
|
||||
<Stack>
|
||||
<Title>{title}</Title>
|
||||
<Text size="lg">{content}</Text>
|
||||
{/* <Button component="a" href={viewMoreLink}>
|
||||
View More
|
||||
</Button> */}
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
<Grid.Col order={imageOnLeft ? 1 : 2} span={{ xs: 6, md: 4 }}>
|
||||
<Carousel
|
||||
slideSize={300}
|
||||
align="start"
|
||||
slideGap="md"
|
||||
controlsOffset="xl"
|
||||
controlSize={28}
|
||||
loop
|
||||
withIndicators
|
||||
>
|
||||
{slides}
|
||||
</Carousel>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExpertiseSection;
|
||||
@@ -0,0 +1,39 @@
|
||||
.title {
|
||||
font-size: 34px;
|
||||
font-weight: 900;
|
||||
|
||||
@media (max-width: $mantine-breakpoint-sm) {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
background-color: var(--mantine-color-blue-filled);
|
||||
width: 45px;
|
||||
height: 2px;
|
||||
margin-top: var(--mantine-spacing-sm);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 1px solid light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5));
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
background-color: var(--mantine-color-blue-filled);
|
||||
width: 45px;
|
||||
height: 2px;
|
||||
margin-top: var(--mantine-spacing-sm);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import { FaChartLine, FaCode, FaEye, FaLightbulb, FaMessage, FaShield } from 'react-icons/fa6';
|
||||
import {
|
||||
Badge,
|
||||
Card,
|
||||
Container,
|
||||
Group,
|
||||
SimpleGrid,
|
||||
Text,
|
||||
Title,
|
||||
useMantineTheme,
|
||||
} from '@mantine/core';
|
||||
import classes from './FeatureCards.module.css';
|
||||
|
||||
const mockdata = [
|
||||
{
|
||||
title: 'Computer Vision',
|
||||
description:
|
||||
'I have experience in building computer vision models for a range of applications, from object detection to image segmentation. If your business works with images, these models can improve your efficiency and accuracy.',
|
||||
icon: FaEye,
|
||||
},
|
||||
{
|
||||
title: 'Natural Language Processing',
|
||||
description:
|
||||
'Expertise working with LLMs, from training to deployment. These state-of-the-art models are a powerful tool for a range of applications, and can drive your business forward.',
|
||||
icon: FaMessage,
|
||||
},
|
||||
{
|
||||
title: 'Data Science',
|
||||
description:
|
||||
'Sometimes you just need a simple model and some nice graphs. I can help you understand your data and build a model that works for you.',
|
||||
icon: FaChartLine,
|
||||
},
|
||||
{
|
||||
title: 'Privacy Focused',
|
||||
description:
|
||||
'Your data is valuable and sensitive. All my solutions are built with privacy and security in mind from the ground up, ensuring regulatory compliance and protecting your competitive advantage.',
|
||||
icon: FaShield,
|
||||
},
|
||||
{
|
||||
title: 'Open Source',
|
||||
description:
|
||||
'Leverage the power and innovation of open source technologies while avoiding vendor lock-in. This approach provides transparency, cost-effectiveness, and ensures your solutions remain maintainable long-term.',
|
||||
icon: FaCode,
|
||||
},
|
||||
{
|
||||
title: 'Cutting-Edge Research',
|
||||
description:
|
||||
'I stay continuously updated with the latest advancements in AI research and immediately apply emerging techniques to solve business problems. Your solutions will never be outdated or obsolete.',
|
||||
icon: FaLightbulb,
|
||||
},
|
||||
];
|
||||
|
||||
export function FeaturesCards() {
|
||||
const theme = useMantineTheme();
|
||||
const features = mockdata.map((feature) => (
|
||||
<Card key={feature.title} shadow="md" radius="md" className={classes.card} padding="xl">
|
||||
<feature.icon size={50} color={theme.colors.blue[6]} />
|
||||
<Text fz="lg" fw={500} className={classes.cardTitle} mt="md">
|
||||
{feature.title}
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed" mt="sm">
|
||||
{feature.description}
|
||||
</Text>
|
||||
</Card>
|
||||
));
|
||||
|
||||
return (
|
||||
<Container size="lg" py="xl">
|
||||
<Group justify="center">
|
||||
<Badge variant="filled" size="lg">
|
||||
My Expertise
|
||||
</Badge>
|
||||
</Group>
|
||||
|
||||
<Title order={2} className={classes.title} ta="center" mt="sm">
|
||||
What can I bring to your business?
|
||||
</Title>
|
||||
|
||||
<Text c="dimmed" className={classes.description} ta="center" mt="md">
|
||||
I've worked with a range of businesses, from startups to established companies, and I've
|
||||
learned a lot about what works and what doesn't. I work across the full Machine Learning
|
||||
stack, from data collection to model deployment.
|
||||
</Text>
|
||||
|
||||
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="xl" mt="50px">
|
||||
{features}
|
||||
</SimpleGrid>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
.footer {
|
||||
margin-top: 120px;
|
||||
border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
|
||||
}
|
||||
|
||||
.inner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-top: var(--mantine-spacing-xl);
|
||||
padding-bottom: var(--mantine-spacing-xl);
|
||||
|
||||
@media (max-width: $mantine-breakpoint-xs) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
@media (max-width: $mantine-breakpoint-xs) {
|
||||
margin-top: var(--mantine-spacing-md);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { FaGithub, FaLinkedin } from 'react-icons/fa';
|
||||
import { SiGitea } from 'react-icons/si';
|
||||
import { ActionIcon, Container, Group, Text } from '@mantine/core';
|
||||
import classes from './FooterSocial.module.css';
|
||||
|
||||
export function FooterSocial() {
|
||||
return (
|
||||
<div className={classes.footer}>
|
||||
<Container className={classes.inner}>
|
||||
<Text>Craig Macfadyen</Text>
|
||||
<Group gap={0} className={classes.links} justify="flex-end" wrap="nowrap">
|
||||
<ActionIcon
|
||||
component="a"
|
||||
target="_blank"
|
||||
href="https://github.com/cdmacfadyen"
|
||||
size="lg"
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
>
|
||||
<FaGithub size={18} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
component="a"
|
||||
target="_blank"
|
||||
href="https://gitea.craigmacfadyen.co.uk"
|
||||
size="lg"
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
>
|
||||
<SiGitea size={18} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
component="a"
|
||||
target="_blank"
|
||||
href="https://www.linkedin.com/in/craig-macfadyen-9a2041197/"
|
||||
size="lg"
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
>
|
||||
<FaLinkedin size={18} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Anchor, Burger, Container, Group } from '@mantine/core';
|
||||
import { Burger, Container, Group, Text } from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import { MantineLogo } from '@mantinex/mantine-logo';
|
||||
import { ColorSchemeToggle } from '../ColorSchemeToggle/ColorSchemeToggle';
|
||||
import classes from './HeaderSimple.module.css';
|
||||
|
||||
@@ -10,14 +9,16 @@ export function HeaderSimple() {
|
||||
return (
|
||||
<header className={classes.header}>
|
||||
<Container size="md" className={classes.inner}>
|
||||
<MantineLogo size={28} />
|
||||
<Text fw={700} size="lg" style={{ userSelect: 'none', cursor: 'default' }}>
|
||||
Craig Macfadyen
|
||||
</Text>
|
||||
<Group gap={5} visibleFrom="xs">
|
||||
<Anchor href="#" className={classes.link}>
|
||||
{/* <Anchor href="#" className={classes.link}>
|
||||
CV
|
||||
</Anchor>
|
||||
<Anchor href="#" className={classes.link}>
|
||||
Blog
|
||||
</Anchor>
|
||||
</Anchor> */}
|
||||
</Group>
|
||||
|
||||
<Burger opened={opened} onClick={toggle} hiddenFrom="xs" size="sm" />
|
||||
|
||||
@@ -14,9 +14,9 @@ export function HeroTitle() {
|
||||
</h1>
|
||||
|
||||
<Text className={classes.description} c="dimmed">
|
||||
Data Scientist with experience in consulting and research. Expertise in Computer Vision
|
||||
and Large Language Models. Take a look at what I can do for your business and get in touch
|
||||
if you have any questions or you'd like to work together!
|
||||
Machine Learning Engineer with experience in consulting and research. Expertise in
|
||||
Computer Vision and Large Language Models. Take a look at what I can do for your business
|
||||
and get in touch if you have any questions or you'd like to work together!
|
||||
</Text>
|
||||
</Container>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Container } from '@mantine/core';
|
||||
import openWebUIGif from '@/assets/open-webui.gif';
|
||||
import outputGif from '@/assets/output.gif';
|
||||
import { Contact } from '@/components/ContactUs/Contact';
|
||||
import ExpertiseSection from '@/components/ExpertiseSection/ExpertiseSection';
|
||||
import { FeaturesCards } from '@/components/FeatureCards/FeatureCards';
|
||||
import { FooterSocial } from '@/components/FooterSocial/FooterSocial';
|
||||
import { HeaderSimple } from '@/components/HeaderSimple/HeaderSimple';
|
||||
import { HeroTitle } from '@/components/HeroTitle/HeroTitle';
|
||||
import Testimonial from '@/components/Testimonial/Testimonial';
|
||||
@@ -12,24 +11,12 @@ export function HomePage() {
|
||||
<>
|
||||
<HeaderSimple />
|
||||
<HeroTitle />
|
||||
<ExpertiseSection
|
||||
title="Computer Vision"
|
||||
content="Expertise in developing and deploying computer vision models for various applications, including object detection, image classification, and more. Ask me about state-of-the-art real-time models for your business."
|
||||
images={[{ url: outputGif, alt: 'Video Segmentation with SAM2.' }]}
|
||||
viewMoreLink="/computer-vision"
|
||||
imageOnLeft
|
||||
/>
|
||||
<ExpertiseSection
|
||||
title="Natural Language Processing"
|
||||
content="Building NLP models for tasks such as sentiment analysis, text classification, and language generation. If you need a chatbot for your business and care about privacy, or a simple text classification algorithm to understand your data, I can help."
|
||||
images={[{ url: openWebUIGif, alt: 'Locally hosted LLM using oLLama and OpenWebUI.' }]}
|
||||
viewMoreLink="/nlp"
|
||||
imageOnLeft={false}
|
||||
/>
|
||||
<FeaturesCards />
|
||||
<Container mt={20}>
|
||||
<Testimonial />
|
||||
</Container>
|
||||
<Contact />
|
||||
<FooterSocial />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user