/* ibm-plex-sans-cyrillic-ext-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_astro/ibm-plex-sans-cyrillic-ext-300-normal.DqmgDkIN.woff2) format('woff2'), url(/_astro/ibm-plex-sans-cyrillic-ext-300-normal.Bbd5v1xK.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_astro/ibm-plex-sans-cyrillic-300-normal.RhT0Ayi3.woff2) format('woff2'), url(/_astro/ibm-plex-sans-cyrillic-300-normal.LoaTnByX.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_astro/ibm-plex-sans-greek-300-normal.J-CBqZoJ.woff2) format('woff2'), url(/_astro/ibm-plex-sans-greek-300-normal.STc8XiDr.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_astro/ibm-plex-sans-vietnamese-300-normal.SDfX6ktj.woff2) format('woff2'), url(/_astro/ibm-plex-sans-vietnamese-300-normal.CkYRZD2a.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* ibm-plex-sans-latin-ext-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_astro/ibm-plex-sans-latin-ext-300-normal.BLFuR0P1.woff2) format('woff2'), url(/_astro/ibm-plex-sans-latin-ext-300-normal.B8Zgwjh3.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-sans-latin-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(/_astro/ibm-plex-sans-latin-300-normal.b4i7YzLG.woff2) format('woff2'), url(/_astro/ibm-plex-sans-latin-300-normal.C9Of02-5.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* ibm-plex-sans-cyrillic-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/ibm-plex-sans-cyrillic-ext-400-normal.g30qAdWV.woff2) format('woff2'), url(/_astro/ibm-plex-sans-cyrillic-ext-400-normal.Dsrv2Tcn.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/ibm-plex-sans-cyrillic-400-normal.DZqxrq2p.woff2) format('woff2'), url(/_astro/ibm-plex-sans-cyrillic-400-normal.BTotfTJu.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/ibm-plex-sans-greek-400-normal._efipK4i.woff2) format('woff2'), url(/_astro/ibm-plex-sans-greek-400-normal.D9ESIMu3.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/ibm-plex-sans-vietnamese-400-normal.DG4YqDda.woff2) format('woff2'), url(/_astro/ibm-plex-sans-vietnamese-400-normal.fK1oJ5dG.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* ibm-plex-sans-latin-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/ibm-plex-sans-latin-ext-400-normal.C5H60-Va.woff2) format('woff2'), url(/_astro/ibm-plex-sans-latin-ext-400-normal.RBey6euL.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-sans-latin-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/ibm-plex-sans-latin-400-normal.CDDApCn2.woff2) format('woff2'), url(/_astro/ibm-plex-sans-latin-400-normal.CYLoc0-x.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* ibm-plex-sans-cyrillic-ext-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/ibm-plex-sans-cyrillic-ext-600-normal.DUMzJB7m.woff2) format('woff2'), url(/_astro/ibm-plex-sans-cyrillic-ext-600-normal.Bz0x94Yp.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/ibm-plex-sans-cyrillic-600-normal.71GNu3SW.woff2) format('woff2'), url(/_astro/ibm-plex-sans-cyrillic-600-normal.BGq0mW3O.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/ibm-plex-sans-greek-600-normal.DzTrcv_p.woff2) format('woff2'), url(/_astro/ibm-plex-sans-greek-600-normal.D-CqTdkO.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/ibm-plex-sans-vietnamese-600-normal.DpPYBSTl.woff2) format('woff2'), url(/_astro/ibm-plex-sans-vietnamese-600-normal.DgdngZtN.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* ibm-plex-sans-latin-ext-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/ibm-plex-sans-latin-ext-600-normal.DOrvGEcy.woff2) format('woff2'), url(/_astro/ibm-plex-sans-latin-ext-600-normal.DIrixKbi.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-sans-latin-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/ibm-plex-sans-latin-600-normal.CuJfVYMP.woff2) format('woff2'), url(/_astro/ibm-plex-sans-latin-600-normal.Cu4Hd6ag.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* jetbrains-mono-cyrillic-ext-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/jetbrains-mono-cyrillic-ext-400-normal.C_uLvvQ5.woff2) format('woff2'), url(/_astro/jetbrains-mono-cyrillic-ext-400-normal.Bh0R7Dhr.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* jetbrains-mono-cyrillic-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/jetbrains-mono-cyrillic-400-normal.BEIGL1Tu.woff2) format('woff2'), url(/_astro/jetbrains-mono-cyrillic-400-normal.ugxPyKxw.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* jetbrains-mono-greek-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/jetbrains-mono-greek-400-normal.C190GLew.woff2) format('woff2'), url(/_astro/jetbrains-mono-greek-400-normal.B9oWc5Lo.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* jetbrains-mono-vietnamese-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/jetbrains-mono-vietnamese-400-normal.ByoDsISC.woff2) format('woff2'), url(/_astro/jetbrains-mono-vietnamese-400-normal.CqNFfHCs.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* jetbrains-mono-latin-ext-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/jetbrains-mono-latin-ext-400-normal.Bc8Ftmh3.woff2) format('woff2'), url(/_astro/jetbrains-mono-latin-ext-400-normal.fXTG6kC5.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* jetbrains-mono-latin-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/_astro/jetbrains-mono-latin-400-normal.V6pRDFza.woff2) format('woff2'), url(/_astro/jetbrains-mono-latin-400-normal.6-qcROiO.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* jetbrains-mono-cyrillic-ext-600-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/jetbrains-mono-cyrillic-ext-600-normal.Dj6eZy5f.woff2) format('woff2'), url(/_astro/jetbrains-mono-cyrillic-ext-600-normal.DVvC-yKp.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* jetbrains-mono-cyrillic-600-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/jetbrains-mono-cyrillic-600-normal.EVf6-Yzo.woff2) format('woff2'), url(/_astro/jetbrains-mono-cyrillic-600-normal.8K4wrrwR.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* jetbrains-mono-greek-600-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/jetbrains-mono-greek-600-normal.H7WoG9Et.woff2) format('woff2'), url(/_astro/jetbrains-mono-greek-600-normal.mc2nkWzM.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* jetbrains-mono-vietnamese-600-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/jetbrains-mono-vietnamese-600-normal.Dtizs43-.woff2) format('woff2'), url(/_astro/jetbrains-mono-vietnamese-600-normal.OWROknRo.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* jetbrains-mono-latin-ext-600-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/jetbrains-mono-latin-ext-600-normal.BfB_LPfz.woff2) format('woff2'), url(/_astro/jetbrains-mono-latin-ext-600-normal.DObL3zCW.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* jetbrains-mono-latin-600-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/_astro/jetbrains-mono-latin-600-normal.C8RAYTDA.woff2) format('woff2'), url(/_astro/jetbrains-mono-latin-600-normal.BfsvjouI.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* Styles of the approved prototype (prototype/home.html at 6c54582), carried over as they are. */

  /* headings: ZabSoft Display, Mona Sans Expanded with the logo's round stroke ends */
  /* Cyrillic: letters unique to Cyrillic come from this half (Roboto Flex set to Mona's proportions, same rounding); look-alikes stay in Mona, declared last so it wins */
  @font-face { font-family:'ZabSoft Display'; src:url('/_astro/zabsoft-display-cyr.Dc9zebRF.woff2') format('woff2'); font-weight:400; font-style:normal; font-display:swap; unicode-range:U+0400-045F, U+0490-0491, U+2116; }
  @font-face { font-family:'ZabSoft Display'; src:url('/_astro/zabsoft-display.xnP2PZYs.woff2') format('woff2'); font-weight:400; font-style:normal; font-display:swap; }
  :root { --display:'ZabSoft Display', 'Arial Black', sans-serif; }
  :root, :root[data-theme="dark"] { color-scheme:dark; --bg:#05070f; --bgc:5 7 15; --ink:#e9edf7; --inkc:233 237 247; --edge:255 255 255; --raise:255 255 255; --rk:1;
    --surface:#0b0f1d; --blue:#8f9cff; --teal:#00d6b4; --line:rgba(120,140,255,.075); --shade:0 0 0; --sk:1;
    --glass:linear-gradient(135deg, rgba(255,255,255,.075), rgba(255,255,255,.02)); --drawer:rgba(8,11,24,.86); --panel:linear-gradient(135deg, rgba(20,26,52,.96), rgba(10,13,28,.96));
    --glow-b:rgba(92,108,255,.42); --glow-t:rgba(0,214,180,.26); --glow-v:rgba(170,90,255,.24); --grain:.06; --hl:rgba(143,156,255,.22); --hl-edge:rgba(160,172,255,.5); --halo:rgba(110,125,255,.25);
    --pulse-a:143,156,255; --pulse-b:190,200,255; --pulse-op:lighter; --ease:cubic-bezier(.7,0,.2,1); --out:cubic-bezier(.2,.8,.2,1); }
  :root[data-theme="light"] { color-scheme:light; --bg:#f2f3f9; --bgc:242 243 249; --ink:#0c1024; --inkc:12 16 36; --edge:20 28 70; --raise:255 255 255; --rk:7;
    --surface:#ffffff; --blue:#4c59e6; --teal:#00957d; --line:rgba(60,72,160,.085); --shade:28 36 90; --sk:.28;
    --glass:linear-gradient(135deg, rgba(255,255,255,.86), rgba(255,255,255,.58)); --drawer:rgba(246,247,252,.84); --panel:linear-gradient(135deg, rgba(255,255,255,.97), rgba(243,245,252,.97));
    --glow-b:rgba(92,108,255,.24); --glow-t:rgba(0,200,170,.2); --glow-v:rgba(170,90,255,.15); --grain:.045; --hl:rgba(92,108,255,.12); --hl-edge:rgba(92,108,255,.45); --halo:rgba(92,108,255,.18);
    --pulse-a:92,108,255; --pulse-b:92,108,255; --pulse-op:source-over; }
  * { box-sizing:border-box; }
  html, body { margin:0; background:var(--bg); color:var(--ink); font-family:'IBM Plex Sans',sans-serif; font-size:16px; line-height:1.5; }
  body { overflow-x:hidden; }
  a { color:inherit; text-decoration:none; }
  button { font:inherit; color:inherit; }

  /* one background for the whole site */
  .grid { position:fixed; inset:0; z-index:0; pointer-events:none; background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px); background-size:44px 44px; }
  canvas.pulse { position:fixed; inset:0; z-index:0; pointer-events:none; }
  .glowwrap { position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden; }
  .glows { position:absolute; inset:0; }
  .glow { position:absolute; top:0; border-radius:50%; animation: drift 22s ease-in-out infinite alternate; }
  .glow.b { background:radial-gradient(circle, var(--glow-b), transparent 65%); }
  .glow.t { background:radial-gradient(circle, var(--glow-t), transparent 65%); }
  .glow.v { background:radial-gradient(circle, var(--glow-v), transparent 65%); }
  @keyframes drift { from { translate:0 0; } to { translate:60px -40px; } }
  .grain { position:fixed; inset:0; z-index:2; pointer-events:none; opacity:var(--grain); background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .55 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }
  main, footer.f { position:relative; z-index:1; }

  .mono { font-family:'JetBrains Mono',monospace; font-size:12px; letter-spacing:.1em; text-transform:uppercase; opacity:.7; }
  h1, h2, h3 { font-family:var(--display); font-weight:400; margin:0; }
  h2 { font-size:clamp(34px,4.4vw,56px); line-height:1.02; margin:12px 0 18px; }
  h3 { font-size:22px; line-height:1.1; margin-bottom:8px; }
  p { margin:0; opacity:.86; }
  .wrap { width:min(1280px,100%); margin:0 auto; padding-left:clamp(18px,4vw,64px); padding-right:clamp(18px,4vw,64px); }
  section.wrap { padding-top:150px; padding-bottom:150px; }
  .head { max-width:760px; }
  .body { margin-top:76px; }          /* room for the parallax: heading and blocks never meet */
  .glass { background:var(--glass); border:1px solid rgb(var(--edge) / .13); border-radius:20px; }
  .btn { display:inline-block; padding:13px 20px; border-radius:12px; background:var(--ink); color:var(--bg); font-weight:600; transition: box-shadow .3s, transform .3s; }
  .btn:hover { box-shadow:0 0 30px rgba(143,156,255,.45); }
  .ghost { display:inline-block; padding:12px 18px; border-radius:12px; border:1px solid rgb(var(--inkc) / .3); transition: background .3s; }
  .ghost:hover { background:rgb(var(--raise) / calc(.06 * var(--rk))); }
  .chip { display:inline-block; padding:6px 12px; border-radius:999px; border:1px solid rgb(var(--edge) / .18); font-size:13px; margin:0 6px 8px 0; cursor:pointer; user-select:none; }
  .chip.on { background:var(--ink); color:var(--bg); border-color:transparent; font-weight:600; }
  .tag b { color:var(--blue); font-weight:600; }

  /* scroll parallax (--sy) and pointer drift (--mx/--my) share one property */
  [data-speed], [data-depth] { translate: var(--mx,0px) calc(var(--sy,0px) + var(--my,0px)); }

  /* hover light: follows the pointer, comes in fast, fades out slowly */
  .hl { position:relative; transition: box-shadow 1.2s ease; }
  .hl::before { content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none; z-index:3; opacity:0;
    background: radial-gradient(460px circle at var(--hx,50%) var(--hy,50%), var(--hl), transparent 60%);
    box-shadow: inset 0 0 0 1px var(--hl-edge); transition: opacity 1.2s ease; }
  .hl:hover::before { opacity:1; transition: opacity .3s ease; }
  .hl:hover { box-shadow:0 0 50px rgba(92,108,255,.22); transition: box-shadow .3s ease; }

  /* header and the menu button that flips into Close */
  header.top { position:fixed; top:0; left:0; right:0; z-index:60; display:flex; justify-content:space-between; align-items:center; padding:18px clamp(18px,3vw,28px); pointer-events:none; }
  header.top > * { pointer-events:auto; }
  .logo { display:inline-flex; align-items:center; color:var(--ink); transition: color .3s, filter .3s; }
  .logo .logo-svg { height:28px; width:auto; display:block; }
  .logo:hover { filter: drop-shadow(0 0 14px rgba(143,156,255,.55)); }
  footer.f .logo .logo-svg { height:24px; }
  .burger { display:flex; align-items:center; gap:12px; padding:10px 18px; border-radius:999px; background:rgb(var(--raise) / calc(.08 * var(--rk))); border:1px solid rgb(var(--edge) / .18); cursor:pointer;
    backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px); transition: background .4s, border-color .4s; }
  .burger:hover { background:rgb(var(--raise) / calc(.14 * var(--rk))); }
  .burger .ic { position:relative; width:16px; height:12px; }
  .burger .ic i { position:absolute; left:0; width:16px; height:2px; border-radius:1px; background:var(--ink); transition: top .45s var(--ease), transform .45s var(--ease); }
  .burger .ic i:first-child { top:2px; } .burger .ic i:last-child { top:8px; }
  .burger .lbl { display:inline-grid; perspective:220px; font-family:'JetBrains Mono'; font-size:13px; letter-spacing:.1em; }
  .burger .lbl span { grid-area:1/1; transition: transform .6s var(--ease), opacity 0s linear .3s; transform-origin:50% 50% -7px; }
  .burger .lbl .b { transform: rotateX(-180deg); opacity:0; }
  body.menu .burger { background:rgb(var(--raise) / calc(.16 * var(--rk))); border-color:rgb(var(--edge) / .3); }
  body.menu .burger .ic i:first-child { top:5px; transform: rotate(45deg); }
  body.menu .burger .ic i:last-child { top:5px; transform: rotate(-45deg); }
  body.menu .burger .lbl .f { transform: rotateX(180deg); opacity:0; }
  body.menu .burger .lbl .b { transform: rotateX(0); opacity:1; }

  /* menu: the page blurs, the drawer opens as a circle from the button, items come in one by one */
  .veil { position:fixed; inset:0; z-index:50; background:rgb(var(--bgc) / 0); backdrop-filter:blur(0); -webkit-backdrop-filter:blur(0); visibility:hidden; pointer-events:none;
    transition: background .5s, backdrop-filter .5s, -webkit-backdrop-filter .5s, visibility 0s .5s; }
  body.menu .veil { visibility:visible; pointer-events:auto; background:rgb(var(--bgc) / .35); backdrop-filter:blur(16px) saturate(.9); -webkit-backdrop-filter:blur(16px) saturate(.9);
    transition: background .5s, backdrop-filter .5s, -webkit-backdrop-filter .5s, visibility 0s; }
  .drawer { position:fixed; top:0; right:0; bottom:0; width:min(600px,100%); z-index:55; padding:92px 26px 22px; display:flex; flex-direction:column; gap:10px;
    background:var(--drawer); backdrop-filter:blur(18px); -webkit-backdrop-filter:blur(18px); border-left:1px solid rgb(var(--edge) / .12);
    clip-path: circle(0px at calc(100% - 70px) 40px); visibility:hidden; transition: clip-path .6s var(--ease), visibility 0s .6s; }
  body.menu .drawer { clip-path: circle(150vmax at calc(100% - 70px) 40px); visibility:visible; transition: clip-path .85s var(--ease), visibility 0s; }
  .drawer > * { opacity:0; transform: translateX(46px); transition: opacity .3s, transform .3s; }
  body.menu .drawer > * { opacity:1; transform:none; transition: opacity .6s var(--out), transform .8s var(--out); }
  body.menu .drawer > :nth-child(1) { transition-delay:.18s; } body.menu .drawer > :nth-child(2) { transition-delay:.24s; }
  body.menu .drawer > :nth-child(3) { transition-delay:.30s; } body.menu .drawer > :nth-child(4) { transition-delay:.36s; }
  body.menu .drawer > :nth-child(5) { transition-delay:.42s; } body.menu .drawer > :nth-child(6) { transition-delay:.50s; }
  .row { position:relative; flex:1; border-radius:16px; overflow:hidden; display:flex; flex-direction:column; align-items:flex-end; justify-content:center; padding:0 22px; gap:6px; border:1px solid rgb(var(--edge) / .12); }
  .row { clip-path: inset(0 round 16px); }
  .row .bg { position:absolute; inset:-6px; background-size:cover; background-position:left center; filter:blur(1.2px) brightness(.85); transition: filter .4s, transform .6s; }
  .row::after { content:''; position:absolute; inset:0; background:linear-gradient(270deg, rgb(var(--bgc) / .55), rgb(var(--bgc) / 0) 60%); }
  .row:hover .bg { filter:none; transform:scale(1.04); }
  .row > span { position:relative; z-index:1; }
  .row .m { font-family:'JetBrains Mono'; font-size:12px; letter-spacing:.06em; opacity:.75; }
  .row .t { font-family:var(--display); font-size:30px; line-height:1; transition: transform .3s; }
  .row:hover .t { transform: translateX(-8px); }
  .dfoot { display:flex; gap:8px; justify-content:flex-end; flex-wrap:wrap; }

  /* messengers: quiet and monochrome, the real brand colour on hover */
  .msg { display:inline-flex; align-items:center; gap:10px; padding:9px 15px; border-radius:999px; border:1px solid rgb(var(--edge) / .2); color:rgb(var(--inkc) / .82); background:rgb(var(--raise) / calc(.03 * var(--rk)));
    transition: background .45s, border-color .45s, color .45s, box-shadow .45s; font-size:14px; }
  .msg svg { width:18px; height:18px; flex:none; }
  .msg.tg:hover { background:#229ED9; border-color:#229ED9; color:#fff; box-shadow:0 0 34px rgba(34,158,217,.5); }
  .msg.wa:hover { background:#25D366; border-color:#25D366; color:#fff; box-shadow:0 0 34px rgba(37,211,102,.45); }
  .msg.em:hover { background:linear-gradient(135deg,#5c6cff,#8f9cff); border-color:#8f9cff; color:#fff; box-shadow:0 0 34px rgba(143,156,255,.5); }
  .msg.go { background:var(--ink); color:var(--bg); border-color:transparent; font-weight:600; }

  /* hero */
  .hero { min-height:100vh; display:grid; grid-template-columns:1fr 1fr; align-items:center; padding-top:90px; padding-bottom:40px; }
  .hero h1 { font-size:clamp(40px,4.8vw,64px); line-height:1.02; }
  .hero .lead { margin:34px 0 26px; max-width:480px; font-weight:300; }
  .deck { position:relative; width:580px; height:450px; justify-self:end; }
  .card { position:absolute; left:62px; top:126px; width:518px; height:324px; border-radius:14px; overflow:hidden; border:1px solid rgb(var(--edge) / .16); box-shadow:0 26px 60px rgb(var(--shade) / calc(.65 * var(--sk))); background:var(--surface);
    transition: transform .65s var(--out), opacity .65s; -webkit-mask-image:-webkit-radial-gradient(white,black); isolation:isolate; cursor:pointer; }
  .card::after { content:''; position:absolute; inset:0; background:var(--bg); opacity:var(--dim,0); transition:opacity .65s; pointer-events:none; }
  .card img, .card video { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:top; display:block; }
  .card video { transform:translateZ(0); }
  .card img.tall { height:auto; bottom:auto; }
  .card[data-pos="0"] img.tall { animation: pan 4.6s cubic-bezier(.45,0,.4,1) .3s both; }
  @keyframes pan { to { transform: translateY(calc(-100% + 324px)); } }
  .card .chip2 { position:absolute; left:12px; bottom:12px; z-index:2; padding:6px 12px; border-radius:999px; background:rgb(var(--bgc) / .62); border:1px solid rgb(var(--edge) / .18); font-size:13px; white-space:nowrap; }
  .card .chip2 b { color:var(--blue); font-weight:600; }
  .card[data-pos="0"] { transform: perspective(1100px) rotateY(-16deg) rotateX(5deg); z-index:7; --dim:0; }
  .card[data-pos="1"] { transform: perspective(1100px) rotateY(-16deg) rotateX(5deg) translate(-31px,-32px) scale(.94); z-index:6; --dim:.25; }
  .card[data-pos="2"] { transform: perspective(1100px) rotateY(-16deg) rotateX(5deg) translate(-62px,-64px) scale(.88); z-index:5; --dim:.45; }
  .card[data-pos="3"] { transform: perspective(1100px) rotateY(-16deg) rotateX(5deg) translate(-93px,-96px) scale(.82); z-index:4; --dim:.6; }
  .card[data-pos="4"] { transform: perspective(1100px) rotateY(-16deg) rotateX(5deg) translate(-124px,-128px) scale(.76); z-index:3; --dim:.72; }
  .card[data-pos="5"], .card[data-pos="6"] { transform: perspective(1100px) rotateY(-16deg) rotateX(5deg) translate(-150px,-150px) scale(.7); z-index:1; opacity:0; }
  .card.leave { transform: perspective(1100px) rotateY(-16deg) rotateX(5deg) translate(330px,40px) rotate(10deg) !important; z-index:8 !important; --dim:0 !important; transition: transform .42s cubic-bezier(.5,0,.75,0); }

  .svc { display:grid; grid-template-columns:repeat(4,1fr); gap:16px; }
  .svc .s { padding:18px; display:flex; flex-direction:column; gap:10px; min-height:340px; }
  .svc .art { height:96px; border-radius:12px; background-size:cover; background-position:left center; border:1px solid rgb(var(--edge) / .1); }
  .svc .price { margin-top:auto; font-family:'JetBrains Mono'; font-size:13px; }
  .svc .cases { font-size:13px; opacity:.7; }

  /* work: screenshots keep their 16:10 frame, the caption sits under the picture */
  .filters { margin:26px 0 0; }
  .work { display:grid; grid-template-columns:repeat(6,1fr); gap:18px; }
  .w { position:relative; border-radius:18px; overflow:hidden; border:1px solid rgb(var(--edge) / .14); background:var(--surface); display:flex; flex-direction:column; }
  .w .shot { aspect-ratio:16/10; overflow:hidden; border-bottom:1px solid rgb(var(--edge) / .08); }
  .w .shot img { width:100%; height:100%; object-fit:cover; object-position:top; display:block; transition: transform .9s var(--out); }
  .w:hover .shot img { transform: scale(1.03); }
  .w .cap { padding:14px 16px 16px; }
  .w .cap h3 { font-size:19px; margin:4px 0; }
  .w .cap p { font-size:14px; }
  .big { grid-column:span 3; } .mid { grid-column:span 2; }

  .prod { display:grid; grid-template-columns:1.5fr 1fr; gap:18px; }
  .live { border-radius:22px; overflow:hidden; border:1px solid rgba(0,214,180,.5); box-shadow:0 0 70px rgba(0,214,180,.12); background:var(--surface); display:flex; flex-direction:column; }
  .live .shot { aspect-ratio:16/10; overflow:hidden; }
  .live .shot img { width:100%; height:100%; object-fit:cover; object-position:top; display:block; }
  .live .cap { padding:18px; display:flex; justify-content:space-between; align-items:center; gap:16px; }
  .promo { display:flex; flex-direction:column; }
  .promo .pv { position:relative; aspect-ratio:16/9; background:var(--surface); border-bottom:1px solid rgb(var(--edge) / .1); }
  .promo video { width:100%; height:100%; object-fit:cover; display:block; }
  .promo .snd { position:absolute; right:12px; bottom:12px; width:40px; height:40px; border-radius:50%; border:1px solid rgb(var(--edge) / .3); background:rgb(var(--bgc) / .55); cursor:pointer; font-size:16px; }
  .promo .pinfo { padding:22px 24px; display:grid; grid-template-columns:1fr auto; gap:6px 20px; align-items:center; }
  .promo .pinfo > span, .promo .pinfo h3, .promo .pinfo p { grid-column:1; }
  .promo .pinfo .btn { grid-column:2; grid-row:1 / span 3; }
  .soon { display:grid; gap:18px; }
  .soon .glass { padding:24px; display:flex; flex-direction:column; justify-content:center; }
  .dot { display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--teal); margin-right:6px; }
  .dot.b { background:var(--blue); }

  .steps { display:grid; grid-template-columns:repeat(4,1fr); gap:16px; }
  .steps .st { padding:20px; }
  .steps .n { font-family:var(--display); font-size:40px; color:var(--blue); opacity:.8; }
  .steps .fact { margin-top:10px; font-family:'JetBrains Mono'; font-size:12px; color:var(--teal); }

  .stepcta { margin-top:34px; display:flex; align-items:center; gap:20px; flex-wrap:wrap; font-size:18px; }
  .stepcta .btn { border:0; cursor:pointer; font-size:16px; }
  /* the brief as a popup */
  .pop { position:fixed; inset:0; z-index:80; display:grid; place-items:center; padding:20px; background:rgb(var(--bgc) / 0); backdrop-filter:blur(0); -webkit-backdrop-filter:blur(0); visibility:hidden;
    transition: background .45s, backdrop-filter .45s, -webkit-backdrop-filter .45s, visibility 0s .45s; }
  .pop.on { visibility:visible; background:rgb(var(--bgc) / .45); backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px); transition: background .45s, backdrop-filter .45s, -webkit-backdrop-filter .45s, visibility 0s; }
  .pop .panel { position:relative; width:min(760px,100%); max-height:calc(100vh - 40px); overflow:auto; padding:30px; border-radius:24px; background:var(--panel); border:1px solid rgb(var(--edge) / .16); box-shadow:0 40px 120px rgb(var(--shade) / calc(.6 * var(--sk))), 0 0 80px rgba(92,108,255,.18);
    opacity:0; transform: translateY(26px) scale(.96); transition: opacity .35s, transform .45s var(--out); }
  .pop.on .panel { opacity:1; transform:none; transition: opacity .45s .05s, transform .6s var(--out) .05s; }
  .pop .panel form { display:grid; gap:14px; margin-top:18px; }
  .pop .x { position:absolute; top:16px; right:16px; width:40px; height:40px; border-radius:50%; border:1px solid rgb(var(--edge) / .22); background:rgb(var(--raise) / calc(.05 * var(--rk))); cursor:pointer; font-size:18px; }
  .pop .msgs { display:flex; gap:8px; flex-wrap:wrap; margin-top:18px; padding-top:18px; border-top:1px solid rgb(var(--edge) / .1); }
  .quotes { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; }
  .q { padding:24px; }
  .q p { font-size:17px; opacity:.95; }
  .q .who { margin-top:14px; font-size:13px; opacity:.7; }

  /* about: the cut-out portrait stands in light */
  .about { display:grid; grid-template-columns:440px 1fr; gap:48px; align-items:center; }
  .portrait { position:relative; height:560px; }
  .portrait img { position:absolute; left:0; right:0; bottom:0; margin:auto; height:100%; object-fit:contain; filter: drop-shadow(0 0 30px var(--halo)); }
  .who-name { margin-top:16px; font-family:'JetBrains Mono'; font-size:13px; letter-spacing:.06em; opacity:.8; }
  .facts { display:flex; gap:12px; margin-top:22px; flex-wrap:wrap; }
  .facts span { padding:8px 12px; border-radius:10px; border:1px solid rgb(var(--edge) / .14); font-family:'JetBrains Mono'; font-size:12px; }

  .posts { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; }
  .p { overflow:hidden; }
  .p .img { height:150px; background-size:cover; background-position:left center; }
  .p .b { padding:18px; }

  .brief { display:grid; grid-template-columns:1.3fr 1fr; gap:24px; align-items:stretch; }
  .brief form { padding:26px; display:grid; gap:14px; }
  .in { padding:13px 14px; border-radius:12px; border:1px solid rgb(var(--edge) / .18); background:rgb(var(--raise) / calc(.03 * var(--rk))); opacity:.8; font-size:15px; }
  .side { padding:22px; display:flex; flex-direction:column; gap:12px; }
  .side h3 { margin:2px 0 4px; }
  .side .msg { flex:1; min-height:92px; border-radius:16px; padding:0 22px; gap:16px; font-size:19px; }
  .side .msg svg { width:30px; height:30px; }
  .side .msg small { display:block; font-family:'JetBrains Mono'; font-size:12px; letter-spacing:.04em; opacity:.7; margin-top:2px; }
  footer.f { padding:40px 0 60px; border-top:1px solid rgb(var(--edge) / .1); }
  footer.f .wrap { display:flex; justify-content:space-between; align-items:center; gap:20px; flex-wrap:wrap; font-size:13px; opacity:.85; }

  @media (max-width:900px) {
    .hero { grid-template-columns:1fr; }
    .deck { zoom:.8; justify-self:center; margin-top:10px; }   /* zoom shrinks the layout box too, transform did not */
    .svc, .steps, .quotes, .posts { grid-template-columns:1fr 1fr; }
    .prod, .brief, .about { grid-template-columns:1fr; }
    .big, .mid { grid-column:span 6; }
    .promo .pinfo { grid-template-columns:1fr; }
    .promo .pinfo .btn { grid-column:1; grid-row:auto; justify-self:start; margin-top:10px; }
    .portrait { height:440px; }
    .portrait img { max-width:100%; }
  }
  @media (max-width:600px) {
    .hero { min-height:auto; padding-top:110px; }
    .deck { zoom:.6; }
    .svc, .steps, .quotes, .posts { grid-template-columns:1fr; }
  }
  @media (max-width:380px) { .deck { zoom:.54; } }
  @media (prefers-reduced-motion: reduce) { .glow { animation:none; } }

  /* once the page moves, the header gets a frosted strip so text never runs under the logo and buttons */
  header.top::before { content:''; position:absolute; inset:0; z-index:-1; pointer-events:none; opacity:0; transition: opacity .35s;
    background:rgb(var(--bgc) / .72); backdrop-filter:blur(14px) saturate(1.1); -webkit-backdrop-filter:blur(14px) saturate(1.1); border-bottom:1px solid rgb(var(--edge) / .08); }
  header.top.solid::before { opacity:1; }
  body.menu header.top::before { opacity:0; }
  /* a card is one big link */
  .stretch::after { content:''; position:absolute; inset:0; z-index:2; }
  .svc .s, .posts .p { transition: transform .5s var(--out), box-shadow 1.2s ease; }
  .svc .s:hover, .posts .p:hover { transform:translateY(-4px); }
  .svc .s .go { margin-top:10px; font-weight:600; font-size:14px; }
  /* "What we build" opens its services: a panel beside the menu, or an accordion inside it on a phone */
  .rowgrp { flex:1; min-height:0; display:flex; flex-direction:column; }
  .rowgrp > .row { flex:1; }
  .rowgrp.open { flex:0 0 auto; }
  .rowgrp.open > .row { flex:none; height:76px; }
  .drawer { overflow-x:hidden; overflow-y:auto; overscroll-behavior:contain; scrollbar-width:none; }
  .drawer .row { min-height:56px; }
  .row.has-sub::before { content:''; position:absolute; left:24px; top:50%; z-index:1; width:9px; height:9px; margin-top:-5px; border-left:2px solid currentColor; border-bottom:2px solid currentColor;
    transform:rotate(45deg); opacity:.7; transition: transform .45s var(--ease), opacity .3s; }
  .row.has-sub.open::before { transform:rotate(45deg) translate(-3px, 3px); opacity:1; }
  .row.has-sub.open { border-color:rgb(var(--edge) / .3); }
  .row.has-sub.open .bg { filter:none; }
  .row.mini { flex:none; height:84px; }
  .row.mini .t { font-size:22px; }
  .row.mini .m { font-size:11px; }
  .row.mini[aria-current="page"] { border-color:var(--blue); box-shadow:inset 0 0 0 1px var(--blue); }
  .subfly { position:fixed; z-index:56; width:400px; display:flex; flex-direction:column; gap:10px; padding:12px; border-radius:20px;
    background:var(--drawer); backdrop-filter:blur(18px); -webkit-backdrop-filter:blur(18px); border:1px solid rgb(var(--edge) / .12);
    clip-path:inset(0 0 0 100% round 20px); visibility:hidden; pointer-events:none; transition: clip-path .45s var(--ease), visibility 0s .45s; }
  .subfly.on { clip-path:inset(0 0 0 0 round 20px); visibility:visible; pointer-events:auto; transition: clip-path .6s var(--ease), visibility 0s; }
  .subfly .row { opacity:0; transform:translateX(30px); transition: opacity .2s, transform .2s; }
  .subfly.on .row { opacity:1; transform:none; transition: opacity .5s var(--out), transform .7s var(--out); }
  .subfly.on .row:nth-child(1) { transition-delay:.08s; } .subfly.on .row:nth-child(2) { transition-delay:.14s; }
  .subfly.on .row:nth-child(3) { transition-delay:.2s; } .subfly.on .row:nth-child(4) { transition-delay:.26s; }
  .subacc { display:grid; grid-template-columns:1fr 1fr; gap:8px; max-height:0; margin-top:0; opacity:0; overflow:hidden; transition: max-height .5s var(--ease), opacity .4s, margin .5s var(--ease); }
  .subacc.on { max-height:240px; margin-top:8px; opacity:1; }
  .subacc .row.mini { height:74px; padding:0 14px; }
  .subacc .row.mini .t { font-size:17px; }
  .subacc .row.mini .m { font-size:10px; }
  @media (max-width:900px), (pointer:coarse) { .row.has-sub::before { transform:rotate(-45deg); } .row.has-sub.open::before { transform:rotate(135deg) translate(-2px, 2px); } }
  /* phones: tighter rhythm between sections, readable labels, comfortable tap areas */
  .logo { padding:8px 0; margin:-8px 0; }
  .crumbs { padding:10px 0; margin-top:-10px; }
  .toc .toc-list a, .pbody .toc-list a { padding-top:10px; padding-bottom:10px; }
  @media (max-width:640px) {
    section.wrap { padding-top:84px; padding-bottom:84px; }
    .body { margin-top:40px; }
    .cv .k, .sfacts span { font-size:12px; }
  }
  .consent { font-size:13px; opacity:.65; margin-top:-4px; } .consent a { text-decoration:underline; text-underline-offset:3px; }
  footer.f a[href$="privacy/"] { text-decoration:underline; text-underline-offset:3px; }
  /* language: a pill in the header (desktop), a row in the menu (phone), a one-time hint for Russian browsers */
  button.ghost { background:none; color:inherit; font:inherit; cursor:pointer; }
  .lang { position:relative; display:flex; height:44px; padding:3px; border-radius:999px; background:rgb(var(--raise) / calc(.08 * var(--rk))); border:1px solid rgb(var(--edge) / .18);
    backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px); font-family:'JetBrains Mono',monospace; font-size:12px; letter-spacing:.08em; }
  .lang::before { content:''; position:absolute; top:3px; bottom:3px; left:3px; width:42px; border-radius:999px; background:var(--ink); transition: transform .45s var(--ease); }
  .lang a { position:relative; width:42px; display:grid; place-items:center; border-radius:999px; transition: color .35s; }
  .lang a[aria-current="true"] { color:var(--bg); }
  .lang a:not([aria-current="true"]):hover { color:var(--blue); }
  .lang.ru::before { transform:translateX(42px); }
  .dfoot .lang { display:none; margin-right:auto; }
  @media (max-width:640px) { .hdr .lang { display:none; } .dfoot .lang { display:flex; } }
  .toast { position:fixed; left:50%; bottom:28px; z-index:90; translate:-50% 20px; max-width:calc(100vw - 36px); padding:12px 18px; border-radius:14px; font-size:14px;
    background:var(--drawer); border:1px solid rgb(var(--edge) / .16); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); box-shadow:0 20px 50px rgb(var(--shade) / calc(.5 * var(--sk)));
    opacity:0; pointer-events:none; transition: opacity .35s, translate .5s var(--out); }
  .toast.on { opacity:1; translate:-50% 0; }
  .langhint { position:fixed; left:18px; bottom:18px; z-index:65; display:flex; align-items:center; gap:12px; padding:12px 12px 12px 16px; border-radius:16px; font-size:14px;
    background:var(--drawer); border:1px solid rgb(var(--edge) / .16); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); box-shadow:0 20px 50px rgb(var(--shade) / calc(.5 * var(--sk)));
    opacity:0; translate:0 20px; pointer-events:none; transition: opacity .5s, translate .6s var(--out); }
  .langhint.on { opacity:1; translate:0 0; pointer-events:auto; }
  .langhint .btn { padding:9px 14px; font-size:14px; }
  .langhint .x { width:34px; height:34px; border-radius:50%; border:1px solid rgb(var(--edge) / .18); background:none; color:inherit; cursor:pointer; }
  /* theme toggle: a moon in the dark theme, a sun in the light one; the new theme spreads as a circle from the button */
  .hdr { display:flex; align-items:center; gap:10px; }
  .theme { width:44px; height:44px; padding:0; border-radius:50%; display:grid; place-items:center; cursor:pointer; color:var(--ink);
    background:rgb(var(--raise) / calc(.08 * var(--rk))); border:1px solid rgb(var(--edge) / .18); backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px); transition: background .4s, border-color .4s, box-shadow .4s; }
  .theme:hover { box-shadow:0 0 24px rgba(143,156,255,.4); }
  .theme svg { width:20px; height:20px; overflow:visible; }
  .theme .core, .theme .bite, .theme .rays { transform-box:fill-box; transform-origin:center; transition: transform .7s var(--ease), opacity .45s; }
  :root[data-theme="dark"] .theme .bite { transform: translate(-12px, 12px); }
  :root[data-theme="dark"] .theme .rays { transform: rotate(-90deg) scale(.4); opacity:0; }
  :root[data-theme="light"] .theme .core { transform: scale(.56); }
  :root[data-theme="light"] .theme .rays { transition-delay:.12s; }
  ::view-transition-old(root), ::view-transition-new(root) { animation:none; mix-blend-mode:normal; }
  /* the menu and card art has a twin for each theme */
  .row .bg, .svc .art, .p .img { background-image:var(--art); }
  :root[data-theme="light"] :is(.row .bg, .svc .art, .p .img) { background-image:var(--artl); }
  :root[data-theme="light"] .row .bg { filter:blur(1.2px); }
  :root[data-theme="light"] .row:hover .bg { filter:none; }
