/* МОЗАЇКА ВІТРИН — плитка-вказівник, одна на портал (packages/ui/mosaic.js).
   Приїхала з apps/home/style/directory.css, щойно знадобилась другій зоні
   (правило 2 в CLAUDE.md). Тут ЛИШЕ те, що спільне: сітка, плитка, мотив,
   гілки, лічильник, поле пошуку. Маршрут, покажчик тем і провідна смуга
   лишились головній — вони про неї, а не про плитку.
   Токени НЕ перевизначаються в :root — тільки на власних контейнерах. */

.dir-mosaic, .dir-find { --dir-ease: cubic-bezier(.22, 1, .36, 1); }

/* ── Поверх ────────────────────────────────────────────────────────────── */
.dir-floor { display: flex; align-items: center; gap: 14px; margin: 0 0 16px; }
.dir-floor h2 { margin: 0; font-family: var(--font); font-size: .74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .13em; color: var(--hint); }
.dir-floor .rule { flex: 1; height: 1px; background: var(--glass-border); }
.dir-band { margin: 0 0 44px; }

/* ── Сітка ─────────────────────────────────────────────────────────────── */
.dir-mosaic { display: grid; grid-template-columns: 1fr; gap: 14px; perspective: 1400px; }
@media (min-width: 640px)  { .dir-mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .dir-mosaic { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; }
  .dir-tile.anchor { grid-column: span 2; grid-row: span 2; }
  .dir-tile.wide   { grid-column: span 2; } }
