# Florist Website Design That Wins Orders | ADTYAA

> Florist website design that turns visitors into orders: custom-built, mobile-first, multi-admin WhatsApp dock. See the Atelier release.

- URL: https://medikabyte.com/florist-website-design/
- Diperbarui: 2026-10-16
- Penulis: MedikaByte
- Penerbit: MedikaByte (B2B digital agency)

Skip to content

[**ADTYAA** Technology & Digital Systems](https://medikabyte.com/)

**EN**

**ID**

**中文**

Consultation

[Capabilities](https://medikabyte.com/#capabilities)
[Expertise](https://medikabyte.com/#expertise)
[Approach](https://medikabyte.com/#approach)
[Proof](https://medikabyte.com/#proof)
[About](https://medikabyte.com/#about)
[Essentials](https://medikabyte.com/essentials/)
Consultation

# Florist Website Design: *Build a Shop Window That Takes Orders While You Arrange Flowers*

**Live demo · Release notes Atelier Florist, *telah rilis.* Browse 16 pages, Florist Kit, and the multi-admin WhatsApp dock in a full preview. **View the demo****

By Adtyaa 10 October 2026 9 min read

A flower shop sells a feeling, and its website has only a few seconds to deliver it. Good florist website design makes a customer see the bouquet, trust the shop, and message an admin before the moment passes. Most florists do not lose orders because their flowers are weak. They lose them because the page is slow, the photos are heavy, and nobody can tell who to message. I am Adtyaa, and this guide covers what I build into a florist’s website so the shop keeps selling while the team is busy at the workbench.

**The idea in one line**

A florist’s website should work like a well-run counter: show the work clearly, answer questions fast, and hand the customer to a real person on WhatsApp without friction.

## Florist website design starts with the order, not the homepage

Before choosing fonts or colors, I trace how a customer actually buys flowers. The journey is short and emotional: an occasion appears, a style is chosen, a person is contacted, and delivery details are confirmed. Strong florist website design supports each of those steps and removes anything that does not.

![Florist website design for a flower shop: florist taking an order by phone beside a fresh bouquet](https://medikabyte.com/wp-content/uploads/2026/10/Custom-florist-website-design.jpg)

Every order starts with a conversation. The website should make that conversation easy to begin.

| The customer is… | The site should… | Built with |
| --- | --- | --- |
| Choosing by occasion | Filter the catalog by mood and color | Catalog filters and curated collections |
| Comparing sizes and styles | Show clear photos, sizes, and what is included | Product sheets with gallery and size options |
| Asking a question | Offer the right admin in one tap | Multi-admin WhatsApp contact dock |
| Waiting for delivery | Show status, schedule, and delivery areas | Order tracking and delivery information |

Think of it as the difference between a shop window and a shop counter. The window attracts attention, but the counter closes the sale. Florist website design that ignores the counter looks lovely and sells little, which is why I plan the ordering path before the visual style.

## Custom website for flower shop: why a made-to-fit build feels faster

Ready-made themes arrive with dozens of features a florist may never use: layered sliders, widgets, built-in animations, and extra script libraries. All of it loads every time a page opens, and the site slows down. A custom website for flower shop owners works the other way around. Only what the shop uses is written, and only what is on the page is loaded.

That is the principle behind the Atelier Florist release. The HTML, CSS, JavaScript, and page components are built exclusively for each website, with no modified template and no polished-up ready-made theme underneath. The release also uses no external JavaScript libraries, which keeps pages light on a mobile connection. Because nothing unused is loaded, the pages open quickly, and quick pages matter for florist website design on a phone. The full release, with live demo and release notes, is available from the card at the top of this page.

## Florist web development services: what sixteen pages cover

When people ask what florist web development services include, I point to a complete structure rather than a single homepage. The Atelier release has sixteen standalone pages that share the same components, grouped around how a floral business actually operates.

#### Collections and gifts

Home, the signature catalog with mood and color filters, seasonal botanicals, curated gifts, grand arrangements, and a members’ privilege page.

#### Moments and events

Curated moments, wedding and corporate event décor, and a bespoke commission page that moves from story to sketch to delivery.

#### Customer service

A gift concierge, product sheets, delivery tracking, and a message reveal card that opens a recipient-only page with text, photo, or video.

#### Corporate

A hospitality and corporate page with account management and scheduled refreshes, plus a client portal for orders, invoices, and support.

Not every shop needs all sixteen. The point is that the structure exists, so adding a wedding page or a corporate gifting program later is an extension, not a rebuild. Good florist website design also anticipates growth: seasonal peaks, wedding bookings, and corporate accounts all arrive eventually. It sits on top of the broader [ADTYAA capabilities](https://medikabyte.com/#capabilities) in engineering, growth, and security.

### Want to see how your shop would look?

Send your shop name and a few favorite photos on WhatsApp. I will reply within 24 hours with a suggested page structure.

[Talk to ADTYAA on WhatsApp](https://wa.me/6281411188809)

**View the Atelier release**

## Responsive florist website: design for the phone in the customer’s hand

Most flower orders start on a phone, often in a hurry and sometimes at night. A responsive florist website is not simply a desktop layout squeezed smaller. Navigation, photos, and buttons are planned for thumbs and small screens first.

- Photos are resized automatically when uploaded and load only when they appear on screen, so a big catalog stays quick.
- One WhatsApp button opens a concierge desk where visitors choose an admin who is online and a topic, and the message fills in automatically.
- Delivery schedules, areas, and care guidance are easy to find, which cuts repeat questions for your team.
- Pages follow Google’s performance guidance, including [Core Web Vitals](https://web.dev/articles/vitals), so speed supports search visibility too.

The multi-admin contact dock deserves a closer look. Each admin has a role, a photo, and online hours, so a customer asking about a wedding reaches the event specialist, while someone checking an order reaches the order desk. It feels like a good shop counter, only available around the clock.

## Web designer for florists: let the owner edit without breaking the design

A beautiful site decays quickly if updating it is painful. When I work as a web designer for florists, I design for the person who will change prices and photos every week. Florist Kit is a plugin and page builder made for flower shops, so owners edit directly on the shop’s own pages, without confusing settings panels.

| Task | How it works |
| --- | --- |
| Swap a bouquet photo | Upload and choose; the image is resized automatically |
| Update text or prices | Type directly on the page |
| Fix a mistake | Open the history and undo changes one at a time |
| Protect the design | The layout is locked, so content edits cannot break it |

The owner needs no coding, no style settings, and no technical vocabulary. If a new feature is needed later, it is written into the site on request, which means no waiting for a third-party plugin update.

## Flower shop website builder or custom build: how to choose

Many owners start by searching for a flower shop website builder, and for a simple catalog with low order volume, a do-it-yourself builder can be a reasonable first step. The question is what you need the site to do in a year.

| If you need… | A builder fits when | A custom build fits when |
| --- | --- | --- |
| A simple online catalog | Orders are few and the look can be generic | You want a distinct brand look |
| Special features | Standard blocks are enough | You need filters, tracking, or a corporate portal |
| Fast, light pages | Default speed is acceptable | Speed on mobile is a priority |
| Ongoing change | You are happy to manage everything yourself | You want updates and fixes handled for you |

ADTYAA sits between the two on purpose: the site is custom-built, but Florist Kit keeps editing as simple as a builder. Maintenance and updates can be handled by our team as part of a care plan, and our [Essentials](https://medikabyte.com/essentials/) range covers themes, plugins, and add-ons.

## Jasa pembuatan website custom Jakarta untuk toko bunga

Bagi pemilik toko bunga di Jakarta, jasa pembuatan website custom Jakarta berarti website yang dibuat khusus untuk cara toko Anda bekerja, bukan template yang dipoles. ADTYAA berbasis di Jakarta melalui DJURAGAN IKLAN ID, dengan pengalaman 80+ klien dan 100+ proyek serta rating 5.0 dari 21 ulasan Google. Pertemuan langsung dapat diatur dengan janji temu, dan setiap pesan dibalas dalam 24 jam.

Pembayaran online lewat Midtrans, Xendit, atau transfer bisa ditambahkan sebagai modul terpisah setelah katalog dan pesanan berjalan. Anda dapat mengenal model kerja kami di bagian [tentang kami](https://medikabyte.com/#about).

In short, the best florist website design is the one your team can run without a developer on call. That is the standard I build to, and the reason editing, tracking, and contact tools are part of the design rather than add-ons.

## After launch: getting the shop found and keeping it running

A finished site is the start, not the end. Florists compete locally, so the website works alongside search and advertising: SEO for the searches your customers use, a complete Google Business Profile, and Google or Meta ads timed to peak seasons. Behind the scenes, security and updates keep the shop online when it matters most, which is why our growth and security systems sit under one team. Treating the site as a living part of the business is what separates durable florist website design from a one-off launch. The [approach](https://medikabyte.com/#approach) is the same for every client: discover, audit, build, and optimize.

### Let’s design the shop window your flowers deserve

Tell me about your shop and the occasions you sell most. You will receive a written proposal with scope, plan, and next steps within 24 hours.

[Talk to ADTYAA on WhatsApp](https://wa.me/6281411188809) [See the Florist Atelier release](https://medikabyte.com/themes-florist-toko-bunga/)

## Florist Website Design: Frequently Asked Questions

**How much does florist website design cost?**

Every project is scoped individually. After a short consultation you receive a written proposal that reflects the pages, features, and integrations your shop needs, such as catalog filters, delivery tracking, or online payment.

**Do I need technical skills to update my flower shop website?**

No. With Florist Kit you edit text and photos directly on the page, and the layout stays locked so the design cannot be broken by a content mistake. Every change is recorded in a history and can be undone one by one.

**Will large bouquet photos slow my website down?**

The site is built to avoid that. Photos are resized automatically when uploaded and only load when they come into view, so a rich catalog still opens quickly on a phone.

**Can several admins handle WhatsApp orders from one button?**

Yes. The Contact Dock supports multiple admins, each with a role, photo, and online hours. Visitors pick an admin and a topic, and the WhatsApp message is filled in automatically.

**Can I accept online payments and add features later?**

Yes. Payment through Midtrans, Xendit, or bank transfer can be added as a separate module once your catalog and orders are running. New features are written directly into your site, so you do not wait for third-party plugin updates.

Project brief

## Share your requirement.

Describe what you are building, what is not performing, or what needs to improve. I will review the brief and respond within 24 hours.

WhatsApp / Phone [0814 111 888 09](tel:+6281411188809)

Email [hallo@adtyaa.cloud](mailto:hallo@adtyaa.cloud)

Base **Jakarta, Indonesia**

Location

## Find us on Google Maps.

In-person meetings are by appointment. Please message first so a time can be confirmed.

### DJURAGAN IKLAN ID

Founded by ADTYAA

Jl. Green Pramuka City No.9 13, RT.13/RW.9, Rawasari, Kec. Cempaka Putih, Kota Jakarta Pusat, DKI Jakarta 10570

#### Opening hours

Mon, Wed to Sat 08:00 – 21:30

Tuesday 08:00 – 21:00

Sunday 09:00 – 21:30

[Get directions](https://www.google.com/maps/dir/?api=1&destination=-6.1883766,106.8732792&destination_place_id=ChIJKcjnOqb1aS4RfbYD_EKMv84)
[Chat on WhatsApp](https://wa.me/6281411188809)
[Call now](tel:+6281411188809)

Build what your business depends on.

## Let’s build something worth depending on.

One accountable technology partner across engineering, growth, security, and digital infrastructure.

Request a consultation [Explore capabilities](https://medikabyte.com/#capabilities)

[**ADTYAA**](https://medikabyte.com/)

Digital Systems & Technology Consultancy

Aditya

Founder & Technology Strategist

Djuragan Iklan

Navigate

- [Capabilities](https://medikabyte.com/#capabilities)
- [Expertise](https://medikabyte.com/#expertise)
- [Approach](https://medikabyte.com/#approach)
- [About](https://medikabyte.com/#about)
- Location
- Contact

Capabilities

- [Software Engineering](https://medikabyte.com/#capabilities)
- [Digital Engineering](https://medikabyte.com/#capabilities)
- [Growth Systems](https://medikabyte.com/#capabilities)
- [Security & Infrastructure](https://medikabyte.com/#capabilities)
- [Medical SEO](https://medikabyte.com/#medical)
- [Custom Plugins](https://medikabyte.com/essentials/)
- [Custom Themes](https://medikabyte.com/essentials/)
- [Add-ons & Care Plans](https://medikabyte.com/essentials/)

Contact

[WhatsApp](https://wa.me/6281411188809)
[hallo@adtyaa.cloud](mailto:hallo@adtyaa.cloud)
Jakarta, Indonesia

ADTYAA

© 2026 ADTYAA. All rights reserved.

[Essentials](https://medikabyte.com/essentials/)

[Chat on WhatsApp](https://wa.me/6281411188809)

**Atelier Florist · Release v1.0** Custom florist website by ADTYAA

[Open full page](https://medikabyte.com/themes-florist-toko-bunga/)

/* ===== halaman ===== */ .flr{width:100%;background:var(--p);overflow:hidden} .flr-w{max-width:1280px;margin:0 auto;padding:0 clamp(20px,5vw,64px)} .flr-ver{display:flex;gap:18px;flex-wrap:wrap;font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--s);padding-bottom:18px;border-bottom:1px solid var(--ln);margin-bottom:clamp(36px,6vw,56px)} .flr-ver b{font-weight:400;color:var(--g)} .flr-hero{padding:clamp(48px,8vw,96px) 0 clamp(48px,7vw,84px)} .flr-hg{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,4fr);gap:clamp(32px,6vw,96px);align-items:end} .flr h1{font-family:var(--serif);font-weight:300;font-size:clamp(48px,7.6vw,112px);line-height:.94;letter-spacing:-.015em} .flr h1 em{font-style:italic;color:var(--g)} .flr-lead{font-size:15px;line-height:1.9;color:var(--s);max-width:54ch;margin:32px 0 38px} .flr-bt{display:flex;gap:14px;flex-wrap:wrap} .flr .flr-btn,.flr-m .flr-btn{display:inline-flex;align-items:center;justify-content:center;min-height:52px;padding:0 34px;border:1px solid var(--i);color:var(--i);font-size:12px;letter-spacing:.22em;text-transform:uppercase;position:relative;overflow:hidden;isolation:isolate;transition:color .5s var(--ease),border-color .5s var(--ease);text-align:center} .flr .flr-btn::before,.flr-m .flr-btn::before{content:"";position:absolute;inset:0;background:var(--i);transform:scaleY(0);transform-origin:bottom;transition:transform .5s var(--ease);z-index:-1} .flr .flr-btn:hover,.flr .flr-btn:focus-visible,.flr-m .flr-btn:hover,.flr-m .flr-btn:focus-visible{color:var(--p)} .flr .flr-btn:hover::before,.flr .flr-btn:focus-visible::before,.flr-m .flr-btn:hover::before,.flr-m .flr-btn:focus-visible::before{transform:scaleY(1)} .flr .flr-btn.solid,.flr-m .flr-btn.solid{background:var(--i);color:var(--p)} .flr .flr-btn.solid::before,.flr-m .flr-btn.solid::before{background:var(--g)} .flr .flr-btn.solid:hover,.flr-m .flr-btn.solid:hover{color:#fff;border-color:var(--g)} .flr .flr-vid,.flr-m .flr-vid{display:inline-flex;align-items:center;gap:10px;font-size:11px;letter-spacing:.2em;text-transform:uppercase;border-bottom:1px solid var(--g);padding-bottom:4px;transition:color .3s,border-color .3s} .flr .flr-vid:hover,.flr-m .flr-vid:hover{color:var(--g)} .flr-vid svg{width:15px;height:15px;fill:var(--g);flex:0 0 auto} .flr-vl{margin-top:26px} .flr-stats{border-top:1px solid var(--i)} .flr-st{padding:20px 0;border-bottom:1px solid var(--ln)} .flr-st b{display:block;font-family:var(--serif);font-weight:300;font-size:clamp(44px,5vw,64px);line-height:1} .flr-st span{display:block;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--s);margin-top:8px} .flr-ex{border-top:1px solid var(--ln);padding:clamp(56px,8vw,104px) 0} .flr-eg{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(28px,6vw,96px);align-items:end} .flr h2{font-family:var(--serif);font-weight:300;font-size:clamp(32px,3.8vw,56px);line-height:1.06} .flr-ex p{font-size:15px;line-height:1.9;color:var(--s);max-width:50ch} .flr-sw{display:flex;margin-top:30px;padding-left:9px} .flr-sw i{display:block;width:44px;height:44px;border-radius:50%;border:2px solid var(--p);margin-left:-9px} .flr-end{background:var(--st);padding:clamp(28px,4vw,44px) 0} .flr-eh{display:flex;justify-content:space-between;align-items:center;gap:22px;flex-wrap:wrap} .flr-eh span.t{font-family:var(--serif);font-weight:300;font-size:clamp(22px,2.6vw,32px);line-height:1.15} .flr-eh .flr-bt{align-items:center} .flr-eh .flr-btn{min-height:46px;padding:0 24px;font-size:11px} .flr.js .flr-rv{opacity:0;transform:translateY(22px);transition:opacity 1s var(--ease),transform 1.1s var(--ease)} .flr.js .flr-rv.in{opacity:1;transform:none} @media(max-width:820px){.flr-hg,.flr-eg{grid-template-columns:1fr}.flr-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;border-top:1px solid var(--i)}.flr-st{border-bottom:0;padding:16px 0 0}} @media(max-width:480px){.flr .flr-btn{width:100%}.flr-stats{grid-template-columns:1fr 1fr}}

/* ===== popup ===== */ .flr-m{position:fixed;inset:0;z-index:100010;display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(43,36,40,.62);-webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);opacity:0;visibility:hidden;transition:opacity .45s var(--ease),visibility 0s .45s} .flr-m.on{opacity:1;visibility:visible;transition-delay:0s} .flr-pn{position:relative;width:min(920px,100%);max-height:92vh;display:flex;background:var(--p);transform:translateY(16px) scale(.985);transition:transform .6s var(--ease)} .flr-m.on .flr-pn{transform:none} .flr-pn.sm{width:min(560px,100%)} .flr-pn::after{content:"";position:absolute;inset:10px;border:1px solid var(--g);opacity:.55;pointer-events:none;z-index:2} .flr-sc{width:100%;overflow:auto;padding:56px 48px 44px;-webkit-overflow-scrolling:touch} .flr-m .flr-x{position:absolute;right:18px;top:18px;width:44px;height:44px;display:flex;align-items:center;justify-content:center;z-index:3;background:var(--p)} .flr-x svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1} .flr-ey{display:block;font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--g);margin-bottom:12px} .flr-m h2{font-family:var(--serif);font-weight:300;font-size:clamp(30px,4vw,44px);line-height:1.08;margin-bottom:12px} .flr-m .d{font-size:14px;line-height:1.85;color:var(--s);margin-bottom:24px;max-width:62ch} .flr-m .flr-bt{margin-bottom:6px;align-items:center} .flr-m .flr-btn{min-height:46px;padding:0 24px;font-size:11px} .flr-sec{margin-top:52px} .flr-m h3{font-family:var(--serif);font-weight:300;font-size:clamp(26px,3vw,34px);line-height:1.1;padding-top:18px;border-top:1px solid var(--i);margin-bottom:6px} .flr-m h3+.d{margin-top:8px} .flr-m .flr-nums{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border-top:1px solid var(--i);margin-top:30px} .flr-nums div{padding:18px 14px 18px 0;border-bottom:1px solid var(--ln)} .flr-nums div+div{padding-left:16px;border-left:1px solid var(--ln)} .flr-nums b{display:block;font-family:var(--serif);font-weight:300;font-size:44px;line-height:1} .flr-nums span{display:block;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--s);margin-top:6px} .flr-cg{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:6px} .flr-cg>div{padding:22px 24px 22px 0;border-bottom:1px solid var(--ln)} .flr-cg>div:nth-child(even){padding-left:24px;border-left:1px solid var(--ln)} .flr-cg h4,.flr-gp h4,.flr-m .k h4{font-family:var(--serif);font-weight:400;font-size:22px;line-height:1.15;margin-bottom:8px} .flr-cg li,.flr-m .k li,.flr-nt li{font-size:13px;line-height:1.65;color:var(--s);padding:6px 0;border-top:1px solid var(--ln)} .flr-gp{margin-top:26px} .flr-gp h4{font-family:var(--sans);font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--g);font-weight:400;margin-bottom:4px} .flr-pr{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,8fr);gap:20px;padding:12px 0;border-top:1px solid var(--ln)} .flr-pr b{font-family:var(--serif);font-weight:400;font-size:20px;line-height:1.2} .flr-pr span{font-size:12.5px;line-height:1.7;color:var(--s)} .flr-tr{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));margin-top:6px} .flr-tr>div{padding:20px 20px 20px 0;border-bottom:1px solid var(--ln)} .flr-tr>div+div{padding-left:20px;border-left:1px solid var(--ln)} .flr-tr h4{font-family:var(--serif);font-weight:400;font-size:24px;margin-bottom:8px} .flr-tr p{font-size:13px;line-height:1.75;color:var(--s)} .flr-lk{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:36px;margin-top:22px} .flr-m .k li{color:var(--i)} .flr-m .k.no li{color:var(--s)} .flr-tb{overflow-x:auto;margin-top:14px} .flr-m table{width:100%;min-width:600px;border-collapse:collapse;font-size:13px} .flr-m th,.flr-m td{text-align:left;vertical-align:top;padding:14px 16px 14px 0;border-bottom:1px solid var(--ln)} .flr-m th{font-size:11px;letter-spacing:.16em;text-transform:uppercase;font-weight:400;color:var(--s);border-bottom:1px solid var(--i)} .flr-m th.us{color:var(--i);border-bottom:2px solid var(--g);padding-left:14px} .flr-m td:first-child{font-family:var(--serif);font-size:18px;color:var(--i);width:24%} .flr-m td{color:var(--s)} .flr-m td.us{color:var(--i);background:rgba(169,143,99,.1);padding-left:14px} .flr-nt{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:36px;margin-top:18px} .flr-nt h4{font-family:var(--serif);font-weight:400;font-size:22px;margin-bottom:8px} .flr-nt li b{font-weight:500;color:var(--i)} .flr-fq{margin-top:10px;border-top:1px solid var(--ln)} .flr-fq details{border-bottom:1px solid var(--ln)} .flr-fq summary{list-style:none;cursor:pointer;position:relative;padding:18px 40px 18px 0;font-family:var(--serif);font-size:clamp(19px,2.2vw,23px);line-height:1.3} .flr-fq summary::-webkit-details-marker{display:none} .flr-fq summary::after{content:"+";position:absolute;right:6px;top:50%;transform:translateY(-50%);font:300 24px/1 var(--sans);color:var(--g);transition:transform .3s var(--ease)} .flr-fq details[open] summary::after{transform:translateY(-50%) rotate(45deg)} .flr-fq details p{padding:0 40px 20px 0;font-size:13.5px;line-height:1.85;color:var(--s)} .flr-fin{margin-top:46px;padding-top:24px;border-top:1px solid var(--i)} .flr-dm{font-size:13px;color:var(--s);margin-top:18px;text-align:center;letter-spacing:.04em} .flr-dm+.flr-bt{margin-top:0} .flr-pn.sm .flr-bt{flex-direction:column;align-items:stretch} .flr-pn.sm .flr-btn{width:100%} .flr-pn.sm .flr-vl2{margin-top:22px;text-align:center} @media(max-width:760px){.flr-sc{padding:50px 22px 32px}.flr-m .flr-nums{grid-template-columns:repeat(2,minmax(0,1fr))}.flr-nums div:nth-child(3){padding-left:0;border-left:0}.flr-cg,.flr-nt,.flr-lk,.flr-tr{grid-template-columns:1fr}.flr-cg>div,.flr-cg>div:nth-child(even),.flr-tr>div,.flr-tr>div+div{padding-left:0;border-left:0}.flr-pr{grid-template-columns:1fr;gap:4px}}

/* ===== peragaan multi admin di catatan rilis ===== */ .flr-pvw{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:clamp(20px,4vw,48px);margin-top:10px;align-items:start} .flr-pv{border:1px solid var(--g);background:rgba(169,143,99,.1);padding:8px 22px 6px;position:relative} .flr-pv .flr-r:last-child{border-bottom:0} .flr-pvh{font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:#8A7248;padding:14px 0 10px;border-bottom:1px solid rgba(31,26,29,.14)} .flr-pvw ul{margin:0} .flr-pvw li{font-size:13px;line-height:1.65;color:var(--s);padding:8px 0;border-top:1px solid var(--ln)} .flr-pvw li b{font-weight:500;color:var(--i)} .flr-pvn{margin-top:14px} @media(max-width:760px){.flr-pvw{grid-template-columns:1fr}.flr-pv{padding:6px 16px 4px}}

/* ===== blok florist kit (hijau sage) ===== */ .flr-m .flr-kit{background:#3B4A40;color:#EEF0E8;padding:44px 40px 40px;margin-top:56px;position:relative} .flr-kit .flr-ey{margin-bottom:10px;color:#CDB98A} .flr-m .flr-kit h3{color:#EEF0E8;border-top:0;padding-top:0;margin-bottom:10px;font-size:clamp(30px,3.6vw,42px)} .flr-m .flr-kit .d{color:#C3CBBE;margin-bottom:22px} .flr-vs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0;margin:0 0 6px;border:1px solid rgba(238,240,232,.24)} .flr-vs div{padding:16px 18px} .flr-vs div+div{border-left:1px solid rgba(238,240,232,.24);background:rgba(238,240,232,.1)} .flr-vs small{display:block;font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:#A9B3A4;margin-bottom:6px} .flr-vs div+div small{color:#CDB98A} .flr-vs b{display:block;font-family:var(--serif);font-weight:400;font-size:20px;line-height:1.25;color:#EEF0E8} .flr-vs div:first-child b{color:#A9B3A4;text-decoration:line-through;text-decoration-color:rgba(169,179,164,.6)} .flr-kit .flr-tr>div{border-bottom-color:rgba(238,240,232,.22)} .flr-kit .flr-tr>div+div{border-left-color:rgba(238,240,232,.22)} .flr-kit .flr-tr h4,.flr-kit .k h4{color:#EEF0E8} .flr-kit .flr-tr p{color:#C3CBBE} .flr-m .flr-kit .k li{color:#EEF0E8;border-top-color:rgba(238,240,232,.22)} .flr-m .flr-kit .k.no li{color:#A9B3A4} @media(max-width:760px){.flr-m .flr-kit{padding:34px 22px 30px}.flr-vs{grid-template-columns:1fr}.flr-vs div+div{border-left:0;border-top:1px solid rgba(238,240,232,.24)}.flr-kit .flr-tr>div+div{border-left:0}}

/* ===== concierge desk ===== */ .flr-tp{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:24px} .flr-m .flr-tp button{min-height:40px;padding:0 16px;border:1px solid rgba(31,26,29,.22);font-size:12px;letter-spacing:.04em;transition:all .3s} .flr-m .flr-tp button:hover{border-color:var(--i)} .flr-m .flr-tp button[aria-pressed="true"]{background:var(--i);color:var(--p);border-color:var(--i)} .flr-l{border-top:1px solid rgba(31,26,29,.14)} .flr-r{display:grid;grid-template-columns:52px minmax(0,1fr) auto;gap:16px;align-items:center;padding:14px 0;border-bottom:1px solid rgba(31,26,29,.14)} .flr-r.off .flr-av,.flr-r.off .flr-ro{opacity:.6} .flr-av{width:52px;height:52px;border-radius:50%;background:var(--st) center/cover no-repeat;display:flex;align-items:center;justify-content:center;font-family:var(--serif);font-size:22px} .flr-nm{font-family:var(--serif);font-size:21px;line-height:1.1} .flr-ro{font-size:12px;color:var(--s)} .flr-su{display:flex;align-items:center;gap:7px;font-size:11.5px;margin-top:3px} .flr-su i{width:7px;height:7px;border-radius:50%;background:var(--on);display:inline-block} .flr-r.off .flr-su i{background:#8F867D} .flr-m .flr-go{display:inline-flex;align-items:center;gap:8px;min-height:42px;padding:0 16px;border:1px solid var(--i);font-size:11px;letter-spacing:.18em;text-transform:uppercase;transition:background .35s,color .35s,border-color .35s} .flr-m .flr-go:hover,.flr-m .flr-go:focus-visible{background:var(--i);color:var(--p)} .flr-go svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.3;stroke-linecap:round;stroke-linejoin:round} .flr-hr{font-size:12px;color:var(--s);margin:18px 0 10px} .flr-ft{display:flex;gap:22px;flex-wrap:wrap;font-size:11px;letter-spacing:.16em;text-transform:uppercase} .flr-m .flr-ft a{border-bottom:1px solid var(--g);padding-bottom:2px} @media(max-width:480px){.flr-r{grid-template-columns:44px minmax(0,1fr);}.flr-r .flr-go{grid-column:1/-1;justify-content:center}.flr-av{width:44px;height:44px}}

/* ===== dock kontak ===== */ .flr-dock{position:fixed;right:max(20px,env(safe-area-inset-right,0px));bottom:max(20px,calc(env(safe-area-inset-bottom,0px) + 12px));z-index:99996;display:flex;align-items:center;gap:12px;opacity:0;transform:translateY(16px);transition:opacity .8s var(--ease),transform .9s var(--ease)} .flr-dock.in{opacity:1;transform:none} .flr-dock .flr-b{position:relative;display:flex;align-items:center;justify-content:center;width:52px;height:52px;border-radius:50%;border:1px solid var(--g);background:var(--p);color:var(--i);box-shadow:0 10px 30px rgba(31,26,29,.22);transition:transform .45s var(--ease),background-color .35s,color .35s} .flr-dock .flr-b.wa{width:60px;height:60px;background:var(--n);color:#fff} .flr-dock .flr-b:hover,.flr-dock .flr-b:focus-visible{transform:translateY(-4px)} .flr-dock .flr-b:not(.wa):hover{background:var(--n);color:#fff} .flr-b svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round} .flr-b.wa svg{width:27px;height:27px} .flr-dot{position:absolute;right:3px;top:3px;width:12px;height:12px;border-radius:50%;background:var(--on);border:2px solid var(--n)} .flr-dot.off{background:#8F867D} .flr-dot::after{content:"";position:absolute;inset:-5px;border-radius:50%;border:1px solid var(--on);opacity:0;animation:flrP 2.8s var(--ease) infinite} .flr-dot.off::after{display:none} @keyframes flrP{0%{opacity:.8;transform:scale(.5)}100%{opacity:0;transform:scale(1.6)}} .flr-tt{position:absolute;bottom:calc(100% + 12px);right:0;white-space:nowrap;background:var(--n);color:#fff;font-size:11px;letter-spacing:.08em;padding:8px 14px;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .3s,transform .4s var(--ease),visibility 0s .3s;pointer-events:none} .flr-b:hover .flr-tt,.flr-b:focus-visible .flr-tt{opacity:1;visibility:visible;transform:none;transition-delay:0s} .flr-toast{position:absolute;right:0;bottom:calc(100% + 14px);background:var(--n);color:#fff;font-size:12px;letter-spacing:.04em;padding:10px 16px;white-space:nowrap;opacity:0;visibility:hidden;transform:translateY(6px);transition:opacity .35s,transform .45s var(--ease),visibility 0s .35s} .flr-toast.on{opacity:1;visibility:visible;transform:none;transition-delay:0s} @media(prefers-reduced-motion:reduce){.flr *,.flr-m *,.flr-dock *{transition:none!important;animation:none!important}.flr.js .flr-rv{opacity:1;transform:none}}

Rilis **v1.0** Oktober 2026

# Atelier Florist, *telah rilis.*

Situs web luxury floral atelier khusus pasar Jakarta yang dibekali Florist Kit siap pakai. Pemilik toko dapat dengan mudah memperbarui katalog foto dan narasi produk tanpa kendala teknis.

**Lihat catatan rilis**

**Lihat demo**

[Video dokumentasi](https://florist.adtyaa.cloud/documentation/)

**16** Halaman lengkap

**5** Palet warna

**0** Code JS luar

## Dibuat eksklusif, bukan template aftermarket.

Tidak ada tema jadi yang dipoles ulang dan tidak ada template yang dimodifikasi. Setiap bagian ditulis untuk toko bunga, dan hanya yang dipakai yang ikut dimuat.

Lihat catatan rilis atau coba demonya.

**Catatan rilis**

**Demo**

[Video dokumentasi](https://florist.adtyaa.cloud/documentation/)

Catatan rilis

## Florist Jakarta v1.0

Satu Platform Digital Floral Atelier Eksklusif di Jakarta.
Lengkap dengan Florist Kit siap pakai — Anda cukup mengunggah foto karya bunga terbaik dan menyesuaikan teks. Ubah toko bunga Anda menjadi brand high-end dalam hitungan menit..

[Buka situs florist](https://florist.adtyaa.cloud/)
[Video dokumentasi](https://florist.adtyaa.cloud/documentation/)

**16** Halaman

**5** Palet warna

**3** Tugas klien

**0** Pustaka JS luar

### Empat komponen bersama

Dibuat sekali dan dipakai di setiap halaman. Mengubah satu pengaturan, semua halaman ikut.

#### Header

- Bar same-day delivery dengan jam tutup 15.00 WIB yang bisa diatur
- Mega menu: Collection, Moments, Bespoke
- Menu samping untuk ponsel
- Transparan di atas hero, otomatis solid di halaman tanpa hero

#### Footer

- Kolom The Atelier dan Client Care
- Langganan Join the Inner Circle
- Tombol cepat lokasi, telepon, dan WhatsApp

#### Palet

- Lima palet: Porcelain dan Aubergine, Ivory dan Emerald, Blush dan Bordeaux, Sage dan Champagne, Midnight dan Gold
- Pilihan tersimpan di peramban pengunjung
- Tombol salin tautan pilihan

#### Contact Dock

- Tiga tombol melayang: lokasi, telepon, WhatsApp
- Multi admin, masing-masing dengan peran, foto, dan jam online
- Admin yang sedang online tampil paling atas
- Pilihan topik mengisi pesan WhatsApp otomatis

### Contact Dock multi admin

Satu tombol WhatsApp, banyak admin. Pengunjung memilih admin yang sedang online, dan pesan terisi otomatis. Daftar di bawah ini hidup: status online mengikuti jam sekarang.

Concierge Desk

- **Banyak admin**, masing-masing dengan peran, foto, dan jam online sendiri
- **Admin online** otomatis tampil paling atas, yang belum buka diberi jam mulainya
- **Titik hijau** di tombol WhatsApp dan jumlah admin online di keterangannya
- **Pilihan topik**: pemesanan, bespoke atau event, corporate, status pesanan
- **Pesan WhatsApp** terisi nama admin, topik, dan halaman yang dibuka
- **Lokasi dan telepon** ikut di dock yang sama

**Coba jendela lengkap**

### Enam belas halaman

Setiap halaman berdiri sendiri sebagai satu berkas dan memakai komponen yang sama.

#### Koleksi dan hadiah

**Beranda** Hero, pilih suasana, kalender musim, Privilege, Gift Concierge, Atelier, Corporate, Journal, Same-Day Delivery

**The Signature Collection** Katalog dengan filter suasana dan warna, bagian atelier

**The Privilege** Early Access, Appreciation Pricing, Priority Concierge, vault musiman, tiga langkah akses

**Fresh Botanicals** Bunga musim ini, indeks, perjalanan kebun ke studio, panduan perawatan

**Patisserie dan Curated Gifts** Perfect Pairs, pita sutra, kemasan premium, kartu tulisan tangan

**Grand Arrangements** Bunga papan Selamat dan Sukses, Turut Berduka Cita, bingkai Solid Wood, Premium Acrylic, Brushed Metal

#### Momen dan acara

**Curated Moments** Empat momen, alur ceritakan, kami memilih, dirangkai dan dikirim, galeri, kutipan

**Event dan Spatial Décor** Wedding Installations, Corporate Gala Scaping, Intimate Dining, sebelum dan sesudah, lima tahap kerja

**Bespoke Commission** Berceritalah, konsep dan sketsa, perangkaian, pengantaran, Commission Brief

#### Layanan pelanggan

**Gift Concierge** Ceritakan, kami memilihkan, reservasi, bicara langsung via WhatsApp

**Lembar produk** Galeri foto, info, pilihan ukuran, timeline tahap pesanan, karya terkait

**Pelacakan pengiriman** Lacak pesanan, jadwal dan area kirim, panduan perawatan, pertanyaan umum

**Message Reveal** Kartu dengan QR, tampilan khusus penerima, pesan, foto, dan video

#### Korporat

**Corporate dan Hospitality** Dedicated Account Manager, Scheduled Weekly Refresh, Corporate Gifting Programs, studi kasus

**Portal korporat** Masuk akun, ringkasan, jadwal minggu ini, lokasi aktif, pesanan hadiah, invoice, bantuan

#### Jurnal

**The Floral Journal** Artikel unggulan, Floristpedia A sampai Z, newsletter Inner Circle

Buatan sendiri, bukan produk pihak ketiga

### Florist Kit

Plugin dan page builder khusus toko bunga. Klien mengedit langsung di halaman tokonya, tanpa panel pengaturan yang membingungkan.

Page builder umum **Ratusan opsi yang tidak Anda perlukan**

Florist Kit **Tiga pekerjaan: foto, teks, urutan**

#### Edit halaman

Klik judul atau foto, lalu ketik atau seret foto baru. Bagian halaman bisa dipindah atau disembunyikan. Ada pratinjau, Batalkan, dan Riwayat.

#### Tambah karya

Satu formulir mengisi katalog, filter, dan halaman produk. Sampai lima foto, harga berformat rupiah, plus suasana dan warna.

#### Lihat pesanan

Semua pesanan di satu kotak masuk. Klien memajukan tahap dari Diterima sampai Terkirim, pelanggan langsung melihatnya.

#### Yang bisa diubah klien

- Foto: unggah atau seret
- Judul, deskripsi, dan teks tombol
- Nama, harga, dan kategori karya
- Urutan dan tampil bagian halaman
- Status pesanan dan foto konfirmasi

#### Dikunci oleh desainer

- Font dan ukuran huruf
- Warna brand dan palet
- Jarak, tata letak, dan animasi
- Struktur halaman dan menu

### Dibuat eksklusif, bukan template aftermarket

Tema siap pakai membawa puluhan fitur yang belum tentu dibutuhkan florist, seperti slider berlapis, widget, animasi bawaan, dan pustaka skrip tambahan. Semuanya ikut dimuat setiap halaman dibuka, sehingga website menjadi lambat. Di sini tidak ada template yang dimodifikasi dan tidak ada tema jadi yang dipoles ulang.

| Aspek | Template aftermarket | Website Custom Boutique Florist |
| --- | --- | --- |
| Asal kode | Tema siap pakai yang dimodifikasi | Dibuat eksklusif |
| Fitur | Puluhan fitur bawaan, belum tentu dibutuhkan | Hanya yang dibutuhkan florist |
| Ketergantungan plugin | Bergantung pada tumpukan plugin pihak ketiga | Minim |
| Page builder | Page builder umum dengan ratusan opsi | Florist Kit buatan sendiri |
| Kecepatan muat | Kode tak terpakai ikut dimuat di setiap halaman | Rata-rata sekitar 48 KB per halaman, sebelum kompresi server |
| Pengembangan | Terbatas pada apa yang disediakan tema | Fitur baru ditambahkan sesuai request |

### Catatan rilis

#### Termasuk di v1.0

- **16 halaman** dengan header, footer, palet, dan Contact Dock bersama
- **5 PILIHANpalet warna** dengan penyimpanan pilihan pengunjung
- **Florist Kit** untuk edit halaman, tambah karya, dan kelola pesanan
- **Pelacakan pesanan** dengan foto konfirmasi
- **Message Reveal** dan portal korporat

#### Diisi per klien

- **Nama brand** dan teks bertanda kurung siku
- **Foto** pada kotak 4:3 yang masih berupa penanda
- **Data admin**: nama, peran, nomor WhatsApp, foto, dan jam online
- **Pembayaran online** (Midtrans, Xendit, transfer) sebagai modul terpisah
- **Perawatan** dan pembaruan sebagai paket tersendiri

### Pertanyaan yang sering diajukan

**Apakah website ini memakai template atau page builder bawaan?**

Tidak. HTML, CSS, JavaScript, dan komponen halaman dibuat eksklusif untuk setiap website. Page builder-nya, Florist Kit, sendiri khusus toko bunga.

**Apakah klien perlu keahlian teknis?**

Tidak. Cukup bisa mengetik dan memilih foto. Tidak ada pengaturan gaya, kode, atau istilah teknis yang ditampilkan.

**Bagaimana jika klien tidak sengaja salah mengubah?**

Setiap perubahan dicatat di Riwayat dan bisa dibatalkan satu per satu. Karena tampilan terkunci, desain tidak bisa rusak oleh kesalahan isi.

**Apakah foto yang besar akan memperlambat situs?**

Dirancang tidak. Foto dikecilkan otomatis saat diunggah dan hanya dimuat ketika terlihat di layar.

**Bisakah menambah fitur baru nanti?**

Bisa. Karena fungsinya ditulis langsung di dalam website, fitur baru ditambahkan sesuai request tanpa menunggu pembaruan plugin pihak ketiga.

**Bisakah memakai lebih dari satu admin untuk WhatsApp?**

Bisa. Contact Dock mendukung banyak admin, masing-masing dengan peran, foto, dan jam online sendiri. Pengunjung memilih admin dan topik, lalu pesan WhatsApp terisi otomatis.

**Bisakah menerima pembayaran online?**

Bisa, sebagai modul terpisah. Midtrans, Xendit, atau transfer dapat ditambahkan setelah katalog dan pesanan berjalan, sesuai kebutuhan toko.

**Siapa yang merawat dan memperbarui?**

Tim kami. Pembaruan dan perbaikan dapat dikelola sebagai bagian dari paket perawatan.

[Buka situs florist](https://florist.adtyaa.cloud/)

**Hubungi admin**

[Video dokumentasi](https://florist.adtyaa.cloud/documentation/)

Demo

## Lihat demo

Jelajahi situs florist yang sudah berjalan, lengkap dengan header, palet, dan halaman-halamannya.

[Buka demo](https://florist.adtyaa.cloud/)

**Jadwalkan via WhatsApp**

[Tonton video dokumentasi](https://florist.adtyaa.cloud/documentation/)

florist.adtyaa.cloud

Concierge Desk

## Pilih admin yang ingin Anda hubungi.

Tim kami siap membantu pemesanan, rangkaian khusus, dan pertanyaan Anda.

Lihat lokasi Telepon

Lihat lokasi
Telepon

**Chat WhatsApp**

/* ===== PENGATURAN: ubah data admin di sini ===== */ var BRAND='Florist Jakarta'; var ADMINS=[ {name:'Admin Satu',role:'Pemesanan dan katalog',wa:'6281411188809',photo:'',open:8,close:17}, {name:'Admin Dua',role:'Bespoke dan event',wa:'6281411188809',photo:'',open:12,close:21}, {name:'Admin Tiga',role:'Corporate dan hadiah',wa:'6281411188809',photo:'',open:9,close:22} ]; var MAPS_URL='https://www.google.com/maps/search/?api=1&query=DJURAGAN+IKLAN+ID+Green+Pramuka+City+Jakarta'; var PHONE='+6281411188809'; var PHONE_LABEL='0814 111 888 09'; var TOPICS=['Pemesanan bunga','Bespoke atau event','Corporate','Status pesanan']; var HOURS_LABEL='Jam layanan 08.00 sampai 22.00 WIB'; /* =============================================== */

function $(i){return document.getElementById(i)} function safe(fn){try{fn()}catch(e){if(window.console)console.warn('[flr]',e)}} function esc(t){return String(t||'').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"')} function digits(n){var d=String(n||'').replace(/[^0-9]/g,'');if(d.charAt(0)==='0')d='62'+d.slice(1);return d} function pad(n){return n<10?'0'+n:''+n} var active=null,lastFocus=null,topic=-1,tick=null,toastT=null; function hourNow(){ try{var q=new URLSearchParams(location.search).get('flrhour');if(q!==null&&q!==''&&!isNaN(parseInt(q,10)))return parseInt(q,10)%24}catch(e){} try{var h=parseInt(new Intl.DateTimeFormat('en-GB',{timeZone:'Asia/Jakarta',hour:'2-digit',hour12:false}).format(new Date()),10);if(!isNaN(h))return h%24}catch(e){} return new Date().getHours(); } function status(a,h){ if(h>=a.open&&h ':' '+esc(a.name.charAt(0))+' '; h+='

'+av+'

'+esc(a.name)+'

'+esc(a.role)+'

'+esc(x.s.txt)+'

**Chat**

'; }); $('flr-l').innerHTML=h; if($('flr-pv'))$('flr-pv').innerHTML=h; } function buildTopics(){ var h='';TOPICS.forEach(function(t,i){h+='

**'+esc(t)+'**

'}); $('flr-tp').innerHTML=h; } function message(a){ var t='Halo '+a.name+', saya '; t+=topic>-1?('ingin bertanya tentang '+TOPICS[topic].toLowerCase()):'ingin bertanya'; t+=' di halaman rilis '+BRAND+'.'; return t; } function toast(m){var t=$('flr-toast');t.textContent=m;t.classList.add('on');clearTimeout(toastT);toastT=setTimeout(function(){t.classList.remove('on')},3200)}

function hide(m){m.classList.remove('on');m.setAttribute('aria-hidden','true')} function setHash(h){try{history.replaceState(null,'',h?('#'+h):(location.pathname+location.search))}catch(e){}} function openM(id){ var m=$(id);if(!m)return; if(active&&active!==m){hide(active);clearInterval(tick)}else if(!active){lastFocus=document.activeElement} if(id==='flr-cd'){buildList();clearInterval(tick);tick=setInterval(buildList,60000)} active=m;m.classList.add('on');m.setAttribute('aria-hidden','false');document.documentElement.style.overflow='hidden'; if(id==='flr-rilis')setHash('rilis');else if(id==='flr-demo')setHash('demo');else setHash(''); var sc=m.querySelector('.flr-sc');if(sc)sc.scrollTop=0; setTimeout(function(){var f=m.querySelector('.flr-go,.flr-btn,.flr-x');if(f)f.focus()},90); } function closeM(){ if(!active)return; hide(active);active=null;clearInterval(tick);document.documentElement.style.overflow='';setHash(''); if(lastFocus&&lastFocus.focus)lastFocus.focus(); } function fromHash(){ var h=(location.hash||'').toLowerCase(); if(h==='#rilis')openM('flr-rilis');else if(h==='#demo')openM('flr-demo'); }

function setup(){ var root=$('flr');root.classList.add('js'); ['flr-rilis','flr-demo','flr-cd','flr-dock'].forEach(function(id){document.body.appendChild($(id))});

var rv=root.querySelectorAll('.flr-rv'); requestAnimationFrame(function(){[].forEach.call(rv,function(el,i){setTimeout(function(){el.classList.add('in')},120+i*130)})});

var tel='tel:'+PHONE.replace(/[^0-9+]/g,''); ['flr-map','flr-map2'].forEach(function(id){$(id).setAttribute('href',MAPS_URL)}); ['flr-tel','flr-tel2'].forEach(function(id){$(id).setAttribute('href',tel)}); $('flr-tel-t').textContent='Telepon '+PHONE_LABEL; $('flr-tel2').textContent='Telepon '+PHONE_LABEL; $('flr-hr').textContent=HOURS_LABEL; buildTopics();buildList();updateDock();setInterval(function(){updateDock();buildList()},60000);

$('flr-wa').addEventListener('click',function(){openM('flr-cd')});

document.addEventListener('click',function(e){ var o=e.target.closest&&e.target.closest('[data-flr-open]'); if(o){e.preventDefault();openM(o.getAttribute('data-flr-open'));return} if(!active)return; if(e.target===active){closeM();return} if(e.target.closest('[data-flr-close]')){closeM();return} var t=e.target.closest('[data-t]'); if(t&&active.id==='flr-cd'){ var i=parseInt(t.getAttribute('data-t'),10);topic=(topic===i)?-1:i; [].forEach.call($('flr-tp').querySelectorAll('[data-t]'),function(b){b.setAttribute('aria-pressed',String(parseInt(b.getAttribute('data-t'),10)===topic))}); return; } var g=e.target.closest('[data-i]'); if(g){var a=ADMINS[parseInt(g.getAttribute('data-i'),10)];window.open('https://wa.me/'+digits(a.wa)+'?text='+encodeURIComponent(message(a)),'_blank','noopener');closeM()} });

document.addEventListener('keydown',function(e){ if(!active)return; if(e.key==='Escape'){closeM();return} if(e.key==='Tab'){ var f=[].slice.call(active.querySelectorAll('button,a[href],summary')).filter(function(x){return x.offsetParent!==null}); if(!f.length)return;var a=f[0],z=f[f.length-1]; if(e.shiftKey&&document.activeElement===a){e.preventDefault();z.focus()} else if(!e.shiftKey&&document.activeElement===z){e.preventDefault();a.focus()} } });

var touch=('ontouchstart' in window)||(navigator.maxTouchPoints>0); ['flr-tel','flr-tel2'].forEach(function(id){ $(id).addEventListener('click',function(e){ if(touch)return;e.preventDefault(); try{if(navigator.clipboard&&navigator.clipboard.writeText){var pr=navigator.clipboard.writeText(PHONE_LABEL);if(pr&&pr.catch)pr.catch(function(){})}}catch(x){} if(id==='flr-tel2')closeM(); toast('Telepon kami: '+PHONE_LABEL); }); });

window.addEventListener('hashchange',fromHash); setTimeout(function(){$('flr-dock').classList.add('in')},900); fromHash(); } function boot(){safe(setup)} if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',boot)}else{boot()} })();

var D = {"skip":["Skip to content","Lewati ke konten","跳到主要内容"],"menu":["Menu","Menu","菜单"],"lang.group":["Language","Bahasa","语言"],"nav.cap":["Capabilities","Keahlian","核心能力"],"nav.work":["Expertise","Spesialisasi","行业专长"],"nav.app":["Approach","Pendekatan","合作流程"],"nav.proof":["Proof","Bukti","实绩"],"nav.about":["About","Tentang","关于"],"nav.ess":["Essentials","Essentials","Essentials"],"nav.cta":["Consultation","Konsultasi","预约咨询"],"nav.contact":["Contact","Kontak","联系我们"],"bag.aria":["ADTYAA Essentials: services, themes, plugins, and add-ons","ADTYAA Essentials: jasa, tema, plugin, dan add-on","ADTYAA Essentials：服务、主题、插件与附加服务"],"hero.cta1":["Request a consultation","Jadwalkan konsultasi","预约咨询"],"hero.cta2":["Explore capabilities","Jelajahi keahlian","了解核心能力"],"hero.role":["Founder & Technology Strategist","Founder & Technology Strategist","创始人 · 技术战略顾问"],"cap4.title":["Software Engineering","Software Engineering","软件工程"],"cap1.title":["Digital Engineering","Digital Engineering","数字工程"],"cap2.title":["Growth Systems","Growth Systems","增长体系"],"cap3.title":["Security & Infrastructure","Security & Infrastructure","安全与基础设施"],"opt.med":["Medical SEO","SEO Medis","医疗 SEO"],"opt.other":["Other / Not sure yet","Lainnya / Belum yakin","其他 / 尚未确定"],"contact.label":["Project brief","Brief proyek","项目简报"],"contact.title":["Share your requirement.","Sampaikan kebutuhan Anda.","请告诉我们您的需求。"],"contact.copy":["Describe what you are building, what is not performing, or what needs to improve. I will review the brief and respond within 24 hours.","Jelaskan apa yang sedang Anda bangun, apa yang belum berjalan optimal, atau apa yang perlu ditingkatkan. Saya akan mempelajari brief dan merespons dalam 24 jam.","请描述您正在构建的内容、表现不佳之处或需要改进的方面。我会审阅简报并在 24 小时内回复，咨询以英文进行。"],"contact.wa":["WhatsApp / Phone","WhatsApp / Telepon","WhatsApp / 电话"],"contact.loc":["Base","Lokasi","所在地"],"contact.city":["Jakarta, Indonesia","Jakarta, Indonesia","印度尼西亚 · 雅加达"],"form.name":["Name *","Nama *","姓名 *"],"form.email":["Email","Email","邮箱"],"form.wa":["WhatsApp","WhatsApp","WhatsApp"],"form.url":["Website","Website","网站"],"form.service":["Capability *","Keahlian *","所需能力 *"],"form.choose":["Choose a capability","Pilih keahlian","请选择能力方向"],"form.eng":["Engagement","Jenis kerja sama","合作类型"],"form.time":["Timeline","Target waktu","时间安排"],"form.choose2":["Choose one","Pilih salah satu","请选择"],"form.msg":["Project / problem","Proyek / masalah","项目 / 问题"],"form.sendwa":["Send via WhatsApp","Kirim lewat WhatsApp","通过 WhatsApp 发送"],"form.sendmail":["Send via email","Kirim lewat email","通过邮件发送"],"form.note":["Your brief opens in WhatsApp or your email application. Nothing is stored on this page.","Brief Anda terbuka di WhatsApp atau aplikasi email, siap dikirim. Tidak ada data yang disimpan di halaman ini.","您的简报将在 WhatsApp 或邮件应用中打开，供您发送。本页面不会保存任何数据。"],"eng.1":["One-time fix or setup","Perbaikan atau setup sekali jalan","一次性修复或设置"],"eng.2":["Full project","Proyek penuh","完整项目"],"eng.3":["Ongoing monthly support","Dukungan bulanan berkelanjutan","持续月度支持"],"eng.4":["Not sure yet","Belum yakin","尚未确定"],"time.1":["As soon as possible","Secepatnya","尽快"],"time.2":["Within 1 month","Dalam 1 bulan","1 个月内"],"time.3":["Within 3 months","Dalam 3 bulan","3 个月内"],"time.4":["Flexible","Fleksibel","灵活"],"f.err":["Please enter your name and choose a capability first.","Isi nama dan pilih keahlian terlebih dahulu.","请先填写姓名并选择能力方向。"],"f.okwa":["Opening WhatsApp...","Membuka WhatsApp...","正在打开 WhatsApp…"],"f.okmail":["Opening your email application...","Membuka aplikasi email Anda...","正在打开邮件应用…"],"m.name":["Name","Nama","Name"],"m.email":["Email","Email","Email"],"m.wa":["WhatsApp","WhatsApp","WhatsApp"],"m.url":["Website","Website","Website"],"m.service":["Capability","Keahlian","Capability"],"m.eng":["Engagement","Jenis kerja sama","Engagement"],"m.time":["Timeline","Target waktu","Timeline"],"m.msg":["Message","Pesan","Message"],"m.subject":["Project enquiry","Permintaan proyek","Project enquiry"],"loc.label":["Location","Lokasi","地点"],"loc.title":["Find us on Google Maps.","Temukan kami di Google Maps.","在 Google 地图上找到我们。"],"loc.lead":["In-person meetings are by appointment. Please message first so a time can be confirmed.","Pertemuan langsung dengan janji temu. Kirim pesan terlebih dahulu agar waktunya dapat dikonfirmasi.","现场会面需提前预约。请先发送消息以确认时间。"],"loc.founded":["Founded by ADTYAA","Founded by ADTYAA","由 ADTYAA 创立"],"loc.hours":["Opening hours","Jam operasional","营业时间"],"loc.d1":["Mon, Wed to Sat","Sen, Rab sampai Sab","周一、周三至周六"],"loc.d2":["Tuesday","Selasa","周二"],"loc.d3":["Sunday","Minggu","周日"],"loc.dir":["Get directions","Petunjuk arah","获取路线"],"loc.wa":["Chat on WhatsApp","Chat via WhatsApp","通过 WhatsApp 洽谈"],"loc.call":["Call now","Telepon sekarang","立即致电"],"loc.map":["DJURAGAN IKLAN ID on Google Maps","DJURAGAN IKLAN ID di Google Maps","DJURAGAN IKLAN ID 的 Google 地图位置"],"final.label":["Build what your business depends on.","Bangun sistem yang diandalkan bisnis Anda.","构建您的业务所依赖的系统。"],"final.title":["Let's build something worth depending on.","Mari bangun sesuatu yang layak diandalkan.","让我们共同构建值得依赖的系统。"],"final.copy":["One accountable technology partner across engineering, growth, security, and digital infrastructure.","Satu partner teknologi yang akuntabel untuk engineering, growth, keamanan, dan infrastruktur digital.","一个对结果负责的技术合作方，覆盖工程、增长、安全与数字基础设施。"],"foot.nav":["Navigate","Navigasi","导航"],"foot.cap":["Capabilities","Keahlian","核心能力"],"foot.con":["Contact","Kontak","联系"],"foot.plugins":["Custom Plugins","Plugin Kustom","定制插件"],"foot.themes":["Custom Themes","Tema Kustom","定制主题"],"foot.addons":["Add-ons & Care Plans","Add-on & Paket Perawatan","附加服务与维护计划"],"foot.rights":["All rights reserved.","Hak cipta dilindungi.","保留所有权利。"],"dock.group":["Quick contact","Kontak cepat","快速联系"],"dock.wa":["Chat on WhatsApp","Chat via WhatsApp","通过 WhatsApp 洽谈"],"dock.maps":["Open in Google Maps","Buka di Google Maps","在 Google 地图中打开"],"dock.call":["Call now","Telepon sekarang","立即致电"],"wa.general":["Hi Adtyaa, I found your guide on florist website design and I'd like to discuss a website for my flower shop.","Hi Adtyaa, I found your guide on florist website design and I'd like to discuss a website for my flower shop.","Hi Adtyaa, I found your guide on florist website design and I'd like to discuss a website for my flower shop."],"wa.article":["Hi Adtyaa, I read your guide on florist website design and I'd like to talk about a custom website for my flower shop.","Hi Adtyaa, I read your guide on florist website design and I'd like to talk about a custom website for my flower shop.","Hi Adtyaa, I read your guide on florist website design and I'd like to talk about a custom website for my flower shop."],"a.home":["Home","Beranda","首页"],"a.m1":["By Adtyaa","Oleh Adtyaa","作者：Adtyaa"],"a.m2":["10 October 2026","10 Oktober 2026","2026 年 10 月 10 日"],"a.m3":["9 min read","Baca 9 menit","阅读约 9 分钟"],"a.toc":["In this article","Dalam artikel ini","本文内容"],"cta.b1":["Talk to ADTYAA on WhatsApp","Hubungi ADTYAA lewat WhatsApp","通过 WhatsApp 联系 ADTYAA"],"cta.b2":["Send a project brief","Kirim brief proyek","提交项目简报"],"au.name":["Adtyaa, Founder of [DJURAGAN IKLAN ID<\/a>","Adtyaa, Founder of](https://maps.app.goo.gl/YRw1yaWB5xfHcjwq5) [DJURAGAN IKLAN ID<\/a>","Adtyaa，](https://maps.app.goo.gl/YRw1yaWB5xfHcjwq5) [DJURAGAN IKLAN ID<\/a> 创始人"],"au.bio":["Builds custom websites, SEO and digital advertising systems for flower shops, B2B brands and startups.","Membangun website custom, SEO, dan sistem iklan digital untuk toko bunga, brand B2B, dan startup.","为花店、B2B 品牌与初创企业构建定制网站、SEO 与数字广告体系。"],"au.cta":["Talk to ADTYAA on WhatsApp","Hubungi ADTYAA lewat WhatsApp","通过 WhatsApp 联系 ADTYAA"],"au.alt":["Adtyaa, author of the florist website design guide","Adtyaa, penulis panduan florist website design","Adtyaa，florist website design 指南作者"]}; var LI = { en: 0, id: 1, zh: 2 }; var L = "en"; var PHONE = "6281411188809", MAIL = "hallo@adtyaa.cloud";](https://maps.app.goo.gl/YRw1yaWB5xfHcjwq5)

function $(sel, ctx) { return Array.prototype.slice.call((ctx || root).querySelectorAll(sel)); } function byId(id) { return document.getElementById(id); } function t(key, lang) { var e = D[key]; if (!e) { return key; } var v = e[LI[lang || L]]; return (v === undefined || v === "") ? e[0] : v; } function msgLang() { return "en"; } function waUrl(m) { return "https://wa.me/" + PHONE + "?text=" + encodeURIComponent(m); }

var scLoaded = false; function loadSC() { if (scLoaded) { return; } scLoaded = true; var l = document.createElement("link"); l.rel = "stylesheet"; l.href = "https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap"; document.head.appendChild(l); } function apply() { if (L === "zh") { loadSC(); } document.documentElement.setAttribute("lang", L === "zh" ? "zh-Hans" : L); root.setAttribute("data-l", L); $("[data-i18n]").forEach(function (el) { el.textContent = t(el.getAttribute("data-i18n")); }); $("[data-i18n-html]").forEach(function (el) { el.innerHTML = t(el.getAttribute("data-i18n-html")); }); $("[data-i18n-alt]").forEach(function (el) { el.setAttribute("alt", t(el.getAttribute("data-i18n-alt"))); }); $("[data-i18n-title]").forEach(function (el) { el.setAttribute("title", t(el.getAttribute("data-i18n-title"))); }); $("[data-i18n-aria]").forEach(function (el) { el.setAttribute("aria-label", t(el.getAttribute("data-i18n-aria"))); }); $("[data-wa]").forEach(function (el) { el.setAttribute("href", waUrl(t(el.getAttribute("data-wa"), msgLang()))); }); $("[data-lang]").forEach(function (b) { b.setAttribute("aria-pressed", b.getAttribute("data-lang") === L ? "true" : "false"); }); var st = byId("fs"); if (st) { st.textContent = ""; st.classList.remove("err"); } }

root.addEventListener("click", function (e) { var b = e.target.closest ? e.target.closest("[data-lang]") : null; if (!b) { return; } L = b.getAttribute("data-lang"); apply(); });

(function initLang() { var pick = null; try { var q = new URLSearchParams(window.location.search || "").get("lang"); if (q && LI[q] !== undefined) { pick = q; } } catch (x) {} if (pick) { L = pick; } })();

var hd = byId("hd"), bg = byId("bg"), mn = byId("mn"); var bar = root.querySelector(".prog span"); var ticking = false; function onScroll() { ticking = false; if (hd) { hd.classList.toggle("sc", window.scrollY > 8); } if (bar) { var h = document.documentElement.scrollHeight - window.innerHeight; var p = h > 0 ? Math.min(1, Math.max(0, window.scrollY / h)) : 0; bar.style.transform = "scaleX(" + p.toFixed(4) + ")"; } } window.addEventListener("scroll", function () { if (!ticking) { ticking = true; window.requestAnimationFrame(onScroll); } }, { passive: true }); onScroll();

function closeMenu() { if (mn) { mn.classList.remove("on"); } if (bg) { bg.setAttribute("aria-expanded", "false"); } } if (bg && mn) { bg.addEventListener("click", function () { var on = mn.classList.toggle("on"); bg.setAttribute("aria-expanded", on ? "true" : "false"); }); mn.addEventListener("click", function (e) { if (e.target.closest && e.target.closest("a")) { closeMenu(); } }); } document.addEventListener("keydown", function (e) { if (e.key === "Escape") { closeMenu(); } }); window.addEventListener("resize", function () { if (window.innerWidth > 1000) { closeMenu(); } });

var form = byId("cf"); if (form) { var fs = byId("fs"); var val = function (id) { var el = byId(id); return el ? el.value.trim() : ""; }; var optText = function (id) { var el = byId(id); if (!el || !el.value) { return ""; } var key = el.options[el.selectedIndex].getAttribute("data-i18n"); return key ? t(key, msgLang()) : el.options[el.selectedIndex].text; }; var setStatus = function (key, err) { fs.textContent = key ? t(key) : ""; fs.classList.toggle("err", !!err); }; var validate = function () { var ok = true; ["f-name", "f-service"].forEach(function (id) { var el = byId(id), bad = !el.value.trim(); el.setAttribute("aria-invalid", bad ? "true" : "false"); if (bad) { ok = false; } }); return ok; }; var compose = function () { var ml = msgLang(), lines = [t("wa.general", ml), ""]; var add = function (k, v) { if (v) { lines.push(t(k, ml) + ": " + v); } }; add("m.name", val("f-name")); add("m.email", val("f-email")); add("m.wa", val("f-wa")); add("m.url", val("f-url")); add("m.service", optText("f-service")); add("m.eng", optText("f-eng")); add("m.time", optText("f-time")); var m = val("f-msg"); if (m) { lines.push(""); lines.push(t("m.msg", ml) + ":"); lines.push(m); } return lines.join("\n"); }; byId("send-wa").addEventListener("click", function () { if (!validate()) { setStatus("f.err", true); return; } setStatus("f.okwa", false); window.open(waUrl(compose()), "_blank", "noopener"); }); byId("send-mail").addEventListener("click", function () { if (!validate()) { setStatus("f.err", true); return; } setStatus("f.okmail", false); var subject = t("m.subject", msgLang()) + " - " + val("f-name"); window.location.href = "mailto:" + MAIL + "?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(compose()); }); form.addEventListener("submit", function (e) { e.preventDefault(); byId("send-wa").click(); }); ["f-name", "f-service"].forEach(function (id) { var el = byId(id); var clear = function () { if (el.value.trim()) { el.setAttribute("aria-invalid", "false"); } }; el.addEventListener("input", clear); el.addEventListener("change", clear); }); }

apply();

var reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;

function initFx(host) { if (!host) { return; } var cv = document.createElement("canvas"); cv.className = "fx"; cv.setAttribute("aria-hidden", "true"); host.insertBefore(cv, host.firstChild); var ctx = cv.getContext("2d"); if (!ctx) { return; } var W = 1, H = 1, stars = [], dust = [], nodes = [], mx = -9999, my = -9999, onScreen = true; var sprite = document.createElement("canvas"); sprite.width = sprite.height = 48; var sg = sprite.getContext("2d"), grad = sg.createRadialGradient(24, 24, 0, 24, 24, 24); grad.addColorStop(0, "rgba(255,243,209,1)"); grad.addColorStop(.25, "rgba(230,200,140,.55)"); grad.addColorStop(1, "rgba(201,164,92,0)"); sg.fillStyle = grad; sg.fillRect(0, 0, 48, 48); function rnd(a, b) { return a + Math.random() * (b - a); } function seed() { var a = W * H, i; stars = []; dust = []; nodes = []; for (i = 0; i < Math.round(a / 9000); i++) { stars.push({ x: rnd(0, W), y: rnd(0, H), r: rnd(.3, 1.05), p: rnd(0, 6.28), s: rnd(.5, 1.6) }); } for (i = 0; i < Math.round(Math.min(46, 16 + a / 42000)); i++) { dust.push({ x: rnd(0, W), y: rnd(0, H), r: rnd(1.4, 3.6), vy: rnd(.1, .38), vx: rnd(-.07, .07), a: rnd(.25, .65), p: rnd(0, 6.28) }); } for (i = 0; i < Math.round(Math.min(64, Math.max(20, a / 24000))); i++) { nodes.push({ x: rnd(0, W), y: rnd(0, H), vx: rnd(-.12, .12), vy: rnd(-.1, .1) }); } } function size() { var r = host.getBoundingClientRect(), dpr = Math.min(window.devicePixelRatio || 1, 2); W = Math.max(1, r.width); H = Math.max(1, r.height); cv.width = Math.round(W * dpr); cv.height = Math.round(H * dpr); ctx.setTransform(dpr, 0, 0, dpr, 0, 0); seed(); draw(0, true); } function draw(t, still) { var i, j, n, m, dx, dy, d, al; ctx.clearRect(0, 0, W, H); for (i = 0; i < stars.length; i++) { n = stars[i]; al = .2 + .6 * (.5 + .5 * Math.sin(t * .001 * n.s + n.p)); ctx.fillStyle = "rgba(243,232,205," + (al * .75).toFixed(3) + ")"; ctx.beginPath(); ctx.arc(n.x, n.y, n.r, 0, 6.2832); ctx.fill(); } for (i = 0; i < nodes.length; i++) { n = nodes[i]; if (!still) { n.x += n.vx; n.y += n.vy; if (n.x < -10) { n.x = W + 10; } else if (n.x > W + 10) { n.x = -10; } if (n.y < -10) { n.y = H + 10; } else if (n.y > H + 10) { n.y = -10; } } for (j = i + 1; j < nodes.length; j++) { m = nodes[j]; dx = n.x - m.x; dy = n.y - m.y; if (dx > 150 || dx < -150 || dy > 150 || dy < -150) { continue; } d = Math.sqrt(dx * dx + dy * dy); if (d < 150) { ctx.strokeStyle = "rgba(217,188,130," + ((1 - d / 150) * .2).toFixed(3) + ")"; ctx.lineWidth = .7; ctx.beginPath(); ctx.moveTo(n.x, n.y); ctx.lineTo(m.x, m.y); ctx.stroke(); } } dx = n.x - mx; dy = n.y - my; d = Math.sqrt(dx * dx + dy * dy); if (d < 190) { ctx.strokeStyle = "rgba(246,231,189," + ((1 - d / 190) * .5).toFixed(3) + ")"; ctx.lineWidth = .9; ctx.beginPath(); ctx.moveTo(n.x, n.y); ctx.lineTo(mx, my); ctx.stroke(); } ctx.fillStyle = "rgba(230,205,150,.7)"; ctx.beginPath(); ctx.arc(n.x, n.y, 1.25, 0, 6.2832); ctx.fill(); } for (i = 0; i < dust.length; i++) { n = dust[i]; if (!still) { n.y -= n.vy; n.x += n.vx + Math.sin(t * .0006 + n.p) * .12; if (n.y < -12) { n.y = H + 12; n.x = rnd(0, W); } } ctx.globalAlpha = n.a * (.65 + .35 * Math.sin(t * .0012 + n.p)); ctx.drawImage(sprite, n.x - n.r * 3, n.y - n.r * 3, n.r * 6, n.r * 6); } ctx.globalAlpha = 1; } function loop(ts) { if (onScreen && !document.hidden) { draw(ts, false); } window.requestAnimationFrame(loop); } size(); if ("ResizeObserver" in window) { new ResizeObserver(function () { size(); }).observe(host); } else { window.addEventListener("resize", size); } if (reduce) { return; } if ("IntersectionObserver" in window) { new IntersectionObserver(function (es) { es.forEach(function (en) { onScreen = en.isIntersecting; }); }, { rootMargin: "100px" }).observe(host); } host.addEventListener("pointermove", function (e) { var r = host.getBoundingClientRect(); mx = e.clientX - r.left; my = e.clientY - r.top; }); host.addEventListener("pointerleave", function () { mx = -9999; my = -9999; }); window.requestAnimationFrame(loop); } initFx(root.querySelector(".ah")); initFx(root.querySelector(".final")); if (reduce || !("IntersectionObserver" in window)) { return; } if (!document.body.classList.contains("elementor-editor-active")) { root.classList.add("js"); var rv = new IntersectionObserver(function (es) { es.forEach(function (en) { if (!en.isIntersecting) { return; } en.target.classList.add("in"); rv.unobserve(en.target); }); }, { threshold: 0, rootMargin: "0px 0px -6% 0px" }); $(".rv").forEach(function (el) { rv.observe(el); }); } })();

tetap bisa diseleksi/disalin. */ (function(){ 'use strict'; if(window.__cgOn)return;window.__cgOn=1; if(document.body&&document.body.classList.contains('elementor-editor-active'))return;

var doc=document,root=doc.documentElement; var EDITABLE="input,textarea,select,[contenteditable='true']"; var COPYABLE='.cm,address'; var WM_MS=5000; /* lama watermark tampil setelah screenshot terdeteksi */ var wm=null,wmTimer=0;

root.classList.add('cg-on');

function inEditable(el){return !!(el&&el.closest&&el.closest(EDITABLE))} function block(e){e.preventDefault()}

/* ---------- Watermark screenshot ---------- */ function showWatermark(){ if(!wm){ if(!doc.body)return; wm=doc.createElement('div'); wm.className='cg-wm'; wm.setAttribute('aria-hidden','true'); doc.body.appendChild(wm); } root.classList.add('cg-shot'); clearTimeout(wmTimer); wmTimer=setTimeout(function(){root.classList.remove('cg-shot')},WM_MS); }

/* ---------- Print ---------- */ function printOn(){root.classList.add('cg-print')} function printOff(){root.classList.remove('cg-print')} window.addEventListener('beforeprint',printOn); window.addEventListener('afterprint',printOff); if(window.matchMedia){ var mq=window.matchMedia('print'); var onMq=function(e){e.matches?printOn():printOff()}; if(mq.addEventListener)mq.addEventListener('change',onMq); else if(mq.addListener)mq.addListener(onMq); }

/* ---------- Mouse / seleksi ---------- */ doc.addEventListener('contextmenu',function(e){ if(!inEditable(e.target))block(e); });

doc.addEventListener('dragstart',block);

doc.addEventListener('selectstart',function(e){ var t=e.target&&e.target.nodeType===1?e.target:(e.target&&e.target.parentElement); if(inEditable(t)||(t&&t.closest&&t.closest(COPYABLE)))return; block(e); });

/* ---------- Keyboard ---------- */ doc.addEventListener('keydown',function(e){ var k=e.code,mod=e.ctrlKey||e.metaKey,stop=false;

/* Screenshot: PrintScreen, Cmd+Shift+3/4/5/6 (Mac), Win+Shift+S */ if(k==='PrintScreen'||e.key==='PrintScreen'|| (e.metaKey&&e.shiftKey&&(k==='Digit3'||k==='Digit4'||k==='Digit5'||k==='Digit6'||k==='KeyS'))){ showWatermark(); }

if(k==='F12'){ stop=true; }else if(mod&&!e.altKey&&(k==='KeyP'||(!e.shiftKey&&(k==='KeyS'||k==='KeyU')))){ stop=true; /* Ctrl/Cmd + P (print), S, U */ }else if( (mod&&e.shiftKey&&(k==='KeyI'||k==='KeyJ'||k==='KeyC'))|| /* Ctrl/Cmd + Shift + I, J, C */ (e.metaKey&&e.altKey&&(k==='KeyI'||k==='KeyJ'||k==='KeyC'||k==='KeyU')) /* Cmd + Option + I, J, C, U (Mac) */ ){ stop=true; } if(stop){block(e);e.stopPropagation()} },true);

/* Di Windows, PrintScreen sering hanya mengirim keyup */ doc.addEventListener('keyup',function(e){ if(e.code==='PrintScreen'||e.key==='PrintScreen')showWatermark(); },true);

/* Desktop saja: bila panel dev tools terbuka (docked), bersihkan console saat jendela di-resize */ if(window.matchMedia&&window.matchMedia('(hover:hover) and (pointer:fine)').matches){ var raf=0; window.addEventListener('resize',function(){ if(raf)return; raf=requestAnimationFrame(function(){ raf=0; if((window.outerWidth-window.innerWidth>200||window.outerHeight-window.innerHeight>260)&&window.console&&console.clear){console.clear()} }); },{passive:true}); } }());
