/* =========================================================
   DJ TIM — Electronic Press Kit
   Monochrome editorial-brutalism (ref: BXLT / Rapylab)
   ========================================================= */

:root{
  --ink:#000;
  --paper:#fff;
  --muted:#9a9a9a;
  --line:#2a2a2a;
  --hero: 'Anton', 'Arial Black', Impact, sans-serif;
  --label:'Archivo Black', 'Arial Black', sans-serif;
  --body: 'Inter', 'Helvetica Neue', Arial, sans-serif;
  --pad: clamp(20px, 6vw, 90px);
}

*{ box-sizing:border-box; margin:0; padding:0; }
html{ scroll-behavior:smooth; }
body{
  background:var(--ink);
  color:var(--paper);
  font-family:var(--body);
  font-weight:300;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{ display:block; max-width:100%; filter:grayscale(1) contrast(1.04); }
a{ color:inherit; text-decoration:none; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible{ outline:3px solid currentColor; outline-offset:3px; }

/* ---------- type helpers ---------- */
.kicker{
  font-family:var(--label);
  font-size:13px; letter-spacing:.34em; text-transform:uppercase;
  color:var(--muted);
}
.h-section{
  font-family:var(--hero); font-weight:400; text-transform:uppercase;
  font-size:clamp(44px, 9vw, 120px); line-height:1; letter-spacing:-.01em;
  overflow-wrap:break-word;
}
/* RU/AZ display caps: Й/Ё breves and AZ İ dots reach above cap-height, Д/Ц/Щ/Ş/Ç
   dip below the baseline — with the tight Latin leading stacked lines collide.
   Loosen the leading for those languages only (EN keeps the brutalist 1.0). */
html[lang="ru"] .h-section, html[lang="az"] .h-section{ line-height:1.12; }
html[lang="ru"] .champ__title, html[lang="az"] .champ__title{ line-height:1.08; }
html[lang="ru"] .setup__title, html[lang="az"] .setup__title{ line-height:1.08; }

/* ---------- nav ---------- */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:50;
  display:flex; align-items:center; justify-content:space-between;
  padding:16px var(--pad);
  mix-blend-mode:difference; color:#fff;
  border-bottom:1px solid transparent;
  transition:border-color .25s ease;
}
/* on scroll: drop the blend, add a frosted dark bar so the menu stays readable over
   any content. The frost lives on ::before, NOT on .nav itself: backdrop-filter on
   .nav would make the bar the containing block for the fixed mobile drawer, so the
   open menu would collapse into a bar-sized stub on any scrolled page. */
.nav::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:rgba(10,10,10,.92);
  backdrop-filter:saturate(140%) blur(10px); -webkit-backdrop-filter:saturate(140%) blur(10px);
  opacity:0; transition:opacity .25s ease;
}
.nav--solid{
  mix-blend-mode:normal; color:#fff;
  border-bottom-color:rgba(255,255,255,.10);
}
.nav--solid::before{ opacity:1; }
.nav__links{ display:flex; gap:clamp(12px,2vw,30px); }
.nav__links a{ font-family:var(--label); font-size:12px; letter-spacing:.18em; text-transform:uppercase; opacity:.85; }
.nav__links a:hover{ opacity:1; }
/* section links + the Book CTA travel together on the right (desktop look unchanged) */
.nav__nav{ display:flex; align-items:center; gap:clamp(12px,2vw,30px); }
.nav__book{ font-family:var(--label); font-size:12px; letter-spacing:.18em; text-transform:uppercase; opacity:.85; }
.nav__book:hover{ opacity:1; }
/* language switcher (lives in .nav__slot; shared by EN/RU/AZ) */
.lang{ display:inline-flex; gap:2px; align-items:center; font-family:var(--label); font-size:12px; letter-spacing:.1em; }
.lang a{ padding:5px 8px; opacity:.5; border-bottom:2px solid transparent; transition:opacity .2s ease, border-color .2s ease; }
.lang a:hover, .lang a:focus-visible{ opacity:1; }
.lang a:not(.is-active):hover{ border-bottom-color:rgba(255,255,255,.45); }
.lang a.is-active{ opacity:1; border-bottom-color:currentColor; }
/* hamburger: hidden on desktop, drives the mobile drawer */
.nav__burger{ display:none; }
.nav__backdrop{ display:none; }

@media(max-width:680px){
  .nav{ padding:11px 15px; gap:12px; }
  .lang a{ padding:4px 6px; }
  /* right side on phones: Book pill + burger; the section links become a slide-in drawer */
  .nav__nav{ align-items:center; gap:12px; }
  .nav__book{ order:1; flex:none; border:1.4px solid currentColor; padding:5px 13px; border-radius:999px;
    opacity:1; font-size:11px; letter-spacing:.07em; }
  .nav__burger{ order:2; display:inline-flex; flex-direction:column; justify-content:center; gap:5px;
    width:32px; height:32px; padding:0; background:none; border:0; color:inherit; cursor:pointer; flex:none; }
  .nav__burger span{ display:block; width:22px; height:2px; background:currentColor;
    transition:transform .3s ease, opacity .2s ease; }
  .nav__links{ position:fixed; top:0; right:0; bottom:0; width:min(82vw,320px); z-index:80;
    flex-direction:column; align-items:stretch; gap:0; background:#0a0a0a; padding:74px 26px 32px;
    overflow-y:auto; transform:translateX(105%);
    /* visibility, not just the off-screen transform: a translated drawer still takes
       keyboard focus and still answers hit-tests, so a phone user tabbing through the
       closed page fell into five invisible links. Delay it by the slide duration when
       closing so the slide-out is still seen; it flips instantly when opening.
       visibility is a discrete property: given a DURATION it switches at the end of the
       interval going to hidden and at the start going to visible, which is exactly the
       behaviour wanted. (A 0s duration with a delay looks equivalent but did not settle
       here -- verified in the browser via getComputedStyle.) */
    visibility:hidden;
    transition:transform .32s cubic-bezier(.4,0,.2,1), visibility .32s;
    -webkit-mask-image:none; mask-image:none; }
  .nav__links a{ padding:16px 2px; border-top:1px solid rgba(255,255,255,.13);
    font-family:var(--hero); font-size:27px; letter-spacing:.01em; opacity:1; white-space:nowrap; }
  .nav__links a:last-child{ border-bottom:1px solid rgba(255,255,255,.13); }
  .nav__backdrop{ display:block; position:fixed; inset:0; z-index:75; background:rgba(0,0,0,.55);
    opacity:0; visibility:hidden; transition:opacity .3s ease; }
  .nav--open{ mix-blend-mode:normal; z-index:100; }
  .nav--open .nav__links{ transform:translateX(0); visibility:visible;
    transition:transform .32s cubic-bezier(.4,0,.2,1), visibility 0s; }
  /* The burger IS the close button once the drawer is open, but it is a static element
     and the drawer is fixed at z-index:80 inside the same stacking context, so the
     drawer's opaque panel painted straight over it: the X was invisible AND swallowed
     the tap (elementFromPoint at the burger's centre returned .nav__links). Lift it
     above the panel, and pin the colour — currentColor follows the section behind the
     nav, which on a light section drew a black X on the near-black drawer. */
  .nav--open .nav__burger{ position:relative; z-index:90; color:#fff; }
  .nav--open .nav__backdrop{ opacity:1; visibility:visible; }
  .nav--open .nav__burger span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
  .nav--open .nav__burger span:nth-child(2){ opacity:0; }
  .nav--open .nav__burger span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }
}

