/* ===================================================================
   Location pages. Loads after style.css and inherits every token from
   it, so a place page cannot drift from the home page's palette,
   spacing scale, radius or type.
   =================================================================== */

.pback { display: inline-flex; align-items: center; gap: .55rem;
  font-size: .6875rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .16em; color: var(--paper); opacity: .78;
  text-decoration: none; transition: opacity .3s var(--ease); }
.pback:hover, .pback:focus-visible { opacity: 1; }
".pback svg { width: 14px; height: 14px; }
/* the back link is 14px of small caps; the hit area is not */
.pback { position: relative; }
.pback::before { content: ""; position: absolute; left: 0; right: 0;
  top: 50%; height: 44px; transform: translateY(-50%); }

/* ---------------------------------------------------------------- hero */
.phero { position: relative; height: 76svh; min-height: 30rem; overflow: hidden;
  background: var(--surface); }
.phero__img { position: absolute; inset: 0; width: 100%; height: 112%;
  object-fit: cover; will-change: transform; }
.phero::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to top, rgba(11,11,12,.92) 0%, rgba(11,11,12,.35) 42%, rgba(11,11,12,.15) 100%),
    linear-gradient(to right, rgba(11,11,12,.6) 0%, transparent 55%); }
.phero__in { position: absolute; z-index: 2; left: var(--gutter); right: var(--gutter);
  bottom: clamp(2rem, 7vh, 5rem); }
.phero__t { margin: 0; font-family: var(--serif); font-weight: 400;
  font-optical-sizing: auto; font-size: clamp(2.5rem, 8vw, 6.5rem);
  line-height: .98; letter-spacing: -.025em; }

/* ---------------------------------------------------------------- lead */
.plead { display: grid; gap: var(--s6); grid-template-columns: 1fr; }
@media (min-width: 900px) { .plead { grid-template-columns: 1.25fr .75fr; gap: var(--s7); } }
.plead__body p { margin: 0 0 var(--s4); max-width: 62ch;
  font-size: clamp(1rem, 1.15vw, 1.125rem); line-height: 1.75; color: var(--soft); }
.plead__body p:first-child { font-size: clamp(1.15rem, 1.5vw, 1.4rem); line-height: 1.6;
  color: var(--paper); }


/* ---------------------------------------------------------------- gallery
   Eleven treatments, one per place, no two alike. The patterns are the
   Skiper UI card family rebuilt in plain CSS and Motion, because this
   site is not a React app and pulling in framer-motion, GSAP, Lenis and
   Swiper to show four photographs would cost more than the whole page.

     k-stack     sticky stack, each card scaling under the next   (baku)
     k-rotate    the same stack, with a tilt on the way down     (sheki)
     k-tunnel    the set strung out along Z, coming at you    (yanardag)
     k-coverflow 3D coverflow, centre card nearest            (ateshgah)
     k-inverted  coverflow turned inside out                  (gobustan)
     k-dealt     cards flying up and landing on the pile       (xinaliq)
     k-deck      a deck you throw off the top                    (lahic)
     k-fade      scale and fade straight through scroll         (goygol)
     k-clip      one frame wiping into the next              (candycane)
     k-parallax  columns travelling at their own speeds       (shahdag)
     k-fan       one pile opening into an arc                    (ganja)

   Every one of them is driven by scroll. Two used to open on hover
   instead, which meant they did nothing at all on a phone and asked for
   the wrong gesture on a desktop; k-tunnel and k-dealt replaced them.

   Every hidden state is behind `.js`, so with scripting off all eleven
   are a plain, complete grid of photographs. */

.pshot { position: relative; margin: 0; overflow: hidden; border-radius: var(--r);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); }
.pshot img { width: 100%; height: 100%; object-fit: cover; display: block;
  will-change: transform; }
.pshot figcaption { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: var(--s5) var(--s3) var(--s3);
  background: linear-gradient(to top, rgba(11,11,12,.9), transparent);
  color: var(--paper); opacity: 0; transform: translateY(8px);
  transition: opacity .45s var(--ease), transform .45s var(--ease); }
