  html, body { margin: 0; padding: 0; background: #FFFEF5; }
  body { font-family: Commissioner, sans-serif; color: #4A4545; -webkit-font-smoothing: antialiased; overflow-x: hidden; }
  * { box-sizing: border-box; }
  a { color: #B5082D; text-decoration: none; }
  a:hover { color: #4A4545; }
  img { max-width: 100%; }
  ::selection { background: #B5082D; color: #FFFEF5; }
  .vz-scroll::-webkit-scrollbar { height: 0; width: 0; }
  .vz-scroll { scrollbar-width: none; }
  @keyframes vzUp { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
  @keyframes vzSlideIn { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
  @keyframes vzFade { from { opacity: 0; } to { opacity: 1; } }
  @keyframes vzMarquee { from { transform: translate3d(0,0,0); } to { transform: translate3d(-50%,0,0); } }
  .vz-marquee:hover .vz-track { animation-play-state: paused; }
  /* Hovering one brand dims the rest and holds the strip still. */
  /* Inline opacity would beat these rules, so the logo's resting state lives here too. */
  .vz-logo { opacity: .92; transition: opacity .55s cubic-bezier(.16,1,.3,1); }
  /* Cancels the parent section's inline padding so the strip runs edge to edge,
     then tapers instead of ending on a hard cut. */
  .vz-bleed {
    width: calc(100% + 2 * clamp(20px, 3vw, 40px));
    margin-left: calc(-1 * clamp(20px, 3vw, 40px));
    -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,0) 0, #000 6%, #000 94%, rgba(0,0,0,0) 100%);
    mask-image: linear-gradient(90deg, rgba(0,0,0,0) 0, #000 6%, #000 94%, rgba(0,0,0,0) 100%);
  }
  /* The rule sweeps out from the centre and brightens; the label opens up beneath it. */
  .vz-cta::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
    background: #FFFEF5; opacity: .7;
    transform: scaleX(.62); transform-origin: 50% 50%;
    transition: transform .6s cubic-bezier(.16,1,.3,1), opacity .45s ease;
  }
  .vz-cta:hover::after { transform: scaleX(1); opacity: 1; }
  /* Chevron slides out from under the label, which steps right to make room. */
  .vz-flychev { opacity: 0; transform: translate(-8px, -50%);
    transition: opacity .4s ease, transform .55s cubic-bezier(.16,1,.3,1); }
  .vz-flylabel { transition: transform .55s cubic-bezier(.16,1,.3,1); }
  .vz-flyrow:hover .vz-flychev { opacity: 1; transform: translate(0, -50%); }
  .vz-flyrow:hover .vz-flylabel { transform: translateX(22px); }
  .vz-drag, .vz-drag * { user-select: none; -webkit-user-select: none; -webkit-user-drag: none; }
  .vz-drag img { pointer-events: none; }
  .vz-logos:hover .vz-track { animation-play-state: paused; }
  .vz-logos:hover .vz-logo { opacity: .18; }
  .vz-logos .vz-logo:hover { opacity: 1; }
  @keyframes vzShrinkA { from { transform: scale(1.648); } to { transform: none; } }
  @keyframes vzShrinkB { from { transform: scale(1.648); } to { transform: none; } }
  @keyframes vzCtrA { from { transform: scale(.607); } to { transform: none; } }
  @keyframes vzCtrB { from { transform: scale(.607); } to { transform: none; } }
  @keyframes vzInA { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: none; } }
  @keyframes vzInB { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: none; } }
  @keyframes vzPreOut { to { transform: translateY(-101%); } }
  @keyframes vzPreLogo { from { opacity: 0; transform: translateY(14px) scale(.94); } to { opacity: 1; transform: none; } }
  @keyframes vzPreBar { from { width: 0; } to { width: 100%; } }
  @keyframes vzNavDown { from { opacity: 0; transform: translateY(-100%); } to { opacity: 1; transform: none; } }
  @keyframes vzWipeIn { from { transform: translateY(100%); } to { transform: none; } }
  @keyframes vzWipeOut { from { transform: none; } to { transform: translateY(-100%); } }
  /* A 1×1 transparent PNG instead of `cursor: none` — Chrome reliably drops `none`
     when the pointer re-enters the window, but never drops a real cursor image. */
  @media (hover: hover) and (pointer: fine) {
    html.vz-nocursor, html.vz-nocursor body, html.vz-nocursor *,
    html.vz-nocursor *::before, html.vz-nocursor *::after {
      cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==") 0 0, none !important;
    }
  }
  @keyframes vzCtrIn { from { transform: scale(.607); } to { transform: none; } }
  @keyframes vzShrink { from { transform: scale(1.648); } to { transform: none; } }
  @keyframes vzSoft { from { opacity: 0; } to { opacity: 1; } }
  @keyframes vzFlyIn { from { opacity: 0; transform: translateX(-100%); } to { opacity: 1; transform: none; } }
  @keyframes vzFlyOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(-100%); } }
  @keyframes vzItemIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
  /* Time-based sequence: children hold hidden until the group scrolls in, then run
     one after another left→right on a clock — independent of scroll speed. */
  /* Only ARMED groups hide. JS arms them at mount, so a missing observer, a failed
     script or reduced motion can never leave content permanently blank. */
  .vz-seq.vz-armed > * { opacity: 0; }
  .vz-seq.vz-in > * {
    animation: vzSeqIn 1.5s cubic-bezier(.16,1,.3,1) both;
    -webkit-mask-image: linear-gradient(90deg, #000 0 22%, rgba(0,0,0,0) 58%);
    mask-image: linear-gradient(90deg, #000 0 22%, rgba(0,0,0,0) 58%);
    -webkit-mask-size: 450% 100%; mask-size: 450% 100%;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  }
  .vz-seq.vz-in > *:nth-child(1) { animation-delay: 0s; }
  .vz-seq.vz-in > *:nth-child(2) { animation-delay: .34s; }
  .vz-seq.vz-in > *:nth-child(3) { animation-delay: .68s; }
  .vz-seq.vz-in > *:nth-child(4) { animation-delay: 1.02s; }
  @keyframes vzSeqIn {
    from { opacity: 0; -webkit-mask-position: 100% 0; mask-position: 100% 0; }
    to   { opacity: 1; -webkit-mask-position: 0% 0;   mask-position: 0% 0; }
  }
  .vz-d1 { animation-delay: .10s; }
  .vz-d2 { animation-delay: .22s; }
  .vz-d3 { animation-delay: .34s; }
  .vz-d4 { animation-delay: .46s; }

  /* Scroll-driven reveal where the browser supports it; a plain load-in animation elsewhere.
     Both end at opacity 1 — nothing is ever hidden by script. */
  [data-reveal] { animation: vzUp 1.7s cubic-bezier(.16,1,.3,1) both; }
  /* Headings and body copy come in on their own, slower and a little later than the block
     that holds them, so a section resolves in two beats instead of one. */
  section h1, section h2, section h3, section p, section [data-t] {
    animation: vzUp 1.9s cubic-bezier(.16,1,.3,1) both;
  }
  @supports (animation-timeline: view()) {
    section h1, section h2, section h3, section p, section [data-t] {
      animation-timeline: view();
      animation-range: entry 22% entry 100%;
    }
  }
  /* Left-to-right fade wipe: a soft gradient edge travels across the text. */
  /* Doubled class so this outranks `section[data-reveal] > *`, whose animation
     shorthand would otherwise replace the wipe on a direct-child heading. */
  .vz-wipe.vz-wipe, section[data-reveal] > .vz-wipe {
    -webkit-mask-image: linear-gradient(90deg, #000 0 22%, rgba(0,0,0,0) 58%);
    mask-image: linear-gradient(90deg, #000 0 22%, rgba(0,0,0,0) 58%);
    -webkit-mask-size: 450% 100%;
    mask-size: 450% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    animation: vzTextWipe 3.2s cubic-bezier(.16,1,.3,1) both;
  }
  /* Opacity rides along: on a very short element (the quote mark) the mask's solid
     band already covers it at the start position, so the wipe alone never hid it. */
  @keyframes vzTextWipe {
    from { opacity: 0; -webkit-mask-position: 100% 0; mask-position: 100% 0; }
    35%  { opacity: 1; }
    to   { opacity: 1; -webkit-mask-position: 0% 0;   mask-position: 0% 0; }
  }
  /* Runs around mid-scroll, staggered per element. */
  @supports (animation-timeline: view()) {
    .vz-wipe.vz-wipe, section[data-reveal] > .vz-wipe { animation-timeline: view(); animation-range: entry 88% cover 128%; }
    .vz-wipe-2.vz-wipe-2, section[data-reveal] > .vz-wipe-2 { animation-range: entry 100% cover 140%; }
    .vz-wipe-3.vz-wipe-3, section[data-reveal] > .vz-wipe-3 { animation-range: entry 112% cover 152%; }
  }
  /* A <section> box itself must never fade or shift — it would expose the pinned hero
     behind it as a grey band. The reveal runs on its children instead. */
  section[data-reveal] { animation: none; }
  section[data-reveal] > * { animation: vzUp 1.7s cubic-bezier(.16,1,.3,1) both; }
  @supports (animation-timeline: view()) {
    [data-reveal] { animation-timeline: view(); animation-range: entry 10% entry 94%; }
    section[data-reveal] > * { animation-timeline: view(); animation-range: entry 10% entry 94%; }
  }

  .vz-g12 { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 20px; row-gap: 20px; }
  @media (max-width: 920px) {
    .vz-g12 { grid-template-columns: 1fr; }
    .vz-g12 > * { grid-column: 1 / -1 !important; grid-row: auto !important; }
  }
  .vz-parallax { background-size: cover; background-position: center; background-repeat: no-repeat; background-attachment: fixed; }
  @media (max-width: 780px) { .vz-parallax { background-attachment: scroll; } }
  .vz-n0 { animation-delay: 3.5s; }
  .vz-n1 { animation-delay: 3.6s; }
  .vz-n2 { animation-delay: 3.7s; }
  .vz-n3 { animation-delay: 3.8s; }
  .vz-fly1 { animation-delay: .26s; }
  .vz-fly2 { animation-delay: .36s; }
  .vz-fly3 { animation-delay: .46s; }
  .vz-fly4 { animation-delay: .56s; }
  .vz-fly5 { animation-delay: .66s; }
  .vz-fly6 { animation-delay: .76s; }
  .vz-mask { position: relative; overflow: hidden; background: #F0EEEE; }
  /* Overscan must exceed the largest parallax shift (24% of height) plus the zoom,
     or the image's own edge slides into view as a pale band top and bottom. */
  .vz-mask > img { position: absolute; left: 0; top: -21%; width: 100%; height: 142%; object-fit: cover; display: block; will-change: transform; }
  section[data-reveal] > .vz-mask { animation: vzFade 1.2s ease both; }
  /* The reveal's `transform` would outrank the drag track's inline transform for good
     (fill-mode: both), freezing the strip — fade these in instead. */
  section[data-reveal] > .vz-drag { animation: vzFade 1.2s ease both; }
