/* ABSTRKTION. Built from the approved design prototype by build-site.py.
   Do not hand edit: re-run the build instead, or the next design revision overwrites you. */

/* ABSTRKTION self hosted fonts. Zero external origins.
 Cabinet Grotesk and General Sans: Indian Type Foundry, ITF Free Font Licence, self hosting permitted.
 IBM Plex Mono: SIL Open Font Licence 1.1.
 All three subset to the characters this site uses, downloaded and subset 25 August 2026.
 The arrow character exists only in IBM Plex Mono, so it is appended to the display stacks
 as a last resort fallback and renders from there. */

@font-face{font-family:'Cabinet Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('/assets/fonts/cabinet-grotesk-700.woff2') format('woff2');}
@font-face{font-family:'Cabinet Grotesk';font-style:normal;font-weight:800;font-display:swap;src:url('/assets/fonts/cabinet-grotesk-800.woff2') format('woff2');}
@font-face{font-family:'General Sans';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/general-sans-400.woff2') format('woff2');}
@font-face{font-family:'General Sans';font-style:normal;font-weight:500;font-display:swap;src:url('/assets/fonts/general-sans-500.woff2') format('woff2');}
@font-face{font-family:'General Sans';font-style:normal;font-weight:600;font-display:swap;src:url('/assets/fonts/general-sans-600.woff2') format('woff2');}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/ibm-plex-mono-400.woff2') format('woff2');}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/assets/fonts/ibm-plex-mono-500.woff2') format('woff2');}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url('/assets/fonts/ibm-plex-mono-600.woff2') format('woff2');}


