[{"data":1,"prerenderedAt":327},["ShallowReactive",2],{"docs:\u002Fdocs\u002Ffoundations\u002Fdark-mode":3},{"id":4,"title":5,"body":6,"component":315,"dependsOn":316,"description":317,"emitDescriptions":318,"extension":319,"meta":320,"navigation":321,"order":72,"path":322,"seo":323,"status":324,"stem":325,"__hash__":326},"docs\u002Fdocs\u002Ffoundations\u002Fdark-mode.md","Темна тема",{"type":7,"value":8,"toc":309},"minimark",[9,22,27,41,48,82,97,101,111,118,247,257,261,276,279,283,290,305],[10,11,12,13,17,18,21],"p",{},"Тема перемикається класом ",[14,15,16],"code",{},".dark"," на ",[14,19,20],{},"\u003Chtml>",", а не медіазапитом. Медіазапит\nне дав би користувачеві вибору — а вибір потрібен: ту саму систему вмикають\nі вдень біля вікна, і вночі.",[23,24,26],"h2",{"id":25},"чому-компоненти-не-мають-dark-префіксів","Чому компоненти не мають dark:-префіксів",[10,28,29,30,32,33,36,37,40],{},"Утиліти посилаються на CSS-змінні, а ",[14,31,16],{}," перевизначає самі змінні. Тому\n",[14,34,35],{},"bg-card"," працює в обох темах без жодного ",[14,38,39],{},"dark:bg-...",".",[10,42,43,44,47],{},"Це тримається на одному слові в ",[14,45,46],{},"theme.css",":",[49,50,55],"pre",{"className":51,"code":52,"language":53,"meta":54,"style":54},"language-css shiki shiki-themes github-light github-dark","@theme inline {\n  --color-card: var(--bg-card);\n}\n","css","",[14,56,57,70,76],{"__ignoreMap":54},[58,59,62,66],"span",{"class":60,"line":61},"line",1,[58,63,65],{"class":64},"szBVR","@theme",[58,67,69],{"class":68},"sVt8B"," inline {\n",[58,71,73],{"class":60,"line":72},2,[58,74,75],{"class":68},"  --color-card: var(--bg-card);\n",[58,77,79],{"class":60,"line":78},3,[58,80,81],{"class":68},"}\n",[10,83,84,85,88,89,93,94,96],{},"Без ",[14,86,87],{},"inline"," Tailwind підставив би ",[90,91,92],"strong",{},"значення"," змінної в момент генерації,\nі ",[14,95,35],{}," назавжди застигла б білою. Це найлегша помилка в усій системі й\nнайважча для діагностики: усе виглядає правильно, поки не перемкнеш тему.",[23,98,100],{"id":99},"спалах-при-завантаженні","Спалах при завантаженні",[10,102,103,104,106,107,110],{},"Сторінки прередерені, і в їхньому HTML класу ",[14,105,16],{}," немає — його ставить\nлише клієнт. Без запобіжника користувач із темною темою бачив би білий\nспалах на ",[90,108,109],{},"кожному"," завантаженні, поки не відпрацює гідрація.",[10,112,113,114,117],{},"Тому в ",[14,115,116],{},"\u003Chead>"," стоїть блокуючий скрипт, який виконується до першого\nмалювання:",[49,119,123],{"className":120,"code":121,"language":122,"meta":54,"style":54},"language-js shiki shiki-themes github-light github-dark","(() => {\n  try {\n    const s = localStorage.getItem('tatetui-theme')\n    const d = s ? s === 'dark' : matchMedia('(prefers-color-scheme:dark)').matches\n    if (d) document.documentElement.classList.add('dark')\n  } catch (e) {}\n})()\n","js",[14,124,125,136,143,172,210,229,241],{"__ignoreMap":54},[58,126,127,130,133],{"class":60,"line":61},[58,128,129],{"class":68},"(() ",[58,131,132],{"class":64},"=>",[58,134,135],{"class":68}," {\n",[58,137,138,141],{"class":60,"line":72},[58,139,140],{"class":64},"  try",[58,142,135],{"class":68},[58,144,145,148,152,155,158,162,165,169],{"class":60,"line":78},[58,146,147],{"class":64},"    const",[58,149,151],{"class":150},"sj4cs"," s",[58,153,154],{"class":64}," =",[58,156,157],{"class":68}," localStorage.",[58,159,161],{"class":160},"sScJk","getItem",[58,163,164],{"class":68},"(",[58,166,168],{"class":167},"sZZnC","'tatetui-theme'",[58,170,171],{"class":68},")\n",[58,173,175,177,180,182,185,188,190,193,196,199,202,204,207],{"class":60,"line":174},4,[58,176,147],{"class":64},[58,178,179],{"class":150}," d",[58,181,154],{"class":64},[58,183,184],{"class":68}," s ",[58,186,187],{"class":64},"?",[58,189,184],{"class":68},[58,191,192],{"class":64},"===",[58,194,195],{"class":167}," 'dark'",[58,197,198],{"class":64}," :",[58,200,201],{"class":160}," matchMedia",[58,203,164],{"class":68},[58,205,206],{"class":167},"'(prefers-color-scheme:dark)'",[58,208,209],{"class":68},").matches\n",[58,211,213,216,219,222,224,227],{"class":60,"line":212},5,[58,214,215],{"class":64},"    if",[58,217,218],{"class":68}," (d) document.documentElement.classList.",[58,220,221],{"class":160},"add",[58,223,164],{"class":68},[58,225,226],{"class":167},"'dark'",[58,228,171],{"class":68},[58,230,232,235,238],{"class":60,"line":231},6,[58,233,234],{"class":68},"  } ",[58,236,237],{"class":64},"catch",[58,239,240],{"class":68}," (e) {}\n",[58,242,244],{"class":60,"line":243},7,[58,245,246],{"class":68},"})()\n",[10,248,249,252,253,256],{},[14,250,251],{},"try\u002Fcatch"," обов'язковий: у приватному режимі Safari звернення до\n",[14,254,255],{},"localStorage"," кидає виняток, і без нього сторінка не намалювалася б узагалі.",[23,258,260],{"id":259},"джерело-правди-dom-а-не-сховище","Джерело правди — DOM, а не сховище",[10,262,263,266,267,272,273,275],{},[14,264,265],{},"useTheme()"," читає початкове значення ",[90,268,269,270],{},"з класу на ",[14,271,20],{},", а не з\n",[14,274,255],{},". Клас уже поставив скрипт вище, і саме він — джерело правди.",[10,277,278],{},"Якби composable читав сховище сам, сервер і клієнт розійшлися б у першому\nрендері прередереної сторінки, і Vue лаявся б на невідповідність гідрації.",[23,280,282],{"id":281},"що-перевіряти-в-кожному-компоненті","Що перевіряти в кожному компоненті",[10,284,285,286,289],{},"Тіні. У світлій темі ",[14,287,288],{},"--shadow-card"," це 4% чорного — на темному тлі такого\nпросто не видно, і картка «злипається» з фоном. Тому в темній темі тіні\nсильніші, і це задано токеном, а не класом.",[10,291,292,293,296,297,300,301,304],{},"Напівпрозорі підкладки. ",[14,294,295],{},"bg-primary-900\u002F30"," над майже чорним тлом дає\nвидимий результат лише тому, що ",[14,298,299],{},"--brand-900"," у темній темі ",[90,302,303],{},"світліший",".\nЯкщо додаєте власний відтінок — перевірте його саме в такому вживанні.",[306,307,308],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":54,"searchDepth":72,"depth":72,"links":310},[311,312,313,314],{"id":25,"depth":72,"text":26},{"id":99,"depth":72,"text":100},{"id":259,"depth":72,"text":260},{"id":281,"depth":72,"text":282},null,[],"Клас на html, блокуючий скрипт проти спалаху і чому inline в @theme обов'язковий.",{},"md",{},true,"\u002Fdocs\u002Ffoundations\u002Fdark-mode",{"title":5,"description":317},"stable","docs\u002Ffoundations\u002Fdark-mode","hzwnp89MCr1EnDEUHfTb1u_-7f_5EVnEx8jqeSPAZJE",1788072641389]