/* ==========================================================================
   Section: projects (Referenzen)
   Figma band y 2800..4020 in a 1440 frame.

   Measured anchors, all reproduced exactly at 1440:
     h2                  x = 136, y = 2879, 56/56, #1b1d36, "Websites" gradient
     card rects          580 x 367, radius 15, shadow 0 4px 4px rgb(0 0 0/.25)
       MAX Holzbau       x = 122,  y = 3068.85   fill white @ 20%
       neovum            x = 754,  y = 3068.71   fill white @ 20%
       Richter Formteile x = 125,  y = 3558.71   fill white @ 90%
       PulsMedia         x = 754,  y = 3556.71   fill: mesh gradient, see below
     mockups (overhang the card top, never clipped)
       mh-usercase       x = 143,  y = 2963, 541.07 x 399.99, rotated 0.43deg
       neovum-usercase   x = 791.1,y = 2949.5, 542.66 x 401.35
       formteile-case    x = 147,  y = 3461, 540 x 399
       pulsmedia-case    x = 777,  y = 3461, 540 x 399
     company names       x = card + 33, y = card + 273, 26/24, #17203f
                         (#ffffff on the dark card)
     descriptors         x = card + 33, y = card + 306.15, 17/19, brand gradient
     column pitch        632 (580 + 52 gap), row pitch 489.85 (367 + 122.85)
     section insets      122 left, 106 right, 79 above the h2, 94 below row 2

   Two coordinates in the file are off a regular grid by a hair — the Richter
   card sits 3px right of the MAX card above it, and the PulsMedia card 2px
   above the Richter card while its text stays on the same baseline as
   Richter's. Both are reproduced (see the per-card blocks) and reported.
   ========================================================================== */


  .projects {
    /* h2 line box at 79, last card rect ends 94 above the band edge. */
    padding-block: 79px 94px;
    /* Left inset is the card grid's 122; the h2 sits 14px further in and
       carries that itself. 122/1440 = 8.4722vw, 106/1440 = 7.3611vw. */
    padding-inline:
      calc(var(--stage-x) + clamp(1.25rem, 8.4722vw, 122px))
      calc(var(--stage-x) + clamp(1.25rem, 7.3611vw, 106px));
  }

  .projects__title {
    /* Figma h2 style, 56/56. Colour is #1b1d36, the near-duplicate of
       dark-navy that this design uses for headings on light ground. */
    color: var(--color-heading-alt);
    /* The h2 text node is 881 wide and starts 14px right of the card grid. */
    max-inline-size: 881px;
    margin-inline-start: clamp(10.5px, 0.9722vw, 14px);
  }

  /* Figma anchors a text gradient to the whole TEXT NODE, not to the coloured
     run, so "Websites" shows the 52%..82% slice of the brand gradient and
     starts periwinkle (#7387ff), not cyan. Measured off the reference render.
     Both values are in em so the slice stays identical as the type scales:
     881px and the advance of "Küzlich gebaute " at the 56px desktop size. */
  .projects__accent {
    background-size: 15.732em 100%;
    background-position-x: -8.237em;
  }

  .projects__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 580px));
    /* 52/1440 = 3.6111vw. */
    column-gap: clamp(1.25rem, 3.6111vw, 52px);
    /* Row 2 sits 122.85 below row 1, and the h2 ends 133.85 above row 1.
       Both are floors, not fixed values: the mockups overhang the card top by
       17.9% of the card width, so as the cards narrow the gaps must stay
       ahead of that overhang. 21vw does exactly that below 1440 and is
       clamped away at 1440, where the measured numbers win. */
    row-gap: clamp(6rem, 21vw, 122.85px);
    margin-block-start: clamp(4rem, 21vw, 133.85px);
  }

  .projects__card {
    position: relative;
    /* 273 / 49 / 41.85 / 33 of 580. The padding box IS the 498px text column
       the design draws, so the name and the descriptor need no geometry of
       their own — and the card grows instead of overflowing when the
       descriptor wraps below 1440. At 1440 the card is 367 tall to the pixel:
       273 + 24 + 9.15 + 19 + 41.85. */
    padding: 47.069% 8.448% 7.216% 5.690%;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    /* Cards 1 and 2 are white at 20%, card 3 at 90%, over the white page.
       Reproduced as measured: the glass is what lets the neighbouring
       sections' 3D shapes tint the corners they pass behind. */
    background-color: var(--color-glass-light);

    /* Mockup placement, as a share of the card width — the Figma frame is
       proportional, so the composition survives the card narrowing.
       Default = card 1. */
    --media-x: 3.879%;        /*   22.50px */
    --media-y: -17.899%;      /* -103.82px */
    --media-w: 93.287%;       /*  541.07px */
    --media-rotate: 0deg;
  }

  .projects__media {
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: var(--media-x);
    /* The vertical offset is a percentage MARGIN, not an inset: percentage
       margins resolve against the containing block's width in both axes, so
       the overhang stays locked to the card's width rather than its
       content-driven height. */
    margin-block-start: var(--media-y);
    inline-size: var(--media-w);
    /* The mockups carry their own transparent margin and the card must not
       clip them: they deliberately overhang its top edge. */
    block-size: auto;
    rotate: var(--media-rotate);
  }

  /* .projects__name is an <h3>: the Figma name style is 26/24 dark-navy, which
     is exactly the H3 the base layer already draws. It carries a class for the
     contract and the motion runtime, and needs no rule of its own. */

  .projects__descriptor {
    /* Name line box ends at 297, descriptor line box starts at 306.15. */
    margin-block-start: 9.15px;
  }

  /* --- per-card geometry ------------------------------------------------
     Each mockup was hand-placed in Figma, so no two sit at the same offset.
     The defaults above are card 1's, which is what a fifth card added in the
     CMS would inherit. */

  .projects__card[data-project="max-holzbau"] {
    /* The only rotated mockup in the section. */
    --media-rotate: 0.43deg;
  }

  .projects__card[data-project="neovum"] {
    /* Placed larger and higher than the other three. */
    --media-x: 6.397%;        /*   37.10px */
    --media-y: -20.546%;      /* -119.17px */
    --media-w: 93.562%;       /*  542.66px */
  }

  .projects__card[data-project="richter-formteile"] {
    /* The one light card that is white at 90% instead of 20%. Invisible over
       the white page, but not over the 3D shape the neighbouring section
       pushes behind this corner: the reference render shows that shape at
       exactly one tenth strength here. */
    background-color: var(--color-glass-strong);
    --media-x: 3.793%;        /*   22.00px */
    --media-y: -16.846%;      /*  -97.71px */
    --media-w: 93.103%;       /*  540.00px */
    /* x = 125, 3px right of the card above it. Reproduced, not squared up.
       As a relative offset rather than a transform: the reveal in section.js
       animates the card's transform, and GSAP folds an existing `translate`
       into it and then overwrites the axis it animates. */
    inset-inline-start: 3px;
  }

  .projects__card[data-project="pulsmedia"] {
    --media-x: 3.966%;        /*   23.00px */
    --media-y: -16.515%;      /*  -95.79px */
    --media-w: 93.103%;       /*  540.00px */
    /* y = 3556.71, 2px above the Richter card, while its name and descriptor
       stay level with Richter's. The rect moves, the text block does not:
       275.29 above / 39.56 below instead of 273 / 41.85. */
    inset-block-start: -2px;
    padding-block: 47.464% 6.820%;
  }

  /* --- dark card --------------------------------------------------------
     Figma's codegen emits no fill for this rectangle (node 190:206): the fill
     is a mesh gradient it cannot express, so it came through as a bare div.

     Now using the real thing, exported from Figma at 2x. It replaces three
     hand-fitted radial stops that reached a mean error of 5/255 per channel —
     close, but a mesh gradient is not expressible as radials, so "close" was
     the ceiling. background-color stays as the paint-time fallback. */

  .projects__card[data-variant="dark"] {
    --color-heading: var(--color-on-dark);
    background-color: #1e1f40;
    background-image: url("../img/pulsmedia-card-fill.png");
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
  }

  /* ------------------------------------------------------------------
     Below 1440 there is no comp. Decisions made here, logged in the
     build report:
       - the two columns hold until 900, where two cards would be under
         360px wide and every descriptor would wrap; then one column
       - the 3px and 2px offsets above are absolute slips in a 1440 frame,
         so they are dropped once the cards no longer sit on that grid
       - the mockups keep their overhang at every width, because the
         gaps above and between the rows scale with it
     ------------------------------------------------------------------ */

  @media (width < 900px) {
    .projects {
      padding-block: 56px 64px;
    }

    /* One column, still capped at the drawn 580 and still starting on the
       section inset, so the h2 keeps sitting 14px inside the card edge the
       way it does at 1440. */
    .projects__grid {
      grid-template-columns: minmax(0, 580px);
    }

    /* Matches the specificity of the per-card rules above so it can undo them. */
    .projects__card[data-project] {
      inset: auto;
    }
  }

