@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@300;400;500;600;700&family=Noto+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&display=swap");

:root{
  --green-50:#F1FBEC;--green-100:#DDF5CF;--green-200:#BCEBA2;--green-300:#9CE27C;--green-400:#7ED957;--green-500:#63C13C;--green-600:#4CA32B;--green-700:#357A1E;--green-800:#215016;--green-900:#123A1E;
  --ink-900:#14261A;--ink-800:#22362A;--ink-700:#3A4A3F;--ink-600:#546158;--ink-500:#6B7A70;--ink-400:#8E9A92;--ink-300:#B3BDB6;--ink-200:#D6DCD6;--ink-100:#E7EBE5;--ink-50:#F4F6F3;--white:#FFFFFF;
  --sun-100:#FFF3D1;--sun-400:#FFC53D;--sun-600:#D99A00;
  --coral-100:#FFE6DF;--coral-400:#FF6B4A;--coral-500:#E8442A;--coral-600:#C5361B;
  --sky-100:#DDF4FB;--sky-400:#4CC3E8;--sky-600:#1E93B5;
  --bg-page:var(--ink-50);--bg-sunken:#EBEEE8;--surface-card:var(--white);--surface-raised:var(--white);--surface-brand:var(--green-400);--surface-brand-soft:var(--green-50);--surface-ink:var(--green-900);
  --text-strong:var(--ink-900);--text-body:var(--ink-700);--text-muted:var(--ink-500);--text-faint:var(--ink-400);--text-on-brand:var(--green-900);--text-on-ink:var(--white);--text-link:var(--green-600);--text-link-hover:var(--green-700);
  --line-soft:var(--ink-100);--line:var(--ink-200);--line-strong:var(--ink-300);--line-brand:var(--green-300);
  --status-clean:var(--green-400);--status-clean-bg:var(--green-50);--status-okay:var(--sun-400);--status-okay-bg:var(--sun-100);--status-dirty:var(--coral-400);--status-dirty-bg:var(--coral-100);--status-closed:var(--ink-300);--status-closed-bg:var(--ink-100);--status-water:var(--sky-400);--status-water-bg:var(--sky-100);
  --focus-ring:0 0 0 4px rgba(126,217,87,.45);

  --shadow-hairline:0 0 0 1px var(--line-soft);
  --shadow-sm:0 1px 2px rgba(20,38,26,.05),0 2px 6px -2px rgba(20,38,26,.06);
  --shadow-card:0 1px 2px rgba(20,38,26,.04),0 10px 24px -12px rgba(20,38,26,.14);
  --shadow-raised:0 2px 4px rgba(20,38,26,.05),0 18px 36px -16px rgba(20,38,26,.18);
  --shadow-float:0 8px 16px -8px rgba(20,38,26,.14),0 32px 64px -24px rgba(20,38,26,.22);
  --shadow-brand:0 8px 20px -8px rgba(99,193,60,.55);

  --radius-xs:6px;--radius-sm:10px;--radius-md:14px;--radius-lg:20px;--radius-xl:28px;--radius-2xl:36px;--radius-pill:999px;
  --radius-card:var(--radius-lg);--radius-control:var(--radius-pill);--radius-sheet:var(--radius-xl);--radius-icon:var(--radius-md);

  --space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:20px;--space-6:24px;--space-7:32px;--space-8:40px;--space-9:48px;--space-10:64px;--space-11:80px;--space-12:96px;--space-13:128px;
  --gutter-mobile:20px;--gutter-desktop:40px;--container-max:1200px;
  --section-y-mobile:64px;--section-y-desktop:112px;
  --control-h-sm:36px;--control-h-md:44px;--control-h-lg:54px;

  --font-core:"Noto Sans Thai","Noto Sans","Thonburi",-apple-system,"SF Pro Text",system-ui,sans-serif;
  --fw-light:300;--fw-regular:400;--fw-medium:500;--fw-semibold:600;--fw-bold:700;
  --type-body-lg-size:18px;--type-body-lg-lh:1.65;
  --type-body-size:16px;--type-body-lh:1.7;
  --type-eyebrow-size:12px;--type-eyebrow-ls:.14em;

  --ease-standard:cubic-bezier(.2,.8,.2,1);
  --ease-out-soft:cubic-bezier(.16,1,.3,1);
  --ease-pop:cubic-bezier(.34,1.56,.64,1);
  --dur-fast:120ms;--dur-base:200ms;--dur-slow:320ms;
  --press-scale:.97;--hover-lift:-2px;

  --gutter:var(--gutter-desktop);--section-y:var(--section-y-desktop);
}

@media (max-width:720px){
  :root{--gutter:var(--gutter-mobile);--section-y:var(--section-y-mobile)}
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg-page);color:var(--text-body);font-family:var(--font-core);font-size:var(--type-body-size);line-height:var(--type-body-lh);-webkit-font-smoothing:antialiased;text-wrap:pretty;overflow-x:hidden}
h1,h2,h3,h4,h5{margin:0;color:var(--text-strong);font-weight:var(--fw-bold);letter-spacing:-.02em;line-height:1.3}
p{margin:0}
img{max-width:100%}
a{color:var(--text-link);text-decoration:none;transition:color var(--dur-fast) var(--ease-standard)}
@media (hover:hover){a:hover{color:var(--text-link-hover)}}
button{font-family:inherit}
:focus-visible{outline:none;box-shadow:var(--focus-ring)}
::selection{background:var(--green-200);color:var(--green-900)}

.container{max-width:var(--container-max);margin:0 auto;padding-left:var(--gutter);padding-right:var(--gutter)}
.section{padding-top:var(--section-y);padding-bottom:var(--section-y)}
section[id]{scroll-margin-top:84px}

/* ---------- header ---------- */
.site-header{position:sticky;top:0;z-index:30;background:rgba(244,246,243,.86);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-bottom:1px solid var(--line-soft)}
.site-header .container{padding-top:14px;padding-bottom:14px;display:flex;align-items:center;justify-content:space-between;gap:24px}
.wordmark{display:inline-flex;align-items:center;gap:10px;text-decoration:none}
/* Full artwork, uncropped: fixed height, width follows the SVG's own ratio. */
.wordmark-mark{display:block;width:auto;height:42px;flex:0 0 auto}
.wordmark-text{font-size:21px;font-weight:var(--fw-bold);letter-spacing:-.03em;color:var(--text-strong)}
.wordmark.on-ink .wordmark-text{color:var(--white)}
/* The row holds eight items now. Letting it wrap keeps everything reachable at
   tablet widths instead of pushing an item off the edge; the gap tightens first
   so the wrap only happens when it genuinely has to. */
.nav-links{display:flex;align-items:center;flex-wrap:wrap;justify-content:flex-end;
  gap:10px clamp(14px,2vw,28px)}
.nav-links a{font-size:15px;font-weight:var(--fw-medium);color:var(--text-body);text-decoration:none}
@media (hover:hover){.nav-links a:hover{color:var(--green-700)}}
.nav-toggle{display:none;width:40px;height:40px;align-items:center;justify-content:center;background:var(--white);border:1px solid var(--line);border-radius:var(--radius-pill);box-shadow:var(--shadow-sm);cursor:pointer}
.nav-toggle svg{width:20px;height:20px;stroke:var(--text-strong)}
.mobile-menu{display:none}

/* The menu collapses at 980 rather than 860: with eight items the horizontal row no
   longer fits beside the wordmark below that, and the compact menu reads better than a
   nav that wraps its main call to action onto a second line. */
@media (max-width:980px){
  .nav-links{position:fixed;inset:70px 16px auto 16px;flex-direction:column;align-items:stretch;gap:4px;background:var(--white);border:1px solid var(--line-soft);border-radius:var(--radius-lg);box-shadow:var(--shadow-float);padding:12px;transform:translateY(-12px);opacity:0;pointer-events:none;transition:opacity var(--dur-base) var(--ease-standard),transform var(--dur-base) var(--ease-out-soft)}
  .nav-links.is-open{opacity:1;transform:translateY(0);pointer-events:auto}
  .nav-links a{padding:12px 14px;border-radius:var(--radius-sm)}
  @media (hover:hover){.nav-links a:hover{background:var(--green-50)}}
  .nav-links .btn{margin:6px 6px 2px}
  .nav-toggle{display:inline-flex}
}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);font-family:var(--font-core);font-weight:var(--fw-semibold);letter-spacing:-.01em;line-height:1;border-radius:var(--radius-control);border:1px solid transparent;cursor:pointer;white-space:nowrap;text-decoration:none;transition:background var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-pop),box-shadow var(--dur-base) var(--ease-standard)}
.btn:active{transform:scale(var(--press-scale))}
.btn-sm{height:var(--control-h-sm);padding:0 16px;font-size:14px}
.btn-md{height:var(--control-h-md);padding:0 22px;font-size:15px}
.btn-lg{height:var(--control-h-lg);padding:0 30px;font-size:17px}
.btn-primary{background:var(--green-400);color:var(--green-900);box-shadow:var(--shadow-brand)}
@media (hover:hover){.btn-primary:hover{background:var(--green-300)}}
.btn-ink{background:var(--green-900);color:var(--white);box-shadow:var(--shadow-card)}
@media (hover:hover){.btn-ink:hover{background:var(--green-800)}}
.btn-secondary{background:var(--white);color:var(--text-strong);border-color:var(--line);box-shadow:var(--shadow-sm)}
@media (hover:hover){.btn-secondary:hover{background:var(--green-50)}}
.btn-ghost{background:transparent;color:var(--text-body)}
@media (hover:hover){.btn-ghost:hover{background:var(--ink-100)}}
.btn-full{display:flex;width:100%}
.btn img{flex:0 0 auto}

