/* ==========================================================================
   RW.001 Puri Dewata Indah. Structure borrowed from jala.tech, palette from
   floc-landing. No emoji anywhere in the output, so every glyph on this site
   comes from assets/icons.svg as single-stroke line art.
   ========================================================================== */

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-padding-top:5.5rem}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font:400 1rem/1.65 "IBM Plex Sans",system-ui,-apple-system,sans-serif;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img,svg{max-width:100%;display:block}
img{height:auto}
a{color:var(--blue);text-decoration-thickness:.06em;text-underline-offset:.18em}
h1,h2,h3,h4{
  font-family:"Montserrat",system-ui,sans-serif;line-height:1.1;
  letter-spacing:-.02em;margin:0;color:var(--ink);text-wrap:balance;
}
h1{font-weight:800;font-size:clamp(1.875rem,4.2vw,3.125rem)}
h2{font-weight:800;font-size:clamp(1.5625rem,3vw,2.375rem)}
h3{font-weight:700;font-size:1.1875rem;letter-spacing:-.01em}
h4{font-weight:700;font-size:1rem}
p{margin:0}
:focus-visible{outline:3px solid var(--blue);outline-offset:3px;border-radius:.25rem}

.wrap{max-width:var(--container);margin-inline:auto;padding-inline:var(--sp-gutter)}
.sec{padding-block:var(--sp-sec)}
.sec-soft{background:var(--bg-soft)}
.stack{display:flex;flex-direction:column}
.skip{position:absolute;left:-9999px}
.skip:focus{left:1rem;top:1rem;z-index:100;background:var(--surface);
  padding:.75rem 1rem;border-radius:var(--r-md);box-shadow:var(--sh2)}

/* jala's two-tone heading. The accent half is the subject, the rest is ink. */
.hl{color:var(--blue)}

.ic{width:1.5rem;height:1.5rem;flex:none;color:currentColor}
.ic-lg{width:2.75rem;height:2.75rem}

.eyebrow{
  font:600 .75rem/1 "IBM Plex Sans",sans-serif;letter-spacing:.16em;
  text-transform:uppercase;color:var(--orange-text);margin:0 0 .875rem;
}
.lede{color:var(--ink-muted);font-size:1.0625rem;max-width:42ch}

.sec-head{max-width:44rem;margin:0 auto var(--sp-sec) auto;text-align:center}
.sec-head p{margin-top:.875rem;color:var(--ink-muted);font-size:1.0625rem}
.sec-head--left{margin-inline:0;text-align:left}

/* ---------- pill button, jala's shape ---------- */
.btn{
  display:inline-flex;align-items:center;gap:.75rem;
  min-height:3rem;padding:.5rem .5rem .5rem 1.5rem;
  border:0;border-radius:var(--r-pill);cursor:pointer;text-decoration:none;
  font:600 1rem/1 "IBM Plex Sans",sans-serif;
  background:var(--blue);color:var(--on-accent);
  transition:background .2s var(--ease-state),transform .2s var(--ease-state);
}
.btn .puck{
  width:2rem;height:2rem;border-radius:50%;display:grid;place-items:center;
  background:rgba(255,255,255,.18);
}
.btn .ic{width:1.125rem;height:1.125rem}
.btn:hover{background:var(--blue-deep);transform:translateY(-1px)}
.btn-ghost{background:transparent;color:var(--blue);
  box-shadow:inset 0 0 0 1.5px var(--line);padding-right:1.5rem}
.btn-ghost:hover{background:var(--bg-soft);transform:none}

/* ---------- glass, surface 1 of 4: sticky masthead ---------- */
.mast{
  position:sticky;top:0;z-index:50;
  background:rgba(var(--glass),var(--glass-a));
  backdrop-filter:blur(18px) saturate(1.2);
  -webkit-backdrop-filter:blur(18px) saturate(1.2);
  border-bottom:1px solid var(--line);
}
.mast .wrap{display:flex;align-items:center;justify-content:space-between;
  gap:1rem;min-height:4.25rem}