*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:#0A0A0B;color:#F4F2ED;font-family:'General Sans','Helvetica Neue',sans-serif;font-size:clamp(1.0625rem,1.02rem + 0.1vw,1.125rem);line-height:1.62;overflow-x:clip;-webkit-font-smoothing:antialiased}
body::after{content:'';position:fixed;inset:0;z-index:95;pointer-events:none;background-image:url("/assets/brand/grain.webp");background-size:240px 240px;opacity:.5;mix-blend-mode:soft-light}
h1,h2,h3,h4{margin:0;text-wrap:pretty}
p{margin:0}
a{color:#F4F2ED;text-decoration:none;transition:color 220ms cubic-bezier(.16,1,.3,1)}
a:hover{color:#2BE8B0}
[data-dark]{color:#F4F2ED}
[data-dark] a{color:#F4F2ED}
[data-dark] a:hover{color:#2BE8B0}
[data-dark] [data-row]:hover{background:rgba(244,242,237,0.045)}
[data-dark] [data-lift]:hover{border-color:rgba(244,242,237,0.3)}
[data-bone]{color:#0A0A0B}
[data-bone] a{color:#0A0A0B}
[data-bone] a:hover{color:#0B7A5E}
[data-bone] [data-row]:hover{background:rgba(10,10,11,0.04)}
[data-bone] [data-lift]:hover{border-color:rgba(10,10,11,0.28)}
:focus-visible{outline:2px solid #2BE8B0;outline-offset:3px}
summary{cursor:pointer;list-style:none}
summary::-webkit-details-marker{display:none}
input,textarea,button,select{font:inherit;color:inherit}
img{max-width:100%;display:block}
@keyframes drift{0%{transform:translate3d(-3%,-2%,0) scale(1.08)}50%{transform:translate3d(3%,2%,0) scale(1.2)}100%{transform:translate3d(-3%,-2%,0) scale(1.08)}}
@keyframes marquee{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
[data-drift]{animation:drift 72s ease-in-out infinite}
[data-drift][data-paused="1"]{animation-play-state:paused}
[data-marquee]{animation:marquee 22s linear infinite}
[data-marquee]:hover{animation-play-state:paused}
[data-arrow]{display:inline-block;transition:transform 240ms cubic-bezier(.16,1,.3,1)}
a:hover [data-arrow],summary:hover [data-arrow]{transform:translateX(7px)}
[data-row]{transition:background 280ms cubic-bezier(.16,1,.3,1)}
[data-row]:hover{background:rgba(244,242,237,0.04)}
[data-row]:hover [data-rule],details[open] [data-rule]{transform:scaleX(1)}
[data-rule]{transform:scaleX(0);transform-origin:left;transition:transform 460ms cubic-bezier(.16,1,.3,1)}
[data-lift]{transition:transform 280ms cubic-bezier(.16,1,.3,1),border-color 280ms cubic-bezier(.16,1,.3,1)}
[data-lift]:hover{transform:translateY(-4px);border-color:rgba(244,242,237,0.26)}
details[open] [data-plus]{transform:rotate(45deg)}
@keyframes sheen{0%{background-position:0% 50%}100%{background-position:100% 50%}}
@keyframes barpulse{0%,100%{opacity:.5}50%{opacity:1}}
[data-sheen]{animation:sheen 11s linear infinite}
@supports not ((-webkit-background-clip:text) or (background-clip:text)){[data-sheen]{-webkit-text-fill-color:currentColor;background-image:none}}
[data-row]{position:relative}
[data-row]::before{content:"";position:absolute;left:0;top:6px;bottom:6px;width:2px;background:linear-gradient(180deg,#2BE8B0,#5B8CF7,#8E6BFF);transform:scaleY(0);transform-origin:top;transition:transform 460ms cubic-bezier(.16,1,.3,1)}
[data-row]:hover::before{transform:scaleY(1)}
[data-row] h3,[data-row] [data-rowname]{transition:transform 460ms cubic-bezier(.16,1,.3,1)}
[data-row]:hover h3,[data-row]:hover [data-rowname]{transform:translateX(14px)}
[data-magnetic]{transition:transform 520ms cubic-bezier(.16,1,.3,1),background 240ms cubic-bezier(.16,1,.3,1),box-shadow 240ms cubic-bezier(.16,1,.3,1)}
[data-magnetic]:active{transform:translate3d(0,2px,0) !important}
[data-mark]{transition:transform 900ms cubic-bezier(.16,1,.3,1)}
a:hover [data-mark]{transform:rotate(90deg)}
[data-quad]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px}
@media (max-width:560px){[data-quad]{grid-template-columns:minmax(0,1fr)}}
@media (min-width:1080px){[data-quad]{grid-template-columns:repeat(4,minmax(0,1fr))}}
[data-progress]{position:absolute;left:0;right:0;bottom:-1px;height:2px;transform:scaleX(0);transform-origin:left;background:linear-gradient(90deg,#2BE8B0,#5B8CF7,#8E6BFF);transition:transform 140ms linear;pointer-events:none}
[data-watermark]{transition:opacity 900ms cubic-bezier(.16,1,.3,1)}
summary [data-plus]{transition:transform 420ms cubic-bezier(.16,1,.3,1)}
[data-motion="off"] [data-drift],[data-motion="off"] [data-marquee],[data-motion="off"] [data-sheen]{animation:none !important}
[data-motion="off"] [data-row]::before,[data-motion="off"] [data-row] h3,[data-motion="off"] [data-magnetic],[data-motion="off"] [data-arrow],[data-motion="off"] [data-mark]{transition:none !important}
@media (max-width:1239px){[data-desktop-only]{display:none !important}body{padding-bottom:calc(66px + env(safe-area-inset-bottom))}}
@media (min-width:1240px){[data-mobile-only]{display:none !important}}

/* The prototype switched motion off through a runtime prop. A real site has to
   honour the setting the reader actually has, so this does it properly. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
  [data-drift],[data-marquee],[data-sheen]{animation:none !important}
  [data-parallax]{transform:none !important}
  [data-glow]{display:none !important}
}
/* The arrow character exists only in IBM Plex Mono, so let it fall through to it. */
[data-arrow]{font-family:'IBM Plex Mono',monospace}
/* Skip link, for keyboard and screen reader users. */
.skip{position:absolute;left:-9999px;top:0;z-index:999;background:#2BE8B0;color:#0A0A0B;
  padding:12px 18px;border-radius:0 0 6px 0;font-weight:600}
.skip:focus{left:0}
/* The enquiry confirmation, revealed by enquiry.php redirecting back with ?sent=1,
   and the error message, revealed on ?error= by site.js. */
[data-sent]{display:none}
body.is-sent [data-sent]{display:inline-block}
[data-error]{display:none}
body.is-error [data-error]{display:inline-block}
/* The teal focus ring is invisible on the bone sections (1.4:1). A darker ring
   there keeps keyboard focus visible everywhere (mobile lens finding 8). */
[data-bone] :focus-visible{outline-color:#0B7A5E}
/* Focus state for form fields, lifted out of the prototype's style-focus. */
.ff:focus{background:#23232A;border-color:#2BE8B0}
/* The hidden attribute always wins. An inline display once beat it and left the
   mobile menu overlay open on every page load (25 Aug 2026). Never remove this. */
[hidden]{display:none!important}
/* overflow-y:auto so a landscape phone can still reach the bottom menu links. */
[data-menu-panel]:not([hidden]){display:flex;flex-direction:column;overflow-y:auto}

/* Hover and focus states, lifted out of the prototype's style-hover attributes
   so they work without JavaScript and never flash before a script loads. */
.h0:hover,.h0:focus-visible{background:#2BE8B0;color:#0A0A0B;box-shadow:0 12px 34px rgba(52,184,150,0.3)}
.h1:hover,.h1:focus-visible{background:#5BFFCB;color:#0A0A0B;box-shadow:0 18px 52px rgba(43,232,176,0.32)}
.h2:hover,.h2:focus-visible{background:#2BE8B0}
