/* ปิ่น site shell — the parts EVERY page shares: palette, type scale, buttons,
   the sticky nav, the footer, and the reveal-on-scroll transition.
   Extracted from index.html once privacy.html had quietly drifted away from it
   (its own copy had a narrower .wrap, a shorter nav, no --ink3, and no favicon),
   which is what two hand-copied shells always turn into.

   Page-specific CSS stays in that page's inline <style>, which must be loaded
   AFTER this file so it keeps winning the cascade. */

:root{
  --blush:#F4F1EB; --blush-2:#FAF8F4; --white:#fff;
  --forest:#1B3A29; --green:#1C7A48; --green-2:#34B06A; --yellow:#F2B829;
  --ink:#2E2A24; --ink2:#6E6457; --ink3:#9A8F7E; --line:#E3DED2;
  /* --line is a hairline BETWEEN things (1.2:1 — fine, it separates, it does
     not bound a control). --edge is for the visible boundary of an actual
     control (chip, input): 3.5:1 on both page backgrounds, which is what
     WCAG 1.4.11 asks of non-text contrast and what --line never met. */
  --edge:#8A7F6E;
  --cardsh:0 1px 2px rgba(60,40,15,.05),0 10px 30px rgba(60,40,15,.08);
  --liftsh:0 2px 6px rgba(60,40,15,.07),0 22px 48px rgba(60,40,15,.12);
  --serif:'Trirong',Georgia,serif;
  --sans:'Sarabun','Leelawadee UI','Tahoma',system-ui,sans-serif;
  --z-nav:100;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--blush);color:var(--ink);font-family:var(--sans);line-height:1.62;
     -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden}
a{color:inherit;text-decoration:none}
/* select and the carousel's role=button frames were falling through to
   Chromium's blue UA ring. `border-radius:0` lets each control keep its own
   shape — the old flat 8px drew a rounded rect around 999px pills. */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,
[tabindex]:focus-visible{outline:2px solid var(--green);outline-offset:3px}
.wrap{width:min(1140px,92vw);margin-inline:auto}
/* Off-screen until focused, then the first thing Tab reaches. Left at -9999px
   rather than display:none so it stays in the tab order at all. */
.skiplink{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}
.skiplink:focus{position:fixed;left:12px;top:12px;width:auto;height:auto;z-index:calc(var(--z-nav) + 1);
  background:var(--forest);color:#fff;font-family:var(--sans);font-weight:600;font-size:15px;
  padding:12px 22px;border-radius:999px;box-shadow:var(--liftsh)}
section{position:relative}
/* The nav is 74px and sticky, so without this every in-page anchor lands with
   the section's first 74px tucked under it — including #cta, whose heading is
   the first thing an arriving visitor should see. */
[id]{scroll-margin-top:90px}
.sec-title{font-family:var(--serif);font-weight:500;color:var(--forest);font-size:clamp(28px,4.6vw,48px);line-height:1.24;letter-spacing:-.01em;text-wrap:balance}
.sec-sub{font-size:clamp(15px,1.9vw,18px);color:var(--ink2);margin-top:14px;max-width:54ch;text-wrap:pretty}
.center{text-align:center}.center .sec-sub{margin-inline:auto}
em{font-style:italic}

.pill{display:inline-flex;align-items:center;gap:8px;background:var(--forest);color:#fff;font-family:var(--sans);font-weight:600;font-size:15px;
      padding:8px 20px;border-radius:999px;cursor:pointer;border:none;transition:transform .18s cubic-bezier(.2,.7,.3,1),background .18s}
