1<!doctype html> 2<html lang="en"> 3<head> 4 <!-- 5 THE PLACE â PERMANENT SINGLE-FILE SITE 6 ----------------------------------------------------------- 7 Structure overview (use the search box in your editor to jump): 8 01) Global meta + theme variables 9 02) Header / Navigation 10 03) Hero (cross-fade slider) 11 04) Villas grid 12 05) Testimonials carousel 13 06) Trust strip (TA award + OTA badges) 14 07) Why Us (simple feature list) 15 08) Location / Map placeholder 16 09) Contact footer 17 18 Notes: 19 ⢠Paths are relative to ROOT. Keep images in /images and assets in /assets 20 ⢠Hero images recommended 1920Ã1080 (WebP @ quality 80â85) 21 ⢠Edit copy inline; styles live in the <style> block below 22 --> 23 <meta charset="utf-8" /> 24 <meta name="viewport" content="width=device-width, initial-scale=1" /> 25 <title>The Place Luxury Boutique Villas | Koh Tao</title> 26 <meta name="description" content="Private luxury pool villas in Koh Tao. Total privacy, jungle and sea views, sunset pools and personal service. Book direct for the best experience. 27" /> 28 <link rel="canonical" href="https://theplacekohtao.com/" /> 29 30 <link rel="icon" href="assets/favicon.ico"> 31 <link rel="icon" type="image/svg+xml" href="assets/favicon.svg"> 32 <link rel="apple-touch-icon" href="assets/apple-touch-icon.png"> 33 <link rel="stylesheet" href="assets/site.css"> 34 35 36 37 <style> 38 /* --------------------------------------------------------- 39 HERO â moved from inline styles 40 ------------------------------------------------------- */ 41 .hero-clip { 42 position: relative; 43 overflow: hidden; 44 } 45 46 .hero-dots { 47 position: absolute; 48 bottom: 2%; 49 left: 50%; 50 transform: translateX(-50%); 51 display: flex; 52 gap: 8px; 53 z-index: 10; 54 } 55 56 /* Hero dots as accessible buttons */ 57 .hero-dots .hero-dot { 58 width: 10px; 59 height: 10px; 60 border-radius: 999px; 61 background: #ccc; 62 border: 0; 63 padding: 0; 64 cursor: pointer; 65 transition: background .3s; 66 } 67 68 .hero-dots .hero-dot[aria-current="true"] { 69 background: #00bcd4; 70 } 71 72 .hero-dots .hero-dot:focus-visible { 73 outline: 2px solid var(--brand2); 74 outline-offset: 4px; 75 } 76 77 /* Reviews dots as accessible buttons */ 78 .review-dots { 79 margin-top: 1.5rem; 80 display: flex; 81 justify-content: center; 82 gap: 8px; 83 } 84 85 .review-dots .review-dot { 86 width: 10px; 87 height: 10px; 88 border-radius: 999px; 89 background: #bbb; 90 border: 0; 91 padding: 0; 92 cursor: pointer; 93 transition: background .3s; 94 } 95 96 .review-dots .review-dot[aria-current="true"] { 97 background: #00bcd4; 98 } 99 100 .review-dots .review-dot:focus-visible { 101 outline: 2px solid var(--brand2); 102 outline-offset: 4px; 103 } 104 105 .hero-box { 106 position: absolute; 107 left: 50%; 108 transform: translateX(-50%); 109 text-align: center; 110 max-width: 88%; 111 background: rgba(0, 0, 0, 0.28); 112 /* match lpv text box opacity */ 113 padding: 1.25rem 1.75rem; 114 border-radius: 12px; 115 backdrop-filter: none; 116 /* remove blur */ 117 box-shadow: 0 10px 35px rgba(0, 0, 0, .35); 118 } 119 120 121 .hero-box-title { 122 top: 16%; 123 } 124 125 .hero-box-sub { 126 bottom: 10%; 127 max-width: 900px; 128 padding: 1rem 1.5rem; 129 } 130 131 .hero-cta-row { 132 display: flex; 133 justify-content: center; 134 gap: 1rem; 135 margin: 16px 0 8px; 136 } 137 138 /* --------------------------------------------------------- 139 HERO TEXT â moved from inline styles 140 ------------------------------------------------------- */ 141 .hero-box h1 { 142 color: #fff; 143 margin: 0; 144 text-shadow: 0 2px 10px rgba(0, 0, 0, 0.55); 145 font-size: clamp(2.4rem, 3vw, 3.2rem); 146 /* DESKTOP HERO H1 SIZE */ 147 line-height: 1.15; 148 } 149 150 .hero-box p { 151 color: #fff; 152 margin: 0; 153 line-height: 1.6; 154 text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5); 155 } 156 157 /* DESKTOP HERO SUBLINE SIZE (only the sub box) */ 158 .hero-box-sub p { 159 font-size: 1.15rem; 160 } 161 162 /* ========================= 163 HERO MOBILE REFLOW 164 ========================= */ 165 @media (max-width: 760px) { 166 167 /* Give the hero some breathing room */ 168 .hero { 169 min-height: 72vh; 170 padding: 72px 16px 22px; 171 place-items: stretch; 172 align-items: end; 173 } 174 175 /* Convert absolute overlay boxes into normal flow blocks */ 176 .hero-box { 177 position: relative; 178 left: auto; 179 top: auto; 180 bottom: auto; 181 transform: none; 182 max-width: 100%; 183 width: 100%; 184 margin: 0 auto 12px; 185 text-align: center; 186 } 187 188 .hero-box h1 { 189 font-size: clamp(1.6rem, 6.5vw, 2.2rem); 190 line-height: 1.1; 191 } 192 193 .hero-box p { 194 font-size: 1.05rem; 195 /* MOBILE HERO SUBLINE SIZE */ 196 line-height: 1.6; 197 } 198 199 /* If your hero CTA is outside the hero, make it feel connected */ 200 .hero-cta-row { 201 padding: 0 16px; 202 } 203 204 .hero-cta-row .btn { 205 width: 100%; 206 justify-content: center; 207 } 208 } 209 210 /* --------------------------------------------------------- 211 04) HERO with CROSS-FADE SLIDER 212 ------------------------------------------------------- */ 213 .hero { 214 position: relative; 215 isolation: isolate; 216 min-height: 68vh; 217 display: grid; 218 place-items: center; 219 } 220 221 .hero-media { 222 position: absolute; 223 inset: 0; 224 z-index: -1; 225 opacity: .22; 226 background: radial-gradient(800px 420px at 80% -10%, rgba(20, 184, 166, .22), transparent 60%), radial-gradient(800px 420px at -10% 0%, rgba(56, 189, 248, .16), transparent 55%) 227 } 228 229 .hero-slides { 230 position: absolute; 231 inset: 0; 232 z-index: -2; 233 overflow: hidden 234 } 235 236 .hslide { 237 position: absolute; 238 inset: 0; 239 width: 100%; 240 height: 100%; 241 object-fit: cover; 242 opacity: 0; 243 transition: opacity .8s ease 244 } 245 246 .hslide.show { 247 opacity: 1 248 } 249 250 .hero-inner { 251 display: grid; 252 gap: 1.1rem; 253 text-align: center; 254 padding: 88px 0 44px; 255 max-width: 1100px; 256 margin: 0 auto 257 } 258 259 .eyebrow { 260 text-transform: uppercase; 261 font-size: .8rem; 262 letter-spacing: .2em; 263 color: var(--muted) 264 } 265 266 h1 { 267 font-size: clamp(2rem, 2.6vw + 1rem, 3rem); 268 line-height: 1.15; 269 margin: 0 270 } 271 272 .lede { 273 color: #d7dde6; 274 max-width: 58ch; 275 margin: 0 auto 276 } 277 278 .cta-row { 279 display: flex; 280 gap: .8rem; 281 justify-content: center; 282 flex-wrap: wrap; 283 margin-top: .6rem 284 } 285 286 /* --------------------------------------------------------- 287 05) VILLAS GRID 288 ------------------------------------------------------- */ 289 main { 290 text-align: center 291 } 292 293 h2 { 294 font-size: 2rem; 295 margin: 2.2rem 0 1.2rem 296 } 297 298 .villas { 299 display: grid; 300 grid-template-columns: repeat(12, 1fr); 301 gap: 18px; 302 max-width: 1100px; 303 margin: 0 auto 3rem; 304 padding: 0 20px 305 } 306 307 .villa { 308 grid-column: span 12; 309 background: linear-gradient(180deg, var(--card), var(--card2)); 310 border-radius: 16px; 311 overflow: hidden; 312 border: 1px solid var(--line); 313 box-shadow: 0 10px 30px rgba(0, 0, 0, .35); 314 text-align: left 315 } 316 317 .villa img { 318 width: 100%; 319 aspect-ratio: 16/10; 320 object-fit: cover 321 } 322 323 .villa h3 { 324 padding: 1rem 1rem .4rem; 325 font-size: 1.2rem 326 } 327 328 .villa p { 329 padding: 0 1rem 1rem; 330 color: var(--muted) 331 } 332 333 .villa .btn { 334 margin: 0 0 1rem 1rem 335 } 336 337 @media(min-width:860px) { 338 .villa { 339 grid-column: span 4 340 } 341 } 342 343 /* --------------------------------------------------------- 344 06) TESTIMONIALS CAROUSEL 345 ------------------------------------------------------- */ 346 .twrap { 347 max-width: 960px; 348 margin: 0 auto; 349 padding: 0 20px 350 } 351 352 .carousel { 353 position: relative 354 } 355 356 .t-slides { 357 display: grid; 358 grid-template-columns: 100% 100% 100%; 359 transition: transform .5s ease 360 } 361 362 .t-card { 363 background: #0f141a; 364 border: 1px solid var(--line); 365 border-radius: var(--radius); 366 padding: 22px; 367 min-height: 140px; 368 display: flex; 369 align-items: flex-start; 370 gap: 10px 371 } 372 373 .t-card .badge { 374 margin-right: 8px 375 } 376 377 .t-dots { 378 display: flex; 379 gap: 8px; 380 justify-content: center; 381 margin-top: 14px 382 } 383 384 .t-dots .dot { 385 width: 8px; 386 height: 8px; 387 border-radius: 50%; 388 background: #2a3340; 389 border: 1px solid #3a4656 390 } 391 392 .t-dots .dot[aria-current="true"] { 393 background: var(--brand) 394 } 395 396 /* --------------------------------------------------------- 397 07) TRUST STRIP (TA + OTA badges) 398 ------------------------------------------------------- */ 399 .strip { 400 background: var(--card); 401 border-top: 1px solid var(--line); 402 border-bottom: 1px solid var(--line); 403 padding: 30px 0; 404 margin-bottom: 18px; 405 } 406 407 .pill { 408 display: inline-flex; 409 align-items: center; 410 gap: 8px; 411 border: 1px solid #243142; 412 background: #10171f; 413 color: #cde4f7; 414 border-radius: 999px; 415 padding: 8px 12px; 416 font-weight: 700 417 } 418 419 .ota { 420 display: inline-flex; 421 align-items: center 422 } 423 424 .ota img { 425 height: 34px; 426 width: auto; 427 display: block; 428 border-radius: 6px 429 } 430 431 432 /* --------------------------------------------------------- 433 08) WHY US (simple feature list) 434 ------------------------------------------------------- */ 435 .why { 436 max-width: 1100px; 437 margin: 0 auto 30px; 438 padding: 0 20px; 439 display: grid; 440 grid-template-columns: repeat(12, 1fr); 441 gap: 16px 442 } 443 444 .why .card { 445 grid-column: span 12; 446 background: var(--card); 447 border: 1px solid var(--line); 448 border-radius: var(--radius); 449 padding: 18px 450 } 451 452 .why .card h3 { 453 font-size: 1.05rem; 454 margin-bottom: 6px 455 } 456 457 .why .card p { 458 color: var(--muted) 459 } 460 461 @media(min-width:860px) { 462 .why .card { 463 grid-column: span 4 464 } 465 } 466 467 /* Centre text inside Why Us cards */ 468 .why .card { 469 text-align: center; 470 } 471 472 /* --------------------------------------------------------- 473 09) MAP + FOOTER 474 ------------------------------------------------------- */ 475 #map { 476 width: 100%; 477 height: 400px; 478 background: #1b2430; 479 border-top: 1px solid var(--line); 480 border-bottom: 1px solid var(--line) 481 } 482 483 footer { 484 border-top: 1px solid var(--line); 485 background: #0f141a; 486 text-align: center; 487 padding: 18px 12px; 488 color: var(--muted) 489 } 490 </style> 491 492 <!-- Google Analytics -->
vendor: 66 bytes, lines 492-493
492 493 <script async src="https://www.googletagmanager.com/gtag/js?id=
493G-M68X6H7HCC
vendor: 14 bytes, lines 493-494
493"></script> 494
494<script> 495
vendor: 142 bytes, lines 495-498
495window.dataLayer = window.dataLayer || []; 496 function gtag() { dataLayer.push(arguments); } 497 gtag('js', new Date()); 498 gtag('config', '
498G-M68X6H7HCC
vendor: 6 bytes, lines 498-499
498'); 499
499</script>
499 500 501 <!-- Meta Pixel Code --> 502
502<script>
vendor: 521 bytes, lines 502-514
502 503 !function (f, b, e, v, n, t, s) { 504 if (f.fbq) return; n = f.fbq = function () { 505 n.callMethod ? 506 n.callMethod.apply(n, arguments) : n.queue.push(arguments) 507 }; 508 if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = '2.0'; 509 n.queue = []; t = b.createElement(e); t.async = !0; 510 t.src = v; s = b.getElementsByTagName(e)[0]; 511 s.parentNode.insertBefore(t, s) 512 }(window, document, 'script', 513 'https://connect.facebook.net/en_US/fbevents.js'); 514 fbq('init', '
514877011314828584
vendor: 36 bytes, lines 514-516
514'); 515 fbq('track', 'PageView'); 516
516</script>
516 517 <noscript><img height="1" width="1" style="display:none" 518 src="https://www.facebook.com/tr?id=877011314828584&ev=PageView&noscript=1" /></noscript> 519 <!-- End Meta Pixel Code --> 520 521 <!-- Mirai core CSS --> 522 <link rel="stylesheet" id="mirai-engine-2023-css" href="https://static.mirai.com/core/index.css" type="text/css" 523 media="all" /> 524 <link rel="stylesheet" href="./core-variables.css"> 525 <link rel="stylesheet" href="./mirai-overrides.css"> 526 527</head> 528<body> 529 530 <!-- Mirai ID --> 531 <div data-mirai-id="100380316"></div> 532 533 534 <!-- ===================== HEADER ===================== --> 535 <header class="site"> 536 <div class="bar nav nav-wrap"> 537 538 539 <a class="brand brand-link" href="index.html" aria-label="Homepage"> 540 541 <img class="brand-logo" src="images/the-place-header-mark.svg" alt="The Place"> 542 543 544 <span class="brand-title">Luxury Boutique Villas ⢠Koh Tao 545 </span> 546 </a> 547 548 <button class="nav-toggle" type="button" aria-label="Open menu" aria-expanded="false" aria-controls="site-nav"> 549 <span></span><span></span><span></span> 550 </button> 551 552 553 <nav id="site-nav" class="nav-links" aria-label="Primary"> 554 555 <!-- Desktop Villas link --> 556 <a class="nav-villas" href="#villas">Villas</a> 557 558 <!-- Mobile first row: Villas + toggle --> 559 <div class="nav-row"> 560 <a href="#villas">Villas</a> 561 562 <button class="theme-switch mobile-theme-toggle" id="themeToggleMobile" type="button" 563 aria-label="Toggle theme" aria-pressed="false"> 564 <span class="theme-switch__track" aria-hidden="true"> 565 <span class="theme-switch__knob"></span> 566 <span class="theme-switch__icon theme-switch__icon--moon">â¾</span> 567 <span class="theme-switch__icon theme-switch__icon--sun">â</span> 568 </span> 569 </button> 570 </div> 571 572 <a href="#why" style="white-space: nowrap;">Why Us</a> 573 <a href="#guest-kind-words">Reviews</a> 574 <a href="#contact">Contact</a> 575 576 <!-- Desktop theme toggle (RIGHT side) --> 577 <button class="theme-switch desktop-theme-toggle" id="themeToggle" type="button" 578 aria-label="Toggle theme" aria-pressed="false"> 579 <span class="theme-switch__track" aria-hidden="true"> 580 <span class="theme-switch__knob"></span> 581 <span class="theme-switch__icon theme-switch__icon--moon">â¾</span> 582 <span class="theme-switch__icon theme-switch__icon--sun">â</span> 583 </span> 584 </button> 585 586 <a class="btn btn-primary" 587 href="https://reservation.mirai.com/XMAS/reservation/miraiFrontDispatcher.htm?lang=en&idtokenprovider=100380316#url=true"> 588 Check availability 589 </a> 590 591</nav> 592 593 594 595 </div> 596 </header> 597 598 <!-- ===================== HERO ===================== --> 599 <section class="hero hero-clip" id="top"> 600 601 <div class="hero-media"></div> 602 603 <!-- Cross-fade slider images --> 604 <div class="hero-slides" id="hero-slides"> 605 <img class="hslide show" alt="Luxury pool villa bedroom with canopy bed and warm wooden interiors" 606 data-live="images/01-1920x1080sml.webp" fetchpriority="high" style="object-position:50% 70%;" /> 607 608 <img class="hslide" alt="Open-air bathroom with natural rock wall and tropical plants in a luxury villa" 609 data-live="images/02-1920x1080sml.webp" loading="lazy" style="object-position:50% 50%;" /> 610 611 <img class="hslide" alt="Open-plan living area and kitchen inside a luxury pool villa" 612 data-live="images/03-1920x1080sml.webp" loading="lazy" style="object-position:50% 70%;" /> 613 614 <img class="hslide" alt="Aerial view of a private luxury pool villa surrounded by tropical jungle" 615 data-live="images/04-1920x1080sml.webp" loading="lazy" style="object-position:50% 80%;" /> 616 617 <img class="hslide" alt="Secluded luxury pool villa nestled in lush jungle on Koh Tao" 618 data-live="images/05-1920x1080sml.webp" loading="lazy" style="object-position:50% 80%;" /> 619 620 <img class="hslide" alt="Sunset reflected in a private infinity pool overlooking Koh Tao" 621 data-live="images/06-1920x1080sml.webp" loading="lazy" style="object-position:50% 50%;" /> 622 623 <img class="hslide" alt="Private terrace with infinity pool and sea views from a luxury villa" 624 data-live="images/07-1920x1080sml.webp" loading="lazy" style="object-position:50% 57%;" /> 625 </div> 626 627 <!-- Navigation dots --> 628 <div class="hero-dots" id="hero-dots"></div> 629 630 631 632 633 <!-- Hero title + subtext overlays (separate boxes) --> 634 <div class="hero-box hero-box-title"> 635 <h1>Luxury Pool Villas
636 <span class="hero-subtitle">Koh Tao, Thailand</span> 637 </h1> 638 </div> 639 640 <div class="hero-box hero-box-sub"> 641 <p class="hero-subline"> 642 Pure privacy and sunset views. Calm, space and personal service away from the crowds.</p> 643 </div> 644 645 <div class="hero-cta hero-cta-row"> 646 </div> 647 </section> 648 649 650 651 <!-- ============ HERO SLIDER SCRIPT (auto cross-fade + dots) ============ --> 652
652<script> 653 (function () { 654 const container = document.getElementById('hero-slides'); 655 const dotsContainer = document.getElementById('hero-dots'); 656 if (!container || !dotsContainer) return; 657 658 const slides = Array.from(container.querySelectorAll('.hslide')); 659 if (slides.length < 2) return; 660 661 // Ensure slides are positioned and initialise src from data-live 662 slides.forEach((img) => { 663 img.style.position = 'absolute'; 664 img.style.inset = '0'; 665 img.style.width = '100%'; 666 img.style.height = '100%'; 667 img.style.objectFit = 'cover'; 668 img.style.transition = 'opacity .8s ease'; 669 img.style.opacity = img.classList.contains('show') ? '1' : '0'; 670 671 const live = img.getAttribute('data-live'); 672 if (live && !img.src) img.src = live; 673 }); 674 675 // Build dots as <button> elements that use your CSS: 676 // .hero-dots .hero-dot and [aria-current="true"] 677 dotsContainer.innerHTML = ''; 678 slides.forEach((_, i) => { 679 const btn = document.createElement('button'); 680 btn.type = 'button'; 681 btn.className = 'hero-dot'; 682 btn.setAttribute('aria-label', `Show slide ${i + 1}`); 683 if (i === 0) btn.setAttribute('aria-current', 'true'); 684 btn.addEventListener('click', () => go(i, true)); 685 dotsContainer.appendChild(btn); 686 }); 687 688 const dots = Array.from(dotsContainer.querySelectorAll('.hero-dot')); 689 690 // Determine initial slide index from .show (fallback to 0) 691 let idx = slides.findIndex((s) => s.classList.contains('show')); 692 if (idx < 0) idx = 0; 693 694 // Normalise initial state: only idx is visible + marked current 695 slides.forEach((img, i) => { 696 if (i === idx) { 697 img.classList.add('show'); 698 img.style.opacity = '1'; 699 } else { 700 img.classList.remove('show'); 701 img.style.opacity = '0'; 702 } 703 }); 704 705 dots.forEach((d, i) => { 706 if (i === idx) d.setAttribute('aria-current', 'true'); 707 else d.removeAttribute('aria-current'); 708 }); 709 710 function setDots() { 711 dots.forEach((d, i) => { 712 if (i === idx) d.setAttribute('aria-current', 'true'); 713 else d.removeAttribute('aria-current'); 714 }); 715 } 716 717 function go(next, userInitiated) { 718 const prevIdx = idx; 719 idx = (next + slides.length) % slides.length; 720 721 if (idx === prevIdx) return; 722 723 const prev = slides[prevIdx]; 724 const curr = slides[idx]; 725 726 curr.style.opacity = '1'; 727 curr.classList.add('show'); 728 729 prev.style.opacity = '0'; 730 prev.classList.remove('show'); 731 732 setDots(); 733 734 if (userInitiated) restart(); 735 } 736 737 function next() { 738 go(idx + 1, false); 739 } 740 741 let timer = null; 742 function start() { 743 timer = setInterval(next, 4000); 744 } 745 function stop() { 746 if (timer) clearInterval(timer); 747 timer = null; 748 } 749 function restart() { 750 stop(); 751 start(); 752 } 753 754 const hero = document.querySelector('.hero'); 755 if (hero) { 756 hero.addEventListener('mouseenter', stop); 757 hero.addEventListener('mouseleave', start); 758 } 759 760 start(); 761 })(); 762 </script>
762 763 764<!-- ===================== AVAILABILITY FINDER ===================== --> 765<section class="finder-section" aria-label="Availability finder"> 766 <div class="container"> 767 <div class="finder_component"> 768 <div data-mirai-component="finder"></div> 769 </div> 770 </div> 771</section> 772 773 <section class="hero-bridge"> 774 <div class="container"> 775 <p class="lede"> 776 Set in the hills above Sairee Beach on Koh Tao, our private luxury pool villas offer sunset and sea views away 777 from the crowds. Each villa is fully self-contained with its own pool, jungle surroundings and calm, personal 778 service. 779 </p> 780 </div> 781 </section> 782 783 784 <!-- ======================== VILLAS ======================== --> 785 <main> 786 <h2 id="villas">Our 8 Pool Villas</h2> 787 <div class="villas"> 788 <article class="villa"> 789 <img src="images/select-lpv.webp" alt="Luxury Pool Villa"> 790 <h3>6 Luxury Pool Villas</h3> 791 <p>Elegant privacy with infinity-edge pool and sunset views.</p> 792 <a class="btn btn-primary" href="lpv.html">View Details</a> 793 </article> 794 795 <article class="villa"> 796 <img src="images/select-hv.webp" alt="Honeymoon Villa"> 797 <h3>Our Honeymoon Villa</h3> 798 <p>Perfect romantic hideaway with panoramic sea views.</p> 799 <a class="btn btn-primary" href="hv.html">View Details</a> 800 </article> 801 802 <article class="villa"> 803 <img src="images/select-fff.webp" alt="Friends & Family Villa"> 804 <h3>Our Friends & Family Villa</h3> 805 <p>Modular in design to accommodate a third adult</p> 806 <a class="btn btn-primary" href="fff.html">View Details</a> 807 </article> 808 </div> 809 </main> 810 811 812 <div id="why"></div> 813 <!-- ===================== OTA SCORES ===================== --> 814 <section class="strip" id="trust" aria-label="OTA scores"> 815 <div class="bar" style="display:flex;flex-direction:column;align-items:center;gap:18px;flex-wrap:wrap"> 816 <div style="display:flex;justify-content:center;align-items:center;gap:22px;flex-wrap:wrap"> 817 <span class="ota"><img src="images/ota-booking.png" alt="Booking.com score"></span> 818 <span class="ota"><img src="images/ota-agoda.png" alt="Agoda score"></span> 819 <span class="ota"><img src="images/ota-expedia.png" alt="Expedia score"></span> 820 <span class="ota"><img src="images/ota-airbnb.png" alt="Airbnb rating"></span> 821 <span class="ota"><img src="images/ota-tripadvisor.png" alt="Tripadvisor rating"></span> 822 <span class="ota"><img src="images/ota-gmap.png" alt="Google rating"></span> 823 </div> 824 <p 825 style="color:#fff;font-size:1.1rem;margin-top:14px;text-align:center;font-weight:700;background:linear-gradient(90deg,var(--brand),var(--brand2));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:0.4px;text-shadow:0 0 10px rgba(56,189,248,0.4);"> 826 â You can book with them but itâs better to book direct â 827 </p> 828 829 830 <details class="why-direct"> 831 <summary>â¾ Why book directly with us? â¾</summary> 832 833 <div class="why-direct__body"> 834 <ul class="why-direct__list"> 835 <li>Weâll prioritise your Villa choice</li> 836 <li>Early check-in / late check-out where possible</li> 837 <li>Flexible payment options</li> 838 <li>Weâll organise your pier pickup with our driver</li> 839 <li>Our team will give you a personal Villa orientation</li> 840 <li>If an OTA undercuts us, weâll try to match it fairly</li> 841 <li>Youâre talking to real people who run the place</li> 842 <li>Fewer commissions make us more smiley humans ;)</li> 843 </ul> 844 845 <p class="why-direct__note"> 846 All subject to availability. No nonsense, no middlemen. 847 </p> 848 </div> 849 </details> 850 851 <div class="mobile-cta"> 852 <a class="btn btn-primary btn-compact" 853 href="https://reservation.mirai.com/XMAS/reservation/miraiFrontDispatcher.htm?lang=en&idtokenprovider=100380316#url=true"> 854 Check availability 855 </a> 856 </div> 857 858 859 860 </section> 861 862 863 864 865 <!-- ======================== WHY US ======================= --> 866 <section aria-label="Why stay with us"> 867 <div class="why"> 868 <div class="card"> 869 <h3>True Privacy</h3> 870 <p>Each villa is freestanding with its own pool and jungle surroundings. Designed so that your time together 871 stays yours.</p> 872 </div> 873 <div class="card"> 874 <h3>Sunset Views</h3> 875 <p>Our Villas are all West-facing giving you the best sunset views from your private pool and balcony.</p> 876 </div> 877 <div class="card"> 878 <h3>
878Direct-Only Benefits</h3> 879 <p>Best price direct, flexible housekeeping and quick help on WhatsApp whenever you need a hand.</p> 880 </div> 881 </div> 882 </section> 883 884 <!-- ===================== Drone Video ===================== --> 885 886 <section class="video-section"> 887 <div class="video-card"> 888 <h2>What to expect...</h2> 889 <p>A short aerial view of our Villas and their surroundings</p> 890 891 <div class="video-embed"> 892 <iframe src="https://www.youtube.com/embed/NpPLDl9I34M" title="The Place Koh Tao drone video" frameborder="0" 893 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 894 allowfullscreen> 895 </iframe> 896 </div> 897 </div> 898 </section> 899 900 901 <!-- ===================== WHY US PERSONAL TOUCH ===================== --> 902 <section id="why-us-personal"> 903 904 <div class="personal-card"> 905 906 907 <div style="display: flex; justify-content: center;"> 908 <img src="images/guy.webp" alt="Guy Welply" 909 style="width: 160px; height: 160px; border-radius: 50%; object-fit: cover; border: 4px solid rgba(255,255,255,0.8); margin-bottom: 1.5rem;"> 910 </div> 911 <blockquote 912 style="font-size: 1.1rem; line-height: 1.8; font-weight: 400; margin-bottom: 2rem; text-align: center;"> 913 âIf privacy matters to you, youâll feel at home here. Each Villa stands alone with its own space and pool and we 914 follow a strict 'Do Not Disturb' approach.<br><br> 915 916 Once you close the gate to your Villa, we step back. No scheduled housekeeping visits, no reception calls, no 917 interruptions. Itâs your time and we respect that.<br><br> 918 919 If you need anything at all, just get in touch. Weâre nearby and always happy to help â but only when you ask.â 920 </blockquote> 921 <p style="font-size: 1.1rem; font-weight: 600; margin: 0; text-align: center;">Guy, <span 922 style="font-weight: 400; opacity: 0.9;">Co-founder</span></p> 923 </div> 924 </section> 925 926 927 <!-- ===================== GUEST KIND WORDS SCROLLER ===================== --> 928 <section id="guest-kind-words"> 929 930 931 <div style="position: relative; z-index: 1;"> 932 <h2 style="font-size: 2rem; margin-bottom: 2rem; ">Guests' Kind Words</h2> 933 <div id="reviews-container" style="max-width: 800px; margin: 0 auto; position: relative; overflow: hidden;"> 934 <div class="review-slide" style="min-width: 100%; transition: transform 0.8s ease;"> 935 <p style="font-size: 1.1rem; line-height: 1.7; color: #fff;">âAn unforgettable stay! The view, privacy, and 936 attention to detail were beyond expectations.â</p> 937 <p style="font-weight: 600; opacity: 0.9;">â Olivia & Mark</p> 938 </div> 939 <div class="review-slide" style="min-width: 100%; transition: transform 0.8s ease;"> 940 <p style="font-size: 1.1rem; line-height: 1.7; color: #fff;">âThe best villa experience we've ever had. Truly 941 private and luxurious.â</p> 942 <p style="font-weight: 600; opacity: 0.9;">â Sophie, UK</p> 943 </div> 944 <div class="review-slide" style="min-width: 100%; transition: transform 0.8s ease;"> 945 <p style="font-size: 1.1rem; line-height: 1.7; color: #fff;">âAbsolutely magical sunsets and perfect peace. 946 Can't wait to return.â</p> 947 <p style="font-weight: 600; opacity: 0.9;">â Daniel, Australia</p> 948 </div> 949 </div> 950 <div class="review-dots" role="tablist" aria-label="Guest reviews"> 951 <button class="review-dot" type="button" aria-label="Show review 1" aria-current="true"></button> 952 <button class="review-dot" type="button" aria-label="Show review 2"></button> 953 <button class="review-dot" type="button" aria-label="Show review 3"></button> 954 </div> 955 956 </div> 957 </section> 958 959
959<script> 960 (function () { 961 const root = document.getElementById('guest-kind-words'); 962 if (!root) return; 963 964 const slides = Array.from(root.querySelectorAll('.review-slide')); 965 const dots = Array.from(root.querySelectorAll('.review-dot')); 966 if (slides.length === 0 || dots.length === 0) return; 967 968 let current = 0; 969 970 function showSlide(index) { 971 current = (index + slides.length) % slides.length; 972 973 slides.forEach((slide, i) => { 974 slide.style.position = 'absolute'; 975 slide.style.inset = '0'; 976 slide.style.transition = 'opacity 0.6s ease'; 977 slide.style.opacity = (i === current) ? '1' : '0'; 978 slide.style.pointerEvents = (i === current) ? 'auto' : 'none'; 979 }); 980 981 dots.forEach((dot, i) => { 982 if (i === current) dot.setAttribute('aria-current', 'true'); 983 else dot.removeAttribute('aria-current'); 984 }); 985} 986 987 988 dots.forEach((dot, i) => { 989 dot.addEventListener('click', () => showSlide(i)); 990 }); 991 992 showSlide(0); 993 setInterval(() => showSlide(current + 1), 6000); 994 })(); 995 </script>
995 996 997 998 999 1000 <!-- ======================== MAP ========================== --> 1001 <section id="contact" aria-label="Find us" style="text-align:center;padding:3rem 0"> 1002 <h2>Find Us</h2> 1003 <p class="lede">14/167 Moo 1, Koh Tao, Suratthani, Thailand 84360</p> 1004 <p class="subtle-note"> 1005 Located in the hills just above Sairee Beach. We're about a 10 minute walk to Sairee or a couple of minutes on a 1006 moped or in a taxi. 1007 </p> 1008 <div class="map-embed"> 1009 <iframe 1010 src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d4664.429571964392!2d99.83518801431451!3d10.101769301925444!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3055a1dd7b4529b7%3A0xafc92e704c32599e!2sThe%20Place%20Luxury%20Boutique%20Villas!5e1!3m2!1sen!2sth!4v1766760469304!5m2!1sen!2sth" 1011 loading="lazy" referrerpolicy="no-referrer-when-downgrade" 1012 aria-label="Map showing location of The Place Luxury Boutique Villas Koh Tao" allowfullscreen> 1013 </iframe> 1014 </div> 1015 1016 1017 </section> 1018 1019 <!-- ======================== FOOTER ======================= --> 1020 <footer> 1021 <div class="footer-inner"> 1022 <div class="footer-divider"></div> 1023 1024 <div class="footer-title">The Place Luxury Boutique Villas, Koh Tao, Thailand</div> 1025 1026 <div class="footer-contact"> 1027 <a href="mailto:[email protected]">[email protected]</a> 1028 1029 <a href="https://wa.me/66632391525" target="_blank" rel="noopener" 1030 onclick="gtag('event','whatsapp_click',{event_category:'contact'})"> 1031 WhatsApp +666 3239 1525 1032 </a> 1033 </div> 1034 1035 <div class="social-links"> 1036 <a href="https://www.instagram.com/theplacekohtao/" target="_blank" rel="noopener" aria-label="Instagram"> 1037 <svg viewBox="0 0 24 24" aria-hidden="true"> 1038 <path 1039 d="M12 2.2c3.2 0 3.6 0 4.9.07 1.2.06 2 .25 2.5.42a4.9 4.9 0 011.77 1.03 4.9 4.9 0 011.03 1.77c.17.5.36 1.3.42 2.5.07 1.3.07 1.7.07 4.9s0 3.6-.07 4.9c-.06 1.2-.25 2-.42 2.5a4.9 4.9 0 01-1.03 1.77 4.9 4.9 0 01-1.77 1.03c-.5.17-1.3.36-2.5.42-1.3.07-1.7.07-4.9.07s-3.6 0-4.9-.07c-1.2-.06-2-.25-2.5-.42a4.9 4.9 0 01-1.77-1.03 4.9 4.9 0 01-1.03-1.77c-.17-.5-.36-1.3-.42-2.5C2.2 15.6 2.2 15.2 2.2 12s0-3.6.07-4.9c.06-1.2.25-2 .42-2.5a4.9 4.9 0 011.03-1.77 4.9 4.9 0 011.77-1.03c.5-.17 1.3-.36 2.5-.42C8.4 2.2 8.8 2.2 12 2.2zm
10390 3.4a6.4 6.4 0 100 12.8 6.4 6.4 0 000-12.8zm0 10.6a4.2 4.2 0 110-8.4 4.2 4.2 0 010 8.4zm6.7-11.7a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z" /> 1040 </svg> 1041 </a> 1042 1043 <a href="https://www.facebook.com/theplacekohtao" target="_blank" rel="noopener" aria-label="Facebook"> 1044 <svg viewBox="0 0 24 24" aria-hidden="true"> 1045 <path 1046 d="M22 12a10 10 0 10-11.6 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.4h-1.3c-1.3 0-1.7.8-1.7 1.6V12h2.9l-.5 2.9h-2.4v7A10 10 0 0022 12z" /> 1047 </svg> 1048 </a> 1049 </div> 1050 1051 <div class="footer-small">© The Place Villas <span id="y"></span>. All rights reserved.</div> 1052 </div> 1053 </footer> 1054 1055 1056 1057 <!-- ======================== SCRIPTS ====================== --> 1058
1058<script> 1059 1060 // Put the current year into the footer 1061 document.getElementById('y').textContent = new Date().getFullYear(); 1062 1063 1064 // -------------------------------------------------------- 1065 </script>
1065 1066
1066<script> 1067 (function () { 1068 const btn = document.querySelector('.nav-toggle'); 1069 const nav = document.getElementById('site-nav'); 1070 if (!btn || !nav) return; 1071 1072 function closeMenu() { 1073 nav.classList.remove('is-open'); 1074 btn.setAttribute('aria-expanded', 'false'); 1075 btn.setAttribute('aria-label', 'Open menu'); 1076 } 1077 1078 function openMenu() { 1079 nav.classList.add('is-open'); 1080 btn.setAttribute('aria-expanded', 'true'); 1081 btn.setAttribute('aria-label', 'Close menu'); 1082 } 1083 1084 btn.addEventListener('click', () => { 1085 nav.classList.contains('is-open') ? closeMenu() : openMenu(); 1086 }); 1087 1088 nav.querySelectorAll('a').forEach(a => a.addEventListener('click', closeMenu)); 1089 1090 document.addEventListener('keydown', (e) => { 1091 if (e.key === 'Escape') closeMenu(); 1092 }); 1093 1094 document.addEventListener('click', (e) => { 1095 if (!nav.classList.contains('is-open')) return; 1096 if (nav.contains(e.target) || btn.contains(e.target)) return; 1097 closeMenu(); 1098 }); 1099 })(); 1100 </script>
1100 1101 1102 1103 <!-- Mirai core JS --> 1104
1104<script type="module" defer src="https://static.mirai.com/core/index.js"></script>
1104 1105 1106 1107
1108<script> 1109(function () { 1110 const root = document.documentElement; 1111 1112 const toggles = [ 1113 document.getElementById('themeToggle'), 1114 document.getElementById('themeToggleMobile') 1115 ].filter(Boolean); 1116 1117 if (!toggles.length) return; 1118 1119 function setTheme(theme) { 1120 root.setAttribute('data-theme', theme); 1121 localStorage.setItem('theme', theme); 1122 toggles.forEach(t => t.setAttribute('aria-pressed', theme === 'dark' ? 'true' : 'false')); 1123 } 1124 1125 // Init from saved theme (default light) 1126 const saved = localStorage.getItem('theme') || 'light'; 1127 setTheme(saved); 1128 1129 // Click handler for both buttons 1130 toggles.forEach(t => t.addEventListener('click', () => { 1131 const isDark = root.getAttribute('data-theme') === 'dark'; 1132 setTheme(isDark ? 'light' : 'dark'); 1133 })); 1134})(); 1135</script>
1135 1136 1137 1138 1139 1140 1141</body> 1142</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.