/* =====================================================================
   Sticky ghost heading.

   The service title and its eyebrow stay with you down the left of the
   section. As the next section's divider comes up to meet them, they
   decode away character by character rather than being shoved off, and
   decode back when you scroll up.

   The two-column layout and the sticky already exist in site.css as
   `.svc` / `.svc__head`; this file only adds what the decode needs. The
   colours are the site's own tokens rather than the hard-coded values in
   the specification, so this block cannot drift away from the rest of
   the page if those tokens change.
   ===================================================================== */

.sgh {
    --sgh-top: 88px;
}

/* The grid cell and the thing that pins have to be two different
   elements. site.css makes .svc__head both the left column and the
   sticky, and pinning it with position:fixed takes the column out of the
   grid entirely — the two-column layout collapses to one and the body
   text slides left to fill the space. The cell stays put; the box inside
   it does the moving. */
.sgh .svc__head {
    position: static;

    /* And it has to fill the row. A sticky element can only travel inside
       its parent's box, and .svc sets align-items:start, so this cell
       would otherwise shrink to the height of the heading — about 110px —
       leaving the sticky nothing to move within. It would sit still and
       never reach the point where it decodes. */
    align-self: stretch;
    height: 100%;
}

.sgh__sticky {
    position: sticky;
    top: var(--sgh-top);
}

/* The eyebrow is two chips (.svc__id, .svc__tag) styled in site.css.
   The decode only runs on the first span, the solid accent one, so its
   scramble glyphs need a light colour or they vanish into the fill. */
.svc__id .sgh__ch[data-glyph="true"] { color: #F7F4F1; }

/* Words stay whole so wrapping still breaks between words, not inside
   them, once every character is its own element. */
.sgh__word {
    display: inline-block;
    white-space: nowrap;
}

/* Natural letter spacing, no width locking. Blanking is opacity, so the
   box keeps its place and the character fades instead of the line
   reflowing under it. */
.sgh__ch {
    display: inline-block;
    transition: opacity 110ms linear;
    will-change: opacity;
}

.sgh__ch[data-blank="true"] { opacity: 0; }

.sgh__ch[data-glyph="true"] {
    color: var(--accent, #B8471F);
    animation: sgh-jitter 150ms steps(3, end) infinite;
}

/* Sub-pixel noise while a character is unresolved. Pure CSS, so it costs
   nothing per frame. */
@keyframes sgh-jitter {
    0%   { transform: translate(-0.4px, -0.5px); }
    33%  { transform: translate(0.5px,  0.4px); }
    66%  { transform: translate(-0.3px, 0.5px); }
    100% { transform: translate(0.4px, -0.4px); }
}

/* Single column below this, so there is nothing to stick and nothing to
   decode away from. */
@media (max-width: 980px) {
    .sgh__sticky { position: static; }
    .sgh__ch { opacity: 1 !important; }
}

@media (prefers-reduced-motion: reduce) {
    .sgh__ch { transition: none; animation: none; opacity: 1 !important; }
}
