# dsh-theme-palette

[English](README.md) · [中文](README-zh.md) · [日本語](README-ja.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)

DeepSeek Harness (वेब और डेस्कटॉप) के लिए थीम पैलेट: **4 प्रीसेट + कस्टम पैलेट × लाइट/डार्क**, दो स्वतंत्र अक्ष।

![सेटिंग्स पेज](assets/screenshot-settings-light.png)

*पैनल की वास्तविक चौड़ाई (564px सामग्री) पर स्थिर रेंडर।*

| डार्क | कस्टम पैलेट | उच्च कंट्रास्ट |
|---|---|---|
| ![डार्क](assets/screenshot-settings-dark.png) | ![कस्टम पैलेट](assets/screenshot-settings-custom.png) | ![उच्च कंट्रास्ट](assets/screenshot-settings-hc.png) |

## Compatibility

| सतह | स्थिति |
|---|---|
| DSH डेस्कटॉप / वेब क्लाइंट | 0.2.x |
| Node.js | 22.19.0+ (22.x श्रृंखला पर) या 24.0.0+ |
| होस्ट सोर्स में बदलाव | कोई नहीं |

पैकेज का `engines` फ़ील्ड `^22.19.0 || >=24.0.0` है — ऊपर की पंक्ति वही आवश्यकता शब्दों में है।

प्लगइन केवल `ctx.theme.overrideTokens` से रंग टोकन की एक परत जोड़ता है; यह नया थीम पंजीकृत नहीं करता, होस्ट को पैच नहीं करता और अपीयरेंस सेटिंग नहीं बदलता।

## What it does

- **4 प्रीसेट + कस्टम** — मोनो, वार्म सैंड, इंडिगो, मॉस (हर एक लाइट और डार्क दोनों के लिए अलग से अनुकूलित), साथ ही तीन रंगों से निकली कस्टम पैलेट;
- पूरी रैंप **दोबारा गणना** होती है, बदली नहीं जाती: OKLCH पुनर्निर्माण → भूमिका-आधारित क्रोमा → **sRGB गैमट क्लैंप** → वास्तविक सतहों पर कंट्रास्ट हल;
- होस्ट के रंग टोकन: रंगीन पैलेट में 179 (+ प्लगइन के अपने 13), मोनो में 19 (1080 सेटिंग संयोजन पूरी तरह स्कैन किए गए); **बिल्ट CSS जो 66 रंग टोकन वास्तव में उपभोग करता है, वे सभी प्लगइन पर ही हल होते हैं**: मुख्य टेक्स्ट, द्वितीयक, तृतीयक, कैप्शन, लिंक, साइडबार, कार्ड, उपयोगकर्ता बबल, प्राइमरी बटन, स्क्रॉलबार, स्विच, Markdown शीर्षक/बोल्ड, कोड ब्लॉक, और अब **त्रुटि/सफलता/चेतावनी की स्थितियाँ तथा फ़ाइल diff की +/− पंक्तियाँ** (लाल/हरा/एम्बर तीनों स्केल पहली बार पुनर्निर्माण में शामिल; केवल तापमान, रंग-कोण घुमाव अधिकतम 8°);
- समायोज्य: टेक्स्ट की तीव्रता (3), साइडबार की गहराई (3), Markdown ज़ोर, स्क्रॉलबार, स्विच का रंग;
- **कस्टम पैलेट** (सतह / टेक्स्ट / एक्सेंट चुनें: टेक्स्ट का रंग-कोण भी व्युत्पन्न में शामिल होता है, और स्पष्ट रूप से गहरी/हल्की सतह उस मोड के कैनवास की चमक बन जाती है — इंजन अपने कंट्रास्ट वादे बनाए रखता है), `dshs1.` कोड से **कॉन्फ़िगरेशन निर्यात/आयात**, **हाई-कॉन्ट्रास्ट** मोड, और **4 UI भाषाएँ**;
- **स्व-उपचार**: यदि होस्ट ओवरराइड परत हटा दे, पैलेट फिर से लगा दी जाती है; बार-बार विफलता पर स्व-उपचार रुक जाता है और सेटिंग्स पेज पर इसे दोबारा चालू करने का बटन मिलता है;
- **कंट्रास्ट के वादे**: मुख्य टेक्स्ट के लिए लाइट में 12:1 और डार्क में 10:1 (उच्च-कंट्रास्ट में 15:1), द्वितीयक ≥ 6.2 (लाइट) / 8.0 (डार्क) (HC 9 / 9.6), तृतीयक ≥ 4.85 (लाइट) / 6.4 (डार्क) (HC 7 / 7.6), लिंक ≥ 4.95 (लाइट) / 4.62 (डार्क) (HC 7) — लाइट की सीमाओं में रंग-दृष्टि दोष के लिए गुंजाइश रखी गई है; डार्क लिंक अतिरिक्त APCA Lc ≥ 60 (HC 75) — उन्हीं सतहों पर मापे गए जहाँ टेक्स्ट वास्तव में बैठता है (डार्क में ज़्यादा चाहिए: गहरे बैकग्राउंड पर WCAG अनुपात पढ़ने की सुविधा को बढ़ा-चढ़ा कर दिखाता है);
- वादे की गई सतहें लाइट में 00/60 और डार्क में 950/875 हैं; डार्क 800 (मॉड्यूल सतह) और 850 (उप-सतह) मुख्य टेक्स्ट को नहीं सहनाते — रिपोर्ट उन्हें अलग «नीति से बाहर» के रूप में गिनती है (न तो पास, न ही फेल);
- इंटरफ़ेस 简体中文 / 繁體中文 / English / 日本語 में (होस्ट की भाषा का पालन करता है, हाथ से भी चुना जा सकता है)।