.brand{display:flex;align-items:center;gap:.75rem;text-decoration:none;color:var(--ink)}
.brand .seal{
  width:2.25rem;height:2.25rem;border-radius:var(--r-md);flex:none;
  background:var(--blue);color:var(--on-accent);display:grid;place-items:center;
  font:800 .6875rem/1 "Montserrat",sans-serif;letter-spacing:.02em;
}
.brand b{font:800 .9375rem/1.15 "Montserrat",sans-serif;letter-spacing:-.01em}
.brand span{display:block;font:400 .75rem/1.3 "IBM Plex Sans",sans-serif;color:var(--ink-muted)}
.mast nav{display:flex;align-items:center;gap:1.75rem}
.mast nav a{
  text-decoration:none;color:var(--ink-muted);font-weight:500;font-size:.9375rem;
  padding-block:.375rem;border-bottom:2px solid transparent;
}
.mast nav a:hover{color:var(--ink)}
.mast nav a[aria-current="page"]{color:var(--blue);border-bottom-color:var(--blue)}
.navtoggle{display:none;background:none;border:0;color:var(--ink);padding:.5rem;cursor:pointer}

/* ---------- hero, glass surface 2 and 3 ---------- */
.hero{position:relative;isolation:isolate;background:var(--blue-deep);overflow:hidden}
.hero>img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;
}
.hero::after{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(100deg,rgba(var(--scrim-rgb),.86) 0%,rgba(var(--scrim-rgb),.62) 48%,rgba(var(--scrim-rgb),.30) 100%);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
}
.hero .wrap{padding-block:clamp(4rem,13vh,8.5rem);max-width:var(--container)}
.hero-in{max-width:38rem;color:#fff}
.hero h1{color:#fff}
.hero h1 .hl{color:var(--blue-light)}
.hero .place{margin-top:1.125rem;font-size:1.125rem;color:rgba(255,255,255,.86)}
.hero .lede{margin-top:1rem;color:rgba(255,255,255,.78);max-width:36rem}
.hero .btn{margin-top:2rem;background:#fff;color:var(--blue-deep)}
.hero .btn .puck{background:rgba(18,50,56,.10)}
.hero .btn:hover{background:#fff;transform:translateY(-1px)}

.award{
  display:inline-flex;align-items:flex-start;gap:.75rem;margin-bottom:1.5rem;
  padding:.6875rem 1.125rem;border-radius:var(--r-lg);
  background:rgba(255,255,255,.14);
  border:1px solid rgba(255,255,255,.26);
  backdrop-filter:blur(14px) saturate(1.3);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
  color:#fff;max-width:30rem;
}
.award b{display:block;font:700 .8125rem/1.35 "IBM Plex Sans",sans-serif}
.award span{display:block;font-size:.75rem;color:rgba(255,255,255,.72);margin-top:.125rem}

/* ---------- stat band ---------- */
.band{background:var(--blue-deep);color:#fff;position:relative;overflow:hidden}
.band::before{content:"";position:absolute;inset:0;background:var(--lattice);opacity:.5}
.band .wrap{position:relative;display:grid;grid-template-columns:repeat(4,1fr);
  gap:1rem;padding-block:2.25rem;text-align:center}
.stat strong{display:block;font:800 2.375rem/1 "Montserrat",sans-serif;
  font-variant-numeric:tabular-nums;color:#fff}
.stat span{display:block;margin-top:.5rem;font-size:.875rem;color:rgba(255,255,255,.74)}
:root[data-theme="dark"] .band{background:var(--bg-soft)}
:root[data-theme="dark"] .stat strong{color:var(--blue-deep)}
:root[data-theme="dark"] .stat span{color:var(--ink-muted)}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .band{background:var(--bg-soft)}
  :root:not([data-theme="light"]) .stat strong{color:var(--blue-deep)}
  :root:not([data-theme="light"]) .stat span{color:var(--ink-muted)}
}

/* ---------- generic card ---------- */
.card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;display:flex;flex-direction:column;
  transition:box-shadow .25s var(--ease-state),transform .25s var(--ease-state);
}
.card--link:hover{box-shadow:var(--sh2);transform:translateY(-2px)}
.card .body{padding:1.25rem 1.375rem 1.375rem;display:flex;flex-direction:column;gap:.5rem;flex:1}
/* The image is absolutely positioned rather than sized 100%/100%. A percentage
   height against a box whose own height comes from aspect-ratio is cyclic, so
   it resolves to auto, the image keeps its intrinsic ratio and object-fit never
   runs. Portrait photos then stretch the card. Absolute positioning gives the
   image a definite box to cover. */
.card .thumb{aspect-ratio:16/10;background:var(--bg-soft);position:relative;overflow:hidden}
.card .thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.meta{font-size:.8125rem;color:var(--ink-muted)}
/* Stepper helper line. js/kwt-chat.js emits this on both surfaces, so it needs
   a rule here as well as in app.css or it renders unstyled on hidroponik.html. */
.stepper-help{padding:0 1.125rem 1rem;font-size:.9375rem;line-height:1.45;color:var(--ink-muted)}

.grid{display:grid;gap:1.125rem}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}

/* ---------- split feature ---------- */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,4.5rem);align-items:center}
.split img{border-radius:var(--r-lg);box-shadow:var(--sh2);width:100%;aspect-ratio:4/3;object-fit:cover}
.split .txt p{color:var(--ink-muted);margin-top:1rem}
.split .txt .btn{margin-top:1.75rem}

/* ---------- facilities, line art ---------- */
.fac{display:flex;flex-direction:column;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.fac-img{position:relative;aspect-ratio:4/3;background:var(--bg-soft);overflow:hidden}
.fac-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* No photo yet, or the file is missing: fall back to the lattice ground rather
   than a broken-image icon. The icon tile below still identifies the facility. */
.fac-img.kosong{background:var(--bg-soft) var(--lattice)}
.fac-img.kosong img{display:none}
.fac-body{display:flex;gap:1.125rem;padding:1.25rem 1.375rem 1.5rem;align-items:flex-start}
.fac-txt{min-width:0}
/* The line art is drawn at 1.6 stroke, which reads light on its own at card
   scale. A tinted tile behind it gives the card an anchor without thickening
   the drawing, which would break consistency with the icons used inline. */
.fac .tile{width:3.25rem;height:3.25rem;flex:none;border-radius:var(--r-md);
  background:var(--bg-soft);display:grid;place-items:center}
.fac .ic{color:var(--blue)}
.fac .ic-lg{width:2rem;height:2rem}
.fac p{margin-top:.4375rem;color:var(--ink-muted);font-size:.9375rem;line-height:1.6}
.fac h3{line-height:1.3}

/* ---------- pengurus ---------- */
.lead{display:flex;align-items:center;gap:1.25rem;padding:1.5rem 1.75rem;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);margin-bottom:1.125rem}
.lead .seal{width:3.5rem;height:3.5rem;border-radius:var(--r-md);flex:none;
  background:var(--blue);color:var(--on-accent);display:grid;place-items:center;
  font:800 .8125rem/1.15 "Montserrat",sans-serif;text-align:center}
.lead .role{font:600 .75rem/1 "IBM Plex Sans",sans-serif;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-muted)}
.lead .nm{font:800 1.375rem/1.2 "Montserrat",sans-serif;letter-spacing:-.02em;margin-top:.3125rem}
.rt{padding:1.25rem 1.375rem;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg)}
.rt .no{font:700 .75rem/1 "IBM Plex Sans",sans-serif;letter-spacing:.1em;
  text-transform:uppercase;color:var(--orange-text)}
