/* home: soft dark (charcoal, not black), white, TKB green with restraint */
:root{
  --bg:#17191b;
  --panel:#202326;
  --ink:#f0f3f1;
  --mute:#b0b9b4;
  --faint:#8b938e;
  --line:rgba(240,243,241,.13);
  --acc:#43c25b;
  --acc-hi:#8fe39d;
  --f:"Onest",system-ui,-apple-system,"Segoe UI",sans-serif;
  --head:"Bricolage Grotesque",var(--f); /* heading face: one token, same as the subpages */
  --gut:clamp(16px,3vw,44px);
  --ease:cubic-bezier(.16,1,.3,1);
  /* motion from TKB Desk (Theme/Spring.cs): real damped springs, sampled.
     spatial ζ.8 k380 = 431ms, may overshoot, only for things that appear or are pressed
     crit    ζ1 k1400 = 226ms, never bounces: anything that travels or repeats, and opacity/colour (212ms)
     exit    Emphasized Accelerate, exits never spring */
  --sp:linear(0,0.0241,0.0848,0.1681,0.2631,0.3619,0.4587,0.5499,0.6331,0.7069,0.771,0.8255,0.8709,0.908,0.9377,0.961,0.9787,0.9919,1.0014,1.0078,1.0119,1.0142,1.0151,1.015,1.0143,1.0132,1.0118,1.0103,1.0088,1.0074,1.0061,1.0049,1.0039,1.003,1.0022,1.0016,1);
  --cr:linear(0,0.0678,0.2079,0.3623,0.5044,0.6243,0.7205,0.7951,0.8514,0.8933,0.9239,0.9462,0.9621,0.9734,0.9815,0.9871,0.9911,0.9938,0.9958,0.9971,1);
  --exit:cubic-bezier(.3,0,.8,.15);
  --t-sp:431ms;--t-slow:594ms;--t-cr:226ms;--t-fx:212ms;--t-exit:150ms;
  /* one rhythm for the page: --G is the visible space between two sections (last thing you see of one, first of the
     next), --V the space between a section's heading block and its scene. Each section keeps --G/2 of free space above
     and below what it shows. */
  --G:clamp(240px,34vh,330px);   /* the gap between two sections */
  --V:clamp(48px,7vh,72px);
  color-scheme:dark;
}
@media (max-width:899px){:root{--G:clamp(170px,22vh,220px)}}
@media (max-width:760px){:root{--V:40px}}
::selection{background:rgba(67,194,91,.38);color:#fff}
html{scrollbar-color:#27302c var(--bg);caret-color:var(--acc-hi)}
*,*::before,*::after{box-sizing:border-box}
html{background:var(--bg);-webkit-text-size-adjust:100%}
body{margin:0;background:transparent;color:var(--ink);font:400 16px/1.5 var(--f);-webkit-font-smoothing:antialiased;overflow-x:hidden}
img,svg{display:block}
a{color:inherit}
button{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--acc-hi);outline-offset:3px;border-radius:6px}
.skip{position:fixed;left:12px;top:-60px;z-index:300;padding:10px 14px;border-radius:8px;background:var(--ink);color:var(--bg);text-decoration:none;font-weight:600}
.skip:focus{top:12px}



/* ---------- header (structure of the live site) ---------- */
.hdr{position:fixed;inset:0 0 auto;z-index:200;display:flex;align-items:center;gap:24px;height:76px;padding:0 var(--gut);transition:transform .5s var(--ease),background-color .4s}
.hdr.is-solid{background:rgba(23,25,27,.86);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.hdr.is-hidden{transform:translateY(-100%)}
.brand{display:flex;align-items:center;gap:9px;text-decoration:none;flex:none}
.brand-logo{display:block;height:38px;width:auto}
.brand-sp{width:30px;height:auto}
.brand-wm{height:19px;width:auto}
.brand-su{height:23.75px;width:auto;margin:4.75px 0 0 -2px}
.nav{margin-left:auto}
.nav>ul{display:flex;gap:2px;list-style:none;margin:0;padding:0}
.nav li{position:relative}
.nav>ul>li>a,.nav>ul>li>button{display:flex;align-items:center;gap:6px;padding:9px 13px;border:0;background:none;border-radius:8px;color:var(--mute);font-size:14.5px;text-decoration:none;cursor:pointer;transition:color .2s}
.nav>ul>li>a:hover,.nav>ul>li>button:hover,.nav>ul>li>a:focus-visible,.nav>ul>li>button:focus-visible,.nav>ul>li.is-open>a,.nav>ul>li.is-open>button,.nav [aria-current]{color:var(--ink)}
.caret{width:9px;height:6px;fill:none;stroke:currentColor;stroke-width:1.6;transition:transform var(--t-cr) var(--cr)}
/* a submenu opens on hover, or from the keyboard with Enter / Space / Arrow down on its item (stage.js), so Tab only
   walks the top level and never through hidden links */
.has-sub:hover .caret,.has-sub.is-open .caret{transform:rotate(180deg)}
.sub{position:absolute;left:4px;top:100%;min-width:200px;margin:0;padding:8px;list-style:none;background:var(--panel);border:1px solid var(--line);border-radius:12px;box-shadow:0 24px 48px -20px rgba(0,0,0,.8);opacity:0;visibility:hidden;transform:translateY(-8px);transition:opacity var(--t-exit) var(--exit),transform 160ms var(--exit),visibility 0s 160ms}
.has-sub:hover .sub,.has-sub.is-open .sub{opacity:1;visibility:visible;transform:none;transition:opacity var(--t-fx) var(--cr),transform var(--t-sp) var(--sp)}
.sub a{display:block;padding:8px 11px;border-radius:7px;color:var(--mute);font-size:14px;text-decoration:none;white-space:nowrap}
.sub a:hover,.sub a:focus-visible{color:var(--ink);background:rgba(255,255,255,.05)}
.hdr-r{display:flex;align-items:center;gap:6px}
.lang{padding:9px 12px;color:var(--mute);font-size:14px;text-decoration:none}
.lang:hover{color:var(--ink)}
.burger{display:none;width:44px;height:44px;border:0;background:none;padding:10px;cursor:pointer}
.burger svg,.menu-x svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round}
@media (max-width:1000px){.nav{display:none}.burger{display:block}.hdr-r{margin-left:auto}}

.menu{position:fixed;inset:0;width:100%;max-width:none;height:100%;max-height:none;margin:0;padding:0 var(--gut) 40px;border:0;background:var(--bg);color:var(--ink);overflow:auto}
.menu::backdrop{background:transparent}
.menu[open]{animation:menuIn .45s var(--ease)}
@keyframes menuIn{from{opacity:0;transform:translateY(-12px)}}
.menu-top{display:flex;align-items:center;justify-content:space-between;height:76px}
.menu-x{width:44px;height:44px;border:0;background:none;padding:10px;cursor:pointer}
.menu-body{display:grid;gap:30px;padding-top:18px}
.menu-grp p{margin:0 0 6px;color:var(--faint);font-size:13px}
.menu-grp a{display:block;padding:7px 0;font-size:22px;text-decoration:none;color:var(--ink)}
@media (min-width:640px){.menu-body{grid-template-columns:1fr 1fr}}

/* ---------- hero: the orbit ---------- */
.hero{position:relative;height:100vh;height:100svh;min-height:520px;overflow:hidden}
.sky{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
/* the stars: one fixed layer behind every section (the page itself is see-through; only the green help band covers them) */
.stars{position:fixed;inset:0;z-index:-1;width:100%;height:100%;pointer-events:none}
/* the one-time dive: the MySorty logo flies over the page into its section */
.fx{position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:205;pointer-events:none}
.flyer{position:fixed;left:0;top:0;z-index:210;width:100px;height:100px;margin:-50px 0 0 -50px;pointer-events:none;visibility:hidden;will-change:transform;filter:drop-shadow(0 14px 22px rgba(0,0,0,.55))}

.core{position:absolute;left:0;top:0;z-index:100;width:var(--cs,64px);height:var(--cs,64px);margin:calc(var(--cs,64px)/-2) 0 0 calc(var(--cs,64px)/-2);pointer-events:auto;cursor:pointer;will-change:transform}
.core img{width:100%;height:100%;filter:drop-shadow(0 0 2px rgba(143,227,157,.55)) drop-shadow(0 0 9px rgba(67,194,91,.32)) drop-shadow(0 6px 12px rgba(0,0,0,.45))}

.apps{list-style:none;margin:0;padding:0}
.app{position:absolute;left:0;top:0;z-index:90;display:block;width:var(--s,80px);height:var(--s,80px);margin:calc(var(--s,80px)/-2) 0 0 calc(var(--s,80px)/-2);text-decoration:none;will-change:transform,opacity;-webkit-tap-highlight-color:transparent}
.app img{width:100%;height:100%;filter:drop-shadow(0 14px 22px rgba(0,0,0,.55));transition:transform var(--t-cr) var(--cr)}
.app:hover img,.app:focus-visible img,.app.is-on img{transform:scale(1.1)}
.app:focus-visible{outline-offset:6px;border-radius:14px}
.app-n{position:absolute;left:50%;top:100%;padding-top:8px;transform:translate(-50%,-6px);white-space:nowrap;font-size:13.5px;font-weight:500;letter-spacing:.005em;opacity:0;pointer-events:none;transition:opacity var(--t-exit) var(--exit),transform var(--t-exit) var(--exit)}
.app:hover .app-n,.app:focus-visible .app-n,.app.is-on .app-n{opacity:1;transform:translate(-50%,0);transition:opacity var(--t-fx) var(--cr),transform var(--t-sp) var(--sp)}
@media (hover:none){.app-n{font-size:12px;padding-top:5px}.app.is-front .app-n{opacity:.9;transform:translate(-50%,0);transition:opacity var(--t-slow) var(--cr),transform var(--t-sp) var(--sp)}}
.app.is-gone{visibility:hidden}

.hero-copy{position:absolute;left:var(--gut);bottom:clamp(22px,5vh,52px);z-index:110;max-width:34ch}
.hero-copy h1{margin:0;font-size:clamp(19px,1.55vw,24px);font-weight:500;line-height:1.25;letter-spacing:-.012em}
.hero-copy p{margin:4px 0 0;color:var(--mute);font-size:clamp(14px,1.05vw,16px)}
.hint{position:absolute;right:var(--gut);bottom:clamp(22px,5vh,52px);z-index:110;display:flex;align-items:center;gap:12px;padding:6px 0;border:0;background:none;color:var(--mute);font-size:13px;cursor:pointer;transition:color var(--t-fx) var(--cr)}
.hint:hover{color:var(--ink)}
.hint i{position:relative;display:block;width:1px;height:46px;background:rgba(240,243,241,.2);overflow:hidden}
.hint i::after{content:"";position:absolute;left:-1px;top:-12px;width:3px;height:12px;border-radius:2px;background:var(--acc);animation:drip 1.8s cubic-bezier(.6,0,.3,1) infinite}
@keyframes drip{to{transform:translateY(70px)}}

/* ---------- MySorty, laid out like the original: files, inputs, MySorty, folders ---------- */
/* no full-screen minimum: the section is as tall as what it shows, with --G/2 below its panels (the output panel reaches
   52 px below the grid); the dive scrolls so the whole scene is on screen (stage.js) */
.ms{position:relative;display:grid;align-content:center;padding:110px var(--gut) calc(var(--G) / 2 + 52px)}
/* the scene lies in the same 1180 px column as every other section: the input plate reaches 20 px left of the grid,
   so the grid starts 20 px in and the plate edge meets the column edge */
.ms-scene{position:relative;display:grid;width:100%;max-width:1180px;padding-left:20px;margin:0 auto;grid-template-columns:minmax(90px,.52fr) minmax(104px,.58fr) minmax(170px,1.45fr) minmax(230px,1.1fr);grid-template-rows:repeat(3,minmax(96px,auto));column-gap:clamp(28px,5vw,90px);row-gap:clamp(18px,3vh,32px);align-items:center;justify-items:center}
.ms-wires{position:absolute;left:0;top:0;width:100%;height:100%;overflow:visible;pointer-events:none;z-index:1}
.file,.src{position:relative;display:block;z-index:2}
.file svg,.src svg{width:100%;height:auto;overflow:visible}
.f-pdf{grid-area:1/1;width:56px}
.pair{grid-area:2/1;display:flex;align-items:center;gap:18px}
.f-stack{width:58px}.f-img{width:74px}
.f-scan{grid-area:3/1;width:48px}
.s-mail{grid-area:1/2;width:86px}
.s-folder{grid-area:2/2;width:94px}
.s-printer{grid-area:3/2;width:124px}
.ms-core{grid-area:1/3/4/4;position:relative;z-index:2;width:clamp(140px,12.5vw,184px)}
.ms-core img{display:block;width:100%;height:auto;filter:drop-shadow(0 18px 30px rgba(0,0,0,.55))}
.ms.is-wait .ms-core img{opacity:0}
.ms-out{grid-area:1/4/4/5;justify-self:stretch;position:relative;z-index:2;display:grid;gap:14px;margin:0;padding:0;list-style:none}
.out{display:flex;align-items:center;gap:16px;padding:13px 22px 13px 14px;border:1px solid rgba(240,243,241,.15);border-radius:12px;background:var(--panel);transition:border-color var(--t-fx) var(--cr),background-color var(--t-fx) var(--cr)}
.out .fd{display:block;width:46px;flex:none}
.out .fd svg{width:100%;height:auto;overflow:visible}
.out-n{font-size:16.5px;font-weight:500;transition:color var(--t-fx) var(--cr)}
.out.is-on{border-color:rgba(143,227,157,.7);background:rgba(67,194,91,.08)}
.out.is-on .out-n{color:var(--acc-hi)}
.out.is-on .fd-front,.out.is-on .fd-back{stroke:#8fe39d}
.out.is-open .fd-front{transform:perspective(160px) rotateX(-36deg)}
.fd-in rect{fill:#eef2ef}

/* documents in flight */
.ms-docs{position:absolute;inset:0;pointer-events:none;z-index:3}
.doc{position:absolute;left:0;top:0;width:var(--dw,34px);will-change:transform,opacity;filter:drop-shadow(0 8px 14px rgba(0,0,0,.5))}
.doc svg{display:block;width:100%;height:auto}
.file{transition:opacity var(--t-fx) var(--cr),transform var(--t-sp) var(--sp)}
.ms.is-in .file.is-used{opacity:0;transform:scale(.8);transition:opacity var(--t-exit) var(--exit),transform var(--t-exit) var(--exit);transition-delay:0ms}

/* entrance once MySorty has landed: colour first, then position */
.ms .file,.ms .src,.ms .out,.ms-copy{opacity:0;transform:translateY(14px)}
.ms.is-in .file,.ms.is-in .src,.ms.is-in .out,.ms.is-in .ms-copy{opacity:1;transform:none;transition:opacity var(--t-fx) var(--cr) var(--d,0ms),transform var(--t-sp) var(--sp) var(--d,0ms),border-color var(--t-fx) var(--cr),background-color var(--t-fx) var(--cr)}

/* section heads (MySorty, TKB Monitor): name, a short text, the link; above the scene, like the app sections */
.ms-copy{width:100%;max-width:1180px;margin:0 auto calc(var(--V) + 24px)}   /* --V to the plate, which reaches 24 px above the grid */
.ms-copy h2,.mon-head h2{margin:0;font-size:clamp(28px,3vw,44px);font-weight:600;letter-spacing:-.03em;line-height:1.05}
.ms-copy p,.mon-head p{max-width:46ch;margin:14px 0 10px;color:var(--mute);font-size:clamp(16px,1.25vw,19px);line-height:1.45}
.tlink{display:inline-block;margin-top:4px;color:var(--mute);font-size:15px;text-decoration:underline;text-decoration-color:rgba(232,237,233,.25);text-underline-offset:4px;transition:color var(--t-fx) var(--cr),text-decoration-color var(--t-fx) var(--cr)}
.tlink:hover{color:var(--ink);text-decoration-color:var(--acc)}

/* icons: dark bodies, light outline, one colour accent each */
.ic-s{fill:#24282b;stroke:#d3dbd6;stroke-width:2;stroke-linejoin:round}
.ic-back{fill:#1f2326;stroke:#d3dbd6;stroke-width:2;stroke-linejoin:round;opacity:.45}
.ic-fold{fill:#2e3337;stroke:#d3dbd6;stroke-width:2;stroke-linejoin:round}
.ic-l{fill:none;stroke:#d3dbd6;stroke-width:2;stroke-linecap:round;opacity:.4}
/* envelope: the flap folds open, a letter rises out */
.ml-flap{fill:#2e3337;stroke:#d3dbd6;stroke-width:2;stroke-linejoin:round;transform-box:fill-box;transform-origin:50% 0;transition:transform 160ms var(--exit)}
.ml-open{fill:#2a2f33;stroke:#d3dbd6;stroke-width:2;stroke-linejoin:round;transform-box:fill-box;transform-origin:50% 100%;transform:scaleY(0);transition:transform 160ms var(--exit)}
.ml-paper{fill:#eef2ef}.ml-lines{fill:none;stroke:#aab4ae;stroke-width:2;stroke-linecap:round}
.ml-letter{opacity:0;transform:translateY(12px);transition:opacity var(--t-exit) var(--exit),transform var(--t-exit) var(--exit)}
.src.is-emit .ml-flap{transform:scaleY(0)}
.src.is-emit .ml-open{transform:none;transition:transform var(--t-sp) var(--sp) 140ms}
.src.is-emit .ml-letter{opacity:1;transform:translateY(-9px);transition:opacity var(--t-fx) var(--cr) 220ms,transform var(--t-sp) var(--sp) 220ms}
/* pdf */
.pdf-b{fill:#f0524a}
.pdf-t{fill:#fff;font:700 9px/1 var(--f);text-anchor:middle;letter-spacing:.06em}
/* photo */
.im-sky{fill:#123039}.im-sun{fill:#f2c75c}.im-far{fill:#2a6a42}.im-near{fill:#43c25b}
/* folders */
.fd-back{fill:#2c3135;stroke:#d3dbd6;stroke-width:2;stroke-linejoin:round}
.fd-front{fill:#24282b;stroke:#d3dbd6;stroke-width:2;stroke-linejoin:round;transform-origin:50% 92%;transition:transform var(--t-cr) var(--cr),fill var(--t-fx) var(--cr),stroke var(--t-fx) var(--cr)}
.fd-paper{fill:#eef2ef;transition:transform var(--t-cr) var(--cr)}
.fd-pl{fill:none;stroke:#aab4ae;stroke-width:2;stroke-linecap:round;transition:transform var(--t-cr) var(--cr)}
.src.is-emit .fd-front{transform:perspective(200px) rotateX(-30deg)}
.src.is-emit .fd-paper,.src.is-emit .fd-pl{transform:translateY(-9px)}
/* printer: the page comes out of the slot */
.pr-in{fill:#e3e8e5}
.pr-hi{fill:none;stroke:#d3dbd6;stroke-width:2;stroke-linecap:round;opacity:.18}
.pr-led{fill:#43c25b;animation:led 2.4s ease-in-out infinite}
@keyframes led{50%{opacity:.35}}
.pr-btn{fill:#2e3337;stroke:#d3dbd6;stroke-width:1.5;opacity:.7}
.pr-slot{fill:#141618;stroke:#d3dbd6;stroke-width:2}
.pr-paper{fill:#eef2ef}.pr-lines{fill:none;stroke:#aab4ae;stroke-width:2;stroke-linecap:round}
.pr-out{transform:translateY(-34px);transition:transform var(--t-slow) var(--cr)}
.src.is-emit .pr-out{transform:translateY(0)}


/* phones: files on top, then the inputs, MySorty, and the folders two by two */
@media (max-width:760px){
  .ms{min-height:0;padding:72px var(--gut) calc(var(--G) / 2)}
  .ms-scene{padding-left:0}
  .ms-scene{grid-template-columns:repeat(12,1fr);grid-template-rows:none;column-gap:4px;row-gap:26px}
  .pair{display:contents}
  .f-pdf{grid-area:1/1/2/4;width:34px}.f-stack{grid-area:1/4/2/7;width:36px}.f-img{grid-area:1/7/2/10;width:46px}.f-scan{grid-area:1/10/2/13;width:30px}
  .s-mail{grid-area:2/1/3/5;width:54px}.s-folder{grid-area:2/5/3/9;width:58px}.s-printer{grid-area:2/9/3/13;width:76px}
  .ms-core{grid-area:3/1/4/13;width:88px;margin-block:12px 4px}
  .ms-out{grid-area:4/1/5/13;grid-template-columns:1fr 1fr;gap:10px}
  .out{gap:10px;padding:9px 10px}.out .fd{width:30px}.out-n{font-size:13.5px}
  .doc{--dw:26px}
  .hint{gap:8px}
  .hint span{display:none}
  .hint i{height:38px}
  .hero-copy{right:calc(var(--gut) + 24px)}
  .brand-logo{height:34px}.brand-sp{width:26px}.brand-wm{height:16px}.brand-su{height:20px;margin-top:4px}
}

/* ---------- TKB Monitor: the real dashboard in a screen ---------- */
/* --mscn-top / --mscn-bot: the empty strip above the first and below the last thing in the scene (monitor-scene.js sets
   them), so the heading-to-scene space is --V and the space to the next section --G, like MySorty */
.mon{padding:calc(var(--G) / 2) var(--gut) max(0px,calc(var(--G) / 2 - var(--mscn-bot,40px)))}
.mon-head{max-width:1180px;margin:0 auto calc(var(--V) - var(--mscn-top,40px))}
.mon-frame{position:relative;max-width:1180px;margin:0 auto;aspect-ratio:1280/800;border:1px solid rgba(232,237,233,.12);border-radius:14px;overflow:hidden;background:#0f1517;box-shadow:0 40px 80px -40px rgba(0,0,0,.8)}
.mon-frame iframe{position:absolute;left:0;top:0;width:1280px;height:800px;border:0;transform-origin:0 0;transform:scale(var(--k,1));pointer-events:none;background:#0f1517}
.mon-head,.mon-frame{opacity:0;transform:translateY(16px)}
.mon.is-in .mon-head,.mon.is-in .mon-frame{opacity:1;transform:none;transition:opacity var(--t-fx) var(--cr) var(--d,0ms),transform var(--t-sp) var(--sp) var(--d,0ms)}
.mon.is-in .mon-frame{--d:90ms}
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
@media (max-width:760px){
  .mon-frame{aspect-ratio:auto;height:900px}   /* the phone layout of the dashboard, down to its alerts */
  .mon-frame iframe{width:100%;height:100%;transform:none}
}

/* ---------- the three Android apps, one section each: calm, functional ---------- */
.app-sec{padding:clamp(70px,11vh,130px) var(--gut)}
.as-grid{max-width:1080px;margin:0 auto;display:grid;grid-template-columns:1fr minmax(240px,320px);align-items:center;gap:clamp(40px,8vw,140px)}
.app-sec.flip .as-grid{grid-template-columns:minmax(240px,320px) 1fr}
.app-sec.flip .as-phone{order:-1}
.as-logo{display:block;width:64px;height:auto;margin-bottom:22px;filter:drop-shadow(0 10px 16px rgba(0,0,0,.5))}
/* a logo waits for its meteor, then lands with a small spring */
.m-wait{visibility:hidden}
.m-land{animation:mland 560ms var(--sp) both}
@keyframes mland{0%{transform:scale(.72)}100%{transform:none}}
.as-copy h2{margin:0;font-size:clamp(28px,3vw,44px);font-weight:600;letter-spacing:-.03em;line-height:1.05}
.as-copy p{max-width:34ch;margin:14px 0 0;color:var(--mute);font-size:clamp(16px,1.25vw,19px);line-height:1.45}
.as-acts{display:flex;flex-wrap:wrap;align-items:center;gap:14px 26px;margin-top:30px}
.as-acts .gp{display:block;width:150px;border-radius:10px;transition:transform var(--t-cr) var(--cr)}
.as-acts .gp img{display:block;width:100%;height:auto}
.as-acts .gp:hover{transform:translateY(-2px)}
.as-acts .tlink{margin-top:0}
.as-phone{justify-self:center;width:100%;max-width:300px}
.as-dev{position:relative;aspect-ratio:400/864;border-radius:13%/6%;background:#0c1012;border:1px solid rgba(232,237,233,.14);box-shadow:0 60px 70px -50px rgba(0,0,0,.9)}
.as-scr{position:absolute;left:2.5%;right:2.5%;top:1.157%;bottom:1.157%;border-radius:11%/5%;overflow:hidden;background:#000;transform:translateZ(0)}
.as-scr iframe{position:absolute;left:0;top:0;width:380px;height:844px;border:0;transform-origin:0 0;transform:scale(var(--k,.7));pointer-events:none}
/* entrance: colour first, then position */
.as-copy,.as-phone{opacity:0;transform:translateY(20px)}
.app-sec.is-in .as-copy,.app-sec.is-in .as-phone{opacity:1;transform:none;transition:opacity var(--t-fx) var(--cr) var(--d,0ms),transform var(--t-slow) var(--sp) var(--d,0ms)}
.app-sec.is-in .as-phone{--d:100ms}
@media (max-width:760px){
  .as-grid,.app-sec.flip .as-grid{grid-template-columns:1fr;gap:40px}
  .app-sec.flip .as-phone{order:0}
  .as-phone{max-width:250px}
}

/* ---------- IT-Hilfe: the one green field ---------- */
.help{padding:clamp(80px,12vh,140px) var(--gut);background:var(--acc);color:#04120a}
.help-in{max-width:1080px;margin:0 auto;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:28px 40px}
.help h2{margin:0;max-width:16ch;font-size:clamp(32px,4.2vw,60px);font-weight:600;letter-spacing:-.035em;line-height:1.02}
.help-txt p{max-width:44ch;margin:16px 0 0;font-size:clamp(16px,1.25vw,19px);line-height:1.45;color:rgba(4,18,10,.78)}
.help-btn{display:inline-flex;align-items:center;justify-content:center;min-height:64px;padding:0 34px;border-radius:14px;background:#17191b;color:#f2f6f3;font-size:clamp(17px,1.3vw,19px);font-weight:600;text-decoration:none;box-shadow:0 22px 34px -20px rgba(0,0,0,.65);transition:transform var(--t-cr) var(--cr),background-color var(--t-fx) var(--cr)}
.help-btn:hover{background:#262a2d;transform:translateY(-2px)}
.help-btn:active{transform:scale(.97)}
.help-btn:focus-visible{outline:3px solid #17191b;outline-offset:4px}
.help ::selection{background:#17191b;color:#fff}

/* ---------- footer (structure of the live site) ---------- */
.foot{padding:40px var(--gut) 34px;border-top:1px solid var(--line);color:var(--faint);font-size:13.5px}
.foot ul{display:flex;flex-wrap:wrap;align-items:center;gap:6px 22px;margin:0;padding:0;list-style:none}
.foot a{color:var(--mute);text-decoration:none}
.foot a:hover{color:var(--ink)}
.cc{display:grid;place-items:center;width:34px;height:34px;padding:0;border:1px solid var(--line);border-radius:50%;background:none;cursor:pointer;color:var(--mute)}
.cc svg{width:17px;height:17px;fill:currentColor}
.cc:hover{color:var(--ink)}
.foot p{margin:22px 0 0}

/* cookie banner (kit.js, same consent as the live site): the same box as on every other page */
.tkb-cc{position:fixed;left:16px;right:16px;bottom:16px;z-index:9999;display:none;max-width:720px;margin:0 auto;padding:18px 20px;background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:14px;box-shadow:0 30px 60px -20px rgba(0,0,0,.9);font:400 14.5px/1.5 var(--f)}
.tkb-cc.is-shown{display:block}
.tkb-cc p{margin:0 0 14px}
.tkb-cc a{color:var(--acc-hi)}
.tkb-cc-btns{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-end}
.tkb-cc button{font:600 14.5px/1 var(--f);padding:12px 18px;border-radius:10px;cursor:pointer;border:1px solid rgba(232,237,233,.22);background:none;color:var(--ink)}
.tkb-cc button.tkb-cc-yes{background:var(--acc);border-color:var(--acc);color:#04120a}

/* page leave cover for the logo zoom */
.leave{position:fixed;inset:0;z-index:240;background:var(--bg);opacity:0;pointer-events:none}

/* reduced motion flattens, it does not remove (TKB Desk rule): no overshoot, durations stay */
@media (prefers-reduced-motion:reduce){
  :root{--sp:var(--cr)}

  .hint i::after{animation:none}
  .pr-led{animation:none}            /* calm stills: the scanner's light just stays on */
}

/* headings: the heading face, balanced lines */
:is(.hero-copy h1,.ms-copy h2,.mon-head h2,.as-copy h2,.help h2){font-family:var(--head);text-wrap:balance}
.hero-copy h1{font-weight:400;letter-spacing:-.005em}
/* Bricolage ships Regular and Bold: section heads Bold with its own tracking, the hero line Regular */
:is(.ms-copy h2,.mon-head h2,.as-copy h2){font-weight:700;letter-spacing:-.022em}
.help h2{font-weight:700;letter-spacing:-.03em}

:is(.ms-copy,.mon-head,.as-copy,.help-txt) p{text-wrap:pretty}

/* ---------- the MySorty scene, grounded: the inputs stand on a plate, the folders on another, MySorty on a ring platform,
   and a card under it says what MySorty is doing, in the app's own words ---------- */
.ms-plate{grid-area:1/1/4/3;align-self:stretch;justify-self:stretch;margin:-24px -20px -38px;border-radius:24px;z-index:0}
.ms-plate,.ms-out{background:linear-gradient(180deg,rgba(38,42,46,.7),rgba(27,30,33,.62));box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 0 0 1px rgba(255,255,255,.05),0 50px 90px -50px rgba(0,0,0,.95)}
.ms-out::before{content:attr(data-label);position:absolute;left:22px;top:16px;color:var(--faint);font-size:13.5px;letter-spacing:.01em}
.ms-out{position:relative;align-self:center;padding:46px 18px 18px !important;border-radius:24px}
.ms .ms-plate{opacity:0;transform:translateY(14px)}
.ms.is-in .ms-plate{opacity:1;transform:none;transition:opacity var(--t-fx) var(--cr),transform var(--t-slow) var(--sp)}
.src::after{content:attr(data-n);position:absolute;left:50%;top:calc(100% + 10px);transform:translateX(-50%);white-space:nowrap;color:var(--faint);font-size:13px}
.src.is-emit::after{color:var(--acc-hi)}
@media (max-width:760px){
  .ms-plate{grid-area:1/1/3/13;margin:-24px 0 -44px}   /* edge to edge with the folder panel and the gutter */
  .s-mail,.s-folder,.s-printer{align-self:end}
  .src::after{font-size:11.5px}
}

/* the star-particle connections (sort.js draws them on .ms-flow); the path itself stays invisible */
.ln-geo{fill:none;stroke:none}
.ms-flow{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:1}


/* ---------- the Android apps: pinned stages with the 3D Android phone (showcase.js) ---------- */
.show{position:relative;height:260vh}
.show-pin{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;perspective:1500px;perspective-origin:50% 46%}
.show .as-copy.show-copy{position:absolute;left:max(var(--gut),calc((100% - 1180px) / 2));top:50%;z-index:20;max-width:380px;opacity:1;transform:translateY(-50%)}
.show-phone{position:absolute;left:var(--at,62%);top:50%;z-index:10;transform:translate(-50%,-50%)}
.show-fx{position:absolute;inset:0;z-index:15;transform-style:preserve-3d;pointer-events:none;opacity:0;transition:opacity 300ms var(--cr)}
.show-out{position:absolute;left:0;top:0;transform-origin:50% 50%;will-change:transform,opacity;backface-visibility:hidden}
/* a flicked photo outside the app fills its card (no dark letterbox), tinted the colour of the decision */
.show-ct{border-radius:16px;filter:drop-shadow(0 30px 40px rgba(0,0,0,.6));box-shadow:0 34px 60px -24px rgba(0,0,0,.85),0 0 0 1px rgba(255,255,255,.08)}
.show-card{border-radius:22px;overflow:hidden;background:#111114 center/cover no-repeat;box-shadow:0 30px 50px -20px rgba(0,0,0,.85),0 0 0 1px rgba(255,255,255,.06)}
.show-card::after{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--wash,transparent);opacity:.26}
.show-pile{position:absolute;bottom:9vh;z-index:16;transform:translateX(-50%);color:var(--faint);font:600 13px/1 var(--f);letter-spacing:.02em;text-align:center;opacity:0;transition:opacity 300ms var(--cr)}
.show-pile b{display:block;margin-top:6px;color:var(--ink);font:700 22px/1 var(--head)}
.show-pile--del{left:40%}.show-pile--keep{left:85%}
.show-pin.is-live .show-pile{opacity:1}
/* stacked: the text, then the phone below it. showcase.js sets .is-stack below 900 px and wherever the phone would not fit
   beside the text with room for what floats out of it (900-1100 px wide windows, tall tablets) */
.show.is-stack{height:auto}
.show.is-stack .show-pin{position:relative;height:auto;min-height:0;display:grid;justify-items:center;gap:56px;padding:calc(var(--G) / 2) var(--gut);overflow:visible}
.show.is-stack .as-copy.show-copy{position:relative;left:auto;right:auto;top:auto;transform:none;max-width:none;justify-self:stretch}
.show.is-stack .show-phone{position:relative;left:auto;top:auto;transform:none}
.show.is-stack :is(.show-fx,.show-pile){display:none}

/* the apps' own fonts, so the pieces that float out of the phones keep their real type */
@font-face{font-family:CtRoboto;src:url(/assets/ui/fonts/contrack/Roboto-Bold.ttf) format("truetype");font-weight:700;ascent-override:92.7734%;descent-override:24.4141%;line-gap-override:0%}
@font-face{font-family:CtRoboto;src:url(/assets/ui/fonts/contrack/Roboto-Regular.ttf) format("truetype");font-weight:400;ascent-override:92.7734%;descent-override:24.4141%;line-gap-override:0%}
@font-face{font-family:Inter18;src:url(/assets/ui/fonts/inter/inter_bold.ttf);font-weight:700}
@font-face{font-family:Inter18;src:url(/assets/ui/fonts/inter/inter_medium.ttf);font-weight:500}
@font-face{font-family:Inter18;src:url(/assets/ui/fonts/inter/inter_regular.ttf);font-weight:400}
@font-face{font-family:Inter18;src:url(/assets/ui/fonts/inter/inter_semibold.ttf);font-weight:600}

/* ---------- second review: the Monitor heading sits beside its text, so the dashboard starts higher;
   the IT-help close is a raised charcoal panel like the other closes, not a green slab ---------- */
@media (min-width:900px){
  .mon-head{display:grid;grid-template-columns:auto minmax(0,1fr) minmax(0,1.15fr);column-gap:22px;align-items:center}
  .mon-head .as-logo{grid-column:1;grid-row:1/3;margin:0}
  .mon-head h2{grid-column:2;grid-row:1/3}
  .mon-head p{grid-column:3;grid-row:1;margin:0 0 8px;max-width:none}
  .mon-head .tlink{grid-column:3;grid-row:2;justify-self:start}
}
.help{padding:calc(var(--G) / 2) var(--gut) clamp(56px,9vh,110px);background:none;color:var(--ink)}
.help-in{max-width:1180px;padding:clamp(32px,5vw,64px);border-radius:24px;background:linear-gradient(180deg,rgba(44,48,52,.66),rgba(33,36,39,.6));box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 0 0 1px rgba(255,255,255,.05),0 30px 60px -40px rgba(0,0,0,.9)}
.help-txt p{color:var(--mute)}
.help-btn:focus-visible{outline-color:var(--acc)}
.help ::selection{background:var(--acc);color:#0b1a10}
/* Flick's piles say nothing until the first photo lands on them */
.show-pile{transition:opacity 260ms var(--cr)}
.show-pin .show-pile:not(.has),.show-pin.is-live .show-pile:not(.has){opacity:0}
/* desktop: every logo carries its name quietly, like icons on a home screen; the one under the pointer brightens */
@media (hover:hover){.app-n{opacity:.78;transform:translate(-50%,0)}.app:hover .app-n,.app:focus-visible .app-n,.app.is-on .app-n{opacity:1}}
@media (max-width:760px){.ms-out::before{left:auto;right:22px}}   /* phones: the file flies in from above at the left, so the label sits right */
@media (max-width:760px){.hdr{height:62px}.brand-logo{height:30px}.brand-sp{width:24px}.brand-wm{height:15px}.brand-su{height:18.75px;margin-top:3.75px}}   /* phones: a slimmer header */
@media (max-width:760px){.menu-top{height:62px}}
@media (min-width:761px){.ms-out{align-self:stretch;margin:-24px 0 -38px !important;align-content:center}}   /* the output panel matches the input panel's height, so the two read as a pair */
/* a mirrored stage: its text stands at the right */
@media (min-width:900px){.show--flip .as-copy.show-copy{left:auto;right:max(var(--gut),calc((100% - 1180px) / 2))}}
/* the IT-help close carries the TKB spiral, like each product close carries its app's logo; it turns slowly into place */
.help-in{display:grid !important;grid-template-columns:auto minmax(0,1fr) auto;align-items:center}
.help-sp{width:clamp(64px,7vw,96px);height:auto;filter:drop-shadow(0 18px 30px rgba(0,0,0,.55));transform:rotate(-40deg) scale(.8);opacity:0;transition:transform 1.2s var(--sp),opacity .5s var(--cr)}
.help.is-in .help-sp,.help-sp.is-in{transform:none;opacity:1}
@media (max-width:760px){.help-in{grid-template-columns:minmax(0,1fr)}.help-sp{width:56px}}
@media (prefers-reduced-motion:reduce){.help-sp{transform:none;opacity:1;transition:none}}
/* Flick: the two piles stand close beside the phone, at its lower half, with a readable count */
@media (min-width:900px){
  .show-pile{bottom:22vh;font-size:14px}
  .show-pile b{font-size:28px;margin-top:8px}
  .show-pile--del{left:47%}.show-pile--keep{left:78%}
}

/* moving between pages: the same soft hand-over as on every other page; the header stays put */
@view-transition{navigation:auto}
.hdr{view-transition-name:site-header}
::view-transition-old(root){animation:o3-vt-out 200ms cubic-bezier(.3,0,.8,.15) both}
::view-transition-new(root){animation:o3-vt-in 460ms cubic-bezier(.2,.8,.2,1) both}
@keyframes o3-vt-out{to{opacity:0;transform:translateY(-10px)}}
@keyframes o3-vt-in{from{opacity:0;transform:translateY(14px)}}
@media (prefers-reduced-motion:reduce){::view-transition-old(root),::view-transition-new(root){animation:none}}
/* the Monitor dashboard without its empty bottom strip (the real UI, only cropped) */
@media (min-width:761px){.mon-frame{aspect-ratio:1280/700}}
/* tablets: the scene's plates stay inside the screen (their negative margins only fit with a wide gutter) */
@media (min-width:761px) and (max-width:1100px){
  .ms{padding-bottom:calc(var(--G) / 2 + 44px)}
  .ms-scene{padding-left:12px}
  .ms-copy{margin-bottom:calc(var(--V) + 20px)}
  .ms-plate{margin:-20px -12px -30px}
  .ms-out{margin:-20px 0 -30px !important}
}
@media (min-width:761px) and (max-width:1100px){.ms .pair{gap:12px;padding-left:14px}.ms .f-stack{width:48px}.ms .f-img{width:62px}.ms .f-pdf{margin-left:14px}}
/* a still stage (TKB Assistant): an ordinary section, no scroll-driven camera */
/* its height is what it shows (the phone or the text, whichever is taller; showcase.js sets --stage-h) plus --G/2 above
   and below, so the space to the next section is the same everywhere */
@media (min-width:900px){.show--still{height:auto}.show--still .show-pin{position:relative;height:calc(var(--stage-h,560px) + var(--G));min-height:0}}

/* the MySorty scene builds itself once MySorty has landed (sort.js): until then its pieces are hidden, and while the
   entrance plays the CSS transitions stay out of the way of the choreography */
.ms:not(.is-built) :is(.file,.src,.out,.ms-plate,.ms-out){opacity:0 !important}
.ms.is-building :is(.file,.src,.out,.ms-plate,.ms-out){transition:none !important}
.ms-core,.src,.out{transform-origin:50% 60%}

/* "Mehr zu …" is a real button now: solid green, about the height of the Play badge.
   On hover the green wipes away to the right and leaves a dark button with a green edge and green text; it lifts a little
   and presses in on click. The glow is kept faint. */
.tlink,.fk .fk-acts .tlink{position:relative;isolation:isolate;overflow:hidden;display:inline-flex;align-items:center;height:46px;margin-top:0;padding:0;border-radius:10px;
  background:#23282b;color:#0b1a10;font-size:16px;font-weight:600;letter-spacing:-.005em;text-decoration:none;white-space:nowrap;box-shadow:inset 0 0 0 1.5px var(--acc);
  transition:transform var(--t-sp,431ms) var(--sp),box-shadow 212ms var(--cr)}
/* "Termin vereinbaren" is the same button, only bigger */
.help-btn{position:relative;isolation:isolate;overflow:hidden;padding:0;background:#23282b;color:#0b1a10;
  box-shadow:inset 0 0 0 1.5px var(--acc),0 22px 34px -20px rgba(0,0,0,.65);transition:transform var(--t-sp,431ms) var(--sp),box-shadow 212ms var(--cr)}
:is(.tlink,.help-btn)::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--acc);transform-origin:100% 50%;transition:transform 420ms cubic-bezier(.65,0,.35,1)}
/* the label is painted in two colours split at the wipe edge, and the split travels with the wipe (same time, same curve):
   dark on the green that is left, light green on the dark that is uncovered, so it reads at every moment */
:is(.tlink,.help-btn)>span{display:flex;align-items:center;justify-content:center;height:100%;width:100%;padding:0 20px;
  color:transparent;-webkit-text-fill-color:transparent;background:linear-gradient(90deg,var(--acc-hi) 50%,#0b1a10 50%) 100% 0/200% 100% no-repeat;
  -webkit-background-clip:text;background-clip:text;transition:background-position 420ms cubic-bezier(.65,0,.35,1)}
.help-btn>span{padding:0 34px}
:is(.tlink,.help-btn):hover{background:#23282b;transform:translateY(-2px);box-shadow:inset 0 0 0 1.5px var(--acc-hi),0 6px 16px -10px rgba(67,194,91,.35)}
.help-btn:hover{box-shadow:inset 0 0 0 1.5px var(--acc-hi),0 6px 16px -10px rgba(67,194,91,.35),0 22px 34px -20px rgba(0,0,0,.65)}
:is(.tlink,.help-btn):hover::before{transform:scaleX(0)}
:is(.tlink,.help-btn):hover>span{background-position:0 0}
:is(.tlink,.help-btn):active{transform:translateY(0) scale(.96);transition-duration:120ms}
@media (prefers-reduced-motion:reduce){
  :is(.tlink,.help-btn),:is(.tlink,.help-btn)::before,:is(.tlink,.help-btn)>span{transition:box-shadow 212ms}
  :is(.tlink,.help-btn):hover{transform:none}
  :is(.tlink,.help-btn):hover::before{transform:none;opacity:0}
}

/* the Google Play badge: the same lift on hover (with the same faint green glow as the button) and the same press squeeze */
.as-acts .gp,.fk-acts .gp{transition:transform var(--t-sp,431ms) var(--sp),box-shadow 212ms var(--cr)}
.as-acts .gp:hover,.fk-acts .gp:hover{transform:translateY(-2px);box-shadow:0 6px 16px -10px rgba(67,194,91,.35)}
.as-acts .gp:active,.fk-acts .gp:active{transform:translateY(0) scale(.96);transition-duration:120ms}
@media (prefers-reduced-motion:reduce){.as-acts .gp:hover,.fk-acts .gp:hover{transform:none}}
/* the badge and the button stay on one row wherever both fit (the column is 400 px; phones get a slightly smaller pair) */
.as-acts,.fk-acts{column-gap:14px}
.show .as-copy.show-copy,.fk-copy{max-width:400px}
@media (max-width:480px){
  .as-acts,.fk-acts{column-gap:10px}
  .as-acts .gp,.fk-acts .gp{width:128px}
  .as-acts .tlink,.fk .fk-acts .tlink{height:42px;font-size:15px}
  .as-acts .tlink>span,.fk .fk-acts .tlink>span{padding:0 14px}
}

/* cookie banner buttons: hover and press like the rest */
.tkb-cc button{transition:transform var(--t-sp,431ms) var(--sp),background-color 212ms var(--cr),border-color 212ms var(--cr),color 212ms var(--cr)}
.tkb-cc button:hover{border-color:rgba(232,237,233,.5);background:rgba(255,255,255,.06);transform:translateY(-1px)}
.tkb-cc button.tkb-cc-yes:hover{background:var(--acc-hi);border-color:var(--acc-hi)}
.tkb-cc button:active{transform:scale(.96);transition-duration:120ms}
@media (prefers-reduced-motion:reduce){.tkb-cc button:hover{transform:none}}

/* footer: where the links wrap, the cookie button stands at the right of the copyright line instead of alone on a row */
@media (max-width:899px){
  .foot{position:relative}
  .foot li:has(>.cc){position:absolute;right:var(--gut);bottom:28px}
  .foot p{padding-right:52px}
}

/* Flick: see-through like the other sections, so the stars run on; its stage already has empty room above and below
   the phone (12.4 % of its height), so the padding is --G/2 minus that */
.fk#flick{background:none;padding-top:max(16px,calc(var(--G) / 2 - .155 * min(600px,73.6vh)));padding-bottom:max(16px,calc(var(--G) / 2 - .155 * min(600px,73.6vh)))}
@media (max-width:899px){.fk#flick{padding-top:calc(var(--G) / 2);padding-bottom:max(16px,calc(var(--G) / 2 - .155 * min(520px,100vw - 2 * var(--gut))))}}

/* the MySorty heading comes in while the dive is still travelling (stage.js), so the screen is never empty */
.ms.is-head .ms-copy{opacity:1;transform:none;transition:opacity var(--t-fx) var(--cr),transform var(--t-sp) var(--sp)}

/* Flick on the homepage (flick/flick-stage.css draws the section): the logo waits for its meteor like the others and
   lands with the same spring */
.fk .fk-logo-img.m-wait{visibility:hidden}
.fk.is-in .fk-logo-img.m-land{opacity:1;animation:mland 560ms var(--sp) both}

/* the IT-help panel's logo: after it has turned in, the spiral keeps turning slowly (once in 18 s). Reduced motion: still. */
.help-sp{transform-origin:50% 50%}
.help.is-in .help-sp{animation:help-turn 18s linear 1.2s infinite}
@keyframes help-turn{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.help.is-in .help-sp{animation:none}}