/* ---------- badges & tags ---------- */
.badge{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px;border-radius:var(--radius-pill);font-size:13px;font-weight:var(--fw-semibold);line-height:1;white-space:nowrap;border:1px solid transparent}
.badge-sm{height:24px;padding:0 9px;gap:4px;font-size:12px}
.badge-clean{background:var(--status-clean-bg);color:var(--green-800);border-color:var(--green-200)}
.badge-okay{background:var(--status-okay-bg);color:#7A5200;border-color:#F5DFA0}
.badge-dirty{background:var(--status-dirty-bg);color:#992A14;border-color:#FFC4B4}
.badge-closed{background:var(--status-closed-bg);color:var(--ink-600);border-color:var(--line)}
.badge-water{background:var(--status-water-bg);color:var(--sky-600);border-color:#B6E6F5}
.badge-brand{background:var(--green-400);color:var(--green-900)}
.badge-ink{background:var(--green-900);color:var(--white)}
.badge img{border-radius:6px;display:block}

.tag{display:inline-flex;align-items:center;gap:7px;height:36px;padding:0 14px;background:var(--white);color:var(--text-body);border:1px solid var(--line);border-radius:var(--radius-pill);font-family:var(--font-core);font-size:14px;font-weight:var(--fw-medium);line-height:1;white-space:nowrap;cursor:default;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard)}
.tag.is-selected{background:var(--green-100);color:var(--green-900);border-color:var(--green-300)}

/* ---------- cards ---------- */
.card{background:var(--surface-card);border:1px solid var(--line-soft);border-radius:var(--radius-card);padding:var(--space-6);box-shadow:var(--shadow-card);transition:box-shadow var(--dur-base) var(--ease-standard),transform var(--dur-base) var(--ease-out-soft)}
.card-sm{padding:var(--space-4)}
.card-soft{background:var(--surface-brand-soft);border-color:var(--green-100)}
.card-ink{background:var(--green-900);border-color:transparent;color:var(--text-on-ink)}
@media (hover:hover){.card-interactive:hover{box-shadow:var(--shadow-raised);transform:translateY(var(--hover-lift))}}

/* ---------- sticker icons ---------- */
.sticker{display:block;border-radius:var(--radius-icon);flex:0 0 auto}

/* ---------- form controls ---------- */
.search-field{display:flex;align-items:center;gap:var(--space-3);height:var(--control-h-lg);padding:0 8px 0 20px;background:var(--white);border:1px solid var(--line);border-radius:var(--radius-pill);box-shadow:var(--shadow-card);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard)}
.search-field:focus-within{border-color:var(--green-400);box-shadow:var(--shadow-raised)}
.search-field svg{flex:0 0 auto;stroke:var(--ink-400)}
.search-field input{flex:1;min-width:0;border:none;outline:none;background:transparent;font:var(--fw-regular) 17px/1.4 var(--font-core);color:var(--text-strong)}
.search-field input::placeholder{color:var(--text-faint)}

/* ---------- eyebrow / section heading ---------- */
.eyebrow{display:inline-block;margin-bottom:var(--space-4);padding:6px 14px;background:var(--green-100);color:var(--green-800);border-radius:var(--radius-pill);font-size:var(--type-eyebrow-size);font-weight:var(--fw-semibold);letter-spacing:var(--type-eyebrow-ls);text-transform:uppercase}
.section-heading{max-width:720px}
.section-heading.center{text-align:center;margin-left:auto;margin-right:auto}
.section-heading h2{font-size:clamp(28px,4vw,36px);line-height:1.3;letter-spacing:-.02em;font-weight:var(--fw-bold);color:var(--text-strong)}
.section-heading p{margin-top:var(--space-4);font-size:var(--type-body-lg-size);line-height:var(--type-body-lg-lh);color:var(--text-muted)}

/* ---------- rating stars ---------- */
.stars{display:inline-flex;gap:2px}
.star{width:14px;height:14px;background:var(--ink-200);clip-path:polygon(50% 0%,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%)}
.star.is-filled{background:var(--sun-400)}
.rating{display:inline-flex;align-items:center;gap:6px}
.rating-value{font-size:14px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.rating-count{font-size:13px;color:var(--text-muted)}
/* A place nobody has reviewed shows no score at all: "0.0" would read as a bad rating. */
.rating-empty{font-size:13px;color:var(--text-muted)}

/* ---------- product: facility chip ---------- */
.facility-chip{display:inline-flex;align-items:center;gap:8px;padding:6px 12px 6px 6px;background:var(--white);border:1px solid var(--line);border-radius:var(--radius-pill)}
.facility-chip img{display:block;border-radius:7px}
.facility-chip span{font-size:13px;font-weight:var(--fw-medium);color:var(--text-strong)}
.facility-chip.unavailable{background:var(--bg-sunken);border-color:transparent;opacity:.5}
.facility-chip.unavailable img{filter:grayscale(1)}
.facility-chip.unavailable span{color:var(--text-muted);text-decoration:line-through}

/* ---------- product: toilet card ---------- */
.toilet-card{display:flex;gap:var(--space-4);padding:var(--space-4);background:var(--surface-card);border:1px solid var(--line-soft);border-radius:var(--radius-card);box-shadow:var(--shadow-card);transition:box-shadow var(--dur-base) var(--ease-standard),transform var(--dur-base) var(--ease-out-soft)}
@media (hover:hover){.toilet-card:hover{box-shadow:var(--shadow-raised);transform:translateY(var(--hover-lift))}}
.toilet-card .thumb{display:block;flex:0 0 auto;width:52px;height:52px;border-radius:var(--radius-md)}
.toilet-card .body{flex:1;min-width:0}
.toilet-card .title-row{display:flex;align-items:center;gap:8px;margin-bottom:4px}
.toilet-card .title-row .name{font-size:17px;font-weight:var(--fw-semibold);color:var(--text-strong);letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.toilet-card .title-row img{display:block;border-radius:5px;flex:0 0 auto}
.toilet-card .meta-row{display:flex;align-items:center;gap:10px;margin-bottom:10px;font-size:13px;color:var(--text-muted)}
.toilet-card .meta-row .distance{font-weight:var(--fw-medium);color:var(--green-700)}
.toilet-card .meta-row .area{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.toilet-card .facts-row{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-3)}
.toilet-card .facts-row img{display:block;border-radius:6px}
.toilet-card.compact{padding:12px;border-radius:16px}
.toilet-card.compact .thumb{width:44px;height:44px}
.toilet-card.compact .title-row .name{font-size:15px}

/* preview-card actions: นำทาง is the primary escape route, details stay tucked away */
.toilet-card .card-actions{display:flex;gap:8px;margin-top:12px}
.toilet-card .card-actions .btn{flex:1;padding:0 12px}
/* the info scrolls if it must, but the community buttons always stay reachable */
.toilet-card .card-detail{margin-top:12px;padding-top:12px;border-top:1px solid var(--line-soft);
  display:flex;flex-direction:column;gap:10px}
/* 104px fitted the old one-line chips. Evidence chips carry a second line saying where
   the claim came from, and location context adds more rows — at the old height a card
   showed one and a half chips and looked broken. */
.toilet-card .card-detail-scroll{display:flex;flex-direction:column;gap:10px;max-height:210px;overflow-y:auto}
.toilet-card .card-detail .chips{display:flex;flex-wrap:wrap;gap:8px}
.toilet-card .card-detail .meta{font-size:13px;line-height:1.6;color:var(--text-muted)}
@media (max-width:480px){
  /* 36px was fine for a chip but not for the pair of buttons that end the journey —
     "นำทาง" is the last thing a person taps, often while walking. */
  .toilet-card .card-actions .btn{font-size:13px;padding:0 8px;height:44px}
  .toilet-card .card-detail-scroll{max-height:168px}
}

/* ---------- product: review item ---------- */
.review-item{display:flex;gap:var(--space-4)}
.review-item .avatar{display:grid;place-items:center;width:40px;height:40px;flex:0 0 auto;border-radius:50%;background:var(--green-100);color:var(--green-800);font-size:16px;font-weight:var(--fw-semibold)}
.review-item .content{flex:1;min-width:0}
.review-item .head{display:flex;align-items:baseline;gap:10px;margin-bottom:4px}
.review-item .author{font-size:15px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.review-item .when{font-size:12px;color:var(--text-faint)}
.review-item .meta{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.review-item .meta img{display:block;border-radius:6px}
.review-item p{font-size:15px;line-height:1.6;color:var(--text-body)}

/* ---------- marketing: stat block / step card ---------- */
.stat-block{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-6);background:var(--surface-card);border:1px solid var(--line-soft);border-radius:var(--radius-card);box-shadow:var(--shadow-card)}
.stat-block .value{font-size:clamp(30px,4vw,42px);line-height:1;font-weight:var(--fw-bold);letter-spacing:-.03em;color:var(--text-strong)}
.stat-block .label{font-size:15px;font-weight:var(--fw-medium);color:var(--text-body)}
.stat-block .sublabel{font-size:13px;color:var(--text-faint)}
.stat-block.ink{background:var(--green-900);border-color:transparent}
.stat-block.ink .value{color:var(--green-400)}
.stat-block.ink .label{color:rgba(255,255,255,.92)}
.stat-block.ink .sublabel{color:rgba(255,255,255,.62)}

.step-card{position:relative;display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-6);background:var(--surface-card);border:1px solid var(--line-soft);border-radius:var(--radius-card);box-shadow:var(--shadow-card)}
.step-card .top-row{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}
.step-card .step-no{font-size:13px;font-weight:var(--fw-bold);letter-spacing:.1em;color:var(--green-500)}
.step-card .title{font-size:20px;line-height:1.45;letter-spacing:-.01em;font-weight:var(--fw-semibold);color:var(--text-strong)}
.step-card .body{font-size:15px;line-height:1.65;color:var(--text-muted)}

/* ---------- scene / illustration frame ---------- */
.scene{position:relative;margin:0;background:var(--white);border:1px solid var(--line-soft);border-radius:var(--radius-2xl);padding:8px;box-shadow:var(--shadow-card);overflow:hidden}
.scene .frame{position:relative;width:100%;border-radius:28px;overflow:hidden;background:var(--green-50)}
.scene .frame img{display:block;width:100%;height:100%;object-fit:cover}
.scene.ratio-hero .frame{aspect-ratio:16/5;min-height:180px}
.scene.ratio-wide .frame{aspect-ratio:16/6;min-height:180px}
.scene.ratio-square .frame{aspect-ratio:4/3;min-height:220px}
.scene.ratio-cta .frame{aspect-ratio:16/7;min-height:170px}

/* ---------- layout: grids ---------- */
/* min(...,100%) so the track floor never forces the grid wider than a 320px phone. */
.grid-auto{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:20px}
.grid-auto-wide{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px}
.grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));gap:48px;align-items:center}