.rt .nm{margin-top:.5rem;font:600 1.0625rem/1.3 "IBM Plex Sans",sans-serif}

/* ---------- umkm ---------- */
.chips{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center;margin-bottom:2.25rem}
.chip{
  border:1px solid var(--line);background:var(--surface);color:var(--ink-muted);
  border-radius:var(--r-pill);padding:.5rem 1rem;min-height:2.5rem;cursor:pointer;
  font:500 .875rem/1 "IBM Plex Sans",sans-serif;
  transition:background .2s var(--ease-state),color .2s var(--ease-state);
}
.chip[aria-pressed="true"]{background:var(--blue);color:var(--on-accent);border-color:var(--blue)}
.chip[disabled]{opacity:.45;cursor:not-allowed}
.chip .n{opacity:.6;margin-left:.25rem}
.prod .thumb{aspect-ratio:5/4}
.prod .harga{font:700 1.0625rem/1 "IBM Plex Sans",sans-serif;color:var(--orange-text)}
.prod .sub{color:var(--ink-muted);font-size:.9375rem}
.wa{
  margin-top:auto;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  min-height:2.75rem;border-radius:var(--r-md);background:var(--green);color:var(--on-accent);
  text-decoration:none;font:600 .9375rem/1 "IBM Plex Sans",sans-serif;padding-inline:1rem;
}
.wa:hover{background:var(--green-hover)}
.wa .ic{width:1.125rem;height:1.125rem}

/* ---------- artikel ---------- */
.article{max-width:42rem;margin-inline:auto}
.article .hero-img{border-radius:var(--r-lg);margin-bottom:2rem;width:100%;
  aspect-ratio:16/9;object-fit:cover}
