/* ------------------------------------------------------------------
   jt.css — redesigned jontryggvi.is home (ported from design/boards/Main.dc.html)
   Everything is scoped under .jt so it never touches the legacy pages.
------------------------------------------------------------------ */

.jt {
  --basalt: #232326;
  --basalt-deep: #17171a;
  --night: #0b0b0d;
  --snow: #f3f1ee;
  --ash: #d6d3cf;
  --rule: #5a5a5e;
  --web: #f0746a;
  --music: #a68bd6;
  --photo: #7cc8d1;
  --sun: #f4b04a;
  --head: 'Bricolage Grotesque', sans-serif;
  --body: 'Newsreader', Georgia, serif;
  --gutter: 56px;

  background: var(--basalt);
  color: var(--snow);
  font-family: var(--body);
  overflow: hidden;
  position: relative;
}
.jt *, .jt *::before, .jt *::after { box-sizing: border-box; }
.jt a { color: inherit; text-decoration: none; }
.jt a:focus-visible { outline: 3px solid var(--sun); outline-offset: 4px; }

/* ---- Keyframes ---- */
@keyframes jt-night { from { opacity: 1; } }
@keyframes jt-sunrise { from { transform: translate(-50%, -50%) translateY(190px) scale(.55); opacity: 0; } }
@keyframes jt-drop {
  0% { transform: translateY(-130%) rotate(-14deg); opacity: 0; }
  55% { transform: translateY(7%) rotate(2deg); opacity: 1; }
  80% { transform: translateY(-3%) rotate(-1deg); }
}
@keyframes jt-pop { from { transform: translateY(-22px) scale(.6); opacity: 0; } }
@keyframes jt-rise { from { transform: translateY(24px); opacity: 0; } }
/* Mobile menu: links are "loose contents" inside the sliding box. They ride
   the home blocks' house overshoot easing — cubic-bezier(.3,1.7,.5,1), the one
   the slabs/glyph use — so the slide AND a tiny tilt both overshoot once and
   settle, given plenty of time. Motion and fade are separate animations so the
   overshoot never touches opacity. --slide / --tilt vary per link (set below)
   to keep them out of lockstep. */
