/* ── The "front desk" look, chosen by the owner on 2026-09-12: paper, ivy and
   brass, a striped awning, hard offset shadows, room keys on a rail. One set
   of tokens; the demo script reads four of them inline (ink-2, ink-3, line,
   warn), so those names are part of its contract with this sheet. ── */
:root{
  --paper:#F2F0E6; --card:#FFFDF6; --card-2:#F7F5EC; --bubble:#F3EFDF;
  --ivy:#1E4636; --ivy-2:#2B5C47;
  --ink:#17241D; --ink-2:#4B5A52; --ink-3:#68756D;
  --line:#D6DACB;
  --brass:#D6A23F; --brass-dk:#A87C22;
  --coral:#E07A5C; --coral-ink:#A9472C;
  --butter:#F4E3A6; --sage:#D6E4D3; --blush:#FBE3DA;
  --ok:#3E8C5E; --warn:#A87C22; --danger:#C4583B;
  --fresh:#D9483B;
  --display:'Bricolage Grotesque','Arial Black',system-ui,sans-serif;
  --body:'Figtree',system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:'DM Mono',ui-monospace,'Courier New',monospace;
  --out:cubic-bezier(.2,.8,.2,1);
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--paper);color:var(--ink);font-family:var(--body);line-height:1.5;
  -webkit-font-smoothing:antialiased}
a{color:inherit}
img{max-width:100%}
svg{flex:none}
.wrap{max-width:1280px;margin:0 auto;padding:0 40px}
.d{font-family:var(--display);font-weight:800;letter-spacing:-.04em}
.m{font-family:var(--mono)}
/* A blank the owner still has to fill: visible on purpose, so it is never
   mistaken for finished copy. */
.fill{color:var(--coral-ink);border-bottom:2px dashed var(--coral)}
:where(a,button,input,summary):focus-visible{outline:2px solid var(--coral);outline-offset:2px}

/* ---------- awning + header ---------- */
.awning{display:block;width:100%;height:58px}
.site-hd{position:sticky;top:0;z-index:60;background:rgba(242,240,230,.94);
  backdrop-filter:blur(10px);border-bottom:1.5px solid var(--line)}
.site-hd .wrap{display:flex;align-items:center;gap:28px;height:70px}
.brand{display:flex;align-items:center;gap:10px;font-family:var(--display);font-weight:800;
  font-size:23px;letter-spacing:-.02em;text-decoration:none}
.brand .dot{width:12px;height:12px;border-radius:50%;background:var(--coral);box-shadow:0 0 0 3px var(--butter)}
.site-nav{margin-left:auto;display:flex;align-items:center;gap:26px;font-size:15px;font-weight:500;color:var(--ink-2)}
.site-nav a{text-decoration:none}
.site-nav a:hover{color:var(--ink)}
.menu-btn{display:none;width:44px;height:44px;border:1.5px solid var(--ink);border-radius:13px;
  background:var(--card);cursor:pointer;place-items:center;padding:0}
.menu-btn svg{width:20px;height:20px}

/* ---------- buttons ---------- */
.btn,.cta{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:0;border-radius:16px;
  padding:16px 30px;font:inherit;font-size:16px;font-weight:700;text-decoration:none;cursor:pointer;
  background:var(--ivy);color:var(--card);box-shadow:0 5px 0 var(--ink);transition:transform .12s,box-shadow .12s}
.btn:hover,.cta:hover{transform:translateY(2px);box-shadow:0 3px 0 var(--ink)}
.btn:active,.cta:active{transform:translateY(5px);box-shadow:0 0 0 var(--ink)}
.btn.sm,.cta.sm{padding:11px 20px;font-size:15px;border-radius:14px;box-shadow:0 4px 0 var(--ink)}
.btn.butter{background:var(--butter);color:var(--ink)}
.link-arrow{display:inline-flex;align-items:center;gap:8px;font-weight:600;font-size:16px;text-decoration:none}
.link-arrow svg{width:18px;height:18px}

/* ---------- sections ---------- */
.sec{padding-top:124px;scroll-margin-top:84px}
.eyebrow{font-family:var(--mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--coral-ink)}
h2{font-family:var(--display);font-weight:800;letter-spacing:-.04em;font-size:clamp(34px,4vw,56px);
  line-height:1;margin:12px 0 0;text-wrap:balance}
.lede{font-size:17px;line-height:1.6;color:var(--ink-2);margin:14px 0 0;max-width:660px}

/* ---------- hero ---------- */
/* Clipped sideways: the rack slides in from the right, and a transformed box
   counts toward the page's width while it moves — enough for a phone to load
   the page zoomed out and stay that way. `clip`, not `hidden`, where the
   browser has it: it cuts without making the section a scroller. */
.hero{padding-top:62px;overflow-x:hidden;overflow-x:clip}
.hero .wrap{display:grid;grid-template-columns:minmax(0,1fr) 540px;gap:60px;align-items:center}
.chip{display:inline-flex;align-items:center;background:var(--sage);color:var(--ivy);border-radius:999px;
  padding:6px 13px;font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase}
h1{font-family:var(--display);font-weight:800;letter-spacing:-.045em;font-size:clamp(46px,6.2vw,90px);
  line-height:.94;margin:24px 0 0}
.hl{position:relative;display:inline-block;isolation:isolate;color:var(--ivy)}
.hl::before{content:"";position:absolute;left:-10px;right:-14px;top:12%;bottom:2%;background:var(--butter);
  border-radius:14px;transform:rotate(-2deg);z-index:-1}
.hero .lede{font-size:20px;line-height:1.55;max-width:600px;margin-top:28px}
.hero-ctas{display:flex;align-items:center;gap:24px;margin-top:34px;flex-wrap:wrap}
.live-note{display:flex;align-items:center;gap:10px;margin-top:36px;font-size:14px;color:var(--ink-2)}
.live-note i{width:8px;height:8px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 4px rgba(62,140,94,.16);flex:none}

/* The rack behind reception: one key tag per channel the agent answers on. */
.hero-art{position:relative;height:560px}
.rack{position:absolute;right:0;top:0;width:500px;height:450px;border-radius:30px;overflow:hidden;
  background-color:var(--ivy);box-shadow:10px 10px 0 var(--ink);
  background-image:radial-gradient(circle at 14px 14px,rgba(255,253,246,.06) 2px,transparent 2.5px);
  background-size:28px 28px}
.rack-hd{position:absolute;left:32px;right:32px;top:26px;display:flex;justify-content:space-between;
  font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--brass)}
.rail{position:absolute;left:28px;right:28px;top:76px;height:6px;border-radius:3px;background:var(--brass);
  box-shadow:0 2px 0 rgba(0,0,0,.25)}
.tags{position:absolute;left:24px;right:22px;top:74px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:18px}
.keytag{transform:rotate(var(--tilt,0deg));transform-origin:50% 4px}
.keytag .hook{display:block;width:10px;height:10px;margin:0 auto;border-radius:50%;background:#F4D38A;border:2px solid var(--brass-dk)}
.keytag .cord{display:block;width:2px;height:var(--cord,36px);margin:0 auto;background:var(--brass)}
.kt{position:relative;background:var(--tag,var(--butter));border-radius:14px 14px 18px 18px;padding:30px 9px 14px;
  box-shadow:0 18px 26px -14px rgba(0,0,0,.55)}
.kt::before{content:"";position:absolute;left:50%;top:9px;width:14px;height:14px;margin-left:-7px;border-radius:50%;
  background:var(--ivy);border:3px solid var(--brass)}
.kt svg{display:block;width:22px;height:22px;fill:none;stroke:var(--ivy);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.kt b{display:block;font-family:var(--display);font-weight:800;font-size:16px;letter-spacing:-.035em;line-height:1.05;margin-top:6px;white-space:nowrap}
.kt small{display:flex;align-items:center;gap:5px;margin-top:8px;font-family:var(--mono);font-size:10px;
  letter-spacing:.06em;color:var(--ok);text-transform:uppercase}
.kt small::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ok)}
.rack-note{position:absolute;right:30px;bottom:28px;width:200px;margin:0;font-size:14px;line-height:1.45;color:var(--sage)}

/* An example conversation, hung over the rack's corner. Illustration, not the
   demo: the real one is further down. */
.hero-chat{position:absolute;left:-36px;top:296px;width:330px;background:var(--card);border:2px solid var(--ink);
  border-radius:22px;box-shadow:8px 8px 0 var(--brass);overflow:hidden}