/* Adjustments the prototype needs on the real site: tap areas and label sizes. site.css stays as the prototype drew it. */

/* Tap areas of at least 40 px. An invisible ::after reaches out from the element, so nothing moves and nothing looks different. */
.lang a::after,
footer.f .wrap > span a::after,
.langhint .btn::after { content:''; position:absolute; left:50%; top:50%; width:max(100%, 40px); height:40px; translate:-50% -50%; }
footer.f .wrap > span a { position:relative; white-space:nowrap; }
/* footer lines are 42 px apart, within a span and from one wrapped row to the next, so the 40 px tap areas of two lines never touch
   (browsers round a touch point to the screen's pixels, and areas that meet edge to edge then overlap by up to a pixel);
   the negative margin takes back what the taller line adds to a single line (the text keeps its place) */
footer.f .wrap > span { line-height:42px; margin-block:-11px; }
footer.f .wrap { row-gap:22px; }
/* EN and RU are short: with the usual " · " between them their 40 px areas would overlap, so the gap is a little wider */
footer.f .wrap > span a[lang="en"] { margin-right:7px; }
footer.f .wrap > span a[lang="ru"] { margin-left:7px; }
/* WebKit sizes the span of EN · RU too narrow for its two links (their areas are absolute ::after boxes) and put RU on a line of
   its own, on every page and every screen; the pair never breaks */
