/*
  Scroll storytelling — the connective tissue of the Home.

  Every rule that MOVES anything is nested under [data-story-armed], which scroll-story.js sets only
  when the visitor has not asked for reduced motion and the site is not in edit mode. Without that
  attribute this file contributes layout and nothing else, so the reduced-motion Home is not a
  degraded Home — it is the same page holding still.

  The progress value --cg-story (0 → 1) is published per element by that module. Only transform and
  opacity are driven by it: both are compositor properties, so a frame costs no layout and no paint,
  and nothing here can cause layout shift.
*/

/* =========================================================================
   1. THE PINNED PROCESS PANEL
   The one pinned moment on the page. Research on a reference site found a single sticky panel across
   a 23,500px document — one is a device, five is a gimmick.

   This is plain CSS sticky and needs no JavaScript, so it survives reduced motion untouched: it does
   not animate, it does not trap scrolling, and the scrollbar keeps telling the truth. The runway is
   the natural height of the step list beside it, not an artificial spacer.
   ========================================================================= */
@media (min-width: 62rem) {
    .craft__layout {
        align-items: start;
    }

    .craft__figure {
        position: sticky;
        /* Clear of the sticky site header, with breathing room above the image. */
        top: calc(var(--cg-header-height, 4.5rem) + var(--space-lg));
    }
}

/* =========================================================================
   2. DEPTH
   Foreground and background moving at slightly different rates is what makes a flat page feel like it
   has air in it. The displacement is deliberately small — a few percent of the element's own height.
   Large parallax reads as a broken page on a laptop trackpad.
   ========================================================================= */
[data-story-armed] [data-story="lift"] {
    /* -1 → +1 across the element's travel, scaled to a visible offset. A 20px drift is a number in a
       spec, not something a visitor perceives; this is large enough to read as depth. */
    --cg-story-shift: calc((var(--cg-story, 0.5) - 0.5) * 2);
    transform: translate3d(0, calc(var(--cg-story-shift) * -3.5rem), 0);
    will-change: transform;
}

/* =========================================================================
   2b. THE HERO HANDOFF
   The hero photograph does not simply scroll away. It scales up and darkens as the page leaves it, so
   the section below takes over from an image still in motion rather than beginning at a hard edge.

   Only the second half of the hero's travel is used: while the hero is the thing being read it holds
   perfectly still, and the movement belongs entirely to the departure.
   ========================================================================= */
[data-story-armed] [data-story="hero"] {
    --cg-exit: max(0, min(1, calc((var(--cg-story, 0) - 0.5) * 2.4)));
    transform: scale(calc(1 + 0.16 * var(--cg-exit)));
    will-change: transform;
}

/* The darkening fades the photograph towards the hero's own black ground (opacity is composited;
   a brightness filter on a full-bleed photograph would repaint it on every scroll frame). It is NOT
   the figure's ::after: that pseudo-element is the hero's legibility scrim (home.css), and replacing
   its background with flat black here removed the scrim for every visitor with the story armed —
   the headline sat on the bare photograph. */
[data-story-armed] [data-story="hero"] > img {
    opacity: calc(1 - 0.55 * var(--cg-exit));
}

/* =========================================================================
   2c. THE ATELIER SEQUENCE — the page's one major transformation

   The pinned photograph does not sit still while a list scrolls past it. Across the section it
   RESOLVES: it starts slightly small and veiled in Ceramigeek red — the piece as raw, unfired clay —
   and ends full size and clear, the finished piece, which then hands off to the store below.

   Measured from the reference site: a pinned panel there travels scale 1.0 → 0.9 with opacity 1 → 0
   over roughly one viewport of runway. That magnitude is what makes the movement legible; a 1.2% scale
   is not perceptible and was the reason the previous attempt read as "sections that fade in".
   ========================================================================= */
[data-story-armed] .craft__figure--resolve {
    --cg-resolve: max(0, min(1, calc((var(--cg-story, 0) - 0.15) * 1.6)));
    transform: scale(calc(0.9 + 0.14 * var(--cg-resolve)));
    transform-origin: center top;
    will-change: transform;
}