@keyframes jt-slide-in  { from { transform: translateX(var(--slide, 58px)) rotate(var(--tilt, 3deg)); } to { transform: none; } }
@keyframes jt-slide-out { from { transform: none; } to { transform: translateX(var(--slide, 58px)) rotate(var(--tilt, 3deg)); } }
@keyframes jt-fade-in   { from { opacity: 0; } to { opacity: 1; } }
@keyframes jt-fade-out  { from { opacity: 1; } to { opacity: 0; } }
@keyframes jt-wipe {
  from { clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%); }
  to { clip-path: var(--clip); }
}
@keyframes jt-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* ---- Hero ---- */
.jt-hero {
  position: relative;
  min-height: 820px;
  background: linear-gradient(180deg, #0b0b0d 0%, #15110f 38%, #4a2412 52%, #2e2321 62%, #232326 100%);
}
/* The hero photo (assets/img/hero-sunrise.jpg) is pre-cropped so its horizon
   sits ~11% down the image; matching background-position keeps that sharp line
   just under the nav at every width (with `cover`, position-% = the feature's
   own image-fraction is the stable point). */
.jt-hero.has-img { background-size: cover; background-position: center 11%; }
/* The drawn CSS sun (.jt-sun) is the sunrise stand-in for a hero with no photo;
   with a real sunrise image it just overlays a second glow, so hide it. */
.jt-hero.has-img .jt-sun { display: none; }
.jt-sun {
  position: absolute; left: 50%; top: 56%;
  width: 1100px; max-width: 100%; height: 300px;
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse 50% 50% at 50% 50%, #f9d78f 0%, #f4a63f 28%, rgba(214,96,40,.75) 55%, rgba(214,96,40,0) 100%);
  animation: jt-sunrise 2.6s cubic-bezier(.2,.7,.2,1) backwards;
  pointer-events: none;
}
.jt-night {
  position: absolute; inset: 0; background: #050506; opacity: 0;
  pointer-events: none; z-index: 2;
  animation: jt-night 2.6s cubic-bezier(.3,.6,.2,1) backwards;
}

/* ---- Header / nav (shared look) ---- */
.jt-head {
  position: fixed; top: 0; left: 0; right: 0; z-index: 3;
  display: flex; flex-wrap: wrap; gap: 16px 40px; align-items: center; justify-content: space-between;
  padding: 28px var(--gutter);
  /* Longer than the rest so the blurred bar eases back in gently after the menu
     closes (and when scrolling), rather than snapping. */
  transition: background-color .7s ease, padding .7s ease,
              -webkit-backdrop-filter .7s ease, backdrop-filter .7s ease;
}

/* Scrolled: the pinned header drops a blurred bar in and forces light text so
   it stays legible over any section (home slabs, dark subpage bodies). The JS
   in jt-nav.js toggles .jt-scrolled on .jt once the page has scrolled. */
.jt.jt-scrolled .jt-head {
  padding-top: 16px; padding-bottom: 16px;
  background: rgba(16, 16, 18, .72);
  -webkit-backdrop-filter: blur(18px) saturate(130%);
  backdrop-filter: blur(18px) saturate(130%);
}
.jt.jt-scrolled .jt-brand,
.jt.jt-scrolled .jt-nav a,
.jt.jt-scrolled .jt-burger { color: var(--snow); }
.jt-brand {
  display: inline-block; font-family: var(--head); font-weight: 700; font-size: 22px;
  letter-spacing: -.01em; color: var(--snow);
  transition: transform .35s cubic-bezier(.3,1.9,.5,1);
  animation: jt-pop .6s cubic-bezier(.3,1.6,.5,1) backwards; animation-delay: 1.7s;
}
.jt-brand:hover { transform: rotate(-3deg) scale(1.06); }
.jt-nav { display: flex; flex-wrap: wrap; gap: 8px 32px; font-family: var(--head); font-weight: 500; font-size: 16px; }
.jt-nav a {
  padding: 10px 2px; display: flex; align-items: center; gap: 10px;
  background: linear-gradient(currentColor, currentColor) 0 calc(100% - 2px) / 0 2px no-repeat;
  transition: background-size .35s cubic-bezier(.2,.8,.2,1);
  animation: jt-pop .6s cubic-bezier(.3,1.6,.5,1) backwards; animation-delay: calc(1.8s + var(--n) * .08s);
}
.jt-nav a:hover, .jt-nav a:focus-visible, .jt-nav a[aria-current] { background-size: 100% 2px; }
.jt-dot { width: 10px; height: 10px; border-radius: 50%; transition: transform .35s cubic-bezier(.3,1.9,.5,1); }
.jt-nav a:hover .jt-dot { transform: scale(1.9); }

/* Hamburger (mobile only — hidden on desktop) */
.jt-burger {
  display: none; position: relative; z-index: 50;
  width: 48px; height: 48px; margin: -10px -10px -10px 0; padding: 0;
  background: none; border: 0; cursor: pointer; color: inherit;
  align-items: center; justify-content: center;
  animation: jt-pop .6s cubic-bezier(.3,1.6,.5,1) backwards; animation-delay: 1.8s;
}
.jt-burger-box { position: relative; width: 26px; height: 14px; }
.jt-burger-bar {
  position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px;
  background: currentColor;
  transition: transform .4s cubic-bezier(.76,0,.24,1), background-color .3s ease;
}
.jt-burger-bar:nth-child(1) { top: 0; }
.jt-burger-bar:nth-child(2) { bottom: 0; }
/* 2 bands cross into an X */
.jt.nav-open .jt-burger-bar { background: var(--snow); }
.jt.nav-open .jt-burger-bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.jt.nav-open .jt-burger-bar:nth-child(2) { transform: translateY(-6px) rotate(-45deg); }

/* ---- Hero title ---- */
.jt-headline { position: absolute; z-index: 3; left: var(--gutter); right: var(--gutter); bottom: 150px; }
.jt-name {
  margin: 0; font-family: var(--head); font-weight: 300;
  font-size: clamp(56px, 13vw, 176px); line-height: .92; letter-spacing: -.045em; color: var(--snow);
}
.jt-name .ch {
  display: inline-block;
  animation: jt-drop 1s cubic-bezier(.25,.8,.3,1) backwards; animation-delay: calc(1.3s + var(--i) * .07s);
  transition: transform .35s cubic-bezier(.3,1.9,.5,1), color .2s;
}
.jt-name .ch:hover { transform: translateY(-.12em) rotate(-5deg) scale(1.06); }
.jt-name .ch:nth-of-type(3n+1):hover { color: var(--web); }
.jt-name .ch:nth-of-type(3n+2):hover { color: var(--music); }
.jt-name .ch:nth-of-type(3n):hover { color: var(--photo); }
.jt-sub {
  margin: 28px 0 0; max-width: 30ch; font-size: clamp(20px, 2.4vw, 28px); line-height: 1.35; color: var(--snow);
  animation: jt-rise .8s ease-out backwards; animation-delay: 2.4s;
}

/* ---- Chapter slabs ---- */
.jt-slabs {
  position: relative; margin-top: -120px;
  display: grid;
  /* Expanded (not repeat()) so the track list matches the :has(:hover) states
     exactly — Chromium won't interpolate a repeat()-derived list against an
     explicit one, which made the enter-from-outside transition snap. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
  transition: grid-template-columns .6s cubic-bezier(.3,1.2,.4,1);
}
/* Hover states reuse the same minmax(0,…) track type as the base so the width
   interpolates smoothly on first entry; mixing minmax(0,1fr) with plain 1fr
   makes the enter transition jump (0 ↔ auto min is not animatable). */
.jt-slabs:has(.s1:hover) { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr) minmax(0, 1fr); }
.jt-slabs:has(.s2:hover) { grid-template-columns: minmax(0, 1fr) minmax(0, 1.45fr) minmax(0, 1fr); }
.jt-slabs:has(.s3:hover) { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.45fr); }
.jt-slab {
  position: relative; display: flex; flex-direction: column; justify-content: flex-end; gap: 20px;
  min-height: 560px; padding: 0 48px 48px; color: var(--basalt);
  clip-path: var(--clip);
  animation: jt-wipe 1s cubic-bezier(.2,.9,.2,1) backwards; animation-delay: calc(2.1s + var(--n) * .16s);
  transition: clip-path .55s cubic-bezier(.3,1.4,.5,1), filter .3s;
}
.jt-slab.s1 { --clip: polygon(0 14%, 100% 0, 100% 100%, 0 100%); --clip-h: polygon(0 3%, 100% 0, 100% 100%, 0 100%); background: var(--web); }
.jt-slab.s2 { --clip: polygon(0 4%, 100% 14%, 100% 100%, 0 100%); --clip-h: polygon(0 0, 100% 3%, 100% 100%, 0 100%); background: var(--music); }
.jt-slab.s3 { --clip: polygon(0 10%, 100% 0, 100% 100%, 0 100%); --clip-h: polygon(0 2%, 100% 0, 100% 100%, 0 100%); background: var(--photo); }
.jt-slab:hover, .jt-slab:focus-visible { clip-path: var(--clip-h); filter: brightness(1.07); }
.jt-slab > * { animation: jt-rise .7s ease-out backwards; animation-delay: calc(2.7s + var(--n) * .16s); }
.jt-slab h2 {
  margin: 0; font-family: var(--head); font-weight: 800; font-size: clamp(30px, 3.2vw, 56px);
  line-height: .95; letter-spacing: -.04em; overflow-wrap: break-word; hyphens: auto;
  transition: transform .45s cubic-bezier(.3,1.7,.5,1), letter-spacing .45s;
}
.jt-slab:hover h2 { transform: translateY(-10px); letter-spacing: -.065em; }
.jt-slab p { margin: 0; max-width: 28ch; font-size: clamp(18px, 2vw, 22px); line-height: 1.4; }
.jt-slab .jt-cta {
  display: flex; align-items: center; gap: 12px; font-family: var(--head); font-weight: 700; font-size: 18px;
}
.jt-glyph {
  position: absolute; top: 26%; right: 36px; width: 104px; height: 104px; opacity: .3;
  transition: transform .6s cubic-bezier(.3,1.7,.5,1), opacity .3s;
}
.jt-glyph path, .jt-glyph circle { stroke-dasharray: 1; stroke-dashoffset: 0; }
.jt-slab:hover .jt-glyph { transform: rotate(-9deg) scale(1.3); opacity: .85; }
.jt-slab:hover .jt-glyph path, .jt-slab:hover .jt-glyph circle { animation: jt-draw .9s ease-out; }
.jt-go { transition: transform .3s cubic-bezier(.3,1.8,.5,1); }
.jt-slab:hover .jt-go { transform: translateX(14px); }

