fix: styles for markdown
All checks were successful
Backend ci / build (pull_request) Successful in 4m2s
All checks were successful
Backend ci / build (pull_request) Successful in 4m2s
This commit is contained in:
123
frontend/package-lock.json
generated
123
frontend/package-lock.json
generated
@@ -9,10 +9,12 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
|
"prismjs": "^1.30.0",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-router-dom": "^7.13.0",
|
"react-router-dom": "^7.13.0",
|
||||||
|
"react-syntax-highlighter": "^16.1.0",
|
||||||
"rehype-raw": "^7.0.0",
|
"rehype-raw": "^7.0.0",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"tailwindcss": "^4.1.18"
|
"tailwindcss": "^4.1.18"
|
||||||
@@ -22,6 +24,7 @@
|
|||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.1",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
"@vitejs/plugin-react": "^5.1.1",
|
"@vitejs/plugin-react": "^5.1.1",
|
||||||
"daisyui": "^5.5.14",
|
"daisyui": "^5.5.14",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
@@ -267,6 +270,15 @@
|
|||||||
"@babel/core": "^7.0.0-0"
|
"@babel/core": "^7.0.0-0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/runtime": {
|
||||||
|
"version": "7.28.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
|
||||||
|
"integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.28.6",
|
"version": "7.28.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
|
||||||
@@ -1684,6 +1696,12 @@
|
|||||||
"undici-types": "~7.16.0"
|
"undici-types": "~7.16.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/prismjs": {
|
||||||
|
"version": "1.26.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz",
|
||||||
|
"integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "19.2.14",
|
"version": "19.2.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
|
||||||
@@ -1703,6 +1721,16 @@
|
|||||||
"@types/react": "^19.2.0"
|
"@types/react": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-syntax-highlighter": {
|
||||||
|
"version": "15.5.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz",
|
||||||
|
"integrity": "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/unist": {
|
"node_modules/@types/unist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
||||||
@@ -2711,6 +2739,19 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fault": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"format": "^0.2.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fdir": {
|
"node_modules/fdir": {
|
||||||
"version": "6.5.0",
|
"version": "6.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||||
@@ -2779,6 +2820,14 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/format": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
@@ -2996,6 +3045,21 @@
|
|||||||
"hermes-estree": "0.25.1"
|
"hermes-estree": "0.25.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/highlight.js": {
|
||||||
|
"version": "10.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
|
||||||
|
"integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/highlightjs-vue": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==",
|
||||||
|
"license": "CC0-1.0"
|
||||||
|
},
|
||||||
"node_modules/html-url-attributes": {
|
"node_modules/html-url-attributes": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
|
||||||
@@ -3527,6 +3591,20 @@
|
|||||||
"url": "https://github.com/sponsors/wooorm"
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lowlight": {
|
||||||
|
"version": "1.20.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
|
||||||
|
"integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fault": "^1.0.0",
|
||||||
|
"highlight.js": "~10.7.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||||
@@ -4628,6 +4706,15 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prismjs": {
|
||||||
|
"version": "1.30.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
|
||||||
|
"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/property-information": {
|
"node_modules/property-information": {
|
||||||
"version": "7.1.0",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
|
||||||
@@ -4744,6 +4831,42 @@
|
|||||||
"react-dom": ">=18"
|
"react-dom": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-syntax-highlighter": {
|
||||||
|
"version": "16.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-16.1.0.tgz",
|
||||||
|
"integrity": "sha512-E40/hBiP5rCNwkeBN1vRP+xow1X0pndinO+z3h7HLsHyjztbyjfzNWNKuAsJj+7DLam9iT4AaaOZnueCU+Nplg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.28.4",
|
||||||
|
"highlight.js": "^10.4.1",
|
||||||
|
"highlightjs-vue": "^1.0.0",
|
||||||
|
"lowlight": "^1.17.0",
|
||||||
|
"prismjs": "^1.30.0",
|
||||||
|
"refractor": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16.20.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">= 0.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/refractor": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/refractor/-/refractor-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-QXOrHQF5jOpjjLfiNk5GFnWhRXvxjUVnlFxkeDmewR5sXkr3iM46Zo+CnRR8B+MDVqkULW4EcLVcRBNOPXHosw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/hast": "^3.0.0",
|
||||||
|
"@types/prismjs": "^1.0.0",
|
||||||
|
"hastscript": "^9.0.0",
|
||||||
|
"parse-entities": "^4.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/rehype-raw": {
|
"node_modules/rehype-raw": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz",
|
||||||
|
|||||||
@@ -11,10 +11,12 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
|
"prismjs": "^1.30.0",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-router-dom": "^7.13.0",
|
"react-router-dom": "^7.13.0",
|
||||||
|
"react-syntax-highlighter": "^16.1.0",
|
||||||
"rehype-raw": "^7.0.0",
|
"rehype-raw": "^7.0.0",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"tailwindcss": "^4.1.18"
|
"tailwindcss": "^4.1.18"
|
||||||
@@ -24,6 +26,7 @@
|
|||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.1",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
"@vitejs/plugin-react": "^5.1.1",
|
"@vitejs/plugin-react": "^5.1.1",
|
||||||
"daisyui": "^5.5.14",
|
"daisyui": "^5.5.14",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// frontend/src/pages/BlogPost.tsx
|
// frontend/src/pages/BlogPost.tsx
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, useCallback } from "react";
|
||||||
import { useParams, useNavigate } from "react-router-dom";
|
import { useParams, useNavigate } from "react-router-dom";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
import rehypeRaw from "rehype-raw";
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||||
|
import { oneDark as theme } from "react-syntax-highlighter/dist/esm/styles/prism";
|
||||||
|
|
||||||
interface Post {
|
interface Post {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -50,6 +51,12 @@ function BlogPost() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const copyCode = useCallback((code: string) => {
|
||||||
|
navigator.clipboard.writeText(code).then(() => {
|
||||||
|
// Можно добавить toast позже
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-black flex items-center justify-center">
|
<div className="min-h-screen bg-black flex items-center justify-center">
|
||||||
@@ -73,7 +80,6 @@ function BlogPost() {
|
|||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-black text-white font-['Commit_Mono',monospace]">
|
<div className="min-h-screen bg-black text-white font-['Commit_Mono',monospace]">
|
||||||
<div className="max-w-[900px] mx-auto px-4 sm:px-6 py-12 sm:py-16">
|
<div className="max-w-[900px] mx-auto px-4 sm:px-6 py-12 sm:py-16">
|
||||||
{/* Back Button */}
|
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate("/blog")}
|
onClick={() => navigate("/blog")}
|
||||||
className="flex items-center gap-2 text-gray-400 hover:text-[hsl(270,73%,63%)] transition-colors mb-8 text-sm sm:text-base"
|
className="flex items-center gap-2 text-gray-400 hover:text-[hsl(270,73%,63%)] transition-colors mb-8 text-sm sm:text-base"
|
||||||
@@ -94,7 +100,6 @@ function BlogPost() {
|
|||||||
Back to blog page
|
Back to blog page
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Article Header */}
|
|
||||||
<article>
|
<article>
|
||||||
<header className="mb-8 sm:mb-12">
|
<header className="mb-8 sm:mb-12">
|
||||||
<h1 className="text-3xl sm:text-4xl md:text-5xl font-bold text-[hsl(270,73%,63%)] mb-4 leading-tight">
|
<h1 className="text-3xl sm:text-4xl md:text-5xl font-bold text-[hsl(270,73%,63%)] mb-4 leading-tight">
|
||||||
@@ -109,11 +114,62 @@ function BlogPost() {
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* Article Content */}
|
<div className="blog-content">
|
||||||
<div className="prose prose-invert prose-lg max-w-none blog-content">
|
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
remarkPlugins={[remarkGfm]}
|
remarkPlugins={[remarkGfm]}
|
||||||
rehypePlugins={[rehypeRaw]}
|
components={{
|
||||||
|
code({ node, inline, className, children, ...props }) {
|
||||||
|
const match = /language-(\w+)/.exec(className || "");
|
||||||
|
const language = match ? match[1] : "text";
|
||||||
|
|
||||||
|
if (inline) {
|
||||||
|
return (
|
||||||
|
<code className="inline-code">
|
||||||
|
{String(children).replace(/\n$/, "")}
|
||||||
|
</code>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="code-container">
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
copyCode(String(children).replace(/\n$/, ""))
|
||||||
|
}
|
||||||
|
className="copy-button"
|
||||||
|
title="Copy code"
|
||||||
|
>
|
||||||
|
<span>Copy</span>
|
||||||
|
</button>
|
||||||
|
<SyntaxHighlighter
|
||||||
|
{...props}
|
||||||
|
style={{
|
||||||
|
...theme,
|
||||||
|
'pre[class*="language-"]': {
|
||||||
|
...theme['pre[class*="language-"]'],
|
||||||
|
background: "rgb(15, 15, 25) !important",
|
||||||
|
marginBottom: "0 !important",
|
||||||
|
borderRadius: "0 0 12px 12px !important",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
language={language}
|
||||||
|
PreTag="div"
|
||||||
|
showLineNumbers
|
||||||
|
wrapLines
|
||||||
|
className="code-highlighter"
|
||||||
|
>
|
||||||
|
{String(children).replace(/\n$/, "")}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
strong: ({ children }) => (
|
||||||
|
<strong className="text-white font-bold">{children}</strong>
|
||||||
|
),
|
||||||
|
em: ({ children }) => (
|
||||||
|
<em className="text-white italic">{children}</em>
|
||||||
|
),
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{post.content}
|
{post.content}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
@@ -123,155 +179,127 @@ function BlogPost() {
|
|||||||
|
|
||||||
<style>{`
|
<style>{`
|
||||||
.blog-content {
|
.blog-content {
|
||||||
color: #ffffff;
|
color: #ffffff !important;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Заголовки - фиолетовые */
|
|
||||||
.blog-content h1,
|
|
||||||
.blog-content h2,
|
|
||||||
.blog-content h3,
|
|
||||||
.blog-content h4,
|
|
||||||
.blog-content h5,
|
|
||||||
.blog-content h6 {
|
|
||||||
color: hsl(270, 73%, 63%);
|
|
||||||
font-weight: 700;
|
|
||||||
margin-top: 2em;
|
|
||||||
margin-bottom: 0.75em;
|
|
||||||
line-height: 1.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content h1 {
|
|
||||||
font-size: 2.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content h2 {
|
|
||||||
font-size: 1.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content h3 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content h4 {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Параграфы - белые */
|
|
||||||
.blog-content p {
|
.blog-content p {
|
||||||
color: #ffffff;
|
color: #ffffff !important;
|
||||||
margin-bottom: 1.5em;
|
margin-bottom: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ссылки */
|
|
||||||
.blog-content a {
|
|
||||||
color: hsl(270, 73%, 63%);
|
|
||||||
text-decoration: underline;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content a:hover {
|
|
||||||
color: hsl(270, 73%, 70%);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Списки */
|
|
||||||
.blog-content ul,
|
|
||||||
.blog-content ol {
|
|
||||||
color: #ffffff;
|
|
||||||
margin: 1.5em 0;
|
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content li {
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Код */
|
|
||||||
.blog-content code {
|
|
||||||
background: #1a1a1a;
|
|
||||||
color: hsl(270, 73%, 63%);
|
|
||||||
padding: 0.2em 0.4em;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 0.9em;
|
|
||||||
font-family: 'Commit Mono', monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content pre {
|
|
||||||
background: #1a1a1a;
|
|
||||||
border: 1px solid #333;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 1.5em;
|
|
||||||
overflow-x: auto;
|
|
||||||
margin: 1.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content pre code {
|
|
||||||
background: transparent;
|
|
||||||
padding: 0;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Цитаты */
|
|
||||||
.blog-content blockquote {
|
|
||||||
border-left: 4px solid hsl(270, 73%, 63%);
|
|
||||||
padding-left: 1.5em;
|
|
||||||
margin: 1.5em 0;
|
|
||||||
color: #cccccc;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Картинки */
|
|
||||||
.blog-content img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
border-radius: 8px;
|
|
||||||
margin: 2em 0;
|
|
||||||
border: 1px solid #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Таблицы */
|
|
||||||
.blog-content table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin: 1.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content th,
|
|
||||||
.blog-content td {
|
|
||||||
border: 1px solid #333;
|
|
||||||
padding: 0.75em;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content th {
|
|
||||||
background: #1a1a1a;
|
|
||||||
color: hsl(270, 73%, 63%);
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content td {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Горизонтальная линия */
|
|
||||||
.blog-content hr {
|
|
||||||
border: none;
|
|
||||||
border-top: 1px solid #333;
|
|
||||||
margin: 2em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Strong/Bold */
|
|
||||||
.blog-content strong {
|
.blog-content strong {
|
||||||
color: hsl(270, 73%, 63%);
|
color: #ffffff !important;
|
||||||
font-weight: 700;
|
font-weight: 700 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-content ul, .blog-content ol {
|
||||||
|
color: #ffffff !important;
|
||||||
|
padding-left: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline код */
|
||||||
|
.inline-code {
|
||||||
|
color: #ffffff !important;
|
||||||
|
background: rgba(255,255,255,0.1) !important;
|
||||||
|
padding: 0.2em 0.4em !important;
|
||||||
|
border-radius: 6px !important;
|
||||||
|
font-size: 0.875em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 🔥 КОНТЕЙНЕР КОДА */
|
||||||
|
.code-container {
|
||||||
|
position: relative;
|
||||||
|
margin: 2em 0;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: linear-gradient(145deg, rgb(10,10,20) 0%, rgb(20,20,35) 100%);
|
||||||
|
border: 1px solid rgba(255,255,255,0.08);
|
||||||
|
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ✨ АНИМИРОВАННАЯ КНОПКА COPY */
|
||||||
|
.copy-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 14px;
|
||||||
|
right: 14px;
|
||||||
|
z-index: 20;
|
||||||
|
background: linear-gradient(135deg, rgba(117,43,255,0.2) 0%, rgba(117,43,255,0.1) 100%);
|
||||||
|
border: 1px solid rgba(117,43,255,0.4);
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
font-family: 'Commit_Mono', monospace;
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
box-shadow: 0 4px 14px rgba(117,43,255,0.2);
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button:hover {
|
||||||
|
background: linear-gradient(135deg, hsl(270,73%,63%) 0%, hsl(270,73%,55%) 100%);
|
||||||
|
transform: translateY(-2px) scale(1.02);
|
||||||
|
box-shadow: 0 8px 25px rgba(117,43,255,0.4);
|
||||||
|
border-color: hsl(270,73%,70%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button:active {
|
||||||
|
transform: translateY(0) scale(0.98);
|
||||||
|
transition: all 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button span {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SyntaxHighlighter */
|
||||||
|
.code-highlighter {
|
||||||
|
margin: 0 !important;
|
||||||
|
border-radius: 0 0 12px 12px !important;
|
||||||
|
font-family: 'Commit_Mono', monospace !important;
|
||||||
|
font-size: 0.875rem !important;
|
||||||
|
line-height: 1.65 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-highlighter pre[class*="language-"] {
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 1.75rem 1.5rem 1.5rem !important;
|
||||||
|
background: transparent !important;
|
||||||
|
border-radius: 0 0 12px 12px !important;
|
||||||
|
overflow-x: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Номера строк */
|
||||||
|
.code-highlighter .token-line {
|
||||||
|
padding-left: 1.25rem !important;
|
||||||
|
counter-increment: line;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Заголовки */
|
||||||
|
.blog-content h1, .blog-content h2, .blog-content h3 {
|
||||||
|
color: hsl(270, 73%, 63%) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Responsive */
|
/* Responsive */
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.blog-content h1 { font-size: 1.875rem; }
|
.code-container {
|
||||||
.blog-content h2 { font-size: 1.5rem; }
|
margin: 1.5em -1rem;
|
||||||
.blog-content h3 { font-size: 1.25rem; }
|
border-radius: 0;
|
||||||
.blog-content h4 { font-size: 1.125rem; }
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.copy-button {
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user