diff --git a/.gitignore b/.gitignore index 7dd7cefd964..a07eb52d84e 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,7 @@ package-lock.json # Misc _sass/vendors assets/js/dist + +# Astro +.astro/ +dist/ diff --git a/README.ASTRO.md b/README.ASTRO.md new file mode 100644 index 00000000000..faf3773d56f --- /dev/null +++ b/README.ASTRO.md @@ -0,0 +1,281 @@ +# Astro Chirpy + +A minimal, responsive, and feature-rich Astro theme for technical writing, migrated from the popular [Jekyll Chirpy theme](https://github.com/cotes2020/jekyll-theme-chirpy). + +## Features + +- **Lightning Fast** - Built with Astro for optimal performance +- **Clean Design** - Minimal and elegant interface +- **Dark Mode** - Automatic theme switching with manual toggle +- **Fully Responsive** - Works perfectly on all devices +- **SEO Optimized** - Built-in SEO best practices +- **MDX Support** - Write content in Markdown or MDX +- **Tags & Categories** - Organize your content effectively +- **TypeScript Ready** - Full TypeScript support +- **Accessible** - WCAG compliant + +## Project Structure + +``` +astro-chirpy/ +├── public/ # Static assets +├── src/ +│ ├── components/ # Astro components +│ │ ├── Head.astro +│ │ ├── Sidebar.astro +│ │ ├── Topbar.astro +│ │ ├── Footer.astro +│ │ └── ... +│ ├── content/ # Content collections +│ │ ├── posts/ # Blog posts +│ │ └── tabs/ # Navigation tabs +│ ├── data/ # Data files (YAML) +│ │ ├── authors.yml +│ │ ├── contact.yml +│ │ ├── locales/ # 33 language translations +│ │ └── ... +│ ├── layouts/ # Astro layouts +│ │ ├── BaseLayout.astro +│ │ └── PostLayout.astro +│ ├── pages/ # Routes +│ │ ├── index.astro # Home page +│ │ ├── [slug].astro # Tab pages +│ │ └── posts/ +│ │ └── [...slug].astro # Blog posts +│ ├── scripts/ # TypeScript modules +│ │ ├── main.ts +│ │ └── theme.ts +│ ├── styles/ # SCSS styles +│ │ ├── abstracts/ +│ │ ├── base/ +│ │ ├── components/ +│ │ ├── layout/ +│ │ ├── pages/ +│ │ └── themes/ +│ └── config.ts # Site configuration +├── astro.config.mjs # Astro configuration +├── tsconfig.json # TypeScript configuration +└── package.json +``` + +## Getting Started + +### Prerequisites + +- Node.js 18+ +- npm or yarn + +### Installation + +1. **Install dependencies:** + +```bash +npm install +``` + +2. **Configure your site:** + +Edit `src/config.ts` to customize your site settings: + +```typescript +export const SITE = { + title: 'Your Site Title', + tagline: 'Your tagline', + description: 'Site description', + url: 'https://your-site.com', + // ... more settings +}; +``` + +3. **Run the development server:** + +```bash +npm run dev +``` + +Visit `http://localhost:4321` to see your site! + +## Creating Content + +### Writing Posts + +Create a new Markdown file in `src/content/posts/`: + +```markdown +--- +title: Your Post Title +date: 2024-01-15T10:00:00+00:00 +categories: [Category1, Category2] +tags: [tag1, tag2, tag3] +description: Brief description of your post +pin: false +--- + +Your content here... +``` + +#### Frontmatter Options + +- `title` (required) - Post title +- `date` (required) - Publication date +- `categories` - Array of categories +- `tags` - Array of tags +- `description` - Post description for SEO and previews +- `image` - Featured image object + - `path` - Image path + - `alt` - Alt text + - `lqip` - Low Quality Image Placeholder +- `pin` - Pin post to top of home page +- `hidden` - Hide post from listings +- `toc` - Enable/disable table of contents +- `comments` - Enable/disable comments +- `author` - Author ID from authors.yml + +### Creating Tabs + +Add a new tab in `src/content/tabs/`: + +```markdown +--- +title: Tab Title +icon: fas fa-icon-name +order: 1 +--- + +Tab content... +``` + +## Customization + +### Styling + +Styles are organized in `src/styles/`: + +- `abstracts/` - Variables, mixins, functions +- `base/` - Base styles and typography +- `components/` - Component styles +- `layout/` - Layout styles +- `pages/` - Page-specific styles +- `themes/` - Light and dark themes + +### Configuration + +Main site configuration is in `src/config.ts`: + +```typescript +// Site settings +export const SITE = { ... }; + +// Social media +export const SOCIAL = { ... }; + +// Analytics +export const ANALYTICS = { ... }; + +// Comments +export const COMMENTS = { ... }; + +// Features +export const FEATURES = { ... }; +``` + +## Deployment + +### Build for Production + +```bash +npm run build +``` + +The built site will be in the `dist/` directory. + +### Preview Production Build + +```bash +npm run preview +``` + +### Deploy + +You can deploy to any static hosting service: + +- **Vercel**: Connect your repo for automatic deployments +- **Netlify**: Drag and drop `dist/` folder or connect repo +- **GitHub Pages**: Use GitHub Actions +- **Cloudflare Pages**: Connect your repo + +## Commands + +| Command | Action | +|---------|--------| +| `npm run dev` | Start development server | +| `npm run build` | Build production site | +| `npm run preview` | Preview production build | +| `npm run astro` | Run Astro CLI commands | +| `npm run lint:js` | Lint JavaScript/TypeScript | +| `npm run lint:scss` | Lint SCSS files | + +## Migration from Jekyll Chirpy + +### Key Differences + +1. **No Ruby/Jekyll** - Pure JavaScript/TypeScript ecosystem +2. **Content Collections** - Type-safe content with Astro's content collections +3. **Component-based** - Reusable Astro components instead of Liquid includes +4. **Faster Builds** - Significantly faster build times with Astro +5. **Modern Tooling** - Vite, TypeScript, and modern JavaScript + +### What's Migrated + +✅ Core layouts and design +✅ Responsive sidebar navigation +✅ Dark/Light theme toggle +✅ Post listings with pagination support +✅ Categories and tags +✅ SCSS styles +✅ 33 language locales +✅ SEO optimization +✅ Analytics integration (Google Analytics, etc.) +✅ Social media integration + +### What's Different + +- Search functionality (to be implemented) +- PWA features (to be implemented) +- Comment systems (to be integrated) +- Some Jekyll-specific features + +### Migration Steps + +If you're migrating from Jekyll Chirpy: + +1. Copy your posts from `_posts/` to `src/content/posts/` +2. Update post frontmatter (mostly compatible) +3. Copy custom tabs from `_tabs/` to `src/content/tabs/` +4. Update `src/config.ts` with your `_config.yml` settings +5. Copy any custom assets to `public/` + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## License + +This project is licensed under the MIT License - see the original [Jekyll Chirpy theme](https://github.com/cotes2020/jekyll-theme-chirpy) for details. + +## Credits + +- Original theme: [Jekyll Chirpy](https://github.com/cotes2020/jekyll-theme-chirpy) by [Cotes Chung](https://github.com/cotes2020) +- Built with [Astro](https://astro.build) +- Icons by [Font Awesome](https://fontawesome.com) +- Styling with [Bootstrap](https://getbootstrap.com) and custom SCSS + +## Support + +- [Documentation](https://astro.build) +- [Astro Discord](https://astro.build/chat) +- [GitHub Issues](https://github.com/your-repo/issues) + +--- + +Made using [Astro](https://astro.build) diff --git a/astro.config.mjs b/astro.config.mjs new file mode 100644 index 00000000000..0aeb70b8322 --- /dev/null +++ b/astro.config.mjs @@ -0,0 +1,26 @@ +import { defineConfig } from 'astro/config'; +import mdx from '@astrojs/mdx'; +import sitemap from '@astrojs/sitemap'; + +// https://astro.build/config +export default defineConfig({ + site: 'https://example.com', // Update this to your site URL + integrations: [ + mdx(), + sitemap(), + ], + markdown: { + syntaxHighlight: 'shiki', + shikiConfig: { + theme: 'github-dark', + wrap: true + } + }, + vite: { + resolve: { + alias: { + '@': '/src' + } + } + } +}); diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 00000000000..bc171e92175 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,75 @@ +# Netlify configuration for Astro Chirpy +# https://docs.netlify.com/configure-builds/file-based-configuration/ + +[build] + # Build command + command = "npm run build" + + # Directory to publish (Astro output) + publish = "dist" + + # Set Node.js version + [build.environment] + NODE_VERSION = "18" + +# Redirect rules +[[redirects]] + # SPA fallback (if needed for dynamic routes) + from = "/*" + to = "/404.html" + status = 404 + +# Headers for security and performance +[[headers]] + for = "/*" + [headers.values] + # Security headers + X-Frame-Options = "DENY" + X-Content-Type-Options = "nosniff" + X-XSS-Protection = "1; mode=block" + Referrer-Policy = "strict-origin-when-cross-origin" + + # Cache control for HTML (don't cache) + Cache-Control = "public, max-age=0, must-revalidate" + +[[headers]] + for = "/assets/*" + [headers.values] + # Cache static assets for 1 year + Cache-Control = "public, max-age=31536000, immutable" + +[[headers]] + for = "/*.js" + [headers.values] + # Cache JavaScript files + Cache-Control = "public, max-age=31536000, immutable" + +[[headers]] + for = "/*.css" + [headers.values] + # Cache CSS files + Cache-Control = "public, max-age=31536000, immutable" + +[[headers]] + for = "/fonts/*" + [headers.values] + # Cache fonts for 1 year + Cache-Control = "public, max-age=31536000, immutable" + +[[headers]] + for = "/images/*" + [headers.values] + # Cache images for 1 year + Cache-Control = "public, max-age=31536000, immutable" + +# Plugin configuration +[[plugins]] + # Netlify plugin for Astro (if available) + package = "@astrojs/netlify" + +# Development server settings +[dev] + command = "npm run dev" + port = 4321 + targetPort = 4321 + autoLaunch = false diff --git a/package.json b/package.json index 61e4a425a0b..160c33efb34 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "jekyll-theme-chirpy", - "version": "7.4.1", - "description": "A minimal, responsive, and feature-rich Jekyll theme for technical writing.", + "name": "astro-chirpy", + "version": "1.0.0", + "description": "A minimal, responsive, and feature-rich Astro theme for technical writing, migrated from Jekyll Chirpy.", "repository": { "type": "git", "url": "git+https://github.com/cotes2020/jekyll-theme-chirpy.git" @@ -15,21 +15,25 @@ "homepage": "https://github.com/cotes2020/jekyll-theme-chirpy/", "type": "module", "scripts": { - "build": "concurrently npm:build:*", - "build:css": "node purgecss.js", - "build:js": "rollup -c --bundleConfigAsCjs --environment BUILD:production", - "watch:js": "rollup -c --bundleConfigAsCjs -w", - "lint:js": "eslint", - "lint:scss": "stylelint _sass/**/*.scss", + "dev": "astro dev", + "start": "astro dev", + "build": "astro check && astro build", + "preview": "astro preview", + "astro": "astro", + "lint:js": "eslint src/**/*.{js,ts,astro}", + "lint:scss": "stylelint src/styles/**/*.scss", "lint:fix:scss": "npm run lint:scss -- --fix", - "test": "npm run lint:js && npm run lint:scss", - "prepare": "husky" + "test": "npm run lint:js && npm run lint:scss" }, "dependencies": { "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.8" }, "devDependencies": { + "@astrojs/check": "^0.9.5", + "@astrojs/mdx": "^4.3.10", + "@astrojs/rss": "^4.0.13", + "@astrojs/sitemap": "^3.6.0", "@babel/core": "^7.28.4", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-private-methods": "^7.27.1", @@ -42,6 +46,7 @@ "@semantic-release/changelog": "^6.0.3", "@semantic-release/exec": "^7.1.0", "@semantic-release/git": "^10.0.1", + "astro": "^5.15.4", "concurrently": "^9.2.1", "conventional-changelog-conventionalcommits": "^9.1.0", "eslint": "^9.38.0", @@ -49,9 +54,11 @@ "husky": "^9.1.7", "purgecss": "^7.0.2", "rollup": "^4.52.5", + "sass": "^1.93.3", "semantic-release": "^25.0.1", "stylelint": "^16.25.0", - "stylelint-config-standard-scss": "^16.0.0" + "stylelint-config-standard-scss": "^16.0.0", + "typescript": "^5.9.3" }, "prettier": { "trailingComma": "none" diff --git a/public/.nojekyll b/public/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/components/Footer.astro b/src/components/Footer.astro new file mode 100644 index 00000000000..6922ae371f7 --- /dev/null +++ b/src/components/Footer.astro @@ -0,0 +1,27 @@ +--- +import { SITE, SOCIAL } from '@/config'; + +export interface Props { + lang?: string; +} + +const { lang } = Astro.props; +const currentYear = new Date().getFullYear(); +--- + + diff --git a/src/components/Head.astro b/src/components/Head.astro new file mode 100644 index 00000000000..ce51198e242 --- /dev/null +++ b/src/components/Head.astro @@ -0,0 +1,107 @@ +--- +import { SITE, SOCIAL, ANALYTICS, FEATURES, WEBMASTER_VERIFICATIONS } from '@/config'; +import { ViewTransitions } from 'astro:transitions'; + +export interface Props { + title?: string; + description?: string; + image?: string; +} + +const { title, description, image } = Astro.props; + +const pageTitle = title ? `${title} | ${SITE.title}` : SITE.title; +const pageDescription = description || SITE.description; +const pageImage = image || SITE.social_preview_image; +const canonicalURL = new URL(Astro.url.pathname, SITE.url).href; + +// Handle image URL (add CDN if needed) +const getImageUrl = (src: string) => { + if (!src) return ''; + if (src.startsWith('http://') || src.startsWith('https://')) return src; + if (src.startsWith('/') && SITE.cdn) return `${SITE.cdn}${src}`; + return src; +}; + +const socialImage = getImageUrl(pageImage); +--- + + + + + + + + + + + + + + {pageTitle} + + + + + + + + + {socialImage && } + + + + + + + + {socialImage && } + + + {WEBMASTER_VERIFICATIONS.google && } + {WEBMASTER_VERIFICATIONS.bing && } + {WEBMASTER_VERIFICATIONS.yandex && } + {WEBMASTER_VERIFICATIONS.baidu && } + + + + + + + + + + + + + + + + + + + + {import.meta.env.PROD && ANALYTICS.google.id && ( + + + )} + + + + diff --git a/src/components/SearchResults.astro b/src/components/SearchResults.astro new file mode 100644 index 00000000000..d9023ce45ff --- /dev/null +++ b/src/components/SearchResults.astro @@ -0,0 +1,49 @@ +--- +export interface Props { + lang?: string; +} + +const { lang } = Astro.props; +--- + +
+
+
+ + +
+
+

Type to search...

+
+
+
+
+ + diff --git a/src/components/Sidebar.astro b/src/components/Sidebar.astro new file mode 100644 index 00000000000..1eb4c5d2610 --- /dev/null +++ b/src/components/Sidebar.astro @@ -0,0 +1,142 @@ +--- +import { SITE, FEATURES } from '@/config'; +import { CONTACT_LINKS } from '@/config-contact'; +import { getCollection } from 'astro:content'; + +export interface Props { + lang?: string; +} + +const { lang = SITE.lang } = Astro.props; + +// Get tabs from content collection +const tabs = await getCollection('tabs'); +const sortedTabs = tabs.sort((a, b) => a.data.order - b.data.order); + +// Get avatar URL +const getAvatarUrl = (src: string) => { + if (!src) return ''; + if (src.startsWith('http://') || src.startsWith('https://')) return src; + if (src.startsWith('/') && SITE.cdn) return `${SITE.cdn}${src}`; + return src; +}; + +const avatarUrl = getAvatarUrl(SITE.avatar); + +// Simple locale strings +const locales: Record = { + en: { + tabs: { + home: 'HOME' + } + } +}; + +const locale = locales[lang] || locales.en; + +// Process contact links +const contactLinks = CONTACT_LINKS.filter((entry: any) => { + if (entry.type === 'github') { + return SITE.github?.username; + } + if (entry.type === 'twitter') { + return SITE.twitter?.username; + } + if (entry.type === 'email') { + return SITE.social?.email; + } + return true; +}).map((entry: any) => { + let url = ''; + + if (entry.type === 'github') { + url = `https://github.com/${SITE.github?.username || ''}`; + } else if (entry.type === 'twitter') { + url = `https://twitter.com/${SITE.twitter?.username || ''}`; + } else if (entry.type === 'rss') { + url = '/rss.xml'; + } else { + url = entry.url || ''; + } + + return { ...entry, url }; +}); +--- + + + + + diff --git a/src/components/Topbar.astro b/src/components/Topbar.astro new file mode 100644 index 00000000000..fd3bda0af3d --- /dev/null +++ b/src/components/Topbar.astro @@ -0,0 +1,111 @@ +--- +export interface Props { + lang?: string; +} + +const { lang } = Astro.props; +const currentPath = Astro.url.pathname; +--- + +
+
+ + + + + +
+
+ + diff --git a/src/components/TrendingTags.astro b/src/components/TrendingTags.astro new file mode 100644 index 00000000000..2fd0d72d80d --- /dev/null +++ b/src/components/TrendingTags.astro @@ -0,0 +1,41 @@ +--- +import { getCollection } from 'astro:content'; + +export interface Props { + lang?: string; +} + +const { lang } = Astro.props; + +// Get all posts and count tags +const posts = await getCollection('posts'); +const tagCounts = new Map(); + +posts + .filter(post => !post.data.hidden) + .forEach(post => { + if (post.data.tags) { + post.data.tags.forEach(tag => { + tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1); + }); + } + }); + +// Sort by count and get top 10 +const trendingTags = Array.from(tagCounts.entries()) + .sort((a, b) => b[1] - a[1]) + .slice(0, 10); +--- + +{trendingTags.length > 0 && ( +
+

Trending Tags

+
+ {trendingTags.map(([tag, count]) => ( + + ))} +
+
+)} diff --git a/src/components/UpdateList.astro b/src/components/UpdateList.astro new file mode 100644 index 00000000000..8410c92aa99 --- /dev/null +++ b/src/components/UpdateList.astro @@ -0,0 +1,33 @@ +--- +import { getCollection } from 'astro:content'; + +export interface Props { + lang?: string; +} + +const { lang } = Astro.props; + +// Get recently updated posts +const posts = await getCollection('posts'); +const recentlyUpdated = posts + .filter(post => !post.data.hidden) + .sort((a, b) => { + const dateA = new Date(a.data.date); + const dateB = new Date(b.data.date); + return dateB.getTime() - dateA.getTime(); + }) + .slice(0, 5); +--- + +{recentlyUpdated.length > 0 && ( +
+

Recently Updated

