@font-face{font-family:'ABC Monument Grotesk';font-weight:300;font-display:block;src:url(../fonts/ABCMonumentGrotesk-Light.otf) format('opentype')}
@font-face{font-family:'ABC Monument Grotesk';font-weight:400;font-display:block;src:url(../fonts/ABCMonumentGrotesk-Regular.otf) format('opentype')}
@font-face{font-family:'ABC Monument Grotesk';font-weight:700;font-display:block;src:url(../fonts/ABCMonumentGrotesk-Bold.otf) format('opentype')}

/* tokens */
:root{
 --hh:80px;--g:clamp(20px,1.93vw,37px);--R:clamp(400px,28.85vw,554px);
 --stf:clamp(28px,2.47vw,47px);                /* section-title font size */
 --cfs:min(var(--stf),calc(var(--R)/15.4));    /* slogan font size: three fixed lines sized by the longest */
 --L:max(clamp(150px,15.4vw,295px),calc(var(--stf)*6.2),var(--Lmin,0px)); /* left column never narrower than the longest title (s⁴ massstäbe) */
 --mid:calc(min(var(--vw,100vw),1920px) - var(--L) - var(--R) - var(--g)*4);
 --ink:#1c1b1b;
 --lh:1.5;--lead:calc((var(--lh) - 1)*.5em); /* half-leading of body text */
 --s1:.45em;--s2:calc(var(--s1)*2);           /* vertical rhythm: title→content, item→item */
 --gap:calc(var(--g)*8);--hfs:31px;--num:36px;      /* chapter gap (lowest content → next chapter) · mobile wordmark size · SIA number column */
 --pls:11px;--plw:1px;--dpx:1px;              /* plus icon = cap height of the text beside it (font cap .70em → 11px @16px); Light 11/1, Bold 12/2; --dpx = one device pixel (JS) – strokes are rounded to whole device pixels */
 --capTop:calc((1lh - 1.2em)/2 + .25em);         /* top of capital letters inside a line box (ascent .95em, descent .25em, cap .70em) */
 --ease:cubic-bezier(.22,1,.36,1);
}
*,*::before,*::after{box-sizing:border-box}
html{visibility:visible;scroll-padding-top:calc(var(--hh) - var(--g));-webkit-text-size-adjust:100%} /* releases the inline html{visibility:hidden} of every page – no unstyled flash */html.ready{scroll-behavior:smooth}
html:not(.ready) *,html:not(.ready) *::before,html:not(.ready) *::after{transition:none!important;animation:none!important} /* first paint is final – nothing fades in on page load */
body{margin:0;background:#fff;color:var(--ink);hyphens:auto;-webkit-hyphens:auto;hyphenate-limit-chars:7 3 3;font:300 16px/var(--lh) 'ABC Monument Grotesk','Helvetica Neue',Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none;transition:opacity .3s ease;-webkit-tap-highlight-color:transparent}a:hover{opacity:.55}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;text-align:left;transition:opacity .3s ease;-webkit-tap-highlight-color:transparent}
h1,h2,h3,p,figure,ul{margin:0}ul{padding:0;list-style:none}img{display:block}
b,strong,.h,.b{font-weight:700}
button:focus-visible,a:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--ink);outline-offset:4px}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}html{scroll-behavior:auto}}

/* layout */
.wrap{max-width:1920px;margin:0 auto;padding:0 var(--g)}
.grid{display:grid;grid-template-columns:var(--L) minmax(0,1fr) var(--R);column-gap:var(--g);align-items:start}
.sec{padding-top:var(--g);padding-bottom:var(--gap)} /* identical gap between all chapters */
.mid{min-width:0}
.r{min-width:0}
.sec .l{position:sticky;top:var(--hh);padding-top:2px;white-space:nowrap}
.l .st{transition:opacity .35s ease}
.stack{display:flex;flex-direction:column;gap:var(--g)}

/* section titles */
.st{display:flex;align-items:baseline;gap:.12em;font-weight:300;font-size:var(--stf);line-height:1.2}
.st .mk{height:.72em;width:auto;aspect-ratio:372/305;align-self:baseline} /* intrinsic ratio known before the file arrives – the word beside the mark never jumps */

