@charset "UTF-8";
/* ==========================================================================
   LANTEK Computers - UI layer
   Preloader, header, hero, diagrams, section components, footer.
   Depends on lantek.css for tokens.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. PRELOADER
   The LANTEK cube-L assembles out of scattered pixels, then the curtain lifts.
   Fails safe: a hard 3s timeout removes it whatever happens.
   -------------------------------------------------------------------------- */
.lk-pre{
  position:fixed;inset:0;z-index:99999;
  background:var(--lk-void);
  display:grid;place-items:center;
  transition:opacity .5s var(--lk-ease),visibility .5s var(--lk-ease);
}
.lk-pre__inner{position:relative;display:flex;flex-direction:column;align-items:center;gap:30px}

/* the assembling mark */
.lk-pre__mark{width:104px;height:104px;overflow:visible;filter:drop-shadow(0 0 26px rgba(32,187,252,.34))}
.lk-pre__mark rect{
  opacity:0;transform-box:fill-box;transform-origin:center;
  animation:lk-assemble .78s var(--lk-ease) forwards;
}
@keyframes lk-assemble{
  0%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.2) rotate(-40deg)}
  60%{opacity:1}
  100%{opacity:1;transform:translate(0,0) scale(1) rotate(0)}
}
/* A slow sweep across the mark while the rest of the hold plays out. */
.lk-pre__inner::before{
  content:"";position:absolute;inset:-40px -60px auto;height:150px;
  background:linear-gradient(90deg,transparent,rgba(32,187,252,.13),transparent);
  animation:lk-presweep 2s var(--lk-ease) infinite;pointer-events:none;
}
@keyframes lk-presweep{0%{transform:translateX(-70%)}100%{transform:translateX(70%)}}

/* Second page onward in a session: no counting, no assembly, just a wipe.
   The full hold is a first-impression device, not something to sit through
   on every click. */
.lk-pre--quick .lk-pre__bar,
.lk-pre--quick .lk-pre__meta{display:none}
.lk-pre--quick .lk-pre__inner::before{animation:none}
.lk-pre--quick .lk-pre__mark rect{animation-duration:.3s;animation-delay:0s !important}
.lk-pre--quick{transition:opacity .28s var(--lk-ease),visibility .28s var(--lk-ease)}

/* progress */
.lk-pre__bar{
  width:190px;height:2px;background:rgba(79,180,245,.16);
  border-radius:2px;overflow:hidden;position:relative;
}
.lk-pre__fill{
  position:absolute;inset:0;transform-origin:left;transform:scaleX(0);
  background:var(--lk-grad);
  transition:transform .28s linear;
}
.lk-pre__meta{
  display:flex;justify-content:space-between;width:190px;
  font-family:var(--lk-mono);font-size:10.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--lk-ink-3);
}
.lk-pre__meta b{color:var(--lk-sky);font-weight:500;font-variant-numeric:tabular-nums}

/* the curtain: two panels that split away */
.lk-pre__curtain{position:fixed;inset:0;z-index:99998;pointer-events:none}
.lk-pre__curtain span{
  position:absolute;left:0;right:0;height:50.5%;background:var(--lk-void);
  transition:transform .78s var(--lk-ease);
}
.lk-pre__curtain span:first-child{top:0}
.lk-pre__curtain span:last-child{bottom:0}

/* done state */
html.lk-loaded .lk-pre{opacity:0;visibility:hidden}
html.lk-loaded .lk-pre__curtain span:first-child{transform:translateY(-100%)}
html.lk-loaded .lk-pre__curtain span:last-child{transform:translateY(100%)}
html.lk-loaded .lk-pre__curtain{transition:visibility 0s .8s;visibility:hidden}

/* lock scroll while loading */
html.lk-loading,html.lk-loading body{overflow:hidden !important;height:100%}

/* --------------------------------------------------------------------------
   2. SMOOTH SCROLL ENGINE
   Nothing is transformed and nothing is hijacked. The engine eases the real
   scroll position, so sticky, fixed, anchors, the admin bar and any plugin
   reading window.scrollY all keep working. The only thing this class does is
   hand scroll-behavior over to the engine, so the two do not fight.
   -------------------------------------------------------------------------- */
html.lk-smooth{scroll-behavior:auto}

/* Drawer open: hold the page still underneath it. */
html.lk-locked,html.lk-locked body{overflow:hidden}

/* --------------------------------------------------------------------------
   2b. SCROLL PROGRESS
   -------------------------------------------------------------------------- */
.lk-prog{
  position:absolute;left:0;right:0;bottom:-1px;height:2px;
  background:transparent;overflow:hidden;pointer-events:none;
  opacity:0;transition:opacity var(--lk-med) var(--lk-ease);
}
.lk-hdr.is-stuck .lk-prog{opacity:1}
.lk-prog__fill{
  height:100%;width:100%;transform:scaleX(0);transform-origin:0 50%;
  background:linear-gradient(90deg,var(--lk-blue-lo),var(--lk-blue-hi) 45%,var(--lk-cyan));
  box-shadow:0 0 12px rgba(32,187,252,.55);
}

/* --------------------------------------------------------------------------
   3. REVEALS - transform + opacity only, never layout

   Every hidden state is gated behind html.lk-anim, which the engine only adds
   once it has an IntersectionObserver in hand. Without JavaScript, without an
   observer, or if the engine throws before that line, the class is never
   added and every element is simply visible. Content is never stranded at
   opacity 0 waiting for a callback that is not coming.
   -------------------------------------------------------------------------- */
.lk-anim .lk-rise{opacity:0;transform:translate3d(0,26px,0);transition:opacity .78s var(--lk-ease),transform .78s var(--lk-ease)}
.lk-anim .lk-rise.is-in{opacity:1;transform:none}
.lk-anim .lk-fade{opacity:0;transition:opacity .9s var(--lk-ease)}
.lk-anim .lk-fade.is-in{opacity:1}
.lk-anim .lk-scale{opacity:0;transform:translate3d(0,20px,0) scale(.97);transition:opacity .8s var(--lk-ease),transform .8s var(--lk-ease)}
.lk-anim .lk-scale.is-in{opacity:1;transform:none}
.lk-anim .lk-clip{clip-path:inset(0 100% 0 0);transition:clip-path 1s var(--lk-ease)}
.lk-anim .lk-clip.is-in{clip-path:inset(0 0 0 0)}
/* stagger children */
.lk-anim .lk-stagger > *{opacity:0;transform:translate3d(0,22px,0);transition:opacity .7s var(--lk-ease),transform .7s var(--lk-ease)}
.lk-anim .lk-stagger.is-in > *{opacity:1;transform:none}
.lk-anim .lk-stagger.is-in > *:nth-child(1){transition-delay:.02s}
.lk-anim .lk-stagger.is-in > *:nth-child(2){transition-delay:.08s}
.lk-anim .lk-stagger.is-in > *:nth-child(3){transition-delay:.14s}
.lk-anim .lk-stagger.is-in > *:nth-child(4){transition-delay:.2s}
.lk-anim .lk-stagger.is-in > *:nth-child(5){transition-delay:.26s}
.lk-anim .lk-stagger.is-in > *:nth-child(6){transition-delay:.32s}
.lk-anim .lk-stagger.is-in > *:nth-child(7){transition-delay:.38s}
.lk-anim .lk-stagger.is-in > *:nth-child(8){transition-delay:.44s}
.lk-anim .lk-stagger.is-in > *:nth-child(n+9){transition-delay:.5s}

/* Directional. Cards that arrive from the side they sit on read as settling
   into place rather than all rising in unison. */
.lk-anim .lk-in-l{opacity:0;transform:translate3d(-34px,0,0);transition:opacity .8s var(--lk-ease),transform .8s var(--lk-ease)}
.lk-anim .lk-in-r{opacity:0;transform:translate3d(34px,0,0);transition:opacity .8s var(--lk-ease),transform .8s var(--lk-ease)}
.lk-anim .lk-in-l.is-in,.lk-anim .lk-in-r.is-in{opacity:1;transform:none}
/* The horizontal reveal only has room where the body measure is capped.
   Below 1280px the wrap runs edge to edge minus --lk-pad, so a full-width
   block holding a 34px offset while it waits below the fold sticks
   (34 - pad) past the viewport and html.scrollWidth grows by exactly that:
   6px at both 768 and 1024, measured. body has overflow-x:hidden so nobody
   ever saw it, but a scrollWidth wider than the screen is the sort of thing an
   audit tool reports and nobody can reproduce.

   It rises instead below that width, which is also the right motion there: the
   two column sections these classes sit on have already stacked, so there is
   no left and right left to come in from. */
@media(max-width:1279px){
  .lk-anim .lk-in-l,.lk-anim .lk-in-r{transform:translate3d(0,20px,0)}
}

/* Focus pull. Used once, on the diagram frames. */
.lk-anim .lk-blur{opacity:0;filter:blur(11px);transform:scale(1.014);transition:opacity .95s var(--lk-ease),filter .95s var(--lk-ease),transform .95s var(--lk-ease)}
.lk-anim .lk-blur.is-in{opacity:1;filter:blur(0);transform:none}

/* Word reveal. Each word rises out of its own clipping box. The padding and
   negative margin give descenders room, otherwise overflow:hidden shears the
   tails off g, y and p. */
.lk-w{display:inline-block;overflow:hidden;vertical-align:bottom;padding-bottom:.14em;margin-bottom:-.14em}
.lk-w > span{display:inline-block;will-change:transform}
.lk-anim .lk-w > span{transform:translate3d(0,110%,0);transition:transform .82s var(--lk-ease)}
.lk-anim .lk-words.is-in .lk-w > span{transform:none}

/* --------------------------------------------------------------------------
   4. HEADER
   -------------------------------------------------------------------------- */
/* Pinned to the top for the whole page. It never hides on the way down:
   the one control that matters most, the health check, has to stay reachable
   from anywhere. */
.lk-hdr{
  position:fixed;top:0;left:0;right:0;z-index:900;
  height:var(--lk-nav-h);display:flex;align-items:center;
  border-bottom:1px solid transparent;
  /* Compositor-only. The bar used to shrink 10px on scroll, but height is a
     layout property and animating it forced a relayout of the header subtree
     on the exact frames the page is already busy scrolling. Background, blur,
     border and shadow signal the stuck state on their own. */
  transition:
    background var(--lk-med) var(--lk-ease),
    border-color var(--lk-med) var(--lk-ease),
    box-shadow var(--lk-med) var(--lk-ease);
}
.lk-hdr.is-stuck{
  background:rgba(7,10,17,.86);
  -webkit-backdrop-filter:blur(18px) saturate(170%);
  backdrop-filter:blur(18px) saturate(170%);
  border-bottom-color:var(--lk-line-2);
  box-shadow:0 12px 40px -28px rgba(0,0,0,.9);
}