.hc-hd{display:flex;align-items:center;gap:9px;padding:10px 14px;border-bottom:1.5px solid var(--line)}
.hc-hd .av{width:28px;height:28px;border-radius:9px;background:var(--ivy);color:var(--butter);display:grid;place-items:center}
.hc-hd .av svg{width:16px;height:16px}
.hc-hd b{font-size:14px}
.hc-hd span{margin-left:auto;font-family:var(--mono);font-size:11px;color:var(--ink-3)}
.hc-body{padding:13px 14px 14px;display:flex;flex-direction:column;gap:9px}
.hc-me{align-self:flex-end;background:var(--ivy);color:var(--card);padding:9px 13px;border-radius:16px 16px 5px 16px;font-size:14px;line-height:1.4}
.hc-bot{align-self:flex-start;background:var(--bubble);padding:10px 13px;border-radius:5px 16px 16px 16px;font-size:14px;line-height:1.45}
.hc-chips{display:flex;gap:7px}
.hc-chips span{border:1.5px solid var(--ink);border-radius:11px;padding:5px 13px;font-size:13px;font-weight:600}
.hc-chips span:first-child{background:var(--ivy);color:var(--card);box-shadow:0 3px 0 var(--ink)}

/* ---------- what it is, in four facts ---------- */
.facts{margin-top:72px}
.facts .row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border-top:2px solid var(--ink);border-bottom:2px solid var(--ink)}
.fact{display:flex;align-items:center;gap:14px;padding:22px 24px}
.fact + .fact{border-left:2px solid var(--ink)}
.fact:first-child{padding-left:8px}
.fact .ico{width:42px;height:42px;border-radius:13px;background:var(--sage);color:var(--ivy);display:grid;place-items:center;flex:none}
.fact .ico svg{width:22px;height:22px}
.fact b{display:block;font-size:16px}
.fact span{font-size:14px;color:var(--ink-2)}

/* ---------- the live demo ---------- */
.banner{margin:0 0 16px}
.banner[hidden]{display:none}
.banner div{background:var(--butter);border:1.5px solid var(--ink);border-radius:12px;padding:10px 14px;font-size:14px}

/* The journey tracker. Steps come from the agent every turn; the page only
   draws them. Todo / active / done / blocked, as key-tag chips. */
.guide{margin:30px 0 24px}
.detected{display:flex;align-items:center;gap:9px;margin-bottom:12px;padding:9px 14px;border-radius:14px;
  font-size:14px;line-height:1.35;background:var(--blush);border:1.5px solid var(--coral);color:var(--ink)}
/* `display:flex` on a class outranks the `hidden` attribute's own
   `display:none`, so without this the default state draws an empty pill. */
.detected[hidden]{display:none}
.detected b{font-weight:700}
.detected .eye{display:grid;color:var(--coral-ink)}
.detected.flash{animation:detected .9s ease}
@keyframes detected{
  0%{opacity:0;transform:translateY(-4px)}
  35%{opacity:1;transform:none;box-shadow:0 0 0 5px rgba(224,122,92,.2)}
  100%{box-shadow:0 0 0 0 rgba(224,122,92,0)}
}
.steps{display:flex;flex-wrap:wrap;gap:8px}
.steps.flash .step{animation:stepflash .9s ease}
@keyframes stepflash{0%{opacity:.35}100%{opacity:1}}
.step{display:inline-flex;align-items:center;gap:9px;padding:7px 14px 7px 7px;border-radius:14px;
  border:1.5px dashed var(--ink-3);color:var(--ink-3);font-size:14px;font-weight:600;line-height:1.25;
  transition:background .25s,border-color .25s,color .25s}
.step .n{flex:none;width:24px;height:24px;border-radius:50%;display:grid;place-items:center;
  font-family:var(--mono);font-size:12px;border:1.5px solid currentColor}
.step.active{background:var(--ivy);color:var(--card);border:1.5px solid var(--ink);box-shadow:0 3px 0 var(--ink)}
.step.active .n{background:var(--butter);color:var(--ink);border-color:var(--butter)}
.step.done{background:var(--sage);color:var(--ivy);border:1.5px solid var(--sage)}
.step.done .n{background:var(--ivy);color:var(--card);border-color:var(--ivy);font-size:11px}
.step.blocked{background:#FBF1CF;color:#7A5A12;border:1.5px solid var(--brass)}
.hint{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px;font-size:15px;color:var(--ink-2)}
.starters button,.try button,.hint button{background:var(--card);border:1.5px solid var(--ink);color:var(--ink);
  border-radius:12px;padding:8px 14px;font:inherit;font-size:14px;font-weight:600;cursor:pointer;transition:background .15s}
.starters button:hover,.try button:hover,.hint button:hover{background:var(--butter)}

.panes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:30px;align-items:stretch}
.pane{background:var(--card);border:2px solid var(--ink);border-radius:24px;box-shadow:8px 8px 0 var(--ivy);
  display:flex;flex-direction:column;overflow:hidden;height:min(78vh,640px);min-height:460px}