/* The red veil is the unfired state receding. It is brand-native — the same red the site uses as its
   maker's mark — and it clears from the bottom up, the way a glaze fires out. */
[data-story-armed] .craft__figure--resolve > img {
    -webkit-mask-image: linear-gradient(to top,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 1) calc(var(--cg-resolve) * 100%),
        rgba(0, 0, 0, 0.55) calc(var(--cg-resolve) * 100% + 18%),
        rgba(0, 0, 0, 0.55) 100%);
    mask-image: linear-gradient(to top,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 1) calc(var(--cg-resolve) * 100%),
        rgba(0, 0, 0, 0.55) calc(var(--cg-resolve) * 100% + 18%),
        rgba(0, 0, 0, 0.55) 100%);
}

/* =========================================================================
   2d. STAGES — one step of the process lit at a time
   Six steps revealed together are a list. One lit at a time is a sequence, and the difference is the
   whole point of pinning the photograph beside them.
   ========================================================================= */
[data-story-armed] [data-story-sequence] .craft__step {
    opacity: 0.32;
    transform: translate3d(0, 0, 0);
    transition: opacity var(--transition-base), transform var(--transition-base);
}

[data-story-armed] [data-story-sequence] .craft__step.is-stage-active {
    opacity: 1;
}

/* The active step's number carries the brand red and grows a rule beside it, so the eye is told where
   in the process it currently is without reading a single word. */
[data-story-armed] [data-story-sequence] .craft__step .craft__num {
    transition: color var(--transition-base);
}

[data-story-armed] [data-story-sequence] .craft__step.is-stage-active .craft__num {
    color: var(--color-accent);
}

[data-story-armed] [data-story-sequence] .craft__step::before {
    content: "";
    position: absolute;
    inset-inline-start: -1rem;
    inset-block: 0.15rem;
    inline-size: 2px;
    background: var(--color-accent);
    transform: scaleY(0);
    transform-origin: top center;
    transition: transform var(--transition-base);
}

[data-story-armed] [data-story-sequence] .craft__step.is-stage-active::before {
    transform: scaleY(1);
}

[data-story-armed] [data-story-sequence] .craft__step { position: relative; }

/* =========================================================================
   2e. THE RUNWAY

   Without this the whole six-step sequence went past in about 700px — the pinned photograph resolved
   from raw to finished in under one flick of a trackpad, and the visitor saw a list scroll by rather
   than a process unfold. Measured: the section's figure travelled from +2770 to -557 between 40% and
   50% of the page.

   So each step is given roughly half a viewport of its own. This is NOT "making the section taller":
   the height exists so that something can progress through it — one step lights while the previous
   stands down, and the photograph clears a little further with each one.

   Desktop and armed only. A reduced-motion or mobile visitor gets the compact list, because a runway
   with nothing travelling along it is just a very long page.
   ========================================================================= */
@media (min-width: 62rem) {
    [data-story-armed] [data-story-sequence] .craft__step {
        min-block-size: 46vh;
        align-content: center;
    }
}

/* =========================================================================
   2f. THE STACK — the page's second major sequence, and its strongest

   Three chapters (the mould, the Academy, Nathy) pin at the SAME height and recede as the next rises
   over them: each scales back and dims while the one behind it takes the foreground. Scrolling stops
   being "next section, next section" and becomes one thing handing over to the next.

   This is the mechanic measured on the reference site (Documents/UxResearchLog.md): a pinned panel
   travelling scale 1.0 → 0.9 with opacity 1 → 0 over roughly a viewport of runway, while the incoming
   panel arrives slightly oversized. The numbers here are deliberately a little gentler — Ceramigeek's
   cards carry photographs of real pieces, and dimming them to nothing hides the product.

   PROGRESS COMES FROM THE STACK, NOT THE CARD. A sticky element stops moving the moment it pins, so a
   card measuring itself would freeze exactly when the effect is supposed to run. The container is not
   sticky, so it keeps travelling; custom properties inherit, so every card reads the same clock.

   No scroll hijacking: `position: sticky` and a transform. The scrollbar stays truthful, the wheel is
   never captured, and the visitor can leave at any moment.
   ========================================================================= */