/* Seven links, a wordmark and two calls to action do not fit inside the 1200px
   body measure, so the bar gets a wider one of its own. Every label is
   nowrap: a nav item that breaks across two lines wrecks the whole bar.

   The nav is taken out of flow and centred on the bar itself, so it sits on
   the exact centre line at every width rather than being centred in whatever
   space the logo and the two buttons happen to leave.

   A three column grid was tried first and is wrong for this. `1fr auto 1fr`
   looks like it centres the middle column, but a grid item's automatic minimum
   is its content, so the two side tracks come out at whatever their contents
   need: measured, 243px against 309px, which put the nav 40px left of centre.
   Out of flow there is nothing to distribute and nothing to drift.

   It spans the full bar height rather than being centred in it, which is what
   lets the mega panel below anchor at `top:calc(100% - 8px)` and land exactly
   8px above the bottom of the bar without anybody hardcoding the nav's own
   height. Below the drawer breakpoint the nav is gone and the row is a plain
   flex bar, so the burger shares the right end with the buttons. */
.lk-hdr .lk-wrap{max-width:1440px}
/* height:100% is load bearing, not tidiness. .lk-hdr is a centring flex row,
   so this box is only as tall as the buttons inside it. The nav stretches to
   it and the mega panel anchors off the nav, so without this the panel landed
   24px inside the bar and sat on top of the nav. Full height here makes
   "the bottom of the nav" and "the bottom of the bar" the same line. */
.lk-hdr__in{
  position:relative;display:flex;align-items:center;justify-content:space-between;
  gap:20px;width:100%;min-width:0;height:100%;
}
.lk-hdr__nav{
  position:absolute;left:50%;top:0;height:100%;transform:translateX(-50%);
  display:flex;align-items:center;gap:2px;
}
.lk-hdr__cta{display:flex;align-items:center;gap:8px;flex:none}
.lk-hdr__cta .lk-btn{white-space:nowrap}

/* Top-level items only. The mega panel's links are also inside .lk-hdr__nav
   and must not inherit the bar treatment, so this is a child selector. */