footer.f .wrap > span:has(> a[lang]) { white-space:nowrap; }
.langhint .x { width:40px; height:40px; flex:none; }
/* the hint's button is drawn 39 px tall (14 px label, 9 px padding); its ::after above makes the area 40 */
.langhint .btn { position:relative; }

/* Labels of at least 12 px; a tile grows with its label instead of clipping it. */
.row.mini { height:auto; min-height:84px; }
.subacc .row.mini { height:auto; min-height:74px; }
.row.mini .m,
.subacc .row.mini .m { font-size:12px; }

/* Home page. The work filters are 34 px chips (13 px label, 6 px padding); their rows are 42 px apart, so the 40 px areas of two rows never overlap. */
.filters .chip { position:relative; }
.filters .chip::after { content:''; position:absolute; left:50%; top:50%; width:max(100%, 40px); height:40px; translate:-50% -50%; }
/* EN and RU among the company facts: the same 40 px areas as in the footer. Their centres are 36 px apart, so the gap grows by 3 px on each side
   (42 px apart, the areas no longer overlap); no more than that, or on a 360 px phone the pill no longer fits beside "since 2025" and drops to a third row */
.facts a { position:relative; white-space:nowrap; }
.facts a::after { content:''; position:absolute; left:50%; top:50%; width:max(100%, 40px); height:40px; translate:-50% -50%; }
.facts a[lang="en"] { margin-right:3px; }
.facts a[lang="ru"] { margin-left:3px; }