/* rider/book compact bar: desktop keeps the minimal back-link bar (drawer markup
   stays hidden); on phones the burger opens the same off-canvas menu as the homepage */
.rbar .nav__links{ display:none; }
@media(max-width:680px){
  .rbar{ gap:12px; }
  .rbar .nav__links{ display:flex; }
  .rbar__doc{ display:none; }  /* duplicated by the page h1 right below; frees space for the burger */
}

/* ---------- HERO ---------- */
.hero{
  position:relative; min-height:100svh; display:flex; flex-direction:column;
  justify-content:flex-end; align-items:center; text-align:center;
  padding:var(--pad); padding-bottom:clamp(84px,6vh,110px); overflow:hidden;
}
.hero__bg{
  position:absolute; inset:0; z-index:0;
}
.hero__bg img{ width:100%; height:100%; object-fit:cover; animation:heroZoom 26s ease-in-out infinite alternate; }
.hero__breathe{ position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(ellipse 60% 46% at 50% 40%, rgba(0,0,0,.82), rgba(0,0,0,0) 62%);
  opacity:0; animation:heroBreathe 6s ease-in-out infinite; }
@keyframes heroBreathe{ 0%,100%{opacity:0} 50%{opacity:1} }
@keyframes heroZoom{ from{transform:scale(1)} to{transform:scale(1.09)} }
.hero__bg::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(0,0,0,.5) 0%, rgba(0,0,0,.12) 28%, rgba(0,0,0,.42) 60%, rgba(0,0,0,.95) 100%);
}
.hero__inner{ position:relative; z-index:2; max-width:1600px; margin-inline:auto; }
.hero__title{
  font-family:var(--hero); font-weight:400; text-transform:uppercase;
  font-size:clamp(54px, min(13vw, 16vh), 160px); line-height:.85; letter-spacing:-.02em;
  color:transparent; background:linear-gradient(100deg,#fff 38%,#9a9a9a 50%,#fff 62%);
  background-size:250% 100%; -webkit-background-clip:text; background-clip:text;
  animation:heroSheen 5.5s ease-in-out infinite;
}
@keyframes heroSheen{ from{background-position:170% 0} to{background-position:-70% 0} }
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  .hero__bg img, .hero__breathe, .hero__title{ animation:none !important; }
  .hero__title{ color:#fff; background:none; -webkit-text-fill-color:#fff; }
  *, *::before, *::after{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
}
.hero__rule{ width:min(260px,60vw); height:3px; background:#fff; margin:26px auto 18px; }
.hero__tagline{
  font-family:var(--label); font-size:clamp(12px,1.4vw,17px);
  letter-spacing:.22em; text-transform:uppercase; text-shadow:0 1px 6px rgba(0,0,0,.5);
}
.hero__proof{
  margin-top:clamp(22px,3.4vh,40px); z-index:2;
  display:flex; flex-direction:column; align-items:center; gap:7px;
  font-family:var(--label); font-size:11px; letter-spacing:.16em; text-transform:uppercase;
}
.hero__proof span{ opacity:.9; text-shadow:0 1px 4px rgba(0,0,0,.55); }
/* primary booking CTA in the hero — promoters get an action without scrolling */
.hero__cta{ display:inline-flex; align-items:center; gap:10px; margin-top:clamp(22px,3.4vh,36px);
  background:#fff; color:#000; border:2px solid #fff; border-radius:999px;
  padding:15px 32px; font-family:var(--label); font-size:13px; letter-spacing:.16em; text-transform:uppercase;
  box-shadow:0 8px 30px rgba(0,0,0,.45); transition:background .2s ease, color .2s ease; }
.hero__cta:hover{ background:transparent; color:#fff; }
@media(max-width:680px){ .hero__cta{ padding:14px 26px; font-size:12px; } }
/* The title itself is height-capped via min(13vw,16vh) above, so on low-height
   viewports we only tighten the vertical rhythm — the block then sits lower and
   keeps the silhouette clear. */
@media (max-height:820px){
  .hero__rule{ margin:16px auto 12px; }
  .hero__proof{ margin-top:clamp(14px,2vh,24px); }
  .hero__cta{ margin-top:clamp(14px,2vh,24px); }
}
.scrollcue{
  position:absolute; bottom:24px; left:50%; transform:translateX(-50%); z-index:3;
  font-family:var(--label); font-size:10px; letter-spacing:.3em; text-transform:uppercase; opacity:.7;
}
/* On phones the fixed WhatsApp pill sits in the bottom-right and, on narrow
   widths, overlaps the centered SCROLL cue. The cue is redundant on touch
   (swiping is obvious), so hide it there and keep WhatsApp clear. */
@media(max-width:680px){ .scrollcue{ display:none; } }

/* ---------- TOUR (gigs list; rows injected from /api/gigs) ---------- */
.tour__list{ margin-top:8px; }
.tour__row{ display:grid; grid-template-columns:auto 1fr auto; align-items:center;
  gap:clamp(18px,3vw,44px); padding:clamp(18px,2.6vw,26px) 0; border-top:1px solid var(--line); }
.tour__row:last-child{ border-bottom:1px solid var(--line); }
.tour__date{ font-family:var(--hero); font-weight:400; text-transform:uppercase;
  font-size:clamp(28px,3.6vw,46px); line-height:.9; letter-spacing:-.01em; white-space:nowrap; }
.tour__meta{ min-width:0; }
.tour__title{ font-family:var(--body); font-weight:600; font-size:clamp(16px,1.6vw,22px); line-height:1.15; }
.tour__city{ font-family:var(--label); font-size:12px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted); margin-top:6px; }
.tour__cta{ display:inline-flex; align-items:center; gap:10px; white-space:nowrap;
  border:2px solid currentColor; border-radius:999px; padding:12px 24px;
  font-family:var(--label); font-size:12px; letter-spacing:.16em; text-transform:uppercase;
  transition:background .2s ease, color .2s ease; }
.tour__cta,.tour__soldout{ box-sizing:border-box; justify-content:center; justify-self:end; width:145px; }
.sec--dark .tour__cta:hover{ background:#fff; color:#000; }
.tour__soldout{ justify-self:end; display:inline-flex; align-items:center; white-space:nowrap;
  border:2px solid currentColor; border-radius:999px; padding:12px 24px;
  font-family:var(--label); font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:var(--muted); }
@media(max-width:620px){
  .tour__row{ grid-template-columns:1fr; gap:12px; }
  .tour__date{ font-size:34px; }
  .tour__cta{ justify-self:start; }
  .tour__soldout{ justify-self:start; }
}

/* ---------- generic section ---------- */
.sec{ padding:clamp(72px,12vh,140px) var(--pad); position:relative; }
.sec > *{ max-width:1600px; margin-inline:auto; }
section[id]{ scroll-margin-top:64px; }   /* clear the fixed 51px nav on anchor jumps */
#hero{ scroll-margin-top:0; }            /* full-screen cover; no menu link targets it */
#f1{ scroll-margin-top:72px; }           /* #f1 starts with a kicker line above the heading */
.sec--light{ background:var(--paper); color:var(--ink); }
.sec--dark{ background:var(--ink); color:var(--paper); }
.sec__head{ display:flex; align-items:baseline; gap:18px; margin-bottom:40px; flex-wrap:wrap; }

/* ---------- BIO ---------- */
.bio{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(30px,5vw,80px); align-items:center; }
.bio__body p{ font-size:clamp(15px,1.3vw,18px); margin-bottom:20px; max-width:46ch; font-weight:400; }
.bio__body a{ text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px; }
.bio__body a:hover{ opacity:.6; }
.bio__photo{ display:flex; justify-content:flex-end; align-items:center; overflow:hidden; }
.bio__photo img{ width:auto; height:auto; max-width:100%; max-height:90vh; object-fit:contain; transition:transform .6s ease; }
.bio__photo:hover img{ transform:scale(1.04); }
@media(max-width:820px){ .bio{ grid-template-columns:1fr; } }

/* ---------- CAREER ---------- */
.cols2{ display:grid; grid-template-columns:repeat(2,1fr); gap:clamp(24px,4vw,60px); }
@media(max-width:820px){ .cols2{ grid-template-columns:1fr; gap:34px; } }
.block h3{ font-family:var(--label); font-size:14px; letter-spacing:.16em; text-transform:uppercase; margin-bottom:16px; padding-bottom:10px; border-bottom:1px solid var(--line); }
.block ul{ list-style:none; }
.block li{ font-size:15px; padding:8px 0; border-bottom:1px solid var(--line); display:flex; gap:10px; }
.block li b{ font-weight:600; }
/* collapsible long list — Stages & Festivals grows over time, so old entries fold away */
.block li[hidden]{ display:none; }
.list-more{ margin-top:16px; font-family:var(--label); font-size:12px; letter-spacing:.16em;
  text-transform:uppercase; background:none; color:inherit; border:1px solid currentColor;
  border-radius:999px; padding:9px 18px; cursor:pointer; transition:background .2s ease, color .2s ease; }
.sec--dark .list-more:hover{ background:#fff; color:#000; }

/* ---------- CAREER champion band ---------- */
.career__champ{ display:grid; grid-template-columns:.95fr 1.05fr; gap:clamp(28px,4vw,60px); align-items:center; margin-bottom:clamp(40px,6vh,72px); }
@media(max-width:820px){ .career__champ{ grid-template-columns:1fr; gap:26px; } }
.career__champ-photo{ margin:0; overflow:hidden; }
.career__champ img{ width:100%; height:auto; display:block; border:1px solid var(--line); transition:transform .6s ease; }
.career__champ-photo:hover img{ transform:scale(1.04); }
.champ__sub{ font-family:var(--label); font-size:clamp(12px,1.2vw,14px); text-transform:uppercase; letter-spacing:.2em; color:var(--muted); margin-top:8px; }
/* margins were 7px top / 11px bottom — the caption sat 4px further from the title than the
   kicker did, which reads as a tilt in a three-line stack. The neighbours' half-leading is
   near-identical (3.6px under the kicker, 3.9px over the caption), so equal margins give
   equal OPTICAL gaps too. */
.champ__title{ font-family:var(--hero); font-weight:400; text-transform:uppercase; font-size:clamp(32px,4.2vw,50px); line-height:.96; margin:7px 0; }
.champ__loc{ font-family:var(--label); font-size:clamp(13px,1.3vw,15px); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); }

/* ---------- F1 / BRANDS ---------- */
.f1__kicker{ font-family:var(--label); font-size:12px; letter-spacing:.2em; text-transform:uppercase; color:#666; margin:0 auto 14px; padding-left:4px; }
.f1__grid{ display:grid; grid-template-columns:.85fr 1.15fr; gap:clamp(28px,4vw,64px); align-items:start; }
@media(max-width:820px){ .f1__grid{ grid-template-columns:1fr; gap:34px; } }
.f1__photos{ display:flex; flex-direction:column; gap:14px; }
.f1__photo{ position:relative; margin:0; overflow:hidden; }
.f1__photo img{ width:100%; height:auto; display:block; border:1px solid var(--ink); filter:grayscale(1) contrast(1.06); transition:transform .6s ease; }
.f1__photo:hover img{ transform:scale(1.04); }
.f1__stamp{ position:absolute; left:14px; bottom:14px; background:var(--ink); color:var(--paper); font-family:var(--label); font-size:10px; letter-spacing:.18em; text-transform:uppercase; padding:8px 12px; }
.f1__h3{ font-family:var(--label); font-size:13px; letter-spacing:.16em; text-transform:uppercase; margin-bottom:14px; padding-bottom:10px; border-bottom:1px solid var(--line); }
.f1__years{ list-style:none; }
.f1__years li{ display:flex; gap:14px; padding:10px 0; border-bottom:1px solid var(--line); font-size:15px; align-items:baseline; }
/* World-artist names were disappearing into the row text: the year owns the visual weight
   (19px display face) and the description ran flat at 14px. Bumped to 15px to match the
   career lists, and <strong> gives the names just enough weight to be caught while
   scanning — deliberately 600, not full bold, so they never compete with the year. */
.f1__years strong, .block li strong{ font-weight:600; }
.f1__years li b{ font-family:var(--hero); font-weight:400; min-width:62px; font-size:19px; line-height:1; }
/* official F1 credit — small underlined link under the Highlights list */
.f1__official{ margin-top:22px; font-family:var(--label); font-size:13px; letter-spacing:.04em; text-transform:uppercase; }
.f1__official a{ text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px; transition:opacity .2s ease; }
.f1__official a:hover{ opacity:.6; }

/* ---------- WATCH PHOTOS strip ---------- */
.watch-photos{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(16px,2.5vw,34px); margin-top:clamp(16px,2.5vw,34px); }
.watch-photos a{ display:block; overflow:hidden; border:1px solid var(--line); }
.watch-photos img{ width:100%; height:100%; aspect-ratio:4/3; object-fit:cover; transition:transform .6s ease; }
.watch-photos a:hover img{ transform:scale(1.04); }
@media(max-width:560px){ .watch-photos{ grid-template-columns:1fr; } }

/* ---------- WATCH (native video carousel) ---------- */
/* Desktop shows a pair across exactly the same rail as the three photos below.
   The only chrome is the position indicator; mouse drag and keyboard remain on
   the native scroll track, while phones keep their existing one-card swipe. */
.watch-carousel{ position:relative; }
.watch-carousel[hidden]{ display:none; }
.watch-carousel__track{ --watch-gap:clamp(14px,2vw,28px); display:flex; gap:var(--watch-gap); overflow-x:auto;
  scroll-snap-type:x mandatory; scroll-behavior:smooth; scrollbar-width:none;
  cursor:grab; touch-action:pan-x; overscroll-behavior-x:contain; }
.watch-carousel__track::-webkit-scrollbar{ display:none; }
.watch-carousel__track.is-dragging{ cursor:grabbing; scroll-snap-type:none; user-select:none; }
.watch-carousel__card{ flex:0 0 calc((100% - var(--watch-gap)) / 2); position:relative; overflow:hidden;
  scroll-snap-align:start; background:#111; border:1px solid var(--line); }
/* With the initial pair the final card cannot physically align to the start edge;
   snapping it to the end avoids the carousel returning to card one after a drag. */
.watch-carousel__card:last-child{ scroll-snap-align:end; }
.watch-carousel__card .video, .watch-carousel__card lite-youtube{ display:block; width:100%; aspect-ratio:16/9; }
.watch-carousel__card .video{ position:relative; overflow:hidden; }
.watch-carousel__card .video iframe{ width:100%; height:100%; border:0; filter:grayscale(1) contrast(1.02); transition:filter .45s ease; }
.watch-carousel__card lite-youtube{ filter:grayscale(1) contrast(1.02); transition:filter .45s ease; }
.watch-carousel__card:hover lite-youtube, .watch-carousel__card:focus-within lite-youtube,
.watch-carousel__card .video:hover iframe, .watch-carousel__card .video:focus-within iframe{ filter:none; }
.watch-carousel__youtube{ display:block; padding:11px 14px; font-family:var(--label); font-size:11px;
  letter-spacing:.12em; text-transform:uppercase; background:#111; text-decoration:underline;
  text-underline-offset:3px; transition:background .2s ease,color .2s ease; }
.watch-carousel__youtube:hover{ background:#fff; color:#000; }
.watch-carousel__new{ position:absolute; top:12px; right:12px; z-index:3; padding:4px 9px;
  background:#fff; color:#000; font-family:var(--label); font-size:10px; letter-spacing:.18em; }
.watch-carousel__hint{ display:flex; justify-content:center; padding-top:14px; }
.watch-carousel__hint[hidden]{ display:none; }
.watch-carousel__dots{ display:flex; align-items:center; gap:8px; min-height:7px; }
.watch-carousel__dots i{ display:block; width:7px; height:7px; border:1px solid #eee; border-radius:50%; }
.watch-carousel__dots i.is-active{ background:#eee; }
.watch-carousel__mobile-arrow{ display:none; }
@media(max-width:680px){
  /* Phones retain their existing one-card native swipe and controls. */
  .watch-carousel__card{ flex-basis:100%; }
  .watch-carousel__hint{ display:grid; grid-template-columns:44px auto 44px; align-items:center;
    justify-content:center; gap:12px; padding-top:10px; }
  .watch-carousel__mobile-arrow{ display:grid; place-items:center; width:44px; height:44px; margin:0;
    padding:0; border:0; background:transparent; color:#eee; cursor:pointer; font-size:23px; line-height:1; }
  .watch-carousel__mobile-arrow:disabled{ opacity:.22; cursor:default; }
  .watch-carousel__dots{ min-height:6px; }
  .watch-carousel__dots i{ width:6px; height:6px; }
  /* Keep the short-lived badge legible over a bright YouTube thumbnail. */
  .watch-carousel__new{ top:10px; right:10px; z-index:5; padding:6px 10px;
    font-size:11px; box-shadow:0 0 0 1px #000; }
}

/* ---------- LISTEN ---------- */
.players{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(16px,2.5vw,28px); margin-bottom:40px; align-items:stretch; }
@media(max-width:820px){ .players{ grid-template-columns:1fr; } }
.players iframe{ width:100%; border:1px solid var(--line); }
.player-col{ display:flex; flex-direction:column; }
.player-lab{ font-family:var(--label); font-size:13px; letter-spacing:.2em; text-transform:uppercase; margin-bottom:14px; }
.streamrow{ display:flex; gap:14px; flex-wrap:wrap; }
.pill{ display:inline-flex; align-items:center; gap:10px; border:2px solid currentColor; border-radius:999px; padding:13px 26px; font-family:var(--label); font-size:12px; letter-spacing:.16em; text-transform:uppercase; transition:.2s; }
.sec--dark .pill:hover{ background:#fff; color:#000; }
/* Solid-bar CTA into /sessions (homepage LISTEN, under the TIM SESSIONS player).
   White fill on the dark section so the archive link cannot be missed - it replaced a
   quiet underlined label that readers skipped. font-weight:600 so Oswald (RU/AZ) shows
   bold; Anton/Archivo Black (EN) is already heavy. */
.sessions-cta{ display:inline-flex; align-items:center; gap:10px; align-self:flex-start;
  margin-top:20px; background:var(--paper); color:var(--ink); border-radius:999px;
  padding:15px 34px; font-family:var(--label); font-weight:600; font-size:13px;
  letter-spacing:.14em; text-transform:uppercase;
  transition:background .2s ease, color .2s ease, box-shadow .2s ease; }
/* invert to an outlined button on hover (clear colour change, not just a fade) */
.sessions-cta:hover{ background:transparent; color:var(--paper); box-shadow:inset 0 0 0 2px var(--paper); }
.sec--light .pill:hover{ background:#000; color:#fff; }

/* ---------- inline booking nudge (after Listen, before Book) ---------- */
.book-nudge{ background:var(--ink); color:var(--paper); padding:0 var(--pad) clamp(56px,9vh,96px); text-align:center; }
.book-nudge .pill{ border-color:#fff; }
.book-nudge .pill:hover{ background:#fff; color:#000; }

/* ---------- CONTACT ---------- */
.contact__grid{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(30px,5vw,80px); align-items:start; }
@media(max-width:820px){ .contact__grid{ grid-template-columns:1fr; gap:40px; } }
.contact__row{ display:flex; flex-direction:column; gap:6px; padding:18px 0; border-top:2px solid var(--ink); }
.contact__row .k{ font-family:var(--label); font-size:12px; letter-spacing:.2em; text-transform:uppercase; color:#666; }
.contact__row .v{ font-family:var(--hero); font-size:clamp(22px,3vw,40px); }
.contact__row a.v{ font-family:var(--hero); }
.socials{ display:flex; gap:18px; flex-wrap:wrap; margin-top:14px; }
.socials a{ font-family:var(--label); font-size:13px; letter-spacing:.12em; text-transform:uppercase; border-bottom:2px solid var(--ink); padding-bottom:3px; }
.dl{ display:flex; align-items:center; justify-content:center; gap:12px; margin-top:36px; background:var(--ink); color:var(--paper); border-radius:999px; padding:20px 34px; font-family:var(--label); font-size:13px; letter-spacing:.16em; text-transform:uppercase; }
.dl:hover{ opacity:.85; }
.dl--ghost{ background:transparent; color:var(--ink); border:2px solid var(--ink); margin-top:12px; transition:.2s; }
.dl--ghost:hover{ background:var(--ink); color:var(--paper); opacity:1; }

/* ---------- footer ---------- */
.foot{ background:var(--ink); color:var(--muted); padding:30px var(--pad) 104px; display:flex; justify-content:space-between; flex-wrap:wrap; gap:10px; font-family:var(--label); font-size:11px; letter-spacing:.18em; text-transform:uppercase; }
/* Narrow phones: the three contact items need ~293px and only ~274px is free at
   320px, so they wrap. space-between then strands the last one alone on the left,
   which reads like a bug. Centre the row instead — a wrapped, centred stack looks
   deliberate. The .dl labels get a fluid size so the longest one ("Download Press
   Kit (PDF)") stays on a single line instead of doubling the pill's height. */
@media(max-width:400px){
  .foot{ justify-content:center; text-align:center; gap:6px 16px; }
  .dl{ padding:18px 20px; font-size:clamp(11.5px,4vw,13px); }
}
/* the two fixed corner FABs (Top / WhatsApp) hover just above the bottom edge —
   reserve a clear strip below the contact lines so the buttons never sit on top of
   them (desktop pills + mobile round icons both need it — set once on .foot above) */

/* ---------- floating booking CTA ---------- */
.fab{ position:fixed; right:clamp(14px,2vw,24px); bottom:clamp(16px,3vw,34px); z-index:60;
  display:inline-flex; align-items:center; gap:7px;
  background:var(--ink); color:#fff; border:2px solid #fff; border-radius:999px;
  padding:11px 20px; font-family:var(--label); font-size:12px; letter-spacing:.16em; text-transform:uppercase;
  box-shadow:0 6px 26px rgba(0,0,0,.45); transition:.2s; }
.fab svg{ width:15px; height:15px; flex:none; }
.fab:hover{ background:#fff; color:#000; }

/* ---------- back-to-top (mirrors the FAB on the opposite corner; fades in past the hero) ---------- */
.totop{ position:fixed; left:clamp(14px,2vw,24px); bottom:clamp(16px,3vw,34px); z-index:60;
  display:inline-flex; align-items:center; gap:7px;
  background:var(--ink); color:#fff; border:2px solid #fff; border-radius:999px;
  padding:11px 20px; font-family:var(--label); font-size:12px; letter-spacing:.16em; text-transform:uppercase;
  box-shadow:0 6px 26px rgba(0,0,0,.45);
  opacity:0; visibility:hidden; transform:translateY(10px);
  transition:opacity .3s ease, transform .3s ease, visibility .3s ease, background .2s ease, color .2s ease; }
.totop--on{ opacity:1; visibility:visible; transform:translateY(0); }
.totop:hover{ background:#fff; color:#000; }
/* phones: icon-only circle (mirrors the WhatsApp FAB across the corner) */
@media(max-width:680px){
  /* line-height:1 makes the line box hug the glyph so the flex centering actually
     centres the arrow — with the inherited 32px leading it sat visibly high. */
  .totop{ padding:0; width:54px; height:54px; justify-content:center; gap:0; font-size:20px; line-height:1; }
  .totop__txt{ display:none; }
}
/* phones: compact icon-only circle (the full "WHATSAPP" pill was too big) */
@media(max-width:680px){
  .fab{ padding:0; width:54px; height:54px; justify-content:center; gap:0; }
  .fab__txt{ display:none; }
  .fab svg{ width:24px; height:24px; }
}
@media (prefers-reduced-motion: reduce){ .fab{ transition:none; } }

/* ---------- polish: a11y skip-link · consistent micro-transitions · rounded focus ---------- */
.skip{ position:absolute; left:-9999px; top:0; z-index:100; background:#000; color:#fff;
  padding:12px 18px; font-family:var(--label); font-size:12px; letter-spacing:.16em; text-transform:uppercase; }
.skip:focus{ left:8px; top:8px; outline:3px solid #fff; }
.nav__links a, .bio__body a, .socials a, .foot a{ transition:opacity .2s ease; }
.socials a:hover{ opacity:.6; }
.foot a:hover{ color:#fff; }
.pill:focus-visible, .dl:focus-visible, .fab:focus-visible, .nav__book:focus-visible{ outline-offset:4px; }

/* ---------- STATS strip (credibility band under the hero) ----------
   Hairline-divided row; --hero carries the digits (Anton in EN, Oswald in RU/AZ). */
.stats{ background:var(--ink); color:var(--paper);
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  padding:clamp(26px,5vh,54px) var(--pad); }
.stats__row{ list-style:none; max-width:1600px; margin-inline:auto;
  display:grid; grid-template-columns:repeat(4,1fr); }
.stats__item{ display:flex; flex-direction:column; gap:10px;
  padding-inline:clamp(12px,2vw,34px); border-left:1px solid var(--line); }
.stats__item:first-child{ border-left:0; padding-left:0; }
.stats__num{ font-family:var(--hero); font-weight:400;
  font-size:clamp(36px,5.6vw,82px); line-height:.92; letter-spacing:-.02em; }
/* min-height reserves TWO lines for every label, so the strip's bottom edge stays even
   whenever any one label wraps. Without it the tile whose label wraps hangs lower than its
   neighbours, and below 820px (2x2 grid) the whole second row grows taller than the first.
   This is language-independent on purpose: RU wraps "Стран с выступлениями", AZ wraps
   "F1 Qran-Pri mövsümü", and at 320px AZ cannot be evened out by shortening copy at all.
   It costs no height against the un-reserved version at any width we ship (verified at
   320/375/840/1440) — the tallest label already set the row height. Labels must stay within
   two lines: a third line reintroduces the ragged edge. */
.stats__lab{ font-family:var(--label); font-size:clamp(10px,1vw,12px);
  letter-spacing:.18em; text-transform:uppercase; color:var(--muted); line-height:1.45;
  min-height:2.9em; }
@media(max-width:820px){
  .stats__row{ grid-template-columns:repeat(2,1fr); row-gap:26px; }
  .stats__item:nth-child(3){ border-left:0; padding-left:0; }
}

/* ---------- BRANDS wall (stages & brands played, inside Experience) ---------- */
.brands{ margin-top:clamp(38px,6vw,70px); }
.brands__kicker{ font-family:var(--label); font-size:12px; letter-spacing:.3em;
  text-transform:uppercase; color:var(--muted); margin-bottom:20px; }
.brands__wall{ list-style:none; display:grid;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  border-top:1px solid var(--line); border-left:1px solid var(--line); }
.brands__wall li{ font-family:var(--label);
  font-size:clamp(14px,1.7vw,24px); letter-spacing:.06em; text-transform:uppercase;
  border-right:1px solid var(--line); border-bottom:1px solid var(--line);
  min-height:clamp(74px,9vw,112px); padding:clamp(16px,2.4vw,28px) clamp(12px,2vw,20px);
  display:flex; align-items:center; justify-content:center; text-align:center;
  transition:background .18s ease, color .18s ease; }
.sec--dark .brands__wall li:hover{ background:var(--paper); color:var(--ink); }
.sec--light .brands__wall li:hover{ background:var(--ink); color:var(--paper); }
/* Phone: the 200px auto-fit floor is larger than half the ~330px content box, so the
   grid could only ever place ONE column and the wall became a 6-storey ladder --
   measured at 445px, 55% of a 375x812 screen, 60% counting its kicker.
   The floor is lowered rather than the column count hard-coded, so auto-fit keeps
   choosing: 130px yields 2 columns from a 320px phone up to ~430px, and 3 columns
   further out, with no constant to revisit when the list grows. The 74px cell is a
   pointer affordance (hover-invert target); on a phone these are read, not clicked,
   so it drops to 46px -- still above the 44px touch-target floor. Type stays 13px so
   the brand names keep outranking their own 12px kicker.
   overflow-wrap keeps the rule independent of string length: RU Cyrillic, AZ
   diacritics and future brand-store names all wrap instead of overflowing. */
@media(max-width:680px){
  .brands__kicker{ margin-bottom:12px; }
  .brands__wall{ grid-template-columns:repeat(auto-fit,minmax(130px,1fr)); }
  .brands__wall li{ font-size:13px; line-height:1.25; min-height:46px;
    padding:10px 8px; overflow-wrap:anywhere; }
}
/* An odd tile count would leave the last cell short of the right edge and the
   rectangle open -- the ugliest failure this hairline lattice has, and the normal
   state for a list being actively added to. Let a lone final tile span the row.
   Scoped to widths where the 130px floor provably yields exactly 2 columns, so it
   can never fire against a 3-column layout. */
@media(max-width:480px){
  .brands__wall li:last-child:nth-child(odd){ grid-column:1 / -1; }
}

/* ---------- SESSIONS archive (/sessions — the monthly TIM SESSIONS series) ----------
   Hero = the CURRENT issue (cover + meta + embed). The grid under it lists PAST issues
   only, so it is absent entirely until issue #002 exists — the hero has to look finished
   on its own, which is why it carries the whole layout and the grid adds only a margin.
   Nothing new is invented here: --hero for the issue number, --label for the small caps,
   .streamrow/.pill for the service links (the generated row carries both classes, exactly
   like the homepage LISTEN row), and the .watch-photos idiom — gap grid, hairline border
   on the cover — for the tiles.
   build_i18n.py emits `<section class="sessions">` — a standalone band, NOT a .sec — so
   the gutter and the 1600px cap live here, modelled on .stats / .book-nudge. The band
   deliberately sets no background: it inherits the black body, which keeps .sec--light
   usable if the page is ever inverted. Top padding is small because the .rhero strip
   above it already ends on clamp(36px,6vh,64px). */
.sessions{ padding:clamp(14px,2.5vh,30px) var(--pad) clamp(64px,10vh,120px); }
.sessions > *{ max-width:1600px; margin-inline:0; }   /* margin-inline:0 = left-aligned, matching .rhero > * on the same page */
/* the archive heading is a bare .h-section (no .sec__head to carry the 40px), and the
   grid follows it directly — so the air between hero and archive is set here */
.sessions .h-section{ margin-top:clamp(56px,9vw,100px); }

/* --- hero: current issue --- */
.session-hero{ display:grid; grid-template-columns:clamp(240px,32vw,520px) minmax(0,1fr);
  gap:clamp(26px,4vw,64px); align-items:start; }
/* the cover is square art (800x800): pin the ratio in CSS so a wrong-sized file can never
   distort the block, and cap the track AND the image so it stops growing on wide screens.
   height:auto is load-bearing, not decoration -- the markup carries width/height attributes
   for CLS, and that height presentation hint keeps aspect-ratio from ever computing (it
   only fills in a dimension that is auto), which rendered the cover 410x800. Same reason
   .career__champ img and .bio__photo img spell it out. */
.session-hero__cover{ width:100%; height:auto; max-width:520px; aspect-ratio:1/1;
  object-fit:cover; border:1px solid var(--line); }
.session-hero__meta{ min-width:0; }
/* __num and __genre deliberately declare no `display`: the generator emits them as <p> and
   <h2> (stacked), but the pair also reads correctly inline on a single "#001 · GENRE" line,
   where the margins below simply drop out. The markup keeps that choice. */
.session-hero__num{ font-family:var(--hero); font-weight:400;
  font-size:clamp(26px,3.4vw,44px); line-height:1; letter-spacing:-.01em; }
.session-hero__genre{ font-family:var(--hero); font-weight:400; text-transform:uppercase;
  font-size:clamp(32px,5vw,72px); line-height:1.02; letter-spacing:-.01em;
  overflow-wrap:break-word; margin-top:6px; }
/* same reason as .h-section / .champ__title at the top of this file: RU/AZ display caps
   need the extra leading (Й/Ё breves above, Д/Ц/Ş/Ç below the baseline). */
html[lang="ru"] .session-hero__genre, html[lang="az"] .session-hero__genre{ line-height:1.12; }
.session-hero__month{ font-family:var(--label); font-size:clamp(11px,1.2vw,13px);
  letter-spacing:.2em; text-transform:uppercase; color:var(--muted); margin-top:14px; }
/* per-issue description + cover credit (both come from the SESSIONS data). */
.session-hero__desc{ font-size:clamp(14px,1.5vw,16px); line-height:1.6; max-width:46ch;
  margin-top:18px; }
.session-hero__credit{ font-family:var(--label); font-size:12px; letter-spacing:.06em;
  color:var(--muted); margin-top:22px; }
.session-hero__credit a{ color:inherit; border-bottom:1px solid currentColor; padding-bottom:1px; }
.session-hero__credit a:hover{ color:var(--paper); }
.session-hero__links{ display:flex; gap:14px; flex-wrap:wrap; margin-top:clamp(20px,3vw,30px); }
/* the pill's hover inversion is theme-scoped (.sec--dark/.sec--light .pill:hover) and this
   band is neither, so without this the service links would have NO hover state at all.
   .book-nudge — the other band that is not a .sec — re-declares it for the same reason. */
.sessions .pill:hover{ background:#fff; color:#000; }
.session-hero__player{ margin-top:clamp(22px,3vw,34px); }
.session-hero__player iframe{ width:100%; border:1px solid var(--line); }  /* height stays in the markup, like .players iframe */
@media(max-width:820px){
  .session-hero{ grid-template-columns:1fr; gap:26px; }
  .session-hero__cover{ max-width:420px; }   /* stacked, the cover would otherwise fill a 780px tablet row */
}

/* --- grid: past issues (from #002 on) --- */
/* auto-FILL, not the wall's auto-fit: auto-fit collapses the empty tracks, so the month
   the archive holds a single past issue that one tile would stretch across the full
   1600px and render a 1600px square cover. auto-fill keeps the track rhythm, so 1, 3, 6
   and 20 issues all read at the same size. The floor (not a column count) still decides
   how many fit, exactly as in .brands__wall. Separation is a gap with a hairline on each
   cover rather than the wall's lattice, so a short last row leaves no half-drawn box. */
.session-grid{ list-style:none; display:grid;
  grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
  gap:clamp(16px,2.5vw,34px); margin-top:clamp(26px,3.5vw,40px); }  /* 40px under its heading, like .sec__head */
.session-tile{ display:block; transition:opacity .2s ease; }
.session-tile:hover, .session-tile:focus-visible{ opacity:.68; }
.session-tile:focus-visible{ outline:3px solid currentColor; outline-offset:4px; }
.session-tile__cover{ width:100%; height:auto; aspect-ratio:1/1; object-fit:cover;
  border:1px solid var(--line); }   /* height:auto for the same reason as the hero cover */
.session-tile__num{ display:block; font-family:var(--hero); font-weight:400;
  font-size:clamp(17px,1.7vw,24px); line-height:1.1; letter-spacing:-.01em; margin-top:12px; }
.session-tile__genre{ display:block; font-family:var(--label);
  font-size:clamp(10px,1vw,12px); letter-spacing:.18em; text-transform:uppercase;
  color:var(--muted); line-height:1.45; margin-top:5px; overflow-wrap:anywhere; }
/* #9a9a9a is too pale on white — light sections use #666 (.f1__kicker, .contact__row .k) */
.sec--light .session-hero__month, .sec--light .session-tile__genre{ color:#666; }
/* Phone: lower the auto floor instead of hard-coding a column count, the same move the
   brands wall makes, so the grid keeps deciding as the archive grows. 130px yields 2
   columns from a 320px phone out to ~430px and 3 beyond; overflow-wrap above keeps a long
   genre inside its tile. */
@media(max-width:680px){
  .session-grid{ grid-template-columns:repeat(auto-fill,minmax(130px,1fr)); gap:14px; }
  .session-tile__num{ font-size:16px; }
  .session-tile__genre{ font-size:10px; letter-spacing:.14em; }
}

/* ---------- PRINT / PDF  (single-page "scroll" — 1:1 with the live site) ----------
   One tall sheet = the whole page (minus Watch/Listen). No A4 pagination, no grid
   collapse: the layout stays exactly as on screen. @page height is auto-fitted to
   the rendered content by build_print.py (measured under print emulation). */
@media print{
  @page{ size:1200px 10000px; margin:0; }   /* height rewritten by build_print.py */
  *, *::before, *::after{
    -webkit-print-color-adjust:exact !important; print-color-adjust:exact !important;
    animation:none !important; transition:none !important;
  }
  /* white paper: the sheet ends on #book (white), so the tiny height buffer
     baked into @page stays invisible instead of showing the black body bg */
  html, body{ background:#fff !important; }
  /* drop the screen chrome + interactive media (all kept on the live site) */
  .nav, #watch, #listen, .fab, .scrollcue, .hero__breathe, .skip, .totop, .hero__cta{ display:none !important; }
  /* /sessions is web-only (the PDF builders never touch it), but a visitor can still hit
     Ctrl+P: drop its Spotify embed for the same reason #listen goes — an iframe prints as
     an empty rectangle. The cover, the number and the service links stay on paper. */
  .session-hero__player{ display:none !important; }
  /* kill full-viewport stretches: in print, 100vh = the whole sheet, so each block
     would balloon. Zero them out; give the hero a fixed cover height instead.
     Small bottom padding drops the title into the lower third so the silhouette
     in the cover photo stays uncovered. */
  .hero{ min-height:0 !important; height:800px !important; padding-bottom:64px !important; }
  .sec{ min-height:0 !important; }
  /* Chrome headless evaluates @media(max-width) against the ~800px OS window, NOT
     the 1200px page box (vw still refs 1200), so the responsive grids wrongly
     collapse in the PDF. Re-assert the desktop templates → print == live desktop. */
  .bio{ grid-template-columns:1fr 1fr !important; }
  .cols2{ grid-template-columns:repeat(2,1fr) !important; }
  .career__champ{ grid-template-columns:.95fr 1.05fr !important; }
  .f1__grid{ grid-template-columns:.85fr 1.15fr !important; }
  .contact__grid{ grid-template-columns:1fr 1fr !important; }
  /* Same guard as the two above: if the headless print window ever renders narrow
     enough to trip the 680px phone rule, a 130px floor across the print sheet would
     explode the wall into ~9 columns. build_kit_a4.py already pins the tile's size
     with !important but never sets the track template, so this is the one property
     that could reach paper. Re-asserting the base value makes it a no-op today. */
  .brands__wall{ grid-template-columns:repeat(auto-fit,minmax(200px,1fr)) !important; }
  /* same guard for the sessions page: without these its hero would stack and its archive
     would explode into ~9 columns whenever the print window trips the 820/680 rules */
  .session-hero{ grid-template-columns:clamp(240px,32vw,520px) minmax(0,1fr) !important; }
  .session-grid{ grid-template-columns:repeat(auto-fill,minmax(220px,1fr)) !important; }
  /* cover text: solid white, no animated gradient/clip. Smaller than on screen so
     it doesn't swallow the cover-photo silhouette in the fixed 1200x800 crop. */
  .hero__title{ color:#fff !important; background:none !important; -webkit-text-fill-color:#fff !important; font-size:120px !important; }
  .hero__tagline, .hero__proof, .hero__proof span{ opacity:1 !important; color:#fff !important; text-shadow:0 1px 9px rgba(0,0,0,.95), 0 0 2px rgba(0,0,0,.9) !important; }
  /* PDF type scale: the on-screen vw headings render large on the 1200px sheet —
     dial them down so the page breathes (live site keeps its responsive sizes). */
  .h-section{ font-size:84px !important; }      /* BIO / EXPERIENCE / F1 / BOOK */
  /* champion-band type (.champ__sub / .champ__title / .champ__loc) is sized in the base CSS only — no print override, so site & PDF stay identical */
  /* PDF ends on the FOLLOW block — no download CTA, no site footer (both stay live) */
  .dl, .foot, .book-nudge{ display:none !important; }
  a{ text-decoration:none !important; }
}