.pshot:hover figcaption, .pshot:focus-within figcaption,
.pshot.is-open figcaption, .pshot.is-front figcaption { opacity: 1; transform: none; }
@media (hover: none) { .pshot figcaption { opacity: 1; transform: none; } }
.pshot::after { content: ""; position: absolute; inset: 0; z-index: 2;
  pointer-events: none; opacity: 0; transition: opacity .45s var(--ease);
  background: radial-gradient(16rem 16rem at var(--mx,50%) var(--my,50%),
              rgba(217,94,34,.18), transparent 70%); }
@media (hover: hover) and (pointer: fine) { .pshot:hover::after { opacity: 1; } }

/* default: a plain grid. Every treatment overrides from here. */
.pgal { display: grid; gap: var(--s4); grid-template-columns: 1fr; overflow-x: clip; }
.pgal .pshot { aspect-ratio: 4 / 3; }
@media (min-width: 760px) { .pgal { grid-template-columns: repeat(2, 1fr); } }

/* Everything below reshapes the gallery into something only the module
   layer can finish laying out: cards stacked absolutely on one another,
   sticky slots, fixed-height stages. If that layer never boots the
   markup must stay the plain grid the base rules describe, so all of it
   is gated on `.mo`, which motion sets on itself once it is running.

   This is not hypothetical. Opened straight off disk, Chrome refuses
   the module scripts (file:// has a null origin), and four of these
   treatments collapsed all four photographs onto one another: you saw
   one picture where there should have been four.                      */

/* ---- 1 + 2. sticky stacks ---------------------------------------
   Each card is its own sticky viewport-height slot. Scrolling drives
   the card behind it down in scale, so the set reads as a pile being
   dealt rather than a list scrolling past. */
.mo .k-stack, .mo .k-rotate { display: block; }
/* Short of the full viewport and offset from the top, so the edge of
   the card under the current one stays visible. At 100svh with square
   corners the stack stopped reading as cards at all and just looked
   like four full-bleed photographs in a row. */
.mo .k-stack .pshot, .mo .k-rotate .pshot {
  position: sticky; top: 8vh; height: 76svh; min-height: 22rem;
  aspect-ratio: auto; border-radius: var(--r);
  box-shadow: 0 -18px 50px rgba(11,11,12,.55), inset 0 0 0 1px var(--line);
  display: grid; place-items: stretch; }
.mo .k-stack, .mo .k-rotate { padding-bottom: 8vh; }
.mo .k-stack .pshot > img, .mo .k-rotate .pshot > img { height: 100%; }
.mo .k-stack .pshot, .mo .k-rotate .pshot { transform-origin: 50% 0%; }
.mo .k-stack .pshot, .mo .k-rotate .pshot { will-change: transform; }

/* ---- 3. tunnel ---------------------------------------------------
   Deeper perspective than the coverflow: these cards travel along Z
   rather than sitting on an arc, so the vanishing point has to be far
   enough back that the far end reads as distance and not as small. */
.mo .k-tunnel { display: block; position: relative;
  height: clamp(20rem, 58vh, 32rem); perspective: 1100px; }
.mo .k-tunnel .pshot { position: absolute; top: 0; left: 50%;
  width: min(78%, 32rem); height: 100%; margin-left: calc(min(78%, 32rem) / -2);
  aspect-ratio: auto; transform-style: preserve-3d;
  will-change: transform, opacity; }

/* ---- 6. dealt ----------------------------------------------------- */
.mo .k-dealt { display: block; position: relative;
  height: clamp(20rem, 58vh, 32rem); }
.mo .k-dealt .pshot { position: absolute; inset: 0; aspect-ratio: auto;
  transform-origin: 50% 100%;   /* pivots on the near edge, like a laid card */
  will-change: transform, opacity; }

/* ---- 4 + 5. coverflow -------------------------------------------- */
.mo .k-coverflow, .mo .k-inverted { display: block; position: relative;
  height: clamp(20rem, 58vh, 32rem); perspective: 1400px; }
.mo .k-coverflow .pshot, .mo .k-inverted .pshot {
  position: absolute; top: 0; left: 50%; width: min(74%, 30rem); height: 100%;
  margin-left: calc(min(74%, 30rem) / -2); aspect-ratio: auto;
  transform-style: preserve-3d; will-change: transform, opacity; }

/* ---- 7. deck ------------------------------------------------------ */
.mo .k-deck { display: block; position: relative;
  height: clamp(20rem, 58vh, 32rem); }