.article h2{font-size:1.375rem;margin-top:2.25rem}
.article p{margin-top:1.125rem;color:var(--ink);line-height:1.75}
.article .byline{color:var(--ink-muted);font-size:.875rem;margin-top:.875rem}

.quote{max-width:52rem;font:400 clamp(1.25rem,2.4vw,1.625rem)/1.5 "Montserrat",sans-serif;
  letter-spacing:-.015em;color:var(--ink)}

/* ---------- footer ---------- */
.foot{border-top:1px solid var(--line);background:var(--surface);padding-block:3rem 2rem}
.foot .cols{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:2rem}
.foot h4{margin-bottom:.75rem}
.foot ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.foot a{color:var(--ink-muted);text-decoration:none;font-size:.9375rem}
.foot a:hover{color:var(--blue)}
.foot .addr{color:var(--ink-muted);font-size:.9375rem;line-height:1.7}
.foot .fine{margin-top:2.5rem;padding-top:1.5rem;border-top:1px solid var(--line);
  display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  font-size:.8125rem;color:var(--ink-muted)}
.byfloc{color:var(--ink-muted);text-decoration:none}
.byfloc b{color:var(--blue);font-weight:600}

/* ---------- responsive ---------- */
@media (max-width:60rem){
  .split{grid-template-columns:1fr}
  .foot .cols{grid-template-columns:1fr 1fr}
}
@media (max-width:48rem){
  .mast nav{
    display:none;position:absolute;top:100%;left:0;right:0;flex-direction:column;
    align-items:stretch;gap:0;padding:.5rem var(--sp-gutter) 1rem;
    background:rgba(var(--glass),.96);
    backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
    border-bottom:1px solid var(--line);
  }
  .mast nav.open{display:flex}
  .mast nav a{padding:.875rem 0;border-bottom:1px solid var(--line)}
  .navtoggle{display:block}
  .band .wrap{grid-template-columns:repeat(2,1fr);gap:1.75rem 1rem}
  .g3,.g2{grid-template-columns:1fr}
  .sec-head{margin-bottom:2.25rem}
}
@media (max-width:34rem){
  .foot .cols{grid-template-columns:1fr}
  .hero .wrap{padding-block:3.5rem}
}

/* ---------- degradation ---------- */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .mast,.mast nav{background:var(--bg)}
  .award{background:rgba(255,255,255,.20)}
  .hero::after{background:rgba(var(--scrim-rgb),.78)}
}
@media (prefers-reduced-transparency:reduce){
  .mast,.mast nav{background:var(--bg);backdrop-filter:none;-webkit-backdrop-filter:none}
  .award{background:rgba(255,255,255,.22);backdrop-filter:none;-webkit-backdrop-filter:none}
  .hero::after{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(var(--scrim-rgb),.78)}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
}

/* ==========================================================================
   Hidroponik. The app half. Users are KWT members in their 50s to 70s on
   cheap Android handsets, so targets are 3rem minimum, numbers are entered
   with steppers rather than keypads, and status is never carried by colour
   alone. This is also the rehearsal surface for the WhatsApp bot: the chat
   script here and the one in server/routes/rw-chat.js are the same script,
   so anything learned in one is meant to move to the other.
   ========================================================================== */
.app{max-width:34rem;margin-inline:auto}
.status{display:flex;gap:1rem;align-items:flex-start;padding:1.25rem;
  border-radius:var(--r-lg);border:1.5px solid;margin-bottom:1rem}
.status .ic{width:2rem;height:2rem}
.status b{display:block;font:700 1.125rem/1.3 "IBM Plex Sans",sans-serif}
.status p{margin-top:.25rem;font-size:1rem;line-height:1.5}
.st-ok{background:color-mix(in srgb,var(--green) 10%,var(--surface));border-color:var(--green);color:var(--ink)}
.st-ok .ic{color:var(--green)}
.st-warn{background:color-mix(in srgb,var(--orange) 12%,var(--surface));border-color:var(--orange);color:var(--ink)}
.st-warn .ic{color:var(--orange-text)}

.task{border:1.5px solid var(--orange);border-radius:var(--r-lg);
  background:var(--surface);padding:1rem 1.25rem;margin-bottom:1.25rem}
.task .lbl{font:600 .75rem/1 "IBM Plex Sans",sans-serif;letter-spacing:.1em;
  text-transform:uppercase;color:var(--orange-text)}
.task p{margin-top:.5rem;font:600 1.125rem/1.4 "IBM Plex Sans",sans-serif}