/* Inner pages (inner.css loads after this file, so a rule here that changes one of its properties needs the higher specificity). */
/* the crumb line above a title is 38 px tall (12 px label, 10 px padding) */
.crumbs { position:relative; }
.crumbs::after { content:''; position:absolute; left:50%; top:50%; width:max(100%, 40px); height:40px; translate:-50% -50%; }
/* the filter chips of the work page are 34 px tall, like the home ones; where they wrap, rows are at least 42 px apart (8 px gap) */
.fgroup .chip { position:relative; }
.fgroup .chip::after { content:''; position:absolute; left:50%; top:50%; width:max(100%, 40px); height:40px; translate:-50% -50%; }
/* on a phone the chips scroll sideways in .fin, which clips what reaches out of it: 3 px more room above and below the row for the
   40 px areas, taken back by the margin so the row keeps its place (.wrap.fin outranks inner.css's .fin) */
.wrap.fin { padding-block:3px; margin-block:-3px; }
/* inner.css pulls .fin 18 px out to each side, as if it sat inside a padded .wrap; it is the .wrap itself (width 100%), so the margin
   only moved the row left: the first chip touched the screen's edge and the row stopped 18 px short of the right one. Without the
   margin the row runs edge to edge, and its 18 px padding puts the first chip 18 px in and leaves 18 px after the last one */