/* ---------- hero ---------- */
.hero{padding:72px var(--gutter) 96px;background:linear-gradient(180deg,var(--green-50),var(--bg-page) 70%)}
.hero .hero-inner{max-width:var(--container-max);margin:0 auto;display:flex;gap:64px;align-items:center;flex-wrap:wrap}
.hero .copy{flex:1 1 420px;min-width:min(320px,100%)}
.hero .kicker{display:inline-flex;align-items:center;gap:8px;padding:7px 14px 7px 8px;background:var(--white);border:1px solid var(--line);border-radius:var(--radius-pill);box-shadow:var(--shadow-sm);font-size:13px;font-weight:var(--fw-medium);color:var(--text-body)}
.hero .kicker img{border-radius:7px}
.hero h1{margin-top:22px;font-size:clamp(40px,5.4vw,72px);line-height:1.2;letter-spacing:-.03em}
.hero h1 .accent{color:var(--green-500)}
.hero .lede{margin-top:20px;max-width:520px;font-size:var(--type-body-lg-size);line-height:1.65;color:var(--text-muted)}
.hero .cta-row{display:flex;gap:12px;margin-top:28px;flex-wrap:wrap}
.hero .stat-row{display:flex;gap:26px;margin-top:32px;flex-wrap:wrap}
.hero .stat-row .stat-value{font-size:26px;font-weight:var(--fw-bold);letter-spacing:-.02em;color:var(--text-strong)}
.hero .stat-row .stat-label{font-size:13px;color:var(--text-faint)}
.hero .scene-wrap{max-width:var(--container-max);margin:56px auto 0}

