/* CloudTour homepage styles - v39
   Consolidated: everything that used to live in a <style> block in homepage.php
   now lives here. homepage.php sets most styling inline on the elements, and an
   inline style attribute beats a stylesheet rule, so many declarations below
   need !important to take effect. Leaflet's stylesheet is injected at runtime
   and lands after this file in the cascade, so its overrides need !important too. */

*{box-sizing:border-box}
html,body{margin:0;padding:0;background:#0a0b0d}
html{scroll-behavior:smooth;scroll-padding-top:84px}
a,button{-webkit-tap-highlight-color:transparent}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15);border-radius:8px;border:3px solid #0a0b0d}
::-webkit-scrollbar-track{background:#0a0b0d}
img{display:block;max-width:100%}
::selection{background:#E0B66B;color:#0a0b0d}
input,textarea{font-family:inherit}
.ct-rail{scrollbar-width:none;-ms-overflow-style:none}
.ct-rail::-webkit-scrollbar{display:none}
@keyframes ctrise{from{opacity:0;transform:translateY(13px)}to{opacity:1;transform:none}}
@keyframes ctdrift{0%{transform:scale(1.04) translate(0,0)}100%{transform:scale(1.1) translate(-1.4%,-1%)}}
@keyframes ctglow{0%,100%{opacity:.5}50%{opacity:.9}}
.ctbtn{transition:transform .25s ease,box-shadow .25s ease,background .25s ease!important}
.ctbtn:hover{transform:translateY(-3px)!important;
  box-shadow:0 0 0 1px rgba(255,255,255,.24),0 16px 38px rgba(0,0,0,.6)!important}
#contact input:focus,#contact textarea:focus{box-shadow:inset 0 0 0 2px var(--accent,#E0B66B)!important;background:rgba(255,255,255,.1)!important;outline:none}
.ctnav{transition:color .25s ease}
.ctnav:hover{color:var(--accent,#E0B66B)!important}
.ctget{transition:transform .25s ease,box-shadow .25s ease}
.ctget:hover{transform:translateY(-3px)!important;box-shadow:0 0 0 1px rgba(255,255,255,.24),0 16px 38px rgba(0,0,0,.6)!important}
/* Cards. The transition shorthand must name transform AND box-shadow: an
   earlier build redeclared it with box-shadow only, which silently killed the
   hover lift. */
.ctcard{background:#101218;transition:transform .55s cubic-bezier(.22,1,.36,1),box-shadow .55s ease}
.ctcard:hover,.ctcard:focus-visible{transform:translateY(-10px)!important;
  box-shadow:0 0 0 1px rgba(224,182,107,.34),0 42px 88px rgba(0,0,0,.62)!important}
.ctcard img{transition:transform 1.1s cubic-bezier(.22,1,.36,1),filter 1.1s ease;will-change:transform}
.ctcard:hover img,.ctcard:focus-visible img{transform:scale(1.04)!important;filter:brightness(1.05)!important}
/* The flagship banner is huge; a 10px lift reads as a lurch, so soften it. */
.ct-flag:hover,.ct-flag:focus-visible{transform:translateY(-4px)!important;
  box-shadow:0 0 0 1px rgba(224,182,107,.4),0 44px 110px rgba(0,0,0,.6)!important}
.ct-flag:hover img,.ct-flag:focus-visible img{transform:scale(1.028)!important}
/* A single slow diagonal highlight. 7.5% white over 1.2s reads as light crossing
   glass; any faster or brighter and it reads as a 2013 button. The banner already
   sets overflow:hidden inline, so the sweep clips to its rounded corners. */
.ct-flag::after{content:"";position:absolute;top:-12%;bottom:-12%;left:0;width:42%;
  z-index:4;pointer-events:none;opacity:0;
  background:linear-gradient(100deg,transparent 0%,rgba(255,255,255,.16) 48%,rgba(255,255,255,.05) 62%,transparent 100%);
  transform:translateX(-160%) skewX(-14deg);
  transition:opacity .2s ease}
.ct-flag:hover::after,.ct-flag:focus-visible::after{opacity:.15;
  transform:translateX(340%) skewX(-14deg);
  transition:transform 1s cubic-bezier(.32,.9,.4,1),opacity .25s ease}
@media (max-width:820px){
.ct-stack{grid-template-columns:1fr!important;gap:26px!important}
.ct-navget{display:none!important}
/* Mobile dropdown sheet — always laid out (position:fixed) but hidden until .ct-open, so it can fade/slide in */
.ct-navlinks{display:flex!important;flex-direction:column;align-items:stretch!important;gap:3px!important;position:fixed;top:64px;left:0;right:0;z-index:95;padding:10px 14px 16px;background:rgba(12,13,16,.96);backdrop-filter:blur(22px) saturate(1.1);-webkit-backdrop-filter:blur(22px) saturate(1.1);border-bottom:1px solid rgba(255,255,255,.08);box-shadow:0 26px 50px -12px rgba(0,0,0,.6);opacity:0;visibility:hidden;transform:translateY(-10px);pointer-events:none;transition:opacity .26s ease,transform .3s cubic-bezier(.22,1,.36,1),visibility .3s}
.ct-navlinks.ct-open{opacity:1;visibility:visible;transform:none;pointer-events:auto}
.ct-navlinks a{display:flex!important;align-items:center;width:100%;padding:12px 14px!important;font-size:15px!important;font-weight:500!important;letter-spacing:-.01em;color:rgba(255,255,255,.82)!important;text-decoration:none!important;border-radius:12px;transition:background .2s ease,color .2s ease}
.ct-navlinks a:hover,.ct-navlinks a:active{background:rgba(255,255,255,.06)!important;color:#fff!important}
.ct-navlinks .ct-menuget{justify-content:center;gap:8px;margin-top:9px;padding:14px!important;font-size:14.5px!important;font-weight:700!important;color:#0a0b0d!important;background:var(--accent,#E0B66B)!important;border-radius:999px;box-shadow:0 12px 28px rgba(224,182,107,.26);transition:transform .25s cubic-bezier(.22,1,.36,1),background .25s ease}
.ct-navlinks .ct-menuget:hover,.ct-navlinks .ct-menuget:active{color:#0a0b0d!important;background:#e9c585!important;transform:translateY(-1px)}
.ct-burger{display:inline-flex!important}
nav{padding-left:22px!important;padding-right:22px!important}
#contact .ct-stack>div{position:static!important}
}

/* social icon hover (footer) */
footer a[aria-label]:hover{background:rgba(255,255,255,.07)!important;color:#fff!important;box-shadow:0 0 0 1px rgba(255,255,255,.6)!important}
/* contact input/textarea hover */
#contact input:hover,#contact textarea:hover{box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.34)}
/* ===================================================================
   Brand lockup — pixel-matched to the tour splash (#intro-screen .brand)
   =================================================================== */
.ct-brand{display:flex;align-items:center;gap:12px}
.ct-logo{display:flex;align-items:center;gap:9px;text-decoration:none;color:inherit}
.ct-logo__mark{height:18.5px;width:auto;display:block;flex:none}
.ct-logo__wm{font-size:19px;letter-spacing:-.022em;line-height:1;white-space:nowrap}
.ct-brand__beta{font-size:7px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#fff;padding:3px 4px 3px 7px;border-radius:6px;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.26)}

/* Reveal-on-scroll: hide the pre-animation baseline ONLY when JS is active, so
   content never stays invisible if JS fails — and never "pops" (flash to 0). */
.ct-js [data-reveal]:not([data-shown]){opacity:0}
/* Mobile: tighter side margins (matches tour --mx:18px) + splash logo sizing */
@media (max-width:600px){
.ct-logo__mark{height:17px!important}
.ct-logo__wm{font-size:17px!important}
.ct-brand__beta{display:none!important}
.ct-sec{padding-left:18px!important;padding-right:18px!important}
.ct-railpad{padding-left:18px!important;padding-right:18px!important}
.ct-hero{padding-left:18px!important;padding-right:18px!important}
.ct-social{width:100%!important;justify-content:center!important}
}

/* Skip-to-content link — visible only on keyboard focus */
.ct-skip{position:absolute;left:-9999px;top:8px;z-index:1100;background:var(--accent,#E0B66B);color:#0a0b0d;padding:10px 16px;border-radius:10px;font-weight:600;font-size:14px;text-decoration:none}
.ct-skip:focus{left:8px}


/* ==================== homepage components ==================== */
/* Client logos. White/greyscale on transparent, so grayscale() does nothing and
   there is no colour to reveal on hover: opacity and brightness do the work.

   Sizing is chosen against the 101px-tall source PNGs. At 50px the logo renders
   at 100 device px on a retina screen (native) and takes a clean 2x downscale on
   a standard one. 42px meant a 2.4x downscale, which resamples badly and is what
   made them look ragged. Cells are wide enough that broad wordmarks (MSDS, the
   British Museum) are limited by height rather than width, so they scale by the
   same factor as everything else. */
.ct-logos{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(20px,2.6vw,28px) 16px}
.ct-partner{display:grid;place-items:center;flex:0 1 168px;height:74px;padding:6px;
  text-decoration:none;border-radius:12px;opacity:.4;
  transition:opacity .35s ease,filter .35s ease,transform .35s cubic-bezier(.22,1,.36,1)}
.ct-partner:hover,.ct-partner:focus-visible{opacity:1;filter:brightness(1.12);transform:translateY(-2px);outline:none}
.ct-partner:focus-visible{box-shadow:0 0 0 2px var(--accent,#E0B66B)}
/* Focus dim: hovering one logo quiets the rest. Pointer-fine only, since a touch
   device has no hover and would leave the wall permanently dimmed. */
@supports selector(:has(*)){
  @media (hover:hover) and (pointer:fine){
    .ct-logos:has(.ct-partner:hover) .ct-partner:not(:hover){opacity:.28}
    .ct-logos:has(.ct-partner:hover) .ct-partner{transition-duration:.4s}
    /* keyboard equivalent, scoped to :focus-visible so a mouse click never dims */
    .ct-logos:has(.ct-partner:focus-visible) .ct-partner:not(:focus-visible){opacity:.28}
  }
}

.ct-partner img{max-height:50px;max-width:100%;width:auto;height:auto;object-fit:contain;display:block}
.ct-partner__wm{font-size:15px;font-weight:600;color:rgba(255,255,255,.75);text-align:center;line-height:1.2}
/* --- mobile polish for the new sections ---
   NOTE: this page sets its styles inline, and inline styles beat stylesheet
   rules, so these overrides need !important to actually take effect. --- */
@media (max-width:600px){
  /* side padding comes from .ct-sec (18px); only the vertical rhythm changes here */
  #partners{padding-top:clamp(52px,13vw,106px)!important;padding-bottom:clamp(52px,13vw,106px)!important}
}
/* Keep the Turnstile widget (min 300px wide) from overflowing narrow phones */
@media (max-width:380px){
  #ctform .cf-turnstile{transform:scale(.94);transform-origin:left center}
}
@media (max-width:340px){
  #ctform .cf-turnstile{transform:scale(.82);transform-origin:left center}
}
/* --- Flagship banner: the wide 16/7 crop and side-lit scrim only suit desktop.
       Narrower screens get a taller crop, a bottom-lit scrim and smaller type. --- */
@media (max-width:900px){
  .ct-flag{aspect-ratio:3/2!important;min-height:0!important}
  .ct-flag__scrim{background:linear-gradient(180deg,rgba(8,9,11,.18) 0%,rgba(8,9,11,.36) 42%,rgba(8,9,11,.95) 100%)!important}
  .ct-flag__body{max-width:none!important;right:0!important}
}
@media (max-width:640px){
  .ct-flag{aspect-ratio:4/5!important}
  .ct-flag__body{padding:20px 18px 24px!important}
  .ct-flag__body h3{font-size:clamp(26px,7.6vw,40px)!important}
  .ct-flag__body p{font-size:14px!important;max-width:none!important;margin-top:10px!important}
  .ct-flag__eyebrow{font-size:10.5px!important;letter-spacing:.16em!important}
  .ct-flag__badge{top:15px!important;left:15px!important;font-size:9.5px!important;padding:6px 10px!important}
}
@media (max-width:400px){
  .ct-flag{aspect-ratio:3/4!important}
}
/* --- Gaussian splatting strip: stack the copy above the video --- */
/* The copy column is tall (heading + paragraph + four ticks); at 1.12fr the
   video barely outweighs it and reads as undersized. Give it real width. */
@media (min-width:901px){
  #splatting .ct-stack{grid-template-columns:1fr 1.38fr!important;gap:clamp(40px,4.5vw,68px)!important;align-items:center!important}
}
@media (max-width:900px){
  #splatting .ct-stack{grid-template-columns:1fr!important;gap:34px!important}
}
@media (max-width:600px){
  #splatting p{font-size:15px!important}
}
/* --- Featured tours: tighter gutters and heading on phones --- */
/* --- global polish: applies on mobile and desktop --- */
html{scroll-behavior:smooth;scroll-padding-top:84px}
a,button{-webkit-tap-highlight-color:transparent}
::selection{background:rgba(224,182,107,.28);color:#fff}
a:focus-visible,button:focus-visible,[data-cursor="hover"]:focus-visible{outline:2px solid var(--accent,#E0B66B);outline-offset:3px}
img,video{max-width:100%}
/* Only disable on genuine touch devices, not touchscreen laptops */
@media (hover:none) and (pointer:coarse){
  .ctcard:hover img,.ct-flag:hover img{transform:none!important;filter:none!important}
}
/* --- Project map: slim strip under the tours rail, expands on tap.
   Leaflet's stylesheet is injected at runtime so it lands after this block in
   the cascade. Overrides are scoped to .ct-popup (higher specificity) or use
   !important where Leaflet targets bare elements. --- */
#ctmap-strip{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:18px;
  padding:16px 18px 16px 20px;border-radius:16px;
  background:rgba(255,255,255,.03);box-shadow:0 0 0 1px rgba(255,255,255,.1)}
.ctmap-strip__copy{display:flex;align-items:center;gap:14px;min-width:0;flex:1 1 340px}
.ctmap-strip__copy p{margin:0;font-size:14.5px;line-height:1.5;color:rgba(255,255,255,.62)}

/* Button: plain white pill, same as the other CTAs */
.ct-mapbtn{display:inline-flex;align-items:center;gap:9px;flex-shrink:0;
  font-family:inherit;font-size:13.5px;font-weight:600;color:#0a0b0d;background:#fff;
  padding:12px 20px;border:0;border-radius:999px;cursor:pointer;
  transition:transform .3s cubic-bezier(.22,1,.36,1),box-shadow .3s ease}
.ct-mapbtn:hover{transform:translateY(-1px);box-shadow:0 10px 26px rgba(0,0,0,.4)}
.ct-mapbtn:active{transform:translateY(0)}
.ct-mapbtn:focus-visible{outline:2px solid var(--accent,#E0B66B);outline-offset:3px}
.ct-mapbtn__chev{transition:transform .45s cubic-bezier(.22,1,.36,1)}
.ct-mapbtn[aria-expanded="true"] .ct-mapbtn__chev{transform:rotate(180deg)}

/* The shell animates height only. The 14px gap under the strip lives on the
   inner frame, so it is revealed and hidden with the map and never collapses
   separately during the close animation. */
#ctmap-shell{height:0;overflow:hidden;transition:height .62s cubic-bezier(.22,1,.36,1)}
#ctmap-shell.is-open{height:calc(clamp(320px,46vh,480px) + 14px)}
#ctmap-frame{position:relative;height:calc(100% - 14px);margin-top:14px;
  border-radius:16px;overflow:hidden;background:#0a0b0d;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.1)}
#ctmap{width:100%;height:100%;opacity:0;transition:opacity .5s ease}
#ctmap.is-ready{opacity:1}
#ctmap-frame .ctmap-loading{position:absolute;inset:0;display:grid;place-items:center;
  font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.35)}

.leaflet-container{background:#0a0b0d!important;font-family:inherit!important;outline:none!important}

/* Marker: a gold pin that lifts on hover */
.ct-marker{position:relative;display:grid;place-items:center;width:28px;height:28px;border-radius:50%;
  background:var(--accent,#E0B66B);color:#0a0b0d;
  box-shadow:0 0 0 1px rgba(255,255,255,.2),0 0 0 4px rgba(224,182,107,.16),0 6px 16px rgba(0,0,0,.6);
  transition:transform .28s cubic-bezier(.22,1,.36,1),box-shadow .28s ease}
.ct-marker:hover{transform:translateY(-2px) scale(1.1);
  box-shadow:0 0 0 1px rgba(255,255,255,.3),0 0 0 6px rgba(224,182,107,.22),0 10px 22px rgba(0,0,0,.7)}

/* Popup: dark glass card, gold hairline, white pill CTA */
/* No backdrop-filter here: inside Leaflet's translate3d popup it makes Chrome
   paint a square backdrop and the rounded corners break. */
.ct-popup .leaflet-popup-content-wrapper{background:#0e1014!important;color:#fff!important;
  border-radius:16px!important;padding:0!important;overflow:hidden!important;
  box-shadow:0 0 0 1px rgba(255,255,255,.12),0 26px 60px rgba(0,0,0,.65)!important}
.ct-popup .leaflet-popup-content{margin:0!important;padding:18px 20px!important;min-width:224px;width:auto!important;
  font-size:14px!important;line-height:1.5!important}
.ct-popup .leaflet-popup-tip{background:#0e1014!important;box-shadow:none!important;border:0!important}
.ct-popup .leaflet-popup-tip-container{margin-top:-1px}
.ct-pop__eyebrow{display:block;font-size:10px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;
  color:var(--accent,#E0B66B);margin-bottom:9px;padding-right:34px;white-space:nowrap}
.ct-pop__title{display:block;font-size:16px;font-weight:600;letter-spacing:-.01em;color:#fff;
  line-height:1.25;margin:0 0 14px;padding-right:0}
.ct-popup .ct-pop__cta{display:inline-flex;align-items:center;gap:8px;white-space:nowrap;
  font-size:12.5px!important;font-weight:600!important;color:#0a0b0d!important;background:#fff;
  padding:9px 15px;border-radius:999px;text-decoration:none!important;
  transition:transform .25s cubic-bezier(.22,1,.36,1),box-shadow .25s ease}
.ct-popup .ct-pop__cta:hover{transform:translateY(-1px);box-shadow:0 8px 20px rgba(0,0,0,.5)}
.ct-popup .ct-pop__alt{display:inline-block;margin-top:10px;font-size:12.5px!important;font-weight:600!important;
  color:var(--accent,#E0B66B)!important;text-decoration:none!important;
  border-bottom:1px solid rgba(224,182,107,.3);padding-bottom:1px}
.ct-popup .ct-pop__alt:hover{border-bottom-color:var(--accent,#E0B66B)}

/* Close button. Leaflet's own rule (.leaflet-container a.leaflet-popup-close-button)
   outranks a plain .ct-popup selector, and its font metrics push the glyph off
   centre, so hide the glyph and draw the cross with pseudo-elements. */
.ct-popup .leaflet-popup-close-button{position:absolute!important;top:12px!important;right:12px!important;
  width:24px!important;height:24px!important;padding:0!important;margin:0!important;
  border-radius:50%!important;background:rgba(255,255,255,.08)!important;
  box-shadow:0 0 0 1px rgba(255,255,255,.08);
  font-size:0!important;line-height:0!important;text-indent:-9999px!important;
  transition:background .2s ease}
.ct-popup .leaflet-popup-close-button span{display:none!important}
/* One masked SVG rather than two rotated 1.5px bars: half-pixel heights round
   differently on each arm, which is what made the cross look lopsided. */
.ct-popup .leaflet-popup-close-button::before{content:'';position:absolute;inset:0;margin:auto;
  width:10px;height:10px;background:rgba(255,255,255,.62);transition:background .2s ease;
  -webkit-mask:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cg stroke='%23000' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M1.4 1.4 8.6 8.6'/%3E%3Cpath d='M8.6 1.4 1.4 8.6'/%3E%3C/g%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cg stroke='%23000' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M1.4 1.4 8.6 8.6'/%3E%3Cpath d='M8.6 1.4 1.4 8.6'/%3E%3C/g%3E%3C/svg%3E") center/contain no-repeat}
.ct-popup .leaflet-popup-close-button:hover{background:rgba(255,255,255,.16)!important}
.ct-popup .leaflet-popup-close-button:hover::before{background:#fff}

/* Zoom + attribution */
.leaflet-bar{border:0!important;box-shadow:0 0 0 1px rgba(255,255,255,.12),0 8px 20px rgba(0,0,0,.5)!important;
  border-radius:10px!important;overflow:hidden}
.leaflet-bar a{background:#15171b!important;color:rgba(255,255,255,.8)!important;
  border-color:rgba(255,255,255,.1)!important;width:32px!important;height:32px!important;line-height:32px!important}
.leaflet-bar a:hover{background:#1e2128!important;color:#fff!important}
.leaflet-control-attribution{background:rgba(10,11,13,.72)!important;color:rgba(255,255,255,.38)!important;
  font-size:10px!important;padding:2px 7px!important;border-radius:6px 0 0 0!important}
.leaflet-control-attribution a{color:rgba(255,255,255,.6)!important}

/* Stack the strip well before the copy and button start fighting for room */
@media (max-width:760px){
  #ctmap-strip{flex-direction:column;align-items:stretch;gap:16px;padding:18px}
  .ctmap-strip__copy{flex:1 1 auto}
  #ctmap-toggle{width:100%!important;justify-content:center!important}
}
@media (max-width:600px){
  #ctmap-strip{padding:16px}
  .ctmap-strip__copy p{font-size:14px}
  #ctmap-shell.is-open{height:calc(clamp(300px,56vh,420px) + 14px)}
}
@media (max-width:420px){
  .ctmap-strip__copy{gap:11px}
  .ct-popup .leaflet-popup-content{min-width:190px;padding:15px 16px!important}
  .ct-pop__eyebrow{white-space:normal;padding-right:30px}
  .ct-pop__title{font-size:15px!important}
}
/* svh does not jump when a mobile browser hides its URL bar, so the shell
   height stays put instead of animating every time the bar collapses. */
@supports (height:1svh){
  #ctmap-shell.is-open{height:calc(clamp(320px,46svh,480px) + 14px)}
  @media (max-width:600px){
    #ctmap-shell.is-open{height:calc(clamp(300px,52svh,420px) + 14px)}
  }
}
/* Touch: bigger hit areas without moving the pin or its map anchor */
@media (pointer:coarse){
  .ct-marker::after{content:'';position:absolute;inset:-8px;border-radius:50%}
  .leaflet-bar a{width:38px!important;height:38px!important;line-height:38px!important}
  .ct-popup .ct-pop__cta{padding:11px 17px}
  .ct-popup .leaflet-popup-close-button{width:28px!important;height:28px!important}
}

/* --- Kinetic rail. Native snap fights momentum, so it is switched off and the
   easing is driven in JS. scroll-snap-align is set inline on each card, and a
   stylesheet !important beats an inline declaration. --- */
#tours .ct-rail{scroll-snap-type:none!important;scroll-behavior:auto!important;
  overscroll-behavior-x:contain;will-change:transform}
#tours .ct-rail>*{scroll-snap-align:none!important}
#tours .ct-rail.is-dragging{cursor:grabbing!important}
#tours .ct-rail.is-dragging *{cursor:grabbing!important}
/* --- Video facade. A raw YouTube iframe paints its own title bar, avatar,
   share buttons and red play button over the page, and none of it is styleable.
   So we show our own poster and only load the player on click. --- */
.ct-video{position:relative;aspect-ratio:16/9;border-radius:16px;overflow:hidden;
  background:#0a0b0d;box-shadow:0 0 0 1px rgba(255,255,255,.1);
  transition:box-shadow .4s ease}
.ct-video:hover{box-shadow:0 0 0 1px rgba(224,182,107,.34),0 24px 60px rgba(0,0,0,.5)}
/* The hero and splat frames set box-shadow inline, which outranks the rule above */
.ct-video--hero:hover{box-shadow:0 0 0 1px rgba(224,182,107,.34),0 50px 120px rgba(0,0,0,.6)!important}
.ct-video__btn{position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;
  background:none;cursor:pointer;display:block}
.ct-video__btn:focus-visible{outline:2px solid var(--accent,#E0B66B);outline-offset:-3px;border-radius:16px}
.ct-video__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  will-change:transform;
  /* 1.04 over 1.1s moves the frame edge at ~12px/sec, below the threshold where
     the eye reads it as motion at all. The tour cards get away with those values
     because they are small and busy; a 645px poster of open sky does not. */
  transition:transform .8s cubic-bezier(.22,1,.36,1),filter .8s ease}
/* The poster is now a DIRECT child of .ct-video, mirroring `.ctcard > img`
   exactly. It used to sit inside the <button>, which is the only structural
   difference from the tour cards, where this zoom has always worked. */
.ct-video:hover .ct-video__img,
.ct-video.is-hover .ct-video__img,
.ct-video:focus-within .ct-video__img{transform:scale(1.065)!important;filter:brightness(1.06)!important}
.ct-video__scrim{position:absolute;inset:0;pointer-events:none;
  transition:opacity .8s ease;
  background:radial-gradient(52% 52% at 50% 50%, rgba(8,9,11,.42), transparent 72%),
             linear-gradient(180deg, rgba(8,9,11,.28) 0%, transparent 34%, rgba(8,9,11,.5) 100%)}
/* Lift the scrim on hover. It darkens the centre and both edges, which is
   precisely where the zoom motion lives, so it was masking the effect. */
.ct-video:hover .ct-video__scrim,
.ct-video.is-hover .ct-video__scrim,
.ct-video:focus-within .ct-video__scrim{opacity:.78}
/* Centred with inset+margin rather than translate(-50%,-50%): the poster's
   aspect-ratio height often lands on a half pixel, and translating onto that
   half pixel is what made the circle's edge look soft. No translucent white
   ring either, which was haloing into the image. */
.ct-video__play{position:absolute;inset:0;margin:auto;
  display:grid;place-items:center;width:66px;height:66px;border-radius:50%;
  background:#fff;color:#0a0b0d;
  box-shadow:0 12px 32px rgba(0,0,0,.5),0 2px 6px rgba(0,0,0,.3);
  transition:transform .35s cubic-bezier(.22,1,.36,1),background .3s ease}
/* Icon scales with whatever size the circle is, and its path centroid is the
   centre of the viewBox, so no nudge is needed. */
.ct-video__play svg{width:40%;height:40%;display:block}
.ct-video:hover .ct-video__play,
.ct-video.is-hover .ct-video__play,
.ct-video:focus-within .ct-video__play{transform:scale(1.08)}
.ct-video__btn:active .ct-video__play{transform:scale(.97)}
.ct-video iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.ct-video--hero .ct-video__play{width:80px;height:80px}
.ct-video--hero .ct-video__btn:focus-visible{border-radius:20px}
@media (max-width:600px){
  .ct-video__play{width:56px;height:56px}
  .ct-video--hero .ct-video__play{width:64px;height:64px}
}
/* ---- Consistent mobile type + rhythm across every section.
   Section headings previously ranged from 26px to 30px on a phone depending on
   which one-off override happened to apply. One rule now governs them all. ---- */
@media (max-width:600px){
  .ct-sec h2,#tours h2{font-size:clamp(27px,7.6vw,42px)!important;letter-spacing:-.025em!important}
  .ct-sec p,#tours p{text-wrap:pretty}
  .ct-video__btn{border-radius:14px}
  #watch .ct-stack{gap:22px!important}
  .ct-logos{gap:18px 14px}
  .ct-partner{flex:0 1 132px;height:62px;padding:4px}
  .ct-partner img{max-height:34px}
  #partners .ct-partner__wm{font-size:15px!important}
}
@media (max-width:470px){
  .ct-sec h2,#tours h2{font-size:clamp(25px,8vw,34px)!important}
  .ct-logos{gap:16px 12px}
  .ct-partner{flex:0 1 100px;height:54px;padding:3px}
  .ct-partner img{max-height:30px}
}
/* Touch: no hover state, so show the logos brighter at rest */
@media (hover:none) and (pointer:coarse){
  .ct-partner{opacity:.55}
  .ct-partner:hover{transform:none}
}
/* --- Oversized embed. YouTube's adaptive bitrate picks a stream from the
   player's CSS width, ignoring device pixel ratio. A 645px player therefore
   gets 480p even on a retina screen. Rendering the iframe at its real 1280x720
   and scaling it down makes YouTube serve 720p, which the browser then
   downsamples into the box. Nothing is obscured, so the embed stays intact.
   The scale factor is set from JS; this is the no-JS fallback. --- */
.ct-embed{position:relative}
.ct-embed__frame{position:absolute;top:0;left:0;width:100%;height:100%;border:0;
  transform-origin:0 0}
.ct-embed.is-scaled .ct-embed__frame{width:var(--ct-embed-w,1280px);height:var(--ct-embed-h,720px);
  transform:scale(var(--ct-embed-s,1))}

/* --- Scroll progress hairline. Sits above the fixed header. --- */
.ct-progress{position:fixed;top:0;left:0;right:0;height:2px;z-index:300;pointer-events:none}
.ct-progress span{display:block;height:100%;transform:scaleX(0);transform-origin:0 50%;
  will-change:transform;
  background:linear-gradient(90deg,rgba(224,182,107,.3),var(--accent,#E0B66B))}

/* ============================================================================
   MOBILE PASS
   ========================================================================= */

/* iOS inflates text in landscape without this. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}

/* The decorative radial blobs are sized max-width:120vw and centred with
   translate(-50%), so they hang ~10vw past each edge and push the page sideways.
   clip (not hidden) because hidden on <body> breaks position:sticky. */
body{overflow-x:clip}
@supports not (overflow:clip){body{overflow-x:hidden}}

/* iOS Safari zooms the entire page when a focused field is under 16px.
   The fields are 14.5px inline, so this needs !important to win. */
@media (max-width:600px){
  #contact input,#contact textarea,#contact select{font-size:16px!important}
}

/* Sticky :hover. On a touch screen a tap applies :hover and leaves it applied
   until the next tap elsewhere, so every hover effect freezes mid-state:
   a poster stays zoomed, the banner keeps a half-finished sheen across it. */
@media (hover:none){
  .ct-flag::after{display:none!important}
  .ctcard:hover,.ctcard:focus-visible,.ct-flag:hover,.ct-flag:focus-visible{transform:none!important}
  .ctbtn:hover{transform:none!important}
  .ct-video:hover .ct-video__img,
  .ct-video.is-hover .ct-video__img,
  .ct-video:focus-within .ct-video__img{transform:none!important;filter:none!important}
  .ct-video:hover .ct-video__scrim,
  .ct-video:focus-within .ct-video__scrim{opacity:1!important}
  .ct-video:hover .ct-video__play,
  .ct-video:focus-within .ct-video__play{transform:none!important}
  .ct-video--hero:hover{box-shadow:0 0 0 1px rgba(255,255,255,.1),0 50px 120px rgba(0,0,0,.6)!important}
}

/* The scaled iframe is 854px wide internally; keep it from escaping its box. */
.ct-embed{overflow:hidden}

/* Apple's minimum comfortable tap target is 44px; the social circles are 40. */
@media (pointer:coarse){
  footer a[aria-label]{width:44px!important;height:44px!important}
}

/* vh includes the mobile URL bar, so the map jumps when it hides. */
@media (max-width:600px){
  @supports (height:1svh){
    #ctmap-shell.is-open{height:calc(clamp(300px,56svh,420px) + 14px)}
  }
}

/* Below 360px the logo wall drops to 2 across, which is 9 rows of scrolling. */
@media (max-width:360px){
  .ct-logos{gap:14px 10px}
  .ct-partner{flex:0 1 88px;height:48px;padding:2px}
  .ct-partner img{max-height:28px}
}

/* Legacy iOS momentum scrolling on the tour rail. */
#tours .ct-rail{-webkit-overflow-scrolling:touch}

/* The Mobile Museum stack collapses to one column below 820px, putting the
   phone directly under the "Meet Mobile Museum" button with only the stack's
   26px gap between them. The frame is a hard edge with a bright 1px ring, so it
   reads tighter than it measures. */
@media (max-width:820px){
  #app{margin-top:28px}
}
@media (max-width:480px){
  #app{margin-top:22px}
}

/* Map reset control. Leaflet's stylesheet is injected at runtime, landing after
   this file, so its .leaflet-control rules outrank ours without !important. */
.leaflet-control .ctmap-reset,
button.ctmap-reset{
  display:block;border:1px solid rgba(255,255,255,.16)!important;
  background:rgba(12,13,16,.86);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  color:rgba(255,255,255,.82);
  font-family:inherit;font-weight:600;font-size:12px;line-height:1;letter-spacing:.02em;
  padding:9px 14px;border-radius:999px;cursor:pointer;
  box-shadow:0 10px 26px rgba(0,0,0,.45);
  transition:background .25s ease,color .25s ease,border-color .25s ease}
.leaflet-control .ctmap-reset:hover,
button.ctmap-reset:hover{
  background:rgba(224,182,107,.16);
  border-color:rgba(224,182,107,.5)!important;
  color:#fff}

@media (max-width:600px){
  .leaflet-control .ctmap-reset,
  button.ctmap-reset{padding:8px 12px;font-size:11.5px}
}

/* The reset pill sits at ~34px, under the 44px touch minimum. */
@media (pointer:coarse){
  .leaflet-control .ctmap-reset,
  button.ctmap-reset{min-height:44px;padding:0 14px}
}