+ +
+)} diff --git a/src/config-contact.ts b/src/config-contact.ts new file mode 100644 index 00000000000..cd7d026c932 --- /dev/null +++ b/src/config-contact.ts @@ -0,0 +1,31 @@ +// Contact links configuration +export const CONTACT_LINKS = [ + { + type: 'github', + icon: 'fab fa-github' + }, + { + type: 'twitter', + icon: 'fa-brands fa-x-twitter' + }, + { + type: 'email', + icon: 'fas fa-envelope' + }, + { + type: 'rss', + icon: 'fas fa-rss' + } +]; + +// You can add more social links here: +// { +// type: 'linkedin', +// icon: 'fab fa-linkedin', +// url: 'https://linkedin.com/in/username' +// }, +// { +// type: 'mastodon', +// icon: 'fab fa-mastodon', +// url: 'https://mastodon.social/@username' +// } diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 00000000000..3c0c731b007 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,113 @@ +export const SITE = { + title: 'Chirpy', + tagline: 'A text-focused Jekyll theme', + description: 'A minimal, responsive and feature-rich Jekyll theme for technical writing.', + url: 'https://example.com', // Update this to your site URL + baseurl: '', + lang: 'en', + timezone: 'Asia/Shanghai', + cdn: 'https://chirpy-img.netlify.app', + avatar: '/commons/avatar.jpg', + social_preview_image: '', + social: { + name: 'your_full_name', + email: 'example@domain.com', + }, + github: { + username: 'github_username', + }, + twitter: { + username: 'twitter_username', + }, +}; + +export const SOCIAL = { + name: 'your_full_name', + email: 'example@domain.com', + links: [ + 'https://twitter.com/username', + 'https://github.com/username', + ], +}; + +export const GITHUB = { + username: 'github_username', +}; + +export const TWITTER = { + username: 'twitter_username', +}; + +export const ANALYTICS = { + google: { + id: '', + }, + goatcounter: { + id: '', + }, + umami: { + id: '', + domain: '', + }, + matomo: { + id: '', + domain: '', + }, + cloudflare: { + id: '', + }, + fathom: { + id: '', + }, +}; + +export const PAGEVIEWS = { + provider: '', // 'goatcounter' +}; + +export const COMMENTS = { + provider: '', // 'disqus' | 'utterances' | 'giscus' + disqus: { + shortname: '', + }, + utterances: { + repo: '', + issue_term: '', + }, + giscus: { + repo: '', + repo_id: '', + category: '', + category_id: '', + mapping: 'pathname', + strict: '0', + input_position: 'bottom', + lang: 'en', + reactions_enabled: '1', + }, +}; + +export const FEATURES = { + toc: true, + theme_mode: '', // 'light' | 'dark' | '' (empty for system default with toggle) + pwa: { + enabled: true, + cache: { + enabled: true, + deny_paths: [], + }, + }, +}; + +export const PAGINATION = { + postsPerPage: 10, +}; + +export const WEBMASTER_VERIFICATIONS = { + google: '', + bing: '', + alexa: '', + yandex: '', + baidu: '', + facebook: '', +}; diff --git a/src/content/config.ts b/src/content/config.ts new file mode 100644 index 00000000000..484f51b3074 --- /dev/null +++ b/src/content/config.ts @@ -0,0 +1,38 @@ +import { defineCollection, z } from 'astro:content'; + +const posts = defineCollection({ + type: 'content', + schema: z.object({ + title: z.string(), + date: z.coerce.date(), + categories: z.array(z.string()).optional(), + tags: z.array(z.string()).optional(), + author: z.string().optional(), + description: z.string().optional(), + image: z.object({ + path: z.string(), + alt: z.string().optional(), + lqip: z.string().optional(), + no_bg: z.boolean().optional(), + }).optional(), + pin: z.boolean().optional(), + hidden: z.boolean().optional(), + toc: z.boolean().default(true), + comments: z.boolean().default(true), + math: z.boolean().optional(), + mermaid: z.boolean().optional(), + media_subpath: z.string().optional(), + render_with_liquid: z.boolean().optional(), + }), +}); + +const tabs = defineCollection({ + type: 'content', + schema: z.object({ + title: z.string(), + icon: z.string(), + order: z.number(), + }), +}); + +export const collections = { posts, tabs }; diff --git a/src/content/posts/welcome-to-astro-chirpy.md b/src/content/posts/welcome-to-astro-chirpy.md new file mode 100644 index 00000000000..a1f1e35afd8 --- /dev/null +++ b/src/content/posts/welcome-to-astro-chirpy.md @@ -0,0 +1,75 @@ +--- +title: Welcome to Astro Chirpy +date: 2024-01-15T10:00:00+00:00 +categories: [Blogging, Tutorial] +tags: [astro, chirpy, migration] +description: A minimal, responsive and feature-rich Astro theme for technical writing, migrated from Jekyll Chirpy. +pin: true +--- + +## Welcome! 🎉 + +This is **Astro Chirpy**, a migration of the popular Jekyll Chirpy theme to Astro. This theme maintains the clean, minimal design while leveraging Astro's modern features for blazing-fast performance. + +## Features + +### Performance +- ⚡ Lightning-fast page loads with Astro +- 🎯 Zero JS by default +- 📦 Optimized bundle sizes + +### Design +- 🎨 Clean, minimal design +- 🌓 Dark/Light mode toggle +- 📱 Fully responsive +- ♿ Accessible + +### Developer Experience +- 🚀 Easy to customize +- 📝 MDX support +- 🔧 TypeScript ready +- 🎭 Component-based architecture + +## Getting Started + +To create a new post, add a markdown file to `src/content/posts/` with the following frontmatter: + +```yaml +--- +title: Your Post Title +date: 2024-01-15T10:00:00+00:00 +categories: [Category1, Category2] +tags: [tag1, tag2] +description: Brief description of your post +--- +``` + +## Syntax Highlighting + +The theme supports syntax highlighting out of the box: + +```javascript +function greet(name) { + console.log(`Hello, ${name}!`); +} + +greet('Astro Chirpy'); +``` + +```python +def fibonacci(n): + if n <= 1: + return n + return fibonacci(n-1) + fibonacci(n-2) + +print(fibonacci(10)) +``` + +## Next Steps + +1. Customize your site configuration in `src/config.ts` +2. Add your own posts to `src/content/posts/` +3. Modify the tabs in `src/content/tabs/` +4. Update the styling in `src/styles/` + +Happy blogging! 📝 diff --git a/src/content/tabs/about.md b/src/content/tabs/about.md new file mode 100644 index 00000000000..771852d2a04 --- /dev/null +++ b/src/content/tabs/about.md @@ -0,0 +1,16 @@ +--- +title: About +icon: fas fa-info-circle +order: 1 +--- + +# About + +This is the about page. Replace this content with information about yourself or your blog. + +## Features + +- Built with Astro +- Migrated from Jekyll Chirpy theme +- Fast and modern +- SEO optimized diff --git a/src/content/tabs/archives.md b/src/content/tabs/archives.md new file mode 100644 index 00000000000..8d54db770a3 --- /dev/null +++ b/src/content/tabs/archives.md @@ -0,0 +1,11 @@ +--- +title: Archives +icon: fas fa-archive +order: 2 +--- + +# Archives + +Browse all posts by date. + + diff --git a/src/content/tabs/categories.md b/src/content/tabs/categories.md new file mode 100644 index 00000000000..218f0de916e --- /dev/null +++ b/src/content/tabs/categories.md @@ -0,0 +1,11 @@ +--- +title: Categories +icon: fas fa-folder-open +order: 3 +--- + +# Categories + +Browse posts by category. + + diff --git a/src/content/tabs/tags.md b/src/content/tabs/tags.md new file mode 100644 index 00000000000..95c60f39743 --- /dev/null +++ b/src/content/tabs/tags.md @@ -0,0 +1,11 @@ +--- +title: Tags +icon: fas fa-tags +order: 4 +--- + +# Tags + +Browse posts by tags. + + diff --git a/src/data/authors.yml b/src/data/authors.yml new file mode 100644 index 00000000000..f012012135a --- /dev/null +++ b/src/data/authors.yml @@ -0,0 +1,17 @@ +## Template › https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/advanced-usage.md#setting-author-url +# ------------------------------------- +# {author_id}: +# name: {full name} +# twitter: {twitter_of_author} +# url: {homepage_of_author} +# ------------------------------------- + +cotes: + name: Cotes Chung + twitter: cotes2020 + url: https://github.com/cotes2020/ + +sille_bille: + name: Dinesh Prasanth Moluguwan Krishnamoorthy + twitter: dinesh_MKD + url: https://github.com/SilleBille/ diff --git a/src/data/contact.yml b/src/data/contact.yml new file mode 100644 index 00000000000..ed40acb7e97 --- /dev/null +++ b/src/data/contact.yml @@ -0,0 +1,40 @@ +# The contact options. + +- type: github + icon: "fab fa-github" + +- type: twitter + icon: "fa-brands fa-x-twitter" + +- type: email + icon: "fas fa-envelope" + noblank: true # open link in current tab + +- type: rss + icon: "fas fa-rss" + noblank: true +# Uncomment and complete the url below to enable more contact options +# +# - type: mastodon +# icon: 'fab fa-mastodon' # icons powered by +# url: '' # Fill with your Mastodon account page, rel="me" will be applied for verification +# +# - type: linkedin +# icon: 'fab fa-linkedin' # icons powered by +# url: '' # Fill with your Linkedin homepage +# +# - type: stack-overflow +# icon: 'fab fa-stack-overflow' +# url: '' # Fill with your stackoverflow homepage +# +# - type: bluesky +# icon: 'fa-brands fa-bluesky' +# url: '' # Fill with your Bluesky profile link +# +# - type: reddit +# icon: 'fa-brands fa-reddit' +# url: '' # Fill with your Reddit profile link +# +# - type: threads +# icon: 'fa-brands fa-threads' +# url: '' # Fill with your Threads profile link diff --git a/src/data/locales/ar.yml b/src/data/locales/ar.yml new file mode 100644 index 00000000000..a79e020091e --- /dev/null +++ b/src/data/locales/ar.yml @@ -0,0 +1,91 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: منشور + category: فئة + tag: وسم + +# The tabs of sidebar +tabs: + # format: : + home: الرئيسية + categories: الفئات + tags: الوسوم + archives: الأرشيف + about: حول + +# the text displayed in the search bar & search results +search: + hint: بحث + cancel: إلغاء + no_results: نأسف! لا يوجد نتائج. + +panel: + lastmod: المحدثة مؤخرا + trending_tags: الوسوم الشائعة + toc: محتويات + +copyright: + # Shown at the bottom of the post + license: + template: هذا المنشور تحت ترخيص :LICENSE_NAME بواسطة المؤلف. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: بعض الحقوق محفوظة. + verbose: >- + ما لم يذكر خلاف ذلك ، يتم ترخيص منشورات المدونة على هذا الموقع + بموجب ترخيص Creative Commons Attribution 4.0 International (CC BY 4.0) من قبل المؤلف. + +meta: باستخدام :PLATFORM السمة :THEME + +not_found: + statement: عذرا, الرابط التالي غير صالح أو انه يشير إلى صفحة غير موجودة. + +notification: + update_found: يتوفر اصدار جديد للمحتوى. + update: تحديث + +# ----- Posts related labels ----- + +post: + written_by: بواسطة + posted: نشّر + updated: حدّث + words: كلمات + pageview_measure: مشاهدات + read_time: + unit: دقيقة + prompt: قراءة + relate_posts: إقرأ المزيد + share: شارك + button: + next: الأجدد + previous: الأقدم + copy_code: + succeed: تم النسخ! + share_link: + title: أنسخ الرابط + succeed: تم نسخ الرابط بنجاح! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: فئة + plural: فئات + post_measure: + singular: منشور + plural: منشورات diff --git a/src/data/locales/bg-BG.yml b/src/data/locales/bg-BG.yml new file mode 100644 index 00000000000..3fb060fdae3 --- /dev/null +++ b/src/data/locales/bg-BG.yml @@ -0,0 +1,81 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Публикация + category: Категория + tag: Таг + +# The tabs of sidebar +tabs: + # format: : + home: Начало + categories: Категории + tags: Тагове + archives: Архив + about: За мен + +# the text displayed in the search bar & search results +search: + hint: търси + cancel: Отмени + no_results: Упс! Не са намерени резултати. + +panel: + lastmod: Наскоро обновени + trending_tags: Популярни тагове + toc: Съдържание + +copyright: + # Shown at the bottom of the post + license: + template: Тази публикация е лицензирана под :LICENSE_NAME от автора. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Някои права запазени. + verbose: >- + Освен ако не е посочено друго, публикациите в блога на този сайт са лицензирани + под лиценза Creative Commons Attribution 4.0 (CC BY 4.0) от автора. + +meta: Създадено чрез :PLATFORM и :THEME тема + +not_found: + statement: Съжалявам, но на този URL адрес няма налично съдържание. + +notification: + update_found: Налична е нова версия на съдържанието. + update: Обнови + +# ----- Posts related labels ----- + +post: + written_by: Автор + posted: Публикувана + updated: Обновена + words: думи + pageview_measure: преглеждания + read_time: + unit: мин + prompt: четиво + relate_posts: Още за четене + share: Споделете + button: + next: По-нови + previous: По-стари + copy_code: + succeed: Копирано! + share_link: + title: Копирай линк + succeed: Линкът е копиран успешно! + +# categories page +categories: + category_measure: + singular: категория + plural: категории + post_measure: + singular: публикация + plural: публикации diff --git a/src/data/locales/ca-ES.yml b/src/data/locales/ca-ES.yml new file mode 100644 index 00000000000..e3d5b39ceae --- /dev/null +++ b/src/data/locales/ca-ES.yml @@ -0,0 +1,84 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Entrada + category: Categoria + tag: Etiqueta + +# The tabs of sidebar +tabs: + # format: : + home: Inici + categories: Categories + tags: Etiquetes + archives: Arxiu + about: Sobre + +# the text displayed in the search bar & search results +search: + hint: Cercar + cancel: Cancel·lar + no_results: Ups! No s'han trobat resultats. + +panel: + lastmod: Actualitzat recentment + trending_tags: Etiquetes populars + toc: Taula de continguts + +copyright: + # Shown at the bottom of the post + license: + template: Aquesta entrada està llicenciada sota :LICENSE_NAME per l'autor. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Alguns drets reservats. + verbose: >- + Excepte que s'indiqui explícitament, les entrades d'aquest blog estan llicenciades + sota la llicència Creative Commons Attribution 4.0 International (CC BY 4.0) per l'autor. + +meta: Fet amb :PLATFORM utilitzant el tema :THEME + +not_found: + statement: Ho sentim, hem perdut aquesta URL o apunta a alguna cosa que no existeix. + +notification: + update_found: Hi ha una nova versió de contingut disponible. + update: Actualitzar + +# ----- Posts related labels ----- + +post: + written_by: Per + posted: Publicat + updated: Actualitzat + words: paraules + pageview_measure: visites + read_time: + unit: min + prompt: " de lectura" + relate_posts: Entrades relacionades + share: Compartir + button: + next: Següent + previous: Anterior + copy_code: + succeed: Copiat! + share_link: + title: Copiar enllaç + succeed: Enllaç copiat! + +# Date time format. +# See: , +df: + post: + strftime: "%Y/%m/%d" + dayjs: "YYYY/MM/DD" + +# categories page +categories: + category_measure: categories + post_measure: entrades diff --git a/src/data/locales/cs-CZ.yml b/src/data/locales/cs-CZ.yml new file mode 100644 index 00000000000..cf93f614a6b --- /dev/null +++ b/src/data/locales/cs-CZ.yml @@ -0,0 +1,89 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Příspěvek + category: Kategorie + tag: Štítek + +# The tabs of sidebar +tabs: + # format: : + home: Domů + categories: Kategorie + tags: Štítky + archives: Archivy + about: O mně + +# the text displayed in the search bar & search results +search: + hint: hledat + cancel: Zrušit + no_results: Ups! Žádný výsledek nenalezen. + +panel: + lastmod: Nedávno aktualizováno + trending_tags: Trendy štítky + toc: Obsah + +copyright: + # Shown at the bottom of the post + license: + template: Tento příspěvek je licencován pod :LICENSE_NAME autorem. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Některá práva vyhrazena. + verbose: >- + Pokud není uvedeno jinak, jsou příspěvky na tomto webu licencovány + pod licencí Creative Commons Attribution 4.0 International (CC BY 4.0) Licence autora. + +meta: Použití :PLATFORM s motivem :THEME + +not_found: + statement: Omlouváme se, adresu URL jsme špatně umístili nebo odkazuje na něco, co neexistuje. + +notification: + update_found: Je k dispozici nová verze obsahu. + update: Aktualizace + +# ----- Posts related labels ----- + +post: + written_by: Od + posted: Zveřejněno + updated: Aktualizováno + words: slova + pageview_measure: zhlednutí + read_time: + unit: minut + prompt: čtení + relate_posts: Další čtení + share: Sdílet + button: + next: Novější + previous: Starší + copy_code: + succeed: Zkopírováno! + share_link: + title: Kopírovat odkaz + succeed: Zkopírováno! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: kategorie + post_measure: + singular: příspěvěk + plural: příspěvky diff --git a/src/data/locales/da-DK.yml b/src/data/locales/da-DK.yml new file mode 100644 index 00000000000..4b41fb389ea --- /dev/null +++ b/src/data/locales/da-DK.yml @@ -0,0 +1,86 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Opslag + category: Kategori + tag: Tag + +# The tabs of sidebar +tabs: + # format: : + home: Hjem + categories: Kategorier + tags: Tags + archives: Arkiv + about: Om siden + +# the text displayed in the search bar & search results +search: + hint: søg + cancel: Afbryd + no_results: Ups! Ingen resultater fundet. + +panel: + lastmod: Senest opdateret + trending_tags: Populære tags + toc: Indhold + +copyright: + # Shown at the bottom of the post + license: + template: Dette opslag er licenseret under :LICENSE_NAME af forfatteren. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Nogle rettigheder forbeholdes. + verbose: >- + Medmindre andet er angivet, er opslag på denne side beskyttet + under Creative Commons Attribution 4.0 International (CC BY 4.0) licensen af forfatteren. + +# meta: Using the :THEME theme for :PLATFORM. + +not_found: + statement: Beklager, vi har malpaceret denne URL, eller den peger på et sted, som ikke findes. + +notification: + update_found: En ny version af indholdet er fundet! + update: Opdater + +# ----- Posts related labels ----- + +post: + written_by: Af + posted: Udgivet + updated: Opdateret + words: ord + pageview_measure: visninger + read_time: + unit: min + prompt: læsetid + relate_posts: Læs videre + share: Del + button: + next: Nyere + previous: Ældre + copy_code: + succeed: Kopieret! + share_link: + title: Kopier link + succeed: Link kopieret! + +# Date time format. +# See: , +df: + post: + strftime: "%Y/%m/%d" + dayjs: "YYYY/MM/DD" + +# categories page +categories: + category_measure: + singular: kategori + plural: kategorier + post_measure: opslag diff --git a/src/data/locales/de-DE.yml b/src/data/locales/de-DE.yml new file mode 100644 index 00000000000..6c9d91d469b --- /dev/null +++ b/src/data/locales/de-DE.yml @@ -0,0 +1,87 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Eintrag + category: Kategorie + tag: Tag + +# The tabs of sidebar +tabs: + # format: : + home: Startseite + categories: Kategorien + tags: Tags + archives: Archiv + about: Über + +# the text displayed in the search bar & search results +search: + hint: Suche + cancel: Abbrechen + no_results: Ups! Keine Einträge gefunden. + +panel: + lastmod: Kürzlich aktualisiert + trending_tags: Beliebte Tags + toc: Inhalt + +copyright: + # Shown at the bottom of the post + license: + template: Dieser Eintrag ist vom Autor unter :LICENSE_NAME lizensiert. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Einige Rechte vorbehalten. + verbose: >- + Alle Einträge auf dieser Seite stehen, soweit nicht anders angegeben, unter der Lizenz Creative Commons Attribution 4.0 (CC BY 4.0). + +meta: Powered by :PLATFORM with :THEME theme + +not_found: + statement: Entschuldigung, dieser Link verweist auf keine vorhandene Ressource. + +notification: + update_found: Eine neue Version ist verfügbar. + update: Neue Version + +# ----- Posts related labels ----- + +post: + written_by: Von + posted: Veröffentlicht + updated: Aktualisiert + words: Wörter + pageview_measure: Aufrufe + read_time: + unit: Minuten + prompt: Lesezeit + relate_posts: Weiterlesen + share: Teilen + button: + next: Nächster Eintrag + previous: Eintrag vorher + copy_code: + succeed: Kopiert! + share_link: + title: Link kopieren + succeed: Link erfolgreich kopiert! + +# Date time format. +# See: , +df: + post: + strftime: "%d.%m.%Y" + dayjs: "DD.MM.YYYY" + +# categories page +categories: + category_measure: + singular: Kategorie + plural: Kategorien + post_measure: + singular: Eintrag + plural: Einträge diff --git "a/src/data/locales/dv\342\200\221MV.yml" "b/src/data/locales/dv\342\200\221MV.yml" new file mode 100644 index 00000000000..680ca1f8b4c --- /dev/null +++ "b/src/data/locales/dv\342\200\221MV.yml" @@ -0,0 +1,90 @@ +# The layout text of site in Dhivehi (Maldives) + +# ----- Commons label ----- + +layout: + post: ޕޯސްޓް + category: ނަތީޖާ + tag: ޓެގް + +# The tabs of sidebar +tabs: + # format: : + home: ހުންނަ + categories: ނަތީޖާތައް + tags: ޓެގްތައް + archives: އާރޗިވްސް + about: އިންސާން + +# the text displayed in the search bar & search results +search: + hint: ސާރޗް + cancel: ކެންސަލް + no_results: އޮޕްސް! އެއްވެސް ނުފެނުނީ. + +panel: + lastmod: އާދަމާ އޮޕްޑޭޓްކުރި + trending_tags: މަރާހު ޓެގްތައް + toc: ކޮންޓެންސް + +copyright: + # Shown at the bottom of the post + license: + template: މި ޕޯސްޓް :LICENSE_NAME އިން ލައިސަންސްކުރާ ނުވަތަ މުޤައްރާއަށް. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: އެކީ ބާރަށް ހުށަހަޅާ. + verbose: >- + އަދި އެ ރަނގަޅުގައި ނުލާހެވެސް، މި ސައިޓުގެ ޕޯސްޓްތައް + މުޤައްރާއަށް Creative Commons Attribution 4.0 International (CC BY 4.0) ލައިސަންސްކުރަނީ. + +meta: :PLATFORM އަށް :THEME ތީމް ބަލާލާށެވެ. + +not_found: + statement: ސޯރީ، މި ޔޫ.އާރއެލް މަށެވެއްނެ ނުވަތަ އެކަމެއް ނުވެއެވެ. + +notification: + update_found: ޔޫ ވާރޝަން ހުރިހާ. + update: އޮޕްޑޭޓް + +# ----- Posts related labels ----- + +post: + written_by: ލެކްއޯލް + posted: ޕޯސްޓްކުރެވި + updated: އޮޕްޑޭޓްކުރެވި + words: ބަސް + pageview_measure: ބަނޑުކުރާ + read_time: + unit: މިނެޓް + prompt: އިސްކާރު + relate_posts: އެއްޗެހި ފަހުރަށްދަން + share: ސެއާރް + button: + next: އަދާވަނަ + previous: ކޮނޯނި + copy_code: + succeed: ކޮޕީ ކުރެވި! + share_link: + title: ލިންކް ކޮޕީ ކުރު + succeed: ލިންކް ހަދަންކުރެވި! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +categories: + category_measure: + singular: ނަތީޖާ + plural: ނަތީޖާތައް + post_measure: + singular: ޕޯސްޓް + plural: ޕޯސްޓްތައް diff --git a/src/data/locales/el-GR.yml b/src/data/locales/el-GR.yml new file mode 100644 index 00000000000..b6d2a866379 --- /dev/null +++ b/src/data/locales/el-GR.yml @@ -0,0 +1,91 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Δημοσίευση + category: Κατηγορία + tag: Ετικέτα + +# The tabs of sidebar +tabs: + # format: : + home: Home + categories: Κατηγορίες + tags: Ετικέτες + archives: Αρχεία + about: Σχετικά + +# the text displayed in the search bar & search results +search: + hint: αναζήτηση + cancel: Ακύρωση + no_results: Oops! Κανένα αποτέλεσμα δεν βρέθηκε. + +panel: + lastmod: Σχετικά ενημερωμένα + trending_tags: Ετικέτες τάσης + toc: Περιεχόμενα + +copyright: + # Shown at the bottom of the post + license: + template: Η δημοσίευση αυτή βρίσκεται υπο την άδεια :LICENSE_NAME Greekforce1821. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Ορισμένα δικαιώματα reserved. + verbose: >- + Εκτός αλλού ή οπουδήποτε αλλού, τα blog posts σε αυτήν την σελίδα βρίσκονται υπο την άδεια + Creative Commons Attribution 4.0 International (CC BY 4.0) του δημιουργού. + +meta: Αξιοποιώντας την :PLATFORM theme :THEME + +not_found: + statement: Συγνώμη, έχουμε τοποθετήσει λάθος αυτήν την διεύθυνση URL ή υποδεικνύει κάτι που δεν υπάρχει. + +notification: + update_found: Υπάρχει διαθέσιμη μια νέα έκδοση του περιεχομένου. + update: Ενημέρωση + +# ----- Posts related labels ----- + +post: + written_by: Από + posted: Δημοσιεύθηκε + updated: Ενημερώθηκε + words: λέξεις + pageview_measure: προβολές + read_time: + unit: Λεπτά + prompt: διαβάσματος + relate_posts: Περισσότερα + share: Κοινοποιήστε + button: + next: Νεότερα + previous: Παλαιότερα + copy_code: + succeed: Αντιγράφθηκε! + share_link: + title: Αντιγραφή συνδέσμου + succeed: Η διεύθυνση αντιγράφθηκε με επιτυχία! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: Κατηγορία + plural: Κατηγορίες + post_measure: + singular: Δημοσίευση + plural: Δημοσιεύσεις diff --git a/src/data/locales/en.yml b/src/data/locales/en.yml new file mode 100644 index 00000000000..152d090ac21 --- /dev/null +++ b/src/data/locales/en.yml @@ -0,0 +1,91 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Post + category: Category + tag: Tag + +# The tabs of sidebar +tabs: + # format: : + home: Home + categories: Categories + tags: Tags + archives: Archives + about: About + +# the text displayed in the search bar & search results +search: + hint: search + cancel: Cancel + no_results: Oops! No results found. + +panel: + lastmod: Recently Updated + trending_tags: Trending Tags + toc: Contents + +copyright: + # Shown at the bottom of the post + license: + template: This post is licensed under :LICENSE_NAME by the author. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Some rights reserved. + verbose: >- + Except where otherwise noted, the blog posts on this site are licensed + under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author. + +meta: Using the :THEME theme for :PLATFORM. + +not_found: + statement: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. + +notification: + update_found: A new version of content is available. + update: Update + +# ----- Posts related labels ----- + +post: + written_by: By + posted: Posted + updated: Updated + words: words + pageview_measure: views + read_time: + unit: min + prompt: read + relate_posts: Further Reading + share: Share + button: + next: Newer + previous: Older + copy_code: + succeed: Copied! + share_link: + title: Copy link + succeed: Link copied successfully! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: category + plural: categories + post_measure: + singular: post + plural: posts diff --git a/src/data/locales/es-ES.yml b/src/data/locales/es-ES.yml new file mode 100644 index 00000000000..8f8d149ea3e --- /dev/null +++ b/src/data/locales/es-ES.yml @@ -0,0 +1,77 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Entrada + category: Categoría + tag: Etiqueta + +# The tabs of sidebar +tabs: + # format: : + home: Inicio + categories: Categorías + tags: Etiquetas + archives: Archivo + about: Acerca de + +# the text displayed in the search bar & search results +search: + hint: Buscar + cancel: Cancelar + no_results: ¡Oops! No se encuentran resultados. + +panel: + lastmod: Actualizado recientemente + trending_tags: Etiquetas populares + toc: Contenido + +copyright: + # Shown at the bottom of the post + license: + template: Esta entrada está licenciada bajo :LICENSE_NAME por el autor. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Algunos derechos reservados. + verbose: >- + Salvo que se indique explícitamente, las entradas de este blog están licenciadas + bajo la Creative Commons Attribution 4.0 International (CC BY 4.0) License por el autor. + +meta: Hecho con :PLATFORM usando el tema :THEME + +not_found: + statement: Lo sentimos, hemos perdido esa URL o apunta a algo que no existe. + +notification: + update_found: Hay una nueva versión de contenido disponible. + update: Actualizar + +# ----- Posts related labels ----- + +post: + written_by: Por + posted: Publicado + updated: Actualizado + words: palabras + pageview_measure: visitas + read_time: + unit: min + prompt: " de lectura" + relate_posts: Lecturas adicionales + share: Compartir + button: + next: Nuevo + previous: Anterior + copy_code: + succeed: ¡Copiado! + share_link: + title: Copiar enlace + succeed: ¡Enlace copiado! + +# categories page +categories: + category_measure: categorias + post_measure: entradas diff --git a/src/data/locales/fa-IR.yml b/src/data/locales/fa-IR.yml new file mode 100644 index 00000000000..7a33deb1209 --- /dev/null +++ b/src/data/locales/fa-IR.yml @@ -0,0 +1,91 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: پست + category: دسته‌بندی + tag: برچسب + +# The tabs of sidebar +tabs: + # format: : + home: خانه + categories: دسته‌بندی‌ها + tags: برچسب‌ها + archives: آرشیو + about: درباره + +# the text displayed in the search bar & search results +search: + hint: جستجو + cancel: لغو + no_results: متأسفیم! هیچ نتیجه‌ای یافت نشد. + +panel: + lastmod: آخرین به‌روزرسانی + trending_tags: برچسب‌های پرطرفدار + toc: فهرست مطالب + +copyright: + # Shown at the bottom of the post + license: + template: این پست تحت مجوز :LICENSE_NAME توسط نویسنده منتشر شده است. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: برخی حقوق محفوظ است. + verbose: >- + به‌جز مواردی که خلاف آن ذکر شده باشد، محتوای پست‌های این وبلاگ + تحت مجوز Creative Commons Attribution 4.0 International (CC BY 4.0) توسط نویسنده منتشر شده‌اند. + +meta: با استفاده از قالب :THEME برای :PLATFORM + +not_found: + statement: متأسفیم، لینک زیر معتبر نیست یا به صفحه‌ای که وجود ندارد اشاره می‌کند. + +notification: + update_found: نسخه جدیدی از محتوا موجود است. + update: به‌روزرسانی + +# ----- Posts related labels ----- + +post: + written_by: نوشته شده توسط + posted: منتشر شده + updated: به‌روزرسانی شده + words: کلمه + pageview_measure: بازدید + read_time: + unit: "دقیقه " + prompt: " زمان مطالعه" + relate_posts: بیشتر بخوانید + share: اشتراک‌گذاری + button: + next: جدیدتر + previous: قدیمی‌تر + copy_code: + succeed: کپی شد! + share_link: + title: کپی لینک + succeed: لینک با موفقیت کپی شد! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: دسته‌بندی + plural: دسته‌بندی‌ + post_measure: + singular: پست + plural: پست‌ diff --git a/src/data/locales/fi-FI.yml b/src/data/locales/fi-FI.yml new file mode 100644 index 00000000000..60c9862054f --- /dev/null +++ b/src/data/locales/fi-FI.yml @@ -0,0 +1,90 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Julkaisu + category: Kateogoria + tag: Tagi + +# The tabs of sidebar +tabs: + # format: : + home: Koti + categories: Kateogoriat + tags: Tagit + archives: Arkistot + about: Minusta + +# the text displayed in the search bar & search results +search: + hint: etsi + cancel: Peruuta + no_results: Hups! Ei tuloksia. + +panel: + lastmod: Viimeksi päivitetty + trending_tags: Trendaavat tagit + toc: Sisältö + +copyright: + # Shown at the bottom of the post + license: + template: Tämä julkaisu on lisenssoitu :LICENSE_NAME julkaisijan toimesta. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Jotkut oikeudet pidätetään. + verbose: >- + Paitsi jos erikseen mainitaan on kaikki sisältö Creative Commons Attribution 4.0 International (CC BY 4.0) Lisensoitu kirjoittajan toimesta. + +meta: Käytetään :PLATFORM iä Teema :THEME + +not_found: + statement: Valitettavasti tällä URL-osoitteella ei ole saatavilla sisältöä. + +notification: + update_found: Uusi versio sisällöstä on saatavilla. + update: Päivitä + +# ----- Posts related labels ----- + +post: + written_by: Kirjoittaja + posted: Julkaistu + updated: Päivitetty + words: sanaa + pageview_measure: katselukertoja + read_time: + unit: minuuttia + prompt: lukea + relate_posts: Jatka lukemista + share: Jaa + button: + next: Uudempi + previous: Vanhempi + copy_code: + succeed: Kopiotu! + share_link: + title: Kopioi linkki + succeed: Linkki kopioitu onnistuneesti! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: kategoria + plural: kategoriat + post_measure: + singular: julkaisu + plural: julkaisut diff --git a/src/data/locales/fr-FR.yml b/src/data/locales/fr-FR.yml new file mode 100644 index 00000000000..dce83c9f4e4 --- /dev/null +++ b/src/data/locales/fr-FR.yml @@ -0,0 +1,77 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Post + category: Catégorie + tag: Tag + +# The tabs of sidebar +tabs: + # format: : + home: Accueil + categories: Catégories + tags: Tags + archives: Archives + about: À propos + +# the text displayed in the search bar & search results +search: + hint: recherche + cancel: Annuler + no_results: Oups ! Aucun résultat trouvé. + +panel: + lastmod: Récemment mis à jour + trending_tags: Tags tendance + toc: Contenu + +copyright: + # Shown at the bottom of the post + license: + template: Cet article est sous licence :LICENSE_NAME par l'auteur. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/deed.fr + + # Displayed in the footer + brief: Certains droits réservés. + verbose: >- + Sauf mention contraire, les articles de ce site sont publiés + sous la licence Creative Commons Attribution 4.0 International (CC BY 4.0) par l'auteur. + +meta: Propulsé par :PLATFORM avec le thème :THEME + +not_found: + statement: Désolé, nous avons égaré cette URL ou elle pointe vers quelque chose qui n'existe pas. + +notification: + update_found: Une nouvelle version du contenu est disponible. + update: Mise à jour + +# ----- Posts related labels ----- + +post: + written_by: Par + posted: Posté + updated: Mis à jour + words: mots + pageview_measure: vues + read_time: + unit: min + prompt: lire + relate_posts: Autres lectures + share: Partager + button: + next: Plus récent + previous: Plus ancien + copy_code: + succeed: Copié ! + share_link: + title: Copier le lien + succeed: Lien copié avec succès ! + +# categories page +categories: + category_measure: catégories + post_measure: posts diff --git a/src/data/locales/hu-HU.yml b/src/data/locales/hu-HU.yml new file mode 100644 index 00000000000..be3a31b7d63 --- /dev/null +++ b/src/data/locales/hu-HU.yml @@ -0,0 +1,92 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Bejegyzés + category: Kategória + tag: Címke + +# The tabs of sidebar +tabs: + # format: : + home: Kezdőlap + categories: Kategóriák + tags: Címkék + archives: Archívum + about: Bemutatkozás + +# the text displayed in the search bar & search results +search: + hint: keresés + cancel: Mégse + no_results: Hoppá! Nincs találat a keresésre. + +panel: + lastmod: Legutóbb frissítve + trending_tags: Népszerű Címkék + toc: Tartalom + +copyright: + # Shown at the bottom of the post + license: + template: A bejegyzést a szerző :LICENSE_NAME licenc alatt engedélyezte. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Néhány jog fenntartva. + verbose: >- + Az oldalon található tartalmak + Creative Commons Attribution 4.0 International (CC BY 4.0) licenccel rendelkeznek, + hacsak másképp nincs jelezve. + +meta: Készítve :THEME témával a :PLATFORM platformra. + +not_found: + statement: Sajnáljuk, az URL-t rosszul helyeztük el, vagy valami nem létezőre mutat. + +notification: + update_found: Elérhető a tartalom új verziója. + update: Frissítés + +# ----- Posts related labels ----- + +post: + written_by: Szerző + posted: Létrehozva + updated: Frissítve + words: szó + pageview_measure: látogató + read_time: + unit: perc + prompt: elolvasni + relate_posts: További olvasnivaló + share: Megosztás + button: + next: Újabb + previous: Régebbi + copy_code: + succeed: Másolva! + share_link: + title: Link másolása + succeed: Link sikeresen másolva! + +# Date time format. +# See: , +df: + post: + strftime: "%Y. %B. %e." + dayjs: "YYYY. MMMM D." + archives: + strftime: "%B" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: kategória + plural: kategória + post_measure: + singular: bejegyzés + plural: bejegyzés diff --git a/src/data/locales/id-ID.yml b/src/data/locales/id-ID.yml new file mode 100644 index 00000000000..d772ec34f1a --- /dev/null +++ b/src/data/locales/id-ID.yml @@ -0,0 +1,77 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Postingan + category: Kategori + tag: Tagar + +# The tabs of sidebar +tabs: + # format: : + home: Beranda + categories: Kategori + tags: Tagar + archives: Arsip + about: Tentang + +# the text displayed in the search bar & search results +search: + hint: Cari + cancel: Batal + no_results: Ups! Tidak ada hasil yang ditemukan. + +panel: + lastmod: Postingan Terbaru + trending_tags: Tagar Terpopuler + toc: Konten + +copyright: + # Shown at the bottom of the post + license: + template: Postingan ini dilisensikan di bawah :LICENSE_NAME oleh penulis. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Sebagian konten dilindungi. + verbose: >- + Kecuali jika dinyatakan, Postingan blog di situs ini dilisensikan + di bawah Lisensi Creative Commons Attribution 4.0 International (CC BY 4.0) oleh penulis. + +meta: Didukung oleh :PLATFORM dengan tema :THEME + +not_found: + statement: Maaf, kami gagal menemukan URL itu atau memang mengarah ke sesuatu yang tidak ada. + +notification: + update_found: Versi konten baru tersedia. + update: Perbarui + +# ----- Posts related labels ----- + +post: + written_by: Oleh + posted: Diterbitkan + updated: Diperbarui + words: kata + pageview_measure: dilihat + read_time: + unit: menit + prompt: baca + relate_posts: Postingan Lainya + share: Bagikan + button: + next: Terbaru + previous: Terlama + copy_code: + succeed: Disalin! + share_link: + title: Salin tautan + succeed: Tautan berhasil disalin! + +# categories page +categories: + category_measure: kategori + post_measure: Postingan diff --git a/src/data/locales/it-IT.yml b/src/data/locales/it-IT.yml new file mode 100644 index 00000000000..c8dfb447c2c --- /dev/null +++ b/src/data/locales/it-IT.yml @@ -0,0 +1,90 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Post + category: Categoria + tag: Tag + +# The tabs of sidebar +tabs: + # format: : + home: Pagina principale + categories: Categorie + tags: Tags + archives: Archivio + about: Informazioni + +# the text displayed in the search bar & search results +search: + hint: ricerca + cancel: Cancella + no_results: Oops! La ricerca non ha fornito risultati. + +panel: + lastmod: Aggiornati recentemente + trending_tags: Tags più cliccati + toc: Contenuti + +copyright: + # Shown at the bottom of the post + license: + template: Questo post è sotto licenza :LICENSE_NAME a nome dell'autore. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Alcuni diritti riservati. + verbose: >- + Eccetto quando esplicitamente menzionato, i post di questo blog sono da ritenersi sotto + i termini di licenza Creative Commons Attribution 4.0 International (CC BY 4.0). + +meta: Servizio offerto da :PLATFORM con tema :THEME +not_found: + statement: Ci scusiamo, non è stato possibile trovare l'URL in questione. Potrebbe puntare ad una pagina non esistente. + +notification: + update_found: Nuova versione del contenuto disponibile. + update: Aggiornamento + +# ----- Posts related labels ----- + +post: + written_by: Da + posted: Postato + updated: Aggiornato + words: parole + pageview_measure: visioni + read_time: + unit: min + prompt: lettura + relate_posts: Continua a leggere + share: Condividi + button: + next: Più recenti + previous: Meno recenti + copy_code: + succeed: Copiato! + share_link: + title: Copia link + succeed: Link copiato con successo! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: categoria + plural: categorie + post_measure: + singular: post + plural: posts diff --git a/src/data/locales/ja-JP.yml b/src/data/locales/ja-JP.yml new file mode 100644 index 00000000000..8e016b997c4 --- /dev/null +++ b/src/data/locales/ja-JP.yml @@ -0,0 +1,84 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: 投稿 + category: カテゴリー + tag: タグ + +# The tabs of sidebar +tabs: + # format: : + home: ホーム + categories: カテゴリー + tags: タグ + archives: アーカイブ + about: このサイトについて + +# the text displayed in the search bar & search results +search: + hint: 検索 + cancel: キャンセル + no_results: 該当なし + +panel: + lastmod: 最近更新された投稿 + trending_tags: トレンドのタグ + toc: コンテンツ + +copyright: + # Shown at the bottom of the post + license: + template: この投稿は投稿者によって :LICENSE_NAME の下でライセンスされています。 + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Some rights reserved. + verbose: >- + Except where otherwise noted, the blog posts on this site are licensed + under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author. + +meta: :PLATFORM 用の :THEME を使用しています。 + +not_found: + statement: このURLは存在しないものを指し示しています。 + +notification: + update_found: 新しいバージョンが利用可能です。 + update: 更新 + +# ----- Posts related labels ----- + +post: + written_by: 投稿者 + posted: 投稿日 + updated: 更新日 + words: 語 + pageview_measure: 回閲覧 + read_time: + unit: 分 + prompt: で読めます + relate_posts: さらに読む + share: シェア + button: + next: 次 + previous: 前 + copy_code: + succeed: コピーしました + share_link: + title: リンクをコピー + succeed: リンクをコピーしました + +# Date time format. +# See: , +df: + post: + strftime: "%Y/%m/%d" + dayjs: "YYYY/MM/DD" + +# categories page +categories: + category_measure: カテゴリー + post_measure: 投稿 diff --git a/src/data/locales/ko-KR.yml b/src/data/locales/ko-KR.yml new file mode 100644 index 00000000000..82976349c88 --- /dev/null +++ b/src/data/locales/ko-KR.yml @@ -0,0 +1,84 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: 포스트 + category: 카테고리 + tag: 태그 + +# The tabs of sidebar +tabs: + # format: : + home: 홈 + categories: 카테고리 + tags: 태그 + archives: 아카이브 + about: 정보 + +# the text displayed in the search bar & search results +search: + hint: 검색 + cancel: 취소 + no_results: 검색 결과가 없습니다. + +panel: + lastmod: 최근 업데이트 + trending_tags: 인기 태그 + toc: 바로가기 + +copyright: + # Shown at the bottom of the post + license: + template: 이 기사는 저작권자의 :LICENSE_NAME 라이센스를 따릅니다. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: 일부 권리 보유 + verbose: >- + 명시되지 않는 한 이 사이트의 블로그 게시물은 작성자의 + Creative Commons Attribution 4.0 International(CC BY 4.0) 라이선스에 따라 사용이 허가되었습니다. + +meta: Powered by :PLATFORM with :THEME theme + +not_found: + statement: 해당 URL은 존재하지 않습니다. + +notification: + update_found: 새 버전의 콘텐츠를 사용할 수 있습니다. + update: 업데이트 + +# ----- Posts related labels ----- + +post: + written_by: By + posted: 게시 + updated: 업데이트 + words: 단어 + pageview_measure: 조회 + read_time: + unit: 분 + prompt: 읽는 시간 + relate_posts: 관련된 글 + share: 공유하기 + button: + next: 다음 글 + previous: 이전 글 + copy_code: + succeed: 복사되었습니다! + share_link: + title: 링크 복사하기 + succeed: 링크가 복사되었습니다! + +# Date time format. +# See: , +df: + post: + strftime: "%Y/%m/%d" + dayjs: "YYYY/MM/DD" + +# categories page +categories: + category_measure: 카테고리 + post_measure: 포스트 diff --git a/src/data/locales/ku-IQ.yml b/src/data/locales/ku-IQ.yml new file mode 100644 index 00000000000..bcc53565f92 --- /dev/null +++ b/src/data/locales/ku-IQ.yml @@ -0,0 +1,91 @@ +# The layout text of site in Kurdish (Sorani) + +# ----- Commons label ----- + +layout: + post: بابەت + category: هاوپۆل + tag: تاگ + +# The tabs of sidebar +tabs: + # format: : + home: سەرەکی + categories: هاوپۆلەکان + tags: تاگەکان + archives: ئەرشیف + about: دەربارە + +# the text displayed in the search bar & search results +search: + hint: گەڕان + cancel: هەڵوەشاندنەوە + no_results: ببوورە! هیچ ئەنجامێک نەدۆزرایەوە. + +panel: + lastmod: دوایین نوێکردنەوەکان + trending_tags: تاگە باوەکان + toc: ناوەڕۆک + +copyright: + # Shown at the bottom of the post + license: + template: ئەم بابەتە لەلایەن نووسەرەوە بە مۆڵەتی :LICENSE_NAME بڵاوکراوەتەوە. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: هەندێک مافی پارێزراوە. + verbose: >- + تەنها لەو شوێنانەی کە بە پێچەوانەوە ئاماژەی پێدراوە، بابەتەکانی بڵۆگ لەم سایتەدا + لەژێر مۆڵەتی Creative Commons Attribution 4.0 International (CC BY 4.0) لەلایەن نووسەرەوە مۆڵەتیان پێدراوە. + +meta: بە بەکارهێنانی :PLATFORM لەگەڵ ڕووکاری :THEME + +not_found: + statement: ببوورە، ئەم بەستەرە نادۆزرێتەوە یان ئاماژە بە شتێک دەکات کە بوونی نییە. + +notification: + update_found: وەشانێکی نوێی ناوەڕۆک بەردەستە. + update: نوێکردنەوە + +# ----- Posts related labels ----- + +post: + written_by: نووسەر + posted: بڵاوکراوەتەوە + updated: نوێکراوەتەوە + words: وشە + pageview_measure: بینین + read_time: + unit: خولەک + prompt: خوێندنەوە + relate_posts: بابەتی پەیوەندیدار + share: بڵاوکردنەوە + button: + next: نوێتر + previous: کۆنتر + copy_code: + succeed: کۆپی کرا! + share_link: + title: کۆپی بەستەر + succeed: بەستەر بە سەرکەوتوویی کۆپی کرا! + +# Date time format. +# See: , +df: + post: + strftime: "%d %b, %Y" + dayjs: "DD MMM, YYYY" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: هاوپۆل + plural: هاوپۆل + post_measure: + singular: بابەت + plural: بابەت diff --git a/src/data/locales/my-MM.yml b/src/data/locales/my-MM.yml new file mode 100644 index 00000000000..d5bf728f9a9 --- /dev/null +++ b/src/data/locales/my-MM.yml @@ -0,0 +1,77 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: ပို့စ် + category: ကဏ္ဍ + tag: နာမ(တက်ဂ်) + +# The tabs of sidebar +tabs: + # format: : + home: အဓိကစာမျက်နှာ + categories: ကဏ္ဍများ + tags: နာမ(တက်ဂ်)များ + archives: မှတ်တမ်း​တိုက် + about: အကြောင်းအရာ + +# the text displayed in the search bar & search results +search: + hint: ရှာဖွေမည် + cancel: ဖျက်သိမ်းမည် + no_results: အိုး! ဘာမှမရှိပါ + +panel: + lastmod: မကြာသေးမီကမွမ်းမံထားသည် + trending_tags: ခေတ်စားနေသည့်တက်ဂ်များ + toc: အကြောင်းအရာများ + +copyright: + # Shown at the bottom of the post + license: + template: ဤပို့စ်သည်စာရေးသူ၏ :LICENSE_NAME လိုင်စင်ရထားသည်။ + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: မူပိုင်ခွင့်အချို့ကို လက်ဝယ်ထားသည်။ + verbose: >- + အခြားမှတ်သားထားချက်များမှလွဲ၍ ဤဆိုက်ရှိ ဘလော့ဂ်ပို့စ်များသည် စာရေးသူ၏ + Creative Commons Attribution 4.0 International (CC BY 4.0) အောက်တွင် လိုင်စင်ရထားပါသည်။ + +meta: Powered by :PLATFORM with :THEME theme + +not_found: + statement: ဝမ်းနည်းပါသည်၊ ကျွန်ုပ်တို့သည် အဆိုပါ URL ကို မှားယွင်းစွာ နေရာချထားခြင်း သို့မဟုတ် ၎င်းသည် မရှိသောအရာကို ညွှန်ပြနေပါသည်။ + +notification: + update_found: အကြောင်းအရာဗားရှင်းအသစ်ကို ရနိုင်ပါပြီ။ + update: အပ်ဒိတ် + +# ----- Posts related labels ----- + +post: + written_by: ကရေးသားခဲ့သည်။ + posted: တင်ထားခဲ့သည်။ + updated: မွမ်းမံထားခဲ့သည်။ + words: စကားလုံးများ + pageview_measure: အမြင်များ + read_time: + unit: မိနစ် + prompt: ဖတ်ပါမည် + relate_posts: နောက်ထပ်ဖတ်ရန် + share: မျှဝေရန် + button: + next: အသစ်များ + previous: အဟောင်းများ + copy_code: + succeed: ကူးယူလိုက်ပြီ။ + share_link: + title: လင့်ခ်ကို ကူးယူရန် + succeed: လင့်ခ်ကို ကူးယူလိုက်ပြီ။ + +# categories page +categories: + category_measure: ကဏ္ဍများ + post_measure: ပို့စ်များ diff --git a/src/data/locales/nl-NL.yml b/src/data/locales/nl-NL.yml new file mode 100644 index 00000000000..d7e8016d00d --- /dev/null +++ b/src/data/locales/nl-NL.yml @@ -0,0 +1,90 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Post + category: Categorie + tag: Tag + +# The tabs of sidebar +tabs: + # format: : + home: Startpagina + categories: Categorieën + tags: Tags + archives: Archief + about: Over + +# the text displayed in the search bar & search results +search: + hint: Zoek + cancel: Annuleer + no_results: Oops! Geen resultaat gevonden. + +panel: + lastmod: Recent Bijgewerkt + trending_tags: Trending Tags + toc: Inhoud + +copyright: + # Shown at the bottom of the post + license: + template: Alle posts zijn onder :LICENSE_NAME gepubliceerd door de auteur. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Sommige rechten voorbehouden. + verbose: >- + Tenzij anders vermeld, alle posts zijn onder de + Creative Commons Attribution 4.0 International (CC BY 4.0) gepubliceerd door de auteur. + +meta: Gebruikt :THEME + +not_found: + statement: Sorry, we hebben de URL verkeerd geplaatst of hij verwijst naar iets dat niet bestaat. + +notification: + update_found: Nieuwe versie van inhoud beschikbaar. + update: Update + +# ----- Posts related labels ----- +post: + written_by: Door + posted: Posted + updated: Bijgewerkt + words: woorden + pageview_measure: Gelezen + read_time: + unit: min + prompt: lees + relate_posts: Verder Lezen + share: Deel + button: + next: Volgende + previous: Vorige + copy_code: + succeed: Gekopieerd! + share_link: + title: Link kopiëren + succeed: Succesvol gekopieerd! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: categorie + plural: categorieën + post_measure: + singular: post + plural: posts diff --git "a/src/data/locales/ps\342\200\221AF.yml" "b/src/data/locales/ps\342\200\221AF.yml" new file mode 100644 index 00000000000..fca6877238c --- /dev/null +++ "b/src/data/locales/ps\342\200\221AF.yml" @@ -0,0 +1,90 @@ +# The layout text of site in Pashto (Afghanistan) + +# ----- Commons label ----- + +layout: + post: لیکنه + category: وېشنيزه + tag: ټګ + +# The tabs of sidebar +tabs: + # format: : + home: کورپاڼه + categories: وېشنيزې + tags: ټګونه + archives: آرشيف + about: په اړه + +# the text displayed in the search bar & search results +search: + hint: لټون + cancel: لغوه + no_results: ها! هېڅ پایله ونه موندل شوه. + +panel: + lastmod: وروستی تازه + trending_tags: مشهور ټګونه + toc: منځپانګه + +copyright: + # Shown at the bottom of the post + license: + template: دا لیکنه د :LICENSE_NAME جواز لاندې د لیکوال له خوا خپره شوې ده. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: ځینې حقونه خوندي دي. + verbose: >- + تر هغه ځایه چې بل ډول نه وي یاد شوي، د دې سایټ لیکنې + د لیکوال له خوا د کریټېو کامنز د انتساب 4.0 نړیوال (CC BY 4.0) جواز لاندې خپرېږي. + +meta: د :PLATFORM لپاره د :THEME موضوع کاروي. + +not_found: + statement: بښنه غواړو، دغه URL ناسم دی یا هغه څه ته اشاره کوي چې شتون نه لري. + +notification: + update_found: نوې نسخه شتون لري. + update: تازه + +# ----- Posts related labels ----- + +post: + written_by: لیکوال + posted: خپره شوې + updated: تازه شوې + words: کلمې + pageview_measure: کتنې + read_time: + unit: دقیقې + prompt: لوستل + relate_posts: نوره لوستنه + share: شریکول + button: + next: نوی + previous: زوړ + copy_code: + succeed: کاپي شو! + share_link: + title: لینک کاپي کړئ + succeed: لینک بریالي کاپي شو! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +categories: + category_measure: + singular: وېشنيزه + plural: وېشنيزې + post_measure: + singular: لیکنه + plural: لیکنې diff --git a/src/data/locales/pt-BR.yml b/src/data/locales/pt-BR.yml new file mode 100644 index 00000000000..7ca60a74b31 --- /dev/null +++ b/src/data/locales/pt-BR.yml @@ -0,0 +1,77 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Post + category: Categoria + tag: Tag + +# The tabs of sidebar +tabs: + # format: : + home: Home + categories: Categorias + tags: Tags + archives: Arquivos + about: Sobre + +# the text displayed in the search bar & search results +search: + hint: Buscar + cancel: Cancelar + no_results: Oops! Nenhum resultado encontrado. + +panel: + lastmod: Atualizados recentemente + trending_tags: Trending Tags + toc: Conteúdo + +copyright: + # Shown at the bottom of the post + license: + template: Esta postagem está licenciada sob :LICENSE_NAME pelo autor. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Alguns direitos reservados. + verbose: >- + Exceto onde indicado de outra forma, as postagens do blog neste site são licenciadas sob a + Creative Commons Attribution 4.0 International (CC BY 4.0) License pelo autor. + +meta: Feito com :PLATFORM usando o tema :THEME + +not_found: + statement: Desculpe, a página não foi encontrada. + +notification: + update_found: Uma nova versão do conteúdo está disponível. + update: atualização + +# ----- Posts related labels ----- + +post: + written_by: Por + posted: Postado em + updated: Atualizado + words: palavras + pageview_measure: visualizações + read_time: + unit: min + prompt: " de leitura" + relate_posts: Leia também + share: Compartilhar + button: + next: Próximo + previous: Anterior + copy_code: + succeed: Copiado! + share_link: + title: Copie o link + succeed: Link copiado com sucesso! + +# categories page +categories: + category_measure: categorias + post_measure: posts diff --git a/src/data/locales/ru-RU.yml b/src/data/locales/ru-RU.yml new file mode 100644 index 00000000000..868ba95787f --- /dev/null +++ b/src/data/locales/ru-RU.yml @@ -0,0 +1,87 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Пост + category: Категория + tag: Тег + +# The tabs of sidebar +tabs: + # format: : + home: Главная + categories: Категории + tags: Теги + archives: Архив + about: О сайте + +# the text displayed in the search bar & search results +search: + hint: поиск + cancel: Отмена + no_results: Упс! Ничего не найдено. + +panel: + lastmod: Недавно обновлено + trending_tags: Популярные теги + toc: Содержание + +copyright: + # Shown at the bottom of the post + license: + template: Авторский пост защищен лицензией :LICENSE_NAME. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Некоторые права защищены. + verbose: >- + Если не указано иное, авторские посты на этом сайте защищены лицензией Creative Commons Attribution 4.0 International (CC BY 4.0). + +meta: Использует тему :THEME для :PLATFORM + +not_found: + statement: Извините, мы перепутали URL-адрес или он указывает на что-то несуществующее. + +notification: + update_found: Доступна новая версия контента. + update: Обновить + +# ----- Posts related labels ----- + +post: + written_by: Автор + posted: Опубликовано + updated: Обновлено + words: слов + pageview_measure: просмотров + read_time: + unit: мин. + prompt: чтения + relate_posts: Похожие посты + share: Поделиться + button: + next: Следующий пост + previous: Предыдущий пост + copy_code: + succeed: Скопировано! + share_link: + title: Скопировать ссылку + succeed: Ссылка успешно скопирована! + +# Date time format. +# See: , +df: + post: + strftime: "%d.%m.%Y" + dayjs: "DD.MM.YYYY" + +# categories page +categories: + category_measure: + singular: категория + plural: категории + post_measure: + singular: пост + plural: посты diff --git a/src/data/locales/sl-SI.yml b/src/data/locales/sl-SI.yml new file mode 100644 index 00000000000..4d9434d4436 --- /dev/null +++ b/src/data/locales/sl-SI.yml @@ -0,0 +1,91 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Objava #Post + category: Kategorija #Category + tag: Oznaka #Tag + +# The tabs of sidebar +tabs: + # format: : + home: Domov #Home + categories: Kategorije #Categories + tags: Oznake #Tags + archives: Arhiv #Archives + about: O meni #About + +# the text displayed in the search bar & search results +search: + hint: išči #search + cancel: Prekliči #Cancel + no_results: Ups! Vsebina ni bila najdena #Oops! No results found. + +panel: + lastmod: Nedavno Posodobljeno #Recently Updated + trending_tags: Priljubljene Oznake #Trending Tags + toc: Vsebina #Contents + +copyright: + # Shown at the bottom of the post + license: + template: Ta objava je licencirana pod :LICENCE_NAME s strani avtorja. #This post is licensed under :LICENSE_NAME by the author. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Nekatere pravice pridržane. #Some rights reserved. + verbose: >- + Razen kjer navedeno drugače, vse objave spletnega dnevnika so licencirane + pod Creative Commons Attribution 4.0 International (CC BY 4.0) s strani avtorja. + +meta: Uporabljena :PLATFORM tema :THEME #Using the :PLATFORM theme :THEME + +not_found: + statement: Oprostite, hiperpovezava je neustrezna ali vsebina ne obstajata. #Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. + +notification: + update_found: Novejša različica vsebine je na voljo. #A new version of content is available. + update: Posodobi #Update + +# ----- Posts related labels ----- + +post: + written_by: Od #By + posted: Objavljeno #Posted + updated: Posodobljeno #Updated + words: besede #words + pageview_measure: ogledi #views + read_time: + unit: min + prompt: beri #read + relate_posts: Nadaljnje branje #Further Reading + share: Deli #Share + button: + next: Novejše #Newer + previous: Starejše #Older + copy_code: + succeed: Kopirano! #Copied! + share_link: + title: Kopiraj povezavo #Copy link + succeed: Povezava uspešno kopirana! #Link copied successfully! + +# Date time format. +# See: , +df: + post: + strftime: "%e %b, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: kategorija #category + plural: kategorije #categories + post_measure: + singular: objava #post + plural: objave #posts diff --git a/src/data/locales/sv-SE.yml b/src/data/locales/sv-SE.yml new file mode 100644 index 00000000000..decb59cf31f --- /dev/null +++ b/src/data/locales/sv-SE.yml @@ -0,0 +1,91 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Inlägg #Post + category: Kategori #Category + tag: Tagga #Tag + +# The tabs of sidebar +tabs: + # format: : + home: Hem #Home + categories: Kategorier #Categories + tags: Taggar #Tags + archives: Arkiv #Archives + about: Om #About + +# the text displayed in the search bar & search results +search: + hint: sök + cancel: Avbryt + no_results: Hoppsan! Hittade inga sökträffar. + +panel: + lastmod: Senast uppdaterad + trending_tags: Trendande taggar + toc: Innehåll + +copyright: + # Shown at the bottom of the post + license: + template: Den här posten är publicerad under licensen :LICENSE_NAME av författaren. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Vissa rättigheter är reserverade. + verbose: >- + Om inte annat anges är blogginläggen på denna webbplats licensierade + under Creative Commons Attribution 4.0 International (CC BY 4.0) av författaren. + +meta: Byggd med :PLATFORM och temat :THEME + +not_found: + statement: Ursäkta, vi har tappat bort den här webbadressen eller så pekar den på något som inte längre finns. + +notification: + update_found: Det finns en ny version av innehållet. + update: Uppdatera sidan + +# ----- Posts related labels ----- + +post: + written_by: Av + posted: Postad + updated: Uppdaterad + words: ord + pageview_measure: visningar + read_time: + unit: min + prompt: läsning + relate_posts: Mer läsning + share: Dela + button: + next: Nyare + previous: Äldre + copy_code: + succeed: Kopierat! + share_link: + title: Kopiera länk + succeed: Länken har kopierats! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: kategori + plural: kategorier + post_measure: + singular: inlägg + plural: inlägg diff --git a/src/data/locales/th.yml b/src/data/locales/th.yml new file mode 100644 index 00000000000..a3f41a0e16e --- /dev/null +++ b/src/data/locales/th.yml @@ -0,0 +1,91 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: โพสต์ + category: หมวดหมู่ + tag: แท็ก + +# The tabs of sidebar +tabs: + # format: : + home: หน้าแรก + categories: หมวดหมู่ + tags: แท็ก + archives: คลังเก็บ + about: เกี่ยวกับ + +# the text displayed in the search bar & search results +search: + hint: ค้นหา + cancel: ยกเลิก + no_results: โอ๊ะ! ไม่พบผลลัพธ์ + +panel: + lastmod: อัปเดตล่าสุด + trending_tags: แท็กยอดนิยม + toc: เนื้อหา + +copyright: + # Shown at the bottom of the post + license: + template: โพสต์นี้อยู่ภายใต้การอนุญาต :LICENSE_NAME โดยผู้เขียน + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: สงวนลิขสิทธิ์เป็นบางส่วน + verbose: >- + เว้นแต่ว่าจะระบุเป็นอย่างอื่น โพสต์บนเว็บไซต์นี้อยู่ภายใต้ + สัญญาอนุญาตครีเอทีฟคอมมอนส์แบบ 4.0 นานาชาติ (CC BY 4.0) โดยผู้เขียน + +meta: กำลังใช้ธีมของ :PLATFORM ชื่อ :THEME + +not_found: + statement: ขออภัย เราวาง URL นั้นไว้ผิดที่ หรือมันชี้ไปยังสิ่งที่ไม่มีอยู่ + +notification: + update_found: มีเวอร์ชันใหม่ของเนื้อหา + update: อัปเดต + +# ----- Posts related labels ----- + +post: + written_by: โดย + posted: โพสต์เมื่อ + updated: อัปเดตเมื่อ + words: คำ + pageview_measure: ครั้ง + read_time: + unit: นาที + prompt: อ่าน + relate_posts: อ่านต่อ + share: แชร์ + button: + next: ใหม่กว่า + previous: เก่ากว่า + copy_code: + succeed: คัดลอกแล้ว! + share_link: + title: คัดลอกลิงก์ + succeed: คัดลอกลิงก์เรียบร้อยแล้ว! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: หมวดหมู่ + plural: หมวดหมู่ + post_measure: + singular: โพสต์ + plural: โพสต์ diff --git a/src/data/locales/tr-TR.yml b/src/data/locales/tr-TR.yml new file mode 100644 index 00000000000..768f57cd1c6 --- /dev/null +++ b/src/data/locales/tr-TR.yml @@ -0,0 +1,77 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Gönderi + category: Kategori + tag: Etiket + +# The tabs of sidebar +tabs: + # format: : + home: Ana Sayfa + categories: Kategoriler + tags: Etiketler + archives: Arşiv + about: Hakkında + +# the text displayed in the search bar & search results +search: + hint: Ara... + cancel: İptal + no_results: Hop! Öyle bir şey bulamadım. + +panel: + lastmod: Son Güncellenenler + trending_tags: Yükselen Etiketler + toc: İçindekiler + +copyright: + # Shown at the bottom of the post + license: + template: Bu gönderi :LICENSE_NAME lisansı altındadır. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/deed.tr + + # Displayed in the footer + brief: Bazı hakları saklıdır. + verbose: >- + Aksi belirtilmediği sürece, bu sitedeki gönderiler Creative Commons Atıf 4.0 Uluslararası (CC BY 4.0) Lisansı altındadır. + Kısaca sayfa linkini vererek değiştirebilir / paylaşabilirsiniz. + +meta: :PLATFORM ve :THEME teması + +not_found: + statement: Üzgünüz, bu linki yanlış yerleştirdik veya var olmayan bir şeye işaret ediyor. + +notification: + update_found: İçeriğin yeni bir sürümü mevcut. + update: Güncelle + +# ----- Posts related labels ----- + +post: + written_by: Yazan + posted: Gönderim + updated: Güncelleme + words: sözcük + pageview_measure: görüntülenme + read_time: + unit: dakikada + prompt: okunabilir + relate_posts: Benzer Gönderiler + share: Paylaş + button: + next: İleri + previous: Geri + copy_code: + succeed: Kopyalandı. + share_link: + title: Linki kopyala + succeed: Link kopyalandı. + +# categories page +categories: + category_measure: kategori + post_measure: gönderi diff --git a/src/data/locales/uk-UA.yml b/src/data/locales/uk-UA.yml new file mode 100644 index 00000000000..8fef52e8569 --- /dev/null +++ b/src/data/locales/uk-UA.yml @@ -0,0 +1,77 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Публікація + category: Категорія + tag: Тег + +# The tabs of sidebar +tabs: + # format: : + home: Домашня сторінка + categories: Категорії + tags: Теги + archives: Архів + about: Про сайт + +# the text displayed in the search bar & search results +search: + hint: пошук + cancel: Скасувати + no_results: Ох! Нічого не знайдено. + +panel: + lastmod: Нещодавно оновлено + trending_tags: Популярні теги + toc: Зміст + +copyright: + # Shown at the bottom of the post + license: + template: Публікація захищена ліцензією :LICENSE_NAME. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Деякі права захищено. + verbose: >- + Публікації на сайті захищено ліцензією Creative Commons Attribution 4.0 International (CC BY 4.0), + якщо інше не вказано в тексті. + +meta: Powered by :PLATFORM with :THEME theme + +not_found: + statement: Вибачте, це посилання вказує на ресурс, що не існує. + +notification: + update_found: Доступна нова версія вмісту. + update: Оновлення + +# ----- Posts related labels ----- + +post: + written_by: Автор + posted: Час публікації + updated: Оновлено + words: слів + pageview_measure: переглядів + read_time: + unit: хвилин + prompt: читання + relate_posts: Вас також може зацікавити + share: Поділитися + button: + next: Попередня публікація + previous: Наступна публікація + copy_code: + succeed: Успішно скопійовано! + share_link: + title: Скопіювати посилання + succeed: Посилання успішно скопійовано! + +# categories page +categories: + category_measure: категорії + post_measure: публікації diff --git a/src/data/locales/ur-PK.yml b/src/data/locales/ur-PK.yml new file mode 100644 index 00000000000..e5184df171c --- /dev/null +++ b/src/data/locales/ur-PK.yml @@ -0,0 +1,90 @@ +# The layout text of site in Urdu (Pakistan) + +# ----- Commons label ----- + +layout: + post: تحریر + category: زمرہ + tag: ٹیگ + +# The tabs of sidebar +tabs: + # format: : + home: گھر + categories: زمروں + tags: ٹیگز + archives: محفوظات + about: تعارف + +# the text displayed in the search bar & search results +search: + hint: تلاش + cancel: منسوخ + no_results: اوہ! کوئی نتیجہ نہیں ملا۔ + +panel: + lastmod: حال ہی میں اپ ڈیٹ + trending_tags: مقبول ٹیگز + toc: مواد + +copyright: + # Shown at the bottom of the post + license: + template: یہ تحریر :LICENSE_NAME کے تحت مصنف کی جانب سے لائسنس یافتہ ہے۔ + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: کچھ حقوق محفوظ ہیں۔ + verbose: >- + جب تک کہ دوسری صورت میں ذکر نہ ہو، اس سائٹ کی تحریریں + مصنف کی جانب سے تخلیقی العام انتساب 4.0 بین الاقوامی (CC BY 4.0) لائسنس کے تحت دستیاب ہیں۔ + +meta: :PLATFORM کے لیے :THEME تھیم استعمال کیا جا رہا ہے۔ + +not_found: + statement: معذرت، یہ URL غلط ہے یا جس چیز کی طرف اشارہ کر رہا ہے وہ موجود نہیں۔ + +notification: + update_found: نیا مواد دستیاب ہے۔ + update: اپ ڈیٹ + +# ----- Posts related labels ----- + +post: + written_by: از + posted: شائع شدہ + updated: اپ ڈیٹ شدہ + words: لفظ + pageview_measure: مشاہدات + read_time: + unit: منٹ + prompt: پڑھیں + relate_posts: مزید مطالعہ + share: شیئر + button: + next: نیا + previous: پرانا + copy_code: + succeed: کاپی ہو گیا! + share_link: + title: لنک کاپی کریں + succeed: لنک کامیابی سے کاپی ہو گیا! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +categories: + category_measure: + singular: زمرہ + plural: زمروں + post_measure: + singular: تحریر + plural: تحریریں diff --git a/src/data/locales/vi-VN.yml b/src/data/locales/vi-VN.yml new file mode 100644 index 00000000000..6c2ceffde38 --- /dev/null +++ b/src/data/locales/vi-VN.yml @@ -0,0 +1,76 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Bài viết + category: Danh mục + tag: Thẻ + +# The tabs of sidebar +tabs: + # format: : + home: Trang chủ + categories: Các danh mục + tags: Các thẻ + archives: Lưu trữ + about: Giới thiệu + +# the text displayed in the search bar & search results +search: + hint: tìm kiếm + cancel: Hủy + no_results: Không có kết quả tìm kiếm. + +panel: + lastmod: Mới cập nhật + trending_tags: Các thẻ thịnh hành + toc: Mục lục + +copyright: + # Shown at the bottom of the post + license: + template: Bài viết này được cấp phép bởi tác giả theo giấy phép :LICENSE_NAME. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Một số quyền được bảo lưu. + verbose: >- + Trừ khi có ghi chú khác, các bài viết đăng trên trang này được cấp phép bởi tác giả theo giấy phép Creative Commons Attribution 4.0 International (CC BY 4.0). + +meta: Trang web này được tạo bởi :PLATFORM với chủ đề :THEME + +not_found: + statement: Xin lỗi, chúng tôi đã đặt nhầm URL hoặc đường dẫn trỏ đến một trang nào đó không tồn tại. + +notification: + update_found: Đã có phiên bản mới của nội dung. + update: Cập nhật + +# ----- Posts related labels ----- + +post: + written_by: Viết bởi + posted: Đăng lúc + updated: Cập nhật lúc + words: từ + pageview_measure: lượt xem + read_time: + unit: phút + prompt: đọc + relate_posts: Bài viết liên quan + share: Chia sẻ + button: + next: Mới hơn + previous: Cũ hơn + copy_code: + succeed: Đã sao chép! + share_link: + title: Sao chép đường dẫn + succeed: Đã sao chép đường dẫn thành công! + +# categories page +categories: + category_measure: danh mục + post_measure: bài viết diff --git a/src/data/locales/zh-CN.yml b/src/data/locales/zh-CN.yml new file mode 100644 index 00000000000..5c134101834 --- /dev/null +++ b/src/data/locales/zh-CN.yml @@ -0,0 +1,83 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: 文章 + category: 分类 + tag: 标签 + +# The tabs of sidebar +tabs: + # format: : + home: 首页 + categories: 分类 + tags: 标签 + archives: 归档 + about: 关于 + +# the text displayed in the search bar & search results +search: + hint: 搜索 + cancel: 取消 + no_results: 搜索结果为空 + +panel: + lastmod: 最近更新 + trending_tags: 热门标签 + toc: 文章内容 + +copyright: + # Shown at the bottom of the post + license: + template: 本文由作者按照 :LICENSE_NAME 进行授权 + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: 保留部分权利。 + verbose: >- + 除非另有说明,本网站上的博客文章均由作者按照知识共享署名 4.0 国际 (CC BY 4.0) 许可协议进行授权。 + +meta: 本站采用 :PLATFORM 主题 :THEME + +not_found: + statement: 抱歉,我们放错了该 URL,或者它指向了不存在的内容。 + +notification: + update_found: 发现新版本的内容。 + update: 更新 + +# ----- Posts related labels ----- + +post: + written_by: 作者 + posted: 发表于 + updated: 更新于 + words: 字 + pageview_measure: 次浏览 + read_time: + unit: 分钟 + prompt: 阅读 + relate_posts: 相关文章 + share: 分享 + button: + next: 下一篇 + previous: 上一篇 + copy_code: + succeed: 已复制! + share_link: + title: 分享链接 + succeed: 链接已复制! + +# Date time format. +# See: , +df: + post: + strftime: "%Y/%m/%d" + dayjs: "YYYY/MM/DD" + +# categories page +categories: + category_measure: 个分类 + post_measure: 篇文章 diff --git a/src/data/locales/zh-TW.yml b/src/data/locales/zh-TW.yml new file mode 100644 index 00000000000..33a4330bb0f --- /dev/null +++ b/src/data/locales/zh-TW.yml @@ -0,0 +1,83 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: 文章 + category: 分類 + tag: 標籤 + +# The tabs of sidebar +tabs: + # format: : + home: 首頁 + categories: 分類 + tags: 標籤 + archives: 封存 + about: 關於 + +# the text displayed in the search bar & search results +search: + hint: 搜尋 + cancel: 取消 + no_results: 沒有搜尋結果 + +panel: + lastmod: 最近更新 + trending_tags: 熱門標籤 + toc: 文章摘要 + +copyright: + # Shown at the bottom of the post + license: + template: 本文章以 :LICENSE_NAME 授權 + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: 保留部份權利。 + verbose: >- + 除非另有說明,否則本網誌的文章均由作者按照姓名標示 4.0 國際 (CC BY 4.0) 授權條款進行授權。 + +meta: 本網站使用 :PLATFORM 產生,採用 :THEME 主題 + +not_found: + statement: 抱歉,您可能正在存取一個已被移動的 URL,或者它從未存在。 + +notification: + update_found: 發現新版本更新。 + update: 更新 + +# ----- Posts related labels ----- + +post: + written_by: 作者 + posted: 發布於 + updated: 更新於 + words: 字 + pageview_measure: 次瀏覽 + read_time: + unit: 分鐘 + prompt: 閱讀 + relate_posts: 相關文章 + share: 分享 + button: + next: 下一篇 + previous: 上一篇 + copy_code: + succeed: 已複製! + share_link: + title: 分享連結 + succeed: 已複製連結! + +# Date time format. +# See: , +df: + post: + strftime: "%Y/%m/%d" + dayjs: "YYYY/MM/DD" + +# categories page +categories: + category_measure: 個分類 + post_measure: 篇文章 diff --git a/src/data/media.yml b/src/data/media.yml new file mode 100644 index 00000000000..9cd69b4ce95 --- /dev/null +++ b/src/data/media.yml @@ -0,0 +1,18 @@ +- extension: mp3 + mime_type: mpeg +- extension: mov + mime_type: quicktime +- extension: avi + mime_type: x-msvideo +- extension: mkv + mime_type: x-matroska +- extension: ogv + mime_type: ogg +- extension: weba + mime_type: webm +- extension: 3gp + mime_type: 3gpp +- extension: 3g2 + mime_type: 3gpp2 +- extension: mid + mime_type: midi diff --git a/src/data/origin/basic.yml b/src/data/origin/basic.yml new file mode 100644 index 00000000000..2d5298229d3 --- /dev/null +++ b/src/data/origin/basic.yml @@ -0,0 +1,39 @@ +# fonts + +webfonts: /assets/lib/fonts/main.css + +# Libraries + +toc: + css: /assets/lib/tocbot/tocbot.min.css + js: /assets/lib/tocbot/tocbot.min.js + +fontawesome: + css: /assets/lib/fontawesome-free/css/all.min.css + +search: + js: /assets/lib/simple-jekyll-search/simple-jekyll-search.min.js + +mermaid: + js: /assets/lib/mermaid/mermaid.min.js + +dayjs: + js: + common: /assets/lib/dayjs/dayjs.min.js + locale: /assets/lib/dayjs/locale/en.js + relativeTime: /assets/lib/dayjs/plugin/relativeTime.js + localizedFormat: /assets/lib/dayjs/plugin/localizedFormat.js + +glightbox: + css: /assets/lib/glightbox/glightbox.min.css + js: /assets/lib/glightbox/glightbox.min.js + +lazy-polyfill: + css: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.min.css + js: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.umd.min.js + +clipboard: + js: /assets/lib/clipboard/clipboard.min.js + +mathjax: + js: /assets/lib/mathjax/tex-chtml.js diff --git a/src/data/origin/cors.yml b/src/data/origin/cors.yml new file mode 100644 index 00000000000..ce99f814109 --- /dev/null +++ b/src/data/origin/cors.yml @@ -0,0 +1,54 @@ +# Resource Hints +resource_hints: + - url: https://fonts.googleapis.com + links: + - rel: preconnect + - rel: dns-prefetch + - url: https://fonts.gstatic.com + links: + - rel: preconnect + opts: [crossorigin] + - rel: dns-prefetch + - url: https://cdn.jsdelivr.net + links: + - rel: preconnect + - rel: dns-prefetch + +# Web Fonts +webfonts: https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Source+Sans+Pro:wght@400;600;700;900&display=swap + +# Libraries + +toc: + css: https://cdn.jsdelivr.net/npm/tocbot@4.36.4/dist/tocbot.min.css + js: https://cdn.jsdelivr.net/npm/tocbot@4.36.4/dist/tocbot.min.js + +fontawesome: + css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.1.0/css/all.min.css + +search: + js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js + +mermaid: + js: https://cdn.jsdelivr.net/npm/mermaid@11.12.0/dist/mermaid.min.js + +dayjs: + js: + common: https://cdn.jsdelivr.net/npm/dayjs@1.11.18/dayjs.min.js + locale: https://cdn.jsdelivr.net/npm/dayjs@1.11.18/locale/:LOCALE.js + relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1.11.18/plugin/relativeTime.js + localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1.11.18/plugin/localizedFormat.js + +glightbox: + css: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/css/glightbox.min.css + js: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/js/glightbox.min.js + +lazy-polyfill: + css: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.min.css + js: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.umd.min.js + +clipboard: + js: https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js + +mathjax: + js: https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-chtml.js diff --git a/src/data/share.yml b/src/data/share.yml new file mode 100644 index 00000000000..edbc02b26b0 --- /dev/null +++ b/src/data/share.yml @@ -0,0 +1,50 @@ +# Sharing options at the bottom of the post. +# Icons from + +platforms: + - type: Twitter + icon: "fa-brands fa-square-x-twitter" + link: "https://twitter.com/intent/tweet?text=TITLE&url=URL" + + - type: Facebook + icon: "fab fa-facebook-square" + link: "https://www.facebook.com/sharer/sharer.php?title=TITLE&u=URL" + + - type: Telegram + icon: "fab fa-telegram" + link: "https://t.me/share/url?url=URL&text=TITLE" + + # Uncomment below if you need to. + # + # - type: Linkedin + # icon: "fab fa-linkedin" + # link: "https://www.linkedin.com/feed/?shareActive=true&shareUrl=URL" + # + # - type: Weibo + # icon: "fab fa-weibo" + # link: "https://service.weibo.com/share/share.php?title=TITLE&url=URL" + # + # - type: Mastodon + # icon: "fa-brands fa-mastodon" + # # See: https://github.com/justinribeiro/share-to-mastodon#properties + # instances: + # - label: mastodon.social + # link: "https://mastodon.social/" + # - label: mastodon.online + # link: "https://mastodon.online/" + # - label: fosstodon.org + # link: "https://fosstodon.org/" + # - label: photog.social + # link: "https://photog.social/" + # + # - type: Bluesky + # icon: "fa-brands fa-bluesky" + # link: "https://bsky.app/intent/compose?text=TITLE%20URL" + # + # - type: Reddit + # icon: "fa-brands fa-square-reddit" + # link: "https://www.reddit.com/submit?url=URL&title=TITLE" + # + # - type: Threads + # icon: "fa-brands fa-square-threads" + # link: "https://www.threads.net/intent/post?text=TITLE%20URL" diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro new file mode 100644 index 00000000000..b6abe8bf933 --- /dev/null +++ b/src/layouts/BaseLayout.astro @@ -0,0 +1,99 @@ +--- +import { SITE, FEATURES } from '@/config'; +import Head from '@components/Head.astro'; +import Sidebar from '@components/Sidebar.astro'; +import Topbar from '@components/Topbar.astro'; +import Footer from '@components/Footer.astro'; +import SearchResults from '@components/SearchResults.astro'; +import UpdateList from '@components/UpdateList.astro'; +import TrendingTags from '@components/TrendingTags.astro'; +import '@styles/main.scss'; + +export interface Props { + title?: string; + description?: string; + image?: string; + lang?: string; + panelIncludes?: string[]; + tailIncludes?: string[]; + refactorContent?: boolean; +} + +const { + title, + description, + image, + lang = SITE.lang, + panelIncludes = [], + tailIncludes = [], + refactorContent = false +} = Astro.props; + +--- + + + + + + + + +
+
+ + +
+
+ +
+ + + +
+ +
+ +
+ {tailIncludes.map((include) => ( + +
{include}
+ ))} + +
+
+
+ + +
+ + +
+ +
+ + {FEATURES.pwa.enabled && ( + +
+ )} + + + + diff --git a/src/layouts/PostLayout.astro b/src/layouts/PostLayout.astro new file mode 100644 index 00000000000..d4744411ff7 --- /dev/null +++ b/src/layouts/PostLayout.astro @@ -0,0 +1,112 @@ +--- +import BaseLayout from './BaseLayout.astro'; +import type { CollectionEntry } from 'astro:content'; +import { SITE } from '@/config'; + +export interface Props { + post: CollectionEntry<'posts'>; +} + +const { post } = Astro.props; +const { title, description, date, categories, tags, image, author } = post.data; + +const formattedDate = new Date(date).toLocaleDateString(SITE.lang, { + year: 'numeric', + month: 'long', + day: 'numeric' +}); +--- + + +
+
+