@media (min-width: 62rem) {
    [data-story-armed] .story-stack {
        /* The stack no longer has a fixed membership: the Home composes its bands from the CMS, so a
           run can be two cards or four depending on what the owner has switched on and how they
           ordered it. The count comes from the markup and the slice arithmetic follows it. */
        --cg-stack-count: 3;
        position: relative;
    }

    [data-story-armed] .story-stack[data-stack-count="2"] { --cg-stack-count: 2; }
    [data-story-armed] .story-stack[data-stack-count="3"] { --cg-stack-count: 3; }
    [data-story-armed] .story-stack[data-stack-count="4"] { --cg-stack-count: 4; }

    [data-story-armed] .story-stack > section {
        position: sticky;

        /* EACH CARD PINS A LITTLE LOWER THAN THE ONE BEFORE IT.
           Pinned at an identical offset the cards align exactly, the incoming one covers the previous
           completely, and the recession happens where nobody can see it — the page looks like ordinary
           sections again. The stagger leaves a visible sliver of every card already in the stack, which
           is what makes the depth legible. */
        top: calc(var(--cg-header-height, 4.5rem) + var(--space-md) + var(--cg-index) * 2.1rem);

        /* 75% of the viewport, measured on the reference site — every pinned panel there is exactly
           that wide, with a 16px radius. At 98% a card is indistinguishable from the page it sits on;
           at 75% it reads as an object, and the shrink is visible at its edges. */
        inline-size: min(100%, 75vw);
        margin-inline: auto;
        border-radius: var(--radius-lg);
        overflow: hidden;
        box-shadow: 0 -1.25rem 2.5rem rgba(16, 14, 14, 0.16);
        transform-origin: center top;

        /* Runway sized for the SHORTEST stack the page can compose, which is two cards. At 42vh a
           two-card stack gave the first card about 350px of pinned travel — the recession happened,
           and happened too fast to be felt. 75vh roughly doubles it. A card is pinned for as long as
           the container has room beneath it, so a longer stack simply gets more. */
        margin-block-end: 75vh;

        /* How far the NEXT card has come over this one, 0 → 1. Each card owns one slice of the
           stack's travel, and starts receding once the slice after its own begins. */
        --cg-slice: calc(1 / var(--cg-stack-count));
        --cg-cover: max(0, min(1, calc((var(--cg-story, 0) - (var(--cg-index) + 1) * var(--cg-slice)) / var(--cg-slice))));

        transform: scale(calc(1 - 0.08 * var(--cg-cover)));
        opacity: calc(1 - 0.55 * var(--cg-cover));
        will-change: transform, opacity;
    }

    /* Index assigned in CSS rather than an inline style: the site's Content-Security-Policy forbids
       inline style attributes, so a `style="--cg-index:1"` would simply be dropped. */
    [data-story-armed] .story-stack > section:nth-of-type(1) { --cg-index: 0; z-index: 1; }
    [data-story-armed] .story-stack > section:nth-of-type(2) { --cg-index: 1; z-index: 2; }
    [data-story-armed] .story-stack > section:nth-of-type(3) { --cg-index: 2; z-index: 3; }
    [data-story-armed] .story-stack > section:nth-of-type(4) { --cg-index: 3; z-index: 4; }

    /* The last card has nothing coming over it, so it never recedes — it is the handoff into the
       atelier section below. */
    [data-story-armed] .story-stack > section:last-of-type {
        --cg-cover: 0;
        margin-block-end: 0;
    }
}

/*
  will-change is scoped to elements that are ACTUALLY animating, not sprayed across the document. The
  reference site promoted 94 nodes to their own compositor layers permanently; that memory cost is paid
  whether or not anything moves.
*/