/* ---------- phone mockup ---------- */
.phone{width:calc(393px * .78);height:calc(852px * .78);flex:0 0 auto}
.phone-inner{width:393px;height:852px;transform:scale(.78);transform-origin:top left;position:relative;background:#1C1C1E;border-radius:55px;padding:11px;box-shadow:var(--shadow-float),inset 0 0 0 1.5px rgba(255,255,255,.16)}
.phone-screen{position:relative;width:100%;height:100%;border-radius:44px;overflow:hidden;background:var(--bg-page)}
.phone-status{position:absolute;top:0;left:0;right:0;height:54px;display:flex;align-items:center;justify-content:space-between;padding:0 30px 0 34px;z-index:30;color:var(--text-strong);font-size:15px;font-weight:600;letter-spacing:.01em;pointer-events:none}
.phone-status svg{display:block}
.phone-notch{position:absolute;top:13px;left:50%;transform:translateX(-50%);width:122px;height:35px;border-radius:20px;background:#000;z-index:40}
.phone-home{position:absolute;bottom:9px;left:50%;transform:translateX(-50%);width:139px;height:5px;border-radius:3px;background:rgba(20,38,26,.32);z-index:40}
.phone-map{position:absolute;inset:0 0 52% 0;background:var(--bg-sunken);overflow:hidden}
.phone-map .grid-lines{position:absolute;inset:0;background-image:linear-gradient(var(--ink-100) 1px,transparent 1px),linear-gradient(90deg,var(--ink-100) 1px,transparent 1px);background-size:52px 52px}
.phone-map .roads{position:absolute;inset:0;background:linear-gradient(90deg,transparent 44%,#F7F9F6 44%,#F7F9F6 52%,transparent 52%),linear-gradient(0deg,transparent 74%,#F7F9F6 74%,#F7F9F6 80%,transparent 80%),radial-gradient(circle at 84% 66%,#E3EBDF 0 18%,transparent 18%)}
.phone-map .pin{position:absolute;transform:translate(-50%,-100%);filter:drop-shadow(0 8px 12px rgba(20,38,26,.22))}
/* Kept slightly back, but not desaturated — a pin's colour is its cleanliness rating. */
.phone-map .pin.dim{opacity:.9}
.phone-map .you-are-here{position:absolute;left:46%;top:52%;transform:translate(-50%,-50%);width:64px;height:64px;border-radius:50%;background:rgba(126,217,87,.22);display:grid;place-items:center}
.phone-map .you-are-here span{width:16px;height:16px;border-radius:50%;background:var(--green-500);border:3px solid var(--white);box-shadow:var(--shadow-raised)}
.phone-map .search-wrap{position:absolute;left:18px;right:18px;top:64px}
.phone-map .search-wrap .search-field{box-shadow:var(--shadow-raised)}
.phone-map .tag-row{display:flex;gap:8px;margin-top:10px}
.phone-map .tag-row .tag{height:32px;font-size:13px}
.phone-sheet{position:absolute;left:0;right:0;bottom:0;height:54%;background:var(--white);border-radius:28px 28px 0 0;box-shadow:var(--shadow-float);padding:12px 16px}
.phone-sheet .handle{width:44px;height:5px;border-radius:999px;background:var(--ink-200);margin:0 auto 14px}
.phone-sheet .sheet-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
.phone-sheet .sheet-head .title{font-size:19px;font-weight:var(--fw-bold);letter-spacing:-.02em;color:var(--text-strong)}
.phone-sheet .list{display:flex;flex-direction:column;gap:10px}

/* ---------- map demo ---------- */
.map-demo-panel{flex:1 1 420px;min-width:min(320px,100%);position:relative;height:460px;border-radius:var(--radius-xl);overflow:hidden;border:1px solid var(--line);background:var(--bg-sunken);box-shadow:var(--shadow-card)}
/* hard ceiling: whatever the card contains, it can never spill out of the map panel */
.map-demo-panel .card-slot{position:absolute;left:16px;right:16px;bottom:16px;z-index:1000;max-height:calc(100% - 32px);overflow-y:auto}
.map-demo-panel .card-slot .toilet-card{box-shadow:var(--shadow-float)}
.map-demo-panel .badges-row{position:absolute;left:16px;top:16px;display:flex;gap:8px;z-index:1000}
.map-demo-panel .map-error{position:absolute;inset:0;display:grid;place-items:center;padding:24px;text-align:center;font-size:14px;color:var(--text-muted)}

/* ---------- THEEKHEE Bangkok background system ----------
   One vocabulary of silhouettes (skyline, BTS, street, public toilets) reused by
   every .city-layer, so scrolling reads as one city rather than separate pictures.
   Purely decorative: inert to pointer input and hidden from assistive tech. */
:root{
  --city-far:#DBE2DA;
  --city-mid:#CBD5CA;
  --city-near:#BCC7BA;
  --city-window:#EAEFE9;
  --city-accent:var(--green-400);
  --city-band-h:190px;
  --city-band-opacity:.6;
}
.city-defs{position:absolute;width:0;height:0;overflow:hidden}
.has-city{position:relative}
/* content sits above the city, never behind it */
.has-city > .container,
.has-city > .hero-inner,
.has-city > .scene-wrap{position:relative;z-index:1}
.city-layer{position:absolute;left:0;right:0;z-index:0;pointer-events:none;overflow:hidden}
.city-layer svg{display:block;width:100%;height:100%}
.city-layer--band{
  bottom:0;height:var(--city-band-h);opacity:var(--city-band-opacity);
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 46%);
          mask-image:linear-gradient(to bottom,transparent 0,#000 46%);
}
.city-layer--sky{
  top:0;height:120px;opacity:.45;
  -webkit-mask-image:linear-gradient(to top,transparent 0,#000 60%);
          mask-image:linear-gradient(to top,transparent 0,#000 60%);
}
.city-layer .city-narrow{display:none}
/* every section gets its own district; white surfaces hold the city back a little */
.city-on-white{--city-band-opacity:.46}
/* the footer sees the same skyline after dark — same symbol, different palette */
.site-footer.has-city{position:relative;overflow:hidden}
.site-footer > .footer-top,
.site-footer > .footer-bottom{position:relative;z-index:1}
.city-night{
  --city-far:#174026;--city-mid:#1C4D2E;--city-near:#225A35;--city-window:#2F7343;
  opacity:.42;
  /* the copyright line sits low in the footer, so fade the city out under it too */
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 40%,#000 78%,transparent 100%);
          mask-image:linear-gradient(to bottom,transparent 0,#000 40%,#000 78%,transparent 100%);
}

@media (max-width:720px){
  :root{--city-band-h:132px;--city-band-opacity:.5}
  .city-layer .city-wide{display:none}
  .city-layer .city-narrow{display:block}
  .city-layer--sky{height:88px;opacity:.38}
}
@media (prefers-reduced-motion:no-preference){
  /* nothing animates here — the city is deliberately still */
}

/* ---------- leaflet surfaces ---------- */
.map-canvas{position:absolute;inset:0;background:var(--bg-sunken)}
.leaflet-container{font-family:var(--font-core);background:var(--bg-sunken)}
.leaflet-control-zoom a{color:var(--text-strong);border-color:var(--line-soft)}
@media (hover:hover){.leaflet-control-zoom a:hover{background:var(--green-50)}}
.leaflet-bar{border-radius:var(--radius-sm);overflow:hidden;box-shadow:var(--shadow-sm)}
.leaflet-control-attribution{font-size:11px;background:rgba(255,255,255,.86)}
.theekhee-marker{background:none;border:none;filter:drop-shadow(0 10px 14px rgba(20,38,26,.24));transition:width var(--dur-base) var(--ease-pop),height var(--dur-base) var(--ease-pop)}
.user-dot{background:var(--green-500);border:3px solid var(--white);border-radius:50%;box-shadow:var(--shadow-raised)}

/* ---------- full-screen map view ----------
   Overlay chrome only: the map itself is the section's Leaflet instance, relocated. */
.full-map{position:fixed;inset:0;z-index:1900;background:var(--bg-sunken);
  padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)}
/* z-index:0 makes this its own stacking context, so Leaflet's internal panes
   (z-index 400-800) stay below the overlay chrome instead of covering it. */
.full-map-canvas{position:absolute;inset:0;z-index:0}
.full-map-canvas .map-canvas{position:absolute;inset:0}
.full-map-top{position:absolute;top:calc(12px + env(safe-area-inset-top));left:12px;right:12px;z-index:20;
  display:flex;align-items:center;gap:10px;pointer-events:none}
.full-map-top > *{pointer-events:auto}
.full-map-icon-btn{display:grid;place-items:center;width:44px;height:44px;flex:0 0 auto;
  background:var(--white);color:var(--text-strong);border:1px solid var(--line-soft);
  border-radius:var(--radius-pill);box-shadow:var(--shadow-card);cursor:pointer}
@media (hover:hover){.full-map-icon-btn:hover{background:var(--green-50)}}
.full-map-icon-btn svg{width:20px;height:20px}
.full-map-title{display:flex;align-items:center;height:44px;padding:0 18px;
  background:var(--white);border:1px solid var(--line-soft);border-radius:var(--radius-pill);
  box-shadow:var(--shadow-card);font-size:16px;font-weight:var(--fw-semibold);color:var(--text-strong);white-space:nowrap}
.full-map-locate{margin-left:auto;height:44px;box-shadow:var(--shadow-card)}
.full-map-locate svg{width:16px;height:16px}
/* The controls column owns the position; each row inside is a normal flex child, so
   hiding a row closes its gap instead of leaving a hole other rows were offset around. */
/* Leaflet's own controls sit at the top-right of the map, which is now under the
   controls column. The column's height changes (the facility row and the cap note come
   and go), so the offset is measured at runtime rather than guessed — the previous
   round of this bug was three stacked bars each with a hand-tuned `top`. */
.full-map .leaflet-top{top:calc(var(--map-controls-h, 104px) + 14px)}

.full-map-controls{position:absolute;top:calc(60px + env(safe-area-inset-top));left:12px;right:12px;
  z-index:20;display:flex;flex-direction:column;gap:8px;pointer-events:none}
.full-map-controls > *{pointer-events:auto}

/* Sized to the job, not to the container. A search field spanning a 1440px map reads
   as a page header rather than a control, and the text you type ends up alone at the
   far left of a very wide box. Capped and left-aligned it lines up with the filter
   chips underneath, so the whole column reads as one group. On phones the cap never
   engages and it stays full width, which is what a phone wants. */
.full-map-search{align-self:flex-start;width:100%;
  display:flex;align-items:center;gap:8px;height:44px;padding:0 8px 0 13px;
  background:var(--surface-card);border:1px solid var(--line);border-radius:var(--radius-pill);
  box-shadow:var(--shadow-sm)}
.full-map-search svg{width:18px;height:18px;color:var(--text-faint);flex:0 0 auto}
.full-map-search input{flex:1 1 auto;min-width:0;height:100%;border:0;background:none;outline:none;
  font-family:var(--font-core);font-size:15px;color:var(--text-strong)}
.full-map-search input::placeholder{color:var(--text-faint)}
.full-map-search input::-webkit-search-cancel-button{display:none}
.full-map-search input:focus-visible{outline:none}
.full-map-search:focus-within{border-color:var(--line-brand);box-shadow:var(--focus-ring)}
.full-map-search button{display:flex;align-items:center;justify-content:center;width:30px;height:30px;
  flex:0 0 auto;border:0;background:var(--bg-sunken);border-radius:50%;cursor:pointer;color:var(--text-muted)}
.full-map-search button svg{width:14px;height:14px;color:inherit}

@media (min-width:640px){.full-map-search{max-width:min(380px,50vw)}}
@media (min-width:1024px){.full-map-search{max-width:min(420px,40vw)}}

.full-map-filters{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;padding-bottom:2px}
.tag-count{font-variant-numeric:tabular-nums;color:var(--text-muted);font-weight:var(--fw-regular)}
.tag.is-selected .tag-count{color:var(--green-700)}
.full-map-filters::-webkit-scrollbar{display:none}
.full-map-filters .tag{cursor:pointer;flex:0 0 auto;box-shadow:var(--shadow-sm)}
@media (hover:hover){.full-map-filters .tag:hover{background:var(--green-50)}}
@media (hover:hover){.full-map-filters .tag.is-selected:hover{background:var(--green-100)}}
.full-map-sheet{position:absolute;left:50%;transform:translateX(-50%);z-index:20;
  bottom:calc(16px + env(safe-area-inset-bottom));width:min(420px,calc(100% - 24px));
  background:var(--surface-card);border:1px solid var(--line-soft);border-radius:var(--radius-xl);
  box-shadow:var(--shadow-float);padding:14px}
.full-map-sheet .toilet-card{border:none;box-shadow:none;padding:0}
@media (hover:hover){.full-map-sheet .toilet-card:hover{transform:none;box-shadow:none}}
.full-map-sheet-close{position:absolute;top:10px;right:10px;z-index:1;display:grid;place-items:center;
  width:30px;height:30px;background:var(--white);color:var(--text-muted);border:1px solid var(--line-soft);
  border-radius:var(--radius-pill);cursor:pointer}
@media (hover:hover){.full-map-sheet-close:hover{background:var(--green-50);color:var(--text-strong)}}
.full-map-sheet-close svg{width:15px;height:15px}
.full-map-sheet .toilet-card .title-row{padding-right:30px}
/* Leaflet's own top-right stack (zoom + credit) drops below our bar and filter row */
/* Was a hand-tuned 112px, from when the controls column was a single filter row.
   Same measured offset as .leaflet-top, kept as its own rule only because this one
   has to out-specify nothing — it exists so a future reader does not re-add a magic
   number here and quietly push the zoom buttons back under the filters. */
.full-map .leaflet-top.leaflet-right{top:calc(var(--map-controls-h, 104px) + 14px)}
/* the section keeps its height while the map is away in the overlay */
.map-demo-panel.is-lent{background:var(--bg-sunken)}
@media (min-width:721px){
  /* desktop: a floating card in the corner rather than a sheet across the bottom */
  .full-map-sheet{left:16px;transform:none;width:380px;bottom:16px}
}

/* ---------- pin picker modal ---------- */
[hidden]{display:none!important}
.pin-modal{position:fixed;inset:0;z-index:2000;display:flex;align-items:center;justify-content:center;padding:24px}
.pin-modal-backdrop{position:absolute;inset:0;background:rgba(20,38,26,.42)}
.pin-modal-sheet{position:relative;display:flex;flex-direction:column;width:100%;max-width:560px;max-height:calc(100vh - 48px);background:var(--surface-card);border:1px solid var(--line-soft);border-radius:var(--radius-xl);box-shadow:var(--shadow-float);overflow:hidden}
.pin-modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:20px 20px 14px}
.pin-modal-head h3{font-size:21px;letter-spacing:-.02em}
.pin-modal-close{display:grid;place-items:center;width:36px;height:36px;flex:0 0 auto;background:var(--white);color:var(--text-strong);border:1px solid var(--line);border-radius:var(--radius-pill);box-shadow:var(--shadow-sm);cursor:pointer}
@media (hover:hover){.pin-modal-close:hover{background:var(--green-50)}}
.pin-modal-close svg{width:18px;height:18px}
.pin-map-wrap{position:relative;height:300px;flex:0 0 auto;margin:0 20px;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;touch-action:none}
.pin-crosshair{position:absolute;left:50%;top:50%;z-index:900;transform:translate(-50%,-100%);pointer-events:none;filter:drop-shadow(0 10px 14px rgba(20,38,26,.28))}
/* block, or the inline descender gap pushes the pin's tip above the map centre */
.pin-crosshair img{display:block}
.pin-locate{position:absolute;left:12px;bottom:26px;z-index:900}
.pin-locate svg{width:16px;height:16px}
.pin-modal-body{padding:16px 20px 4px;overflow-y:auto}
.pin-hint{font-size:14px;color:var(--text-muted)}
.pin-status{margin-top:10px;padding:10px 14px;border-radius:var(--radius-md);font-size:14px;background:var(--sun-100);color:#7A5200;border:1px solid #F5DFA0}
.pin-status.is-ok{background:var(--status-clean-bg);color:var(--green-800);border-color:var(--green-200)}
.pin-status.is-error{background:var(--status-dirty-bg);color:#992A14;border-color:#FFC4B4}
.pin-duplicate-choice{display:flex;gap:8px;margin-top:12px}
.pin-duplicate-choice .btn{flex:1}
.pin-status.is-warn{background:var(--sun-100);color:#7A5200;border-color:#F5DFA0}
.pin-coords{margin-top:12px;font-size:13px;font-weight:var(--fw-medium);color:var(--green-700)}
.pin-field{display:block;margin-top:14px}
.pin-field>span{display:block;margin-bottom:var(--space-2);font-size:14px;font-weight:var(--fw-medium);color:var(--text-strong)}
.pin-field-optional{font-weight:var(--fw-regular);color:var(--text-faint)}
.pin-field input{width:100%;height:var(--control-h-md);padding:0 16px;background:var(--white);border:1px solid var(--line);border-radius:var(--radius-pill);box-shadow:var(--shadow-sm);font:var(--fw-regular) 15px/1.4 var(--font-core);color:var(--text-strong);outline:none;transition:border-color var(--dur-fast) var(--ease-standard)}
.pin-field input:focus{border-color:var(--green-400)}
.pin-field input::placeholder{color:var(--text-faint)}
/* แถบขอความช่วยเหลือน้ำท่วม — รูปร่างเดียวกับแถบเล่าเรื่องอื่นบนหน้าแรก
   (ป้ายหัวข้อ · หัวเรื่องกลาง · ภาพกว้าง · ปุ่ม) ต่างแค่โทนเหลืองอำพัน
   เพื่อไม่ให้ชนกับเขียวของห้องน้ำและแดงของปุ่ม "ไม่ไหวแล้ว" */
.flood-band{background:var(--white)}
/* Tracking is for Latin capitals ("COMMUNITY LOOP"). On Thai it pulls vowels and tone marks
   away from their consonants, so script.js marks Thai eyebrows and they drop it. */
.eyebrow.is-thai,.tk-group-title.is-thai{letter-spacing:normal;text-transform:none}
.flood-band .eyebrow{background:var(--sun-100);color:#7A5200}
.flood-band-art{margin-top:44px}
.flood-band .scene{border-color:var(--sun-400)}
.flood-band-cta{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin-top:32px}
/* สามปุ่มกว้างเท่ากันในแถวเดียว ดูสมดุล · จอแคบเรียงลงเต็มความกว้างทุกปุ่ม */
.flood-band-cta .btn{flex:1 1 0;max-width:250px;min-width:0;justify-content:center;white-space:nowrap}
@media (max-width:720px){.flood-band-cta .btn{flex:1 1 100%;max-width:none}}
.flood-open-go{background:var(--sun-400);color:var(--ink-900);border-color:var(--sun-400);font-weight:var(--fw-bold)}
@media (hover:hover){.flood-open-go:hover{filter:brightness(.97)}}
/* หัวข้อสองท่อน: ตัดบรรทัดระหว่างท่อนเท่านั้น ไม่ตัดกลางคำว่า "ขอความ|ช่วยเหลือ" */
.flood-band h2 span{display:inline-block}
.flood-band-who{margin:16px auto 0;max-width:560px;text-align:center;font-size:13px;line-height:1.6;color:var(--text-muted)}

.pin-hours{display:grid;grid-template-columns:1fr auto 1fr;align-items:end;gap:8px}
.pin-hours-time>span{display:block;margin-bottom:6px;font-size:13px;color:var(--text-muted)}
.pin-hours-dash{padding-bottom:14px;color:var(--text-faint)}
.pin-field .pin-hours input:disabled{opacity:.45;box-shadow:none}
.pin-hours-allday{margin-top:10px}
.pin-modal-foot{display:flex;justify-content:flex-end;gap:10px;padding:16px 20px 20px}
body.modal-open{overflow:hidden}

/* ---------- donation: footer button + dialog ---------- */
.qr-button{display:block;padding:0;background:none;border:none;cursor:pointer;text-align:left}
.qr-button img{display:block;border-radius:var(--radius-sm);background:var(--white);padding:6px;
  transition:transform var(--dur-base) var(--ease-out-soft),box-shadow var(--dur-base) var(--ease-standard)}
.qr-button span{display:block;margin-top:8px;max-width:104px;font-size:12px;line-height:1.4;color:rgba(255,255,255,.6)}
@media (hover:hover){.qr-button:hover img{transform:translateY(var(--hover-lift));box-shadow:var(--shadow-brand)}}
@media (hover:hover){.qr-button:hover span{color:var(--green-400)}}
.qr-button:active img{transform:scale(var(--press-scale))}

.donate-modal .pin-modal-sheet{max-width:440px}
.donate-qr{margin:0 auto;text-align:center}
/* height must follow width, or a narrow screen stretches the code and it stops scanning */
.donate-qr img{display:block;margin:0 auto;width:260px;max-width:100%;height:auto;aspect-ratio:1;padding:20px;background:var(--white);
  border:1px solid var(--line-soft);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}
.donate-qr figcaption{margin-top:10px;font-size:13px;font-weight:var(--fw-medium);color:var(--text-muted)}
.donate-lead{margin-top:18px;font-size:15px;line-height:1.7;color:var(--text-body)}
.donate-merit{margin-top:18px}
.donate-merit-title{display:flex;align-items:center;gap:8px;margin-bottom:10px;
  font-size:15px;font-weight:var(--fw-semibold);color:var(--green-900)}
.donate-merit-title img{border-radius:7px}
.donate-merit ul{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:6px}
.donate-merit li{font-size:14px;line-height:1.6;color:var(--green-800)}
.donate-merit li::marker{color:var(--green-500)}
.donate-thanks{margin-top:16px;font-size:14px;line-height:1.7;color:var(--text-muted)}
/* the last line shouldn't sit flush against the scroll boundary on short screens */
.donate-modal .pin-modal-body{padding-bottom:16px}
/* .pin-modal-body ends at 4px because it normally sits above .pin-modal-foot, which
   supplies the sheet's bottom edge. The emergency dialog has no foot in any of its
   four states — the choices, the search, the result and the error all live in the
   body — so that 4px was the whole bottom margin, against 20px everywhere else.
   Matching the side padding closes the frame. */
.emergency-modal .pin-modal-body{padding-bottom:20px}
.reviews-modal .pin-modal-body{padding-bottom:20px}
/* ช่องทางของหน่วยงาน (น้ำท่วม) — ป๊อปอัปเดียวใช้ทั้งหน้าแรกและหน้าแผนที่ขอความช่วยเหลือ
   เนื้อหาอยู่ใน incident/agencies.js */
.agencies-modal .pin-modal-head h2{margin:0;font-size:21px;letter-spacing:-.02em;color:var(--text-strong)}
.agencies-modal .pin-modal-body{padding-bottom:20px}
.agencies-lead{margin:0 0 6px;font-size:14px;line-height:1.6;color:var(--text-muted)}
.agencies-head{margin:18px 0 8px;font-size:15px;color:var(--text-strong)}
.agencies-note{margin:0 0 8px;font-size:12px;line-height:1.6;color:var(--text-muted)}
.agencies-calls{display:flex;flex-direction:column;gap:8px;margin-top:4px}
.agencies-calls a{display:flex;align-items:center;min-height:52px;padding:10px 16px;
  background:var(--sun-100);border:1px solid var(--sun-400);border-radius:var(--radius-pill);
  font-size:15px;font-weight:var(--fw-semibold);color:var(--text-strong);text-decoration:none}
@media (hover:hover){.agencies-calls a:hover{background:var(--white)}}
.agencies-list{display:flex;flex-direction:column;gap:8px}
.agencies-list a{display:block;padding:12px 14px;background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius-md);text-decoration:none;color:var(--text-body)}
@media (hover:hover){.agencies-list a:hover{background:var(--green-50);border-color:var(--line-brand)}}
.agencies-list strong{display:block;font-size:15px;color:var(--text-strong)}
.agencies-list span{display:block;margin-top:2px;font-size:12px;line-height:1.55;color:var(--text-muted)}

/* ---------- pin form: cleanliness + facilities ---------- */
.pin-subfield{margin:-2px 0 10px;font-size:13px;color:var(--text-muted)}
.clean-stars{display:flex;gap:8px}
.clean-stars button{width:48px;height:48px;font-size:26px;line-height:1;background:var(--white);
  color:var(--ink-200);border:1px solid var(--line);border-radius:var(--radius-md);cursor:pointer;
  transition:color var(--dur-fast) var(--ease-standard),background var(--dur-fast) var(--ease-standard)}
@media (hover:hover){.clean-stars button:hover{background:var(--green-50)}}
.clean-stars button.is-on{color:var(--sun-400);background:var(--green-50);border-color:var(--green-300)}
.clean-hint{margin-top:8px;font-size:12px;line-height:1.6;color:var(--text-faint)}
.clean-hint.is-picked{color:var(--green-700);font-weight:var(--fw-medium)}
.facility-picker{display:flex;flex-wrap:wrap;gap:8px}
.facility-option{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:8px 14px;
  background:var(--white);color:var(--text-body);border:1px solid var(--line);border-radius:var(--radius-pill);
  font:var(--fw-medium) 14px/1 var(--font-core);cursor:pointer;
  transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard)}
@media (hover:hover){.facility-option:hover{background:var(--green-50)}}
.facility-option img{border-radius:6px;flex:0 0 auto}
.facility-option[aria-pressed="true"]{background:var(--green-100);border-color:var(--green-300);color:var(--green-900)}
.facility-option[aria-pressed="true"]::after{content:"✓";font-weight:var(--fw-bold);color:var(--green-600)}
/* the confirm button stays reachable however long the form gets */
#pinModal .pin-modal-foot{position:sticky;bottom:0;background:var(--surface-card);
  border-top:1px solid var(--line-soft);z-index:2}

/* ---------- community trust & moderation ---------- */
.card-clean{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:10px;font-size:12px;color:var(--text-muted)}
.card-clean span{color:var(--text-body);font-weight:var(--fw-medium)}
.facility-mini{padding:3px 8px;border-radius:var(--radius-pill);background:var(--green-50);
  border:1px solid var(--green-100);font-size:11px;color:var(--green-800);white-space:nowrap}
.card-provenance{display:flex;flex-wrap:wrap;gap:6px 12px;margin-top:10px}
.source-tag{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-muted)}
.source-tag img{border-radius:5px;flex:0 0 auto}
.community-status{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-muted)}
.community-status::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--ink-300);flex:0 0 auto}
.community-status.is-fresh::before{background:var(--green-400)}
.community-status.is-stale::before{background:var(--sun-400)}
.community-status.is-old::before{background:#E08A2E}
.community-status.is-ancient::before{background:var(--coral-400)}
.community-status.is-flagged{color:#992A14}
.community-status.is-flagged::before{background:var(--coral-400)}
.community-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}
.community-actions .btn{flex:1 1 auto;padding:0 12px}
.btn-danger-ghost{color:var(--coral-600)}
@media (hover:hover){.btn-danger-ghost:hover{background:var(--coral-100)}}
.review-stars{display:flex;gap:6px;margin:14px 0 4px}
.review-stars button{width:40px;height:40px;font-size:24px;line-height:1;background:var(--white);
  color:var(--ink-200);border:1px solid var(--line);border-radius:var(--radius-md);cursor:pointer}
.review-stars button.is-on{color:var(--sun-400);border-color:var(--green-300);background:var(--green-50)}
.report-reasons{display:flex;flex-direction:column;gap:8px;margin-top:14px}
.report-reason{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--white);
  border:1px solid var(--line);border-radius:var(--radius-md);font-size:15px;color:var(--text-strong);cursor:pointer}
.report-reason:has(input:checked){background:var(--green-50);border-color:var(--green-300)}
.report-reason input{accent-color:var(--green-500);width:18px;height:18px}
.pin-field textarea,.pin-field select{width:100%;padding:12px 16px;background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius-md);box-shadow:var(--shadow-sm);font:var(--fw-regular) 15px/1.6 var(--font-core);
  color:var(--text-strong);outline:none;resize:vertical}
.pin-field textarea:focus,.pin-field select:focus{border-color:var(--green-400)}
.feedback-optional{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.feedback-context{margin-top:12px;font-size:12px;color:var(--text-faint)}
.feedback-done{padding:18px 0 6px;font-size:16px;font-weight:var(--fw-semibold);color:var(--green-700);text-align:center}
#feedbackDone .feedback-context{text-align:center}
@media (max-width:480px){.feedback-optional{grid-template-columns:1fr}}
.footer-link-btn{padding:0;background:none;border:none;font:var(--fw-regular) 15px/1.7 var(--font-core);
  color:rgba(255,255,255,.78);text-align:left;cursor:pointer}
@media (hover:hover){.footer-link-btn:hover{color:var(--white);text-decoration:underline;text-underline-offset:3px}}

/* ---------- Hall of Fame ---------- */
.hall-podium{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:16px;margin-top:40px}
.hall-card{display:flex;align-items:flex-start;gap:14px;padding:20px;text-align:left;cursor:pointer;
  background:var(--surface-card);border:1px solid var(--line-soft);border-radius:var(--radius-card);
  box-shadow:var(--shadow-card);
  transition:box-shadow var(--dur-base) var(--ease-standard),transform var(--dur-base) var(--ease-out-soft)}
@media (hover:hover){.hall-card:hover{box-shadow:var(--shadow-raised);transform:translateY(var(--hover-lift))}}
.hall-card.is-me,.hall-row.is-me{border-color:var(--green-300);background:var(--green-50)}
.rank-badge{display:grid;place-items:center;width:38px;height:38px;flex:0 0 auto;border-radius:var(--radius-pill);
  background:var(--bg-page);border:1px solid var(--line-soft);
  font-size:15px;font-weight:var(--fw-bold);color:var(--text-muted)}
.rank-badge.is-medal{font-size:22px;background:none;border-color:transparent}
.hall-avatar{display:grid;place-items:center;width:44px;height:44px;flex:0 0 auto;border-radius:50%;
  background:var(--green-100);color:var(--green-800);font-size:18px;font-weight:var(--fw-semibold)}
.hall-avatar.sm{width:34px;height:34px;font-size:15px}
.hall-avatar.lg{width:60px;height:60px;font-size:24px}
.hall-body{display:flex;flex-direction:column;gap:3px;min-width:0}
.hall-name{font-size:17px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.hall-tag{display:inline-block;padding:1px 8px;border-radius:var(--radius-pill);background:var(--green-400);
  color:var(--green-900);font-size:11px;font-weight:var(--fw-semibold);vertical-align:middle}
.hall-points-value{font-size:20px;font-weight:var(--fw-bold);letter-spacing:-.02em;color:var(--green-700)}
.hall-meta{font-size:13px;color:var(--text-muted)}
.hall-badges{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.hall-badge{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:var(--radius-pill);
  background:var(--green-50);border:1px solid var(--green-100);font-size:12px;
  font-weight:var(--fw-medium);color:var(--green-800)}
.hall-badge img{border-radius:4px}

.hall-rows{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.hall-row{display:flex;align-items:center;gap:12px;width:100%;min-height:56px;padding:10px 16px;text-align:left;
  cursor:pointer;background:var(--surface-card);border:1px solid var(--line-soft);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-sm)}
@media (hover:hover){.hall-row:hover{background:var(--green-50)}}
.hall-row-name{flex:1 1 auto;min-width:0;font-size:15px;font-weight:var(--fw-medium);color:var(--text-strong);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hall-row-meta{font-size:12px;color:var(--text-muted);white-space:nowrap}
.hall-row-points{font-size:16px;font-weight:var(--fw-bold);color:var(--green-700);white-space:nowrap}

.hall-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:14px;margin-top:28px}
.hall-you{font-size:14px;color:var(--text-muted)}
.hall-empty{display:flex;flex-direction:column;align-items:center;gap:14px;margin-top:40px;padding:40px 24px;
  background:var(--surface-card);border:1px solid var(--line-soft);border-radius:var(--radius-card);
  box-shadow:var(--shadow-card);text-align:center}
.hall-empty p{font-size:16px;line-height:1.7;color:var(--text-muted)}
.hall-empty-line{padding:20px 0;text-align:center;color:var(--text-muted)}

.hall-mine-card{display:flex;align-items:center;gap:14px;padding:16px;margin-bottom:6px;
  background:var(--green-50);border:1px solid var(--green-100);border-radius:var(--radius-lg)}
.hall-mine-rank{display:grid;place-items:center;width:46px;height:46px;flex:0 0 auto;border-radius:var(--radius-pill);
  background:var(--green-400);color:var(--green-900);font-size:16px;font-weight:var(--fw-bold)}
.hall-mine-card span{display:flex;flex-direction:column;gap:2px;font-size:13px;color:var(--text-muted)}
.hall-mine-card strong{font-size:16px;color:var(--text-strong)}
.hall-points-legend{display:flex;flex-direction:column;gap:8px;margin-top:16px;padding:14px 16px;
  background:var(--bg-page);border-radius:var(--radius-lg);font-size:13px;color:var(--text-body)}
.hall-points-legend span{display:flex;align-items:center;gap:8px}
.hall-points-legend img{border-radius:5px}
.hall-legend-title{font-weight:var(--fw-semibold);color:var(--text-strong)}

.profile-head{display:flex;align-items:center;gap:14px}
.profile-name{font-size:19px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.profile-rank{margin-top:2px;font-size:14px;color:var(--text-muted)}
.profile-badges{margin-top:14px}
.profile-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:16px}
.profile-stats div{display:flex;flex-direction:column;gap:2px;padding:12px;background:var(--surface-card);
  border:1px solid var(--line-soft);border-radius:var(--radius-md);font-size:12px;color:var(--text-muted)}
.profile-stats strong{font-size:22px;font-weight:var(--fw-bold);color:var(--text-strong);line-height:1.1}
.profile-stats span{font-size:11px;color:var(--text-faint)}

@media (max-width:640px){
  .hall-row-meta{display:none}
  .profile-stats{grid-template-columns:1fr}
  .hall-foot{flex-direction:column}
}

/* ---------- emergency CTA ----------

   The one red thing on a green site. That is the whole idea: on a page where every
   other control is THEEKHEE green, red means "this one is different, press it when it
   is urgent" without a single word of explanation.

   These reds are local to this button on purpose — they are not added to the global
   token set, because nothing else on the site should ever be able to reach for them.

   What used to be here: a ring that pulsed every five seconds, forever. It was removed
   rather than restyled. A control that keeps flashing while you are calmly reading the
   page is asking for attention it has not earned, and by the time you actually need it
   you have learned to ignore it. Emphasis now comes from colour and weight, which are
   always on, and motion is kept for the moments you are already touching the thing. */
.btn-emergency{
  --em-red:#E53935;
  --em-red-hover:#D32F2F;
  --em-red-active:#C62828;
  position:relative;
  background:var(--em-red);
  color:#FFFFFF;
  /* A neutral shadow for the lift plus a red one tinted from the button's own colour,
     so it reads as a control resting above the page rather than a glowing object. */
  box-shadow:0 1px 2px rgba(20,38,26,.10), 0 6px 18px -4px rgba(229,57,53,.42);
  transition:background var(--dur-fast) var(--ease-standard),
             box-shadow var(--dur-base) var(--ease-standard),
             transform var(--dur-fast) var(--ease-standard);
}

/* 19px/700 is not decoration. White on #E53935 is 4.23:1, which clears WCAG AA for
   large text (3:1) but not for normal text (4.5:1) — and 14pt bold counts as large.
   Sizing the label up is what makes the mandated red legal to use with white on it. */
.btn-emergency__label{font-size:19px;font-weight:var(--fw-bold);letter-spacing:-.01em}

.btn-emergency__icon{display:inline-flex;flex:0 0 auto}
.btn-emergency__icon svg{
  display:block;width:24px;height:24px;
  transition:transform var(--dur-base) var(--ease-pop);
}

@media (hover:hover){.btn-emergency:hover{
  background:var(--em-red-hover);
  box-shadow:0 2px 4px rgba(20,38,26,.12), 0 10px 24px -6px rgba(229,57,53,.50);
}}
/* The toilet leans forward a touch, as if already heading off. Only on hover — this is
   a reaction to the person, not something the page does at them. */
@media (hover:hover){.btn-emergency:hover .btn-emergency__icon svg{transform:translateX(2px) rotate(-4deg)}}

/* Press it and it goes down, not smaller. The global .btn:active scales every button;
   for something this size a real 2px depression reads as a physical control. */
.btn-emergency:active{
  background:var(--em-red-active);
  transform:translateY(2px);
  box-shadow:0 1px 2px rgba(20,38,26,.10), 0 3px 8px -3px rgba(229,57,53,.40);
}

/* The site-wide focus ring is green, which on a red button looks like a rendering
   fault. Same shape, same thickness, this button's own colour. */
.btn-emergency:focus-visible{
  outline:none;
  box-shadow:0 0 0 3px #FFFFFF, 0 0 0 6px rgba(229,57,53,.55),
             0 6px 18px -4px rgba(229,57,53,.42);
}

@media (prefers-reduced-motion:reduce){
  .btn-emergency,.btn-emergency__icon svg{transition:none}
  @media (hover:hover){.btn-emergency:hover .btn-emergency__icon svg{transform:none}}
}

.emergency-option{display:flex;align-items:center;gap:14px;width:100%;min-height:64px;
  margin-top:12px;padding:14px 18px;background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);cursor:pointer;text-align:left;
  transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard)}
@media (hover:hover){.emergency-option:hover{background:var(--green-50);border-color:var(--green-300)}}
.emergency-option.is-primary{background:var(--green-50);border-color:var(--green-300)}
@media (hover:hover){.emergency-option.is-primary:hover{background:var(--green-100)}}
.emergency-option img{border-radius:9px;flex:0 0 auto}
.emergency-option span{display:flex;flex-direction:column;gap:2px;font-size:14px;color:var(--text-muted)}
.emergency-option strong{font-size:17px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.emergency-busy{padding:28px 0;text-align:center;font-size:16px;color:var(--text-muted)}
.emergency-found{margin-bottom:12px;font-size:15px;font-weight:var(--fw-semibold);color:var(--green-700)}
.em-card{display:flex;align-items:center;gap:12px;padding:14px;background:var(--green-50);
  border:1px solid var(--green-100);border-radius:var(--radius-lg)}
.em-pin{flex:0 0 auto}
.em-name{font-size:17px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.em-source{display:flex;align-items:center;gap:6px;margin-top:4px;font-size:12px;color:var(--text-muted)}
.em-source img{border-radius:5px}
.em-facts{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.em-fact{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:96px;padding:10px 12px;
  background:var(--white);border:1px solid var(--line-soft);border-radius:var(--radius-md);
  font-size:12px;color:var(--text-muted)}
.em-fact strong{font-size:15px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.em-actions{display:flex;flex-direction:column;gap:8px;margin-top:16px}
.emergency-error-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.emergency-error-actions .btn{flex:1 1 auto}

/* ---------- toast ---------- */
.toast{position:fixed;left:50%;bottom:28px;z-index:2100;transform:translateX(-50%);display:flex;align-items:center;gap:10px;max-width:calc(100vw - 40px);padding:12px 18px;background:var(--green-900);color:var(--white);border-radius:var(--radius-pill);box-shadow:var(--shadow-float);font-size:15px;font-weight:var(--fw-medium)}
.toast img{border-radius:7px}

@media (max-width:640px){
  .pin-modal{padding:0;align-items:flex-end}
  .pin-modal-sheet{max-width:none;max-height:92vh;border-radius:var(--radius-xl) var(--radius-xl) 0 0}
  /* The form grew (cleanliness + facilities), and the map sits outside the scroll
     area, so it has to give some height back or the fields get a 180px window. */
  .pin-map-wrap{height:34vh;min-height:200px;max-height:300px}
  .pin-modal-foot{padding-bottom:calc(20px + env(safe-area-inset-bottom))}
  .pin-modal-foot .btn{flex:1}
}

/* ---------- final CTA ---------- */
.final-cta{position:relative;overflow:hidden;background:var(--green-400);border-radius:var(--radius-2xl);padding:64px 48px;text-align:center;margin:0 0 96px}
.final-cta .dots{position:absolute;inset:0;opacity:.32;background-image:radial-gradient(circle at 12% 22%,#fff 0 2.5px,transparent 2.5px),radial-gradient(circle at 62% 72%,#fff 0 2.5px,transparent 2.5px);background-size:54px 54px}
.final-cta .content{position:relative}
.final-cta .content .scene{max-width:760px;margin:0 auto 30px}
/* Portrait artwork: keep its own ratio and let the shadow follow the shape, not the box. */
.final-cta .mascot{margin:0 auto 22px;display:block;height:auto;filter:drop-shadow(0 10px 18px rgba(20,38,26,.22))}
.final-cta h2{font-size:clamp(30px,4.4vw,52px);line-height:1.22;letter-spacing:-.03em;color:var(--green-900)}
.final-cta .lede{max-width:520px;margin:18px auto 30px;font-size:18px;line-height:1.6;color:var(--green-900);opacity:.82}
.final-cta .cta-row{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}

/* ---------- footer ---------- */
.site-footer{background:var(--surface-ink);color:var(--white);padding:56px var(--gutter) 40px}
.site-footer .footer-top{max-width:var(--container-max);margin:0 auto;display:flex;flex-wrap:wrap;gap:40px;justify-content:space-between}
.site-footer .brand-col{max-width:340px}
.site-footer .brand-col p{margin-top:14px;font-size:15px;line-height:1.7;color:rgba(255,255,255,.7)}
.site-footer .link-cols{display:flex;gap:56px;flex-wrap:wrap}
.site-footer .link-col h4{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--green-400);font-weight:var(--fw-semibold);margin:0 0 14px}
.site-footer .link-col{display:flex;flex-direction:column;gap:10px}
.site-footer .link-col a{font-size:15px;color:rgba(255,255,255,.78);text-decoration:none}
@media (hover:hover){.site-footer .link-col a:hover{color:var(--white)}}
.site-footer .qr img{display:block;border-radius:var(--radius-sm);background:var(--white);padding:6px}
.site-footer .footer-bottom{max-width:var(--container-max);margin:40px auto 0;padding-top:20px;border-top:1px solid rgba(255,255,255,.12);font-size:13px;color:rgba(255,255,255,.5)}

@media (max-width:640px){
  .phone{width:calc(393px * .62);height:calc(852px * .62)}
  .phone-inner{transform:scale(.62)}
  .final-cta{padding:48px 24px}
  .hero .hero-inner{gap:40px}
}


/* ---------- pre-deploy QA additions ---------- */
/* Nav "แจ้งปัญหา" became a button so it stops jumping the page to the top;
   it still has to read as one of the nav links beside it. */
.nav-link-btn{background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer}
@media (hover:hover){.nav-link-btn:hover{color:var(--green-700)}}
.community-empty{display:grid;place-items:center;min-height:96px;text-align:center;color:var(--text-muted)}
.community-empty p{margin:0;font-size:14px;line-height:1.7}
.review-place{font-size:12px;color:var(--text-muted)}
.map-empty-note{position:absolute;left:50%;top:50%;z-index:30;transform:translate(-50%,-50%);
  max-width:min(320px,80vw);margin:0;padding:14px 18px;text-align:center;
  background:var(--surface-card);color:var(--text-body);border:1px solid var(--line);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-float);font-size:14px;line-height:1.7}
.footer-attribution{display:inline-block;margin-top:6px;font-size:12px;line-height:1.7;opacity:.75}
.footer-attribution a{color:inherit;text-decoration:underline}
/* Sits under the filter row, not over the preview card. It describes what the current
   view is showing — the same job as a filter — so it belongs with them at the top.
   At the bottom it covered the card's "ดูรายละเอียด" button outright.
   Width stops short of the zoom control on the right at every phone size. */
.map-cap-note{position:absolute;z-index:20;left:50%;transform:translateX(-50%);
  top:calc(var(--map-controls-h, 104px) + 14px);
  /* leaves the right-hand gutter clear for Leaflet's zoom buttons at the same height */
  max-width:min(320px,calc(100% - 120px));margin:0;padding:7px 14px;text-align:center;
  background:var(--surface-card);color:var(--text-muted);border:1px solid var(--line);
  border-radius:var(--radius-pill);box-shadow:var(--shadow-sm);font-size:12px;line-height:1.5;
  pointer-events:none}

/* ---------- version + changelog ---------- */
/* Was a bare 20px-tall run of text with no padding: a real button that behaved like
   one on a mouse and was close to unhittable with a thumb. Padding gives it a target
   without turning a quiet footer link into a loud control, and the underline says it
   is something you can press — which the plain text never did. */
.version-btn{display:inline-block;margin-top:8px;padding:11px 2px;min-height:44px;
  text-underline-offset:3px;background:none;border:0;
  font:inherit;font-size:12px;color:inherit;opacity:.75;text-decoration:underline;cursor:pointer}
@media (hover:hover){.version-btn:hover{opacity:1}}
.changelog-entry{padding:14px 0;border-bottom:1px solid var(--line-soft)}
.changelog-entry:last-child{border-bottom:0}
.changelog-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.changelog-version{font-size:17px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.changelog-now{font-size:11px;font-weight:var(--fw-medium);padding:2px 8px;border-radius:var(--radius-pill);
  background:var(--green-100);color:var(--green-800)}
.changelog-date{margin-left:auto;font-size:12px;color:var(--text-faint)}
.changelog-list{margin:0;padding-left:18px;color:var(--text-body);font-size:14px;line-height:1.8}
.changelog-list li{margin:3px 0}

/* ---------- display name ---------- */
.hall-you-link{background:none;border:0;padding:0;font:inherit;color:var(--green-700);
  text-decoration:underline;cursor:pointer}
@media (hover:hover){.hall-you-link:hover{color:var(--green-800)}}
.name-editor{margin:16px 0 4px;padding:14px;background:var(--bg-page);
  border:1px solid var(--line-soft);border-radius:var(--radius-lg)}
.name-editor .pin-field{margin:0}
.name-editor-foot{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:10px}
.name-editor-foot .pin-status{margin:0;flex:1;min-width:160px;font-size:12.5px}

/* ---------- install guide ---------- */
.nav-donate::before{content:"\2764\FE0F";margin-right:5px}
.nav-install::before{content:"\2B07\FE0F";margin-right:5px}
.install-guide{margin:14px 0 0;padding:16px;background:var(--bg-page);
  border:1px solid var(--line-soft);border-radius:var(--radius-lg)}
.install-guide h4{margin:0 0 10px;font-size:15px;color:var(--text-strong)}
.install-guide ol{margin:0;padding-left:20px;color:var(--text-body);font-size:14px;line-height:1.9}
.install-guide li{margin:5px 0}
.install-guide li strong{color:var(--text-strong);font-weight:var(--fw-semibold)}
.install-note{margin:12px 0 0;padding-top:10px;border-top:1px solid var(--line-soft);
  font-size:12.5px;line-height:1.7;color:var(--status-okay);}
.install-foot{margin:14px 0 0;font-size:12.5px;line-height:1.7;color:var(--text-faint)}

/* ---------- community evidence ----------
   Four states that must be told apart at a glance, without turning the card into a
   traffic light. Colour carries the state, the small line under the label carries the
   actual claim, and "ไม่ตรงกัน" is the only one that gets a warning tone — because it
   is the only one asking the reader to be careful. */
.facility-chip.evidence{align-items:flex-start;padding:7px 13px 7px 7px;gap:9px}
.facility-chip.evidence span{display:flex;flex-direction:column;gap:1px;line-height:1.35}
.facility-chip.evidence b{font-size:13px;font-weight:var(--fw-semibold);color:var(--text-strong)}
.facility-chip.evidence small{font-size:11px;font-weight:var(--fw-regular);color:var(--text-muted)}
.facility-chip.evidence.is-official{background:var(--sky-100);border-color:#A9DEEF}
.facility-chip.evidence.is-official small{color:var(--sky-600)}
.facility-chip.evidence.is-yes{background:var(--green-50);border-color:var(--line-brand)}
.facility-chip.evidence.is-yes small{color:var(--green-700)}
.facility-chip.evidence.is-no{background:var(--bg-sunken);border-color:transparent}
.facility-chip.evidence.is-no b{color:var(--text-muted)}
.facility-chip.evidence.is-no img{filter:grayscale(1);opacity:.55}
.facility-chip.evidence.is-conflict{background:var(--sun-100);border-color:#F0D28A}
.facility-chip.evidence.is-conflict small{color:var(--sun-600);font-weight:var(--fw-medium)}

/* where in the building it actually is */
.loc-list{list-style:none;margin:10px 0 0;padding:0;display:grid;gap:6px}
.loc-list li{display:flex;gap:10px;align-items:baseline;font-size:13px;color:var(--text-body)}
.loc-list .loc-key{flex:0 0 74px;color:var(--text-muted);font-size:12px}
.loc-list small{display:block;color:var(--text-faint);font-size:11px}

.btn.is-saved{background:var(--green-50);border-color:var(--line-brand);color:var(--green-800)}

/* ---------- contribution sheet ---------- */
.contrib-group{margin-bottom:18px}
.contrib-group:first-child{margin-top:14px}
.contrib-group h4{margin:0 0 8px;font-size:13px;font-weight:var(--fw-semibold);color:var(--text-muted);
  letter-spacing:.04em;text-transform:uppercase}
.contrib-row{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:9px 0;border-bottom:1px solid var(--line-soft)}
.contrib-row:last-child{border-bottom:0}
.contrib-label{display:flex;flex-direction:column;gap:2px;font-size:14px;color:var(--text-strong);min-width:0}
.contrib-known{font-size:11px;color:var(--text-faint);font-weight:var(--fw-regular)}
.contrib-choice{display:flex;gap:6px;flex:0 0 auto}
.contrib-choice button{min-width:52px;height:34px;padding:0 12px;cursor:pointer;
  background:var(--white);color:var(--text-body);border:1px solid var(--line);
  border-radius:var(--radius-pill);font-family:var(--font-core);font-size:13px;
  font-weight:var(--fw-medium);line-height:1;
  transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard)}
@media (hover:hover){.contrib-choice button:hover{background:var(--green-50)}}
.contrib-choice button[data-val="yes"].is-on{background:var(--green-400);border-color:var(--green-500);color:var(--green-900)}
.contrib-choice button[data-val="no"].is-on{background:var(--ink-200);border-color:var(--ink-300);color:var(--ink-900)}
.contrib-location .pin-field{margin-bottom:10px}

@media (max-width:420px){
  /* the answer buttons must stay full-size targets; the label is what gives way
     (kept vertically centred: top-aligning left every one-line label floating above its buttons) */
  .contrib-label{font-size:13px}
  .contrib-choice button{min-width:48px}
}

.contrib-history{margin-top:18px;padding-top:16px;border-top:1px solid var(--line-soft)}
.contrib-history h4{margin:0 0 10px;font-size:14px;color:var(--text-strong)}
.contrib-history ul{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.contrib-history li{display:flex;flex-direction:column;gap:2px}
.contrib-history li span{font-size:13px;font-weight:var(--fw-medium);color:var(--text-strong)}
.contrib-history li small{font-size:12px;color:var(--text-muted)}

/* ---------- reading reviews ----------
   A list of opinions, not a comment thread. No avatars, no reply affordance, no nesting:
   the reader is deciding whether to walk somewhere, and everything that does not help
   with that decision is noise. */
.review-cta{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;
  margin-top:2px;padding:10px 14px;background:var(--surface-brand-soft);color:var(--green-800);
  border:1px solid var(--line-brand);border-radius:var(--radius-sm);cursor:pointer;
  font-family:var(--font-core);font-size:14px;font-weight:var(--fw-semibold);text-align:left;
  transition:background var(--dur-fast) var(--ease-standard)}
@media (hover:hover){.review-cta:hover{background:var(--green-100)}}
.review-cta-count{font-weight:var(--fw-regular);color:var(--green-700);font-variant-numeric:tabular-nums}

.reviews-modal .pin-modal-sheet{max-width:520px}
.rv-summary{display:flex;align-items:center;gap:10px;margin:0 0 16px;padding-bottom:14px;
  border-bottom:1px solid var(--line-soft);font-size:14px;color:var(--text-muted)}
.rv-summary strong{font-size:19px;color:var(--text-strong);font-variant-numeric:tabular-nums}
.rv-list{list-style:none;margin:0;padding:0;display:grid;gap:14px}
.rv-item{padding:14px 16px;background:var(--surface-card);border:1px solid var(--line-soft);
  border-radius:var(--radius-card)}
.rv-item.is-flagged{border-color:#F0D28A;background:var(--sun-100)}
.rv-top{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap}
.rv-who{display:inline-flex;align-items:center;gap:6px;font-size:14px;
  font-weight:var(--fw-semibold);color:var(--text-strong)}
.rv-when{font-size:12px;color:var(--text-faint);white-space:nowrap}
.rv-stars{margin:6px 0 8px}
.rv-text{margin:0;font-size:14px;line-height:1.65;color:var(--text-body);overflow-wrap:anywhere}
.rv-text.is-empty{color:var(--text-faint);font-style:italic}
.rv-flag{margin:10px 0 0;font-size:12px;line-height:1.6;color:var(--sun-600);font-weight:var(--fw-medium)}
.rv-actions{display:flex;align-items:center;gap:8px;margin-top:12px}
.rv-act{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  /* 40px keeps both controls a comfortable thumb target on a phone */
  min-height:40px;padding:0 13px;background:var(--white);color:var(--text-muted);
  border:1px solid var(--line);border-radius:var(--radius-pill);cursor:pointer;
  font-family:var(--font-core);font-size:13px;font-weight:var(--fw-medium);line-height:1;
  transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),
             border-color var(--dur-fast) var(--ease-standard)}
@media (hover:hover){.rv-act:hover{background:var(--bg-sunken)}}
.rv-heart-count{font-variant-numeric:tabular-nums;min-width:6px}
/* Pink only once it is on. A row of pre-filled red hearts would read as a score, and a
   heart here is one person saying "this helped me", never part of the rating. */
.rv-heart.is-on{color:#E8447A;border-color:#F6BDD1;background:#FDEDF3}
@media (hover:hover){.rv-heart.is-on:hover{background:#FBE0EB}}
@media (hover:hover){.rv-report:hover{color:var(--coral-600);border-color:var(--coral-400)}}

.rv-empty{display:flex;flex-direction:column;align-items:flex-start;gap:8px;
  padding:22px 18px;background:var(--bg-sunken);border-radius:var(--radius-card)}
.rv-empty strong{font-size:15px;color:var(--text-strong)}
.rv-empty span{font-size:14px;color:var(--text-muted)}
.rv-empty .btn{margin-top:6px}

@media (max-width:420px){
  .rv-when{width:100%}
  .rv-item{padding:13px 14px}
}

/* ---------- live presence ----------
   A caption, not a metric. Muted text, no card, no border — it should read as a small
   true remark under the buttons rather than a figure on a dashboard. */
.presence{display:flex;align-items:center;gap:8px;margin:16px 0 0;
  font-size:13px;line-height:1.5;color:var(--text-muted)}
.presence strong{color:var(--text-body);font-weight:var(--fw-semibold);font-variant-numeric:tabular-nums}
.presence-dot{width:8px;height:8px;flex:0 0 auto;border-radius:50%;background:var(--green-500);
  /* A ring instead of a blink. The dot means "there are people here", which is a state,
     and a state does not need to flash to be understood. */
  box-shadow:0 0 0 3px var(--green-100)}
@media (max-width:480px){.presence{font-size:12px;margin-top:14px}}

/* ---------- community: what's happening now, how to get in, badges ---------- */
.place-badges{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.status-now{margin:4px 0 12px;padding:8px 8px 8px 12px;background:var(--bg-sunken);border-radius:var(--radius-md)}
.status-now-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.status-now-text{min-width:0;font-size:13px;color:var(--text-muted);line-height:1.4}
.status-now-text b{color:var(--text-strong)}
.status-now-text .nowrap{white-space:nowrap}
.status-now-text .is-known{color:var(--text-body);font-weight:var(--fw-medium)}
.status-toggle{flex:0 0 auto;height:30px;padding:0 12px;background:var(--white);color:var(--text-strong);border:1px solid var(--line);border-radius:var(--radius-pill);font:inherit;font-size:12px;font-weight:var(--fw-semibold);cursor:pointer}
.status-now-actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.status-now-actions[hidden]{display:none}
.status-btn{height:32px;padding:0 11px;background:var(--white);color:var(--text-strong);border:1px solid var(--line);border-radius:var(--radius-pill);font:inherit;font-size:13px;font-weight:var(--fw-medium);cursor:pointer}
@media (hover:hover){.status-btn:hover{background:var(--green-50)}}
.status-btn:active{transform:scale(var(--press-scale))}
.contrib-attr{display:flex;flex-direction:column;gap:8px;padding:10px 0;border-top:1px solid var(--line-soft)}
.contrib-attr:first-of-type{border-top:0}
.contrib-options{display:flex;flex-wrap:wrap;gap:6px}
.contrib-options button{min-height:36px;padding:6px 12px;background:var(--white);color:var(--text-body);border:1px solid var(--line);border-radius:var(--radius-pill);font:inherit;font-size:13px;cursor:pointer;text-align:left}
.contrib-options button.is-on{background:var(--green-100);color:var(--green-900);border-color:var(--green-300);font-weight:var(--fw-semibold)}

/* ---------- rows that scroll sideways ----------
   A chip cut clean at the screen edge ("ครอบค|") reads as a rendering bug. Fading the last
   32px makes it read as "swipe for more". The fade goes away once the row is scrolled to its end
   (class set by the small watcher in script.js / incident.js). */
.fade-x{-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 32px),transparent);
  mask-image:linear-gradient(to right,#000 calc(100% - 32px),transparent)}
.fade-x.is-end{-webkit-mask-image:none;mask-image:none}

/* ---------- no visible scrollbars anywhere ----------
   Owner's call: bars inside cards and popups look like a stray frame on the edge. Everything
   still scrolls by finger, wheel and trackpad; only the bar itself is hidden. */
html,body,*{scrollbar-width:none;-ms-overflow-style:none}
html::-webkit-scrollbar,body::-webkit-scrollbar,*::-webkit-scrollbar{display:none;width:0;height:0;background:transparent}
