/* 047 v5, Lumen DYNAMICS: what Our Process, the Case Study and Services share beyond theme.css and chrome.css.
   The page head (the hero's light on load, the headline landing line by line), the close every page ends on (the same
   light once more, triggered), the labels, the proximity snap, and the ink of the code-drawn figures.

   THE MOTION MODEL (HANDOFF "The motion model"): nothing is driven by the scroll. Under html.motion each piece is armed in
   its START state; motion.js adds ONE class once when it reaches the reading zone, and a time-based CSS animation plays to
   its end and holds (fill-mode both), whatever the reader does next. Signature moments carry scroll-snap-align: center
   under the page's proximity snap, so the browser glides them into the centre on its own. Transform and opacity (and the
   drawn line's dash offset) only. No .motion (reduced motion, no JS, an old browser): every piece stands finished. */

/* ------------------------------------------------------------------ the snap: the signature moments settle into the centre (motion only) */
html.motion { scroll-snap-type: y proximity; }
.motion .close { scroll-snap-align: center; }

/* ------------------------------------------------------------------ labels and lines (the Services conventions) */
.label--rule { display: inline-flex; align-items: center; gap: 14px; }
.label--rule i { display: block; width: 22px; height: 2px; background: linear-gradient(90deg, var(--bw-oxblood), var(--bw-oxblood-lit)); }
.line { font: 400 clamp(1.125rem, 1rem + .5vw, 1.4375rem)/1.5 var(--sans); color: var(--bw-silver); max-width: 36em; text-wrap: pretty; }
.line--lit { color: var(--bw-white); }
.ln { display: block; -webkit-box-decoration-break: clone; box-decoration-break: clone; }   /* a line that wraps (phones) is lit and swept whole on each of its lines */
main .lead, main .body, main .line, main .foot-note { text-wrap: pretty; }                     /* no lonely last word */

/* ------------------------------------------------------------------ the page head: the hero's light, no plate; the headline's lines land as the light comes up */
.phead .hero__stage, .close .hero__stage { grid-template-columns: minmax(0, 1fr); }
.phead .hero__stage { --hh: round(down, max(460px, 68svh - var(--nav-h)), 1px); }         /* a head of words takes two thirds of the screen, never a whole one
   (ROUND_FINAL2: full-screen sections only where a visual fills them); the Services head, which carries the steel, keeps the screen */
.phead--pitch .hero__stage { --hh: round(down, 100svh - var(--nav-h) - var(--foot), 1px); }
.phead .hero__words, .close .hero__words { max-width: 820px; }
.phead .hero__words .lead, .close .hero__words .lead { max-width: 34em; }
/* desktop: the cloth stands behind the words only, and (no plate to end against) dissolves over the right third of its width, so no
   straight edge or sliced row of stars shows mid-page. Phones keep the theme's full-width cloth (its phone mask has no right fade). */