{title}

+ + +
+ + {image?.path && ( +
+ {image.alt +
+ )} + +
+ +
+ + {tags && tags.length > 0 && ( + + )} +
+
+ + diff --git a/src/pages/[...slug].astro b/src/pages/[...slug].astro new file mode 100644 index 00000000000..ca24e65e189 --- /dev/null +++ b/src/pages/[...slug].astro @@ -0,0 +1,34 @@ +--- +import { getCollection } from 'astro:content'; +import BaseLayout from '@layouts/BaseLayout.astro'; + +export async function getStaticPaths() { + const tabs = await getCollection('tabs'); + return tabs.map((tab) => ({ + params: { slug: tab.slug }, + props: { tab }, + })); +} + +const { tab } = Astro.props; +const { Content } = await tab.render(); +--- + + +
+

{tab.data.title}

+ +
+
+ + diff --git a/src/pages/index.astro b/src/pages/index.astro new file mode 100644 index 00000000000..5305dfc443d --- /dev/null +++ b/src/pages/index.astro @@ -0,0 +1,160 @@ +--- +import BaseLayout from '@layouts/BaseLayout.astro'; +import { getCollection } from 'astro:content'; +import { PAGINATION, SITE } from '@/config'; + +// Get all posts +const allPosts = await getCollection('posts'); + +// Separate pinned and normal posts +const pinnedPosts = allPosts.filter(post => post.data.pin && !post.data.hidden); +const normalPosts = allPosts.filter(post => !post.data.pin && !post.data.hidden); + +// Sort by date (newest first) +const sortByDate = (a: any, b: any) => { + return new Date(b.data.date).getTime() - new Date(a.data.date).getTime(); +}; + +pinnedPosts.sort(sortByDate); +normalPosts.sort(sortByDate); + +// Combine for first page (pinned first, then normal) +const postsPerPage = PAGINATION.postsPerPage; +const displayPosts = [...pinnedPosts, ...normalPosts].slice(0, postsPerPage); + +// Helper to get image URL +const getImageUrl = (post: any) => { + const image = post.data.image; + if (!image) return null; + + const src = image.path || image; + if (src.startsWith('http://') || src.startsWith('https://')) return src; + if (src.startsWith('/') && SITE.cdn) return `${SITE.cdn}${src}`; + return src; +}; + +// Format date +const formatDate = (date: Date) => { + return new Date(date).toLocaleDateString(SITE.lang, { + year: 'numeric', + month: 'short', + day: 'numeric' + }); +}; +--- + + +
+ {displayPosts.map((post) => { + const imageUrl = getImageUrl(post); + + return ( + + ); + })} +
+ + + +
+ + diff --git a/src/pages/posts/[...slug].astro b/src/pages/posts/[...slug].astro new file mode 100644 index 00000000000..f936c1a63e1 --- /dev/null +++ b/src/pages/posts/[...slug].astro @@ -0,0 +1,19 @@ +--- +import { getCollection } from 'astro:content'; +import PostLayout from '@layouts/PostLayout.astro'; + +export async function getStaticPaths() { + const posts = await getCollection('posts'); + return posts.map((post) => ({ + params: { slug: post.slug }, + props: { post }, + })); +} + +const { post } = Astro.props; +const { Content } = await post.render(); +--- + + + + diff --git a/src/scripts/main.ts b/src/scripts/main.ts new file mode 100644 index 00000000000..2c5bfed911a --- /dev/null +++ b/src/scripts/main.ts @@ -0,0 +1,75 @@ +// Main application JavaScript +import './theme'; + +// Back to top button +function initBackToTop() { + const backToTopBtn = document.getElementById('back-to-top'); + if (!backToTopBtn) return; + + const toggleVisibility = () => { + if (window.scrollY > 300) { + backToTopBtn.style.display = 'block'; + } else { + backToTopBtn.style.display = 'none'; + } + }; + + window.addEventListener('scroll', toggleVisibility); + toggleVisibility(); // Initial check + + backToTopBtn.addEventListener('click', () => { + window.scrollTo({ + top: 0, + behavior: 'smooth' + }); + }); +} + +// Sidebar mobile toggle +function initSidebar() { + const sidebar = document.getElementById('sidebar'); + const mask = document.getElementById('mask'); + const sidebarTrigger = document.getElementById('sidebar-trigger'); + + if (!sidebar || !mask || !sidebarTrigger) return; + + sidebarTrigger.addEventListener('click', () => { + sidebar.classList.toggle('shown'); + mask.classList.toggle('d-none'); + }); + + mask.addEventListener('click', () => { + sidebar.classList.remove('shown'); + mask.classList.add('d-none'); + }); +} + +// Image lazy loading with fallback +function initImageLoading() { + // Add loading error handlers + const images = document.querySelectorAll('img[loading="lazy"]'); + images.forEach((img) => { + img.addEventListener('error', function(this: HTMLImageElement) { + this.style.display = 'none'; + }); + }); +} + +// Initialize on DOM ready +if (typeof document !== 'undefined') { + document.addEventListener('DOMContentLoaded', () => { + initBackToTop(); + initSidebar(); + initImageLoading(); + }); + + // Re-initialize on page navigation (for view transitions) + document.addEventListener('astro:after-swap', () => { + initBackToTop(); + initSidebar(); + initImageLoading(); + }); +} + +// Export for use in other modules +export { initBackToTop, initSidebar, initImageLoading }; diff --git a/src/scripts/theme.ts b/src/scripts/theme.ts new file mode 100644 index 00000000000..5567d45b787 --- /dev/null +++ b/src/scripts/theme.ts @@ -0,0 +1,59 @@ +// Theme management +export const THEME_KEY = 'theme'; +export const THEME_ATTR = 'data-mode'; + +export type Theme = 'light' | 'dark'; + +export function getThemePreference(): Theme { + const stored = localStorage.getItem(THEME_KEY); + if (stored === 'light' || stored === 'dark') { + return stored; + } + + // Check system preference + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; +} + +export function setTheme(theme: Theme) { + document.documentElement.setAttribute(THEME_ATTR, theme); + localStorage.setItem(THEME_KEY, theme); + + // Dispatch event for components that need to react to theme changes + window.dispatchEvent(new CustomEvent('themechange', { detail: { theme } })); +} + +export function toggleTheme() { + const current = getThemePreference(); + const next = current === 'light' ? 'dark' : 'light'; + setTheme(next); + return next; +} + +export function initTheme() { + const theme = getThemePreference(); + document.documentElement.setAttribute(THEME_ATTR, theme); +} + +// Initialize theme on page load +if (typeof window !== 'undefined') { + // Apply theme immediately to prevent flash + initTheme(); + + // Setup theme toggle + document.addEventListener('DOMContentLoaded', () => { + const toggleBtn = document.getElementById('mode-toggle'); + if (toggleBtn) { + toggleBtn.addEventListener('click', () => { + toggleTheme(); + }); + } + }); + + // Listen for system theme changes + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { + // Only auto-switch if user hasn't set a preference + if (!localStorage.getItem(THEME_KEY)) { + setTheme(e.matches ? 'dark' : 'light'); + } + }); +} diff --git a/src/styles/abstracts/_breakpoints.scss b/src/styles/abstracts/_breakpoints.scss new file mode 100644 index 00000000000..e40cefeee36 --- /dev/null +++ b/src/styles/abstracts/_breakpoints.scss @@ -0,0 +1,73 @@ +@use 'sass:map'; + +$-breakpoints: ( + // 1 column + sm: 576px, + md: 768px, + // 2 columns + lg: 850px, + // 3 columns + xl: 1200px, + xxl: 1400px, + xxxl: 1650px +); + +@function get($breakpoint) { + @return map.get($-breakpoints, $breakpoint); +} + +/* Less than the given width */ +@mixin lt($width) { + @media all and (max-width: calc(#{$width} - 1px)) { + @content; + } +} + +/* Less than or equal to the given width */ +@mixin lte($width) { + @media all and (max-width: $width) { + @content; + } +} + +@mixin sm { + @media all and (min-width: get(sm)) { + @content; + } +} + +@mixin md { + @media all and (min-width: get(md)) { + @content; + } +} + +@mixin lg { + @media all and (min-width: get(lg)) { + @content; + } +} + +@mixin xl { + @media all and (min-width: get(xl)) { + @content; + } +} + +@mixin xxl { + @media all and (min-width: get(xxl)) { + @content; + } +} + +@mixin xxxl { + @media all and (min-width: get(xxxl)) { + @content; + } +} + +@mixin between($min, $max) { + @media all and (min-width: $min) and (max-width: $max) { + @content; + } +} diff --git a/src/styles/abstracts/_index.scss b/src/styles/abstracts/_index.scss new file mode 100644 index 00000000000..6c9e21cf46b --- /dev/null +++ b/src/styles/abstracts/_index.scss @@ -0,0 +1,4 @@ +@forward 'variables'; +@forward 'mixins'; +@forward 'placeholders'; +@forward 'breakpoints'; diff --git a/src/styles/abstracts/_mixins.scss b/src/styles/abstracts/_mixins.scss new file mode 100644 index 00000000000..c5eeee3cafc --- /dev/null +++ b/src/styles/abstracts/_mixins.scss @@ -0,0 +1,80 @@ +@mixin text-ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +@mixin mt-mb($value) { + margin-top: $value; + margin-bottom: $value; +} + +@mixin ml-mr($value) { + margin-left: $value; + margin-right: $value; +} + +@mixin pt-pb($val) { + padding-top: $val; + padding-bottom: $val; +} + +@mixin pl-pr($val, $important: false) { + @if $important { + padding-left: $val !important; + padding-right: $val !important; + } @else { + padding-left: $val; + padding-right: $val; + } +} + +@mixin placeholder { + color: var(--text-muted-color) !important; +} + +@mixin placeholder-focus { + opacity: 0.6; +} + +@mixin label($font-size: 1rem, $font-weight: 600, $color: var(--label-color)) { + color: $color; + font-size: $font-size; + font-weight: $font-weight; +} + +@mixin align-center { + position: relative; + left: 50%; + transform: translateX(-50%); +} + +@mixin prompt($type, $fa-content, $fa-style: 'solid', $rotate: 0) { + &.prompt-#{$type} { + background-color: var(--prompt-#{$type}-bg); + + &::before { + content: $fa-content; + color: var(--prompt-#{$type}-icon-color); + font: var(--fa-font-#{$fa-style}); + + @if $rotate != 0 { + transform: rotate(#{$rotate}deg); + } + } + } +} + +@mixin slide($append: null) { + $basic: transform 0.4s ease; + + @if $append { + transition: $basic, $append; + } @else { + transition: $basic; + } +} + +@mixin max-w-100 { + max-width: 100%; +} diff --git a/src/styles/abstracts/_placeholders.scss b/src/styles/abstracts/_placeholders.scss new file mode 100644 index 00000000000..d8a10604620 --- /dev/null +++ b/src/styles/abstracts/_placeholders.scss @@ -0,0 +1,163 @@ +@use 'variables' as v; +@use 'mixins' as mx; + +%heading { + color: var(--heading-color); + font-weight: 400; + font-family: v.$font-family-heading; + scroll-margin-top: 3.5rem; +} + +%anchor { + .anchor { + font-size: 80%; + } + + @media (hover: hover) { + .anchor { + visibility: hidden; + opacity: 0; + transition: opacity 0.25s ease-in, visibility 0s ease-in 0.25s; + } + + &:hover { + .anchor { + visibility: visible; + opacity: 1; + transition: opacity 0.25s ease-in, visibility 0s ease-in 0s; + } + } + } +} + +%tag-hover { + @extend %link-color; + + background: var(--tag-hover); + border-color: var(--tag-hover); + transition: background 0.35s ease-in-out; +} + +%table-cell { + padding: 0.4rem 1rem; + font-size: 95%; + white-space: nowrap; +} + +%link-hover { + color: #d2603a !important; + border-bottom: 1px solid #d2603a; + text-decoration: none; +} + +%link-color { + color: var(--link-color); +} + +%link-underline { + border-bottom: 1px solid var(--link-underline-color); +} + +%clickable-transition { + transition: all 0.3s ease-in-out; +} + +%no-cursor { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +%no-bottom-border { + border-bottom: none; +} + +%cursor-pointer { + cursor: pointer; +} + +%normal-font-style { + font-style: normal; +} + +%rounded { + border-radius: v.$radius-lg; +} + +%img-caption { + + em { + display: block; + text-align: center; + font-style: normal; + font-size: 80%; + padding: 0; + color: #6d6c6c; + } +} + +%sidebar-links { + color: var(--sidebar-muted-color); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +%text-clip { + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +%text-ellipsis { + @include mx.text-ellipsis; +} + +%text-highlight { + color: var(--text-muted-highlight-color); + font-weight: 600; +} + +%text-sm { + font-size: 0.85rem; +} + +%text-xs { + font-size: 0.8rem; +} + +%sup-fn-target { + &:target { + background-color: var(--footnote-target-bg); + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; + transition: background-color 1.75s ease-in-out; + } +} + +%btn-color { + button i { + color: #999999; + } +} + +%code-snippet-bg { + background-color: var(--highlight-bg-color); +} + +%code-snippet-padding { + padding-left: 1rem; + padding-right: 1.5rem; +} + +%max-w-100 { + max-width: 100%; +} + +%panel-border { + border-left: 1px solid var(--main-border-color); +} diff --git a/src/styles/abstracts/_variables.scss b/src/styles/abstracts/_variables.scss new file mode 100644 index 00000000000..0194e40baa3 --- /dev/null +++ b/src/styles/abstracts/_variables.scss @@ -0,0 +1,30 @@ +/* sidebar */ + +$sidebar-width: 260px !default; /* the basic width */ +$sidebar-width-large: 300px !default; /* screen width: >= 1650px */ +$sb-btn-gap: 0.8rem !default; +$sb-btn-gap-lg: 1rem !default; + +/* other framework sizes */ + +$topbar-height: 3rem !default; +$search-max-width: 200px !default; +$footer-height: 5rem !default; +$footer-height-large: 6rem !default; /* screen width: < 850px */ +$main-content-max-width: 1250px !default; +$radius-sm: 6px !default; +$radius-lg: 10px !default; +$back2top-size: 2.75rem !default; + +/* syntax highlight */ + +$code-font-size: 0.85rem !default; +$code-header-height: 2.25rem !default; +$code-dot-size: 0.75rem !default; +$code-dot-gap: 0.5rem !default; +$code-icon-width: 1.75rem !default; + +/* fonts */ + +$font-family-base: 'Source Sans Pro', 'Microsoft Yahei', sans-serif !default; +$font-family-heading: Lato, 'Microsoft Yahei', sans-serif !default; diff --git a/src/styles/base/_base.scss b/src/styles/base/_base.scss new file mode 100644 index 00000000000..b512a484cc2 --- /dev/null +++ b/src/styles/base/_base.scss @@ -0,0 +1,483 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/mixins' as mx; +@use '../abstracts/placeholders'; +@use '../themes/light'; +@use '../themes/dark'; + +:root { + font-size: 16px; +} + +html { + @media (prefers-color-scheme: light) { + &:not([data-mode]), + &[data-mode='light'] { + @include light.styles; + } + + &[data-mode='dark'] { + @include dark.styles; + } + } + + @media (prefers-color-scheme: dark) { + &:not([data-mode]), + &[data-mode='dark'] { + @include dark.styles; + } + + &[data-mode='light'] { + @include light.styles; + } + } + + @include bp.lg { + overflow-y: scroll; + } +} + +body { + background: var(--main-bg); + padding: env(safe-area-inset-top) env(safe-area-inset-right) + env(safe-area-inset-bottom) env(safe-area-inset-left); + color: var(--text-color); + -webkit-font-smoothing: antialiased; + font-family: v.$font-family-base; +} + +h1.dynamic-title { + @include bp.lt(bp.get(lg)) { + display: none; + + ~ .content { + margin-top: 2.5rem; + } + } +} + +main { + &.col-12 { + @include bp.xxxl { + padding-right: 4.5rem !important; + } + } +} + +.preview-img { + aspect-ratio: 40 / 21; + width: 100%; + height: 100%; + overflow: hidden; + + @extend %rounded; + + &:not(.no-bg) { + background: var(--img-bg); + } + + img { + height: 100%; + -o-object-fit: cover; + object-fit: cover; + + @extend %rounded; + + @at-root #post-list & { + width: 100%; + } + } +} + +.post-preview { + @extend %rounded; + + border: 0; + background: var(--card-bg); + box-shadow: var(--card-shadow); + + &::before { + @extend %rounded; + + content: ''; + width: 100%; + height: 100%; + position: absolute; + background-color: var(--card-hover-bg); + opacity: 0; + transition: opacity 0.35s ease-in-out; + } + + &:hover { + &::before { + opacity: 0.3; + } + } +} + +.post-meta { + @extend %text-sm; + + a { + &:not([class]):hover { + @extend %link-hover; + } + } + + em { + @extend %normal-font-style; + } +} + +.content { + font-size: 1.08rem; + margin-top: 2rem; + overflow-wrap: break-word; + + @include bp.xl { + font-size: 1.03rem; + } + + a { + &.popup { + @extend %no-cursor; + @extend %img-caption; + @include mx.mt-mb(0.5rem); + + cursor: zoom-in; + } + + &:not(.img-link) { + @extend %link-underline; + + &:hover { + @extend %link-hover; + } + } + } + + ol, + ul { + &:not([class]), + &.task-list { + -webkit-padding-start: 1.75rem; + padding-inline-start: 1.75rem; + + li { + margin: 0.25rem 0; + padding-left: 0.25rem; + } + + ol, + ul { + -webkit-padding-start: 1.25rem; + padding-inline-start: 1.25rem; + margin: 0.5rem 0; + } + } + } + + ul.task-list { + -webkit-padding-start: 1.25rem; + padding-inline-start: 1.25rem; + + li { + list-style-type: none; + padding-left: 0; + + /* checkbox icon */ + > i { + width: 2rem; + margin-left: -1.25rem; + color: var(--checkbox-color); + + &.checked { + color: var(--checkbox-checked-color); + } + } + + ul { + -webkit-padding-start: 1.75rem; + padding-inline-start: 1.75rem; + } + } + + input[type='checkbox'] { + margin: 0 0.5rem 0.2rem -1.3rem; + vertical-align: middle; + } + } /* ul */ + + dl > dd { + margin-left: 1rem; + } + + ::marker { + color: var(--text-muted-color); + } + + .table-wrapper > table { + @include bp.lg { + min-width: 70%; + } + } +} /* .content */ + +.tag:hover { + @extend %tag-hover; +} + +.post-tag { + display: inline-block; + min-width: 2rem; + text-align: center; + border-radius: 0.5rem; + border: 1px solid var(--btn-border-color); + padding: 0 0.4rem; + color: var(--text-muted-color); + line-height: 1.3rem; + + &:not(:last-child) { + margin-right: 0.2rem; + } +} + +.rounded-10 { + border-radius: 10px !important; +} + +.img-link { + color: transparent; + display: inline-flex; +} + +.shimmer { + overflow: hidden; + position: relative; + background: var(--img-bg); + + &::before { + content: ''; + position: absolute; + background: var(--shimmer-bg); + height: 100%; + width: 100%; + -webkit-animation: shimmer 1.3s infinite; + animation: shimmer 1.3s infinite; + } + + @-webkit-keyframes shimmer { + 0% { + transform: translateX(-100%); + } + + 100% { + transform: translateX(100%); + } + } + + @keyframes shimmer { + 0% { + transform: translateX(-100%); + } + + 100% { + transform: translateX(100%); + } + } +} + +.embed-video { + width: 100%; + height: 100%; + margin-bottom: 1rem; + aspect-ratio: 16 / 9; + + @extend %rounded; + + &.twitch { + aspect-ratio: 310 / 189; + } + + &.file { + display: block; + width: auto; + height: auto; + max-width: 100%; + max-height: 100%; + margin: auto; + margin-bottom: 0; + } + + @extend %img-caption; +} + +.embed-audio { + width: 100%; + + &.file { + display: block; + } + + &.spotify { + border-radius: 14px; + } + + @extend %img-caption; +} + +/* --- Effects classes --- */ + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.btn-box-shadow { + box-shadow: var(--card-shadow); +} + +/* overwrite bootstrap muted */ +.text-muted { + color: var(--text-muted-color) !important; +} + +/* Overwrite bootstrap tooltip */ +.tooltip-inner { + font-size: 0.7rem; + max-width: 220px; + text-align: left; +} + +/* Overwrite bootstrap outline button */ +.btn.btn-outline-primary { + &:not(.disabled):hover { + border-color: #007bff !important; + } +} + +.disabled { + color: rgb(206 196 196); + pointer-events: auto; + cursor: not-allowed; +} + +.hide-border-bottom { + border-bottom: none !important; +} + +.input-focus { + box-shadow: none; + border-color: var(--input-focus-border-color) !important; + background: center !important; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; +} + +.left { + float: left; + margin: 0.75rem 1rem 1rem 0; +} + +.right { + float: right; + margin: 0.75rem 0 1rem 1rem; +} + +/* --- Overriding --- */ + +/* mermaid */ +.mermaid { + text-align: center; +} + +/* MathJax */ +mjx-container { + overflow-y: hidden; + min-width: auto !important; +} + +@media (hover: hover) { + #sidebar ul > li:last-child::after { + transition: top 0.5s ease; + } + + .nav-link { + transition: background-color 0.3s ease-in-out; + } + + .post-preview { + transition: background-color 0.35s ease-in-out; + } +} + +#mask { + inset: 0 0 0 0; +} + +#main-wrapper { + position: relative; + + @include mx.pl-pr(0); + + @include bp.lt(bp.get(lg)) { + @include mx.slide; + } + + @include bp.lg { + margin-left: v.$sidebar-width; + } + + @include bp.xxxl { + margin-left: v.$sidebar-width-large; + } + + > .container { + min-height: 100vh; + + @include bp.lte(bp.get(md)) { + @include mx.max-w-100; + @include mx.pl-pr(0); + } + + @include bp.lt(bp.get(lg)) { + max-width: 100%; + } + + /* Pad horizontal */ + @include bp.between(992px, calc(#{bp.get(xl)} - 1px)) { + .col-lg-11 { + flex: 0 0 96%; + max-width: 96%; + } + } + + @include bp.lt(bp.get(xl)) { + > .row { + justify-content: center !important; + } + } + + @include bp.xxxl { + max-width: v.$main-content-max-width; + + @include mx.pl-pr(1.75rem, true); + } + } +} + +/* --- basic wrappers --- */ + +#topbar-wrapper.row, +#main-wrapper > .container > .row, +#search-result-wrapper > .row { + @include mx.ml-mr(0); +} + +#tail-wrapper { + @include bp.xxxl { + padding-right: 4.5rem !important; + } + + > :not(script) { + margin-top: 3rem; + } +} diff --git a/src/styles/base/_index.scss b/src/styles/base/_index.scss new file mode 100644 index 00000000000..611d28ff4ab --- /dev/null +++ b/src/styles/base/_index.scss @@ -0,0 +1,4 @@ +@forward 'reset'; +@forward 'base'; +@forward 'typography'; +@forward 'syntax'; diff --git a/src/styles/base/_reset.scss b/src/styles/base/_reset.scss new file mode 100644 index 00000000000..1e5a6294662 --- /dev/null +++ b/src/styles/base/_reset.scss @@ -0,0 +1,41 @@ +@use '../abstracts/mixins' as *; + +::-webkit-input-placeholder { + @include placeholder; +} + +::-moz-placeholder { + @include placeholder; +} + +:-ms-input-placeholder { + @include placeholder; +} + +::-ms-input-placeholder { + @include placeholder; +} + +::placeholder { + @include placeholder; +} + +:focus::-webkit-input-placeholder { + @include placeholder-focus; +} + +:focus::-moz-placeholder { + @include placeholder-focus; +} + +:focus:-ms-input-placeholder { + @include placeholder-focus; +} + +:focus::-ms-input-placeholder { + @include placeholder-focus; +} + +:focus::placeholder { + @include placeholder-focus; +} diff --git a/src/styles/base/_syntax.scss b/src/styles/base/_syntax.scss new file mode 100644 index 00000000000..34ddbe600f4 --- /dev/null +++ b/src/styles/base/_syntax.scss @@ -0,0 +1,252 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/mixins' as mx; +@use '../abstracts/placeholders'; + +.highlighter-rouge { + color: var(--highlighter-rouge-color); + margin-top: 0.5rem; + margin-bottom: 1.2em; /* Override BS Inline-code style */ +} + +.highlight { + @extend %rounded; + @extend %code-snippet-bg; + + overflow: auto; + padding-bottom: 0.75rem; + + @at-root figure#{&} { + @extend %code-snippet-bg; + } + + pre { + margin-bottom: 0; + font-size: v.$code-font-size; + line-height: 1.4rem; + } + + table { + td { + &:first-child { + display: inline-block; + margin-left: 1rem; + margin-right: 0.75rem; + } + + &:last-child { + padding-right: 2rem !important; + } + + pre { + overflow: visible; /* Fixed iOS safari overflow-x */ + word-break: normal; /* Fixed iOS safari linenos code break */ + } + } + } + + .lineno { + text-align: right; + color: var(--highlight-lineno-color); + -webkit-user-select: none; + -moz-user-select: none; + -o-user-select: none; + -ms-user-select: none; + user-select: none; + } +} /* .highlight */ + +code { + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + color: var(--code-color); + + &.highlighter-rouge { + font-size: v.$code-font-size; + padding: 3px 5px; + overflow-wrap: break-word; + border-radius: v.$radius-sm; + background-color: var(--inline-code-bg); + } + + &.filepath { + background-color: inherit; + color: var(--filepath-text-color); + font-weight: 600; + padding: 0; + } + + a > &.highlighter-rouge { + padding-bottom: 0; /* show link's underlinke */ + color: inherit; + } + + a:hover > &.highlighter-rouge { + border-bottom: none; + } + + blockquote & { + color: inherit; + } +} + +td.rouge-code { + @extend %code-snippet-padding; + + /* + Prevent some browser extends from + changing the URL string of code block. + */ + a { + color: inherit !important; + border-bottom: none !important; + pointer-events: none; + } +} + +div[class^='language-'] { + @extend %rounded; + @extend %code-snippet-bg; + + box-shadow: var(--language-border-color) 0 0 0 1px; + + .content > & { + @include mx.ml-mr(-1rem); + + border-radius: 0; + + @include bp.sm { + @include mx.ml-mr(0); + + border-radius: v.$radius-lg; + } + } + + .code-header { + @include bp.sm { + @include mx.ml-mr(0); + + $dot-margin: 1rem; + + &::before { + content: ''; + display: inline-block; + margin-left: $dot-margin; + width: v.$code-dot-size; + height: v.$code-dot-size; + border-radius: 50%; + background-color: var(--code-header-muted-color); + box-shadow: (v.$code-dot-size + v.$code-dot-gap) 0 0 + var(--code-header-muted-color), + (v.$code-dot-size + v.$code-dot-gap) * 2 0 0 + var(--code-header-muted-color); + } + + span { + // center the text of label + margin-left: calc(($dot-margin + v.$code-dot-size) / 2 * -1); + } + } + } + + .highlight { + border-top-left-radius: 0; + border-top-right-radius: 0; + } +} + +/* Hide line numbers for default, console, and terminal code snippets */ +div { + &.nolineno, + &.language-plaintext, + &.language-console, + &.language-terminal { + td:first-child { + padding: 0 !important; + margin-right: 0; + + .lineno { + display: none; + } + } + } +} + +.code-header { + @extend %no-cursor; + + display: flex; + justify-content: space-between; + align-items: center; + height: v.$code-header-height; + margin-left: 0.75rem; + margin-right: 0.25rem; + + /* the label block */ + span { + line-height: v.$code-header-height; + + /* label icon */ + i { + font-size: 1rem; + width: v.$code-icon-width; + color: var(--code-header-icon-color); + + &.small { + font-size: 70%; + } + } + + @at-root [file] #{&} > i { + position: relative; + top: 1px; /* center the file icon */ + } + + /* label text */ + &::after { + content: attr(data-label-text); + font-size: 0.85rem; + font-weight: 600; + color: var(--code-header-text-color); + } + } + + /* clipboard */ + button { + @extend %cursor-pointer; + @extend %rounded; + + border: 1px solid transparent; + height: v.$code-header-height; + width: v.$code-header-height; + padding: 0; + background-color: inherit; + + i { + color: var(--code-header-icon-color); + } + + &[timeout] { + &:hover { + border-color: var(--clipboard-checked-color); + } + + i { + color: var(--clipboard-checked-color); + } + } + + &:focus { + outline: none; + } + + &:not([timeout]):hover { + background-color: rgb(128 128 128 / 37%); + + i { + color: white; + } + } + } +} diff --git a/src/styles/base/_typography.scss b/src/styles/base/_typography.scss new file mode 100644 index 00000000000..8b679726e91 --- /dev/null +++ b/src/styles/base/_typography.scss @@ -0,0 +1,264 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/mixins' as mx; +@use '../abstracts/placeholders'; + +@for $i from 1 through 5 { + h#{$i} { + @extend %heading; + + @if $i > 1 { + @extend %anchor; + } + + @if $i < 5 { + $size-factor: 0.25rem; + + @if $i > 1 { + $size-factor: 0.18rem; + + main & { + @if $i == 2 { + margin: 2.5rem 0 1.25rem; + } @else { + margin: 2rem 0 1rem; + } + } + } + + font-size: 1rem + (5 - $i) * $size-factor; + } @else { + font-size: 1.05rem; + } + } +} + +a { + @extend %link-color; + + text-decoration: none; +} + +img { + max-width: 100%; + height: auto; + transition: all 0.35s ease-in-out; + + .blur & { + $blur: 20px; + + -webkit-filter: blur($blur); + filter: blur($blur); + } +} + +blockquote { + border-left: 0.125rem solid var(--blockquote-border-color); + padding-left: 1rem; + color: var(--blockquote-text-color); + margin-top: 0.5rem; + + > p:last-child { + margin-bottom: 0; + } + + &[class^='prompt-'] { + border-left: 0; + position: relative; + padding: 1rem 1rem 1rem 3rem; + color: var(--prompt-text-color); + + @extend %rounded; + + &::before { + text-align: center; + width: 3rem; + position: absolute; + left: 0.25rem; + margin-top: 0.4rem; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + } + } + + @include mx.prompt('tip', '\f0eb', $fa-style: 'regular'); + @include mx.prompt('info', '\f06a', $rotate: 180); + @include mx.prompt('warning', '\f06a'); + @include mx.prompt('danger', '\f071'); +} + +kbd { + font-family: Lato, sans-serif; + display: inline-block; + vertical-align: middle; + line-height: 1.3rem; + min-width: 1.75rem; + text-align: center; + margin: 0 0.3rem; + padding-top: 0.1rem; + color: var(--kbd-text-color); + background-color: var(--kbd-bg-color); + border-radius: v.$radius-sm; + border: solid 1px var(--kbd-wrap-color); + box-shadow: inset 0 -2px 0 var(--kbd-wrap-color); +} + +hr { + border-color: var(--main-border-color); + opacity: 1; +} + +footer { + background-color: var(--main-bg); + height: v.$footer-height; + border-top: 1px solid var(--main-border-color); + + @extend %text-xs; + + a { + @extend %text-highlight; + + &:hover { + @extend %link-hover; + } + } + + em { + @extend %text-highlight; + } + + p { + text-align: center; + margin-bottom: 0; + } +} + +/* fontawesome icons */ +i { + &.far, + &.fas { + @extend %no-cursor; + } +} + +sup { + @extend %sup-fn-target; +} + +main { + line-height: 1.75; + + h1 { + margin-top: 2rem; + + @include bp.lg { + margin-top: 3rem; + } + } + + p { + > a.popup { + &:not(.normal):not(.left):not(.right) { + @include mx.align-center; + } + } + } + + .categories, + #tags, + #archives { + a:not(:hover) { + @extend %no-bottom-border; + } + } + + @include bp.lte(bp.get(sm)) { + .content { + > blockquote[class^='prompt-'] { + @include mx.ml-mr(-1rem); + + border-radius: 0; + max-width: none; + } + } + } +} + +.footnotes > ol { + padding-left: 2rem; + margin-top: 0.5rem; + + > li { + &:not(:last-child) { + margin-bottom: 0.3rem; + } + + @extend %sup-fn-target; + + > p { + margin-left: 0.25em; + + @include mx.mt-mb(0); + } + } +} + +.footnote { + @at-root a#{&} { + @include mx.ml-mr(1px); + @include mx.pl-pr(2px); + + border-bottom-style: none !important; + } +} + +.reversefootnote { + @at-root a#{&} { + font-size: 0.6rem; + line-height: 1; + position: relative; + bottom: 0.25em; + margin-left: 0.25em; + border-bottom-style: none !important; + } +} + +/* --- Begin of Markdown table style --- */ + +/* it will be created by Liquid */ +.table-wrapper { + overflow-x: auto; + margin-bottom: 1.5rem; + + > table { + min-width: 100%; + overflow-x: auto; + border-spacing: 0; + + thead { + border-bottom: solid 2px rgb(210 215 217 / 75%); + + th { + @extend %table-cell; + } + } + + tbody { + tr { + border-bottom: 1px solid var(--tb-border-color); + + &:nth-child(2n) { + background-color: var(--tb-even-bg); + } + + &:nth-child(2n + 1) { + background-color: var(--tb-odd-bg); + } + + td { + @extend %table-cell; + } + } + } /* tbody */ + } /* table */ +} diff --git a/src/styles/components/_buttons.scss b/src/styles/components/_buttons.scss new file mode 100644 index 00000000000..bd7363e5586 --- /dev/null +++ b/src/styles/components/_buttons.scss @@ -0,0 +1,51 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/breakpoints' as bp; + +#back-to-top { + visibility: hidden; + opacity: 0; + z-index: 1; + cursor: pointer; + position: fixed; + right: 1rem; + bottom: calc(v.$footer-height-large - v.$back2top-size / 2); + background: var(--button-bg); + color: var(--btn-backtotop-color); + padding: 0; + width: v.$back2top-size; + height: v.$back2top-size; + border-radius: 50%; + border: 1px solid var(--btn-backtotop-border-color); + transition: opacity 0.5s ease-in-out, transform 0.2s ease-out; + + @include bp.lg { + right: 5%; + bottom: calc(v.$footer-height - v.$back2top-size / 2); + } + + @include bp.xxl { + right: calc((100vw - v.$sidebar-width - 1140px) / 2 + 3rem); + } + + @include bp.xxxl { + right: calc( + (100vw - v.$sidebar-width-large - v.$main-content-max-width) / 2 + 2rem + ); + } + + &:hover { + transform: translate3d(0, -5px, 0); + -webkit-transform: translate3d(0, -5px, 0); + } + + i { + line-height: v.$back2top-size; + position: relative; + bottom: 2px; + } + + &.show { + opacity: 1; + visibility: visible; + } +} diff --git a/src/styles/components/_index.scss b/src/styles/components/_index.scss new file mode 100644 index 00000000000..ffbb9083479 --- /dev/null +++ b/src/styles/components/_index.scss @@ -0,0 +1,2 @@ +@forward 'buttons'; +@forward 'popups'; diff --git a/src/styles/components/_popups.scss b/src/styles/components/_popups.scss new file mode 100644 index 00000000000..e94fcde368f --- /dev/null +++ b/src/styles/components/_popups.scss @@ -0,0 +1,172 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/placeholders'; + +/* PWA update popup */ +#notification { + @-webkit-keyframes popup { + from { + opacity: 0; + bottom: 0; + } + } + + @keyframes popup { + from { + opacity: 0; + bottom: 0; + } + } + + .toast-header { + background: none; + border-bottom: none; + color: inherit; + } + + .toast-body { + font-family: Lato, sans-serif; + line-height: 1.25rem; + + button { + font-size: 90%; + min-width: 4rem; + } + } + + &.toast { + &.show { + display: block; + min-width: 20rem; + border-radius: 0.5rem; + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); + background-color: rgb(255 255 255 / 50%); + color: #1b1b1eba; + position: fixed; + left: 50%; + bottom: 20%; + transform: translateX(-50%); + -webkit-animation: popup 0.8s; + animation: popup 0.8s; + } + } +} + +#toc-popup { + $slide-in: slide-in 0.3s ease-out; + $slide-out: slide-out 0.3s ease-out; + $curtain-height: 2rem; + $backdrop: blur(5px); + + border-color: var(--toc-popup-border-color); + border-width: 1px; + border-radius: v.$radius-lg; + color: var(--text-color); + background: var(--card-bg); + margin-top: v.$topbar-height; + min-width: 20rem; + font-size: 1.05rem; + + @include bp.sm { + max-width: 32rem; + } + + &[open] { + -webkit-animation: $slide-in; + animation: $slide-in; + } + + &[closing] { + -webkit-animation: $slide-out; + animation: $slide-out; + } + + @include bp.lg { + left: v.$sidebar-width; + } + + .header { + @extend %btn-color; + + position: -webkit-sticky; + position: sticky; + top: 0; + background-color: inherit; + border-bottom: 1px solid var(--main-border-color); + + .label { + font-family: v.$font-family-heading; + } + } + + button { + > i { + font-size: 1.25rem; + vertical-align: middle; + } + + &:focus-visible { + box-shadow: none; + } + } + + ul { + list-style-type: none; + padding-left: 0; + + li { + ul, + & + li { + margin-top: 0.25rem; + } + + a { + display: flex; + line-height: 1.5; + padding: 0.375rem 0; + padding-right: 1.125rem; + + &.toc-link::before { + display: none; + } + } + } + } + + @for $i from 2 through 4 { + .node-name--H#{$i} { + padding-left: 1.125rem * ($i - 1); + } + } + + .is-active-link { + color: var(--toc-highlight) !important; + font-weight: 600; + } + + &::-webkit-backdrop { + -webkit-backdrop-filter: $backdrop; + backdrop-filter: $backdrop; + } + + &::backdrop { + -webkit-backdrop-filter: $backdrop; + backdrop-filter: $backdrop; + } + + &::after { + display: flex; + content: ''; + position: relative; + background: linear-gradient(transparent, var(--card-bg) 70%); + height: $curtain-height; + } + + #toc-popup-content { + overflow: auto; + max-height: calc(100vh - 4 * v.$topbar-height); + font-family: v.$font-family-heading; + margin-bottom: -$curtain-height; + } +} diff --git a/src/styles/layout/_footer.scss b/src/styles/layout/_footer.scss new file mode 100644 index 00000000000..fd49ea041f2 --- /dev/null +++ b/src/styles/layout/_footer.scss @@ -0,0 +1,36 @@ +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/variables' as v; +@use '../abstracts/mixins' as mx; +@use '../abstracts/placeholders'; + +footer { + background-color: var(--main-bg); + height: v.$footer-height; + border-top: 1px solid var(--main-border-color); + + @extend %text-xs; + + @include bp.lt(bp.get(lg)) { + @include mx.slide; + + height: v.$footer-height-large; + padding: 1.5rem 0; + } + + a { + @extend %text-highlight; + + &:hover { + @extend %link-hover; + } + } + + em { + @extend %text-highlight; + } + + p { + text-align: center; + margin-bottom: 0; + } +} diff --git a/src/styles/layout/_index.scss b/src/styles/layout/_index.scss new file mode 100644 index 00000000000..fa75daf9377 --- /dev/null +++ b/src/styles/layout/_index.scss @@ -0,0 +1,4 @@ +@forward 'sidebar'; +@forward 'topbar'; +@forward 'panel'; +@forward 'footer'; diff --git a/src/styles/layout/_panel.scss b/src/styles/layout/_panel.scss new file mode 100644 index 00000000000..c0d5e9ebc57 --- /dev/null +++ b/src/styles/layout/_panel.scss @@ -0,0 +1,70 @@ +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/mixins' as mx; +@use '../abstracts/placeholders'; + +.access { + top: 2rem; + transition: top 0.2s ease-in-out; + margin-top: 3rem; + + &:only-child { + position: -webkit-sticky; + position: sticky; + } + + > section { + @extend %panel-border; + + padding-left: 1rem; + + &:not(:first-child) { + margin-top: 4rem; + } + } + + .content { + font-size: 0.9rem; + } +} + +#panel-wrapper { + /* the headings */ + .panel-heading { + font-family: inherit; + line-height: inherit; + + @include mx.label(inherit); + } + + .post-tag { + line-height: 1.05rem; + font-size: 0.85rem; + border-radius: 0.8rem; + padding: 0.3rem 0.5rem; + margin: 0 0.35rem 0.5rem 0; + + &:hover { + transition: all 0.3s ease-in; + } + } + + > :last-child { + margin-bottom: 4rem; + } + + @include bp.lt(bp.get(xl)) { + display: none; + } +} + +#access-lastmod { + a { + color: inherit; + + &:hover { + @extend %link-hover; + } + + @extend %no-bottom-border; + } +} diff --git a/src/styles/layout/_sidebar.scss b/src/styles/layout/_sidebar.scss new file mode 100644 index 00000000000..eaad470c6c4 --- /dev/null +++ b/src/styles/layout/_sidebar.scss @@ -0,0 +1,258 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/mixins' as mx; +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/placeholders'; + +$btn-border-width: 3px; +$btn-mb: 0.5rem; +$sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */ + +#sidebar { + @include mx.pl-pr(0); + + position: fixed; + top: 0; + left: 0; + height: 100%; + overflow-y: auto; + width: v.$sidebar-width; + background: var(--sidebar-bg); + border-right: 1px solid var(--sidebar-border-color); + + /* Hide scrollbar for IE, Edge and Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ + + /* Hide scrollbar for Chrome, Safari and Opera */ + &::-webkit-scrollbar { + display: none; + } + + @include bp.lt(bp.get(lg)) { + @include mx.slide; + + transform: translateX(-#{v.$sidebar-width}); /* hide */ + -webkit-transform: translateX(-#{v.$sidebar-width}); + + [#{$sidebar-display}] & { + transform: translateX(0); + } + } + + @include bp.xxxl { + width: v.$sidebar-width-large; + } + + %sidebar-link-hover { + &:hover { + color: var(--sidebar-active-color); + } + } + + a { + @extend %sidebar-links; + } + + #avatar { + display: block; + width: 6.5rem; + height: 6.5rem; + overflow: hidden; + box-shadow: var(--avatar-border-color) 0 0 0 2px; + transform: translateZ(0); /* fixed the zoom in Safari */ + + @include bp.sm { + width: 7rem; + height: 7rem; + } + + img { + transition: transform 0.5s; + + &:hover { + transform: scale(1.2); + } + } + } + + .profile-wrapper { + @include mx.mt-mb(2.5rem); + @extend %clickable-transition; + + padding-left: 2.5rem; + padding-right: 1.25rem; + width: 100%; + + @include bp.lg { + margin-top: 3rem; + } + + @include bp.xxxl { + margin-top: 3.5rem; + margin-bottom: 2.5rem; + padding-left: 3.5rem; + } + } + + .site-title { + @extend %clickable-transition; + @extend %sidebar-link-hover; + + font-family: inherit; + font-weight: 900; + font-size: 1.75rem; + line-height: 1.2; + letter-spacing: 0.25px; + margin-top: 1.25rem; + margin-bottom: 0.5rem; + width: fit-content; + color: var(--site-title-color); + } + + .site-subtitle { + font-size: 95%; + color: var(--site-subtitle-color); + margin-top: 0.25rem; + word-spacing: 1px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + ul { + margin-bottom: 2rem; + + li.nav-item { + opacity: 0.9; + width: 100%; + + @include mx.pl-pr(1.5rem); + + @include bp.xxxl { + @include mx.pl-pr(2.75rem); + } + + a.nav-link { + @include mx.pt-pb(0.6rem); + + display: flex; + align-items: center; + border-radius: 0.75rem; + font-weight: 600; + + &:hover { + background-color: var(--sidebar-hover-bg); + } + + i { + font-size: 95%; + opacity: 0.8; + margin-right: 1.5rem; + } + + span { + font-size: 90%; + letter-spacing: 0.2px; + } + } + + &.active { + .nav-link { + color: var(--sidebar-active-color); + background-color: var(--sidebar-hover-bg); + + span { + opacity: 1; + } + } + } + + &:not(:first-child) { + margin-top: 0.25rem; + } + } + } + + .sidebar-bottom { + padding-left: 2rem; + padding-right: 1rem; + margin-bottom: 1.5rem; + + @include bp.xxxl { + padding-left: 2.75rem; + margin-bottom: 1.75rem; + } + + $btn-size: 1.75rem; + + %button { + width: $btn-size; + height: $btn-size; + margin-bottom: $btn-mb; // multi line gap + border-radius: 50%; + color: var(--sidebar-btn-color); + background-color: var(--sidebar-btn-bg); + text-align: center; + display: flex; + align-items: center; + justify-content: center; + + &:not(:focus-visible) { + box-shadow: var(--sidebar-border-color) 0 0 0 1px; + } + + &:hover { + background-color: var(--sidebar-hover-bg); + } + } + + a { + @extend %button; + @extend %sidebar-link-hover; + @extend %clickable-transition; + + &:not(:last-child) { + margin-right: v.$sb-btn-gap; + + @include bp.xxxl { + margin-right: v.$sb-btn-gap-lg; + } + } + } + + i { + line-height: $btn-size; + } + + #mode-toggle { + @extend %button; + @extend %sidebar-links; + @extend %sidebar-link-hover; + } + + .icon-border { + @extend %no-cursor; + @include mx.ml-mr(calc((v.$sb-btn-gap - $btn-border-width) / 2)); + + background-color: var(--sidebar-btn-color); + content: ''; + width: $btn-border-width; + height: $btn-border-width; + border-radius: 50%; + margin-bottom: $btn-mb; + + @include bp.xxxl { + @include mx.ml-mr(calc((v.$sb-btn-gap-lg - $btn-border-width) / 2)); + } + } + } /* .sidebar-bottom */ +} /* #sidebar */ + +[#{$sidebar-display}] { + #main-wrapper { + @include bp.lt(bp.get(lg)) { + transform: translateX(v.$sidebar-width); + } + } +} diff --git a/src/styles/layout/_topbar.scss b/src/styles/layout/_topbar.scss new file mode 100644 index 00000000000..eb0aea9b0ca --- /dev/null +++ b/src/styles/layout/_topbar.scss @@ -0,0 +1,86 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/mixins' as mx; +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/placeholders'; + +#topbar-wrapper { + height: v.$topbar-height; + background-color: var(--topbar-bg); + + @include bp.lt(bp.get(lg)) { + @include mx.slide(top 0.2s ease); + + left: 0; + } +} + +#topbar { + @extend %btn-color; + + #breadcrumb { + font-size: 1rem; + color: var(--text-muted-color); + padding-left: 0.5rem; + + a:hover { + @extend %link-hover; + } + + span { + &:not(:last-child) { + &::after { + content: '›'; + padding: 0 0.3rem; + } + } + } + + @include bp.lt(bp.get(lg)) { + display: none; + } + + @include bp.between(bp.get(lg), calc(#{bp.get(xl)} - 1px)) { + width: 65%; + overflow: hidden; + text-overflow: ellipsis; + word-break: keep-all; + white-space: nowrap; + } + } + + @include bp.lte(bp.get(md)) { + @include mx.max-w-100; + } + + @include bp.lt(bp.get(lg)) { + max-width: 100%; + } +} + +#topbar-title { + display: none; + font-size: 1.1rem; + font-weight: 600; + font-family: sans-serif; + color: var(--topbar-text-color); + text-align: center; + width: 70%; + word-break: keep-all; + + @include bp.lt(bp.get(lg)) { + display: block; + } + + @include bp.lg { + text-align: left; + } +} + +#sidebar-trigger, +#search-trigger { + display: none; + + @include bp.lt(bp.get(lg)) { + display: block; + } +} diff --git a/src/styles/main.bundle.scss b/src/styles/main.bundle.scss new file mode 100644 index 00000000000..5d84f938ec6 --- /dev/null +++ b/src/styles/main.bundle.scss @@ -0,0 +1,2 @@ +@use 'vendors/bootstrap'; +@use 'main'; diff --git a/src/styles/main.scss b/src/styles/main.scss new file mode 100644 index 00000000000..3bbb70d6515 --- /dev/null +++ b/src/styles/main.scss @@ -0,0 +1,4 @@ +@forward 'base'; +@forward 'components'; +@forward 'layout'; +@forward 'pages'; diff --git a/src/styles/pages/_archives.scss b/src/styles/pages/_archives.scss new file mode 100644 index 00000000000..86e77a89b48 --- /dev/null +++ b/src/styles/pages/_archives.scss @@ -0,0 +1,140 @@ +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/placeholders'; + +#archives { + letter-spacing: 0.03rem; + + @include bp.lt(bp.get(sm)) { + margin-top: -1rem; + + ul { + letter-spacing: 0; + } + } + + $timeline-width: 4px; + + %timeline { + content: ''; + width: $timeline-width; + position: relative; + float: left; + background-color: var(--timeline-color); + } + + .year { + height: 3.5rem; + font-size: 1.5rem; + position: relative; + left: 2px; + margin-left: -$timeline-width; + + &::before { + @extend %timeline; + + height: 72px; + left: 79px; + bottom: 16px; + } + + &:first-child::before { + @extend %timeline; + + height: 32px; + top: 24px; + } + + /* Year dot */ + &::after { + content: ''; + display: inline-block; + position: relative; + border-radius: 50%; + width: 12px; + height: 12px; + left: 21.5px; + border: 3px solid; + background-color: var(--timeline-year-dot-color); + border-color: var(--timeline-node-bg); + box-shadow: 0 0 2px 0 #c2c6cc; + z-index: 1; + } + } + + ul { + li { + font-size: 1.1rem; + line-height: 3rem; + + @extend %text-ellipsis; + + &:nth-child(odd) { + background-color: var(--main-bg, #ffffff); + background-image: linear-gradient( + to left, + #ffffff, + #fbfbfb, + #fbfbfb, + #fbfbfb, + #ffffff + ); + } + + &::before { + @extend %timeline; + + top: 0; + left: 77px; + height: 3.1rem; + } + } + + &:last-child li:last-child::before { + height: 1.5rem; + } + } /* #archives ul */ + + .date { + white-space: nowrap; + display: inline-block; + position: relative; + right: 0.5rem; + + &.month { + width: 1.4rem; + text-align: center; + } + + &.day { + font-size: 85%; + font-family: Lato, sans-serif; + } + } + + a { + /* post title in Archvies */ + margin-left: 2.5rem; + position: relative; + top: 0.1rem; + + &:hover { + border-bottom: none; + } + + &::before { + /* the dot before post title */ + content: ''; + display: inline-block; + position: relative; + border-radius: 50%; + width: 8px; + height: 8px; + float: left; + top: 1.35rem; + left: 71px; + background-color: var(--timeline-node-bg); + box-shadow: 0 0 3px 0 #c2c6cc; + z-index: 1; + } + } +} /* #archives */ diff --git a/src/styles/pages/_categories.scss b/src/styles/pages/_categories.scss new file mode 100644 index 00000000000..64a2df500c5 --- /dev/null +++ b/src/styles/pages/_categories.scss @@ -0,0 +1,82 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/placeholders'; + +%-category-icon-color { + color: gray; +} + +.categories { + margin-bottom: 2rem; + border-color: var(--categories-border); + + &.card, + .list-group { + @extend %rounded; + } + + .card-header { + $radius: calc(v.$radius-lg - 1px); + + padding: 0.75rem; + border-radius: $radius; + border-bottom: 0; + + &.hide-border-bottom { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + } + + i { + @extend %-category-icon-color; + + font-size: 86%; /* fontawesome icons */ + } + + .list-group-item { + border-left: none; + border-right: none; + padding-left: 2rem; + + &:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + &:last-child { + border-bottom: 0; + } + } +} /* .categories */ + +.category-trigger { + width: 1.7rem; + height: 1.7rem; + border-radius: 50%; + text-align: center; + color: #6c757d !important; + + i { + position: relative; + height: 0.7rem; + width: 1rem; + transition: transform 300ms ease; + } + + &:hover { + i { + color: var(--categories-icon-hover-color); + } + } +} + +/* only works on desktop */ +@media (hover: hover) { + .category-trigger:hover { + background-color: var(--categories-hover-bg); + } +} + +.rotate { + transform: rotate(-90deg); +} diff --git a/src/styles/pages/_category-tag.scss b/src/styles/pages/_category-tag.scss new file mode 100644 index 00000000000..0a827121bad --- /dev/null +++ b/src/styles/pages/_category-tag.scss @@ -0,0 +1,63 @@ +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/mixins' as mx; +@use '../abstracts/placeholders'; + +.dash { + margin: 0 0.5rem 0.6rem 0.5rem; + border-bottom: 2px dotted var(--dash-color); +} + +#page-category, +#page-tag { + ul > li { + line-height: 1.5rem; + padding: 0.6rem 0; + + /* dot */ + &::before { + background: #999999; + width: 5px; + height: 5px; + border-radius: 50%; + display: block; + content: ''; + position: relative; + top: 0.6rem; + margin-right: 0.5rem; + + @include bp.lt(bp.get(sm)) { + margin: 0 0.5rem; + } + } + + /* post's title */ + > a { + @extend %no-bottom-border; + + font-size: 1.1rem; + + @include bp.lt(bp.get(sm)) { + @include mx.text-ellipsis; + } + } + } +} + +/* tag icon */ +#page-tag h1 > i { + font-size: 1.2rem; +} + +#page-category h1 > i { + font-size: 1.25rem; +} + +#page-category, +#page-tag, +#access-lastmod { + a:hover { + @extend %link-hover; + + margin-bottom: -1px; /* Avoid jumping */ + } +} diff --git a/src/styles/pages/_home.scss b/src/styles/pages/_home.scss new file mode 100644 index 00000000000..84f4b4aae5b --- /dev/null +++ b/src/styles/pages/_home.scss @@ -0,0 +1,170 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/placeholders'; + +#post-list { + margin-top: 2rem; + + @include bp.lg { + margin-top: 2.5rem; + } + + .card-wrapper { + &:hover { + text-decoration: none; + } + + &:not(:last-child) { + margin-bottom: 1.25rem; + } + } + + .card { + border: 0; + background: none; + + %img-radius { + border-radius: v.$radius-lg v.$radius-lg 0 0; + + @include bp.md { + border-radius: 0 v.$radius-lg v.$radius-lg 0; + } + } + + .preview-img { + @extend %img-radius; + + img { + @extend %img-radius; + } + } + + .card-body { + height: 100%; + padding: 1rem; + + @include bp.md { + padding: 1.75rem 1.75rem 1.25rem; + } + + .card-title { + @extend %text-clip; + + color: var(--heading-color) !important; + font-size: 1.25rem; + } + + %muted { + color: var(--text-muted-color) !important; + } + + .card-text { + @include bp.md { + display: inherit !important; + } + + &.content { + @extend %muted; + + p { + @extend %text-clip; + + line-height: 1.5; + margin: 0; + } + } + } + + .post-meta { + @extend %muted; + + i { + &:not(:first-child) { + margin-left: 1.5rem; + + @include bp.md { + margin-left: 1.75rem; + } + } + } + + em { + @extend %normal-font-style; + + color: inherit; + } + + > div:first-child { + display: block; + + @extend %text-ellipsis; + } + } + } + } +} /* #post-list */ + +.pagination { + color: var(--text-color); + font-family: Lato, sans-serif; + justify-content: space-evenly; + + @include bp.lg { + font-size: 0.85rem; + justify-content: center; + } + + a:hover { + text-decoration: none; + } + + .page-item { + @include bp.lt(bp.get(lg)) { + &:not(:first-child):not(:last-child) { + display: none; + } + } + + @include bp.lg { + &:not(:last-child) { + margin-right: 0.7rem; + } + } + + .page-link { + color: var(--btn-patinator-text-color); + padding: 0 0.6rem; + border-radius: 0.5rem; + border: 0; + background-color: inherit; + } + + &.active { + .page-link { + background-color: var(--btn-paginator-hover-color); + } + } + + &:not(.active) { + .page-link { + &:hover { + box-shadow: inset var(--btn-border-color) 0 0 0 1px; + } + } + } + + &.disabled { + cursor: not-allowed; + + .page-link { + color: rgb(108 117 125 / 57%); + } + } + } /* .page-item */ + + .page-index { + @include bp.lg { + display: none; + } + } +} diff --git a/src/styles/pages/_index.scss b/src/styles/pages/_index.scss new file mode 100644 index 00000000000..74e9ea6eb55 --- /dev/null +++ b/src/styles/pages/_index.scss @@ -0,0 +1,7 @@ +@forward 'search'; +@forward 'home'; +@forward 'post'; +@forward 'categories'; +@forward 'tags'; +@forward 'archives'; +@forward 'category-tag'; diff --git a/src/styles/pages/_post.scss b/src/styles/pages/_post.scss new file mode 100644 index 00000000000..2cd3eee3352 --- /dev/null +++ b/src/styles/pages/_post.scss @@ -0,0 +1,496 @@ +@use '../abstracts/variables' as v; +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/mixins' as mx; +@use '../abstracts/placeholders'; + +%-btn-post-nav { + width: 50%; + position: relative; + border-color: var(--btn-border-color); +} + +@mixin -dot($pl: 0.25rem, $pr: 0.25rem) { + content: '\2022'; + padding-left: $pl; + padding-right: $pr; +} + +header { + .post-desc { + @extend %heading; + + font-size: 1.125rem; + line-height: 1.6; + } + + .post-meta { + span + span::before { + @include -dot; + } + + em, + time { + @extend %text-highlight; + } + + em { + a { + color: inherit; + } + } + } + + h1 + .post-meta { + margin-top: 1.5rem; + } +} + +.post-tail-wrapper { + @extend %text-sm; + + margin-top: 6rem; + border-bottom: 1px double var(--main-border-color); + + .license-wrapper { + line-height: 1.2rem; + + > a { + @extend %text-highlight; + + &:hover { + @extend %link-hover; + } + } + + span:last-child { + @extend %text-sm; + } + } /* .license-wrapper */ + + .post-meta a:not(:hover) { + @extend %link-underline; + } + + .share-wrapper { + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + %icon-size { + font-size: 1.125rem; + } + + .share-icons { + display: flex; + + i { + color: var(--btn-share-color); + + @extend %icon-size; + } + + > * { + @extend %icon-size; + + margin-left: 0.5rem; + + &:hover { + i { + @extend %btn-share-hover; + } + } + } + + button { + padding: 0; + border: none; + line-height: inherit; + + @extend %cursor-pointer; + } + } /* .share-icons */ + } /* .share-wrapper */ +} + +.post-tail-bottom { + @include bp.lte(bp.get(sm)) { + flex-wrap: wrap-reverse !important; + + > div:first-child { + width: 100%; + margin-top: 1rem; + } + } +} + +.share-mastodon { + /* See: https://github.com/justinribeiro/share-to-mastodon#properties */ + --wc-stm-font-family: v.$font-family-base; + --wc-stm-dialog-background-color: var(--card-bg); + --wc-stm-form-button-border: 1px solid var(--btn-border-color); + --wc-stm-form-submit-background-color: var(--sidebar-btn-bg); + --wc-stm-form-cancel-background-color: var(--sidebar-btn-bg); + --wc-stm-form-button-background-color-hover: #007bff; + --wc-stm-form-button-color-hover: white; + + font-size: 1rem; +} + +.post-tags { + line-height: 2rem; + + .post-tag { + &:hover { + @extend %tag-hover; + } + } +} + +.post-navigation { + @include bp.lt(bp.get(lg)) { + @include mx.pl-pr(0); + @include mx.ml-mr(-0.5rem); + } + + .btn { + @extend %-btn-post-nav; + + &:not(:hover) { + color: var(--link-color); + } + + &:hover { + &:not(.disabled)::before { + color: whitesmoke; + } + } + + &.disabled { + @extend %-btn-post-nav; + + pointer-events: auto; + cursor: not-allowed; + background: none; + color: gray; + } + + &.btn-outline-primary.disabled:focus { + box-shadow: none; + } + + &::before { + color: var(--text-muted-color); + font-size: 0.65rem; + text-transform: uppercase; + content: attr(aria-label); + } + + &:first-child { + border-radius: v.$radius-lg 0 0 v.$radius-lg; + left: 0.5px; + } + + &:last-child { + border-radius: 0 v.$radius-lg v.$radius-lg 0; + right: 0.5px; + } + } + + p { + font-size: 1.1rem; + line-height: 1.5rem; + margin-top: 0.3rem; + white-space: normal; + } +} /* .post-navigation */ + +@media (hover: hover) { + .post-navigation { + .btn, + .btn::before { + transition: all 0.35s ease-in-out; + } + } +} + +@-webkit-keyframes fade-up { + from { + opacity: 0; + margin-top: 4rem; + } + + to { + opacity: 1; + } +} + +@keyframes fade-up { + from { + opacity: 0; + margin-top: 4rem; + } + + to { + opacity: 1; + } +} + +/* TOC panel */ + +%top-cover { + content: ''; + display: block; + position: -webkit-sticky; + position: sticky; + top: 0; + width: 100%; + height: 3rem; + background: linear-gradient(var(--main-bg) 50%, transparent); +} + +#toc-wrapper { + top: 0; + transition: top 0.2s ease-in-out; + overflow-y: auto; + max-height: 100vh; + scrollbar-width: none; + margin-top: 2rem; + + &:not(.invisible) { + -webkit-animation: fade-up 0.8s; + animation: fade-up 0.8s; + } + + ul { + list-style: none; + font-size: 0.85rem; + line-height: 1.25; + padding-left: 0; + + li { + a { + padding: 0.4rem 0 0.4rem 1.25rem; + } + } + + /* Overwrite TOC plugin style */ + + .toc-link { + display: block; + + @extend %text-ellipsis; + + &:hover { + color: var(--toc-highlight); + text-decoration: none; + } + + &::before { + display: none; + } + } + + .is-active-link { + color: var(--toc-highlight) !important; + font-weight: 600; + + &::before { + display: inline-block; + width: 1px; + height: 1.25rem; + background-color: var(--toc-highlight) !important; + } + } + + ul { + padding-left: 0.75rem; + } + } + + @at-root .toc-border-cover { + @extend %top-cover; + + margin-bottom: -4rem; + } + + &::before { + @extend %top-cover; + } + + &::after { + content: ''; + position: fixed; + bottom: 0; + width: 15%; + height: 2.25rem; + margin-left: -1px; + background: linear-gradient(transparent, var(--main-bg) 70%); + } + + > * { + @extend %panel-border; + } +} + +/* --- TOC button, bar and popup in mobile/tablet --- */ + +#toc-bar { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1; + margin: 0 -1rem; + height: v.$topbar-height; + background: var(--main-bg); + border-bottom: 1px solid var(--main-border-color); + transition: all 0.2s ease-in-out; + + @extend %btn-color; + + @include bp.xl { + display: none !important; + } + + .label { + @extend %heading; + + margin-left: 0.375rem; + padding: 0 0.75rem; + color: inherit; + } + + &.invisible { + top: -#{v.$topbar-height}; + transition: none; + } +} + +#toc-solo-trigger { + color: var(--text-muted-color); + border-color: var(--btn-border-color); + border-radius: v.$radius-lg; + + @include bp.xl { + display: none !important; + } + + .label { + font-size: 1rem; + font-family: v.$font-family-heading; + } + + &:hover { + box-shadow: none; + background: none; + } +} + +@mixin slide-in { + from { + opacity: 0.7; + transform: translateY(-#{v.$topbar-height}); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@mixin slide-out { + 0% { + transform: translateY(0); + opacity: 1; + } + + 100% { + transform: translateY(-#{v.$topbar-height}); + opacity: 0; + } +} + +@-webkit-keyframes slide-in { + @include slide-in; +} + +@keyframes slide-in { + @include slide-in; +} + +@-webkit-keyframes slide-out { + @include slide-out; +} + +@keyframes slide-out { + @include slide-out; +} + +/* --- Related Posts --- */ + +#related-posts { + > h3 { + @include mx.label(1.1rem, 600); + } + + time { + @extend %normal-font-style; + @extend %text-xs; + + color: var(--text-muted-color); + } + + p { + @extend %text-ellipsis; + + font-size: 0.9rem; + margin-bottom: 0.5rem; + white-space: break-spaces; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + + .card { + h4 { + @extend %text-clip; + } + } +} + +/* stylelint-disable-next-line selector-id-pattern */ +#disqus_thread { + min-height: 8.5rem; +} + +.utterances { + max-width: 100%; + min-height: 269px; +} + +%btn-share-hover { + color: var(--btn-share-hover-color) !important; +} + +.share-label { + @include mx.label(inherit, 400, inherit); + + &::after { + content: ':'; + } +} + +.content > p > img { + @include bp.lte(bp.get(md)) { + max-width: calc(100% + 1rem); + } +} + +h2, +h3, +h4 { + @include bp.xl { + scroll-margin-top: 2rem; + } +} diff --git a/src/styles/pages/_search.scss b/src/styles/pages/_search.scss new file mode 100644 index 00000000000..dfb044edd6a --- /dev/null +++ b/src/styles/pages/_search.scss @@ -0,0 +1,184 @@ +@use '../abstracts/breakpoints' as bp; +@use '../abstracts/variables' as v; +@use '../abstracts/placeholders'; + +search { + display: flex; + width: 100%; + border-radius: 1rem; + border: 1px solid var(--search-border-color); + background: var(--main-bg); + padding: 0 0.5rem; + + i { + z-index: 2; + font-size: 0.9rem; + color: var(--search-icon-color); + } + + @include bp.lt(bp.get(lg)) { + display: none; + } + + @include bp.lg { + max-width: v.$search-max-width; + } + + @include bp.xl { + margin-right: 4rem; + } + + @include bp.xxxl { + margin-right: calc( + v.$main-content-max-width / 4 - v.$search-max-width - 0.75rem + ); + } +} + +#search-result-wrapper { + display: none; + height: 100%; + width: 100%; + overflow: auto; + + .content { + margin-top: 2rem; + } + + @include bp.lt(bp.get(lg)) { + width: 100%; + + .content { + letter-spacing: 0; + } + } + + @include bp.lg { + max-width: v.$main-content-max-width; + justify-content: start !important; + } +} + +#search-results { + padding-bottom: 3rem; + + @include bp.between(bp.get(lg), calc(#{bp.get(xl)} - 1px)) { + > div { + max-width: 700px; + } + } + + a { + font-size: 1.4rem; + line-height: 1.5rem; + + &:hover { + @extend %link-hover; + } + + @extend %link-color; + @extend %no-bottom-border; + @extend %heading; + } + + > article { + width: 100%; + + &:not(:last-child) { + margin-bottom: 1rem; + } + + @include bp.xl { + width: 45%; + + &:nth-child(odd) { + margin-right: 1.5rem; + } + + &:nth-child(even) { + margin-left: 1.5rem; + } + + &:last-child:nth-child(odd) { + position: relative; + right: 24.3%; + } + } + + h2 { + line-height: 2.5rem; + } + + /* icons */ + i { + color: #818182; + margin-right: 0.15rem; + font-size: 80%; + } + + > p { + @extend %text-ellipsis; + + white-space: break-spaces; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + } + } +} + +/* 'Cancel' link */ +#search-cancel { + color: var(--link-color); + display: none; + white-space: nowrap; + + @extend %cursor-pointer; +} + +#search-input { + background: center; + border: 0; + border-radius: 0; + padding: 0.18rem 0.3rem; + color: var(--text-color); + height: auto; + + &:focus { + box-shadow: none; + } + + @include bp.xl { + transition: all 0.3s ease-in-out; + } +} + +#search-hints { + padding: 0 1rem; + + @include bp.lg { + display: none; + } + + h4 { + margin-bottom: 1.5rem; + } + + .post-tag { + display: inline-block; + line-height: 1rem; + font-size: 1rem; + background: var(--search-tag-bg); + border: none; + padding: 0.5rem; + margin: 0 1.25rem 1rem 0; + + &::before { + content: '#'; + color: var(--text-muted-color); + padding-right: 0.2rem; + } + + @extend %link-color; + } +} diff --git a/src/styles/pages/_tags.scss b/src/styles/pages/_tags.scss new file mode 100644 index 00000000000..d22f20d6cd7 --- /dev/null +++ b/src/styles/pages/_tags.scss @@ -0,0 +1,23 @@ +@use '../abstracts/breakpoints' as bp; + +.tag { + border-radius: 0.7em; + padding: 6px 8px 7px; + margin-right: 0.8rem; + line-height: 3rem; + letter-spacing: 0; + border: 1px solid var(--tag-border) !important; + box-shadow: 0 0 3px 0 var(--tag-shadow); + + span { + margin-left: 0.6em; + font-size: 0.7em; + font-family: Oswald, sans-serif; + } +} + +#tags { + @include bp.lt(bp.get(lg)) { + justify-content: center !important; + } +} diff --git a/src/styles/themes/_dark.scss b/src/styles/themes/_dark.scss new file mode 100644 index 00000000000..aae652213d4 --- /dev/null +++ b/src/styles/themes/_dark.scss @@ -0,0 +1,303 @@ +@mixin styles { + color-scheme: dark; + + /* Framework color */ + --main-bg: rgb(27 27 30); + --mask-bg: rgb(68 69 70); + --main-border-color: rgb(44 45 45); + + /* Common color */ + --text-color: rgb(175 176 177); + --text-muted-color: #868686; + --text-muted-highlight-color: #aeaeae; + --heading-color: #cccccc; + --label-color: #a7a7a7; + --blockquote-border-color: rgb(66 66 66); + --blockquote-text-color: #868686; + --link-color: rgb(138 180 248); + --link-underline-color: rgb(82 108 150); + --button-bg: #1e1e1e; + --btn-border-color: #2e2f31; + --btn-backtotop-color: var(--text-color); + --btn-backtotop-border-color: #212122; + --card-header-bg: #292929; + --checkbox-color: rgb(118 120 121); + --checkbox-checked-color: var(--link-color); + --img-bg: radial-gradient(circle, rgb(22 22 24) 0%, rgb(32 32 32) 100%); + --shimmer-bg: linear-gradient( + 90deg, + rgb(255 255 255 / 0%) 0%, + rgb(58 55 55 / 40%) 50%, + rgb(255 255 255 / 0%) 100% + ); + + /* Sidebar */ + --site-title-color: #717070; + --site-subtitle-color: #868686; + --sidebar-bg: #1e1e1e; + --sidebar-border-color: #292929; + --sidebar-muted-color: #868686; + --sidebar-active-color: rgb(255 255 255 / 95%); + --sidebar-hover-bg: #262626; + --sidebar-btn-bg: #232328; + --sidebar-btn-color: #787878; + --avatar-border-color: rgb(206 206 206 / 90%); + + /* Topbar */ + --topbar-bg: rgb(27 27 30 / 64%); + --topbar-text-color: var(--text-color); + --search-border-color: rgb(55 55 55); + --search-icon-color: rgb(100 102 105); + --input-focus-border-color: rgb(112 114 115); + + /* Home page */ + --post-list-text-color: rgb(175 176 177); + --btn-patinator-text-color: var(--text-color); + --btn-paginator-hover-color: #2e2e2e; + + /* Posts */ + --toc-highlight: rgb(116 178 243); + --toc-popup-border-color: #373737; + --tag-hover: rgb(43 56 62); + --tb-odd-bg: #252526; /* odd rows of the posts' table */ + --tb-even-bg: rgb(31 31 34); /* even rows of the posts' table */ + --tb-border-color: var(--tb-odd-bg); + --footnote-target-bg: rgb(63 81 181); + --btn-share-color: #6c757d; + --btn-share-hover-color: #bfc1ca; + --card-bg: #1e1e1e; + --card-hover-bg: #464d51; + --card-shadow: rgb(21 21 21 / 72%) 0 6px 18px 0, + rgb(137 135 135 / 24%) 0 0 0 1px; + --kbd-wrap-color: #6a6a6a; + --kbd-text-color: #d3d3d3; + --kbd-bg-color: #242424; + --prompt-text-color: rgb(216 212 212 / 75%); + --prompt-tip-bg: rgb(22 60 36 / 64%); + --prompt-tip-icon-color: rgb(15 164 15 / 81%); + --prompt-info-bg: rgb(7 59 104 / 80%); + --prompt-info-icon-color: #0075d1; + --prompt-warning-bg: rgb(90 69 3 / 88%); + --prompt-warning-icon-color: rgb(255 165 0 / 80%); + --prompt-danger-bg: rgb(86 28 8 / 80%); + --prompt-danger-icon-color: #cd0202; + + /* Tags */ + --tag-border: rgb(59 79 88); + --tag-shadow: rgb(32 33 33); + --dash-color: rgb(63 65 68); + --search-tag-bg: #292828; + + /* Categories */ + --categories-border: rgb(64 66 69 / 50%); + --categories-hover-bg: rgb(73 75 76); + --categories-icon-hover-color: white; + + /* Archive */ + --timeline-node-bg: rgb(150 152 156); + --timeline-color: rgb(63 65 68); + --timeline-year-dot-color: var(--timeline-color); + + /* Code highlight colors */ + --language-border-color: #2d2d2d; + --highlight-bg-color: #151515; + --highlighter-rouge-color: #c9def1; + --highlight-lineno-color: #808080; + --inline-code-bg: rgb(255 255 255 / 5%); + --code-color: #b0b0b0; + --code-header-text-color: #6a6a6a; + --code-header-muted-color: #353535; + --code-header-icon-color: #565656; + --clipboard-checked-color: #2bcc2b; + --filepath-text-color: #cacaca; + + .light { + display: none; + } + + /* Categories */ + .categories.card, + .list-group-item { + background-color: var(--card-bg); + } + + .categories { + .card-header { + background-color: var(--card-header-bg); + } + + .list-group-item { + border-left: none; + border-right: none; + padding-left: 2rem; + border-color: var(--categories-border); + + &:last-child { + border-bottom-color: var(--card-bg); + } + } + } + + #archives li:nth-child(odd) { + background-image: linear-gradient( + to left, + rgb(26 26 30), + rgb(39 39 45), + rgb(39 39 45), + rgb(39 39 45), + rgb(26 26 30) + ); + } + + /* stylelint-disable-next-line selector-id-pattern */ + #disqus_thread { + color-scheme: none; + } + + /* --- Syntax highlight theme from `rougify style base16.dark` --- */ + + .highlight .gp { + color: #87939d; + } + + .highlight table td { + padding: 5px; + } + + .highlight table pre { + margin: 0; + } + + .highlight, + .highlight .w { + color: #d0d0d0; + background-color: #151515; + } + + .highlight .err { + color: #151515; + background-color: #ac4142; + } + + .highlight .c, + .highlight .ch, + .highlight .cd, + .highlight .cm, + .highlight .cpf, + .highlight .c1, + .highlight .cs { + color: #848484; + } + + .highlight .cp { + color: #f4bf75; + } + + .highlight .nt { + color: #f4bf75; + } + + .highlight .o, + .highlight .ow { + color: #d0d0d0; + } + + .highlight .p, + .highlight .pi { + color: #d0d0d0; + } + + .highlight .gi { + color: #90a959; + } + + .highlight .gd { + color: #f08a8b; + background-color: #320000; + } + + .highlight .gh { + color: #6a9fb5; + background-color: #151515; + font-weight: bold; + } + + .highlight .k, + .highlight .kn, + .highlight .kp, + .highlight .kr, + .highlight .kv { + color: #aa759f; + } + + .highlight .kc { + color: #d28445; + } + + .highlight .kt { + color: #d28445; + } + + .highlight .kd { + color: #d28445; + } + + .highlight .s, + .highlight .sb, + .highlight .sc, + .highlight .dl, + .highlight .sd, + .highlight .s2, + .highlight .sh, + .highlight .sx, + .highlight .s1 { + color: #90a959; + } + + .highlight .sa { + color: #aa759f; + } + + .highlight .sr { + color: #75b5aa; + } + + .highlight .si { + color: #b76d45; + } + + .highlight .se { + color: #b76d45; + } + + .highlight .nn { + color: #f4bf75; + } + + .highlight .nc { + color: #f4bf75; + } + + .highlight .no { + color: #f4bf75; + } + + .highlight .na { + color: #6a9fb5; + } + + .highlight .m, + .highlight .mb, + .highlight .mf, + .highlight .mh, + .highlight .mi, + .highlight .il, + .highlight .mo, + .highlight .mx { + color: #90a959; + } + + .highlight .ss { + color: #90a959; + } +} diff --git a/src/styles/themes/_light.scss b/src/styles/themes/_light.scss new file mode 100644 index 00000000000..48d47558a8f --- /dev/null +++ b/src/styles/themes/_light.scss @@ -0,0 +1,309 @@ +@mixin styles { + /* Framework color */ + --main-bg: white; + --mask-bg: #c1c3c5; + --main-border-color: #f3f3f3; + + /* Common color */ + --text-color: #34343c; + --text-muted-color: #757575; + --text-muted-highlight-color: inherit; + --heading-color: #2a2a2a; + --label-color: #585858; + --blockquote-border-color: #eeeeee; + --blockquote-text-color: #757575; + --link-color: #0056b2; + --link-underline-color: #dee2e6; + --button-bg: #ffffff; + --btn-border-color: #e9ecef; + --btn-backtotop-color: #686868; + --btn-backtotop-border-color: #f1f1f1; + --checkbox-color: #c5c5c5; + --checkbox-checked-color: #07a8f7; + --img-bg: radial-gradient(circle, rgb(255 255 255) 0%, rgb(239 239 239) 100%); + --shimmer-bg: linear-gradient( + 90deg, + rgb(250 250 250 / 0%) 0%, + rgb(232 230 230 / 100%) 50%, + rgb(250 250 250 / 0%) 100% + ); + + /* Sidebar */ + --site-title-color: rgb(113 113 113); + --site-subtitle-color: #717171; + --sidebar-bg: #f6f8fa; + --sidebar-border-color: #efefef; + --sidebar-muted-color: #545454; + --sidebar-active-color: #1d1d1d; + --sidebar-hover-bg: rgb(223 233 241 / 64%); + --sidebar-btn-bg: white; + --sidebar-btn-color: #8e8e8e; + --avatar-border-color: white; + + /* Topbar */ + --topbar-bg: rgb(255 255 255 / 70%); + --topbar-text-color: rgb(78 78 78); + --search-border-color: rgb(240 240 240); + --search-icon-color: #c2c6cc; + --input-focus-border-color: #b8b8b8; + + /* Home page */ + --post-list-text-color: dimgray; + --btn-patinator-text-color: #555555; + --btn-paginator-hover-color: var(--sidebar-bg); + + /* Posts */ + --toc-highlight: #0550ae; + --toc-popup-border-color: lightgray; + --btn-share-color: gray; + --btn-share-hover-color: #0d6efd; + --card-bg: white; + --card-hover-bg: #e2e2e2; + --card-shadow: rgb(104 104 104 / 5%) 0 2px 6px 0, + rgb(211 209 209 / 15%) 0 0 0 1px; + --footnote-target-bg: lightcyan; + --tb-odd-bg: #fbfcfd; + --tb-border-color: #eaeaea; + --dash-color: silver; + --kbd-wrap-color: #bdbdbd; + --kbd-text-color: var(--text-color); + --kbd-bg-color: white; + --prompt-text-color: rgb(46 46 46 / 77%); + --prompt-tip-bg: rgb(123 247 144 / 20%); + --prompt-tip-icon-color: #03b303; + --prompt-info-bg: #e1f5fe; + --prompt-info-icon-color: #0070cb; + --prompt-warning-bg: rgb(255 243 205); + --prompt-warning-icon-color: #ef9c03; + --prompt-danger-bg: rgb(248 215 218 / 56%); + --prompt-danger-icon-color: #df3c30; + + /* Tags */ + --tag-border: #dee2e6; + --tag-shadow: var(--btn-border-color); + --tag-hover: rgb(222 226 230); + --search-tag-bg: #f8f9fa; + + /* Categories */ + --categories-border: rgb(0 0 0 / 12.5%); + --categories-hover-bg: var(--btn-border-color); + --categories-icon-hover-color: darkslategray; + + /* Archive */ + --timeline-color: rgb(0 0 0 / 7.5%); + --timeline-node-bg: #c2c6cc; + --timeline-year-dot-color: #ffffff; + + /* --- Custom code light mode colors --- */ + --language-border-color: #ececec; + --highlight-bg-color: #f6f8fa; + --highlighter-rouge-color: #3f596f; + --highlight-lineno-color: #9e9e9e; + --inline-code-bg: rgb(25 25 28 / 5%); + --code-color: #3a3a3a; + --code-header-text-color: #a3a3a3; + --code-header-muted-color: #e5e5e5; + --code-header-icon-color: #c9c8c8; + --clipboard-checked-color: #43c743; + + [class^='prompt-'] { + --link-underline-color: rgb(219 216 216); + } + + .dark { + display: none; + } + + /* --- Syntax highlight theme from `rougify style github` --- */ + + .highlight table td { + padding: 5px; + } + + .highlight table pre { + margin: 0; + } + + .highlight, + .highlight .w { + color: #24292f; + background-color: #f6f8fa; + } + + .highlight .k, + .highlight .kd, + .highlight .kn, + .highlight .kp, + .highlight .kr, + .highlight .kt, + .highlight .kv { + color: #cf222e; + } + + .highlight .gr { + color: #f6f8fa; + } + + .highlight .gd { + color: #82071e; + background-color: #ffebe9; + } + + .highlight .nb { + color: #953800; + } + + .highlight .nc { + color: #953800; + } + + .highlight .no { + color: #953800; + } + + .highlight .nn { + color: #953800; + } + + .highlight .sr { + color: #116329; + } + + .highlight .na { + color: #116329; + } + + .highlight .nt { + color: #116329; + } + + .highlight .gi { + color: #116329; + background-color: #dafbe1; + } + + .highlight .kc { + color: #0550ae; + } + + .highlight .l, + .highlight .ld, + .highlight .m, + .highlight .mb, + .highlight .mf, + .highlight .mh, + .highlight .mi, + .highlight .il, + .highlight .mo, + .highlight .mx { + color: #0550ae; + } + + .highlight .sb { + color: #0550ae; + } + + .highlight .bp { + color: #0550ae; + } + + .highlight .ne { + color: #0550ae; + } + + .highlight .nl { + color: #0550ae; + } + + .highlight .py { + color: #0550ae; + } + + .highlight .nv, + .highlight .vc, + .highlight .vg, + .highlight .vi, + .highlight .vm { + color: #0550ae; + } + + .highlight .o, + .highlight .ow { + color: #0550ae; + } + + .highlight .gh { + color: #0550ae; + font-weight: bold; + } + + .highlight .gu { + color: #0550ae; + font-weight: bold; + } + + .highlight .s, + .highlight .sa, + .highlight .sc, + .highlight .dl, + .highlight .sd, + .highlight .s2, + .highlight .se, + .highlight .sh, + .highlight .sx, + .highlight .s1, + .highlight .ss { + color: #0a3069; + } + + .highlight .nd { + color: #8250df; + } + + .highlight .nf, + .highlight .fm { + color: #8250df; + } + + .highlight .err { + color: #f6f8fa; + background-color: #82071e; + } + + .highlight .c, + .highlight .ch, + .highlight .cd, + .highlight .cm, + .highlight .cp, + .highlight .cpf, + .highlight .c1, + .highlight .cs { + color: #68717a; + } + + .highlight .gl { + color: #68717a; + } + + .highlight .gt { + color: #68717a; + } + + .highlight .ni { + color: #24292f; + } + + .highlight .si { + color: #24292f; + } + + .highlight .ge { + color: #24292f; + font-style: italic; + } + + .highlight .gs { + color: #24292f; + font-weight: bold; + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..ce67e1348e9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "extends": "astro/tsconfigs/strict", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + "@components/*": ["src/components/*"], + "@layouts/*": ["src/layouts/*"], + "@data/*": ["src/data/*"], + "@styles/*": ["src/styles/*"], + "@scripts/*": ["src/scripts/*"] + } + }, + "exclude": [ + "_includes", + "_layouts", + "_javascript", + "_plugins", + "_posts", + "_sass", + "_tabs", + "assets", + "tools", + "node_modules" + ] +}