<!DOCTYPE html><html><head><meta charset="utf-8" /><meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'unsafe-inline'; img-src https: data:; font-src https: data:; media-src https: data:; connect-src https://cdn.jsdelivr.net; frame-src 'none'" /><script>
(function(){
var nav=navigator;
var reduced=matchMedia("(prefers-reduced-motion: reduce)").matches;
var conn=nav.connection||{};
var saveData=!!conn.saveData;
var slow=/(^|[^a-z])(2g|slow-2g)$/.test(conn.effectiveType||"");
var mem=nav.deviceMemory||8;
var cores=nav.hardwareConcurrency||8;
var webgl2=false;
try{var c=document.createElement("canvas");webgl2=!!(c.getContext("webgl2")||c.getContext("webgl"));}catch(e){}
var tier=1;
if(reduced||saveData||slow)tier=4;
else if(mem<=2||cores<=2||!webgl2)tier=3;
else if(mem<=4||cores<=4||conn.effectiveType==="3g")tier=2;
var q=new URLSearchParams(location.search||"");
var forced=parseInt(document.documentElement.getAttribute("data-te-tier")||q.get("tier")||"",10);
if(forced>=1&&forced<=4)tier=forced;
var listeners={tier:[],scroll:[],visible:[],copy:[]};
var copy=null;
document.documentElement.style.setProperty("--te-band","0.5");
var visible=true,hidden=document.hidden;
var loops=[];var loopHandle=0;var last=0;
var nativeRAF=window.requestAnimationFrame.bind(window);
var pending=[];
function active(){return visible&&!hidden&&tier<4}
function pump(now){
loopHandle=0;
if(!active())return;
var dt=last?Math.min(64,now-last):16;last=now;
for(var i=0;i<loops.length;i++){try{loops[i](dt,now)}catch(e){if(!loops[i].te_err){loops[i].te_err=1;console.error("TE.loop",e)}}}
var queued=pending;pending=[];
for(var j=0;j<queued.length;j++){try{queued[j](now)}catch(e){if(!queued[j].te_err){queued[j].te_err=1;console.error("TE.raf",e)}}}
// A callback above may already have scheduled the next frame through the
// wrapped requestAnimationFrame; never queue pump twice for one frame.
if(!loopHandle&&(loops.length||pending.length))loopHandle=nativeRAF(pump);
}
function schedule(){if(!loopHandle&&active())loopHandle=nativeRAF(pump)}
window.requestAnimationFrame=function(fn){pending.push(fn);schedule();return pending.length};
window.cancelAnimationFrame=function(){};
var videoState=new Map();
function pauseAll(){
document.querySelectorAll("video").forEach(function(v){videoState.set(v,!v.paused);if(!v.paused)v.pause()});
}
function resumeAll(){
document.querySelectorAll("video").forEach(function(v){if(videoState.get(v)){var p=v.play();if(p&&p.catch)p.catch(function(){})}});
last=0;schedule();
}
function setVisible(v){
if(v===visible)return;visible=v;
if(v)resumeAll();else pauseAll();
listeners.visible.forEach(function(f){f(v)});
}
document.addEventListener("visibilitychange",function(){hidden=document.hidden;if(hidden)pauseAll();else resumeAll()});
var frames=0,slowSince=0,checked=0;
loops.push(function(dt,now){
frames++;
if(now-checked<1000)return;
var fps=frames*1000/(now-checked);frames=0;checked=now;
if(fps<40){if(!slowSince)slowSince=now;else if(now-slowSince>2000){degrade();slowSince=0}}
else slowSince=0;
});
function degrade(){
if(tier>=3)return;tier++;
document.documentElement.setAttribute("data-te-tier",String(tier));
listeners.tier.forEach(function(f){f(tier)});
}
var pointer={x:0.5,y:0.5,vx:0,vy:0,down:false,fine:matchMedia("(pointer:fine)").matches,active:false};
var px=0,py=0,pt=0;
function onMove(e){
var w=innerWidth||1,h=innerHeight||1,now=performance.now();
var x=e.clientX/w,y=e.clientY/h;
if(pt){var s=Math.max(1,now-pt);pointer.vx=(x-px)*1000/s;pointer.vy=(y-py)*1000/s}
px=x;py=y;pt=now;pointer.x=x;pointer.y=y;pointer.active=true;
}
addEventListener("pointermove",onMove,{passive:true});
addEventListener("pointerdown",function(e){pointer.down=true;onMove(e)},{passive:true});
addEventListener("pointerup",function(){pointer.down=false},{passive:true});
addEventListener("pointerleave",function(){pointer.active=false;pointer.vx=0;pointer.vy=0});
addEventListener("message",function(e){
var d=e.data;if(!d||typeof d!=="object")return;
if(d.type==="te:scroll"&&typeof d.t==="number")listeners.scroll.forEach(function(f){f(d.t)});
if(d.type==="te:visible")setVisible(!!d.visible);
if(d.type==="te:copy"&&typeof d.y0==="number"){copy={x0:d.x0,y0:d.y0,x1:d.x1,y1:d.y1};document.documentElement.style.setProperty("--te-band",String(Math.round(d.y0*1000)/1000));listeners.copy.forEach(function(f){f(copy)})}
if(d.type==="te:tier"&&d.tier>=1&&d.tier<=4){tier=d.tier;document.documentElement.setAttribute("data-te-tier",String(tier));listeners.tier.forEach(function(f){f(tier)})}
});
document.documentElement.setAttribute("data-te-tier",String(tier));
window.TE={
get tier(){return tier},
get visible(){return visible&&!hidden},
get reduced(){return reduced},
get dpr(){return tier===1?Math.min(devicePixelRatio||1,2):tier===2?Math.min(devicePixelRatio||1,1.5):1},
caps:{memory:mem,cores:cores,webgl:webgl2,saveData:saveData,effectiveType:conn.effectiveType||"",reduced:reduced},
pointer:pointer,
loop:function(fn){loops.push(fn);schedule();return function(){var i=loops.indexOf(fn);if(i>=0)loops.splice(i,1)}},
onScroll:function(fn){listeners.scroll.push(fn)},
onTier:function(fn){listeners.tier.push(fn)},
onVisible:function(fn){listeners.visible.push(fn)},
onCopy:function(fn){listeners.copy.push(fn);if(copy)fn(copy)},
get copy(){return copy},
get band(){return copy?copy.y0:0.5},
degrade:degrade,
video:function(el,src){
if(tier>=4)return false;
var small=tier>=2||Math.min(innerWidth,innerHeight)<700;
el.src=small?src.replace(/\.mp4$/,"-sm.mp4"):src;
if(tier>=3)el.preload="metadata";
return true;
},
rendition:function(){return tier>=2||Math.min(innerWidth,innerHeight)<700?"-sm":""},
debug:function(){return {handle:loopHandle,loops:loops.length,pending:pending.length,visible:visible,hidden:hidden,tier:tier,active:active()}}
};
})();
</script><style>html,body{margin:0;padding:0;overflow:hidden;background:transparent}</style><script src="https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.min.js"></script></head><body><style>
html,body{margin:0;height:100%;background:#0f0d0a;overflow:hidden;color:#f4efe6;font-family:'Jost',system-ui,-apple-system,sans-serif}
#g{position:absolute;inset:0;width:100%;height:100%;display:none}
#col{position:absolute;left:50%;top:20px;transform:translateX(-50%);transform-origin:top center;width:min(92vw,580px)}
#rows{position:relative}
#now{position:absolute;left:-10px;right:-10px;height:1px;background:#c9a24b;opacity:0;transition:opacity .4s}
#now span{position:absolute;left:-14px;top:0;transform:translate(-100%,-50%);white-space:nowrap;font-family:ui-monospace,Menlo,monospace;font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:#c9a24b}
#now::after{content:"";position:absolute;left:-10px;top:-2px;width:5px;height:5px;border-radius:50%;background:#c9a24b}
@media (max-width:860px){#now span{left:auto;right:0;top:-14px;transform:none;background:#0f0d0a;padding:0 5px}}
#head{display:flex;justify-content:space-between;font-family:ui-monospace,Menlo,monospace;font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:rgba(201,162,75,.72);padding-bottom:10px}
.r{display:grid;grid-template-columns:58px 1fr auto;gap:14px;align-items:baseline;padding:8px 10px 8px 0;border-top:1px solid rgba(201,162,75,.16);opacity:0;transform:translateY(6px);animation:in .5s cubic-bezier(.2,.8,.2,1) forwards}
@keyframes in{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.r{animation:none;opacity:1;transform:none}}
.t{font-family:ui-monospace,Menlo,monospace;font-size:11px;letter-spacing:.16em;color:rgba(244,239,230,.55)}
.n{font-size:14px;letter-spacing:.01em}
.w{font-family:ui-monospace,Menlo,monospace;font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:rgba(244,239,230,.38)}
.r.b{background:linear-gradient(90deg,rgba(201,162,75,.14),rgba(201,162,75,0) 72%)}
.r.b .n{color:#f4efe6}
.r.f .n{font-family:ui-monospace,Menlo,monospace;font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:#c9a24b}
.r.p{opacity:.3}
.r.p .n{color:rgba(244,239,230,.6)}
.r.x{box-shadow:inset 2px 0 0 #c9a24b}
.r.x .w{color:#c9a24b}
#foot{display:flex;justify-content:space-between;border-top:1px solid rgba(201,162,75,.3);margin-top:2px;padding-top:10px;font-family:ui-monospace,Menlo,monospace;font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:rgba(201,162,75,.72)}
@media (max-width:640px){.r{grid-template-columns:48px 1fr;gap:10px}.r .w{display:none}.n{font-size:13px}}
</style>
<canvas id=g></canvas>
<div id=col>
<div id=head><span>Agenda hari ini</span><span id=date></span></div>
<div id=rows><div id=now><span></span></div></div>
<div id=foot><span id=left></span><span>Buka sampai 20.00</span></div>
</div>
<script>
window.TE3=function(o){
var TE=window.TE;
if(!TE||!TE.caps||!TE.caps.webgl)return false;
if(TE.tier>(o.tier||2))return false;
if(typeof THREE==="undefined")return false;
var gc=document.getElementById(o.canvas||"g");
if(!gc)return false;
var ren;
try{ren=new THREE.WebGLRenderer({canvas:gc,antialias:o.aa!==false,alpha:!!o.alpha})}catch(e){return false}
if(THREE.SRGBColorSpace)ren.outputColorSpace=THREE.SRGBColorSpace;
if(o.tone){ren.toneMapping=THREE.ACESFilmicToneMapping;ren.toneMappingExposure=o.tone}
if(!o.alpha)ren.setClearColor(o.clear===undefined?0x000000:o.clear,1);
var scene=new THREE.Scene();
var cam=new THREE.PerspectiveCamera(o.fov||32,1,0.05,160);
cam.position.set(o.camX||0,o.camY||0,o.dist||4);
cam.lookAt(o.lookX||0,o.lookY||0,0);
var root=new THREE.Group();scene.add(root);
var k={THREE:THREE,ren:ren,scene:scene,cam:cam,root:root,band:0.5,w:0,h:0,
narrow:false,px:0,py:0,pw:0,t:0,visW:0,visH:0,tier:TE.tier,dpr:1,time:0};
// A scene that throws while it is being built must not take the stage down
// with it: the 2D canvas is still there and still correct, so we hand back
// false and let it boot. Same for the frame loop, which freezes on the last
// good frame rather than throwing sixty times a second.
try{if(o.build&&o.build(k)===false)return false}catch(e){return false}
var dead=o.replace===null?null:document.getElementById(o.replace||"c");
if(dead&&dead.parentNode)dead.parentNode.removeChild(dead);
gc.style.display="block";
function layout(){
k.w=innerWidth;k.h=innerHeight;k.narrow=k.w<(o.narrow||640);
if(o.host){var hb=o.host.getBoundingClientRect();if(hb.width>1&&hb.height>1){k.w=hb.width;k.h=hb.height}}
// A hero shares its frame with the headline, so the subject is fitted into
// the band the parent reports. An embed owns its whole box, so it passes
// band:1 and gets all of it.
k.band=o.band!==undefined?o.band:Math.max(TE.band||0.5,o.minBand||0.24);
k.dpr=Math.min(TE.dpr,o.maxDpr||1.75);
ren.setPixelRatio(k.dpr);ren.setSize(k.w,k.h,false);
cam.aspect=k.w/Math.max(1,k.h);cam.updateProjectionMatrix();
k.visH=2*Math.tan(cam.fov*Math.PI/360)*cam.position.z;
k.visW=k.visH*cam.aspect;
if(o.fit!==false){
var size=o.size||1;
var s=Math.min(k.band*k.visH*(o.fitH||0.74)/size,k.visW*(o.fitW||0.84)/size);
root.scale.setScalar(Math.max(o.minScale||0.12,s));
root.position.y=(0.5-k.band*0.5)*k.visH+(o.lift||0)*root.scale.x;
}
try{if(o.layout)o.layout(k)}catch(e){}
}
layout();addEventListener("resize",layout);
if(TE.onCopy)TE.onCopy(layout);
var frozen=false;
if(TE.onTier)TE.onTier(function(n){k.tier=n;if(n>=3)frozen=true});
addEventListener("pointermove",function(e){
k.px=(e.clientX/Math.max(1,innerWidth))*2-1;
k.py=-((e.clientY/Math.max(1,innerHeight))*2-1);
k.pw=1;
try{if(o.onPointer)o.onPointer(k)}catch(e){}
},{passive:true});
if(o.onScroll){
var os=function(v){k.t=Math.min(1,Math.max(0,v));try{o.onScroll(k)}catch(e){}};
if(TE.onScroll)TE.onScroll(os);
else addEventListener("message",function(e){if(e.data&&e.data.type==="te:scroll")os(e.data.t)});
}
TE.loop(function(dt){
if(frozen)return;
k.time+=dt;
k.pw*=Math.pow(0.988,dt/16);
try{
if(o.frame)o.frame(dt,k);
ren.render(scene,cam);
}catch(e){frozen=true}
});
return true;
};
</script>
<script>
(function(){
var TE=window.TE,col=document.getElementById("col"),rowsEl=document.getElementById("rows"),dateEl=document.getElementById("date"),leftEl=document.getElementById("left"),nowEl=document.getElementById("now");
var WORK=[["Creambath rempah","Mbak Sari"],["Facial kombinasi","Mbak Ratih"],["Potong dan blow","Mbak Dewi"],["Pijat tubuh 60 menit","Mbak Sari"],["Facial dasar","Mbak Ratih"],["Paket pengantin, sesi 2","Mbak Dewi"],["Potong dan blow","Mbak Ratih"],["Creambath rempah","Mbak Dewi"]];
var HARI=["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"];
var BULAN=["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"];
var now=new Date(),seed=now.getDate()*7+now.getMonth()*13;
function rnd(){seed=(seed*9301+49297)%233280;return seed/233280}
var HOURS=[9,10,11,12,13,14,15,16,17,18,19];
var plan=HOURS.map(function(h,i){return rnd()<0.62?WORK[i%WORK.length]:null});
var rows=[];
function pad(n){return (n<10?"0":"")+n}
HOURS.forEach(function(h,i){
var r=document.createElement("div");r.className="r";r.style.animationDelay=(i*0.045)+"s";
var job=plan[i];
r.innerHTML="<span class=t>"+pad(h)+".00</span><span class=n>"+(job?job[0]:"Kosong")+"</span><span class=w>"+(job?job[1]:"")+"</span>";
rowsEl.appendChild(r);rows.push({el:r,h:h,job:job});
});
// what the agenda says at this minute: which hours have gone, which are
// taken and by whom, which are still free, and which one is the soonest.
// Factored out of paint() so the three.js column can stand on exactly the
// same answer without a row of divs to read it off.
function agenda(){
var d=new Date(),hh=d.getHours()+d.getMinutes()/60,first=-1,free=0,out=[],i;
for(i=0;i<rows.length;i++){
var r=rows[i],past=r.h+1<=hh,open=!r.job&&!past;
if(open){free++;if(first<0)first=i}
out.push({h:r.h,job:r.job,past:past,open:open});
}
for(i=0;i<out.length;i++){
out[i].first=out[i].open&&first===i;
out[i].note=out[i].job?out[i].job[1]:(out[i].first?"Paling cepat":(out[i].past?"Lewat":"Bisa diambil"));
}
return {r:out,free:free,hh:hh,d:d,
date:HARI[d.getDay()]+", "+d.getDate()+" "+BULAN[d.getMonth()],
now:"Sekarang "+pad(d.getHours())+"."+pad(d.getMinutes()),
left:free>0?"Sisa "+free+" jam kosong":"Hari ini penuh, besok mulai 09.00"};
}
function paint(){
var st=agenda(),d=st.d,hh=st.hh;
if(paint.t)clearTimeout(paint.t);paint.t=setTimeout(function(){paint()},60000-d.getSeconds()*1000);
for(var i=0;i<rows.length;i++){
var r=rows[i],s2=st.r[i];
r.el.className="r"+(r.job?" b":" f")+(s2.past?" p":"");
if(s2.first)r.el.className+=" x";
if(!r.job)r.el.lastChild.textContent=s2.note;
}
var top=null;
for(var j=0;j<rows.length;j++){if(hh>=rows[j].h&&hh<rows[j].h+1){var rc=rows[j].el;top=rc.offsetTop+rc.offsetHeight*(hh-rows[j].h)}}
if(top===null&&hh<HOURS[0])top=0;
if(top===null){nowEl.style.opacity="0"}
else{nowEl.style.top=Math.round(top)+"px";nowEl.style.opacity="1";nowEl.firstChild.textContent=st.now}
dateEl.textContent=st.date;
leftEl.textContent=st.left;
}
function place(){
var band=TE&&TE.band||0.5,H=innerHeight,ch=col.offsetHeight||1,k=Math.min(1,(band*H-28)/ch);
col.style.transform="translateX(-50%) scale("+k.toFixed(3)+")";
col.style.top=Math.max(10,(band*H-ch*k)/2)+"px";
}
// Three.js, tier 1 and 2: today as a real column standing in space. Every
// hour from 09.00 to 19.00 is one rung. A booked hour is a solid block that
// comes forward out of the column and says its perawatan and its terapis;
// a free hour is an open kuningan frame you can take; an hour that has gone
// dims. The gold bar crossing the column is now, at the visitor's minute.
var PITCH=0.46,RW=6.4,RH=0.40;
function initGL(){
var cards=[],nowBar=null,nowLab=null,headLab=null,footLab=null,acc=9e9,lastKey="",nar=false;
return TE3({
tier:2,clear:0x0f0d0a,fov:32,dist:5.0,fit:false,maxDpr:1.4,replace:"col",
build:function(k){
var T=k.THREE,i;
function plate(w,h,pw,ph){
var cn=document.createElement("canvas");cn.width=pw;cn.height=ph;
var cx2=cn.getContext("2d");
if(!cx2)return null;
var tx=new T.CanvasTexture(cn);
if(T.SRGBColorSpace)tx.colorSpace=T.SRGBColorSpace;
var m=new T.Mesh(new T.PlaneGeometry(w,h),
new T.MeshBasicMaterial({map:tx,transparent:true}));
return {m:m,cx:cx2,tex:tx,w:pw,h:ph};
}
var solid=new T.MeshLambertMaterial({color:0x1d1811});
var gold=new T.MeshBasicMaterial({color:0xc9a24b,transparent:true,opacity:0.55});
var edge=new T.LineBasicMaterial({color:0xc9a24b,transparent:true,opacity:0.28});
var barH=new T.BoxGeometry(RW,0.028,0.05),barV=new T.BoxGeometry(0.028,RH,0.05);
var boxG=new T.BoxGeometry(RW,RH,0.34);
var top=(rows.length-1)*PITCH/2;
for(i=0;i<rows.length;i++){
var g=new T.Group();g.position.y=top-i*PITCH;k.root.add(g);
var blk=new T.Mesh(boxG,solid);blk.position.z=0.17;g.add(blk);
var eg=new T.LineSegments(new T.EdgesGeometry(boxG),edge);eg.position.z=0.17;g.add(eg);
var fr=new T.Group();g.add(fr);
var b1=new T.Mesh(barH,gold);b1.position.y=RH/2;fr.add(b1);
var b2=new T.Mesh(barH,gold);b2.position.y=-RH/2;fr.add(b2);
var b3=new T.Mesh(barV,gold);b3.position.x=-RW/2;fr.add(b3);
var b4=new T.Mesh(barV,gold);b4.position.x=RW/2;fr.add(b4);
var pl=plate(RW,RH,760,48);
if(!pl)return false;
g.add(pl.m);
cards.push({g:g,blk:blk,eg:eg,fr:fr,pl:pl,key:""});
}
headLab=plate(RW,0.30,760,36);footLab=plate(RW,0.30,760,36);
if(!headLab||!footLab)return false;
headLab.m.position.y=top+0.52;k.root.add(headLab.m);
footLab.m.position.y=-top-0.52;k.root.add(footLab.m);
var rule=new T.Mesh(new T.BoxGeometry(RW,0.016,0.04),
new T.MeshBasicMaterial({color:0xc9a24b,transparent:true,opacity:0.45}));
rule.position.y=-top-0.34;k.root.add(rule);
nowBar=new T.Mesh(new T.BoxGeometry(RW+0.5,0.022,0.66),
new T.MeshBasicMaterial({color:0xc9a24b}));
nowBar.position.z=0.2;k.root.add(nowBar);
nowLab=plate(2.4,0.26,600,54);
if(!nowLab)return false;
nowLab.m.position.x=-RW/2-1.62;k.root.add(nowLab.m);
k.scene.add(new T.AmbientLight(0xc9a24b,0.9));
var key2=new T.DirectionalLight(0xfff0d0,2.2);key2.position.set(-3,5,7);k.scene.add(key2);
k.root.rotation.y=0.30;
return true;
},
layout:function(k){
var span=(rows.length-1)*PITCH+RH+1.7;
var wide=RW*Math.cos(0.30)+(k.narrow?0.4:3.4);
var s=Math.min(k.band*k.visH*0.94/span,k.visW*(k.narrow?1.0:0.92)/wide);
k.root.scale.setScalar(s);
k.root.position.y=(0.5-k.band*0.5)*k.visH;
// a phone column has no room for the terapis column, exactly as the
// rows drop it in CSS, and the now label moves inside the column
if(nar!==k.narrow){nar=k.narrow;lastKey="";}
nowLab.m.position.x=nar?RW/2-1.25:-RW/2-1.62;nowLab.m.position.z=0.5;
acc=9e9;
},
frame:function(dt,k){
acc+=dt;
if(acc>4000){
acc=0;
var st=agenda(),i,key=st.now+"|"+st.left;
for(i=0;i<cards.length;i++)key+="|"+(st.r[i].past?1:0)+(st.r[i].first?1:0);
if(key!==lastKey){
lastKey=key;
for(i=0;i<cards.length;i++){
var c=cards[i],r=st.r[i],dim=r.past?0.32:1;
c.blk.visible=!!r.job;c.eg.visible=!!r.job;c.fr.visible=!r.job;
c.fr.children[0].material.opacity=r.first?0.9:0.55*dim;
var x=c.pl.cx,W2=c.pl.w,H2=c.pl.h;
x.clearRect(0,0,W2,H2);
x.globalAlpha=dim;
if(r.job){
var gd=x.createLinearGradient(0,0,W2*0.72,0);
gd.addColorStop(0,"rgba(201,162,75,.20)");gd.addColorStop(1,"rgba(201,162,75,0)");
x.fillStyle=gd;x.fillRect(0,0,W2,H2);
}
x.fillStyle="rgba(244,239,230,.55)";
x.font=(nar?"25px":"20px")+" ui-monospace,Menlo,monospace";
x.textAlign="left";x.fillText(pad(r.h)+".00",14,33);
if(r.job){
x.fillStyle="#f4efe6";x.font=(nar?"35px":"27px")+" 'Jost',system-ui,sans-serif";
x.fillText(r.job[0],nar?112:96,33);
}else{
x.fillStyle="#c9a24b";x.font=(nar?"25px":"20px")+" ui-monospace,Menlo,monospace";
x.fillText("K O S O N G",nar?112:96,33);
}
if(!nar){
x.fillStyle=r.first?"#c9a24b":"rgba(244,239,230,.42)";
x.font="17px ui-monospace,Menlo,monospace";
x.textAlign="right";x.fillText(r.note.toUpperCase(),W2-14,33);
}
x.globalAlpha=1;
c.pl.tex.needsUpdate=true;
c.pl.m.position.z=r.job?0.35:0.03;
}
var hx=headLab.cx;hx.clearRect(0,0,headLab.w,headLab.h);
hx.font=(nar?"28px":"23px")+" ui-monospace,Menlo,monospace";hx.fillStyle="rgba(201,162,75,.78)";
hx.textAlign="left";hx.fillText("AGENDA HARI INI",14,27);
hx.textAlign="right";hx.fillText(st.date.toUpperCase(),headLab.w-14,27);
headLab.tex.needsUpdate=true;
var fx=footLab.cx;fx.clearRect(0,0,footLab.w,footLab.h);
fx.font=(nar?"28px":"23px")+" ui-monospace,Menlo,monospace";fx.fillStyle="rgba(201,162,75,.78)";
fx.textAlign="left";fx.fillText(st.left.toUpperCase(),14,27);
fx.textAlign="right";fx.fillText("BUKA SAMPAI 20.00",footLab.w-14,27);
footLab.tex.needsUpdate=true;
var nx=nowLab.cx;nx.clearRect(0,0,nowLab.w,nowLab.h);
nx.font="34px ui-monospace,Menlo,monospace";nx.fillStyle="#c9a24b";
nx.textAlign="right";nx.fillText(st.now.toUpperCase(),nowLab.w-8,38);
nowLab.tex.needsUpdate=true;
// the gold bar sits where the clock is between the hours
var topY=(rows.length-1)*PITCH/2,on=true,y=0;
if(st.hh<HOURS[0])y=topY+RH/2;
else if(st.hh>=HOURS[HOURS.length-1]+1)on=false;
else y=topY-(st.hh-HOURS[0])*PITCH;
nowBar.visible=on;nowLab.m.visible=on;
if(on){nowBar.position.y=y;nowLab.m.position.y=y+(nar?0.27:0)}
}
}
k.root.rotation.y=0.30+k.px*0.09;
k.root.rotation.x=-k.py*0.05;
}
});
}
if(!initGL()){
paint();place();setTimeout(place,60);addEventListener("resize",place);
if(TE&&TE.onCopy)TE.onCopy(place);
if(TE&&TE.onVisible)TE.onVisible(function(v){if(v)paint()});
}
})();
</script></body></html>
Salon dan perawatan, Kemang, Jakarta Selatan, sejak 2014
Jam kosong hari ini, bukan janji kosong
Agenda di atas adalah agenda kami hari ini, dihitung dari jam di teleponmu. Yang terisi tertulis perawatan dan terapisnya, yang kosong bisa kamu ambil lewat WhatsApp dalam satu menit.
Satu terapis untuk satu tamuProduk dibuka di depanmuGanti jadwal sampai 3 jam sebelum
2014 buka di Kemang, di ruko yang sama6 terapis tetap, bukan terapis lepas10 menit tunggu paling lama, kalau lebih perawatan berikutnya gratis4,9 dari 812 ulasan Google
Perawatan, durasi, dan harganya
Potong dan blow
Konsultasi bentuk wajah dulu, potong, keramas dengan pijat kepala sepuluh menit, blow rapi.
Rp150.00060 menit
Creambath rempah
Kemiri dan urang aring, lalu pijat leher dan bahu. Untuk rambut yang sering diikat dan kering di ujung.
Rp185.00075 menit
Facial dasar
Pembersihan, ekstraksi lembut, masker sesuai kondisi kulit hari itu. Tanpa alat yang tidak kamu butuhkan.
Rp275.00090 menit
Facial kombinasiPaling sering diambil
Facial dasar ditambah serum vitamin C dan pijat wajah. Isi produknya kami sebut sebelum mulai.
Rp420.000120 menit
Pijat tubuh
Minyak kelapa atau lavender. Tekanan diatur di sepuluh menit pertama, bukan ditebak.
Rp220.00060 menit
Paket pengantin
Tiga sesi sebelum hari H dan satu sesi pagi hari H, di salon atau di rumahmu.
Agenda di beranda ini dihitung dari jam sekarang. Sebut jamnya lewat WhatsApp dan kami kunci lima menit sambil kamu memastikan.
Konsultasi lima menit
Sebelum mulai, terapis melihat kulit dan rambutmu lalu menyebut produk yang akan dipakai. Kalau ada yang tidak cocok, kami ganti tanpa biaya.
Pulang dengan catatan
Kamu pulang dengan catatan: apa yang dipakai hari ini, kapan sebaiknya kembali, dan apa yang tidak perlu kamu beli.
Produk yang kami sebut, dibuka di depanmu
Saya tahu jam datang, jam selesai, dan berapa yang saya bayar sebelum masuk. Rina, tamu sejak 2019Terapisnya menyebut isi produknya satu per satu. Belum pernah saya dapat di tempat lain. Dina, KemangPernah mereka telat sebelas menit, dan facial saya berikutnya benar-benar gratis. Aisyah, CipetePaket pengantin saya diurus empat sesi, tidak ada tambahan biaya di hari H. Melati, menikah 2025Anak saya ikut potong di sini karena tidak ada musik keras dan tidak diburu. Tari, PejatenSaya tahu jam datang, jam selesai, dan berapa yang saya bayar sebelum masuk. Rina, tamu sejak 2019Terapisnya menyebut isi produknya satu per satu. Belum pernah saya dapat di tempat lain. Dina, KemangPernah mereka telat sebelas menit, dan facial saya berikutnya benar-benar gratis. Aisyah, CipetePaket pengantin saya diurus empat sesi, tidak ada tambahan biaya di hari H. Melati, menikah 2025Anak saya ikut potong di sini karena tidak ada musik keras dan tidak diburu. Tari, Pejaten
Yang sering ditanyakan
Kalau saya datang tanpa janji?
Boleh, dan agenda di beranda ini menunjukkan jam yang masih kosong hari ini. Kalau semua terisi, kami sebutkan jam kosong paling cepat besok.
Apakah harga di daftar sudah final?
Sudah. Yang tertulis termasuk produk dan pajak. Kalau terapis menyarankan tambahan, harganya disebut dulu dan kamu boleh menolak.
Produk apa yang dipakai?
Kemasannya dibuka di depanmu dan namanya disebut sebelum dipakai. Untuk kulit sensitif kami punya rangkaian tanpa pewangi.
Bisa ganti jadwal?
Bisa sampai tiga jam sebelum, tanpa biaya. Kurang dari itu kami minta setengah biaya karena jam terapisnya sudah terkunci.
Ada perawatan untuk pria?
Ada, dan tidak dibedakan harganya. Potong, facial, dan pijat tubuh sama daftarnya.