:root{
  --bg:#0a0a0b; --ink:#f2efe9; --dim:#8d877d; --line:#1e1e21;
  --gold:#e8a33d; --card:#0f0f11;
  --sans:-apple-system,BlinkMacSystemFont,"Helvetica Neue","Segoe UI",system-ui,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
  --pad:clamp(1.25rem,4vw,3.5rem);
  --ease:cubic-bezier(.22,1,.36,1);
}
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  background:var(--bg);color:var(--ink);font-family:var(--sans);
  font-size:clamp(1rem,1.15vw,1.0625rem);line-height:1.55;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
::selection{background:var(--gold);color:#0a0a0b}
:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:2px}

/* ============ grain over everything ============ */
.grain{
  position:fixed;inset:0;z-index:9000;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============ intro counter ============ */
.load{
  position:fixed;inset:0;z-index:9500;background:var(--bg);
  display:none;align-items:flex-end;justify-content:space-between;
  padding:var(--pad);
}
.js .load{display:flex}
.load.gone{transform:translateY(-100%);transition:transform .9s var(--ease)}
.load b{
  font-family:var(--mono);font-weight:400;font-size:clamp(3rem,14vw,9rem);
  line-height:.8;letter-spacing:-.04em;font-variant-numeric:tabular-nums;
}
.load span{font-family:var(--mono);font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;color:var(--dim);padding-bottom:.6rem}

/* ============ sticky nav ============ */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:8000;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.9rem var(--pad);
  font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  background:rgba(10,10,11,.72);backdrop-filter:blur(14px);
  border-bottom:1px solid transparent;
  transform:translateY(-101%);transition:transform .5s var(--ease),border-color .5s;
}
.nav.on{transform:none;border-bottom-color:var(--line)}
.nav b{font-weight:500}
.nav b i{font-style:normal;color:var(--gold)}
.nav-right{display:flex;align-items:center;gap:1rem}
.nav .pill{border:1px solid var(--line);border-radius:99px;padding:.5rem .95rem;transition:background .2s,color .2s,border-color .2s}
.nav .pill:hover,.nav .pill:focus-visible{background:var(--gold);color:#0a0a0b;border-color:var(--gold)}

/* ============ letter wave on hover ============ */
/* Each letter is its own inline-block with a stagger keyed off --i, so one
   hover sends a ripple across the word. Pure CSS, no per-frame work. */
.wave i{display:inline-block;font-style:normal;transition:transform .45s var(--ease),color .45s var(--ease);transition-delay:calc(var(--i) * 26ms)}
.wave:hover i,.wave:focus-visible i{transform:translateY(-.16em)}
@media(hover:none){.wave:hover i{transform:none}}

/* the nav logo swaps its two colours as the ripple passes */
.brand{display:inline-block}
.brand .g{color:var(--gold)}
.brand:hover i,.brand:focus-visible i{color:var(--gold)}
.brand:hover .g,.brand:focus-visible .g{color:var(--ink)}

/* the hero wordmark washes gold */
.mark:hover i{color:var(--gold)}

/* ============ language switch ============ */
.lang{
  display:inline-flex;align-items:center;gap:.4rem;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);
}
.lang a{transition:color .2s}
.lang a:hover{color:var(--ink)}
.lang [aria-current]{color:var(--gold)}
.lang s{text-decoration:none;opacity:.4}

/* ============ shared bits ============ */
.pad{padding-left:var(--pad);padding-right:var(--pad)}
.tag{
  font-family:var(--mono);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);display:block;
}
.tag i{font-style:normal;color:var(--gold)}
.big{
  font-weight:800;letter-spacing:-.035em;line-height:.94;text-wrap:balance;
  font-size:clamp(2.1rem,6.6vw,5.5rem);
}
.big em{font-style:normal;color:var(--gold)}
.lede{color:var(--dim);max-width:34ch;text-wrap:pretty;font-size:clamp(1.05rem,1.7vw,1.3rem)}

/* reveal */
.js .r{opacity:0;transform:translateY(28px);transition:opacity .9s var(--ease),transform .9s var(--ease);transition-delay:var(--d,0s)}
.js .r.in{opacity:1;transform:none}