.bigbtn{display:flex;align-items:center;gap:1rem;width:100%;min-height:4rem;
  padding:.875rem 1.25rem;margin-bottom:.75rem;border:1.5px solid var(--line);
  border-radius:var(--r-lg);background:var(--surface);color:var(--ink);
  font:600 1.125rem/1.3 "IBM Plex Sans",sans-serif;text-align:left;cursor:pointer}
.bigbtn .ic{width:1.75rem;height:1.75rem;color:var(--blue)}
.bigbtn--go{background:var(--blue);border-color:var(--blue);color:var(--on-accent)}
.bigbtn--go .ic{color:var(--on-accent)}

.metrics{display:grid;grid-template-columns:1fr 1fr;gap:.625rem;margin-top:1rem}
.metric{background:var(--bg-soft);border:1px solid var(--line);
  border-radius:var(--r-md);padding:.875rem 1rem}
.metric .k{display:block;font-size:.875rem;color:var(--ink-muted)}
.metric .v{font:800 1.625rem/1.1 "Montserrat",sans-serif;font-variant-numeric:tabular-nums;
  letter-spacing:-.02em;display:block;margin-top:.125rem}
.metric .r{font-size:.8125rem;color:var(--ink-muted)}
.metric[data-state="warn"] .v{color:var(--orange-text)}

.prov{display:inline-flex;align-items:center;gap:.375rem;margin-top:1rem;
  padding:.25rem .625rem;border-radius:var(--r-pill);font-size:.75rem;
  border:1px solid var(--line);background:var(--bg-soft);color:var(--ink-muted)}
.prov::before{content:"";width:.5rem;height:.5rem;border-radius:50%;background:var(--orange)}
.prov[data-src="measured"]::before{background:var(--green)}

/* ---- guided chat. The bot asks, the user taps. Typing is never required. --- */
.chat{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface);
  overflow:hidden;margin-top:1.25rem}
.chat .hd{display:flex;align-items:center;gap:.75rem;padding:.875rem 1.125rem;
  border-bottom:1px solid var(--line);background:var(--bg-soft)}
.chat .hd b{font:600 .9375rem/1 "IBM Plex Sans",sans-serif}
.chat .hd .ic{width:1.25rem;height:1.25rem;color:var(--green)}
.log{padding:1.125rem;display:flex;flex-direction:column;gap:.625rem;
  min-height:13rem;max-height:26rem;overflow-y:auto}
.msg{max-width:85%;padding:.75rem 1rem;border-radius:1.125rem;font-size:1.0625rem;line-height:1.5}
.msg.bot{align-self:flex-start;background:var(--bg-soft);border-bottom-left-radius:.375rem}
.msg.me{align-self:flex-end;background:var(--blue);color:var(--on-accent);border-bottom-right-radius:.375rem}
.answers{display:flex;flex-wrap:wrap;gap:.5rem;padding:0 1.125rem 1.125rem}
.ans{min-height:3rem;padding:.625rem 1.125rem;border-radius:var(--r-pill);
  border:1.5px solid var(--blue);background:var(--surface);color:var(--blue);
  font:600 1rem/1 "IBM Plex Sans",sans-serif;cursor:pointer}
/* .ans:hover must not out-specify the primary variant. It used to repaint the
   background pale while the text stayed white, so the confirm button went
   unreadable the moment a finger or cursor rested on it. */
.ans:not(.ans--main):hover{background:color-mix(in srgb,var(--blue) 8%,var(--surface))}
.ans--main{background:var(--blue);color:var(--on-accent)}
.ans--main:hover{background:var(--blue-deep);color:var(--on-accent)}
.ans--quiet{border-color:var(--line);color:var(--ink-muted)}
.stepper{display:flex;align-items:center;gap:.75rem;padding:0 1.125rem 1.125rem}
.stepper button{width:3.5rem;height:3.5rem;border-radius:var(--r-md);flex:none;
  border:1.5px solid var(--blue);background:var(--surface);color:var(--blue);
  font:700 1.75rem/1 "IBM Plex Sans",sans-serif;cursor:pointer}
.stepper .val{flex:1;text-align:center}
.stepper .val b{display:block;font:800 2.25rem/1 "Montserrat",sans-serif;
  font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.stepper .val span{font-size:.875rem;color:var(--ink-muted)}

.byfloc-app{display:flex;align-items:center;justify-content:center;gap:.5rem;
  margin-top:1.5rem;font-size:.8125rem;color:var(--ink-muted);text-decoration:none}
.byfloc-app b{color:var(--blue);font-weight:600}
