/* 047 v5, the Case Study (1 Vision USA Security), the Captain's success story (ROUND_FINAL2 section 4): built ON theme.css,
   chrome.css and dyn.css. Four sections, each with one visual that fills its screen and one animation played for the reader:
     the opening    the words, and beside them the Services frame BUILT TO SCALE: three storeys lowered into place, a rake of light
     the footprint  the lit 24-state map (the page's signature stop, centred by the snap): a line of light runs west to east
     the platform   the hub: one lit core, six parts around it lighting in turn, the five Connect names, the closing statement
     the close      the hero's light once more; beside the words the same frame, the next storey lowered onto the waiting plates
   Every piece is armed in its START state under html.motion and plays when motion.js adds its class (it unwinds when the reader
   goes back above it and replays on the way down). Without .motion every piece stands finished. Transform, opacity and a drawn
   line's dash offset only. No animation or display:none inside a width query on an animated piece (Chromium's full-page capture
   resizes the page for a frame, which would restart it): the layouts change, the pieces do not. */

/* ------------------------------------------------------------------ the opening: the partner named beside the badge; the frame beside the words */
.phead--case .client { display: flex; align-items: center; gap: 14px; font: 500 .9375rem/1.3 var(--sans); color: var(--bw-white); }
.client__logo { width: 48px; height: 48px; flex: none; }
.phead--case .display { max-width: 16.5em; }       /* BUILT TO SCALE / WITH THE FASTEST-GROWING / ADT DEALER IN THE COUNTRY. (the last line 16.2em) */
.phead--case .nw { white-space: nowrap; }          /* FASTEST-GROWING never breaks at its hyphen on a phone */
.tower { position: relative; margin: 0; pointer-events: none; }
.tower svg { display: block; width: 100%; height: auto; overflow: visible; }
@media (min-width: 1100px) {
  /* the words keep the headline's three lines (16.6em of the display size); the frame takes the rest, standing in the lamp's light */
  .phead--case .hero__stage, .close--case .hero__stage { grid-template-columns: minmax(0, calc(16.6 * clamp(1.75rem, 1.2rem + 2vw, 3rem))) minmax(0, 1fr); column-gap: clamp(24px, 3vw, 56px); }
  /* exactly one screen (dyn.css's head), so the map starts at the fold and can leave the screen when the reader goes back to
     the top (it unwinds, and replays on the way down); the frame fills the height beside the words */
  .phead--case .hero__stage { --hh: round(down, max(600px, 100svh - var(--nav-h) - var(--foot)), 1px); }
  .phead--case .hero__words { padding-block: 24px; }
  /* the frame runs out into the gutter on the lamp's side, as tall as the opening allows (its box: 532 x 780) */
  .tower--open { align-self: center; justify-self: end; width: min(calc(100% + var(--gutter) - 12px), calc((var(--hh) - 36px) * 532 / 780)); margin-right: calc(12px - var(--gutter)); }
  .close--case .hero__stage { --hh: round(down, max(560px, 76svh), 1px); }
  .tower--next { align-self: center; justify-self: end; width: min(calc(100% + var(--gutter) - 12px), calc((var(--hh) - 24px) * 536 / 900)); margin-right: calc(12px - var(--gutter)); }   /* its box: 536 x 900 */
}
@media (max-width: 1099.98px) {
  .tower { justify-self: center; width: min(100%, 340px); }
  .tower--open { margin-top: 4px; }
  .tower--next { margin: -8px 0 8px; }
}
@media (max-width: 899.98px) {
  .phead--case .hero__stage { min-height: 0; padding-bottom: 8px; }
  .phead--case .hero__words { align-self: start; }
  .tower--open { width: min(100%, 262px); }
  .tower--next { width: min(100%, 236px); }
  .close--case .hero__stage { padding-bottom: 8px; }
}
/* the steel (tower.py): every face flat-shaded by the one lamp; the waiting plates' far edges glint when the light reaches them */
.tw-glint { fill: none; stroke: #fefefd; stroke-width: 1.2; opacity: 0; }
html:not(.motion) .tw-glint { opacity: .55; }
.tw-rake { transform-box: fill-box; transform: translateX(400%); }      /* at rest: the rake has crossed (it travels in its own widths) */
/* START STATES (motion): the opening's storeys wait above their seats, in shadow; the close's next storey waits above the plates */
.motion .tower--open .tw-mod.m1 { opacity: 0; transform: translateY(14px); }
.motion .tower--open .tw-mod.m2, .motion .tower--open .tw-mod.m3, .motion .tower--open .tw-mod.m4 { opacity: 0; transform: translateY(-46px); }
.motion .tower--open .tw-wait { opacity: 0; }
.motion .tower .tw-rake { transform: none; }
.motion .tower--next .tw-next, .motion .tower--next .tw-wait { opacity: 0; transform: translateY(-64px); }   /* the plates come with their storey */
@media (prefers-reduced-motion: no-preference) {
  /* the opening, 3.1 s: the first storey comes up out of the shadow; the second, third and fourth are lowered onto the one below,
     accelerating, a hard stop (weight, no bounce); the waiting plates come up; one rake of light crosses the frame; the plates glint */
  .tower--open.is-on .tw-mod.m1 { animation: tw-rise .8s var(--ease-light) .1s both; }
  .tower--open.is-on .tw-mod.m2 { animation: tw-lower .6s cubic-bezier(.55, 0, 1, .45) .5s both; }
  .tower--open.is-on .tw-mod.m3 { animation: tw-lower .6s cubic-bezier(.55, 0, 1, .45) .92s both; }
  .tower--open.is-on .tw-mod.m4 { animation: tw-lower .6s cubic-bezier(.55, 0, 1, .45) 1.34s both; }
  .tower--open.is-on .tw-wait { animation: gx-on .4s var(--ease-light) 1.86s both; }
  .tower--open.is-on .tw-rake { animation: tw-rake 1s cubic-bezier(.4, 0, .25, 1) 1.95s both; }
  .tower--open.is-on .tw-glint { animation: tw-glint .5s var(--ease-light) 2.6s both; }
  /* the close, 2.3 s: the next storey is lowered onto the waiting plates; the rake crosses the whole frame; the new plates glint */
  .tower--next.is-on .tw-next, .tower--next.is-on .tw-wait { animation: tw-lower-far .78s cubic-bezier(.55, 0, 1, .45) .3s both; }
  .tower--next.is-on .tw-rake { animation: tw-rake 1s cubic-bezier(.4, 0, .25, 1) 1.15s both; }
  .tower--next.is-on .tw-glint { animation: tw-glint .5s var(--ease-light) 1.8s both; }
  @keyframes tw-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
  @keyframes tw-lower { 0% { opacity: 0; transform: translateY(-46px); } 35% { opacity: 1; } 100% { opacity: 1; transform: none; } }
  @keyframes tw-lower-far { 0% { opacity: 0; transform: translateY(-64px); } 30% { opacity: 1; } 100% { opacity: 1; transform: none; } }
  @keyframes tw-rake { from { transform: none; } to { transform: translateX(400%); } }
  @keyframes tw-glint { 0% { opacity: 0; } 40% { opacity: 1; } 100% { opacity: .55; } }
}

/* ------------------------------------------------------------------ the footprint: the lit map, the page's signature stop */
.map { position: relative; isolation: isolate; padding-block: 40px; }
.motion .map { scroll-snap-align: center; }       /* the snap glides the map into the middle of the screen below the header's bar; the
                                                     section is as tall as the map (no forced full screen): the neighbours show above and below */
.map__in { display: grid; gap: 26px; justify-items: start; }
.map__head { display: grid; gap: 18px; justify-items: start; }
.gfx--usmap { justify-self: center; width: 100%; max-width: min(100%, calc((100svh - 300px - var(--bar-h)) * 951 / 636)); }   /* the whole moment fits under the bar */
@media (min-width: 1100px) {
  /* the words on the left, the map as large as the screen allows on the right */
  .map__in { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); grid-template-rows: auto auto; column-gap: var(--gap); row-gap: 28px; align-items: end; }
  .map__head { grid-column: 1; grid-row: 1; }
  .map__line { grid-column: 1; grid-row: 2; align-self: start; }
  .gfx--usmap { grid-column: 2; grid-row: 1 / span 2; align-self: center; max-width: min(100%, calc((100svh - var(--bar-h) - 112px) * 951 / 636)); }
}
.us-st { fill: rgba(254, 254, 253, .015); stroke: rgba(254, 254, 253, .16); stroke-width: .7; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.us-st--lit { fill: url(#us-litfill); stroke: rgba(223, 223, 219, .85); stroke-width: .9; }
.us-fl { fill: var(--bw-white); opacity: 0; pointer-events: none; }
.us-line-base { fill: var(--bw-gun-700); }
.us-line { fill: var(--bw-white); transform-box: fill-box; transform-origin: left center; }
.us-tick { fill: var(--bw-silver); }
.motion .map .us-st--lit { fill-opacity: 0; stroke-opacity: 0; }
.motion .map .us-line { transform: scaleX(0); }
.motion .map .us-tick--end { opacity: 0; }
.motion .map .map__line { opacity: 0; transform: translateY(12px); }
@media (prefers-reduced-motion: no-preference) {
  /* 2.6 s from the trigger: the line of light runs west to east under the map (1.7 s); each state flashes white and settles lit as the line passes
     its centre (case-study.map.css carries every state's moment); the east tick lights; the line of words rises */
  .map.is-on .us-line { animation: line-run 1.7s linear .1s both; }
  .map.is-on .us-st--lit { animation: state-on .55s var(--ease-light) both; }
  .map.is-on .us-fl { animation: state-flash .75s var(--ease-light) both; }
  .map.is-on .us-tick--end { animation: gx-on .3s var(--ease-light) 1.8s both; }
  .map.is-on .map__line { animation: words-up .7s var(--ease-light) 1.9s both; }
  @keyframes line-run { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  @keyframes state-on { from { fill-opacity: 0; stroke-opacity: 0; } to { fill-opacity: 1; stroke-opacity: 1; } }
  @keyframes state-flash { 0% { opacity: 0; } 35% { opacity: .55; } 100% { opacity: 0; } }
  @keyframes words-up { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
}

/* ------------------------------------------------------------------ the platform: one lit core, six parts around it, lighting in turn */
.platform { position: relative; isolation: isolate; padding-block: 48px 72px; }
.platform::before { content: ""; position: absolute; z-index: -1; inset: 0; pointer-events: none;      /* the lamp's light pooled on the hub, nothing at the edges */
  background: radial-gradient(38% 46% at 56% 58%, rgba(185, 195, 220, .055) 0%, rgba(143, 155, 187, .02) 55%, transparent 100%); }
.platform__in { display: grid; gap: 40px; }
.platform__head { display: grid; gap: 18px; justify-items: start; }
.platform__h { max-width: none; }
.hub { display: grid; gap: 30px; justify-items: center; }
.hub__stage { position: relative; width: 100%; }
.hub__parts { list-style: none; margin: 0; padding: 0; }
.part__name { color: var(--bw-white); }
.part__line { font: 400 1rem/1.5 var(--sans); color: var(--bw-silver); text-wrap: pretty; }
/* the core: a lit block (the card's navy, a hairline, the lamp catching its top and right edges), a white heart, Connect beneath it */
.hub__core { position: absolute; z-index: 1; width: 136px; height: 136px; display: grid; place-items: center; align-content: center; gap: 18px;
  background: linear-gradient(200deg, #16254e 0%, #0a1433 38%, #05070f 100%); box-shadow: inset 0 0 0 1px var(--bw-silver), 0 18px 48px -12px rgba(0, 0, 0, .9); }
.hub__glow { position: absolute; inset: -46px; pointer-events: none; background: radial-gradient(closest-side, rgba(223, 228, 240, .16), rgba(185, 195, 220, .05) 55%, transparent); }
.hub__edge { position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, transparent 0%, var(--light-1) 30%, var(--light-4) 100%) top / 100% 1px no-repeat,
              linear-gradient(180deg, var(--light-4) 0%, var(--light-2) 40%, transparent 85%) right / 1px 100% no-repeat; }
.hub__dot { position: relative; width: 16px; height: 16px; background: var(--bw-white); box-shadow: 0 0 18px 3px rgba(254, 254, 253, .35); }
.hub__label { position: relative; font: 450 .75rem/1 var(--mono); letter-spacing: .2em; text-transform: uppercase; color: var(--bw-silver); }
/* the spokes and the parts' blocks (hub.py) */
.hub__spokes { position: absolute; pointer-events: none; overflow: visible; }
.hub-port { fill: var(--bw-silver); }
.hub-mk__core { fill: var(--bw-white); transform-box: fill-box; transform-origin: center; }
.hub-mk__edge { stroke: rgba(254, 254, 253, .85); }
/* the five Connect names, in small mono; the closing statement */
.hub__names { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 0; }
.hub__names li { position: relative; font: 400 .8125rem/1.4 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--bw-gun-300); padding-inline: 16px; }
.hub__names li strong { font-weight: 500; color: var(--bw-white); }
.hub__names li + li::before { content: "\00b7"; position: absolute; left: -.3em; color: var(--bw-gun-400); }
.hub__statement { font: 600 clamp(1.25rem, 1rem + .9vw, 1.75rem)/1.2 var(--sans); letter-spacing: .05em; text-transform: uppercase; text-align: center; text-wrap: balance; font-feature-settings: "case"; }
@media (min-width: 1100px) {
  /* three parts down each side of the core; every part's name sits on its row's centre line, where its spoke arrives (hub.py: W 440, ROW 128) */
  .hub__parts { display: grid; grid-template-columns: minmax(0, 1fr) 440px minmax(0, 1fr); grid-template-rows: repeat(3, 128px); }
  .part { padding-top: 52px; display: grid; gap: 8px; align-content: start; }
  .part:nth-child(-n+3) { grid-column: 1; text-align: right; justify-items: end; padding-right: 26px; }
  .part:nth-child(n+4) { grid-column: 3; padding-left: 26px; }
  .part:nth-child(1), .part:nth-child(4) { grid-row: 1; }
  .part:nth-child(2), .part:nth-child(5) { grid-row: 2; }
  .part:nth-child(3), .part:nth-child(6) { grid-row: 3; }
  .part__line { max-width: 34ch; }
  .hub__spokes { left: 50%; top: 0; width: 440px; height: 384px; transform: translateX(-50%); }
  .hub__core { left: 50%; top: 192px; transform: translate(-50%, -50%); }
  .part__mark { display: none; }
  .hub__stage { padding-bottom: 28px; }      /* the third row's lines run on below the drawing */
}
@media (max-width: 1099.98px) {
  /* phones and narrow windows: the core at the top, a trunk running down from it, each part branching off the trunk */
  .hub { justify-items: start; }
  .hub__spokes { visibility: hidden; left: 0; top: 0; width: 1px; height: 1px; }
  .hub__core { position: relative; width: 84px; height: 84px; gap: 12px; }
  .hub__dot { width: 12px; height: 12px; }
  .hub__label { font-size: .625rem; letter-spacing: .16em; }
  .hub__glow { inset: -30px; }
  .hub__parts { position: relative; margin-top: 26px; }
  .hub__parts::before { content: ""; position: absolute; left: 41px; top: -26px; height: 37px; width: 2px; background: var(--bw-gun-700); }
  .part { position: relative; padding: 0 0 26px 76px; display: grid; gap: 6px; }
  .part:last-child { padding-bottom: 0; }
  .part:not(:last-child)::before { content: ""; position: absolute; left: 41px; top: 11px; bottom: -11px; width: 2px; background: var(--bw-gun-700); }
  .part:not(:last-child)::after { content: ""; position: absolute; left: 41px; top: 11px; bottom: -11px; width: 2px; transform-origin: top center;
    background: linear-gradient(180deg, var(--bw-white), var(--bw-silver)); }
  .part__mark { position: absolute; z-index: 1; left: 32px; top: 2px; width: 20px; height: 20px;
    background: linear-gradient(200deg, #16254e 0%, #0a1433 38%, #05070f 100%); box-shadow: inset 0 0 0 1px var(--bw-silver), inset 0 1px 0 rgba(254, 254, 253, .55); }
  .part__mark::after { content: ""; position: absolute; left: 6px; top: 6px; width: 8px; height: 8px; background: var(--bw-white); }
  .part__name { font-size: 1.0625rem; line-height: 24px; }
  .part__line { font-size: .9375rem; }
  .hub__names { display: grid; grid-template-columns: repeat(2, max-content); column-gap: 32px; justify-content: start; }   /* two columns, no separators (a wrapped row began with a dot) */
  .hub__names li { padding-inline: 0; }
  .hub__names li + li::before { content: none; }
  .hub__statement { text-align: left; }
}
/* START STATES (motion): the core dark, the spokes undrawn, the parts' blocks and words dim, the names low, the statement below */
.part { --t: .62s; }
.part.p2 { --t: .88s; } .part.p3 { --t: 1.14s; } .part.p4 { --t: 1.4s; } .part.p5 { --t: 1.66s; } .part.p6 { --t: 1.92s; }
.hub-sp.s1, .hub-mk.s1 { --t: .62s; } .hub-sp.s2, .hub-mk.s2 { --t: .88s; } .hub-sp.s3, .hub-mk.s3 { --t: 1.14s; }
.hub-sp.s4, .hub-mk.s4 { --t: 1.4s; } .hub-sp.s5, .hub-mk.s5 { --t: 1.66s; } .hub-sp.s6, .hub-mk.s6 { --t: 1.92s; }
.motion .hub .hub__glow, .motion .hub .hub__edge, .motion .hub .hub__dot { opacity: 0; }
.motion .hub .hub__label { opacity: .35; }
.motion .hub .hub__core { box-shadow: inset 0 0 0 1px var(--bw-gun-500), 0 18px 48px -12px rgba(0, 0, 0, .9); }
.motion .hub .hub-sp { stroke-dashoffset: 1; }
.motion .hub .hub-mk { opacity: .4; }
.motion .hub .hub-mk__core, .motion .hub .hub-mk__edge { opacity: 0; }
.motion .hub .part__name, .motion .hub .part__line { opacity: .28; }
.motion .hub .part__mark { opacity: .4; }
.motion .hub .part__mark::after { opacity: 0; }
.motion .hub .part::after { transform: scaleY(0); }
.motion .hub .hub__names li { opacity: .25; transform: translateY(6px); }
.motion .hub .hub__statement { opacity: 0; transform: translateY(14px); }
@media (prefers-reduced-motion: no-preference) {
  /* 3.2 s from the trigger: the core comes out of the dark and its heart lights (0 to .6 s); then, in the Captain's order, a line of
     light runs from the core to each part (.26 s apart) and the part lights as it arrives: its block, then its name and line; the
     five Connect names light in turn; the closing statement rises */
  .hub.is-on .hub__core { animation: core-on .5s var(--ease-light) both; }
  .hub.is-on .hub__glow { animation: gx-on .7s var(--ease-light) .1s both; }
  .hub.is-on .hub__dot { animation: gx-pop .45s var(--ease-light) .12s both; }
  .hub.is-on .hub__edge { animation: gx-on .5s var(--ease-light) .3s both; }
  .hub.is-on .hub__label { animation: label-on .5s var(--ease-light) .25s both; }
  .hub.is-on .hub-sp { animation: gx-draw .34s cubic-bezier(.3, 0, .3, 1) calc(var(--t) - .32s) both; }
  .hub.is-on .hub-mk { animation: mk-on .3s var(--ease-light) var(--t) both; }
  .hub.is-on .hub-mk__core { animation: gx-pop .4s var(--ease-light) var(--t) both; }
  .hub.is-on .hub-mk__edge { animation: gx-on .4s var(--ease-light) calc(var(--t) + .1s) both; }
  .hub.is-on .part__name, .hub.is-on .part__line { animation: part-on .45s var(--ease-light) calc(var(--t) + .02s) both; }
  .hub.is-on .part__line { animation-delay: calc(var(--t) + .1s); }
  .hub.is-on .part__mark { animation: mk-on .3s var(--ease-light) var(--t) both; }
  .hub.is-on .part__mark::after { animation: gx-pop .4s var(--ease-light) var(--t) both; }
  .hub.is-on .part::after { animation: seg-run .26s linear var(--t) both; }
  .hub.is-on .hub__names li { animation: name-on .35s var(--ease-light) 2.25s both; }
  .hub.is-on .hub__names li:nth-child(2) { animation-delay: 2.33s; } .hub.is-on .hub__names li:nth-child(3) { animation-delay: 2.41s; }
  .hub.is-on .hub__names li:nth-child(4) { animation-delay: 2.49s; } .hub.is-on .hub__names li:nth-child(5) { animation-delay: 2.57s; }
  .hub.is-on .hub__statement { animation: words-up .7s var(--ease-light) 2.5s both; }
  @keyframes core-on { from { box-shadow: inset 0 0 0 1px var(--bw-gun-500), 0 18px 48px -12px rgba(0, 0, 0, .9); } to { box-shadow: inset 0 0 0 1px var(--bw-silver), 0 18px 48px -12px rgba(0, 0, 0, .9); } }
  @keyframes label-on { from { opacity: .35; } to { opacity: 1; } }
  @keyframes mk-on { from { opacity: .4; } to { opacity: 1; } }
  @keyframes part-on { from { opacity: .28; } to { opacity: 1; } }
  @keyframes seg-run { from { transform: scaleY(0); } to { transform: scaleY(1); } }
  @keyframes name-on { from { opacity: .25; transform: translateY(6px); } to { opacity: 1; transform: none; } }
}

/* ------------------------------------------------------------------ phones and narrow windows */
@media (max-width: 899.98px) {
  .map { padding-block: 32px; }
  .gfx--usmap { max-width: none; }
  .platform { padding-block: 32px 56px; }
  .platform__in { gap: 30px; }
}
