/* =========================================================================
 * Home 2026-10-21, block 6 — "Under the hood": the wheel of fourteen modules
 * (reworked the same day to match the 6.png mock-up).
 *
 * The wheel is a STACK of <svg> roots over one square box (.lmx-mod-stage,
 * sized by block6-modules.js through --mod-stage: the height left under the
 * heading on desktop, the width on narrow screens). All roots share the
 * viewBox 72 72 856 856 (the dashed ring is the box edge; the group arcs,
 * brackets and labels overflow it — overflow:visible on every root).
 *
 *   .lmx-mod-base   — static: the blurred glow copy of the sectors, the group
 *                     arcs (drop-shadow), the hub, the halo, the pointer, logo;
 *   .lmx-mod-spin   — one root per spinning ring and for the light sweep: the
 *                     rotation is a CSS transform on the ROOT (a composited
 *                     layer, no repaint — rotating an element inside one big
 *                     svg repainted the whole drawing with its filters every
 *                     frame and cost 20 fps);
 *   .lmx-mod-pulse  — the pulsing hub glow (opacity + scale on the root);
 *   .lmx-mod-svg    — the interactive sectors, on top.
 *
 * Entry (.is-in): the ring wrappers scale up from 0.72, the arcs draw
 * themselves (pathLength=1), the sectors appear one after another. Off screen
 * every animation is paused; under prefers-reduced-motion nothing moves and
 * everything is in its final state. Hover reacts in 150 ms.
 * ====================================================================== */

.lmx-mod-inner{position:relative;width:100%;min-height:100vh;background:#040d10 !important;color:#fff;
  font-family:'Hanken Grotesk',Helvetica,Arial,sans-serif;padding:0 var(--lmx-section-padding-x);box-sizing:border-box;overflow:hidden;
  --mod-scale:1;--mod-cyan:#3ff0ec;--mod-cyan-hi:#b6fbf9;--mod-ink:#e8edef;--mod-dim:#9aa6aa;
  --mod-stage:70vh}
.lmx-mod-inner *{box-sizing:border-box}