@media (max-width:640px) { .wrap.fin { margin-inline:0; } }
/* The product's card has the class `live`, and the home page's promo rule `.live .cap { justify-content:space-between; align-items:center }`
   (site.css) reached its caption too: the title and the line sat in the middle of the card, while the caption of every other card runs
   from the left. A deliberate departure from the prototype (a class clash with the home promo, which has no .cap of its own): the caption
   of a card of the work grid is laid out like the others. */
.wc.live .cap { justify-content:flex-start; align-items:stretch; }
/* Live demo, Landing page and Get notified on a project card are 36 px pills (13 px label, 7 px padding), above the card's own link;
   the plain labels drawn as the same pill (the product's address, Video and screens) are not controls and get no area.
   Get notified is a link too (to the brief on the home page, the popup with the script) */
.wc a.demo::after { content:''; position:absolute; left:50%; top:50%; width:max(100%, 40px); height:40px; translate:-50% -50%; }
/* those plain labels sit above the card's link too (z-index 4), so a tap on them did nothing; taps now fall through to the link,
   which opens the product or the case (the label loses its own hover tint) */
.wc span.demo { pointer-events:none; }

/* The contents of an article (beside the text on a computer, folded under "On this page" on a phone): site.css gives each entry 10 px
   above and below a 14 px line, 39 px in all, and on a computer the entries touch, so each one's 40 px area reached into the next.
   42 px, as the footer lines: the sticky column is drawn on whole pixels, up to a pixel off the place the page measures for it, and
   areas that meet edge to edge would then overlap (the text stays where it was, the extra 3 px are below it) */