.lk-hdr__nav > a,
.lk-hdr__nav .lk-nav__lnk{
  position:relative;white-space:nowrap;
  font-size:13.6px;font-weight:500;color:var(--lk-ink-2);
  padding:9px 8px;border-radius:var(--lk-r);
  transition:color var(--lk-fast) var(--lk-ease),background var(--lk-fast) var(--lk-ease);
}
.lk-hdr__nav > a::after,
.lk-hdr__nav .lk-nav__lnk::after{
  content:"";position:absolute;left:8px;right:8px;bottom:4px;height:1px;
  background:var(--lk-cyan);transform:scaleX(0);transform-origin:right;
  transition:transform var(--lk-med) var(--lk-ease);
}
.lk-hdr__nav > a:hover,
.lk-hdr__nav .lk-nav__lnk:hover{color:#fff}
.lk-hdr__nav > a:hover::after,
.lk-hdr__nav .lk-nav__lnk:hover::after{transform:scaleX(1);transform-origin:left}
.lk-hdr__nav > a[aria-current="page"],
.lk-hdr__nav .lk-nav__lnk[aria-current="page"]{color:#fff}
.lk-hdr__nav > a[aria-current="page"]::after,
.lk-hdr__nav .lk-nav__lnk[aria-current="page"]::after{transform:scaleX(1)}

/* Fitting a centred nav next to two buttons.

   A centred nav needs (content - nav) / 2 clear on BOTH sides, so the wider of
   the logo and the button pair sets the requirement, and the button pair is
   much the wider: 152px against 309px. The bar's own measure is capped at
   1440px, so the widest content ever available is 1360px and the requirement
   does not ease off on a bigger monitor. At 14.5px the nav measured 761px,
   which leaves 299px a side and overlapped the buttons by 10px at every width
   from 1520 to 3840. That is why 13.6px and 8px of padding are the base size
   rather than a breakpoint: it takes the nav to 684px, which leaves 338px and
   clears the buttons by 29px at every width above the drawer.

   One breakpoint is still needed. Between 1241 and 1400 the viewport, not the
   cap, sets the measure, so the TeamViewer button goes icon only there and the
   pair drops from 309px to 203px. Measured across 22 widths from 320 to 3840.
   The alternative was dropping a nav item, which loses a page from the bar
   permanently to save one breakpoint. */
@media(min-width:1241px) and (max-width:1400px){
  .lk-hdr__cta .lk-btn--dl{padding-left:12px;padding-right:12px}
  /* Hidden visually, not removed, so the accessible name stays. */
  .lk-hdr__cta .lk-btn--dl .lk-btn__t{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
  }
  /* The caret goes with the label. An arrow with nothing to point at is
     noise, and the button keeps its accessible name from aria-label. */
  .lk-hdr__cta .lk-dd__c{display:none}
}

/* Below 1240px the row is too tight to stay honest, so hand it to the drawer
   rather than let it crowd. */
@media(max-width:1240px){
  .lk-hdr__nav{display:none}
  /* Three children under space-between puts the buttons in the middle of the
     bar once the nav is gone, which reads as a mistake. This groups them with
     the burger at the right where they belong. */
  .lk-hdr__cta{margin-left:auto}
}
/* The download goes to the drawer below 820px, where it is two labelled
   buttons. .lk-dd goes with it: an empty inline-flex wrapper still collects an
   8px flex gap from .lk-hdr__cta and leaves a hole where the button was. */
@media(max-width:820px){.lk-hdr__cta .lk-btn--dl,.lk-hdr__cta .lk-dd{display:none}}
@media(max-width:560px){.lk-hdr__cta .lk-btn{padding:10px 14px;font-size:13px}}
@media(max-width:400px){.lk-hdr__cta{display:none}}

/* --- What we do: the mega panel ------------------------------------------
   Anchored to the nav rather than to the trigger, and therefore centred on the
   same axis as the nav and on the bar. Anchoring it under "What we do" would
   put a 680px panel near the left of a centred nav and overflow the viewport
   on a 1280px screen; centred on the bar it cannot overflow at any width the
   panel is shown at.

   .lk-hdr__nav is the containing block, because it is the nearest positioned
   ancestor. Nothing between here and it may be positioned, which is why
   .lk-nav__grp is not.                                                       */
.lk-nav__grp{display:inline-flex;align-items:center;gap:1px}
.lk-nav__tog{
  display:grid;place-items:center;width:22px;height:26px;padding:0;
  background:transparent;border:0;cursor:pointer;color:var(--lk-ink-3);
  transition:color var(--lk-fast) var(--lk-ease),transform var(--lk-med) var(--lk-ease);
}
.lk-nav__tog svg{width:10px;height:6px;display:block}
.lk-nav__grp:hover .lk-nav__tog,
.lk-nav__tog:hover{color:var(--lk-cyan)}
.lk-nav__tog[aria-expanded="true"]{color:var(--lk-cyan);transform:rotate(180deg)}

.lk-mega{
  position:absolute;top:calc(100% - 8px);left:50%;
  /* Three columns since the sectors joined it. Still narrower than the
     narrowest viewport the panel is ever shown at, which is 1241px. */
  width:min(940px,calc(100vw - 2 * var(--lk-pad)));
  background:rgba(10,15,25,.97);
  -webkit-backdrop-filter:blur(22px) saturate(160%);
  backdrop-filter:blur(22px) saturate(160%);
  border:1px solid var(--lk-line-3);border-radius:var(--lk-r-lg);
  box-shadow:var(--lk-glow),0 40px 90px -50px rgba(0,0,0,.95);
  overflow:hidden;z-index:1;
  opacity:0;transform:translate(-50%,-8px);
  transition:opacity var(--lk-fast) var(--lk-ease),transform var(--lk-med) var(--lk-ease);
}
/* An author display value beats the user agent's [hidden]{display:none}, and
   this element has one. See the same trap on .lk-dock__list. */
.lk-mega[hidden]{display:none}
.lk-mega.is-open{opacity:1;transform:translate(-50%,0)}
.lk-mega__in{display:grid;grid-template-columns:1fr 1.12fr 1fr;gap:0}
.lk-mega__col{display:flex;flex-direction:column;padding:20px 22px 22px;min-width:0}
.lk-mega__col + .lk-mega__col{border-left:1px solid var(--lk-line-2)}
.lk-mega__k{
  font-family:var(--lk-mono);font-size:10px;font-weight:500;letter-spacing:.17em;
  text-transform:uppercase;color:var(--lk-sky);margin-bottom:12px;
}
.lk-mega a{
  font-size:14.5px;font-weight:500;color:var(--lk-ink-2);line-height:1.35;
  padding:8px 10px;margin:0 -10px;border-radius:var(--lk-r);
  display:flex;align-items:center;gap:8px;
  transition:color var(--lk-fast) var(--lk-ease),background var(--lk-fast) var(--lk-ease);
}
.lk-mega a:hover,.lk-mega a:focus-visible{color:#fff;background:rgba(79,180,245,.09)}
/* The offer at the foot of the Company column. Pushed to the bottom with an
   auto margin so it sits on the panel's baseline whichever column is taller.

   Selectors are doubled up rather than using !important, because `.lk-mega a`
   is a class plus a type and therefore already outranks a single class. */
.lk-mega .lk-mega__pitch{
  margin:auto 0 0;
  /* align-items comes from .lk-mega a, where it centres a glyph against a
     label. In a column that centres all three lines, so it is reset here. */
  display:flex;flex-direction:column;align-items:flex-start;text-align:left;gap:3px;
  padding:14px 14px 15px;
  background:var(--lk-grad-soft);border:1px solid var(--lk-line-3);
  border-radius:var(--lk-r);
}
.lk-mega .lk-mega__pitch:hover,
.lk-mega .lk-mega__pitch:focus-visible{
  background:rgba(32,187,252,.16);border-color:var(--lk-sky);
}
.lk-mega__pitch-k{
  font-family:var(--lk-mono);font-size:9.5px;font-weight:500;letter-spacing:.17em;
  text-transform:uppercase;color:var(--lk-cyan);
}
.lk-mega__pitch-t{font-size:15px;font-weight:600;letter-spacing:-.02em;color:#fff}
.lk-mega__pitch-d{font-size:12.8px;line-height:1.45;color:var(--lk-ink-3)}

/* --- the TeamViewer download menu ----------------------------------------
   Same glass as the mega panel and the same JS behaviour, but anchored to its
   own trigger rather than to the bar: it is 320px wide, so unlike a 940px
   panel it cannot overflow the viewport from the right edge of the button.

   right:0 rather than a centred transform, because the button is the last
   thing before the burger and a centred panel would hang off the bar.

   .lk-dd is the containing block and must stay positioned. The trigger is a
   .lk-btn, which sets overflow:hidden to clip its own gradient wash, which is
   why the panel is the button's sibling and not its child.                  */
.lk-dd{position:relative;display:inline-flex;align-items:center}
/* .lk-btn sets gap:10px for an icon against a label. A caret is a third item
   and 10px twice over reads as a gap rather than a control, so the trigger
   tightens it and the caret pulls back in. This matters beyond looks: the
   button pair sets the clearance a centred nav needs on both sides, and every
   pixel added here is two pixels off that clearance. Measured across the 22
   widths in e2e-header.cjs. */
.lk-dd__tog{gap:7px}
.lk-dd__c{width:9px;height:6px;flex:none;margin-left:-1px;opacity:.75;
  transition:transform var(--lk-med) var(--lk-ease),opacity var(--lk-fast) var(--lk-ease)}
.lk-dd__tog:hover .lk-dd__c{opacity:1}
.lk-dd__tog[aria-expanded="true"] .lk-dd__c{transform:rotate(180deg);opacity:1}
/* .lk-btn:hover .lk-btn__ic slides the icon 4px right and .lk-btn--dl:hover
   drops it 2px. Neither should touch the caret, which has its own state. */
.lk-dd__tog:hover .lk-dd__c{transform:none}
.lk-dd__tog[aria-expanded="true"]:hover .lk-dd__c{transform:rotate(180deg)}

.lk-dd__menu{
  position:absolute;top:calc(100% + 9px);right:0;
  width:min(320px,calc(100vw - 2 * var(--lk-pad)));
  background:rgba(10,15,25,.97);
  -webkit-backdrop-filter:blur(22px) saturate(160%);
  backdrop-filter:blur(22px) saturate(160%);
  border:1px solid var(--lk-line-3);border-radius:var(--lk-r-lg);
  box-shadow:var(--lk-glow),0 40px 90px -50px rgba(0,0,0,.95);
  overflow:hidden;z-index:2;
  opacity:0;transform:translateY(-8px);
  transition:opacity var(--lk-fast) var(--lk-ease),transform var(--lk-med) var(--lk-ease);
}
/* An author display value beats the user agent's [hidden]{display:none}, and
   this element has one. Same trap as .lk-mega and .lk-dock__list. */
.lk-dd__menu[hidden]{display:none}
.lk-dd__menu.is-open{opacity:1;transform:translateY(0)}
.lk-dd__i{
  display:flex;flex-direction:column;gap:3px;padding:13px 15px 14px;
  transition:background var(--lk-fast) var(--lk-ease);
}
.lk-dd__i + .lk-dd__i{border-top:1px solid var(--lk-line-2)}
.lk-dd__i:hover,.lk-dd__i:focus-visible{background:rgba(79,180,245,.09)}
.lk-dd__t{font-size:14.5px;font-weight:600;letter-spacing:-.01em;color:#fff}
.lk-dd__d{font-size:12.4px;line-height:1.45;color:var(--lk-ink-3)}

.lk-mega__foot{
  display:flex;flex-wrap:wrap;gap:8px 24px;
  padding:14px 24px;border-top:1px solid var(--lk-line-2);
  background:rgba(79,180,245,.045);
}
.lk-mega__foot a{
  font-family:var(--lk-mono);font-size:11px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--lk-sky);padding:5px 0;margin:0;
}
.lk-mega__foot a:hover{color:var(--lk-cyan);background:transparent}
.lk-mega__foot svg{width:13px;height:13px;flex:none}
@media(max-width:1000px){.lk-mega__in{grid-template-columns:1fr 1fr}
  .lk-mega__col:nth-child(3){border-left:0;border-top:1px solid var(--lk-line-2);grid-column:1 / -1}}
@media(max-width:760px){.lk-mega__in{grid-template-columns:1fr}
  .lk-mega__col + .lk-mega__col{border-left:0;border-top:1px solid var(--lk-line-2)}}

/* Logo
   The supplied artwork, painted as a background so the theme can own the url.
   Aspect is fixed at 4:1 by the width, which is what stops it collapsing to
   nothing before the image arrives. */
.lk-logo{display:flex;align-items:center;gap:12px;flex:none}
.lk-logo svg{height:34px;width:auto}
/* background-image is printed by lantek_brand_css(), because only the theme
   knows its own URI. Everything else about the box lives here. */
.lk-logo__img{
  /* 38x152 until 15 September 2026. Raised with the bar. */
  display:block;height:52px;width:208px;
  background-position:center left;background-size:contain;background-repeat:no-repeat;
}
.lk-logo--foot .lk-logo__img{height:46px;width:184px}
@media(max-width:1024px){.lk-logo__img{height:44px;width:176px}}
@media(max-width:560px){.lk-logo__img{height:38px;width:152px}}
/* Retired with the wordmark, kept so an older cached layout does not break. */
.lk-logo__txt{display:flex;flex-direction:column;line-height:1}
.lk-logo__n,.lk-logo__s{white-space:nowrap}
.lk-logo__n{font-size:19px;font-weight:800;letter-spacing:-.05em;color:#fff}
.lk-logo__s{font-family:var(--lk-mono);font-size:9px;letter-spacing:.18em;text-transform:uppercase;color:var(--lk-ink-3);margin-top:4px}
@media(max-width:560px){.lk-logo__s{display:none}}

/* Burger + mobile drawer */
.lk-burger{
  display:none;width:42px;height:42px;background:transparent;border:1px solid var(--lk-line-2);
  border-radius:var(--lk-r);cursor:pointer;position:relative;flex:none;padding:0;
}
.lk-burger span{
  position:absolute;left:12px;right:12px;height:1.5px;background:var(--lk-ink);
  transition:transform var(--lk-med) var(--lk-ease),opacity var(--lk-fast) var(--lk-ease);
}
.lk-burger span:nth-child(1){top:15px}
.lk-burger span:nth-child(2){top:20px}
.lk-burger span:nth-child(3){top:25px}
.lk-burger[aria-expanded="true"] span:nth-child(1){transform:translateY(5px) rotate(45deg)}
.lk-burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.lk-burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}
@media(max-width:1240px){.lk-burger{display:block}}

.lk-drawer{
  position:fixed;inset:var(--lk-nav-h) 0 0;z-index:890;
  background:rgba(4,6,11,.97);
  -webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);
  padding:32px var(--lk-pad) 40px;
  display:flex;flex-direction:column;gap:6px;
  opacity:0;visibility:hidden;transform:translateY(-12px);
  transition:opacity var(--lk-med) var(--lk-ease),transform var(--lk-med) var(--lk-ease),visibility var(--lk-med);
  overflow-y:auto;overscroll-behavior:contain;
}
.lk-drawer.is-open{opacity:1;visibility:visible;transform:none}
.lk-drawer a{
  font-size:21px;font-weight:600;letter-spacing:-.03em;color:var(--lk-ink);
  padding:15px 0;border-bottom:1px solid var(--lk-line-2);
  display:flex;align-items:center;justify-content:space-between;
}
.lk-drawer a:hover{color:var(--lk-sky)}
.lk-drawer a span{font-family:var(--lk-mono);font-size:11px;color:var(--lk-ink-4)}
.lk-drawer .lk-btn{margin-top:26px}
.lk-drawer .lk-btn + .lk-btn{margin-top:10px}

/* What we do expands in place rather than opening a second layer. A nested
   drawer on a phone loses people: they lose track of which level they are on
   and the back gesture leaves the site instead of going up one. */
.lk-drawer__grp{display:flex;align-items:stretch}
.lk-drawer__grp > a{flex:1 1 auto;min-width:0}
.lk-drawer__tog{
  flex:none;width:54px;padding:0;background:transparent;border:0;
  border-bottom:1px solid var(--lk-line-2);cursor:pointer;
  display:grid;place-items:center;color:var(--lk-ink-3);
  transition:color var(--lk-fast) var(--lk-ease),transform var(--lk-med) var(--lk-ease);
}
.lk-drawer__tog svg{width:13px;height:8px;display:block}
.lk-drawer__tog:hover{color:var(--lk-sky)}
.lk-drawer__tog[aria-expanded="true"]{color:var(--lk-cyan);transform:rotate(180deg)}
.lk-drawer__sub{
  display:flex;flex-direction:column;
  margin:2px 0 8px 3px;padding-left:16px;
  border-left:1px solid var(--lk-line-3);
}
.lk-drawer__sub[hidden]{display:none}
.lk-drawer__sub a{
  font-size:15.5px;font-weight:500;color:var(--lk-ink-2);
  padding:10px 0;border-bottom:0;
}
.lk-drawer__foot{margin-top:auto;padding-top:30px;font-size:13.5px;color:var(--lk-ink-3);line-height:1.7}
.lk-drawer__foot a{font-size:13.5px;font-weight:500;border:0;padding:0;color:var(--lk-sky);display:inline}

/* --------------------------------------------------------------------------
   5. HERO
   -------------------------------------------------------------------------- */
/* A column, so the accredited partner carousel can sit on the bottom edge with
   the copy still centred in the space above it. It was `align-items:center` on
   a row and 90px of bottom padding; the padding moved into the band, which now
   owns the bottom of the section. */
.lk-hero{
  position:relative;min-height:100svh;display:flex;flex-direction:column;
  padding:calc(var(--lk-nav-h) + 36px) 0 0;
  overflow:hidden;background:var(--lk-void);
}
.lk-hero__canvas{position:absolute;inset:0;width:100%;height:100%;z-index:0;opacity:.85}
/* Takes the space the band does not, and centres the grid inside it. This is
   what keeps the headline on the same optical line it was on before the band
   existed. */
.lk-hero__in{
  position:relative;z-index:2;width:100%;
  flex:1 1 auto;display:flex;align-items:center;
  padding-bottom:20px;
}
.lk-hero__grid{display:grid;grid-template-columns:1.06fr .94fr;gap:clamp(36px,5vw,72px);align-items:center;
  flex:1 1 auto;min-width:0}
@media(max-width:1000px){.lk-hero__grid{grid-template-columns:1fr;gap:48px}}

/* No parallax. The hero holds still: the copy, the panel and the backdrop all
   stay exactly where they are painted, on scroll and under the pointer.
   Removed by request, and it also removes every will-change on this section. */
/* Foreground vignette. Sits closest, so it barely moves, and it keeps the
   headline legible over whatever the canvas is drawing behind it. */
.lk-hero__veil{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(100deg,var(--lk-void) 4%,rgba(4,6,11,.72) 34%,transparent 62%),
    radial-gradient(ellipse 90% 70% at 50% 118%,rgba(4,6,11,.9),transparent 62%);
}

.lk-hero h1{margin:22px 0 26px}
/* "watching" is the emphasis, and it is now just colour.
   It used to be gradient-filled text with a cyan scanning line sweeping down
   it on a 3.6s loop and an 18px glow behind the line. Three separate tells in
   one word: gradient text, a coloured glow, and a decorative loop. Across
   nine letters a gradient resolves to roughly one colour anyway, so the
   gradient was costing the word its legibility and buying nothing, and the
   monitoring panel beside it is the page's one authored moment.

   The colour alone still does the emphasis, and it is now a real colour a
   screen reader's high-contrast mode can override. */
.lk-scanword{display:inline-block}
.lk-scanword span{color:var(--lk-sky)}

.lk-hero__actions{display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin-top:8px}
.lk-hero__note{font-size:14px;color:var(--lk-ink-3);max-width:26ch;line-height:1.45}
.lk-hero__note b{color:var(--lk-ink-2);font-weight:600}

/* The hero trust strip and the accreditation plate row that briefly sat
   beside it were removed from the markup on 9 September 2026 on request. Their
   rules are gone with them rather than left as dead weight: the strip is not a
   one-line restore the way .lk-cue below is, it was a block of markup, and the
   plate styling it carried is superseded by .lk-part in the carousel at the
   foot of the hero. Recover either from git if they are ever wanted back.

   The founding year now reads only in the hero lead paragraph, and the two
   offices only in the footer and the LocalBusiness schema. */

/* Scroll cue */
/* Retired from the markup on 8 September 2026, when the partner carousel took
   the bottom of the hero. Kept because it is a one-line restore and because an
   older cached layout may still carry it. See the note in src/sections/01-hero.html. */
.lk-cue{
  position:absolute;bottom:26px;left:50%;transform:translateX(-50%);z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  font-family:var(--lk-mono);font-size:9.5px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--lk-ink-4);
  
}
.lk-cue__line{width:1px;height:38px;background:linear-gradient(to bottom,var(--lk-sky),transparent);position:relative;overflow:hidden}
.lk-cue__line::after{
  content:"";position:absolute;inset:0;background:var(--lk-cyan);
  animation:lk-cue 2.1s var(--lk-ease) infinite;
}
@keyframes lk-cue{0%{transform:translateY(-100%)}60%,100%{transform:translateY(100%)}}
@media(max-width:1000px){.lk-cue{display:none}}

/* --------------------------------------------------------------------------
   6. SOC PANEL - the "always watching" proof object
   -------------------------------------------------------------------------- */
.lk-soc{
  position:relative;background:linear-gradient(168deg,var(--lk-panel-2),var(--lk-panel));
  border:1px solid var(--lk-line);border-radius:var(--lk-r-lg);
  box-shadow:var(--lk-glow);overflow:hidden;
}
.lk-soc__bar{
  display:flex;align-items:center;gap:10px;padding:13px 18px;
  border-bottom:1px solid var(--lk-line-2);background:rgba(255,255,255,.018);
}
.lk-soc__dot{width:7px;height:7px;border-radius:50%;background:var(--lk-ok);flex:none;position:relative}
.lk-soc__dot::after{
  content:"";position:absolute;inset:-4px;border-radius:50%;border:1px solid var(--lk-ok);
  opacity:0;animation:lk-ping 2.4s var(--lk-ease) infinite;
}
@keyframes lk-ping{0%{transform:scale(.6);opacity:.9}100%{transform:scale(2.1);opacity:0}}
.lk-soc__t{font-family:var(--lk-mono);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--lk-ink-2)}
.lk-soc__clock{margin-left:auto;font-family:var(--lk-mono);font-size:11.5px;color:var(--lk-sky);font-variant-numeric:tabular-nums}

.lk-soc__body{padding:20px 18px 22px}
.lk-soc__row{
  display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center;
  padding:11px 0;border-bottom:1px solid var(--lk-line-2);
  font-family:var(--lk-mono);font-size:12px;
}
.lk-soc__row:last-child{border-bottom:0}
.lk-soc__time{color:var(--lk-ink-4);font-variant-numeric:tabular-nums}
.lk-soc__ev{color:var(--lk-ink-2);font-family:var(--lk-sans);font-size:13.5px;letter-spacing:-.01em}
.lk-soc__tag{
  font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  padding:4px 9px;border-radius:2px;white-space:nowrap;
}
.lk-soc__tag--ok{color:var(--lk-ok);background:rgba(31,191,143,.1);border:1px solid rgba(31,191,143,.25)}
.lk-soc__tag--w{color:var(--lk-warn);background:rgba(242,163,60,.1);border:1px solid rgba(242,163,60,.25)}
.lk-soc__tag--h{color:var(--lk-hot);background:rgba(255,90,71,.1);border:1px solid rgba(255,90,71,.25)}

.lk-soc__foot{
  display:flex;align-items:center;gap:10px;padding:14px 18px;
  border-top:1px solid var(--lk-line-2);background:rgba(79,180,245,.035);
  font-size:12.5px;color:var(--lk-ink-3);
}
.lk-soc__foot b{color:var(--lk-sky);font-family:var(--lk-mono);font-variant-numeric:tabular-nums;font-weight:500}

/* --------------------------------------------------------------------------
   7. STATS
   -------------------------------------------------------------------------- */
.lk-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:1px;background:var(--lk-line-2)}
.lk-stat{background:var(--lk-black);padding:28px 24px 26px}
.lk-sec--panel .lk-stat{background:var(--lk-panel)}
.lk-stat__n{
  font-size:clamp(2.6rem,6.4vw,4rem);font-weight:700;letter-spacing:-.055em;line-height:.9;
  font-variant-numeric:tabular-nums;
  /* Solid, not gradient-filled. The emphasis is already carried by the
     size and the weight; a gradient across a figure is decoration, and a
     transparent text fill means the contrast pass skips it entirely. */
  color:var(--lk-sky);
}
.lk-stat__t{margin-top:15px;font-size:14.5px;color:var(--lk-ink-2);line-height:1.45;max-width:26ch}

