Skip to content

Commit 93d5fd4

Browse files
committed
initial commit
0 parents  commit 93d5fd4

18 files changed

Lines changed: 474 additions & 0 deletions

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# shared-web-assets
2+
3+
Central asset hub for all 21no.de web properties. Served from **assets.21no.de**.
4+
5+
## Structure
6+
7+
```
8+
├── css/
9+
│ ├── tokens.css # Design tokens (CSS variables)
10+
│ ├── base.css # Reset, typography, layout
11+
│ ├── nav.css # Sticky navigation
12+
│ ├── hero.css # Hero section + stats
13+
│ ├── buttons.css # .btn, .btn-primary, .btn-secondary
14+
│ ├── cards.css # .card, .project-card, .feature-grid
15+
│ ├── footer.css # Site footer
16+
│ └── blog-carousel.css # Blog carousel + skeleton
17+
├── fonts/
18+
│ ├── fonts.css # @font-face declarations
19+
│ ├── Outfit-*.ttf # Outfit (300–700)
20+
│ └── JetBrainsMono-*.ttf # JetBrains Mono (400–600)
21+
└── README.md
22+
```
23+
24+
## Usage
25+
26+
```html
27+
<!-- Fonts -->
28+
<link rel="stylesheet" href="https://assets.21no.de/fonts/fonts.css" />
29+
<!-- Design system -->
30+
<link rel="stylesheet" href="https://assets.21no.de/css/tokens.css" />
31+
<link rel="stylesheet" href="https://assets.21no.de/css/base.css" />
32+
<link rel="stylesheet" href="https://assets.21no.de/css/nav.css" />
33+
<!-- Components as needed -->
34+
<link rel="stylesheet" href="https://assets.21no.de/css/buttons.css" />
35+
<link rel="stylesheet" href="https://assets.21no.de/css/cards.css" />
36+
<link rel="stylesheet" href="https://assets.21no.de/css/hero.css" />
37+
<link rel="stylesheet" href="https://assets.21no.de/css/footer.css" />
38+
```
39+
40+
Page-specific styles stay inline in the project's own HTML.
41+
42+
## Adding a New Site
43+
44+
1. Point your site's HTML to `https://assets.21no.de/css/*.css`
45+
2. Add any page-specific CSS inline
46+
3. Done — no font or design system duplication