@media (min-width: 1440px) { .dir-mosaic { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* Режим сторінки розділу — див. блок «Навстіж» унизу файлу. Колонок дві на
   будь-якій ширині: чотири плитки лягають квадратом, сім — трьома парами й
   останньою. Шість колонок тут дали б плитку, у якій гілці нема куди рости. */
@media (min-width: 1024px) {
  .dir-mosaic.open { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Плитка ────────────────────────────────────────────────────────────── */
.dir-tile {
  position: relative; display: flex; flex-direction: column; overflow: hidden; isolation: isolate;
  min-height: 168px; padding: 20px 22px; border-radius: 18px;
  background: var(--surface); border: 1px solid var(--glass-border); box-shadow: var(--shadow-card);
  color: inherit; text-decoration: none; transform-style: preserve-3d;
  /* Без цього браузер чекає 300 мс, чи не буде другого тапу (подвійний тап =
     зум), і плитка відгукується із затримкою, яку відчутно пальцем. */
  touch-action: manipulation;
  transform: perspective(1400px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--ty, 0px));
  transition: transform .35s var(--dir-ease), box-shadow .35s var(--dir-ease), border-color var(--transition);
}
.dir-tile.anchor { min-height: 340px; padding: 28px 30px; }
.dir-tile.wide { min-height: 186px; }

.dir-tile .sign { position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--zone); opacity: .9; z-index: 4; }
/* Гравюрна штриховка — найглибший шар. Градієнтом, а не SVG-патерном: та сама
   картинка, але без <defs> у розмітці й без другого дерева елементів. */
.dir-tile .hatch { position: absolute; inset: -8%; z-index: 0; pointer-events: none; opacity: .5;
  background-image: repeating-linear-gradient(38deg,
    color-mix(in srgb, var(--zone) 20%, transparent) 0 1px, transparent 1px 7px);
  transform: translate3d(calc(var(--mx, 0) * 4px), calc(var(--my, 0) * 4px), -40px);
  transition: transform .5s var(--dir-ease); }
.dir-tile .wash { position: absolute; inset: -10%; z-index: 1; pointer-events: none; opacity: .7;
  background: radial-gradient(130% 95% at 14% -8%, color-mix(in srgb, var(--zone) 24%, transparent), transparent 64%);
  transform: translate3d(calc(var(--mx, 0) * 9px), calc(var(--my, 0) * 9px), -20px);
  transition: transform .5s var(--dir-ease), opacity .3s var(--dir-ease); }
.dir-tile .sheen { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; mix-blend-mode: soft-light;
  background: radial-gradient(340px circle at var(--px, 50%) var(--py, 50%), rgba(255,255,255,.5), transparent 62%);
  transition: opacity .3s var(--dir-ease); }
.dir-tile .body { position: relative; z-index: 5; display: flex; flex-direction: column; height: 100%; transform: translateZ(24px); }

.dir-tile .ico { width: 26px; height: 26px; margin-bottom: auto; transition: transform .3s var(--dir-ease); }
.dir-tile.anchor .ico { width: 34px; height: 34px; }
.dir-tile :is(h2, h3) { margin: 16px 0 5px; font-size: 1.08rem; text-wrap: balance;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dir-tile.anchor :is(h2, h3) { font-size: 1.62rem; margin-top: 20px; }
.dir-tile p { margin: 0; color: var(--hint); font-size: .92rem; text-wrap: pretty; max-width: 46ch; }
.dir-tile.anchor p { font-size: 1rem; max-width: 40ch; }

/* ── Лічильник вмісту ──────────────────────────────────────────────────────
   Скільки в зоні всередині — і скільки з того нового саме для цього
   відвідувача. Стоїть під описом, останнім рядком вітрини: це не обіцянка
   («що тут є»), а міра («скільки його»), і читається вона після обіцянки.

   Цифри ТАБЛИЧНІ. Число набігає від нуля, а пропорційні цифри мають різну
   ширину — рядок смикався б на кожному кадрі. tabular-nums прибиває колонку
   намертво, і рухається лише саме число.

   Колір зони на числі, а не сірий: це частина вітрини, а не підпис під нею. */
.dir-stock {
  display: flex; align-items: baseline; gap: 7px; margin: 12px 0 0;
  font-size: .82rem; color: var(--hint); font-variant-numeric: tabular-nums;
}
.dir-stock b { font-size: .98rem; font-weight: 700; color: var(--zone); }
.dir-tile.anchor .dir-stock { font-size: .9rem; margin-top: 16px; }
.dir-tile.anchor .dir-stock b { font-size: 1.12rem; }

/* «Нове» — золота пігулка. Золото на порталі скрізь означає «сюди дивись»
   (кільце фокуса, рамка плитки під курсором), і тут воно значить те саме.
   Чорнило темне власне, а не з --gold: світле золото на кремовому тлі дає
   близько чотирьох до одного, а це підпис у 12 пікселів — йому треба більше. */
.dir-stock :is(i, .dir-new) {
  font-style: normal; font-weight: 600; font-size: .74rem;
  padding: 2px 9px; border-radius: 999px; white-space: nowrap;
  background: color-mix(in srgb, var(--gold) 20%, transparent);
  border: 1px solid var(--border-gold); color: #6E5709;
  transition: opacity .18s var(--dir-ease), transform .18s var(--dir-ease), background var(--transition);
}
/* Пігулка з переліком — кнопка. Стрілка каже, що вона розгортається, а не веде
   геть; висота 24px — найменша ціль, у яку влучає палець. */
.dir-stock .dir-new {
  display: inline-flex; align-items: center; gap: 5px; min-height: 24px; padding: 2px 10px;
  font-family: inherit; line-height: 1; cursor: pointer; position: relative; z-index: 1;
}
.dir-stock .dir-new::after { content: ''; width: 5px; height: 5px; margin-top: -3px;
  border: solid currentColor; border-width: 0 1.5px 1.5px 0; transform: rotate(45deg); }
.dir-stock .dir-new:hover { background: color-mix(in srgb, var(--gold) 34%, transparent); }
.dir-stock .dir-new:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.dir-stock .dir-new[aria-expanded="true"] { background: color-mix(in srgb, var(--gold) 34%, transparent); }

/* Число — кнопка «що всередині» (головне в зоні, apps/home/picks.js). Виглядає
   як той самий рядок лічильника, а не як кнопка: його читають як міру, і лише
   пунктир під одиницею та шеврон кажуть, що воно розгортається. Ціль — уся
   фраза «163 записи», не саме число: у шість пікселів цифри палець не влучить. */
.dir-stock .dir-more {
  display: inline-flex; align-items: baseline; gap: 7px; margin: 0 0 0 -6px; padding: 3px 6px;
  border: 0; border-radius: 8px; background: transparent; color: inherit;
  font: inherit; font-variant-numeric: tabular-nums; cursor: pointer; position: relative; z-index: 1;
  text-decoration: underline dotted color-mix(in srgb, var(--zone) 55%, transparent);
  text-underline-offset: 4px; text-decoration-thickness: 1.5px;
  transition: background-color .15s var(--dir-ease), transform .16s var(--dir-ease);
}
.dir-stock .dir-more::after { content: ''; align-self: center; width: 5px; height: 5px; margin: -3px 0 0 -1px;
  border: solid var(--zone); border-width: 0 1.5px 1.5px 0; transform: rotate(45deg); }
.dir-stock .dir-more:hover, .dir-stock .dir-more[aria-expanded="true"] {
  background: color-mix(in srgb, var(--zone) 10%, transparent); }
.dir-stock .dir-more:active, .dir-stock .dir-new:active { transform: scale(.97); }
.dir-stock .dir-more:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* Пальцем — ціль не менша за 36px заввишки, і між двома кнопками рядка є зазор. */
@media (pointer: coarse) {
  .dir-stock { align-items: center; gap: 8px; }
  .dir-stock .dir-more { min-height: 36px; align-items: center; padding: 4px 8px; margin-left: -8px; }
  .dir-stock .dir-new { min-height: 32px; }
}

/* Стан на час набігання — його ставить і знімає клієнт. Без скрипта (і при
   вимкненій анімації) клас не з'являється взагалі, тож вітрина повна з
   першого кадру: числа в розмітці справжні, а не нулі.
   Пігулка чекає, поки добіжить число: спершу «скільки всього», потім
   «скільки з цього для вас» — разом вони змагалися б за один погляд. */
.dir-stock.counting :is(i, .dir-new) { opacity: 0; transform: scale(.94); }

/* ── Плата: гравюрний мотив у куті ────────────────────────────────────── */
.dir-plate { position: absolute; right: 0; bottom: 0; width: 200px; height: 200px; z-index: 2;
  pointer-events: none; color: var(--zone);
  transform: translate3d(calc(var(--mx, 0) * 18px), calc(var(--my, 0) * 18px), 8px);
  transition: transform .5s var(--dir-ease); }
.dir-tile.anchor .dir-plate { width: 300px; height: 300px; }
/* Плита на звичайній плитці (Календар, Презентації, Демо) — кутовий акцент, а
   не тло. На плитці ~210px завширшки плата в 200px накривала її цілком і лізла
   під текст, а виїжджати на наведенні їй нема куди. Тож менша, глибше в кут і
   нерухома. */
.dir-tile:not(:is(.anchor, .wide)) .dir-plate { width: 132px; height: 132px; right: -14px; bottom: -16px; }
.dir-tile:not(:is(.anchor, .wide)) .dir-plate .art { opacity: .13; transform: none; }
/* На телефоні плата в 300px накривала майже всю плитку й тиснула текст. */
@media (max-width: 639px) {
  .dir-plate { width: 170px; height: 170px; }
  .dir-tile.anchor .dir-plate { width: 215px; height: 215px; }
  .dir-tile:not(:is(.anchor, .wide)) .dir-plate { width: 130px; height: 130px; }
}
.dir-plate .plate { width: 100%; height: 100%; overflow: visible; }
/* Гравюра живе рівним волосяним штрихом: без non-scaling-stroke лінія на
   якірній платі 300px була б у півтора раза жирніша, ніж на звичайній 200px. */
.dir-plate :is(path, circle, rect, line) { vector-effect: non-scaling-stroke; }
/* У спокої мотив трохи менший і зсунутий у кут; на наведенні виростає на
   місце. Масштаб від кута плитки (transform-box: fill-box не потрібен —
   origin у нижньому правому куті вікна плати), тож росте він «з кута». */
.dir-plate .art { stroke-width: 1.6; opacity: .18; transform: translate(18px, 22px) scale(.94);
  transform-origin: 100% 100%;
  transition: opacity .35s var(--dir-ease), transform .45s var(--dir-ease); }

/* ── Гілки: мапа думок від іконки ──────────────────────────────────────────
   Іконка — корінь, гілки — розділи зони з їхнім розміром. Шар лежить у тій
   самій площині, що й текст (translateZ 24px): інакше при нахилі плитки корінь
   від'їжджав би від іконки, з якої росте.
   Ліва межа — правий край іконки плюс зазор; від неї геометрія в mosaic.js
   (LEAF_LEN, LEAF_STEP) міряє довжину гілок і крок між ними в пікселях.
   Права межа — край плитки: підпис, якому не вистачило ширини, обрізається
   трьома крапками, а не вилазить за плитку. */
.dir-map { --leaf-len: 96px; position: absolute; z-index: 6; pointer-events: none; color: var(--zone);
  left: calc(22px + 26px + 8px); top: calc(20px + 13px); right: 14px;
  transform: translateZ(24px); }
.dir-tile.anchor .dir-map { left: calc(30px + 34px + 8px); top: calc(28px + 17px); }
/* Корінь — крапка на початку гілок. HTML, не <circle>: SVG стискається по
   ширині, і коло стало б овалом. */
.dir-map::before { content: ''; position: absolute; left: -2px; top: -2px; width: 5px; height: 5px;
  border-radius: 50%; background: currentColor; opacity: 0; transition: opacity .2s var(--dir-ease); }
.dir-map svg { position: absolute; left: 0; top: 0; width: var(--leaf-len); overflow: visible; }
.dir-map path { stroke-width: 1.4; vector-effect: non-scaling-stroke;
  stroke-dasharray: 100; stroke-dashoffset: 100; transition: stroke-dashoffset .5s var(--dir-ease); }
/* Підпис відцентровано по лінії гілки (top ставить розмітка, це та сама
   ордината, що в кінця кривої). Назва — чорнилом тексту, число — кольором
   зони, дата — сірим: три ваги, які читаються без роздільників. Стискається
   лише назва: число й дата на гілці головні. */
.dir-map .leaf { position: absolute; left: calc(var(--leaf-len) + 8px);
  max-width: calc(100% - var(--leaf-len) - 8px); display: flex; align-items: baseline; gap: 6px;
  transform: translate(-6px, -50%); white-space: nowrap;
  font: 600 .76rem/1.25 var(--font); color: var(--text); font-variant-numeric: tabular-nums;
  opacity: 0; transition: opacity .2s var(--dir-ease), transform .3s var(--dir-ease); }
.dir-map .leaf > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.dir-map .leaf b { font-weight: 700; color: var(--zone); }
.dir-map .leaf time { font-weight: 500; color: var(--hint); }
/* На телефоні гілка коротша: на 340 пікселях плитки довга гілка лишала
   підпису менше, ніж треба «Одиницям та перерахункам».
   І дата йде геть. На 343px плитки підпис ділить із числом і датою близько
   двохсот пікселів, тобто тринадцять символів на назву: розділи бази знань
   («Складання та Перший запуск (DIY)», «Каталог периферійних пристроїв») усі
   до одного зрізались на другому слові. З трьох дата тут найменш потрібна:
   скільки — каже число, ЩО — каже назва, а коли оновлювали — питання, з яким
   на плитку не приходять. Без неї назві дістається вдвічі більше. */
@media (max-width: 639px) {
  .dir-map { --leaf-len: 64px; }
  .dir-map .leaf time { display: none; }
}
/* Під гілки над назвою резервується місце — і там, де вони стоять постійно, і
   на наведенні: інакше на широкій плитці з довгим описом третя гілка лягала на
   заголовок. Крок на гілку мінус те, що між іконкою і назвою вже є. */
.dir-tile.noted :is(h2, h3) { margin-top: max(16px, calc(var(--leaves) * 24px - 19px)); }
.dir-tile.anchor.noted :is(h2, h3) { margin-top: max(20px, calc(var(--leaves) * 24px - 23px)); }
/* Дрібній плитці на широкому екрані (чотири-шість колонок) гілки вже нема куди
   рости — на 200 пікселях підпис обрізався б після другого слова. Числа та
   сама плитка все одно каже рядком лічильника, і місця під гілки не тримає.
   Саме через це сторінка розділу бере режим .open: там плиток чотири-сім, а не
   дванадцять, і ховати від них найкорисніше нема за чим. */
@media (min-width: 1024px) {
  .dir-mosaic:not(.open) .dir-tile:not(:is(.anchor, .wide)) .dir-map { display: none; }
  .dir-mosaic:not(.open) .dir-tile.noted:not(:is(.anchor, .wide)) :is(h2, h3) { margin-top: 16px; }
}

/* ── Стани. Наведення і клавіатурний фокус ведуть себе однаково ─────────── */
.dir-tile.noted:is(:hover, :has(.dir-go:focus-visible)) .dir-plate .art { opacity: .4; transform: none; }
/* Без гілок мотив на наведенні лише трохи проявляється, з місця не рушить */
.dir-tile:not(.noted):is(:hover, :has(.dir-go:focus-visible)) .dir-plate .art { opacity: .24; }
/* Гілки викреслюються від кореня одна за одною, підпис проявляється, коли його
   гілка доросла. Назад — усі разом і швидко: зникати має швидше, ніж
   з'являтись, бо рука вже на іншій плитці. */
.dir-tile:is(:hover, :has(.dir-go:focus-visible)) .dir-map::before { opacity: 1; }
.dir-tile:is(:hover, :has(.dir-go:focus-visible)) .dir-map path { stroke-dashoffset: 0; transition-delay: calc(var(--n) * 70ms); }
.dir-tile:is(:hover, :has(.dir-go:focus-visible)) .dir-map .leaf { opacity: 1; transform: translate(0, -50%);
  transition-delay: calc(260ms + var(--n) * 70ms); }

/* ── Гілки навстіж: лише там, де наводити нічим ────────────────────────────
   Одна поведінка на весь портал: гілки зʼявляються НА НАВЕДЕННІ, і більше
   ніде не стоять. Доти було три випадки — дотик, сторінка розділу й
   «Розбори», — і на сторінці розділу це читалось як намальоване наперед:
   рух на плитці вже нічого не додавав, бо все й так було показане.

   Виняток лишається один і він не про смак: `(hover: none)`. Навести там
   нічим, і сховані за наведенням гілки не дістати взагалі — на телефоні
   пропали б і склад розділу, і заголовки в «Розборах». Тому на дотику вони
   стоять і викреслюються на вʼїзді в екран (клас `unseen` ставить і знімає
   mosaic-client.js); без скрипта — намальовані одразу. */
@media (hover: none) {
  .dir-tile.noted .dir-plate .art { opacity: .16; }
  .dir-map::before { opacity: 1; }
  .dir-map path { stroke-dashoffset: 0; transition-delay: calc(var(--n) * 70ms); }
  .dir-map .leaf { opacity: 1; transform: translate(0, -50%);
    transition-delay: calc(260ms + var(--n) * 70ms); }

  /* Ще не в екрані — згорнуті, щоб викреслитись на вʼїзді. */
  .dir-tile.unseen .dir-map::before { opacity: 0; }
  .dir-tile.unseen .dir-map path { stroke-dashoffset: 100; }
  .dir-tile.unseen .dir-map .leaf { opacity: 0; transform: translate(-6px, -50%); }
}

/* Гілка коротша, ніж деінде: у «Розборах» підпис — заголовок новини, а не
   назва розділу з двох слів, і кожен піксель стебла з'їдається з тексту. */
.dir-tile[data-zone="news"] .dir-map { --leaf-len: 56px; }

/* ── Навстіж: сторінка розділу ─────────────────────────────────────────────
   Плитка тут не дрібна, хоч і без ваги: мотив їй належить такий самий, як
   широкій, а не кутовий недогризок у 132px. І місце під гілки резервується
   завжди — вони нікуди не зникають. */
.dir-mosaic.open .dir-tile { min-height: 200px; }
.dir-mosaic.open .dir-tile .dir-plate { width: 200px; height: 200px; right: 0; bottom: 0; }
.dir-mosaic.open .dir-tile .dir-plate .art { opacity: .18; transform: translate(18px, 22px) scale(.94); }
.dir-mosaic.open .dir-tile:is(:hover, :has(.dir-go:focus-visible)) .dir-plate .art { opacity: .4; transform: none; }
@media (max-width: 639px) { .dir-mosaic.open .dir-tile .dir-plate { width: 170px; height: 170px; } }

@media (hover: hover) and (pointer: fine) {
  .dir-tile.go:hover { --ty: -6px; box-shadow: var(--shadow-lift); border-color: var(--gold); }
  .dir-tile.go:hover .sheen { opacity: 1; }
  .dir-tile.go:hover .wash { opacity: 1; }
  .dir-tile.go:hover .ico { transform: scale(1.1); }
}
.dir-tile.go:has(> .dir-go:active) { --ty: -2px; }
.dir-tile.go:has(> .dir-go:focus-visible) { outline: 2px solid var(--focus); outline-offset: 3px; }

/* Посилання-обкладинка (mosaic.js, tile): лежить під усіма шарами на всю
   плитку, а шари пропускають клік крізь себе. Ловить його, крім обкладинки,
   лише пігулка «нове» — вона кнопка й веде не в зону, а до переліку. */
.dir-go { position: absolute; inset: 0; z-index: 4; border-radius: inherit; }
.dir-go:focus-visible { outline: none; }
.dir-tile.go > :not(.dir-go) { pointer-events: none; }
.dir-tile :is(.dir-new, .dir-more) { pointer-events: auto; }

/* «Незабаром» — порожня вітрина, а не пригашений блок: опис лишається
   читабельним. Пригашення всієї плитки давало опису 2.4:1. */
.dir-tile.soon { background: transparent; border-style: dashed; box-shadow: none; cursor: default; }
.dir-tile.soon .ico { opacity: .55; }

/* ── Перелік нового ────────────────────────────────────────────────────────
   Верхній шар (popover), тож ні нахил плитки, ні її overflow його не
   обрізають. Це виноска-вікно ядра (callout.js + callout.css): збоку від
   плитки, ближче до середини сторінки, з гілкою від числа. position: absolute
   у верхньому шарі рахується від документа, тож вікно їде разом зі сторінкою.
   Сам popover — прозора рамка без обрізання (з неї виходить гілка); картка й
   прокрутка — у .dir-fresh-in. На телефоні — аркуш знизу, без гілки. */
.dir-fresh { display: none; }
.dir-fresh:popover-open {
  display: block; position: absolute; inset: auto; margin: 0; padding: 0; border: 0;
  overflow: visible; background: transparent; color: var(--text);
  width: min(380px, calc(100vw - 32px));
}
.dir-fresh-in {
  position: relative; max-height: min(76vh, 600px); overflow: auto; overscroll-behavior: contain;
  padding: 14px 18px 14px; border-radius: 14px;
  /* Вікно над сторінкою, а не ще одна плитка: тло з дрібкою кольору зони, облямівка
     зони й тінь її ж кольору — глибша й ширша за тінь плиток під наведенням. */
  background: color-mix(in srgb, var(--zone) 5%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--zone) 30%, var(--glass-border));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--zone) 8%, transparent),
    0 24px 56px -12px color-mix(in srgb, var(--zone) 38%, rgba(0, 0, 0, .3)),
    0 6px 16px rgba(0, 0, 0, .1);
  transition: border-color .15s ease;
}
/* Кольорова смужка — з того боку, звідки приходить гілка: вікно праворуч від
   плитки — ліворуч, ліворуч — праворуч. Без гілки (до розміщення) — згори. */