/* --------------------------------------------------------------------------
   8. DIAGRAMS - shared frame
   -------------------------------------------------------------------------- */
.lk-dia{
  position:relative;background:
    radial-gradient(ellipse 80% 60% at 50% 0%,rgba(15,118,196,.1),transparent 70%),
    var(--lk-panel);
  border:1px solid var(--lk-line);border-radius:var(--lk-r-lg);
  padding:clamp(20px,3vw,36px);overflow:hidden;
}
.lk-dia__grid{
  position:absolute;inset:0;pointer-events:none;
  background-image:
    linear-gradient(to right,rgba(79,180,245,.05) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(79,180,245,.05) 1px,transparent 1px);
  background-size:38px 38px;
  mask-image:radial-gradient(ellipse 70% 70% at 50% 50%,#000,transparent 82%);
  -webkit-mask-image:radial-gradient(ellipse 70% 70% at 50% 50%,#000,transparent 82%);
}
.lk-dia svg{position:relative;z-index:1;width:100%;height:auto;overflow:visible}
/* .lk-scoped on purpose. This rule sets a margin on an element that `.lk
   p{margin:0}` / `.lk h1..h4{margin:0}` also matches, and a bare class
   (0-1-0) loses to a class plus a type (0-1-1). Every instance of this
   component was rendering flush against its neighbour. Found by a sweep on
   14 September 2026 and fixed the same way as the .lk-mt-* utilities. */
.lk .lk-dia__cap{
  position:relative;z-index:1;margin-top:20px;padding-top:16px;
  border-top:1px solid var(--lk-line-2);
  font-family:var(--lk-mono);font-size:11px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--lk-ink-4);
}

/* SVG diagram primitives */
.lk-d-plate{fill:var(--lk-panel-2);stroke:var(--lk-line-3);stroke-width:1}
.lk-d-plate-2{fill:rgba(15,118,196,.07);stroke:rgba(79,180,245,.3);stroke-width:1}
.lk-d-lantek{fill:rgba(32,187,252,.09);stroke:var(--lk-cyan);stroke-width:1.5}
.lk-d-t{fill:#fff;font-family:var(--lk-sans);font-size:14px;font-weight:600;letter-spacing:-.02em}
.lk-d-s{fill:var(--lk-ink-2);font-family:var(--lk-sans);font-size:11.5px}
.lk-d-l{fill:var(--lk-sky);font-family:var(--lk-mono);font-size:9.5px;letter-spacing:.16em;text-transform:uppercase}
.lk-d-line{stroke:var(--lk-line-3);stroke-width:1;fill:none}
.lk-d-flow{
  stroke:var(--lk-cyan);stroke-width:1.5;fill:none;
  stroke-dasharray:5 9;
  /* The travelling dashes stopped on 14 September 2026. A diagram that is
     not showing live data should not animate forever. */
}
@keyframes lk-flow{to{stroke-dashoffset:-28}}
.lk-d-node{fill:var(--lk-cyan)}
.lk-d-pulse{transform-box:fill-box;transform-origin:center;opacity:.85}
@keyframes lk-pulse{0%,100%{opacity:.35;transform:scale(.9)}50%{opacity:1;transform:scale(1.12)}}

/* draw-on-scroll for diagram strokes */
.lk-draw{stroke-dasharray:var(--len,600);stroke-dashoffset:var(--len,600);transition:stroke-dashoffset 1.5s var(--lk-ease)}
.is-in .lk-draw{stroke-dashoffset:0}

/* --------------------------------------------------------------------------
   9. NIST WHEEL
   -------------------------------------------------------------------------- */
/* The table is far taller than the wheel. Centring the wheel against it left
   it stranded in the middle of a tall empty column, so it aligns to the top
   and then pins, staying beside whichever function you are reading. */
.lk-nist{display:grid;grid-template-columns:.92fr 1.08fr;gap:clamp(28px,4vw,56px);align-items:start}
.lk-nist > .lk-dia{position:sticky;top:calc(var(--lk-nav-h) + 24px)}
@media(max-width:900px){
  .lk-nist{grid-template-columns:1fr}
  .lk-nist > .lk-dia{position:static}
}
.lk-nist__seg{cursor:pointer;transition:opacity var(--lk-med) var(--lk-ease)}
.lk-nist__seg path{transition:fill var(--lk-med) var(--lk-ease),stroke var(--lk-med) var(--lk-ease)}
.lk-nist__seg:hover path,.lk-nist__seg.is-on path{fill:rgba(32,187,252,.2);stroke:var(--lk-cyan)}
.lk-nist__seg:hover text,.lk-nist__seg.is-on text{fill:#fff}

.lk-nist__list{display:flex;flex-direction:column;gap:1px;background:var(--lk-line-2);border:1px solid var(--lk-line-2);border-radius:var(--lk-r-lg);overflow:hidden}
.lk-nist__row{
  background:var(--lk-panel-2);padding:17px 20px;display:grid;
  grid-template-columns:104px 1fr;gap:18px;align-items:start;
  transition:background var(--lk-med) var(--lk-ease);cursor:pointer;
}
.lk-nist__row:hover,.lk-nist__row.is-on{background:var(--lk-panel-3)}
/* Active row. A ring on all four sides rather than a bar down one edge: it
   reads as "this row is selected" from the corner of the eye while you are
   looking at the wheel, which is the whole point of the cross-link. */
.lk-nist__row.is-on{box-shadow:inset 0 0 0 1px rgba(32,187,252,.5)}
.lk-nist__row.is-on .lk-nist__f{color:var(--lk-cyan)}
.lk-nist__f{
  font-family:var(--lk-mono);font-size:11.5px;font-weight:600;letter-spacing:.14em;
  color:var(--lk-sky);transition:color var(--lk-med) var(--lk-ease);
}
.lk-nist__p{font-size:14px;font-weight:600;color:var(--lk-head);margin-bottom:5px;letter-spacing:-.02em}
.lk-nist__d{font-size:13.8px;line-height:1.55;color:var(--lk-ink-2)}
@media(max-width:520px){.lk-nist__row{grid-template-columns:1fr;gap:8px}}

/* --------------------------------------------------------------------------
   10. DARK WEB SCAN TERMINAL
   -------------------------------------------------------------------------- */
.lk-term{
  background:#04070D;border:1px solid var(--lk-line);border-radius:var(--lk-r-lg);
  overflow:hidden;box-shadow:var(--lk-glow);
}
.lk-term__bar{
  display:flex;align-items:center;gap:8px;padding:12px 16px;
  border-bottom:1px solid var(--lk-line-2);background:rgba(255,255,255,.02);
}
.lk-term__bar i{width:9px;height:9px;border-radius:50%;background:var(--lk-ink-4);display:block}
.lk-term__bar i:nth-child(1){background:rgba(255,90,71,.6)}
.lk-term__bar i:nth-child(2){background:rgba(242,163,60,.6)}
.lk-term__bar i:nth-child(3){background:rgba(31,191,143,.6)}
.lk-term__bar span{margin-left:8px;font-family:var(--lk-mono);font-size:11px;color:var(--lk-ink-3);letter-spacing:.08em}
.lk-term__body{
  padding:20px 18px;font-family:var(--lk-mono);font-size:12.5px;line-height:1.95;
  min-height:264px;color:var(--lk-ink-2);
}
.lk-term__body .g{color:var(--lk-ok)}
.lk-term__body .b{color:var(--lk-sky)}
.lk-term__body .w{color:var(--lk-warn)}
.lk-term__body .h{color:var(--lk-hot)}
.lk-term__body .d{color:var(--lk-ink-4)}
.lk-term__caret{
  display:inline-block;width:7px;height:14px;background:var(--lk-cyan);
  vertical-align:-2px;animation:lk-blink 1.05s steps(2) infinite;
}
@keyframes lk-blink{0%,49%{opacity:1}50%,100%{opacity:0}}

/* --------------------------------------------------------------------------
   11. MARQUEE - accreditations
   -------------------------------------------------------------------------- */
.lk-marq{
  position:relative;overflow:hidden;
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
}
.lk-marq__track{display:flex;width:max-content;animation:lk-marq var(--dur,44s) linear infinite}
.lk-marq:hover .lk-marq__track{animation-play-state:paused}
.lk-marq--rev .lk-marq__track{animation-direction:reverse}
@keyframes lk-marq{to{transform:translate3d(-50%,0,0)}}
.lk-marq__item{
  flex:none;display:flex;align-items:center;gap:11px;
  margin-right:12px;padding:14px 22px;
  border:1px solid var(--lk-line-2);border-radius:var(--lk-r);
  background:var(--lk-panel-2);white-space:nowrap;
  transition:border-color var(--lk-fast) var(--lk-ease),background var(--lk-fast) var(--lk-ease);
}
.lk-marq__item:hover{border-color:var(--lk-line-3);background:var(--lk-panel-3)}
.lk-marq__item svg{width:18px;height:18px;flex:none;color:var(--lk-sky)}
.lk-marq__n{font-size:14.5px;font-weight:600;color:var(--lk-head);letter-spacing:-.02em}
.lk-marq__r{font-family:var(--lk-mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--lk-ink-4)}

/* --------------------------------------------------------------------------
   11a. ACCREDITED PARTNERS
   The logo carousel, on the bottom edge of the hero.

   It had a section of its own for a day. Now it is a band inside the hero, so
   the fold ends on fourteen vendor marks moving rather than on empty ground,
   and the page gains a section back.

   Deliberately quiet. It sits under a 100svh headline, so the heading is set
   at eyebrow scale and the whole band is a darker shelf rather than a panel
   competing for attention.
   -------------------------------------------------------------------------- */
.lk-hero__band{
  position:relative;z-index:2;flex:none;width:100%;
  padding:clamp(16px,2vw,22px) 0 clamp(18px,2.2vw,26px);
  border-top:1px solid var(--lk-line-2);
  /* Sinks toward the ground colour, so the hero reads as ending here rather
     than as having a strip bolted on. */
  background:linear-gradient(180deg,rgba(4,6,11,0),rgba(7,10,17,.72));
}
.lk-hero__band .lk-parts__h{
  font-family:var(--lk-mono);font-size:10.5px;font-weight:500;letter-spacing:.2em;
  text-transform:uppercase;color:var(--lk-ink-3);line-height:1;
  text-align:center;margin-bottom:clamp(12px,1.6vw,16px);
}
@media(max-width:560px){
  .lk-hero__band{padding-bottom:14px}
  .lk-hero__band .lk-parts__h{margin-bottom:10px}
}

/* The plate. White, because these are other people's trademarks and every one
   of those policies asks for the artwork unaltered: on a white ground the
   colours are right and the contrast is guaranteed whatever the vendor uses.
   Knocking them all to white silhouettes is the usual dark-site shortcut and
   it breaks outright on ESET, whose mark is white type inside a teal box. */
.lk-part{
  flex:none;display:grid;place-items:center;
  height:56px;min-width:116px;margin-right:12px;padding:0 22px;
  background:#fff;border-radius:var(--lk-r-lg);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.6),0 14px 34px -24px rgba(0,0,0,.95);
  transition:transform var(--lk-med) var(--lk-ease),box-shadow var(--lk-med) var(--lk-ease);
}
.lk-part:hover{
  transform:translateY(-3px);
  box-shadow:0 0 0 1px var(--lk-line-3),0 18px 42px -22px rgba(32,187,252,.55);
}
/* Height comes from --h in the markup, width from the aspect ratio that
   lantek_brand_css() reads out of each file's viewBox. */
.lk-part__i{display:block;height:var(--h,26px);width:auto;aspect-ratio:3;
  background:center/contain no-repeat}
@media(max-width:640px){
  .lk-part{height:48px;min-width:96px;padding:0 16px;margin-right:9px}
  .lk-part__i{height:calc(var(--h,26px) * .8)}
}

/* --------------------------------------------------------------------------
   12. QUOTES + CLIENTS
   -------------------------------------------------------------------------- */
.lk-quote{display:flex;flex-direction:column;gap:18px;height:100%}
.lk-quote__m{
  font-size:15.5px;line-height:1.6;color:var(--lk-ink);
  font-family:var(--lk-sans);letter-spacing:-.012em;
}
.lk-quote__w{
  width:26px;height:20px;color:var(--lk-blue-hi);opacity:.8;
}
.lk-quote__by{margin-top:auto;padding-top:16px;border-top:1px solid var(--lk-line-2)}
.lk-quote__n{font-size:14px;font-weight:600;color:var(--lk-head)}
/* .lk-scoped on purpose. This rule sets a margin on an element that `.lk
   p{margin:0}` / `.lk h1..h4{margin:0}` also matches, and a bare class
   (0-1-0) loses to a class plus a type (0-1-1). Every instance of this
   component was rendering flush against its neighbour. Found by a sweep on
   14 September 2026 and fixed the same way as the .lk-mt-* utilities. */
.lk .lk-quote__r{font-size:12.5px;color:var(--lk-ink-3);margin-top:3px}

/* A noted fact, set apart from the surrounding copy.
   Differentiated by surface rather than by an accent rail on one edge: this
   one recesses below the section it sits in, where .lk-soft raises above it.
   The mono eyebrow already labels what it is, so a coloured stripe would be
   saying the same thing twice. */
.lk-flag{
  background:var(--lk-void);border:1px solid var(--lk-line-2);
  border-radius:var(--lk-r-lg);padding:28px 30px;overflow:hidden;position:relative;
}

/* --------------------------------------------------------------------------
   13. FAQ
   -------------------------------------------------------------------------- */
.lk-faq{border-top:1px solid var(--lk-line-2)}
.lk-faq details{border-bottom:1px solid var(--lk-line-2)}
.lk-faq summary{
  padding:21px 0;font-size:17px;font-weight:600;letter-spacing:-.024em;color:var(--lk-head);
  cursor:pointer;list-style:none;display:flex;gap:18px;align-items:center;
  transition:color var(--lk-fast) var(--lk-ease);
}
.lk-faq summary::-webkit-details-marker{display:none}
.lk-faq summary:hover{color:var(--lk-sky)}
.lk-faq summary::after{
  content:"";margin-left:auto;flex:none;width:11px;height:11px;
  border-right:1.5px solid var(--lk-sky);border-bottom:1.5px solid var(--lk-sky);
  transform:rotate(45deg) translateY(-3px);
  transition:transform var(--lk-med) var(--lk-ease);
}
.lk-faq details[open] summary::after{transform:rotate(-135deg) translateY(-3px)}
.lk-faq .lk-faq__a{padding:0 0 24px;color:var(--lk-ink-2);font-size:15.5px;line-height:1.65;max-width:74ch}

/* --------------------------------------------------------------------------
   14. CTA BAND
   -------------------------------------------------------------------------- */
.lk-cta{position:relative;overflow:hidden;background:var(--lk-void)}
/* Flat, tokenised, and it has to be both.
   This carried `linear-gradient(155deg,rgba(15,118,196,.14),rgba(10,15,25,.5))`
   and a 120px blue glow: a tinted glass panel, which is decoration standing in
   for hierarchy, and hardcoded dark, so on paper it rendered as a murky grey
   box with near-black text at 1.94:1. A surface, a real border and a real
   shadow do the same job in both scopes. */
.lk-cta__box{
  position:relative;z-index:1;
  background:var(--lk-panel);
  border:1px solid var(--lk-line-3);border-radius:var(--lk-r-lg);
  padding:clamp(32px,5vw,64px);
  box-shadow:var(--lk-glow);
}
/* The counterpart to .lk-flag: raised rather than recessed.
   `rgba(255,255,255,.042)` is a wash that only exists on a dark ground; on
   paper it was invisible. --lk-panel-3 is the raised surface in both. */
.lk-soft{
  background:var(--lk-panel-3);border:1px solid var(--lk-line-2);
  border-radius:var(--lk-r);padding:24px 26px;
}
.lk-soft h3{font-size:16.5px;margin-bottom:10px;letter-spacing:-.024em}
.lk-soft p{font-size:14.8px;color:var(--lk-ink-2);line-height:1.6}

/* --------------------------------------------------------------------------
   15. FOOTER
   -------------------------------------------------------------------------- */
.lk-foot{position:relative;background:var(--lk-void);border-top:1px solid var(--lk-line-2);overflow:hidden}
/* padding-block, not the padding shorthand. .lk-foot__in sits on the same
   element as .lk-wrap, and .lk-wrap gets its side gutter from
   padding-inline:var(--lk-pad). A four value shorthand here wrote that gutter
   back to zero, so on a 390px screen the legal row ran edge to edge with the
   copyright touching the left bezel and Privacy Policy touching the right.
   Every page on the site shares this footer. */
.lk-foot__in{position:relative;z-index:1;padding-block:clamp(56px,7vw,88px) 34px}
.lk-foot__grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:clamp(24px,4vw,44px)}
@media(max-width:900px){.lk-foot__grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.lk-foot__grid{grid-template-columns:1fr;gap:34px}}
.lk-foot h4{
  font-family:var(--lk-mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--lk-sky);margin-bottom:16px;font-weight:500;
}
.lk-foot ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.lk-foot li,.lk-foot p{font-size:14.5px;color:var(--lk-ink-2);line-height:1.55}
.lk-foot a{color:var(--lk-ink-2);transition:color var(--lk-fast) var(--lk-ease)}
.lk-foot a:hover{color:var(--lk-cyan)}
.lk-foot__brand p{max-width:36ch;margin-top:16px;font-size:14px;color:var(--lk-ink-3)}
.lk-foot__badges{display:flex;flex-wrap:wrap;gap:7px;margin-top:20px}
.lk-foot__badge{
  font-family:var(--lk-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--lk-ink-3);border:1px solid var(--lk-line-2);border-radius:2px;padding:6px 10px;
}
.lk-foot__bottom{
  margin-top:clamp(40px,5vw,60px);padding-top:24px;border-top:1px solid var(--lk-line-2);
  display:flex;gap:12px 26px;flex-wrap:wrap;align-items:center;
  font-family:var(--lk-mono);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--lk-ink-4);
}
.lk-foot__bottom .lk-sep{opacity:.4}
.lk-foot__top{margin-left:auto}

/* the oversized watermark wordmark */
.lk-foot__mark{
  position:absolute;left:50%;bottom:-4%;transform:translateX(-50%);
  width:min(1500px,132%);pointer-events:none;z-index:0;opacity:.05;
}
.lk-foot__mark svg{width:100%;height:auto}

/* --------------------------------------------------------------------------
   15b. DIAGRAM SCROLL
   An 860-unit viewBox rendered under about 800px shrinks the 11.5px labels
   below 9px, so from 900px down the diagram scrolls inside its own frame at a
   legible size instead of shrinking. The cards underneath carry the same
   information as text, so nothing is lost either way.
   -------------------------------------------------------------------------- */
.lk-dia__scroll{position:relative;z-index:1}
@media(max-width:900px){
  .lk-dia__scroll{
    overflow-x:auto;overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;
    padding-bottom:12px;
    scrollbar-width:thin;scrollbar-color:var(--lk-line-3) transparent;
  }
  .lk-dia__scroll > svg{min-width:640px}
  .lk-dia__scroll::-webkit-scrollbar{height:5px}
  .lk-dia__scroll::-webkit-scrollbar-thumb{background:var(--lk-line-3);border-radius:3px}
  .lk-dia__scroll::-webkit-scrollbar-track{background:transparent}
}

/* --------------------------------------------------------------------------
   15c. CLIENT LOGOS
   Supplied logos are every colour under the sun. Knocking them to a single
   white silhouette is the only way a row of them reads as one thing on a
   dark ground. They lift to full white on hover.
   -------------------------------------------------------------------------- */
.lk-clients{
  display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:1px;
  background:var(--lk-line-2);border:1px solid var(--lk-line-2);border-radius:var(--lk-r-lg);overflow:hidden;
}
@media(max-width:900px){.lk-clients{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:520px){.lk-clients{grid-template-columns:repeat(2,minmax(0,1fr))}}
.lk-client{
  background:var(--lk-panel);min-height:104px;
  display:grid;place-items:center;padding:22px 18px;
  transition:background var(--lk-med) var(--lk-ease);
}
.lk-client:hover{background:var(--lk-panel-3)}
.lk-client__logo{
  max-height:38px;width:auto;max-width:100%;object-fit:contain;
  filter:brightness(0) invert(1);
  opacity:.52;
  transition:opacity var(--lk-med) var(--lk-ease),filter var(--lk-med) var(--lk-ease);
}
.lk-client:hover .lk-client__logo{opacity:.95}
.lk-client__txt{
  font-size:14.5px;font-weight:600;letter-spacing:-.02em;color:var(--lk-ink-3);
  text-align:center;transition:color var(--lk-med) var(--lk-ease);
}
.lk-client:hover .lk-client__txt{color:var(--lk-head)}

/* --------------------------------------------------------------------------
   15d. BACKDROP TEXTURES
   Drawn rather than photographed: an SVG data URI stays sharp at any density,
   weighs a fraction of a raster, and needs no network request. Each one is
   masked so it fades out instead of stopping at a hard edge.
   -------------------------------------------------------------------------- */
/* The four texture fields (topo, circuit, dots, mesh) were removed with the
   rest of the decorative backdrop system on 14 September 2026. */
@keyframes lk-mesh{
  0%{transform:translate3d(0,0,0) scale(1)}
  100%{transform:translate3d(2%,-2.5%,0) scale(1.08)}
}

/* --------------------------------------------------------------------------
   15e. WEEK COVERAGE GRAPH
   168 cells, one per hour of the week. The lit block is a normal working
   week, which is arithmetic rather than a claim: 9 hours across 5 days.
   -------------------------------------------------------------------------- */
.lk-graph{
  position:relative;background:var(--lk-panel);border:1px solid var(--lk-line);
  border-radius:var(--lk-r-lg);padding:clamp(20px,3vw,34px);overflow:hidden;
}
.lk-graph__head{
  position:relative;z-index:1;display:flex;flex-wrap:wrap;gap:14px;
  align-items:baseline;justify-content:space-between;margin-bottom:22px;
}
.lk-graph__t{font-size:16px;font-weight:600;letter-spacing:-.024em;color:var(--lk-head)}
.lk-graph__key{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--lk-mono);font-size:10px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--lk-ink-3);white-space:nowrap;
}
.lk-graph__sw{
  width:10px;height:10px;border-radius:2px;flex:none;
  background:rgba(79,180,245,.07);box-shadow:inset 0 0 0 1px rgba(79,180,245,.3);
}
.lk-graph__sw--on{background:var(--lk-grad);box-shadow:none}
.lk-graph__scroll{position:relative;z-index:1}
@media(max-width:720px){
  .lk-graph__scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:10px}
  .lk-graph__scroll > svg{min-width:600px}
}
.lk-graph svg{width:100%;height:auto;display:block}
.lk-g-day{fill:var(--lk-ink-4);font-family:var(--lk-mono);font-size:10px;letter-spacing:.1em}
.lk-g-hr{fill:var(--lk-ink-4);font-family:var(--lk-mono);font-size:9.5px;letter-spacing:.08em}