/* ---- CV / Tetris bands ---- */
.jt-bands { display: flex; flex-wrap: wrap; gap: 0; padding: 96px var(--gutter) 40px; }
.jt-band {
  flex: 1 1 420px; display: flex; flex-direction: column; gap: 12px; border-bottom: 1px solid var(--rule);
  background: linear-gradient(var(--snow), var(--snow)) 0 100% / 100% 0 no-repeat;
  transition: background-size .4s cubic-bezier(.2,.8,.2,1), color .3s, padding .4s cubic-bezier(.3,1.5,.5,1);
}
.jt-band.cv { padding: 28px 48px 40px 28px; }
.jt-band.tetris { padding: 28px 28px 40px 48px; }
.jt-band:hover, .jt-band:focus-visible { background-size: 100% 100%; color: var(--basalt); }
.jt-band h2 { margin: 0; font-family: var(--head); font-weight: 700; font-size: clamp(40px, 5vw, 56px); letter-spacing: -.035em; transition: transform .4s cubic-bezier(.3,1.7,.5,1); }
.jt-band:hover h2 { transform: translateX(18px); }
.jt-band p { margin: 0; max-width: 34ch; font-size: clamp(18px, 2vw, 22px); line-height: 1.4; color: var(--ash); transition: color .3s; }
.jt-band:hover p { color: var(--basalt); }