.dir-fresh:not([data-side]) .dir-fresh-in { border-top: 3px solid var(--zone); }
.dir-fresh[data-side="right"] .dir-fresh-in { border-left: 3px solid var(--zone); }
.dir-fresh[data-side="left"] .dir-fresh-in { border-right: 3px solid var(--zone); }
/* Наведення на число, точку, гілку чи вікно — підсвічує всю виноску. */
.dir-fresh.is-on .dir-fresh-in { border-color: color-mix(in srgb, var(--zone) 60%, var(--glass-border)); }
.dir-fresh.is-on[data-side="right"] .dir-fresh-in { border-left-color: var(--zone); }
.dir-fresh.is-on[data-side="left"] .dir-fresh-in { border-right-color: var(--zone); }
.dir-stock .dir-more.is-open, .dir-stock .dir-more.is-on { background: color-mix(in srgb, var(--zone) 12%, transparent); }
.dir-fresh .callout-line { color: var(--zone); }
.dir-fresh-h { margin: 0 34px 6px 0; font-size: .8rem; color: var(--hint); }
.dir-fresh-h b { color: var(--zone); font-weight: 700; }
/* Підпис групи в переліку: нове для вас, головне в зоні, розділи. */
.dir-fresh-sub { margin: 12px 0 2px; font-size: .7rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--hint); }
.dir-fresh-part:first-of-type .dir-fresh-sub { margin-top: 4px; }
.dir-fresh-sub.is-new { color: #6E5709; }
/* Розділи — гілки плитки посиланнями: ярлики в рядок, число кольором зони. */
.dir-hubs { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.dir-hubs a { display: inline-flex; align-items: baseline; gap: 5px; padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--glass-border); color: var(--text); font-size: .82rem; font-weight: 500;
  text-decoration: none; font-variant-numeric: tabular-nums;
  transition: border-color .15s var(--dir-ease), background-color .15s var(--dir-ease); }
.dir-hubs a b { color: var(--zone); font-weight: 700; }
.dir-hubs a:hover { border-color: var(--zone); background: color-mix(in srgb, var(--zone) 8%, transparent); }
.dir-fresh-x {
  position: absolute; top: 6px; right: 6px; width: 32px; height: 32px; border: 0; border-radius: 8px;
  background: transparent; color: var(--hint); font: 400 1.3rem/1 var(--font); cursor: pointer;
}
.dir-fresh-x:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.dir-fresh :is(a, button):focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.dir-fresh ol { list-style: none; margin: 0; padding: 0; }
.dir-fresh ol > li { display: flex; align-items: baseline; gap: 12px; border-top: 1px solid var(--glass-border); }
.dir-fresh ol a {
  flex: 1; min-width: 0; padding: 10px 0; color: var(--text); font-weight: 500; font-size: .92rem;
  line-height: 1.35; text-decoration: none; text-wrap: pretty;
}
.dir-fresh ol small { display: block; margin-top: 2px; color: var(--hint); font-size: .76rem; font-weight: 400; }
.dir-fresh ol a:hover { color: var(--zone); text-decoration: underline; text-underline-offset: 3px; }
.dir-fresh time { flex: none; color: var(--hint); font-size: .76rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dir-fresh-all {
  display: inline-block; margin-top: 10px; padding: 6px 0;
  color: var(--zone); font-weight: 600; font-size: .86rem; text-decoration: none;
}
.dir-fresh-all:hover { text-decoration: underline; text-underline-offset: 3px; }
/* Поява — від того боку, звідки йде гілка, коротко й без відскоку; зникає
   швидше, ніж з'являється. */
.dir-fresh[data-side="left"] { transform-origin: 100% 30px; }
.dir-fresh {
  transform-origin: 0 30px; opacity: 0; transform: scale(.97);
  transition: opacity .12s ease-out, transform .12s ease-out, overlay .12s allow-discrete, display .12s allow-discrete;
}
.dir-fresh:popover-open { opacity: 1; transform: none;
  transition: opacity .18s cubic-bezier(.23, 1, .32, 1), transform .18s cubic-bezier(.23, 1, .32, 1),
    overlay .18s allow-discrete, display .18s allow-discrete; }
@starting-style { .dir-fresh:popover-open { opacity: 0; transform: scale(.97); } }
@media (max-width: 639px) {
  .dir-fresh:popover-open { position: fixed; inset: auto 0 0 0 !important; width: auto; }
  /* Аркуш виїжджає знизу — смужка згори, хоч би який бік вийшов на широкому. */
  .dir-fresh .dir-fresh-in { max-height: 72vh; padding-bottom: max(14px, env(safe-area-inset-bottom)); border-radius: 16px 16px 0 0;
    border-width: 3px 0 0; border-style: solid; border-color: var(--zone); box-shadow: 0 -12px 32px rgba(0, 0, 0, .14); }
  .dir-fresh .callout-line { display: none; }
  /* Аркуш виїжджає знизу на свою висоту. */
  .dir-fresh { transform: translateY(100%); opacity: 1; }
  .dir-fresh:popover-open { transform: none;
    transition: transform .26s cubic-bezier(.32, .72, 0, 1), overlay .26s allow-discrete, display .26s allow-discrete; }
  @starting-style { .dir-fresh:popover-open { transform: translateY(100%); opacity: 1; } }
  .dir-fresh::backdrop { background: rgba(0, 0, 0, .28); }
}
/* Пальцем — рядок переліку й ярлик розділу мають бути ціллю, а не рядком тексту. */
@media (pointer: coarse) {
  .dir-fresh ol a { min-height: 44px; display: flex; flex-direction: column; justify-content: center; }
  .dir-hubs { gap: 8px; }
  .dir-hubs a { min-height: 36px; align-items: center; padding: 6px 12px; }
}

/* ── Пошук ─────────────────────────────────────────────────────────────── */
.dir-find { position: relative; margin: 0 0 26px; }
.dir-find input {
  width: 100%; padding: 16px 112px 16px 48px; border: 1px solid var(--glass-border);
  border-radius: 14px; background: var(--surface); color: var(--text);
  font: 500 1rem var(--font); box-shadow: var(--shadow-card);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.dir-find input::placeholder { color: var(--hint); font-weight: 400; }
.dir-find input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-color: var(--gold); }
.dir-find .dir-lens { position: absolute; left: 17px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; opacity: .45; pointer-events: none; }
.dir-find kbd, .dir-find .dir-count {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  color: var(--hint); font: 600 .74rem var(--font); pointer-events: none;
}
.dir-find kbd { padding: 5px 10px; border: 1px solid var(--glass-border); border-radius: 8px; background: var(--bg); }
.dir-find .dir-count { display: none; }
.dir-find.searching kbd { display: none; }
.dir-find.searching .dir-count { display: block; }

/* ── Фільтрація ────────────────────────────────────────────────────────── */
.dir-tile[hidden], .dir-band[hidden] { display: none; }
.dir-empty { display: none; padding: 26px 2px; color: var(--hint); }
.dir-empty.on { display: block; }

/* ── Спокійний режим ───────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .dir-tile, .dir-plate, .dir-plate .art, .dir-map::before, .dir-map path, .dir-map .leaf,
  .dir-tile .hatch, .dir-tile .wash, .dir-tile .sheen, .dir-tile .ico { transition: none; }
  /* Перелік лише проявляється, без руху. */
  .dir-fresh, .dir-fresh:popover-open { transform: none !important; transition-property: opacity, overlay, display; }
  .dir-tile { transform: none !important; }
  .dir-plate { transform: none !important; }
  .dir-plate .art { transform: none; }
  /* Гілки показуються одразу й без викреслювання */
  .dir-map path, .dir-map .leaf { transition-delay: 0s !important; }
}
