/* ============================================================================
   zbt-porcelain.css — СКИН-СЛОЙ „Порцелан" за всички модули (v2 · 2026-10-31).
   Централизираната версия на пилота на yufa (GRAPHIC-PLAN §1: решения 8, 9) +
   донастройките от §2–§5 по решението на собственика от 2026-10-31
   („както препоръчваш"): неутрали porcelain-cool, по-тъмен --muted, токенизирани
   сенки/ръбове (готови за тъмен паритет), скали радиус/елевация/движение,
   типографски мащаб, :focus-visible, тап-цели, opt-in бутони/табове.
   Self-hosted, в корена на ВСЕКИ поддомейн, ПОСЛЕДЕН <link> в <head>:
     <link rel="stylesheet" href="/zbt-porcelain.css?v=2">

   КАСКАДА (защо :root тук печели): всяка страница носи свой inline :root с
   --bg/--card/--muted/--line/--shadow; този файл е ПОСЛЕДНИЯТ <link>, затова
   неговият :root бие inline-а при равна специфичност. Това се ползва СЪЗНАТЕЛНО и
   САМО за неутралите (--bg --card --muted --line --shadow --accent-soft) — това е
   контрактът „единственото per-модул различие е акцентът" (CLAUDE.md).
   НИКОГА за --accent / --accent2 / --ink / --font — те остават на страницата.
   НЕ пипа оформлението (без размери на блокове, отстъпи, display) и цветовете на
   заглавията (страниците оцветяват свои — напр. ерите в keji/space-program).
   Хедърът (/zbt-header.css, /zbt-chrome.css) и футърът (/zbt-footer.js) са отделно.

   ТЪМЕН ПАРИТЕТ (НЕ сега — решение 2026-10-31): всички компоненти сочат токени,
   не литерали. Тъмен скин = един блок html[data-skin="porcelain-dark"], който
   предефинира САМО блока „НЕУТРАЛИ" + --shadow* + color-scheme:dark (шаблон в
   коментар най-долу). Акцентите пак идват от страницата.
   ============================================================================ */
@import url("https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@500;600;700&display=swap");