/* Two summary bars underneath, same arithmetic stated plainly. */
.lk-graph__bars{position:relative;z-index:1;margin-top:26px;display:flex;flex-direction:column;gap:16px}
.lk-gbar__top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px;gap:12px}
.lk-gbar__n{font-size:13.5px;color:var(--lk-ink-2)}
.lk-gbar__v{font-family:var(--lk-mono);font-size:12.5px;color:var(--lk-head);font-variant-numeric:tabular-nums;white-space:nowrap}
.lk-gbar__track{height:8px;border-radius:4px;background:rgba(79,180,245,.1);overflow:hidden}
/* The bars rest at their value.
   They used to start at scaleX(0) and fill only once an ancestor picked up
   `.is-in` from the reveal observer. With the reveals removed on 14 September
   2026 that ancestor never got the class, so both bars sat at zero and the
   chart showed nothing: 45 of 168 hours and 168 of 168 hours both rendered as
   an empty track. A chart is not an entrance; it should show its data.

   Flat fills rather than a gradient and a cyan glow, for the same reason the
   rest of the decoration went. The two colours still carry the comparison,
   which is the only thing the fill has to do. */
.lk-gbar__fill{
  height:100%;border-radius:4px;
  transform:scaleX(var(--v,1));transform-origin:0 50%;
}
.lk-gbar__fill--dim{background:var(--lk-ink-4)}
.lk-gbar__fill--full{background:var(--lk-blue)}

