  /* ---- scroll zone ---- */
  .scroll-zone {
    position: relative;
    /* Five settled states × four transitions. Keeping each leg at ~180vh of
       scroll travel matches the pacing the 3-state version had. */
    height: 820vh;
  }

  .hero {
    position: sticky;
    top: 0;
    height: 100vh;
    width: 100%;
    overflow: hidden;
    display: grid;
    grid-template-rows: 1fr auto 1fr;
    place-items: center;
  }

  /* ---- the logo ---- */
  .logo-wrap {
    grid-row: 2;
    position: relative;
    /* Sized so the layout always "breathes": the halves translate ±18vh
       at state B, the logo is capped at 50vh, and text is anchored on
       the half centers (32vh from top/bottom — fixed by V=0.18, NOT by
       the logo cap). The top/bottom edge-to-half margin is ~9.4% of
       viewport height at every aspect ratio — solved from the closed
       form margin = 0.5 − 0.4525·K − V, with K = 0.50 and V = 0.18. */
    width: var(--logo-w);
    aspect-ratio: 1 / 1;
    /* .logo-wrap (assembled small parts) is the visible logo ONLY for
       states A and B. From state C onward the big halves take over and
       carry the logo all the way to state E — no crossfade. This element
       fades out across the first half of B→C and stays at 0 thereafter.
       The slide-left during B→C plays under the opacity fade, then is
       reset to 0 once we're past E (pBC - pDE*2 hits zero), so when the
       big halves take over they get a clean stage. */
    transform:
      translate(
        calc(max(0, var(--pBC) - var(--pDE) * 2) * -80vw),
        0
      );
    opacity: calc(max(0, 1 - var(--pBC) * 2));
    will-change: transform, opacity;
    color: var(--ink);
  }

  /* Layered logo parts — each pinned to its position in the 1500x1500
     coordinate space of Full.svg so they overlap into the assembled mark.
     SVGs are inlined and inherit color via fill="currentColor". */
  .part {
    position: absolute;
    color: var(--ink);
    will-change: transform;
    transition: color 0.4s ease;
    display: block;
  }
  .part-left {
    left: 3.81%;   top: 4.75%;
    width: 43.46%; height: 91.59%;
    /* Cap horizontal spread by vh as well so on wide-but-short windows
       the halves don't end up far apart in pixels while the logo itself
       has been height-capped — keeps the H:V spread ratio consistent.
       V is 18vh, which combined with the 50vh logo cap gives ~9.4%
       margin between the half and the top of the viewport.
       Half also shrinks to 0.80 across the A→B split so the bigger
       state-A logo doesn't leave the halves crowding the side text
       in state B — they settle back into their lanes. The shrink is
       around each half's own centre, so half-centres (and the side-
       text anchors at 32vh) stay put. */
    transform:
      translate(calc(var(--p2) * -1 * min(4vw, 7vh)), calc(var(--p1) * -18vh))
      scale(calc(1 - var(--p1) * 0.20));
  }
  .part-middle {
    /* `left` is nudged right by --mast-shift-a so the mast bar reads
       as separated from the clock arc — see comment on --mast-shift-a
       in base.css. SVG-pinned base is 17.83%. */
    left: calc(17.83% + var(--mast-shift-a));
    top: 24.32%;
    width: 36.44%; height: 45.90%;
    /* Continuous, gentle transform across the entire vertical-split phase:
       rotates counter-clockwise 0 → -90°, shrinks to 50%, fades to 0,
       all anchored on the circular bulge in the middle of the mast.
       Linear over --p1 so the motion feels calm and tied to the halves. */
    opacity: calc(1 - var(--p1));
    transform:
      rotate(calc(var(--p1) * -90deg))
      scale(calc(1 - var(--p1) * 0.5));
    transform-origin: 87.55% 56.68%;
  }
  .part-right {
    /* `left` is nudged right by --smiley-shift-a so the smiley arc
       reads as separated from the mast bar — see comment on
       --smiley-shift-a in base.css. SVG-pinned base is 17.83%. */
    left: calc(17.83% + var(--smiley-shift-a));
    top: 4.75%;
    width: 77.71%; height: 91.60%;
    /* Mirror of .part-left — shrinks to 0.80 at state B around its own
       centre so the smiley settles into the bottom-right lane instead
       of overlapping the side text. */
    transform:
      translate(calc(var(--p2) * min(4vw, 7vh)), calc(var(--p1) *  18vh))
      scale(calc(1 - var(--p1) * 0.20));
  }

  /* ---- side reveal text blocks ---- */
  .story {
    position: absolute;
    max-width: 380px;
    z-index: 2;
    pointer-events: none;
    /* Rises with the B-reveal (p2) and fades out together with the logo
       during B→C's first half — same `max(0, 1 - pBC*2)` envelope as
       .logo-wrap so they stay in lockstep. */
    opacity: calc(var(--p2) * max(0, 1 - var(--pBC) * 2));
  }
  .story.active { pointer-events: auto; }
  .story .kicker {
    display: block;
    font-size: 11px;
    letter-spacing: 0.4em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 18px;
  }
  .story h2 {
    /* Cap font-size by vh as well so on wide-but-short windows the
       heading doesn't crash into the nav. Same min()-inside-clamp()
       pattern used on the logo cap. */
    font-size: var(--story-fs-h2);
    font-weight: 400;
    letter-spacing: -0.01em;
    line-height: 1.18;
    margin-bottom: clamp(8px, 1.6vh, 18px);
  }
  .story p {
    font-size: var(--story-fs-p);
    color: var(--ink-soft);
    line-height: 1.5;
    margin: 0;
    padding: 0;
    font-weight: 400;
    letter-spacing: 0.5px;
  }
  /* anchor each block right beside its half, vertically centered on the
     semicircle's visual middle. The halves translate ±18vh from center,
     so each half-center sits at 32vh from the top/bottom edge. Anchor
     the text's own midline there with translateY(±50%) so its visual
     centre lines up with the half regardless of paragraph length. */
  .story-top {
    top: 32vh;
    left: calc(50% + 3vw);
    text-align: left;
    /* Same B→C slide-left envelope as .logo-wrap so the whole B-state
       composition exits as one piece. */
    transform: translate(
      calc(
        (1 - var(--p2)) * -60px
        + max(0, var(--pBC) - var(--pDE) * 2) * -80vw
      ),
      -50%
    );
  }
  .story-top h2 { width: 400px; max-width: 100%; }
  .story-top p { width: 380px; max-width: 100%; text-align: left; }
  .story-bottom {
    bottom: 32vh;
    right: calc(50% + 3vw);
    text-align: right;
    transform: translate(
      calc(
        (1 - var(--p2)) * 60px
        + max(0, var(--pBC) - var(--pDE) * 2) * -80vw
      ),
      50%
    );
  }
  .story-bottom p { text-align: right; }

  /* ---- states C + E + (assembled) C: the big halves carry the logo ----
     The same two .big-half elements are visible from state C through to
     state E — they slide in from their viewport edges (D, E), then
     re-converge on the assembled-logo offsets (D→E first half), then
     scale + lift + shift down to the state-E small-logo pose (D→E
     second half). No crossfade with .logo-wrap; the small parts stay
     hidden from state C onward.
     The transform reads top-to-bottom as a stack of independent motions:
       1. side-offset   slide off / on the viewport edge   (D, E)
       2. pull          ride into the assembled-logo offset (D→E 0→0.5)
       3. shift         move with the logo to make room for the wordmark
       4. shrink-dx     re-snap the inter-half spacing as the pair scales
                        (otherwise scaling around each half's own centre
                        leaves a gap between clock and smiley)
       5. lift (Y)      raise the pair to the state-E Y
       6. scale         shrink to the state-E size
  */
  .big-half {
    position: absolute;
    top: 50%;
    height: var(--big-half-h);
    width: auto;
    z-index: 2;
    pointer-events: none;
    color: var(--ink);
    display: block;
    will-change: transform, opacity;
  }
  .big-half-right {
    right: 0;
    aspect-ratio: 1165.66 / 1374.02;
    transform:
      translate(
        calc(
          var(--bigR-side) * (120% + var(--big-half-inset))
          - var(--big-half-inset)
          - var(--bigR-pull) * var(--big-pull-r)
          - var(--pShift) * var(--e-shift-x)
          - var(--pShrink) * var(--big-shrink-dx-r)
        ),
        calc(
          -50%
          - var(--pLift) * var(--e-lift)
        )
      )
      scale(calc(1 - var(--pShrink) * (1 - var(--big-final-scale))));
    opacity: 1;
  }
  .big-half-left {
    left: 0;
    aspect-ratio: 651.94 / 1373.9;
    transform:
      translate(
        calc(
          -1 * var(--bigL-side) * (120% + var(--big-half-inset))
          + var(--big-half-inset)
          + var(--bigL-pull) * var(--big-pull-l)
          - var(--pShift) * var(--e-shift-x)
          + var(--pShrink) * var(--big-shrink-dx-l)
        ),
        calc(
          -50%
          - var(--pLift) * var(--e-lift)
        )
      )
      scale(calc(1 - var(--pShrink) * (1 - var(--big-final-scale))));
    opacity: 1;
  }

  /* Mast (part-middle, big version). Hidden until D→E; fades in alongside
     the halves' assembly so the completed logo reads as one mark. It
     never lives at a viewport edge — its only "rest" is the assembled
     position relative to the big logo centre, then it tracks the same
     shrink/lift/shift as the two halves. */
  .big-half-middle {
    top: 50%;
    left: 50%;
    height: var(--big-middle-h);
    width: auto;
    aspect-ratio: 546.53 / 688.51;
    transform:
      translate(
        calc(
          -50%
          + var(--big-middle-dx)
          + var(--pShrink) * var(--big-shrink-dx-mid)
          - var(--pShift) * var(--e-shift-x)
        ),
        calc(
          -50%
          + var(--big-middle-dy)
          + var(--pShrink) * var(--big-shrink-dy-mid)
          - var(--pLift) * var(--e-lift)
        )
      )
      scale(calc(1 - var(--pShrink) * (1 - var(--big-final-scale))));
    /* Fades in across pDE 0.15 → 0.45 so it appears alongside the
       halves converging on the assembled position. */
    opacity: calc(min(1, max(0, (var(--pDE) - 0.15) * 3.33)));
  }

  /* D-state manifesto text — sits to the LEFT of the big right-half.
     Vertically centred, with a column capped at ~540px so the lines
     stay readable on wide screens. */
  .story-c {
    position: absolute;
    top: 50%;
    /* Pulled in from the rim (was clamp(24px, 6vw, 80px)) so the column
       reads as a centred block rather than hugging the left edge. */
    left: clamp(48px, 9vw, 120px);
    /* big-right is now inset by 3vw from the right rim; reserve its
       ~67.8vh of width plus the 3vw inset plus a 4vw gap. */
    right: calc(68vh + 7vw);
    max-width: 700px;
    z-index: 2;
    pointer-events: none;
    color: var(--ink);
    transform: translate(
      calc((1 - min(1, max(0, var(--pBC) - 0.4) * 1.67)) * -40px),
      -50%
    );
    /* Fades in over the second half of B→C, fades out in the first
       third of C→D. */
    opacity: calc(
      min(1, max(0, var(--pBC) - 0.5) * 2)
      * max(0, 1 - var(--pCD) * 3.33)
    );
  }
  .story-c.active { pointer-events: auto; }
  .story-c p {
    /* Bumped again from clamp(15px, min(1.25vw, 2.05vh), 22px). User
       asked for a slightly larger reading block in state C; cap raised
       to 26px and the vw/vh scaling lets it grow on tall or wide windows
       before the cap. */
    font-size: clamp(17px, min(1.4vw, 2.3vh), 26px);
    color: var(--ink);
    line-height: 1.6;
    letter-spacing: 0.2px;
    margin: 0 0 1.05em 0;
    font-weight: 400;
  }
  .story-c p:last-child { margin-bottom: 0; }

  /* E-state showcase text — mirrored layout, sits to the RIGHT of the
     big left-half. Placeholder copy until the real work grid is built. */
  .story-d {
    position: absolute;
    top: 50%;
    /* big-left is now inset by 3vw from the left rim; reserve that +
       its ~38vh width + a 4vw gap. Width is uncapped here so the bold
       service names can stretch into the empty right half of the stage. */
    left: calc(38vh + 7vw);
    right: clamp(24px, 6vw, 80px);
    max-width: 820px;
    z-index: 2;
    pointer-events: none;
    color: var(--ink);
    text-align: left;
    transform: translate(
      calc((1 - min(1, max(0, var(--pCD) - 0.4) * 1.67)) * 40px),
      -50%
    );
    /* Fades in over the second half of C→D, fades out in the first
       third of D→E. */
    opacity: calc(
      min(1, max(0, var(--pCD) - 0.5) * 2)
      * max(0, 1 - var(--pDE) * 3.33)
    );
  }
  .story-d.active { pointer-events: auto; }
  .story-d .kicker {
    display: block;
    font-size: 13px;
    letter-spacing: 0.4em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 22px;
  }
  .story-d .services {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: clamp(20px, 3vh, 38px);
  }
  .story-d .services li {
    display: flex;
    flex-direction: column;
    gap: clamp(8px, 1.1vh, 14px);
  }
  .story-d .services strong {
    /* Barlow 900 — Black display weight. Sized to dominate the column
       so each service name reads as a poster headline, not a label. */
    font-family: 'Barlow', system-ui, sans-serif;
    font-size: clamp(38px, min(4.6vw, 7vh), 80px);
    font-weight: 900;
    letter-spacing: 0.04em;
    line-height: 0.98;
    color: var(--ink);
    text-transform: uppercase;
  }
  .story-d .services span {
    font-size: clamp(14px, min(1.25vw, 2vh), 22px);
    /* Brighter than --ink-soft (#8b8680) so descriptors stay legible
       under the big Barlow 900 service names. Ink at ~82% reads as a
       clear secondary tier without competing with the headlines. */
    color: rgba(239, 236, 230, 0.82);
    line-height: 1.45;
    letter-spacing: 0.2px;
    font-weight: 400;
  }

  /* ---- state E: wordmark sits just to the right of the logo, slightly up ---- */
  .contact-reveal {
    position: absolute;
    top: 50%;
    left: var(--e-wordmark-x);
    /* Cap by vh too so on short-and-wide windows the wordmark stays
       proportional to the logo (which is also vh-capped). */
    width: clamp(110px, min(22vw, 38vh), 340px);
    z-index: 2;
    pointer-events: none;
    opacity: var(--p3);
    /* Lift is keyed on pLift (vertical-merge phase) so the wordmark
       fades in at the already-lifted Y rather than sliding diagonally
       into it during pShift. */
    transform: translate(calc((1 - var(--p3)) * 30px), calc(-50% - var(--pLift) * var(--e-lift)));
    color: var(--ink);
  }
  .contact-reveal.active { pointer-events: auto; }
  .wordmark {
    display: block;
    width: 100%;
    height: auto;
  }

  /* ---- state E: “Spojme se” + email centered below the logo + wordmark ---- */
  .below-logo {
    position: absolute;
    top: var(--e-contact-y);
    left: 50%;
    z-index: 2;
    text-align: center;
    pointer-events: none;
    opacity: var(--p3);
    /* Shift the whole state-E group up so the logo+wordmark cluster sits
       closer to the nav title. Keyed on pLift so the lift happens during
       the vertical-merge phase, in lockstep with the logo and wordmark. */
    transform: translate(-50%, calc(-50% + (1 - var(--p3)) * 12px - var(--pLift) * var(--e-lift)));
    color: var(--ink);
  }
  .below-logo.active { pointer-events: auto; }
  .below-logo h3 {
    font-size: var(--below-h3-fs);
    font-weight: 300;
    letter-spacing: -0.01em;
    margin-bottom: 18px;
  }
  .below-logo .mail {
    color: var(--ink);
    text-decoration: none;
    font-size: clamp(15px, 1.1vw, 18px);
    letter-spacing: 0.04em;
    border-bottom: 1px solid var(--ink-soft);
    padding-bottom: 3px;
    transition: border-color 0.2s ease;
  }
  .below-logo .mail:hover { border-color: var(--ink); }
  .below-logo .instagram {
    display: flex;
    align-items: center;
    justify-content: center;
    width: fit-content;
    margin: 18px auto 0;
    color: var(--ink);
    transition: color 0.2s ease, transform 0.2s ease;
  }
  .below-logo .instagram:hover {
    color: var(--ink);
    transform: scale(1.08);
  }

  /* ---- scroll hints (clickable arrows for forward / back) ---- */
  .hint {
    grid-row: 3;
    align-self: end;
    padding-bottom: clamp(40px, 8vh, 90px);
    display: flex;
    flex-direction: column;
    align-items: center;
    background: transparent;
    border: none;
    color: var(--ink);
    cursor: pointer;
    font: inherit;
    z-index: 3;
    opacity: 1; /* JS sets this per state */
    transition: opacity 0.4s cubic-bezier(.2,.7,.2,1);
    pointer-events: auto;
  }
  .hint.hint-up {
    grid-row: 1;
    align-self: start;
    padding-top: clamp(80px, 12vh, 130px);
    padding-bottom: 0;
  }
  .hint.hint-up .hint-arrow { animation: nudgeUp 2.6s cubic-bezier(.4,.0,.2,1) infinite; }
  @keyframes nudgeUp {
    0%, 60%, 100% { transform: translateY(0); }
    30%           { transform: translateY(-7px); }
  }
  .hint[disabled] { pointer-events: none; }
  .hint .hint-arrow {
    width: 48px;
    height: 48px;
    border-radius: 9999px;
    border: 1px solid var(--line);
    display: grid;
    place-items: center;
    color: var(--ink);
    animation: nudge 2.6s cubic-bezier(.4,.0,.2,1) infinite;
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
  }
  .hint:hover .hint-arrow {
    background: var(--ink);
    color: var(--bg);
    border-color: var(--ink);
    animation-play-state: paused;
  }
  .hint:focus-visible { outline: none; }
  .hint:focus-visible .hint-arrow { border-color: var(--ink); }
  @keyframes nudge {
    0%, 60%, 100% { transform: translateY(0); }
    30%           { transform: translateY(7px); }
  }