/* ---- Footer ---- */
.jt-foot {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px 48px; align-items: center;
  padding: 32px var(--gutter) 48px; font-family: var(--head); font-size: 15px; color: var(--ash);
}
.jt-foot > :first-child { justify-self: start; }
.jt-foot .jt-social { justify-self: end; }
.jt-foot .mail { color: var(--snow); border-bottom: 1px solid #8a8a8e; }
.jt-social { display: flex; gap: 28px; }
.jt-social a { display: inline-block; transition: transform .3s cubic-bezier(.3,1.9,.5,1), color .2s; }
.jt-social a:hover { transform: translateY(-5px) rotate(-4deg); }
.jt-social .f:hover { color: var(--web); }
.jt-social .i:hover { color: var(--music); }
.jt-social .l:hover { color: var(--photo); }
.jt-social .x:hover { color: var(--sun); }

/* ---- Responsive (Mobile board) ---- */
@media (max-width: 900px) {
  .jt { --gutter: 20px; }

  /* ---- Mobile menu: blurred slide-in panel + staggered links ---- */
  .jt-burger { display: inline-flex; }

  /* Freeze the page behind the open panel so touch/scroll can't drift the
     content underneath the blur. Released the moment the panel starts closing. */
  html:has(.jt.nav-open) { overflow: hidden; }

  /* .jt-head is a z-index:3 stacking context, which would trap the whole menu
     (panel + burger) behind front-page layers like .jt-headline and the pulled-
     up slabs. Lift the header above everything while the menu is open. */
  .jt.nav-open .jt-head,
  .jt.nav-closing .jt-head { z-index: 60; }

  /* The scrolled header carries backdrop-filter, which makes .jt-head the
     containing block for its fixed child .jt-nav — clipping the open panel to
     the header's own box. Drop it while the menu is open so the panel fills the
     viewport again (the panel's own blur covers the page). */
  .jt.nav-open .jt-head,
  .jt.nav-closing .jt-head {
    /* instant, not transitioned: any non-none backdrop-filter value (even
       mid-transition) re-forms the containing block and re-clips the panel. */
    transition: none;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .jt-nav {
    position: fixed; inset: 0; z-index: 40;
    display: flex; flex-direction: column; flex-wrap: nowrap;
    align-items: flex-start; justify-content: center; gap: 6px;
    padding: 0 max(var(--gutter), 32px);
    color: var(--snow);
    /* Morph in/out: the panel stays in place and blurs from 0 -> full (no slide).
       Closed = zero blur + transparent fill. */
    background: rgba(16, 16, 18, 0);
    -webkit-backdrop-filter: blur(0px) saturate(100%);
    backdrop-filter: blur(0px) saturate(100%);
    visibility: hidden;
    transition: -webkit-backdrop-filter .5s ease, backdrop-filter .5s ease,
      background-color .5s ease, visibility 0s linear .5s;
  }
  .jt-nav a {
    font-family: var(--head); font-weight: 400;
    font-size: clamp(34px, 9vw, 52px); line-height: 1.1;
    padding: 8px 0; gap: 16px;
    transform-origin: left center;   /* tilt hinges from the left, like a loose flap */
    animation: none; opacity: 0;     /* overrides desktop entrance; hidden until opened */
  }
  /* break the lockstep: each link a slightly different throw + tilt */
  .jt-nav a:nth-child(odd)  { --slide: 62px; --tilt: 3.4deg; }
  .jt-nav a:nth-child(even) { --slide: 52px; --tilt: 2.2deg; }
  .jt-nav a:nth-child(3n)   { --slide: 58px; --tilt: 4deg; }
  .jt-nav a::after { content: none; }
  .jt-dot { width: 14px; height: 14px; }

  /* Open: the panel blurs in, THEN the links stagger in once it's ~90% there */
  .jt.nav-open .jt-nav {
    background: rgba(16, 16, 18, .22);
    -webkit-backdrop-filter: blur(28px) saturate(130%);
    backdrop-filter: blur(28px) saturate(130%);
    visibility: visible;
    transition: -webkit-backdrop-filter .5s ease, backdrop-filter .5s ease,
      background-color .5s ease;
  }
  .jt.nav-open .jt-nav a,
  .jt.nav-closing .jt-nav a { color: var(--snow); }
  .jt.nav-open .jt-nav a {
    animation:
      jt-slide-in .72s cubic-bezier(.3,1.7,.5,1) both,
      jt-fade-in .4s ease both;
    animation-delay: calc(.45s + var(--n) * .12s);   /* start at ~90% of the blur */
  }

  /* Close: links stagger out first, THEN the blur recedes to 0 (delayed) */
  .jt.nav-closing .jt-nav {
    visibility: visible;
    background: rgba(16, 16, 18, 0);
    -webkit-backdrop-filter: blur(0px) saturate(100%);
    backdrop-filter: blur(0px) saturate(100%);
    transition: -webkit-backdrop-filter .5s ease .4s, backdrop-filter .5s ease .4s,
      background-color .5s ease .4s;
  }
  .jt.nav-closing .jt-nav a {
    animation:
      jt-slide-out .5s cubic-bezier(.5,0,.75,.4) both,
      jt-fade-out .46s ease both;
    animation-delay: calc((var(--count) - 1 - var(--n)) * .08s);
  }

  .jt-hero { min-height: 620px; }
  .jt-headline { bottom: 110px; }
  .jt-slabs { grid-template-columns: 1fr; margin-top: -80px; }
  .jt-slabs:has(.s1:hover), .jt-slabs:has(.s2:hover), .jt-slabs:has(.s3:hover) { grid-template-columns: 1fr; }
  .jt-slab { min-height: 420px; padding: 0 24px 32px; clip-path: none !important; }
  .jt-glyph { right: 20px; width: 72px; height: 72px; }
  .jt-bands { padding: 64px var(--gutter) 24px; }
  .jt-band.cv, .jt-band.tetris { padding: 24px; flex-basis: 100%; }
}

/* ------------------------------------------------------------------
   Subpages (Web / Music / Photography) — shared shell + coloured hero
------------------------------------------------------------------ */
.jt-page-hero {
  position: relative; min-height: 440px;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 18px;
  padding: 150px var(--gutter) 56px; color: var(--basalt);
}
.jt-page-hero.web { background: var(--web); }
.jt-page-hero.music { background: var(--music); }
.jt-page-hero.photo { background: var(--photo); }
.jt-page-hero h1 {
  margin: 0; font-family: var(--head); font-weight: 300;
  font-size: clamp(52px, 10vw, 132px); line-height: .92; letter-spacing: -.045em;
  animation: jt-rise .8s ease-out backwards; animation-delay: .1s;
}
.jt-page-hero p {
  margin: 0; max-width: 42ch; font-size: clamp(18px, 2.2vw, 24px); line-height: 1.4;
  animation: jt-rise .8s ease-out backwards; animation-delay: .25s;
}

/* On subpages the nav sits over a light colour band, so it reads dark. */
.jt--sub .jt-brand, .jt--sub .jt-nav a, .jt--sub .jt-burger { color: var(--basalt); }

/* Subpages have no long sunrise intro, so the header would otherwise sit
   invisible for ~1.8s (burger included). Bring it in promptly here; the home
   page keeps its choreographed, hero-synced entrance. */
.jt--sub .jt-brand,
.jt--sub .jt-burger { animation-delay: .2s; }
.jt--sub .jt-nav a { animation-delay: calc(.28s + var(--n) * .08s); }

.jt-page { padding: 72px var(--gutter) 48px; }

/* Web project rows (fed from cv_work) */
.jt-works { display: flex; flex-direction: column; }
.jt-work {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 24px;
  padding: 28px 0; border-bottom: 1px solid var(--rule); color: var(--snow);
  transition: padding-left .4s cubic-bezier(.3,1.5,.5,1);
}
.jt-work:hover, .jt-work:focus-visible { padding-left: 16px; }
.jt-work h2 {
  margin: 0; flex: 1 1 340px; font-family: var(--head); font-weight: 700;
  font-size: clamp(26px, 3.2vw, 42px); letter-spacing: -.03em; line-height: 1; transition: color .2s;
}
.jt-work:hover h2 { color: var(--web); }
.jt-work .meta { color: var(--ash); font-family: var(--head); font-size: 15px; }
.jt-work .sum { flex: 1 1 100%; margin: 8px 0 0; max-width: 72ch; color: var(--ash); font-size: 19px; line-height: 1.45; }
.jt-work .tech { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.jt-work .chip { font-family: var(--head); font-size: 13px; font-weight: 500; color: var(--ash); border: 1px solid var(--rule); border-radius: 999px; padding: 4px 12px; }

/* Music embed */
.jt-embed { max-width: 900px; }
.jt-embed iframe { width: 100%; height: 450px; border: 0; border-radius: 8px; display: block; }

/* Photography gallery — masonry collage + scroll reveal + lightbox */
.jt-gallery { columns: 300px; column-gap: 12px; }
@media (min-width: 1100px) { .jt-gallery { columns: 4; } }
@media (max-width: 520px)  { .jt-gallery { columns: 2; column-gap: 8px; } }
.jt-shot { break-inside: avoid; margin: 0 0 12px; }

/* Cinematic reveal — blur-up + clip wipe + rise. */
@keyframes jt-shot-reveal {
  from { opacity: 0; transform: translateY(52px) scale(1.06); filter: blur(16px) brightness(.45); clip-path: inset(20% 0 0 0); }
  60%  { opacity: 1; }
  to   { opacity: 1; transform: none; filter: blur(0) brightness(1); clip-path: inset(0 0 0 0); }
}
/* IntersectionObserver-driven reveal (reliable on all browsers incl. iOS Safari). */
.jt-gallery.reveal .jt-shot { opacity: 0; transform: translateY(52px) scale(1.06); filter: blur(16px) brightness(.45); clip-path: inset(20% 0 0 0); }
.jt-gallery.reveal .jt-shot.in {
  opacity: 1; transform: none; filter: blur(0) brightness(1); clip-path: inset(0 0 0 0);
  transition: opacity .9s cubic-bezier(.2,.7,.2,1), transform 1.05s cubic-bezier(.16,1,.3,1), filter .9s ease, clip-path 1.05s cubic-bezier(.16,1,.3,1);
  transition-delay: var(--d, 0ms);
}
.jt-shot-btn {
  display: block; width: 100%; padding: 0; border: 0; margin: 0; cursor: zoom-in;
  background: var(--basalt-deep); border-radius: 8px; overflow: hidden; position: relative; line-height: 0;
}
.jt-shot-btn img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s cubic-bezier(.2,.8,.2,1); }
.jt-shot-btn::after { content: ""; position: absolute; inset: 0; background: linear-gradient(transparent 55%, rgba(0,0,0,.3)); opacity: 0; transition: opacity .3s; }
.jt-shot-btn:hover img, .jt-shot-btn:focus-visible img { transform: scale(1.06); }
.jt-shot-btn:hover::after { opacity: 1; }

.jt-empty { color: var(--ash); font-size: 20px; line-height: 1.5; max-width: 52ch; }
.jt-empty a { color: var(--snow); border-bottom: 1px solid var(--rule); }

/* Lightbox */
.jt-lb {
  position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; padding: 24px;
  background: rgba(8,8,10,0); -webkit-backdrop-filter: blur(0); backdrop-filter: blur(0);
  visibility: hidden; transition: background .35s ease, backdrop-filter .35s ease, visibility 0s linear .35s;
}
.jt-lb.open { visibility: visible; background: rgba(8,8,10,.93); -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px); transition: background .35s ease, backdrop-filter .35s ease; }
.jt-lb-stage { position: relative; width: min(94vw, 1400px); height: 80vh; display: grid; place-items: center; }
.jt-lb-img { position: absolute; max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 6px; box-shadow: 0 30px 80px rgba(0,0,0,.6); opacity: 0; transition: opacity .55s ease; will-change: transform, opacity; }
.jt-lb-img.show { opacity: 1; }
/* Slow Ken-Burns drift once the open animation has settled. */
.jt-lb.kb .jt-lb-img.show { animation: jt-kenburns 20s ease-in-out infinite alternate; }
@keyframes jt-kenburns { from { transform: scale(1); } to { transform: scale(1.07); } }
.jt-lb-cap { position: absolute; bottom: 74px; left: 0; right: 0; text-align: center; font-family: var(--head); font-size: 14px; color: var(--ash); padding: 0 24px; opacity: 0; transition: opacity .3s .1s; }

/* Filmstrip */
.jt-lb-strip { position: absolute; bottom: 14px; left: 0; right: 0; display: flex; gap: 6px; justify-content: center; align-items: center; overflow-x: auto; padding: 6px 16px; opacity: 0; transition: opacity .3s; scrollbar-width: none; }
.jt-lb.open .jt-lb-strip { opacity: 1; }
.jt-lb-strip::-webkit-scrollbar { display: none; }
.jt-lb-thumb { flex: 0 0 auto; width: 54px; height: 40px; object-fit: cover; border-radius: 4px; opacity: .4; cursor: pointer; outline: 2px solid transparent; outline-offset: 2px; transition: opacity .2s, outline-color .2s, transform .2s; }
.jt-lb-thumb:hover { opacity: .85; transform: translateY(-2px); }
.jt-lb-thumb.active { opacity: 1; outline-color: var(--snow); }
@media (max-width: 560px) { .jt-lb-strip { display: none; } .jt-lb-cap { bottom: 20px; } .jt-lb-stage { height: 82vh; } }
.jt-lb.open .jt-lb-cap { opacity: 1; }
.jt-lb-count { position: absolute; top: 20px; left: 0; right: 0; text-align: center; font-family: var(--head); font-size: 13px; letter-spacing: .04em; color: var(--ash); opacity: 0; transition: opacity .3s; }
.jt-lb.open .jt-lb-count { opacity: .8; }
.jt-lb-btn { position: absolute; top: 50%; transform: translateY(-50%); width: 56px; height: 56px; border: 0; border-radius: 50%; background: rgba(255,255,255,.08); color: var(--snow); font: 400 24px/1 var(--head); cursor: pointer; display: grid; place-items: center; opacity: 0; transition: background .2s, transform .2s, opacity .3s; }
.jt-lb.open .jt-lb-btn { opacity: 1; }
.jt-lb-btn:hover { background: rgba(255,255,255,.18); }
.jt-lb-prev { left: 18px; } .jt-lb-next { right: 18px; }
.jt-lb-prev:hover { transform: translateY(-50%) translateX(-3px); }
.jt-lb-next:hover { transform: translateY(-50%) translateX(3px); }
.jt-lb-close { top: 16px; right: 16px; bottom: auto; transform: none; width: 48px; height: 48px; font-size: 20px; }
.jt-lb-close:hover { transform: rotate(90deg); }
@media (max-width: 760px) { .jt-lb-prev { left: 6px; } .jt-lb-next { right: 6px; } .jt-lb-btn { width: 46px; height: 46px; } }

@media (max-width: 900px) {
  .jt-page-hero { min-height: 340px; padding: 112px var(--gutter) 40px; }
  .jt-page { padding: 48px var(--gutter) 24px; }
  .jt-embed iframe { height: 380px; }
  .jt-foot { grid-template-columns: 1fr; gap: 14px; }
  .jt-foot > :first-child, .jt-foot .jt-social { justify-self: start; }
}

/* ---- Reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
  .jt *, .jt *::before, .jt *::after { animation: none !important; transition: none !important; }
  /* links default to opacity:0 on mobile for the stagger — show them when open */
  .jt.nav-open .jt-nav a { opacity: 1 !important; }
}