/* --------------------------------------------------------------------------
   15f. BENTO
   Mixed-weight cells on a six column field. Each cell states its own span,
   so the arrangement is readable in the markup rather than implied.
   -------------------------------------------------------------------------- */
.lk-bento{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:14px}
.lk-bento > *{grid-column:span 2}
.lk-bento__c--3{grid-column:span 3}
.lk-bento__c--4{grid-column:span 4}
.lk-bento__c--6{grid-column:span 6}
@media(max-width:1000px){
  .lk-bento{grid-template-columns:repeat(4,minmax(0,1fr))}
  .lk-bento > *,.lk-bento__c--3{grid-column:span 2}
  .lk-bento__c--4,.lk-bento__c--6{grid-column:span 4}
}
@media(max-width:620px){
  .lk-bento{grid-template-columns:1fr}
  .lk-bento > *,.lk-bento__c--3,.lk-bento__c--4,.lk-bento__c--6{grid-column:span 1}
}
/* A cell that leads with a number rather than a title. */
.lk-bento__fig{
  font-size:clamp(2rem,4vw,2.9rem);font-weight:700;letter-spacing:-.05em;line-height:.95;
  font-variant-numeric:tabular-nums;
  /* Solid, not gradient-filled. The emphasis is already carried by the
     size and the weight; a gradient across a figure is decoration, and a
     transparent text fill means the contrast pass skips it entirely. */
  color:var(--lk-sky);
}
.lk-bento__spark{margin-top:auto;padding-top:16px}
.lk-bento__spark svg{width:100%;height:auto;display:block}