/* =========================================================================
   3. CONTINUITY — the red thread
   A single hairline in Ceramigeek red that runs down the page THROUGH section boundaries, so one
   section visually hands off to the next instead of ending at a hard edge. Brand-native: the red rule
   is already the site's punctuation mark. Decorative only, so it is hidden from assistive technology.
   ========================================================================= */
.story-thread {
    position: relative;
    display: block;
    block-size: var(--space-2xl);
    margin: 0;
    overflow: hidden;
}

.story-thread::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: 50%;
    inline-size: 2px;
    background: linear-gradient(to bottom,
        rgba(198, 40, 40, 0) 0%,
        var(--cg-red) 30%,
        var(--cg-red) 70%,
        rgba(198, 40, 40, 0) 100%);
    transform: translateX(-50%);
}

/* Armed: the thread draws itself as the boundary is crossed, so the handoff reads as continuous
   rather than as a divider that was always there. */
[data-story-armed] .story-thread::before {
    transform: translateX(-50%) scaleY(var(--cg-story, 1));
    transform-origin: top center;
}

/* =========================================================================
   4. REDUCED MOTION AND SMALL SCREENS

   Reduced motion: the armed rules simply never apply, because the attribute is never set. This block
   is belt-and-braces for anything that might still carry a stale inline --cg-story.

   Mobile: measurement of the reference site showed its pinned sequences REMOVED below ~768px, not
   compressed — the section carrying the sticky panel lost 74% of its height. A pinned panel on a
   375px screen eats the whole viewport and turns reading into a fight. So mobile gets the same content
   as a plain, well-spaced stack, which is a deliberate composition rather than a fallback.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
    [data-story] {
        transform: none !important;
        will-change: auto !important;
    }

    /* The veil and the dimming are progress-driven, and with no progress they would freeze at their
       starting values — a permanently half-masked photograph and five permanently faint steps. Reduced
       motion must show the finished composition, not the first frame of an animation that never runs. */
    .craft__figure--resolve > img {
        -webkit-mask-image: none !important;
        mask-image: none !important;
    }

    [data-story-sequence] .craft__step {
        opacity: 1 !important;
        transition: none !important;
    }

    [data-story-sequence] .craft__step::before { display: none; }
    [data-story="hero"]::after { display: none; }

    .story-thread::before {
        transform: translateX(-50%) !important;
    }
}

/* Mobile is a different composition, not a narrower desktop. The pinned sequence and its veil are
   removed rather than compressed: a pinned panel on a 390px screen eats the viewport, and a step lit
   one at a time on a small screen means most of the list is faint at any moment. The content stays,
   complete and legible, as a plain stack. */
@media (max-width: 61.99rem) {
    [data-story] {
        transform: none !important;
        will-change: auto !important;
    }

    .craft__figure--resolve > img {
        -webkit-mask-image: none !important;
        mask-image: none !important;
    }

    [data-story-sequence] .craft__step {
        opacity: 1 !important;
    }

    [data-story-sequence] .craft__step::before { display: none; }
    [data-story="hero"]::after { display: none; }

    .story-thread {
        block-size: var(--space-lg);
    }
}

/*
  CONTENT INSIDE A PINNED CARD IS NEVER HELD BACK.

  The reveal effect lights an element when it crosses the middle of the viewport. That is right for a
  band the page scrolls past, and wrong for a card that SLIDES UP and pins: the card arrives from the
  bottom edge long before its contents reach the middle, so for several hundred pixels the visitor
  sees a large empty panel rising over the card beneath it — and, because it is opaque, cropping that
  card's button in half.

  The owner reported exactly that as "a section that looks deleted or lost its buttons". It was not
  deleted; it was a blank card arriving early. Inside the stack the card's own entrance IS the effect,
  so the contents come with it.
*/
[data-reveal-armed] .story-stack .reveal {
    opacity: 1;
    transform: none;
}