.toc .toc-list a, .pbody .toc-list a { min-height:42px; }
/* A link inside running text (on the page of a post still to come, "our work"): its line is 24 px tall, so an invisible 40 px area
   reaches out of it; the link never breaks between two lines, or the area would span both and cover the text between them */
a.inl { position:relative; white-space:nowrap; }
a.inl::after { content:''; position:absolute; left:50%; top:50%; width:max(100%, 40px); height:40px; translate:-50% -50%; }
/* not in the prototype, on purpose: there .inl has no rule of its own and such a link reads as plain text; it is underlined like the
   links of the brief's consent line (.consent a) and Privacy in the footer (the address on the privacy page will use it too) */
a.inl { text-decoration:underline; text-underline-offset:3px; }
/* Labels of at least 12 px on the inner pages: the layers set .cv .k (blog covers) and .sfacts span (service facts)
   to 11 px after site.css, so the 12 px rule for phones never wins; :root lifts this rule above both. */
:root .cv .k, :root .sfacts span { font-size:12px; }
/* The facts of a service page in one row on a computer, as on the prototype at 1440. The hero's column is 572 px at 1440 and 565
   at 1920. With 12 px labels and the terms "from 3 weeks" (owner feedback 1) the English tiles need up to 604 px with 15 px sides,
   the Russian ones 533. From 641 px a tile has 11 px on each side (24 px back); where the hero has two columns (above 900 px,
   inner.css) its numbers are 24 px instead of 26 (another 26 px): 554 px at most. Phones are left as they were, and below about
   1250 px the tiles wrap, as on the prototype. */
