setShowAuthModal(false)} />}
+ >
);
}
diff --git a/src/pages/AboutPage.tsx b/src/pages/AboutPage.tsx
new file mode 100644
index 0000000..ef09bf9
--- /dev/null
+++ b/src/pages/AboutPage.tsx
@@ -0,0 +1,168 @@
+import { Link } from 'react-router-dom';
+import { useLanguage } from '../contexts/LanguageContext';
+import SEOHead from '../components/seo/SEOHead';
+
+export default function AboutPage() {
+ const { language } = useLanguage();
+ const zh = language === 'zh';
+
+ return (
+ <>
+
+
+
+
+
+ {zh ? '返回首页' : 'Back to home'}
+
+
+
+
+ {zh ? '公司' : 'Company'}
+
+
{zh ? '关于 TexPixel' : 'About TexPixel'}
+
+ {zh ? '让数学排版触手可及' : 'Making math typesetting effortless'}
+
+
+
+
+
+ >
+ );
+}
+
+function AboutEn() {
+ return (
+ <>
+ Our Mission
+
+ TexPixel exists to eliminate the most tedious part of academic writing: transcribing handwritten or printed
+ formulas into LaTeX. We believe that students, researchers, and educators should spend their time thinking
+ about ideas — not fighting with syntax.
+
+
+ A photograph of a chalkboard, a scan of a textbook, a snapshot of your own handwriting — TexPixel turns any
+ of these into clean, copy-paste-ready LaTeX, Markdown, or Word equations in under a second.
+
+
+ What We Build
+
+ Our core product is an AI-powered document recognition engine trained specifically on mathematical notation.
+ Unlike general-purpose OCR tools, TexPixel understands the structure of formulas — fractions, integrals,
+ summations, matrices, and multi-line expressions — and produces output that actually works the first time.
+
+ We offer:
+
+ - Web App — instant recognition in the browser, no installation required.
+ - API (Beta) — integrate formula recognition directly into your tools and workflows.
+ - Desktop App — fully offline processing for privacy-sensitive documents.
+
+
+ Who Uses TexPixel
+
+ Our users range from undergraduate students digitizing lecture notes to researchers processing thousands of
+ equations from scanned papers. TexPixel is used in over 50 countries, with particular strength in China,
+ the United States, Germany, Japan, and India.
+
+
+ Our Principles
+
+ - Speed over friction. Every extra click is one too many. We optimize for the fastest possible path from image to output.
+ - Accuracy where it matters. A wrong minus sign or missing exponent can invalidate an entire equation. We hold our models to a high bar.
+ - Privacy by design. Your documents belong to you. We do not use uploaded content to train models without your explicit consent.
+ - Accessible pricing. Students should not have to pay enterprise prices. Our free tier is generous, and our paid plans are priced for individuals.
+
+
+ The Team
+
+ TexPixel is a small, focused team of engineers and researchers who care deeply about tools that make
+ scientific writing easier. We are based in China, with contributors around the world.
+
+
+ We're always looking for people who share our obsession with accuracy and clean user interfaces.
+ If that sounds like you, reach out at hello@texpixel.com.
+
+
+ Get in Touch
+
+ For general inquiries: hello@texpixel.com
+ For support: support@texpixel.com
+ For legal and privacy matters: legal@texpixel.com
+
+
+ Send us a message →
+
+ >
+ );
+}
+
+function AboutZh() {
+ return (
+ <>
+ 我们的使命
+
+ TexPixel 的存在,是为了消除学术写作中最繁琐的一环:将手写或印刷的公式转录为 LaTeX。
+ 我们相信,学生、研究者和教育工作者的时间应该用来思考问题,而不是与语法格式较劲。
+
+
+ 一张黑板照片、一份教材扫描件、一页你自己的手写笔记——TexPixel 能在一秒内将它们转换为
+ 可直接复制使用的 LaTeX、Markdown 或 Word 公式。
+
+
+ 我们做什么
+
+ 我们的核心产品是一个专为数学符号训练的 AI 文档识别引擎。与通用 OCR 工具不同,
+ TexPixel 能理解公式的结构——分数、积分、求和、矩阵、多行表达式——并生成一次就能用的输出。
+
+ 我们提供:
+
+ - Web 应用——在浏览器中即时识别,无需安装。
+ - API(Beta)——将公式识别直接集成到您的工具和工作流程中。
+ - 桌面版——完全离线处理,适合隐私敏感的文档场景。
+
+
+ 谁在使用 TexPixel
+
+ 我们的用户从正在数字化课堂笔记的本科生,到处理大量扫描论文公式的科研人员,不一而足。
+ TexPixel 已在全球 50 多个国家被广泛使用,在中国、美国、德国、日本和印度尤为普及。
+
+
+ 我们的原则
+
+ - 速度优先,减少摩擦。每一次多余的点击都是累赘。我们追求从图片到输出的最短路径。
+ - 精度至上。一个错误的负号或漏掉的指数,可能让整个方程失效。我们对模型保持高标准。
+ - 隐私设计。您的文档属于您自己。未经您明确同意,我们不会使用上传内容训练模型。
+ - 亲民定价。学生不应为企业级服务付费。我们的免费额度足够慷慨,付费套餐也专为个人用户定价。
+
+
+ 我们的团队
+
+ TexPixel 是一支小而精的工程师与研究者团队,深度专注于让科学写作更便捷的工具。
+ 我们总部位于中国,贡献者遍布全球。
+
+
+ 我们始终欢迎同样痴迷于精准度与简洁交互设计的伙伴加入。
+ 如果这说的是你,请联系 hello@texpixel.com。
+
+
+ 联系我们
+
+ 综合咨询:hello@texpixel.com
+ 技术支持:support@texpixel.com
+ 法律与隐私:legal@texpixel.com
+
+
+ 发送消息 →
+
+ >
+ );
+}
diff --git a/src/pages/ContactPage.tsx b/src/pages/ContactPage.tsx
new file mode 100644
index 0000000..aaef912
--- /dev/null
+++ b/src/pages/ContactPage.tsx
@@ -0,0 +1,185 @@
+import { Link } from 'react-router-dom';
+import { useLanguage } from '../contexts/LanguageContext';
+import SEOHead from '../components/seo/SEOHead';
+
+export default function ContactPage() {
+ const { language } = useLanguage();
+ const zh = language === 'zh';
+
+ return (
+ <>
+
+
+
+
+
+ {zh ? '返回首页' : 'Back to home'}
+
+
+
+
+ {zh ? '公司' : 'Company'}
+
+
{zh ? '联系我们' : 'Contact Us'}
+
+ {zh ? '我们通常在 1 个工作日内回复' : 'We typically reply within 1 business day'}
+
+
+
+
+ {zh ? : }
+
+
+ >
+ );
+}
+
+function ContactEn() {
+ return (
+ <>
+
+ Have a question, a bug to report, or an idea to share? We'd love to hear from you.
+ Choose the right channel below and we'll get back to you as quickly as we can.
+
+
+ Support
+
+ For issues with recognition quality, account problems, credit purchases, or any technical questions about
+ the product:
+
+
+ support@texpixel.com
+
+
+ When writing in, please include:
+
+
+ - A brief description of the issue
+ - The task ID (shown in your history panel) if the issue is recognition-related
+ - Your browser and operating system (for web app issues)
+
+
+ Billing & Credits
+
+ For questions about charges, credit balance discrepancies, or refund requests:
+
+
+ billing@texpixel.com
+
+
+ Please include your account email and a description of the issue. For potential billing errors,
+ include the transaction date and amount.
+
+
+ Partnerships & API Access
+
+ Interested in integrating TexPixel into your platform, LMS, or research pipeline? Looking for volume
+ pricing or a custom agreement?
+
+
+ partnerships@texpixel.com
+
+
+ Legal & Privacy
+
+ For privacy requests (data access, deletion, correction), legal inquiries, or DMCA notices:
+
+
+ legal@texpixel.com
+
+
+ General Inquiries
+
+ For everything else — press, feedback, or just saying hello:
+
+
+ hello@texpixel.com
+
+
+ Response Times
+
+ We aim to respond to all inquiries within 1 business day (China Standard Time, UTC+8).
+ During periods of high volume, support requests may take up to 3 business days.
+
+
+ For self-service help, check our documentation — most common questions are
+ answered there.
+
+ >
+ );
+}
+
+function ContactZh() {
+ return (
+ <>
+
+ 有问题想反馈、发现了 Bug,或者有好的建议?我们很乐意听到您的声音。
+ 请根据需求选择对应的联系方式,我们会尽快回复。
+
+
+ 技术支持
+
+ 如遇识别质量问题、账户故障、积分购买疑问或其他产品技术问题:
+
+
+ support@texpixel.com
+
+ 来信时请提供以下信息,以便我们更快处理:
+
+ - 问题的简要描述
+ - 任务 ID(在历史记录面板中可见),如问题与识别结果相关
+ - 浏览器名称和操作系统(针对 Web 应用问题)
+
+
+ 账单与积分
+
+ 如有扣款疑问、积分余额异常或退款申请:
+
+
+ billing@texpixel.com
+
+
+ 请在邮件中注明您的账户邮箱及问题描述。若涉及账单错误,请提供交易日期和金额。
+
+
+ 合作与 API 接入
+
+ 希望将 TexPixel 集成到您的平台、学习管理系统或科研流程中?寻求批量定价或定制合作?
+
+
+ partnerships@texpixel.com
+
+
+ 法律与隐私
+
+ 隐私权利请求(数据访问、删除、更正)、法律咨询或 DMCA 版权通知:
+
+
+ legal@texpixel.com
+
+
+ 综合咨询
+
+ 其他一切事宜——媒体采访、产品反馈,或者只是想打个招呼:
+
+
+ hello@texpixel.com
+
+
+ 响应时间
+
+ 我们争取在 1 个工作日内回复所有咨询(中国标准时间 UTC+8)。
+ 高峰期内,支持请求最多可能需要 3 个工作日。
+
+
+ 如需自助解答,请查阅我们的文档,大多数常见问题都有详细解答。
+
+ >
+ );
+}
diff --git a/src/pages/CookiePolicyPage.tsx b/src/pages/CookiePolicyPage.tsx
new file mode 100644
index 0000000..8344976
--- /dev/null
+++ b/src/pages/CookiePolicyPage.tsx
@@ -0,0 +1,304 @@
+import { Link } from 'react-router-dom';
+import { useLanguage } from '../contexts/LanguageContext';
+import SEOHead from '../components/seo/SEOHead';
+
+const EFFECTIVE_DATE_EN = 'March 26, 2026';
+const EFFECTIVE_DATE_ZH = '2026年3月26日';
+
+export default function CookiePolicyPage() {
+ const { language } = useLanguage();
+ const zh = language === 'zh';
+
+ return (
+ <>
+
+
+
+
+
+ {zh ? '返回首页' : 'Back to home'}
+
+
+
+
+ Legal
+
+
{zh ? 'Cookie 政策' : 'Cookie Policy'}
+
+ {zh ? `生效日期:${EFFECTIVE_DATE_ZH}` : `Effective: ${EFFECTIVE_DATE_EN}`}
+ ·
+ TexPixel
+
+
+
+
+ {zh ? : }
+
+
+ >
+ );
+}
+
+function CookieEn() {
+ return (
+ <>
+
+ This Cookie Policy explains how TexPixel ("we", "us", or "our") uses cookies and similar technologies on our
+ website and web application. By using the Service, you consent to the use of cookies as described here.
+
+
+ 1. What Are Cookies?
+
+ Cookies are small text files placed on your device by websites you visit. They are widely used to make websites
+ work efficiently and to provide information to site owners. Beyond traditional cookies, we also use browser
+ localStorage — a similar technology that stores data in your browser without an expiration date.
+
+
+ 2. Cookies and Storage We Use
+ We use the following types of storage technologies:
+
+
+ Strictly Necessary
+
+
+ These are essential for the Service to function. They cannot be disabled without breaking core functionality.
+
+
+
+
+ | Name |
+ Type |
+ Purpose |
+ Retention |
+
+
+
+
+ | texpixel_token |
+ localStorage |
+ Stores your JWT authentication token to keep you logged in |
+ Until sign-out or token expiry |
+
+
+ | language |
+ localStorage |
+ Remembers your language preference (en/zh) |
+ Persistent (until cleared) |
+
+
+ | texpixel_guest_usage_count |
+ localStorage |
+ Tracks free-tier usage count for guest (unauthenticated) users |
+ Persistent (until cleared) |
+
+
+
+
+
+ Functional
+
+
+ These enhance your experience but are not strictly required. Disabling them may affect some features.
+
+
+
+
+ | Name |
+ Type |
+ Purpose |
+ Retention |
+
+
+
+
+ | _ga, _gid |
+ Cookie |
+ Analytics (if enabled): distinguishes users and sessions for aggregate usage statistics |
+ 2 years / 24 hours |
+
+
+
+
+ 3. Third-Party Cookies
+
+ When you use Sign in with Google, Google may set its own cookies as part of the OAuth
+ authentication flow. These cookies are governed by{' '}
+ Google's Privacy Policy.
+ We do not control Google's cookies and cannot disable them on Google's behalf.
+
+
+ Our payment processor may also set session cookies during the checkout process. These are strictly necessary
+ for completing your purchase and are removed after the transaction.
+
+
+ 4. What We Do Not Do
+
+ - We do not use cookies or localStorage to track you across third-party websites.
+ - We do not sell data derived from cookies to advertisers or data brokers.
+ - We do not serve targeted advertising cookies.
+
+
+ 5. Managing Cookies & Local Storage
+
+ You can control and delete cookies and localStorage data through your browser settings. Note that clearing
+ your authentication token (texpixel_token) will sign you out. Clearing the language{' '}
+ key will reset your language preference to auto-detection.
+
+ Instructions for managing storage in common browsers:
+
+ - Chrome: Settings → Privacy and security → Clear browsing data
+ - Firefox: Settings → Privacy & Security → Cookies and Site Data → Clear Data
+ - Safari: Settings → Privacy → Manage Website Data
+ - Edge: Settings → Privacy, search, and services → Clear browsing data
+
+
+ To inspect or manually delete our localStorage entries, open your browser's Developer Tools → Application
+ tab → Local Storage → texpixel.com.
+
+
+ 6. Changes to This Policy
+
+ We may update this Cookie Policy from time to time. The "Effective" date at the top of this page indicates
+ when the policy was last revised. Continued use of the Service after changes constitutes acceptance.
+
+
+ 7. Contact Us
+
+ If you have questions about our use of cookies, contact us at{' '}
+ privacy@texpixel.com.
+
+ >
+ );
+}
+
+function CookieZh() {
+ return (
+ <>
+
+ 本 Cookie 政策说明 TexPixel("我们")如何在我们的网站及 Web 应用中使用 Cookie 及类似技术。
+ 使用本服务即表示您同意按本政策所述使用 Cookie。
+
+
+ 1. 什么是 Cookie?
+
+ Cookie 是您访问网站时由网站在您设备上放置的小型文本文件。它们被广泛用于使网站高效运行,
+ 并向网站所有者提供信息。除传统 Cookie 外,我们还使用浏览器的
+ localStorage——一种在浏览器中存储数据且无过期时间的类似技术。
+
+
+ 2. 我们使用的 Cookie 及存储项
+ 我们使用以下几类存储技术:
+
+
+ 严格必要类
+
+ 这些存储项对于服务的正常运行不可或缺,禁用后核心功能将无法使用。
+
+
+
+ | 名称 |
+ 类型 |
+ 用途 |
+ 保留时间 |
+
+
+
+
+ | texpixel_token |
+ localStorage |
+ 存储 JWT 身份验证令牌,维持登录状态 |
+ 退出登录或令牌过期时清除 |
+
+
+ | language |
+ localStorage |
+ 记录您的语言偏好(en/zh) |
+ 持久(直至手动清除) |
+
+
+ | texpixel_guest_usage_count |
+ localStorage |
+ 记录未登录访客用户的免费使用次数 |
+ 持久(直至手动清除) |
+
+
+
+
+
+ 功能类
+
+ 这些存储项可改善您的使用体验,但非严格必需。禁用可能影响部分功能。
+
+
+
+ | 名称 |
+ 类型 |
+ 用途 |
+ 保留时间 |
+
+
+
+
+ | _ga, _gid |
+ Cookie |
+ 数据分析(如已启用):区分用户与会话,用于汇总使用统计 |
+ 2年 / 24小时 |
+
+
+
+
+ 3. 第三方 Cookie
+
+ 使用谷歌登录时,Google 可能在 OAuth 身份验证流程中设置自己的 Cookie。
+ 这些 Cookie 受{' '}
+ Google 隐私政策
+ 约束。我们无法控制 Google 的 Cookie,也无法代表 Google 禁用它们。
+
+
+ 我们的支付处理商也可能在结账过程中设置会话 Cookie,这些 Cookie 是完成购买所必需的,交易结束后将自动删除。
+
+
+ 4. 我们不会做的事
+
+ - 我们不会使用 Cookie 或 localStorage 跨第三方网站追踪您。
+ - 我们不会将 Cookie 衍生数据出售给广告商或数据经纪商。
+ - 我们不会投放定向广告 Cookie。
+
+
+ 5. 管理 Cookie 与本地存储
+
+ 您可以通过浏览器设置控制和删除 Cookie 及 localStorage 数据。请注意,清除身份验证令牌
+ (texpixel_token)将导致您退出登录;清除 language 键将重置语言偏好为自动检测。
+
+ 常见浏览器管理存储的操作路径:
+
+ - Chrome:设置 → 隐私设置和安全性 → 清除浏览数据
+ - Firefox:设置 → 隐私与安全 → Cookie 和网站数据 → 清除数据
+ - Safari:设置 → 隐私 → 管理网站数据
+ - Edge:设置 → 隐私、搜索和服务 → 清除浏览数据
+
+
+ 如需手动检查或删除我们的 localStorage 条目,请打开浏览器开发者工具 → Application 选项卡 →
+ Local Storage → texpixel.com。
+
+
+ 6. 政策变更
+
+ 我们可能不时更新本 Cookie 政策。页面顶部的"生效日期"表示本政策最近一次修订的时间。
+ 变更后继续使用本服务,即视为您接受修订内容。
+
+
+ 7. 联系我们
+
+ 如对我们使用 Cookie 的方式有任何疑问,请通过{' '}
+ privacy@texpixel.com 联系我们。
+
+ >
+ );
+}
diff --git a/src/pages/PrivacyPage.tsx b/src/pages/PrivacyPage.tsx
new file mode 100644
index 0000000..94b1ebc
--- /dev/null
+++ b/src/pages/PrivacyPage.tsx
@@ -0,0 +1,283 @@
+import { Link } from 'react-router-dom';
+import { useLanguage } from '../contexts/LanguageContext';
+import SEOHead from '../components/seo/SEOHead';
+
+const EFFECTIVE_DATE_EN = 'March 26, 2026';
+const EFFECTIVE_DATE_ZH = '2026年3月26日';
+
+export default function PrivacyPage() {
+ const { language } = useLanguage();
+ const zh = language === 'zh';
+
+ return (
+ <>
+
+
+
+
+
+ {zh ? '返回首页' : 'Back to home'}
+
+
+
+
+ Legal
+
+
{zh ? '隐私政策' : 'Privacy Policy'}
+
+ {zh ? `生效日期:${EFFECTIVE_DATE_ZH}` : `Effective: ${EFFECTIVE_DATE_EN}`}
+ ·
+ TexPixel
+
+
+
+
+
+ >
+ );
+}
+
+function PrivacyEn() {
+ return (
+ <>
+
+ TexPixel ("we", "us", or "our") is committed to protecting your privacy. This Privacy Policy explains what
+ information we collect, how we use it, and your rights regarding your data. By using the Service, you consent
+ to the practices described here.
+
+
+ 1. Information We Collect
+ Information you provide directly:
+
+ - Account data: email address, password (stored as a hashed value — we never see your plaintext password), and display name.
+ - Google OAuth data: if you sign in with Google, we receive your Google account email, name, and profile picture URL as provided by Google.
+ - Payment data: when you purchase credits, payment is processed by a third-party payment processor. We receive only a transaction ID and purchase amount — we do not store your card details.
+ - User Content: documents, images, and files you upload for recognition processing.
+ - Support communications: messages you send to our support team.
+
+ Information collected automatically:
+
+ - Usage data: pages visited, features used, recognition tasks submitted, timestamps, and error logs.
+ - Device and technical data: IP address, browser type, operating system, and referring URL.
+ - Cookies and local storage: authentication tokens (JWT stored in localStorage), language preference, and guest usage count. See our Cookie Policy for details.
+
+
+ 2. How We Use Your Information
+
+ - Provide, operate, and improve the Service.
+ - Authenticate your identity and maintain your session.
+ - Process recognition tasks you submit.
+ - Manage your credit balance and transaction history.
+ - Send transactional emails: verification codes, payment receipts, and account security alerts.
+ - Detect and prevent fraud, abuse, and violations of our Terms of Service.
+ - Analyze aggregate usage patterns to improve the Service (using anonymized or pseudonymized data).
+ - Comply with legal obligations.
+
+
+ We do not use your User Content to train AI or machine learning models without your explicit,
+ opt-in consent. We do not sell your personal information to third parties.
+
+
+ 3. Information Sharing
+ We share your information only in the following circumstances:
+
+ - Service providers: cloud object storage (for file storage), email delivery services (for verification codes and notifications), and payment processors. These parties process data on our behalf under data processing agreements.
+ - Google: when you use Google OAuth, data is exchanged with Google in accordance with Google's Privacy Policy.
+ - Legal compliance: we may disclose information if required by law, court order, or governmental authority, or to protect the rights, property, or safety of TexPixel, our users, or the public.
+ - Business transfers: in the event of a merger, acquisition, or sale of assets, your information may be transferred to the successor entity, subject to the same privacy protections.
+
+
+ 4. Data Retention
+
+ - Account data: retained for as long as your account is active, plus a 30-day grace period after deletion.
+ - User Content: uploaded files are retained for up to 90 days after task completion, then permanently deleted unless you save them to your account history.
+ - Task history: recognition results in your account history are retained until you delete them or close your account.
+ - Payment records: retained for 7 years as required by applicable financial regulations.
+ - Log data: server and access logs are retained for up to 90 days.
+
+
+ 5. Data Security
+
+ We implement industry-standard security measures including TLS encryption for data in transit, encrypted storage
+ for sensitive credentials, and access controls limiting who can access production data. However, no system is
+ completely secure. We encourage you to use a strong, unique password and to contact us immediately if you suspect
+ unauthorized access to your account.
+
+
+ 6. Your Rights
+
+ Depending on your location, you may have the following rights regarding your personal data:
+
+
+ - Access: request a copy of the personal data we hold about you.
+ - Correction: request correction of inaccurate or incomplete data.
+ - Deletion: request deletion of your personal data ("right to be forgotten"), subject to legal retention obligations.
+ - Portability: receive your data in a structured, machine-readable format.
+ - Objection / Restriction: object to or request restriction of certain processing activities.
+ - Withdraw Consent: where processing is based on consent, withdraw that consent at any time.
+
+
+ To exercise any of these rights, contact us at privacy@texpixel.com.
+ We will respond within 30 days. We may need to verify your identity before processing your request.
+
+
+ 7. Children's Privacy
+
+ The Service is not directed to children under 13. We do not knowingly collect personal information from children
+ under 13. If we become aware that a child under 13 has provided us with personal information, we will delete it
+ promptly. If you believe a child has provided us with their data, please contact us immediately.
+
+
+ 8. International Data Transfers
+
+ TexPixel operates primarily from servers located in China. If you access the Service from outside China,
+ your data will be transferred to and processed in China. By using the Service, you consent to this transfer.
+ We take appropriate safeguards to ensure your data is treated in accordance with this Privacy Policy regardless
+ of where it is processed.
+
+
+ 9. Third-Party Links
+
+ The Service may contain links to third-party websites. This Privacy Policy does not apply to those sites.
+ We encourage you to review the privacy policies of any third-party services you visit.
+
+
+ 10. Changes to This Policy
+
+ We may update this Privacy Policy from time to time. We will notify you of material changes via email or a
+ prominent notice on the Service at least 14 days before the changes take effect. The "Effective" date at the
+ top of this page indicates when the policy was last revised.
+
+
+ 11. Contact Us
+
+ For privacy-related questions or to exercise your rights, contact us at{' '}
+ privacy@texpixel.com.
+
+ >
+ );
+}
+
+function PrivacyZh() {
+ return (
+ <>
+
+ TexPixel("我们")致力于保护您的隐私。本隐私政策说明我们收集哪些信息、如何使用这些信息,
+ 以及您对自己数据所享有的权利。使用本服务即表示您同意本政策所述的相关做法。
+
+
+ 1. 我们收集的信息
+ 您主动提供的信息:
+
+ - 账户数据:电子邮件地址、密码(以哈希形式存储,我们从不接触您的明文密码)及显示名称。
+ - Google OAuth 数据:通过 Google 登录时,我们会获取 Google 提供的账户邮箱、姓名及头像 URL。
+ - 支付数据:购买积分时,支付由第三方支付处理商完成。我们仅获取交易 ID 和购买金额,不存储您的银行卡信息。
+ - 用户内容:您上传以供识别处理的文档、图片及文件。
+ - 支持沟通:您向我们客服发送的消息。
+
+ 自动收集的信息:
+
+ - 使用数据:访问的页面、使用的功能、提交的识别任务、时间戳及错误日志。
+ - 设备与技术数据:IP 地址、浏览器类型、操作系统及来源页面 URL。
+ - Cookie 与本地存储:身份验证令牌(JWT,存储于 localStorage)、语言偏好及访客使用次数。详情请参阅我们的 Cookie 政策。
+
+
+ 2. 我们如何使用您的信息
+
+ - 提供、运营和改进本服务。
+ - 验证您的身份并维持您的登录会话。
+ - 处理您提交的识别任务。
+ - 管理您的积分余额和交易记录。
+ - 发送交易类邮件:验证码、支付收据及账户安全提醒。
+ - 检测和防止欺诈、滥用及违反服务条款的行为。
+ - 使用匿名化或假名化数据分析汇总使用模式,以改进服务。
+ - 履行法律义务。
+
+
+ 未经您明确选择同意,我们不会使用您的用户内容训练 AI 或机器学习模型。
+ 我们不会将您的个人信息出售给第三方。
+
+
+ 3. 信息共享
+ 仅在以下情况下,我们会共享您的信息:
+
+ - 服务提供商:云对象存储(用于文件存储)、邮件发送服务(用于验证码和通知)及支付处理商。这些方依据数据处理协议代表我们处理数据。
+ - Google:使用 Google OAuth 时,数据将依据 Google 隐私政策与 Google 进行交换。
+ - 法律合规:法律、法院命令或政府机构要求时,或为保护 TexPixel、用户或公众的权利、财产或安全时,我们可能披露相关信息。
+ - 业务转让:发生合并、收购或资产出售时,您的信息可能转移至继承方,并受同等隐私保护。
+
+
+ 4. 数据保留
+
+ - 账户数据:在账户有效期间保留,账户删除后额外保留 30 天宽限期。
+ - 用户内容:上传的文件在任务完成后最多保留 90 天,之后永久删除,除非您将其保存至账户历史记录。
+ - 任务历史:账户中的识别结果保留至您删除它们或注销账户为止。
+ - 支付记录:依据适用财务法规保留 7 年。
+ - 日志数据:服务器及访问日志保留最多 90 天。
+
+
+ 5. 数据安全
+
+ 我们实施行业标准安全措施,包括传输中的 TLS 加密、敏感凭证的加密存储,
+ 以及限制生产数据访问权限的访问控制。然而,任何系统都无法做到绝对安全。
+ 建议您使用强密码,并在怀疑账户遭到未授权访问时立即联系我们。
+
+
+ 6. 您的权利
+ 根据您所在地区,您可能对个人数据享有以下权利:
+
+ - 访问权:请求获取我们持有的关于您的个人数据副本。
+ - 更正权:请求更正不准确或不完整的数据。
+ - 删除权:请求删除您的个人数据("被遗忘权"),受法律保留义务约束。
+ - 数据可携权:以结构化、机器可读的格式接收您的数据。
+ - 反对权/限制权:反对或要求限制某些处理活动。
+ - 撤回同意:对于基于同意的处理,可随时撤回同意。
+
+
+ 如需行使上述任何权利,请发送邮件至{' '}
+ privacy@texpixel.com。
+ 我们将在 30 天内答复。处理请求前,我们可能需要验证您的身份。
+
+
+ 7. 儿童隐私
+
+ 本服务不面向 13 周岁以下儿童。我们不会有意收集 13 周岁以下儿童的个人信息。
+ 若发现 13 周岁以下儿童向我们提供了个人信息,我们将立即予以删除。
+ 如您认为儿童已向我们提供个人数据,请立即联系我们。
+
+
+ 8. 国际数据传输
+
+ TexPixel 主要依托位于中国的服务器运营。如您从中国境外访问本服务,
+ 您的数据将被传输至中国并在中国境内处理。使用本服务即表示您同意此类传输。
+ 无论数据在何处处理,我们均采取适当保障措施,确保您的数据受本隐私政策保护。
+
+
+ 9. 第三方链接
+
+ 本服务可能包含第三方网站的链接。本隐私政策不适用于这些网站。
+ 建议您查阅所访问的任何第三方服务的隐私政策。
+
+
+ 10. 政策变更
+
+ 我们可能不时更新本隐私政策。对于重大变更,我们将通过电子邮件或服务内显著通知的方式,
+ 在变更生效前至少 14 天提前告知您。页面顶部的"生效日期"表示本政策最近一次修订的时间。
+
+
+ 11. 联系我们
+
+ 如有隐私相关问题或需行使您的权利,请通过{' '}
+ privacy@texpixel.com 联系我们。
+
+ >
+ );
+}
diff --git a/src/pages/TermsPage.tsx b/src/pages/TermsPage.tsx
new file mode 100644
index 0000000..3c88117
--- /dev/null
+++ b/src/pages/TermsPage.tsx
@@ -0,0 +1,322 @@
+import { Link } from 'react-router-dom';
+import { useLanguage } from '../contexts/LanguageContext';
+import SEOHead from '../components/seo/SEOHead';
+
+const EFFECTIVE_DATE_EN = 'March 26, 2026';
+const EFFECTIVE_DATE_ZH = '2026年3月26日';
+
+export default function TermsPage() {
+ const { language } = useLanguage();
+ const zh = language === 'zh';
+
+ return (
+ <>
+
+
+
+
+
+ {zh ? '返回首页' : 'Back to home'}
+
+
+
+
+ Legal
+
+
{zh ? '服务条款' : 'Terms of Service'}
+
+ {zh ? `生效日期:${EFFECTIVE_DATE_ZH}` : `Effective: ${EFFECTIVE_DATE_EN}`}
+ ·
+ TexPixel
+
+
+
+
+ {zh ? : }
+
+
+ >
+ );
+}
+
+function TermsEn() {
+ return (
+ <>
+
+ Please read these Terms of Service ("Terms") carefully before using TexPixel ("Service", "we", "us", or "our").
+ By creating an account or using the Service, you agree to be bound by these Terms. If you do not agree, do not use the Service.
+
+
+ 1. Eligibility
+
+ You must be at least 13 years old to use the Service. If you are under 18, you must have your parent or legal guardian's
+ permission. By using the Service, you represent and warrant that you meet these requirements. Paid features (credits
+ purchases) are available only to users who are 18 or older or have legal capacity to enter into contracts in their jurisdiction.
+
+
+ 2. Account Registration
+
+ You may register using an email address and one-time verification code, or by linking a Google account via OAuth 2.0.
+ You are responsible for maintaining the confidentiality of your account credentials and for all activities that occur
+ under your account. You must provide accurate, current, and complete information and keep your account information updated.
+ We reserve the right to suspend or terminate accounts that contain false information or that are used fraudulently.
+
+
+ 3. Credits & Payment
+
+ Access to certain features of the Service requires purchasing credits. Credits are a prepaid, non-refundable virtual
+ currency used to pay for recognition tasks (image-to-LaTeX, PDF-to-Markdown, handwriting OCR, etc.).
+
+
+ - No Refunds. Credits are non-refundable except where required by applicable law. If you believe
+ you were charged in error, contact us within 30 days of the charge.
+ - Expiration. Credits do not expire as long as your account remains active. We reserve the right
+ to introduce expiration policies with at least 60 days' notice.
+ - Price Changes. We may change credit prices at any time. Changes will not affect credits already purchased.
+ - Taxes. You are responsible for all applicable taxes on credit purchases in your jurisdiction.
+ - Free Tier. Guest users receive a limited number of free recognition tasks. Free usage is subject
+ to change without notice.
+ - Chargebacks. Initiating a chargeback without first contacting us may result in immediate account suspension.
+
+
+ 4. User Content
+
+ You retain all intellectual property rights in the documents, images, and files you upload ("User Content"). By
+ uploading User Content, you grant TexPixel a limited, non-exclusive, royalty-free license to process, store, and
+ transmit your content solely to provide the Service.
+
+
+ - We do not use your User Content to train AI models without your explicit consent.
+ - We do not share your User Content with third parties except as necessary to operate the Service (e.g., cloud
+ storage providers).
+ - You are responsible for ensuring you have the right to upload and process any content you submit.
+ - Do not upload content that is illegal, infringes third-party rights, or contains personally identifiable
+ information of others without their consent.
+
+
+ 5. Accuracy Disclaimer
+
+ TexPixel uses AI-based recognition technology. Recognition results (LaTeX, Markdown, text) are provided on an
+ "as-is" basis. We do not warrant that results will be accurate, complete, or suitable for any particular purpose.
+ You are responsible for verifying all outputs before use in academic, professional, or published work.
+
+
+ 6. Prohibited Uses
+ You agree not to:
+
+ - Use the Service to process content that is illegal, obscene, defamatory, or violates third-party rights.
+ - Reverse-engineer, decompile, or attempt to extract source code from the Service.
+ - Automate requests to the Service in a manner that exceeds your plan limits or degrades service for others.
+ - Use the Service to build a competing product or service without our written permission.
+ - Share, sell, or transfer your account or credits to another party.
+ - Use bots, scrapers, or automated tools to access the Service beyond what is permitted by the API documentation.
+ - Circumvent any technical measures we use to limit usage or enforce these Terms.
+
+
+ 7. Intellectual Property
+
+ The Service, including its software, design, trademarks, and content (excluding User Content), is owned by TexPixel
+ and protected by applicable intellectual property laws. You may not copy, modify, distribute, sell, or lease any part
+ of the Service without our prior written consent.
+
+
+ 8. Third-Party Services
+
+ The Service integrates with third-party services including Google (for OAuth), cloud object storage providers (for
+ file storage), and payment processors. Your use of these services is also subject to their respective terms and
+ privacy policies. We are not responsible for the practices of third-party services.
+
+
+ 9. Disclaimer of Warranties
+
+ THE SERVICE IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ WE DO NOT WARRANT THAT THE SERVICE WILL BE UNINTERRUPTED, ERROR-FREE, OR SECURE.
+
+
+ 10. Limitation of Liability
+
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, TEXPIXEL SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
+ CONSEQUENTIAL, OR PUNITIVE DAMAGES, INCLUDING LOSS OF DATA, LOSS OF PROFITS, OR BUSINESS INTERRUPTION, ARISING
+ FROM YOUR USE OF THE SERVICE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+ OUR TOTAL LIABILITY TO YOU FOR ANY CLAIMS ARISING FROM YOUR USE OF THE SERVICE SHALL NOT EXCEED THE AMOUNT YOU
+ PAID US IN THE 12 MONTHS PRECEDING THE CLAIM.
+
+
+ 11. Termination
+
+ We may suspend or terminate your account at any time, with or without notice, for conduct that we determine violates
+ these Terms or is harmful to other users, us, or third parties. You may delete your account at any time by contacting
+ us. Upon termination, your right to use the Service ceases immediately. Unused credits at the time of termination for
+ cause are forfeited; credits remaining upon voluntary account closure may be refunded at our discretion.
+
+
+ 12. Indemnification
+
+ You agree to indemnify, defend, and hold harmless TexPixel and its officers, directors, employees, and agents from
+ any claims, liabilities, damages, and expenses (including reasonable attorneys' fees) arising from your use of the
+ Service, your User Content, or your violation of these Terms.
+
+
+ 13. Governing Law & Dispute Resolution
+
+ These Terms are governed by the laws of the People's Republic of China without regard to conflict-of-law principles.
+ Any disputes arising from these Terms shall first be subject to good-faith negotiation. If unresolved within 30 days,
+ disputes shall be submitted to binding arbitration in accordance with applicable rules, or to the competent courts of
+ the jurisdiction where TexPixel is incorporated.
+
+
+ 14. Changes to These Terms
+
+ We may modify these Terms at any time. We will provide notice of material changes via email or a prominent notice on
+ the Service at least 14 days before changes take effect. Your continued use of the Service after the effective date
+ constitutes your acceptance of the revised Terms.
+
+
+ 15. Contact Us
+
+ If you have questions about these Terms, please contact us at{' '}
+ legal@texpixel.com.
+
+ >
+ );
+}
+
+function TermsZh() {
+ return (
+ <>
+
+ 请在使用 TexPixel("服务"、"我们")之前仔细阅读本服务条款("条款")。
+ 注册账户或使用本服务,即表示您同意受本条款约束。如您不同意,请勿使用本服务。
+
+
+ 1. 使用资格
+
+ 您须年满 13 周岁方可使用本服务。若您未满 18 周岁,须取得父母或法定监护人的同意。
+ 付费功能(积分购买)仅向具备完全民事行为能力的成年用户开放。
+ 使用本服务即表示您保证符合上述要求。
+
+
+ 2. 账户注册
+
+ 您可通过电子邮件地址及一次性验证码注册账户,或通过 Google OAuth 2.0 关联 Google 账号登录。
+ 您有责任妥善保管账户凭证,并对账户下发生的所有活动承担责任。
+ 您须提供真实、准确、完整的注册信息,并保持信息更新。
+ 对于包含虚假信息或存在欺诈行为的账户,我们保留暂停或注销的权利。
+
+
+ 3. 积分与付费
+
+ 使用本服务的部分功能需要购买积分。积分是一种预付制虚拟货币,用于支付识别任务费用(图片转 LaTeX、PDF 转 Markdown、手写识别等)。
+
+
+ - 不予退款。除法律另有规定外,积分一经购买不予退款。若您认为被错误扣款,请在扣款后 30 天内联系我们。
+ - 有效期。只要账户保持活跃,积分不会过期。我们保留引入有效期规则的权利,届时将提前至少 60 天通知。
+ - 价格变动。我们可随时调整积分价格,但调整不影响已购积分。
+ - 税费。您须自行承担所在地区购买积分时产生的适用税费。
+ - 免费额度。访客用户可享有有限次数的免费识别任务,免费额度可能随时变更,恕不另行通知。
+ - 拒付争议。在未事先联系我们的情况下发起拒付,可能导致账户被立即暂停。
+
+
+ 4. 用户内容
+
+ 您对上传的文档、图片及文件("用户内容")保留全部知识产权。上传用户内容,即表示您授予 TexPixel
+ 有限的、非独占的、免版税的许可,以仅为提供服务之目的处理、存储和传输您的内容。
+
+
+ - 未经您明确同意,我们不会使用您的用户内容训练 AI 模型。
+ - 除运营服务所必需(如云存储服务商)外,我们不会将您的用户内容分享给第三方。
+ - 您须确保有权上传并处理所提交的任何内容。
+ - 请勿上传违法、侵犯第三方权利,或在未经当事人同意的情况下包含他人个人身份信息的内容。
+
+
+ 5. 识别结果免责声明
+
+ TexPixel 采用基于 AI 的识别技术。识别结果(LaTeX、Markdown、文本等)按"现状"提供。
+ 我们不保证结果的准确性、完整性或适用于特定用途。
+ 在将输出用于学术、专业或发表场景之前,您有责任自行核验所有结果。
+
+
+ 6. 禁止行为
+ 您同意不得:
+
+ - 使用本服务处理违法、淫秽、诽谤或侵犯第三方权利的内容。
+ - 对服务进行逆向工程、反编译或尝试提取源代码。
+ - 以超出套餐限额或影响其他用户体验的方式自动化发送请求。
+ - 在未获得我们书面许可的情况下,利用本服务构建竞争性产品或服务。
+ - 转让、出售或将账户或积分转移给他人。
+ - 使用机器人、爬虫或自动化工具以超出 API 文档许可范围的方式访问服务。
+ - 绕过我们为限制使用或执行本条款而采取的任何技术措施。
+
+
+ 7. 知识产权
+
+ 本服务(包括软件、设计、商标及内容,但用户内容除外)归 TexPixel 所有,受适用知识产权法律保护。
+ 未经我们事先书面同意,您不得复制、修改、分发、出售或出租服务的任何部分。
+
+
+ 8. 第三方服务
+
+ 本服务集成了第三方服务,包括 Google(用于 OAuth 登录)、云对象存储服务商(用于文件存储)及支付处理商。
+ 您对上述服务的使用同样受其各自条款和隐私政策约束。我们不对第三方服务的做法承担责任。
+
+
+ 9. 免责声明
+
+ 本服务按"现状"和"可用状态"提供,不附带任何明示或暗示的保证,
+ 包括但不限于适销性、特定用途适用性及不侵权保证。
+ 我们不保证服务不中断、无错误或绝对安全。
+
+
+ 10. 责任限制
+
+ 在法律允许的最大范围内,TexPixel 不对因您使用本服务而产生的任何间接、附带、特殊、
+ 后果性或惩罚性损害(包括数据丢失、利润损失或业务中断)承担责任,
+ 即便我们已被告知此类损害的可能性。
+
+
+ 我们就您使用本服务的任何索赔所承担的全部责任,不超过索赔发生前 12 个月内您向我们支付的金额。
+
+
+ 11. 账户终止
+
+ 对于违反本条款或有害于其他用户、我们或第三方的行为,我们可随时暂停或注销相关账户,无需事先通知。
+ 您可随时通过联系我们删除账户。账户终止后,您使用本服务的权利立即终止。
+ 因违规而终止账户时,未使用的积分将被没收;主动注销账户时,剩余积分是否退款由我们自行决定。
+
+
+ 12. 赔偿
+
+ 您同意就因您使用本服务、您的用户内容或您违反本条款而产生的任何索赔、责任、损害及费用
+ (包括合理律师费),向 TexPixel 及其管理人员、董事、员工和代理人进行赔偿和辩护。
+
+
+ 13. 适用法律与争议解决
+
+ 本条款受中华人民共和国法律管辖,不考虑法律冲突原则。
+ 因本条款引发的争议,双方应首先进行善意协商。
+ 若 30 天内未能解决,争议将提交仲裁或由 TexPixel 注册地的有管辖权的法院处理。
+
+
+ 14. 条款变更
+
+ 我们可随时修改本条款。对于重大变更,我们将通过电子邮件或服务内显著通知的方式,
+ 在变更生效前至少 14 天提前告知您。变更生效后继续使用本服务,即表示您接受修订后的条款。
+
+
+ 15. 联系我们
+
+ 如您对本条款有任何疑问,请通过{' '}
+ legal@texpixel.com 联系我们。
+
+ >
+ );
+}
diff --git a/src/routes/AppRouter.tsx b/src/routes/AppRouter.tsx
index ec6d4c9..609678f 100644
--- a/src/routes/AppRouter.tsx
+++ b/src/routes/AppRouter.tsx
@@ -10,6 +10,11 @@ const DocsListPage = lazy(() => import('../pages/DocsListPage'));
const DocDetailPage = lazy(() => import('../pages/DocDetailPage'));
const BlogListPage = lazy(() => import('../pages/BlogListPage'));
const BlogDetailPage = lazy(() => import('../pages/BlogDetailPage'));
+const TermsPage = lazy(() => import('../pages/TermsPage'));
+const PrivacyPage = lazy(() => import('../pages/PrivacyPage'));
+const CookiePolicyPage = lazy(() => import('../pages/CookiePolicyPage'));
+const AboutPage = lazy(() => import('../pages/AboutPage'));
+const ContactPage = lazy(() => import('../pages/ContactPage'));
function LoadingFallback() {
return (
@@ -29,6 +34,11 @@ export default function AppRouter() {
} />
} />
} />
+ } />
+ } />
+ } />
+ } />
+ } />
}>
} />
diff --git a/src/styles/landing.css b/src/styles/landing.css
index ff8df0b..0c7ab17 100644
--- a/src/styles/landing.css
+++ b/src/styles/landing.css
@@ -1,7 +1,13 @@
/* Landing page CSS — scoped under .marketing-page to prevent workspace bleed */
/* Extracted from texpixel-landing.html, lines 10-1593 */
-.marketing-page *, .marketing-page *::before, .marketing-page *::after { box-sizing: border-box; margin: 0; padding: 0; }
+.marketing-page *,
+.marketing-page *::before,
+.marketing-page *::after {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
:root {
--primary: #C8622A;
@@ -18,8 +24,8 @@
--gold: #F3C96A;
--rose: #F2A38C;
--lavender: #B7AFE8;
- --shadow-soft: 0 8px 24px rgba(198,134,85,0.10);
- --shadow-float: 0 18px 40px rgba(220,195,175,0.30);
+ --shadow-soft: 0 8px 24px rgba(198, 134, 85, 0.10);
+ --shadow-float: 0 18px 40px rgba(220, 195, 175, 0.30);
--r-s: 16px;
--r-m: 20px;
--r-l: 28px;
@@ -65,20 +71,29 @@
will-change: transform;
transform: translateZ(0);
}
+
.glow-blob-1 {
- width: 520px; height: 400px;
- background: radial-gradient(circle, rgba(200,98,42,0.13) 0%, transparent 70%);
- top: -100px; right: 60px;
+ width: 520px;
+ height: 400px;
+ background: radial-gradient(circle, rgba(200, 98, 42, 0.13) 0%, transparent 70%);
+ top: -100px;
+ right: 60px;
}
+
.glow-blob-2 {
- width: 400px; height: 360px;
- background: radial-gradient(circle, rgba(140,201,190,0.13) 0%, transparent 70%);
- bottom: 25%; left: -100px;
+ width: 400px;
+ height: 360px;
+ background: radial-gradient(circle, rgba(140, 201, 190, 0.13) 0%, transparent 70%);
+ bottom: 25%;
+ left: -100px;
}
+
.glow-blob-3 {
- width: 360px; height: 300px;
- background: radial-gradient(circle, rgba(243,201,106,0.11) 0%, transparent 70%);
- top: 50%; right: -80px;
+ width: 360px;
+ height: 300px;
+ background: radial-gradient(circle, rgba(243, 201, 106, 0.11) 0%, transparent 70%);
+ top: 50%;
+ right: -80px;
}
/* ── LAYOUT ── */
@@ -91,7 +106,10 @@
}
.marketing-page section,
-.marketing-page main { position: relative; z-index: 1; }
+.marketing-page main {
+ position: relative;
+ z-index: 1;
+}
/* ── NAVBAR ── */
.marketing-page nav {
@@ -99,7 +117,7 @@
top: 0;
z-index: 100;
height: 72px;
- background: rgba(255,251,247,0.85);
+ background: rgba(255, 251, 247, 0.85);
backdrop-filter: blur(16px);
border-bottom: 1px solid var(--border);
}
@@ -123,7 +141,8 @@
}
.logo-icon {
- width: 38px; height: 38px;
+ width: 38px;
+ height: 38px;
background: var(--primary);
border-radius: 10px;
display: flex;
@@ -132,7 +151,8 @@
}
.logo-icon svg {
- width: 22px; height: 22px;
+ width: 22px;
+ height: 22px;
fill: none;
stroke: white;
stroke-width: 2;
@@ -189,7 +209,10 @@
cursor: pointer;
transition: all 0.15s;
}
-.lang-switch:hover { color: var(--text-body); }
+
+.lang-switch:hover {
+ color: var(--text-body);
+}
.btn-cta {
height: 52px;
@@ -204,12 +227,13 @@
cursor: pointer;
transition: all 0.2s ease;
white-space: nowrap;
- box-shadow: 0 2px 12px rgba(200,98,42,0.25);
+ box-shadow: 0 2px 12px rgba(200, 98, 42, 0.25);
}
+
.btn-cta:hover {
background: #A84E20;
transform: translateY(-1px);
- box-shadow: 0 6px 20px rgba(200,98,42,0.32);
+ box-shadow: 0 6px 20px rgba(200, 98, 42, 0.32);
}
/* ── BUTTONS ── */
@@ -233,12 +257,13 @@
.btn-primary {
background: var(--primary);
color: white;
- box-shadow: 0 2px 14px rgba(200,98,42,0.28);
+ box-shadow: 0 2px 14px rgba(200, 98, 42, 0.28);
}
+
.btn-primary:hover {
background: #A84E20;
transform: translateY(-1px);
- box-shadow: 0 8px 24px rgba(200,98,42,0.36);
+ box-shadow: 0 8px 24px rgba(200, 98, 42, 0.36);
}
.btn-secondary {
@@ -247,6 +272,7 @@
border: 1.5px solid var(--border);
box-shadow: var(--shadow-soft);
}
+
.btn-secondary:hover {
border-color: var(--primary-light);
transform: translateY(-1px);
@@ -274,13 +300,16 @@
}
.pill-dot {
- width: 8px; height: 8px;
+ width: 8px;
+ height: 8px;
border-radius: 50%;
background: var(--teal);
flex-shrink: 0;
}
-.pill-dot.orange { background: var(--primary); }
+.pill-dot.orange {
+ background: var(--primary);
+}
/* ── EYEBROW ── */
.eyebrow {
@@ -308,7 +337,9 @@
flex: 0 0 560px;
}
-.hero-pill { margin-bottom: 28px; }
+.hero-pill {
+ margin-bottom: 28px;
+}
.hero-title {
font-family: 'Lora', serif;
@@ -367,7 +398,9 @@
font-weight: 500;
}
-.trust-item svg { flex-shrink: 0; }
+.trust-item svg {
+ flex-shrink: 0;
+}
.social-proof {
display: flex;
@@ -380,7 +413,8 @@
}
.avatar {
- width: 36px; height: 36px;
+ width: 36px;
+ height: 36px;
border-radius: 50%;
border: 2px solid var(--bg);
margin-right: -10px;
@@ -392,10 +426,23 @@
color: white;
}
-.av1 { background: var(--teal); }
-.av2 { background: var(--rose); }
-.av3 { background: var(--gold); color: #6f5800; }
-.av4 { background: var(--lavender); color: #3d3870; }
+.av1 {
+ background: var(--teal);
+}
+
+.av2 {
+ background: var(--rose);
+}
+
+.av3 {
+ background: var(--gold);
+ color: #6f5800;
+}
+
+.av4 {
+ background: var(--lavender);
+ color: #3d3870;
+}
.social-text {
font-size: 14px;
@@ -403,7 +450,9 @@
font-weight: 500;
}
-.social-text strong { color: var(--text-body); }
+.social-text strong {
+ color: var(--text-body);
+}
/* ── MOCK WINDOW ── */
.hero-right {
@@ -415,14 +464,21 @@
background: var(--elevated);
border-radius: var(--r-l);
border: 1.5px solid var(--border);
- box-shadow: var(--shadow-float), 0 2px 0 rgba(200,98,42,0.06);
+ box-shadow: var(--shadow-float), 0 2px 0 rgba(200, 98, 42, 0.06);
overflow: hidden;
animation: float 6s ease-in-out infinite;
}
@keyframes float {
- 0%, 100% { transform: translateY(0); }
- 50% { transform: translateY(-8px); }
+
+ 0%,
+ 100% {
+ transform: translateY(0);
+ }
+
+ 50% {
+ transform: translateY(-8px);
+ }
}
.window-topbar {
@@ -441,12 +497,22 @@
}
.window-dot {
- width: 11px; height: 11px;
+ width: 11px;
+ height: 11px;
border-radius: 50%;
}
-.wd-red { background: #FF6059; }
-.wd-yellow { background: #FFBD2E; }
-.wd-green { background: #29C940; }
+
+.wd-red {
+ background: #FF6059;
+}
+
+.wd-yellow {
+ background: #FFBD2E;
+}
+
+.wd-green {
+ background: #29C940;
+}
.window-url {
flex: 1;
@@ -464,7 +530,8 @@
}
.url-lock {
- width: 10px; height: 12px;
+ width: 10px;
+ height: 12px;
fill: var(--teal);
flex-shrink: 0;
}
@@ -476,45 +543,63 @@
gap: 16px;
}
-.upload-zone {
- border: 1.5px dashed var(--border);
- border-radius: var(--r-m);
- padding: 28px 20px;
- text-align: center;
- background: var(--bg);
- transition: border-color 0.2s;
-}
-
-.upload-zone:hover { border-color: var(--primary-light); }
-
-.upload-icon-wrap {
- width: 48px; height: 48px;
- background: var(--warm-wash);
- border-radius: 14px;
+/* ── UPLOAD PREVIEW (hero demo) ── */
+.upload-zone-preview {
+ position: relative;
+ height: 148px;
display: flex;
align-items: center;
justify-content: center;
- margin: 0 auto 12px;
+ border-style: dashed;
+ border-color: var(--border);
+ background: var(--bg);
+ overflow: hidden;
}
-.upload-icon-wrap svg {
- width: 24px; height: 24px;
- stroke: var(--primary);
- fill: none;
- stroke-width: 1.8;
+.upload-preview-img {
+ position: absolute;
+ height: 110px;
+ width: auto;
+ max-width: 80%;
+ object-fit: contain;
+ border-radius: 6px;
+ box-shadow: 0 2px 12px rgba(0,0,0,0.10);
+ background: white;
+ opacity: 0;
+ transition: opacity 0.5s ease;
+ pointer-events: none;
}
-.upload-text {
- font-size: 13px;
- color: var(--text-body);
- font-weight: 500;
- line-height: 1.5;
+.upload-preview-img.upload-preview-active {
+ opacity: 1;
+ pointer-events: auto;
}
-.upload-sub {
- font-size: 12px;
- color: var(--text-muted);
- margin-top: 4px;
+.window-slide-dots {
+ display: flex;
+ justify-content: center;
+ gap: 6px;
+ padding: 8px 0 4px;
+}
+
+.window-dot-btn {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ border: none;
+ background: var(--border);
+ cursor: pointer;
+ padding: 0;
+ transition: background 0.2s, transform 0.2s;
+}
+
+.window-dot-btn.window-dot-active {
+ background: var(--primary);
+ transform: scale(1.3);
+}
+
+.window-dot-btn:hover {
+ background: var(--primary-light);
}
.output-zone {
@@ -551,23 +636,36 @@
.output-badge::before {
content: '';
- width: 6px; height: 6px;
+ width: 6px;
+ height: 6px;
background: var(--teal);
border-radius: 50%;
}
.output-code {
- padding: 16px;
+ padding: 12px 16px;
font-family: 'JetBrains Mono', monospace;
- font-size: 14px;
+ font-size: 12.5px;
color: var(--text-strong);
- line-height: 1.7;
- min-height: 72px;
+ line-height: 1.55;
+ height: 72px;
+ overflow: hidden;
+ position: relative;
}
-.code-comment { color: var(--text-muted); font-style: italic; font-size: 12px; }
-.code-kw { color: var(--primary); }
-.code-num { color: var(--teal); }
+.code-comment {
+ color: var(--text-muted);
+ font-style: italic;
+ font-size: 12px;
+}
+
+.code-kw {
+ color: var(--primary);
+}
+
+.code-num {
+ color: var(--teal);
+}
.output-actions {
padding: 10px 16px;
@@ -593,12 +691,14 @@
color: white;
}
-.output-btn-copy:hover { background: #A84E20; }
+.output-btn-copy:hover {
+ background: #A84E20;
+}
.output-btn-word {
background: var(--warm-wash);
color: var(--primary);
- border: 1px solid rgba(200,98,42,0.2);
+ border: 1px solid rgba(200, 98, 42, 0.2);
}
.window-status {
@@ -692,7 +792,8 @@
}
.card-icon {
- width: 54px; height: 54px;
+ width: 54px;
+ height: 54px;
border-radius: 16px;
display: flex;
align-items: center;
@@ -700,19 +801,36 @@
margin-bottom: 20px;
}
-.icon-orange { background: var(--warm-wash); }
-.icon-teal { background: rgba(140,201,190,0.15); }
-.icon-lavender { background: rgba(183,175,232,0.15); }
+.icon-orange {
+ background: var(--warm-wash);
+}
+
+.icon-teal {
+ background: rgba(140, 201, 190, 0.15);
+}
+
+.icon-lavender {
+ background: rgba(183, 175, 232, 0.15);
+}
.card-icon svg {
- width: 26px; height: 26px;
+ width: 26px;
+ height: 26px;
fill: none;
stroke-width: 1.8;
}
-.icon-orange svg { stroke: var(--primary); }
-.icon-teal svg { stroke: var(--teal); }
-.icon-lavender svg { stroke: var(--lavender); }
+.icon-orange svg {
+ stroke: var(--primary);
+}
+
+.icon-teal svg {
+ stroke: var(--teal);
+}
+
+.icon-lavender svg {
+ stroke: var(--lavender);
+}
.card-title {
font-family: 'Lora', serif;
@@ -740,12 +858,14 @@
gap: 4px;
}
-.card-link:hover { gap: 8px; }
+.card-link:hover {
+ gap: 8px;
+}
/* ── CORE FEATURES ── */
.core-features {
padding: 96px 0;
- background: linear-gradient(180deg, transparent, rgba(200,98,42,0.03), transparent);
+ background: linear-gradient(180deg, transparent, rgba(200, 98, 42, 0.03), transparent);
}
.feature-card {
@@ -781,14 +901,22 @@
.feature-mini::before {
content: '';
position: absolute;
- top: 0; left: 0; right: 0;
+ top: 0;
+ left: 0;
+ right: 0;
height: 2px;
background: linear-gradient(90deg, transparent, var(--primary), transparent);
}
-.feature-speed { color: var(--teal); font-weight: 600; font-size: 20px; }
+.feature-speed {
+ color: var(--teal);
+ font-weight: 600;
+ font-size: 20px;
+}
-.feature-card .card-title { margin-bottom: 6px; }
+.feature-card .card-title {
+ margin-bottom: 6px;
+}
/* ── EXAMPLE SHOWCASE ── */
.showcase {
@@ -885,9 +1013,17 @@
line-height: 1.7;
}
-.sc-output .kw { color: #C8622A; }
-.sc-output .num { color: #6ee7b7; }
-.sc-output .br { color: #c4b5fd; }
+.sc-output .kw {
+ color: #C8622A;
+}
+
+.sc-output .num {
+ color: #6ee7b7;
+}
+
+.sc-output .br {
+ color: #c4b5fd;
+}
.showcase-footer {
padding: 0 28px 28px;
@@ -933,7 +1069,8 @@
}
.map-dot {
- width: 12px; height: 12px;
+ width: 12px;
+ height: 12px;
border-radius: 50%;
animation: pulse-dot 2s ease-in-out infinite;
position: relative;
@@ -947,8 +1084,29 @@
animation: pulse-ring 2s ease-in-out infinite;
}
-@keyframes pulse-dot { 0%,100%{transform:scale(1)} 50%{transform:scale(1.15)} }
-@keyframes pulse-ring { 0%{opacity:0.6;transform:scale(1)} 100%{opacity:0;transform:scale(2.4)} }
+@keyframes pulse-dot {
+
+ 0%,
+ 100% {
+ transform: scale(1)
+ }
+
+ 50% {
+ transform: scale(1.15)
+ }
+}
+
+@keyframes pulse-ring {
+ 0% {
+ opacity: 0.6;
+ transform: scale(1)
+ }
+
+ 100% {
+ opacity: 0;
+ transform: scale(2.4)
+ }
+}
.map-label {
font-size: 11px;
@@ -961,17 +1119,37 @@
color: var(--text-body);
}
-.dot-china { background: var(--primary); }
-.dot-china::after { background: var(--primary); }
+.dot-china {
+ background: var(--primary);
+}
-.dot-us { background: var(--teal); }
-.dot-us::after { background: var(--teal); }
+.dot-china::after {
+ background: var(--primary);
+}
-.dot-eu { background: var(--lavender); }
-.dot-eu::after { background: var(--lavender); }
+.dot-us {
+ background: var(--teal);
+}
-.dot-jp { background: var(--rose); }
-.dot-jp::after { background: var(--rose); }
+.dot-us::after {
+ background: var(--teal);
+}
+
+.dot-eu {
+ background: var(--lavender);
+}
+
+.dot-eu::after {
+ background: var(--lavender);
+}
+
+.dot-jp {
+ background: var(--rose);
+}
+
+.dot-jp::after {
+ background: var(--rose);
+}
.map-stat {
margin-top: 32px;
@@ -992,11 +1170,34 @@
padding: 96px 0;
}
+/* Beta notice */
+.pricing-beta-notice {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ background: rgba(22, 163, 74, 0.08);
+ border: 1px solid rgba(22, 163, 74, 0.22);
+ border-radius: var(--r-m);
+ padding: 12px 20px;
+ font-size: 13.5px;
+ font-weight: 500;
+ color: #15803d;
+ margin-bottom: 32px;
+ text-align: center;
+ line-height: 1.5;
+}
+
+.pricing-beta-icon {
+ font-size: 16px;
+ flex-shrink: 0;
+}
+
.pricing-cards {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
- align-items: start;
+ align-items: stretch;
}
.pricing-card {
@@ -1006,6 +1207,10 @@
padding: 28px 24px;
box-shadow: var(--shadow-soft);
transition: all 0.22s ease;
+ position: relative;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
}
.pricing-card:hover {
@@ -1016,14 +1221,23 @@
.pricing-card.featured {
background: linear-gradient(160deg, #FFF4EC, #FFFBF7);
border: 2px solid var(--primary);
- position: relative;
- padding-top: 40px;
- box-shadow: 0 8px 32px rgba(200,98,42,0.15);
+ padding-top: 44px;
+ box-shadow: 0 8px 32px rgba(200, 98, 42, 0.15);
+}
+
+/* Desktop / Lifetime card */
+.pricing-card-desktop {
+ border: 1.5px solid rgba(200, 98, 42, 0.35);
+}
+
+.pricing-card-desktop:hover {
+ border-color: rgba(200, 98, 42, 0.55);
}
.featured-badge {
position: absolute;
- top: -1px; left: 50%;
+ top: 0;
+ left: 50%;
transform: translateX(-50%);
background: var(--primary);
color: white;
@@ -1032,6 +1246,52 @@
padding: 5px 16px;
border-radius: 0 0 12px 12px;
letter-spacing: 0.04em;
+ white-space: nowrap;
+ z-index: 2;
+}
+
+/* Diagonal corner ribbon */
+.plan-ribbon {
+ position: absolute;
+ top: 20px;
+ right: -34px;
+ width: 130px;
+ padding: 6px 0;
+ font-size: 11px;
+ font-weight: 800;
+ text-align: center;
+ transform: rotate(45deg);
+ letter-spacing: 0.06em;
+ pointer-events: none;
+ z-index: 3;
+}
+
+.plan-ribbon-free {
+ background: #16a34a;
+ color: #fff;
+ box-shadow: 0 2px 10px rgba(22, 163, 74, 0.45);
+}
+
+.plan-ribbon-soon {
+ background: #94a3b8;
+ color: #fff;
+ box-shadow: 0 2px 8px rgba(100, 116, 139, 0.3);
+}
+
+/* Desktop tag badge */
+.plan-desktop-tag {
+ display: inline-flex;
+ align-items: center;
+ gap: 5px;
+ font-size: 11px;
+ font-weight: 700;
+ padding: 4px 10px;
+ border-radius: 20px;
+ margin-bottom: 12px;
+ letter-spacing: 0.04em;
+ background: rgba(200, 98, 42, 0.1);
+ color: var(--primary);
+ border: 1px solid rgba(200, 98, 42, 0.25);
}
.plan-name {
@@ -1053,15 +1313,35 @@
}
.plan-price span {
- font-size: 22px;
+ font-size: 16px;
color: var(--text-muted);
font-weight: 600;
+ letter-spacing: 0;
+ font-family: 'DM Sans', sans-serif;
}
.plan-period {
font-size: 13px;
color: var(--text-muted);
- margin-bottom: 16px;
+ margin-bottom: 8px;
+}
+
+.plan-edu-price {
+ font-size: 12px;
+ color: var(--teal);
+ font-weight: 600;
+ margin-bottom: 20px;
+ padding: 4px 10px;
+ background: rgba(140, 201, 190, 0.12);
+ border-radius: 6px;
+ display: inline-block;
+}
+
+.plan-edu-price-placeholder {
+ background: transparent;
+ color: transparent;
+ pointer-events: none;
+ user-select: none;
}
.plan-desc {
@@ -1069,7 +1349,6 @@
color: var(--text-body);
line-height: 1.55;
margin-bottom: 24px;
- min-height: 48px;
}
.plan-features {
@@ -1078,6 +1357,7 @@
display: flex;
flex-direction: column;
gap: 8px;
+ flex: 1;
}
.plan-features li {
@@ -1090,8 +1370,9 @@
.plan-features li::before {
content: '✓';
- width: 18px; height: 18px;
- background: rgba(140,201,190,0.2);
+ width: 18px;
+ height: 18px;
+ background: rgba(140, 201, 190, 0.2);
color: var(--teal);
border-radius: 50%;
display: flex;
@@ -1105,7 +1386,7 @@
}
.featured .plan-features li::before {
- background: rgba(200,98,42,0.12);
+ background: rgba(200, 98, 42, 0.12);
color: var(--primary);
}
@@ -1136,7 +1417,7 @@
background: var(--primary);
color: white;
border-color: transparent;
- box-shadow: 0 4px 16px rgba(200,98,42,0.28);
+ box-shadow: 0 4px 16px rgba(200, 98, 42, 0.28);
}
.plan-btn.featured-btn:hover {
@@ -1144,6 +1425,24 @@
transform: translateY(-1px);
}
+.plan-btn-desktop-disabled {
+ display: block;
+ width: 100%;
+ height: 52px;
+ border-radius: var(--r-m);
+ font-size: 15px;
+ font-weight: 600;
+ font-family: 'DM Sans', sans-serif;
+ cursor: not-allowed;
+ opacity: 0.45;
+ background: var(--elevated);
+ color: var(--text-muted);
+ border: 1.5px solid var(--border);
+ box-shadow: none;
+ text-align: center;
+ line-height: 52px;
+}
+
/* ── DOCS SEO ── */
.docs-seo {
padding: 96px 0;
@@ -1182,7 +1481,8 @@
}
.doc-icon {
- width: 44px; height: 44px;
+ width: 44px;
+ height: 44px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 12px;
@@ -1193,7 +1493,8 @@
}
.doc-icon svg {
- width: 20px; height: 20px;
+ width: 20px;
+ height: 20px;
stroke: var(--primary);
fill: none;
stroke-width: 1.8;
@@ -1282,7 +1583,9 @@
transition: color 0.15s;
}
-.footer-links a:hover { color: var(--primary); }
+.footer-links a:hover {
+ color: var(--primary);
+}
.footer-bottom {
border-top: 1px solid var(--border);
@@ -1306,23 +1609,51 @@
}
.footer-made svg {
- width: 14px; height: 14px;
+ width: 14px;
+ height: 14px;
fill: var(--rose);
}
/* ── HERO LOAD ANIMATION ── */
@keyframes fadeUp {
- from { opacity: 0; transform: translateY(20px); }
- to { opacity: 1; transform: none; }
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+
+ to {
+ opacity: 1;
+ transform: none;
+ }
}
-.hero-pill { animation: fadeUp 0.5s ease both; }
-.hero-title { animation: fadeUp 0.55s ease 0.08s both; }
-.hero-desc { animation: fadeUp 0.55s ease 0.16s both; }
-.hero-actions { animation: fadeUp 0.55s ease 0.22s both; }
-.hero-trust { animation: fadeUp 0.55s ease 0.28s both; }
-.social-proof { animation: fadeUp 0.55s ease 0.34s both; }
-.mock-window { animation: fadeUp 0.6s ease 0.18s both; }
+.hero-pill {
+ animation: fadeUp 0.5s ease both;
+}
+
+.hero-title {
+ animation: fadeUp 0.55s ease 0.08s both;
+}
+
+.hero-desc {
+ animation: fadeUp 0.55s ease 0.16s both;
+}
+
+.hero-actions {
+ animation: fadeUp 0.55s ease 0.22s both;
+}
+
+.hero-trust {
+ animation: fadeUp 0.55s ease 0.28s both;
+}
+
+.social-proof {
+ animation: fadeUp 0.55s ease 0.34s both;
+}
+
+.mock-window {
+ animation: fadeUp 0.6s ease 0.18s both;
+}
/* ── DIVIDER ── */
.section-divider {
@@ -1343,10 +1674,13 @@
}
/* ── NAV AVATAR & USER MENU ── */
-.nav-user { position: relative; }
+.nav-user {
+ position: relative;
+}
.nav-avatar {
- width: 38px; height: 38px;
+ width: 38px;
+ height: 38px;
border-radius: 50%;
border: 1.5px solid var(--border);
background: var(--card);
@@ -1358,8 +1692,16 @@
color: var(--text-muted);
}
-.nav-avatar svg { width: 20px; height: 20px; }
-.nav-avatar:hover { border-color: var(--primary-light); color: var(--primary); background: var(--warm-wash); }
+.nav-avatar svg {
+ width: 20px;
+ height: 20px;
+}
+
+.nav-avatar:hover {
+ border-color: var(--primary-light);
+ color: var(--primary);
+ background: var(--warm-wash);
+}
.nav-user-menu {
position: absolute;
@@ -1382,7 +1724,8 @@
}
.nav-menu-avatar {
- width: 34px; height: 34px;
+ width: 34px;
+ height: 34px;
border-radius: 50%;
background: var(--teal);
color: #1a5c54;
@@ -1425,12 +1768,37 @@
cursor: pointer;
}
-.nav-menu-item:hover { background: var(--bg); color: var(--text-strong); }
-.nav-menu-item svg { color: var(--text-muted); flex-shrink: 0; }
-.nav-menu-logout { color: #b84040; }
-.nav-menu-logout:hover { background: #fff0f0; color: #b84040; }
+.nav-menu-item:hover {
+ background: var(--bg);
+ color: var(--text-strong);
+}
-.nav-login-btn .btn-cta { height: 40px; font-size: 14px; padding: 0 18px; border-radius: 12px; }
+.nav-menu-item svg {
+ color: var(--text-muted);
+ flex-shrink: 0;
+}
+
+.nav-menu-logout {
+ color: #b84040;
+}
+
+.nav-menu-logout:hover {
+ background: #fff0f0;
+ color: #b84040;
+}
+
+.nav-login-btn .btn-cta {
+ height: 40px;
+ font-size: 14px;
+ padding: 0 18px;
+ border-radius: 12px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ line-height: 1;
+ text-decoration: none;
+ box-sizing: border-box;
+}
/* ── TESTIMONIAL CAROUSEL ── */
.testimonial-wrap {
@@ -1442,7 +1810,7 @@
display: grid;
grid-template-columns: repeat(6, calc(33.333% - 14px));
gap: 20px;
- transition: transform 0.45s cubic-bezier(0.4,0,0.2,1);
+ transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}
.testimonial-card {
@@ -1458,7 +1826,9 @@
transition: box-shadow 0.2s;
}
-.testimonial-card:hover { box-shadow: var(--shadow-float); }
+.testimonial-card:hover {
+ box-shadow: var(--shadow-float);
+}
.t-quote {
font-family: 'Lora', serif;
@@ -1485,7 +1855,8 @@
}
.t-avatar {
- width: 36px; height: 36px;
+ width: 36px;
+ height: 36px;
border-radius: 50%;
font-size: 14px;
font-weight: 700;
@@ -1524,7 +1895,8 @@
}
.t-nav-btn {
- width: 36px; height: 36px;
+ width: 36px;
+ height: 36px;
border-radius: 50%;
border: 1.5px solid var(--border);
background: var(--elevated);
@@ -1549,7 +1921,8 @@
}
.t-dot {
- width: 6px; height: 6px;
+ width: 6px;
+ height: 6px;
border-radius: 50%;
background: var(--border);
transition: all 0.2s;
@@ -1574,11 +1947,29 @@
transform: translateY(0);
}
-.reveal-delay-1 { transition-delay: 0.10s; }
-.reveal-delay-2 { transition-delay: 0.20s; }
-.reveal-delay-3 { transition-delay: 0.30s; }
+.reveal-delay-1 {
+ transition-delay: 0.10s;
+}
-@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0} }
+.reveal-delay-2 {
+ transition-delay: 0.20s;
+}
+
+.reveal-delay-3 {
+ transition-delay: 0.30s;
+}
+
+@keyframes blink {
+
+ 0%,
+ 100% {
+ opacity: 1
+ }
+
+ 50% {
+ opacity: 0
+ }
+}
/* ═══════════════════════════════════════════════════════
DOCS PAGES
@@ -1756,7 +2147,9 @@
font-weight: 500;
}
-.docs-back-link:hover { color: var(--primary); }
+.docs-back-link:hover {
+ color: var(--primary);
+}
.docs-back-link svg {
width: 15px;
@@ -1798,7 +2191,9 @@
flex-wrap: wrap;
}
-.docs-meta-sep { opacity: 0.4; }
+.docs-meta-sep {
+ opacity: 0.4;
+}
/* ── Docs prose body ── */
.docs-prose {
@@ -1808,7 +2203,9 @@
color: var(--text-body);
}
-.docs-prose > h1:first-child { display: none; }
+.docs-prose>h1:first-child {
+ display: none;
+}
.docs-prose h2 {
font-family: 'Lora', serif;
@@ -1836,7 +2233,9 @@
margin: 24px 0 8px;
}
-.docs-prose p { margin-bottom: 20px; }
+.docs-prose p {
+ margin-bottom: 20px;
+}
.docs-prose ul,
.docs-prose ol {
@@ -1844,7 +2243,9 @@
margin-bottom: 20px;
}
-.docs-prose li { margin-bottom: 8px; }
+.docs-prose li {
+ margin-bottom: 8px;
+}
.docs-prose strong {
color: var(--text-strong);
@@ -1858,7 +2259,9 @@
text-underline-offset: 3px;
}
-.docs-prose a:hover { text-decoration-color: var(--primary); }
+.docs-prose a:hover {
+ text-decoration-color: var(--primary);
+}
.docs-prose code {
font-family: 'JetBrains Mono', monospace;
@@ -1924,7 +2327,9 @@
vertical-align: top;
}
-.docs-prose tr:nth-child(even) td { background: var(--bg); }
+.docs-prose tr:nth-child(even) td {
+ background: var(--bg);
+}
.docs-prose .katex-display {
margin: 32px 0;
@@ -1975,8 +2380,15 @@
}
@keyframes skeleton-pulse {
- 0%, 100% { opacity: 0.7; }
- 50% { opacity: 0.35; }
+
+ 0%,
+ 100% {
+ opacity: 0.7;
+ }
+
+ 50% {
+ opacity: 0.35;
+ }
}
/* ════════════════════════════════════════
@@ -2029,7 +2441,7 @@
content: '';
position: absolute;
inset: 0;
- background: linear-gradient(135deg, rgba(200,98,42,0.04) 0%, transparent 60%);
+ background: linear-gradient(135deg, rgba(200, 98, 42, 0.04) 0%, transparent 60%);
pointer-events: none;
}
@@ -2158,10 +2570,18 @@
}
@media (max-width: 640px) {
- .blog-grid { grid-template-columns: 1fr; }
- .blog-featured { padding: 24px; }
- .blog-page { padding: 40px 16px 64px; }
+ .blog-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .blog-featured {
+ padding: 24px;
+ }
+
+ .blog-page {
+ padding: 40px 16px 64px;
+ }
}
/* ── Blog detail page (reuses .docs-detail, .docs-back-link,
- .docs-prose, .docs-cta-box, .docs-skeleton-wrap) ── */
+ .docs-prose, .docs-cta-box, .docs-skeleton-wrap) ── */
\ No newline at end of file