.pill:hover{background:#12301F;transform:translateY(-1px)}
.pill.lg{font-size:17px;padding:15px 32px}
.pill .ar{color:var(--blush);transition:transform .18s}.pill:hover .ar{transform:translateX(3px)}
/* --edge, not --line: .ghost's fill differs from the page by 1.06:1, so a
   --line border (1.19:1) left the hero's secondary CTA with no visible
   boundary in either channel — it read as a floating text label. */
.ghost{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-weight:600;font-size:16px;color:var(--forest);
       padding:14px 26px;border-radius:999px;border:1.5px solid var(--edge);background:var(--blush-2);cursor:pointer}
.ghost:hover{border-color:var(--green)}

/* nav */
.nav{position:sticky;top:0;z-index:var(--z-nav);background:color-mix(in srgb,var(--blush) 82%,transparent);
     backdrop-filter:saturate(1.3) blur(10px);transition:border-color .2s;border-bottom:1px solid transparent}
.nav.scrolled{border-color:var(--line)}
.nav .row{display:flex;align-items:center;gap:20px;height:74px}
.brand{display:flex;align-items:center;gap:9px;min-height:44px;min-width:44px}
.brand img{height:42px;border-radius:11px;display:block}
.brand span{font-family:var(--serif);font-weight:600;font-size:24px;color:var(--forest)}
.nav nav{display:flex;gap:24px}
.nav nav a{font-size:15px;color:var(--ink2);font-weight:500}
.nav nav a:hover{color:var(--forest)}
.nav .sp{margin-left:auto}
.burger{display:none;width:44px;height:44px;border-radius:12px;border:1.5px solid var(--edge);background:var(--blush-2);color:var(--forest);place-items:center;cursor:pointer}
.burger i{font-size:22px;display:block}
.mnav{display:none}
.mnav a{display:block;padding:14px 2px;font-size:17px;color:var(--ink);border-top:1px solid var(--line);font-family:var(--serif)}
/* color is NOT inherited here: `.mnav a` (0,1,1) outranks `.pill` (0,1,0),
   so without this the burger menu's only CTA rendered --ink on --forest —
   measured 1.14:1, an unreadable label on the one install path a phone has
   once .navcta is hidden below 760px. */
.mnav a.pill{font-family:var(--sans);justify-content:center;margin-top:14px;border-top:none;color:#fff}
@media(max-width:760px){.nav nav,.navcta{display:none}.burger{display:grid}.mnav.open{display:block;padding:6px 0 18px}}

/* page opening — every page starts with a centred title, a lede and a CTA row.
   (index adds .brandmark/.wm on top; that wordmark is the landing page's alone.) */
.hero{text-align:center;padding:clamp(48px,8vw,104px) 0 clamp(34px,5vw,60px)}
.h1{font-family:var(--serif);font-weight:500;color:var(--forest);font-size:clamp(34px,5.6vw,60px);line-height:1.26;letter-spacing:-.014em;text-wrap:balance}
.h1 em{font-weight:400}
.lede{font-size:clamp(16px,2.1vw,20px);color:var(--ink2);max-width:56ch;margin:24px auto 0;text-wrap:pretty}
.hero-cta{margin-top:32px;display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
.hero-note{margin-top:18px;font-size:15px;color:var(--ink2)}
/* A page whose hero is a heading rather than a pitch — the legal pages. Same
   class, one step down the scale, because 80pt over "ข้อกำหนดการใช้งาน" reads as
   a launch announcement. */
.hero.doc{padding:clamp(40px,6vw,76px) 0 clamp(18px,3vw,28px)}
.hero.doc .h1{font-size:clamp(32px,5.4vw,54px)}
.hero.doc .lede{margin-top:18px}
/* the round mark a doc hero opens with, in place of the wordmark */
.heromark{width:58px;height:58px;border-radius:17px;background:var(--forest);color:#fff;
  display:grid;place-items:center;font-size:29px;margin:0 auto 20px;box-shadow:var(--cardsh)}
.heromark i{display:block}

/* section rhythm */
.pad{padding:clamp(56px,8vw,100px) 0}
/* The alternating band index uses around its waitlist section — a section that
   should read as a different room from the one above it. */
.band{background:var(--blush-2);border-block:1px solid var(--line)}
/* The white rounded surface index's cards are cut from, for content that is
   text rather than a photo. */
.surface{background:var(--white);border-radius:22px;box-shadow:var(--cardsh)}

footer{padding:46px 0 40px;color:var(--ink2);font-size:15px;border-top:1px solid var(--line)}
.frow{display:flex;justify-content:space-between;align-items:center;gap:18px;flex-wrap:wrap}
.fleft{display:flex;align-items:center;gap:14px}
.fnav{display:flex;gap:22px;flex-wrap:wrap;margin:-11px 0}
/* 11px of vertical padding turns a 22px line of text into a 44px target.
   Footer links were the smallest touch targets on the page after the inline
   ones, and they are the links a phone user reaches for one-handed. */
.fnav a{display:inline-block;padding:11px 0}
footer a:hover{color:var(--forest)}
@media(max-width:880px){
  /* footer stacks centered instead of brand-left / nav-right / copyright orphaned */
  .frow{flex-direction:column;justify-content:center;text-align:center;gap:16px}
}

/* The reveal is an ENHANCEMENT, never a gate. Everything hangs off `.js`,
   which the one-liner in each page's <head> adds before first paint — so when
   script is blocked, fails, or simply never runs (a link-preview renderer, an
   OG-image capture, a crawler that does not execute), .rv carries no opacity
   rule at all and the content is just there. The old version defaulted every
   .rv to opacity 0 and relied on a <noscript> block plus an IntersectionObserver
   firing; anything that ran neither left the section blank. */
.js .rv{opacity:0;transform:translateY(16px);transition:opacity .6s ease,transform .6s cubic-bezier(.2,.7,.3,1)}
.js .rv.in{opacity:1;transform:none}

/* `animation` and an explicit `html` rule, not just `transition` on `*`:
   `*{scroll-behavior:auto}` at specificity (0,0,0) lost to `html{...smooth}`
   at (0,0,1), so every in-page anchor kept smooth-scrolling for a reader who
   asked the OS for less motion — and keyframe animations were never covered
   at all. Both were measured still running under the reduce preference. */
@media(prefers-reduced-motion:reduce){
  /* `*` does not match pseudo-elements — the carousel's neighbour scrim
     (.car-item .screen::after) kept its 450ms cross-fade under reduce. */
  *,*::before,*::after{transition:none!important;animation:none!important}
  html{scroll-behavior:auto!important}
  /* `.js .rv` above is (0,2,0); a bare `.rv` here at (0,1,0) lost to it and
     every reveal stayed at opacity 0 under the reduce preference. */
  .js .rv{opacity:1;transform:none}
}