/* ============ hero: the wordmark fills the frame ============ */
.hero{min-height:100svh;display:flex;flex-direction:column;justify-content:flex-end;padding-bottom:var(--pad)}
.mark{padding:0 var(--pad);margin-top:auto}
.mark span{display:block;font-weight:800;letter-spacing:-.05em;line-height:.78;white-space:nowrap}
/* Sized so each line fills the frame without ever clipping: measured glyph
   widths at weight 800 are 3.81em (HANNES) and 4.76em (WEBSITES.), and the
   usable width is ~89vw at the narrowest padding, with ~4% headroom for
   fallback fonts that run wider than Helvetica Neue. Remeasure if the words
   ever change. */
.mark .a{font-size:clamp(3rem,22.5vw,30rem)}
.mark .b{font-size:clamp(2.4rem,17.9vw,24rem)}
.mark .b u{text-decoration:none;color:var(--gold)}
.js .mark span{opacity:0;transform:translateY(.14em);animation:rise 1.1s var(--ease) forwards}
.js .mark .a{animation-delay:.1s}
.js .mark .b{animation-delay:.22s}
@keyframes rise{to{opacity:1;transform:none}}

.herofoot{
  margin-top:clamp(2rem,6vh,4rem);padding:0 var(--pad);
  display:flex;flex-wrap:wrap;gap:1.5rem 2.5rem;align-items:flex-end;justify-content:space-between;
}
.claim{font-family:var(--mono);font-size:clamp(.8rem,1.3vw,.95rem);letter-spacing:.06em;line-height:1.7;text-transform:uppercase;font-weight:400}
.claim i{font-style:normal;color:var(--gold)}
.herolinks{display:flex;flex-direction:column;align-items:flex-start;gap:.9rem}
.herobtns{display:flex;gap:.75rem;flex-wrap:wrap;align-items:center}

/* ============ buttons ============ */
.btn{
  display:inline-flex;align-items:center;gap:.7rem;
  font-family:var(--mono);font-size:.78rem;letter-spacing:.1em;text-transform:uppercase;
  padding:.85rem 1.35rem;border-radius:99px;border:1px solid var(--line);
  transition:background .25s var(--ease),color .25s var(--ease),border-color .25s var(--ease);
}
.btn svg{width:.85em;height:.85em;overflow:visible}
.btn svg path{transition:transform .3s var(--ease)}
.btn:hover svg path,.btn:focus-visible svg path{transform:translateX(3px)}
.btn:hover,.btn:focus-visible{background:var(--ink);color:#0a0a0b;border-color:var(--ink)}
.btn.go{background:var(--gold);color:#0a0a0b;border-color:var(--gold)}
.btn.go:hover,.btn.go:focus-visible{background:var(--ink);border-color:var(--ink)}
.inline-mail{
  font-family:var(--mono);font-size:.78rem;letter-spacing:.06em;color:var(--dim);
  border-bottom:1px solid var(--line);padding-bottom:.15rem;transition:color .2s,border-color .2s;
}
.inline-mail:hover,.inline-mail:focus-visible{color:var(--gold);border-bottom-color:var(--gold)}

/* ============ marquee ============ */
/* One track holding six identical groups, shifted by exactly one group width,
   so the reset lands on a pixel-identical frame. The five groups still on
   screen at the end of a cycle are what stop a gap ever scrolling into view;
   five group widths clear any display. Keep the copy count and the translate
   percentage in step: translate = 100% / groups. */
.mq{overflow:hidden;border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:1.1rem 0}
.mq-track{display:flex;width:max-content;animation:slide 66s linear infinite}
.mq-track p{
  flex:none;font-family:var(--mono);
  font-size:clamp(.85rem,1.6vw,1.05rem);letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;
}
.mq-track p i{font-style:normal;color:var(--gold);padding:0 1.6rem}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-16.6667%)}}

/* ============ numbers ============ */
.nums{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--line)}
.nums>div{border-bottom:1px solid var(--line);border-right:1px solid var(--line);padding:clamp(1.75rem,3.5vw,3rem) clamp(1.25rem,2.5vw,2.25rem)}
.nums>div:last-child{border-right:0}
.nums b{display:block;margin-top:1.5rem;font-weight:800;letter-spacing:-.04em;line-height:.95;font-size:clamp(1.9rem,5.2vw,4.2rem)}
.nums span{display:block;margin-top:.6rem;color:var(--dim);font-size:.95rem;text-wrap:pretty}
.nums b small{display:block;font-family:var(--mono);font-size:.3em;font-weight:400;letter-spacing:.16em;text-transform:uppercase;color:var(--gold);margin-bottom:.5rem}
@media(max-width:760px){.nums{grid-template-columns:1fr}.nums>div{border-right:0}}

