/* Feature cards (js/features.js): a feature line opens a large card, the way Apple's "+" tiles do.
   Desktop: a centred card over a blurred page. Phones: a sheet that rises from the bottom.
   Colours are the page's own tokens, so the card follows a page's dark mode where it has one. */

/* The line itself: a plus where the arrow was, and it turns rather than tilts. */
.hx-rows a.hx-fx .hx-arrow svg { transition: transform .45s var(--hx-ease, cubic-bezier(.22, 1, .36, 1)); }
.hx-rows a.hx-fx:hover .hx-arrow { transform: none; }
.hx-rows a.hx-fx:hover .hx-arrow svg { transform: rotate(90deg); }

.wfx[hidden] { display: none; }
.wfx { position: fixed; inset: 0; z-index: 10070; display: flex; align-items: center; justify-content: center; padding: 24px; }
.wfx-scrim { position: absolute; inset: 0; background: rgba(12, 10, 22, .38); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); opacity: 0; transition: opacity .45s cubic-bezier(.22, 1, .36, 1); }
.wfx.is-open .wfx-scrim { opacity: 1; }
.wfx-card { position: relative; width: min(720px, 100%); max-height: calc(100dvh - 48px); display: flex; flex-direction: column; border-radius: 28px;
  background: var(--surface, #fff); color: var(--text, #1a1a1a); box-shadow: 0 30px 80px -20px rgba(20, 10, 40, .35);
  opacity: 0; transform: translateY(28px) scale(.96); will-change: transform, opacity;
  /* Opening: a soft spring, long enough to read as motion, short enough not to wait for. */
  transition: opacity .35s cubic-bezier(.22, 1, .36, 1), transform .6s cubic-bezier(.16, 1, .3, 1); }
.wfx.is-open .wfx-card { opacity: 1; transform: none; }
/* Closing: the same path back, quicker and accelerating out, so it feels dismissed rather than dropped. */
.wfx.is-closing .wfx-card { transition: opacity .26s cubic-bezier(.4, 0, 1, 1), transform .3s cubic-bezier(.4, 0, 1, 1); }
.wfx.is-closing .wfx-scrim { transition: opacity .3s ease; }
.wfx-in { overflow-y: auto; overscroll-behavior: contain; padding: 40px 48px 44px; }
/* The close button: a solid dark circle with a white X, easy to find on any drawing behind it, and a
   44px target. It sits on the card, not in the scrolling content, so it never scrolls away. */
.wfx-x { position: absolute; top: 14px; right: 14px; z-index: 3; width: 44px; height: 44px; border-radius: 50%; border: 0; display: grid; place-items: center; cursor: pointer;
  background: color-mix(in srgb, var(--text, #1a1a1a) 82%, transparent); color: var(--surface, #fff);
  box-shadow: 0 6px 18px -6px rgba(0, 0, 0, .45), 0 0 0 3px color-mix(in srgb, var(--surface, #fff) 70%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); transition: transform .25s cubic-bezier(.34, 1.56, .64, 1), background .2s; }
.wfx-x svg { width: 18px; height: 18px; }
.wfx-x:hover { background: var(--text, #1a1a1a); transform: scale(1.06); }
.wfx-x:active { transform: scale(.94); }
.wfx-x:focus-visible, .wfx-more:focus-visible { outline: 3px solid #a07dd0; outline-offset: 2px; }

.wfx-art { margin: 0 0 28px; border-radius: 20px; background: var(--brand-tint, #f3eefb); padding: 18px 10px; }
.wfx-art svg { display: block; width: 100%; height: auto; max-height: 220px; }
.wfx-t { margin: 0; font: 600 clamp(1.7rem, 3.6vw, 2.3rem)/1.12 'Poppins', system-ui, sans-serif; letter-spacing: -.035em; color: var(--text, #1a1a1a); padding-right: 40px; }
.wfx-l { margin: 12px 0 0; font-size: clamp(1.05rem, 1.6vw, 1.2rem); line-height: 1.5; color: var(--text, #1a1a1a); font-weight: 500; }
.wfx-p { margin: 16px 0 0; font-size: 1rem; line-height: 1.7; color: var(--muted, #5b6072); }
.wfx-i { list-style: none; margin: 22px 0 0; padding: 0; border-top: 1px solid var(--border, #e5e7eb); }
.wfx-i li { position: relative; padding: 12px 0 12px 28px; border-bottom: 1px solid var(--border, #e5e7eb); font-size: .98rem; line-height: 1.5; color: var(--text, #1a1a1a); }
.wfx-i li::before { content: ""; position: absolute; left: 2px; top: 17px; width: 13px; height: 7px; border-left: 2px solid var(--brand, #7851a9); border-bottom: 2px solid var(--brand, #7851a9); transform: rotate(-45deg); }
.wfx-more { display: inline-flex; align-items: center; gap: 8px; margin-top: 26px; font-weight: 600; font-size: 1rem; color: var(--brand, #7851a9); text-decoration: none; }
.wfx-more:hover { text-decoration: underline; text-underline-offset: 4px; }
.wfx-more span { transition: transform .2s; }
.wfx-more:hover span { transform: translateX(3px); }

/* The drawings: soft tint panel, white cards, brand accents. */
.wfx-art .fx-card { fill: var(--surface, #fff); }
.wfx-art .fx-line { stroke: color-mix(in srgb, var(--text, #1a1a1a) 12%, transparent); stroke-width: 1.5; }
.wfx-art .fx-line-s { fill: none; stroke: color-mix(in srgb, var(--brand, #7851a9) 25%, transparent); stroke-width: 6; stroke-linecap: round; }
.wfx-art .fx-mut { fill: color-mix(in srgb, var(--text, #1a1a1a) 12%, transparent); }
.wfx-art .fx-dot { fill: color-mix(in srgb, var(--text, #1a1a1a) 20%, transparent); }
.wfx-art .fx-soft { fill: color-mix(in srgb, var(--brand, #7851a9) 14%, var(--surface, #fff)); }
.wfx-art .fx-acc { fill: var(--brand-fill, #7851a9); }
.wfx-art .fx-acc-o { fill: none; stroke: var(--brand, #7851a9); stroke-width: 3; }
.wfx-art .fx-acc-s { fill: none; stroke: var(--brand, #7851a9); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.wfx-art .fx-acc-line { stroke: var(--brand, #7851a9); stroke-width: 2; }
.wfx-art .fx-acc-t { fill: var(--brand, #7851a9); }
.wfx-art .fx-on { fill: #fff; }
.wfx-art .fx-on-s { fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.wfx-art .fx-ok { fill: #16a34a; }
.wfx-art .fx-star { fill: #f5b301; }
.wfx-art .fx-tx, .wfx-art .fx-tx-f { fill: var(--text, #1a1a1a); }
.wfx-art .fx-mt { fill: var(--muted, #6b7280); }
.wfx-art .fx-on-t { fill: #fff; }
.wfx-art .fx-ink { fill: #1c1f2b; }
.wfx-art .fx-code { fill: #c9cde0; }
.wfx-art .fx-code-k { fill: #c3a4f0; }
.wfx-art .fx-mut-s { fill: none; stroke: color-mix(in srgb, var(--text, #1a1a1a) 12%, transparent); stroke-linecap: round; }
.wfx-art .fx-mt-s { fill: none; stroke: var(--muted, #6b7280); stroke-linecap: round; }
.wfx-art .fx-acc-soft { fill: color-mix(in srgb, var(--brand, #7851a9) 22%, var(--surface, #fff)); }
.wfx-art .fx-heart { fill: #e0245e; }
.wfx-art .fx-gray { fill: color-mix(in srgb, var(--text, #1a1a1a) 34%, transparent); }
.wfx-art .fx-brand2 { fill: #f59e0b; }

/* Phones: a sheet from the bottom, nearly full height, scrolling inside itself. */
@media (max-width: 640px) {
  .wfx { align-items: flex-end; padding: 0; }
  .wfx-card { width: 100%; max-height: 92dvh; border-radius: 24px 24px 0 0; opacity: 1; transform: translateY(100%); transition: transform .55s cubic-bezier(.16, 1, .3, 1); }
  .wfx.is-closing .wfx-card { transition: transform .32s cubic-bezier(.4, 0, 1, 1); }
  /* The grab handle says "you can pull this down". */
  .wfx-card::before { content: ""; position: absolute; top: 8px; left: 50%; width: 40px; height: 5px; margin-left: -20px; border-radius: 3px; background: color-mix(in srgb, var(--text, #1a1a1a) 22%, transparent); z-index: 3; }
  .wfx-in { padding: 28px 22px calc(32px + env(safe-area-inset-bottom, 0px)); }
  .wfx-x { top: 16px; right: 14px; width: 42px; height: 42px; }
  .wfx-art { margin-bottom: 22px; border-radius: 16px; }
}
html.wfx-lock { overflow: hidden; }

/* ── The drawings come alive (js/features.js animateArt). Start states sit on the classes; the motion
   only runs once the card is up (.fx-go), and never for reduced motion (the classes are not added). */
.wfx-art .fx-a-draw { stroke-dasharray: 1; stroke-dashoffset: 1; }
.wfx-art.fx-go .fx-a-draw { animation: fxDraw .9s cubic-bezier(.65, 0, .35, 1) forwards; animation-delay: calc(.25s + var(--d, 0s)); }
@keyframes fxDraw { to { stroke-dashoffset: 0; } }
.wfx-art.fx-go .fx-a-flow { animation: fxFlow 1.4s linear infinite; }
@keyframes fxFlow { to { stroke-dashoffset: -28; } }
.wfx-art .fx-a-wipe, .wfx-art .fx-a-grow, .wfx-art .fx-a-pop { transform-box: fill-box; }
.wfx-art .fx-a-wipe { transform-origin: left center; transform: scaleX(0); }
.wfx-art.fx-go .fx-a-wipe { animation: fxWipe .6s cubic-bezier(.22, 1, .36, 1) forwards; animation-delay: calc(.2s + var(--d, 0s)); }
@keyframes fxWipe { to { transform: none; } }
.wfx-art .fx-a-grow { transform-origin: center bottom; transform: scaleY(0); }
.wfx-art.fx-go .fx-a-grow { animation: fxWipe .75s cubic-bezier(.22, 1, .36, 1) forwards; animation-delay: calc(.25s + var(--d, 0s)); }
.wfx-art .fx-a-pop { transform-origin: center; transform: scale(0); }
.wfx-art.fx-go .fx-a-pop { animation: fxPop .5s cubic-bezier(.34, 1.56, .64, 1) forwards; animation-delay: calc(.25s + var(--d, 0s)); }
@keyframes fxPop { to { transform: none; } }
/* One-off moments in particular drawings. */
.wfx-art .fx-a-needle, .wfx-art .fx-a-hand { transform-box: view-box; }
.wfx-art .fx-a-needle { transform-origin: 220px 180px; }
.wfx-art.fx-go .fx-a-needle { animation: fxNeedle 1.3s cubic-bezier(.34, 1.4, .64, 1) .3s both; }
@keyframes fxNeedle { from { transform: rotate(-95deg); } }
.wfx-art .fx-a-hand { transform-origin: 200px 120px; }
.wfx-art.fx-go .fx-a-hand { animation: fxSpinOnce 1.4s cubic-bezier(.22, 1, .36, 1) .25s both; }
.wfx-art .fx-a-spin, .wfx-art .fx-a-drop, .wfx-art .fx-a-ring, .wfx-art .fx-a-blink, .wfx-art .fx-a-turn, .wfx-art .fx-a-slide, .wfx-art .fx-a-in-r { transform-box: fill-box; transform-origin: center; }
.wfx-art.fx-go .fx-a-spin { animation: fxSpinOnce 1.2s cubic-bezier(.65, 0, .35, 1) .35s both; }
@keyframes fxSpinOnce { from { transform: rotate(-360deg); } }
.wfx-art.fx-go .fx-a-turn { animation: fxTurn 1s cubic-bezier(.34, 1.3, .64, 1) .35s both; }
@keyframes fxTurn { from { transform: rotate(-70deg) translateY(-6px); } }
.wfx-art.fx-go .fx-a-drop { animation: fxDrop .8s cubic-bezier(.34, 1.56, .64, 1) .3s both; }
@keyframes fxDrop { from { transform: translateY(-34px); opacity: 0; } 60% { opacity: 1; } }
.wfx-art .fx-a-ring { transform-origin: center top; }
.wfx-art.fx-go .fx-a-ring { animation: fxRing 1.1s ease-in-out .9s both; }
@keyframes fxRing { 0%, 100% { transform: none; } 15% { transform: rotate(14deg); } 30% { transform: rotate(-12deg); } 45% { transform: rotate(9deg); } 60% { transform: rotate(-6deg); } 75% { transform: rotate(3deg); } }
.wfx-art.fx-go .fx-a-slide { animation: fxSlide .6s cubic-bezier(.16, 1, .3, 1) both; animation-delay: var(--d, .3s); }
@keyframes fxSlide { from { opacity: 0; transform: translateY(-16px) scale(.96); } to { opacity: 1; transform: none; } }
.wfx-art.fx-go .fx-a-in-r { animation: fxInR .7s cubic-bezier(.16, 1, .3, 1) both; animation-delay: var(--d, .6s); }
@keyframes fxInR { from { opacity: 0; transform: translateX(24px) scale(.96); } to { opacity: 1; transform: none; } }
.wfx-art.fx-go .fx-a-blink { animation: fxBlink 4s ease-in-out 1.2s infinite; }
@keyframes fxBlink { 0%, 44%, 52%, 100% { transform: none; } 48% { transform: scaleY(.1); } }

@media (prefers-reduced-motion: reduce) { .wfx-card, .wfx-scrim, .wfx-x { transition: none; } }

/* ── Hero illustrations (build-service-pages.js, visual: { art }) ──
   The service pages show what the service does, drawn, instead of the same five client screenshots
   every page shared. Same drawings as the cards, larger, animating once on load. */
.hx-art-hero { position: relative; border-radius: 32px; padding: clamp(18px, 3.4vw, 40px) clamp(10px, 2vw, 24px);
  background: radial-gradient(circle at 85% 8%, color-mix(in srgb, var(--brand, #7851a9) 22%, transparent), transparent 58%),
              radial-gradient(circle at 8% 100%, color-mix(in srgb, var(--brand, #7851a9) 14%, transparent), transparent 55%), var(--brand-tint, #f3eefb);
  box-shadow: 0 40px 80px -48px rgba(40, 20, 80, .45); overflow: hidden; }
.hx-art-hero .wfx-art { margin: 0; padding: 0; background: none; border-radius: 0; }
.hx-art-hero svg { display: block; width: 100%; height: auto; max-height: none; animation: hxArtFloat 7s ease-in-out 1.6s infinite; }
@keyframes hxArtFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
@media (max-width: 860px) { .hx-art-hero { margin-top: 8px; border-radius: 24px; } }
@media (prefers-reduced-motion: reduce) {
  .hx-art-hero svg { animation: none; }
  .wfx-art [class*="fx-a-"] { animation: none !important; transform: none !important; stroke-dashoffset: 0 !important; opacity: 1 !important; }
}