## Install

```bash
# npm से
cd ~/.dsh/profiles/desktop
pnpm add dsh-theme-palette
```

किसी संस्करण को पिन करने के लिए `pnpm add dsh-theme-palette@<version>` — [CHANGELOG.md](CHANGELOG.md) में जिन संस्करणों पर「未发布」लिखा है वे npm पर कभी प्रकाशित नहीं हुए; उन्हें पिन न करें।
GitHub रिलीज़ के tarball से: [releases पेज](https://github.com/zuoyunlai/dsh-theme-palette/releases) पर asset चुनें, फिर `pnpm add <tgz का पता>`।

इसके बाद **GUI को फिर से शुरू करें** — चल रहा प्रोसेस पुराना मॉड्यूल रखता है। खोलें: अवतार → सेटिंग्स → **Color theme**।

## Configuration

| विकल्प | विकल्प |
|---|---|
| पैलेट | मोनो · वार्म सैंड · इंडिगो · मॉस (थंबनेल लाइट/डार्क का पालन करते हैं) |
| तीव्रता | शांत / मानक / गहरा — टेक्स्ट पैलेट का कितना पालन करे |
| सतहें | साइडबार (हल्का / समान / गहरा)। दायाँ पैनल कभी रंगा नहीं जाता: वह पूरी ऊँचाई की पारदर्शी परत है, रंगने पर बातचीत ढक जाएगी (1.9.10 में यह सेटिंग हटा दी गई) |
| और विकल्प | भाषा, Markdown ज़ोर, स्क्रॉलबार, स्विच/चेक |

हर चुनाव तुरंत लागू होता है और `localStorage` में सहेजा जाता है। लाइट/डार्क होस्ट की «अपीयरेंस» सेटिंग में ही रहता है।

## Palette engine

```
OKLCH(L, C, ह्यू) ──► गैमट क्लैंप (C पर बाइनरी खोज) ──► sRGB हेक्स
        ▲
        └── भूमिका क्रोमा × तीव्रता, फिर {कैनवास, कार्ड, साइडबार, ओवरले} पर कंट्रास्ट
```

- सेमांटिक एलियस `var(--dsw-static-neutral-bluish-NN)` श्रृंखलाएँ बनाए रखते हैं, इसलिए जो भी टोकन का पालन करता है वह पैलेट का भी करता है;
- लाइट सतहें स्टेप 00–300, डार्क सतहें 800–950;
- टेक्स्ट की न्यूनतम सीमा बनाते समय लागू: मुख्य लाइट में ≥ 12:1 और डार्क में ≥ 10:1 (उच्च-कंट्रास्ट: 15:1), द्वितीयक ≥ 6.2 लाइट / 8.0 डार्क (HC 9 / 9.6), तृतीयक ≥ 4.85 लाइट / 6.4 डार्क (HC 7 / 7.6), लिंक ≥ 4.95 लाइट / 4.62 डार्क (HC 7), लिंक APCA Lc ≥ 60 डार्क (HC 75); साइडबार और बबल का टेक्स्ट रैंप के साथ चलता है और मापा ≥ 7 रहता है (कोई अलग कंट्रास्ट गेट नहीं);
- वादे की गई सतहें लाइट में 00/60 और डार्क में 950/875 हैं; डार्क 800 (मॉड्यूल सतह) और 850 (उप-सतह) मुख्य टेक्स्ट को नहीं सहनाते — रिपोर्ट उन्हें अलग «नीति से बाहर» के रूप में गिनती है (न तो पास, न ही फेल), और हर सतह को AA की न्यूनतम सीमा 4.5 से गुज़रना ही होता है;
- रिपोर्ट तीन बातें अलग रखती है: घोषित लक्ष्य, भौतिक सीमा (उस सतह पर सफ़ेद या काला कितना हासिल कर सकता है) और नीति छूट; 0.93 केवल सॉल्वर का मार्जिन है, इससे तय होता है कि लक्ष्य सीमा से ऊपर है या नहीं;
- `node palette-dev.mjs` 1080 संयोजन जाँचता है (5 पैलेट × 216 सेटिंग, दोनों कंट्रास्ट स्तर सहित)।

डिज़ाइन नोट्स, घटक-वार तर्क और कंट्रास्ट तालिकाएँ [docs/DESIGN.md](docs/DESIGN.md) में। इतिहास: [CHANGELOG.md](CHANGELOG.md)।

## Development

```bash
npm run report                        # सभी पैलेट का टोकन रिपोर्ट (-- --hc से उच्च-कंट्रास्ट)
npm run sheet                         # पैलेट बोर्ड → tools/sheet.html
npm run shot-sheet                    # बोर्ड का स्क्रीनशॉट (हेडलेस Chrome/Edge)
npm run compare -- --dir tools/out/<run>   # स्थानीय बेसलाइन से तुलना
npm run preview -- --lang en          # सेटिंग्स पेज रेंडर करें
npm run contract                      # होस्ट टोकन/DOM कॉन्ट्रैक्ट (strict: SKIP विफल)
npm run release -- --dry              # रिलीज़ प्रीफ़्लाइट
npm run release -- --tag              # npm पर प्रकाशित + टैग
npm run release -- --ci               # CI में प्रकाशन: केवल tag; Actions Trusted Publishing से प्रकाशित करे
npm run clean                         # स्थानीय tarball / tools/out / dist हटाएँ
```

स्क्रीनशॉट रिग्रेशन की दो परतें हैं: पैलेट बोर्ड (बिना लॉगिन) और CDP से असली डेस्कटॉप विंडो (`tools/shoot-desktop.mjs`, `--remote-debugging-port` चाहिए)। देखें [tools/README.md](tools/README.md)।


## Pitfalls we hit

1.7.0 ऑडिट में सबसे चौंकाने वाली पाँच बातें — हर एक टेस्ट से निकली, स्क्रीनशॉट देखकर नहीं।

- **सफ़ेद एक्सेंट से सफ़ेद लिंक बनता था** (1.13:1)। कॉन्ट्रास्ट सॉल्वर केवल एक ही दिशा में चलता था — बैकग्राउंड से दूर — इसलिए बैकग्राउंड से हल्का एक्सेंट सफ़ेद की ओर ही बढ़ता गया।
- **रंग बदलने पर पेज बदला, पैनल नहीं।** कंपोनेंट पैलेट id पर सब्सक्राइब था, जो रंग बदलने पर नहीं बदलता; React ने स्नैपशॉट की तुलना की, अंतर न मिला, और री-रेंडर छोड़ दिया।
- **कॉन्फ़िगरेशन साझा हुआ, रंग नहीं।** शॉर्ट कोड में मोड्स तो थे पर तीन कस्टम रंग नहीं, इसलिए दूसरी मशीन पर इम्पोर्ट सफल बताता और स्थानीय मान रख लेता था।
- **«वादा नहीं» का अर्थ «असंभव» नहीं है।** पुरानी रिपोर्ट गहरे मॉड्यूल सतहों को "सतह-सीमित" बताती थी, क्योंकि वह मुख्य टेक्स्ट के लक्ष्य की तुलना सबसे गहरी सतह (800) से करती थी। पर सफ़ेद अग्रभूमि के साथ 800 लगभग 10.22:1 और 850 लगभग 15.27:1 तक पहुँचते हैं, जो 10:1 के लक्ष्य से ऊपर है — कुछ भी कभी असंभव नहीं था; वे सतहें बस वादे में नहीं थीं। अब रिपोर्ट घोषित लक्ष्य, भौतिक सीमा और नीति छूट को अलग रखती है, और 800/850 को "भौतिक रूप से असंभव" की जगह «नीति से बाहर» गिनती है।
- **एक चयनकर्ता जिसे हम मृत समझते थे, वह जीवित था।** ऑडिट ने शुरू में उसे टूटा बताया; शिप की गई CSS के विरुद्ध कॉन्ट्रैक्ट टेस्ट ने विपरीत साबित किया। गलती निष्कर्ष में थी, कोड में नहीं।

## Sharing

पूरी कॉन्फ़िगरेशन — तीन कस्टम रंगों समेत — एक ही शॉर्ट कोड में जाती है। इम्पोर्ट बॉक्स में पेस्ट करें और प्रीव्यू दबाएँ — लागू करने से पहले देखें कि क्या बदलेगा:

```text
dshs1.eyJ2IjoxLCJwIjoiY3VzdG9tIiwicyI6ImRlZXAiLCJ0IjoidGludGVkIiwiYyI6InRpbnRlZCIsImsiOiJhY2NlbnQiLCJtIjoib24iLCJoIjoib2ZmIiwibCI6InpoLUNOIiwieCI6eyJiZyI6IiNmNWVmZTYiLCJ0ZXh0IjoiIzFkMWExNyIsImFjY2VudCI6IiMzZjY2YTMifX0
```

यह वास्तविक उदाहरण इसमें डिकोड होता है:

- पैलेट: custom · साइडबार: deep · टेक्स्ट: tinted
- स्क्रॉलबार: tinted · नियंत्रण: accent · Markdown: on · उच्च-कंट्रास्ट: off · भाषा: zh-CN
- तीन रंग: `#f5efe6` (फ़ॉन्ड) · `#1d1a17` (टेक्स्ट) · `#3f66a3` (एक्सेंट)

कोड उत्पादन एनकोडर से बनता है और इस README में जाने से पहले आगे-पीछे आत्म-जाँचा जाता है — कभी हाथ से नहीं लिखा जाता।

## Trade-offs

यहाँ के अन्य थीम प्लगइन ग्लास, वॉलपेपर और एनिमेशन देते हैं। हम जानबूझकर नहीं करते:

- **न ग्लास, न वॉलपेपर।** वे स्क्रीनशॉट से जीतते हैं; हम प्रमाण से जीतना चाहते हैं।
- **न थीम मार्केट, न AI रंग सृजन।** दोनों ऐसे रंग लाते हैं जिन्हें हम गारंटी नहीं दे सकते; कॉन्ट्रास्ट सॉल्वर ही संपत्ति है।
- **और पैलेट नहीं।** चार प्रीसेट + तीन-रंग जनरेटर, हाथ से चुने दस से बेहतर है; मात्रा बढ़ाना फ़ायदा नहीं।
- **न आँखों की सुरक्षा के वादे।** हम उसी सतह पर मापे अनुपात बताते हैं जहाँ टेक्स्ट वास्तव में बैठता है, और जब कोई सतह वादे की नहीं होती तो वहाँ «नीति से बाहर» कहते हैं — यह एक माप है, बहाना नहीं।


## License

MIT © 2026 Zuoyunlai
