<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
<title>Fjære Yoga · Nordnes, Bergen</title>
<meta name="description" content="Slow yoga at the water’s edge. A small studio on the Nordnes peninsula in Bergen: twelve mats, no mirrors, a kettle that is always on.">
<script>document.documentElement.className='js';document.documentElement.style.setProperty('--vh',innerHeight+'px')</script>
<style>
:root{
  --sand:#f6efe4;--paper:#fcf8f1;--foam:#e1ece5;--ink:#11283a;--mute:#455b6b;--deep:#10303f;
  --sun:#f1a03d;--clay:#a9431f;--coral:#e47a55;--kelp:#5a8672;--ring:var(--ink);
  --pad:clamp(20px,5vw,56px);--max:1180px;
  --serif:"Iowan Old Style","Palatino Linotype",Palatino,"URW Palladio L",P052,Georgia,serif;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --out:cubic-bezier(.22,1,.36,1);--pop:cubic-bezier(.34,1.56,.64,1);
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-padding-top:72px}
body{margin:0;background:var(--sand);color:var(--ink);font:400 17px/1.55 var(--sans);-webkit-font-smoothing:antialiased}
svg{display:block;max-width:100%}
button{font:inherit;color:inherit;cursor:pointer;border:0;background:none;padding:0;-webkit-tap-highlight-color:transparent}
h1,h2,h3,p,ul{margin:0}
ul{padding:0;list-style:none}
a{color:inherit}
:focus-visible{outline:3px solid var(--ring);outline-offset:3px;border-radius:8px}
.skip{position:absolute;left:12px;top:-64px;z-index:100;background:var(--ink);color:var(--sand);padding:12px 18px;border-radius:99px;text-decoration:none;font-weight:600}
.skip:focus{top:12px}
.wrap{width:100%;max-width:calc(var(--max) + 2*var(--pad));margin:0 auto;padding:0 var(--pad)}
h1,h2,h3,.serif{font-family:var(--serif);font-weight:400;letter-spacing:-.015em}
h2{font-size:clamp(2.2rem,6.4vw,3.7rem);line-height:1.03;text-wrap:balance}
.eyebrow{font:600 12px/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--clay);margin-bottom:18px}
.lead{font-size:clamp(1.05rem,2.4vw,1.2rem);color:var(--mute);max-width:36em;margin-top:18px}

/* buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:48px;padding:0 24px;border-radius:99px;font:600 15px/1 var(--sans);text-decoration:none;white-space:nowrap;transition:transform .4s var(--pop),background .25s,color .25s,box-shadow .25s}
.btn.solid{background:var(--ink);color:var(--sand)}
.btn.line{box-shadow:inset 0 0 0 2px var(--ink)}
.btn:active{transform:scale(.96)}
@media(hover:hover){.btn.solid:hover{transform:translateY(-2px) scale(1.03);box-shadow:0 12px 24px -12px rgba(17,40,58,.7)}.btn.line:hover{background:var(--ink);color:var(--sand);transform:translateY(-2px)}}
.btn[disabled]{opacity:.4;cursor:not-allowed;transform:none;box-shadow:none}
.pulse{width:9px;height:9px;border-radius:50%;background:var(--coral);position:relative}
.pulse::after{content:"";position:absolute;inset:0;border-radius:50%;background:var(--coral);animation:ping 2s ease-out infinite}

/* nav */
.nav{position:fixed;inset:0 0 auto 0;z-index:40;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px var(--pad);transition:background .3s,box-shadow .3s}
.nav.solid{background:rgba(246,239,228,.95);box-shadow:0 1px 0 rgba(17,40,58,.1)}
.logo{display:flex;align-items:center;gap:10px;font:italic 400 30px/1 var(--serif);letter-spacing:-.02em;text-decoration:none;padding:6px 0}
.logo svg{width:30px;height:14px;fill:none;stroke:var(--clay);stroke-width:2.4;stroke-linecap:round}
.nav ul{display:none;gap:30px}
.nav a.nl{font:600 14px/1 var(--sans);text-decoration:none;padding:12px 2px;background:linear-gradient(currentColor,currentColor) 0 78%/0 2px no-repeat;transition:background-size .4s var(--out)}
.nav a.nl:hover{background-size:100% 2px}
.nav .btn{min-height:42px;padding:0 20px;font-size:14px}
@media(min-width:760px){.nav ul{display:flex}}

