/* Bangkok Events — the parts Tailwind utilities can't express.
   Loaded after the Tailwind CDN, so anything here wins on equal specificity.
   Plain CSS only: the Play CDN cannot process @apply in an external file. */

/* ------------------------------------------------------------------ theme -- */
:root {
  /* Должно совпадать с h-20 / sm:h-24 в partials/header.html — от этого
     считается прилипание заголовков дней. */
  --header-h: 5rem;
  --subbar-h: 0px;          /* pages with no filter bar */
  --ring: theme;                      /* placeholder, see :focus-visible below */
}

/* --------------------------------------------------------------- category --
   One hue per category, identical saturation and lightness across the set —
   that is what makes nine colours read as one family instead of nine brands.
   Every chip, pin, tile and border derives from --cat-h alone. */
/* Generic fallback first: equal specificity means source order decides, so a
   trailing catch-all would silently flatten every category to one hue. */
[data-cat]             { --cat-h: 215; }   /* 'venue', 'other', unknown slugs */
[data-cat="music"]        { --cat-h: 268; }
[data-cat="expo"]         { --cat-h: 232; }
[data-cat="sport"]        { --cat-h: 145; }
[data-cat="art"]          { --cat-h: 325; }
[data-cat="workshop"]     { --cat-h: 88; }
[data-cat="festival"]     { --cat-h: 48; }
[data-cat="food"]         { --cat-h: 22; }
[data-cat="theatre"]      { --cat-h: 300; }
[data-cat="family"]       { --cat-h: 175; }
[data-cat="mall"]         { --cat-h: 355; }
[data-cat="community"]    { --cat-h: 202; }

.chip-cat {
  background: hsl(var(--cat-h) 72% 95%);
  color:      hsl(var(--cat-h) 62% 28%);
  border-color: hsl(var(--cat-h) 55% 87%);
}
.dark .chip-cat {
  background: hsl(var(--cat-h) 38% 17%);
  color:      hsl(var(--cat-h) 70% 78%);
  border-color: hsl(var(--cat-h) 40% 27%);
}
.chip-cat[aria-pressed="true"],
.chip-cat.is-active {
  background: hsl(var(--cat-h) 62% 32%);
  color: #fff;
  border-color: hsl(var(--cat-h) 62% 32%);
}
.dark .chip-cat[aria-pressed="true"],
.dark .chip-cat.is-active {
  background: hsl(var(--cat-h) 65% 62%);
  color: hsl(var(--cat-h) 60% 12%);
  border-color: hsl(var(--cat-h) 65% 62%);
}

.cat-accent  { background: hsl(var(--cat-h) 62% 48%); }
.cat-tile    { background: hsl(var(--cat-h) 72% 96%); border-color: hsl(var(--cat-h) 50% 88%); }
.cat-tile:hover { background: hsl(var(--cat-h) 72% 92%); }
.dark .cat-tile { background: hsl(var(--cat-h) 34% 15%); border-color: hsl(var(--cat-h) 32% 24%); }
.dark .cat-tile:hover { background: hsl(var(--cat-h) 34% 19%); }
.cat-ink     { color: hsl(var(--cat-h) 62% 28%); }
.dark .cat-ink { color: hsl(var(--cat-h) 72% 76%); }

/* Poster fallback: 94% of real events have an image, 6% don't. The 6% get a
   category-tinted gradient rather than a grey box, so a rail stays readable. */
.poster-fallback {
  background:
    radial-gradient(120% 90% at 20% 0%,  hsl(var(--cat-h) 62% 62%) 0%, transparent 60%),
    linear-gradient(140deg, hsl(var(--cat-h) 52% 42%), hsl(var(--cat-h) 60% 22%));
}

/* ------------------------------------------------------------------- Thai --
   Thai stacks vowels above and tone marks above those; at Latin line-height the
   marks collide with the line before. 88% of our titles can contain Thai. */
:lang(th), .t-thai { line-height: 1.75; }
.t-thai.clamp-2, .t-thai.clamp-3 { line-height: 1.7; }

/* line-clamp without the plugin */
.clamp-1, .clamp-2, .clamp-3 {
  display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
}
.clamp-1 { -webkit-line-clamp: 1; }
.clamp-2 { -webkit-line-clamp: 2; }
.clamp-3 { -webkit-line-clamp: 3; }