/* --- background ----------------------------------------------------------- */
.lmx-mod-bg{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background:
    linear-gradient(rgba(63,240,236,.05) 1px,transparent 1px) 0 0 / 80px 80px,
    linear-gradient(90deg,rgba(63,240,236,.05) 1px,transparent 1px) 0 0 / 80px 80px,
    radial-gradient(42% 46% at 50% 56%,rgba(63,240,236,.16),rgba(63,240,236,.05) 45%,rgba(63,240,236,0) 72%),
    radial-gradient(70% 40% at 50% 60%,#07181c,#040d10 70%)}
/* the dotted wave: a dot texture clipped by a soft wave-shaped mask (an inline SVG), two layers
   200% wide sliding left to right (translateX, seamless: the mask period divides the width),
   the band itself sways (translateY + rotate) — every motion is a compositor transform */
.lmx-mod-wave{position:absolute;left:0;right:0;top:22%;height:60%;overflow:hidden;animation:lmxModSway 9s ease-in-out infinite alternate;will-change:transform}
.lmx-mod-wave-layer{position:absolute;top:0;bottom:0;left:0;width:200%;display:block;will-change:transform;
  background:radial-gradient(circle at center,rgba(63,240,236,.85) 0 .9px,rgba(63,240,236,0) 1.4px) 0 0 / 12px 12px;
  -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 300' preserveAspectRatio='none'><filter id='b' x='-5%' y='-30%' width='110%' height='160%'><feGaussianBlur stdDeviation='14'/></filter><path filter='url(%23b)' fill='white' d='M0 110C100 50 300 50 400 110S700 170 800 110L800 230C700 290 500 290 400 230S100 170 0 230Z'/></svg>") 0 0 / 50% 100% repeat-x;
  mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 300' preserveAspectRatio='none'><filter id='b' x='-5%' y='-30%' width='110%' height='160%'><feGaussianBlur stdDeviation='14'/></filter><path filter='url(%23b)' fill='white' d='M0 110C100 50 300 50 400 110S700 170 800 110L800 230C700 290 500 290 400 230S100 170 0 230Z'/></svg>") 0 0 / 50% 100% repeat-x;
  animation:lmxModWave 26s linear infinite}
.lmx-mod-wave-layer--a{opacity:.55}
.lmx-mod-wave-layer--b{opacity:.32;background-position:6px 7px;background-size:14px 14px;animation-duration:38s;animation-direction:reverse;top:8%;bottom:-8%}
@keyframes lmxModWave{to{transform:translateX(-50%)}}
@keyframes lmxModSway{from{transform:translateY(-14px) rotate(-1.2deg)}to{transform:translateY(14px) rotate(1.2deg)}}
/* twinkling squares and plus marks (in the nodes svg) */
.lmx-mod-spark{fill:#7cf4f1;stroke:#7cf4f1;stroke-width:1.4;opacity:var(--o,.4);animation:lmxModTwinkle var(--dur,3s) ease-in-out var(--d,0s) infinite alternate}
rect.lmx-mod-spark{stroke:none}
@keyframes lmxModTwinkle{from{opacity:calc(var(--o,.4) * .25)}to{opacity:var(--o,.4)}}
.lmx-mod-orbits,.lmx-mod-nodes{position:absolute;inset:0;width:100%;height:100%;display:block}
.lmx-mod-nodes{will-change:transform} /* the SMIL nodes repaint their own layer only */
.lmx-mod-orbit{fill:none;stroke:rgba(63,240,236,.42);stroke-width:1.6;stroke-dasharray:2 8;stroke-linecap:round}
.lmx-mod-node-dot{fill:#fff}
.lmx-mod-node-halo{fill:url(#lmx-mod-node-halo)}

/* --- heading ----------------------------------------------------------------- */
.lmx-mod-head{position:relative;z-index:2;text-align:center}
.lmx-mod-eyebrow{display:block;color:var(--mod-cyan);font-size:max(10px,calc(12.5px * var(--mod-scale,1)));font-weight:600;letter-spacing:.34em;text-transform:uppercase;line-height:1.3}
.lmx-mod-title{margin:max(6px,calc(10px * var(--mod-scale,1))) 0 0 !important;font-family:'Outfit','Poppins',sans-serif !important;font-weight:600 !important;font-size:max(30px,calc(48px * var(--mod-scale,1))) !important;line-height:1.05 !important;letter-spacing:-.02em;color:#fff !important}
.lmx-mod-title-accent{color:var(--mod-cyan);text-shadow:0 0 18px rgba(63,240,236,.45)}
.lmx-mod-desc{margin:max(6px,calc(10px * var(--mod-scale,1))) auto 0 !important;max-width:calc(1100px * var(--mod-scale,1));font-size:max(13px,calc(17px * var(--mod-scale,1))) !important;line-height:1.4 !important;font-weight:300;color:var(--mod-ink) !important}

/* --- the stage and its layers ------------------------------------------------- */
.lmx-mod-stage{position:relative;z-index:2;width:var(--mod-stage);max-width:100%;aspect-ratio:1 / 1;margin:max(24px,calc(36px * var(--mod-scale,1))) auto 0;overflow:visible}
/* two classes: normalize sets svg:not(:root){overflow:hidden} with a higher specificity than one class */
.lmx-mod-stage .lmx-mod-layer{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:visible;font-family:'Hanken Grotesk',Helvetica,Arial,sans-serif;pointer-events:none}
.lmx-mod-stage .lmx-mod-svg{pointer-events:auto;z-index:3;will-change:transform}
.lmx-mod-stage .lmx-mod-base{will-change:transform} /* the blur and drop-shadow are rasterised once into this layer */
.lmx-mod-ringwrap{position:absolute;inset:0;transform:scale(.72);opacity:0;transition:transform .9s cubic-bezier(.2,.7,.2,1),opacity .6s ease}
.lmx-mod-ringwrap--ticks{transition-delay:.1s}
.lmx-mod-ringwrap--inner{transition-delay:.2s}
.lmx-mod-ringwrap--dash{transition-delay:.3s}
.lmx-mod-inner.is-in .lmx-mod-ringwrap{transform:none;opacity:1}

/* the glow copy of the sectors — blurred once, static */
.lmx-mod-glow path{fill:rgba(63,240,236,.28);stroke:var(--mod-cyan);stroke-width:4}
.lmx-mod-glow{opacity:.85}

/* group arcs, brackets, labels */
.lmx-mod-group-arc{fill:none;stroke:var(--mod-cyan);stroke-width:2.4;stroke-linecap:round;filter:drop-shadow(0 0 4px rgba(63,240,236,.75));
  stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset 1.1s cubic-bezier(.2,.7,.2,1);transition-delay:calc(.35s + var(--g,0) * .18s)}
.lmx-mod-group-tick{fill:none;stroke:var(--mod-cyan);stroke-width:3;stroke-linecap:round;opacity:0;transition:opacity .4s ease;transition-delay:calc(1.2s + var(--g,0) * .18s)}
.lmx-mod-group-label{fill:var(--mod-cyan-hi);font-size:24px;font-weight:600;letter-spacing:.32em;text-transform:uppercase;paint-order:stroke;stroke:rgba(4,13,16,.6);stroke-width:4px;stroke-linejoin:round;
  opacity:0;transition:opacity .6s ease;transition-delay:calc(1.1s + var(--g,0) * .18s)}
.lmx-mod-inner.is-in .lmx-mod-group-arc{stroke-dashoffset:0}
.lmx-mod-inner.is-in .lmx-mod-group-tick,.lmx-mod-inner.is-in .lmx-mod-group-label{opacity:1}

/* spinning rings: the whole svg root rotates (composited) */
.lmx-mod-spin{will-change:transform;transform-origin:50% 50%}
.lmx-mod-spin--dash{animation:lmxModSpin 36s linear infinite}
.lmx-mod-spin--ticks{animation:lmxModSpin 28s linear infinite reverse}
.lmx-mod-spin--bright{animation:lmxModSpin 44s linear infinite}
.lmx-mod-spin--dots{animation:lmxModSpin 60s linear infinite reverse}
.lmx-mod-spin--sweep{animation:lmxModSpin 7s linear infinite;opacity:0;transition:opacity .8s ease 1s}
.lmx-mod-inner.is-in .lmx-mod-spin--sweep{opacity:.6}
@keyframes lmxModSpin{to{transform:rotate(360deg)}}
/* off screen: paused (after the shorthands — the animation shorthand resets play-state) */
.lmx-mod-inner:not(.is-in) .lmx-mod-spin,.lmx-mod-inner:not(.is-in) .lmx-mod-pulse,.lmx-mod-inner:not(.is-in) .lmx-mod-wave,.lmx-mod-inner:not(.is-in) .lmx-mod-wave-layer,.lmx-mod-inner:not(.is-in) .lmx-mod-spark{animation-play-state:paused}
.lmx-mod-dash{fill:none;stroke:var(--mod-cyan);stroke-width:7;stroke-linecap:butt;opacity:.82}
.lmx-mod-ticks{fill:none;stroke:var(--mod-cyan);stroke-width:2;stroke-linecap:round;opacity:.7}
.lmx-mod-ring{fill:none}
.lmx-mod-ring--halo{stroke:rgba(63,240,236,.55);stroke-width:14;filter:blur(6px)} /* the static glow under the spinning bright ring */
.lmx-mod-ring--bright{stroke:var(--mod-cyan);stroke-width:7;stroke-linecap:butt}
.lmx-mod-ring--thin{stroke:rgba(63,240,236,.55);stroke-width:1.2}
.lmx-mod-ring--dots{stroke:rgba(63,240,236,.5);stroke-width:2.4}

/* hub: pulse, disc, pointer, logo */
.lmx-mod-pulse{will-change:opacity,transform;transform-origin:50% 50%;opacity:0;animation:lmxModPulse 3.2s ease-in-out infinite}
@keyframes lmxModPulse{0%,100%{opacity:.3;transform:scale(1)}50%{opacity:.85;transform:scale(1.04)}}
.lmx-mod-hub-disc{fill:url(#lmx-mod-hub-fill);stroke:rgba(63,240,236,.5);stroke-width:1.2}
.lmx-mod-pointer{fill:var(--mod-cyan);filter:drop-shadow(0 0 5px rgba(63,240,236,.9))}
.lmx-mod-logo{filter:drop-shadow(0 0 12px rgba(63,240,236,.4))}
.lmx-mod-pointer,.lmx-mod-logo{opacity:0;transition:opacity .6s ease .5s}
.lmx-mod-inner.is-in .lmx-mod-pointer,.lmx-mod-inner.is-in .lmx-mod-logo{opacity:1}

/* sectors */
.lmx-mod-seg{cursor:pointer;outline:none;transform-box:fill-box;transform-origin:center;
  opacity:0;transform:scale(.9);transition:opacity .45s ease,transform .45s cubic-bezier(.2,.7,.2,1);transition-delay:calc(.25s + var(--i,0) * 35ms)}
.lmx-mod-inner.is-in .lmx-mod-seg{opacity:1;transform:translate(0,0)}
.lmx-mod-seg-shape{fill:url(#lmx-mod-seg-fill);stroke:var(--mod-cyan);stroke-width:2.2;stroke-linejoin:round;transition:fill .15s ease,stroke .15s ease,stroke-width .15s ease,filter .15s ease}
.lmx-mod-seg--nolink{cursor:default}
/* the label wrapper carries transform="rotate(a cx cy)" for phones (radial labels, ≤760); wider than that the
   labels are horizontal — the CSS property outranks the presentation attribute */
@media (min-width:761px){.lmx-mod-labelwrap{transform:none}}
.lmx-mod-label{fill:#f4fbfb;font-size:24px;font-weight:500;letter-spacing:.01em;pointer-events:none;paint-order:stroke;stroke:rgba(4,13,16,.55);stroke-width:3px;stroke-linejoin:round;transition:fill .15s ease}
/* the active sector: brighter, stronger glow, pushed outwards along its radius (--tx/--ty from PHP) */
.lmx-mod-inner.is-in .lmx-mod-seg:hover,.lmx-mod-inner.is-in .lmx-mod-seg:focus-visible,.lmx-mod-inner.is-in .lmx-mod-seg.is-active{transform:translate(var(--tx,0),var(--ty,0));transition-delay:0s;transition-duration:.15s}
.lmx-mod-seg:hover .lmx-mod-seg-shape,.lmx-mod-seg:focus-visible .lmx-mod-seg-shape,.lmx-mod-seg.is-active .lmx-mod-seg-shape{fill:url(#lmx-mod-seg-hot);stroke:#dffefd;stroke-width:3.4;filter:drop-shadow(0 0 6px #3ff0ec) drop-shadow(0 0 16px rgba(63,240,236,.85))}
.lmx-mod-seg:hover .lmx-mod-label,.lmx-mod-seg:focus-visible .lmx-mod-label,.lmx-mod-seg.is-active .lmx-mod-label{fill:#fff;font-weight:600}
.lmx-mod-seg:focus-visible .lmx-mod-seg-shape{stroke:#fff}
.lmx-mod-segs.has-active .lmx-mod-seg:not(.is-active) .lmx-mod-seg-shape{opacity:.8}

/* --- the card ---------------------------------------------------------------- */
.lmx-mod-card{position:absolute;z-index:5;left:var(--card-x,50%);top:var(--card-y,50%);transform:translate(0,-50%);
  width:max(230px,calc(300px * var(--mod-scale,1)));padding:max(14px,calc(20px * var(--mod-scale,1))) max(44px,calc(56px * var(--mod-scale,1))) max(14px,calc(20px * var(--mod-scale,1))) max(16px,calc(22px * var(--mod-scale,1)));
  border:1px solid rgba(63,240,236,.6);background:rgba(4,13,16,.94);box-shadow:0 18px 44px rgba(0,0,0,.55),0 0 0 1px rgba(0,0,0,.4),0 0 24px rgba(63,240,236,.12);backdrop-filter:blur(6px);
  pointer-events:auto;animation:lmxModCard .15s ease}
.lmx-mod-card[hidden]{display:none}
@keyframes lmxModCard{from{opacity:0;transform:translate(0,-50%) translateY(6px)}to{opacity:1;transform:translate(0,-50%)}}
.lmx-mod-card-bar{display:block;width:34px;height:3px;margin-bottom:max(8px,calc(12px * var(--mod-scale,1)));background:var(--mod-cyan)}
.lmx-mod-card-title{margin:0 !important;font-family:'Outfit','Poppins',sans-serif !important;font-weight:600 !important;font-size:max(17px,calc(22px * var(--mod-scale,1))) !important;line-height:1.2 !important;color:#fff !important}
.lmx-mod-card-text{margin:max(4px,calc(8px * var(--mod-scale,1))) 0 0 !important;font-size:max(13px,calc(15.5px * var(--mod-scale,1))) !important;line-height:1.45 !important;font-weight:300;color:#d6e1e2 !important}
.lmx-mod-card-link{position:absolute;right:max(12px,calc(18px * var(--mod-scale,1)));bottom:max(12px,calc(18px * var(--mod-scale,1)));display:grid;place-items:center;width:30px;height:30px;color:var(--mod-cyan);text-decoration:none !important;transition:transform .15s ease,color .15s ease}
.lmx-mod-card-link:hover,.lmx-mod-card-link:focus-visible{color:#fff;transform:translateX(3px)}
.lmx-mod-card-link[hidden]{display:none}
.lmx-mod-card-arrow{width:22px;height:22px;display:block}

/* --- the list under the wheel (narrow screens) ---------------------------- */
.lmx-mod-list{display:none;position:relative;z-index:2;margin-top:28px}
.lmx-mod-list-group+.lmx-mod-list-group{margin-top:26px}
.lmx-mod-list-title{margin:0 0 10px !important;font-family:'Hanken Grotesk',Helvetica,Arial,sans-serif !important;font-size:12px !important;font-weight:600 !important;letter-spacing:.28em;text-transform:uppercase;color:var(--mod-cyan) !important}
.lmx-mod-list-items{list-style:none;margin:0 !important;padding:0 !important;border-top:1px solid rgba(255,255,255,.12)}
.lmx-mod-list-item{margin:0 !important;border-bottom:1px solid rgba(255,255,255,.12)}
.lmx-mod-list-link{display:grid;grid-template-columns:1fr auto;grid-template-areas:"name arrow" "desc arrow";column-gap:14px;padding:12px 0;color:#fff;text-decoration:none !important}
.lmx-mod-list-name{grid-area:name;font-weight:600;font-size:16px;line-height:1.3}
.lmx-mod-list-desc{grid-area:desc;font-size:14px;line-height:1.4;font-weight:300;color:var(--mod-dim)}
.lmx-mod-list-arrow{grid-area:arrow;align-self:center;width:20px;height:20px;color:var(--mod-cyan)}

/* --- desktop ----------------------------------------------------------------- */
@media (min-width:1025px){
.lmx-mod-inner{display:grid;grid-template-rows:auto 1fr;align-content:start;justify-items:center;height:100%;min-height:100%;
  padding-top:max(12px,calc(22px * var(--mod-scale,1)));padding-bottom:max(8px,calc(12px * var(--mod-scale,1)))}
.lmx-mod-head{width:100%}
.lmx-mod-stage{align-self:center}
}

/* --- narrow screens ------------------------------------------------------------ */
@media (max-width:1024px){
.lmx-mod-inner{display:block !important;height:auto !important;min-height:0 !important;padding:90px 42px 70px;--mod-stage:min(100%,720px)}
.lmx-mod-title{font-size:42px !important}
.lmx-mod-desc{font-size:17px !important;max-width:620px}
.lmx-mod-stage{margin-top:44px}
.lmx-mod-card{position:relative;left:auto;top:auto;transform:none;width:100%;margin-top:18px;animation:none}
/* lite mode on phones and tablets (2026-10-26, mobile audit): the dot wave (SVG mask + two 200%-wide layers
   sliding), the twinkling sparks, the hub pulse and the light sweep repaint every frame; on WebKit without
   a GPU the block ran at 4 fps. Here only the composited ring spins stay; block6-modules.js keeps the SMIL
   nodes and the sector sweep paused off desktop. */
.lmx-mod-wave,.lmx-mod-wave-layer,.lmx-mod-spark,.lmx-mod-pulse{animation:none !important}
.lmx-mod-wave-layer--b{display:none}
.lmx-mod-spark{opacity:var(--o,.4)}
.lmx-mod-pulse{opacity:.5;transform:none}
.lmx-mod-spin--sweep{display:none}
/* on narrow screens the wheel never waits for JS to become visible (2026-10-26, evening): sectors, labels,
   group arcs, hub logo and pointer are in their final state without .is-in — the text renders with scripts
   blocked, with the entrance animation skipped and under prefers-reduced-motion alike */
.lmx-mod-seg,.lmx-mod-ringwrap{opacity:1;transform:none;transition:none}
.lmx-mod-group-arc{stroke-dashoffset:0;transition:none}
.lmx-mod-group-tick,.lmx-mod-group-label,.lmx-mod-pointer,.lmx-mod-logo{opacity:1;transition:none}
}
@media (max-width:760px){
/* side padding grows with the window: the group labels on the arcs reach ~50 SVG units past the stage box
   (≈5.8 % of the wheel width) and must stay inside the window on 360–430 */
.lmx-mod-inner{padding:70px max(16px,5.4vw) 50px;--mod-stage:min(100%,420px)}
.lmx-mod-title{font-size:32px !important}
.lmx-mod-desc{font-size:15px !important}
/* labels on phones (2026-10-26, evening — until then they were hidden here and the sectors were not tappable):
   the wheel is 328–400px wide, 14 sectors, a sector is ~128 units across at the label radius, so readable
   horizontal text (≥10px ≈ 26 units) does not fit a sector («Intelligence» is 172 units). The labels therefore
   run along the radius (--rot from PHP: the right half reads outwards, the left half towards the hub), where
   the ring is 168 units deep; 26 units are 10–12.5px at 360–430. Group labels stay on their arcs, with less
   tracking so the longest («POST-BREACH FORENSICS & IR») fits its three sectors. */
.lmx-mod-label{font-size:27px;letter-spacing:0}
/* the rotation itself is the SVG attribute on .lmx-mod-labelwrap (PHP) — above 760px it is switched off, see the
   base rules. Group labels stay outside their arcs as on desktop (dominant-baseline:hanging is ignored by WebKit
   on textPath text); the window-based padding above keeps them on screen */
.lmx-mod-group-label{font-size:26px;letter-spacing:.2em}
/* the background stays behind the wheel, not under the list of modules: block6-modules.js writes the bounds from the stage */
.lmx-mod-orbits,.lmx-mod-nodes{bottom:auto;height:var(--mod-bg-h,min(60%,760px))}
.lmx-mod-wave{top:var(--mod-wave-top,10%);height:var(--mod-wave-h,26%)}
/* a tap works as on tablets: the card opens under the wheel (position:relative above), a second tap or the
   card arrow opens the module page; the list under the wheel stays as the second way in */
.lmx-mod-list{display:block}
/* phones (≤760, 2026-10-26): the wheel is decorative here (no hover, no card, the list below is the navigation) —
   fully static: no ring spins and no compositor layers (will-change); five 420×420 layers at DPR 3 are ~30 MB of
   GPU memory on a phone. Tablets 761–1024 keep the ring spins (lite mode above). */
.lmx-mod-spin{animation:none !important}
.lmx-mod-spin,.lmx-mod-stage .lmx-mod-svg,.lmx-mod-stage .lmx-mod-base,.lmx-mod-wave,.lmx-mod-wave-layer,.lmx-mod-nodes{will-change:auto}
}

/* --- less motion: everything static, in its final state ----------------------- */
@media (prefers-reduced-motion:reduce){
.lmx-mod-inner *{animation:none !important;transition:none !important}
.lmx-mod-seg,.lmx-mod-ringwrap{opacity:1;transform:none}
.lmx-mod-group-arc{stroke-dashoffset:0}
.lmx-mod-group-tick,.lmx-mod-group-label,.lmx-mod-pointer,.lmx-mod-logo{opacity:1}
.lmx-mod-pulse{opacity:.5;transform:none}
.lmx-mod-spin--sweep{display:none}
.lmx-mod-wave,.lmx-mod-wave-layer{transform:none}
}
