jsonresume-theme-bold-header-statement 1.0.0

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/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "jsonresume-theme-bold-header-statement",
3
+ "version": "1.0.0",
4
+ "description": "Magazine-inspired layout with commanding header and confident personal brand aesthetic",
5
+ "main": "src/index.js",
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "keywords": [
9
+ "jsonresume",
10
+ "theme",
11
+ "bold",
12
+ "header",
13
+ "magazine",
14
+ "personal-brand",
15
+ "creative"
16
+ ],
17
+ "peerDependencies": {
18
+ "react": "^18.0.0 || ^19.0.0",
19
+ "react-dom": "^18.0.0 || ^19.0.0"
20
+ },
21
+ "dependencies": {
22
+ "styled-components": "^6.1.19",
23
+ "@resume/core": "0.1.0"
24
+ }
25
+ }
package/src/Resume.jsx ADDED
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Header } from './components/Header.jsx';
4
+ import { WorkSection } from './components/WorkSection.jsx';
5
+ import { SkillsSection } from './components/SkillsSection.jsx';
6
+ import { EducationSection } from './components/EducationSection.jsx';
7
+ import { ProjectsSection } from './components/ProjectsSection.jsx';
8
+
9
+ const Layout = styled.div`
10
+ max-width: 900px;
11
+ margin: 0 auto;
12
+ padding: 0;
13
+ background: white;
14
+ font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI',
15
+ sans-serif;
16
+ color: #1f2937;
17
+
18
+ @media print {
19
+ padding: 0;
20
+ }
21
+ `;
22
+
23
+ const ContentWrapper = styled.div`
24
+ padding: 0 60px 60px 60px;
25
+
26
+ @media print {
27
+ padding: 0 40px 40px 40px;
28
+ }
29
+ `;
30
+
31
+ const Summary = styled.p`
32
+ font-size: 18px;
33
+ line-height: 1.8;
34
+ color: #374151;
35
+ margin: 0 0 60px 0;
36
+ font-weight: 300;
37
+ max-width: 800px;
38
+ `;
39
+
40
+ function Resume({ resume }) {
41
+ const {
42
+ basics = {},
43
+ work = [],
44
+ education = [],
45
+ skills = [],
46
+ projects = [],
47
+ } = resume;
48
+
49
+ return (
50
+ <Layout>
51
+ <Header basics={basics} />
52
+ <ContentWrapper>
53
+ {basics.summary && <Summary>{basics.summary}</Summary>}
54
+ <WorkSection work={work} />
55
+ <SkillsSection skills={skills} />
56
+ <EducationSection education={education} />
57
+ <ProjectsSection projects={projects} />
58
+ </ContentWrapper>
59
+ </Layout>
60
+ );
61
+ }
62
+
63
+ export default Resume;
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Section, SectionTitle, DateRange } from '@resume/core';
4
+
5
+ const StyledSectionTitle = styled(SectionTitle)`
6
+ font-size: 14px;
7
+ font-weight: 700;
8
+ color: #0f766e;
9
+ text-transform: uppercase;
10
+ letter-spacing: 2px;
11
+ margin: 60px 0 32px 0;
12
+ padding-bottom: 12px;
13
+ border-bottom: 3px solid #0f766e;
14
+ `;
15
+
16
+ const ContentBlock = styled.div`
17
+ margin-bottom: 50px;
18
+ background: #fafafa;
19
+ padding: 32px;
20
+ border-radius: 8px;
21
+ border-left: 4px solid #0f766e;
22
+
23
+ &:last-child {
24
+ margin-bottom: 0;
25
+ }
26
+
27
+ @media print {
28
+ background: white;
29
+ border: 1px solid #e5e7eb;
30
+ padding: 24px;
31
+ }
32
+ `;
33
+
34
+ const Institution = styled.h3`
35
+ font-size: 20px;
36
+ font-weight: 700;
37
+ color: #111827;
38
+ margin: 0 0 8px 0;
39
+ `;
40
+
41
+ const Degree = styled.div`
42
+ font-size: 16px;
43
+ color: #4b5563;
44
+ margin-bottom: 8px;
45
+ font-weight: 400;
46
+ `;
47
+
48
+ const EducationDate = styled.div`
49
+ font-size: 14px;
50
+ color: #6b7280;
51
+ text-transform: uppercase;
52
+ letter-spacing: 1px;
53
+ `;
54
+
55
+ export function EducationSection({ education }) {
56
+ if (!education?.length) return null;
57
+
58
+ return (
59
+ <Section>
60
+ <StyledSectionTitle>Education</StyledSectionTitle>
61
+ {education.map((edu, index) => (
62
+ <ContentBlock key={index}>
63
+ <Institution>{edu.institution}</Institution>
64
+ <Degree>
65
+ {edu.studyType} in {edu.area}
66
+ {edu.score && ` • ${edu.score}`}
67
+ </Degree>
68
+ <EducationDate>
69
+ <DateRange startDate={edu.startDate} endDate={edu.endDate} />
70
+ </EducationDate>
71
+ </ContentBlock>
72
+ ))}
73
+ </Section>
74
+ );
75
+ }
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { ContactInfo } from '@resume/core';
4
+
5
+ const HeaderSection = styled.header`
6
+ width: 100%;
7
+ background: linear-gradient(135deg, #0f766e 0%, #0d9488 100%);
8
+ padding: 80px 60px;
9
+ margin-bottom: 60px;
10
+ position: relative;
11
+ overflow: hidden;
12
+
13
+ &::before {
14
+ content: '';
15
+ position: absolute;
16
+ top: 0;
17
+ right: 0;
18
+ width: 300px;
19
+ height: 300px;
20
+ background: rgba(255, 255, 255, 0.05);
21
+ border-radius: 50%;
22
+ transform: translate(30%, -30%);
23
+ }
24
+
25
+ @media print {
26
+ padding: 60px 40px;
27
+ background: #0f766e;
28
+ }
29
+ `;
30
+
31
+ const Name = styled.h1`
32
+ font-size: 4rem;
33
+ font-weight: 900;
34
+ color: white;
35
+ margin: 0 0 16px 0;
36
+ letter-spacing: -2px;
37
+ line-height: 1;
38
+ text-transform: uppercase;
39
+ position: relative;
40
+ z-index: 1;
41
+
42
+ @media print {
43
+ font-size: 3.5rem;
44
+ }
45
+ `;
46
+
47
+ const Label = styled.div`
48
+ font-size: 1.5rem;
49
+ color: rgba(255, 255, 255, 0.95);
50
+ margin-bottom: 32px;
51
+ font-weight: 300;
52
+ letter-spacing: 0.5px;
53
+ position: relative;
54
+ z-index: 1;
55
+ `;
56
+
57
+ const StyledContactInfo = styled(ContactInfo)`
58
+ font-size: 16px;
59
+ position: relative;
60
+ z-index: 1;
61
+
62
+ a {
63
+ color: white;
64
+ font-weight: 400;
65
+ }
66
+
67
+ span {
68
+ color: rgba(255, 255, 255, 0.9);
69
+ }
70
+ `;
71
+
72
+ export function Header({ basics }) {
73
+ return (
74
+ <HeaderSection>
75
+ <Name>{basics.name}</Name>
76
+ {basics.label && <Label>{basics.label}</Label>}
77
+ <StyledContactInfo basics={basics} />
78
+ </HeaderSection>
79
+ );
80
+ }
@@ -0,0 +1,96 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Section, SectionTitle } from '@resume/core';
4
+
5
+ const StyledSectionTitle = styled(SectionTitle)`
6
+ font-size: 14px;
7
+ font-weight: 700;
8
+ color: #0f766e;
9
+ text-transform: uppercase;
10
+ letter-spacing: 2px;
11
+ margin: 60px 0 32px 0;
12
+ padding-bottom: 12px;
13
+ border-bottom: 3px solid #0f766e;
14
+ `;
15
+
16
+ const ContentBlock = styled.div`
17
+ margin-bottom: 50px;
18
+ background: #fafafa;
19
+ padding: 32px;
20
+ border-radius: 8px;
21
+ border-left: 4px solid #0f766e;
22
+
23
+ &:last-child {
24
+ margin-bottom: 0;
25
+ }
26
+
27
+ @media print {
28
+ background: white;
29
+ border: 1px solid #e5e7eb;
30
+ padding: 24px;
31
+ }
32
+ `;
33
+
34
+ const Position = styled.h3`
35
+ font-size: 22px;
36
+ font-weight: 700;
37
+ color: #111827;
38
+ margin: 0 0 8px 0;
39
+ letter-spacing: -0.5px;
40
+ `;
41
+
42
+ const WorkSummary = styled.p`
43
+ margin: 16px 0;
44
+ color: #4b5563;
45
+ line-height: 1.7;
46
+ font-size: 16px;
47
+ font-weight: 300;
48
+ `;
49
+
50
+ const Highlights = styled.ul`
51
+ margin: 16px 0 0 0;
52
+ padding-left: 24px;
53
+ list-style-type: none;
54
+
55
+ li {
56
+ margin: 10px 0;
57
+ color: #374151;
58
+ line-height: 1.7;
59
+ font-weight: 300;
60
+ position: relative;
61
+ padding-left: 8px;
62
+
63
+ &::before {
64
+ content: '▸';
65
+ position: absolute;
66
+ left: -16px;
67
+ color: #0f766e;
68
+ font-weight: 700;
69
+ }
70
+ }
71
+ `;
72
+
73
+ export function ProjectsSection({ projects }) {
74
+ if (!projects?.length) return null;
75
+
76
+ return (
77
+ <Section>
78
+ <StyledSectionTitle>Projects</StyledSectionTitle>
79
+ {projects.map((project, index) => (
80
+ <ContentBlock key={index}>
81
+ <Position>{project.name}</Position>
82
+ {project.description && (
83
+ <WorkSummary>{project.description}</WorkSummary>
84
+ )}
85
+ {project.highlights?.length > 0 && (
86
+ <Highlights>
87
+ {project.highlights.map((highlight, i) => (
88
+ <li key={i}>{highlight}</li>
89
+ ))}
90
+ </Highlights>
91
+ )}
92
+ </ContentBlock>
93
+ ))}
94
+ </Section>
95
+ );
96
+ }
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Section, SectionTitle } from '@resume/core';
4
+
5
+ const StyledSectionTitle = styled(SectionTitle)`
6
+ font-size: 14px;
7
+ font-weight: 700;
8
+ color: #0f766e;
9
+ text-transform: uppercase;
10
+ letter-spacing: 2px;
11
+ margin: 60px 0 32px 0;
12
+ padding-bottom: 12px;
13
+ border-bottom: 3px solid #0f766e;
14
+ `;
15
+
16
+ const SkillsGrid = styled.div`
17
+ display: grid;
18
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
19
+ gap: 24px;
20
+ `;
21
+
22
+ const SkillCategory = styled.div`
23
+ padding: 24px;
24
+ background: white;
25
+ border-radius: 8px;
26
+ border: 2px solid #0f766e;
27
+ transition: transform 0.2s;
28
+ `;
29
+
30
+ const SkillName = styled.h4`
31
+ font-size: 16px;
32
+ font-weight: 700;
33
+ color: #0f766e;
34
+ margin: 0 0 12px 0;
35
+ text-transform: uppercase;
36
+ letter-spacing: 1px;
37
+ `;
38
+
39
+ const SkillTags = styled.div`
40
+ font-size: 14px;
41
+ color: #6b7280;
42
+ line-height: 1.6;
43
+ font-weight: 300;
44
+ `;
45
+
46
+ export function SkillsSection({ skills }) {
47
+ if (!skills?.length) return null;
48
+
49
+ return (
50
+ <Section>
51
+ <StyledSectionTitle>Skills</StyledSectionTitle>
52
+ <SkillsGrid>
53
+ {skills.map((skill, index) => (
54
+ <SkillCategory key={index}>
55
+ <SkillName>{skill.name}</SkillName>
56
+ {skill.keywords?.length > 0 && (
57
+ <SkillTags>{skill.keywords.join(', ')}</SkillTags>
58
+ )}
59
+ </SkillCategory>
60
+ ))}
61
+ </SkillsGrid>
62
+ </Section>
63
+ );
64
+ }
@@ -0,0 +1,119 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Section, SectionTitle, DateRange } from '@resume/core';
4
+
5
+ const StyledSectionTitle = styled(SectionTitle)`
6
+ font-size: 14px;
7
+ font-weight: 700;
8
+ color: #0f766e;
9
+ text-transform: uppercase;
10
+ letter-spacing: 2px;
11
+ margin: 60px 0 32px 0;
12
+ padding-bottom: 12px;
13
+ border-bottom: 3px solid #0f766e;
14
+ `;
15
+
16
+ const ContentBlock = styled.div`
17
+ margin-bottom: 50px;
18
+ background: #fafafa;
19
+ padding: 32px;
20
+ border-radius: 8px;
21
+ border-left: 4px solid #0f766e;
22
+
23
+ &:last-child {
24
+ margin-bottom: 0;
25
+ }
26
+
27
+ @media print {
28
+ background: white;
29
+ border: 1px solid #e5e7eb;
30
+ padding: 24px;
31
+ }
32
+ `;
33
+
34
+ const WorkHeader = styled.div`
35
+ margin-bottom: 16px;
36
+ `;
37
+
38
+ const Position = styled.h3`
39
+ font-size: 22px;
40
+ font-weight: 700;
41
+ color: #111827;
42
+ margin: 0 0 8px 0;
43
+ letter-spacing: -0.5px;
44
+ `;
45
+
46
+ const Company = styled.div`
47
+ font-size: 18px;
48
+ color: #0f766e;
49
+ font-weight: 500;
50
+ margin-bottom: 8px;
51
+ `;
52
+
53
+ const DateText = styled.div`
54
+ font-size: 14px;
55
+ color: #6b7280;
56
+ font-weight: 400;
57
+ text-transform: uppercase;
58
+ letter-spacing: 1px;
59
+ `;
60
+
61
+ const WorkSummary = styled.p`
62
+ margin: 16px 0;
63
+ color: #4b5563;
64
+ line-height: 1.7;
65
+ font-size: 16px;
66
+ font-weight: 300;
67
+ `;
68
+
69
+ const Highlights = styled.ul`
70
+ margin: 16px 0 0 0;
71
+ padding-left: 24px;
72
+ list-style-type: none;
73
+
74
+ li {
75
+ margin: 10px 0;
76
+ color: #374151;
77
+ line-height: 1.7;
78
+ font-weight: 300;
79
+ position: relative;
80
+ padding-left: 8px;
81
+
82
+ &::before {
83
+ content: '▸';
84
+ position: absolute;
85
+ left: -16px;
86
+ color: #0f766e;
87
+ font-weight: 700;
88
+ }
89
+ }
90
+ `;
91
+
92
+ export function WorkSection({ work }) {
93
+ if (!work?.length) return null;
94
+
95
+ return (
96
+ <Section>
97
+ <StyledSectionTitle>Experience</StyledSectionTitle>
98
+ {work.map((job, index) => (
99
+ <ContentBlock key={index}>
100
+ <WorkHeader>
101
+ <Position>{job.position}</Position>
102
+ {job.name && <Company>{job.name}</Company>}
103
+ <DateText>
104
+ <DateRange startDate={job.startDate} endDate={job.endDate} />
105
+ </DateText>
106
+ </WorkHeader>
107
+ {job.summary && <WorkSummary>{job.summary}</WorkSummary>}
108
+ {job.highlights?.length > 0 && (
109
+ <Highlights>
110
+ {job.highlights.map((highlight, i) => (
111
+ <li key={i}>{highlight}</li>
112
+ ))}
113
+ </Highlights>
114
+ )}
115
+ </ContentBlock>
116
+ ))}
117
+ </Section>
118
+ );
119
+ }
package/src/index.js ADDED
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { renderToString } from 'react-dom/server';
3
+ import { ServerStyleSheet } from 'styled-components';
4
+ import Resume from './Resume.jsx';
5
+
6
+ export function render(resume) {
7
+ const sheet = new ServerStyleSheet();
8
+
9
+ try {
10
+ const html = renderToString(
11
+ sheet.collectStyles(<Resume resume={resume} />)
12
+ );
13
+ const styles = sheet.getStyleTags();
14
+
15
+ return `<!DOCTYPE html>
16
+ <html lang="en">
17
+ <head>
18
+ <meta charset="UTF-8">
19
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
20
+ <title>${resume.basics?.name || 'Resume'} - Resume</title>
21
+ <link rel="preconnect" href="https://fonts.googleapis.com">
22
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
23
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;700;900&display=swap" rel="stylesheet">
24
+ ${styles}
25
+ <style>
26
+ * {
27
+ box-sizing: border-box;
28
+ margin: 0;
29
+ padding: 0;
30
+ }
31
+ body {
32
+ margin: 0;
33
+ padding: 0;
34
+ background: #f5f5f5;
35
+ }
36
+ @media print {
37
+ body {
38
+ background: white;
39
+ }
40
+ @page {
41
+ margin: 0.5in;
42
+ }
43
+ }
44
+ </style>
45
+ </head>
46
+ <body>
47
+ ${html}
48
+ </body>
49
+ </html>`;
50
+ } finally {
51
+ sheet.seal();
52
+ }
53
+ }