/* ============ section frame ============ */
.sec{padding-top:clamp(5rem,14vh,10rem);padding-bottom:clamp(5rem,14vh,10rem)}
.sec .tag{margin-bottom:clamp(1.75rem,4vh,3rem)}
.tinted{background:var(--card);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}

/* the word that assembles letter by letter */
.word{display:flex;flex-wrap:wrap;line-height:.8;margin-bottom:clamp(1.5rem,4vh,2.5rem)}
.word i{font-style:normal;font-weight:800;letter-spacing:-.045em;font-size:clamp(3.4rem,16vw,11rem);display:block}
.js .word i{opacity:0;transform:translateY(.3em) rotate(6deg);transition:opacity .7s var(--ease),transform .7s var(--ease);transition-delay:calc(var(--i) * 70ms)}
.js .word.in i{opacity:1;transform:none}

/* ============ the list ============ */
/* Hover fades the background and lifts the number only. Nothing in the text
   column moves, so a mouse crossing the rows never shoves the line you read. */
.rows{border-top:1px solid var(--line)}
.row{
  display:grid;grid-template-columns:4.5rem 1fr 1.2fr;gap:1rem 2rem;align-items:baseline;
  padding:clamp(1.4rem,3vw,2.1rem) var(--row-pad,0);border-bottom:1px solid var(--line);
  transition:background .45s var(--ease);
}
.row:hover{background:var(--card)}
.row b{font-family:var(--mono);font-size:.78rem;font-weight:400;color:var(--dim);letter-spacing:.1em;transition:color .45s var(--ease)}
.row:hover b{color:var(--gold)}
.row h3{font-weight:700;letter-spacing:-.02em;font-size:clamp(1.25rem,2.8vw,2rem);line-height:1.1;text-wrap:balance}
.row p{color:var(--dim);text-wrap:pretty}
@media(max-width:760px){
  .row{grid-template-columns:3.2rem 1fr;gap:.4rem 1rem}
  .row p{grid-column:2}
}
.count{margin-top:1.75rem;font-family:var(--mono);font-size:.78rem;letter-spacing:.14em;color:var(--dim);text-transform:uppercase}
.count i{font-style:normal;color:var(--gold)}

/* ============ faq ============ */
/* Native <details>, so it works with no JavaScript and the answers stay in
   the DOM for crawlers and AI assistants even while collapsed. */
.faq{border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{
  display:grid;grid-template-columns:4.5rem 1fr 2rem;gap:1rem 2rem;align-items:baseline;
  padding:clamp(1.2rem,2.6vw,1.8rem) 0;cursor:pointer;list-style:none;
  transition:background .45s var(--ease);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::marker{content:""}
.faq summary:hover{background:var(--card)}
.faq summary b{font-family:var(--mono);font-size:.78rem;font-weight:400;color:var(--dim);letter-spacing:.1em;transition:color .45s var(--ease)}
.faq summary:hover b,.faq details[open] summary b{color:var(--gold)}
.faq summary h3{font-weight:700;letter-spacing:-.02em;font-size:clamp(1.05rem,2vw,1.45rem);line-height:1.2;text-wrap:balance}
.faq .sign{justify-self:end;color:var(--gold);font-family:var(--mono);transition:transform .3s var(--ease)}
.faq details[open] .sign{transform:rotate(45deg)}
.faq .a{padding:0 2rem clamp(1.4rem,3vw,2rem) 5.5rem;color:var(--dim);max-width:64ch;text-wrap:pretty}
@media(max-width:760px){
  .faq summary{grid-template-columns:3.2rem 1fr 1.5rem;gap:.4rem 1rem}
  .faq .a{padding-left:3.2rem;padding-right:0}
}

/* ============ the deal ============ */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);margin-top:clamp(2.5rem,6vh,4rem)}
.steps div{background:var(--card);padding:clamp(1.5rem,3vw,2.25rem) 0;padding-right:2rem}
.steps b{display:block;font-family:var(--mono);font-size:.75rem;letter-spacing:.14em;color:var(--gold);margin-bottom:.7rem}
.steps p{color:var(--dim);text-wrap:pretty}
@media(max-width:760px){.steps{grid-template-columns:1fr}.steps div{padding-right:0;padding-left:0}}

