/* ===========================================================================
   V8 — hero, light.

   Third pass. Out: the uppercase letter-spaced micro-labels, which read as
   monospace tech-chrome rather than brand. In: sentence case throughout, a
   larger reel, client marks at full strength and optically balanced, V7's own
   dot tile as ground, and a staggered entrance.
   ======================================================================== */

.v8 {
  --paper: var(--grey, #fbfbfb);
  --ink: var(--black, #1b1b1b);
  --mute: var(--grey--50, #8b8b8b);
  --hair: var(--grey--10, #e8e8e8);
  --live: var(--green, #10d07f);
  --beam: var(--blue-primary, #0f9ded);

  position: relative;
  /* the hero always fills the display; svh so mobile browser chrome does not
     push the client rail below the fold */
  box-sizing: border-box;
  min-height: 100vh;
  min-height: 100svh;
  padding-top: 78px;
  display: flex;
  flex-direction: column;
  font-family: Poppins, sans-serif;
  /* base wash under the drifting blobs, so the field never falls back to flat
     white between them */
  background:
    linear-gradient(168deg, rgba(15, 157, 237, .06) 0%, rgba(16, 117, 233, .028) 34%, rgba(251, 251, 251, 0) 66%),
    var(--paper);
  color: var(--ink);
  overflow-x: clip;
}

/* Fluid blue field.
   Three oversized, heavily blurred blobs drifting on independent cycles. They
   are translated rather than repositioned so the work stays on the compositor,
   and the layer is masked out before the client rail so the marks stay clean. */
.v8-aura {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 68%, transparent 96%);
  mask-image: linear-gradient(180deg, #000 0%, #000 68%, transparent 96%);
}

.v8-aura span {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(88px);
  will-change: transform;
}

.v8-aura span:nth-child(1) {
  width: 56vw; height: 56vw;
  left: -12%; top: -20%;
  background: radial-gradient(closest-side, rgba(16, 117, 233, .34), rgba(16, 117, 233, 0) 100%);
  animation: v8-drift-a 30s ease-in-out infinite alternate;
}

.v8-aura span:nth-child(2) {
  width: 48vw; height: 48vw;
  right: -8%; top: -8%;
  background: radial-gradient(closest-side, rgba(15, 157, 237, .30), rgba(15, 157, 237, 0) 100%);
  animation: v8-drift-b 38s ease-in-out infinite alternate;
}

.v8-aura span:nth-child(3) {
  width: 64vw; height: 42vw;
  left: 16%; top: 20%;
  background: radial-gradient(closest-side, rgba(88, 190, 245, .26), rgba(88, 190, 245, 0) 100%);
  animation: v8-drift-c 34s ease-in-out infinite alternate;
}

@keyframes v8-drift-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(14vw, 8vh, 0) scale(1.18); }
}

@keyframes v8-drift-b {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to   { transform: translate3d(-16vw, 12vh, 0) scale(.92); }
}

@keyframes v8-drift-c {
  from { transform: translate3d(0, 0, 0) scale(.95); }
  to   { transform: translate3d(-12vw, -8vh, 0) scale(1.22); }
}

@media (prefers-reduced-motion: reduce) {
  .v8-aura span { animation: none; }
}

/* nav-only shell for pages that reuse the menu without the hero */
.v8.is-bare { min-height: 0; padding-top: 0; display: block; }
.v8.is-bare .v8-aura { display: none; }

.v8 > * { position: relative; z-index: 1; }
.v8 > .v8-bleed { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.v8 > .v8-bleed > .v8-wrap { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.v8-hero { display: flex; }

/* Menu links are same-page anchors. Jumping to a section gives no sense of
   where it sits relative to where you were, so the page travels there.
   scroll-margin keeps the target clear of the fixed bar — without it the
   section lands underneath it and its first line is hidden. */
html { scroll-behavior: smooth; }
.v8s, .v8p, .v8c, .v8n { scroll-margin-top: 96px; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* Full width, minus the scrollbar — plain 100vw overflows. */
.v8-bleed {
  width: calc(100vw - (100vw - 100%));
  margin-left: calc(50% - (100vw - (100vw - 100%)) / 2);
}

.v8-wrap {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 40px;
}

/* --- Entrance ------------------------------------------------------------*/
@keyframes v8-in {
  from { opacity: 0; transform: translate3d(0, 18px, 0); }
  to   { opacity: 1; transform: none; }
}

.v8-anim {
  opacity: 0;
  animation: v8-in .85s cubic-bezier(.22, .61, .36, 1) forwards;
  animation-delay: var(--d, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  .v8-anim { opacity: 1; animation: none; }
}

/* --- Top menu ------------------------------------------------------------
   Replaces V7's floating bottom pill on V8 pages: a real bar at the top, clear
   at rest and frosted once the page moves under it. */
/* Fixed, not sticky, and outside .v8: that section sets overflow-x: clip,
   which makes it the sticky containing block — so the bar used to scroll away
   the moment the hero ended. */
.v8-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  transition: background-color .3s ease, box-shadow .3s ease,
              backdrop-filter .3s ease, border-color .3s ease;
}

.v8-nav-inner {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 40px;
}

.v8-nav.is-stuck {
  background: rgba(251, 251, 251, .78);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
}

/* Over the dark bands the light frosted bar cut the page in two, so it flips.
   Toggled by script from whichever section is currently behind it. */
.v8-nav.is-dark.is-stuck {
  background: rgba(12, 12, 12, .72);
}


.v8-nav.is-dark .v8-menu a { color: rgba(255, 255, 255, .62); }
.v8-nav.is-dark .v8-menu a:hover { color: #fff; background: rgba(255, 255, 255, .08); }

.v8-nav.is-dark .v8-ghost.v8-nav-cta {
  color: #fff;
  background:
    linear-gradient(#101010, #101010) padding-box,
    linear-gradient(90deg,
      rgba(15, 157, 237, .9), rgba(88, 190, 245, 1),
      rgba(16, 208, 127, .85), rgba(15, 157, 237, .9)) border-box;
  background-size: 100% 100%, 280% 100%;
}

.v8-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  padding: 20px 0;
}

.v8-menu {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}

.v8-menu a {
  position: relative;
  padding: 9px 14px;
  border-radius: 999px;
  font-size: .9375rem;
  font-weight: 400;
  color: var(--mute);
  text-decoration: none;
  transition: color .22s ease, background-color .22s ease;
}

.v8-menu a:hover { color: var(--ink); background: rgba(27, 27, 27, .05); }

/* Lives in the panel only; on the desktop bar the real pill is on show. */
.v8-menu-cta { display: none; }

/* Language picker.
   A lone "EN" in the corner read as decoration, so this is built to read as a
   control: globe, current code, chevron, and a panel that names each language
   in that language. The button carries the same moving gradient border as the
   call to action — the two are the only controls in the bar, and they should
   look like they belong to the same site. Literal colours throughout, because
   .v8-nav sits outside .v8 and inherits none of its tokens. */
.v8-lang { position: relative; flex: 0 0 auto; }

.v8-lang-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 38px;
  padding: 0 10px 0 11px;
  border: 1px solid transparent;
  border-radius: 999px;
  /* fill clipped to the padding box, moving gradient clipped to the border
     box — that gradient is the border, same trick as .v8-nav-cta */
  background:
    linear-gradient(#fff, #fff) padding-box,
    linear-gradient(90deg,
      rgba(15, 157, 237, .75), rgba(88, 190, 245, .95),
      rgba(16, 208, 127, .70), rgba(15, 157, 237, .75)) border-box;
  background-size: 100% 100%, 280% 100%;
  background-position: 0 0, 0% 50%;
  animation: v8-cta-border 7s ease-in-out infinite;
  color: #1b1b1b;
  font: 500 .8125rem/1 Poppins, sans-serif;
  letter-spacing: .04em;
  cursor: pointer;
  transition: transform .2s ease, box-shadow .25s ease;
}

.v8-lang-btn:hover { transform: translateY(-1px); box-shadow: 0 10px 20px -14px rgba(16, 60, 110, .8); }
.v8-lang-btn b { font-weight: 600; }
.v8-lang-globe { width: 15px; height: 15px; opacity: .75; }
.v8-lang-caret { width: 13px; height: 13px; opacity: .6; transition: transform .28s cubic-bezier(.22,.61,.36,1); }
.v8-lang.is-open .v8-lang-caret { transform: rotate(180deg); }

.v8-nav.is-dark .v8-lang-btn {
  color: #fff;
  background:
    linear-gradient(#101010, #101010) padding-box,
    linear-gradient(90deg,
      rgba(15, 157, 237, .9), rgba(88, 190, 245, 1),
      rgba(16, 208, 127, .85), rgba(15, 157, 237, .9)) border-box;
  background-size: 100% 100%, 280% 100%;
}

/* The panel. Opaque, because the bar above it is transparent until the page
   scrolls and the sections behind it are frequently dark. */
.v8-lang-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 60;
  min-width: 194px;
  padding: 6px;
  border-radius: 16px;
  border: 1px solid rgba(27, 27, 27, .10);
  background: #fff;
  box-shadow: 0 26px 50px -26px rgba(16, 60, 110, .55), 0 2px 6px rgba(0, 0, 0, .05);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px) scale(.97);
  transform-origin: 100% 0;
  transition: opacity .2s ease, transform .24s cubic-bezier(.22,.61,.36,1), visibility .24s;
}

.v8-lang.is-open .v8-lang-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.v8-lang-item {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 44px;
  padding: 0 10px;
  border-radius: 11px;
  font-size: .9375rem;
  color: #1b1b1b;
  text-decoration: none;
  cursor: pointer;
}

/* The two-letter code as a chip, so the row scans even before the name. */
.v8-lang-item i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 24px;
  border-radius: 7px;
  background: rgba(27, 27, 27, .06);
  font: 600 .6875rem/1 Poppins, sans-serif;
  font-style: normal;
  letter-spacing: .06em;
  color: #6b6b6b;
}

.v8-lang-item:hover { background: rgba(15, 157, 237, .08); }
.v8-lang-item:hover i { background: rgba(15, 157, 237, .16); color: #0f9ded; }

.v8-lang-item.is-on { cursor: default; font-weight: 500; }
.v8-lang-item.is-on i {
  background: linear-gradient(115deg, #0f9ded, #10d07f);
  color: #fff;
}

.v8-lang-tick { width: 15px; height: 15px; margin-left: auto; color: #10d07f; }

.v8-nav.is-dark .v8-lang-menu {
  border-color: rgba(255, 255, 255, .14);
  background: #101010;
  box-shadow: 0 26px 50px -26px rgba(0, 0, 0, .9);
}

.v8-nav.is-dark .v8-lang-item { color: #fff; }
.v8-nav.is-dark .v8-lang-item i { background: rgba(255, 255, 255, .10); color: rgba(255, 255, 255, .7); }
.v8-nav.is-dark .v8-lang-item:hover { background: rgba(255, 255, 255, .08); }
/* Needs the full selector: the plain dark rule above is more specific than
   .v8-lang-item.is-on i, so the grey chip was winning and the current
   language lost its gradient on every dark band. */
.v8-nav.is-dark .v8-lang-item.is-on i {
  background: linear-gradient(115deg, #0f9ded, #10d07f);
  color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .v8-lang-btn { animation: none; background-position: 0 0, 50% 50%; transition: none; }
  .v8-lang-menu, .v8-lang-caret { transition: opacity .01s linear; }
}

/* Three bars from one element: the span is the middle one, its two pseudo
   elements the outer two. On open the outer two travel to the middle and
   cross, and the middle one fades — one transform each, nothing to keep in
   sync. Hidden above 991px, where the real menu is on show. */
.v8-burger {
  display: none;
  align-items: center;
  justify-content: center;
  /* flex would otherwise shrink the square to fit the bar and hand back a
     33px target — the whole point of the 44 is that it does not shrink. */
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: transparent;
  /* literal, not var(--ink): .v8-nav is outside .v8 and inherits none of its
     tokens, so var(--ink) here is invalid and the declaration is dropped */
  color: #1b1b1b;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.v8-burger span,
.v8-burger span::before,
.v8-burger span::after {
  display: block;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform .26s ease, opacity .18s ease;
}

.v8-burger span { position: relative; }
.v8-burger span::before,
.v8-burger span::after { content: ""; position: absolute; left: 0; }
.v8-burger span::before { top: -6px; }
.v8-burger span::after { top: 6px; }

/* transparent, not opacity:0 — opacity on the span would take its two
   pseudo elements with it and the whole icon would disappear. */
.v8-nav.is-open .v8-burger span { background: transparent; }
.v8-nav.is-open .v8-burger span::before { transform: translateY(6px) rotate(45deg); }
.v8-nav.is-open .v8-burger span::after { transform: translateY(-6px) rotate(-45deg); }

.v8-nav.is-dark .v8-burger { color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .v8-burger span, .v8-burger span::before, .v8-burger span::after { transition: none; }
}

/* Two backgrounds on one element: a flat fill clipped to the padding box, and
   a moving gradient clipped to the border box — that gradient is the border.
   Only the second layer is animated, so nothing reflows. */
.v8-ghost.v8-nav-cta {
  margin-left: 8px;
  border: 1px solid transparent;
  background:
    linear-gradient(#fff, #fff) padding-box,
    linear-gradient(90deg,
      rgba(15, 157, 237, .75), rgba(88, 190, 245, .95),
      rgba(16, 208, 127, .70), rgba(15, 157, 237, .75)) border-box;
  background-size: 100% 100%, 280% 100%;
  background-position: 0 0, 0% 50%;
  animation: v8-cta-border 7s ease-in-out infinite;
}

@keyframes v8-cta-border {
  0%, 100% { background-position: 0 0, 0% 50%; }
  50%      { background-position: 0 0, 100% 50%; }
}

/* The shared ghost hover swaps border-color, which would blank the gradient. */
.v8-ghost.v8-nav-cta:hover {
  border-color: transparent;
  transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
  .v8-ghost.v8-nav-cta { animation: none; background-position: 0 0, 50% 50%; }
}

/* V7's bottom pill would sit under this on the same page. */
body:has(.v8) .nav { display: none !important; }

/* Full wordmark, one flat layer. The SVG rides as a mask so the background
   colours the letterforms — an <img> could not be recoloured this way. */
.v8-logo {
  display: block;
  height: 26px;
  width: calc(26px * 306 / 49);
  background: #1b1b1b;
  -webkit-mask: url("../img/683d6d3bc64f7141dc6f697d_LogoDreamfx-1b95a6.svg") no-repeat center / contain;
  mask: url("../img/683d6d3bc64f7141dc6f697d_LogoDreamfx-1b95a6.svg") no-repeat center / contain;
}

/* On the dark bands the mark would vanish. */
.v8-nav.is-dark .v8-logo { background: #fff; }

/* --- Hero -----------------------------------------------------------------
   Copy first, reel underneath in cinema format. Side by side, the reel could
   only ever be a third of the page; full width at 21:9 it is far larger while
   costing less vertical space than the 16:9 slab did. */
.v8-hero {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 40px 0 32px;
}

/* Headline left, supporting copy right, both sitting on the same baseline —
   otherwise a single left column leaves the right half of the page empty. */
.v8-head {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  align-items: start;
  gap: 64px;
  margin-top: 26px;
}

/* nudge the supporting column down to sit on the headline's cap height rather
   than its line box */
.v8-head-side { padding-top: 12px; }

/* --- Eyebrow -------------------------------------------------------------
   Was a bordered pill; reduced to a plain line so nothing sits in a box above
   the headline. */
.v8-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: .9375rem;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--mute);
}

.v8-pulse {
  position: relative;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--live);
  flex: 0 0 auto;
}

.v8-pulse::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid var(--live);
  animation: v8-ping 2.4s cubic-bezier(.2, .6, .3, 1) infinite;
}

@keyframes v8-ping {
  0%   { transform: scale(.5); opacity: .9; }
  70%  { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}

/* --- Headline ------------------------------------------------------------*/
.v8-title {
  margin: 26px 0 0;
  font-size: clamp(2.75rem, 5.8vw, 5.25rem);
  line-height: 1.0;
  letter-spacing: -.034em;
  font-weight: 500;
  color: var(--ink);
  max-width: 14ch;
}

/* V7's .h1-highlight paints a blue block behind the word. At display size that
   reads as a marker pen over the headline, so the second line is set a step
   lighter instead — same two-tone split, no coloured slab. */
.v8-title .v8-soft { color: var(--mute); }

.v8-lede {
  margin: 0;
  max-width: 42ch;
  font-size: 1rem;
  line-height: 1.65;
  font-weight: 400;
  color: var(--mute);
}

.v8-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 32px;
}

.v8-ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 14px 24px;
  border-radius: 999px;
  border: 1px solid var(--grey--20, #cecece);
  background: #fff;
  color: var(--ink);
  font-size: .9375rem;
  font-weight: 500;
  text-decoration: none;
  transition: border-color .25s ease, transform .25s ease;
}

.v8-ghost:hover { border-color: var(--ink); transform: translateY(-1px); }

/* --- Reel ----------------------------------------------------------------*/
.v8-reel-holder {
  position: relative;
  flex: 1 1 auto;
  /* Was min-height: 180px, which in practice meant "whatever the copy leaves".
     On a 1280x800 laptop that was 226 px against a 1200 px width — a 5.3:1
     slot for a 2.67:1 master, so cover-fit threw away half the frame and the
     three-up bands arrived as unreadable strips. This floor tracks the width,
     so the window stays between about 2.4:1 and 2.9:1 at every size and the
     master is only ever trimmed, never halved. */
  min-height: clamp(300px, 32vw, 540px);
  margin-top: 36px;
}

.v8-reel {
  position: relative;
  z-index: 1;
  border-radius: 20px;
  overflow: hidden;
  background: #0b0b0b;
  /* Fills the height the copy leaves over. Absolute rather than height:100%:
     a percentage height against a flex-basis:auto parent resolves to zero, which
     collapsed the reel entirely. The 16:9 master is cover-fitted, so it simply
     crops harder on shorter displays. */
  position: absolute;
  inset: 0;
  /* no hairline: against the blue field a dark 1px edge read as a black frame */
  box-shadow: 0 30px 70px -34px rgba(16, 60, 110, .30);
}

.v8-reel video,
.v8-reel img.v8-reel-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.v8-reel img.v8-reel-poster { z-index: 1; transition: opacity .6s ease; }
.v8-reel.is-playing img.v8-reel-poster { opacity: 0; }
.v8-reel video { z-index: 2; }

.v8-reel-sound {
  position: absolute;
  z-index: 3;
  right: 16px;
  bottom: 16px;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  cursor: pointer;
  color: #fff;
  background: rgba(10, 10, 10, .4);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, .18);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .3s ease, transform .3s ease, background-color .25s ease;
}

.v8-reel:hover .v8-reel-sound,
.v8-reel-sound:focus-visible { opacity: 1; transform: none; }
.v8-reel-sound:hover { background: rgba(255, 255, 255, .22); }
.v8-reel-sound svg { width: 16px; height: 16px; display: block; }
.v8-reel-sound .v8-icon-on { display: none; }
.v8-reel-sound.is-on .v8-icon-on { display: block; }
.v8-reel-sound.is-on .v8-icon-off { display: none; }

/* --- Client rail ---------------------------------------------------------*/
.v8-clients {
  --k: .88;
  padding: 34px 0 72px;
  border-top: 1px solid var(--hair);
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 36px;
}

/* sentence case, no tracking — this used to read "SELECTED CLIENTS" */
.v8-clients-label {
  font-size: .9375rem;
  font-weight: 500;
  color: var(--mute);
  white-space: nowrap;
}

.v8-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

.v8-track {
  display: flex;
  align-items: center;
  gap: calc(60px * var(--k, 1));
  width: max-content;
  animation: v8-marquee 46s linear infinite;
}

.v8-marquee:hover .v8-track { animation-play-state: paused; }

@keyframes v8-marquee {
  to { transform: translate3d(-50%, 0, 0); }
}

/* Names, not marks. Set in one weight at one size, a roster reads as a list of
   companies; a row of supplied logo files reads as a row of mismatched files.
   The optical-weight juggling the logos needed disappears with them. */
/* A mark, not a word. The file is a mask and this is the colour: ten brand
   manuals arrive as ten palettes, and half of them as white artwork meant for
   dark backgrounds. Masked, none of that reaches the page — the rail decides.
   Box and height come from client_logos.py, one measurement per mark, so the
   row reads as one weight rather than one size. */
.v8-client {
  flex: 0 0 auto;
  display: block;
  /* One dial for the whole rail. The measured box stays in the markup and
     --k scales it, so a change of mind about size does not mean re-measuring
     ten logos. */
  width: calc(var(--w) * var(--k, 1));
  height: calc(var(--h) * var(--k, 1));
  background: #8b8b8b;
  /* the image itself is set per mark in the markup; everything else is here */
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  opacity: .78;
  transition: opacity .3s ease, background-color .3s ease;
}

/* The rail pauses on hover; the mark under the cursor is the reason it did. */
.v8-marquee:hover .v8-client { opacity: .5; }
.v8-client:hover { opacity: 1; background: #1b1b1b; }

.v8-client:hover { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .v8-track { animation: none; }
  .v8-marquee { overflow-x: auto; }
  .v8-pulse::after { animation: none; }
}

/* --- Responsive ----------------------------------------------------------*/
@media (max-width: 1100px) {
  /* below this the stacked copy plus a reel cannot honestly fit one screen */
  .v8 { min-height: 0; display: block; }
  .v8 > .v8-bleed, .v8 > .v8-bleed > .v8-wrap { display: block; }
  .v8-hero { display: block; padding: 32px 0 56px; }
  .v8-reel-holder { flex: none; min-height: 0; margin-top: 36px; }
  .v8-reel { position: relative; inset: auto; height: auto; aspect-ratio: 2 / 1; }
  .v8-head { grid-template-columns: 1fr; gap: 28px; align-items: start; }
  .v8-head-side { padding-bottom: 0; }
  .v8-title { max-width: none; }
  .v8-reel-holder { margin-top: 44px; }
  .v8-reel { aspect-ratio: 2 / 1; }
}

@media (max-width: 991px) {
  .v8-wrap { padding: 0 24px; }
  .v8-nav-inner { padding: 0 24px; }
  .v8-menu { display: none; }
  /* Smaller again on a phone: the rail is the width of a hand, and a mark at
     desktop size leaves room for barely two of them. */
  .v8-clients { --k: .72; grid-template-columns: 1fr; gap: 20px; padding-bottom: 52px; }
  .v8-reel-sound { opacity: 1; transform: none; }

  /* The menu was hidden here and nothing replaced it, so a phone had no way
     to reach Storitve, Projekti or Kontakt from the bar — only the logo and
     the call-to-action were left. This is that way back. */
  .v8-burger { display: inline-flex; }
  .v8-top { gap: 12px; }
  /* the mark is 26px tall; the link around it should still be tappable */
  .v8-top > a.w-inline-block { padding: 9px 0; }

  /* At 360px the logo is 162px and the pill 120px: together with the menu
     button they do not fit, and the pill was wrapping to two lines and
     making the bar 112px tall. It moves into the panel instead. */
  .v8-nav .v8-nav-cta { display: none; }
  /* The picker stays in the bar: someone who cannot read the page must not
     have to open a menu labelled in that language to get out of it. At 360px
     the globe is what gives way — the code and the chevron still say what the
     control is, and the bar has to fit a 162px logo beside it. */
  .v8-lang-btn { height: 40px; padding: 0 9px; }
  .v8-lang-globe { display: none; }
  .v8-lang-menu { right: -6px; min-width: 190px; }
  .v8-nav.is-open .v8-menu .v8-menu-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: 10px;
    padding: 13px 18px;
    border-radius: 999px;
    border: 1px solid rgba(27, 27, 27, .16);
    font-size: 1rem;
    color: #1b1b1b;
    text-decoration: none;
  }
  .v8-nav.is-open.is-dark .v8-menu .v8-menu-cta {
    color: #fff;
    border-color: rgba(255, 255, 255, .22);
  }

  .v8-nav.is-open .v8-menu {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    margin: 0;
    padding: 8px 24px 18px;
    /* Opaque, unlike the bar above it. At .94 with a blur the section behind
       still read through — over the dark contact band the headline sat right
       across the three links. A menu has to be legible before it is pretty. */
    background: #fbfbfb;
    border-top: 1px solid rgba(27, 27, 27, .10);
    box-shadow: 0 18px 34px -26px rgba(16, 60, 110, .5);
  }

  /* The panel carries its own fill because the bar above it is transparent
     until the page scrolls; without this the links float over the hero. */
  .v8-nav.is-open.is-dark .v8-menu {
    background: #0c0c0c;
    border-top-color: rgba(255, 255, 255, .12);
    box-shadow: none;
  }

  .v8-nav.is-open .v8-menu a { padding: 13px 12px; font-size: 1.0625rem; }
}

@media (max-width: 640px) {
  .v8-actions > * { flex: 1 1 auto; justify-content: center; }
  /* a letterbox is a sliver on a phone — open it back up */
  .v8-reel { border-radius: 14px; position: relative; inset: auto; height: auto; aspect-ratio: 16 / 10; }
}

/* --- Scrollbar -----------------------------------------------------------
   White track, brand-blue thumb, and the same gradient sweep the call-to-action
   border runs. Animations do not run on ::-webkit-scrollbar pseudo-elements,
   but a registered custom property animated on :root does inherit into them,
   and the repaint follows. Browsers without @property keep the flat blue. */

@property --sb-sweep {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

:root {
  --sb-sweep: 0%;
  animation: v8-sb 6s ease-in-out infinite;
}

/* Careful: in current Chrome, setting scrollbar-width or scrollbar-color
   DISABLES ::-webkit-scrollbar entirely, gradient and all. So the standard
   pair is handed only to engines that have no webkit pseudo-element to lose,
   which in practice means Firefox. */
@supports not selector(::-webkit-scrollbar) {
  :root {
    scrollbar-color: #0f9ded #ffffff;
    scrollbar-width: thin;
  }
}

@keyframes v8-sb {
  0%, 100% { --sb-sweep:   0%; }
  50%      { --sb-sweep: 100%; }
}

::-webkit-scrollbar { width: 12px; height: 12px; }

::-webkit-scrollbar-track {
  background: #fff;
  border-left: 1px solid rgba(0, 0, 0, .06);
}

::-webkit-scrollbar-thumb {
  border: 3px solid #fff;
  border-radius: 999px;
  background-color: #0f9ded;
  background-image: linear-gradient(180deg,
    #0f9ded 0%, #58bef5 28%, #10d07f 52%, #58bef5 74%, #0f9ded 100%);
  background-size: 100% 300%;
  background-position: 0 var(--sb-sweep);
}

::-webkit-scrollbar-thumb:hover { border-width: 2px; }

::-webkit-scrollbar-corner { background: #fff; }

@media (prefers-reduced-motion: reduce) {
  :root { animation: none; }
}


/* --- Cookie choice --------------------------------------------------------
   A bar, not a modal. Nothing on this site is gated behind the answer, so
   taking the screen hostage for it would be a lie about how much it matters.
   Both buttons are real buttons of the same size: an "accept" styled as the
   only way out is not a choice. */
.dfx-cc {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 80;
  display: flex;
  align-items: center;
  gap: 20px;
  max-width: 720px;
  margin: 0 auto;
  padding: 14px 16px;
  border-radius: 16px;
  border: 1px solid rgba(27, 27, 27, .10);
  background: #fff;
  box-shadow: 0 24px 48px -28px rgba(16, 60, 110, .55);
  font-family: Poppins, sans-serif;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .35s ease, transform .45s cubic-bezier(.22, .61, .36, 1);
}

/* An author display: flex outranks the user agent's [hidden] rule, so the bar
   stayed on screen after the choice was made and came back on every reload.
   The attribute has to be honoured explicitly. */
.dfx-cc[hidden] { display: none; }

.dfx-cc.is-in { opacity: 1; transform: none; }

.dfx-cc-text {
  margin: 0;
  font-size: .875rem;
  line-height: 1.5;
  color: #4a4a4a;
}

.dfx-cc-text a { color: #0f9ded; text-decoration: none; white-space: nowrap; }
.dfx-cc-text a:hover { text-decoration: underline; }

.dfx-cc-acts { display: flex; gap: 8px; margin-left: auto; flex: 0 0 auto; }

.dfx-cc-yes,
.dfx-cc-no {
  min-height: 40px;
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid rgba(27, 27, 27, .16);
  background: #fff;
  font: 500 .875rem/1 Poppins, sans-serif;
  color: #1b1b1b;
  cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease;
}

.dfx-cc-no:hover { border-color: rgba(27, 27, 27, .38); }
.dfx-cc-yes { background: #1b1b1b; border-color: #1b1b1b; color: #fff; }
.dfx-cc-yes:hover { background: #000; }

@media (max-width: 640px) {
  .dfx-cc { flex-direction: column; align-items: stretch; gap: 12px; }
  .dfx-cc-acts { margin-left: 0; }
  .dfx-cc-acts > * { flex: 1 1 0; }
}

@media (prefers-reduced-motion: reduce) {
  .dfx-cc { transition: none; }
}

/* --- Legal pages ----------------------------------------------------------
   Long-form reading, so: one column, a measure that stops around 68 characters,
   and numbered headings so a section can be pointed at in an email. Set on the
   same paper as the rest of the site rather than in the V7 internal-page frame
   these pages used to borrow. */
.lg {
  padding: 132px 0 96px;
  background: var(--grey, #fbfbfb);
  color: #1b1b1b;
  font-family: Poppins, sans-serif;
}

.lg-wrap {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 0 24px;
}

.lg-head { padding-bottom: 34px; border-bottom: 1px solid rgba(27, 27, 27, .10); }

.lg-head h1 {
  margin: 0 0 16px;
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 1.08;
}

.lg-lede { margin: 0; font-size: 1.0625rem; line-height: 1.65; color: #4a4a4a; }

.lg-date {
  margin: 18px 0 0;
  font-size: .8125rem;
  color: #8b8b8b;
}

.lg-block { padding: 34px 0; border-bottom: 1px solid rgba(27, 27, 27, .07); }

.lg-block h2 {
  display: flex;
  gap: 14px;
  margin: 0 0 14px;
  font-size: 1.1875rem;
  font-weight: 500;
  letter-spacing: -.01em;
}

.lg-num { color: #0f9ded; font-variant-numeric: tabular-nums; }

.lg-block p {
  margin: 0 0 12px;
  font-size: .9375rem;
  line-height: 1.72;
  color: #4a4a4a;
}

.lg-block p:last-child { margin-bottom: 0; }
.lg-block b { font-weight: 500; color: #1b1b1b; }
.lg-block a { color: #0f9ded; text-decoration: none; }
.lg-block a:hover { text-decoration: underline; }

.lg-reset { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

.lg-reset-btn {
  min-height: 44px;
  padding: 0 18px;
  border-radius: 999px;
  border: 1px solid rgba(27, 27, 27, .18);
  background: #fff;
  font: 500 .875rem/1 Poppins, sans-serif;
  color: #1b1b1b;
  cursor: pointer;
}

.lg-reset-btn:hover { border-color: rgba(27, 27, 27, .4); }
.lg-reset-btn:disabled { opacity: .45; cursor: default; }
.lg-reset-done { font-size: .875rem; color: #10d07f; }
