PageSourceSearch

https://theplacekohtao.com/index.html

html theplacekohtao.com collected 2026-10-08 10:32:12 UTC 35,075 bytes, 1,142 lines download raw bytes

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.