@media (min-width:641px) { :root .sfacts div { padding-inline:11px; } }
@media (min-width:901px) { :root .sfacts b { font-size:24px; } }

/* What is not shown is out of the Tab order and out of the accessibility tree, not only faded out. Visibility turns on at once when
   the thing opens and turns off only after its fade when it closes, as the popup does in site.css. The language hint is a dialog that
   only exists for the eye while it is on; the accordion of services in the menu is folded (on a computer the services open in the side panel instead). */
.langhint { visibility:hidden; transition: opacity .5s, translate .6s var(--out), visibility 0s .5s; }
.langhint.on { visibility:visible; transition: opacity .5s, translate .6s var(--out), visibility 0s; }
.subacc { visibility:hidden; transition: max-height .5s var(--ease), opacity .4s, margin .5s var(--ease), visibility 0s .5s; }
.subacc.on { visibility:visible; transition: max-height .5s var(--ease), opacity .4s, margin .5s var(--ease), visibility 0s; }

/* Reduced motion (the spec: no parallax, no waves, no automatic flipping). site.js keeps the deck, its clips, the promo film and the light spots still
   and site.css stops the spots' own drift; a tall picture in front of the deck does not pan either. */
@media (prefers-reduced-motion: reduce) {
  .card[data-pos="0"] img.tall { animation:none; }
}

/* The Russian version: the same boxes hold longer words. Each place is sized for its own longest Russian word here, under :lang(ru),
   so the English pages stay as the prototype drew them; nothing else gets smaller. */
/* The menu button is as wide as its longer label, and ЗАКРЫТЬ is two letters longer than CLOSE: on a 360 px phone the button pushed
   the theme button against the logo (1 px between them, 20 px in English). Up to 380 px its sides are 5 px narrower and its icon
   sits 3 px closer to the label: 14 px between the logo and the theme button at 360. */
@media (max-width:380px) { :lang(ru) .burger { padding-inline:13px; gap:9px; } }
/* The menu's big titles: at 30 px (site.css) «Наши продукты» (8.88 em) took a second line, which its tile cut off, and «Что мы делаем»
   (8.45 em) ran onto the arrow that opens the services. Up to 375 px a title takes the size at which «Что мы делаем» begins 9 px clear
   of the arrow: the screen less the menu's padding (2 × 26 px), the tile's right padding (22 px) and the arrow with that room (46 px),
   over the word's width with a little to spare (28 px at 360, 30 px at 375, as before from there on). */
@media (max-width:375px) { :lang(ru) .drawer > .row .t, :lang(ru) .rowgrp > .row .t { font-size:calc((100vw - 120px) / 8.5); } }
/* The services in the phone menu: two Russian tiles side by side were cramped («от $250 · 1–3 недели» on two lines over the tile's
   picture, «CRM и внутренние инструменты» on three, down to the tile's bottom edge). Up to 460 px, where two columns no longer hold
   «CRM и внутренние» and the price line, the four tiles stand in one column at the same type (17 px titles, 12 px prices), each as
   wide as the menu's rows; the folded block opens to 340 px instead of 240 (four 74 px tiles and three 8 px gaps are 320). */
@media (max-width:460px) {
  :lang(ru) .subacc { grid-template-columns:1fr; }
  :lang(ru) .subacc.on { max-height:340px; }
}
/* The title of an article or of the policy on a phone: at 40 px (inner.css) «фиксированной» (8.94 em, the longest word of a Russian
   article title) ran 16 px past a 360 px screen. Up to 400 px the title takes the size at which that word fits the column (the
   screen less 2 × 18 px), 35.6 px at 360; from 400 px it is 40 px as before. */
@media (max-width:400px) { :lang(ru) .phead h1 { font-size:min(40px, calc((100vw - 36px) / 9.1)); } }
/* «конфиденциальности» (12.2 em) in the policy's title fits no phone at a heading's size (it would take 26 px at 360), so that title,
   and only that one, breaks it with a hyphen (the policy's header is followed by its text; an article's, by its cover). Only a word
   of 14 letters or more breaks, with at least 6 letters on each side, and only up to 531 px: the word fits its column from about
   530 px (487 px of 40 px letters in the screen less 2 × 4vw). A browser without a Russian hyphenation dictionary breaks the word
   where it overflows instead of letting it run past the screen (overflow-wrap). */
@media (max-width:531px) {
  :lang(ru) .phead:has(+ .pgrid) h1 { -webkit-hyphens:auto; hyphens:auto; hyphenate-limit-chars:14 6 6; -webkit-hyphenate-limit-before:6; -webkit-hyphenate-limit-after:6; overflow-wrap:break-word; }
}
/* Covers. The longest Russian cover words are wider than any English one: «приложение» (7.04 em) lost its last letters on every blog
   card and on its article's cover, «готовая» on a phone's cover, and the card's «или готовая» took a third line that covered the
   card's label. A cover keeps its size (inner.css) unless its longest piece that stays on one line would not fit: then it takes the
   size at which a piece of that many letters fits the cover's inner width. 0.71 em a letter is the worst case («приложение», the
   widest Russian cover word, has 0.70), so a piece of narrower letters, or with a space in it (a space counts as a letter), comes
   out a little smaller than it strictly needs to. The markup of a Russian page gives each cover that count (--letters): a card keeps
   the lines of its data whole, as the English cards do, an article's cover only its words. The cover is the container its width is
   read from (cqi). Only where the browser has container units: elsewhere the substituted calc() would be invalid at computed-value
   time and the size would fall back to the body's, so a browser without them keeps the sizes of inner.css. */