@media (min-width: 900px) {
  .phead .cloth { right: max(30%, calc(100% - 820px)); }
  .close .cloth { right: max(16%, calc(100% - 1100px)); }       /* the close's cloth runs wider: the ask stands in it, not beside black */
  .phead .cloth, .close .cloth {
    -webkit-mask-image: linear-gradient(270deg, transparent 0, rgba(0, 0, 0, .1) 10%, rgba(0, 0, 0, .45) 26%, #000 46%);
    mask-image: linear-gradient(270deg, transparent 0, rgba(0, 0, 0, .1) 10%, rgba(0, 0, 0, .45) 26%, #000 46%); }
}
/* the head has no seam under it (the seam closes the page): the far corner's deep black fades into the ground before the head
   ends, so no hard edge shows where the first section begins (the close's light is masked at its top for the same reason) */
.phead .hero__light { -webkit-mask-image: linear-gradient(0deg, transparent 0, #000 160px); mask-image: linear-gradient(0deg, transparent 0, #000 160px); }
.phead .hero__words .label--rule, .close .hero__words .label--rule { margin-bottom: -4px; }
@media (prefers-reduced-motion: no-preference) {
  .light .hero__words > h1.display, .light .hero__words > h2.display { animation: none; }   /* the lines carry it, not the block */
  .light .hero__words .ln.sweep { animation: ln-land .8s var(--ease-light) var(--ln-d, .05s) both, sweep-text 1.5s var(--ease-light) .55s both; }
  .light .hero__words .ln:nth-child(2) { --ln-d: .19s; }
  .light .hero__words .ln:nth-child(3) { --ln-d: .33s; }
  .light .hero__words .ln:nth-child(4) { --ln-d: .47s; }
  .light .hero__words > .actions { animation: act-land .9s var(--ease-light) 1.05s both; }
  @keyframes ln-land { from { transform: translateY(32px); opacity: 0; } to { transform: none; opacity: 1; } }
  @keyframes act-land { from { transform: translateY(18px); opacity: 0; } to { transform: none; opacity: 1; } }
}

/* ------------------------------------------------------------------ the close: the hero's light arrives once more (triggered); the seam closes the page */
.close .hero__stage { padding-top: 0; --hh: round(down, max(400px, 58svh), 1px); min-height: var(--hh); }   /* the ask, in the cloth's light; it held 72svh of black */
.close .hero__words { padding-block: 64px; }
.close .hero__stage { overflow: hidden; }       /* the cloth ends at the seam (on phones it was taller than the close and ran on under it) */
/* the close's light: masked at its top (no edge mid-page) and at its foot, so the far corner's deep black does not run on under the
   seam into the strip above the footer */
.close .hero__light { -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 34%, #000 calc(100% - 150px), transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 34%, #000 calc(100% - 150px), transparent 100%); }
.close .foot-note { font: 400 .875rem/1.6 var(--sans); color: var(--bw-gun-300); margin-top: 6px; }
.close .foot-note a { color: var(--bw-silver); text-underline-offset: 3px; }
/* in shadow until the light arrives (the start of the hero's own animations), so nothing jumps when it does */
.motion .close:not(.light) .hero__light { opacity: 0; }
.motion .close:not(.light) .cloth { opacity: .15; }
.motion .close:not(.light) .hero__words > :not(h2) { opacity: .18; }
.motion .close:not(.light) .ln { opacity: 0; transform: translateY(32px); }
.motion .close:not(.light) .ln.sweep { background-image: linear-gradient(105deg, #333435 0%, #333435 30%, #ffffff 38%, #ffffff 41%, #ececE9 50%, #e1e1dd 66.7%, #efefec 82%, var(--bw-white) 100%);
  background-size: 300% 100%; background-position: 0 0; }
@media (prefers-reduced-motion: no-preference) {
  .close.light .hero__words > .actions { animation: act-land .9s var(--ease-light) 1.05s both; }
}

/* ------------------------------------------------------------------ phones and narrow windows */
@media (max-width: 899.98px) {
  .phead .hero__stage { min-height: calc(100svh - var(--foot)); padding-top: var(--nav-h); padding-bottom: 32px; }
  .phead .hero__words { align-self: end; }        /* the cloth fills the top of the screen, the words stand at its foot (centred, a
                                                    head with no buttons left a third of the screen empty under its words) */
  .ln { display: inline; }
  .close .hero__stage { --hh: 0px; min-height: 0; padding-top: 32px; padding-bottom: 24px; }
  .close .cloth { height: auto; bottom: 0; }      /* the cloth fills the close, so its own falloff ends it above the seam */
  .close .hero__words { padding-block: 40px; align-self: start; }
}

/* ------------------------------------------------------------------ the drawings: shared ink (hairlines and resting parts in gunmetal; what the light reaches in silver and white; the eye's red once) */
.gfx { position: relative; margin: 0; width: 100%; }
.gfx svg { display: block; width: 100%; height: auto; overflow: visible; }
.gfx svg.gfx__tall { display: none; }
@media (max-width: 699.98px) { .gfx svg.gfx__wide { display: none; } .gfx svg.gfx__tall { display: block; } }
.gfx text { font-family: var(--mono); font-weight: 450; letter-spacing: .14em; }
.gx-blk, .gx-card, .gx-team { stroke: none; }
.gx-base { fill: none; stroke: var(--bw-gun-600); stroke-width: 1.5; stroke-dasharray: 6 4; }
.gx-lit { fill: none; stroke: var(--bw-silver); stroke-width: 2; stroke-dasharray: 1; stroke-dashoffset: 0; stroke-linejoin: miter; }
.gx-edge { fill: none; stroke: url(#gx-edge-fade); stroke-width: 1.5; }   /* the key light along a top and right edge: full at the corner nearest
   the lamp, falling to nothing at both ends (it read as a broken stroke when it switched on mid-edge at full white) */
.gx-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.gx-card-line, .gx-st-line, .gx-team-line { fill: none; stroke: var(--bw-gun-400); stroke-width: 1; }
.gx-st-line, .gx-team-line.is-lit { stroke: var(--bw-silver); }
.gx-st-core, .gx-team-core, .gx-rec-dot { fill: var(--bw-white); }
.gx-num { fill: var(--bw-gun-300); font-size: 13px; }
.gx-lab-t { fill: var(--bw-silver); font-size: 13px; }
.gx-lab-t--lg { font-size: 15px; }
.gx-mark { fill: none; stroke: var(--bw-silver); stroke-width: 1.4; vector-effect: non-scaling-stroke; }
.gx-contour { fill: none; stroke: rgba(105, 106, 105, .22); stroke-width: 1; }
.gx-rule { stroke: var(--bw-union-line); stroke-width: 1; }
.gx-check { fill: none; stroke: var(--bw-white); stroke-width: 2; }
.gx-handset { fill: var(--bw-white); }
.gx-ring { fill: none; stroke: var(--bw-silver); stroke-width: 1.5; }
@media (prefers-reduced-motion: no-preference) {
  @keyframes gx-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
  @keyframes gx-on { from { opacity: 0; } to { opacity: 1; } }
  @keyframes gx-on-25 { from { opacity: .25; } to { opacity: 1; } }
  @keyframes gx-pop { from { opacity: 0; transform: scale(.4); } 70% { opacity: 1; transform: scale(1.18); } to { opacity: 1; transform: scale(1); } }
  @keyframes gx-flash { 0% { opacity: 0; } 30% { opacity: 1; } 55% { opacity: .35; } 100% { opacity: 1; } }
}