.mo .k-deck .pshot { position: absolute; inset: 0; aspect-ratio: auto;
  cursor: grab; will-change: transform, opacity; touch-action: pan-y; }
.mo .k-deck .pshot:active { cursor: grabbing; }

/* ---- 8. fade ------------------------------------------------------ */
.mo .k-fade { gap: var(--s6); }
@media (min-width: 760px) { .k-fade { grid-template-columns: repeat(2, 1fr); } }
.mo .k-fade .pshot { aspect-ratio: 4 / 3; }
.mo .k-fade .pshot { will-change: transform, opacity; }

/* ---- 9. clip wipe ------------------------------------------------- */
.mo .k-clip { display: block; position: relative;
  height: clamp(20rem, 60vh, 34rem); }
.mo .k-clip .pshot { position: absolute; inset: 0; aspect-ratio: auto;
  will-change: clip-path; }

/* ---- 10. parallax columns ----------------------------------------- */
.mo .k-parallax { grid-template-columns: 1fr; gap: var(--s4); }
/* .mo has to be on this one too. Without it the single-column rule above
   outranks it at every width, so the four columns this treatment is named
   for never appeared and the page ran a vertical offset down one column -
   which is the one thing the script says not to do. */
@media (min-width: 760px) { .mo .k-parallax { grid-template-columns: repeat(4, 1fr);
  align-items: start; } }
.mo .k-parallax .pshot { aspect-ratio: 3 / 4; }
.mo .k-parallax .pshot { will-change: transform; }

/* ---- scroll-driven treatments -------------------------------------
   The track is what the page scrolls through; the gallery pins inside
   it. Both are added by script, so with scripting off or under reduced
   motion the gallery is a plain grid and the page gains no extra
   scrolling for a mechanic that is not running. */
.ktrack { position: relative; }
.mo .pgal.is-pinned { position: sticky; top: 11vh; }
.mo .k-coverflow.is-pinned, .mo .k-inverted.is-pinned,
.mo .k-clip.is-pinned, .mo .k-deck.is-pinned,
.mo .k-tunnel.is-pinned, .mo .k-dealt.is-pinned { height: clamp(20rem, 62vh, 34rem); }

/* Position readout, not a control: the set advances on scroll now. */
.kdots { position: absolute; left: 0; right: 0; bottom: -1.9rem; z-index: 5;
  display: flex; gap: .45rem; justify-content: center; pointer-events: none; }
.kdots span { width: 22px; height: 2px; border-radius: 1px;
  background: rgba(242,237,230,.22);
  transition: background .35s var(--ease), transform .35s var(--ease); }
.kdots span[data-on="true"] { background: var(--accent); transform: scaleY(2); }

/* ---------------------------------------------------------------- map card */
.pmap { display: grid; gap: var(--s5); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 860px) { .pmap { grid-template-columns: 1.1fr .9fr; gap: var(--s7); } }
.pmap__stage { margin: 0; padding: var(--s4); border-radius: var(--r);
  background:
    radial-gradient(120% 90% at 78% 44%, rgba(217,94,34,.10), transparent 58%),
    linear-gradient(180deg, rgba(242,237,230,.035), rgba(242,237,230,.012));
  box-shadow: inset 0 0 0 1px var(--line); }
.pmap__svg { width: 100%; height: auto; overflow: visible; }
.pmap__land { fill: rgba(242,237,230,.05); stroke: rgba(242,237,230,.34);
  stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.pmap__rg { fill: rgba(217,94,34,.22); stroke: var(--accent); stroke-width: 1.6;
  vector-effect: non-scaling-stroke; }
.pmap__dot { fill: var(--accent); filter: drop-shadow(0 0 8px rgba(217,94,34,.9)); }
.pmap__ring { fill: none; stroke: var(--accent); stroke-width: 1.4; opacity: .5;
  vector-effect: non-scaling-stroke; }

/* ---------------------------------------------------------------- next */
.pnext { display: grid; gap: var(--s4); grid-template-columns: 1fr; }
@media (min-width: 700px) { .pnext { grid-template-columns: repeat(3, 1fr); } }
.pnext__c { display: block; text-decoration: none; color: var(--paper);
  background: var(--raise); border-radius: var(--r); overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line);
  transition: box-shadow .45s var(--ease); }