/* ============ me ============ */
.me{display:grid;grid-template-columns:minmax(0,16rem) minmax(0,1fr);gap:clamp(2rem,5vw,5rem);align-items:center}
/* height:auto is load-bearing: the width/height attributes make both axes
   definite, and aspect-ratio is ignored until one of them is auto.
   16rem is also the largest hannes.jpg (320x308) renders without upscaling. */
.me img{width:100%;height:auto;aspect-ratio:1;object-fit:cover;border-radius:50%;max-width:16rem}
.me p{color:var(--dim);margin-top:1.25rem;text-wrap:pretty;max-width:42ch}
.me a.gold{color:var(--gold)}
.me .li{display:inline-flex;align-items:center;gap:.5rem;margin-top:1.5rem;font-family:var(--mono);font-size:.78rem;letter-spacing:.1em;text-transform:uppercase;color:var(--gold);border-bottom:1px solid rgba(232,163,61,.3);padding-bottom:.2rem}
.me .li:hover{border-bottom-color:var(--gold)}
.me .li svg{width:.8em;height:.8em}
@media(max-width:820px){.me{grid-template-columns:1fr}.me img{max-width:11rem}}

/* ============ close ============ */
.close{padding-top:clamp(6rem,18vh,12rem);padding-bottom:clamp(4rem,10vh,7rem)}
.close h2{font-weight:800;letter-spacing:-.045em;line-height:.86;font-size:clamp(3rem,14vw,11rem);text-wrap:balance}
.close h2 em{font-style:normal;color:var(--gold)}
.close .cta{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:clamp(2rem,5vh,3rem)}
.mail{display:inline-block;margin-top:2rem;font-weight:700;letter-spacing:-.02em;font-size:clamp(1.15rem,3.4vw,2.2rem);border-bottom:1px solid rgba(232,163,61,.3);color:var(--gold)}
.mail:hover{border-bottom-color:var(--gold)}

footer{border-top:1px solid var(--line);padding-top:1.75rem;padding-bottom:2.5rem;font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}
.foot{display:flex;flex-wrap:wrap;gap:.9rem 2rem;justify-content:space-between}
footer a:hover{color:var(--ink)}

/* ============ cursor ============ */
.cur{position:fixed;top:0;left:0;width:9px;height:9px;border-radius:50%;background:var(--gold);z-index:9200;pointer-events:none;opacity:0;transition:opacity .3s,transform .25s var(--ease);will-change:transform}
@media(hover:hover) and (pointer:fine){.cur.on{opacity:1}.cur.big{transform:scale(4.5);opacity:.35}}

/* ============ legal page ============ */
.doc{max-width:46rem;margin:0 auto}
.doc-head{padding-top:1.5rem;padding-bottom:1rem;font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.doc-head .brand b{color:var(--gold)}
.doc-head .back{color:var(--dim)}
.doc-head .back:hover{color:var(--ink)}
.doc h1{font-weight:800;letter-spacing:-.045em;line-height:.9;font-size:clamp(2.6rem,10vw,5.5rem);margin-top:clamp(3rem,10vh,6rem)}
.doc h2{font-weight:800;letter-spacing:-.035em;line-height:1;font-size:clamp(1.6rem,4.5vw,2.6rem);margin-top:clamp(3.5rem,8vh,5.5rem);padding-top:2rem;border-top:1px solid var(--line)}
.doc h3{font-family:var(--mono);font-size:.78rem;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:var(--gold);margin-top:2.25rem;margin-bottom:.5rem}
.doc p,.doc ul{margin-top:.85rem;color:var(--dim);text-wrap:pretty}
.doc a{color:var(--gold)}
.doc ul{padding-left:1.2rem}
.doc li{margin-top:.35rem}
.doc address{font-style:normal;margin-top:.85rem;color:var(--ink);line-height:1.75}
.stamp{margin-top:1.75rem;background:var(--card);border:1px solid var(--line);border-left:2px solid var(--gold);padding:1.25rem 1.4rem}
.stamp p{margin-top:0}
.stamp strong{color:var(--ink)}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .js .r{opacity:1;transform:none}
  .js .mark span{opacity:1;transform:none}
  .js .word i{opacity:1;transform:none}
  .cur{display:none}
}