:root{
  /* ── НЕУТРАЛИ — porcelain-cool (GRAPHIC-PLAN §2 + донастройки) ──
     --card off-white (#fcfeff, не чисто #fff); --muted потъмнен → 5.5:1 върху --bg,
     5.8:1 върху --card (AA за дребен текст, запас). Бият inline :root на страницата. */
  --bg:#f4f7fb;
  --card:#fcfeff;
  --muted:#5b6572;
  --line:#e1e9f2;

  /* ── ЕЛЕВАЦИЯ — само през токени (§4; тъмен скин ги предефинира, инак сянката
     се обръща в светъл ореол). Големият слой е .07 навсякъде. */
  --shadow:0 1px 2px rgba(20,40,74,.04),0 12px 32px rgba(20,40,74,.07);
  --shadow-hover:0 2px 4px rgba(20,40,74,.05),0 18px 44px rgba(20,40,74,.10);
  --shadow-sm:0 1px 2px rgba(20,40,74,.06);
  /* ръбове, базирани на мастилото (не изчезват на топъл фон, обръщат се на тъмен) */
  --zbt-edge:rgba(27,36,48,.12);
  --zbt-edge-soft:rgba(27,36,48,.07);

  /* ── АКЦЕНТ-ПРОИЗВОДНИ — изведени от --accent на МОДУЛА (не го пипаме) ──
     --accent-soft: тонална плочка (чипове/табове/hover) — тонирана с акцента, не сиво;
     --accent-ink: дребен текст/връзки в акцента, по-тъмен за AA. Страница, която
     дава свой --accent-ink, го бие само ако е по-късно в каскадата (не е). */
  --accent-soft:#e9f1fb;
  --accent-ink:color-mix(in srgb,var(--accent,#2f66ba) 84%,#000);

  /* ── ТИПОГРАФИЯ (§3) — размерите на мащаба (--zbt-fs-*, стъпка 1.2) са в /zbt-ui.css */
  --font-display:"Noto Serif SC",Georgia,"Songti SC",serif;
  --zbt-fs-body:1rem;          /* тяло ≥16px */
  --zbt-fs-read:1.0625rem;     /* четиво 17px */
  --zbt-fs-lead:1.1875rem;     /* водещ абзац 19px */
  --zbt-lh:1.6;                /* тяло */
  --zbt-lh-cjk:1.75;           /* CJK-тежки абзаци */

  /* ── РАДИУС (§4) ── */
  --zbt-r-1:6px;    /* сегменти в панел */
  --zbt-r-2:8px;    /* бутони, чипове, табове — каноничен */
  --zbt-r-3:12px;   /* панели, инпути */
  --zbt-r-4:16px;   /* карти */
  --zbt-r-pill:999px;/* тагове */

  /* ── ДВИЖЕНИЕ (§4) ── */
  --zbt-t:.18s;
  --zbt-t-slow:.3s;
  --zbt-ease:cubic-bezier(.2,.6,.2,1);

  /* ── ФОКУС / ТАП ── (--zbt-tap:40px идва от /zbt-ui.css; споделените контроли ползват ≥44px) */
  --zbt-focus:2px solid var(--accent,#2f66ba);
  --zbt-tap-lg:44px;
}
/* Производните токени се декларират на :root,* — т.е. на ВСЕКИ елемент, — защото
   var() вътре в custom property се замества там, където е декларирано: само на :root
   те биха „замръзнали" с акцента на :root и нямаше да следват локален override
   (body.m-…/html[data-module] — куката за модула от GRAPHIC-PLAN §1b, или секция
   със свой --accent). Така всеки елемент ги изчислява от наследения --accent/--ink.
   Цената е нищожна (четири color-mix на елемент). */
@supports (background:color-mix(in srgb,red,blue)){
  :root,*{
    --accent-soft:color-mix(in srgb,var(--accent,#2f66ba) 10%,var(--card,#fcfeff));
    --accent-ink:color-mix(in srgb,var(--accent,#2f66ba) 84%,#000);
    --zbt-edge:color-mix(in srgb,var(--ink,#1b2430) 12%,transparent);
    --zbt-edge-soft:color-mix(in srgb,var(--ink,#1b2430) 7%,transparent);
    --zbt-focus:2px solid var(--accent,#2f66ba);
  }
}
@media (prefers-reduced-motion:reduce){
  :root{--zbt-t:.01ms;--zbt-t-slow:.01ms}
}

/* 9) серифни заглавия. Хедър-заглавието (.htitle) остава безсерифно — то е част
   от лентата, като на yufa. В :where() → НУЛЕВА специфичност: всяко правило на
   страницата/модула, което само избира шрифт/тегло за свое заглавие, печели
   (каскадата „централизирано → локален приоритет"): напр. дисплейният Palatino на
   zhuangrong, атласът/статистиките (--f-display) и малките главни етикети в
   контролните панели (там страницата казва font-family:inherit).
   Тегло 600 (по-тихо от bold), без положителен тракинг (§3). */
:where(h1:not(.htitle),h2,h3){font-family:var(--font-display);font-weight:600;letter-spacing:0}

/* 3) тяло: ред 1.6 (CJK 1.75, без тракинг). Пак :where() — страница със свой
   line-height на body печели. Размерът НЕ се пипа тук (идва от /zbt-ui.css). */
:where(body){line-height:var(--zbt-lh)}
:where(html[lang="zh"] body){line-height:var(--zbt-lh-cjk);letter-spacing:normal}
/* водещ абзац излиза от --muted (граничен контраст) → смес мастило/muted ≈7:1;
   --muted остава за дребни мета-етикети */
:where(.lead,.zbt-lead){color:color-mix(in srgb,var(--ink,#1b2430) 35%,var(--muted))}
:where(.zbt-lead){font-size:var(--zbt-fs-lead);font-weight:400;line-height:1.55;max-width:64ch}
:where(.zbt-read){font-size:var(--zbt-fs-read);line-height:var(--zbt-lh)}

/* 7) фокус-пръстен навсякъде (WCAG 2.4.7). outline, не box-shadow — не се реже от
   backdrop-filter. :where() → страница с по-специфично :focus-правило печели. */
:where(a,button,[role="button"],input,select,textarea,summary,[tabindex]):focus-visible{outline:var(--zbt-focus);outline-offset:2px}

/* 5.2) езиков панел — сегментираният мини-панел (решение 5: правоъгълна релса 10px +
   повдигнат активен сегмент 7px) е И ТУК, не само в /zbt-header.css и /zbt-chrome.css:
   този файл е на ВСЯКА страница и е ПОСЛЕДНИЯТ <link>, затова при равна специфичност
   бие остатъчните inline `.langs{…border-radius:999px}` (стария кръгъл пил) на
   страници без /zbt-header.css (keji/math/*, zhongyi/xiyi/) или с inline <style> СЛЕД
   него (wenhua/normi, rodnini) — задача D, 2026-10-31. Стойностите са ЕДНАКВИ с
   /zbt-header.css (без order — подредбата в бара остава там); промяна на вида = и на
   трите места. Плюс фокус + тап-цел: видимата височина остава компактна (2rem), а
   тап-целта се разширява до ≥44px с невидим ::before (±6px вертикално, само в реда на
   лентата) — без да расте хедърът. Тежестта НЕ се сменя при активиране (без джитър). */
.langs{display:inline-flex;flex:0 0 auto;align-items:center;gap:2px;padding:3px;border-radius:10px;
  background:rgba(31,26,23,.05);border:1px solid var(--line);box-shadow:none}
.langs button{position:relative;min-height:2rem;border:0;background:none;color:var(--muted);
  font:inherit;font-weight:600;font-size:.8rem;line-height:1.2;padding:.25rem .7rem;border-radius:7px;
  cursor:pointer;white-space:nowrap;box-shadow:none;transition:background .15s,color .15s,box-shadow .15s}
.langs button::before{content:"";position:absolute;left:0;right:0;top:-6px;bottom:-6px}
.langs button:hover{color:var(--ink)}
.langs button.on{background:var(--card,#fcfeff);color:var(--accent-ink,var(--accent));box-shadow:0 1px 2px rgba(31,26,23,.12)}
.langs button:focus-visible{outline:var(--zbt-focus);outline-offset:1px}
@supports (background:color-mix(in srgb,red,blue)){
  .langs{background:color-mix(in srgb,var(--ink) 5%,transparent);border-color:color-mix(in srgb,var(--line) 60%,transparent)}
  .langs button.on{box-shadow:0 1px 2px color-mix(in srgb,var(--ink) 12%,transparent)}
}

/* ============================================================================
   OPT-IN КОМПОНЕНТИ за бъдещи/мигрирани страници (бутоните в модулите носят свои
   класове — НЕ се преследват). Решение 2026-10-31 (бутон-галерията, §8.1):
     .zbt-btn          — второстепенен: семейство „ръб/контур" (outline-soft-fill):
                         прозрачен, hairline-ръб от мастилото, при hover лек пълнеж.
     .zbt-btn-primary  — основно действие (outline-soft-fill, pri): акцент-текст +
                         акцент-ръб 50%; hover = тонална плочка --accent-soft + пълен ръб.
                         Почти без пълнеж — „наситено само на дребно".
     .zbt-tab          — таб (flat-ghost): прозрачен + hairline; hover акцент 6%;
                         активен (.on / aria-selected / aria-pressed) = ТОНАЛЕН
                         (акцент 11% + вътрешен ринг + --accent-ink). Без скок на тежестта.
     .zbt-tabs         — ред от табове (flex, пренася се).
   Маркъп: <button class="zbt-btn-primary">…</button> · <a class="zbt-btn">…</a>
           <div class="zbt-tabs" role="tablist"><button class="zbt-tab on" role="tab" aria-selected="true">…</button>…</div>
   Тап-цел ≥44px (min-height), радиус --zbt-r-2 (8px), фокус = outline, движение
   през --zbt-t/--zbt-ease, без backdrop-filter. Всичко през токени → скин-безопасно.
   ============================================================================ */
.zbt-btn,.zbt-btn-primary,.zbt-tab{
  display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  min-height:var(--zbt-tap-lg);padding:.55em 1.1em;margin:0;
  border:0;border-radius:var(--zbt-r-2);
  font:inherit;font-weight:600;line-height:1.2;text-decoration:none;white-space:nowrap;
  color:var(--ink,#1b2430);background:transparent;cursor:pointer;
  box-shadow:inset 0 0 0 1px var(--zbt-edge);
  transition:background-color var(--zbt-t) var(--zbt-ease),box-shadow var(--zbt-t) var(--zbt-ease),color var(--zbt-t) var(--zbt-ease),border-color var(--zbt-t) var(--zbt-ease);
  -webkit-tap-highlight-color:transparent;
}
.zbt-btn:hover{background:rgba(27,36,48,.06);box-shadow:inset 0 0 0 1px rgba(27,36,48,.22)}
.zbt-btn:active{background:rgba(27,36,48,.10)}
.zbt-btn-primary{color:var(--accent-ink,var(--accent));box-shadow:inset 0 0 0 1px var(--accent,#2f66ba)}
.zbt-btn-primary:hover{background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--accent,#2f66ba)}
.zbt-btn-primary:active{background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--accent,#2f66ba)}
.zbt-tab{box-shadow:none;border:1px solid var(--zbt-edge);padding:.5em .95em}
.zbt-tab:hover{background:var(--accent-soft)}
.zbt-tab.on,.zbt-tab[aria-selected="true"],.zbt-tab[aria-pressed="true"]{
  background:var(--accent-soft);border-color:var(--accent,#2f66ba);color:var(--accent-ink,var(--accent))}
.zbt-tabs{display:inline-flex;flex-wrap:wrap;gap:.35rem;align-items:center}
.zbt-btn:disabled,.zbt-btn-primary:disabled,.zbt-tab:disabled,.zbt-btn[aria-disabled="true"],.zbt-btn-primary[aria-disabled="true"]{opacity:.45;cursor:default;pointer-events:none}
@supports (background:color-mix(in srgb,red,blue)){
  .zbt-btn:hover{background:color-mix(in srgb,var(--ink,#1b2430) 6%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink,#1b2430) 22%,transparent)}
  .zbt-btn:active{background:color-mix(in srgb,var(--ink,#1b2430) 10%,transparent)}
  .zbt-btn-primary{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent,#2f66ba) 50%,var(--line))}
  .zbt-btn-primary:hover{background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--accent,#2f66ba)}
  .zbt-btn-primary:active{background:color-mix(in srgb,var(--accent,#2f66ba) 16%,var(--card));box-shadow:inset 0 0 0 1px var(--accent,#2f66ba)}
  .zbt-tab:hover{background:color-mix(in srgb,var(--accent,#2f66ba) 6%,var(--card));border-color:color-mix(in srgb,var(--accent,#2f66ba) 28%,var(--line))}
  .zbt-tab.on,.zbt-tab[aria-selected="true"],.zbt-tab[aria-pressed="true"]{
    background:color-mix(in srgb,var(--accent,#2f66ba) 11%,var(--card));
    border-color:color-mix(in srgb,var(--accent,#2f66ba) 45%,transparent);
    box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent,#2f66ba) 28%,transparent)}
}
@media (prefers-reduced-motion:reduce){.zbt-btn,.zbt-btn-primary,.zbt-tab,.langs button{transition:none}}

/* 8) фонова шарка 青海波 (сеигайха) ~3.5% (решение 2026-10-31: остава), оцветена с
   мастилото на скина. На <html>::before (не на body), за да не се бие със страничен
   body::before. Вижда се, защото фонът на body се пренася върху платното (никоя
   страница не слага фон на <html>); непрозрачна обвивка на страницата просто я покрива. */
html::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:var(--ink,#1f1a17);opacity:.035;
  -webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='24' viewBox='0 0 48 24'><g fill='none' stroke='%23808080' stroke-width='1'><path d='M0 24 A24 24 0 0 1 48 24'/><path d='M-24 24 A24 24 0 0 1 24 24'/><path d='M24 24 A24 24 0 0 1 72 24'/><path d='M0 12 A12 12 0 0 1 24 12'/><path d='M24 12 A12 12 0 0 1 48 12'/></g></svg>");
          mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='24' viewBox='0 0 48 24'><g fill='none' stroke='%23808080' stroke-width='1'><path d='M0 24 A24 24 0 0 1 48 24'/><path d='M-24 24 A24 24 0 0 1 24 24'/><path d='M24 24 A24 24 0 0 1 72 24'/><path d='M0 12 A12 12 0 0 1 24 12'/><path d='M24 12 A12 12 0 0 1 48 12'/></g></svg>");
  -webkit-mask-size:48px;mask-size:48px;-webkit-mask-repeat:repeat;mask-repeat:repeat}
@media print{html::before{display:none}}

/* ----------------------------------------------------------------------------
   ШАБЛОН ЗА ТЪМЕН СКИН (неактивен; включва се, когато собственикът реши — тогава
   /zbt-skin.js слага html[data-skin]). Предефинира САМО неутрали + елевация:
   html[data-skin="porcelain-dark"]{
     color-scheme:dark;
     --bg:#141a21; --card:#1b232c; --muted:#9aa7b5; --line:#2a3542; --ink:#e6edf5;
     --shadow:0 1px 2px rgba(0,0,0,.35),0 12px 32px rgba(0,0,0,.45);
     --shadow-hover:0 2px 4px rgba(0,0,0,.4),0 18px 44px rgba(0,0,0,.55);
     --shadow-sm:0 1px 2px rgba(0,0,0,.4);
   }
   (--zbt-edge*/--accent-soft/--accent-ink са color-mix от --ink/--accent → следват сами.)
   ---------------------------------------------------------------------------- */
