/* ДИРЕКТОРІЯ — головна сторінка кореневого домену.
   Живе в зоні, а не в ядрі: поки що це потрібно одній сторінці. Стане
   потрібним другій зоні — переїде в packages/ui (правило 2 в CLAUDE.md).
   Токени НЕ перевизначаються в :root — тільки на власному контейнері. */

.dir { --dir-ease: cubic-bezier(.22, 1, .36, 1); }

/* Заголовок сторінки — поза екраном, але в дереві доступності. Не
   display:none і не visibility:hidden: обидва ховають вміст і від читача
   екрана теж, а нам треба лише прибрати його з очей. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ── Пошук ─────────────────────────────────────────────────────────────── */
.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); }
/* Відкрита панель — продовження поля, а не друга картка над ним: поле віддає
   їй нижні кути, вона підхоплює їх своїми, а нижню грань поле знімає — інакше
   на шві лежали б одразу дві лінії. Кільце фокуса притискається до поля
   (offset 0): на відстані 2px воно лягало просвітом на пігулки й читалось як
   роздільник, а не як «поле активне». Стоїть ПІСЛЯ :focus-visible навмисно —
   специфічність однакова, вирішує порядок. */
.dir-find.open input { border-radius: 14px 14px 0 0; border-bottom-color: transparent; }
.dir-find.open input:focus-visible { outline-offset: 0; }
.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; }

/* ── Покажчик тем: панель під полем пошуку ─────────────────────────────── */
/* Тло КРЕМОВЕ, як сторінка, а не біле, як поле. Панель, поле й пігулки були
   однакового --surface, тож панель читалась як порожня біла плита з
   привидами пігулок замість таці, на якій вони лежать.
   Тінь --shadow-card, а не --shadow-lift: підказку, яку відкривають десятки
   разів на день, не піднімають на вісімнадцять пікселів. */
.dir-index {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 40;
  padding: 12px 14px 14px; border: 1px solid var(--glass-border); border-top: 0;
  border-radius: 0 0 14px 14px;
  background: var(--bg); box-shadow: var(--shadow-card);
  /* Стеля потрібна не заради десктопа (там усі теми — три-п'ять рядків), а
     заради телефона: там пігулки стають майже по одній у рядок, і без стелі
     покажчик з'їдав би екран цілком. Прокрутка не пролазить на сторінку. */
  max-height: min(42vh, 320px); overflow-y: auto; overscroll-behavior: contain;
}
/* Без переходу появи навмисно: див. коментар в apps/home/js/directory.js —
   у придушеній вкладці кадр анімації не настає, і панель лишалась прозорою. */
.dir-index[hidden] { display: none; }

/* Група тем: підпис ліворуч, пігулки праворуч. Підпис у своїй колонці, а не
   рядком зверху, — так чотири групи займають чотири смуги, а не вісім. */
.dir-group { display: grid; grid-template-columns: 106px 1fr; gap: 10px 14px; align-items: start; }
.dir-group + .dir-group { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--glass-border); }
.dir-group-name {
  margin-top: 9px; font: 700 .7rem var(--font); text-transform: uppercase;
  letter-spacing: .12em; color: var(--hint); text-align: right;
}
/* Вузький екран: на підпис збоку немає ширини — він стає рядком над темами. */
@media (max-width: 720px) {
  .dir-group { grid-template-columns: 1fr; gap: 6px; }
  .dir-group-name { margin-top: 0; text-align: left; }
}

.dir-topics { display: flex; flex-wrap: wrap; gap: 8px; }
.dir-topic {
  min-height: 38px; padding: 8px 14px; border-radius: 999px;
  border: 1px solid var(--glass-border); background: var(--surface);
  color: var(--text); font: 500 .88rem var(--font); cursor: pointer;
  transition: border-color var(--transition), color var(--transition), background-color var(--transition);
}
/* Палець вимагає 44px; миші вистачає 38. Тем тридцять три й стоять вони
   щільно — на дотику розмір важить більше за компактність, а висоту панелі
   все одно тримає стеля. */
@media (pointer: coarse) { .dir-topic { min-height: 44px; } }
@media (hover: hover) and (pointer: fine) {
  .dir-topic:hover { border-color: var(--gold); color: var(--green); }
}
.dir-topic:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.dir-topic.on { background: var(--green); border-color: var(--green); color: #fff; }

/* ── Поверх ────────────────────────────────────────────────────────────── */
.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)); } }

/* ── Плитка ────────────────────────────────────────────────────────────── */
.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;
  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; }
/* Провідна зона — вітрина на весь рядок. Плата в неї більша й посунена
   вправо, щоб не лізти під заголовок. */
@media (min-width: 1024px) {
  .dir-band.lead .dir-tile { grid-column: 1 / -1; grid-row: auto; }
  .dir-band.lead .dir-plate { width: 300px; height: 300px; right: 4%; }
}
/* Провідна плитка росте від вмісту, а не від min-height, і іконка не
   розпихається з текстом по краях: маршрут уже тримає низ, тож `auto` лишав
   зверху дірку. Висота тут diktує вміст — порожнечі нема звідки взятись. */
.dir-band.lead .dir-tile { min-height: 0; }
.dir-band.lead .dir-tile .ico { margin-bottom: 18px; }

.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 h3 { margin: 16px 0 5px; font-size: 1.08rem; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dir-tile.anchor 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 i {
  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);
}

