Skip to content

Commit b6311dc

Browse files
authored
Merge pull request #1 from chechen-language/v2
V2
2 parents 679ebc4 + 5913207 commit b6311dc

25 files changed

Lines changed: 1966 additions & 82 deletions

.eleventy.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ module.exports = function (eleventyConfig) {
33
eleventyConfig.addPassthroughCopy('src/assets');
44
eleventyConfig.addPassthroughCopy({ 'node_modules/@ce/transliteration/translit.js': 'assets/repositories/chechen-transliterator/translit.js'});
55

6+
// Copy SEO files
7+
eleventyConfig.addPassthroughCopy('src/robots.txt');
8+
eleventyConfig.addPassthroughCopy('src/sitemap.xml');
9+
610
return {
711
dir: {
812
input: 'src',

CLAUDE.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is a static website for the Chechen Language organization, built with Eleventy (11ty). The site showcases various Chechen language tools and projects, including keyboard layouts for different platforms and a Chechen transliterator tool.
8+
9+
## Build and Development Commands
10+
11+
- `npm run build` - Build the static site (output to `_site/`)
12+
- `npm run serve` - Start development server with live reload
13+
- `npm run prettier` - Format all files with Prettier
14+
15+
## Architecture
16+
17+
### Static Site Generation (Eleventy)
18+
19+
The site uses Eleventy with the following structure:
20+
- Input directory: `src/`
21+
- Output directory: `_site/`
22+
- Templates: `src/_includes/` (Nunjucks templates)
23+
24+
### Configuration (.eleventy.js)
25+
26+
- Base layout template: `src/_includes/layout.njk`
27+
- Static assets are copied from `src/assets/` to output
28+
- The `@ce/transliteration` package is copied from node_modules to `_site/assets/repositories/chechen-transliterator/translit.js`
29+
30+
### Content Organization
31+
32+
- `src/index.md` - Home page
33+
- `src/repositories/` - Individual project pages (markdown files)
34+
- `chechen-transliterator/` - Interactive transliterator tool
35+
- `chechen-latin-keyboard-{platform}/` - Platform-specific keyboard documentation
36+
- Includes privacy policy pages for Android app
37+
38+
### Layout System
39+
40+
- Single base template: `src/_includes/layout.njk`
41+
- Uses Bootstrap 4.5.2 for styling
42+
- Responsive navigation with dropdown menu for projects
43+
- Sticky footer layout
44+
45+
### Interactive Features
46+
47+
The transliterator page (`src/repositories/chechen-transliterator/index.md`) has special functionality:
48+
- Uses `@ce/transliteration` package (JSR package: `@jsr/ce__transliteration`)
49+
- Client-side JavaScript: `src/assets/repositories/chechen-transliterator/main.js`
50+
- Handles URL query parameters to pre-fill and transliterate text
51+
- Syncs input text to URL query string for sharing/bookmarking
52+
53+
### Special Handling
54+
55+
- The transliteration logic handles the letter 'н' at word endings with blacklist and unsure list checking
56+
- Unsure words get flagged with 'ŋ[REPLACE]' for manual review
57+
58+
## Dependencies
59+
60+
- Core: `@11ty/eleventy` (static site generator)
61+
- Formatting: `prettier` with `lint-staged` and `husky` for pre-commit hooks
62+
- Runtime: `@ce/transliteration` (Chechen transliteration logic)
63+
64+
## Deployment
65+
66+
This is a GitHub Pages site (indicated by `.nojekyll` file). The built site from `_site/` is deployed to GitHub Pages.

src/_includes/layout.njk

Lines changed: 152 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,59 +3,164 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>{{ title }}</title>
7-
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
6+
7+
<!-- Primary Meta Tags -->
8+
<title>{{ title }} | Chechen Language Projects</title>
9+
<meta name="title" content="{{ title }} | Chechen Language Projects">
10+
<meta name="description" content="{% if description %}{{ description }}{% else %}Open source tools and resources for the Chechen language including Latin keyboard layouts, transliteration tools, and language preservation projects.{% endif %}">
11+
<meta name="keywords" content="Chechen language, Chechen keyboard, Latin script, transliteration, Noxchi, keyboard layout, language tools, Caucasian languages">
12+
<meta name="author" content="Chechen Language Projects">
13+
<meta name="language" content="English">
14+
15+
<!-- Canonical URL -->
16+
<link rel="canonical" href="https://chechen-language.github.io{{ page.url }}">
17+
18+
<!-- Open Graph / Facebook -->
19+
<meta property="og:type" content="website">
20+
<meta property="og:url" content="https://chechen-language.github.io{{ page.url }}">
21+
<meta property="og:title" content="{{ title }} | Chechen Language Projects">
22+
<meta property="og:description" content="{% if description %}{{ description }}{% else %}Open source tools and resources for the Chechen language including Latin keyboard layouts, transliteration tools, and language preservation projects.{% endif %}">
23+
<meta property="og:image" content="https://chechen-language.github.io/assets/images/og-image.png">
24+
<meta property="og:locale" content="en_US">
25+
<meta property="og:site_name" content="Chechen Language Projects">
26+
27+
<!-- Twitter Card -->
28+
<meta name="twitter:card" content="summary_large_image">
29+
<meta name="twitter:url" content="https://chechen-language.github.io{{ page.url }}">
30+
<meta name="twitter:title" content="{{ title }} | Chechen Language Projects">
31+
<meta name="twitter:description" content="{% if description %}{{ description }}{% else %}Open source tools and resources for the Chechen language including Latin keyboard layouts, transliteration tools, and language preservation projects.{% endif %}">
32+
<meta name="twitter:image" content="https://chechen-language.github.io/assets/images/og-image.png">
33+
34+
<!-- Theme Color -->
35+
<meta name="theme-color" content="#8B2332">
36+
<meta name="msapplication-TileColor" content="#8B2332">
37+
38+
<!-- Structured Data (JSON-LD) -->
39+
<script type="application/ld+json">
40+
{
41+
"@context": "https://schema.org",
42+
"@type": "Organization",
43+
"name": "Chechen Language Projects",
44+
"url": "https://chechen-language.github.io",
45+
"logo": "https://chechen-language.github.io/assets/images/logo.png",
46+
"description": "Open source tools and resources for the Chechen language preservation and development",
47+
"sameAs": [
48+
"https://github.com/chechen-language"
49+
],
50+
"contactPoint": {
51+
"@type": "ContactPoint",
52+
"contactType": "Community Support",
53+
"url": "https://github.com/chechen-language"
54+
}
55+
}
56+
</script>
57+
858
<link rel="stylesheet" href="/assets/style.css">
9-
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
10-
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
11-
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
12-
<script src="/assets/main.js" defer></script>
1359
{% block extra_head %}
1460
{% endblock %}
1561
</head>
16-
<body class="d-flex flex-column min-vh-100">
17-
<header class="bg-dark text-white py-3">
18-
<div class="container">
19-
<h1>Chechen Language Projects</h1>
20-
<nav class="navbar navbar-expand-lg navbar-dark">
21-
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
22-
<span class="navbar-toggler-icon"></span>
23-
</button>
24-
<div class="collapse navbar-collapse" id="navbarNav">
25-
<ul class="navbar-nav">
26-
<li class="nav-item">
27-
<a class="nav-link text-white" href="/">Home</a>
28-
</li>
29-
<li class="nav-item dropdown">
30-
<a class="nav-link dropdown-toggle text-white" href="#" id="projectsDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
31-
Projects
32-
</a>
33-
<div class="dropdown-menu" aria-labelledby="projectsDropdown">
34-
<a class="dropdown-item" href="/repositories/chechen-transliterator">Chechen Transliterator</a>
35-
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-macos">macOS Keyboard</a>
36-
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-windows">Windows Keyboard</a>
37-
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-linux">Linux Keyboard</a>
38-
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-ios">iOS Keyboard</a>
39-
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-android">Android Keyboard</a>
40-
<!-- Add more projects here -->
41-
</div>
42-
</li>
43-
</ul>
44-
</div>
45-
</nav>
46-
</div>
47-
</header>
48-
<div class="container flex-grow-1 mt-4">
49-
<main>
50-
{{ content | safe }}
62+
<body class="istang-layout">
63+
<div class="istang-border-wrapper">
64+
<div class="istang-border istang-border-top"></div>
65+
66+
<header class="site-header">
67+
<div class="istang-corner istang-corner-tl" aria-hidden="true"></div>
68+
<div class="istang-corner istang-corner-tr" aria-hidden="true"></div>
69+
<div class="container">
70+
<h1>Chechen Language Projects</h1>
71+
<button class="mobile-menu-toggle" id="mobile-menu-toggle" aria-label="Toggle navigation">☰</button>
72+
<nav class="nav" id="main-nav">
73+
<button class="mobile-close" id="mobile-close" aria-label="Close menu">×</button>
74+
<a href="/" class="nav-link">Home</a>
75+
<div class="nav-dropdown">
76+
<button class="dropdown-toggle" aria-haspopup="true" aria-expanded="false">Projects</button>
77+
<div class="dropdown-menu" role="menu">
78+
<a class="dropdown-item" href="/repositories/chechen-transliterator" role="menuitem">Chechen Transliterator</a>
79+
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-macos" role="menuitem">macOS Keyboard</a>
80+
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-windows" role="menuitem">Windows Keyboard</a>
81+
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-linux" role="menuitem">Linux Keyboard</a>
82+
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-ios" role="menuitem">iOS Keyboard</a>
83+
<a class="dropdown-item" href="/repositories/chechen-latin-keyboard-android" role="menuitem">Android Keyboard</a>
84+
</div>
85+
</div>
86+
</nav>
87+
</div>
88+
</header>
89+
90+
<main class="site-main">
91+
<div class="container">
92+
{{ content | safe }}
93+
</div>
5194
</main>
95+
96+
<footer class="site-footer">
97+
<div class="istang-corner istang-corner-bl" aria-hidden="true"></div>
98+
<div class="istang-corner istang-corner-br" aria-hidden="true"></div>
99+
<div class="container">
100+
<p>&copy; 2024 Chechen Language Projects</p>
101+
</div>
102+
</footer>
103+
104+
<div class="istang-border istang-border-bottom"></div>
52105
</div>
53-
<footer class="bg-dark text-white py-3 mt-4">
54-
<div class="container text-center">
55-
<p>&copy; 2024 Chechen Language Projects</p>
56-
</div>
57-
</footer>
106+
107+
<div class="mobile-overlay" id="mobile-overlay"></div>
108+
109+
<script>
110+
// Mobile menu toggle
111+
const mobileToggle = document.getElementById('mobile-menu-toggle');
112+
const mobileClose = document.getElementById('mobile-close');
113+
const mainNav = document.getElementById('main-nav');
114+
const mobileOverlay = document.getElementById('mobile-overlay');
115+
116+
function openMobileMenu() {
117+
mainNav.classList.add('active');
118+
mobileOverlay.classList.add('active');
119+
document.body.style.overflow = 'hidden';
120+
}
121+
122+
function closeMobileMenu() {
123+
mainNav.classList.remove('active');
124+
mobileOverlay.classList.remove('active');
125+
document.body.style.overflow = '';
126+
}
127+
128+
if (mobileToggle) {
129+
mobileToggle.addEventListener('click', function(e) {
130+
e.preventDefault();
131+
e.stopPropagation();
132+
if (mainNav.classList.contains('active')) {
133+
closeMobileMenu();
134+
} else {
135+
openMobileMenu();
136+
}
137+
});
138+
}
139+
140+
if (mobileClose) {
141+
mobileClose.addEventListener('click', function(e) {
142+
e.preventDefault();
143+
e.stopPropagation();
144+
closeMobileMenu();
145+
});
146+
}
147+
148+
// Close when clicking on the overlay
149+
if (mobileOverlay) {
150+
mobileOverlay.addEventListener('click', function(e) {
151+
closeMobileMenu();
152+
});
153+
}
154+
155+
// Close mobile menu on escape key
156+
document.addEventListener('keydown', function(event) {
157+
if (event.key === 'Escape' && mainNav.classList.contains('active')) {
158+
closeMobileMenu();
159+
}
160+
});
161+
</script>
162+
58163
{% block extra_scripts %}
59164
{% endblock %}
60165
</body>
61-
</html>
166+
</html>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/* Button component */
2+
3+
.btn {
4+
display: inline-block;
5+
padding: var(--space-sm) var(--space-lg);
6+
font-family: var(--font-sans);
7+
font-size: var(--text-base);
8+
font-weight: var(--font-medium);
9+
text-decoration: none;
10+
border-radius: var(--radius-sm);
11+
border: var(--border-thin) solid transparent;
12+
cursor: pointer;
13+
transition: all var(--transition-base);
14+
position: relative;
15+
text-align: center;
16+
}
17+
18+
.btn:focus {
19+
outline: 2px solid var(--color-gold);
20+
outline-offset: 2px;
21+
}
22+
23+
/* Primary button */
24+
.btn-primary {
25+
background-color: var(--color-burgundy);
26+
color: var(--color-gold);
27+
border-color: var(--color-burgundy-dark);
28+
}
29+
30+
.btn-primary:hover,
31+
.btn-primary:focus {
32+
background-color: var(--color-gold);
33+
color: var(--color-burgundy);
34+
border-color: var(--color-burgundy);
35+
box-shadow: var(--shadow-md);
36+
text-decoration: none;
37+
}
38+
39+
/* Secondary button */
40+
.btn-secondary {
41+
background-color: var(--color-forest);
42+
color: var(--color-gold-light);
43+
border-color: var(--color-forest-dark);
44+
}
45+
46+
.btn-secondary:hover,
47+
.btn-secondary:focus {
48+
background-color: var(--color-forest-light);
49+
color: var(--color-white);
50+
border-color: var(--color-forest);
51+
box-shadow: var(--shadow-md);
52+
text-decoration: none;
53+
}
54+
55+
/* Outline button */
56+
.btn-outline {
57+
background-color: transparent;
58+
color: var(--color-burgundy);
59+
border-color: var(--color-burgundy);
60+
}
61+
62+
.btn-outline:hover,
63+
.btn-outline:focus {
64+
background-color: var(--color-burgundy);
65+
color: var(--color-gold);
66+
text-decoration: none;
67+
}
68+
69+
/* Button sizes */
70+
.btn-sm {
71+
padding: var(--space-xs) var(--space-md);
72+
font-size: var(--text-sm);
73+
}
74+
75+
.btn-lg {
76+
padding: var(--space-md) var(--space-xl);
77+
font-size: var(--text-lg);
78+
}
79+
80+
/* Full width button */
81+
.btn-block {
82+
display: block;
83+
width: 100%;
84+
}
85+
86+
/* Disabled state */
87+
.btn:disabled,
88+
.btn[disabled] {
89+
opacity: 0.6;
90+
cursor: not-allowed;
91+
pointer-events: none;
92+
}

0 commit comments

Comments
 (0)