/* ═══════════════════════════════════════════════════════════════
   GOLDFINGER · header common law · one file, every forum
   ───────────────────────────────────────────────────────────────
   Canonical copy lives at 00_canonical/. Each site root holds a
   byte-identical copy. Never edit a site copy: edit here and
   redistribute, or the six rooms drift apart again.

   The estate grew four header naming patterns before this file
   existed. BILS, AIO and gbxcircle use .gbx-header / .gbx-mark /
   .gbx-key / .gbx-cta. CGTI and DDIF use .hdr / .hdr-mark /
   .hdr-key / .hdr-cta. MEVO uses .hdr-cta with .key-glyph. SCLI
   uses .hdr with .mark / .lx-key-eye / .hcta. Rather than rewrite
   four sites' markup, this file binds the one choreography to all
   four sets of hooks.

   Requires: goldfinger-tokens.css for --gold, --gold-hover, --ease
   Pairs with: goldfinger-header-common.js which drives the classes
   ═══════════════════════════════════════════════════════════════ */

/* ── 1 · the CTA carries no underline ────────────────────────────
   .gbx-cta never set text-decoration. The component only reset it
   on .gbx-nav a, so the browser default underlined every "request
   access" link on BILS, CGTI, DDIF, MEVO and SCLI. AIO and
   gbxcircle had it right, which is why it read as a per-site quirk
   rather than a missing line in the shared component.
   !important is deliberate here and in section 2: this file has to
   win over seven sites of legacy page CSS whose load order varies. */
.gbx-cta, .gbx-cta:link, .gbx-cta:visited, .gbx-cta:hover, .gbx-cta:focus,
.hdr-cta, .hdr-cta:link, .hdr-cta:visited, .hdr-cta:hover, .hdr-cta:focus,
.hcta,    .hcta:link,    .hcta:visited,    .hcta:hover,    .hcta:focus,
.gbx-cta a, .hdr-cta a, .hcta a {
  text-decoration: none !important;
  border-bottom: 0 !important;
}

/* ── 2 · no hairline under the header ────────────────────────────
   The full-width rule under the header read as a seam between the
   header and the room rather than as structure. The header now
   separates by ground and by blur on scroll, which is quieter and
   holds at every width. Hairlines elsewhere on the page are
   untouched: this removes the header's own bottom edge only. */
header.gbx-header, header.hdr, .gbx-header, .hdr,
header.gbx-header.gbx-scrolled, header.hdr.scrolled,
.gbx-header.gbx-scrolled, .hdr.scrolled,
.gbx-header[data-mode="light"], .hdr[data-mode="light"] {
  border-bottom: 0 !important;
}

/* ═══ 3 · MOTION ═══ choreography: load -> ambient -> arrival -> hover -> idle
   Timing is the BILS index reference: eye blink 6s, key turn 6s
   offset 3.6s, load 1.2s. Every forum now runs the same clock. */