/* --------------------------------------------------------------------------
   15g. SECTOR ROUTER
   Six rows rather than a pill cloud: the labels are long enough that pills
   wrap badly, and a list reads as a set of destinations rather than filters.
   -------------------------------------------------------------------------- */
.lk-sectors{display:flex;flex-direction:column;gap:1px;
  background:var(--lk-line-2);border:1px solid var(--lk-line-2);
  border-radius:var(--lk-r-lg);overflow:hidden}
.lk-sector{
  display:flex;align-items:center;gap:16px;justify-content:space-between;
  background:var(--lk-panel-2);padding:20px 24px;
  transition:background var(--lk-med) var(--lk-ease);
}
.lk-sector:hover{background:var(--lk-panel-3)}
/* The label steps forward on hover. This used to animate padding-left on the
   row, which is a layout property and relaid out the row on every frame of the
   transition. Translating the label is compositor-only and looks the same. */
.lk-sector__n{
  font-size:16.5px;font-weight:600;letter-spacing:-.024em;color:var(--lk-head);
  transition:transform var(--lk-med) var(--lk-ease);
}
.lk-sector:hover .lk-sector__n{transform:translateX(6px)}
.lk-sector svg{
  width:16px;height:16px;flex:none;color:var(--lk-sky);opacity:0;
  transform:translateX(-6px);
  transition:opacity var(--lk-med) var(--lk-ease),transform var(--lk-med) var(--lk-ease);
}
.lk-sector:hover svg{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  .lk-sector:hover .lk-sector__n{transform:none}
  .lk-sector svg{opacity:1;transform:none}
}

/* --------------------------------------------------------------------------
   16. UTILITIES
   -------------------------------------------------------------------------- */
/* Doubled up on purpose. `.lk p{margin:0}` is a class plus a type, which
   outranks a bare utility class, so every one of the 28 paragraphs carrying
   .lk-mt-* on the home page was silently sitting flush against the block above
   it. The .lk-scoped copy is a class plus a class and wins; the bare copy stays
   for anything used outside a .lk root. Seventh instance of this trap, after
   .lk-plan__note, the heading colours and the three list components. */
.lk-mt-s{margin-top:14px}.lk-mt-m{margin-top:26px}.lk-mt-l{margin-top:44px}
.lk .lk-mt-s{margin-top:14px}.lk .lk-mt-m{margin-top:26px}.lk .lk-mt-l{margin-top:44px}
.lk-flex{display:flex;flex-wrap:wrap;gap:14px;align-items:center}
.lk-hairline{height:1px;background:linear-gradient(90deg,transparent,var(--lk-line-3),transparent);border:0;margin:0}

/* --------------------------------------------------------------------------
   17. REDUCED MOTION - the whole system degrades to static, still legible
   -------------------------------------------------------------------------- */
@media(prefers-reduced-motion:reduce){
  html.lk{scroll-behavior:auto}
  .lk *,.lk *::before,.lk *::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important;
  }
  .lk-rise,.lk-fade,.lk-scale,.lk-stagger > *,
  .lk-in-l,.lk-in-r,.lk-blur,.lk-w > span{
    opacity:1 !important;transform:none !important;filter:none !important;
  }
  .lk-w{overflow:visible;padding-bottom:0;margin-bottom:0}
  .lk-clip{clip-path:none !important}
  .lk-draw{stroke-dashoffset:0 !important}
  .lk-prog{display:none}
  .lk-hero__copy,.lk-hero__panel,.lk-hero__canvas{transform:none !important;opacity:1 !important}
  .lk-cue{opacity:1 !important}
  .lk-marq__track{animation:none !important}
  /* A stopped marquee shows whatever happens to be at the left and clips the
     rest, which for the partner strip means hiding most of the partners. With
     the motion off it becomes a centred, wrapping grid instead, and the second
     printed set drops out so nobody appears twice. */
  .lk-hero__band .lk-marq{mask-image:none;-webkit-mask-image:none}
  .lk-hero__band .lk-marq__track{
    width:auto;flex-wrap:wrap;justify-content:center;gap:10px;
    padding-inline:var(--lk-pad);
  }
  .lk-hero__band .lk-part{margin-right:0}
  .lk-hero__band .lk-part[data-dup]{display:none}
  .lk-scanword::after{display:none}
}

/* --------------------------------------------------------------------------
   18. PRINT
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   ENGAGEMENT FURNITURE
   The "Are we a fit" invitation and the social dock. Markup in inc/engage.php,
   behaviour in engage() in lantek.js.

   Layering, because this is the crowded end of the stack:
     99999  .lk-pre        preloader
     99998  .lk-pre__curtain
      9999  .lk-skip:focus
       970  .lk-fit        the panel, over everything but the preloader
       950  .lk-dock       the rail, over the header
       900  .lk-hdr
       890  .lk-drawer
   -------------------------------------------------------------------------- */

/* ---- the rail ---- */
.lk-dock{
  position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:950;
  display:flex;flex-direction:column;align-items:flex-end;gap:10px;
  pointer-events:none;   /* the rail is a layout box, the controls take events */
}
.lk-dock > *{pointer-events:auto}

/* ---- social ----
   Redesigned 8 September 2026: the old control was a 44px panel-coloured
   square flush to the edge, which is exactly what a visitor's eye is trained
   to skip. Three things changed and each does a different job.

   The button is now a full-radius gradient disc that sits clear of the edge
   with the house glow under it, so it reads as the one thing on the page
   asking to be pressed. A slow ring breathes out of it, twice, and then stops:
   enough to catch the eye once, not enough to become a distraction on a page
   somebody is trying to read. And the glyph crossfades to a close mark when
   the list is open, instead of rotating a share icon 90 degrees, which said
   nothing about what pressing it again would do.

   Each network then carries its own colour at rest rather than only on hover,
   which is what makes the open list read as a row of real accounts. */
.lk-dock__soc{position:relative;display:flex;align-items:center;gap:10px}

/* A label that arrives on hover and focus. It is aria-hidden because the
   button already carries "Follow LANTEK" for a screen reader; this is for the
   eye only, and duplicating it would just be read twice. */
.lk-dock__cue{
  font:600 10.5px/1 var(--lk-mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--lk-ink-2);white-space:nowrap;
  background:var(--lk-panel-2);border:1px solid var(--lk-line-2);
  border-radius:var(--lk-r);padding:8px 11px;
  opacity:0;transform:translateX(8px);pointer-events:none;
  transition:opacity var(--lk-fast) var(--lk-ease),transform var(--lk-med) var(--lk-ease);
}
/* focus-within rather than a sibling selector: the label is printed before the
   button so it can sit to its left, and a sibling combinator only reaches
   forwards. */
.lk-dock__soc:hover .lk-dock__cue,
.lk-dock__soc:focus-within .lk-dock__cue{opacity:1;transform:none}
@media(max-width:640px){.lk-dock__cue{display:none}}

.lk-dock__btn{
  position:relative;display:grid;place-items:center;
  width:50px;height:50px;padding:0;cursor:pointer;
  margin-right:12px;
  background:var(--lk-blue);color:#fff;border:0;border-radius:50%;
  box-shadow:0 0 0 1px rgba(79,180,245,.4),0 14px 34px -12px rgba(15,118,196,.95);
  transition:transform var(--lk-fast) var(--lk-ease),box-shadow var(--lk-med) var(--lk-ease);
}
.lk-dock__btn::before{
  content:"";position:absolute;inset:0;border-radius:50%;background:var(--lk-grad);
  opacity:0;transition:opacity var(--lk-med) var(--lk-ease);
}
.lk-dock__btn:hover{transform:scale(1.06);box-shadow:var(--lk-glow-hi)}
.lk-dock__btn:hover::before,
.lk-dock__btn[aria-expanded="true"]::before{opacity:1}
.lk-dock__btn:active{transform:scale(.98)}

/* Two breaths and done. An indefinite pulse on a fixed element is the kind of
   thing people install an extension to stop. */
.lk-dock__ring{
  position:absolute;inset:0;border-radius:50%;
  border:1.5px solid var(--lk-cyan);pointer-events:none;
  animation:lk-dock-ring 2.6s var(--lk-ease) .9s 2 both;
}
@keyframes lk-dock-ring{
  0%{transform:scale(1);opacity:.5}
  70%,100%{transform:scale(1.85);opacity:0}
}