.pane-hd{display:flex;align-items:center;gap:11px;padding:12px 16px;background:var(--ivy);color:var(--card)}
.pane-hd .av{width:34px;height:34px;border-radius:12px;background:var(--butter);color:var(--ivy);display:grid;place-items:center;flex:none}
.pane-hd .av svg{width:19px;height:19px}
.pane-hd .av.alt{background:var(--ivy-2);color:var(--butter)}
.pane-hd .kicker{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--brass)}
.pane-hd .name{font-weight:700;font-size:15px}
.pane-hd .name span{font-weight:400;color:var(--sage)}
.pane-hd .tag{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:#BFE3C8;white-space:nowrap}
.pane-hd .tag::before{content:"";width:7px;height:7px;border-radius:50%;background:#7FD39A}
.pane-hd .tag.live::before{animation:p 2.4s infinite}
.pane-hd .tag.off{color:#F6CDBF}
.pane-hd .tag.off::before{background:var(--coral);animation:none}
@keyframes p{0%{box-shadow:0 0 0 0 rgba(127,211,154,.55)}70%{box-shadow:0 0 0 7px rgba(127,211,154,0)}100%{box-shadow:0 0 0 0 rgba(127,211,154,0)}}

/* chat */
.log{flex:1;overflow-y:auto;padding:18px 16px;display:flex;flex-direction:column;gap:11px}
.bub{max-width:82%;padding:10px 14px;border-radius:18px;font-size:15px;line-height:1.45;
  white-space:pre-wrap;word-break:break-word;animation:in .22s ease}
@keyframes in{from{opacity:0;transform:translateY(5px)}}
.bot{background:var(--bubble);border-top-left-radius:6px;align-self:flex-start}
.me{background:var(--ivy);color:var(--card);border-bottom-right-radius:6px;align-self:flex-end}
.qr{display:flex;flex-wrap:wrap;gap:8px;align-self:flex-start;max-width:90%}
.qr button{background:var(--card);border:1.5px solid var(--ink);color:var(--ink);border-radius:12px;padding:7px 15px;
  font:inherit;font-size:14px;font-weight:600;cursor:pointer;box-shadow:0 3px 0 var(--ink)}
.qr button:hover{background:var(--ivy);color:var(--card)}
/* Not a message — the chat itself saying what just happened to it. Centred and
   dashed so it cannot be mistaken for something Mochi said. */
.sys{align-self:center;max-width:92%;text-align:center;font-size:13px;color:var(--ink-2);background:var(--card-2);
  border:1.5px dashed var(--line);border-radius:12px;padding:10px 14px}
.composer.silent input{background:#ECE8DB;color:var(--ink-3)}
/* The deposit QR, under the message that asks for it. Capped so a 720px image
   does not take over a phone screen. */
.bub .qrimg{display:block;margin-top:10px;width:min(190px,60%);height:auto;border-radius:10px;background:#fff;border:1.5px solid var(--ink)}
.bub .qrimg-missing{margin-top:9px;font-size:13px;color:var(--ink-2);font-style:italic}
.typing{display:flex;gap:4px;padding:12px 14px;align-self:flex-start}
.typing i{width:6px;height:6px;border-radius:50%;background:var(--ink-3);animation:b 1.2s infinite}
.typing i:nth-child(2){animation-delay:.15s}
.typing i:nth-child(3){animation-delay:.3s}
@keyframes b{0%,60%,100%{opacity:.25;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}
.composer{display:flex;gap:10px;padding:12px 14px;border-top:2px solid var(--ink)}
.composer input{flex:1;min-width:0;border:1.5px solid var(--line);border-radius:14px;padding:11px 16px;font:inherit;
  font-size:15px;background:var(--card-2);color:var(--ink)}
.composer input:focus{outline:none;border-color:var(--ivy);background:var(--card)}
.composer button{flex:none;width:46px;height:46px;border:0;border-radius:14px;background:var(--coral);color:var(--card);
  cursor:pointer;display:grid;place-items:center;box-shadow:0 3px 0 var(--ink)}
.composer button svg{width:18px;height:18px}
.composer button:disabled{opacity:.45;cursor:default}

/* The chat before anybody has typed: the page offering the first question. It
   leaves the moment anything lands in the log. */
.hello{margin:auto;text-align:center;max-width:340px;padding:8px 4px;animation:in .3s ease}
.hello .av{width:52px;height:52px;border-radius:16px;background:var(--ivy);color:var(--butter);display:grid;
  place-items:center;margin:0 auto 12px;box-shadow:4px 4px 0 var(--brass)}
.hello .av svg{width:26px;height:26px}
.hello b{display:block;font-family:var(--display);font-weight:800;letter-spacing:-.03em;font-size:22px}
.hello p{margin:4px 0 16px;font-size:14px;color:var(--ink-2)}
.starters{display:flex;flex-wrap:wrap;justify-content:center;gap:8px}

/* staff */
.staff{flex:1;overflow-y:auto;padding:16px 18px;display:flex;flex-direction:column;gap:15px}
.calhd{display:flex;align-items:center;gap:10px}
.calnav{flex:none;width:34px;height:34px;padding:0;border-radius:10px;border:1.5px solid var(--ink);background:var(--card);
  color:var(--ink);display:grid;place-items:center;cursor:pointer}
.calnav:hover{background:var(--butter)}
.calnav svg{width:14px;height:14px}
.calwhen{flex:1;text-align:center;font-family:var(--display);font-weight:800;letter-spacing:-.02em;font-size:19px}
.calwhen small{display:block;font-family:var(--mono);font-weight:400;font-size:11px;letter-spacing:.12em;color:var(--ink-3)}
.strip{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:6px}
.day{background:var(--card-2);border:1.5px solid var(--line);border-radius:12px;padding:8px 2px;text-align:center;cursor:pointer}
.day .dow{font-family:var(--mono);font-size:10px;color:var(--ink-3);text-transform:uppercase;letter-spacing:.04em}
.day .num{font-family:var(--display);font-weight:800;font-size:19px;letter-spacing:-.02em;line-height:1.25}
.day .occ{font-family:var(--mono);font-size:11px;color:var(--ink-2)}
.day.full{background:var(--blush);border-color:#E9A892}
.day.full .occ{color:var(--coral-ink)}
.day.focus{background:var(--ivy);border-color:var(--ink);color:var(--card);box-shadow:0 3px 0 var(--ink)}
.day.focus .dow{color:var(--brass)}
.day.focus .occ{color:var(--butter)}
.sect{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);
  display:flex;align-items:center;gap:8px;margin-bottom:8px}
.count{background:var(--coral);color:var(--card);border-radius:999px;padding:0 7px;letter-spacing:0}
#dayList{display:flex;flex-direction:column;gap:8px}
.card{display:flex;align-items:center;gap:10px;padding:9px 12px;border:1.5px solid var(--line);border-radius:12px;
  background:var(--card);font-size:14px;animation:in .3s ease}
.card .who{font-weight:700}
.card .when{font-size:12px;color:var(--ink-2)}
.card .src{font-size:12px;font-weight:500;color:var(--coral-ink)}
.card.unplaced{border-style:dashed;border-color:var(--brass);background:#FDF8E8}
/* The visitor's OWN bookings: a red border that shines. They are what the demo
   just made, and the one thing on a shared calendar the visitor should find
   without reading (the owner, 2026-09-11). */
.card.fresh,.card.fresh.unplaced{border:2px solid var(--fresh);background:#FFF2EF;
  animation:in .3s ease,freshglow 1.6s ease-in-out infinite}
.newpill{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.06em;color:#fff;background:var(--fresh);
  border-radius:999px;padding:1px 7px;margin-left:6px;vertical-align:middle}
@keyframes freshglow{0%,100%{box-shadow:0 0 0 0 rgba(217,72,59,.5)}50%{box-shadow:0 0 12px 4px rgba(217,72,59,.3)}}
/* ...and green once the payment is confirmed: the same rows, so the press is
   seen where its effect is (the owner, 2026-09-11). */
.card.fresh.confirmed,.card.fresh.confirmed.unplaced{border-color:var(--ok);background:#EEF6EF;
  animation:in .3s ease,okglow 1.6s ease-in-out infinite}
.newpill.ok{background:var(--ok)}
@keyframes okglow{0%,100%{box-shadow:0 0 0 0 rgba(62,140,94,.5)}50%{box-shadow:0 0 12px 4px rgba(62,140,94,.3)}}
.room{margin-left:auto;flex:none;font-family:var(--mono);font-size:11px;text-transform:uppercase;letter-spacing:.03em;
  background:var(--sage);color:var(--ivy);border-radius:8px;padding:4px 8px}
.empty{font-size:13px;color:var(--ink-3);padding:4px 0}
.nameless{font-size:12px;color:var(--ink-3);font-style:italic;padding:6px 2px 0}

/* one card per thing waiting on a person */
.todo{border:2px solid var(--ink);border-radius:14px;padding:13px 14px;margin-bottom:10px;background:var(--card);animation:in .3s ease}
.todo.pay{background:var(--butter)}
.todo.care{background:#FDF0E9;border-color:var(--coral)}
.todo.room{border-style:dashed;border-color:var(--brass);background:#FDF8E8}
.todo.handover{background:var(--sage);border-color:var(--ivy)}
.todo .th{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:700;margin-bottom:6px}
.ic{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.todo .tb{font-size:14px;line-height:1.45;margin-bottom:4px}
.todo .tm{font-size:12px;color:var(--ink-2);margin-bottom:10px}
.todo .tq{font-size:14px;border-left:3px solid var(--brass);padding-left:10px;margin-bottom:10px}
.todo .acts{display:flex;gap:8px;flex-wrap:wrap}
.todo button{border:0;border-radius:12px;padding:8px 16px;font:inherit;font-size:14px;font-weight:700;cursor:pointer}
.todo .go{background:var(--ivy);color:var(--card);box-shadow:0 3px 0 var(--ink)}
.todo .stop{background:var(--card);color:var(--danger);border:1.5px solid var(--danger)}
.todo .neutral{background:var(--ink);color:var(--card)}
.todo button:disabled{opacity:.5;cursor:default}

/* the owner's notifications, under the staff view */
.drawer{border-top:2px solid var(--ink);background:#FBF6E4;padding:0;max-height:0;overflow:hidden;transition:max-height .4s ease}
.drawer.open{max-height:260px;overflow-y:auto;padding:12px 16px}
.note{display:flex;gap:9px;font-size:13px;border-left:3px solid var(--brass);padding:2px 0 2px 10px;margin-bottom:9px;white-space:pre-wrap}

/* The owner view is shaded until the chat has put something in it — a demo
   whose claim is "the conversation CAUSES this" should not show the effect
   before the cause. */
.pane.ops{position:relative}
.lock{position:absolute;inset:0;z-index:20;display:grid;place-items:center;padding:24px;text-align:center;
  background:rgba(242,240,230,.82);backdrop-filter:blur(3px);transition:opacity .45s ease}
.lock.lifting{opacity:0;pointer-events:none}
.lock .lk{max-width:300px}
.lock .lk-ic{width:46px;height:46px;border-radius:14px;background:var(--ivy);color:var(--butter);display:grid;place-items:center;
  margin:0 auto 12px;box-shadow:4px 4px 0 var(--brass)}
.lock .lk-ic svg{width:22px;height:22px}
.lock .lk b{display:block;font-family:var(--display);font-weight:800;letter-spacing:-.03em;font-size:22px;margin-bottom:6px}
.lock .lk .msg{display:block;font-size:14px;color:var(--ink-2)}

/* Over the owner view while a staff button waits on the bot. Those presses take
   seconds, and a button that only greys out reads as a page that has hung. */
.working{position:absolute;inset:0;z-index:25;display:grid;place-items:center;
  background:rgba(242,240,230,.7);cursor:progress}
.working[hidden]{display:none}
.working .wk{display:flex;align-items:center;gap:10px;background:var(--card);border:2px solid var(--ink);
  border-radius:14px;padding:12px 18px;box-shadow:4px 4px 0 var(--ivy);font-weight:700;color:var(--ink)}
.working .spin{width:18px;height:18px;border-radius:50%;border:3px solid var(--sage);border-top-color:var(--ivy);
  animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* The tutorial ring round whichever control is waiting on the visitor. Only
   the ring's shadow animates; see the script for why. */
.spot{position:absolute;z-index:30;pointer-events:none}
@keyframes fadein{from{opacity:0}}
.spot .tip,.spot .arw{animation:fadein .28s ease}
.spot .ring{position:absolute;inset:-9px;border:2px solid var(--coral);border-radius:18px;
  box-shadow:0 0 0 4px rgba(224,122,92,.2);animation:ringp 1.9s ease-out infinite}
@keyframes ringp{0%{box-shadow:0 0 0 3px rgba(224,122,92,.3)}70%{box-shadow:0 0 0 11px rgba(224,122,92,0)}100%{box-shadow:0 0 0 0 rgba(224,122,92,0)}}
.spot .tip{position:absolute;width:max-content;max-width:210px;background:var(--ink);color:var(--card);font-size:13px;
  line-height:1.35;padding:8px 12px;border-radius:12px;box-shadow:4px 4px 0 var(--brass)}
.spot .arw{position:absolute;color:var(--coral)}

.try{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:32px}
/* Same trap as `.detected[hidden]`. */
.try[hidden]{display:none}
.try b{font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);font-weight:400;margin-right:4px}

/* ---------- how it works ---------- */
.how-hd{display:grid;grid-template-columns:minmax(0,1fr) 420px;gap:60px;align-items:end}
.how-hd p{margin:0;font-size:17px;line-height:1.6;color:var(--ink-2)}
.steps3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:30px;margin-top:48px}
.lug{position:relative;background:var(--card);border:2px solid var(--ink);border-radius:20px;padding:26px 26px 28px 60px;
  box-shadow:6px 6px 0 var(--brass)}
.lug:nth-child(1){transform:rotate(-1deg)}
.lug:nth-child(2){transform:rotate(.8deg)}
.lug:nth-child(3){transform:rotate(-.6deg)}
.lug::before{content:"";position:absolute;left:20px;top:28px;width:18px;height:18px;border-radius:50%;background:var(--paper);border:2px solid var(--ink)}
.lug .k{font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--coral-ink)}
.lug h3{font-family:var(--display);font-weight:800;letter-spacing:-.03em;font-size:26px;line-height:1.1;margin:8px 0 0}
.lug p{margin:10px 0 0;font-size:15px;line-height:1.6;color:var(--ink-2)}

/* ---------- features ---------- */
.feats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;margin-top:48px}
.feat{background:var(--card);border:2px solid var(--ink);border-radius:20px;padding:26px;display:flex;flex-direction:column;gap:12px}
.feat .ico{width:46px;height:46px;border-radius:14px;background:var(--sage);color:var(--ivy);display:grid;place-items:center}
.feat .ico.warm{background:var(--butter);color:var(--ink)}
.feat .ico svg{width:24px;height:24px}
.feat h3{font-family:var(--display);font-weight:800;letter-spacing:-.03em;font-size:23px;line-height:1.1;margin:4px 0 0}
.feat p{margin:0;font-size:15px;line-height:1.6;color:var(--ink-2)}

/* ---------- any business ---------- */
.biz{margin-top:124px;background:var(--ivy);color:var(--card);padding:96px 0;scroll-margin-top:84px}
.biz .wrap{display:grid;grid-template-columns:minmax(0,1fr) 560px;gap:72px;align-items:center}
.biz .eyebrow{color:var(--brass)}
.biz p{font-size:18px;line-height:1.6;color:var(--sage);margin:18px 0 0;max-width:600px}
.biz .btn{margin-top:32px}
.biz-k{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--brass);margin-bottom:18px}
.biz-tags{display:flex;flex-wrap:wrap;gap:16px 14px}
.biz-tag{display:flex;align-items:center;gap:12px;background:var(--card);color:var(--ink);border:2px solid var(--ink);border-radius:14px;
  padding:13px 18px 13px 14px;box-shadow:4px 4px 0 var(--ink);transform:rotate(var(--tilt,0deg));
  font-family:var(--display);font-weight:800;letter-spacing:-.03em;font-size:21px}
.biz-tag::before{content:"";width:13px;height:13px;border-radius:50%;background:var(--ivy);border:2px solid var(--brass);flex:none}
.biz-tag em{font-style:normal;font-family:var(--mono);font-weight:400;letter-spacing:.04em;font-size:10px;
  background:var(--ivy);color:var(--butter);border-radius:999px;padding:2px 7px}

/* ---------- pricing ---------- */
/* Priced per SERVICE the agent is asked to handle, not per tier (the owner,
   2026-09-12): one base for answering questions about the business, one line
   for each job after that, and a small monthly to run it. The middle card is
   the part of the model nobody expects, so it is the one lifted off the page. */
.plans{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:26px;margin-top:48px;align-items:stretch}
.plan{position:relative;background:var(--card);border:2px solid var(--ink);border-radius:24px;padding:30px 28px;
  display:flex;flex-direction:column;gap:12px}
.plan.hot{background:var(--ivy);color:var(--card);box-shadow:10px 10px 0 var(--brass)}
.plan .k{font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2)}
.plan.hot .k{color:var(--brass)}
.plan .for{margin:0;font-size:15px;color:var(--ink-2)}
.plan .amt{display:flex;align-items:baseline;gap:6px;margin-top:8px}
.plan .amt b{font-family:var(--display);font-weight:800;letter-spacing:-.04em;font-size:54px;line-height:1}
.plan .amt span,.plan .setup{font-size:15px;color:var(--ink-2)}
.plan.hot .for,.plan.hot .amt span,.plan.hot .setup{color:var(--sage)}
.plan ul{list-style:none;margin:8px 0 0;padding:14px 0 0;border-top:1.5px dashed var(--line);display:flex;flex-direction:column;gap:10px;flex:1}
.plan.hot ul{border-top-color:rgba(214,228,211,.3)}
.plan li{display:flex;gap:10px;font-size:15px;line-height:1.45}
.plan li svg{width:20px;height:20px;margin-top:1px;color:var(--ivy)}
.plan.hot li svg{color:var(--butter)}
.plan .btn{margin-top:12px}
.plan.hot .btn{background:var(--butter);color:var(--ink)}
.plan .badge{position:absolute;top:-15px;right:24px;background:var(--coral);color:var(--card);border:2px solid var(--ink);
  border-radius:999px;padding:4px 11px;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase}
.plan .amt.rng b{font-size:42px}
.price-note{margin:30px 0 0;font-size:14px;color:var(--ink-2)}

/* The rate card is a METHOD, not a list of SKUs, and a method is only
   believable applied to something. The receipt is the demo above priced by it,
   which is why the line items are the six services you can watch it handle. */
.calc{display:grid;grid-template-columns:1fr 1fr;gap:36px;margin-top:46px;align-items:start}
.calc-hd h3{margin:0;font-family:var(--display);font-weight:800;letter-spacing:-.03em;font-size:clamp(26px,3vw,34px);line-height:1.12}
.calc-hd p{margin:16px 0 0;font-size:16px;line-height:1.65;color:var(--ink-2)}
.receipt{background:var(--card);border:2px solid var(--ink);border-radius:22px;padding:24px 28px 26px;box-shadow:9px 9px 0 var(--butter)}
.rc-hd{display:flex;align-items:center;gap:11px;padding-bottom:13px;border-bottom:2px solid var(--ink)}
.rc-hd svg{width:22px;height:22px;color:var(--ivy);flex:none}
.rc-hd b{font-family:var(--display);font-weight:800;letter-spacing:-.02em;font-size:19px}
.rc-hd span{margin-left:auto;font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.receipt ul{list-style:none;margin:0;padding:0}
.receipt li{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:10px 0;
  border-bottom:1.5px dashed var(--line);font-size:15px;line-height:1.4}
.receipt li i{font-style:normal;flex:1}
.receipt li i em{font-style:normal;display:block;margin-top:2px;font-size:13px;color:var(--ink-3)}
.receipt li b{flex:none;font-family:var(--mono);font-weight:500;font-size:14px;color:var(--ink-2)}
.receipt li.base b{color:var(--ink)}
.rc-tot{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-top:17px;padding-top:15px;border-top:2px solid var(--ink)}
.rc-tot i{font-style:normal;font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2)}
.rc-tot b{font-family:var(--display);font-weight:800;letter-spacing:-.04em;font-size:40px;line-height:1}
.rc-run{margin:13px 0 0;font-size:14px;color:var(--ink-2)}
.price-cta{margin-top:26px;display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.price-cta small{font-size:14px;color:var(--ink-2)}

/* ---------- founder's discount ---------- */
/* Half off every ONE-TIME price — the base and each service — for the first
   three customers (the owner, 2026-09-20: "everything 50% off … limited to the
   first 3 customers only … set it as founder's discount", and then, asked
   whether that meant the monthly too: "no, not for monthly"). So the S$150 a
   month is never struck through, and the copy says so wherever the offer is
   stated: a halved running cost with no end date is a promise nobody made.

   ONE SWITCH: the `founder` class on <body>. With it, every .fd-on element
   shows and every .fd-off one hides; without it the page is the rate card
   exactly as it was. So ending the offer is deleting one word, not hunting for
   every halved price — and "first 3" describes the offer rather than counting
   down, so nothing here needs editing as the places fill.

   The class is the INSTANT switch, and it is a visual one: the offer's words
   are still in the source for anything that reads HTML rather than rendering
   it. Once the third customer has signed, the owner's plan is to put back the
   page as it was before the offer — deploy/SHOWCASE.md, "The founder's
   discount", says where that copy is and what restoring it would overwrite.

   The full price stays in the markup beside each halved one for that reason,
   and because a discount nobody can check against the real figure reads as an
   invented one. The halves are TYPED, not computed: a visitor with no script,
   and a crawler, must see the same offer. Change a full price and its half
   changes with it, by hand — they sit on the same line so that is hard to miss. */
/* Hidden BY the absence of the class, not shown by its presence: an .fd-on
   element then keeps whatever display its own rule gives it (the receipt row is
   a flex <li>, and `.receipt li` out-specified a plain `.fd-on{display:none}` —
   the row stayed on the bill with the offer switched off). Any rule below that
   SETS a display on an .fd-on element is scoped to body.founder for the same
   reason. */
body:not(.founder) .fd-on{display:none}
body.founder .fd-off{display:none}

/* WHO it is for is the headline, everywhere the offer appears (the owner,
   2026-09-20: "highlight 'only for the first 3 customers'. Make it large and
   limited"). Half off is the reason to read on; three places is the reason to
   act, so the 3 is the biggest thing in each of the three places it is said.

   The band above the door is the first thing on the page. It scrolls away with
   the awning; above 960px the tag on the sticky header's Pricing link stays in
   view after that. Below it the nav is folded into the menu and nothing does —
   there is no room for a tag in a 375px header. */
.fd-band{background:var(--butter);color:var(--ink);border-bottom:2px solid var(--ink);
  font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase}
.fd-band a{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px 18px;padding:14px 20px;text-decoration:none}
.fd-band b{font-weight:500;background:var(--ink);color:var(--butter);border-radius:999px;padding:4px 12px}
.fd-band strong{font-family:var(--display);font-weight:800;font-size:22px;letter-spacing:-.02em;line-height:1.15;text-transform:none}
.fd-band u{text-underline-offset:3px}
/* The page's focus ring is coral, drawn OUTSIDE the box. This link is the full
   width of the viewport, so three of its four sides fell off the screen, and
   coral on butter is 2.3:1 besides. Ink, inside. The button on the butter
   callout gets the ink ring for the same contrast reason. */
.fd-band a:focus-visible,.fd-hero:focus-visible,.offer .btn:focus-visible{outline-color:var(--ink)}
.fd-band a:focus-visible{outline-offset:-5px}

/* The same thing, said once in the hero, as a ticket under the two buttons. */
.fd-hero{align-items:center;gap:14px;max-width:500px;margin-top:30px;padding:11px 18px 11px 11px;background:var(--butter);
  border:2px solid var(--ink);border-radius:18px;box-shadow:4px 4px 0 var(--ink);text-decoration:none;
  font-size:15px;line-height:1.4;color:var(--ink-2);animation:rise .8s var(--out) both .95s}
body.founder .fd-hero{display:flex}
body.founder .fd-hero + .live-note{margin-top:22px}
.fd-hero > b{flex:none;display:grid;place-items:center;width:50px;height:50px;border-radius:50%;background:var(--ink);color:var(--butter);
  font-family:var(--display);font-weight:800;font-size:30px;letter-spacing:-.04em;rotate:-6deg}
.fd-hero strong{display:block;font-family:var(--display);font-weight:800;font-size:19px;letter-spacing:-.02em;line-height:1.2;color:var(--ink)}
.fd-hero svg{flex:none;width:18px;height:18px;margin-left:auto;color:var(--ink)}
@media(prefers-reduced-motion:reduce){ .fd-hero{animation:none} }
.nav-tag{margin-left:7px;font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;background:var(--butter);color:var(--ink);
  border:1.5px solid var(--ink);border-radius:999px;padding:1px 7px;vertical-align:1px}
body.founder .nav-tag{display:inline-block}

/* The offer itself, stated once and in full, at the head of the prices it cuts. */
.offer{position:relative;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:30px;margin-top:44px;
  background:var(--butter);border:2px solid var(--ink);border-radius:24px;padding:30px 32px;box-shadow:8px 8px 0 var(--ink)}
body.founder .offer{display:grid}
.offer .badge{position:absolute;top:-15px;right:26px;background:var(--coral-ink);color:var(--card);border:2px solid var(--ink);
  border-radius:999px;padding:4px 12px;font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase}
.offer-cut{display:flex;flex-direction:column;align-items:center;justify-content:center;width:112px;height:112px;
  border-radius:50%;background:var(--ink);color:var(--butter);rotate:-8deg}
.offer-cut b{font-family:var(--display);font-weight:800;font-size:40px;letter-spacing:-.04em;line-height:.95}
.offer-cut span{font-family:var(--mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase}
.offer .k{font-family:var(--mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--coral-ink)}
.offer h3{margin:8px 0 0;font-family:var(--display);font-weight:800;letter-spacing:-.035em;font-size:clamp(30px,3.9vw,50px);line-height:1.08}
.offer h3 b{display:inline-block;margin:0 .06em;padding:0 .24em;border-radius:.22em;background:var(--ink);color:var(--butter);rotate:-4deg}
.offer .sub{margin:14px 0 0;font-size:18px;font-weight:600;line-height:1.4;color:var(--ink)}
.offer p{margin:10px 0 0;font-size:15px;line-height:1.6;color:var(--ink-2);max-width:620px}

/* On a card the full price sits struck through ABOVE the halved one, on its
   own line: beside it, "S$300–500" and "S$150–250" do not fit a third of the
   page. The words "was" and "now" are there for a screen reader, which does
   not announce a strike-through. */
.plan .amt{flex-wrap:wrap}
.plan .amt .was{flex-basis:100%;align-items:center;gap:9px;font-family:var(--mono);font-size:15px;color:var(--ink-3)}
body.founder .plan .amt .was{display:flex}
.plan.hot .amt .was{color:var(--sage)}
.was s,.rc-tot s{text-decoration-thickness:2px;text-decoration-color:var(--coral)}
.plan .amt .was em{font-style:normal;font-size:11px;letter-spacing:.06em;background:var(--butter);color:var(--ink);
  border:1.5px solid var(--ink);border-radius:999px;padding:1px 8px}
/* On the receipt the lines keep their full price and the discount is its own
   row, the way a till prints one — so the sum can be checked by eye. */
.receipt li.off b{color:var(--coral-ink)}
.rc-tot b s{margin-right:12px;font-family:var(--mono);font-weight:500;font-size:15px;letter-spacing:0;color:var(--ink-3)}
/* Struck total + new total is one 199px run that cannot break, and .rc-tot is a
   nowrap row: on a 320px phone it pushed the receipt out of its column and the
   whole page scrolled sideways — only with the offer on. So the row may wrap,
   and the figures keep to the right edge when it does. */
.rc-tot{flex-wrap:wrap}
.rc-tot b{margin-left:auto;text-align:right}
/* Below 1180px the cards and the receipt stack into one 560px column; the
   callout was left at full width, nearly twice as wide as the prices it heads. */
@media(max-width:1180px){
  .offer{grid-template-columns:auto minmax(0,1fr);max-width:560px;gap:22px;padding:26px 24px}
  .offer .btn{grid-column:1/-1;justify-self:start}
  .offer h3{font-size:clamp(28px,5.4vw,38px)}
}
@media(max-width:640px){
  .fd-band{font-size:11px;letter-spacing:.08em}
  .fd-band a{gap:8px 14px;padding:12px 16px}
  .fd-band strong{flex-basis:100%;text-align:center;font-size:18px}
  .fd-band u{display:none}   /* the whole band is the link */
  .fd-hero{margin-top:22px}
  .fd-hero strong{font-size:17px}
  .offer{grid-template-columns:1fr;gap:16px;margin-top:34px;padding:26px 20px 22px;box-shadow:6px 6px 0 var(--ink)}
  .offer-cut{width:84px;height:84px}
  .offer-cut b{font-size:30px}
  .offer .sub{font-size:16px}
}

/* ---------- about ---------- */
/* Who is behind it (the owner, 2026-09-17): an owner checks that a real,
   local person answers before they reply to a stranger's site. */
.about{display:grid;grid-template-columns:220px minmax(0,1fr);gap:48px;align-items:start;margin-top:44px;
  background:var(--card);border:2px solid var(--ink);border-radius:24px;padding:36px 40px;box-shadow:7px 7px 0 var(--ink)}
.about img{width:220px;height:220px;margin-top:6px;border-radius:50%;object-fit:cover;border:2px solid var(--ink);background:var(--sage);display:block}
.about h3{margin:0;font-family:var(--display);font-weight:800;letter-spacing:-.03em;font-size:34px;line-height:1.1}
.about .role{display:inline-block;margin-top:8px;font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--ivy)}
.about p{font-size:17px;line-height:1.65;color:var(--ink-2);margin:16px 0 0;max-width:680px}
@media(max-width:640px){
  .about{grid-template-columns:1fr;gap:22px;padding:26px 22px;text-align:center;box-shadow:5px 5px 0 var(--ink)}
  .about img{width:150px;height:150px;margin:0 auto}
  .about h3{font-size:28px}
  .about p{text-align:left;font-size:16px}
}

/* ---------- FAQ ---------- */
.faq{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;margin-top:44px;align-items:start}
.qa{background:var(--card);border:1.5px solid var(--line);border-radius:18px;padding:22px 26px}
.qa summary{display:flex;align-items:flex-start;gap:14px;cursor:pointer;list-style:none}
.qa summary::-webkit-details-marker{display:none}
.qa h3{flex:1;margin:0;font-family:var(--display);font-weight:800;letter-spacing:-.02em;font-size:21px;line-height:1.2}
.qa .pm{flex:none;position:relative;width:18px;height:18px;margin-top:4px}
.qa .pm::before,.qa .pm::after{content:"";position:absolute;left:0;right:0;top:8px;height:2px;background:var(--ink);transition:transform .2s}
.qa .pm::after{transform:rotate(90deg)}
.qa[open] .pm::after{transform:rotate(0deg)}
.qa p{margin:10px 0 0;font-size:15px;line-height:1.6;color:var(--ink-2)}

/* ---------- get in touch ---------- */
.book{padding-top:124px;scroll-margin-top:84px}
.book-card{margin-top:30px;background:var(--ivy);color:var(--card);border-radius:30px;padding:64px;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,460px);align-items:center;gap:48px;
  box-shadow:10px 10px 0 var(--ink)}
.book-card h2{font-size:clamp(34px,4.2vw,60px);line-height:.98;margin:0}
.book-card p{margin:16px 0 0;font-size:18px;line-height:1.55;color:var(--sage);max-width:600px}
.book-alt{display:block;margin-top:22px;font-size:15px;color:var(--sage)}
.book-alt a{color:var(--butter);text-decoration:underline}
/* The note itself: a card on the ivy, like the chat hung over the rack. No <p>
   inside it on purpose — `.book-card p` is the ivy card's sage copy. */
.note{position:relative;display:flex;flex-direction:column;gap:14px;background:var(--card);color:var(--ink);
  border:2px solid var(--ink);border-radius:22px;padding:24px;box-shadow:8px 8px 0 var(--brass)}
.note[hidden]{display:none}
.note-f{display:flex;flex-direction:column;gap:6px}
.note-f span{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
/* 16px, not the composer's 15: iOS zooms the page into any smaller field. */
.note-f input,.note-f textarea{width:100%;border:1.5px solid var(--line);border-radius:14px;padding:11px 14px;
  font:inherit;font-size:16px;line-height:1.45;background:var(--card-2);color:var(--ink)}
.note-f textarea{min-height:132px;resize:vertical}
.note-f input:focus,.note-f textarea:focus{outline:none;border-color:var(--ivy);background:var(--card)}
.note-f input::placeholder,.note-f textarea::placeholder{color:var(--ink-3)}
/* The honeypot: out of sight and out of the tab order, still in the form. */
.note-hp{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.note-go{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.note-go small{font-size:13px;color:var(--ink-2)}
.note-go .btn:disabled{opacity:.6;cursor:default;transform:none;box-shadow:0 5px 0 var(--ink)}
.note-status{font-size:14px;line-height:1.5;color:var(--ink-2)}
.note-status:empty{display:none}
.note-status.bad{color:var(--coral-ink)}
.note-status a{color:var(--ivy);font-weight:600}
.note-done{align-items:flex-start;gap:6px;outline:none}
.note-done .ok{width:44px;height:44px;border-radius:14px;background:var(--sage);color:var(--ivy);display:grid;place-items:center;margin-bottom:8px}
.note-done .ok svg{width:22px;height:22px}
.note-done b{font-family:var(--display);font-weight:800;letter-spacing:-.03em;font-size:26px;line-height:1.1}
.note-done div{font-size:15px;color:var(--ink-2);word-break:break-word}

/* ---------- footer ---------- */
.site-ft{margin-top:96px;border-top:2px solid var(--ink);padding:44px 0 40px}
.ft-grid{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,.8fr) minmax(0,1.4fr);gap:40px}
.ft-grid p{margin:10px 0 0;font-size:15px;line-height:1.55;color:var(--ink-2)}
.ft-col{display:flex;flex-direction:column;gap:9px;font-size:14px;color:var(--ink-2)}
.ft-col a{text-decoration:none}
.ft-col a:hover{color:var(--ink)}
.ft-k{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);margin-bottom:4px}
.ft-note{background:var(--card);border:1.5px solid var(--line);border-radius:16px;padding:18px 20px;font-size:13px;line-height:1.55;color:var(--ink-2)}
.ft-note b{display:block;color:var(--ink);margin-bottom:4px}
.ft-mail{margin-top:12px!important;font-family:var(--mono);font-size:13px}
.ft-mail a{color:var(--ivy);text-decoration:none;border-bottom:1.5px solid var(--brass);padding-bottom:1px}
.ft-mail a:hover{color:var(--ink)}
.ft-base{display:flex;align-items:center;margin-top:40px;padding-top:20px;border-top:1.5px solid var(--line);
  font-family:var(--mono);font-size:12px;color:var(--ink-3)}

/* ---------- motion ---------- */
/* One orchestrated entrance for the first screen — the awning drops, the
   headline rises line by line, the highlight sweeps in behind "front desk",
   the keys swing onto their rail and the example chat plays itself — then a
   quiet fade-up for each section as it arrives. Nothing depends on it: the
   hidden starting states only apply under .js, and a visitor who asked for less
   motion gets none of it (the last block in the sheet). */
@keyframes drop{from{transform:translateY(-100%)}}
@keyframes rise{from{opacity:0;transform:translateY(22px)}}
@keyframes lineup{from{transform:translateY(112%)}}
@keyframes sweep{from{transform:rotate(-2deg) scaleX(0)}to{transform:rotate(-2deg) scaleX(1)}}
@keyframes slidein{from{opacity:0;transform:translateX(48px)}}
@keyframes hang{
  0%{opacity:0;transform:translateY(-46px) rotate(calc(var(--tilt,0deg) - 16deg))}
  55%{opacity:1;transform:translateY(0) rotate(calc(var(--tilt,0deg) + 7deg))}
  78%{transform:rotate(calc(var(--tilt,0deg) - 3deg))}
  100%{transform:rotate(var(--tilt,0deg))}
}
@keyframes sway{0%,100%{transform:rotate(var(--tilt,0deg))}50%{transform:rotate(calc(var(--tilt,0deg) + 1.8deg))}}
@keyframes pop{from{opacity:0;transform:translateY(10px) scale(.97)}}
@keyframes gone{to{opacity:0;max-height:0;margin-top:-9px;padding-top:0;padding-bottom:0}}
@keyframes nudge{0%,100%{transform:none}50%{transform:translateY(3px)}}
@keyframes rot{
  0%{opacity:0;transform:translateY(80%)}
  5%{opacity:1;transform:none}
  19%{opacity:1;transform:none}
  24%{opacity:0;transform:translateY(-80%)}
  100%{opacity:0;transform:translateY(-80%)}
}

.awning.top{animation:drop .8s var(--out) both}
.hero .chip{animation:rise .7s var(--out) both .15s}
/* Each headline line rises from behind its own mask. The padding and the
   matching negative margin give the mask room for the highlight's overhang and
   the "y" of "your" without moving a pixel of layout. */
.ln{display:block;overflow:hidden;padding:0 16px .14em;margin:0 -16px -.14em}
.ln > span{display:inline-block;animation:lineup .95s var(--out) both}
.ln:nth-child(1) > span{animation-delay:.25s}
.ln:nth-child(2) > span{animation-delay:.37s}
.ln:nth-child(3) > span{animation-delay:.49s}
.ln:nth-child(4) > span{animation-delay:.61s}
.hl::before{transform-origin:0 50%;animation:sweep .75s var(--out) both 1.17s}
.hero .lede{animation:rise .8s var(--out) both .7s}
.hero-ctas{animation:rise .8s var(--out) both .85s}
.live-note{animation:rise .8s var(--out) both 1s}
.link-arrow svg{animation:nudge 1.8s ease-in-out infinite 2.2s}
.rack{animation:slidein .9s var(--out) both .45s}
/* The keys: swung onto the rail, then left to sway, each on its own clock so
   they never move in step. */
.keytag{animation:hang 1.15s var(--out) both var(--d,1s),
  sway var(--sw,6s) ease-in-out infinite calc(var(--d,1s) + 1.15s)}
/* The example chat plays itself once: the question, Mochi typing, the answer,
   the two buttons. */
.hero-chat{animation:pop .55s var(--out) both 1.5s}
.hc-me{animation:pop .4s var(--out) both 2s}
.hc-typing{display:flex;gap:4px;align-self:flex-start;padding:10px 12px;background:var(--bubble);
  border-radius:5px 16px 16px 16px;max-height:40px;overflow:hidden;
  animation:pop .3s var(--out) both 2.45s,gone .25s ease forwards 3.5s}
.hc-typing i{width:6px;height:6px;border-radius:50%;background:var(--ink-3);animation:b 1.2s infinite}
.hc-typing i:nth-child(2){animation-delay:.15s}
.hc-typing i:nth-child(3){animation-delay:.3s}
.hc-bot{animation:pop .45s var(--out) both 3.6s}
.hc-chips{animation:pop .45s var(--out) both 4.1s}

/* Sections, as they scroll in. `translate`, not `transform`, so the cards a
   transform tilts keep their tilt. The script hands each element back to its
   own styles once it has arrived, so hovers are not the reveal's slow ones. */
.js .rv{opacity:0;translate:0 26px;transition:opacity .8s var(--out),translate .8s var(--out);
  transition-delay:calc(var(--i,0) * 90ms)}
.js .rv.in{opacity:1;translate:0 0}
/* The business tags fall into the pile instead, with a little overshoot. */
.js .biz-tag.rv{translate:0 -34px;transition-timing-function:ease,cubic-bezier(.34,1.56,.64,1)}
.js .biz-tag.rv.in{translate:0 0}

/* Things you could pick up, lift. */
.feat,.lug,.biz-tag{transition:transform .2s var(--out),box-shadow .2s var(--out)}
.feat:hover{transform:translateY(-3px);box-shadow:6px 6px 0 var(--ivy)}
.lug:hover{transform:rotate(0deg) translateY(-3px)}
.biz-tag:hover{transform:rotate(0deg) scale(1.04)}

/* "Yours runs your clinic. salon. homestay. restaurant. business." — one word
   at a time. The grid stacks every word in one cell, so the slot is always as
   wide as the widest and the line never jumps. */
.rot{display:inline-grid;vertical-align:top;overflow:hidden;color:var(--butter);padding-bottom:.12em;margin-bottom:-.12em}
.rot > span{grid-area:1/1;opacity:0;transform:translateY(80%);animation:rot 12.5s var(--out) infinite}
.rot > span:nth-child(2){animation-delay:2.5s}
.rot > span:nth-child(3){animation-delay:5s}
.rot > span:nth-child(4){animation-delay:7.5s}
.rot > span:nth-child(5){animation-delay:10s}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- narrower screens ---------- */
@media(max-width:1180px){
  .hero .wrap{grid-template-columns:1fr}
  .hero-art{width:min(540px,100%);margin:40px auto 0}
  .biz .wrap,.how-hd{grid-template-columns:1fr;gap:36px}
  .plans{grid-template-columns:1fr;max-width:560px;gap:30px}
  .calc{grid-template-columns:1fr;max-width:560px;gap:28px}
  .book-card{grid-template-columns:minmax(0,1fr);gap:36px}
  .note{max-width:600px}
}
@media(max-width:960px){
  .site-nav{display:none}
  .menu-btn{display:grid;margin-left:auto}
  .site-hd.open .site-nav{display:flex;position:absolute;top:100%;left:0;right:0;flex-direction:column;align-items:stretch;
    gap:0;background:var(--paper);border-bottom:2px solid var(--ink);padding:6px 40px 14px}
  .site-hd.open .site-nav a{padding:12px 0;border-bottom:1.5px solid var(--line);font-size:17px}
  .facts .row{grid-template-columns:repeat(2,minmax(0,1fr))}
  .fact:nth-child(3){border-left:0;padding-left:8px}
  .fact:nth-child(n+3){border-top:2px solid var(--ink)}
  .steps3,.feats{grid-template-columns:1fr 1fr}
  .faq,.ft-grid{grid-template-columns:1fr 1fr}
}
@media(max-width:900px){
  .panes{grid-template-columns:1fr}
  .pane.chat{height:52vh;min-height:340px}
  .pane.ops{height:auto;min-height:0}
  .staff{max-height:none}
}
/* Phones. The whole point of the split is watching the chat CAUSE the calendar
   to change, so the day strip has to be on screen at the same time as the
   composer — every value below is bought to make that fit. */
@media(max-width:640px){
  .wrap{padding:0 20px}
  .awning{height:40px}
  .site-hd .wrap{height:64px;gap:10px}
  .site-hd .btn.sm{padding:10px 14px;font-size:14px}
  .site-hd.open .site-nav{padding:6px 20px 14px}
  .brand{font-size:20px}
  .sec,.book{padding-top:72px}
  .hero{padding-top:30px}
  /* 44, not 50: the headline is written as four lines and at 50 a phone wraps
     two of them again. */
  h1{font-size:44px}
  .hero .lede{font-size:17px;margin-top:20px}
  .hero-ctas{flex-direction:column;align-items:stretch;gap:10px;margin-top:24px}
  .hero-ctas .btn,.hero-ctas .link-arrow{justify-content:center;height:52px;padding:0 20px}
  .hero-ctas .link-arrow{border:1.5px solid var(--ink);border-radius:15px;background:var(--card)}
  .live-note{margin-top:20px;font-size:13px}
  .hero-art{height:auto;margin-top:30px}
  .rack{position:relative;width:100%;height:236px;border-radius:24px;box-shadow:7px 7px 0 var(--ink)}
  .rack-hd{left:18px;right:18px;top:16px;font-size:10px}
  .rack-hd span:last-child{display:none}
  .rail{left:12px;right:12px;top:46px;height:5px}
  .tags{left:14px;right:14px;top:44px;gap:6px}
  .keytag .cord{height:calc(var(--cord,36px) * .6)}
  .keytag .hook{width:8px;height:8px}
  .kt{padding:22px 5px 10px;border-radius:11px 11px 14px 14px}
  .kt::before{width:11px;height:11px;margin-left:-5.5px;top:7px;border-width:2px}
  .kt svg{width:16px;height:16px}
  .kt b{font-size:12px;letter-spacing:-.02em;margin-top:3px}
  .kt small{font-size:8px;margin-top:5px}
  .rack-note{display:none}
  .hero-chat{position:relative;left:auto;top:auto;margin:-40px 0 0 22px;width:min(318px,calc(100% - 22px));box-shadow:6px 6px 0 var(--brass)}
  .facts{margin-top:36px}
  .facts .row{border:2px solid var(--ink);border-radius:18px;background:var(--card);overflow:hidden}
  .fact{padding:16px 14px;display:block}
  .fact .ico{display:none}
  .fact:first-child,.fact:nth-child(3){padding-left:14px}
  .fact b{font-size:15px}
  .fact span{font-size:13px}
  .guide{margin:20px 0 16px}
  .step{font-size:13px}
  .hint{font-size:14px;gap:7px}
  .panes{gap:22px}
  .pane{border-radius:22px;box-shadow:6px 6px 0 var(--ivy)}
  .pane.chat{height:40vh;min-height:250px}
  .pane-hd .name span{display:none}
  .log{padding:12px;gap:8px}
  .bub{font-size:14px}
  .staff{padding:14px}
  .day{padding:6px 0;border-radius:10px}
  .day .num{font-size:16px}
  .day .dow,.day .occ{font-size:9px}
  /* The chat is 40vh here, so the opening state has to fit in what is left
     after the header and the composer. */
  .hello{padding:0}
  .hello .av{width:36px;height:36px;border-radius:12px;margin-bottom:7px;box-shadow:3px 3px 0 var(--brass)}
  .hello .av svg{width:19px;height:19px}
  .hello b{font-size:18px}
  .hello p{font-size:13px;margin-bottom:9px}
  .starters{gap:6px}
  .starters button{padding:6px 11px;font-size:13px}
  .steps3,.feats,.faq,.ft-grid{grid-template-columns:1fr}
  .steps3{gap:16px;margin-top:24px}
  .lug{transform:none !important;padding:20px 20px 22px 52px;box-shadow:5px 5px 0 var(--brass)}
  .lug::before{left:18px;top:22px;width:16px;height:16px}
  .lug h3{font-size:22px}
  .feats{gap:12px;margin-top:24px}
  .feat{flex-direction:row;align-items:flex-start;gap:14px;padding:18px}
  .feat .ico{width:42px;height:42px;flex:none}
  .feat h3{font-size:19px;margin:0}
  .feat p{font-size:14px;margin-top:6px}
  .biz{margin-top:72px;padding:56px 0}
  .biz p{font-size:16px}
  .biz-tags{gap:12px 10px}
  .biz-tag{font-size:17px;padding:10px 13px 10px 11px;box-shadow:3px 3px 0 var(--ink)}
  .plans{margin-top:28px}
  .plan{padding:24px 20px}
  .plan.hot{box-shadow:7px 7px 0 var(--brass)}
  .plan .amt b{font-size:44px}
  .faq{gap:10px;margin-top:22px}
  .qa{padding:18px}
  .qa h3{font-size:18px}
  .book-card{padding:30px 18px;border-radius:24px;box-shadow:7px 7px 0 var(--ink);gap:26px}
  .book-card p{font-size:16px}
  .note{padding:18px 16px;border-radius:18px;box-shadow:5px 5px 0 var(--brass)}
  .note-go .btn{flex:1 1 100%}
  .site-ft{margin-top:64px;padding:32px 0 36px}
}

/* Everything that loops forever, stilled for visitors who asked their system
   for less motion. Last in the sheet so it outranks the rules it quiets. The
   visitor's own rows keep their red / green border — that is the badge. */
@media(prefers-reduced-motion:reduce){
  .detected.flash,.steps.flash .step{animation:none}
  .pane-hd .tag.live::before,.typing i,.spot .ring{animation:none}
  .card.fresh,.card.fresh.unplaced,.card.fresh.confirmed,.card.fresh.confirmed.unplaced{animation:none}
  .btn,.cta{transition:none}
  /* The entrance, the swaying keys, the self-playing chat and the reveals. */
  .awning.top,.hero .chip,.ln > span,.hl::before,.hero .lede,.hero-ctas,.live-note,.link-arrow svg,
  .rack,.keytag,.hero-chat,.hc-me,.hc-bot,.hc-chips{animation:none}
  .hc-typing{display:none}
  .js .rv{opacity:1;translate:none;transition:none}
  .feat,.lug,.biz-tag{transition:none}
  /* The rotating word stands still on the last one: "your business." */
  .rot > span{animation:none;opacity:0}
  .rot > span:last-child{opacity:1;transform:none}
}

/* ---------- language switcher (2026-09-21) ----------
   One link, in the header of both pages, to the same page in the other
   language. OUTSIDE the nav on purpose: below 960px the nav is behind the menu
   button, and a visitor who cannot read the page cannot be expected to find the
   way out of it inside a menu whose label they cannot read either. */
.lang-sw{display:inline-flex;align-items:center;gap:7px;height:40px;padding:0 14px;border:1.5px solid var(--ink);
  border-radius:999px;background:var(--card);font-size:14px;font-weight:600;line-height:1;text-decoration:none;
  color:var(--ink);white-space:nowrap;transition:background .15s}
.lang-sw:hover{background:var(--butter)}
.lang-sw svg{width:16px;height:16px}
.ft-base a{color:inherit}
@media(max-width:960px){
  /* The menu button used to take the auto margin; the switcher is now the
     first thing on the right, and the others follow it. */
  .lang-sw{margin-left:auto}
  .menu-btn{margin-left:0}
}
@media(max-width:640px){
  .lang-sw{padding:0 11px;font-size:13px}
  .lang-sw svg{display:none}
}
/* Nothing in the header may be squeezed: a wrapped button is twice the height
   of the bar it sits in. */
.lang-sw,.menu-btn,.site-hd .btn.sm{flex:none;white-space:nowrap}
/* ...and no nav label may wrap. Found on the LIVE page an hour after the
   switcher shipped (2026-09-21): between 961px and about 1100px — a 1024px
   laptop, a tablet on its side — the header had been exactly full, the
   switcher was one thing too many, and "Live demo" became two lines. So the
   labels never wrap, the spacing tightens where the room runs out, and the
   Thai page — whose labels are longer — hands over to the menu button sooner
   (its own block, under "Thai" below). */
.site-nav a{white-space:nowrap}
/* Bounded below: under 961px the nav is the menu, and the phone rules above
   set their own gap — an open-ended query here would outrank them by order.
   960.01 and not 961: on a scaled display a window can be 960.8px wide, which
   is neither "at most 960" nor "at least 961" — no rule applied, the bar
   overflowed and the whole page scrolled sideways. */
@media(min-width:960.01px) and (max-width:1180px){
  .site-hd .wrap{gap:18px}
  .site-nav{gap:16px;font-size:14px}
}
/* The contact link inside the menu — only where the header has no room left
   for its own button (below). */
.site-nav .nav-cta{display:none}
@media(max-width:400px){
  .site-hd .wrap{gap:8px}
  .site-hd .btn.sm{padding:10px 11px;font-size:13px}
}
/* 320px phones: brand, switcher, button and menu do not fit in 280px whatever
   is shaved off them, so the button goes into the menu as its last link. */
@media(max-width:350px){
  .site-hd .btn.sm{display:none}
  .site-nav .nav-cta{display:block;font-weight:700;color:var(--ink)}
}

/* ---------- Thai (/th) ----------
   The three brand faces carry no Thai, so the browser falls through the stack
   glyph by glyph: Latin stays in the brand face, Thai lands in Noto Sans Thai
   (loaded by th/index.html only). Two things the Latin rules get wrong for it:
   NEGATIVE TRACKING pulls a consonant under its neighbour's vowel mark, and a
   line-height under 1 cuts the tone marks stacked above the line — the hero's
   line-by-line reveal clips at the box, so it needs the headroom inside it. */
:root:lang(th){
  --display:'Bricolage Grotesque','Noto Sans Thai','Leelawadee UI','Thonburi',system-ui,sans-serif;
  --body:'Figtree','Noto Sans Thai','Leelawadee UI','Thonburi',system-ui,-apple-system,sans-serif;
  --mono:'DM Mono','Noto Sans Thai',ui-monospace,'Courier New',monospace;
}
:lang(th) body{line-height:1.7}
/* Tracking, everywhere and outranking every rule above: the tight display
   headings AND the wide mono labels (.sect, .eyebrow, .tag, the day strip) are
   both Latin habits. Wide tracking pulls a Thai word apart into letters, and
   there are two dozen such rules — naming them one by one is how the next label
   added in English arrives on /th spaced out. */
:lang(th) *{letter-spacing:0 !important}
:lang(th) h1{font-size:clamp(38px,4.6vw,66px);line-height:1.22}
:lang(th) h2{font-size:clamp(30px,3.3vw,46px);line-height:1.3}
:lang(th) .ln{padding-top:.32em;margin-top:-.32em}
:lang(th) .rot{padding-top:.32em;margin-top:-.32em}
:lang(th) :is(.lede,.hero .lede){line-height:1.8}
@media(max-width:640px){ :lang(th) h1{font-size:36px} }
/* The Thai nav labels are longer than the English ones, so the bar runs out of
   room sooner: the same hand-over to the menu button the 960px rule makes,
   from 1080px. The open-menu rules are that block's own, repeated because a
   media query cannot be borrowed. */
@media(min-width:960.01px) and (max-width:1080px){
  :lang(th) .site-nav{display:none}
  :lang(th) .menu-btn{display:grid}
  :lang(th) .lang-sw{margin-left:auto}
  :lang(th) .site-hd.open .site-nav{display:flex;position:absolute;top:100%;left:0;right:0;flex-direction:column;
    align-items:stretch;gap:0;background:var(--paper);border-bottom:2px solid var(--ink);padding:6px 40px 14px}
  :lang(th) .site-hd.open .site-nav a{padding:12px 0;border-bottom:1.5px solid var(--line);font-size:17px}
}
