/* =====================================================================
   CARD ART (assets/revamp/card-art.js): one drawing per card, never repeated.
   Two themes by class: .ca--night (dark cards) and .ca--white. Same look as products-art.
   ===================================================================== */
.ca { --ca-line: rgba(255, 255, 255, .5); --ca-k: rgba(255, 255, 255, .3); --ca-bg: #0e1020; --ca-soft: #1d1f3a; --ca-soft2: #16182f; --ca-key: #e7e7f1; --ca-hover: rgba(255, 255, 255, .8); }
.ca--white { --ca-line: rgba(17, 24, 39, .5); --ca-k: rgba(17, 24, 39, .35); --ca-bg: #fff; --ca-soft: #eceafb; --ca-soft2: #f5f4fd; --ca-key: #11131f; --ca-hover: rgba(17, 24, 39, .78); }
.ca { display: grid; place-items: center; }
.ca svg { display: block; width: 100%; height: 100%; max-width: 280px; max-height: 200px; overflow: visible; }

.ca .p { fill: var(--ca-bg); stroke: var(--ca-line); stroke-width: .9; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; fill-opacity: 0; transition: stroke-dashoffset 1.4s cubic-bezier(.4, 0, .2, 1), fill-opacity .6s .9s, stroke .3s; }
.ca.is-drawn .p { stroke-dashoffset: 0; fill-opacity: 1; }
.ca.ca-re .p { stroke-dashoffset: 1; transition: none; }
.ca .l { fill: none; stroke: var(--ca-line); stroke-width: .9; stroke-linecap: round; stroke-linejoin: round; }
.ca .l.k { stroke: var(--ca-k); }
.ca .l.dash { stroke-dasharray: 3 4; }
.ca .l.flow { stroke-dasharray: 3 4; animation: caMarch 1.2s linear infinite paused; }
.ca .l.teal, .ca .l.tick { stroke: #29ccb2; stroke-width: 1.5; }
.ca .l.acc-l { stroke: #6a5ff0; stroke-width: 1.6; }
.ca--white .l.acc-l { stroke: #4a3dcc; }
.ca .bx.soft .p.ft, .ca .p.soft { fill: var(--ca-soft); }
.ca .bx.soft .p.fl, .ca .bx.soft .p.fr { fill: var(--ca-soft2); }
.ca .bx.key .p { stroke: var(--ca-key); fill: var(--ca-key); }
.ca .bx.key .p.fl { fill: color-mix(in srgb, var(--ca-key) 78%, var(--ca-bg)); }
.ca .bx.key .p.fr { fill: color-mix(in srgb, var(--ca-key) 58%, var(--ca-bg)); }
.ca .bx.acc .p, .ca .p.accf { fill: #4a3dcc; stroke: #4a3dcc; }
.ca .bx.acc .p.fl { fill: #3b31a6; stroke: #3b31a6; }
.ca .bx.acc .p.fr { fill: #2d2580; stroke: #2d2580; }
.ca .p.q { fill: var(--ca-key); stroke: none; }
.ca .bx.ghost .p { fill: none !important; stroke-dasharray: 3 4 !important; stroke-dashoffset: 0 !important; }
li:hover > .ca .p, a:hover .ca .p, .n3dFitsCard:hover .ca .p { stroke: var(--ca-hover); }
li:hover > .ca .bx.acc .p, a:hover .ca .bx.acc .p, .n3dFitsCard:hover .ca .bx.acc .p { stroke: #4a3dcc; }

/* motion: always running while on screen */
.ca g[class*="a-"] { transform-box: view-box; animation-iteration-count: infinite; animation-timing-function: cubic-bezier(.45, 0, .2, 1); animation-play-state: paused; }
.ca.is-on g[class*="a-"], .ca.is-on .l.flow { animation-play-state: running; }
.ca .a-move { animation-name: caMove; animation-duration: 3s; }
.ca .a-stream { animation-name: caStream; animation-duration: 4s; animation-timing-function: linear !important; }
.ca .a-lift { animation-name: caLift; animation-duration: 4s; }
.ca .a-bob { animation-name: caBob; animation-duration: 4s; animation-timing-function: ease-in-out !important; }
.ca .a-swap { animation-name: caSwap; animation-duration: 4s; }
.ca .a-sweep { animation-name: caBob; animation-duration: 3s; animation-timing-function: ease-in-out !important; }
.ca .a-drop { animation-name: caDrop; animation-duration: 3s; }
.ca .a-drop2 { animation-name: caDrop2; animation-duration: 4s; }
.ca .a-in { animation-name: caIn; animation-duration: 5s; }
.ca .a-out { animation-name: caOut; animation-duration: 5s; }
.ca .a-fill { animation-name: caFill; animation-duration: 5s; }
.ca .a-path { animation-name: caMove; animation-duration: 5s; }
.ca .a-blink { animation-name: caBlink; animation-duration: 2s; animation-timing-function: ease-in-out !important; }
.ca .a-seq { animation-name: caSeq; animation-duration: 4s; opacity: 0; }
.ca .a-seq2 { animation-name: caSeq2; animation-duration: 4s; opacity: 0; }
.ca .a-type { animation-name: caType; animation-duration: 4s; }
.ca .a-wave { animation-name: caWave; animation-duration: 2.4s; transform-box: fill-box; transform-origin: center; }
.ca .a-pulse { animation-name: caPulse; animation-duration: 2.4s; transform-box: fill-box; transform-origin: center; }
.ca .a-sway { animation-name: caSway; animation-duration: 4s; animation-timing-function: ease-in-out !important; transform-box: fill-box; transform-origin: 50% 0%; }
.ca .a-spin { animation-name: caSpin; animation-duration: 4s; animation-timing-function: linear !important; }
.ca .a-shrink { animation-name: caShrink; animation-duration: 5s; transform-box: fill-box; transform-origin: 50% 100%; }

@keyframes caMarch { to { stroke-dashoffset: -14; } }
@keyframes caMove { 0% { transform: translate(0, 0); opacity: 0; } 10% { opacity: 1; } 70% { transform: translate(var(--dx), var(--dy)); opacity: 1; } 82%, 100% { transform: translate(var(--dx), var(--dy)); opacity: 0; } }
@keyframes caStream { 0% { transform: translate(0, 0); opacity: 0; } 8%, 88% { opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)); opacity: 0; } }
@keyframes caLift { 0%, 55%, 100% { transform: translate(0, 0); } 20%, 38% { transform: translate(var(--dx), var(--dy)); } }
@keyframes caBob { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(var(--dx), var(--dy)); } }
@keyframes caSwap { 0%, 12% { transform: translate(0, 0); } 42%, 62% { transform: translate(var(--dx), var(--dy)); } 92%, 100% { transform: translate(0, 0); } }
@keyframes caDrop { 0%, 10% { transform: translate(0, 0); opacity: 0; } 20% { opacity: 1; } 50%, 85% { transform: translate(var(--dx), var(--dy)); opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)); opacity: 0; } }
@keyframes caDrop2 { 0%, 10% { transform: translateY(-22px); opacity: 0; } 40%, 85% { transform: none; opacity: 1; } 100% { transform: none; opacity: 0; } }
@keyframes caIn { 0%, 30% { transform: translate(var(--dx), var(--dy)); opacity: 0; } 50%, 85% { transform: translate(0, 0); opacity: 1; } 100% { transform: translate(0, 0); opacity: 0; } }
@keyframes caOut { 0%, 30% { opacity: 1; } 42%, 88% { opacity: 0; } 100% { opacity: 1; } }
@keyframes caFill { 0% { transform: translate(var(--dx), var(--dy)); } 55%, 85% { transform: translate(0, 0); } 100% { transform: translate(var(--dx), var(--dy)); } }
@keyframes caBlink { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@keyframes caSeq { 0%, 25%, 100% { opacity: 0; } 8%, 18% { opacity: 1; } }
@keyframes caSeq2 { 0%, 8% { opacity: 0; transform: translateY(-8px); } 20%, 80% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: none; } }
@keyframes caType { 0% { opacity: 0; } 15%, 85% { opacity: 1; } 100% { opacity: 0; } }
@keyframes caWave { 0% { transform: scale(.5); opacity: 0; } 30% { opacity: 1; } 100% { transform: scale(1.25); opacity: 0; } }
@keyframes caPulse { 0%, 100% { transform: scale(.92); opacity: .5; } 50% { transform: scale(1.06); opacity: 1; } }
@keyframes caSway { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes caSpin { to { transform: rotate(360deg); } }
@keyframes caShrink { 0%, 20% { transform: none; opacity: 1; } 50%, 80% { transform: scale(.62); opacity: .6; } 100% { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ca g[class*="a-"], .ca .l.flow { animation: none !important; opacity: 1 !important; } }

/* ---- review 27 Oct 2026: solid volumes + a hover beat (docs/ILLUSTRATION-GUIDE.md) ----
   Fill: plain boxes were filled with the card colour on every side, so they read as empty wireframes. Each side now
   takes its own quiet shade (top lightest, left middle, right darkest), so every volume reads solid and what stands in
   front clearly hides what is behind. Ghost boxes stay open on purpose.
   Hover: the line work re-traces (card-art.js redraw), the purple part lifts on a spring, the flows run faster and the
   key pieces nudge up; the idle loop keeps running underneath. */
.ca { --ca-top: #262a4f; --ca-left: #1b1e3b; --ca-right: #13152c; }   /* Fresh Eyes: night steps doubled */
/* floors, rails and bases (flat faces outside a box) take the top shade too, so they hide what is under them */
.ca g:not(.bx) > .p.ft:not(.soft):not(.q):not(.accf) { fill: var(--ca-top); }
.ca--white { --ca-top: #fbfbff; --ca-left: #f1f0fa; --ca-right: #e6e5f3; }
.ca .bx:not(.soft):not(.key):not(.acc):not(.ghost) > .p.ft { fill: var(--ca-top); }
.ca .bx:not(.soft):not(.key):not(.acc):not(.ghost) > .p.fl { fill: var(--ca-left); }
.ca .bx:not(.soft):not(.key):not(.acc):not(.ghost) > .p.fr { fill: var(--ca-right); }
.ca .bx.acc, .ca .bx.key { transition: transform .7s cubic-bezier(.34, 1.56, .64, 1); }
li:hover > .ca .bx.acc, a:hover .ca .bx.acc, article:hover .ca .bx.acc, .n3dFitsCard:hover .ca .bx.acc { transform: translateY(-6px); }
li:hover > .ca .bx.key, a:hover .ca .bx.key, article:hover .ca .bx.key, .n3dFitsCard:hover .ca .bx.key { transform: translateY(-3px); transition-delay: .08s; }
li:hover > .ca .l.flow, a:hover .ca .l.flow, article:hover .ca .l.flow, .n3dFitsCard:hover .ca .l.flow { animation-duration: .5s; }
.ca.ca-hv .p { transition: stroke-dashoffset .9s cubic-bezier(.4, 0, .2, 1), fill-opacity .6s .9s, stroke .3s; }
@media (prefers-reduced-motion: reduce) { .ca .bx.acc, .ca .bx.key { transition: none; transform: none !important; } }

/* ---- motion v2 (spec: agentic-designer-work/motion/card-illustrations.md) ----
   Parts stay visible and travel → hold → return, state lights stay on long enough to read, nothing flashes,
   eased in-out (no linear except true conveyors). The hover lift of single parts and the speed change are switched off
   (they detached parts from their seats and made loops jump); hover is now a lift of the whole drawing plus corner
   brackets that draw in. */
.ca g[class*="a-"] { animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
.ca .a-move, .ca .a-path { animation-name: caMove2; }
.ca .a-stream { animation-name: caStream2; animation-timing-function: cubic-bezier(.65, 0, .35, 1) !important; }
.ca .a-seq { animation-name: caSeq3; }
.ca .a-seq2 { animation-name: caRise; transform-box: fill-box; transform-origin: 50% 100%; }
.ca .a-blink { animation-name: caBlink2; }
/* delivered: rises at its source, travels, holds at the destination, goes into it; hidden while it resets */
@keyframes caMove2 { 0% { transform: translate(0, 0); opacity: 0; } 8% { transform: translate(0, 0); opacity: 1; } 50%, 70% { transform: translate(var(--dx), var(--dy)); opacity: 1; } 80%, 100% { transform: translate(var(--dx), var(--dy)); opacity: 0; } }
@keyframes caStream2 { 0% { transform: translate(0, 0); opacity: 0; } 8% { opacity: 1; } 55%, 78% { transform: translate(var(--dx), var(--dy)); opacity: 1; } 88%, 100% { transform: translate(var(--dx), var(--dy)); opacity: 0; } }
@keyframes caSeq3 { 0%, 8% { opacity: 0; } 22%, 62% { opacity: 1; } 76%, 100% { opacity: 0; } }
@keyframes caRise { 0%, 6% { opacity: 0; transform: scale(.9); } 20%, 74% { opacity: 1; transform: none; } 88%, 100% { opacity: 0; transform: scale(.9); } }
@keyframes caBlink2 { 0%, 100% { opacity: .6; } 50% { opacity: 1; } }
li:hover > .ca .bx.acc, a:hover .ca .bx.acc, article:hover .ca .bx.acc, .n3dFitsCard:hover .ca .bx.acc,
li:hover > .ca .bx.key, a:hover .ca .bx.key, article:hover .ca .bx.key, .n3dFitsCard:hover .ca .bx.key { transform: none; }
li:hover > .ca .l.flow, a:hover .ca .l.flow, article:hover .ca .l.flow, .n3dFitsCard:hover .ca .l.flow { animation-duration: 1.2s; }
.ca svg { transition: transform .3s cubic-bezier(.23, 1, .32, 1); }
li:hover > .ca svg, a:hover .ca svg, article:hover .ca svg, .n3dFitsCard:hover .ca svg { transform: translateY(-4px); }
.ca g.floor > .p.floor { fill: var(--ca-soft2); stroke: var(--ca-k); }
.ca--white g.floor > .p.floor { fill: #f7f6fd; }
.ca .brk { fill: none; stroke: #6a5ff0; stroke-width: 1.4; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0; transition: stroke-dashoffset .4s cubic-bezier(.23, 1, .32, 1), opacity .2s; }
.ca--white .brk { stroke: #4a3dcc; }
li:hover > .ca .brk, a:hover .ca .brk, article:hover .ca .brk, .n3dFitsCard:hover .ca .brk { stroke-dashoffset: 0; opacity: 1; }
@media (prefers-reduced-motion: reduce) { .ca svg { transition: none; transform: none !important; } .ca .brk { transition: opacity .2s; stroke-dashoffset: 0; } }
/* build steps (Fresh Eyes): parts appear one after another in one 8 s loop and all leave together at the end,
   so a screen rebuilds as a whole instead of emptying tile by tile */
.ca .a-step0, .ca .a-step1, .ca .a-step2, .ca .a-step3, .ca .a-step4, .ca .a-step5, .ca .a-step6 { animation-duration: 8s; transform-box: fill-box; transform-origin: 50% 100%; }
.ca .a-step0 { animation-name: caStep0; } .ca .a-step1 { animation-name: caStep1; } .ca .a-step2 { animation-name: caStep2; } .ca .a-step3 { animation-name: caStep3; }
.ca .a-step4 { animation-name: caStep4; } .ca .a-step5 { animation-name: caStep5; } .ca .a-step6 { animation-name: caStep6; }
@keyframes caStep0 { 0%, 4% { opacity: 0; transform: scale(.9); } 12%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: none; } }
@keyframes caStep1 { 0%, 10% { opacity: 0; transform: scale(.9); } 18%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: none; } }
@keyframes caStep2 { 0%, 16% { opacity: 0; transform: scale(.9); } 24%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: none; } }
@keyframes caStep3 { 0%, 22% { opacity: 0; transform: scale(.9); } 30%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: none; } }
@keyframes caStep4 { 0%, 28% { opacity: 0; transform: scale(.9); } 36%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: none; } }
@keyframes caStep5 { 0%, 34% { opacity: 0; transform: scale(.9); } 42%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: none; } }
@keyframes caStep6 { 0%, 46% { opacity: 0; transform: scale(.9); } 56%, 84% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: none; } }
/* the cards already draw their own corner brackets on hover; a second set around the drawing doubled them */
.ca .brk { display: none; }