.gbx-mark svg, .gbx-mark img,
.hdr-mark svg, .hdr-mark img,
.hdr .mark img, .hdr-brand svg, .hdr-brand img {
  transform-origin: 50% 50%;
  will-change: transform, opacity;
}
.gbx-key, .hdr-key, .key-glyph, .lx-key-eye,
.gbx-cta svg, .hdr-cta svg, .hcta svg {
  transform-origin: 50% 27%;
  will-change: transform;
}
.gbx-key .pupil, .hdr-key .pupil, .key-glyph .pupil {
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes gbxOpen      { from{opacity:0;transform:scale(.5) rotate(-14deg)} to{opacity:1;transform:none} }
@keyframes gbxKeyLoad   { 0%{transform:rotate(0);opacity:1} 42%{transform:rotate(90deg);opacity:0} 60%{transform:rotate(0);opacity:0} 100%{transform:rotate(0);opacity:1} }
@keyframes gbxBlink     { 0%,92%,100%{transform:scaleY(1)} 96%{transform:scaleY(.06)} }
@keyframes gbxBlinkSlow { 0%,90%,100%{transform:scaleY(1)} 95%{transform:scaleY(.06)} }
@keyframes gbxKeyTurn   { 0%,84%,100%{transform:rotate(0)} 92%{transform:rotate(90deg)} }
@keyframes gbxKeyPupil  { 0%,100%{opacity:1} 50%{opacity:.32} }
@keyframes gbxPop       { 0%{transform:scale(1)} 45%{transform:scale(1.14)} 100%{transform:scale(1)} }
@keyframes gbxUnlock    { 0%{transform:rotate(0)} 40%{transform:rotate(-16deg)} 100%{transform:rotate(0)} }

@media (prefers-reduced-motion: no-preference) {

  /* page load · "you are admitted" */
  html.gbx-booting .gbx-mark svg,  html.gbx-booting .gbx-mark img,
  html.gbx-booting .hdr-mark svg,  html.gbx-booting .hdr-mark img,
  html.gbx-booting .hdr .mark img, html.gbx-booting .hdr-brand svg {
    animation: gbxOpen .9s var(--ease, cubic-bezier(.2,.7,.2,1)) both;
  }
  html.gbx-booting .gbx-key, html.gbx-booting .hdr-key,
  html.gbx-booting .key-glyph, html.gbx-booting .lx-key-eye {
    animation: gbxKeyLoad 1.2s var(--ease, cubic-bezier(.2,.7,.2,1)) both;
  }

  /* ambient · "we are present" · the key never stops */
  html.gbx-ambient .gbx-mark svg,  html.gbx-ambient .gbx-mark img,
  html.gbx-ambient .hdr-mark svg,  html.gbx-ambient .hdr-mark img,
  html.gbx-ambient .hdr .mark img, html.gbx-ambient .hdr-brand svg {
    animation: gbxBlink 6s ease-in-out infinite;
  }
  html.gbx-ambient .gbx-key, html.gbx-ambient .hdr-key,
  html.gbx-ambient .key-glyph, html.gbx-ambient .lx-key-eye {
    animation: gbxKeyTurn 6s var(--ease, cubic-bezier(.2,.7,.2,1)) infinite;
    animation-delay: -3.6s;
  }
  html.gbx-ambient .gbx-key .pupil, html.gbx-ambient .hdr-key .pupil,
  html.gbx-ambient .key-glyph .pupil {
    animation: gbxKeyPupil 3.6s ease-in-out infinite;
  }

  /* idle 10s · "waiting, unhurried" · the eye slows, the key does not */
  html.gbx-ambient.gbx-idle .gbx-mark svg,  html.gbx-ambient.gbx-idle .gbx-mark img,
  html.gbx-ambient.gbx-idle .hdr-mark svg,  html.gbx-ambient.gbx-idle .hdr-mark img,
  html.gbx-ambient.gbx-idle .hdr .mark img, html.gbx-ambient.gbx-idle .hdr-brand svg {
    animation: gbxBlinkSlow 9s ease-in-out infinite;
  }

  /* section arrival · "this room opens" */
  .gbx-header.gbx-arrive .gbx-mark svg, .gbx-header.gbx-arrive .gbx-mark img,
  .hdr.gbx-arrive .hdr-mark svg, .hdr.gbx-arrive .hdr-mark img,
  .hdr.gbx-arrive .mark img, .hdr.gbx-arrive .hdr-brand svg {
    animation: gbxPop .55s var(--ease, cubic-bezier(.2,.7,.2,1));
  }
  .gbx-header.gbx-arrive .gbx-key, .hdr.gbx-arrive .hdr-key,
  .hdr.gbx-arrive .key-glyph, .hdr.gbx-arrive .lx-key-eye {
    animation: gbxUnlock .55s var(--ease, cubic-bezier(.2,.7,.2,1));
  }

  /* hover on the CTA · "step forward" */
  .gbx-header:has(.gbx-cta:hover) .gbx-mark svg,
  .gbx-header:has(.gbx-cta:hover) .gbx-mark img,
  .hdr:has(.hdr-cta:hover) .hdr-mark svg,
  .hdr:has(.hdr-cta:hover) .hdr-mark img,
  .hdr:has(.hdr-cta:hover) .hdr-brand svg,
  .hdr:has(.hcta:hover) .mark img {
    animation: none;
    transform: scale(1.12);
  }
  .gbx-header:has(.gbx-cta:hover) .gbx-key,
  .hdr:has(.hdr-cta:hover) .hdr-key,
  .hdr:has(.hdr-cta:hover) .key-glyph,
  .hdr:has(.hcta:hover) .lx-key-eye {
    animation: none;
    transform: rotate(90deg);
    color: var(--gold-hover, #cda861);
    filter: drop-shadow(0 0 7px rgba(186,153,51,.55));
  }
}

@media (prefers-reduced-motion: reduce) {
  .gbx-mark svg, .gbx-mark img, .gbx-key,
  .hdr-mark svg, .hdr-mark img, .hdr-key,
  .hdr .mark img, .hdr-brand svg, .key-glyph, .lx-key-eye {
    animation: none !important;   /* resting state */
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MEDIA CONTROLS · one sound control, every forum
   ─────────────────────────────────────────────────────────────────────
   Measured 2026-09-13: eleven hero videos across the estate, and the
   sound control existed on one of them, bils/index. Carousel videos told
   the same story. BILS wired 8 pages with data-snd and .snd-toggle. CGTI,
   DDIF, MEVO and AIO had none on any page, so 26 pages played footage a
   visitor could not hear and could not ask to hear.

   The markup lived in the pages, which is why it never spread. It lives
   here now, next to the header it ships with, so a page gets the control
   by loading the kit rather than by being edited.

   Values are BILS's, verbatim. This is a port, not a redesign.
   ═══════════════════════════════════════════════════════════════════════ */

.snd-toggle, .hero-sound {
  position: absolute; z-index: 30;
  background: rgba(17,22,22,.55);
  border: .5px solid rgba(186,153,51,.2);
  color: rgba(243,246,249,0.52);
  font-family: var(--sans, 'Jost', system-ui, sans-serif);
  font-size: 8px; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 300; padding: 8px 14px; cursor: pointer;
  display: flex; align-items: center; gap: 8px;
  transition: all .2s; backdrop-filter: blur(4px);
}
.snd-toggle { bottom: 18px; right: 18px; }
.hero-sound { bottom: var(--sp4, 21px); right: var(--sp5, 34px); z-index: 10; }

.snd-toggle:hover, .hero-sound:hover {
  color: var(--cashmere, #F3F6F9);
  border-color: rgba(186,153,51,.45);
}
.snd-toggle:focus-visible, .hero-sound:focus-visible {
  outline: 1px solid var(--gold, #ba9933); outline-offset: 3px;
}

/* A carousel video answers a click. The cursor has to say so before the
   click, not after. Set by script only where the click is ours to take:
   a video inside a link belongs to the link. */
video.gbx-clickable { cursor: pointer; }

/* ═══════════════════════════════════════════════════════════════════════
   ORGANISATION MARQUEE · the scrolling logo strip
   ─────────────────────────────────────────────────────────────────────
   Measured 2026-09-13: SCLI carried this on 9 of 10 pages and CGTI and
   MEVO had it nowhere. It was page CSS, which is why it never travelled.

   Values are SCLI's verbatim. The spacing reads from each forum's own
   tokens, so it keeps that forum's rhythm rather than importing SCLI's:
   --sp5 is 55px on CGTI and 34px on MEVO, and both are correct there.

   The track holds the logo list TWICE. slide moves it -50%, so the
   second copy is exactly where the first began and the loop has no seam.
   Removing the duplicate list breaks the loop, not just the length.
   ═══════════════════════════════════════════════════════════════════════ */

.marquee {
  overflow: hidden; position: relative; z-index: 2;
  border-top: 0.5px solid var(--g2, rgba(186,153,51,0.236));
  border-bottom: 0.5px solid var(--g2, rgba(186,153,51,0.236));
  padding: var(--sp5, 34px) 0;
}
.track {
  display: flex; width: max-content;
  gap: var(--sp7, 89px);
  animation: gbx-marquee 46s linear infinite;
}
.track img {
  height: 26px; width: auto;
  filter: brightness(0) invert(1);
  opacity: .42;
  transition: opacity .3s var(--ease, cubic-bezier(.22,1,.36,1));
}
.track img:hover { opacity: .85; }

@keyframes gbx-marquee { from { transform: translateX(0) } to { transform: translateX(-50%) } }

/* A strip that never stops is the exact thing this media query exists
   for. It holds at the start rather than jumping to a random offset. */
@media (prefers-reduced-motion: reduce) {
  .track { animation: none; }
}