.pnext__c:hover { box-shadow: inset 0 0 0 1px rgba(242,237,230,.32); }
.pnext__im { aspect-ratio: 16 / 10; overflow: hidden; background: var(--surface); }
.pnext__im img { width: 100%; height: 100%; object-fit: cover;
  transition: transform .8s var(--ease); }
.pnext__c:hover .pnext__im img { transform: scale(1.06); }
.pnext__b { padding: var(--s3); }
.pnext__r { margin: 0 0 .25rem; font-size: .625rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .16em; color: var(--accent); }
.pnext__n { margin: 0; font-family: var(--serif); font-weight: 400; font-size: 1.25rem;
  line-height: 1.15; letter-spacing: -.02em; }

@media (prefers-reduced-motion: reduce) {
  /* place.js does not run any gallery grammar under reduce, so every
     hidden state declared above has to be undone here or the gallery
     never appears at all. One selector list, so adding an eleventh
     grammar cannot quietly leave it out. */
  .mo .k-stack .pshot, .mo .k-rotate .pshot, .mo .k-tunnel .pshot,
  .mo .k-coverflow .pshot, .mo .k-inverted .pshot, .mo .k-dealt .pshot,
  .mo .k-deck .pshot, .mo .k-fade .pshot, .mo .k-clip .pshot,
  .mo .k-parallax .pshot, .mo .k-fan .pshot {
    opacity: 1; transform: none; filter: none; clip-path: none;
    position: static; inset: auto; margin-left: 0; width: auto; height: auto; }
  /* the two that lay their cards on top of each other need the frame
     back as well, or four photographs render inside one box */
  .mo .k-tunnel, .mo .k-dealt, .mo .k-coverflow, .mo .k-inverted,
  .mo .k-clip, .mo .k-deck, .mo .k-fan {
    display: grid; height: auto; perspective: none; }
  .js .pgal .pshot img { transform: none; }
  .phero__img { height: 100%; }
}

/* Same press rhythm on the location pages. */
a, button, .pshot { touch-action: manipulation; }
:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }


/* ---- 11. fan ------------------------------------------------------
   Ganja's own. The set starts as one pile at the centre and spreads
   into an arc as you scroll, the way you would lay four photographs out
   on a table to look at them together. Nothing else on the site opens
   outward from a single point, which is the reason it is here.

   Gated on .mo with the rest: without the module layer this stays the
   plain grid the base rules describe. */
.mo .k-fan { display: block; position: relative;
  height: clamp(21rem, 62vh, 34rem); perspective: 1500px; }
/* Centred on both axes, because the second movement lays the cards out
   around that centre rather than up from the bottom edge. */
.mo .k-fan .pshot { position: absolute; top: 50%; left: 50%;
  width: min(46%, 19rem); height: 74%;
  margin-left: calc(min(46%, 19rem) / -2); margin-top: -37%;
  aspect-ratio: auto; transform-origin: 50% 118%; will-change: transform;
  box-shadow: 0 24px 60px rgba(11,11,12,.5), inset 0 0 0 1px var(--line); }
@media (max-width: 620px) {
  .mo .k-fan .pshot { width: min(66%, 16rem); margin-left: calc(min(66%, 16rem) / -2); }
}

/* ===================================================================
   TYPE SCALE, location pages
   Same pass as the home page. These labels were each set in their own
   rule at .6875rem or .625rem, which lands at 11px and 10px, and at
   w600 while every other label on the site is w500. On their own none
   of them looked wrong; together they were a second, quieter type
   system running underneath the first.
   =================================================================== */
.pback, .pfact dt, .pnext__r {
  font-family: var(--mono); font-weight: 500;
  font-size: var(--t-micro); letter-spacing: .1em; text-transform: uppercase; }
.pnext__r { letter-spacing: .09em; }

/* Prose on these pages reads at the same size as everywhere else. */
.plead__body p, .pfact dd {
  font-family: var(--sans); font-weight: 400;
  font-size: var(--t-body); line-height: 1.65;
  text-transform: none; letter-spacing: normal; }
.plead__body p:first-child { font-size: var(--t-lede); line-height: 1.55; }
.pshot figcaption { font-size: var(--t-small); letter-spacing: normal; }

/* Same superfamily wiring on the location pages. */
.phero__t, .pnext__n { font-variation-settings: "opsz" 96; }
.plead__body p, .pfact dd { font-variation-settings: "opsz" 14; }