/* hero */
.hero{position:relative;display:grid;grid-template-rows:auto 1fr;min-height:max(680px,min(var(--vh,100vh),920px));overflow:hidden;isolation:isolate;background:linear-gradient(#f6cba0 0%,#f9dcbc 34%,#fcebd5 66%,#fdf3e4 100%)}
.copy{position:relative;z-index:6;width:100%;max-width:calc(var(--max) + 2*var(--pad));margin:0 auto;padding:92px var(--pad) 10px;pointer-events:none}
.copy>div{max-width:680px;pointer-events:auto}
.copy h1{font-size:clamp(2.75rem,12.2vw,5.5rem);line-height:.98;margin-bottom:20px;text-wrap:balance}
.copy h1 em{color:var(--clay)}
.hero .lede{font-size:clamp(1.05rem,2.5vw,1.22rem);line-height:1.5;max-width:31em}
.cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:26px}
.next{display:flex;align-items:flex-start;gap:12px;margin-top:22px;font:500 14px/1.4 var(--sans);color:var(--mute)}
.next .pulse{margin-top:6px;flex:none}
.next b{display:block;color:var(--ink);font-weight:600;font-size:15px}
.w{display:inline-block;overflow:hidden;vertical-align:top;padding:.1em 0 .16em;margin:-.1em 0 -.16em}
.wi{display:inline-block}
.js .wi{transform:translateY(112%)}
.go .wi{transform:none;transition:transform .9s var(--out);transition-delay:calc(.3s + var(--n)*.06s)}
.js .fade{opacity:0;transform:translateY(16px)}
.go .fade{opacity:1;transform:none;transition:opacity .7s var(--out),transform .7s var(--out);transition-delay:calc(.7s + var(--d,0)*.1s)}

.scene{position:relative;min-height:250px;--ss:clamp(190px,54vw,300px);--sx:50%;--sea:23%}
.cloud{position:absolute;height:22px;border-radius:99px;background:rgba(255,255,255,.62);animation:cloud var(--t) linear infinite;animation-delay:var(--dl);left:0;top:var(--y);width:var(--w)}
.cloud::after{content:"";position:absolute;left:22%;bottom:55%;width:38%;height:100%;border-radius:99px;background:inherit}
.sun{position:absolute;left:var(--sx);bottom:calc(var(--sea) - var(--ss)*.3);width:var(--ss);height:var(--ss);margin-left:calc(var(--ss)/-2);z-index:1;translate:0 calc(var(--p,0)*160px)}
.go .sun .rise{animation:rise 2s var(--out) .1s both}
.js .sun .rise{transform:translateY(60%)}
.rise,.disc{position:absolute;inset:0}
.disc{border-radius:50%;background:radial-gradient(circle at 36% 30%,#f9c068 0,#f1a03d 54%,#ea8a35 100%);transition:transform 1s ease-in-out}
.rg{position:absolute;inset:0;border-radius:50%;border:2px solid rgba(241,160,61,.5);animation:ring 7s ease-out infinite;animation-delay:var(--d)}
.sun[data-ph=in] .disc{transform:scale(1.22);transition-duration:4s}
.sun[data-ph=hold] .disc{transform:scale(1.22)}
.sun[data-ph=out] .disc{transform:scale(1);transition-duration:6s}
.cue{position:absolute;left:0;right:0;top:15%;text-align:center;font:italic 400 clamp(1.25rem,3.6vw,1.85rem)/1.1 var(--serif);color:var(--ink);opacity:0;transition:opacity .5s;pointer-events:none;padding:0 12%}
.cue small{display:block;margin-top:8px;font:600 11px/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:#5b2a14}
.sun.on .cue{opacity:1}
.gull{position:absolute;z-index:2;left:0;top:var(--y);width:28px;animation:fly var(--t) linear infinite;animation-delay:var(--dl);opacity:0}
.gull svg{width:100%;fill:none;stroke:var(--ink);stroke-width:1.7;stroke-linecap:round;animation:flap 1.2s ease-in-out infinite;animation-delay:var(--dl)}
.sea{position:absolute;inset:0;z-index:3;pointer-events:none}
.l{position:absolute;left:0;right:0;overflow:hidden}
.go .l{animation:wup 1.3s var(--out) both;animation-delay:var(--e)}
.l svg{position:absolute;left:0;bottom:0;width:200%;max-width:none;height:100%;animation:drift var(--t) linear infinite;animation-direction:var(--dir,normal)}
.l1{bottom:calc(var(--sea) + 2%);height:70px;--t:50s;--e:.1s;fill:#acd0d2}
.l2{bottom:calc(var(--sea) - 4%);height:80px;--t:38s;--dir:reverse;--e:.2s;fill:#72a9b2}
.l3{bottom:calc(var(--sea) - 11%);height:92px;--t:30s;--e:.3s;fill:#3b7b8d}
.l4{bottom:calc(var(--sea) - 18%);height:96px;--t:23s;--dir:reverse;--e:.4s;fill:#225b70}
.l5{bottom:-2px;height:58px;--t:17s;--e:.5s;fill:var(--sand)}
.glit{position:absolute;left:var(--sx);bottom:calc(var(--sea) - 8%);width:calc(var(--ss)*.8);margin-left:calc(var(--ss)*-.4);z-index:3;pointer-events:none}
.glit i{display:block;height:4px;border-radius:3px;margin:8px auto;background:rgba(255,238,205,.9);width:var(--w);animation:glit 3.2s ease-in-out infinite;animation-delay:var(--d)}
.cairn{position:absolute;z-index:5;right:5%;bottom:3px;width:clamp(64px,17vw,112px);-webkit-tap-highlight-color:transparent}
.cairn svg{width:100%;overflow:visible}
.st{transform-box:fill-box;transform-origin:50% 100%}
.cairn.wob .st{animation:wob 1.3s ease-out both;animation-delay:calc(var(--k)*70ms)}
.cairn .hint{position:absolute;right:100%;bottom:26px;margin-right:4px;white-space:nowrap;padding:7px 14px 8px;border-radius:99px;background:rgba(246,239,228,.94);font:italic 400 15px/1.2 var(--serif);color:var(--ink);transition:opacity .4s;display:none}
@media(min-width:900px){.cairn .hint{display:block}}
.go .cairn .st{animation:drop .8s var(--pop) both;animation-delay:calc(1.1s + var(--k)*.1s)}
.js .cairn .st{opacity:0}

@media(min-width:900px){
  .hero{grid-template-rows:1fr}
  .copy,.scene{grid-area:1/1}
  .copy{align-self:start;padding-top:max(112px,12vh);padding-bottom:40px}
  .scene{--ss:min(38vw,430px);--sx:73%;--sea:17%}
  .cairn{right:7%}
  .gull{animation-name:flyd}
}
.js .copy>div{translate:0 calc(var(--p,0)*-50px)}

/* ribbon */
.ribbon{overflow:hidden;padding:34px 0 30px;background:var(--sand)}
.tape{width:104%;margin-left:-2%;overflow:hidden;background:var(--ink);color:var(--sand);transform:rotate(-1.3deg);padding:15px 0}
.track{display:flex;width:max-content;animation:tape 46s linear infinite}
.track span{display:flex;align-items:center;gap:26px;padding-right:26px;font:italic 400 clamp(1.3rem,3.2vw,1.9rem)/1 var(--serif);white-space:nowrap}
.track i{width:12px;height:12px;border-radius:50%;background:var(--sun)}

/* sections */
section{position:relative}
.pad{padding:clamp(72px,10vw,132px) 0}
.edge{position:absolute;left:0;top:1px;width:100%;height:clamp(26px,4vw,50px);transform:translateY(-100%);fill:var(--bg)}
.rv{transition:opacity .9s var(--out),transform .9s var(--out);transition-delay:calc(var(--i,0)*90ms)}
.js .rv{opacity:0;transform:translateY(30px)}
.js .rv.in{opacity:1;transform:none}

/* the room */
.facts{display:grid;gap:34px;margin-top:clamp(44px,6vw,76px)}
.fact{display:grid;grid-template-columns:clamp(104px,30vw,132px) 1fr;gap:20px;align-items:center}
.pebble{aspect-ratio:1;display:grid;place-items:center;border-radius:58% 42% 55% 45%/52% 48% 52% 48%;font:italic 400 clamp(3rem,12vw,4.8rem)/1 var(--serif);color:var(--ink);animation:bob 7s ease-in-out infinite;animation-delay:var(--d);transition:transform .6s var(--pop)}
.fact:nth-child(2) .pebble{border-radius:44% 56% 41% 59%/58% 44% 56% 42%}
.fact:nth-child(3) .pebble{border-radius:52% 48% 60% 40%/46% 56% 44% 54%}
.fact h3{font-size:clamp(1.45rem,4.4vw,1.9rem);line-height:1.1;margin-bottom:8px}
.fact p{color:var(--mute);max-width:26em}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
@media(min-width:760px){.facts{grid-template-columns:repeat(3,1fr);gap:40px}.fact{grid-template-columns:1fr;gap:26px;align-items:start}.pebble{width:clamp(150px,19vw,210px)}}
@media(hover:hover){.fact:hover .pebble{transform:rotate(-6deg) scale(1.06)}}

/* week */
.week{--bg:var(--paper);background:var(--bg)}
.days{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:6px;margin:34px 0 18px}
.day{min-height:64px;border-radius:18px;display:grid;place-content:center;justify-items:center;gap:7px;font:600 14px/1 var(--sans);background:#efe6d6;transition:transform .45s var(--pop),background .25s,color .25s}
.day em{display:flex;gap:3px;font-style:normal}
.day em i{width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.45}
.day[aria-pressed=true]{background:var(--ink);color:var(--sand);transform:translateY(-5px)}
.day.today::before{content:"";position:absolute;top:9px;right:10px;width:6px;height:6px;border-radius:50%;background:var(--coral)}
.day{position:relative}
@media(hover:hover){.day:not([aria-pressed=true]):hover{transform:translateY(-3px);background:#e8dcc7}}
.list{display:grid;gap:12px;min-height:220px}
.row{display:grid;grid-template-columns:92px 1fr;grid-template-areas:"t nm" "ft ft";gap:6px 16px;padding:20px 18px;border-radius:24px;background:var(--sand);align-items:center;animation:rowin .8s var(--out) both;animation-delay:calc(var(--i)*90ms)}
.row .t{grid-area:t;font:italic 400 clamp(2rem,7vw,2.8rem)/1 var(--serif);letter-spacing:-.03em}
.row .nm{grid-area:nm}
.row h3{font-size:clamp(1.4rem,4.6vw,1.75rem);line-height:1.1}
.row .meta{font-size:14px;color:var(--mute);margin-top:4px}
.row .ft{grid-area:ft;display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-top:12px;padding-top:14px;border-top:1px dashed rgba(17,40,58,.22)}
.lv{display:inline-flex;align-items:center;gap:8px;font:600 12px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--mute)}
.lv svg{width:42px;height:12px;fill:none;stroke:var(--ink);stroke-width:2.2;stroke-linecap:round}
.lv svg path{opacity:.22}.lv svg path.on{opacity:1}
.mats{display:flex;align-items:center;gap:10px;font:600 13px/1 var(--sans)}
.bars{display:flex;gap:3px}
.bars i{width:5px;height:16px;border-radius:3px;background:#d8cdb8;transform-origin:50% 100%;animation:grow .6s var(--out) both;animation-delay:calc(var(--i)*90ms + var(--b)*25ms + .2s)}
.bars i.x{background:var(--ink)}
.low{color:var(--clay)}
.row .btn{min-height:44px;padding:0 20px;font-size:14px}
@media(min-width:900px){
  .row{grid-template-columns:130px minmax(0,1fr) auto auto;grid-template-areas:"t nm lv bt";gap:0 28px;padding:22px 28px}
  .row .ft{display:contents}
  .row .lv{grid-area:lv}
  .row .tail{grid-area:bt;display:flex;align-items:center;gap:22px}
}
@media(max-width:899px){.row .tail{display:contents}}
@media(hover:hover){.row{transition:transform .5s var(--pop),background .3s}.row:hover{transform:translateX(6px);background:#f1e8d8}}

/* people */
.people{--bg:var(--foam);background:var(--bg)}
.cards{display:flex;gap:16px;overflow-x:auto;scroll-snap-type:x mandatory;margin:44px calc(var(--pad)*-1) 0;padding:6px var(--pad) 26px;scrollbar-width:none}
.cards::-webkit-scrollbar{display:none}
.card{flex:0 0 min(78vw,300px);scroll-snap-align:center;border-radius:28px;background:var(--paper);overflow:hidden;display:flex;flex-direction:column;transition:transform .6s var(--pop)}
.art{aspect-ratio:10/7;position:relative;overflow:hidden;background:var(--c)}
.art svg{position:absolute;inset:0;width:100%;height:100%}
.card .bd{padding:20px 20px 24px;display:flex;flex-direction:column;gap:8px;flex:1}
.card h3{font-size:1.9rem;line-height:1}
.card .rl{font:600 12px/1.3 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--clay)}
.card p{color:var(--mute);font-size:15.5px;line-height:1.5;margin-bottom:8px}
.card .tg{margin-top:auto;font:600 13px/1.4 var(--sans);padding-top:12px;border-top:1px dashed rgba(17,40,58,.22)}
@media(min-width:900px){.cards{display:grid;grid-template-columns:repeat(4,1fr);overflow:visible;margin:56px 0 0;padding:0}.card{flex:none}}
@media(hover:hover){.card:hover{transform:translateY(-8px) rotate(-.6deg)}}
.rays{transform-box:fill-box;transform-origin:50% 100%;animation:spin 40s linear infinite}
.card:hover .rays{animation-duration:6s}
.moon{transform-origin:100px 20px;animation:sway 6s ease-in-out infinite}
.stw{animation:twinkle 3s ease-in-out infinite;animation-delay:var(--d)}
.wl{stroke-dasharray:12 10;animation:dash 3s linear infinite}
.pb{transform-box:fill-box;transform-origin:50% 100%;animation:pebw 5s ease-in-out infinite;animation-delay:var(--d)}

/* prices */
.prices{--bg:var(--deep);background:var(--bg);color:var(--sand);--ring:var(--sand)}
.prices .eyebrow{color:#f2b78f}
.prices .lead{color:#b9cdd4}
.seg{position:relative;display:inline-grid;grid-template-columns:1fr 1fr;margin-top:30px;padding:5px;border-radius:99px;background:rgba(246,239,228,.12)}
.seg::before{content:"";position:absolute;top:5px;bottom:5px;left:5px;width:calc(50% - 5px);border-radius:99px;background:var(--sand);transition:transform .5s var(--pop)}
.seg[data-v="1"]::before{transform:translateX(100%)}
.seg button{position:relative;z-index:1;min-height:44px;padding:0 20px;border-radius:99px;font:600 14px/1 var(--sans);color:var(--sand);transition:color .3s}
.seg button[aria-pressed=true]{color:var(--ink)}
.plans{display:grid;gap:14px;margin-top:34px}
.plan{position:relative;padding:28px 26px 30px;border-radius:28px;background:var(--paper);color:var(--ink);display:grid;gap:6px;align-content:start;transition:transform .6s var(--pop)}
.plan.hot{background:var(--sun)}
.plan h3{font-size:1.5rem}
.plan .n{font:italic 400 clamp(3rem,11vw,4.2rem)/1 var(--serif);letter-spacing:-.03em;margin:10px 0 4px}
.plan .n small{font:600 15px var(--sans);letter-spacing:0;margin-left:6px}
.plan p{font-size:15px;color:#33495a}
.plan.hot p{color:#3b2008}
@media(min-width:900px){.plans{grid-template-columns:repeat(3,1fr);gap:18px}}
@media(hover:hover){.plan:hover{transform:translateY(-8px)}}
.stamp{position:absolute;right:14px;top:-34px;width:104px;height:104px;border-radius:50%;overflow:hidden}
.stamp svg{width:100%;height:100%;animation:spin 22s linear infinite}
.stamp text{font:700 11px var(--sans);fill:var(--ink);text-transform:uppercase}
.free{margin-top:36px;font:italic 400 clamp(1.3rem,3.4vw,1.7rem)/1.3 var(--serif);color:#f2dcc0;text-wrap:balance}

/* visit */
.visit{--bg:var(--sand);background:var(--bg)}
.vgrid{display:grid;gap:44px;margin-top:44px}
.info{display:grid;gap:28px;align-content:start}
.info h3{font:600 12px/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--clay);margin-bottom:10px}
.info p{font-size:1.1rem;line-height:1.5}
.hrs{display:grid;grid-template-columns:auto 1fr;gap:6px 22px;font-size:1.05rem}
.hrs dt{font-weight:600}.hrs dd{margin:0;color:var(--mute)}
.map{border-radius:30px;overflow:hidden;background:#bcd8dc;aspect-ratio:5/4;position:relative}
.map svg{width:100%;height:100%}
.route{fill:none;stroke:var(--ink);stroke-width:3;stroke-linecap:round;stroke-dasharray:2 9;animation:march 1.4s linear infinite}
.pin{transform-box:fill-box;transform-origin:50% 50%;animation:ping2 2.4s ease-out infinite}
.mp{font:600 12px var(--sans);fill:#33495a}
@media(min-width:900px){.vgrid{grid-template-columns:5fr 6fr;gap:64px;align-items:center}}

/* footer */
footer{--bg:var(--deep);position:relative;background:var(--bg);color:var(--sand);padding:clamp(64px,9vw,110px) 0 36px;--ring:var(--sand)}
footer .bigw{overflow:hidden;margin-bottom:20px}
footer .big{font:italic 400 clamp(5.5rem,30vw,17rem)/1 var(--serif);letter-spacing:-.05em;color:#1a4356;margin:0;padding:0 .1em .1em .06em;user-select:none;white-space:nowrap}
footer .fl{display:flex;flex-wrap:wrap;gap:12px 40px;justify-content:space-between;align-items:end;font-size:15px;color:#b9cdd4}
footer .fl b{color:var(--sand);font-weight:600;display:block;margin-bottom:4px}
footer .fine{margin-top:34px;padding-top:22px;border-top:1px solid rgba(246,239,228,.18);font-size:13.5px;color:#9fb6bf}
.up{display:inline-flex;align-items:center;gap:10px;font:600 14px/1 var(--sans);padding:14px 20px;border-radius:99px;box-shadow:inset 0 0 0 1.5px rgba(246,239,228,.45);color:var(--sand);text-decoration:none;transition:background .3s,color .3s}
@media(hover:hover){.up:hover{background:var(--sand);color:var(--ink)}}

/* booking sheet */
dialog{margin:0;padding:0;border:0;background:transparent;width:100%;height:100%;max-width:none;max-height:none;color:var(--ink)}
dialog[open]{display:flex;align-items:flex-end;justify-content:center}
dialog::backdrop{background:rgba(10,30,44,.6)}
.sheet{position:relative;width:min(100%,520px);max-height:94%;overflow:auto;background:var(--paper);border-radius:30px 30px 0 0;padding:30px 22px calc(26px + env(safe-area-inset-bottom));animation:sheet .55s var(--out)}
.sheet h3{font-size:2rem;line-height:1.05}
.sheet .sub{color:var(--mute);margin:8px 0 22px;font-size:15px}
.cx{position:absolute;right:12px;top:12px;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;font-size:26px;line-height:1;background:#efe6d6;transition:transform .4s var(--pop)}
.cx:hover{transform:rotate(90deg)}
.room-map{display:grid;grid-template-columns:22px 1fr;gap:10px;margin-bottom:12px}
.room-map .wn{writing-mode:vertical-rl;transform:rotate(180deg);text-align:center;border-radius:99px;background:repeating-linear-gradient(#cfe3e6 0 22px,#bcd8dc 22px 24px);font:600 10.5px/22px var(--sans);letter-spacing:.2em;text-transform:uppercase;color:#33586a}
.fr{grid-column:2;text-align:center;font:600 10.5px/1 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--mute);padding-bottom:10px;border-bottom:2px solid var(--ink);margin-bottom:2px}
.mgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.mat{height:52px;border-radius:12px;background:var(--foam);box-shadow:inset 0 0 0 2px #b7cfc3;font:600 15px var(--sans);transition:transform .35s var(--pop),background .2s}
.mat[disabled]{background:repeating-linear-gradient(135deg,#e8dfce 0 6px,#efe6d6 6px 12px);box-shadow:none;color:#a39a89;cursor:not-allowed}
.mat[aria-pressed=true]{background:var(--sun);box-shadow:inset 0 0 0 2px var(--ink);transform:scale(1.08)}
@media(hover:hover){.mat:not([disabled]):hover{transform:scale(1.08)}}
.legend{display:flex;gap:18px;flex-wrap:wrap;font-size:13px;color:var(--mute);margin:14px 0 22px}
.legend span{display:inline-flex;align-items:center;gap:7px}
.legend i{width:14px;height:14px;border-radius:5px;background:var(--foam);box-shadow:inset 0 0 0 2px #b7cfc3}
.legend i.t{background:#e8dfce;box-shadow:none}.legend i.m{background:var(--sun);box-shadow:inset 0 0 0 2px var(--ink)}
.wide{width:100%}
.fine2{margin-top:14px;font-size:13px;color:var(--mute);text-align:center}
.done{text-align:center;padding:20px 0 4px}
.done svg{width:88px;height:88px;margin:0 auto 18px;fill:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round}
.done circle{stroke:var(--sun);stroke-dasharray:300;stroke-dashoffset:300;animation:draw .9s var(--out) forwards}
.done path{stroke:var(--ink);stroke-dasharray:60;stroke-dashoffset:60;animation:draw .5s var(--out) .6s forwards}
.done p{margin:10px auto 22px;max-width:24em;color:var(--mute)}
html.lock{overflow:hidden}
@media(min-width:700px){dialog[open]{align-items:center}.sheet{border-radius:30px;padding:34px 30px 28px}}

@keyframes drift{to{transform:translateX(-50%)}}
@keyframes rise{from{transform:translateY(60%)}to{transform:none}}
@keyframes wup{from{transform:translateY(110%)}to{transform:none}}
@keyframes ring{0%{transform:scale(1);opacity:.9}100%{transform:scale(1.9);opacity:0}}
@keyframes ping{0%{transform:scale(1);opacity:.6}100%{transform:scale(3);opacity:0}}
@keyframes ping2{0%{transform:scale(.6);opacity:.8}100%{transform:scale(2.4);opacity:0}}
@keyframes glit{50%{transform:scaleX(.5);opacity:.5}}
@keyframes cloud{from{transform:translateX(-30vw)}to{transform:translateX(130vw)}}
@keyframes flyd{0%{transform:translate(45vw,0);opacity:0}10%{opacity:1}50%{transform:translate(75vw,-20px)}90%{opacity:1}100%{transform:translate(112vw,8px);opacity:0}}
@keyframes fly{0%{transform:translate(-10vw,0);opacity:0}8%{opacity:1}50%{transform:translate(55vw,-24px)}92%{opacity:1}100%{transform:translate(115vw,10px);opacity:0}}
@keyframes flap{50%{transform:scaleY(.45)}}
@keyframes tape{to{transform:translateX(-50%)}}
@keyframes bob{50%{transform:translateY(-10px) rotate(2deg)}}
@keyframes drop{0%{transform:translateY(-70px);opacity:0}55%{opacity:1}70%{transform:translateY(0) scale(1.08,.9)}100%{transform:none;opacity:1}}
@keyframes wob{0%{transform:rotate(0)}18%{transform:rotate(calc(var(--k)*-1.6deg))}38%{transform:rotate(calc(var(--k)*1.4deg))}58%{transform:rotate(calc(var(--k)*-.8deg))}78%{transform:rotate(calc(var(--k)*.4deg))}100%{transform:rotate(0)}}
@keyframes rowin{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:none}}
@keyframes grow{from{transform:scaleY(.15)}to{transform:none}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes sway{50%{transform:rotate(8deg)}}
@keyframes twinkle{50%{opacity:.2}}
@keyframes dash{to{stroke-dashoffset:-44}}
@keyframes pebw{50%{transform:rotate(3deg)}}
@keyframes march{to{stroke-dashoffset:-11}}
@keyframes sheet{from{opacity:0;transform:translateY(60px)}to{opacity:1;transform:none}}
@keyframes draw{to{stroke-dashoffset:0}}
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.001ms!important;transition-delay:0s!important}
  .js .wi,.js .rv,.js .fade,.js .sun .rise,.js .cairn .st{transform:none!important;opacity:1!important}
  .sun .disc{transform:none!important}
  .gull{display:none}
  .cloud{left:var(--x)}
}
</style>
</head>
<body>
<a class="skip" href="#classes">Skip to classes</a>

<header class="nav" id="nav">
  <a class="logo" href="#top" aria-label="Fjære Yoga, back to the top">Fjære<svg viewBox="0 0 30 14" aria-hidden="true"><path d="M1 7c3-6 6-6 9 0s6 6 9 0 6-6 10 0"/></svg></a>
  <ul>
    <li><a class="nl" href="#room">The room</a></li>
    <li><a class="nl" href="#classes">Classes</a></li>
    <li><a class="nl" href="#teachers">Teachers</a></li>
    <li><a class="nl" href="#prices">Prices</a></li>
    <li><a class="nl" href="#visit">Find us</a></li>
  </ul>
  <a class="btn solid" href="#classes">Book a mat</a>
</header>

<main id="top">
<section class="hero" aria-labelledby="h1">
  <div class="copy"><div>
    <p class="eyebrow fade" style="--d:0">Yoga studio · Nordnes, Bergen</p>
    <h1 id="h1" data-split>Slow yoga at the <em>water’s edge.</em></h1>
    <p class="lede fade" style="--d:1">Fjære is a small studio on the Nordnes peninsula in Bergen. Twelve mats, a view of the fjord, and a kettle that’s always on.</p>
    <div class="cta fade" style="--d:2">
      <a class="btn solid" href="#classes">Book a class</a>
      <button class="btn line" id="breathe" type="button" aria-pressed="false"><span class="pulse" aria-hidden="true"></span><span id="bl">Try 3 breaths</span></button>
    </div>
    <p class="next fade" style="--d:3" id="next" hidden></p>
  </div></div>

  <div class="scene" id="scene" aria-hidden="false">
    <div aria-hidden="true">
      <span class="cloud" style="--y:15%;--w:130px;--t:120s;--dl:-30s;--x:8%"></span>
      <span class="cloud" style="--y:32%;--w:90px;--t:160s;--dl:-110s;--x:66%"></span>
      <span class="cloud" style="--y:21%;--w:170px;--t:200s;--dl:-150s;--x:38%"></span>
      <span class="gull" style="--y:22%;--t:70s;--dl:-8s"><svg viewBox="0 0 28 12"><path d="M1 9C6 1 11 1 14 7 17 1 22 1 27 9"/></svg></span>
      <span class="gull" style="--y:30%;--t:90s;--dl:-40s;width:20px"><svg viewBox="0 0 28 12"><path d="M1 9C6 1 11 1 14 7 17 1 22 1 27 9"/></svg></span>
    </div>
    <div class="sun" id="sun" data-ph="">
      <div class="rise" aria-hidden="true">
        <i class="rg" style="--d:0s"></i><i class="rg" style="--d:-2.3s"></i><i class="rg" style="--d:-4.6s"></i>
        <div class="disc"></div>
      </div>
      <p class="cue" id="cue" role="status"></p>
    </div>
    <div class="sea" aria-hidden="true">
      <div class="l l1"><svg viewBox="0 0 1200 120" preserveAspectRatio="none"><path d="M0 60C100 20 200 20 300 60S500 100 600 60 800 20 900 60 1100 100 1200 60V120H0Z"/></svg></div>
      <div class="glit"><i style="--w:70%;--d:0s"></i><i style="--w:54%;--d:-.5s"></i><i style="--w:40%;--d:-1s"></i><i style="--w:28%;--d:-1.5s"></i><i style="--w:18%;--d:-2s"></i></div>
      <div class="l l2"><svg viewBox="0 0 1200 120" preserveAspectRatio="none"><path d="M0 50C75 14 225 14 300 50S525 86 600 50 825 14 900 50 1125 86 1200 50V120H0Z"/></svg></div>
      <div class="l l3"><svg viewBox="0 0 1200 120" preserveAspectRatio="none"><path d="M0 54C100 18 200 18 300 54S500 90 600 54 800 18 900 54 1100 90 1200 54V120H0Z"/></svg></div>
      <div class="l l4"><svg viewBox="0 0 1200 120" preserveAspectRatio="none"><path d="M0 46C60 12 240 12 300 46S540 80 600 46 840 12 900 46 1140 80 1200 46V120H0Z"/></svg></div>
      <div class="l l5"><svg viewBox="0 0 1200 120" preserveAspectRatio="none"><path d="M0 52C150 14 250 14 400 52S650 90 800 52 1050 14 1200 52V120H0Z"/></svg></div>
    </div>
    
    <button class="cairn" id="cairn" type="button" aria-label="A little stack of stones. Press it to make it wobble.">
      <svg viewBox="0 0 120 170" aria-hidden="true">
        <ellipse cx="60" cy="160" rx="54" ry="6" fill="rgba(17,40,58,.16)"/>
        <g class="st" style="--k:1"><ellipse cx="60" cy="144" rx="52" ry="17" fill="#76706a"/><ellipse cx="44" cy="138" rx="22" ry="5.5" fill="#948d85"/></g>
        <g class="st" style="--k:2"><ellipse cx="64" cy="118" rx="40" ry="15" fill="#8d867d"/><ellipse cx="52" cy="113" rx="16" ry="4.5" fill="#aaa399"/></g>
        <g class="st" style="--k:3"><ellipse cx="57" cy="95" rx="30" ry="12.5" fill="#a39b8f"/><ellipse cx="48" cy="91" rx="12" ry="3.8" fill="#bdb6a9"/></g>
        <g class="st" style="--k:4"><ellipse cx="62" cy="76" rx="21" ry="10" fill="#bcb3a4"/><ellipse cx="55" cy="72.5" rx="8" ry="3" fill="#d3ccbd"/></g>
        <g class="st" style="--k:5"><ellipse cx="59" cy="61" rx="12" ry="8" fill="#d2c9b8"/><ellipse cx="55" cy="58" rx="4.5" ry="2.4" fill="#e6dfd0"/></g>
      </svg>
      <span class="hint" id="hint" aria-hidden="true">Give them a tap</span>
    </button>
  </div>
</section>

<div class="ribbon" aria-hidden="true"><div class="tape"><div class="track">
  <span>Slow flow<i></i>Yin<i></i>Morning breath<i></i>Beginners welcome<i></i>Tea after<i></i>Slow flow<i></i>Yin<i></i>Morning breath<i></i>Beginners welcome<i></i>Tea after<i></i></span>
  <span>Slow flow<i></i>Yin<i></i>Morning breath<i></i>Beginners welcome<i></i>Tea after<i></i>Slow flow<i></i>Yin<i></i>Morning breath<i></i>Beginners welcome<i></i>Tea after<i></i></span>
</div></div></div>

<section class="room pad" id="room" aria-labelledby="h-room">
  <div class="wrap">
    <div class="rv"><p class="eyebrow">The room</p><h2 id="h-room">A small room, kept small.</h2>
    <p class="lead">One bright room on the second floor of an old harbour warehouse. We keep classes small so the teacher can actually see you.</p></div>
    <ul class="facts">
      <li class="fact rv" style="--i:0"><div class="pebble" style="--d:0s;background:#d6e5dc" aria-hidden="true">12</div><div><h3><span class="sr">12 </span>mats. Never 13.</h3><p>That’s the whole room. You get a corner, a window seat, or a neighbour you nod to.</p></div></li>
      <li class="fact rv" style="--i:1"><div class="pebble" style="--d:-2.4s;background:#f6d7a6" aria-hidden="true">0</div><div><h3><span class="sr">0 </span>mirrors.</h3><p>Nobody is checking your triangle pose. Least of all us.</p></div></li>
      <li class="fact rv" style="--i:2"><div class="pebble" style="--d:-4.8s;background:#f3cdbd" aria-hidden="true">1</div><div><h3><span class="sr">1 </span>kettle, always on.</h3><p>Ginger, mint or plain. Stay after class; most people do.</p></div></li>
    </ul>
  </div>
</section>

<section class="week pad" id="classes" aria-labelledby="h-week">
  <svg class="edge" viewBox="0 0 1200 48" preserveAspectRatio="none" aria-hidden="true"><path d="M0 48V28C120 4 240 4 360 22S600 50 720 30 960 0 1200 20V48Z"/></svg>
  <div class="wrap">
    <div class="rv"><p class="eyebrow">This week</p><h2 id="h-week">Pick a day, then pick a mat.</h2>
    <p class="lead">Everything is drop-in. Doors open fifteen minutes before, and the mats, blocks and blankets are ours.</p></div>
    <div class="days rv" id="days" role="group" aria-label="Day of the week"></div>
    <div class="list" id="list" aria-live="polite"></div>
  </div>
</section>

<section class="people pad" id="teachers" aria-labelledby="h-people">
  <svg class="edge" viewBox="0 0 1200 48" preserveAspectRatio="none" aria-hidden="true"><path d="M0 48V22C150 44 300 44 450 22S750 0 900 22 1100 40 1200 26V48Z"/></svg>
  <div class="wrap">
    <div class="rv"><p class="eyebrow">At the front of the room</p><h2 id="h-people">Four teachers, no shouting.</h2></div>
    <div class="cards rv" tabindex="0" aria-label="Teachers">
      <article class="card" style="--c:#f9dcb3">
        <div class="art"><svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" aria-hidden="true"><g class="rays" fill="none" stroke="#f1a03d" stroke-width="5" stroke-linecap="round"><path d="M100 22V8M62 36L52 26M138 36L148 26M40 66H26M160 66H174"/></g><circle cx="100" cy="98" r="40" fill="#f1a03d"/><path d="M0 100C40 92 70 108 100 100S160 92 200 102V140H0Z" fill="#7fb0b6"/><path d="M0 118C40 110 80 126 120 118S170 112 200 120V140H0Z" fill="#3b7b8d"/></svg></div>
        <div class="bd"><h3>Marit Solheim</h3><p class="rl">Founder · slow flow &amp; yin</p><p>Opened Fjære in 2019 after fourteen years of teaching in borrowed rooms. Will tell you to lie down more often than you expect.</p><p class="tg">Mon · Wed · Fri · Sat<br>English &amp; Norwegian</p></div>
      </article>
      <article class="card" style="--c:#cfe0e6">
        <div class="art"><svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" aria-hidden="true"><g fill="#fff"><circle class="stw" style="--d:0s" cx="40" cy="30" r="2.2"/><circle class="stw" style="--d:-1s" cx="160" cy="24" r="1.8"/><circle class="stw" style="--d:-2s" cx="172" cy="84" r="2.4"/><circle class="stw" style="--d:-.5s" cx="30" cy="96" r="1.6"/><circle class="stw" style="--d:-1.5s" cx="70" cy="16" r="1.4"/></g><g class="moon"><path d="M112 20A52 52 0 1 0 112 124A40 40 0 1 1 112 20Z" fill="#f6efe4"/></g></svg></div>
        <div class="bd"><h3>Aksel Brenna</h3><p class="rl">Mornings &amp; first steps</p><p>Former rower. Teaches the 07:00 class like it’s a conversation: breath first, poses after, no one left behind.</p><p class="tg">Mon–Fri mornings · Sat<br>English &amp; Norwegian</p></div>
      </article>
      <article class="card" style="--c:#d6e6d9">
        <div class="art"><svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" aria-hidden="true"><g fill="none" stroke="#2f6a58" stroke-width="5" stroke-linecap="round"><path class="wl" d="M-10 44C10 30 30 30 50 44S90 58 110 44 150 30 170 44 210 58 230 44"/><path class="wl" style="animation-duration:4s" d="M-10 74C10 60 30 60 50 74S90 88 110 74 150 60 170 74 210 88 230 74"/><path class="wl" style="animation-duration:5s" d="M-10 104C10 90 30 90 50 104S90 118 110 104 150 90 170 104 210 118 230 104"/></g></svg></div>
        <div class="bd"><h3>Selma Haugland</h3><p class="rl">Restorative &amp; yin</p><p>Physiotherapist by day. Her classes are mostly blankets, and somehow they work. Bring socks.</p><p class="tg">Mon · Wed · Sun<br>English &amp; Norwegian</p></div>
      </article>
      <article class="card" style="--c:#f3cfc0">
        <div class="art"><svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" aria-hidden="true"><ellipse cx="100" cy="128" rx="66" ry="7" fill="rgba(17,40,58,.14)"/><g class="pb" style="--d:0s"><ellipse cx="100" cy="112" rx="52" ry="17" fill="#76706a"/></g><g class="pb" style="--d:-1s"><ellipse cx="104" cy="84" rx="38" ry="14" fill="#948d85"/></g><g class="pb" style="--d:-2s"><ellipse cx="98" cy="60" rx="26" ry="11" fill="#b3ab9e"/></g><g class="pb" style="--d:-3s"><ellipse cx="101" cy="42" rx="14" ry="8" fill="#d2c9b8"/></g></svg></div>
        <div class="bd"><h3>Elias Tran</h3><p class="rl">Strength &amp; flow</p><p>Climbing coach turned yoga teacher. Strong classes, kind cues, and playlists with no lyrics.</p><p class="tg">Tue · Thu<br>English &amp; Norwegian</p></div>
      </article>
    </div>
  </div>
</section>

<section class="prices pad" id="prices" aria-labelledby="h-prices">
  <svg class="edge" viewBox="0 0 1200 48" preserveAspectRatio="none" aria-hidden="true"><path d="M0 48V24C140 2 280 2 420 26S700 48 840 26 1080 4 1200 22V48Z"/></svg>
  <div class="wrap">
    <div class="rv"><p class="eyebrow">Prices</p><h2 id="h-prices">No contracts, no joining fee.</h2>
    <p class="lead">Pay when you come. Students and anyone under 26 pay less.</p>
    <div class="seg" id="seg" data-v="0" role="group" aria-label="Price group"><button type="button" aria-pressed="true" data-v="0">Regular</button><button type="button" aria-pressed="false" data-v="1">Student · under 26</button></div></div>
    <div class="plans">
      <article class="plan rv" style="--i:0"><h3>Drop-in</h3><p class="n"><span data-p="0">190</span><small>kr</small></p><p>One class, any day. Pay at the door.</p></article>
      <article class="plan hot rv" style="--i:1">
        <div class="stamp" aria-hidden="true"><svg viewBox="0 0 120 120"><defs><path id="circ" d="M60 60m-44 0a44 44 0 1 1 88 0a44 44 0 1 1-88 0"/></defs><circle cx="60" cy="60" r="58" fill="#fcf8f1"/><text><textPath href="#circ" textLength="274" lengthAdjust="spacing">Most people start here ·</textPath></text><circle cx="60" cy="60" r="9" fill="#f1a03d"/></svg></div>
        <h3>Ten-class card</h3><p class="n"><span data-p="1">1 600</span><small>kr</small></p><p>Valid for four months. Lend it to a friend; we won’t ask.</p></article>
      <article class="plan rv" style="--i:2"><h3>Unlimited month</h3><p class="n"><span data-p="2">890</span><small>kr</small></p><p>Every class for 30 days from your first visit.</p></article>
    </div>
    <p class="free rv">Your first class is on us. Just say so at the door.</p>
  </div>
</section>

<section class="visit pad" id="visit" aria-labelledby="h-visit">
  <svg class="edge" viewBox="0 0 1200 48" preserveAspectRatio="none" aria-hidden="true"><path d="M0 48V20C100 40 220 46 360 28S640 0 800 22 1080 44 1200 24V48Z"/></svg>
  <div class="wrap">
    <div class="rv"><p class="eyebrow">Find us</p><h2 id="h-visit">Up 31 steps, door on the left.</h2></div>
    <div class="vgrid">
      <div class="info rv">
        <div><h3>Address</h3><p>Fjæregata 12, 2nd floor<br>Nordnes, 5817 Bergen</p></div>
        <div><h3>Opening hours</h3><dl class="hrs"><dt>Mon–Fri</dt><dd>06:45–20:30</dd><dt>Saturday</dt><dd>09:00–13:00</dd><dt>Sunday</dt><dd>17:30–19:30</dd></dl></div>
        <div><h3>Good to know</h3><p>Ten minutes’ walk from the fish market. Bike racks in the yard. No lift, sorry: 31 steps, we counted twice. The door sticks, so push with your hip.</p></div>
      </div>
      <div class="map rv" style="--i:1" role="img" aria-label="Sketch map: Fjære is on the east side of the Nordnes peninsula, a ten-minute walk from the harbour and fish market.">
        <svg viewBox="0 0 500 400" preserveAspectRatio="xMidYMid slice">
          <rect width="500" height="400" fill="#bcd8dc"/>
          <path d="M-10 -10H170C190 60 160 110 200 170S300 230 290 300 330 380 360 410H-10Z" fill="#bcd8dc"/>
          <path d="M520 -10V420H330C340 360 290 330 300 270S200 190 215 120 250 40 260 -10Z" fill="#efe5d2"/>
          <path d="M300 60C380 50 450 70 470 120 480 170 420 200 360 190S270 120 300 60Z" fill="#bfd9c0"/>
          <g stroke="#fff" stroke-width="7" stroke-linecap="round" fill="none"><path d="M262 20C250 90 215 130 232 190S320 250 314 330"/><path d="M240 150C300 140 380 150 520 130"/><path d="M290 230C360 240 430 260 520 250"/><path d="M314 330C380 320 450 330 520 320"/></g>
          <path class="route" d="M470 96C420 112 360 140 322 176S298 222 300 252"/>
          <circle class="pin" cx="300" cy="252" r="12" fill="rgba(228,122,85,.5)"/>
          <circle cx="300" cy="252" r="9" fill="#e47a55" stroke="#11283a" stroke-width="3"/>
          <text class="mp" x="316" y="244">Fjære</text>
          <text class="mp" x="404" y="88">Fish market</text><circle cx="470" cy="96" r="5" fill="#11283a"/>
          <text class="mp" x="296" y="96" style="fill:#2f6a58">Park</text>
          <text class="mp" x="40" y="120" style="fill:#4d7c86">Harbour</text>
          <text class="mp" x="404" y="196" style="font-weight:500">10 min walk</text>
        </svg>
      </div>
    </div>
  </div>
</section>
</main>

<footer>
  <svg class="edge" viewBox="0 0 1200 48" preserveAspectRatio="none" aria-hidden="true"><path d="M0 48V26C150 6 250 6 400 28S650 48 800 26 1050 4 1200 24V48Z"/></svg>
  <div class="wrap">
    <div class="bigw"><p class="big" aria-hidden="true">Fjære</p></div>
    <div class="fl">
      <p><b>Fjære Yoga Studio</b>Fjæregata 12, 2nd floor · Nordnes, Bergen</p>
      <a class="up" href="#top">Back to the water <span aria-hidden="true">↑</span></a>
    </div>
    <p class="fine">Example page. Fjære, its address, its teachers and its timetable are made up, and nothing on this page is booked or saved.</p>
  </div>
</footer>

<dialog id="book" aria-labelledby="bk-t"><div class="sheet"><button class="cx" id="bk-x" type="button" aria-label="Close">×</button><div id="bk-body"></div></div></dialog>

<script>
(()=>{
const $=(s,r=document)=>r.querySelector(s),$$=(s,r=document)=>[...r.querySelectorAll(s)];
const RM=matchMedia('(prefers-reduced-motion:reduce)'),de=document.documentElement;
// The viewer's bar slims once the visitor scrolls, which resizes this frame. Freeze the hero height unless the width changes.
let W=innerWidth;addEventListener('resize',()=>{if(innerWidth!==W){W=innerWidth;de.style.setProperty('--vh',innerHeight+'px')}});

// headline words rise from a mask
const split=(n,c={n:0})=>{[...n.childNodes].forEach(k=>{if(k.nodeType===3){const f=document.createDocumentFragment();k.textContent.split(/(\s+)/).forEach(t=>{if(!t)return;if(!t.trim()){f.append(t);return}const w=document.createElement('span'),i=document.createElement('span');w.className='w';i.className='wi';i.style.setProperty('--n',c.n++);i.textContent=t;w.append(i);f.append(w)});k.replaceWith(f)}else split(k,c)})};
$$('[data-split]').forEach(e=>split(e));
const hero=$('.hero');requestAnimationFrame(()=>requestAnimationFrame(()=>hero.classList.add('go')));

// reveal on scroll
const io='IntersectionObserver'in window?new IntersectionObserver(es=>es.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target)}}),{threshold:.1,rootMargin:'0px 0px -5% 0px'}):null;
$$('.rv').forEach(e=>io?io.observe(e):e.classList.add('in'));

// nav + hero parallax
const nav=$('#nav');let raf=0;
const onScroll=()=>{if(raf)return;raf=requestAnimationFrame(()=>{raf=0;const y=scrollY;nav.classList.toggle('solid',y>40);if(!RM.matches&&y<hero.offsetHeight)hero.style.setProperty('--p',(y/hero.offsetHeight).toFixed(3))})};
addEventListener('scroll',onScroll,{passive:true});onScroll();
// in-page links: scroll in place without adding history entries to the frame
document.addEventListener('click',e=>{const a=e.target.closest('a[href^="#"]');if(!a)return;const t=document.getElementById(a.getAttribute('href').slice(1));if(!t)return;e.preventDefault();t.scrollIntoView({behavior:RM.matches?'auto':'smooth',block:'start'})});

// three breaths: 4 in, 1 hold, 6 out
const sun=$('#sun'),cue=$('#cue'),bb=$('#breathe'),bl=$('#bl');let tok=0;
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
const ph=(p,t,n)=>{sun.dataset.ph=p;cue.innerHTML=t+(n?'<small>'+n+' of 3</small>':'')};
const rest=()=>{sun.classList.remove('on');sun.dataset.ph='';bb.setAttribute('aria-pressed','false');bl.textContent='Try 3 breaths'};
bb.addEventListener('click',async()=>{
  if(bb.getAttribute('aria-pressed')==='true'){tok++;rest();return}
  const my=++tok;bb.setAttribute('aria-pressed','true');bl.textContent='Stop';sun.classList.add('on');
  for(let i=1;i<=3;i++){
    ph('in','Breathe in',i);await sleep(4000);if(my!==tok)return;
    ph('hold','Hold',i);await sleep(1000);if(my!==tok)return;
    ph('out','Breathe out',i);await sleep(6000);if(my!==tok)return;
  }
  ph('','That was thirty seconds.<small>A class is sixty minutes</small>');await sleep(5200);if(my===tok)rest();
});

// the stones
const cairn=$('#cairn');
cairn.addEventListener('click',()=>{cairn.classList.remove('wob');void cairn.offsetWidth;cairn.classList.add('wob');$('#hint').style.opacity=0});
cairn.addEventListener('animationend',e=>{if(e.animationName==='wob'&&e.target.dataset)cairn.classList.remove('wob')});

// timetable
const DAYS=['Mon','Tue','Wed','Thu','Fri','Sat','Sun'],LONG=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'];
const CL={
  tide:['Morning Tide','Aksel',60,1,.6],low:['Low Tide Flow','Marit',75,2,.75],high:['High Tide Flow','Elias',60,3,.5],
  yin:['Yin & Tea','Selma',60,1,.4],slack:['Slack Water','Selma',75,1,.55],lunch:['Lunch Stretch','Elias',45,1,.35],
  sat:['Slow Saturday','Marit',90,2,.8],first:['First Steps','Aksel',60,1,.3],reset:['Sunday Reset','Selma',60,1,.5],unwind:['Friday Unwind','Marit',60,1,.55]};
const WEEK=[
  [['07:00','tide'],['17:30','low'],['19:15','yin']],
  [['07:00','tide'],['12:10','lunch'],['18:30','high']],
  [['07:00','tide'],['17:30','low'],['19:15','slack']],
  [['07:00','tide'],['12:10','lunch'],['18:30','high']],
  [['07:00','tide'],['17:00','unwind']],
  [['09:30','sat'],['11:45','first']],
  [['18:00','reset']]];
const rng=a=>()=>{a|=0;a=a+0x6D2B79F5|0;let t=Math.imul(a^a>>>15,1|a);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296};
const taken=(d,s)=>{const r=rng(d*31+s*7+11),k=CL[WEEK[d][s][1]][4],o=[];for(let n=1;n<=12;n++)if(r()<k)o.push(n);if(o.length>11)o.pop();return o};
const wave='<path d="M1 7c3-6 6-6 10 0"/><path d="M15 7c3-6 6-6 10 0"/><path d="M29 7c3-6 6-6 10 0"/>';
const lvl=n=>'<svg viewBox="0 0 42 12" aria-hidden="true">'+[0,1,2].map(i=>'<path '+(i<n?'class="on" ':'')+'d="M'+(1+i*14)+' 7c3-6 6-6 10 0"/>').join('')+'</svg>';
const now=new Date(),today=(now.getDay()+6)%7;let sel=today;
const days=$('#days'),list=$('#list');
days.innerHTML=DAYS.map((d,i)=>`<button type="button" class="day${i===today?' today':''}" data-d="${i}" aria-pressed="${i===sel}" aria-label="${LONG[i]}, ${WEEK[i].length} classes">${d}<em aria-hidden="true">${WEEK[i].map(()=>'<i></i>').join('')}</em></button>`).join('');
function draw(){
  list.innerHTML=WEEK[sel].map(([t,id],s)=>{const c=CL[id],x=taken(sel,s),left=12-x.length;
    return `<article class="row" style="--i:${s}"><div class="t">${t}</div><div class="nm"><h3>${c[0]}</h3><p class="meta">${c[2]} min · with ${c[1]}</p></div><div class="ft"><span class="lv">${lvl(c[3])}${['Easy','Steady','Strong'][c[3]-1]}</span><div class="tail"><span class="mats"><span class="bars" aria-hidden="true">${Array.from({length:12},(_,n)=>`<i class="${x.includes(n+1)?'x':''}" style="--b:${n}"></i>`).join('')}</span><span class="${left<4?'low':''}">${left} left</span></span><button class="btn solid" type="button" data-s="${s}">Pick a mat</button></div></div></article>`}).join('');
}
days.addEventListener('click',e=>{const b=e.target.closest('.day');if(!b)return;sel=+b.dataset.d;$$('.day',days).forEach(x=>x.setAttribute('aria-pressed',x===b));draw()});
draw();

// next class, under the buttons
{const hm=now.getHours()*60+now.getMinutes();let out='';
 for(let k=0;k<7&&!out;k++){const d=(today+k)%7;for(let s=0;s<WEEK[d].length;s++){const [t,id]=WEEK[d][s],m=+t.slice(0,2)*60+ +t.slice(3);if(k>0||m>hm){out=`<b>Next class · ${k===0?'today':k===1?'tomorrow':LONG[d]} ${t}</b>${CL[id][0]} · ${12-taken(d,s).length} mats left`;break}}}
 if(out&&!navigator.webdriver){const n=$('#next');n.innerHTML='<span class="pulse" aria-hidden="true"></span><span>'+out+'</span>';n.hidden=false}}

// booking sheet
const dlg=$('#book'),body=$('#bk-body');let pick=0,ctx;
const close=()=>{dlg.close()};
dlg.addEventListener('close',()=>{de.classList.remove('lock');if(ctx)ctx.focus()});
dlg.addEventListener('click',e=>{if(e.target===dlg)close()});
$('#bk-x').addEventListener('click',close);
list.addEventListener('click',e=>{const b=e.target.closest('[data-s]');if(!b)return;ctx=b;openSheet(sel,+b.dataset.s)});
function openSheet(d,s){
  const [t,id]=WEEK[d][s],c=CL[id],x=taken(d,s);pick=0;
  body.innerHTML=`<p class="eyebrow">Pick your mat</p><h3 id="bk-t">${c[0]}</h3><p class="sub">${LONG[d]} · ${t} · ${c[2]} min · with ${c[1]}</p>
  <div class="room-map"><div class="fr">Front of the room</div><div class="wn" aria-hidden="true">Windows</div><div class="mgrid" role="group" aria-label="Mats">${Array.from({length:12},(_,n)=>`<button type="button" class="mat" data-n="${n+1}" aria-pressed="false" ${x.includes(n+1)?'disabled aria-label="Mat '+(n+1)+', taken"':'aria-label="Mat '+(n+1)+'"'}>${n+1}</button>`).join('')}</div></div>
  <p class="legend"><span><i></i>Free</span><span><i class="t"></i>Taken</span><span><i class="m"></i>Yours</span></p>
  <button class="btn solid wide" id="bk-go" type="button" disabled>Choose a mat</button><p class="fine2">Example page: nothing is booked or saved.</p>`;
  de.classList.add('lock');dlg.showModal();
  const go=$('#bk-go');
  $('.mgrid',body).addEventListener('click',e=>{const m=e.target.closest('.mat');if(!m||m.disabled)return;pick=+m.dataset.n;$$('.mat',body).forEach(k=>k.setAttribute('aria-pressed',k===m));go.disabled=false;go.textContent='Reserve mat '+pick});
  go.addEventListener('click',()=>{
    body.innerHTML=`<div class="done"><svg viewBox="0 0 88 88" aria-hidden="true"><circle cx="44" cy="44" r="40"/><path d="M27 45l12 12 22-24"/></svg><p class="eyebrow" style="margin-bottom:10px">You’re on the mat</p><h3 id="bk-t">See you ${LONG[d]}.</h3><p>Mat ${pick}, ${c[0]} at ${t}. Doors open at ${(m=>String(Math.floor(m/60)).padStart(2,'0')+':'+String(m%60).padStart(2,'0'))(+t.slice(0,2)*60+ +t.slice(3)-15)}. Bring yourself; we have the rest.</p><button class="btn solid wide" type="button" id="bk-ok">Lovely</button><p class="fine2">Example page: nothing is booked or saved.</p></div>`;
    $('#bk-ok').addEventListener('click',close);$('#bk-ok').focus();
  });
}

// prices
const PR=[[190,140],[1600,1200],[890,690]],seg=$('#seg'),fmt=n=>String(n).replace(/\B(?=(\d{3})+$)/g,'\u00a0');
const spans=$$('[data-p]'),cur=PR.map(p=>p[0]);
seg.addEventListener('click',e=>{const b=e.target.closest('button');if(!b)return;const v=+b.dataset.v;if(seg.dataset.v==v)return;seg.dataset.v=v;$$('button',seg).forEach(k=>k.setAttribute('aria-pressed',k===b));
  spans.forEach((s,i)=>{const from=cur[i],to=PR[i][v],t0=performance.now(),D=RM.matches?1:700;cur[i]=to;
    const step=t=>{const k=Math.min(1,(t-t0)/D),e=1-Math.pow(1-k,4);s.textContent=fmt(Math.round(from+(to-from)*e));if(k<1)requestAnimationFrame(step)};requestAnimationFrame(step)})});
})();
</script>
</body>
</html>