.lk-dock__ic{position:relative;display:grid;width:21px;height:21px}
.lk-dock__ic svg{
  grid-area:1/1;display:block;width:100%;height:100%;
  transition:opacity var(--lk-fast) var(--lk-ease),transform var(--lk-med) var(--lk-ease);
}
.lk-dock__ic-x{opacity:0;transform:rotate(-90deg) scale(.7)}
.lk-dock__btn[aria-expanded="true"] .lk-dock__ic-share{opacity:0;transform:rotate(90deg) scale(.7)}
.lk-dock__btn[aria-expanded="true"] .lk-dock__ic-x{opacity:1;transform:none}

/* Expands leftward from the button, so it never leaves the viewport. */
.lk-dock__list{
  list-style:none;margin:0;padding:7px;display:flex;flex-direction:column;gap:3px;
  /* 50px disc + 12px of margin + 10px of air. Flush against the disc the two
     read as one lumpy shape. */
  position:absolute;right:72px;top:50%;transform:translateY(-50%);
  background:rgba(10,15,25,.97);
  -webkit-backdrop-filter:blur(18px) saturate(160%);
  backdrop-filter:blur(18px) saturate(160%);
  border:1px solid var(--lk-line-3);
  border-radius:var(--lk-r-lg);box-shadow:var(--lk-glow),0 26px 60px -30px rgba(0,0,0,.9);
  min-width:182px;
  animation:lk-dock-list .28s var(--lk-ease) both;
}
@keyframes lk-dock-list{from{opacity:0;transform:translate(10px,-50%)}to{opacity:1;transform:translate(0,-50%)}}
/* display:flex above beats the user agent's [hidden]{display:none}, because an
   author rule wins over a UA rule. Without this the list is visible on load
   and the toggle appears to do nothing. Same trap for anything else here that
   sets display and relies on the hidden attribute. */
.lk-dock__list[hidden]{display:none}
.lk-dock__link{
  --net:var(--lk-sky);
  display:flex;align-items:center;gap:11px;padding:9px 12px 9px 10px;text-decoration:none;
  color:var(--lk-ink);border-radius:var(--lk-r);
  font:500 14px/1 var(--lk-sans);white-space:nowrap;position:relative;
  transition:background-color var(--lk-fast) var(--lk-ease),color var(--lk-fast) var(--lk-ease);
}
/* The glyph carries the network's colour at rest. The label stays in the house
   ink, because six coloured words in a stack is a ransom note. */
.lk-dock__link svg{width:20px;height:20px;flex:0 0 20px;color:var(--net)}
.lk-dock__link:hover,.lk-dock__link:focus-visible{
  background:color-mix(in srgb,var(--net) 15%,transparent);color:#fff;
}
.lk-dock__link[data-net="facebook"]{--net:#4d90ff}
.lk-dock__link[data-net="linkedin"]{--net:#48a3e8}
.lk-dock__link[data-net="instagram"]{--net:#e46a92}
.lk-dock__link[data-net="tiktok"]{--net:#4de8e0}
.lk-dock__link[data-net="youtube"]{--net:#ff5a52}
.lk-dock__link[data-net="x"]{--net:#e9f1fa}
.lk-dock__link[data-net="whatsapp"]{--net:#4ad066}
@supports not (color:color-mix(in srgb,#000 50%,#fff)){
  .lk-dock__link:hover,.lk-dock__link:focus-visible{background:var(--lk-panel-3)}
}

/* ---- the tab ---- */
.lk-dock__tab{
  cursor:pointer;padding:16px 11px;
  background:var(--lk-panel);color:var(--lk-ink-2);
  border:1px solid var(--lk-line-2);border-right:0;
  border-radius:var(--lk-r) 0 0 var(--lk-r);
  font:600 11.5px/1 var(--lk-mono);letter-spacing:.13em;text-transform:uppercase;
  transition:color var(--lk-fast) var(--lk-ease),background-color var(--lk-fast) var(--lk-ease),
             border-color var(--lk-fast) var(--lk-ease),padding-right var(--lk-fast) var(--lk-ease);
}
.lk-dock__tab span{writing-mode:vertical-rl;display:block}
.lk-dock__tab:hover{
  background:var(--lk-panel-2);color:var(--lk-cyan);border-color:var(--lk-blue);
  padding-right:15px;
}
/* Arrives rather than appearing, so a dismissal reads as a move to the side
   rather than the panel vanishing. */
.lk-dock__tab{animation:lk-tab-in .5s var(--lk-ease) both}
@keyframes lk-tab-in{from{transform:translateX(100%);opacity:0}to{transform:none;opacity:1}}

/* ---- the panel ---- */
.lk-fit{position:fixed;inset:0;z-index:970}
/* The smooth scroll engine drives window.scrollTo on its own, so overflow
   hidden on the root is what actually stops the page moving behind the panel. */
html.lk-fit-open{overflow:hidden}
.lk-fit__scrim{
  position:absolute;inset:0;background:rgba(2,4,8,.72);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:lk-fade-in .32s var(--lk-ease) both;
}
.lk-fit__box{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(560px,calc(100vw - 2 * var(--lk-pad)));
  max-height:calc(100vh - 2 * var(--lk-pad));overflow-y:auto;
  background:
    radial-gradient(120% 90% at 100% 0%,rgba(15,118,196,.16),transparent 62%),
    var(--lk-panel);
  border:1px solid var(--lk-line-3);border-radius:var(--lk-r-lg);
  padding:clamp(26px,4vw,44px);
  box-shadow:0 40px 100px rgba(0,0,0,.62);
  animation:lk-fit-in .42s var(--lk-ease) both;
}
@keyframes lk-fade-in{from{opacity:0}to{opacity:1}}
@keyframes lk-fit-in{
  from{opacity:0;transform:translate(-50%,calc(-50% + 16px)) scale(.985)}
  to{opacity:1;transform:translate(-50%,-50%) scale(1)}
}
.lk-fit__x{
  position:absolute;top:12px;right:12px;width:38px;height:38px;padding:0;cursor:pointer;
  display:grid;place-items:center;color:var(--lk-ink-3);
  background:transparent;border:1px solid transparent;border-radius:var(--lk-r);
  transition:color var(--lk-fast) var(--lk-ease),background-color var(--lk-fast) var(--lk-ease),
             border-color var(--lk-fast) var(--lk-ease);
}
.lk-fit__x svg{width:19px;height:19px}
.lk-fit__x:hover{color:#fff;background:var(--lk-panel-3);border-color:var(--lk-line-2)}

.lk-fit__k{
  display:block;font:600 10.5px/1.3 var(--lk-mono);letter-spacing:.17em;
  text-transform:uppercase;color:var(--lk-cyan);margin-bottom:12px;
}
.lk-fit__h{
  font:800 clamp(1.6rem,3.6vw,2.15rem)/1.13 var(--lk-sans);letter-spacing:-.028em;
  color:#fff;margin:0;text-wrap:balance;
}
.lk-fit__p{
  font:400 15.5px/1.66 var(--lk-sans);color:var(--lk-ink-2);margin:14px 0 0;max-width:52ch;
}
.lk-fit__list{list-style:none;margin:20px 0 0;padding:0;display:grid;gap:11px}
.lk-fit__list li{display:flex;gap:11px;align-items:flex-start}
.lk-fit__list svg{width:19px;height:19px;flex:0 0 19px;margin-top:2px}
.lk-fit__list span{font:400 14.5px/1.58 var(--lk-sans);color:var(--lk-ink-2)}
.lk-fit__cta{margin-top:26px}

/* On a narrow screen the vertical tab is unusable, so it becomes a pill rather
   than a strip down the edge, and the button flattens against the edge.

   The rail stays vertically centred, which it did not until 9 September 2026.
   It used to move to bottom:16px on a phone, for thumb reach, and that broke
   the menu: .lk-dock__list is centred on its button with translateY(-50%), so
   a button 39px off the bottom of the screen opened a 130px panel with about
   65px of it below the fold. Three networks were configured and the third was
   cut in half. Centred, the panel has the whole viewport height to open into,
   and the middle of the right edge is a better one-handed target than the
   bottom corner anyway. */
@media(max-width:640px){
  .lk-dock{gap:8px;align-items:flex-end;padding-right:0}
  .lk-dock__tab{
    padding:11px 15px;border-radius:999px 0 0 999px;
    font-size:11px;letter-spacing:.1em;
  }
  .lk-dock__tab span{writing-mode:horizontal-tb}
  .lk-dock__btn{border-radius:999px 0 0 999px;width:46px;height:46px}
  .lk-dock__list{right:46px;min-width:158px}
}

/* Belt and braces on the same fault, at every width: however many networks
   get configured, the panel can never be taller than the screen it opens on.
   Six are wired up in _site-meta.json and three have URLs today, so a future
   three additions would take it past a short laptop viewport on their own. */
.lk-dock__list{
  max-height:calc(100vh - 32px);
  overflow-y:auto;
  overscroll-behavior:contain;
}

@media(prefers-reduced-motion:reduce){
  .lk-fit__scrim,.lk-fit__box,.lk-dock__tab{animation:none !important}
  .lk-dock__ic,.lk-dock__tab{transition-property:color,background-color,border-color !important}
}

/* --------------------------------------------------------------------------
   PRINT
   -------------------------------------------------------------------------- */
@media print{
  .lk-pre,.lk-pre__curtain,.lk-hdr,.lk-cue,.lk-hero__canvas,.lk-bg{display:none !important}
  .lk-dock,.lk-fit{display:none !important}
  body.lk-body{background:#fff;color:#000}
  .lk h1,.lk h2,.lk h3{color:#000}
}

/* A group label inside the drawer's expanded What we do list. Not a link, so
   it needs its own type: without it the six sectors read as more services. */
.lk-drawer__k{
  display:block;margin:14px 0 4px;
  font-family:var(--lk-mono);font-size:9.5px;font-weight:500;letter-spacing:.18em;
  text-transform:uppercase;color:var(--lk-sky);
}


/* --------------------------------------------------------------------------
   DIAGRAM LABELS ON A PHONE
   SVG text is in user units, so it shrinks with the drawing. The framework
   wheel is 340 units wide and renders at 312px on a 390px screen, which puts
   a 9.5 unit label on screen at 8.7px. There is room inside the ring band for
   the extra unit and a half, and every one of these words is repeated in the
   table below the wheel, so nothing depends on reading them. Legible anyway.
   -------------------------------------------------------------------------- */
@media(max-width:768px){
  .lk-d-l{font-size:11px;letter-spacing:.1em}
}