css/base.css

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* === Reset & Base === */
2+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
3+
html { scroll-behavior: smooth; }
4+
body {
5+
font-family: var(--font-sans);
6+
background: var(--bg-primary);
7+
color: var(--text-primary);
8+
line-height: 1.6;
9+
-webkit-font-smoothing: antialiased;
10+
-moz-osx-font-smoothing: grayscale;
11+
}
12+
a { color: var(--accent); text-decoration: none; transition: color 0.15s; }
13+
a:hover { color: #7dd3fc; }
14+
code, pre { font-family: var(--font-mono); }
15+
img { max-width: 100%; display: block; }
16+
17+
/* === Layout === */
18+
.container { max-width: var(--max-width); margin: 0 auto; padding: 0 24px; }
19+
20+
/* === Section Defaults === */
21+
.section { padding: 80px 0; }
22+
.section + .section { border-top: 1px solid var(--border-subtle); }
23+
.section-label {
24+
font-family: var(--font-mono); font-size: 12px; font-weight: 500;
25+
color: var(--accent); text-transform: uppercase; letter-spacing: 0.8px;
26+
margin-bottom: 12px;
27+
}
28+
.section h2 {
29+
font-size: clamp(28px, 3vw, 40px); font-weight: 600;
30+
letter-spacing: -1.2px; line-height: 1.2;
31+
margin-bottom: 12px;
32+
}
33+
.section .lead {
34+
font-size: 18px; color: var(--text-secondary); font-weight: 300;
35+
max-width: 600px; line-height: 1.7; margin-bottom: 32px;
36+
}
37+
38+
/* === Animations === */
39+
.fade-in {
40+
opacity: 0; transform: translateY(16px);
41+
transition: all 0.6s ease-out;
42+
}
43+
.fade-in.visible { opacity: 1; transform: translateY(0); }
44+
@keyframes fadeUp {
45+
from { opacity: 0; transform: translateY(20px); }
46+
to { opacity: 1; transform: translateY(0); }
47+
}
48+
@keyframes fadeDown {
49+
from { opacity: 0; transform: translateY(-10px); }
50+
to { opacity: 1; transform: translateY(0); }
51+
}
52+
53+
/* === Responsive === */
54+
@media (max-width: 768px) {
55+
.hero { padding: 60px 0 48px; }
56+
.hero h1 { letter-spacing: -1.6px; }
57+
.hero p { font-size: 17px; }
58+
.section { padding: 48px 0; }
59+
.nav-links a:not(.nav-cta) { display: none; }
60+
}
61+
@media (max-width: 480px) {
62+
.hero h1 { letter-spacing: -1.2px; }
63+
.hero { padding: 60px 0 48px; }
64+
.hero-stats { gap: 16px; }
65+
}

css/blog-carousel.css

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/* === Blog Carousel === */
2+
.blog-carousel { padding: 60px 0; }
3+
.carousel-wrapper {
4+
position: relative; display: flex; align-items: center; gap: 16px;
5+
}
6+
.carousel-container {
7+
flex: 1; overflow: hidden; position: relative;
8+
}
9+
.carousel-track {
10+
display: flex; gap: 24px; transition: transform 0.5s ease; will-change: transform;
11+
}
12+
.blog-card {
13+
flex: 0 0 320px; min-width: 0; overflow: hidden;
14+
background: var(--bg-card); border: 1px solid var(--border-card);
15+
border-radius: var(--radius-lg); padding: 24px;
16+
transition: all 0.3s ease; cursor: pointer;
17+
}
18+
.blog-card:hover {
19+
border-color: rgba(255,255,255,0.12); transform: translateY(-2px);
20+
}
21+
.blog-card h3 {
22+
font-size: 16px; font-weight: 600; margin-bottom: 10px;
23+
color: var(--text-primary); letter-spacing: -0.2px;
24+
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
25+
overflow: hidden;
26+
}
27+
.blog-card .post-image img {
28+
width: 100%; height: 160px; object-fit: cover;
29+
border-radius: 8px; margin-bottom: 12px;
30+
}
31+
.blog-card .blog-excerpt {
32+
color: var(--text-secondary); font-size: 13px; font-weight: 300;
33+
line-height: 1.6; margin-bottom: 16px;
34+
display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
35+
overflow: hidden;
36+
}
37+
.blog-card .blog-meta {
38+
display: flex; gap: 12px; align-items: center;
39+
font-size: 13px; color: var(--text-tertiary);
40+
}
41+
.blog-card .blog-date { display: flex; align-items: center; gap: 4px; }
42+
.carousel-btn {
43+
background: var(--bg-card); border: 1px solid var(--border-card);
44+
border-radius: 50%; width: 40px; height: 40px;
45+
display: flex; align-items: center; justify-content: center;
46+
cursor: pointer; transition: all 0.2s ease; flex-shrink: 0; color: var(--text-secondary);
47+
}
48+
.carousel-btn:hover { border-color: rgba(255,255,255,0.15); color: var(--text-primary); }
49+
.carousel-btn:disabled { opacity: 0.3; cursor: not-allowed; }
50+
.carousel-dots {
51+
display: flex; justify-content: center; gap: 8px; margin-top: 20px;
52+
}
53+
.carousel-dot {
54+
width: 8px; height: 8px; border-radius: 50%;
55+
background: var(--border-card); cursor: pointer; transition: all 0.3s ease; border: none;
56+
}
57+
.carousel-dot.active {
58+
background: var(--accent); width: 24px; border-radius: 4px;
59+
}
60+
61+
/* === Skeleton === */
62+
.skeleton { pointer-events: none; cursor: default; }
63+
.skeleton-title, .skeleton-text {
64+
background: linear-gradient(90deg, var(--border-card) 25%, rgba(255,255,255,0.06) 50%, var(--border-card) 75%);
65+
background-size: 200% 100%;
66+
animation: skeleton-loading 1.5s ease-in-out infinite;
67+
border-radius: 4px;
68+
}
69+
.skeleton-title { height: 24px; width: 80%; margin-bottom: 16px; }
70+
.skeleton-text { height: 16px; margin-bottom: 8px; }
71+
.skeleton-text:last-child { width: 60%; }
72+
@keyframes skeleton-loading {
73+
0% { background-position: 200% 0; }
74+
100% { background-position: -200% 0; }
75+
}
76+
77+
/* === Mobile Carousel === */
78+
@media (max-width: 768px) {
79+
.carousel-btn { display: none; }
80+
.carousel-wrapper { gap: 0; }
81+
.carousel-track { gap: 16px; padding: 0; }
82+
.blog-card { flex: none; width: calc(100vw - 72px); padding: 24px; }
83+
.blog-card h3 { -webkit-line-clamp: 3; font-size: 15px; }
84+
.blog-card .blog-excerpt { -webkit-line-clamp: 4; }
85+
.blog-card .post-image img { height: 180px; }
86+
.carousel-container { overflow-x: auto; -webkit-overflow-scrolling: touch; scroll-snap-type: x mandatory; }
87+
.blog-card { scroll-snap-align: center; }
88+
}

css/buttons.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* === Buttons === */
2+
.btn {
3+
display: inline-flex; align-items: center; gap: 6px;
4+
padding: 10px 22px; border-radius: var(--radius-sm);
5+
font-family: var(--font-sans); font-size: 14px; font-weight: 500;
6+
cursor: pointer; transition: all 0.15s; border: none; text-decoration: none;
7+
}
8+
.btn-primary {
9+
background: var(--accent); color: #000;
10+
box-shadow: 0 0 20px var(--accent-glow);
11+
}
12+
.btn-primary:hover { background: #7dd3fc; color: #000; }
13+
.btn-secondary {
14+
background: transparent; color: var(--text-secondary);
15+
border: 1px solid var(--border-card);
16+
}
17+
.btn-secondary:hover { border-color: rgba(255,255,255,0.15); color: var(--text-primary); }

css/cards.css

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* === Cards (base) === */
2+
.card {
3+
background: var(--bg-card); border: 1px solid var(--border-card);
4+
border-radius: var(--radius-lg); padding: 28px;
5+
transition: border-color 0.2s, transform 0.2s;
6+
}
7+
.card:hover { border-color: rgba(255,255,255,0.12); transform: translateY(-1px); }
8+
.card-icon {
9+
width: 40px; height: 40px; border-radius: var(--radius-sm);
10+
display: flex; align-items: center; justify-content: center;
11+
font-size: 20px; margin-bottom: 16px;
12+
}
13+
.card-icon.accent { background: var(--accent-subtle); color: var(--accent); }
14+
.card-icon.green { background: var(--green-subtle); color: var(--green); }
15+
.card-icon.purple { background: var(--purple-subtle); color: var(--purple); }
16+
.card h3 { font-size: 18px; font-weight: 600; margin-bottom: 8px; letter-spacing: -0.3px; }
17+
.card p { font-size: 14px; color: var(--text-secondary); line-height: 1.6; font-weight: 300; }
18+
19+
/* === Project Cards === */
20+
.project-card {
21+
background: var(--bg-card); border: 1px solid var(--border-card);
22+
border-radius: var(--radius-lg); padding: 28px;
23+
display: flex; flex-direction: column; gap: 12px;
24+
transition: border-color 0.2s, transform 0.2s;
25+
}
26+
.project-card:hover { border-color: rgba(255,255,255,0.12); transform: translateY(-1px); }
27+
.project-card h3 {
28+
font-size: 18px; font-weight: 600; letter-spacing: -0.3px;
29+
color: var(--text-primary);
30+
}
31+
.project-card .tags {
32+
display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px;
33+
}
34+
.project-card .tag {
35+
display: inline-flex; align-items: center;
36+
font-family: var(--font-mono); font-size: 10px; font-weight: 500;
37+
padding: 2px 8px; border-radius: 4px;
38+
background: rgba(255,255,255,0.04); color: var(--text-tertiary);
39+
border: 1px solid var(--border-subtle);
40+
text-transform: uppercase; letter-spacing: 0.5px;
41+
}
42+
.project-card .desc {
43+
font-size: 14px; color: var(--text-secondary); line-height: 1.65; font-weight: 300;
44+
}
45+
.project-card .links {
46+
display: flex; gap: 16px; flex-wrap: wrap; margin-top: auto; padding-top: 4px;
47+
}
48+
.project-card .links a {
49+
display: inline-flex; align-items: center; gap: 4px;
50+
font-size: 13px; font-weight: 500; color: var(--text-tertiary);
51+
transition: color 0.15s;
52+
}
53+
.project-card .links a:hover { color: var(--accent); }
54+
.project-card .cat {
55+
font-family: var(--font-mono); font-size: 10px; font-weight: 500;
56+
color: var(--accent); text-transform: uppercase; letter-spacing: 0.5px;
57+
margin-bottom: 2px;
58+
}
59+
.project-card .pub-date,
60+
.book-card .pub-date {
61+
font-size: 11px; color: var(--text-tertiary); margin-top: 2px; margin-bottom: 4px;
62+
}
63+
64+
/* === Feature Grid === */
65+
.features-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
66+
@media (max-width: 900px) { .features-grid { grid-template-columns: 1fr; } }
67+
68+
/* === Project Grid === */
69+
.projects-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
70+
@media (max-width: 900px) { .projects-grid { grid-template-columns: 1fr; } }

css/footer.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* === Footer === */
2+
.footer {
3+
border-top: 1px solid var(--border-subtle); padding: 40px 0;
4+
text-align: center; color: var(--text-tertiary); font-size: 13px;
5+
}
6+
.footer a { color: var(--text-secondary); }
7+
.footer a:hover { color: var(--text-primary); }
8+
.footer .social-links { display: flex; gap: 20px; justify-content: center; margin-bottom: 16px; }
9+
.footer .social-links a {
10+
color: var(--text-tertiary); font-size: 14px;
11+
display: inline-flex; align-items: center; gap: 6px;
12+
}

css/hero.css

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* === Hero === */
2+
.hero {
3+
padding: 80px 0 60px; text-align: center; position: relative; overflow: hidden;
4+
}
5+
.hero::before {
6+
content: ''; position: absolute; top: -40%; left: 50%; transform: translateX(-50%);
7+
width: 800px; height: 800px;
8+
background: radial-gradient(circle, var(--accent-glow) 0%, transparent 60%);
9+
pointer-events: none;
10+
}
11+
.hero-badge {
12+
display: inline-flex; align-items: center; gap: 6px;
13+
background: var(--accent-subtle); border: 1px solid rgba(56,189,248,0.2);
14+
color: var(--accent); padding: 4px 14px; border-radius: 999px;
15+
font-size: 13px; font-weight: 500; margin-bottom: 28px;
16+
}
17+
.hero-badge .dot { width: 6px; height: 6px; background: var(--accent); border-radius: 50%; }
18+
.hero h1 {
19+
font-size: clamp(40px, 5vw, 60px); font-weight: 700;
20+
letter-spacing: -2.4px; line-height: 1.08;
21+
margin-bottom: 20px; position: relative;
22+
}
23+
.hero h1 .accent {
24+
background: linear-gradient(135deg, var(--accent) 0%, #818cf8 100%);
25+
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
26+
background-clip: text;
27+
}
28+
.hero p {
29+
font-size: clamp(16px, 2vw, 20px); font-weight: 300; color: var(--text-secondary);
30+
max-width: 600px; margin: 0 auto 28px; line-height: 1.7;
31+
}
32+
.hero-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
33+
34+
/* === Stats Bar === */
35+
.hero-stats {
36+
display: flex; gap: 32px; justify-content: center; align-items: center;
37+
margin-top: 40px; flex-wrap: wrap;
38+
}
39+
.hero-stats .stat {
40+
display: flex; align-items: center; gap: 8px;
41+
font-size: 14px; color: var(--text-tertiary);
42+
}
43+
.hero-stats .stat .num {
44+
font-family: var(--font-mono); font-size: 18px; font-weight: 600;
45+
color: var(--text-primary);
46+
}
47+
48+
/* === Code Block (Hero) === */
49+
.code-block {
50+
max-width: 700px; margin: 48px auto 0;
51+
background: var(--bg-code); border: 1px solid var(--border-card);
52+
border-radius: var(--radius-lg); overflow: hidden;
53+
text-align: left; position: relative;
54+
}
55+
.code-block .bar {
56+
display: flex; align-items: center; gap: 8px;
57+
padding: 12px 16px; border-bottom: 1px solid var(--border-subtle);
58+
}
59+
.code-block .bar .dot { width: 10px; height: 10px; border-radius: 50%; }
60+
.code-block .bar .dot.r { background: #e5484d; }
61+
.code-block .bar .dot.y { background: var(--yellow); }
62+
.code-block .bar .dot.g { background: var(--green); }
63+
.code-block .bar .title { font-size: 12px; color: var(--text-tertiary); margin-left: 8px; font-family: var(--font-mono); }

css/nav.css

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* === Navigation === */
2+
.nav {
3+
position: sticky; top: 0; z-index: 100;
4+
background: rgba(10,10,11,0.85); backdrop-filter: blur(12px);
5+
border-bottom: 1px solid var(--border-subtle);
6+
}
7+
.nav-inner {
8+
display: flex; align-items: center; justify-content: space-between;
9+
height: 56px; max-width: var(--max-width); margin: 0 auto; padding: 0 24px;
10+
}
11+
.nav-logo {
12+
display: flex; align-items: center; gap: 10px;
13+
font-weight: 600; font-size: 18px; color: var(--text-primary);
14+
letter-spacing: -0.3px;
15+
}
16+
.nav-logo img {
17+
width: 28px; height: 28px; border-radius: var(--radius-sm);
18+
}
19+
.nav-links { display: flex; gap: 24px; align-items: center; }
20+
.nav-links a {
21+
font-size: 14px; font-weight: 400; color: var(--text-secondary);
22+
letter-spacing: -0.1px; transition: color 0.15s;
23+
}
24+
.nav-links a:hover { color: var(--text-primary); }
25+
.nav-cta {
26+
background: var(--text-primary); color: var(--bg-primary) !important;
27+
padding: 6px 14px; border-radius: var(--radius-sm);
28+
font-weight: 500 !important; font-size: 13px !important;
29+
transition: opacity 0.15s;
30+
}
31+
.nav-cta:hover { opacity: 0.85; }

0 commit comments

Comments
 (0)