/* Стан на час набігання — його ставить і знімає клієнт. Без скрипта (і при
   вимкненій анімації) клас не з'являється взагалі, тож вітрина повна з
   першого кадру: числа в розмітці справжні, а не нулі.
   Пігулка чекає, поки добіжить число: спершу «скільки всього», потім
   «скільки з цього для вас» — разом вони змагалися б за один погляд. */
.dir-stock.counting i { opacity: 0; transform: scale(.94); }

/* ── Маршрут: наголос порталу вздовж провідної вітрини ──────────────────────
   Заповнює порожнечу, яка лишалась між іконкою та заголовком на високій
   плитці, і водночас промовляє гасло без жодної великої літери — угорі
   сторінки їх і так було забагато.
   Анімація ОДНОРАЗОВА, на завантаженні: головну бачать щодня, і рух, який
   повторюється при кожному наведенні, тут швидко набрид би. */
.dir-route { position: relative; display: flex; justify-content: space-between;
  max-width: 430px; margin: 26px 0 0; color: var(--zone); }
.dir-route .rail { position: absolute; left: 6px; right: 6px; top: 6px; height: 2px;
  background: currentColor; opacity: .3; border-radius: 2px;
  transform: scaleX(0); transform-origin: left;
  animation: dir-rail .75s cubic-bezier(.22, 1, .36, 1) .2s forwards; }
.dir-route .stop { display: flex; flex-direction: column; align-items: flex-start; gap: 9px;
  font: 500 .8rem var(--font); color: var(--hint); white-space: nowrap;
  opacity: 0; animation: dir-stop .35s cubic-bezier(.22, 1, .36, 1) forwards;
  animation-delay: calc(.35s + var(--s) * .26s); }
.dir-route .stop i { width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor; background: var(--surface); }
@keyframes dir-rail { to { transform: scaleX(1); } }
@keyframes dir-stop { to { opacity: 1; } }

/* ── Плата: мотив + виноски ────────────────────────────────────────────── */
.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(.noted) .dir-plate { width: 132px; height: 132px; right: -14px; bottom: -16px; }
.dir-tile:not(.noted) .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(.noted) .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; }
.dir-plate .art { stroke-width: 1.6; opacity: .18; transform: translate(18px, 22px);
  transition: opacity .35s var(--dir-ease), transform .4s var(--dir-ease); }
.dir-plate .notes { opacity: 0; transition: opacity .2s var(--dir-ease); }
.dir-plate .lead { stroke-width: 1; stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset .4s var(--dir-ease); }
.dir-plate .dot { fill: currentColor; stroke: none; opacity: 0; transition: opacity .2s; }
.dir-plate text { fill: var(--green); stroke: none; font: 600 5.4px var(--font); letter-spacing: .02em;
  opacity: 0; transition: opacity .22s var(--dir-ease); }
.dir-tile.anchor .dir-plate text { font-size: 3.7px; }

/* ── Стани. Наведення і клавіатурний фокус ведуть себе однаково ─────────── */
.dir-tile:is(:hover, :focus-visible) .dir-plate .notes { opacity: 1; }
.dir-tile.noted:is(:hover, :focus-visible) .dir-plate .art { opacity: .4; transform: none; }
/* Без виносок мотив на наведенні лише трохи проявляється, з місця не рушить */
.dir-tile:not(.noted):is(:hover, :focus-visible) .dir-plate .art { opacity: .24; }
.dir-tile:is(:hover, :focus-visible) .dir-plate .lead { stroke-dashoffset: 0; transition-delay: calc(var(--n) * 90ms); }
.dir-tile:is(:hover, :focus-visible) .dir-plate .dot { opacity: 1; transition-delay: calc(var(--n) * 90ms); }
.dir-tile:is(:hover, :focus-visible) .dir-plate text { opacity: 1; transition-delay: calc(380ms + var(--n) * 90ms); }

@media (hover: hover) and (pointer: fine) {
  a.dir-tile:hover { --ty: -6px; box-shadow: var(--shadow-lift); border-color: var(--gold); }
  a.dir-tile:hover .sheen { opacity: 1; }
  a.dir-tile:hover .wash { opacity: 1; }
  a.dir-tile:hover .ico { transform: scale(1.1); }
}
a.dir-tile:active { --ty: -2px; }
a.dir-tile:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

/* «Незабаром» — порожня вітрина, а не пригашений блок: опис лишається
   читабельним. Пригашення всієї плитки давало опису 2.4:1. */
.dir-tile.soon { background: transparent; border-style: dashed; box-shadow: none; cursor: default; }
.dir-tile.soon .ico { opacity: .55; }

/* ── Фільтрація ────────────────────────────────────────────────────────── */
.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-plate .lead, .dir-plate .dot,
  .dir-plate text, .dir-plate .notes, .hatch, .wash, .sheen, .dir-tile .ico { transition: none; }
  /* Маршрут показується одразу зібраним, без викреслювання */
  .dir-route .rail, .dir-route .stop { animation: none; transform: none; opacity: 1; }
  .dir-tile { transform: none !important; }
  .dir-plate { transform: none !important; }
  .dir-plate .art { transform: none; }
  /* Виноски показуються одразу й без викреслювання */
  .dir-tile:is(:hover, :focus-visible) .dir-plate .lead { stroke-dashoffset: 0; transition-delay: 0s; }
  .dir-tile:is(:hover, :focus-visible) .dir-plate :is(.dot, text) { transition-delay: 0s; }
}