@supports (width:1cqi) {
  :lang(ru) .cv { container-type:inline-size; }
  :lang(ru) .cv b { --fit:calc(100cqi / var(--letters, 1) / .71); font-size:min(clamp(44px,4.6vw,68px), var(--fit)); }
  :lang(ru) .cv.big b { font-size:min(clamp(64px,8.4vw,128px), var(--fit)); }
  :lang(ru) .pcover .cv b { font-size:min(clamp(70px,11vw,170px), var(--fit)); }
}

/* Without a script. sun.js marks the page with the class js on <html> before the first paint (site.js does it later if sun.js did not
   arrive). An article's contents are built by pages.js and its share links filled by it, so without the script they would be an empty
   list and links to "#": both are hidden. The contents' column beside the text keeps its place (visibility), so the text stands where
   it stands with the script; on a phone that column is not drawn at all and the folded list goes. */
html:not(.js) .toc { visibility:hidden; }
html:not(.js) .tocm, html:not(.js) .share { display:none; }
/* The openers of the brief were buttons and are links now (to the brief on the home page, for a browser without the script). A button
   centres its label, so the one that wraps (Получить фиксированную цену → on a 360 px phone) keeps its two lines centred; :where()
   leaves the rule as weak as the browser's own one for buttons, so any rule of the page about the element wins over it */
:where(a[data-popup]) { text-align:center; }

/* Contrast of 4.5:1 for small text (WCAG 2.2 AA), measured by scripts/audit.mjs. The dark theme passes as drawn; in the light one
   the hint under the 404 page's tiles ("Tap the grid. It lights up.", 12 px) is ink at half strength, #7f828e on the page's #f2f3f9:
   3.5:1. At .62 it is #636675, 5.1:1, enough to stay above 4.5 where a glow tints the page behind it. */
:root[data-theme="light"] .lost .hint { opacity:.62; }
/* The contents of an article on a computer: the entries that are not the current one are ink at .55, #737684 on #f2f3f9, 4.1:1 in the
   light theme (5.5:1 in the dark one). At .62 they are 5.1:1; hover (.9) and the current entry (1) stay as they were. */
:root[data-theme="light"] .toc-list a:not(.on):not(:hover) { opacity:.62; }
/* Teal text in the light theme (#00957d): the step facts of the home and service pages, the numbers of a service's features and of the
   principles on the about page (12 px), the term of a price (14 px). On their glass cards, white at .86 to .58 over the page, that is
   3.7:1 at best, 3.4:1 on the page itself. A darker teal of the same hue, #007a66, is 5.3:1 on white and 4.8:1 on the page. The teal of
   lines, dots and borders stays as it was (they carry no text). Lighthouse did not flag these (text on a gradient); measured by hand. */
:root[data-theme="light"] :is(.steps .fact, .feats .f .n, .price .t, .prin .n) { color:#007a66; }

/* The home deck (LCP on a phone, scripts/audit.mjs). site.css shows five of its seven cards (data-pos 0 to 4) and keeps the other two
   transparent until they come forward. The picture of the sixth card, a full-page screenshot and the heaviest of the deck (122 KB), was
   loaded with the page all the same and took a phone's bandwidth from the front card. It is lazy now (Hero.astro), and a lazy picture
   loads once it is drawn: until the page's load event (site.js then marks the deck loaded) it is not drawn while its card stands at
   data-pos 5 (hidden, a turn before it comes forward), nor before site.js has placed the cards. After the load it loads at once, well
   before the deck turns (4.6 s). Without a script the deck stands as one pile and every picture loads, as before. */
html.js .deck:not(.loaded) > .card:nth-child(6):not([data-pos]) img, .deck:not(.loaded) > .card[data-pos="5"] img { display:none; }
/* Real form fields keep the look of the prototype's boxes; chips are radio buttons. */
/* On a phone the brief opens with the focus on the panel itself (see brief.js); it is not a control and needs no ring. */
.pop .panel:focus { outline:none; }
.brief-form { display:grid; gap:14px; }
.brief-form .in { width:100%; color:inherit; font:inherit; font-size:15px; opacity:1; outline:none; resize:vertical; transition: border-color .3s, box-shadow .3s; }
.brief-form .in::placeholder { color:inherit; opacity:.55; }
/* iOS Safari zooms the page when a field under 16 px gets the focus, so fields are 16 px wherever a finger is the pointer */
@media (pointer:coarse) { .brief-form .in { font-size:16px; } }
.brief-form .in:focus { border-color:var(--blue); box-shadow:0 0 0 3px rgba(143,156,255,.25); }
.brief-form .in[aria-invalid="true"] { border-color:#ff6b7a; }
.brief-form fieldset { border:0; margin:0; padding:0; min-width:0; }
/* as in the prototype, the 12 px label is a span on the legend's 16 px line: the line is 24 px tall and the label sits on its baseline */
.brief-form legend { padding:0; margin-bottom:8px; }
.brief-form .chip { position:relative; }
.brief-form .chip input { position:absolute; inset:0; opacity:0; margin:0; cursor:pointer; }
.brief-form .chip:has(input:checked) { background:var(--ink); color:var(--bg); border-color:transparent; font-weight:600; }
.brief-form .chip:has(input:focus-visible) { box-shadow:0 0 0 2px var(--blue); }
.brief-form .hp { position:absolute; left:-9999px; width:1px; height:1px; opacity:0; }
.brief-form .send { display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.brief-form .send .btn { border:0; cursor:pointer; font-size:16px; }
.brief-form .state { font-size:14px; opacity:.85; }
.brief-form[data-state="sending"] .send .btn { opacity:.6; pointer-events:none; }
.brief-form[data-state="error"] .state { color:#ff6b7a; opacity:1; }
.brief-form[data-state="sent"] > :not(.done) { display:none; }
.brief-form[data-state="sent"] .done { display:block; }
.brief-form .done h3 { margin:0 0 6px; }
/* the thank-you block takes the focus once the brief is sent, so that it is read out; it is not a control and needs no ring */
.brief-form .done:focus { outline:none; }

/* Tap areas of at least 40 px, as everywhere on the site. An invisible ::after reaches out from the chip or the link, so nothing moves and nothing looks different.
   Chip rows are 41 px apart, so the areas of two rows never overlap. The send button sits above the link's area in case they ever touch.
   The row of the send button is 11 px above the privacy link, and the link's area reaches 11.5 px up: the empty part of that row lets a tap
   through to the link, only the button and the message in it take taps. */
.brief-form .chip::after,
.brief-form .consent a::after { content:''; position:absolute; left:50%; top:50%; width:max(100%, 40px); height:40px; translate:-50% -50%; }
.brief-form .consent a { position:relative; white-space:nowrap; }
.brief-form .send { position:relative; z-index:1; pointer-events:none; }
.brief-form .send > * { pointer-events:auto; }

/* On the home page the brief sits inside a glass block that carries the padding (in the prototype the form itself was the block, .brief form { padding:26px }) */
.brief .glass > .brief-form { padding:0; }
/* the message box on the page is as tall as the prototype drew it (90 px); four rows would make it 118 px and stretch the messenger column beside it */
.brief .glass > .brief-form textarea.in { height:90px; }
/* the message box in the popup is as tall as the prototype drew it there (80 px); three rows make it 95.5 px */
.pop .brief-form textarea.in { height:80px; }
