/* ==========================================================================
   Marker Text - layout
   ==========================================================================
   Structure only. Visual settings live in marker-text-theme.css.

   Markup after initialisation:

   <h2 class="marker-text is-ready">
     <span class="marker-text__source">Original text</span>   hidden, sets width
     <span class="marker-text__stage" aria-hidden="true">     <svg> goes here
   </h2>

   With .marker-arrow on the element, the stage also holds
   <span class="marker-arrow__stage"> — see marker-text-arrow.js. Placement
   modifiers for it live in marker-text-theme.css, because where the arrow
   goes is a design choice rather than the component's structure.

   Three states:

   .marker-text             untouched — plain text, the no-JS baseline
   .marker-text.is-ready    the drawing is in place and takes over
   .marker-text.is-static   JS gave up — fall back to plain text

   Everything the component does is wrapped in prefers-reduced-motion:
   no-preference, so a reader who does not want motion always gets the
   plain text, whatever state the classes happen to be in.
   ========================================================================== */

.marker-text__stage {
    display: none;
}

@media (prefers-reduced-motion: no-preference) {
    /* The element still holds plain text until the library, the font JSON and
       the web fonts have all loaded, and that text would be painted in the
       meantime — the flash we are avoiding. Hidden rather than removed, so
       the space is already reserved and nothing shifts when the drawing
       arrives. Same .js-gated trick as chain-animations: no JavaScript means
       no .js class, and the text is never hidden in the first place. */
    .js .marker-text {
        visibility: hidden;
    }

    .js .marker-text.is-ready,
    .js .marker-text.is-static {
        visibility: visible;
    }

    .js .marker-text.is-ready:not(.is-static) .marker-text__stage {
        display: block;
        width: 100%;
        /* The heading's own line-height would add a gap under the drawing,
           which sizes itself from the SVG. */
        line-height: 0;
        /* Anchor for the arrow, which is positioned against ink coordinates
           measured in this element's own box. */
        position: relative;
    }

    .js .marker-text.is-ready:not(.is-static) .marker-text__stage svg {
        display: block;
        /* Descender tails and umlaut dots can sit outside the measured box. */
        overflow: visible;
    }

    /* Hidden, but deliberately left in normal flow: the source text is also
       what gives the element its width. Ancestors that size to their content
       (a flex item, an inline-block) would otherwise collapse to zero once
       the text is taken out of flow, leaving the drawing no width to lay out
       in.

       Height is zeroed so it costs no vertical space, and the overflow clip
       hides it. Unlike display:none or visibility:hidden, this keeps the text
       in the accessibility tree. */
    .js .marker-text.is-ready:not(.is-static) .marker-text__source {
        display: block;
        height: 0;
        overflow: hidden;
    }

    /* Arrow. Only ever injected inside the stage, which is already
       aria-hidden, so it needs no accessibility handling of its own.

       CSS sizes it by width alone; the height comes from the chosen shape's
       aspect ratio, which marker-text-arrow.js sets inline. */
    .marker-arrow__stage {
        position: absolute;
        display: block;
        width: var(--marker-arrow-size);
        aspect-ratio: var(--marker-arrow-aspect, 1);
        pointer-events: none;
    }

    .marker-arrow__stage svg {
        display: block;
        width: 100%;
        height: 100%;
        /* Round line caps reach a little past the viewBox. */
        overflow: visible;
    }

    /* The arrow may already be in the DOM when the drawing is abandoned
       mid-flight, e.g. a resize that leaves the stage without a width. */
    .js .marker-text.is-static .marker-arrow__stage {
        display: none;
    }
}