/* ---------------------------------------------------------------- surfaces -- */
.card {
  background: #fff;
  border: 1px solid #E2E8F0;
  border-radius: 0.875rem;
  transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}
.dark .card { background: #12253C; border-color: #1E3350; }
.card:hover { box-shadow: 0 2px 4px rgb(9 28 50 / .08), 0 18px 40px -16px rgb(9 28 50 / .28); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .card-lift:hover { transform: translateY(-2px); }
}

/* Sticky day headers park directly below the sticky filter bar. --subbar-h must
   be set on a common ANCESTOR of both (see .has-subbar) — setting it on the bar
   itself only reaches the bar's own subtree, and the headers then slide under it.
   Measured: header 64px, filter bar 105px. */
@media (min-width: 640px) { :root { --header-h: 6rem; } }

.has-subbar { --subbar-h: 105px; }
.day-sticky { position: sticky; top: calc(var(--header-h) + var(--subbar-h)); z-index: 20; }

/* --------------------------------------------------------------- scrolling -- */
.rail {
  display: flex; gap: 1rem; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  padding-bottom: .25rem;
}
.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; flex: 0 0 auto; }

.scroll-x { overflow-x: auto; scrollbar-width: none; }
.scroll-x::-webkit-scrollbar { display: none; }

/* ---------------------------------------------------------------- a11y ------ */
:focus-visible {
  outline: 2px solid #F49B3C;
  outline-offset: 2px;
  border-radius: 4px;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------------ prose --- */
.prose-bkk { max-width: 68ch; }
.prose-bkk p { margin-bottom: 1rem; line-height: 1.7; }
.prose-bkk a { color: #B26A0F; text-decoration: underline; text-underline-offset: 2px; }
.dark .prose-bkk a { color: #F9BE74; }

/* -------------------------------------------------------------- map / sheet - */
#map, .map-canvas { background: #E2E8F0; }
.dark #map, .dark .map-canvas { background: #0D1E33; }

/* Карта обязана быть ОТДЕЛЬНЫМ контекстом наложения.
   Leaflet раздаёт своим панелям z-index 400–800, а .leaflet-container это
   position:relative без z-index — такой элемент контекста не создаёт, и эти
   400 конкурируют напрямую с остальной страницей. Нижняя шторка (z-30)
   оказывалась ЗА картой: в разметке она есть, на экране её нет.

   ТОЛЬКО isolation, без position. Раньше здесь стояло position:relative, и
   оно перебивало Tailwind-класс .absolute на самом контейнере: inset-0
   переставал действовать, высота схлопывалась в ноль, и карта не рисовалась
   вовсе. isolation создаёт контекст независимо от позиционирования. */
#map, .map-canvas { isolation: isolate; }

/* Leaflet рисует свою хромированную обвязку — приводим её к системе сайта. */
.leaflet-container { font: inherit; }
.leaflet-control-attribution {
  background: rgb(255 255 255 / .85); color: #4F5D6D;
  font-size: 11px; padding: 2px 6px;
}
.dark .leaflet-control-attribution { background: rgb(9 28 50 / .85); color: #9EAEC4; }
.dark .leaflet-control-attribution a { color: #C7D2E0; }
.leaflet-bar a {
  background: #fff; color: #12253C; border-bottom-color: #E2E8F0;
}
.dark .leaflet-bar a { background: #12253C; color: #E2E8F0; border-bottom-color: #1E3350; }
.dark .leaflet-bar a:hover { background: #1E3350; }

/* На телефоне нижний край карты занят шторкой (peek = 8.5rem) и таб-баром.
   Подпись об источнике тайлов — лицензионное требование CARTO и OSM, она не
   имеет права оказаться под ними; зум туда же, иначе до него не дотянуться. */
@media (max-width: 767px) {
  .leaflet-bottom { bottom: 9.25rem; }
  .leaflet-control-attribution { font-size: 10px; }
}

.leaflet-popup-content-wrapper, .leaflet-popup-tip {
  background: #fff; color: #091C32;
  box-shadow: 0 2px 4px rgb(9 28 50 / .08), 0 18px 40px -16px rgb(9 28 50 / .28);
}
.dark .leaflet-popup-content-wrapper, .dark .leaflet-popup-tip {
  background: #12253C; color: #E2E8F0;
}
.leaflet-popup-content { margin: .75rem .9rem; min-width: 12rem; }

.bkk-pop-venue {
  display: block; font-weight: 700; font-size: .95rem; line-height: 1.3;
  color: inherit; text-decoration: none;
}
.bkk-pop-venue:hover { text-decoration: underline; }
.bkk-pop-meta { margin-top: .15rem; font-size: .75rem; color: #4F5D6D; }
.dark .bkk-pop-meta { color: #9EAEC4; }
.bkk-pop-list { margin-top: .5rem; border-top: 1px solid #E2E8F0; padding-top: .4rem; }
.dark .bkk-pop-list { border-top-color: #1E3350; }
.bkk-pop-row {
  display: flex; gap: .5rem; padding: .22rem 0; font-size: .8125rem;
  color: inherit; text-decoration: none;
}
.bkk-pop-row:hover .bkk-pop-title { text-decoration: underline; }
.bkk-pop-when { flex: 0 0 5.4rem; font-weight: 600; color: #B26A0F; white-space: nowrap; }
.dark .bkk-pop-when { color: #F9BE74; }
.bkk-pop-title { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; }
.bkk-pop-more {
  display: inline-block; margin-top: .45rem; font-size: .75rem; font-weight: 600;
  color: #B26A0F;
}
.dark .bkk-pop-more { color: #F9BE74; }

/* Сетка-заглушка осталась только у мини-карт на карточках события и площадки. */
.map-stub {
  background-image:
    linear-gradient(rgba(9,28,50,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(9,28,50,.07) 1px, transparent 1px),
    linear-gradient(160deg, #DDE6EE, #EEF3F7);
  background-size: 44px 44px, 44px 44px, 100% 100%;
}
.dark .map-stub {
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(160deg, #0D1E33, #12253C);
}

/* Врезку можно открыть — это должно быть видно до клика. */
/* Leaflet ставит свой курсор на .leaflet-container — перебиваем
   тем же весом селектора. */
.minimap-clickable, .minimap-clickable.leaflet-container,
.minimap-clickable .leaflet-grab { cursor: zoom-in; }
.minimap-clickable::after {
  content: "Click to explore";
  position: absolute; right: .5rem; bottom: .5rem; z-index: 500;
  padding: .25rem .5rem; border-radius: .5rem;
  background: rgb(255 255 255 / .92); color: #12253C;
  font-size: 11px; font-weight: 600; pointer-events: none;
  box-shadow: 0 1px 2px rgb(9 28 50 / .12);
}
.dark .minimap-clickable::after { background: rgb(18 37 60 / .92); color: #E2E8F0; }
/* подпись OSM/CARTO не должна оказаться под этой плашкой */
.minimap-clickable .leaflet-control-attribution { margin-right: 8.5rem; }

.pin {
  background: hsl(var(--cat-h) 62% 46%);
  box-shadow: 0 0 0 3px hsl(var(--cat-h) 62% 46% / .25), 0 4px 10px rgb(9 28 50 / .35);
}
.pin.is-active { box-shadow: 0 0 0 6px hsl(var(--cat-h) 62% 46% / .3), 0 6px 16px rgb(9 28 50 / .45); }

/* Bottom sheet on /map — three snap points, dragged by its handle.
   Только на телефоне: тот же элемент на десктопе становится боковой панелью,
   и translateY увёл бы её за нижний край экрана. */
@media (max-width: 767px) {
  .sheet {
    transition: transform .28s cubic-bezier(.32,.72,0,1);
    will-change: transform;
    touch-action: none;
  }
  .sheet[data-snap="peek"] { transform: translateY(calc(100% - 8.5rem)); }
  .sheet[data-snap="half"] { transform: translateY(45%); }
  .sheet[data-snap="full"] { transform: translateY(0); }
}

/* --------------------------------------------------------------- utilities -- */
.hairline { border-color: #E2E8F0; }
.dark .hairline { border-color: #1E3350; }
.tnum { font-variant-numeric: tabular-nums; }