/* images */
.img{position:relative;aspect-ratio:3/2;background:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;overflow:hidden}
.img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:opacity .3s ease}
.img[data-ph]:not([data-ph=""])::after{content:attr(data-ph)}.img:not(:has(img)),.img[data-ph]:not([data-ph=""]){background:repeating-linear-gradient(135deg,rgba(28,27,27,.07) 0 1px,transparent 1px 8px)} /* hatch only for a genuinely missing photo */
.cap{margin-top:6px}
#pimgx figcaption,#simg figcaption,#mimgx figcaption{display:none}

/* text (left aligned everywhere, no Blocksatz) */
.meta,.desc{margin:0} /* title, client, info, description: one uniform line rhythm */
.lead{margin-bottom:var(--s2)}
.h{margin:0;hyphens:manual}.act,.row>span:first-child,.grp>span:first-child,.meta,.cap{hyphens:manual} /* only running text hyphenates */

/* plus / cross – an SVG line pair, the same simple cross as the cursor: axis-aligned strokes are drawn without anti-aliasing (crispEdges); stroke (--w) and box (--s) are rounded to whole device pixels with (box − stroke) even, so the two arms of every plus have exactly the same length on every row, at any zoom level or OS scaling; the rotated × is anti-aliased */
.pl{--w:max(var(--dpx),round(var(--plw),var(--dpx)));--s:calc(round(calc(var(--pls) - var(--w)),calc(var(--dpx)*2)) + var(--w));width:var(--s);height:var(--s);flex:0 0 var(--s);display:inline-block;overflow:visible;stroke:currentColor;stroke-width:var(--w);shape-rendering:crispEdges;transform-origin:center;transition:transform .35s var(--ease),shape-rendering 0s .35s allow-discrete} /* crisp mode returns only once the cross has rotated back */
[aria-expanded="true"]>.pl,.pl.x{transform:rotate(45deg);shape-rendering:auto;transition:transform .35s var(--ease),shape-rendering 0s allow-discrete} /* smooth diagonals from the first frame of the rotation */
.b,button.h,.acc button[aria-expanded="true"]{--plw:2px;--pls:12px} /* plus/x as heavy as the Bold text beside it */
/* contact actions: label left, + right (same row) */
.acts{display:flex;flex-direction:column}
.act{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;padding:1px 0}
.act>span:first-child{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.act .pl,.acc button>.pl,#pgrid .cap>.pl{margin-top:round(down,calc(var(--capTop) - (var(--s) - .7em)/2),1px)} /* plus spans exactly cap top → baseline of the letters beside it */
.act.vcard[hidden]{display:none}
.close{justify-content:flex-end;gap:.4em;margin-bottom:var(--s2)}

/* accordion */
.acc button{width:100%;display:flex;justify-content:space-between;align-items:flex-start;gap:16px;padding:var(--s2) 0 0} /* all row spacing sits ABOVE the row and never changes on open/close – nothing around an opening body jumps */
.acc button>span:first-child{flex:1 1 auto;min-width:0;text-align:left;hyphens:manual} /* titles never hyphenate */
.acc button:hover{opacity:.55}
.sec>.r>.acc:first-child>div:first-child>button{padding-top:0} /* first row starts on the chapter's top edge (desktop + mobile) */
.lead+.acc>div:first-child>button{padding-top:var(--s1)}
.acc button[aria-expanded="true"]{font-weight:700}
.acc .bd{display:grid;grid-template-rows:0fr;--bdp:0px;transition:grid-template-rows .35s var(--ease)} /* the only motion: the row grows from 0 to its content height, pushing everything below down smoothly */
.acc .bd>*{min-height:0;overflow:hidden}
.acc .bd>*::after{content:"";display:block;height:var(--bdp)} /* extra gap after an open body – part of the animated content, never an instant step */
.acc [aria-expanded="true"]+.bd{grid-template-rows:1fr}
.acc [aria-expanded="false"]+.bd{transition-duration:.3s}
.acc .bd p+.img{margin-top:12px}
.acc.refs button{padding:2px 0 0}
.acc.refs .bd{--bdp:var(--s2)} /* visible gap after an open project block */
.acc.emp{margin-top:calc(var(--s1) + 2px)}.acc.emp:first-child{margin-top:0}.acc.emp>div>button{font-weight:300;padding:2px 0 0}.acc.emp>div>button[aria-expanded="true"]{font-weight:700} /* employer reads Bold while open */
.acc.emp>div>.bd{--bdp:var(--s1)}.acc.emp>div>.bd>*::before{content:"";display:block;height:var(--s1)} /* paragraph before the project list – part of the animated content */
#leistungen .acc button{padding:2px 0 0}#leistungen .acc .bd{--bdp:var(--s2)}

/* rows (dates / phases) */
.rows{display:flex;flex-direction:column}
.row,.grp{display:grid;grid-template-columns:110px minmax(0,1fr);gap:0 16px}.row{padding:1px 0}.grp{flex:1 1 auto;min-width:0}
.row>span:first-child,.grp>span:first-child{white-space:nowrap}
.row.grp{font-weight:700;margin-top:var(--s2)}.row.grp:first-child{margin-top:0}
.sia .row{grid-template-columns:var(--num) minmax(0,1fr)}
.sia .bd .rows{padding-left:var(--num)}.num{display:inline-block;width:var(--num)}
.h.gap{margin-top:calc(var(--g)*1.5)}.ort .img.m-only{margin-bottom:var(--s2)}

/* CV */
.cvg{margin-top:var(--s2)}
.cvg.acc{margin-top:0} /* the row's own top padding (s2) is the gap */
.cv[hidden]{display:none}
.cv{animation:cvin .4s var(--ease)}
@keyframes cvin{from{clip-path:inset(0 0 100% 0)}to{clip-path:inset(0 0 0 0)}} /* CV switch wipes top → bottom too */
.note{margin:var(--s2) 0}

/* header + navigation */
header{position:fixed;top:0;left:0;right:0;z-index:100;height:var(--hh);background:#fff}
header .grid{height:var(--hh);align-items:center}
header .logo{display:flex;align-items:center;height:var(--hh)}
#hsec{margin:0;white-space:nowrap} /* also the static wordmark on subpages */
#hsec .mkw{position:relative;display:inline-block;height:.72em;align-self:baseline;flex:0 0 auto}#hsec .mkw .mk{height:100%;display:block}
#hfull{position:absolute;left:0;top:0;height:100%;width:auto;aspect-ratio:2400/305;max-width:none;transition:opacity .25s ease}
#hsec>span:last-child{display:inline-block;transition:opacity .25s ease;will-change:opacity}
#hsec.land>span:last-child,#hsec.sw>span:last-child{opacity:0}#hsec:not(.land) #hfull{opacity:0}
#hsec.now,#hsec.now *{transition:none!important} /* instant state change (menu, nav jump) – no cross-fade */
#nav{display:flex;justify-content:space-between;gap:12px}#nav.r{padding:0;margin:0}
#nav a{padding:6px 0}#nav.r{position:relative;top:calc((var(--stf) - 16px)*.135)} /* nav sits on the logo's baseline (not its optical centre) */#nav a[aria-current="true"]{font-weight:700}
#burger{display:none;width:44px;justify-content:flex-end}
#menu{display:flex;visibility:hidden;opacity:0;position:fixed;inset:var(--hh) 0 0 0;z-index:99;background:#fff;flex-direction:column;justify-content:safe center;gap:1.35em;overflow-y:auto;padding:var(--g) var(--g) var(--hh) calc(var(--g) + 1em);font-size:var(--hfs);transition:opacity .35s ease,visibility 0s .35s}
#menu.open{visibility:visible;opacity:1;transition:opacity .35s ease}
#menu a{font-weight:300;transform:translateY(-8px);transition:transform .35s var(--ease)}#menu.open a{transform:none} /* only the links slide – the white panel itself always covers the full viewport (no page strip at the bottom edge) */
@media (max-height:640px){#menu{padding-bottom:var(--g);gap:.9em}}
main{padding-top:var(--hh)}

/* footer */
footer{padding:calc(var(--g)*1.5) 0 calc(var(--g)*2)}
footer .r{display:flex;flex-direction:column;gap:var(--s2);padding:0}
footer .fl{display:flex;flex-direction:column;gap:2px}footer .fl .act{padding:0} /* footer links: label left, + flush right (same row as .act in Kontakt) */

/* sections */
#intro{min-height:calc(100vh - var(--hh));display:grid;grid-template-rows:1fr auto;padding-bottom:calc(var(--g)*5);margin-bottom:calc(var(--gap) - var(--g)*5)}#intro>*{grid-row:2} /* first screen unchanged (hero 5g above the fold); the rest of the standard chapter gap follows below the fold */
.claim{margin-bottom:0;font-weight:300;font-size:var(--cfs);line-height:1.2;white-space:nowrap;margin-top:calc(var(--lead) - .247em)} /* glyph top flush with the image top */
.news{overflow:hidden;white-space:nowrap;hyphens:manual;margin-top:calc(var(--g) - .25*var(--cfs) - var(--capTop))} /* news ticker, exactly as wide as the right column; slogan baseline → cap top of the news = one gutter (same as slogan → image); .25em = slogan descent, its line-height 1.2 adds no leading */
.news>span{display:inline-block;white-space:pre;animation:news var(--nd,30s) linear infinite var(--nd0,0s)}.news>span::before,.news>span>span::before{content:"";display:inline-block;width:2em} /* the text is doubled by JS (SSOT: one copy in the markup); each copy starts with a 2em breath, so the loop reads … Wattwil    News I Offene …; both halves are identical, the strip scrolls by exactly one half; JS sets duration (constant speed) and starts the first pass at the right edge */
.news.paused>span{animation-play-state:paused}
@keyframes news{to{transform:translateX(-50%)}}
@media (hover:hover){.news:hover>span{animation-play-state:paused}}
@media (prefers-reduced-motion:reduce){.news{white-space:normal}.news>span{display:inline;white-space:normal}.news>span>span{display:none}} /* static wrapping text instead of motion */
#pgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--g)}
#pgrid a{display:block}#pgrid .img{aspect-ratio:2/3}
#pgrid .cap{display:flex;justify-content:space-between;align-items:flex-start;gap:8px}#pgrid .cap>span:first-child{flex:1 1 auto;min-width:0}
#pgrid a:hover{opacity:1}#pgrid a:hover .img{opacity:.85}
.ort+.ort{margin-top:var(--g)}

/* desktop */
@media (min-width:1024px){
 .m-only{display:none}
 .sec .l .st{display:none} /* chapter name lives only in the header (top left) */
 .sec>.r{margin-top:calc(var(--lead)*-1)}        /* first text line sits on the image top edge */
 #nav a{display:inline-flex;flex-direction:column;align-items:center}#nav a::after{content:attr(data-t);font-weight:700;height:0;overflow:hidden;visibility:hidden}
 #pgrid a[aria-current="true"] .cap{font-weight:700;--plw:2px;--pls:12px}#pgrid a[aria-current="true"] .pl{transform:rotate(45deg);shape-rendering:auto;transition:transform .35s var(--ease),shape-rendering 0s allow-discrete} /* desktop only: the selected person reads Bold with an × – on mobile every card stays Light */
 #cvcol.win{position:sticky;top:calc(var(--hh) - 4px);overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:rgba(28,27,27,.3) transparent;margin-right:calc(var(--g)*-1);padding-right:calc(var(--g) - 8px);scrollbar-gutter:stable} /* sticks at its static position (−lead); scrollbar lives in the page margin – JS refines padding-right to the real scrollbar width */
 #cvcol.win::-webkit-scrollbar{width:8px}#cvcol.win::-webkit-scrollbar-thumb{background:rgba(28,27,27,.3);border-radius:4px}#cvcol.win::-webkit-scrollbar-track{background:transparent}
 #kontakt .ort{min-height:calc(var(--mid)*2/3 + var(--g))}#kontakt .ort:last-child{min-height:0}#kontakt .ort+.ort{margin-top:0}
}
@media (max-width:1280px) and (min-width:1024px){:root{--R:clamp(360px,36vw,420px)}}
@media (hover:hover) and (pointer:fine){
 html,body{cursor:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><path d='M12 2v20M2 12h20' stroke='%23000' stroke-width='2'/></svg>") 12 12, auto}
 a,button,label,summary,[role="button"],#projekte .stack figure .img{cursor:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='26' height='26' viewBox='0 0 26 26'><path d='M11.75 1.5h2.5v10.25H24.5v2.5H14.25V24.5h-2.5V14.25H1.5v-2.5h10.25z' fill='%23fff' stroke='%23000' stroke-width='1' stroke-linejoin='miter'/></svg>") 13 13, pointer}
 input,textarea{cursor:text}
}
@media (hover:none){a:hover,.acc button:hover{opacity:1}}

/* mobile / tablet */
@media (max-width:1023px){
 :root{--g:clamp(15px,4vw,32px);--lh:1.35;--cfs:min(22px,calc((100vw - var(--g)*2)/15.6))}
 body{font-size:16px}
 .grid{grid-template-columns:minmax(0,1fr)}
 .grid>.l:not(.logo):empty,.grid>.mid:empty,.l:not(.logo),.d-only,#nav{display:none}
 #burger{display:flex;height:var(--hh);align-items:flex-start;--pls:22px;--plw:2px;margin-right:calc((var(--pls) - 11px)/-2)} /* 22px = cap height of the wordmark; same axis as the 11px icons below */
 #burger .pl{margin-top:round(calc((var(--hh) - 1.2*var(--hfs))/2 + .25*var(--hfs)),1px)} /* cap top of the wordmark */
 header .grid{align-items:center;display:flex;justify-content:space-between}
 .r{padding:0}
 :root{--gap:calc(var(--g)*6)}
 .sec .mid{margin-bottom:0}.sec .mid:not(.d-only)+.r:not(.d-only):not(:empty){margin-top:var(--g)} /* gap only when a right column really follows */
 .st,#hsec{font-size:var(--hfs)}
 .act{gap:10px}
 .row,.grp{grid-template-columns:96px minmax(0,1fr);gap:0 12px}.sia .row{grid-template-columns:var(--num) minmax(0,1fr)}
 #intro{min-height:calc(100svh - var(--hh));padding:var(--g) var(--g) var(--gap);margin-bottom:0;margin-bottom:calc(100lvh - 100svh);grid-template-rows:1fr auto auto auto}#intro .r{display:contents}#intro .claim{grid-row:2}#intro .mid{margin:0;grid-row:3}#intro .news{grid-row:4;margin-top:calc(var(--g) - var(--capTop))} /* slogan, image and news stack at the bottom of the first screen (mockup) – .r dissolves so the news can follow the image; image bottom → cap top of the news = one gutter (same as image → screen edge); the margin equals the browser-bar collapse, so the next chapter never peeks in while the bars are hidden (logo jump to top) */
 #intro .claim{margin:max(calc(var(--g)*3),calc(var(--hh) - var(--g))) 0 clamp(56px,20vw,80px)} /* at least 3 gutters of white between header and slogan on every device – on short screens (iPhone/iPad in Safari) the 1fr row above collapses to 0, so this margin is what guarantees the breathing room; tall screens (Pixel) are unaffected */
 #pstack{gap:calc(var(--g)*1.5)} /* project title/description → next image: one and a half gutters */
 #pgrid{gap:calc(var(--g)*.6)}
 #pgrid .cap{--pls:.7em;--plw:.75px;gap:3px;font-size:clamp(9.6px,calc(3.5vw - 1.6px),11px);line-height:1.25;letter-spacing:-.01em} /* 11px from 360px up, scaling down to 9.6px at 320px so the longest name (Florian Schällibaum) always stays on one line; plus = cap height of the caption (.7em), flush with the portrait's right edge; stroke as thin as the Light glyphs */
 #kontakt .ort+.ort{margin-top:calc(var(--g)*2)}
 .act{padding-block:12px;margin-block:-11px;position:relative} /* 44px touch targets without changing the visible rhythm */
 .act.close{margin-bottom:calc(var(--s2) - 11px)} /* keeps the paragraph gap to the name (the generic -11px above would swallow it) */
 footer .fl{gap:3px}footer .fl .act{padding-block:12px;margin-block:-11px} /* same tight list rhythm as desktop; each link box ≥24px (WCAG 2.5.8) */
}

/* subpages */
#cvp{padding-top:var(--hh)}.legal{padding-top:calc(var(--hh) - var(--lead))} /* content meets the header edge exactly like a chapter after a nav jump (desktop: em box of the first line on the edge, as .sec>.r) */
.legal .block{display:grid;grid-template-columns:var(--L) minmax(0,1fr) var(--R);column-gap:var(--g);padding:0 0 calc(var(--g)*.9)}
.legal .block h2,.legal .txt{grid-column:3}
.legal .block h2{font-size:inherit;font-weight:700;margin-bottom:2px}
.legal .acc .bd>*::before{content:"";display:block;height:2px}
.legal .txt p+p,.legal .bd p+p{margin-top:10px}
@media (max-width:1023px){.legal{padding-top:var(--hh)}.legal .block{grid-template-columns:minmax(0,1fr)}.legal .block h2,.legal .txt{grid-column:1}}
