/* v10 closing-CTA artwork (rebuild 2026-10-01 after the owner rejected v6: did not fill, too dark, weak, not integrated).
   Reference = Cuberto MOBILE OutroSection (research/phone-v10/outro-ref.md): static full-bleed art, 4 nested lit plates whose edges
   step down the section ~150 px apart, luma rising top -> bottom, black only at the very top, hard bottom edge into the footer.
   Art = tools/phone/card-art/outro.py --v N (compose10): 4 nested browser windows with splayed sides, tops in the text gaps,
   one red lamp low in the front window. Phone only (all rules inside max-width:940px). Two layers:
     .phs-oart-b  static art. Canvas 430 x 624 CSS px (section 576 + 24 px bleed top and bottom), 3x file, 2x file for dpr 2.
     .phs-oart-g  additive light delta of the red lamp; only its opacity breathes.
   Vertical placement tracks the CTA pill (its top moves with the fluid H2 and the language):
     shift = --oart-shift (set by outro-art.js from pill.offsetTop - 366), no-JS fallback clamp(-24px, (100vw - 390px) * .15, 4px).
   Pulse: 6.4 s loop, opacity only, easeInOutSine (easings.net), runs only while the outro is on screen (.is-in from outro-art.js),
   static under prefers-reduced-motion. No hover, pointer-agnostic. */
/* v14 (2026-10-01, owner: black visible left/right, windows read as an object inside black): outro.py --v 14 (compose14). Back windows
   wider than the frame (W1 = full-bleed horizon), light mostly vertical, edge columns lit from y ~34 down (390 art: edge/centre luma
   0.87 vs v13 0.66, edge px < 16: 9.9 % vs 33.3 %), edge-colour ramp under the art for widths > 430, 1 px steel sill on the bottom edge.
   v15 (visual critic on v14): top rises softly out of black over ~100 px (no box edge, bottom stays crisp), outermost window's
   rounded top restored at y 34 (A 172), top 150 px lifted (mean luma 16.7 -> 18.9), red rim 2 px. v14 kept as *_v14.
   v13 kept as outro-art_v13.css + outro10-*_v13.webp. Numbers: research/phone-v11/cta/edge-luma.json. */
@media (max-width:940px){
  .phs-outro{position:relative;isolation:isolate;overflow:hidden}
  .phs-outro > :not(.phs-oart){position:relative;z-index:1}
  .phs-oart{position:absolute;inset:0;z-index:0;pointer-events:none}
  .phs-oart-b,.phs-oart-g{position:absolute;inset:0;background-repeat:no-repeat;background-size:430px 624px;
    background-position:50% calc(100% + 24px + var(--oart-shift, clamp(-24px, (100vw - 390px) * .15, 4px)))}
  /* v14: under the art a full-bleed edge-colour ramp (the canvas edge column, MEASURED, canvas y + 24 = gradient y) so phones wider
     than the 430 canvas continue the lit field instead of showing black sides. Same size/position math as the art. */
  .phs-oart-b{background-color:#000;
    --oart-edge:linear-gradient(#000 0%,#010102 6%,#030407 10%,#06080e 14%,#080c13 18%,#090d15 24%,#171f2d 33.3%,#182030 41.7%,#1d2637 50%,#1e283a 58.3%,#202a3c 66.7%,#293449 75%,#2b374c 83.3%,#323f56 91.7%,#344259 100%);
    background-image:url("../outro10-art.webp?v=15"),var(--oart-edge);
    background-image:image-set(url("../outro10-art-2x.webp?v=15") 2x,url("../outro10-art.webp?v=15") 3x),var(--oart-edge);
    background-size:430px 624px,100% 624px}
  /* v14: deliberate bottom edge. A 1 px steel sill across the full width on the section's last row (CSS, not painted, because the art
     slides with the pill), so the lit field ends on a lit edge and the black footer reads as a cut, not as the art running out. */
  .phs-oart::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
    background:linear-gradient(90deg,rgba(150,166,194,.5),rgba(184,198,222,.8) 50%,rgba(150,166,194,.5))}
  .phs-oart-g{background-image:url("../outro10-glow.webp?v=15");mix-blend-mode:screen;opacity:.15;will-change:opacity;
    animation:phs-oart-breathe 6.4s cubic-bezier(.37,0,.63,1) infinite;animation-play-state:paused}
  @supports (mix-blend-mode:plus-lighter){.phs-oart-g{mix-blend-mode:plus-lighter}}
  .phs-outro.is-in .phs-oart-g{animation-play-state:running}
  /* below 360 px: narrow variant (window top half-width 118 instead of 150) so the window corners + browser dots stay on screen */
  @media (max-width:359px){
    .phs-oart-b{background-image:url("../outro10-art-n.webp?v=15"),var(--oart-edge);background-image:image-set(url("../outro10-art-n-2x.webp?v=15") 2x,url("../outro10-art-n.webp?v=15") 3x),var(--oart-edge)}
    .phs-oart-g{background-image:url("../outro10-glow-n.webp?v=15")}
  }
  @keyframes phs-oart-breathe{0%,100%{opacity:.15}50%{opacity:1}}
  @media (prefers-reduced-motion:reduce){.phs-oart-g{animation:none;opacity:.5;will-change:auto}}
}

/* v16 (2026-10-02, owner: "make the cta button ... have the effect the rest do"): the closing pill gets the same Cuberto button
   mechanic as the footer pills (.fcta in phone.css): a fill rises from below while the label rolls up to its copy. Inverted
   colours (white pill -> black fill, white label). Markup is wrapped by outro-art.js (i18n rewrites the label, so it re-wraps).
   Pointer devices only, exactly like the footer pills; touch keeps the plain pill. */
@media (max-width:940px){
  .phs-outro .phs-pill-w{overflow:hidden;-webkit-tap-highlight-color:transparent;transform-origin:50% 50%}
  .phs-outro .pw-r{position:absolute;inset:0;border-radius:inherit;overflow:hidden;z-index:1;pointer-events:none}
  .phs-outro .pw-r span{position:absolute;inset:0;background:#000;border-radius:50% 50% 0 0;transform:translateY(101%);transition:transform .5s cubic-bezier(.4,0,0,1),border-radius .5s cubic-bezier(.4,0,0,1)}
  .phs-outro .pw-t{position:relative;z-index:2;display:block;overflow:hidden;padding:.16em 0;margin:-.16em 0}
  .phs-outro .pw-t span{display:block;transition:transform .8s cubic-bezier(.16,1,.3,1)}
  .phs-outro .pw-t span::after{content:attr(data-text);position:absolute;left:0;top:110%;color:#fff;white-space:nowrap}
}
@media (max-width:940px) and (hover:hover) and (pointer:fine){
  .phs-outro .phs-pill-w.rv-in,.phs-outro .phs-pill-w:not(.rv-card){transition:transform .3s ease}
  .phs-outro .phs-pill-w.rv-in:hover{transform:scaleX(1.02)!important;transition:transform .6s cubic-bezier(.34,5.56,.64,1)!important}
  .phs-outro .phs-pill-w:hover .pw-r span{transform:translateY(0);border-radius:0;transition:transform .5s cubic-bezier(.4,0,0,1),border-radius .9s cubic-bezier(.4,0,0,1)}
  .phs-outro .phs-pill-w:hover .pw-t span{transform:translateY(-110%)}
}
